1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00
lvm2/daemons/lvmdbusd/udevwatch.py
Tony Asleson 3ead4fb7ac lvmdbusd: Limit state refreshes for udev events
Udev events can come in like a flood when something changes.  It really
doesn't do us any good to refresh the state of the service numerous times
when 1 would suffice.  We had something like this before, but it was
removed when we added the refresh thread.  However, we have since learned
that we need to sequence events in the correct order and block dbus
operations if we believe the state has been affected, thus udev events are
being processed on the main work queue.  This change limits spurious
work items from getting to the queue.
2017-03-20 10:08:39 -05:00

92 lines
2.0 KiB
Python

# Copyright (C) 2015-2016 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pyudev
import threading
from . import cfg
from .request import RequestEntry
from . import utils
observer = None
observer_lock = threading.RLock()
_udev_lock = threading.RLock()
_udev_count = 0
def udev_add():
global _udev_count
with _udev_lock:
if _udev_count == 0:
_udev_count += 1
# Place this on the queue so any other operations will sequence
# behind it
r = RequestEntry(
-1, _udev_event, (), None, None, False)
cfg.worker_q.put(r)
def udev_complete():
global _udev_count
with _udev_lock:
if _udev_count > 0:
_udev_count -= 1
def _udev_event():
utils.log_debug("Processing udev event")
udev_complete()
cfg.load()
# noinspection PyUnusedLocal
def filter_event(action, device):
# Filter for events of interest and add a request object to be processed
# when appropriate.
refresh = False
if '.ID_FS_TYPE_NEW' in device:
fs_type_new = device['.ID_FS_TYPE_NEW']
if 'LVM' in fs_type_new:
refresh = True
elif fs_type_new == '':
# Check to see if the device was one we knew about
if 'DEVNAME' in device:
found = cfg.om.get_object_by_lvm_id(device['DEVNAME'])
if found:
refresh = True
if 'DM_LV_NAME' in device:
refresh = True
if refresh:
udev_add()
def add():
with observer_lock:
global observer
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by('block')
observer = pyudev.MonitorObserver(monitor, filter_event)
observer.start()
def remove():
with observer_lock:
global observer
if observer:
observer.stop()
observer = None
return True
return False