From b01ef8eae1acc5105e623a25c8988bcc3326ea1c Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 25 Oct 2010 12:52:49 +0100 Subject: [PATCH] New API: lvm-canonical-lv-name: make LV name canonical. When logical volume names appear in places like /etc/fstab files they can have the form "/dev/mapper/foo-bar". This function takes such names and makes them canonical. Note that this operation cannot be performed using the current API, because 'guestfs_stat' does not work on device names, and we don't really want to make a 'stat-device' call since that exposes too much non-useful detail about the appliance. With this patch you can do this: > debug ll /dev/mapper total 8 drwxrwxr-x 2 root root 4096 Oct 25 12:51 . drwxr-xr-x 16 root root 4096 Oct 25 12:51 .. crw------- 1 root root 10, 62 Oct 25 12:51 control lrwxrwxrwx 1 root root 7 Oct 25 12:51 vg_f13x64-lv_root -> ../dm-0 lrwxrwxrwx 1 root root 7 Oct 25 12:51 vg_f13x64-lv_swap -> ../dm-1 > lvm-canonical-lv-name /dev/mapper/vg_f13x64-lv_root /dev/vg_f13x64/lv_root > lvm-canonical-lv-name /dev/mapper/vg_f13x64-lv_swap /dev/vg_f13x64/lv_swap > lvm-canonical-lv-name /dev/mapper/foo libguestfs: error: lvm_canonical_lv_name: lvm_canonical_lv_name_stub: /dev/mapper/foo: No such file or directory > lvm-canonical-lv-name /dev/mapper/control libguestfs: error: lvm_canonical_lv_name: /dev/mapper/control: not a logical volume > lvm-canonical-lv-name /dev/vg_f13x64/lv_root /dev/vg_f13x64/lv_root --- daemon/lvm.c | 42 ++++++++++++++++++++++++++++++++++++++++++ generator/generator_actions.ml | 16 ++++++++++++++++ src/MAX_PROC_NR | 2 +- 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/daemon/lvm.c b/daemon/lvm.c index 0df27e2..2691daa 100644 --- a/daemon/lvm.c +++ b/daemon/lvm.c @@ -709,3 +709,45 @@ do_is_lv (const char *device) free_strings (lvs); return 0; } + +/* Similar to is_lv above (RHBZ#638899). */ +char * +do_lvm_canonical_lv_name (const char *device) +{ + struct stat stat1, stat2; + + int r = stat (device, &stat1); + if (r == -1) { + reply_with_perror ("stat: %s", device); + return NULL; + } + + char **lvs = do_lvs (); + if (lvs == NULL) + return NULL; + + size_t i; + for (i = 0; lvs[i] != NULL; ++i) { + r = stat (lvs[i], &stat2); + if (r == -1) { + reply_with_perror ("stat: %s", lvs[i]); + free_strings (lvs); + return NULL; + } + if (stat1.st_rdev == stat2.st_rdev) { /* found it */ + char *r = strdup (lvs[i]); + if (r == NULL) { + reply_with_perror ("strdup"); + free_strings (lvs); + } + free_strings (lvs); + return r; + } + } + + free_strings (lvs); + + /* not found */ + reply_with_error ("%s: not a logical volume", device); + return NULL; +} diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index 695a73d..38f1db3 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -5208,6 +5208,22 @@ see the L system call. See also C."); + ("lvm_canonical_lv_name", (RString "lv", [Device "lvname"], []), 277, [], + [InitBasicFSonLVM, IfAvailable "lvm2", TestOutput ( + [["lvm_canonical_lv_name"; "/dev/mapper/VG-LV"]], "/dev/VG/LV"); + InitBasicFSonLVM, IfAvailable "lvm2", TestOutput ( + [["lvm_canonical_lv_name"; "/dev/VG/LV"]], "/dev/VG/LV")], + "get canonical name of an LV", + "\ +This converts alternative naming schemes for LVs that you +might find to the canonical name. For example, C +is converted to C. + +This command returns an error if the C parameter does +not refer to a logical volume. + +See also C."); + ] let all_functions = non_daemon_functions @ daemon_functions diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index 15007f1..2681747 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -276 +277 -- 1.8.3.1