From fba2076f43032632b1cbd29416c57955f943d828 Mon Sep 17 00:00:00 2001 From: John Ferlan Date: Thu, 1 Oct 2015 08:24:14 -0400 Subject: [PATCH] storage: Add additional errors/checks for disk label Let's check to ensure we can find the Partition Table in the label and that libvirt actually recognizes that type; otherwise, when we go to read the partitions during a refresh operation we may not be reading what we expect. This will expand upon the types of errors or reason that a build would fail, so we can create more direct error messages. --- src/libvirt_private.syms | 1 + src/storage/storage_backend_disk.c | 41 +++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c1b7b87e91..be6ee19546 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -834,6 +834,7 @@ virStoragePoolDefParseFile; virStoragePoolDefParseNode; virStoragePoolDefParseSourceString; virStoragePoolDefParseString; +virStoragePoolFormatDiskTypeFromString; virStoragePoolFormatDiskTypeToString; virStoragePoolFormatFileSystemNetTypeToString; virStoragePoolFormatFileSystemTypeToString; diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c index 6f9fab17eb..b66a4a1a81 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -396,7 +396,9 @@ virStorageBackendDiskRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, * Check for a valid disk label (partition table) on device * * return: 0 - valid disk label found - * >0 - no or unrecognized disk label + * 1 - no or unrecognized disk label + * 2 - did not find the Partition Table type + * 3 - Partition Table type unknown * <0 - error finding the disk label */ static int @@ -408,6 +410,7 @@ virStorageBackendDiskFindLabel(const char* device) virCommandPtr cmd = virCommandNew(PARTED); char *output = NULL; char *error = NULL; + char *start, *end; int ret = -1; virCommandAddArgSet(cmd, args); @@ -422,15 +425,40 @@ virStorageBackendDiskFindLabel(const char* device) (error && strstr(error, "unrecognised disk label"))) { ret = 1; } + goto cleanup; } + /* Search for "Partition Table:" in the output. If not present, + * then we cannot validate the partition table type. + */ + if (!(start = strstr(output, "Partition Table: ")) || + !(end = strstr(start, "\n"))) { + VIR_DEBUG("Unable to find tag in output: %s", output); + ret = 2; + goto cleanup; + } + start += strlen("Partition Table: "); + *end = '\0'; + + /* on disk it's "msdos", but we document/use "dos" so deal with it here */ + if (STREQ(start, "msdos")) + start += 2; + + /* Make sure we know about this type */ + if (virStoragePoolFormatDiskTypeFromString(start) < 0) { + ret = 3; + goto cleanup; + } + + ret = 0; + + cleanup: virCommandFree(cmd); VIR_FREE(output); VIR_FREE(error); return ret; } - /** * Determine whether the label on the disk is valid or in a known format * for the purpose of rewriting the label during build @@ -452,12 +480,19 @@ virStorageBackendDiskValidLabel(const char *device, int check; check = virStorageBackendDiskFindLabel(device); - if (check > 0) { + if (check == 1) { if (writelabel) valid = true; else virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Unrecognized disk label found, requires build")); + } else if (check == 2) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("Unable to determine Partition Type, " + "requires build --overwrite")); + } else if (check == 3) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("Unknown Partition Type, requires build --overwrite")); } else if (check < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Error checking for disk label, failed to get "