summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--align/scan.c12
-rw-r--r--cat/virt-filesystems.c56
-rw-r--r--fish/options.c20
-rw-r--r--generator/generator_actions.ml30
-rw-r--r--inspector/virt-inspector.c51
-rw-r--r--resize/resize.ml4
-rw-r--r--resize/utils.ml14
-rw-r--r--resize/utils_tests.ml9
-rw-r--r--sparsify/sparsify.ml4
-rw-r--r--sparsify/utils.ml14
-rw-r--r--src/guestfs.c23
-rw-r--r--src/guestfs.pod2
12 files changed, 117 insertions, 122 deletions
diff --git a/align/scan.c b/align/scan.c
index adc51ea2..121dc770 100644
--- a/align/scan.c
+++ b/align/scan.c
@@ -246,7 +246,7 @@ main (int argc, char *argv[])
void
scan (size_t *worst_alignment, const char *prefix)
{
- char **devices;
+ char **devices, *p;
size_t i, j;
size_t alignment;
uint64_t start;
@@ -262,11 +262,11 @@ scan (size_t *worst_alignment, const char *prefix)
exit (EXIT_FAILURE);
/* Canonicalize the name of the device for printing. */
- if (STRPREFIX (devices[i], "/dev/") &&
- (devices[i][5] == 'h' || devices[i][5] == 'v') &&
- devices[i][6] == 'd' &&
- c_isalpha (devices[i][7]))
- devices[i][5] = 's';
+ p = guestfs_canonical_device_name (g, devices[i]);
+ if (p == NULL)
+ exit (EXIT_FAILURE);
+ free (devices[i]);
+ devices[i] = p;
for (j = 0; j < parts->len; ++j) {
/* Start offset of the partition in bytes. */
diff --git a/cat/virt-filesystems.c b/cat/virt-filesystems.c
index 1d324637..690fe3c6 100644
--- a/cat/virt-filesystems.c
+++ b/cat/virt-filesystems.c
@@ -82,8 +82,6 @@ static int output = 0;
#define NR_COLUMNS 8
static int columns;
-static char *canonical_device (const char *dev);
-
static void do_output_title (void);
static void do_output (void);
static void do_output_end (void);
@@ -466,7 +464,9 @@ do_output_filesystems (void)
(STREQ (fses[i+1], "swap") || STREQ (fses[i+1], "unknown")))
goto next;
- dev = canonical_device (fses[i]);
+ dev = guestfs_canonical_device_name (g, fses[i]);
+ if (dev == NULL)
+ exit (EXIT_FAILURE);
/* Only bother to look these up if we will be displaying them,
* otherwise pass them as NULL.
@@ -639,7 +639,9 @@ do_output_pvs (void)
char uuid[33];
const char *parents[1] = { NULL };
- dev = canonical_device (pvs->val[i].pv_name);
+ dev = guestfs_canonical_device_name (g, pvs->val[i].pv_name);
+ if (!dev)
+ exit (EXIT_FAILURE);
memcpy (uuid, pvs->val[i].pv_uuid, 32);
uuid[32] = '\0';
@@ -693,7 +695,9 @@ do_output_partitions (void)
int64_t size = -1;
int mbr_id = -1;
- dev = canonical_device (parts[i]);
+ dev = guestfs_canonical_device_name (g, parts[i]);
+ if (!dev)
+ exit (EXIT_FAILURE);
if ((columns & COLUMN_SIZE)) {
size = guestfs_blockdev_getsize64 (g, parts[i]);
@@ -708,7 +712,9 @@ do_output_partitions (void)
if ((columns & COLUMN_MBR))
mbr_id = get_mbr_id (parts[i], parent_name);
- char *p = canonical_device (parent_name);
+ char *p = guestfs_canonical_device_name (g, parent_name);
+ if (!p)
+ exit (EXIT_FAILURE);
free (parent_name);
parent_name = p;
@@ -742,7 +748,9 @@ do_output_blockdevs (void)
char *dev;
char **parents;
- dev = canonical_device (devices[i]);
+ dev = guestfs_canonical_device_name (g, devices[i]);
+ if (!dev)
+ exit (EXIT_FAILURE);
if ((columns & COLUMN_SIZE)) {
size = guestfs_blockdev_getsize64 (g, devices[i]);
@@ -766,26 +774,6 @@ do_output_blockdevs (void)
free (devices);
}
-/* /dev/vda1 -> /dev/sda. Returns a string which the caller must free. */
-static char *
-canonical_device (const char *dev)
-{
- char *ret = strdup (dev);
- if (ret == NULL) {
- perror ("strdup");
- exit (EXIT_FAILURE);
- }
-
- if (STRPREFIX (ret, "/dev/") &&
- (ret[5] == 'h' || ret[5] == 'v') &&
- ret[6] == 'd' &&
- c_isalpha (ret[7]) &&
- (c_isdigit (ret[8]) || ret[8] == '\0'))
- ret[5] = 's';
-
- return ret;
-}
-
/* Returns an empty list of parents. Note this must be freed using
* free_strings.
*/
@@ -841,8 +829,11 @@ parents_of_md (char *device)
exit (EXIT_FAILURE);
}
- for (i = 0; i < stats->len; ++i)
- ret[i] = canonical_device (stats->val[i].mdstat_device);
+ for (i = 0; i < stats->len; ++i) {
+ ret[i] = guestfs_canonical_device_name (g, stats->val[i].mdstat_device);
+ if (!ret[i])
+ exit (EXIT_FAILURE);
+ }
ret[stats->len] = NULL;
@@ -902,8 +893,11 @@ parents_of_vg (char *vg)
break;
}
- if (j < pvs->len)
- ret[i] = canonical_device (pvs->val[j].pv_name);
+ if (j < pvs->len) {
+ ret[i] = guestfs_canonical_device_name (g, pvs->val[j].pv_name);
+ if (!ret[i])
+ exit (EXIT_FAILURE);
+ }
else {
fprintf (stderr, "%s: warning: unknown PV UUID ignored\n", __func__);
ret[i] = strndup (pvuuids[i], 32);
diff --git a/fish/options.c b/fish/options.c
index a2b4ca48..b1a12e8c 100644
--- a/fish/options.c
+++ b/fish/options.c
@@ -105,7 +105,6 @@ add_drives (struct drv *drv, char next_drive)
}
static void display_mountpoints_on_failure (const char *mp_device, const char *user_supplied_options);
-static void canonical_device_name (char *dev);
/* List is built in reverse order, so mount them in reverse order. */
void
@@ -139,7 +138,7 @@ static void
display_mountpoints_on_failure (const char *mp_device,
const char *user_supplied_options)
{
- char **fses;
+ char **fses, *p;
size_t i;
fses = guestfs_list_filesystems (g);
@@ -162,8 +161,10 @@ display_mountpoints_on_failure (const char *mp_device,
program_name);
for (i = 0; fses[i] != NULL; i += 2) {
- canonical_device_name (fses[i]);
- fprintf (stderr, "%s: \t%s (%s)\n", program_name, fses[i], fses[i+1]);
+ p = guestfs_canonical_device_name (g, fses[i]);
+ fprintf (stderr, "%s: \t%s (%s)\n", program_name,
+ p ? p : fses[i], fses[i+1]);
+ free (p);
free (fses[i]);
free (fses[i+1]);
}
@@ -171,17 +172,6 @@ display_mountpoints_on_failure (const char *mp_device,
free (fses);
}
-static void
-canonical_device_name (char *dev)
-{
- if (STRPREFIX (dev, "/dev/") &&
- (dev[5] == 'h' || dev[5] == 'v') &&
- dev[6] == 'd' &&
- c_isalpha (dev[7]) &&
- (c_isdigit (dev[8]) || dev[8] == '\0'))
- dev[5] = 's';
-}
-
void
free_drives (struct drv *drv)
{
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index f5da217a..7b2bd97f 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -1734,6 +1734,34 @@ versions of libguestfs the limit was 25.
See L<guestfs(3)/MAXIMUM NUMBER OF DISKS> for additional
information on this topic.");
+ ("canonical_device_name", (RString "canonical", [String "device"], []), -1, [],
+ [],
+ "return canonical device name",
+ "\
+This utility function is useful when displaying device names to
+the user. It takes a number of irregular device names and
+returns them in a consistent format:
+
+=over 4
+
+=item C</dev/hdX>
+
+=item C</dev/vdX>
+
+These are returned as C</dev/sdX>. Note this works for device
+names and partition names. This is approximately the reverse of
+the algorithm described in L<guestfs(3)/BLOCK DEVICE NAMING>.
+
+=item C</dev/mapper/VG-LV>
+
+=item C</dev/dm-N>
+
+Converted to C</dev/VG/LV> form using C<guestfs_lvm_canonical_lvm_name>.
+
+=back
+
+Other strings are returned unmodified.");
+
]
(* daemon_functions are any functions which cause some action
@@ -6132,7 +6160,7 @@ is converted to C</dev/VG/LV>.
This command returns an error if the C<lvname> parameter does
not refer to a logical volume.
-See also C<guestfs_is_lv>.");
+See also C<guestfs_is_lv>, C<guestfs_canonical_device_name>.");
("mkfs_opts", (RErr, [String "fstype"; Device "device"], [OInt "blocksize"; OString "features"; OInt "inode"; OInt "sectorsize"]), 278, [],
[InitEmpty, Always, TestOutput (
diff --git a/inspector/virt-inspector.c b/inspector/virt-inspector.c
index 103a61ef..cf0a7ab7 100644
--- a/inspector/virt-inspector.c
+++ b/inspector/virt-inspector.c
@@ -60,7 +60,6 @@ static void output_mountpoints (xmlTextWriterPtr xo, char *root);
static void output_filesystems (xmlTextWriterPtr xo, char *root);
static void output_drive_mappings (xmlTextWriterPtr xo, char *root);
static void output_applications (xmlTextWriterPtr xo, char *root);
-static void canonicalize (char *dev);
static void free_strings (char **argv);
static size_t count_strings (char *const*argv);
static void do_xpath (const char *query);
@@ -363,15 +362,17 @@ output_root (xmlTextWriterPtr xo, char *root)
char *str;
int i, r;
char buf[32];
- char canonical_root[strlen (root) + 1];
+ char *canonical_root;
size_t size;
XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "operatingsystem"));
- strcpy (canonical_root, root);
- canonicalize (canonical_root);
+ canonical_root = guestfs_canonical_device_name (g, root);
+ if (canonical_root == NULL)
+ exit (EXIT_FAILURE);
XMLERROR (-1,
xmlTextWriterWriteElement (xo, BAD_CAST "root", BAD_CAST canonical_root));
+ free (canonical_root);
str = guestfs_inspect_get_type (g, root);
if (!str) exit (EXIT_FAILURE);
@@ -560,7 +561,7 @@ compare_keys_len (const void *p1, const void *p2)
static void
output_mountpoints (xmlTextWriterPtr xo, char *root)
{
- char **mountpoints;
+ char **mountpoints, *p;
size_t i;
mountpoints = guestfs_inspect_get_mountpoints (g, root);
@@ -576,16 +577,19 @@ output_mountpoints (xmlTextWriterPtr xo, char *root)
XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "mountpoints"));
for (i = 0; mountpoints[i] != NULL; i += 2) {
- canonicalize (mountpoints[i+1]);
+ p = guestfs_canonical_device_name (g, mountpoints[i+1]);
+ if (!p)
+ exit (EXIT_FAILURE);
XMLERROR (-1,
xmlTextWriterStartElement (xo, BAD_CAST "mountpoint"));
XMLERROR (-1,
- xmlTextWriterWriteAttribute (xo, BAD_CAST "dev",
- BAD_CAST mountpoints[i+1]));
+ xmlTextWriterWriteAttribute (xo, BAD_CAST "dev", BAD_CAST p));
XMLERROR (-1,
xmlTextWriterWriteString (xo, BAD_CAST mountpoints[i]));
XMLERROR (-1, xmlTextWriterEndElement (xo));
+
+ free (p);
}
XMLERROR (-1, xmlTextWriterEndElement (xo));
@@ -611,12 +615,14 @@ output_filesystems (xmlTextWriterPtr xo, char *root)
XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "filesystems"));
for (i = 0; filesystems[i] != NULL; ++i) {
- canonicalize (filesystems[i]);
+ str = guestfs_canonical_device_name (g, filesystems[i]);
+ if (!str)
+ exit (EXIT_FAILURE);
XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "filesystem"));
XMLERROR (-1,
- xmlTextWriterWriteAttribute (xo, BAD_CAST "dev",
- BAD_CAST filesystems[i]));
+ xmlTextWriterWriteAttribute (xo, BAD_CAST "dev", BAD_CAST str));
+ free (str);
DISABLE_GUESTFS_ERRORS_FOR (
str = guestfs_vfs_type (g, filesystems[i]);
@@ -657,6 +663,7 @@ static void
output_drive_mappings (xmlTextWriterPtr xo, char *root)
{
char **drive_mappings = NULL;
+ char *str;
size_t i;
DISABLE_GUESTFS_ERRORS_FOR (
@@ -678,7 +685,9 @@ output_drive_mappings (xmlTextWriterPtr xo, char *root)
XMLERROR (-1, xmlTextWriterStartElement (xo, BAD_CAST "drive_mappings"));
for (i = 0; drive_mappings[i] != NULL; i += 2) {
- canonicalize (drive_mappings[i+1]);
+ str = guestfs_canonical_device_name (g, drive_mappings[i+1]);
+ if (!str)
+ exit (EXIT_FAILURE);
XMLERROR (-1,
xmlTextWriterStartElement (xo, BAD_CAST "drive_mapping"));
@@ -686,8 +695,10 @@ output_drive_mappings (xmlTextWriterPtr xo, char *root)
xmlTextWriterWriteAttribute (xo, BAD_CAST "name",
BAD_CAST drive_mappings[i]));
XMLERROR (-1,
- xmlTextWriterWriteString (xo, BAD_CAST drive_mappings[i+1]));
+ xmlTextWriterWriteString (xo, BAD_CAST str));
XMLERROR (-1, xmlTextWriterEndElement (xo));
+
+ free (str);
}
XMLERROR (-1, xmlTextWriterEndElement (xo));
@@ -773,20 +784,6 @@ output_applications (xmlTextWriterPtr xo, char *root)
guestfs_free_application_list (apps);
}
-/* "/dev/vda1" -> "/dev/sda1"
- * See BLOCK DEVICE NAMING in guestfs(3).
- */
-static void
-canonicalize (char *dev)
-{
- if (STRPREFIX (dev, "/dev/") &&
- (dev[5] == 'h' || dev[5] == 'v') &&
- dev[6] == 'd' &&
- c_isalpha (dev[7]) &&
- (c_isdigit (dev[8]) || dev[8] == '\0'))
- dev[5] = 's';
-}
-
static void
free_strings (char **argv)
{
diff --git a/resize/resize.ml b/resize/resize.ml
index e8187c89..5e323bae 100644
--- a/resize/resize.ml
+++ b/resize/resize.ml
@@ -348,7 +348,7 @@ let get_partition_content =
| [] ->
error (f_"%s: physical volume not returned by pvs_full")
dev
- | pv :: _ when canonicalize pv.G.pv_name = dev ->
+ | pv :: _ when g#canonical_device_name pv.G.pv_name = dev ->
ContentPV pv.G.pv_size
| _ :: pvs -> loop pvs
in
@@ -529,7 +529,7 @@ let find_partition =
"/dev/" ^ name
else
name in
- let name = canonicalize name in
+ let name = g#canonical_device_name name in
let partition =
try Hashtbl.find hash name
diff --git a/resize/utils.ml b/resize/utils.ml
index d99f489b..82d45a3e 100644
--- a/resize/utils.ml
+++ b/resize/utils.ml
@@ -84,20 +84,6 @@ let error fs =
in
ksprintf display fs
-(* The reverse of device name translation, see
- * BLOCK DEVICE NAMING in guestfs(3).
- *)
-let canonicalize dev =
- if String.length dev >= 8 &&
- dev.[0] = '/' && dev.[1] = 'd' && dev.[2] = 'e' && dev.[3] = 'v' &&
- dev.[4] = '/' && (dev.[5] = 'h' || dev.[5] = 'v') && dev.[6] = 'd' then (
- let dev = String.copy dev in
- dev.[5] <- 's';
- dev
- )
- else
- dev
-
let feature_available (g : Guestfs.guestfs) names =
try g#available names; true
with G.Error _ -> false
diff --git a/resize/utils_tests.ml b/resize/utils_tests.ml
index 9356d7b6..cc00061e 100644
--- a/resize/utils_tests.ml
+++ b/resize/utils_tests.ml
@@ -25,15 +25,6 @@ let () =
assert (int_of_le32 "\x80\x60\x40\x20" = 0x20406080L);
assert (le32_of_int 0x20406080L = "\x80\x60\x40\x20")
-(* Test Utils.canonicalize. *)
-let () =
- assert (canonicalize "/dev/vda" = "/dev/sda");
- assert (canonicalize "/dev/hda3" = "/dev/sda3");
- assert (canonicalize "/dev/sda4" = "/dev/sda4");
- assert (canonicalize "/dev/hdaa" = "/dev/sdaa");
- assert (canonicalize "/dev/sdaa" = "/dev/sdaa");
- assert (canonicalize "/dev/cciss/c0d0p1" = "/dev/cciss/c0d0p1")
-
(* Test Utils.parse_size. *)
let () =
(* For absolute sizes, oldsize is ignored. *)
diff --git a/sparsify/sparsify.ml b/sparsify/sparsify.ml
index 600a9e5f..ec3512a9 100644
--- a/sparsify/sparsify.ml
+++ b/sparsify/sparsify.ml
@@ -214,8 +214,8 @@ let () =
let filesystems = List.sort compare filesystems in
let is_ignored fs =
- let fs = canonicalize fs in
- List.exists (fun fs' -> fs = canonicalize fs') ignores
+ let fs = g#canonical_device_name fs in
+ List.exists (fun fs' -> fs = g#canonical_device_name fs') ignores
in
List.iter (
diff --git a/sparsify/utils.ml b/sparsify/utils.ml
index dd27ba88..5c999712 100644
--- a/sparsify/utils.ml
+++ b/sparsify/utils.ml
@@ -112,20 +112,6 @@ let error fs =
in
ksprintf display fs
-(* The reverse of device name translation, see
- * BLOCK DEVICE NAMING in guestfs(3).
- *)
-let canonicalize dev =
- if String.length dev >= 8 &&
- dev.[0] = '/' && dev.[1] = 'd' && dev.[2] = 'e' && dev.[3] = 'v' &&
- dev.[4] = '/' && (dev.[5] = 'h' || dev.[5] = 'v') && dev.[6] = 'd' then (
- let dev = String.copy dev in
- dev.[5] <- 's';
- dev
- )
- else
- dev
-
let feature_available (g : Guestfs.guestfs) names =
try g#available names; true
with G.Error _ -> false
diff --git a/src/guestfs.c b/src/guestfs.c
index 561fab4f..32bcbeff 100644
--- a/src/guestfs.c
+++ b/src/guestfs.c
@@ -996,3 +996,26 @@ guestfs___free_drives (struct drive **drives)
i = next;
}
}
+
+char *
+guestfs__canonical_device_name (guestfs_h *g, const char *device)
+{
+ char *ret;
+
+ if (STRPREFIX (device, "/dev/hd") ||
+ STRPREFIX (device, "/dev/vd")) {
+ ret = safe_strdup (g, device);
+ ret[5] = 's';
+ }
+ else if (STRPREFIX (device, "/dev/mapper/") ||
+ STRPREFIX (device, "/dev/dm-")) {
+ /* XXX hide errors */
+ ret = guestfs_lvm_canonical_lv_name (g, device);
+ if (ret == NULL)
+ ret = safe_strdup (g, device);
+ }
+ else
+ ret = safe_strdup (g, device);
+
+ return ret; /* caller frees */
+}
diff --git a/src/guestfs.pod b/src/guestfs.pod
index fd8b70ca..6959f50c 100644
--- a/src/guestfs.pod
+++ b/src/guestfs.pod
@@ -1158,7 +1158,7 @@ C</dev/hda2> transparently.
Note that this I<only> applies to parameters. The
L</guestfs_list_devices>, L</guestfs_list_partitions> and similar calls
return the true names of the devices and partitions as known to the
-appliance.
+appliance, but see L</guestfs_canonical_device_name>.
=head3 ALGORITHM FOR BLOCK DEVICE NAME TRANSLATION