On Thu, Apr 10, 2008 at 09:14:44AM +0200, Robert Millan wrote:
> tags 474343 - moreinfo
> tags 474343 patch
> thanks
>
> On Tue, Apr 08, 2008 at 08:00:49AM +0900, Junichi Uekawa wrote:
> > Breakpoint 1, grub_lvm_scan_device (name=0x6350c0 "hd0,4") at
> > /tmp/grub-common/grub2-1.96+20080228/disk/lvm.c:376
> > 376 p += 18;
> > (gdb) print p
> > $1 = 0x0
> > (gdb)
>
> Ok I think this would do it. Please, can you try?
Please try also this one (separately) if you can. It's supposed to improve
robustness in case similar problems arise.
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
diff -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/disk/lvm.c ./disk/lvm.c
--- ../grub2/disk/lvm.c 2008-02-09 11:49:29.000000000 +0100
+++ ./disk/lvm.c 2008-04-10 10:06:00.000000000 +0200
@@ -29,11 +29,15 @@ static int lv_count;
/* Go the string STR and return the number after STR. *P will point
- at the number. */
+ at the number. In case STR is not found, *P will be NULL and the
+ return value will be 0. */
static int
grub_lvm_getvalue (char **p, char *str)
{
- *p = grub_strstr (*p, str) + grub_strlen (str);
+ *p = grub_strstr (*p, str);
+ if (! *p)
+ return 0;
+ *p += grub_strlen (str);
return grub_strtoul (*p, NULL, 10);
}
@@ -44,6 +48,7 @@ grub_lvm_iterate (int (*hook) (const cha
for (vg = vg_list; vg; vg = vg->next)
{
struct grub_lvm_lv *lv;
+if (vg->lvs)
for (lv = vg->lvs; lv; lv = lv->next)
if (hook (lv->name))
return 1;
@@ -60,6 +65,7 @@ grub_lvm_memberlist (grub_disk_t disk)
grub_disk_memberlist_t list = NULL, tmp;
struct grub_lvm_pv *pv;
+ if (lv->vg->pvs)
for (pv = lv->vg->pvs; pv; pv = pv->next)
{
tmp = grub_malloc (sizeof (*tmp));
@@ -79,6 +85,7 @@ grub_lvm_open (const char *name, grub_di
struct grub_lvm_lv *lv = NULL;
for (vg = vg_list; vg; vg = vg->next)
{
+if (vg->lvs)
for (lv = vg->lvs; lv; lv = lv->next)
if (! grub_strcmp (lv->name, name))
break;
@@ -330,14 +337,19 @@ grub_lvm_scan_device (const char *name)
grub_memcpy (vg->id, vg_id, GRUB_LVM_ID_STRLEN+1);
vg->extent_size = grub_lvm_getvalue (&p, "extent_size = ");
+ if (p == NULL)
+ goto fail2;
vg->lvs = NULL;
vg->pvs = NULL;
vg->next = vg_list;
vg_list = vg;
- p = grub_strstr (p, "physical_volumes {")
- + sizeof ("physical_volumes {") - 1;
+ p = grub_strstr (p, "physical_volumes {");
+ if (p)
+ {
+
+ p += sizeof ("physical_volumes {") - 1;
/* Add all the pvs to the volume group. */
while (1)
@@ -360,19 +372,33 @@ grub_lvm_scan_device (const char *name)
pv->name[s] = '\0';
p = grub_strstr (p, "id = \"") + sizeof("id = \"") - 1;
+ if (p == NULL)
+ goto pvs_fail;
grub_memcpy (pv->id, p, GRUB_LVM_ID_STRLEN);
pv->id[GRUB_LVM_ID_STRLEN] = '\0';
pv->start = grub_lvm_getvalue (&p, "pe_start = ");
+ if (p == NULL)
+ goto pvs_fail;
pv->disk = NULL;
pv->next = vg->pvs;
vg->pvs = pv;
p = grub_strchr (p, '}') + 1;
+
+ continue;
+ pvs_fail:
+ grub_free (pv->name);
+ grub_free (pv);
+ goto fail2;
+ }
+
}
p = grub_strstr (p, "logical_volumes");
+if (p)
+{
p += 18;
/* And add all the lvs to the volume group. */
@@ -404,6 +430,8 @@ grub_lvm_scan_device (const char *name)
lv->size = 0;
lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
+ if (p == NULL)
+ goto lvs_fail;
lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
seg = lv->segments;
@@ -412,10 +440,18 @@ grub_lvm_scan_device (const char *name)
struct grub_lvm_stripe *stripe;
p = grub_strstr (p, "segment");
+ if (p == NULL)
+ goto lvs_segment_fail;
seg->start_extent = grub_lvm_getvalue (&p, "start_extent = ");
+ if (p == NULL)
+ goto lvs_segment_fail;
seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
+ if (p == NULL)
+ goto lvs_segment_fail;
seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
+ if (p == NULL)
+ goto lvs_segment_fail;
lv->size += seg->extent_count * vg->extent_size;
@@ -426,14 +462,19 @@ grub_lvm_scan_device (const char *name)
* seg->stripe_count);
stripe = seg->stripes;
- p = grub_strstr (p, "stripes = [")
- + sizeof("stripes = [") - 1;
+ p = grub_strstr (p, "stripes = [");
+ if (p == NULL)
+ goto lvs_segment_fail2;
+ p += sizeof("stripes = [") - 1;
for (j = 0; j < seg->stripe_count; j++)
{
char pvname[10];
- q = p = grub_strchr (p, '"') + 1;
+ p = grub_strchr (p, '"');
+ if (p == NULL)
+ continue;
+ q = ++p;
while (*q != '"')
q++;
@@ -441,6 +482,7 @@ grub_lvm_scan_device (const char *name)
grub_memcpy (pvname, p, s);
pvname[s] = '\0';
+ if (vg->pvs)
for (pv = vg->pvs; pv; pv = pv->next)
{
if (! grub_strcmp (pvname, pv->name))
@@ -450,13 +492,20 @@ grub_lvm_scan_device (const char *name)
}
}
- p = grub_strchr (p, ',') + 1;
- stripe->start = grub_strtoul (p, NULL, 10);
+ stripe->start = grub_lvm_getvalue (&p, ",");
+ if (p == NULL)
+ continue;
stripe++;
}
seg++;
+
+ continue;
+ lvs_segment_fail2:
+ grub_free (seg->stripes);
+ lvs_segment_fail:
+ goto fail2;
}
lv->number = lv_count++;
@@ -464,8 +513,18 @@ grub_lvm_scan_device (const char *name)
lv->next = vg->lvs;
vg->lvs = lv;
- p = grub_strchr (p, '}') + 3;
+ p = grub_strchr (p, '}');
+ if (p == NULL)
+ goto lvs_fail;
+ p += 3;
+
+ continue;
+ lvs_fail:
+ grub_free (lv->name);
+ grub_free (lv);
+ goto fail2;
}
+}
}
else
{
@@ -474,6 +533,7 @@ grub_lvm_scan_device (const char *name)
/* Match the device we are currently reading from with the right
PV. */
+ if (vg->pvs)
for (pv = vg->pvs; pv; pv = pv->next)
{
if (! grub_memcmp (pv->id, pv_id, GRUB_LVM_ID_STRLEN))