From: Andrey Borzenkov To: grub-devel@gnu.org Subject: [PATCH] fix parsing of LVM PV names for short names Default format of vgs output is - two spaces as standard prefix - PV name left aligned to field width which is 10 characters This means that if PV name has less than 10 chacaters it has some spaces at the end. Example: linux-chxo:~ # vgs -o pv_name --noheadings | cat -E /dev/md1 $ /dev/md101$ linux-chxo:~ # There is no explicit option to turn off alignment; it is implicitly disabled if one of --separator or --nameprefixes option is used. --separator was added in 2007, --nameprefixes - in 2009. So let's use --separator to extend range of versions we are compatible with. Note that one or another must be used, current parsing is broken otherwise. Signed-off-by: Andrey Borzenkov --- util/getroot.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/util/getroot.c b/util/getroot.c index 2ad8a55..3afcf96 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -1322,7 +1322,7 @@ grub_util_get_dev_abstraction (const char *os_dev) static void pull_lvm_by_command (const char *os_dev) { - char *argv[6]; + char *argv[8]; int fd; pid_t pid; FILE *mdadm; @@ -1351,12 +1351,17 @@ pull_lvm_by_command (const char *os_dev) /* execvp has inconvenient types, hence the casts. None of these strings will actually be modified. */ + /* by default PV name is left aligned in 10 character field, meaning that + we do not know where name ends. Using dummy --separator disables + alignment. We have a single field, so separator itself is not output */ argv[0] = (char *) "vgs"; argv[1] = (char *) "--options"; argv[2] = (char *) "pv_name"; argv[3] = (char *) "--noheadings"; - argv[4] = vgname; - argv[5] = NULL; + argv[4] = (char *) "--separator"; + argv[5] = (char *) ":"; + argv[6] = vgname; + argv[7] = NULL; pid = exec_pipe (argv, &fd); free (vgname); @@ -1376,6 +1381,7 @@ pull_lvm_by_command (const char *os_dev) while (getline (&buf, &len, mdadm) > 0) { char *ptr; + /* LVM adds two spaces as standard prefix */ for (ptr = buf; ptr < buf + 2 && *ptr == ' '; ptr++); if (*ptr == '\0') continue; -- tg: (ebd40b6..) u/strip-pv-trailing-blanks (depends on: master)