]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* disk/lvm.c (grub_lvm_scan_device): Skip snapshots.
authorSean Finney <seanius@seanius.net>
Thu, 1 Jul 2010 21:19:11 +0000 (23:19 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 1 Jul 2010 21:19:11 +0000 (23:19 +0200)
2010-07-01  Vladimir Serbinenko  <phcoder@gmail.com>

* disk/lvm.c (grub_lvm_checkvalue): New function.
(grub_lvm_check_flag): Likewise.

Also-By: Vladimir Serbinenko <phcoder@gmail.com>
ChangeLog
disk/lvm.c

index f21d94425dfe28b6042a6c1477838b382040b34e..341e122f3f713900dd75c6ae53eadd9b948fdfdc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-07-01  Sean Finney  <seanius@seanius.net>
+
+       * disk/lvm.c (grub_lvm_scan_device): Skip snapshots.
+
+2010-07-01  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * disk/lvm.c (grub_lvm_checkvalue): New function.
+       (grub_lvm_check_flag): Likewise.
+
 2010-07-01  Robert Millan  <rmh@gnu.org>
 
        * kern/emu/hostdisk.c (convert_system_partition_to_system_disk):
index 7dde4092021ab1644fe0d5d4a5ae3eda7783bd65..71860e853f70c99ec19940740d011550dc920372 100644 (file)
@@ -45,6 +45,52 @@ grub_lvm_getvalue (char **p, char *str)
   return grub_strtoul (*p, NULL, 10);
 }
 
+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))
 {
@@ -421,6 +467,7 @@ grub_lvm_scan_device (const char *name)
          while (1)
            {
              int s;
+             int skip_lv = 0;
              struct grub_lvm_lv *lv;
              struct grub_lvm_segment *seg;
 
@@ -445,6 +492,12 @@ grub_lvm_scan_device (const char *name)
 
              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;
@@ -465,6 +518,14 @@ grub_lvm_scan_device (const char *name)
                  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;
@@ -531,12 +592,20 @@ grub_lvm_scan_device (const char *name)
                  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;