diff -u grub2-1.98/debian/changelog grub2-1.98/debian/changelog --- grub2-1.98/debian/changelog +++ grub2-1.98/debian/changelog @@ -1,3 +1,10 @@ +grub2 (1.98-1ubuntu12.1) lucid-proposed; urgency=low + + * Skip LVM snapshots (closes: #574863) + (LP: #563895). + + -- Ken Stailey Tue, 8 Nov 2011 06:30:15 +0500 + grub2 (1.98-1ubuntu12) lucid-proposed; urgency=low * Fix use of freed memory when replacing existing loopback device only in patch2: unchanged: --- grub2-1.98.orig/disk/lvm.c +++ grub2-1.98/disk/lvm.c @@ -42,6 +42,52 @@ } static int +grub_lvm_checkvalue (char **p, char *str, char *tmpl) +{ + int tmpllen = grub_strlen (tmpl); + *p = grub_strstr (*p, str); + if (! *p) + return 0; + *p += grub_strlen (str); + if (**p != '"') + return 0; + return (grub_memcmp (*p + 1, tmpl, tmpllen) == 0 && (*p)[tmpllen + 1] == '"'); +} + +static int +grub_lvm_check_flag (char *p, char *str, char *flag) +{ + int len_str = grub_strlen (str), len_flag = grub_strlen (flag); + while (1) + { + char *q; + p = grub_strstr (p, str); + if (! p) + return 0; + p += len_str; + if (grub_memcmp (p, " = [", sizeof (" = [") - 1) != 0) + continue; + q = p + sizeof (" = [") - 1; + while (1) + { + while (grub_isspace (*q)) + q++; + if (*q != '"') + return 0; + q++; + if (grub_memcmp (q, flag, len_flag) == 0 && q[len_flag] == '"') + return 1; + while (*q != '"') + q++; + q++; + if (*q == ']') + return 0; + q++; + } + } +} + +static int grub_lvm_iterate (int (*hook) (const char *name)) { struct grub_lvm_vg *vg; @@ -414,6 +460,7 @@ while (1) { int s; + int skip_lv = 0; struct grub_lvm_lv *lv; struct grub_lvm_segment *seg; @@ -438,6 +485,12 @@ lv->size = 0; + if (!grub_lvm_check_flag (p, "status", "VISIBLE")) + { + skip_lv = 1; + goto lv_parsed; + } + lv->segment_count = grub_lvm_getvalue (&p, "segment_count = "); if (p == NULL) goto lvs_fail; @@ -458,6 +511,14 @@ seg->extent_count = grub_lvm_getvalue (&p, "extent_count = "); if (p == NULL) goto lvs_segment_fail; + + if (grub_lvm_checkvalue (&p, "type = ", "snapshot")) + { + /* Found a snapshot, give up and move on. */ + skip_lv = 1; + break; + } + seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = "); if (p == NULL) goto lvs_segment_fail; @@ -524,12 +585,20 @@ goto fail4; } + lv_parsed: if (p != NULL) p = grub_strchr (p, '}'); if (p == NULL) goto lvs_fail; p += 3; + if (skip_lv) + { + grub_free (lv->name); + grub_free (lv); + continue; + } + lv->number = lv_count++; lv->vg = vg; lv->next = vg->lvs;