[libvirt] [PATCH 1/2] LXC: hostdev: introduce lxcContainerSetupHostdevCapsMakePath

This helper function is used to create parent directroy for the hostdev which will be added to the container. if the parent directory of this hostdev doesn't exist, the mknod of the hostdev will fail. Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com> --- src/lxc/lxc_container.c | 17 +++++++++++++++++ src/lxc/lxc_container.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index c8420db..b954107 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -1544,6 +1544,23 @@ cleanup: } +int lxcContainerSetupHostdevCapsMakePath(char *dev) +{ + int ret = 0; + char *dir = NULL; + + if ((dir = strrchr(dev, '/'))) { + *dir = '\0'; + if ((virFileMakePath(dev) < 0) && (errno != EEXIST)) + ret = -1; + + *dir = '/'; + } + + return ret; +} + + static int lxcContainerSetupHostdevCapsStorage(virDomainDefPtr vmDef ATTRIBUTE_UNUSED, virDomainHostdevDefPtr def ATTRIBUTE_UNUSED, virSecurityManagerPtr securityDriver ATTRIBUTE_UNUSED) diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h index ada72f7..f168703 100644 --- a/src/lxc/lxc_container.h +++ b/src/lxc/lxc_container.h @@ -63,6 +63,8 @@ int lxcContainerStart(virDomainDefPtr def, int lxcContainerAvailable(int features); +int lxcContainerSetupHostdevCapsMakePath(char *dev); + virArch lxcContainerGetAlt32bitArch(virArch arch); #endif /* LXC_CONTAINER_H */ -- 1.8.3.1

Create parent directroy for hostdev atomically when we start a lxc domain or attach a hostdev to a lxc domain. Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com> --- src/lxc/lxc_container.c | 42 ++++++++++++++++++++++++++++-------------- src/lxc/lxc_driver.c | 14 ++++++++++++++ 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index b954107..a204789 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -1569,14 +1569,15 @@ static int lxcContainerSetupHostdevCapsStorage(virDomainDefPtr vmDef ATTRIBUTE_U int ret = -1; struct stat sb; mode_t mode; + char *dev = def->source.caps.u.storage.block; - if (def->source.caps.u.storage.block == NULL) { + if (dev == NULL) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Missing storage host block path")); goto cleanup; } - if (virAsprintf(&src, "/.oldroot/%s", def->source.caps.u.storage.block) < 0) { + if (virAsprintf(&src, "/.oldroot/%s", dev) < 0) { virReportOOMError(); goto cleanup; } @@ -1591,19 +1592,25 @@ static int lxcContainerSetupHostdevCapsStorage(virDomainDefPtr vmDef ATTRIBUTE_U if (!S_ISBLK(sb.st_mode)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Storage source %s must be a block device"), - def->source.caps.u.storage.block); + dev); + goto cleanup; + } + + if (lxcContainerSetupHostdevCapsMakePath(dev) < 0) { + virReportError(errno, + _("Failed to create directory for device %s"), + dev); goto cleanup; } mode = 0700 | S_IFBLK; - VIR_DEBUG("Creating dev %s (%d,%d)", - def->source.caps.u.storage.block, + VIR_DEBUG("Creating dev %s (%d,%d)", dev, major(sb.st_rdev), minor(sb.st_rdev)); - if (mknod(def->source.caps.u.storage.block, mode, sb.st_rdev) < 0) { + if (mknod(dev, mode, sb.st_rdev) < 0) { virReportSystemError(errno, _("Unable to create device %s"), - def->source.caps.u.storage.block); + dev); goto cleanup; } @@ -1626,14 +1633,15 @@ static int lxcContainerSetupHostdevCapsMisc(virDomainDefPtr vmDef ATTRIBUTE_UNUS int ret = -1; struct stat sb; mode_t mode; + char *dev = def->source.caps.u.misc.chardev; - if (def->source.caps.u.misc.chardev == NULL) { + if (dev == NULL) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Missing storage host block path")); goto cleanup; } - if (virAsprintf(&src, "/.oldroot/%s", def->source.caps.u.misc.chardev) < 0) { + if (virAsprintf(&src, "/.oldroot/%s", dev) < 0) { virReportOOMError(); goto cleanup; } @@ -1648,19 +1656,25 @@ static int lxcContainerSetupHostdevCapsMisc(virDomainDefPtr vmDef ATTRIBUTE_UNUS if (!S_ISCHR(sb.st_mode)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Storage source %s must be a character device"), - def->source.caps.u.misc.chardev); + dev); + goto cleanup; + } + + if (lxcContainerSetupHostdevCapsMakePath(dev) < 0) { + virReportError(errno, + _("Failed to create directory for device %s"), + dev); goto cleanup; } mode = 0700 | S_IFCHR; - VIR_DEBUG("Creating dev %s (%d,%d)", - def->source.caps.u.misc.chardev, + VIR_DEBUG("Creating dev %s (%d,%d)", dev, major(sb.st_rdev), minor(sb.st_rdev)); - if (mknod(def->source.caps.u.misc.chardev, mode, sb.st_rdev) < 0) { + if (mknod(dev, mode, sb.st_rdev) < 0) { virReportSystemError(errno, _("Unable to create device %s"), - def->source.caps.u.misc.chardev); + dev); goto cleanup; } diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 1a6d086..2661c1b 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -3616,6 +3616,13 @@ lxcDomainAttachDeviceHostdevStorageLive(virLXCDriverPtr driver, goto cleanup; } + if (lxcContainerSetupHostdevCapsMakePath(dst) < 0) { + virReportSystemError(errno, + _("Unable to create directroy for device %s"), + dst); + goto cleanup; + } + mode = 0700 | S_IFBLK; VIR_DEBUG("Creating dev %s (%d,%d)", @@ -3720,6 +3727,13 @@ lxcDomainAttachDeviceHostdevMiscLive(virLXCDriverPtr driver, goto cleanup; } + if (lxcContainerSetupHostdevCapsMakePath(dst) < 0) { + virReportSystemError(errno, + _("Unable to create directroy for device %s"), + dst); + goto cleanup; + } + mode = 0700 | S_IFCHR; VIR_DEBUG("Creating dev %s (%d,%d)", -- 1.8.3.1

On Tue, Jul 09, 2013 at 11:20:36AM +0800, Gao feng wrote:
Create parent directroy for hostdev atomically when we start a lxc domain or attach a hostdev to a lxc domain.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com> --- src/lxc/lxc_container.c | 42 ++++++++++++++++++++++++++++-------------- src/lxc/lxc_driver.c | 14 ++++++++++++++ 2 files changed, 42 insertions(+), 14 deletions(-)
ACK 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 :|

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Guys, thank you for your help and your effort! (Didn't try the solution yet, but I will.) Thomas -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEARECAAYFAlHepkcACgkQiMyIQtYO79zSLwCfdVfFwU5Tz5FYxmoYaKXTHOHT uAsAoM54vncy6HjftWl5mQMTOe+Rpw0Z =gems -----END PGP SIGNATURE-----

On Tue, Jul 09, 2013 at 11:20:35AM +0800, Gao feng wrote:
This helper function is used to create parent directroy for the hostdev which will be added to the container. if the parent directory of this hostdev doesn't exist, the mknod of the hostdev will fail.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com> --- src/lxc/lxc_container.c | 17 +++++++++++++++++ src/lxc/lxc_container.h | 2 ++ 2 files changed, 19 insertions(+)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index c8420db..b954107 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -1544,6 +1544,23 @@ cleanup: }
+int lxcContainerSetupHostdevCapsMakePath(char *dev) +{ + int ret = 0; + char *dir = NULL; + + if ((dir = strrchr(dev, '/'))) { + *dir = '\0';
Modifying arguments that are passed into a function is bad practice, so I'm changing this to strdup the arg thus: +int lxcContainerSetupHostdevCapsMakePath(const char *dev) +{ + int ret = -1; + char *dir, *tmp; + + if (VIR_STRDUP(dir, dev) < 0) + return -1; + + if ((tmp = strrchr(dir, '/'))) { + *tmp = '\0'; + if (virFileMakePath(dir) < 0) { + virReportSystemError(errno, + _("Failed to create directory for '%s' dev '%s'"), + dir, dev); + goto cleanup; + } + } + + ret = 0; + +cleanup: + VIR_FREE(dir); + return ret; +} 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 :|
participants (3)
-
Daniel P. Berrange
-
Gao feng
-
Thomas Karcher