7083584 snv 172 text installer does not initially present SAS drive aliases/receptacles
authorKaren Tung <Karen.Tung@oracle.com>
Fri, 02 Sep 2011 10:18:43 -0700
changeset 1450 60f63c2d05d7
parent 1449 1e9e58eedcbe
child 1451 9b3261795610
7083584 snv 172 text installer does not initially present SAS drive aliases/receptacles 7083367 composed string have localization issue: _("The new size ") + locale_new_size + _(" is greater ... 7082485 AI install fails when dump zvol specified in manifest. 7081220 S11 TI crashes after configuring on partitioning screen-'no Solaris partition found' 7064286 [Text Installer] Installation restarts when partitions are changed.
usr/src/cmd/auto-install/svc/auto-installer.xml
usr/src/cmd/text-install/disk_window.py
usr/src/cmd/text-install/partition_edit_screen.py
usr/src/cmd/text-install/svc/text-mode-menu.xml
usr/src/cmd/text-install/ti_target_utils.py
usr/src/lib/install_target/logical.py
--- a/usr/src/cmd/auto-install/svc/auto-installer.xml	Fri Sep 02 19:10:38 2011 +0100
+++ b/usr/src/cmd/auto-install/svc/auto-installer.xml	Fri Sep 02 10:18:43 2011 -0700
@@ -19,8 +19,7 @@
 
  CDDL HEADER END
 
- Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- Use is subject to license terms.
+ Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
 
  NOTE:  This service manifest is not editable; its contents will
  be overwritten by package or patch operations, including
@@ -49,6 +48,18 @@
 		<service_fmri value='svc:/system/console-login' />
 	</dependency>
 
+        <!-- Do not start the auto-installer until devchassis daemon 
+             SMF service is online to ensure target selection works 
+             correctly for manifests that specifies receptacle
+             information for the drives -->
+        <dependency
+                name='devchassis-daemon'
+                grouping='require_all'
+                restart_on='none'
+                type='service'>
+                <service_fmri value='svc:/system/devchassis:daemon' />
+        </dependency>
+
 	<dependency
 		name='manifest-locator'
 		grouping='require_all'
--- a/usr/src/cmd/text-install/disk_window.py	Fri Sep 02 19:10:38 2011 +0100
+++ b/usr/src/cmd/text-install/disk_window.py	Fri Sep 02 10:18:43 2011 -0700
@@ -804,8 +804,10 @@
         if new_size_rounded > max_size_rounded:
             locale_new_size = locale.format("%.1f", new_size_rounded)
             locale_max_size = locale.format("%.1f", max_size_rounded)
-            msg = _("The new size ") + locale_new_size + \
-                _(" is greater than the available space ") + locale_max_size
+            msg = _("The new size %(size)s is greater than "
+                    "the available space %(avail)s") % \
+                    {"size": locale_new_size,
+                     "avail": locale_max_size}
             raise UIMessage(msg)
     return True
 
--- a/usr/src/cmd/text-install/partition_edit_screen.py	Fri Sep 02 19:10:38 2011 +0100
+++ b/usr/src/cmd/text-install/partition_edit_screen.py	Fri Sep 02 10:18:43 2011 -0700
@@ -205,6 +205,10 @@
                 part.in_zpool = None
                 part.bootid = Partition.ACTIVE
 
+                # Make sure in_zpool is not set on the Disk, target controller
+                # puts it there in some cases
+                disk.in_zpool = None
+
                 # perform final target validation
                 perform_final_validation(doc)
 
--- a/usr/src/cmd/text-install/svc/text-mode-menu.xml	Fri Sep 02 19:10:38 2011 +0100
+++ b/usr/src/cmd/text-install/svc/text-mode-menu.xml	Fri Sep 02 10:18:43 2011 -0700
@@ -19,7 +19,7 @@
 
  CDDL HEADER END
 
- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
 
  NOTE:  This service manifest is not editable; its contents will
  be overwritten by package or patch operations, including
@@ -52,6 +52,17 @@
 		<service_fmri value='svc:/milestone/single-user' />
 	</dependency>
 
+        <!-- Don't display the menu until devchassis daemon SMF service
+             is online
+        -->
+        <dependency
+                name='devchassis-daemon'
+                grouping='require_all'
+                restart_on='none'
+                type='service'>
+                <service_fmri value='svc:/system/devchassis:daemon' />
+        </dependency>
+
 	<method_context>
 		<method_credential user='root' group='root'/>
 	</method_context>
--- a/usr/src/cmd/text-install/ti_target_utils.py	Fri Sep 02 19:10:38 2011 +0100
+++ b/usr/src/cmd/text-install/ti_target_utils.py	Fri Sep 02 10:18:43 2011 -0700
@@ -57,6 +57,10 @@
 
 UI_PRECISION = "0.05gb"
 
+UI_MIN_EMPTY_PRIMARY_PART = "1gb"
+UI_MIN_EMPTY_LOGICAL_PART = "0.1gb"
+UI_MIN_EMPTY_SLICE = "1gb"
+
 UI_TYPE_IN_USE = "UI Object In-use" # partition/slice in use
 UI_TYPE_EMPTY_SPACE = "UI Object EMPTY"   # unused components
 UI_TYPE_NOT_USED = "UI Object not-in-use" 
@@ -412,7 +416,7 @@
         existing_gaps.sort(size_sort)
 
         self.have_logical = add_missed_parts(numbers, existing_parts, \
-            existing_gaps, Size("1" + Size.gb_units), self.all_parts, \
+            existing_gaps, Size(UI_MIN_EMPTY_PRIMARY_PART), self.all_parts, \
             check_extended=use_partitions)
 
         if use_partitions == False:
@@ -447,7 +451,7 @@
 
         # Fill in all the missing logical if necessary
         add_missed_parts(numbers, existing_parts, logical_part_gaps,
-                         Size("0.1" + Size.gb_units), self.all_parts,
+                         Size(UI_MIN_EMPTY_LOGICAL_PART), self.all_parts,
                          adding_logical=True)
         
     @property
@@ -662,7 +666,7 @@
         existing_gaps.sort(size_sort)
 
         add_missed_parts(numbers, existing_parts, existing_gaps,
-                         Size("1gb"), self.all_parts)
+                         Size(UI_MIN_EMPTY_SLICE), self.all_parts)
 
         # If there's a backup slice, move it to end of the list for display
         slice2 = self.all_parts[2]
@@ -843,7 +847,7 @@
             else:
                 return False
 
-        return True
+        return False
 
     def is_extended(self):
         if self.ui_type == UI_TYPE_IN_USE and self.doc_obj.is_extended:
@@ -914,17 +918,46 @@
             self.cycle_type(new_type=new_type, extra_type=extra_type)
         else:
             if self.ui_type == UI_TYPE_EMPTY_SPACE:
-                LOGGER.debug("Partition used to be unsed.  Add partition with"
+                if new_type == UIPartition.UNUSED:
+                    # already cycled through all possible types, can't
+                    # change to anything
+                    return
+
+                # find largest available gap, and create a partition
+                # of the specified type in that gap.  We do not want to
+                # use the start sector and size value in the empty objects
+                # because those are fake values.
+                existing_gaps = self.parent.doc_obj.get_gaps()
+
+                if not existing_gaps:
+                    # There's no free space anymore, do not do anything
+                    return
+
+                # sort the gaps by size, largest gap will be at
+                # the end of the list.
+                existing_gaps.sort(size_sort)
+
+                largest_empty = existing_gaps[-1]
+
+                # check to make sure the largest gap is big enough.
+                # For primary partitions, we ignore all gaps smaller than 1G.
+                # For logical partitions, we ignore all gaps smaller than 0.1G. 
+                if self.is_logical():
+                    min_gap_size = Size(UI_MIN_EMPTY_LOGICAL_PART)
+                else:
+                    min_gap_size = Size(UI_MIN_EMPTY_PRIMARY_PART)
+                if largest_empty.size < min_gap_size:
+                    return
+
+                LOGGER.debug("Partition used to be unused.  Add partition with"
                              "type: %s, start_sec=%s, size=%s" %
                              (libdiskmgt_const.PARTITION_ID_MAP[new_type], 
-                             self.empty_space_obj.start_sector,
-                             self.get_max_size()))
+                             largest_empty.start_sector,
+                             largest_empty.size))
 
-                size_in_sector = self.empty_space_obj.size.get(\
-                    Size.sector_units)
-
-                new_part = self.parent.doc_obj.add_partition(self.name, \
-                    self.empty_space_obj.start_sector, size_in_sector, \
+                new_part = self.parent.doc_obj.add_partition(self.name,
+                    largest_empty.start_sector,
+                    largest_empty.size.get(Size.sector_units),
                     size_units=Size.sector_units, partition_type=new_type)
                 if new_part.is_solaris:
                     new_part.bootid = Partition.ACTIVE
@@ -1108,7 +1141,8 @@
                 # Use the backup slice to define the absolute max size
                 # any given slice can be. (This is usually the last slice,
                 # hence the use of a reversed iterator)
-                if int(slice_info.name) == BACKUP_SLICE:
+                if int(slice_info.name) == BACKUP_SLICE and \
+                    slice_info.ui_type == UI_TYPE_IN_USE:
                     end_pt = slice_info.size.get(Size.sector_units)
                     break
             else:
@@ -1224,7 +1258,7 @@
 
         new_type = types[type_index]
 
-        if new_type == UIPartition.UNUSED:
+        if new_type == UISlice.UNUSED:
             LOGGER.debug("new type == unused")
         else:
             LOGGER.debug("new type == %s", new_type)
@@ -1234,27 +1268,48 @@
         else:
             if self.ui_type == UI_TYPE_EMPTY_SPACE:
                 if new_type == ROOT_POOL:
-                    # making this the new root pool
-                    size_in_sector = self.empty_space_obj.size.get( \
-                        Size.sector_units)
-                    LOGGER.debug("Used to be unused... adding new slice")
-                    new_slice = self.parent.doc_obj.add_slice(self.name, \
-                        self.empty_space_obj.start_sector, size_in_sector, \
-                        size_units=Size.sector_units)
-                    new_slice.in_zpool = ROOT_POOL
-                    new_slice.in_vdev = DEFAULT_VDEV_NAME
-                    new_slice.tag = V_ROOT
+
+                    # find largest available gap, and create a slice
+                    # of the specified type in that gap.  We do not want to
+                    # use the start sector and size value in the empty objects
+                    # because those are fake values.
+                    existing_gaps = self.parent.doc_obj.get_gaps()
+
+                    if not existing_gaps:
+
+                        # sort the gaps by size, largest gap will be at
+                        # the end of the list.
+                        existing_gaps.sort(size_sort)
+
+                        largest_empty = existing_gaps[-1]
+
+                        # check to make sure the largest gap is big enough.
+                        # gaps smaller than 1G are not used.
+                        if largest_empty.size < Size(UI_MIN_EMPTY_SLICE):
+                            return
+
+                        # making this the new root pool
+                        LOGGER.debug("Used to be unused... adding new slice")
+                        new_slice = self.parent.doc_obj.add_slice(self.name,
+                            largest_empty.start_sector,
+                            largest_empty.size.get(Size.sector_units),
+                            size_units=Size.sector_units)
+                        new_slice.in_zpool = ROOT_POOL
+                        new_slice.in_vdev = DEFAULT_VDEV_NAME
+                        new_slice.tag = V_ROOT
+                        dump_doc("After change slice type")
+                        return
+
+                # setting it back to whatever value was discovered
+                discovered_obj = self.discovered_doc_obj
+                if discovered_obj is not None:
+                    self.parent.doc_obj.insert_children(discovered_obj)
                 else:
-                    # setting it back to whatever value was discovered
-                    discovered_obj = self.discovered_doc_obj
-                    if discovered_obj is not None:
-                        self.parent.doc_obj.insert_children(discovered_obj)
-                    else:
-                        LOGGER.debug("Unable to reset to discovered value")
+                    LOGGER.debug("Unable to reset to discovered value")
                 
             else:
-                if new_type == UIPartition.UNUSED:
+                if new_type == UISlice.UNUSED:
                     LOGGER.debug("Changing to unused, deleting")
                     LOGGER.debug("Target Call: deleting %s", self.name)
                     self.parent.doc_obj.delete_slice(self.doc_obj)
-        dump_doc("AFTER change type")
+        dump_doc("After change slice type")
--- a/usr/src/lib/install_target/logical.py	Fri Sep 02 19:10:38 2011 +0100
+++ b/usr/src/lib/install_target/logical.py	Fri Sep 02 10:18:43 2011 -0700
@@ -629,6 +629,7 @@
         self.use = "none"
 
         self.size = ""
+        self.create_failure_ok = False
 
     @property
     def full_name(self):