protocol: Memory leak: Free temporary buffer along recv_discard path.
[libguestfs.git] / daemon / parted.c
index d52ad2c..0d22948 100644 (file)
@@ -13,7 +13,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #include <config.h>
@@ -184,15 +184,16 @@ do_part_disk (const char *device, const char *parttype)
     return -1;
   }
 
-  /* 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:
+  /* Align all partitions created this way to 128 sectors, and leave
+   * the last 128 sectors at the end of the disk free.  This wastes
+   * 64K+64K = 128K on 512-byte sector disks.  The rationale is:
    *
    * - aligned operations are faster
+   * - absolute minimum recommended alignment is 64K (1M would be better)
    * - GPT requires at least 34 sectors at the end of the disk.
    */
-  const char *startstr = "64s";
-  const char *endstr = "-64s";
+  const char *startstr = "128s";
+  const char *endstr = "-128s";
 
   RUN_PARTED (return -1,
               device,
@@ -573,15 +574,41 @@ do_part_get_bootable (const char *device, int partnum)
     /* New-style parsing using the "machine-readable" format from
      * 'parted -m'.
      *
-     * We want lines[1+partnum].
+     * Partitions may not be in any order, so we have to look for
+     * the matching partition number (RHBZ#602997).
      */
-    if (count_strings (lines) < (size_t) 1+partnum) {
-      reply_with_error ("partition number out of range: %d", partnum);
+    if (lines[0] == NULL || STRNEQ (lines[0], "BYT;")) {
+      reply_with_error ("unknown signature, expected \"BYT;\" as first line of the output: %s",
+                        lines[0] ? lines[0] : "(signature was null)");
+      free_strings (lines);
+      return -1;
+    }
+
+    if (lines[1] == NULL) {
+      reply_with_error ("parted didn't return a line describing the device");
+      free_strings (lines);
+      return -1;
+    }
+
+    size_t row;
+    int pnum;
+    for (row = 2; lines[row] != NULL; ++row) {
+      if (sscanf (lines[row], "%d:", &pnum) != 1) {
+        reply_with_error ("could not parse row from output of parted print command: %s", lines[row]);
+        free_strings (lines);
+        return -1;
+      }
+      if (pnum == partnum)
+        break;
+    }
+
+    if (lines[row] == NULL) {
+      reply_with_error ("partition number %d not found", partnum);
       free_strings (lines);
       return -1;
     }
 
-    char *boot = get_table_field (lines[1+partnum], 6);
+    char *boot = get_table_field (lines[row], 6);
     if (boot == NULL) {
       free_strings (lines);
       return -1;