* grub-core/disk/diskfilter.c: Handle non-md UUIDs.
* grub-core/disk/lvm.c: Add LVM UUIDs. * util/getroot.c: Use LVM UUIDs whenever possible.
This commit is contained in:
parent
53c6b7d658
commit
63653cfdae
5 changed files with 136 additions and 50 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2013-09-20 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/disk/diskfilter.c: Handle non-md UUIDs.
|
||||||
|
* grub-core/disk/lvm.c: Add LVM UUIDs.
|
||||||
|
* util/getroot.c: Use LVM UUIDs whenever possible.
|
||||||
|
|
||||||
2013-09-19 Andrey Borzenkov <arvidjaar@gmail.com>
|
2013-09-19 Andrey Borzenkov <arvidjaar@gmail.com>
|
||||||
|
|
||||||
* docs/grub.texi (Networking commands): Add documentation for
|
* docs/grub.texi (Networking commands): Add documentation for
|
||||||
|
|
|
@ -117,6 +117,7 @@ is_valid_diskfilter_name (const char *name)
|
||||||
{
|
{
|
||||||
return (grub_memcmp (name, "md", sizeof ("md") - 1) == 0
|
return (grub_memcmp (name, "md", sizeof ("md") - 1) == 0
|
||||||
|| grub_memcmp (name, "lvm/", sizeof ("lvm/") - 1) == 0
|
|| grub_memcmp (name, "lvm/", sizeof ("lvm/") - 1) == 0
|
||||||
|
|| grub_memcmp (name, "lvmid/", sizeof ("lvmid/") - 1) == 0
|
||||||
|| grub_memcmp (name, "ldm/", sizeof ("ldm/") - 1) == 0);
|
|| grub_memcmp (name, "ldm/", sizeof ("ldm/") - 1) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,16 +388,12 @@ grub_diskfilter_getname (struct grub_disk *disk)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline int
|
static inline char
|
||||||
ascii2hex (char c)
|
hex2ascii (int c)
|
||||||
{
|
{
|
||||||
if (c >= '0' && c <= '9')
|
if (c >= 10)
|
||||||
return c - '0';
|
return 'a' + c - 10;
|
||||||
if (c >= 'a' && c <= 'f')
|
return c + '0';
|
||||||
return c - 'a' + 10;
|
|
||||||
if (c >= 'A' && c <= 'F')
|
|
||||||
return c - 'A' + 10;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct grub_diskfilter_lv *
|
static struct grub_diskfilter_lv *
|
||||||
|
@ -405,30 +402,12 @@ find_lv (const char *name)
|
||||||
struct grub_diskfilter_vg *vg;
|
struct grub_diskfilter_vg *vg;
|
||||||
struct grub_diskfilter_lv *lv = NULL;
|
struct grub_diskfilter_lv *lv = NULL;
|
||||||
|
|
||||||
if (grub_memcmp (name, "mduuid/", sizeof ("mduuid/") - 1) == 0)
|
|
||||||
{
|
|
||||||
const char *uuidstr = name + sizeof ("mduuid/") - 1;
|
|
||||||
grub_size_t uuid_len = grub_strlen (uuidstr) / 2;
|
|
||||||
grub_uint8_t uuidbin[uuid_len];
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < uuid_len; i++)
|
|
||||||
uuidbin[i] = ascii2hex (uuidstr[2 * i + 1])
|
|
||||||
| (ascii2hex (uuidstr[2 * i]) << 4);
|
|
||||||
|
|
||||||
for (vg = array_list; vg; vg = vg->next)
|
|
||||||
{
|
|
||||||
if (uuid_len == vg->uuid_len
|
|
||||||
&& grub_memcmp (uuidbin, vg->uuid, uuid_len) == 0)
|
|
||||||
if (is_lv_readable (vg->lvs, 0))
|
|
||||||
return vg->lvs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (vg = array_list; vg; vg = vg->next)
|
for (vg = array_list; vg; vg = vg->next)
|
||||||
{
|
{
|
||||||
if (vg->lvs)
|
if (vg->lvs)
|
||||||
for (lv = vg->lvs; lv; lv = lv->next)
|
for (lv = vg->lvs; lv; lv = lv->next)
|
||||||
if (lv->fullname && grub_strcmp (lv->fullname, name) == 0
|
if (((lv->fullname && grub_strcmp (lv->fullname, name) == 0)
|
||||||
|
|| (lv->idname && grub_strcmp (lv->idname, name) == 0))
|
||||||
&& is_lv_readable (lv, 0))
|
&& is_lv_readable (lv, 0))
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
@ -440,9 +419,7 @@ grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||||
{
|
{
|
||||||
struct grub_diskfilter_lv *lv;
|
struct grub_diskfilter_lv *lv;
|
||||||
|
|
||||||
if (grub_memcmp (name, "md", sizeof ("md") - 1) != 0
|
if (!is_valid_diskfilter_name (name))
|
||||||
&& grub_memcmp (name, "lvm/", sizeof ("lvm/") - 1) != 0
|
|
||||||
&& grub_memcmp (name, "ldm/", sizeof ("ldm/") - 1) != 0)
|
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown DISKFILTER device %s",
|
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown DISKFILTER device %s",
|
||||||
name);
|
name);
|
||||||
|
|
||||||
|
@ -929,6 +906,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
||||||
{
|
{
|
||||||
struct grub_diskfilter_vg *array;
|
struct grub_diskfilter_vg *array;
|
||||||
int i;
|
int i;
|
||||||
|
grub_size_t j;
|
||||||
grub_uint64_t totsize;
|
grub_uint64_t totsize;
|
||||||
struct grub_diskfilter_pv *pv;
|
struct grub_diskfilter_pv *pv;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
@ -995,6 +973,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
||||||
|
|
||||||
array->name = new_name;
|
array->name = new_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
array->extent_size = 1;
|
array->extent_size = 1;
|
||||||
array->lvs = grub_zalloc (sizeof (*array->lvs));
|
array->lvs = grub_zalloc (sizeof (*array->lvs));
|
||||||
if (!array->lvs)
|
if (!array->lvs)
|
||||||
|
@ -1004,6 +983,20 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
||||||
array->lvs->name = array->name;
|
array->lvs->name = array->name;
|
||||||
array->lvs->fullname = array->name;
|
array->lvs->fullname = array->name;
|
||||||
|
|
||||||
|
array->lvs->idname = grub_malloc (sizeof ("mduuid/") + 2 * uuidlen);
|
||||||
|
if (!array->lvs->idname)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
grub_memcpy (array->lvs->idname, "mduuid/", sizeof ("mduuid/") - 1);
|
||||||
|
for (j = 0; j < uuidlen; j++)
|
||||||
|
{
|
||||||
|
array->lvs->idname[sizeof ("mduuid/") - 1 + 2 * j]
|
||||||
|
= hex2ascii (((unsigned char) uuid[j] >> 4));
|
||||||
|
array->lvs->idname[sizeof ("mduuid/") - 1 + 2 * j + 1]
|
||||||
|
= hex2ascii (((unsigned char) uuid[j] & 0xf));
|
||||||
|
}
|
||||||
|
array->lvs->idname[sizeof ("mduuid/") - 1 + 2 * uuidlen] = '\0';
|
||||||
|
|
||||||
array->lvs->size = totsize;
|
array->lvs->size = totsize;
|
||||||
|
|
||||||
array->lvs->segments = grub_zalloc (sizeof (*array->lvs->segments));
|
array->lvs->segments = grub_zalloc (sizeof (*array->lvs->segments));
|
||||||
|
|
|
@ -387,6 +387,29 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
*optr++ = '-';
|
*optr++ = '-';
|
||||||
}
|
}
|
||||||
*optr++ = 0;
|
*optr++ = 0;
|
||||||
|
lv->idname = grub_malloc (sizeof ("lvmid/")
|
||||||
|
+ 2 * GRUB_LVM_ID_STRLEN + 1);
|
||||||
|
if (!lv->idname)
|
||||||
|
goto lvs_fail;
|
||||||
|
grub_memcpy (lv->idname, "lvmid/",
|
||||||
|
sizeof ("lvmid/") - 1);
|
||||||
|
grub_memcpy (lv->idname + sizeof ("lvmid/") - 1,
|
||||||
|
vg_id, GRUB_LVM_ID_STRLEN);
|
||||||
|
lv->idname[sizeof ("lvmid/") - 1 + GRUB_LVM_ID_STRLEN] = '/';
|
||||||
|
|
||||||
|
p = grub_strstr (q, "id = \"");
|
||||||
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
#ifdef GRUB_UTIL
|
||||||
|
grub_util_info ("couldn't find ID\n");
|
||||||
|
#endif
|
||||||
|
goto lvs_fail;
|
||||||
|
}
|
||||||
|
p += sizeof ("id = \"") - 1;
|
||||||
|
grub_memcpy (lv->idname + sizeof ("lvmid/") - 1
|
||||||
|
+ GRUB_LVM_ID_STRLEN + 1,
|
||||||
|
p, GRUB_LVM_ID_STRLEN);
|
||||||
|
lv->idname[sizeof ("lvmid/") - 1 + 2 * GRUB_LVM_ID_STRLEN + 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
lv->size = 0;
|
lv->size = 0;
|
||||||
|
|
|
@ -80,6 +80,7 @@ struct grub_diskfilter_pv {
|
||||||
struct grub_diskfilter_lv {
|
struct grub_diskfilter_lv {
|
||||||
/* Name used for disk. */
|
/* Name used for disk. */
|
||||||
char *fullname;
|
char *fullname;
|
||||||
|
char *idname;
|
||||||
/* Optional. */
|
/* Optional. */
|
||||||
char *name;
|
char *name;
|
||||||
int number;
|
int number;
|
||||||
|
|
|
@ -1333,26 +1333,55 @@ pull_lvm_by_command (const char *os_dev)
|
||||||
FILE *mdadm;
|
FILE *mdadm;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
char *vgname;
|
char *vgname = NULL;
|
||||||
const char *iptr;
|
const char *iptr;
|
||||||
char *optr;
|
char *optr;
|
||||||
|
char *vgid = NULL;
|
||||||
|
grub_size_t vgidlen = 0;
|
||||||
|
|
||||||
if (strncmp (os_dev, "/dev/mapper/", sizeof ("/dev/mapper/") - 1)
|
#ifdef HAVE_DEVICE_MAPPER
|
||||||
!= 0)
|
char *uuid;
|
||||||
return;
|
|
||||||
|
|
||||||
vgname = xmalloc (strlen (os_dev + sizeof ("/dev/mapper/") - 1) + 1);
|
uuid = get_dm_uuid (os_dev);
|
||||||
for (iptr = os_dev + sizeof ("/dev/mapper/") - 1, optr = vgname; *iptr; )
|
if (uuid)
|
||||||
if (*iptr != '-')
|
{
|
||||||
*optr++ = *iptr++;
|
int dashes[] = { 0, 6, 10, 14, 18, 22, 26, 32};
|
||||||
else if (iptr[0] == '-' && iptr[1] == '-')
|
unsigned i;
|
||||||
{
|
vgid = xmalloc (grub_strlen (uuid));
|
||||||
iptr += 2;
|
optr = vgid;
|
||||||
*optr++ = '-';
|
for (i = 0; i < ARRAY_SIZE (dashes) - 1; i++)
|
||||||
}
|
{
|
||||||
else
|
memcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i],
|
||||||
break;
|
dashes[i+1] - dashes[i]);
|
||||||
*optr = '\0';
|
optr += dashes[i+1] - dashes[i];
|
||||||
|
*optr++ = '-';
|
||||||
|
}
|
||||||
|
optr--;
|
||||||
|
*optr = '\0';
|
||||||
|
vgidlen = optr - vgid;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!vgid)
|
||||||
|
{
|
||||||
|
if (strncmp (os_dev, LVM_DEV_MAPPER_STRING,
|
||||||
|
sizeof (LVM_DEV_MAPPER_STRING) - 1)
|
||||||
|
!= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vgname = xmalloc (strlen (os_dev + sizeof (LVM_DEV_MAPPER_STRING) - 1) + 1);
|
||||||
|
for (iptr = os_dev + sizeof (LVM_DEV_MAPPER_STRING) - 1, optr = vgname; *iptr; )
|
||||||
|
if (*iptr != '-')
|
||||||
|
*optr++ = *iptr++;
|
||||||
|
else if (iptr[0] == '-' && iptr[1] == '-')
|
||||||
|
{
|
||||||
|
iptr += 2;
|
||||||
|
*optr++ = '-';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
*optr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
/* execvp has inconvenient types, hence the casts. None of these
|
/* execvp has inconvenient types, hence the casts. None of these
|
||||||
strings will actually be modified. */
|
strings will actually be modified. */
|
||||||
|
@ -1361,7 +1390,10 @@ pull_lvm_by_command (const char *os_dev)
|
||||||
alignment. We have a single field, so separator itself is not output */
|
alignment. We have a single field, so separator itself is not output */
|
||||||
argv[0] = (char *) "vgs";
|
argv[0] = (char *) "vgs";
|
||||||
argv[1] = (char *) "--options";
|
argv[1] = (char *) "--options";
|
||||||
argv[2] = (char *) "pv_name";
|
if (vgid)
|
||||||
|
argv[2] = (char *) "vg_uuid,pv_name";
|
||||||
|
else
|
||||||
|
argv[2] = (char *) "pv_name";
|
||||||
argv[3] = (char *) "--noheadings";
|
argv[3] = (char *) "--noheadings";
|
||||||
argv[4] = (char *) "--separator";
|
argv[4] = (char *) "--separator";
|
||||||
argv[5] = (char *) ":";
|
argv[5] = (char *) ":";
|
||||||
|
@ -1388,6 +1420,12 @@ pull_lvm_by_command (const char *os_dev)
|
||||||
char *ptr;
|
char *ptr;
|
||||||
/* LVM adds two spaces as standard prefix */
|
/* LVM adds two spaces as standard prefix */
|
||||||
for (ptr = buf; ptr < buf + 2 && *ptr == ' '; ptr++);
|
for (ptr = buf; ptr < buf + 2 && *ptr == ' '; ptr++);
|
||||||
|
|
||||||
|
if (vgid && (grub_strncmp (vgid, ptr, vgidlen) != 0
|
||||||
|
|| ptr[vgidlen] != ':'))
|
||||||
|
continue;
|
||||||
|
if (vgid)
|
||||||
|
ptr += vgidlen + 1;
|
||||||
if (*ptr == '\0')
|
if (*ptr == '\0')
|
||||||
continue;
|
continue;
|
||||||
*(ptr + strlen (ptr) - 1) = '\0';
|
*(ptr + strlen (ptr) - 1) = '\0';
|
||||||
|
@ -2534,7 +2572,32 @@ grub_util_get_grub_dev (const char *os_dev)
|
||||||
|
|
||||||
switch (grub_util_get_dev_abstraction (os_dev))
|
switch (grub_util_get_dev_abstraction (os_dev))
|
||||||
{
|
{
|
||||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
#ifdef HAVE_DEVICE_MAPPER
|
||||||
|
case GRUB_DEV_ABSTRACTION_LVM:
|
||||||
|
{
|
||||||
|
char *uuid, *optr;
|
||||||
|
unsigned i;
|
||||||
|
int dashes[] = { 0, 6, 10, 14, 18, 22, 26, 32, 38, 42, 46, 50, 54, 58};
|
||||||
|
uuid = get_dm_uuid (os_dev);
|
||||||
|
if (!uuid)
|
||||||
|
break;
|
||||||
|
grub_dev = xmalloc (grub_strlen (uuid) + 40);
|
||||||
|
optr = grub_stpcpy (grub_dev, "lvmid/");
|
||||||
|
for (i = 0; i < ARRAY_SIZE (dashes) - 1; i++)
|
||||||
|
{
|
||||||
|
memcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i],
|
||||||
|
dashes[i+1] - dashes[i]);
|
||||||
|
optr += dashes[i+1] - dashes[i];
|
||||||
|
*optr++ = '-';
|
||||||
|
}
|
||||||
|
optr = stpcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i]);
|
||||||
|
*optr = '\0';
|
||||||
|
grub_dev[sizeof("lvmid/xxxxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxxxx") - 1]
|
||||||
|
= '/';
|
||||||
|
free (uuid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
case GRUB_DEV_ABSTRACTION_LVM:
|
case GRUB_DEV_ABSTRACTION_LVM:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue