1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-27 16:39:08 +00:00

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
This commit is contained in:
Mark Johnston 2025-01-07 14:31:02 +00:00
parent 2be86b6cc1
commit ce87828431
2 changed files with 54 additions and 7 deletions

View File

@ -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

View File

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