makefs: don't needlessly require directories to exist

If a type=dir entry exists and all contents are directories, files
added with contents=, or symlinks with link= attributes then it doesn't
need to exist.  Just let openat fail in that case.  It's conceivable
this will make debugging some cases weird, but it's sufficent to handle
the way we add /root/.ssh in CheriBSD VM images.

This is a recommit of 794154149f with
bugfixes.

Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D38029
This commit is contained in:
Brooks Davis 2023-01-12 18:19:14 +00:00
parent 5e5baba880
commit 6e011d1503

View File

@ -292,6 +292,17 @@ fs_open(const fsnode *cur, struct fs_populate_arg *arg, int flags)
return (fd);
}
static int
fs_open_can_fail(const fsnode *cur, struct fs_populate_arg *arg, int flags)
{
int fd;
char path[PATH_MAX];
fs_populate_path(cur, arg, path, sizeof(path), &fd);
return (openat(fd, path, flags));
}
static void
fs_readlink(const fsnode *cur, struct fs_populate_arg *arg,
char *buf, size_t bufsz)
@ -590,7 +601,12 @@ fs_populate_dir(fsnode *cur, struct fs_populate_arg *arg)
*/
if (!SLIST_EMPTY(&arg->dirs)) {
fs_populate_dirent(arg, cur, dnid);
dirfd = fs_open(cur, arg, O_DIRECTORY | O_RDONLY);
/*
* We only need the directory fd if we're finding files in
* it. If it's just there for other directories or
* files using contents= we don't need to succeed here.
*/
dirfd = fs_open_can_fail(cur, arg, O_DIRECTORY | O_RDONLY);
} else {
arg->rootdirid = dnid;
dirfd = arg->rootdirfd;