15742315 moving driver_alias from 'hermon' to 'mcxnex' fails with 'onu' s11-sru10 s11sru10.1
authorsaurabh.vyas@oracle.com
Wed, 07 Aug 2013 11:06:38 +0530
branchs11-sru10
changeset 2929 60b857b1ce6d
parent 2741 1dc473995939
15742315 moving driver_alias from 'hermon' to 'mcxnex' fails with 'onu'
src/modules/actions/driver.py
src/modules/client/imageplan.py
src/tests/cli/t_pkg_install.py
--- a/src/modules/actions/driver.py	Mon Jul 16 14:35:02 2012 +0530
+++ b/src/modules/actions/driver.py	Wed Aug 07 11:06:38 2013 +0530
@@ -85,15 +85,16 @@
                 else:
                         self.attrs["clone_perms"] = new_cloneperms
 
-        def __usr_sbin_init(self):
+        @staticmethod
+        def __usr_sbin_init():
                 """Initialize paths to device management commands that we will
                 execute when handling package driver actions"""
 
                 usr_sbin = DebugValues.get("driver-cmd-dir", "/usr/sbin") + "/"
-                self.__class__.usr_sbin = usr_sbin
-                self.__class__.add_drv = usr_sbin + "add_drv"
-                self.__class__.rem_drv = usr_sbin + "rem_drv"
-                self.__class__.update_drv = usr_sbin + "update_drv"
+                DriverAction.usr_sbin = usr_sbin
+                DriverAction.add_drv = usr_sbin + "add_drv"
+                DriverAction.rem_drv = usr_sbin + "rem_drv"
+                DriverAction.update_drv = usr_sbin + "update_drv"
 
         def __getstate__(self):
                 """This object doesn't have a default __dict__, instead it
@@ -136,6 +137,17 @@
                         print buf,
                         print "-" * 60
 
+        @staticmethod
+        def remove_aliases(driver_name, aliases, image):
+                if not DriverAction.update_drv:
+                        DriverAction.__usr_sbin_init()
+                rem_base = (DriverAction.update_drv, "-b", image.get_root(), "-d")
+                for i in aliases:
+                        args = rem_base + ("-i", '%s' % i, driver_name)
+                        DriverAction.__call(args, "driver (%(name)s) upgrade (removal "
+                            "of alias '%(alias)s')",
+                            {"name": driver_name, "alias": i})
+
         @classmethod
         def __activate_drivers(cls):
                 cls.__call([cls.usr_sbin + "devfsadm", "-u"],
@@ -372,10 +384,8 @@
                 add_base = ( self.update_drv, "-b", image.get_root(), "-a" )
                 rem_base = ( self.update_drv, "-b", image.get_root(), "-d" )
 
-                nalias = set(self.attrlist("alias"))
-                oalias = set(orig.attrlist("alias"))
-                add_alias = nalias - oalias
-                rem_alias = oalias - nalias
+                add_alias = set(self.attrlist("alias")) - \
+                    set(orig.attrlist("alias"))
 
                 nclass = set(self.attrlist("class"))
                 oclass = set(orig.attrlist("class"))
@@ -408,11 +418,8 @@
                             "of alias '%(alias)s')",
                             {"name": self.attrs["name"], "alias": i})
 
-                for i in rem_alias:
-                        args = rem_base + ("-i", '%s' % i, self.attrs["name"])
-                        self.__call(args, "driver (%(name)s) upgrade (removal "
-                            "of alias '%(alias)s')",
-                            {"name": self.attrs["name"], "alias": i})
+                # Removing aliases has already been taken care of in
+                # imageplan.execute by calling remove_aliases.
 
                 # update_drv doesn't do anything with classes, so we have to
                 # futz with driver_classes by hand.
--- a/src/modules/client/imageplan.py	Mon Jul 16 14:35:02 2012 +0530
+++ b/src/modules/client/imageplan.py	Wed Aug 07 11:06:38 2013 +0530
@@ -37,6 +37,7 @@
 logger = global_settings.logger
 
 import pkg.actions
+import pkg.actions.driver as driver
 import pkg.catalog
 import pkg.client.actuator as actuator
 import pkg.client.api_errors as api_errors
@@ -178,6 +179,7 @@
                 self.__changed_facets = {}
                 self.__removed_facets = set()
                 self.__varcets_change = False
+                self.__rm_aliases = {}
                 self.__match_inst = {} # dict of fmri -> pattern
                 self.__match_rm = {} # dict of fmri -> pattern
                 self.__match_update = {} # dict of fmri -> pattern
@@ -2357,6 +2359,7 @@
                 self.__progtrack.evaluate_progress()
 
                 self.update_actions = []
+                self.__rm_aliases = {}
                 for p in self.pkg_plans:
                         for src, dest in p.gen_update_actions():
                                 if dest.name == "user":
@@ -2365,6 +2368,14 @@
                                 elif dest.name == "group":
                                         self.added_groups[dest.attrs["groupname"]] = \
                                             p.destination_fmri
+                                elif dest.name == "driver" and src:
+                                        rm = \
+                                            set(src.attrlist("alias")) - \
+                                            set(dest.attrlist("alias"))
+                                        if rm:
+                                                self.__rm_aliases.setdefault(
+                                                    dest.attrs["name"],
+                                                    set()).update(rm)
                                 self.update_actions.append(ActionPlan(p, src,
                                     dest))
                 self.__progtrack.evaluate_progress()
@@ -2921,14 +2932,19 @@
                 #    other.  Clearly, all the removals must be done first,
                 #    followed by the installs and updates.
                 #
-                # 2) Installs of new actions must preceed updates of existing
+                # 2) Installs of new actions must precede updates of existing
                 # ones.
                 #
-                #    In order to accomodate changes of file ownership of
+                #    In order to accommodate changes of file ownership of
                 #    existing files to a newly created user, it is necessary
-                #    for the installation of that user to preceed the update of
+                #    for the installation of that user to precede the update of
                 #    files to reflect their new ownership.
                 #
+                #    The exception to this rule is driver actions.  Aliases of
+                #    existing drivers which are going to be removed must be
+                #    removed before any new drivers are installed or updated.
+                #    This prevents an error if an alias is moving from one
+                #    driver to another.
 
                 if self.nothingtodo():
                         self.state = EXECUTED_OK
@@ -2957,6 +2973,15 @@
                                         self.__progtrack.actions_add_progress()
                                 self.__progtrack.actions_done()
 
+                                # Update driver alias database to reflect the
+                                # aliases drivers have lost in the new image.
+                                # This prevents two drivers from ever attempting
+                                # to have the same alias at the same time.
+                                for name, aliases in \
+                                    self.__rm_aliases.iteritems():
+                                        driver.DriverAction.remove_aliases(name,
+                                            aliases, self.image)
+
                                 # Done with removals; discard them so memory can
                                 # be re-used.
                                 self.removal_actions = []
--- a/src/tests/cli/t_pkg_install.py	Mon Jul 16 14:35:02 2012 +0530
+++ b/src/tests/cli/t_pkg_install.py	Wed Aug 07 11:06:38 2013 +0530
@@ -3407,6 +3407,7 @@
                 self.image_create(self.rurl)
                 self.pkg("install devicebase devaliasmove@1")
                 self.pkg("update devaliasmove")
+                self.assert_("pci8086,5555" not in self.output)
 
         def test_uninstall_without_perms(self):
                 """Test for bug 4569"""