7041406 Disk class needs prop_matches() method
authorDrew Fisher <drew.fisher@oracle.com>
Thu, 12 May 2011 11:06:35 -0600
changeset 1122 d30415c63b07
parent 1121 670325895b19
child 1123 7f09b2655fe1
7041406 Disk class needs prop_matches() method 7044077 Copying shouldn't copy the validate_children flag and overlap shouldn't be checked on deleted slices 7044105 fix for 7042607 breaks slice discovery
usr/src/lib/install_target/discovery.py
usr/src/lib/install_target/physical.py
usr/src/lib/install_target/shadow/physical.py
--- a/usr/src/lib/install_target/discovery.py	Wed May 11 15:30:11 2011 -0700
+++ b/usr/src/lib/install_target/discovery.py	Thu May 12 11:06:35 2011 -0600
@@ -50,6 +50,7 @@
 
 
 EEPROM = "/usr/sbin/eeprom"
+FSTYP = "/usr/sbin/fstyp"
 PRTVTOC = "/usr/sbin/prtvtoc"
 ZFS = "/usr/sbin/zfs"
 ZPOOL = "/usr/sbin/zpool"
@@ -187,9 +188,29 @@
                     new_slice = self.discover_slice(slc,
                         drive_media_attributes.blocksize)
 
-                    # only insert the slice if the partition ID is a Solaris ID
+                    # constrain when a slice is added to the DOC.  We only want
+                    # to add a slice when:
+                    # - the partition id is a Solaris partition (non EFI)
+                    # - the fstyp is 'zfs' (for EFI labeled disks)
+                    # - the fstyp is 'unknown_fstyp' AND it's slice 8 (for EFI
+                    #   labeled disks)
                     if new_partition.is_solaris:
                         new_partition.insert_children(new_slice)
+                    elif new_partition.part_type == 238:
+                        # call fstyp to try to figure out the slice type
+                        cmd = [FSTYP, slc.name]
+                        p = Popen.check_call(cmd, stdout=Popen.STORE,
+                                             stderr=Popen.STORE, logger=ILN,
+                                             check_result=Popen.ANY)
+                        if p.returncode == 0:
+                            if p.stdout.strip() == "zfs":
+                                # add the slice since it's used by zfs
+                                new_partition.insert_children(new_slice)
+                        else:
+                            if p.stderr.startswith("unknown_fstyp") and \
+                                new_slice.name == "8":
+                                # add the slice since it's an EFI boot slice
+                                new_partition.insert_children(new_slice)
 
                     # keep a record this slice so it's not discovered again
                     visited_slices.append(slc.name)
--- a/usr/src/lib/install_target/physical.py	Wed May 11 15:30:11 2011 -0700
+++ b/usr/src/lib/install_target/physical.py	Thu May 12 11:06:35 2011 -0600
@@ -334,10 +334,12 @@
 
     def __copy__(self):
         """ method to override the parent's version of __copy__.
-        We want the _children list to be a shadow list instead of a flat list
+        We want the _children list to be a shadow list instead of a flat list.
+        We also need to reset validate_children to True.
         """
         new_copy = super(Partition, self).__copy__()
-        new_copy._children = ShadowPhysical(self)
+        new_copy._children = ShadowPhysical(new_copy)
+        new_copy.validate_children = True
         return new_copy
 
     def __repr__(self):
@@ -851,9 +853,11 @@
     def __copy__(self):
         """ method to override the parent's version of __copy__.
         We want the _children list to be a shadow list instead of a flat list
+        We also need to reset validate_children to True.
         """
         new_copy = super(Disk, self).__copy__()
-        new_copy._children = ShadowPhysical(self)
+        new_copy._children = ShadowPhysical(new_copy)
+        new_copy.validate_children = True
         return new_copy
 
     def __repr__(self):
@@ -1111,6 +1115,26 @@
         self.dev_vendor = None
         self.dev_size = None
 
+    def prop_matches(self, other):
+        """ Attempt to match disk_prop. Any of the properties
+        dev_type/dev_vendor/dev_size must been specified
+
+        For comparrisons of dev_size, a match is found if the size of other's
+        dev_size is smaller than this dev_size
+        """
+        for k in self.__dict__:
+            if getattr(self, k) is not None and getattr(other, k) is not None:
+                # special case for dev_size.  other.dev_size must be smaller
+                # than self.dev_size
+                if k == "dev_size":
+                    if self.dev_size < other.dev_size:
+                        return False
+                else:
+                    if getattr(self, k).lower() != getattr(other, k).lower():
+                        # the strings are not equal
+                        return False
+        return True
+
 
 class DiskKeyword(object):
     def __init__(self):
--- a/usr/src/lib/install_target/shadow/physical.py	Wed May 11 15:30:11 2011 -0700
+++ b/usr/src/lib/install_target/shadow/physical.py	Thu May 12 11:06:35 2011 -0600
@@ -38,8 +38,9 @@
     and Slice)
     """
     class OverlappingSliceError(ShadowExceptionBase):
-        def __init__(self, slice_name):
-            self.value = "Slice overlaps with existing slice: %s" % slice_name
+        def __init__(self, slice_name, existing_slice):
+            self.value = "Slice %s overlaps with existing slice: %s" % \
+                         (slice_name, existing_slice)
 
     class OverlappingSliceZpoolError(ShadowExceptionBase):
         def __init__(self):
@@ -236,10 +237,13 @@
             end = slc.start_sector + slc.size.sectors - 1
 
             # check that the start sector is not within another slice and
-            # the existing slice isn't inside the new slice
-            if ((start <= cb_start <= end) or (start <= cb_end <= end)) or \
-               ((cb_start <= start <= cb_end) or (cb_start <= end <= cb_end)):
-                self.set_error(self.OverlappingSliceError(slc.name))
+            # the existing slice isn't inside the new slice but only for slices
+            # not marked for deletion
+            if value.action != "delete" and slc.action != "delete":
+                if (start <= cb_start <= end or start <= cb_end <= end) or \
+                   (cb_start <= start <= cb_end or cb_start <= end <= cb_end):
+                    self.set_error(
+                        self.OverlappingSliceError(value.name, slc.name))
 
         if len(self._shadow) >= V_NUMPAR:
             self.set_error(self.TooManySlicesError())
@@ -397,11 +401,13 @@
             # insert is not within another partition and the existing partition
             # isn't inside the partition we're inserting.  Primary partitions
             # are only checked against other primary partitions and logical
-            # partitions are only checked aginst other logical partitions
-            if ((start <= p_start <= end) or (start <= p_end <= end)) or \
-               ((p_start <= start <= p_end) or (p_start <= end <= p_end)):
-                self.set_error(self.OverlappingPartitionError(
-                    partition.name))
+            # partitions are only checked aginst other logical partitions.
+            # Partitions marked for deletion should not be checked at all
+            if value.action != "delete" and partition.action != "delete":
+                if ((start <= p_start <= end) or (start <= p_end <= end)) or \
+                   ((p_start <= start <= p_end) or (p_start <= end <= p_end)):
+                    self.set_error(self.OverlappingPartitionError(
+                        partition.name))
 
         # check that a primary partition doesn't exceed the size of the Disk,
         # if the dev_size is specified