git: ce878284318e - main - makefs: Handle special file types when creating a zpool
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 07 Jan 2025 14:32:31 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=ce878284318e71217d8d8f43f7d590b6c338d3aa
commit ce878284318e71217d8d8f43f7d590b6c338d3aa
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-01-07 14:31:02 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-01-07 14:32:20 +0000
makefs: Handle special file types when creating a zpool
Previously, anything other than a regular file, directory or symlink
would cause makefs to exit with an assertion failure. Make it a bit
more resilient to user error: print a warning and skip the file. Add a
regression test wherein we create an image from a devfs mount.
PR: 283583
MFC after: 2 weeks
---
usr.sbin/makefs/tests/makefs_zfs_tests.sh | 22 +++++++++++++++++
usr.sbin/makefs/zfs/fs.c | 39 +++++++++++++++++++++++++------
2 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/usr.sbin/makefs/tests/makefs_zfs_tests.sh b/usr.sbin/makefs/tests/makefs_zfs_tests.sh
index aeda889d9a5c..3d5819439a73 100644
--- a/usr.sbin/makefs/tests/makefs_zfs_tests.sh
+++ b/usr.sbin/makefs/tests/makefs_zfs_tests.sh
@@ -148,6 +148,27 @@ dataset_removal_cleanup()
common_cleanup
}
+#
+# Make sure that we can handle some special file types. Anything other than
+# regular files, symlinks and directories are ignored.
+#
+atf_test_case devfs cleanup
+devfs_body()
+{
+ atf_check mkdir dev
+ atf_check mount -t devfs none ./dev
+
+ atf_check -e match:"skipping unhandled" $MAKEFS -s 1g -o rootpath=/ \
+ -o poolname=$ZFS_POOL_NAME $TEST_IMAGE ./dev
+
+ import_image
+}
+devfs_cleanup()
+{
+ common_cleanup
+ umount -f ./dev
+}
+
#
# Make sure that we can create and remove an empty directory.
#
@@ -842,6 +863,7 @@ atf_init_test_cases()
atf_add_test_case autoexpand
atf_add_test_case basic
atf_add_test_case dataset_removal
+ atf_add_test_case devfs
atf_add_test_case empty_dir
atf_add_test_case empty_fs
atf_add_test_case file_extend
diff --git a/usr.sbin/makefs/zfs/fs.c b/usr.sbin/makefs/zfs/fs.c
index 9413241da0c7..073dce3ce697 100644
--- a/usr.sbin/makefs/zfs/fs.c
+++ b/usr.sbin/makefs/zfs/fs.c
@@ -177,6 +177,13 @@ fsnode_isroot(const fsnode *cur)
return (strcmp(cur->name, ".") == 0);
}
+static bool
+fsnode_valid(const fsnode *cur)
+{
+ return (cur->type == S_IFREG || cur->type == S_IFDIR ||
+ cur->type == S_IFLNK);
+}
+
/*
* Visit each node in a directory hierarchy, in pre-order depth-first order.
*/
@@ -186,9 +193,11 @@ fsnode_foreach(fsnode *root, int (*cb)(fsnode *, void *), void *arg)
assert(root->type == S_IFDIR);
for (fsnode *cur = root; cur != NULL; cur = cur->next) {
- assert(cur->type == S_IFREG || cur->type == S_IFDIR ||
- cur->type == S_IFLNK);
-
+ if (!fsnode_valid(cur)) {
+ warnx("skipping unhandled %s %s/%s",
+ inode_type(cur->type), cur->path, cur->name);
+ continue;
+ }
if (cb(cur, arg) == 0)
continue;
if (cur->type == S_IFDIR && cur->child != NULL)
@@ -381,9 +390,15 @@ fs_populate_sattrs(struct fs_populate_arg *arg, const fsnode *cur,
*/
for (fsnode *c = fsnode_isroot(cur) ? cur->next : cur->child;
c != NULL; c = c->next) {
- if (c->type == S_IFDIR)
+ switch (c->type) {
+ case S_IFDIR:
links++;
- objsize++;
+ /* FALLTHROUGH */
+ case S_IFREG:
+ case S_IFLNK:
+ objsize++;
+ break;
+ }
}
/* The root directory is its own parent. */
@@ -652,6 +667,16 @@ fs_populate_symlink(fsnode *cur, struct fs_populate_arg *arg)
fs_populate_sattrs(arg, cur, dnode);
}
+static fsnode *
+fsnode_next(fsnode *cur)
+{
+ for (cur = cur->next; cur != NULL; cur = cur->next) {
+ if (fsnode_valid(cur))
+ return (cur);
+ }
+ return (NULL);
+}
+
static int
fs_foreach_populate(fsnode *cur, void *_arg)
{
@@ -678,7 +703,7 @@ fs_foreach_populate(fsnode *cur, void *_arg)
ret = (cur->inode->flags & FI_ROOT) != 0 ? 0 : 1;
- if (cur->next == NULL &&
+ if (fsnode_next(cur) == NULL &&
(cur->child == NULL || (cur->inode->flags & FI_ROOT) != 0)) {
/*
* We reached a terminal node in a subtree. Walk back up and
@@ -694,7 +719,7 @@ fs_foreach_populate(fsnode *cur, void *_arg)
eclose(dir->dirfd);
free(dir);
cur = cur->parent;
- } while (cur != NULL && cur->next == NULL &&
+ } while (cur != NULL && fsnode_next(cur) == NULL &&
(cur->inode->flags & FI_ROOT) == 0);
}