partitionedfs: add disks while adding partitions
authorArtem Bityutskiy <artem.bityutskiy@intel.com>
Fri, 4 Jan 2013 09:02:16 +0000 (11:02 +0200)
committerArtem Bityutskiy <artem.bityutskiy@intel.com>
Thu, 10 Jan 2013 12:11:20 +0000 (14:11 +0200)
The PartitionedMount class used to work as follows:

1. The user adds all partitions using 'add_partition()'. We create an internal
   list of partitions.
2. User adds all disks using 'add_disks()'. We create an internal list of
   disks. Additionally, 'add_disks()' provides the real disk object.

The problem with this is that in order to create the real disk object, we need
to know its size. But it is difficult to calculate it when complex options like
--align are used.

The real calculations happen in the '__format_disks()' method of
PartitionedMount.

What I want to do is to make things work this way:

1. The user adds all the partitions.
2. The user asks what disk size is required.
3. The user creates disk objects of the right size and adds them.

In order to achieve it, I need to separate out the partitions positioning from
the '_format_disks()' function, and do this before the user adds the disks.

However, the positioning code assumes we already have the internal disks
dictionaries (self.disks). But current code creates those dictionaries only in
'add_disks()', which is too late for our purposes.

This patch basically makes the inderal disks dictionaries while adding the
partitions, because the partition already contains the disk name (internal
target physical name). So we can create the disk dictionaries right away.

The only missing thing will be the host disk objects, which are added by
'add_disks()' later on.

Change-Id: Ie8245c8b61c941165aea3a583826a2896f4c85d9
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@intel.com>
mic/utils/partitionedfs.py

index c725ecd..a8545eb 100644 (file)
@@ -51,20 +51,38 @@ class PartitionedMount(Mount):
         # Size of a sector used in calculations
         self.sector_size = SECTOR_SIZE
 
+    def __add_disk(self, disk_name):
+        """ Add a disk 'disk_name' to the internal list of disks. Note,
+        'disk_name' is the name of the disk in the target system
+        (e.g., sdb). """
+
+        if disk_name in self.disks:
+            # We already have this disk
+            return
+
+        self.disks[disk_name] = \
+                { 'disk': None,     # Disk object
+                  '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 to the extended partition.
+                  'extended': 0,    # Size of extended partition
+                  'offset': 0 }     # Offset of next partition (in sectors)
+
     def add_disks(self, disks):
         """ Add the disks which have to be partitioned. """
 
         for name in disks.keys():
-            self.disks[name] = { 'disk': disks[name],  # Disk object
-                                 '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 of next partition (in sectors)
-                                 'offset': 0 }
+            self.__add_disk(name)
+            self.disks[name]['disk'] = disks[name]
 
+    def __add_partition(self, part):
+        """ This is a helper function for 'add_partition()' which adds a
+        partition to the internal list of partitions. """
+
+        self.partitions.append(part)
+        self.__add_disk(part['disk'])
 
     def add_partition(self, size, disk, mountpoint, fstype = None, label=None, fsopts = None, boot = False, align = None):
         # Converting MB to sectors for parted
@@ -103,17 +121,20 @@ class PartitionedMount(Mount):
                         opts.remove(opt)
                         break
                 fsopts = ",".join(opts)
-            self.partitions.append({'size': size, # In sectors
-                                    'mountpoint': mountpoint, # Mount relative to chroot
-                                    'fstype': fstype, # Filesystem type
-                                    'fsopts': fsopts, # Filesystem mount options
-                                    'label': label, # Partition label
-                                    '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
-                                    'align': align}) # Partition alignment
+
+            part = { 'size': size, # In sectors
+                     'mountpoint': mountpoint, # Mount relative to chroot
+                     'fstype': fstype, # Filesystem type
+                     'fsopts': fsopts, # Filesystem mount options
+                     'label': label, # Partition label
+                     '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
+                     'align': align } # Partition alignment
+
+            self.__add_partition(part)
 
     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.