1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

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
This commit is contained in:
Tony Asleson 2016-09-26 22:02:08 -05:00
parent a882eb2b3b
commit 063265eacd

View File

@ -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: