commit 8f72881a6476cfeb855abf158b7774e555621b71
Author: Marko Saukko <[email protected]>
Date:   Fri Dec 10 10:49:12 2010 +0200

    - Fix for vfat even sector thing with omap boot rom.
    - Add more debugging to parted commands.

diff --git a/mic/appcreate/partitionedfs.py b/mic/appcreate/partitionedfs.py
index bca3801..9754c46 100644
--- a/mic/appcreate/partitionedfs.py
+++ b/mic/appcreate/partitionedfs.py
@@ -28,7 +28,6 @@ import logging
 from mic.imgcreate.errors import *
 from mic.imgcreate.fs import *
 
-
 class PartitionedMount(Mount):
     def __init__(self, disks, mountdir, skipformat = False):
         Mount.__init__(self, mountdir)
@@ -38,8 +37,12 @@ class PartitionedMount(Mount):
                                  'mapped': False, # True if kpartx mapping 
exists
                                  'numpart': 0, # Number of allocate partitions
                                  'partitions': [], # indexes to self.partitions
+                                 # Partitions with part num higher than 3 will 
+                                 # be put inside extended partition.
                                  'extended': 0, # Size of extended partition
-                                 'offset': 0 } # Offset of next partition
+                                 # Sector 0 is used by the MBR and can't be 
used
+                                 # as the start, so setting offset to 1.
+                                 'offset': 1 } # Offset of next partition (in 
sectors)
 
         self.partitions = []
         self.mapped = False
@@ -49,26 +52,51 @@ class PartitionedMount(Mount):
         self.kpartx=find_binary_path("kpartx")
         self.mkswap=find_binary_path("mkswap")
         self.skipformat = skipformat
+        # Size of a sector used in calculations
+        self.sector_size = 512
 
     def add_partition(self, size, disk, mountpoint, fstype = None, boot = 
False):
-        self.partitions.append({'size': size,
+        # Converting M to s for parted
+        size = size * 1024 * 1024 / self.sector_size
+        self.partitions.append({'size': size, # In sectors
                                 'mountpoint': mountpoint, # Mount relative to 
chroot
-                                'fstype': fstype,
-                                'disk': disk,  # physical disk name holding 
partition
+                                'fstype': fstype, # Filesystem type
+                                'disk': disk, # physical disk name holding 
partition
                                 'device': None, # kpartx device node for 
partition
                                 'mount': None, # Mount object
                                 'num': None, # Partition number
                                 'boot': boot}) # Bootable flag
 
-    def __format_disks(self):
-        dev_null = os.open("/dev/null", os.O_WRONLY)
+    def __create_part_to_image(self,device, parttype, fstype, start, size):
+        # Start is included to the size so we need to substract one from the 
end.
+        end = start+size-1
+        logging.debug("Added '%s' part at %d of size %d" % 
(parttype,start,end))
+        part_cmd = [self.parted, "-s", device, "unit", "s", "mkpart", parttype]
+        if fstype:
+            part_cmd.extend([fstype])
+        part_cmd.extend(["%d" % start, "%d" % end])
+        logging.debug(part_cmd)
+        p1 = subprocess.Popen(part_cmd, stdout=subprocess.PIPE, 
stderr=subprocess.STDOUT)
+        (out,err) = p1.communicate()
+        logging.debug(out)
+        return p1
 
+    def __format_disks(self):
         logging.debug("Assigning partitions to disks")
+        
+        mbr_sector_skipped = False
+        
         for n in range(len(self.partitions)):
             p = self.partitions[n]
 
             if not self.disks.has_key(p['disk']):
                 raise MountError("No disk %s for partition %s" % (p['disk'], 
p['mountpoint']))
+            
+            if not mbr_sector_skipped:
+                # This hack is used to remove one sector from the first 
partition,
+                # that is the used to the MBR.
+                p['size'] -= 1
+                mbr_sector_skipped = True
 
             d = self.disks[p['disk']]
             d['numpart'] += 1
@@ -87,34 +115,30 @@ class PartitionedMount(Mount):
             logging.debug("Assigned %s to %s%d at %d at size %d" % 
(p['mountpoint'], p['disk'], p['num'], p['start'], p['size']))
 
         if self.skipformat:
-            logging.debug("Skip disks format")
+            logging.debug("Skipping disk format, because skipformat flag is 
set.")
             return
-        logging.debug("Formatting disks")
+            
         for dev in self.disks.keys():
             d = self.disks[dev]
             logging.debug("Initializing partition table for %s" % 
(d['disk'].device))
-            # FIXME
-            rc = subprocess.call([self.parted, "-s", d['disk'].device, 
"mklabel", "msdos"],
-                                 stdout = dev_null, stderr = dev_null)
-
-            # XXX disabled return code check because parted always fails to
-            # reload part table with loop devices. Annoying because we can't
-            # distinguish this failure from real partition failures :-(
-            if rc != 0 and 1 == 0:
-                os.close(dev_null)
-                raise MountError("Error writing partition table on %s" % 
d['disk'].device)
+            p1 = subprocess.Popen([self.parted, "-s", d['disk'].device, 
"mklabel", "msdos"],
+                                 stdout=subprocess.PIPE, 
stderr=subprocess.STDOUT)
+            (out,err) = p1.communicate()            
+            logging.debug(out)
+            
+            if p1.returncode != 0:
+                # NOTE: We don't throw exception when return code is not 0, 
because
+                # parted always fails to reload part table with loop devices.
+                # This prevents us from distinguishing real errors based on 
return code.
+                logging.debug("WARNING: parted returned '%s' instead of 0 when 
creating partition-table for disk '%s'." % (p1.returncode,d['disk'].device))
 
-        # XXX we should probably work in cylinder units to keep fdisk happier..
-        start = 0
         logging.debug("Creating partitions")
+
         for p in self.partitions:
             d = self.disks[p['disk']]
             if p['num'] == 5:
-                logging.debug("Added extended part at %d of size %d" % 
(p['start'], d['extended']))
-                rc = subprocess.call([self.parted, "-s", d['disk'].device, 
"mkpart", "extended",
-                                     "%dM" % p['start'], "%dM" % (p['start'] + 
d['extended'])],
-                                     stdout = dev_null, stderr = dev_null)
-
+                
self.__create_part_to_image(d['disk'].device,"extended",None,p['start'],d['extended'])
+                
             if p['fstype'] == "swap":
                 parted_fs_type = "linux-swap"
             elif p['fstype'] == "vfat":
@@ -125,21 +149,36 @@ class PartitionedMount(Mount):
                 # Type for ext2/ext3/ext4/btrfs
                 parted_fs_type = "ext2"
 
-            logging.debug("Add %s part at %d of size %d" % (p['type'], 
p['start'], p['size']))
-            rc = subprocess.call([self.parted, "-s", d['disk'].device, 
"mkpart",
-                                 p['type'], parted_fs_type, "%dM" % 
p['start'], "%dM" % (p['start']+p['size'])],
-                                 stdout = dev_null, stderr = dev_null)
+            # Boot ROM of OMAP boards require vfat boot partition to have an 
+            # even number of sectors.
+            if p['mountpoint'] == "/boot" and p['fstype'] in ["vfat","msdos"] 
and p['size'] % 2:
+                logging.debug("Substracting one sector from '%s' partition to 
get even number of sectors for the partition." % (p['mountpoint']))
+                p['size'] -= 1
+                
+            p1 = self.__create_part_to_image(d['disk'].device,p['type'], 
+                                             parted_fs_type, p['start'], 
+                                             p['size'])
+
+            if p1.returncode != 0:
+                # NOTE: We don't throw exception when return code is not 0, 
because
+                # parted always fails to reload part table with loop devices.
+                # This prevents us from distinguishing real errors based on 
return code.
+                logging.debug("WARNING: parted returned '%s' instead of 0 when 
creating partition '%s' for disk '%s'." % 
(p1.returncode,p['mountpoint'],d['disk'].device))
 
             if p['boot']:
-                rc = subprocess.call([self.parted, "-s", d['disk'].device, 
"set", "%d" % p['num'], "boot", "on"],
-                                     stdout = dev_null, stderr = dev_null)
-            # XXX disabled return code check because parted always fails to
-            # reload part table with loop devices. Annoying because we can't
-            # distinguish this failure from real partition failures :-(
-            if rc != 0 and 1 == 0:
-                os.close(dev_null)
-                raise MountError("Error creating partition on %s" % 
d['disk'].device)
-        os.close(dev_null)
+                logging.debug("Setting boot flag for partition '%s' on disk 
'%s'." % (p['num'],d['disk'].device))
+                boot_cmd = [self.parted, "-s", d['disk'].device, "set", "%d" % 
p['num'], "boot", "on"]
+                logging.debug(boot_cmd)
+                p1 = subprocess.Popen(boot_cmd,
+                                      stdout=subprocess.PIPE, 
stderr=subprocess.STDOUT)
+                (out,err) = p1.communicate()            
+                logging.debug(out)
+
+                if p1.returncode != 0:
+                    # NOTE: We don't throw exception when return code is not 
0, because
+                    # parted always fails to reload part table with loop 
devices.
+                    # This prevents us from distinguishing real errors based 
on return code.
+                    logging.debug("WARNING: parted returned '%s' instead of 0 
when adding boot flag for partition '%s' disk '%s'." % 
(p1.returncode,p['num'],d['disk'].device))
 
     def __map_partitions(self):
         """Load it if dm_snapshot isn't loaded"""
@@ -308,7 +347,7 @@ class PartitionedMount(Mount):
             else:
                 raise MountError("Fail to support file system " + p['fstype'])
 
-            pdisk = myDiskMount(RawDisk(p['size'] * 1024 * 1024, p['device']),
+            pdisk = myDiskMount(RawDisk(p['size'] * self.sector_size, 
p['device']),
                                  self.mountdir + p['mountpoint'],
                                  p['fstype'],
                                  4096,
_______________________________________________
MeeGo-distribution-tools mailing list
[email protected]
http://lists.meego.com/listinfo/meego-distribution-tools

Reply via email to