]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage: Allow to delete device mapper disk partition
authorOsier Yang <jyang@redhat.com>
Thu, 17 Feb 2011 07:29:07 +0000 (15:29 +0800)
committerOsier Yang <jyang@redhat.com>
Thu, 17 Feb 2011 07:29:07 +0000 (15:29 +0800)
The name convention of device mapper disk is different, and 'parted'
can't be used to delete a device mapper disk partition. e.g.

Name                 Path
-----------------------------------------
3600a0b80005ad1d7000093604cae912fp1 /dev/mapper/3600a0b80005ad1d7000093604cae912fp1

Error: Expecting a partition number.

This patch introduces 'dmsetup' to fix it.

Changes:
  - New function "virIsDevMapperDevice" in "src/utils/utils.c"
  - remove "is_dm_device" in "src/storage/parthelper.c", use
    "virIsDevMapperDevice" 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 "virIsDevMapperDevice" in "src/libvirt_private.syms"

Changes from v1 to v3:
  - s/virIsDeviceMapperDevice/virIsDevMapperDevice/g
  - replace "virRun" with "virCommand"
  - sort the list of util functions in "libvirt_private.syms"
  - ATTRIBUTE_NONNULL(1) for virIsDevMapperDevice declaration.

e.g.

Name                 Path
-----------------------------------------
3600a0b80005ad1d7000093604cae912fp1 /dev/mapper/3600a0b80005ad1d7000093604cae912fp1

Vol /dev/mapper/3600a0b80005ad1d7000093604cae912fp1 deleted

Name                 Path
-----------------------------------------

configure.ac
libvirt.spec.in
src/Makefile.am
src/libvirt_private.syms
src/storage/parthelper.c
src/storage/storage_backend_disk.c
src/util/util.c
src/util/util.h

index 22884e2feb6a53202e11ed44dd47e654b75428b9..2bb69181293abdd59a55d9d0eaeea3efdc2dec46 100644 (file)
@@ -1725,12 +1725,19 @@ 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
     PARTED_FOUND=no
   else
     PARTED_FOUND=yes
   fi
 
+  if test -z "$DMSETUP" ; then
+    DMSETUP_FOUND=no
+  else
+    DMSETUP_FOUND=yes
+  fi
+
   if test "$PARTED_FOUND" = "yes" && test "x$PKG_CONFIG" != "x" ; then
     PKG_CHECK_MODULES([LIBPARTED], [libparted >= $PARTED_REQUIRED], [],
       [PARTED_FOUND=no])
@@ -1748,14 +1755,17 @@ if test "$with_storage_disk" = "yes" ||
     CFLAGS="$save_CFLAGS"
   fi
 
-  if test "$PARTED_FOUND" = "no" ; then
-    if test "$with_storage_disk" = "yes" ; then
-      AC_MSG_ERROR([We need parted for disk storage driver])
-    else
+  if test "$with_storage_disk" = "yes" &&
+     test "$PARTED_FOUND:$DMSETUP_FOUND" != "yes:yes"; then
+    AC_MSG_ERROR([Need both parted and dmsetup for disk storage driver])
+  fi
+
+  if test "$with_storage_disk" = "check"; then
+    if test "$PARTED_FOUND:$DMSETUP_FOUND" != "yes:yes"; then
       with_storage_disk=no
+    else
+      with_storage_disk=yes
     fi
-  else
-    with_storage_disk=yes
   fi
 
   if test "$with_storage_disk" = "yes"; then
@@ -1763,6 +1773,8 @@ if test "$with_storage_disk" = "yes" ||
       [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"])
index d4208e800b239b881c8c76c81b1127f967a3517c..095139103e46f90b9dcb36417830d16eb8b250b9 100644 (file)
@@ -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
index 2f94efdb28d75a466aa9370f1317baab3536db7e..6e14043c87677e14f5093c66152ffb844653b7ec 100644 (file)
@@ -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_CFLAGS)
 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,8 @@ 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)               \
index b9e3efe50fffc20536a4b938e7accee8d8d8a072..301eaefd883f83cf81b24a427f7e36702fa2e434 100644 (file)
@@ -884,6 +884,7 @@ virGetUserID;
 virGetUserName;
 virHexToBin;
 virIndexToDiskName;
+virIsDevMapperDevice;
 virKillProcess;
 virMacAddrCompare;
 virParseMacAddr;
index 6ef413d963293b33b499cf0af4bf2add3b15c6a3..acc917190476e406d2bdae4a4e152ccb3b113ef6 100644 (file)
@@ -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 (virIsDevMapperDevice(path)) {
         partsep = "p";
         canonical_path = strdup(path);
         if (canonical_path == NULL) {
index c7ade6b79256bbe894509642bdfdf46070976545..98f74daf78b64dde0bfb91d2ed05f309ea441c7a 100644 (file)
@@ -31,6 +31,7 @@
 #include "storage_backend_disk.h"
 #include "util.h"
 #include "memory.h"
+#include "command.h"
 #include "configmake.h"
 
 #define VIR_FROM_THIS VIR_FROM_STORAGE
@@ -647,6 +648,8 @@ virStorageBackendDiskDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED,
     char *part_num = NULL;
     char *devpath = NULL;
     char *devname, *srcname;
+    virCommandPtr cmd = NULL;
+    bool isDevMapperDevice;
     int rc = -1;
 
     if (virFileResolveLink(vol->target.path, &devpath) < 0) {
@@ -660,38 +663,45 @@ virStorageBackendDiskDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED,
     srcname = basename(pool->def->source.devices[0].path);
     DEBUG("devname=%s, srcname=%s", devname, srcname);
 
-    if (!STRPREFIX(devname, srcname)) {
+    isDevMapperDevice = virIsDevMapperDevice(devpath);
+
+    if (!isDevMapperDevice && !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 (!isDevMapperDevice) {
+        part_num = devname + strlen(srcname);
 
-    if (*part_num == 0) {
-        virStorageReportError(VIR_ERR_INTERNAL_ERROR,
-                              _("cannot parse partition number from target "
-                                "'%s'"), devname);
-        goto cleanup;
-    }
+        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,
-    };
+        /* eg parted /dev/sda rm 2 */
+        cmd = virCommandNewArgList(PARTED,
+                                   pool->def->source.devices[0].path,
+                                   "rm",
+                                   "--script",
+                                   part_num,
+                                   NULL);
+        if (virCommandRun(cmd, NULL) < 0)
+            goto cleanup;
+    } else {
+        cmd = virCommandNewArgList(DMSETUP, "remove", "--force", devpath, NULL);
 
-    if (virRun(prog, NULL) < 0)
-        goto cleanup;
+        if (virCommandRun(cmd, NULL) < 0)
+            goto cleanup;
+    }
 
     rc = 0;
 cleanup:
     VIR_FREE(devpath);
+    virCommandFree(cmd);
     return rc;
 }
 
index 6161be6fbaef510293f1645f6190352b25e96d7b..a7ce4b31101c0cbaf0f45ad6e3d39bf932a99ad2 100644 (file)
@@ -45,6 +45,7 @@
 #include <string.h>
 #include <signal.h>
 #include <termios.h>
+#include <libdevmapper.h>
 #include "c-ctype.h"
 
 #ifdef HAVE_PATHS_H
@@ -3123,3 +3124,16 @@ virTimestamp(void)
 
     return timestamp;
 }
+
+bool
+virIsDevMapperDevice(const char *devname)
+{
+    struct stat buf;
+
+    if (!stat(devname, &buf) &&
+        S_ISBLK(buf.st_mode) &&
+        dm_is_dm_major(major(buf.st_rdev)))
+            return true;
+
+    return false;
+}
index 8373038de8406e86ad8ca26c77b0b47e2073d430..c822174cbb0b03adf3d1d541b5e86367dbcfe462 100644 (file)
@@ -296,4 +296,5 @@ int virBuildPathInternal(char **path, ...) ATTRIBUTE_SENTINEL;
 
 char *virTimestamp(void);
 
+bool virIsDevMapperDevice(const char *devname) ATTRIBUTE_NONNULL(1);
 #endif /* __VIR_UTIL_H__ */