diff options
Diffstat (limited to 'scripts/lib/wic/utils/partitionedfs.py')
| -rw-r--r-- | scripts/lib/wic/utils/partitionedfs.py | 158 |
1 files changed, 70 insertions, 88 deletions
diff --git a/scripts/lib/wic/utils/partitionedfs.py b/scripts/lib/wic/utils/partitionedfs.py index b7ab1d528e..fb5c0c2f0a 100644 --- a/scripts/lib/wic/utils/partitionedfs.py +++ b/scripts/lib/wic/utils/partitionedfs.py | |||
| @@ -71,47 +71,29 @@ class Image(): | |||
| 71 | 'ptable_format': "msdos", # Partition table format | 71 | 'ptable_format': "msdos", # Partition table format |
| 72 | 'identifier': None} # Disk system identifier | 72 | 'identifier': None} # Disk system identifier |
| 73 | 73 | ||
| 74 | def add_disk(self, disk_name, disk_obj, identifier): | 74 | def add_disk(self, name, disk_obj, identifier): |
| 75 | """ Add a disk object which have to be partitioned. More than one disk | 75 | """ Add a disk object which have to be partitioned. More than one disk |
| 76 | can be added. In case of multiple disks, disk partitions have to be | 76 | can be added. In case of multiple disks, disk partitions have to be |
| 77 | added for each disk separately with 'add_partition()". """ | 77 | added for each disk separately with 'add_partition()". """ |
| 78 | 78 | ||
| 79 | self._add_disk(disk_name) | 79 | self._add_disk(name) |
| 80 | self.disks[disk_name]['disk'] = disk_obj | 80 | self.disks[name]['disk'] = disk_obj |
| 81 | self.disks[disk_name]['identifier'] = identifier | 81 | self.disks[name]['identifier'] = identifier |
| 82 | 82 | ||
| 83 | def add_partition(self, size, disk_name, mountpoint, source_file=None, fstype=None, | 83 | def add_partition(self, part): |
| 84 | label=None, fsopts=None, boot=False, align=None, no_table=False, | 84 | """ |
| 85 | part_type=None, uuid=None, system_id=None): | 85 | Add the next partition. Partitions have to be added in the |
| 86 | """ Add the next partition. Partitions have to be added in the | 86 | first-to-last order. |
| 87 | first-to-last order. """ | 87 | """ |
| 88 | 88 | part.ks_pnum = len(self.partitions) | |
| 89 | ks_pnum = len(self.partitions) | ||
| 90 | 89 | ||
| 91 | # Converting kB to sectors for parted | 90 | # Converting kB to sectors for parted |
| 92 | size = size * 1024 // self.sector_size | 91 | part.size_sec = part.disk_size * 1024 // self.sector_size |
| 93 | |||
| 94 | part = {'ks_pnum': ks_pnum, # Partition number in the KS file | ||
| 95 | 'size': size, # In sectors | ||
| 96 | 'mountpoint': mountpoint, # Mount relative to chroot | ||
| 97 | 'source_file': source_file, # partition contents | ||
| 98 | 'fstype': fstype, # Filesystem type | ||
| 99 | 'fsopts': fsopts, # Filesystem mount options | ||
| 100 | 'label': label, # Partition label | ||
| 101 | 'disk_name': disk_name, # physical disk name holding partition | ||
| 102 | 'device': None, # kpartx device node for partition | ||
| 103 | 'num': None, # Partition number | ||
| 104 | 'boot': boot, # Bootable flag | ||
| 105 | 'align': align, # Partition alignment | ||
| 106 | 'no_table' : no_table, # Partition does not appear in partition table | ||
| 107 | 'part_type' : part_type, # Partition type | ||
| 108 | 'uuid': uuid, # Partition UUID | ||
| 109 | 'system_id': system_id} # Partition system id | ||
| 110 | 92 | ||
| 111 | assert not self._partitions_layed_out | 93 | assert not self._partitions_layed_out |
| 112 | 94 | ||
| 113 | self.partitions.append(part) | 95 | self.partitions.append(part) |
| 114 | self._add_disk(part['disk_name']) | 96 | self._add_disk(part.disk) |
| 115 | 97 | ||
| 116 | def layout_partitions(self, ptable_format="msdos"): | 98 | def layout_partitions(self, ptable_format="msdos"): |
| 117 | """ Layout the partitions, meaning calculate the position of every | 99 | """ Layout the partitions, meaning calculate the position of every |
| @@ -129,11 +111,11 @@ class Image(): | |||
| 129 | for num in range(len(self.partitions)): | 111 | for num in range(len(self.partitions)): |
| 130 | part = self.partitions[num] | 112 | part = self.partitions[num] |
| 131 | 113 | ||
| 132 | if part['disk_name'] not in self.disks: | 114 | if part.disk not in self.disks: |
| 133 | raise ImageError("No disk %s for partition %s" \ | 115 | raise ImageError("No disk %s for partition %s" \ |
| 134 | % (part['disk_name'], part['mountpoint'])) | 116 | % (part.disk, part.mountpoint)) |
| 135 | 117 | ||
| 136 | if ptable_format == 'msdos' and part['part_type']: | 118 | if ptable_format == 'msdos' and part.part_type: |
| 137 | # The --part-type can also be implemented for MBR partitions, | 119 | # The --part-type can also be implemented for MBR partitions, |
| 138 | # in which case it would map to the 1-byte "partition type" | 120 | # in which case it would map to the 1-byte "partition type" |
| 139 | # filed at offset 3 of the partition entry. | 121 | # filed at offset 3 of the partition entry. |
| @@ -141,9 +123,9 @@ class Image(): | |||
| 141 | "implemented for msdos partitions") | 123 | "implemented for msdos partitions") |
| 142 | 124 | ||
| 143 | # Get the disk where the partition is located | 125 | # Get the disk where the partition is located |
| 144 | disk = self.disks[part['disk_name']] | 126 | disk = self.disks[part.disk] |
| 145 | disk['numpart'] += 1 | 127 | disk['numpart'] += 1 |
| 146 | if not part['no_table']: | 128 | if not part.no_table: |
| 147 | disk['realpart'] += 1 | 129 | disk['realpart'] += 1 |
| 148 | disk['ptable_format'] = ptable_format | 130 | disk['ptable_format'] = ptable_format |
| 149 | 131 | ||
| @@ -163,50 +145,50 @@ class Image(): | |||
| 163 | disk['offset'] += 1 | 145 | disk['offset'] += 1 |
| 164 | 146 | ||
| 165 | 147 | ||
| 166 | if part['align']: | 148 | if part.align: |
| 167 | # If not first partition and we do have alignment set we need | 149 | # If not first partition and we do have alignment set we need |
| 168 | # to align the partition. | 150 | # to align the partition. |
| 169 | # FIXME: This leaves a empty spaces to the disk. To fill the | 151 | # FIXME: This leaves a empty spaces to the disk. To fill the |
| 170 | # gaps we could enlargea the previous partition? | 152 | # gaps we could enlargea the previous partition? |
| 171 | 153 | ||
| 172 | # Calc how much the alignment is off. | 154 | # Calc how much the alignment is off. |
| 173 | align_sectors = disk['offset'] % (part['align'] * 1024 // self.sector_size) | 155 | align_sectors = disk['offset'] % (part.align * 1024 // self.sector_size) |
| 174 | 156 | ||
| 175 | if align_sectors: | 157 | if align_sectors: |
| 176 | # If partition is not aligned as required, we need | 158 | # If partition is not aligned as required, we need |
| 177 | # to move forward to the next alignment point | 159 | # to move forward to the next alignment point |
| 178 | align_sectors = (part['align'] * 1024 // self.sector_size) - align_sectors | 160 | align_sectors = (part.align * 1024 // self.sector_size) - align_sectors |
| 179 | 161 | ||
| 180 | msger.debug("Realignment for %s%s with %s sectors, original" | 162 | msger.debug("Realignment for %s%s with %s sectors, original" |
| 181 | " offset %s, target alignment is %sK." % | 163 | " offset %s, target alignment is %sK." % |
| 182 | (part['disk_name'], disk['numpart'], align_sectors, | 164 | (part.disk, disk['numpart'], align_sectors, |
| 183 | disk['offset'], part['align'])) | 165 | disk['offset'], part.align)) |
| 184 | 166 | ||
| 185 | # increase the offset so we actually start the partition on right alignment | 167 | # increase the offset so we actually start the partition on right alignment |
| 186 | disk['offset'] += align_sectors | 168 | disk['offset'] += align_sectors |
| 187 | 169 | ||
| 188 | part['start'] = disk['offset'] | 170 | part.start = disk['offset'] |
| 189 | disk['offset'] += part['size'] | 171 | disk['offset'] += part.size_sec |
| 190 | 172 | ||
| 191 | part['type'] = 'primary' | 173 | part.type = 'primary' |
| 192 | if not part['no_table']: | 174 | if not part.no_table: |
| 193 | part['num'] = disk['realpart'] | 175 | part.num = disk['realpart'] |
| 194 | else: | 176 | else: |
| 195 | part['num'] = 0 | 177 | part.num = 0 |
| 196 | 178 | ||
| 197 | if disk['ptable_format'] == "msdos": | 179 | if disk['ptable_format'] == "msdos": |
| 198 | # only count the partitions that are in partition table | 180 | # only count the partitions that are in partition table |
| 199 | if len([p for p in self.partitions if not p['no_table']]) > 4: | 181 | if len([p for p in self.partitions if not p.no_table]) > 4: |
| 200 | if disk['realpart'] > 3: | 182 | if disk['realpart'] > 3: |
| 201 | part['type'] = 'logical' | 183 | part.type = 'logical' |
| 202 | part['num'] = disk['realpart'] + 1 | 184 | part.num = disk['realpart'] + 1 |
| 203 | 185 | ||
| 204 | disk['partitions'].append(num) | 186 | disk['partitions'].append(num) |
| 205 | msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d " | 187 | msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d " |
| 206 | "sectors (%d bytes)." \ | 188 | "sectors (%d bytes)." \ |
| 207 | % (part['mountpoint'], part['disk_name'], part['num'], | 189 | % (part.mountpoint, part.disk, part.num, |
| 208 | part['start'], disk['offset'] - 1, | 190 | part.start, disk['offset'] - 1, |
| 209 | part['size'], part['size'] * self.sector_size)) | 191 | part.size_sec, part.size_sec * self.sector_size)) |
| 210 | 192 | ||
| 211 | # Once all the partitions have been layed out, we can calculate the | 193 | # Once all the partitions have been layed out, we can calculate the |
| 212 | # minumim disk sizes. | 194 | # minumim disk sizes. |
| @@ -256,11 +238,11 @@ class Image(): | |||
| 256 | msger.debug("Creating partitions") | 238 | msger.debug("Creating partitions") |
| 257 | 239 | ||
| 258 | for part in self.partitions: | 240 | for part in self.partitions: |
| 259 | if part['num'] == 0: | 241 | if part.num == 0: |
| 260 | continue | 242 | continue |
| 261 | 243 | ||
| 262 | disk = self.disks[part['disk_name']] | 244 | disk = self.disks[part.disk] |
| 263 | if disk['ptable_format'] == "msdos" and part['num'] == 5: | 245 | if disk['ptable_format'] == "msdos" and part.num == 5: |
| 264 | # Create an extended partition (note: extended | 246 | # Create an extended partition (note: extended |
| 265 | # partition is described in MBR and contains all | 247 | # partition is described in MBR and contains all |
| 266 | # logical partitions). The logical partitions save a | 248 | # logical partitions). The logical partitions save a |
| @@ -273,16 +255,16 @@ class Image(): | |||
| 273 | # add a sector at the back, so that there is enough | 255 | # add a sector at the back, so that there is enough |
| 274 | # room for all logical partitions. | 256 | # room for all logical partitions. |
| 275 | self._create_partition(disk['disk'].device, "extended", | 257 | self._create_partition(disk['disk'].device, "extended", |
| 276 | None, part['start'] - 1, | 258 | None, part.start - 1, |
| 277 | disk['offset'] - part['start'] + 1) | 259 | disk['offset'] - part.start + 1) |
| 278 | 260 | ||
| 279 | if part['fstype'] == "swap": | 261 | if part.fstype == "swap": |
| 280 | parted_fs_type = "linux-swap" | 262 | parted_fs_type = "linux-swap" |
| 281 | elif part['fstype'] == "vfat": | 263 | elif part.fstype == "vfat": |
| 282 | parted_fs_type = "fat32" | 264 | parted_fs_type = "fat32" |
| 283 | elif part['fstype'] == "msdos": | 265 | elif part.fstype == "msdos": |
| 284 | parted_fs_type = "fat16" | 266 | parted_fs_type = "fat16" |
| 285 | elif part['fstype'] == "ontrackdm6aux3": | 267 | elif part.fstype == "ontrackdm6aux3": |
| 286 | parted_fs_type = "ontrackdm6aux3" | 268 | parted_fs_type = "ontrackdm6aux3" |
| 287 | else: | 269 | else: |
| 288 | # Type for ext2/ext3/ext4/btrfs | 270 | # Type for ext2/ext3/ext4/btrfs |
| @@ -290,47 +272,47 @@ class Image(): | |||
| 290 | 272 | ||
| 291 | # Boot ROM of OMAP boards require vfat boot partition to have an | 273 | # Boot ROM of OMAP boards require vfat boot partition to have an |
| 292 | # even number of sectors. | 274 | # even number of sectors. |
| 293 | if part['mountpoint'] == "/boot" and part['fstype'] in ["vfat", "msdos"] \ | 275 | if part.mountpoint == "/boot" and part.fstype in ["vfat", "msdos"] \ |
| 294 | and part['size'] % 2: | 276 | and part.size_sec % 2: |
| 295 | msger.debug("Subtracting one sector from '%s' partition to " \ | 277 | msger.debug("Subtracting one sector from '%s' partition to " \ |
| 296 | "get even number of sectors for the partition" % \ | 278 | "get even number of sectors for the partition" % \ |
| 297 | part['mountpoint']) | 279 | part.mountpoint) |
| 298 | part['size'] -= 1 | 280 | part.size_sec -= 1 |
| 299 | 281 | ||
| 300 | self._create_partition(disk['disk'].device, part['type'], | 282 | self._create_partition(disk['disk'].device, part.type, |
| 301 | parted_fs_type, part['start'], part['size']) | 283 | parted_fs_type, part.start, part.size_sec) |
| 302 | 284 | ||
| 303 | if part['part_type']: | 285 | if part.part_type: |
| 304 | msger.debug("partition %d: set type UID to %s" % \ | 286 | msger.debug("partition %d: set type UID to %s" % \ |
| 305 | (part['num'], part['part_type'])) | 287 | (part.num, part.part_type)) |
| 306 | exec_native_cmd("sgdisk --typecode=%d:%s %s" % \ | 288 | exec_native_cmd("sgdisk --typecode=%d:%s %s" % \ |
| 307 | (part['num'], part['part_type'], | 289 | (part.num, part.part_type, |
| 308 | disk['disk'].device), self.native_sysroot) | 290 | disk['disk'].device), self.native_sysroot) |
| 309 | 291 | ||
| 310 | if part['uuid'] and disk['ptable_format'] == "gpt": | 292 | if part.uuid and disk['ptable_format'] == "gpt": |
| 311 | msger.debug("partition %d: set UUID to %s" % \ | 293 | msger.debug("partition %d: set UUID to %s" % \ |
| 312 | (part['num'], part['uuid'])) | 294 | (part.num, part.uuid)) |
| 313 | exec_native_cmd("sgdisk --partition-guid=%d:%s %s" % \ | 295 | exec_native_cmd("sgdisk --partition-guid=%d:%s %s" % \ |
| 314 | (part['num'], part['uuid'], disk['disk'].device), | 296 | (part.num, part.uuid, disk['disk'].device), |
| 315 | self.native_sysroot) | 297 | self.native_sysroot) |
| 316 | 298 | ||
| 317 | if part['label'] and disk['ptable_format'] == "gpt": | 299 | if part.label and disk['ptable_format'] == "gpt": |
| 318 | msger.debug("partition %d: set name to %s" % \ | 300 | msger.debug("partition %d: set name to %s" % \ |
| 319 | (part['num'], part['label'])) | 301 | (part.num, part.label)) |
| 320 | exec_native_cmd("parted -s %s name %d %s" % \ | 302 | exec_native_cmd("parted -s %s name %d %s" % \ |
| 321 | (disk['disk'].device, part['num'], part['label']), | 303 | (disk['disk'].device, part.num, part.label), |
| 322 | self.native_sysroot) | 304 | self.native_sysroot) |
| 323 | 305 | ||
| 324 | if part['boot']: | 306 | if part.active: |
| 325 | flag_name = "legacy_boot" if disk['ptable_format'] == 'gpt' else "boot" | 307 | flag_name = "legacy_boot" if disk['ptable_format'] == 'gpt' else "boot" |
| 326 | msger.debug("Set '%s' flag for partition '%s' on disk '%s'" % \ | 308 | msger.debug("Set '%s' flag for partition '%s' on disk '%s'" % \ |
| 327 | (flag_name, part['num'], disk['disk'].device)) | 309 | (flag_name, part.num, disk['disk'].device)) |
| 328 | exec_native_cmd("parted -s %s set %d %s on" % \ | 310 | exec_native_cmd("parted -s %s set %d %s on" % \ |
| 329 | (disk['disk'].device, part['num'], flag_name), | 311 | (disk['disk'].device, part.num, flag_name), |
| 330 | self.native_sysroot) | 312 | self.native_sysroot) |
| 331 | if part['system_id']: | 313 | if part.system_id: |
| 332 | exec_native_cmd("sfdisk --part-type %s %s %s" % \ | 314 | exec_native_cmd("sfdisk --part-type %s %s %s" % \ |
| 333 | (disk['disk'].device, part['num'], part['system_id']), | 315 | (disk['disk'].device, part.num, part.system_id), |
| 334 | self.native_sysroot) | 316 | self.native_sysroot) |
| 335 | 317 | ||
| 336 | # Parted defaults to enabling the lba flag for fat16 partitions, | 318 | # Parted defaults to enabling the lba flag for fat16 partitions, |
| @@ -339,9 +321,9 @@ class Image(): | |||
| 339 | if parted_fs_type == "fat16": | 321 | if parted_fs_type == "fat16": |
| 340 | if disk['ptable_format'] == 'msdos': | 322 | if disk['ptable_format'] == 'msdos': |
| 341 | msger.debug("Disable 'lba' flag for partition '%s' on disk '%s'" % \ | 323 | msger.debug("Disable 'lba' flag for partition '%s' on disk '%s'" % \ |
| 342 | (part['num'], disk['disk'].device)) | 324 | (part.num, disk['disk'].device)) |
| 343 | exec_native_cmd("parted -s %s set %d lba off" % \ | 325 | exec_native_cmd("parted -s %s set %d lba off" % \ |
| 344 | (disk['disk'].device, part['num']), | 326 | (disk['disk'].device, part.num), |
| 345 | self.native_sysroot) | 327 | self.native_sysroot) |
| 346 | 328 | ||
| 347 | def cleanup(self): | 329 | def cleanup(self): |
| @@ -360,16 +342,16 @@ class Image(): | |||
| 360 | msger.debug("Installing partitions") | 342 | msger.debug("Installing partitions") |
| 361 | 343 | ||
| 362 | for part in self.partitions: | 344 | for part in self.partitions: |
| 363 | source = part['source_file'] | 345 | source = part.source_file |
| 364 | if source: | 346 | if source: |
| 365 | # install source_file contents into a partition | 347 | # install source_file contents into a partition |
| 366 | sparse_copy(source, image_file, part['start'] * self.sector_size) | 348 | sparse_copy(source, image_file, part.start * self.sector_size) |
| 367 | 349 | ||
| 368 | msger.debug("Installed %s in partition %d, sectors %d-%d, " | 350 | msger.debug("Installed %s in partition %d, sectors %d-%d, " |
| 369 | "size %d sectors" % \ | 351 | "size %d sectors" % \ |
| 370 | (source, part['num'], part['start'], | 352 | (source, part.num, part.start, |
| 371 | part['start'] + part['size'] - 1, part['size'])) | 353 | part.start + part.size_sec - 1, part.size_sec)) |
| 372 | 354 | ||
| 373 | partimage = image_file + '.p%d' % part['num'] | 355 | partimage = image_file + '.p%d' % part.num |
| 374 | os.rename(source, partimage) | 356 | os.rename(source, partimage) |
| 375 | self.partimages.append(partimage) | 357 | self.partimages.append(partimage) |
