diff options
author | Tony Asleson <tasleson@redhat.com> | 2016-09-26 22:02:08 -0500 |
---|---|---|
committer | Tony Asleson <tasleson@redhat.com> | 2016-09-27 13:28:54 -0500 |
commit | 063265eacda95dbc1567e647734a000c8d68c8b7 (patch) | |
tree | d31a18e126f321dff8f443e04031cada676c53e5 | |
parent | a882eb2b3b6eba6a482d4dcb1079a3ffa615fb6a (diff) | |
download | lvm2-063265eacda95dbc1567e647734a000c8d68c8b7.tar.gz |
lvmdbusd: Allow PV device names to be '[unknown]'
When a PV device is missing lvm will return '[unknown]' for the device
path. The object manager keeps a hash table lookup for uuid and for PV's
device name. When we had multiple PVs with the same device path we
we only had 1 key in the table for the lvm id (device path). This caused
a problem when the PV device transitioned from '[unknown]' to known as any
subsequent transitions would cause an exception:
Traceback (most recent call last):
File "/usr/lib/python3.5/site-packages/lvmdbusd/request.py", line 66, in run_cmd
result = self.method(*self.arguments)
File "/usr/lib/python3.5/site-packages/lvmdbusd/manager.py", line 205, in _pv_scan
cfg.load()
File "/usr/lib/python3.5/site-packages/lvmdbusd/fetch.py", line 24, in load
cache_refresh=False)[1]
File "/usr/lib/python3.5/site-packages/lvmdbusd/pv.py", line 48, in load_pvs
emit_signal, cache_refresh)
File "/usr/lib/python3.5/site-packages/lvmdbusd/loader.py", line 80, in common
cfg.om.remove_object(cfg.om.get_object_by_path(k), True)
File "/usr/lib/python3.5/site-packages/lvmdbusd/objectmanager.py", line 153, in remove_object
self._lookup_remove(path)
File "/usr/lib/python3.5/site-packages/lvmdbusd/objectmanager.py", line 97, in _lookup_remove
del self._id_to_object_path[lvm_id]
KeyError: '[unknown]'
when trying to delete a key that wasn't present. In this case we don't add a
lookup key for the device path and the PV can only be located by UUID.
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1379357
-rw-r--r-- | daemons/lvmdbusd/objectmanager.py | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/daemons/lvmdbusd/objectmanager.py b/daemons/lvmdbusd/objectmanager.py index 55f17292f..f491df49e 100644 --- a/daemons/lvmdbusd/objectmanager.py +++ b/daemons/lvmdbusd/objectmanager.py @@ -13,7 +13,7 @@ import traceback import dbus import os from . import cfg -from .utils import log_debug +from .utils import log_debug, pv_obj_path_generate from .automatedproperties import AutomatedProperties @@ -75,7 +75,7 @@ class ObjectManager(AutomatedProperties): Store information about what we added to the caches so that we can remove it cleanly :param obj: The dbus object we are storing - :param lvm_id: The user name for the asset + :param lvm_id: The lvm id for the asset :param uuid: The uuid for the asset :return: """ @@ -85,7 +85,12 @@ class ObjectManager(AutomatedProperties): self._lookup_remove(path) self._objects[path] = (obj, lvm_id, uuid) - self._id_to_object_path[lvm_id] = path + + # Make sure we have one or the other + assert lvm_id or uuid + + if lvm_id: + self._id_to_object_path[lvm_id] = path if uuid: self._id_to_object_path[uuid] = path @@ -94,8 +99,13 @@ class ObjectManager(AutomatedProperties): # Note: Only called internally, lock implied if obj_path in self._objects: (obj, lvm_id, uuid) = self._objects[obj_path] - del self._id_to_object_path[lvm_id] - del self._id_to_object_path[uuid] + + if lvm_id in self._id_to_object_path: + del self._id_to_object_path[lvm_id] + + if uuid in self._id_to_object_path: + del self._id_to_object_path[uuid] + del self._objects[obj_path] def lookup_update(self, dbus_obj, new_uuid, new_lvm_id): @@ -206,7 +216,8 @@ class ObjectManager(AutomatedProperties): :return: None """ # This gets called when we found an object based on lvm_id, ensure - # uuid is correct too, as they can change + # uuid is correct too, as they can change. There is no durable + # non-changeable name in lvm if lvm_id != uuid: if uuid and uuid not in self._id_to_object_path: obj = self.get_object_by_path(path) @@ -221,12 +232,14 @@ class ObjectManager(AutomatedProperties): :param lvm_id: lvm_id to verify :return: None """ - # This gets called when we found an object based on lvm_id, ensure - # uuid is correct too, as they can change + # This gets called when we found an object based on uuid, ensure + # lvm_id is correct too, as they can change. There is no durable + # non-changeable name in lvm if lvm_id != uuid: if lvm_id and lvm_id not in self._id_to_object_path: obj = self.get_object_by_path(path) self._lookup_add(obj, path, lvm_id, uuid) + def _id_lookup(self, the_id): path = None @@ -277,6 +290,12 @@ class ObjectManager(AutomatedProperties): # We have a uuid and a lvm_id we can do sanity checks to ensure # that they are consistent + # If a PV is missing it's device path is '[unknown]'. When + # we see the lvm_id as such we will re-assign to None + if path_create == pv_obj_path_generate and \ + lvm_id == '[unknown]': + lvm_id = None + # Lets check for the uuid first path = self._id_lookup(uuid) if path: |