parted: Don't return "loop" for non-partitioned devices (RHBZ#634246).
[libguestfs.git] / daemon / parted.c
index fe68d1d..068384e 100644 (file)
@@ -161,6 +161,11 @@ do_part_add (const char *device, const char *prlogex,
 int
 do_part_del (const char *device, int partnum)
 {
+  if (partnum <= 0) {
+    reply_with_error ("partition number must be >= 1");
+    return -1;
+  }
+
   char partnum_str[16];
   snprintf (partnum_str, sizeof partnum_str, "%d", partnum);
 
@@ -173,27 +178,21 @@ do_part_del (const char *device, int partnum)
 int
 do_part_disk (const char *device, const char *parttype)
 {
-  const char *startstr;
-  const char *endstr;
-
   parttype = check_parttype (parttype);
   if (!parttype) {
     reply_with_error ("unknown partition type: common choices are \"gpt\" and \"msdos\"");
     return -1;
   }
 
-  /* Voooooodooooooooo (thanks Jim Meyering for working this out). */
-  if (STREQ (parttype, "msdos")) {
-    startstr = "1s";
-    endstr = "-1s";
-  } else if (STREQ (parttype, "gpt")) {
-    startstr = "34s";
-    endstr = "-34s";
-  } else {
-    /* untested */
-    startstr = "1s";
-    endstr = "-1s";
-  }
+  /* Align all partitions created this way to 64 sectors, and leave
+   * the last 64 sectors at the end of the disk free.  This wastes
+   * 32K+32K = 64K on 512-byte sector disks.  The rationale is:
+   *
+   * - aligned operations are faster
+   * - GPT requires at least 34 sectors at the end of the disk.
+   */
+  const char *startstr = "64s";
+  const char *endstr = "-64s";
 
   RUN_PARTED (return -1,
               device,
@@ -210,6 +209,11 @@ do_part_disk (const char *device, const char *parttype)
 int
 do_part_set_bootable (const char *device, int partnum, int bootable)
 {
+  if (partnum <= 0) {
+    reply_with_error ("partition number must be >= 1");
+    return -1;
+  }
+
   char partstr[16];
 
   snprintf (partstr, sizeof partstr, "%d", partnum);
@@ -225,6 +229,11 @@ do_part_set_bootable (const char *device, int partnum, int bootable)
 int
 do_part_set_name (const char *device, int partnum, const char *name)
 {
+  if (partnum <= 0) {
+    reply_with_error ("partition number must be >= 1");
+    return -1;
+  }
+
   char partstr[16];
 
   snprintf (partstr, sizeof partstr, "%d", partnum);
@@ -369,6 +378,14 @@ do_part_get_parttype (const char *device)
     }
 
     free_strings (lines);
+
+    /* If "loop" return an error (RHBZ#634246). */
+    if (STREQ (r, "loop")) {
+      free (r);
+      reply_with_error ("not a partitioned device");
+      return NULL;
+    }
+
     return r;
   }
   else {
@@ -397,6 +414,13 @@ do_part_get_parttype (const char *device)
       return NULL;
     }
 
+    /* If "loop" return an error (RHBZ#634246). */
+    if (STREQ (p, "loop")) {
+      free (p);
+      reply_with_error ("not a partitioned device");
+      return NULL;
+    }
+
     return p;                   /* caller frees */
   }
 }
@@ -529,6 +553,11 @@ do_part_list (const char *device)
 int
 do_part_get_bootable (const char *device, int partnum)
 {
+  if (partnum <= 0) {
+    reply_with_error ("partition number must be >= 1");
+    return -1;
+  }
+
   int parted_has_m_opt = test_parted_m_opt ();
   if (parted_has_m_opt == -1)
     return -1;
@@ -622,6 +651,11 @@ do_part_get_bootable (const char *device, int partnum)
 int
 do_part_get_mbr_id (const char *device, int partnum)
 {
+  if (partnum <= 0) {
+    reply_with_error ("partition number must be >= 1");
+    return -1;
+  }
+
   char partnum_str[16];
   snprintf (partnum_str, sizeof partnum_str, "%d", partnum);
 
@@ -653,6 +687,11 @@ do_part_get_mbr_id (const char *device, int partnum)
 int
 do_part_set_mbr_id (const char *device, int partnum, int idbyte)
 {
+  if (partnum <= 0) {
+    reply_with_error ("partition number must be >= 1");
+    return -1;
+  }
+
   char partnum_str[16];
   snprintf (partnum_str, sizeof partnum_str, "%d", partnum);