[libvirt] This patch creates a mount point for libvirt-lxc containers to mount on the destination system if it does not exist.
Daniel P. Berrange
berrange at redhat.com
Mon Jun 25 09:56:51 UTC 2012
On Fri, Jun 22, 2012 at 09:59:58AM -0400, Daniel J Walsh wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> 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.
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.12 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iEYEARECAAYFAk/kel4ACgkQrlYvE4MpobP7uwCfXUPMJP4bNZiBGTwnJ70dezVf
> KPwAnjt3MYSlHxkcwZCe5H1X4C0P4ky/
> =1te/
> -----END PGP SIGNATURE-----
> 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
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list