A device may be formatted using some sort of disk partition format type.
We can check that using the blkid_ API's as well - so alter the logic to
allow checking the device for both a filesystem and a disk partition.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/storage/storage_backend.c | 177 ++++++++++++++++++++++++++++++++----------
1 file changed, 138 insertions(+), 39 deletions(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 108f2b9..065f2ef 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -2639,37 +2639,117 @@ virStorageBackendFindGlusterPoolSources(const char *host
ATTRIBUTE_UNUSED,
#if WITH_BLKID
+
+typedef enum {
+ VIR_STORAGE_BLKID_PROBE_ERROR = -1,
+ VIR_STORAGE_BLKID_PROBE_UNDEFINED, /* Nothing found */
+ VIR_STORAGE_BLKID_PROBE_UNKNOWN, /* Don't know libvirt fs/part type */
+ VIR_STORAGE_BLKID_PROBE_MATCH, /* Matches the on disk format */
+ VIR_STORAGE_BLKID_PROBE_DIFFERENT, /* Format doesn't match on disk format */
+} virStorageBackendBLKIDProbeResult;
+
+/*
+ * Utility function to probe for a file system on the device using the
+ * blkid "superblock" (e.g. default) APIs.
+ *
+ * NB: In general this helper will handle the virStoragePoolFormatFileSystem
+ * format types; however, if called from the Disk path, the initial fstype
+ * check will fail forcing the usage of the ProbePart helper.
+ *
+ * Returns virStorageBackendBLKIDProbeResult enum
+ */
+static virStorageBackendBLKIDProbeResult
+virStorageBackendBLKIDProbeFS(blkid_probe probe,
+ const char *device,
+ const char *format)
+{
+ const char *fstype = NULL;
+
+ /* Make sure we're doing a superblock probe from the start */
+ blkid_probe_enable_superblocks(probe, true);
+ blkid_probe_reset_superblocks_filter(probe);
+
+ if (blkid_do_probe(probe) != 0) {
+ VIR_INFO("No filesystem found on device '%s'", device);
+ return VIR_STORAGE_BLKID_PROBE_UNDEFINED;
+ }
+
+ if (blkid_probe_lookup_value(probe, "TYPE", &fstype, NULL) == 0) {
+ if (STREQ(fstype, format))
+ return VIR_STORAGE_BLKID_PROBE_MATCH;
+
+ return VIR_STORAGE_BLKID_PROBE_DIFFERENT;
+ }
+
+ if (blkid_known_fstype(format) == 0)
+ return VIR_STORAGE_BLKID_PROBE_UNKNOWN;
+
+ return VIR_STORAGE_BLKID_PROBE_ERROR;
+}
+
+
+/*
+ * Utility function to probe for a partition on the device using the
+ * blkid "partitions" APIs.
+ *
+ * NB: In general, this API will be validating the virStoragePoolFormatDisk
+ * format types.
+ *
+ * Returns virStorageBackendBLKIDProbeResult enum
+ */
+static virStorageBackendBLKIDProbeResult
+virStorageBackendBLKIDProbePart(blkid_probe probe,
+ const char *device,
+ const char *format)
+{
+ const char *pttype = NULL;
+
+ /* Make sure we're doing a partitions probe from the start */
+ blkid_probe_enable_partitions(probe, true);
+ blkid_probe_reset_partitions_filter(probe);
+
+ if (blkid_do_probe(probe) != 0) {
+ VIR_INFO("No partition found on device '%s'", device);
+ return VIR_STORAGE_BLKID_PROBE_UNDEFINED;
+ }
+
+ if (blkid_probe_lookup_value(probe, "PTTYPE", &pttype, NULL) == 0) {
+ if (STREQ(pttype, format))
+ return VIR_STORAGE_BLKID_PROBE_MATCH;
+
+ return VIR_STORAGE_BLKID_PROBE_DIFFERENT;
+ }
+
+ if (blkid_known_pttype(format) == 0)
+ return VIR_STORAGE_BLKID_PROBE_UNKNOWN;
+
+ return VIR_STORAGE_BLKID_PROBE_ERROR;
+}
+
+
/*
* @device: Path to device
* @format: Desired format
*
* Use the blkid_ APIs in order to get details regarding whether a file
- * system exists on the disk already.
+ * system or partition exists on the disk already.
*
* Returns:
* -1: An error was encountered, with error message set
* 0: No file system found
*/
static int
-virStorageBackendBLKIDProbeFS(const char *device,
- const char *format)
+virStorageBackendBLKIDProbe(const char *device,
+ const char *format)
{
int ret = -1;
+ int rc;
blkid_probe probe = NULL;
- const char *fstype = NULL;
- VIR_DEBUG("Probing for existing filesystem of type %s on device %s",
+ VIR_DEBUG("Probe for existing filesystem/partition format %s on device
%s",
format, device);
- if (blkid_known_fstype(format) == 0) {
- virReportError(VIR_ERR_STORAGE_PROBE_FAILED,
- _("Not capable of probing for filesystem of "
- "type %s, requires --overwrite"),
- format);
- return -1;
- }
-
if (!(probe = blkid_new_probe_from_filename(device))) {
virReportError(VIR_ERR_STORAGE_PROBE_FAILED,
_("Failed to create filesystem probe for device %s"),
@@ -2677,34 +2757,53 @@ virStorageBackendBLKIDProbeFS(const char *device,
return -1;
}
- if (blkid_do_probe(probe) != 0) {
- VIR_INFO("No filesystem of type '%s' found on device
'%s'",
- format, device);
- } else if (blkid_probe_lookup_value(probe, "TYPE", &fstype, NULL) == 0)
{
- if (STREQ(fstype, format)) {
- virReportError(VIR_ERR_STORAGE_POOL_BUILT,
- _("Device '%s' already contains a filesystem
"
- "of type '%s'"),
- device, fstype);
- } else {
- virReportError(VIR_ERR_STORAGE_POOL_BUILT,
- _("Existing filesystem of type '%s' found on
"
- "device '%s', requires --overwrite"),
- fstype, device);
- }
- goto cleanup;
+ /* Look for something on FS, if it either doesn't recognize the
+ * format type as a valid FS format type or it doesn't find a valid
+ * format type on the device, then perform the same check using
+ * partition probing. */
+ rc = virStorageBackendBLKIDProbeFS(probe, device, format);
+ if (rc == VIR_STORAGE_BLKID_PROBE_UNDEFINED ||
+ rc == VIR_STORAGE_BLKID_PROBE_UNKNOWN)
+ rc = virStorageBackendBLKIDProbePart(probe, device, format);
+
+ switch (rc) {
+ case VIR_STORAGE_BLKID_PROBE_UNDEFINED:
+ ret = 0;
+ break;
+
+ case VIR_STORAGE_BLKID_PROBE_ERROR:
+ virReportError(VIR_ERR_STORAGE_PROBE_FAILED,
+ _("Failed to probe for format type '%s'"),
format);
+ break;
+
+ case VIR_STORAGE_BLKID_PROBE_UNKNOWN:
+ virReportError(VIR_ERR_STORAGE_PROBE_FAILED,
+ _("Not capable of probing for format type '%s',
"
+ "requires build --overwrite"),
+ format);
+ break;
+
+ case VIR_STORAGE_BLKID_PROBE_MATCH:
+ virReportError(VIR_ERR_STORAGE_POOL_BUILT,
+ _("Device '%s' already formatted using
'%s'"),
+ device, format);
+ break;
+
+ case VIR_STORAGE_BLKID_PROBE_DIFFERENT:
+ virReportError(VIR_ERR_STORAGE_POOL_BUILT,
+ _("Device '%s' formatted cannot overwrite using
'%s', "
+ "requires build --overwrite"),
+ device, format);
+ break;
}
- if (blkid_do_probe(probe) != 1) {
+ if (ret == 0 && blkid_do_probe(probe) != 1) {
virReportError(VIR_ERR_STORAGE_PROBE_FAILED, "%s",
- _("Found additional probes to run, "
- "filesystem probing may be incorrect"));
- goto cleanup;
+ _("Found additional probes to run, probing may "
+ "be incorrect"));
+ ret = -1;
}
- ret = 0;
-
- cleanup:
blkid_free_probe(probe);
return ret;
@@ -2713,8 +2812,8 @@ virStorageBackendBLKIDProbeFS(const char *device,
#else /* #if WITH_BLKID */
static int
-virStorageBackendBLKIDProbeFS(const char *device ATTRIBUTE_UNUSED,
- const char *format ATTRIBUTE_UNUSED)
+virStorageBackendBLKIDProbe(const char *device ATTRIBUTE_UNUSED,
+ const char *format ATTRIBUTE_UNUSED)
{
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("probing for filesystems is unsupported "
@@ -2739,7 +2838,7 @@ bool
virStorageBackendDeviceProbeEmpty(const char *devpath,
const char *format)
{
- if (virStorageBackendBLKIDProbeFS(devpath, format) == 0)
+ if (virStorageBackendBLKIDProbe(devpath, format) == 0)
true;
return false;
--
2.7.4