2016-02-18 02:53:35 +03:00
# 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
2016-08-25 02:29:35 +03:00
import threading
2016-02-18 02:53:35 +03:00
from . import cfg
2017-03-09 00:31:45 +03:00
from . request import RequestEntry
from . import utils
2016-02-18 02:53:35 +03:00
observer = None
2016-08-25 02:29:35 +03:00
observer_lock = threading . RLock ( )
2016-02-18 02:53:35 +03:00
2017-03-15 21:08:19 +03:00
_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
2016-02-18 02:53:35 +03:00
2017-03-09 00:31:45 +03:00
def _udev_event ( ) :
utils . log_debug ( " Processing udev event " )
2017-03-15 21:08:19 +03:00
udev_complete ( )
2017-03-09 00:31:45 +03:00
cfg . load ( )
2016-02-18 02:53:35 +03:00
# noinspection PyUnusedLocal
def filter_event ( action , device ) :
# Filter for events of interest and add a request object to be processed
# when appropriate.
refresh = False
2022-10-18 20:30:09 +03:00
# Ignore everything but change
if action != ' change ' :
return
2021-06-02 18:17:40 +03:00
if ' ID_FS_TYPE ' in device :
fs_type_new = device [ ' ID_FS_TYPE ' ]
2016-02-18 02:53:35 +03:00
if ' LVM ' in fs_type_new :
2022-10-20 18:46:51 +03:00
# If we get a lvm related udev event for a block device
# we don't know about, it's either a pvcreate which we
# would handle with the dbus notification or something
# copied a pv signature onto a block device, this is
# required to catch the latter.
if not cfg . om . get_object_by_lvm_id ( device [ ' DEVNAME ' ] ) :
refresh = True
2016-02-18 02:53:35 +03:00
elif fs_type_new == ' ' :
# Check to see if the device was one we knew about
if ' DEVNAME ' in device :
2022-10-18 20:30:09 +03:00
if cfg . om . get_object_by_lvm_id ( device [ ' DEVNAME ' ] ) :
2016-02-18 02:53:35 +03:00
refresh = True
2022-10-18 20:30:09 +03:00
else :
# This handles the wipefs -a path
if not refresh and ' DEVNAME ' in device :
if cfg . om . get_object_by_lvm_id ( device [ ' DEVNAME ' ] ) :
refresh = True
2016-02-18 02:53:35 +03:00
if refresh :
2017-03-15 21:08:19 +03:00
udev_add ( )
2016-02-18 02:53:35 +03:00
def add ( ) :
2016-08-25 02:29:35 +03:00
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 ( )
2016-02-18 02:53:35 +03:00
def remove ( ) :
2016-08-25 02:29:35 +03:00
with observer_lock :
global observer
if observer :
observer . stop ( )
observer = None
return True
return False