From: root <root(a)amd-1352-8-2.englab.nay.redhat.com>
The name convention of device mapper disk is different, and 'parted'
can't be used to delete a device mapper disk partition. e.g.
[root@amd-1352-8-2 ~]# virsh vol-list --pool osier
Name Path
-----------------------------------------
3600a0b80005ad1d7000093604cae912fp1 /dev/mapper/3600a0b80005ad1d7000093604cae912fp1
[root@amd-1352-8-2 ~]# parted /dev/mapper/3600a0b80005adb0b0000ab2d4cae9254 rm p1
Error: Expecting a partition number.
This patch introduces 'dmsetup' to fix it.
Changes:
- New function 'virIsDeviceMapperDevice' in src/utils/utils.c
- Delete 'is_dm_device' in src/storage/parthelper.c, use
'virIsDeviceMapperDevice' instead.
- Requires device-mapper for 'with-storage-disk' in libvirt.spec.in
- Check 'dmsetup' in configure.ac for 'with-storage-disk'
- Changes on src/Makefile.am to link against libdevmapper
- New entry for 'virIsDeviceMapperDevice' in src/libvirt_private.syms
e.g.
[root@amd-1352- ~]# virsh vol-list --pool osier
Name Path
-----------------------------------------
3600a0b80005ad1d7000093604cae912fp1 /dev/mapper/3600a0b80005ad1d7000093604cae912fp1
[root@amd-1352- ~]# virsh vol-delete /dev/mapper/3600a0b80005ad1d7000093604cae912fp1
Vol /dev/mapper/3600a0b80005ad1d7000093604cae912fp1 deleted
[root@amd-1352- ~]# virsh vol-list --pool osier
Name Path
-----------------------------------------
---
configure.ac | 21 ++++++++++++++
libvirt.spec.in | 1 +
src/Makefile.am | 7 ++--
src/libvirt_private.syms | 1 +
src/storage/parthelper.c | 14 +--------
src/storage/storage_backend_disk.c | 54 ++++++++++++++++++++++-------------
src/util/util.c | 14 +++++++++
src/util/util.h | 1 +
8 files changed, 76 insertions(+), 37 deletions(-)
diff --git a/configure.ac b/configure.ac
index f310a5e..b101faa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1705,6 +1705,8 @@ LIBPARTED_CFLAGS=
LIBPARTED_LIBS=
if test "$with_storage_disk" = "yes" || test
"$with_storage_disk" = "check"; then
AC_PATH_PROG([PARTED], [parted], [], [$PATH:/sbin:/usr/sbin])
+ AC_PATH_PROG([DMSETUP], [dmsetup], [], [$PATH:/sbin:/usr/sbin])
+
if test -z "$PARTED" ; then
with_storage_disk=no
PARTED_FOUND=no
@@ -1712,9 +1714,17 @@ if test "$with_storage_disk" = "yes" || test
"$with_storage_disk" = "check"; the
PARTED_FOUND=yes
fi
+ if test -z "$DMSETUP" ; then
+ with_storage_disk=no
+ DMSETUP_FOUND=no
+ else
+ DMSETUP_FOUND=yes
+ fi
+
if test "$with_storage_disk" != "no" && test
"x$PKG_CONFIG" != "x" ; then
PKG_CHECK_MODULES(LIBPARTED, libparted >= $PARTED_REQUIRED, [],
[PARTED_FOUND=no])
fi
+
if test "$PARTED_FOUND" = "no"; then
# RHEL-5 vintage parted is missing pkg-config files
save_LIBS="$LIBS"
@@ -1738,9 +1748,20 @@ if test "$with_storage_disk" = "yes" || test
"$with_storage_disk" = "check"; the
with_storage_disk=yes
fi
+ if test "$DMSETUP_FOUND" = "no"; then
+ if test "$with_storage_disk" = "yes" ; then
+ AC_MSG_ERROR([We need dmsetup for disk storage driver])
+ else
+ with_storage_disk=no
+ fi
+ else
+ with_storage_disk=yes
+ fi
+
if test "$with_storage_disk" = "yes"; then
AC_DEFINE_UNQUOTED([WITH_STORAGE_DISK], 1, [whether Disk backend for storage driver
is enabled])
AC_DEFINE_UNQUOTED([PARTED],["$PARTED"], [Location or name of the parted
program])
+ AC_DEFINE_UNQUOTED([DMSETUP],["$DMSETUP"], [Location or name of the dmsetup
program])
fi
fi
AM_CONDITIONAL([WITH_STORAGE_DISK], [test "$with_storage_disk" =
"yes"])
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 0a2d10e..27e6a99 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -279,6 +279,7 @@ Requires: iscsi-initiator-utils
%if %{with_storage_disk}
# For disk driver
Requires: parted
+Requires: device-mapper
%endif
%if %{with_storage_mpath}
# For multipath support
diff --git a/src/Makefile.am b/src/Makefile.am
index f8b8434..3680074 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -437,9 +437,9 @@ libvirt_la_BUILT_LIBADD = libvirt_util.la
libvirt_util_la_SOURCES = \
$(UTIL_SOURCES)
libvirt_util_la_CFLAGS = $(CAPNG_CFLAGS) $(YAJL_CFLAGS) $(LIBNL_CFLAGS) \
- $(AM_CFLAGS) $(AUDIT_CFLAGS)
+ $(AM_CFLAGS) $(AUDIT_CFLAGS) $(DEVMAPPER_LIBS)
libvirt_util_la_LIBADD = $(CAPNG_LIBS) $(YAJL_LIBS) $(LIBNL_LIBS) \
- $(LIB_PTHREAD) $(AUDIT_LIBS)
+ $(LIB_PTHREAD) $(AUDIT_LIBS) $(DEVMAPPER_LIBS)
noinst_LTLIBRARIES += libvirt_conf.la
@@ -1154,7 +1154,6 @@ libvirt_parthelper_SOURCES = $(STORAGE_HELPER_DISK_SOURCES)
libvirt_parthelper_LDFLAGS = $(WARN_LDFLAGS) $(AM_LDFLAGS)
libvirt_parthelper_LDADD = \
$(LIBPARTED_LIBS) \
- $(DEVMAPPER_LIBS) \
libvirt_util.la \
../gnulib/lib/libgnu.la
@@ -1179,7 +1178,7 @@ libvirt_lxc_SOURCES = \
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS)
libvirt_lxc_LDADD = $(CAPNG_LIBS) $(YAJL_LIBS) \
$(LIBXML_LIBS) $(NUMACTL_LIBS) $(LIB_PTHREAD) \
- $(LIBNL_LIBS) $(AUDIT_LIBS) ../gnulib/lib/libgnu.la
+ $(LIBNL_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) ../gnulib/lib/libgnu.la
libvirt_lxc_CFLAGS = \
$(LIBPARTED_CFLAGS) \
$(NUMACTL_CFLAGS) \
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3a5aec9..9d974e8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -900,6 +900,7 @@ virStrcpy;
virStrncpy;
virTimestamp;
virVasprintf;
+virIsDeviceMapperDevice;
# uuid.h
diff --git a/src/storage/parthelper.c b/src/storage/parthelper.c
index 6ef413d..1f662fb 100644
--- a/src/storage/parthelper.c
+++ b/src/storage/parthelper.c
@@ -59,18 +59,6 @@ enum diskCommand {
DISK_GEOMETRY
};
-static int
-is_dm_device(const char *devname)
-{
- struct stat buf;
-
- if (devname && !stat(devname, &buf) &&
dm_is_dm_major(major(buf.st_rdev))) {
- return 1;
- }
-
- return 0;
-}
-
int main(int argc, char **argv)
{
PedDevice *dev;
@@ -96,7 +84,7 @@ int main(int argc, char **argv)
}
path = argv[1];
- if (is_dm_device(path)) {
+ if (virIsDeviceMapperDevice(path)) {
partsep = "p";
canonical_path = strdup(path);
if (canonical_path == NULL) {
diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c
index c7ade6b..45e43c4 100644
--- a/src/storage/storage_backend_disk.c
+++ b/src/storage/storage_backend_disk.c
@@ -660,34 +660,48 @@ virStorageBackendDiskDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED,
srcname = basename(pool->def->source.devices[0].path);
DEBUG("devname=%s, srcname=%s", devname, srcname);
- if (!STRPREFIX(devname, srcname)) {
+ if (!virIsDeviceMapperDevice(devpath) && !STRPREFIX(devname, srcname)) {
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
_("Volume path '%s' did not start with parent
"
"pool source device name."), devname);
goto cleanup;
}
- part_num = devname + strlen(srcname);
+ if (!virIsDeviceMapperDevice(devpath)) {
+ part_num = devname + strlen(srcname);
- if (*part_num == 0) {
- virStorageReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse partition number from target "
- "'%s'"), devname);
- goto cleanup;
- }
-
- /* eg parted /dev/sda rm 2 */
- const char *prog[] = {
- PARTED,
- pool->def->source.devices[0].path,
- "rm",
- "--script",
- part_num,
- NULL,
- };
+ if (*part_num == 0) {
+ virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse partition number from target
"
+ "'%s'"), devname);
+ goto cleanup;
+ }
- if (virRun(prog, NULL) < 0)
- goto cleanup;
+ /* eg parted /dev/sda rm 2 */
+ const char *prog[] = {
+ PARTED,
+ pool->def->source.devices[0].path,
+ "rm",
+ "--script",
+ part_num,
+ NULL,
+ };
+
+ if (virRun(prog, NULL) < 0)
+ goto cleanup;
+ } else {
+ const char *prog[] = {
+ DMSETUP,
+ "remove",
+ "-f",
+ devpath,
+ NULL,
+ NULL,
+ };
+
+ if (virRun(prog, NULL) < 0)
+ goto cleanup;
+ }
rc = 0;
cleanup:
diff --git a/src/util/util.c b/src/util/util.c
index ee04ca9..6e2f966 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -45,6 +45,7 @@
#include <string.h>
#include <signal.h>
#include <termios.h>
+#include <libdevmapper.h>
#include "c-ctype.h"
#ifdef HAVE_PATHS_H
@@ -3100,3 +3101,16 @@ virTimestamp(void)
return timestamp;
}
+
+int
+virIsDeviceMapperDevice(const char *devname)
+{
+ struct stat buf;
+
+ if (devname && !stat(devname, &buf) &&
dm_is_dm_major(major(buf.st_rdev))) {
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/src/util/util.h b/src/util/util.h
index 8373038..dd683ea 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -296,4 +296,5 @@ int virBuildPathInternal(char **path, ...) ATTRIBUTE_SENTINEL;
char *virTimestamp(void);
+int virIsDeviceMapperDevice(const char *devname);
#endif /* __VIR_UTIL_H__ */
--
1.7.1