From: Yifeng Tan Date: Mon, 18 Dec 2017 16:50:58 +0000 (+0800) Subject: conf.c: add relative option for lxc.mount.entry X-Git-Tag: lxc-3.0.0.beta1~104^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=181437fd530cb1d2a9e1ce2afd8aaa5fca16b872;p=thirdparty%2Flxc.git conf.c: add relative option for lxc.mount.entry Signed-off-by: Yifeng Tan --- diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in index 4b97de611..f777ac35f 100644 --- a/doc/lxc.container.conf.sgml.in +++ b/doc/lxc.container.conf.sgml.in @@ -1066,6 +1066,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA don't fail if mount does not work. or to create dir (or file) when the point will be mounted. + source path is taken to be relative to + the mounted container root. For instance, + + +dev/null proc/kcore none bind,relative 0 0 + + + Will expand dev/null to ${}/dev/null, + and mount it to proc/kcore inside the container. + + diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 93d4d09f5..fb02e3e78 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -1814,24 +1814,35 @@ static char *get_field(char *src, int nfields) static int mount_entry(const char *fsname, const char *target, const char *fstype, unsigned long mountflags, const char *data, int optional, int dev, - const char *rootfs) + int relative, const char *rootfs) { int ret; + char srcbuf[MAXPATHLEN]; + const char *srcpath = fsname; #ifdef HAVE_STATVFS struct statvfs sb; #endif - ret = safe_mount(fsname, target, fstype, mountflags & ~MS_REMOUNT, data, + if (relative) { + ret = snprintf(srcbuf, MAXPATHLEN, "%s/%s", rootfs ? rootfs : "/", fsname ? fsname : ""); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("source path is too long"); + return -1; + } + srcpath = srcbuf; + } + + ret = safe_mount(srcpath, target, fstype, mountflags & ~MS_REMOUNT, data, rootfs); if (ret < 0) { if (optional) { INFO("Failed to mount \"%s\" on \"%s\" (optional): %s", - fsname ? fsname : "(null)", target, strerror(errno)); + srcpath ? srcpath : "(null)", target, strerror(errno)); return 0; } SYSERROR("Failed to mount \"%s\" on \"%s\"", - fsname ? fsname : "(null)", target); + srcpath ? srcpath : "(null)", target); return -1; } @@ -1839,12 +1850,12 @@ static int mount_entry(const char *fsname, const char *target, unsigned long rqd_flags = 0; DEBUG("Remounting \"%s\" on \"%s\" to respect bind or remount " - "options", fsname ? fsname : "(none)", target ? target : "(none)"); + "options", srcpath ? srcpath : "(none)", target ? target : "(none)"); if (mountflags & MS_RDONLY) rqd_flags |= MS_RDONLY; #ifdef HAVE_STATVFS - if (fsname && statvfs(fsname, &sb) == 0) { + if (srcpath && statvfs(srcpath, &sb) == 0) { unsigned long required_flags = rqd_flags; if (sb.f_flag & MS_NOSUID) @@ -1860,7 +1871,7 @@ static int mount_entry(const char *fsname, const char *target, required_flags |= MS_NOEXEC; DEBUG("Flags for \"%s\" were %lu, required extra flags " - "are %lu", fsname, sb.f_flag, required_flags); + "are %lu", srcpath, sb.f_flag, required_flags); /* If this was a bind mount request, and required_flags * does not have any flags which are not already in @@ -1879,18 +1890,18 @@ static int mount_entry(const char *fsname, const char *target, } #endif - ret = mount(fsname, target, fstype, mountflags | MS_REMOUNT, data); + ret = mount(srcpath, target, fstype, mountflags | MS_REMOUNT, data); if (ret < 0) { if (optional) { INFO("Failed to mount \"%s\" on \"%s\" " "(optional): %s", - fsname ? fsname : "(null)", target, + srcpath ? srcpath : "(null)", target, strerror(errno)); return 0; } SYSERROR("Failed to mount \"%s\" on \"%s\"", - fsname ? fsname : "(null)", target); + srcpath ? srcpath : "(null)", target); return -1; } } @@ -1899,7 +1910,7 @@ static int mount_entry(const char *fsname, const char *target, skipremount: #endif DEBUG("Mounted \"%s\" on \"%s\" with filesystem type \"%s\"", - fsname ? fsname : "(null)", target, fstype); + srcpath ? srcpath : "(null)", target, fstype); return 0; } @@ -1908,7 +1919,7 @@ skipremount: static void cull_mntent_opt(struct mntent *mntent) { int i; - char *list[] = {"create=dir", "create=file", "optional", NULL}; + char *list[] = {"create=dir", "create=file", "optional", "relative", NULL}; for (i = 0; list[i]; i++) { char *p, *p2; @@ -1988,11 +1999,12 @@ static inline int mount_entry_on_generic(struct mntent *mntent, int ret; unsigned long mntflags; char *mntdata; - bool dev, optional; + bool dev, optional, relative; char *rootfs_path = NULL; optional = hasmntopt(mntent, "optional") != NULL; dev = hasmntopt(mntent, "dev") != NULL; + relative = hasmntopt(mntent, "relative") != NULL; if (rootfs && rootfs->path) rootfs_path = rootfs->mount; @@ -2012,7 +2024,7 @@ static inline int mount_entry_on_generic(struct mntent *mntent, return -1; ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type, mntflags, - mntdata, optional, dev, rootfs_path); + mntdata, optional, dev, relative, rootfs_path); free(mntdata); return ret; @@ -3240,11 +3252,6 @@ int lxc_setup(struct lxc_handler *handler) return -1; } - if (!lxc_list_empty(&lxc_conf->mount_list) && setup_mount_entries(lxc_conf, &lxc_conf->rootfs, &lxc_conf->mount_list, name, lxcpath)) { - ERROR("failed to setup the mount entries for '%s'", name); - return -1; - } - /* Make sure any start hooks are in the container */ if (!verify_start_hooks(lxc_conf)) return -1; @@ -3278,6 +3285,11 @@ int lxc_setup(struct lxc_handler *handler) } } + if (!lxc_list_empty(&lxc_conf->mount_list) && setup_mount_entries(lxc_conf, &lxc_conf->rootfs, &lxc_conf->mount_list, name, lxcpath)) { + ERROR("failed to setup the mount entries for '%s'", name); + return -1; + } + ret = lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console, lxc_conf->ttydir); if (ret < 0) {