[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH 2/2] Add fs pool formatting



On Fri, May 14, 2010 at 08:00:52AM -0600, Eric Blake wrote:
> On 05/13/2010 08:18 PM, David Allan wrote:
> > * This patch adds the ability to make the filesystem for a filesystem
> >   pool during a pool build.
> > 
> >   The patch adds two new flags, probe and overwrite, to control when
> >   mkfs gets executed.  By default, the patch preserves the current
> >   behavior, i.e., if no flags are specified, pool build on a
> >   filesystem pool only makes the directory on which the filesystem
> >   will be mounted.
> > 
> >  typedef enum {
> >    VIR_STORAGE_POOL_BUILD_NEW  = 0,   /* Regular build from scratch */
> > -  VIR_STORAGE_POOL_BUILD_REPAIR = 1, /* Repair / reinitialize */
> > -  VIR_STORAGE_POOL_BUILD_RESIZE = 2  /* Extend existing pool */
> > +  VIR_STORAGE_POOL_BUILD_REPAIR = (1 << 0), /* Repair / reinitialize */
> > +  VIR_STORAGE_POOL_BUILD_RESIZE = (1 << 1),  /* Extend existing pool */
> > +  VIR_STORAGE_POOL_BUILD_PROBE = (1 << 2),  /* Probe for existing pool */
> > +  VIR_STORAGE_POOL_BUILD_OVERWRITE = (1 << 3)  /* Overwrite data */
> 
> Can one specify both probe and overwrite, or are they mutually
> exclusive?  Maybe it makes sense to allow both - don't overwrite the
> filesystem if it is not already of the correct type, but if it is the
> correct type, then erase it and start from scratch (contrasted with
> probe in isolation doing nothing if the right type is present but
> overwriting on all other types).
> 
> > +++ b/src/Makefile.am
> > @@ -747,6 +747,11 @@ libvirt_driver_storage_la_LDFLAGS += -module -avoid-version
> >  endif
> >  libvirt_driver_storage_la_SOURCES += $(STORAGE_DRIVER_SOURCES)
> >  libvirt_driver_storage_la_SOURCES += $(STORAGE_DRIVER_FS_SOURCES)
> > +if HAVE_LIBBLKID
> > +libvirt_driver_storage_la_SOURCES += storage/storage_backend_fs_libblkid.c
> > +libvirt_driver_storage_la_CFLAGS += $(BLKID_CFLAGS)
> > +libvirt_driver_storage_la_LDFLAGS += $(BLKID_LIBS)
> 
> Should be LIBADD, not LDFLAGS.
> 
> > +
> > +static int
> > +virStorageBackendMakeFileSystem(virStoragePoolObjPtr pool,
> > +                                unsigned int flags)
> > +{
> > +    const char *device = NULL, *format = NULL;
> > +    bool ok_to_mkfs = false;
> > +    int ret = -1;
> 
> Missing virCheckFlags().
> 
> > +
> > +    if (flags & VIR_STORAGE_POOL_BUILD_OVERWRITE) {
> > +        ok_to_mkfs = true;
> > +    } else if (flags & VIR_STORAGE_POOL_BUILD_PROBE &&
> > +               virStorageBackendFileSystemProbe(device, format) ==
> > +               FILESYSTEM_PROBE_NOT_FOUND) {
> > +        ok_to_mkfs = true;
> > +    }
> 
> Here's where your logic would need to change - either the two flags are
> mutually exclusive, and you need to error out if both are given, or the
> two are both supported, but you need to take into account if both are
> specified.
> 
> > --- /dev/null
> > +++ b/src/storage/storage_backend_fs_libblkid.c
> > @@ -0,0 +1,97 @@
> > +/*
> > + * storage_backend_fs_libblkid.c: libblkid specific code for
> > + * filesystem backend
> > + *
> > + * Copyright (C) 2007-2010 Red Hat, Inc.
> 
> Is this just 2010, or did you really borrow significant content from
> other files with earlier copyrights?  If so, list what file you borrowed
> from.
> 
> > +
> > +    /* Unfortunately this value comes from the pool definition
> > +     * where it is correctly const char, but liblbkid expects it
> 
> s/liblbkid/libblkid/
> 
> > +     * to be char, thus the cast. */
> > +    names[0] = (char *)format;
> > +    names[1] = NULL;
> 
> Yeah, unfortunate but necessary.  Seems safe, though; libblkid has no
> business modifying the string.
> 
> > diff --git a/src/util/virterror.c b/src/util/virterror.c
> > index 96dd1e7..bd845fb 100644
> > --- a/src/util/virterror.c
> > +++ b/src/util/virterror.c
> > @@ -1019,6 +1019,18 @@ virErrorMsg(virErrorNumber error, const char *info)
> >              else
> >                      errmsg = _("Storage volume not found: %s");
> >              break;
> > +        case VIR_ERR_STORAGE_PROBE_FAILED:
> > +            if (info == NULL)
> > +                    errmsg = _("Storage pool probe failed");
> > +            else
> > +                    errmsg = _("Storage pool probe failed: %s");
> > +            break;
> 
> Goody - a merge conflict with my error cleanups.  It's a race to see who
> gets first ACK :)
> 
> > +++ b/tools/virsh.c
> > @@ -4668,6 +4668,9 @@ static const vshCmdInfo info_pool_build[] = {
> > 
> >  static const vshCmdOptDef opts_pool_build[] = {
> >      {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")},
> > +    {"probe", VSH_OT_BOOL, 0, N_("do not overwrite an existing "
> > +                                 "pool of this type")},
> > +    {"overwrite", VSH_OT_BOOL, 0, N_("overwrite any existing data")},
> 
> If we do allow both flags at once, then the wording of "probe" needs to
> be tweaked.  So maybe it's better to make them mutually exclusive.
> 
> > @@ -4675,7 +4678,7 @@ static int
> >  cmdPoolBuild(vshControl *ctl, const vshCmd *cmd)
> >  {
> >      virStoragePoolPtr pool;
> > -    int ret = TRUE;
> > +    int ret = TRUE, flags = 0;
> 
> Should flags be unsigned int?
> 
> Looks like we'll need a v2 patch before I feel good giving an ack.

Ok, thanks for all the feedback.  I've attached a v2 patch as well as
an incremental.  

Dave
>From 08d32da5e2c78d12518c31de755b5e5c6fb7ae71 Mon Sep 17 00:00:00 2001
From: David Allan <dallan redhat com>
Date: Wed, 12 May 2010 16:46:40 -0400
Subject: [PATCH 1/1] Add fs pool formatting v2

* This patch adds the ability to make the filesystem for a filesystem
  pool during a pool build.

  The patch adds two new flags, probe and overwrite, to control when
  mkfs gets executed.  By default, the patch preserves the current
  behavior, i.e., if no flags are specified, pool build on a
  filesystem pool only makes the directory on which the filesystem
  will be mounted.

  If the probe flag is specified, the target device is checked to
  determine if a filesystem of the type specified in the pool is
  present.  If a filesystem of that type is already present, mkfs is
  not executed and the build call returns an error.  Otherwise, mkfs
  is executed and any data present on the device is overwritten.

  If the overwrite flag is specified, mkfs is always executed, and any
  existing data on the target device is overwritten unconditionally.

Changes per feedback from eblake:
* Made probe & overwrite flags exclusive
* Changed LDFLAGS to LIBADD in Makefile.am
* Added missing virCheckFlags()
* Fixed copyright dates
* Removed cast of char * passed to libblkid and replaced it with a strdup'd copy
* Changed flags to an unsigned int in virsh.c
---
 include/libvirt/libvirt.h.in              |    6 +-
 include/libvirt/virterror.h               |    2 +
 libvirt.spec.in                           |    5 ++
 po/POTFILES.in                            |    1 +
 src/Makefile.am                           |    5 ++
 src/libvirt_private.syms                  |    4 +
 src/storage/storage_backend_fs.c          |  102 ++++++++++++++++++++++++++++-
 src/storage/storage_backend_fs.h          |   19 +++++
 src/storage/storage_backend_fs_libblkid.c |  102 +++++++++++++++++++++++++++++
 src/util/virterror.c                      |   12 ++++
 tools/virsh.c                             |   14 ++++-
 11 files changed, 266 insertions(+), 6 deletions(-)
 create mode 100644 src/storage/storage_backend_fs_libblkid.c

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index db107cc..f72246e 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1123,8 +1123,10 @@ typedef enum {

 typedef enum {
   VIR_STORAGE_POOL_BUILD_NEW  = 0,   /* Regular build from scratch */
-  VIR_STORAGE_POOL_BUILD_REPAIR = 1, /* Repair / reinitialize */
-  VIR_STORAGE_POOL_BUILD_RESIZE = 2  /* Extend existing pool */
+  VIR_STORAGE_POOL_BUILD_REPAIR = (1 << 0), /* Repair / reinitialize */
+  VIR_STORAGE_POOL_BUILD_RESIZE = (1 << 1),  /* Extend existing pool */
+  VIR_STORAGE_POOL_BUILD_PROBE = (1 << 2),  /* Probe for existing pool */
+  VIR_STORAGE_POOL_BUILD_OVERWRITE = (1 << 3)  /* Overwrite data */
 } virStoragePoolBuildFlags;

 typedef enum {
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 3bbb293..8d15671 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -163,6 +163,8 @@ typedef enum {
     VIR_WAR_NO_STORAGE, /* failed to start storage */
     VIR_ERR_NO_STORAGE_POOL, /* storage pool not found */
     VIR_ERR_NO_STORAGE_VOL, /* storage pool not found */
+    VIR_ERR_STORAGE_PROBE_FAILED, /* storage pool probe failed */
+    VIR_ERR_STORAGE_PROBE_BUILT, /* storage pool already built */
     VIR_WAR_NO_NODE, /* failed to start node driver */
     VIR_ERR_INVALID_NODE_DEVICE,/* invalid node device object */
     VIR_ERR_NO_NODE_DEVICE,/* node device not found */
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 7d5ea85..6af905f 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -222,6 +222,11 @@ BuildRequires: util-linux
 # For showmount in FS driver (netfs discovery)
 BuildRequires: nfs-utils
 Requires: nfs-utils
+# For mkfs
+Requires: util-linux
+# For pool-build probing for existing pools
+BuildRequires: libblkid-devel >= 2.17
+Requires: libblkid >= 2.17
 # For glusterfs
 %if 0%{?fedora} >= 11
 Requires: glusterfs-client >= 2.0.1
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 88218bd..13df560 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -60,6 +60,7 @@ src/security/virt-aa-helper.c
 src/storage/storage_backend.c
 src/storage/storage_backend_disk.c
 src/storage/storage_backend_fs.c
+src/storage/storage_backend_fs_libblkid.c
 src/storage/storage_backend_iscsi.c
 src/storage/storage_backend_logical.c
 src/storage/storage_backend_mpath.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 15bc8fc..457e567 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -747,6 +747,11 @@ libvirt_driver_storage_la_LDFLAGS += -module -avoid-version
 endif
 libvirt_driver_storage_la_SOURCES += $(STORAGE_DRIVER_SOURCES)
 libvirt_driver_storage_la_SOURCES += $(STORAGE_DRIVER_FS_SOURCES)
+if HAVE_LIBBLKID
+libvirt_driver_storage_la_SOURCES += storage/storage_backend_fs_libblkid.c
+libvirt_driver_storage_la_CFLAGS += $(BLKID_CFLAGS)
+libvirt_driver_storage_la_LIBADD += $(BLKID_LIBS)
+endif
 endif

 if WITH_STORAGE_LVM
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 09f3da1..d6c8478 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -614,6 +614,10 @@ virStorageFileFormatTypeFromString;
 virStorageFileGetMetadata;
 virStorageFileGetMetadataFromFD;

+# storage_backend_fs.h
+virStorageBackendFileSystemProbeLibblkid;
+virStorageBackendFileSystemProbeDummy;
+
 # threads.h
 virMutexInit;
 virMutexDestroy;
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index c96c4f3..c770870 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -45,6 +45,7 @@
 #include "util.h"
 #include "memory.h"
 #include "xml.h"
+#include "logging.h"

 #define VIR_FROM_THIS VIR_FROM_STORAGE

@@ -485,6 +486,83 @@ virStorageBackendFileSystemStart(virConnectPtr conn ATTRIBUTE_UNUSED,
 #endif /* WITH_STORAGE_FS */


+virStoragePoolProbeResult
+virStorageBackendFileSystemProbeDummy(const char *device ATTRIBUTE_UNUSED,
+                                      const char *format ATTRIBUTE_UNUSED)
+{
+    virStorageReportError(VIR_ERR_OPERATION_INVALID,
+                          _("probing for filesystems is unsupported "
+                            "by this build"));
+
+    return FILESYSTEM_PROBE_ERROR;
+}
+
+
+static int
+virStorageBackendExecuteMKFS(const char *device,
+                             const char *format)
+{
+    int ret = 0;
+    const char *mkfsargv[5] = { MKFS,
+                                "-t",
+                                format,
+                                device,
+                                NULL };
+
+    if (virRun(mkfsargv, NULL) < 0) {
+        virReportSystemError(errno,
+                             _("Failed to make filesystem of "
+                               "type '%s' on device '%s'"),
+                             format, device);
+        ret = -1;
+    }
+
+    return ret;
+}
+
+
+static int
+virStorageBackendMakeFileSystem(virStoragePoolObjPtr pool,
+                                unsigned int flags)
+{
+    const char *device = NULL, *format = NULL;
+    bool ok_to_mkfs = false;
+    int ret = -1;
+
+    if (pool->def->source.devices == NULL) {
+        virStorageReportError(VIR_ERR_OPERATION_INVALID,
+                              _("No source device specified when formatting pool '%s'"),
+                              pool->def->name);
+        goto error;
+    }
+
+    device = pool->def->source.devices[0].path;
+    format = virStoragePoolFormatFileSystemTypeToString(pool->def->source.format);
+    VIR_DEBUG("source device: '%s' format: '%s'", device, format);
+
+    if (!virFileExists(device)) {
+        virStorageReportError(VIR_ERR_OPERATION_INVALID,
+                              _("Source device does not exist when formatting pool '%s'"),
+                              pool->def->name);
+        goto error;
+    }
+
+    if (flags & VIR_STORAGE_POOL_BUILD_OVERWRITE) {
+        ok_to_mkfs = true;
+    } else if (flags & VIR_STORAGE_POOL_BUILD_PROBE &&
+               virStorageBackendFileSystemProbe(device, format) ==
+               FILESYSTEM_PROBE_NOT_FOUND) {
+        ok_to_mkfs = true;
+    }
+
+    if (ok_to_mkfs) {
+        ret = virStorageBackendExecuteMKFS(device, format);
+    }
+
+error:
+    return ret;
+}
+
 /**
  * @conn connection to report errors against
  * @pool storage pool to build
@@ -498,12 +576,24 @@ virStorageBackendFileSystemStart(virConnectPtr conn ATTRIBUTE_UNUSED,
 static int
 virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED,
                                  virStoragePoolObjPtr pool,
-                                 unsigned int flags ATTRIBUTE_UNUSED)
+                                 unsigned int flags)
 {
     int err, ret = -1;
-    char *parent;
+    char *parent = NULL;
     char *p;

+    virCheckFlags(VIR_STORAGE_POOL_BUILD_OVERWRITE |
+                  VIR_STORAGE_POOL_BUILD_PROBE, ret);
+
+    if (flags == (VIR_STORAGE_POOL_BUILD_OVERWRITE |
+                  VIR_STORAGE_POOL_BUILD_PROBE)) {
+
+        virStorageReportError(VIR_ERR_OPERATION_INVALID,
+                              _("Overwrite and probe flags "
+                                "are mutually exclusive"));
+        goto error;
+    }
+
     if ((parent = strdup(pool->def->target.path)) == NULL) {
         virReportOOMError();
         goto error;
@@ -552,7 +642,13 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED,
             goto error;
         }
     }
-    ret = 0;
+
+    if (flags != 0) {
+        ret = virStorageBackendMakeFileSystem(pool, flags);
+    } else {
+        ret = 0;
+    }
+
 error:
     VIR_FREE(parent);
     return ret;
diff --git a/src/storage/storage_backend_fs.h b/src/storage/storage_backend_fs.h
index 7def53e..d9e397f 100644
--- a/src/storage/storage_backend_fs.h
+++ b/src/storage/storage_backend_fs.h
@@ -29,6 +29,25 @@
 # if WITH_STORAGE_FS
 extern virStorageBackend virStorageBackendFileSystem;
 extern virStorageBackend virStorageBackendNetFileSystem;
+
+typedef enum {
+ FILESYSTEM_PROBE_FOUND,
+ FILESYSTEM_PROBE_NOT_FOUND,
+ FILESYSTEM_PROBE_ERROR,
+} virStoragePoolProbeResult;
+
+#  if HAVE_LIBBLKID
+#   define virStorageBackendFileSystemProbe virStorageBackendFileSystemProbeLibblkid
+virStoragePoolProbeResult
+virStorageBackendFileSystemProbeLibblkid(const char *device,
+                                         const char *format);
+#  else /* if HAVE_LIBBLKID */
+#   define virStorageBackendFileSystemProbe virStorageBackendFileSystemProbeDummy
+#  endif /* if HAVE_LIBBLKID */
+virStoragePoolProbeResult
+virStorageBackendFileSystemProbeDummy(const char *device,
+                                      const char *format);
+
 # endif
 extern virStorageBackend virStorageBackendDirectory;

diff --git a/src/storage/storage_backend_fs_libblkid.c b/src/storage/storage_backend_fs_libblkid.c
new file mode 100644
index 0000000..ed026ff
--- /dev/null
+++ b/src/storage/storage_backend_fs_libblkid.c
@@ -0,0 +1,102 @@
+/*
+ * storage_backend_fs_libblkid.c: libblkid specific code for
+ * filesystem backend
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: David Allan <dallan redhat com>
+ */
+
+#include <config.h>
+#include <blkid/blkid.h>
+
+#include "virterror_internal.h"
+#include "storage_backend_fs.h"
+#include "logging.h"
+#include "memory.h"
+
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
+virStoragePoolProbeResult
+virStorageBackendFileSystemProbeLibblkid(const char *device,
+                                         const char *format) {
+
+    virStoragePoolProbeResult ret = FILESYSTEM_PROBE_ERROR;
+    blkid_probe probe = NULL;
+    const char *fstype = NULL;
+    char *names[2], *libblkid_format = NULL;
+
+    VIR_DEBUG("Probing for existing filesystem of type %s on device %s",
+              format, device);
+
+    if (blkid_known_fstype(format) == 0) {
+        virStorageReportError(VIR_ERR_STORAGE_PROBE_FAILED,
+                              _("Not capable of probing for "
+                                "filesystem of type %s"),
+                              format);
+        goto error;
+    }
+
+    probe = blkid_new_probe_from_filename(device);
+    if (probe == NULL) {
+        virStorageReportError(VIR_ERR_STORAGE_PROBE_FAILED,
+                                  _("Failed to create filesystem probe "
+                                  "for device %s"),
+                                  device);
+        goto error;
+    }
+
+    if ((libblkid_format = strdup(format)) == NULL) {
+        virReportOOMError();
+        goto error;
+    }
+
+    names[0] = libblkid_format;
+    names[1] = NULL;
+
+    blkid_probe_filter_superblocks_type(probe,
+                                        BLKID_FLTR_ONLYIN,
+                                        names);
+
+    if (blkid_do_probe(probe) != 0) {
+        VIR_INFO("No filesystem of type '%s' found on device '%s'",
+                 format, device);
+        ret = FILESYSTEM_PROBE_NOT_FOUND;
+    } else if (blkid_probe_lookup_value(probe, "TYPE", &fstype, NULL) == 0) {
+        virStorageReportError(VIR_ERR_STORAGE_PROBE_BUILT,
+                              _("Existing filesystem of type '%s' found on "
+                                "device '%s'"),
+                              fstype, device);
+        ret = FILESYSTEM_PROBE_FOUND;
+    }
+
+    if (blkid_do_probe(probe) != 1) {
+        virStorageReportError(VIR_ERR_STORAGE_PROBE_FAILED,
+                                  _("Found additional probes to run, "
+                                    "filesystem probing may be incorrect"));
+        ret = FILESYSTEM_PROBE_ERROR;
+    }
+
+error:
+    VIR_FREE(libblkid_format);
+
+    if (probe != NULL) {
+        blkid_free_probe(probe);
+    }
+
+    return ret;
+}
diff --git a/src/util/virterror.c b/src/util/virterror.c
index 96dd1e7..bd845fb 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1019,6 +1019,18 @@ virErrorMsg(virErrorNumber error, const char *info)
             else
                     errmsg = _("Storage volume not found: %s");
             break;
+        case VIR_ERR_STORAGE_PROBE_FAILED:
+            if (info == NULL)
+                    errmsg = _("Storage pool probe failed");
+            else
+                    errmsg = _("Storage pool probe failed: %s");
+            break;
+        case VIR_ERR_STORAGE_PROBE_BUILT:
+            if (info == NULL)
+                    errmsg = _("Storage pool already built");
+            else
+                    errmsg = _("Storage pool already built: %s");
+            break;
         case VIR_ERR_INVALID_STORAGE_POOL:
             if (info == NULL)
                     errmsg = _("invalid storage pool pointer in");
diff --git a/tools/virsh.c b/tools/virsh.c
index 693d409..c6c5d61 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -4668,6 +4668,9 @@ static const vshCmdInfo info_pool_build[] = {

 static const vshCmdOptDef opts_pool_build[] = {
     {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")},
+    {"probe", VSH_OT_BOOL, 0, N_("do not overwrite an existing "
+                                 "pool of this type")},
+    {"overwrite", VSH_OT_BOOL, 0, N_("overwrite any existing data")},
     {NULL, 0, 0, NULL}
 };

@@ -4676,6 +4679,7 @@ cmdPoolBuild(vshControl *ctl, const vshCmd *cmd)
 {
     virStoragePoolPtr pool;
     int ret = TRUE;
+    unsigned int flags = 0;
     char *name;

     if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
@@ -4684,7 +4688,15 @@ cmdPoolBuild(vshControl *ctl, const vshCmd *cmd)
     if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name)))
         return FALSE;

-    if (virStoragePoolBuild(pool, 0) == 0) {
+    if (vshCommandOptBool (cmd, "probe")) {
+        flags |= VIR_STORAGE_POOL_BUILD_PROBE;
+    }
+
+    if (vshCommandOptBool (cmd, "overwrite")) {
+        flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE;
+    }
+
+    if (virStoragePoolBuild(pool, flags) == 0) {
         vshPrint(ctl, _("Pool %s built\n"), name);
     } else {
         vshError(ctl, _("Failed to build pool %s"), name);
-- 
1.7.0.1

>From 410e0781485218fd4f3f2accf5f33c5475081018 Mon Sep 17 00:00:00 2001
From: David Allan <dallan redhat com>
Date: Fri, 14 May 2010 12:30:05 -0400
Subject: [PATCH 1/1] Changes per feedback from eblake

* Made probe & overwrite flags exclusive
* Changed LDFLAGS to LIBADD in Makefile.am
* Added missing virCheckFlags()
* Fixed copyright dates
* Removed cast of char * passed to libblkid and replaced it with a strdup'd copy
* Changed flags to an unsigned int in virsh.c
---
 src/Makefile.am                           |    2 +-
 src/storage/storage_backend_fs.c          |   14 +++++++++++++-
 src/storage/storage_backend_fs_libblkid.c |   23 ++++++++++++++---------
 tools/virsh.c                             |    3 ++-
 4 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 95b77fa..457e567 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -750,7 +750,7 @@ libvirt_driver_storage_la_SOURCES += $(STORAGE_DRIVER_FS_SOURCES)
 if HAVE_LIBBLKID
 libvirt_driver_storage_la_SOURCES += storage/storage_backend_fs_libblkid.c
 libvirt_driver_storage_la_CFLAGS += $(BLKID_CFLAGS)
-libvirt_driver_storage_la_LDFLAGS += $(BLKID_LIBS)
+libvirt_driver_storage_la_LIBADD += $(BLKID_LIBS)
 endif
 endif

diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index c31f6a6..c770870 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -579,9 +579,21 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED,
                                  unsigned int flags)
 {
     int err, ret = -1;
-    char *parent;
+    char *parent = NULL;
     char *p;

+    virCheckFlags(VIR_STORAGE_POOL_BUILD_OVERWRITE |
+                  VIR_STORAGE_POOL_BUILD_PROBE, ret);
+
+    if (flags == (VIR_STORAGE_POOL_BUILD_OVERWRITE |
+                  VIR_STORAGE_POOL_BUILD_PROBE)) {
+
+        virStorageReportError(VIR_ERR_OPERATION_INVALID,
+                              _("Overwrite and probe flags "
+                                "are mutually exclusive"));
+        goto error;
+    }
+
     if ((parent = strdup(pool->def->target.path)) == NULL) {
         virReportOOMError();
         goto error;
diff --git a/src/storage/storage_backend_fs_libblkid.c b/src/storage/storage_backend_fs_libblkid.c
index ddd9264..ed026ff 100644
--- a/src/storage/storage_backend_fs_libblkid.c
+++ b/src/storage/storage_backend_fs_libblkid.c
@@ -2,7 +2,7 @@
  * storage_backend_fs_libblkid.c: libblkid specific code for
  * filesystem backend
  *
- * Copyright (C) 2007-2010 Red Hat, Inc.
+ * Copyright (C) 2010 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -27,6 +27,7 @@
 #include "virterror_internal.h"
 #include "storage_backend_fs.h"
 #include "logging.h"
+#include "memory.h"

 #define VIR_FROM_THIS VIR_FROM_STORAGE

@@ -37,7 +38,7 @@ virStorageBackendFileSystemProbeLibblkid(const char *device,
     virStoragePoolProbeResult ret = FILESYSTEM_PROBE_ERROR;
     blkid_probe probe = NULL;
     const char *fstype = NULL;
-    char *names[2];
+    char *names[2], *libblkid_format = NULL;

     VIR_DEBUG("Probing for existing filesystem of type %s on device %s",
               format, device);
@@ -47,7 +48,7 @@ virStorageBackendFileSystemProbeLibblkid(const char *device,
                               _("Not capable of probing for "
                                 "filesystem of type %s"),
                               format);
-        goto out;
+        goto error;
     }

     probe = blkid_new_probe_from_filename(device);
@@ -56,13 +57,15 @@ virStorageBackendFileSystemProbeLibblkid(const char *device,
                                   _("Failed to create filesystem probe "
                                   "for device %s"),
                                   device);
-        goto out;
+        goto error;
     }

-    /* Unfortunately this value comes from the pool definition
-     * where it is correctly const char, but liblbkid expects it
-     * to be char, thus the cast. */
-    names[0] = (char *)format;
+    if ((libblkid_format = strdup(format)) == NULL) {
+        virReportOOMError();
+        goto error;
+    }
+
+    names[0] = libblkid_format;
     names[1] = NULL;

     blkid_probe_filter_superblocks_type(probe,
@@ -88,7 +91,9 @@ virStorageBackendFileSystemProbeLibblkid(const char *device,
         ret = FILESYSTEM_PROBE_ERROR;
     }

-out:
+error:
+    VIR_FREE(libblkid_format);
+
     if (probe != NULL) {
         blkid_free_probe(probe);
     }
diff --git a/tools/virsh.c b/tools/virsh.c
index 5f7804a..c6c5d61 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -4678,7 +4678,8 @@ static int
 cmdPoolBuild(vshControl *ctl, const vshCmd *cmd)
 {
     virStoragePoolPtr pool;
-    int ret = TRUE, flags = 0;
+    int ret = TRUE;
+    unsigned int flags = 0;
     char *name;

     if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
-- 
1.7.0.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]