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(a)oracle.com>
---
Changes since v2:
- Sort the newly added symbol in the list
---
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..7e60d87 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -148,6 +148,7 @@ virDomainCapsNew;
# conf/domain_conf.h
virBlkioDeviceArrayClear;
+virDiskNameParse;
virDiskNameToBusDeviceIndex;
virDiskNameToIndex;
virDomainActualNetDefFree;
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