conf: move /dev setup to be file descriptor based

parent 567104e5
...@@ -1610,15 +1610,15 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, ...@@ -1610,15 +1610,15 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
if (!wants_console(console)) if (!wants_console(console))
return 0; return 0;
ret = snprintf(path, sizeof(path), "%s/dev/console", rootfs_path);
if (ret < 0 || (size_t)ret >= sizeof(path))
return -1;
/* /*
* When we are asked to setup a console we remove any previous * When we are asked to setup a console we remove any previous
* /dev/console bind-mounts. * /dev/console bind-mounts.
*/ */
if (file_exists(path)) { if (exists_file_at(rootfs->dev_mntpt_fd, "console")) {
ret = snprintf(path, sizeof(path), "%s/dev/console", rootfs_path);
if (ret < 0 || (size_t)ret >= sizeof(path))
return -1;
ret = lxc_unstack_mountpoint(path, false); ret = lxc_unstack_mountpoint(path, false);
if (ret < 0) if (ret < 0)
return log_error_errno(-ret, errno, "Failed to unmount \"%s\"", path); return log_error_errno(-ret, errno, "Failed to unmount \"%s\"", path);
...@@ -1630,7 +1630,7 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, ...@@ -1630,7 +1630,7 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
* For unprivileged containers autodev or automounts will already have * For unprivileged containers autodev or automounts will already have
* taken care of creating /dev/console. * taken care of creating /dev/console.
*/ */
ret = mknod(path, S_IFREG | 0000, 0); ret = mknodat(rootfs->dev_mntpt_fd, "console", S_IFREG | 0000, 0);
if (ret < 0 && errno != EEXIST) if (ret < 0 && errno != EEXIST)
return log_error_errno(-errno, errno, "Failed to create console"); return log_error_errno(-errno, errno, "Failed to create console");
...@@ -1639,7 +1639,7 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, ...@@ -1639,7 +1639,7 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name); return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name);
if (pty_mnt_fd >= 0) { if (pty_mnt_fd >= 0) {
ret = move_mount(pty_mnt_fd, "", -EBADF, path, MOVE_MOUNT_F_EMPTY_PATH); ret = move_mount(pty_mnt_fd, "", rootfs->dev_mntpt_fd, "console", MOVE_MOUNT_F_EMPTY_PATH);
if (!ret) { if (!ret) {
DEBUG("Moved mount \"%s\" onto \"%s\"", console->name, path); DEBUG("Moved mount \"%s\" onto \"%s\"", console->name, path);
goto finish; goto finish;
...@@ -1651,9 +1651,18 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, ...@@ -1651,9 +1651,18 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
pty_mnt_fd, console->name, path); pty_mnt_fd, console->name, path);
} }
ret = safe_mount(console->name, path, "none", MS_BIND, 0, rootfs_path); ret = safe_mount_beneath_at(rootfs->dev_mntpt_fd, console->name, "console", NULL, MS_BIND, NULL);
if (ret < 0) if (ret < 0) {
return log_error_errno(-1, errno, "Failed to mount %d(%s) on \"%s\"", pty_mnt_fd, console->name, path); if (errno == ENOSYS) {
ret = snprintf(path, sizeof(path), "%s/dev/console", rootfs_path);
if (ret < 0 || (size_t)ret >= sizeof(path))
return -1;
ret = safe_mount(console->name, path, "none", MS_BIND, NULL, rootfs_path);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to mount %d(%s) on \"%s\"", pty_mnt_fd, console->name, path);
}
}
finish: finish:
DEBUG("Mounted pty device %d(%s) onto \"%s\"", pty_mnt_fd, console->name, path); DEBUG("Mounted pty device %d(%s) onto \"%s\"", pty_mnt_fd, console->name, path);
...@@ -2581,6 +2590,7 @@ struct lxc_conf *lxc_conf_init(void) ...@@ -2581,6 +2590,7 @@ struct lxc_conf *lxc_conf_init(void)
} }
new->rootfs.managed = true; new->rootfs.managed = true;
new->rootfs.mntpt_fd = -EBADF; new->rootfs.mntpt_fd = -EBADF;
new->rootfs.dev_mntpt_fd = -EBADF;
new->logfd = -1; new->logfd = -1;
lxc_list_init(&new->cgroup); lxc_list_init(&new->cgroup);
lxc_list_init(&new->cgroup2); lxc_list_init(&new->cgroup2);
...@@ -3259,6 +3269,11 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -3259,6 +3269,11 @@ int lxc_setup(struct lxc_handler *handler)
return log_error(-1, "Failed to mount \"/dev\""); return log_error(-1, "Failed to mount \"/dev\"");
} }
lxc_conf->rootfs.dev_mntpt_fd = openat(lxc_conf->rootfs.mntpt_fd, "dev",
O_RDONLY | O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW);
if (lxc_conf->rootfs.dev_mntpt_fd < 0 && errno != ENOENT)
return log_error_errno(-errno, errno, "Failed to open \"/dev\"");
/* Do automatic mounts (mainly /proc and /sys), but exclude those that /* Do automatic mounts (mainly /proc and /sys), but exclude those that
* need to wait until other stuff has finished. * need to wait until other stuff has finished.
*/ */
...@@ -3378,7 +3393,8 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -3378,7 +3393,8 @@ int lxc_setup(struct lxc_handler *handler)
return log_error(-1, "Failed to drop capabilities"); return log_error(-1, "Failed to drop capabilities");
} }
close_prot_errno_disarm(lxc_conf->rootfs.mntpt_fd); close_prot_errno_disarm(lxc_conf->rootfs.mntpt_fd)
close_prot_errno_disarm(lxc_conf->rootfs.dev_mntpt_fd)
NOTICE("The container \"%s\" is set up", name); NOTICE("The container \"%s\" is set up", name);
return 0; return 0;
...@@ -3743,6 +3759,7 @@ void lxc_conf_free(struct lxc_conf *conf) ...@@ -3743,6 +3759,7 @@ void lxc_conf_free(struct lxc_conf *conf)
free(conf->rootfs.path); free(conf->rootfs.path);
free(conf->rootfs.data); free(conf->rootfs.data);
close_prot_errno_disarm(conf->rootfs.mntpt_fd); close_prot_errno_disarm(conf->rootfs.mntpt_fd);
close_prot_errno_disarm(conf->rootfs.dev_mntpt_fd);
free(conf->logfile); free(conf->logfile);
if (conf->logfd != -1) if (conf->logfd != -1)
close(conf->logfd); close(conf->logfd);
......
...@@ -139,17 +139,19 @@ struct lxc_tty_info { ...@@ -139,17 +139,19 @@ struct lxc_tty_info {
/* Defines a structure to store the rootfs location, the /* Defines a structure to store the rootfs location, the
* optionals pivot_root, rootfs mount paths * optionals pivot_root, rootfs mount paths
* @path : the rootfs source (directory or device) * @path : the rootfs source (directory or device)
* @mount : where it is mounted * @mount : where it is mounted
* @bev_type : optional backing store type * @bev_type : optional backing store type
* @options : mount options * @options : mount options
* @mountflags : the portion of @options that are flags * @mountflags : the portion of @options that are flags
* @data : the portion of @options that are not flags * @data : the portion of @options that are not flags
* @managed : whether it is managed by LXC * @managed : whether it is managed by LXC
* @mntpt_fd : fd for @mount * @mntpt_fd : fd for @mount
* @dev_mntpt_fd : fd for /dev of the container
*/ */
struct lxc_rootfs { struct lxc_rootfs {
int mntpt_fd; int mntpt_fd;
int dev_mntpt_fd;
char *path; char *path;
char *mount; char *mount;
char *bdev_type; char *bdev_type;
......
...@@ -551,3 +551,10 @@ bool exists_dir_at(int dir_fd, const char *path) ...@@ -551,3 +551,10 @@ bool exists_dir_at(int dir_fd, const char *path)
return S_ISDIR(sb.st_mode); return S_ISDIR(sb.st_mode);
} }
bool exists_file_at(int dir_fd, const char *path)
{
struct stat sb;
return fstatat(dir_fd, path, &sb, 0) == 0;
}
...@@ -74,5 +74,6 @@ __hidden extern FILE *fdopen_cached(int fd, const char *mode, void **caller_free ...@@ -74,5 +74,6 @@ __hidden extern FILE *fdopen_cached(int fd, const char *mode, void **caller_free
__hidden extern FILE *fopen_cached(const char *path, const char *mode, void **caller_freed_buffer); __hidden extern FILE *fopen_cached(const char *path, const char *mode, void **caller_freed_buffer);
__hidden extern int timens_offset_write(clockid_t clk_id, int64_t s_offset, int64_t ns_offset); __hidden extern int timens_offset_write(clockid_t clk_id, int64_t s_offset, int64_t ns_offset);
__hidden extern bool exists_dir_at(int dir_fd, const char *path); __hidden extern bool exists_dir_at(int dir_fd, const char *path);
__hidden extern bool exists_file_at(int dir_fd, const char *path);
#endif /* __LXC_FILE_UTILS_H */ #endif /* __LXC_FILE_UTILS_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment