static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs,
int autodevtmpfssize, const char *lxcpath)
{
- __do_free char *path = NULL;
+ __do_close int root_mntpt_fd = -EBADF;
+ const char *path = rootfs->path ? rootfs->mount : NULL;
int ret;
- size_t clen;
mode_t cur_mask;
char mount_options[128];
INFO("Preparing \"/dev\"");
- /* $(rootfs->mount) + "/dev/pts" + '\0' */
- clen = (rootfs->path ? strlen(rootfs->mount) : 0) + 9;
- path = must_realloc(NULL, clen);
sprintf(mount_options, "size=%d,mode=755", (autodevtmpfssize != 0) ? autodevtmpfssize : 500000);
DEBUG("Using mount options: %s", mount_options);
- ret = snprintf(path, clen, "%s/dev", rootfs->path ? rootfs->mount : "");
- if (ret < 0 || (size_t)ret >= clen)
- return -1;
+ root_mntpt_fd = openat(-1, path, O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
+ if (root_mntpt_fd < 0)
+ return log_error_errno(-errno, errno, "Failed to open \"%s\"", path);
cur_mask = umask(S_IXUSR | S_IXGRP | S_IXOTH);
- ret = mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+ ret = mkdirat(root_mntpt_fd, "dev" , S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
if (ret < 0 && errno != EEXIST) {
SYSERROR("Failed to create \"/dev\" directory");
ret = -errno;
goto reset_umask;
}
- ret = safe_mount("none", "dev", "tmpfs", 0, mount_options,
- rootfs->path ? rootfs->mount : NULL );
+ ret = safe_mount_beneath(path, "none", "dev", "tmpfs", 0, mount_options);
if (ret < 0) {
- SYSERROR("Failed to mount tmpfs on \"%s\"", path);
- goto reset_umask;
- }
- TRACE("Mounted tmpfs on \"%s\"", path);
+ __do_free char *fallback_path = NULL;
- ret = snprintf(path, clen, "%s/dev/pts", rootfs->path ? rootfs->mount : "");
- if (ret < 0 || (size_t)ret >= clen) {
- ret = -1;
- goto reset_umask;
+ if (errno != ENOSYS) {
+ SYSERROR("Failed to mount tmpfs on \"%s\"", path);
+ goto reset_umask;
+ }
+
+ if (path) {
+ fallback_path = must_make_path(path, "/dev", NULL);
+ ret = safe_mount("none", fallback_path, "tmpfs", 0, mount_options, path);
+ } else {
+ ret = safe_mount("none", "dev", "tmpfs", 0, mount_options, NULL);
+ }
+ if (ret < 0) {
+ SYSERROR("Failed to mount tmpfs on \"%s\"", path);
+ goto reset_umask;
+ }
}
+ TRACE("Mounted tmpfs on \"%s\"", path);
/* If we are running on a devtmpfs mapping, dev/pts may already exist.
* If not, then create it and exit if that fails...
*/
- ret = mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+ ret = mkdirat(root_mntpt_fd, "dev/pts", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
if (ret < 0 && errno != EEXIST) {
SYSERROR("Failed to create directory \"%s\"", path);
ret = -errno;