diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index e9a1e32c9b..38b2763013 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1670,8 +1670,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_NO_OVERWRITE = (1 << 2),  /* Do not overwrite 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 c270b54b4a..0aae6229d1 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -235,6 +235,8 @@ typedef enum {
     VIR_ERR_INVALID_STREAM = 73,        /* stream pointer not valid */
     VIR_ERR_ARGUMENT_UNSUPPORTED = 74,  /* valid API use but unsupported by
                                            the given driver */
+    VIR_ERR_STORAGE_PROBE_FAILED = 75,  /* storage pool proble failed */
+    VIR_ERR_STORAGE_POOL_BUILT = 76,    /* storage pool already built */
 } virErrorNumber;
 
 /**
diff --git a/src/Makefile.am b/src/Makefile.am
index 322c900a3c..14f09e4c8c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -954,6 +954,10 @@ endif
 if WITH_SECDRIVER_APPARMOR
 libvirt_driver_storage_la_LIBADD += $(APPARMOR_LIBS)
 endif
+if HAVE_LIBBLKID
+libvirt_driver_storage_la_CFLAGS += $(BLKID_CFLAGS)
+libvirt_driver_storage_la_LIBADD += $(BLKID_LIBS)
+endif
 if WITH_STORAGE_DIR
 if WITH_DRIVER_MODULES
 mod_LTLIBRARIES += libvirt_driver_storage.la
diff --git a/src/libvirt.c b/src/libvirt.c
index eca919ad0e..13425ff852 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -10466,6 +10466,10 @@ error:
  * virStoragePoolBuild:
  * @pool: pointer to storage pool
  * @flags: future flags, use 0 for now
+ * @flags: flags to control pool build behaviour
+ *
+ * Currently only filesystem pool accepts flags VIR_STORAGE_POOL_BUILD_OVERWRITE
+ * and VIR_STORAGE_POOL_BUILD_NO_OVERWRITE.
  *
  * Build the underlying storage pool
  *
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 61d86d207b..02c4c175a3 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -37,6 +37,10 @@
 #include <libxml/tree.h>
 #include <libxml/xpath.h>
 
+#if HAVE_LIBBLKID
+# include <blkid/blkid.h>
+#endif
+
 #include "virterror_internal.h"
 #include "storage_backend_fs.h"
 #include "storage_conf.h"
@@ -45,6 +49,7 @@
 #include "memory.h"
 #include "xml.h"
 #include "virfile.h"
+#include "logging.h"
 
 #define VIR_FROM_THIS VIR_FROM_STORAGE
 
@@ -534,13 +539,172 @@ virStorageBackendFileSystemStart(virConnectPtr conn ATTRIBUTE_UNUSED,
 }
 #endif /* WITH_STORAGE_FS */
 
+#if HAVE_LIBBLKID
+static virStoragePoolProbeResult
+virStorageBackendFileSystemProbe(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_POOL_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;
+}
+
+#else /* #if HAVE_LIBBLKID */
+
+static virStoragePoolProbeResult
+virStorageBackendFileSystemProbe(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;
+}
+
+#endif /* #if HAVE_LIBBLKID */
+
+static int
+virStorageBackendExecuteMKFS(const char *device,
+                             const char *format)
+{
+    int ret = 0;
+    virCommandPtr cmd = NULL;
+
+    cmd = virCommandNewArgList(MKFS,
+                               "-t",
+                               format,
+                               device,
+                               NULL);
+
+    if (virCommandRun(cmd, 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_NO_OVERWRITE &&
+               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
+ * @flags controls the pool formating behaviour
  *
  * Build a directory or FS based storage pool.
  *
+ * If no flag is set, it only makes the directory; If
+ * VIR_STORAGE_POOL_BUILD_NO_OVERWRITE set, it probes to determine if
+ * filesystem already exists on the target device, renurning an error
+ * if exists, or using mkfs to format the target device if not; If
+ * VIR_STORAGE_POOL_BUILD_OVERWRITE is set, mkfs is always executed,
+ * any existed data on the target device is overwritten unconditionally.
+ *
  *  - If it is a FS based pool, mounts the unlying source device on the pool
  *
  * Returns 0 on success, -1 on error
@@ -551,10 +715,20 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED,
                                  unsigned int flags)
 {
     int err, ret = -1;
-    char *parent;
-    char *p;
+    char *parent = NULL;
+    char *p = NULL;
 
-    virCheckFlags(0, -1);
+    virCheckFlags(VIR_STORAGE_POOL_BUILD_OVERWRITE |
+                  VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, ret);
+
+    if (flags == (VIR_STORAGE_POOL_BUILD_OVERWRITE |
+                  VIR_STORAGE_POOL_BUILD_NO_OVERWRITE)) {
+
+        virStorageReportError(VIR_ERR_OPERATION_INVALID,
+                              _("Overwrite and no overwrite flags"
+                                " are mutually exclusive"));
+        goto error;
+    }
 
     if ((parent = strdup(pool->def->target.path)) == NULL) {
         virReportOOMError();
@@ -604,7 +778,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 7def53ef3d..54c6739c6a 100644
--- a/src/storage/storage_backend_fs.h
+++ b/src/storage/storage_backend_fs.h
@@ -29,6 +29,11 @@
 # if WITH_STORAGE_FS
 extern virStorageBackend virStorageBackendFileSystem;
 extern virStorageBackend virStorageBackendNetFileSystem;
+typedef enum {
+    FILESYSTEM_PROBE_FOUND,
+    FILESYSTEM_PROBE_NOT_FOUND,
+    FILESYSTEM_PROBE_ERROR,
+} virStoragePoolProbeResult;
 # endif
 extern virStorageBackend virStorageBackendDirectory;
 
diff --git a/src/util/virterror.c b/src/util/virterror.c
index b50fbfd109..26c4981b06 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1030,6 +1030,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_POOL_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");