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 <berrange@redhat.com>
This commit is contained in:
Daniel J Walsh 2012-06-25 10:53:39 +01:00 committed by Daniel P. Berrange
parent 63f5c83bb0
commit 465c055f4a

View File

@ -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) {