--- 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"""