From: Daniel J Walsh Date: Mon, 25 Jun 2012 09:53:39 +0000 (+0100) Subject: Support bind mounting host files, as well as directories in LXC X-Git-Tag: v0.9.13-rc1~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=465c055f4a3baa72f06c7677f2203d1002cb2520;p=thirdparty%2Flibvirt.git Support bind mounting host files, as well as directories in LXC Currently libvirt-lxc checks to see if the destination exists and is a directory. If it is not a directory then the mount fails. Since libvirt-lxc can bind mount files on an inode, this patch is needed to allow us to bind mount files on files. Currently we want to bind mount on top of /etc/machine-id, and /etc/adjtime If the destination of the mount point does not exists, it checks if the src is a directory and then attempts to create a directory, otherwise it creates an empty file for the destination. The code will then bind mount over the destination. Signed-off-by: Daniel P. Berrange --- diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index bf67ba11ab..071d8d1bf0 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -650,17 +650,50 @@ static int lxcContainerMountFSBind(virDomainFSDefPtr fs, { char *src = NULL; int ret = -1; + struct stat st; if (virAsprintf(&src, "%s%s", srcprefix, fs->src) < 0) { virReportOOMError(); goto cleanup; } - if (virFileMakePath(fs->dst) < 0) { - virReportSystemError(errno, - _("Failed to create %s"), - fs->dst); - goto cleanup; + if (stat(fs->dst, &st) < 0) { + if (errno != ENOENT) { + virReportSystemError(errno, _("Unable to stat bind target %s"), + fs->dst); + goto cleanup; + } + /* ENOENT => create the target dir or file */ + if (stat(src, &st) < 0) { + virReportSystemError(errno, _("Unable to stat bind source %s"), + src); + goto cleanup; + } + if (S_ISDIR(st.st_mode)) { + if (virFileMakePath(fs->dst) < 0) { + virReportSystemError(errno, + _("Failed to create %s"), + fs->dst); + goto cleanup; + } + } else { + /* Create Empty file for target mount point */ + int fd = open(fs->dst, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666); + if (fd < 0) { + if (errno != EEXIST) { + virReportSystemError(errno, + _("Failed to create bind target %s"), + fs->dst); + goto cleanup; + } + } + if (VIR_CLOSE(fd) < 0) { + virReportSystemError(errno, + _("Failed to close bind target %s"), + fs->dst); + goto cleanup; + } + } } if (mount(src, fs->dst, NULL, MS_BIND, NULL) < 0) {