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); }