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/>.
2022-09-08 23:37:34 +03:00
import errno
2016-02-18 02:53:35 +03:00
from . pv import load_pvs
from . vg import load_vgs
from . lv import load_lvs
from . import cfg
2022-08-31 19:20:49 +03:00
from . utils import MThreadRunner , log_debug , log_error , LvmBug , extract_stack_trace
2016-11-10 21:19:48 +03:00
import threading
import queue
2018-12-18 18:49:36 +03:00
import time
2016-02-18 02:53:35 +03:00
2016-11-02 01:50:10 +03:00
def _main_thread_load ( refresh = True , emit_signal = True ) :
2016-02-18 02:53:35 +03:00
num_total_changes = 0
lvmdbusd: Defer dbus object removal
When we are walking the new lvm state comparing it to the old state we can
run into an issue where we remove a VG that is no longer present from the
object manager, but is still needed by LVs that are left to be processed.
When we try to process existing LVs to see if their state needs to be
updated, or if they need to be removed, we need to be able to reference the
VG that was associated with it. However, if it's been removed from the
object manager we fail to find it which results in:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/lvmdbusd/utils.py", line 666, in _run
self.rc = self.f(*self.args)
File "/usr/lib/python3.6/site-packages/lvmdbusd/fetch.py", line 36, in _main_thread_load
cache_refresh=False)[1]
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 146, in load_lvs
lv_name, object_path, refresh, emit_signal, cache_refresh)
File "/usr/lib/python3.6/site-packages/lvmdbusd/loader.py", line 68, in common
num_changes += dbus_object.refresh(object_state=o)
File "/usr/lib/python3.6/site-packages/lvmdbusd/automatedproperties.py", line 160, in refresh
search = self.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 483, in lvm_id
return self.state.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 173, in lvm_id
return "%s/%s" % (self.vg_name_lookup(), self.Name)
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 169, in vg_name_lookup
return cfg.om.get_object_by_path(self.Vg).Name
Instead of removing objects from the object manager immediately, we will
keep them in a list and remove them once we have processed all of the state.
Ref:
https://bugzilla.redhat.com/show_bug.cgi?id=1968752
2021-06-10 21:38:38 +03:00
to_remove = [ ]
2016-02-18 02:53:35 +03:00
lvmdbusd: Defer dbus object removal
When we are walking the new lvm state comparing it to the old state we can
run into an issue where we remove a VG that is no longer present from the
object manager, but is still needed by LVs that are left to be processed.
When we try to process existing LVs to see if their state needs to be
updated, or if they need to be removed, we need to be able to reference the
VG that was associated with it. However, if it's been removed from the
object manager we fail to find it which results in:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/lvmdbusd/utils.py", line 666, in _run
self.rc = self.f(*self.args)
File "/usr/lib/python3.6/site-packages/lvmdbusd/fetch.py", line 36, in _main_thread_load
cache_refresh=False)[1]
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 146, in load_lvs
lv_name, object_path, refresh, emit_signal, cache_refresh)
File "/usr/lib/python3.6/site-packages/lvmdbusd/loader.py", line 68, in common
num_changes += dbus_object.refresh(object_state=o)
File "/usr/lib/python3.6/site-packages/lvmdbusd/automatedproperties.py", line 160, in refresh
search = self.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 483, in lvm_id
return self.state.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 173, in lvm_id
return "%s/%s" % (self.vg_name_lookup(), self.Name)
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 169, in vg_name_lookup
return cfg.om.get_object_by_path(self.Vg).Name
Instead of removing objects from the object manager immediately, we will
keep them in a list and remove them once we have processed all of the state.
Ref:
https://bugzilla.redhat.com/show_bug.cgi?id=1968752
2021-06-10 21:38:38 +03:00
( changes , remove ) = load_pvs (
2016-11-02 01:50:10 +03:00
refresh = refresh ,
emit_signal = emit_signal ,
lvmdbusd: Defer dbus object removal
When we are walking the new lvm state comparing it to the old state we can
run into an issue where we remove a VG that is no longer present from the
object manager, but is still needed by LVs that are left to be processed.
When we try to process existing LVs to see if their state needs to be
updated, or if they need to be removed, we need to be able to reference the
VG that was associated with it. However, if it's been removed from the
object manager we fail to find it which results in:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/lvmdbusd/utils.py", line 666, in _run
self.rc = self.f(*self.args)
File "/usr/lib/python3.6/site-packages/lvmdbusd/fetch.py", line 36, in _main_thread_load
cache_refresh=False)[1]
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 146, in load_lvs
lv_name, object_path, refresh, emit_signal, cache_refresh)
File "/usr/lib/python3.6/site-packages/lvmdbusd/loader.py", line 68, in common
num_changes += dbus_object.refresh(object_state=o)
File "/usr/lib/python3.6/site-packages/lvmdbusd/automatedproperties.py", line 160, in refresh
search = self.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 483, in lvm_id
return self.state.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 173, in lvm_id
return "%s/%s" % (self.vg_name_lookup(), self.Name)
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 169, in vg_name_lookup
return cfg.om.get_object_by_path(self.Vg).Name
Instead of removing objects from the object manager immediately, we will
keep them in a list and remove them once we have processed all of the state.
Ref:
https://bugzilla.redhat.com/show_bug.cgi?id=1968752
2021-06-10 21:38:38 +03:00
cache_refresh = False ) [ 1 : ]
num_total_changes + = changes
to_remove . extend ( remove )
( changes , remove ) = load_vgs (
2016-11-02 01:50:10 +03:00
refresh = refresh ,
emit_signal = emit_signal ,
lvmdbusd: Defer dbus object removal
When we are walking the new lvm state comparing it to the old state we can
run into an issue where we remove a VG that is no longer present from the
object manager, but is still needed by LVs that are left to be processed.
When we try to process existing LVs to see if their state needs to be
updated, or if they need to be removed, we need to be able to reference the
VG that was associated with it. However, if it's been removed from the
object manager we fail to find it which results in:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/lvmdbusd/utils.py", line 666, in _run
self.rc = self.f(*self.args)
File "/usr/lib/python3.6/site-packages/lvmdbusd/fetch.py", line 36, in _main_thread_load
cache_refresh=False)[1]
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 146, in load_lvs
lv_name, object_path, refresh, emit_signal, cache_refresh)
File "/usr/lib/python3.6/site-packages/lvmdbusd/loader.py", line 68, in common
num_changes += dbus_object.refresh(object_state=o)
File "/usr/lib/python3.6/site-packages/lvmdbusd/automatedproperties.py", line 160, in refresh
search = self.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 483, in lvm_id
return self.state.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 173, in lvm_id
return "%s/%s" % (self.vg_name_lookup(), self.Name)
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 169, in vg_name_lookup
return cfg.om.get_object_by_path(self.Vg).Name
Instead of removing objects from the object manager immediately, we will
keep them in a list and remove them once we have processed all of the state.
Ref:
https://bugzilla.redhat.com/show_bug.cgi?id=1968752
2021-06-10 21:38:38 +03:00
cache_refresh = False ) [ 1 : ]
num_total_changes + = changes
to_remove . extend ( remove )
2019-10-11 00:53:10 +03:00
lvmdbusd: Defer dbus object removal
When we are walking the new lvm state comparing it to the old state we can
run into an issue where we remove a VG that is no longer present from the
object manager, but is still needed by LVs that are left to be processed.
When we try to process existing LVs to see if their state needs to be
updated, or if they need to be removed, we need to be able to reference the
VG that was associated with it. However, if it's been removed from the
object manager we fail to find it which results in:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/lvmdbusd/utils.py", line 666, in _run
self.rc = self.f(*self.args)
File "/usr/lib/python3.6/site-packages/lvmdbusd/fetch.py", line 36, in _main_thread_load
cache_refresh=False)[1]
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 146, in load_lvs
lv_name, object_path, refresh, emit_signal, cache_refresh)
File "/usr/lib/python3.6/site-packages/lvmdbusd/loader.py", line 68, in common
num_changes += dbus_object.refresh(object_state=o)
File "/usr/lib/python3.6/site-packages/lvmdbusd/automatedproperties.py", line 160, in refresh
search = self.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 483, in lvm_id
return self.state.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 173, in lvm_id
return "%s/%s" % (self.vg_name_lookup(), self.Name)
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 169, in vg_name_lookup
return cfg.om.get_object_by_path(self.Vg).Name
Instead of removing objects from the object manager immediately, we will
keep them in a list and remove them once we have processed all of the state.
Ref:
https://bugzilla.redhat.com/show_bug.cgi?id=1968752
2021-06-10 21:38:38 +03:00
( lv_changes , remove ) = load_lvs (
2016-11-02 01:50:10 +03:00
refresh = refresh ,
emit_signal = emit_signal ,
lvmdbusd: Defer dbus object removal
When we are walking the new lvm state comparing it to the old state we can
run into an issue where we remove a VG that is no longer present from the
object manager, but is still needed by LVs that are left to be processed.
When we try to process existing LVs to see if their state needs to be
updated, or if they need to be removed, we need to be able to reference the
VG that was associated with it. However, if it's been removed from the
object manager we fail to find it which results in:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/lvmdbusd/utils.py", line 666, in _run
self.rc = self.f(*self.args)
File "/usr/lib/python3.6/site-packages/lvmdbusd/fetch.py", line 36, in _main_thread_load
cache_refresh=False)[1]
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 146, in load_lvs
lv_name, object_path, refresh, emit_signal, cache_refresh)
File "/usr/lib/python3.6/site-packages/lvmdbusd/loader.py", line 68, in common
num_changes += dbus_object.refresh(object_state=o)
File "/usr/lib/python3.6/site-packages/lvmdbusd/automatedproperties.py", line 160, in refresh
search = self.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 483, in lvm_id
return self.state.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 173, in lvm_id
return "%s/%s" % (self.vg_name_lookup(), self.Name)
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 169, in vg_name_lookup
return cfg.om.get_object_by_path(self.Vg).Name
Instead of removing objects from the object manager immediately, we will
keep them in a list and remove them once we have processed all of the state.
Ref:
https://bugzilla.redhat.com/show_bug.cgi?id=1968752
2021-06-10 21:38:38 +03:00
cache_refresh = False ) [ 1 : ]
2016-11-02 01:50:10 +03:00
2019-10-11 00:53:10 +03:00
num_total_changes + = lv_changes
lvmdbusd: Defer dbus object removal
When we are walking the new lvm state comparing it to the old state we can
run into an issue where we remove a VG that is no longer present from the
object manager, but is still needed by LVs that are left to be processed.
When we try to process existing LVs to see if their state needs to be
updated, or if they need to be removed, we need to be able to reference the
VG that was associated with it. However, if it's been removed from the
object manager we fail to find it which results in:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/lvmdbusd/utils.py", line 666, in _run
self.rc = self.f(*self.args)
File "/usr/lib/python3.6/site-packages/lvmdbusd/fetch.py", line 36, in _main_thread_load
cache_refresh=False)[1]
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 146, in load_lvs
lv_name, object_path, refresh, emit_signal, cache_refresh)
File "/usr/lib/python3.6/site-packages/lvmdbusd/loader.py", line 68, in common
num_changes += dbus_object.refresh(object_state=o)
File "/usr/lib/python3.6/site-packages/lvmdbusd/automatedproperties.py", line 160, in refresh
search = self.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 483, in lvm_id
return self.state.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 173, in lvm_id
return "%s/%s" % (self.vg_name_lookup(), self.Name)
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 169, in vg_name_lookup
return cfg.om.get_object_by_path(self.Vg).Name
Instead of removing objects from the object manager immediately, we will
keep them in a list and remove them once we have processed all of the state.
Ref:
https://bugzilla.redhat.com/show_bug.cgi?id=1968752
2021-06-10 21:38:38 +03:00
to_remove . extend ( remove )
2019-10-11 00:53:10 +03:00
# When the LVs change it can cause another change in the VGs which is
# missed if we don't scan through the VGs again. We could achieve this
# the other way and re-scan the LVs, but in general there are more LVs than
# VGs, thus this should be more efficient. This happens when a LV interface
# changes causing the dbus object representing it to be removed and
# recreated.
if refresh and lv_changes > 0 :
lvmdbusd: Defer dbus object removal
When we are walking the new lvm state comparing it to the old state we can
run into an issue where we remove a VG that is no longer present from the
object manager, but is still needed by LVs that are left to be processed.
When we try to process existing LVs to see if their state needs to be
updated, or if they need to be removed, we need to be able to reference the
VG that was associated with it. However, if it's been removed from the
object manager we fail to find it which results in:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/lvmdbusd/utils.py", line 666, in _run
self.rc = self.f(*self.args)
File "/usr/lib/python3.6/site-packages/lvmdbusd/fetch.py", line 36, in _main_thread_load
cache_refresh=False)[1]
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 146, in load_lvs
lv_name, object_path, refresh, emit_signal, cache_refresh)
File "/usr/lib/python3.6/site-packages/lvmdbusd/loader.py", line 68, in common
num_changes += dbus_object.refresh(object_state=o)
File "/usr/lib/python3.6/site-packages/lvmdbusd/automatedproperties.py", line 160, in refresh
search = self.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 483, in lvm_id
return self.state.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 173, in lvm_id
return "%s/%s" % (self.vg_name_lookup(), self.Name)
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 169, in vg_name_lookup
return cfg.om.get_object_by_path(self.Vg).Name
Instead of removing objects from the object manager immediately, we will
keep them in a list and remove them once we have processed all of the state.
Ref:
https://bugzilla.redhat.com/show_bug.cgi?id=1968752
2021-06-10 21:38:38 +03:00
( changes , remove ) = load_vgs (
2019-10-11 00:53:10 +03:00
refresh = refresh ,
emit_signal = emit_signal ,
lvmdbusd: Defer dbus object removal
When we are walking the new lvm state comparing it to the old state we can
run into an issue where we remove a VG that is no longer present from the
object manager, but is still needed by LVs that are left to be processed.
When we try to process existing LVs to see if their state needs to be
updated, or if they need to be removed, we need to be able to reference the
VG that was associated with it. However, if it's been removed from the
object manager we fail to find it which results in:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/lvmdbusd/utils.py", line 666, in _run
self.rc = self.f(*self.args)
File "/usr/lib/python3.6/site-packages/lvmdbusd/fetch.py", line 36, in _main_thread_load
cache_refresh=False)[1]
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 146, in load_lvs
lv_name, object_path, refresh, emit_signal, cache_refresh)
File "/usr/lib/python3.6/site-packages/lvmdbusd/loader.py", line 68, in common
num_changes += dbus_object.refresh(object_state=o)
File "/usr/lib/python3.6/site-packages/lvmdbusd/automatedproperties.py", line 160, in refresh
search = self.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 483, in lvm_id
return self.state.lvm_id
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 173, in lvm_id
return "%s/%s" % (self.vg_name_lookup(), self.Name)
File "/usr/lib/python3.6/site-packages/lvmdbusd/lv.py", line 169, in vg_name_lookup
return cfg.om.get_object_by_path(self.Vg).Name
Instead of removing objects from the object manager immediately, we will
keep them in a list and remove them once we have processed all of the state.
Ref:
https://bugzilla.redhat.com/show_bug.cgi?id=1968752
2021-06-10 21:38:38 +03:00
cache_refresh = False ) [ 1 : ]
num_total_changes + = changes
to_remove . extend ( remove )
# Remove any objects that are no longer needed. We do this after we process
# all the objects to ensure that references still exist for objects that
# are processed after them.
to_remove . reverse ( )
for i in to_remove :
dbus_obj = cfg . om . get_object_by_path ( i )
if dbus_obj :
cfg . om . remove_object ( dbus_obj , True )
num_total_changes + = 1
2019-10-11 00:53:10 +03:00
2016-11-02 01:50:10 +03:00
return num_total_changes
def load ( refresh = True , emit_signal = True , cache_refresh = True , log = True ,
need_main_thread = True ) :
2016-02-18 02:53:35 +03:00
# Go through and load all the PVs, VGs and LVs
if cache_refresh :
cfg . db . refresh ( log )
2016-11-02 01:50:10 +03:00
if need_main_thread :
rc = MThreadRunner ( _main_thread_load , refresh , emit_signal ) . done ( )
else :
rc = _main_thread_load ( refresh , emit_signal )
2016-02-18 02:53:35 +03:00
2016-11-02 01:50:10 +03:00
return rc
2016-11-10 21:19:48 +03:00
# Even though lvm can handle multiple changes concurrently it really doesn't
# make sense to make a 1-1 fetch of data for each change of lvm because when
# we fetch the data once all previous changes are reflected.
class StateUpdate ( object ) :
class UpdateRequest ( object ) :
def __init__ ( self , refresh , emit_signal , cache_refresh , log ,
need_main_thread ) :
self . is_done = False
self . refresh = refresh
self . emit_signal = emit_signal
self . cache_refresh = cache_refresh
self . log = log
self . need_main_thread = need_main_thread
self . result = None
self . cond = threading . Condition ( threading . Lock ( ) )
def done ( self ) :
with self . cond :
if not self . is_done :
self . cond . wait ( )
return self . result
def set_result ( self , result ) :
with self . cond :
self . result = result
self . is_done = True
self . cond . notify_all ( )
@staticmethod
def update_thread ( obj ) :
2018-12-18 18:49:36 +03:00
exception_count = 0
2017-06-02 20:29:27 +03:00
queued_requests = [ ]
2022-08-18 01:21:19 +03:00
def set_results ( val ) :
nonlocal queued_requests
for idx in queued_requests :
idx . set_result ( val )
# Only clear out the requests after we have given them a result
# otherwise we can orphan the waiting threads, and they never
# wake up if we get an exception
queued_requests = [ ]
def bailing ( rv ) :
set_results ( rv )
try :
while True :
item = obj . queue . get ( False )
item . set_result ( rv )
except queue . Empty :
pass
2022-08-30 00:18:06 +03:00
def _load_args ( requests ) :
"""
If we have multiple requests in the queue , they might not all have the same options . If any of the requests
have an option set we need to honor it .
"""
refresh = any ( [ r . refresh for r in requests ] )
emit_signal = any ( [ r . emit_signal for r in requests ] )
cache_refresh = any ( [ r . cache_refresh for r in requests ] )
log = any ( [ r . log for r in requests ] )
need_main_thread = any ( [ r . need_main_thread for r in requests ] )
return refresh , emit_signal , cache_refresh , log , need_main_thread
def _drain_queue ( queued , incoming ) :
try :
while True :
queued . append ( incoming . get ( block = False ) )
except queue . Empty :
pass
2022-08-31 19:20:49 +03:00
def _handle_error ( ) :
nonlocal exception_count
exception_count + = 1
if exception_count > = 5 :
log_error ( " Too many errors in update_thread, exiting daemon " )
cfg . debug . dump ( )
cfg . flightrecorder . dump ( )
2022-09-08 23:37:34 +03:00
bailing ( errno . EFAULT )
2022-08-31 19:20:49 +03:00
cfg . exit_daemon ( )
else :
# Slow things down when encountering errors
2022-08-31 23:04:59 +03:00
cfg . lvmdebug . complete ( )
2022-08-31 19:20:49 +03:00
time . sleep ( 1 )
2016-11-10 21:19:48 +03:00
while cfg . run . value != 0 :
# noinspection PyBroadException
try :
with obj . lock :
wait = not obj . deferred
obj . deferred = False
2017-06-02 20:29:27 +03:00
if len ( queued_requests ) == 0 and wait :
2024-03-27 19:49:05 +03:00
# Note: If we don't have anything for N seconds we will
2022-08-26 19:10:24 +03:00
# get a queue.Empty exception raised here
2024-03-27 19:49:05 +03:00
queued_requests . append ( obj . queue . get ( block = True , timeout = cfg . G_LOOP_TMO ) )
2016-11-10 21:19:48 +03:00
# Ok we have one or the deferred queue has some,
2022-08-30 00:18:06 +03:00
# check if any others and grab them too
_drain_queue ( queued_requests , obj . queue )
2016-11-10 21:19:48 +03:00
2016-11-11 18:46:12 +03:00
if len ( queued_requests ) > 1 :
log_debug ( " Processing %d updates! " % len ( queued_requests ) ,
' bg_black ' , ' fg_light_green ' )
2016-11-10 21:19:48 +03:00
2022-08-30 00:18:06 +03:00
num_changes = load ( * _load_args ( queued_requests ) )
2016-11-10 21:19:48 +03:00
# Update is done, let everyone know!
2022-08-18 01:21:19 +03:00
set_results ( num_changes )
2017-06-02 20:29:27 +03:00
2018-12-18 18:49:36 +03:00
# We retrieved OK, clear exception count
exception_count = 0
2016-11-10 21:19:48 +03:00
except queue . Empty :
pass
2022-08-26 19:10:24 +03:00
except SystemExit :
break
2022-08-31 19:20:49 +03:00
except LvmBug as bug :
2022-08-31 23:04:59 +03:00
# If a lvm bug occurred, we will dump the lvm debug data if
# we have it.
cfg . lvmdebug . dump ( )
2022-08-31 19:20:49 +03:00
log_error ( str ( bug ) )
_handle_error ( )
2018-12-18 18:49:36 +03:00
except Exception as e :
2022-08-31 19:20:49 +03:00
log_error ( " update_thread: \n %s " % extract_stack_trace ( e ) )
_handle_error ( )
2022-08-31 23:04:59 +03:00
finally :
cfg . lvmdebug . complete ( )
2016-11-10 21:19:48 +03:00
2022-08-18 01:21:19 +03:00
# Make sure to unblock any that may be waiting before we exit this thread
# otherwise they hang forever ...
bailing ( Exception ( " update thread exiting " ) )
log_debug ( " update thread exiting! " )
2016-11-10 21:19:48 +03:00
def __init__ ( self ) :
self . lock = threading . RLock ( )
self . queue = queue . Queue ( )
self . deferred = False
2023-03-09 20:29:58 +03:00
# Do initial load, with retries. During error injection testing we can and do fail here.
count = 0
need_refresh = False # First attempt we are building from new, any subsequent will be true
while count < 5 :
try :
load ( refresh = need_refresh , emit_signal = False , need_main_thread = False )
break
except LvmBug as bug :
count + = 1
need_refresh = True
log_error ( " We encountered an lvm bug on initial load, trying again %s " % str ( bug ) )
2016-11-10 21:19:48 +03:00
self . thread = threading . Thread ( target = StateUpdate . update_thread ,
2017-09-25 23:18:43 +03:00
args = ( self , ) ,
name = " StateUpdate.update_thread " )
2016-11-10 21:19:48 +03:00
def load ( self , refresh = True , emit_signal = True , cache_refresh = True ,
log = True , need_main_thread = True ) :
# Place this request on the queue and wait for it to be completed
req = StateUpdate . UpdateRequest ( refresh , emit_signal , cache_refresh ,
log , need_main_thread )
self . queue . put ( req )
return req . done ( )
def event ( self ) :
with self . lock :
self . deferred = True