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