[libvirt] This patch creates a mount point for libvirt-lxc containers to mount on the destination system if it does not exist.

Daniel J Walsh dwalsh at redhat.com
Mon Jun 25 13:14:35 UTC 2012


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 06/25/2012 05:56 AM, Daniel P. Berrange wrote:
> On Fri, Jun 22, 2012 at 09:59:58AM -0400, Daniel J Walsh wrote: 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.
> 
> Current code blows up if the destination was not a directory.  We want to
> be able to bind mount files on files.
> 
> Sorry if you are seeing this patch for the second time, since I sent it to
> the wrong list.
> 
>> diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index
>> 24b1017..6cd8760 100644 --- a/src/lxc/lxc_container.c +++
>> b/src/lxc/lxc_container.c @@ -648,17 +665,37 @@ 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) && (errno == ENOENT)) { +
>> if (stat(src, &st) >= 0) {
> 
> We should be reporting errors if either of the stat() calls fails.
> 
>> +            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) { +                    close(fd);
> 
> This needs to be VIR_CLOSE & have it exit stats checked, since close() can
> fail (particularly on NFS).
> 
>> +                } else { +                    if (errno != EEXIST) { +
>> virReportSystemError(errno, +
>> _("Failed to create %s"), +
>> fs->dst); +                        goto cleanup; +                    } +
>> } +            } +        }
> 
> 
> I'm applying the following variation on your patch which fixes the issues I
> mention above:
> 
> 
> -    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; +            } +        }
> 
> 
> Daniel
> 

Great thanks.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk/oZDsACgkQrlYvE4MpobMa6ACg30+YwXBo1R8Tk7HjRGCEqqJN
DQQAn0t26CHFffhWv73PZhmg1JSx7xRv
=iM5A
-----END PGP SIGNATURE-----




More information about the libvir-list mailing list