Introduce a new helper function "virDiskNameParse" which extends virDiskNameToIndex but handling both disk index and partition index. Also rework virDiskNameToIndex to be based on virDiskNameParse. A test is also added for this function testing both valid and invalid disk names. Signed-off-by: Joao Martins <joao.m.martins@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virutil.c | 41 +++++++++++++++++++++++++++++++---- src/util/virutil.h | 1 + tests/utiltest.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a835f18..6913d7c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -149,6 +149,7 @@ virDomainCapsNew; # conf/domain_conf.h virBlkioDeviceArrayClear; virDiskNameToBusDeviceIndex; +virDiskNameParse; virDiskNameToIndex; virDomainActualNetDefFree; virDomainBlockedReasonTypeFromString; diff --git a/src/util/virutil.c b/src/util/virutil.c index cddc78a..76591be 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -537,14 +537,17 @@ const char *virEnumToString(const char *const*types, } /* Translates a device name of the form (regex) /^[fhv]d[a-z]+[0-9]*$/ - * into the corresponding index (e.g. sda => 0, hdz => 25, vdaa => 26) - * Note that any trailing string of digits is simply ignored. + * into the corresponding index and partition number + * (e.g. sda0 => (0,0), hdz2 => (25,2), vdaa12 => (26,12)) * @param name The name of the device - * @return name's index, or -1 on failure + * @param disk The disk index to be returned + * @param partition The partition index to be returned + * @return 0 on success, or -1 on failure */ -int virDiskNameToIndex(const char *name) +int virDiskNameParse(const char *name, int *disk, int *partition) { const char *ptr = NULL; + char *rem; int idx = 0; static char const* const drive_prefix[] = {"fd", "hd", "vd", "sd", "xvd", "ubd"}; size_t i; @@ -573,6 +576,36 @@ int virDiskNameToIndex(const char *name) if (ptr[n_digits] != '\0') return -1; + *disk = idx; + + /* Convert trailing digits into our partition index */ + if (partition) { + *partition = 0; + + /* Shouldn't start by zero */ + if (n_digits > 1 && *ptr == '0') + return -1; + + if (n_digits && virStrToLong_i(ptr, &rem, 10, partition) < 0) + return -1; + } + + return 0; +} + +/* Translates a device name of the form (regex) /^[fhv]d[a-z]+[0-9]*$/ + * into the corresponding index (e.g. sda => 0, hdz => 25, vdaa => 26) + * Note that any trailing string of digits is simply ignored. + * @param name The name of the device + * @return name's index, or -1 on failure + */ +int virDiskNameToIndex(const char *name) +{ + int idx; + + if (virDiskNameParse(name, &idx, NULL)) + idx = -1; + return idx; } diff --git a/src/util/virutil.h b/src/util/virutil.h index 53025f7..02387e0 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -67,6 +67,7 @@ int virDoubleToStr(char **strp, double number) char *virFormatIntDecimal(char *buf, size_t buflen, int val) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virDiskNameParse(const char *name, int *disk, int *partition); int virDiskNameToIndex(const char* str); char *virIndexToDiskName(int idx, const char *prefix); diff --git a/tests/utiltest.c b/tests/utiltest.c index 98c689d..a8f9060 100644 --- a/tests/utiltest.c +++ b/tests/utiltest.c @@ -23,6 +23,23 @@ static const char* diskNames[] = { "sdia", "sdib", "sdic", "sdid", "sdie", "sdif", "sdig", "sdih", "sdii", "sdij", "sdik", "sdil", "sdim", "sdin", "sdio", "sdip", "sdiq", "sdir", "sdis", "sdit", "sdiu", "sdiv", "sdiw", "sdix", "sdiy", "sdiz" }; +struct testDiskName +{ + const char *name; + int idx; + int partition; +}; + +static struct testDiskName diskNamesPart[] = { + {"sda0", 0, 0}, + {"sdb10", 1, 10}, + {"sdc2147483647", 2, 2147483647}, +}; + +static const char* diskNamesInvalid[] = { + "sda00", "sda01", "sdb-1" +}; + static int testIndexToDiskName(const void *data ATTRIBUTE_UNUSED) { @@ -79,6 +96,44 @@ testDiskNameToIndex(const void *data ATTRIBUTE_UNUSED) +static int +testDiskNameParse(const void *data ATTRIBUTE_UNUSED) +{ + size_t i; + int idx; + int partition; + struct testDiskName *disk = NULL; + + for (i = 0; i < ARRAY_CARDINALITY(diskNamesPart); ++i) { + disk = &diskNamesPart[i]; + if (virDiskNameParse(disk->name, &idx, &partition)) + return -1; + + if (disk->idx != idx) { + VIR_TEST_DEBUG("\nExpect [%d]\n", disk->idx); + VIR_TEST_DEBUG("Actual [%d]\n", idx); + return -1; + } + + if (disk->partition != partition) { + VIR_TEST_DEBUG("\nExpect [%d]\n", disk->partition); + VIR_TEST_DEBUG("Actual [%d]\n", partition); + return -1; + } + } + + for (i = 0; i < ARRAY_CARDINALITY(diskNamesInvalid); ++i) { + if (!virDiskNameParse(diskNamesInvalid[i], &idx, &partition)) { + VIR_TEST_DEBUG("Should Fail [%s]\n", diskNamesInvalid[i]); + return -1; + } + } + + return 0; +} + + + struct testVersionString { const char *string; @@ -220,6 +275,7 @@ mymain(void) DO_TEST(IndexToDiskName); DO_TEST(DiskNameToIndex); + DO_TEST(DiskNameParse); DO_TEST(ParseVersionString); DO_TEST(RoundValueToPowerOfTwo); DO_TEST(OverflowCheckMacro); -- 2.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list