1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-28 03:27:58 +03:00
lvm2/daemons/lvmdbusd/main.py

180 lines
4.8 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/>.
from . import cfg
from . import objectmanager
from . import utils
from .cfg import BUS_NAME, BASE_INTERFACE, BASE_OBJ_PATH, MANAGER_OBJ_PATH
import threading
from . import cmdhandler
import time
import signal
import dbus
import dbus.mainloop.glib
from . import lvmdb
# noinspection PyUnresolvedReferences
from gi.repository import GLib
from .fetch import StateUpdate
from .manager import Manager
import traceback
import queue
from . import udevwatch
from .utils import log_debug, log_error
import argparse
import os
import sys
from .cmdhandler import LvmFlightRecorder
class Lvm(objectmanager.ObjectManager):
def __init__(self, object_path):
super(Lvm, self).__init__(object_path, BASE_INTERFACE)
def process_request():
while cfg.run.value != 0:
# noinspection PyBroadException
try:
req = cfg.worker_q.get(True, 5)
log_debug(
"Running method: %s with args %s" %
(str(req.method), str(req.arguments)))
req.run_cmd()
log_debug("Method complete ")
except queue.Empty:
pass
except Exception:
st = traceback.format_exc()
utils.log_error("process_request exception: \n%s" % st)
def check_bb_size(value):
v = int(value)
if v < 0:
raise argparse.ArgumentTypeError(
"positive integers only ('%s' invalid)" % value)
return v
def main():
start = time.time()
# Add simple command line handling
parser = argparse.ArgumentParser()
parser.add_argument(
"--udev", action='store_true',
help="Use udev for updating state",
default=False,
dest='use_udev')
parser.add_argument(
"--debug", action='store_true',
help="Dump debug messages", default=False,
dest='debug')
parser.add_argument(
"--nojson", action='store_false',
help="Do not use LVM JSON output (disables lvmshell)", default=True,
dest='use_json')
parser.add_argument(
"--lvmshell", action='store_true',
help="Use the lvm shell, not fork & exec lvm",
default=False,
dest='use_lvm_shell')
parser.add_argument(
"--blackboxsize",
help="Size of the black box flight recorder, 0 to disable",
default=10,
type=check_bb_size,
dest='bb_size')
use_session = os.getenv('LVMDBUSD_USE_SESSION', False)
# Ensure that we get consistent output for parsing stdout/stderr
os.environ["LC_ALL"] = "C"
cfg.args = parser.parse_args()
# We create a flight recorder in cmdhandler too, but we replace it here
# as the user may be specifying a different size. The default one in
# cmdhandler is for when we are running other code with a different main.
cfg.blackbox = LvmFlightRecorder(cfg.args.bb_size)
if cfg.args.use_lvm_shell and not cfg.args.use_json:
log_error("You cannot specify --lvmshell and --nojson")
sys.exit(1)
# List of threads that we start up
thread_list = []
# Install signal handlers
for s in [signal.SIGHUP, signal.SIGINT]:
try:
signal.signal(s, utils.handler)
except RuntimeError:
pass
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
dbus.mainloop.glib.threads_init()
cmdhandler.set_execution(cfg.args.use_lvm_shell)
if use_session:
cfg.bus = dbus.SessionBus()
else:
cfg.bus = dbus.SystemBus()
# The base name variable needs to exist for things to work.
# noinspection PyUnusedLocal
base_name = dbus.service.BusName(BUS_NAME, cfg.bus)
cfg.om = Lvm(BASE_OBJ_PATH)
cfg.om.register_object(Manager(MANAGER_OBJ_PATH))
cfg.db = lvmdb.DataStore(cfg.args.use_json)
# Using a thread to process requests, we cannot hang the dbus library
# thread that is handling the dbus interface
thread_list.append(threading.Thread(target=process_request))
# Have a single thread handling updating lvm and the dbus model so we
# don't have multiple threads doing this as the same time
updater = StateUpdate()
thread_list.append(updater.thread)
cfg.load = updater.load
cfg.event = updater.event
cfg.loop = GLib.MainLoop()
for thread in thread_list:
thread.damon = True
thread.start()
# Add udev watching
if cfg.args.use_udev:
log_debug('Utilizing udev to trigger updates')
# In all cases we are going to monitor for udev until we get an
# ExternalEvent. In the case where we get an external event and the user
# didn't specify --udev we will stop monitoring udev
udevwatch.add()
end = time.time()
log_debug(
'Service ready! total time= %.4f, lvm time= %.4f count= %d' %
(end - start, cmdhandler.total_time, cmdhandler.total_count),
'bg_black', 'fg_light_green')
try:
if cfg.run.value != 0:
cfg.loop.run()
udevwatch.remove()
for thread in thread_list:
thread.join()
except KeyboardInterrupt:
utils.handler(signal.SIGINT, None)
return 0