mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-22 17:35:59 +03:00
2bb09b4015
The python dbus library tries to make best on what the dbus type is based on python data type. Some times it gets this wrong, so we will be explicit.
958 lines
28 KiB
Python
958 lines
28 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 .automatedproperties import AutomatedProperties
|
|
|
|
from . import utils
|
|
from .utils import pv_obj_path_generate, vg_obj_path_generate, n
|
|
import dbus
|
|
from . import cfg
|
|
from .cfg import VG_INTERFACE
|
|
from . import cmdhandler
|
|
from .request import RequestEntry
|
|
from .loader import common
|
|
from .state import State
|
|
from . import background
|
|
from .utils import round_size
|
|
from .job import JobState
|
|
|
|
|
|
# noinspection PyUnusedLocal
|
|
def vgs_state_retrieve(selection, cache_refresh=True):
|
|
rc = []
|
|
|
|
if cache_refresh:
|
|
cfg.db.refresh()
|
|
|
|
for v in cfg.db.fetch_vgs(selection):
|
|
rc.append(
|
|
VgState(
|
|
v['vg_uuid'], v['vg_name'], v['vg_fmt'], n(v['vg_size']),
|
|
n(v['vg_free']), v['vg_sysid'], n(v['vg_extent_size']),
|
|
n(v['vg_extent_count']), n(v['vg_free_count']),
|
|
v['vg_profile'], n(v['max_lv']), n(v['max_pv']),
|
|
n(v['pv_count']), n(v['lv_count']), n(v['snap_count']),
|
|
n(v['vg_seqno']), n(v['vg_mda_count']),
|
|
n(v['vg_mda_free']), n(v['vg_mda_size']),
|
|
n(v['vg_mda_used_count']), v['vg_attr'], v['vg_tags']))
|
|
return rc
|
|
|
|
|
|
def load_vgs(vg_specific=None, object_path=None, refresh=False,
|
|
emit_signal=False, cache_refresh=True):
|
|
return common(vgs_state_retrieve, (Vg,), vg_specific, object_path, refresh,
|
|
emit_signal, cache_refresh)
|
|
|
|
|
|
# noinspection PyPep8Naming,PyUnresolvedReferences,PyUnusedLocal
|
|
class VgState(State):
|
|
@property
|
|
def lvm_id(self):
|
|
return self.Name
|
|
|
|
def identifiers(self):
|
|
return (self.Uuid, self.Name)
|
|
|
|
def _lv_paths_build(self):
|
|
rc = []
|
|
for lv in cfg.db.lvs_in_vg(self.Uuid):
|
|
(lv_name, meta, lv_uuid) = lv
|
|
full_name = "%s/%s" % (self.Name, lv_name)
|
|
|
|
gen = utils.lv_object_path_method(lv_name, meta)
|
|
|
|
lv_path = cfg.om.get_object_path_by_uuid_lvm_id(
|
|
lv_uuid, full_name, gen)
|
|
rc.append(lv_path)
|
|
return dbus.Array(rc, signature='o')
|
|
|
|
def _pv_paths_build(self):
|
|
rc = []
|
|
for p in cfg.db.pvs_in_vg(self.Uuid):
|
|
(pv_name, pv_uuid) = p
|
|
rc.append(cfg.om.get_object_path_by_uuid_lvm_id(
|
|
pv_uuid, pv_name, pv_obj_path_generate))
|
|
return rc
|
|
|
|
def __init__(self, Uuid, Name, Fmt,
|
|
SizeBytes, FreeBytes, SysId, ExtentSizeBytes,
|
|
ExtentCount, FreeCount, Profile, MaxLv, MaxPv, PvCount,
|
|
LvCount, SnapCount, Seqno, MdaCount, MdaFree,
|
|
MdaSizeBytes, MdaUsedCount, attr, tags):
|
|
utils.init_class_from_arguments(self)
|
|
self.Pvs = self._pv_paths_build()
|
|
self.Lvs = self._lv_paths_build()
|
|
|
|
def create_dbus_object(self, path):
|
|
if not path:
|
|
path = cfg.om.get_object_path_by_uuid_lvm_id(
|
|
self.Uuid, self.Name, vg_obj_path_generate)
|
|
return Vg(path, self)
|
|
|
|
# noinspection PyMethodMayBeStatic
|
|
def creation_signature(self):
|
|
return (Vg, vg_obj_path_generate)
|
|
|
|
|
|
# noinspection PyPep8Naming
|
|
@utils.dbus_property(VG_INTERFACE, 'Uuid', 's')
|
|
@utils.dbus_property(VG_INTERFACE, 'Name', 's')
|
|
@utils.dbus_property(VG_INTERFACE, 'Fmt', 's')
|
|
@utils.dbus_property(VG_INTERFACE, 'SizeBytes', 't', 0)
|
|
@utils.dbus_property(VG_INTERFACE, 'FreeBytes', 't', 0)
|
|
@utils.dbus_property(VG_INTERFACE, 'SysId', 's')
|
|
@utils.dbus_property(VG_INTERFACE, 'ExtentSizeBytes', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'ExtentCount', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'FreeCount', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'Profile', 's')
|
|
@utils.dbus_property(VG_INTERFACE, 'MaxLv', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'MaxPv', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'PvCount', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'LvCount', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'SnapCount', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'Seqno', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'MdaCount', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'MdaFree', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'MdaSizeBytes', 't')
|
|
@utils.dbus_property(VG_INTERFACE, 'MdaUsedCount', 't')
|
|
class Vg(AutomatedProperties):
|
|
_Tags_meta = ("as", VG_INTERFACE)
|
|
_Pvs_meta = ("ao", VG_INTERFACE)
|
|
_Lvs_meta = ("ao", VG_INTERFACE)
|
|
_Writeable_meta = ("b", VG_INTERFACE)
|
|
_Readable_meta = ("b", VG_INTERFACE)
|
|
_Resizeable_meta = ("b", VG_INTERFACE)
|
|
_Exportable_meta = ('b', VG_INTERFACE)
|
|
_Partial_meta = ('b', VG_INTERFACE)
|
|
_AllocContiguous_meta = ('b', VG_INTERFACE)
|
|
_AllocCling_meta = ('b', VG_INTERFACE)
|
|
_AllocNormal_meta = ('b', VG_INTERFACE)
|
|
_AllocAnywhere_meta = ('b', VG_INTERFACE)
|
|
_Clustered_meta = ('b', VG_INTERFACE)
|
|
|
|
# noinspection PyUnusedLocal,PyPep8Naming
|
|
def __init__(self, object_path, object_state):
|
|
super(Vg, self).__init__(object_path, vgs_state_retrieve)
|
|
self.set_interface(VG_INTERFACE)
|
|
self._object_path = object_path
|
|
self.state = object_state
|
|
|
|
@staticmethod
|
|
def fetch_new_lv(vg_name, lv_name):
|
|
cfg.load()
|
|
return cfg.om.get_object_by_lvm_id("%s/%s" % (vg_name, lv_name))
|
|
|
|
@staticmethod
|
|
def _rename(uuid, vg_name, new_name, rename_options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
rc, out, err = cmdhandler.vg_rename(vg_name, new_name,
|
|
rename_options)
|
|
if rc == 0:
|
|
cfg.load()
|
|
else:
|
|
# Need to work on error handling, need consistent
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
return '/'
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='sia{sv}', out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def Rename(self, name, tmo, rename_options, cb, cbe):
|
|
utils.validate_vg_name(VG_INTERFACE, name)
|
|
r = RequestEntry(tmo, Vg._rename,
|
|
(self.state.Uuid, self.state.lvm_id, name,
|
|
rename_options), cb, cbe, False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _remove(uuid, vg_name, remove_options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
# Remove the VG, if successful then remove from the model
|
|
rc, out, err = cmdhandler.vg_remove(vg_name, remove_options)
|
|
|
|
if rc == 0:
|
|
# Remove the VG
|
|
cfg.om.remove_object(dbo, True)
|
|
|
|
# If an LV has hidden LVs, things can get quite involved,
|
|
# especially if it's the last thin pool to get removed, so
|
|
# lets refresh all
|
|
cfg.load()
|
|
|
|
else:
|
|
# Need to work on error handling, need consistent
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
return '/'
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='ia{sv}', out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def Remove(self, tmo, remove_options, cb, cbe):
|
|
r = RequestEntry(tmo, Vg._remove,
|
|
(self.state.Uuid, self.state.lvm_id, remove_options),
|
|
cb, cbe, False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _change(uuid, vg_name, change_options):
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
rc, out, err = cmdhandler.vg_change(change_options, vg_name)
|
|
|
|
# To use an example with d-feet (Method input)
|
|
# {"activate": __import__('gi.repository.GLib', globals(),
|
|
# locals(), ['Variant']).Variant("s", "n")}
|
|
|
|
if rc == 0:
|
|
cfg.load()
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
return '/'
|
|
|
|
# TODO: This should be broken into a number of different methods
|
|
# instead of having one method that takes a hash for parameters. Some of
|
|
# the changes that vgchange does works on entire system, not just a
|
|
# specfic vg, thus that should be in the Manager interface.
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='ia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def Change(self, tmo, change_options, cb, cbe):
|
|
r = RequestEntry(tmo, Vg._change,
|
|
(self.state.Uuid, self.state.lvm_id, change_options),
|
|
cb, cbe, False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _reduce(uuid, vg_name, missing, pv_object_paths, reduce_options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
pv_devices = []
|
|
|
|
# If pv_object_paths is not empty, then get the device paths
|
|
if pv_object_paths and len(pv_object_paths) > 0:
|
|
for pv_op in pv_object_paths:
|
|
pv = cfg.om.get_object_by_path(pv_op)
|
|
if pv:
|
|
pv_devices.append(pv.lvm_id)
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'PV Object path not found = %s!' % pv_op)
|
|
|
|
rc, out, err = cmdhandler.vg_reduce(vg_name, missing, pv_devices,
|
|
reduce_options)
|
|
if rc == 0:
|
|
cfg.load()
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE, 'Exit code %s, stderr = %s' % (str(rc), err))
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
return '/'
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='baoia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def Reduce(self, missing, pv_object_paths, tmo, reduce_options, cb, cbe):
|
|
r = RequestEntry(tmo, Vg._reduce,
|
|
(self.state.Uuid, self.state.lvm_id, missing,
|
|
pv_object_paths, reduce_options), cb, cbe, False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _extend(uuid, vg_name, pv_object_paths, extend_options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
extend_devices = []
|
|
|
|
for i in pv_object_paths:
|
|
pv = cfg.om.get_object_by_path(i)
|
|
if pv:
|
|
extend_devices.append(pv.lvm_id)
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE, 'PV Object path not found = %s!' % i)
|
|
|
|
if len(extend_devices):
|
|
rc, out, err = cmdhandler.vg_extend(vg_name, extend_devices,
|
|
extend_options)
|
|
if rc == 0:
|
|
cfg.load()
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE, 'No pv_object_paths provided!')
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
return '/'
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='aoia{sv}', out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def Extend(self, pv_object_paths, tmo, extend_options, cb, cbe):
|
|
r = RequestEntry(tmo, Vg._extend,
|
|
(self.state.Uuid, self.state.lvm_id, pv_object_paths,
|
|
extend_options),
|
|
cb, cbe, False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='o(tt)a(ott)ia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def Move(self, pv_src_obj, pv_source_range, pv_dests_and_ranges,
|
|
tmo, move_options, cb, cbe):
|
|
|
|
job_state = JobState()
|
|
|
|
r = RequestEntry(
|
|
tmo, background.move,
|
|
(VG_INTERFACE, None, pv_src_obj, pv_source_range,
|
|
pv_dests_and_ranges, move_options, job_state), cb, cbe, False,
|
|
job_state)
|
|
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _lv_create(uuid, vg_name, name, size_bytes, pv_dests_and_ranges,
|
|
create_options):
|
|
# Make sure we have a dbus object representing it
|
|
pv_dests = []
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
if len(pv_dests_and_ranges):
|
|
for pr in pv_dests_and_ranges:
|
|
pv_dbus_obj = cfg.om.get_object_by_path(pr[0])
|
|
if not pv_dbus_obj:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'PV Destination (%s) not found' % pr[0])
|
|
|
|
pv_dests.append((pv_dbus_obj.lvm_id, pr[1], pr[2]))
|
|
|
|
rc, out, err = cmdhandler.vg_lv_create(
|
|
vg_name, create_options, name, size_bytes, pv_dests)
|
|
|
|
if rc == 0:
|
|
return Vg.fetch_new_lv(vg_name, name)
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='sta(ott)ia{sv}',
|
|
out_signature='(oo)',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def LvCreate(self, name, size_bytes, pv_dests_and_ranges,
|
|
tmo, create_options, cb, cbe):
|
|
"""
|
|
This one it for the advanced users that want to roll their own
|
|
:param name: Name of the LV
|
|
:param size_bytes: Size of LV in bytes
|
|
:param pv_dests_and_ranges: Optional array of PV object paths and
|
|
ranges
|
|
:param tmo: -1 == Wait forever, 0 == return job immediately, > 0 ==
|
|
willing to wait that number of seconds before
|
|
getting a job
|
|
:param create_options: hash of key/value pairs
|
|
:param cb: Internal, not accessible by dbus API user
|
|
:param cbe: Internal, not accessible by dbus API user
|
|
:return: (oo) First object path is newly created object, second is
|
|
job object path if created. Each == '/' when it doesn't
|
|
apply.
|
|
"""
|
|
utils.validate_lv_name(VG_INTERFACE, self.Name, name)
|
|
r = RequestEntry(tmo, Vg._lv_create,
|
|
(self.state.Uuid, self.state.lvm_id,
|
|
name, round_size(size_bytes), pv_dests_and_ranges,
|
|
create_options), cb, cbe)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _lv_create_linear(uuid, vg_name, name, size_bytes,
|
|
thin_pool, create_options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
rc, out, err = cmdhandler.vg_lv_create_linear(
|
|
vg_name, create_options, name, size_bytes, thin_pool)
|
|
|
|
if rc == 0:
|
|
created_lv = Vg.fetch_new_lv(vg_name, name)
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
|
|
return created_lv
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='stbia{sv}',
|
|
out_signature='(oo)',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def LvCreateLinear(self, name, size_bytes,
|
|
thin_pool, tmo, create_options, cb, cbe):
|
|
utils.validate_lv_name(VG_INTERFACE, self.Name, name)
|
|
r = RequestEntry(tmo, Vg._lv_create_linear,
|
|
(self.state.Uuid, self.state.lvm_id,
|
|
name, round_size(size_bytes), thin_pool,
|
|
create_options), cb, cbe)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _lv_create_striped(uuid, vg_name, name, size_bytes, num_stripes,
|
|
stripe_size_kb, thin_pool, create_options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
rc, out, err = cmdhandler.vg_lv_create_striped(
|
|
vg_name, create_options, name, size_bytes,
|
|
num_stripes, stripe_size_kb, thin_pool)
|
|
if rc == 0:
|
|
created_lv = Vg.fetch_new_lv(vg_name, name)
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE, 'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
|
|
return created_lv
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='stuubia{sv}',
|
|
out_signature='(oo)',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def LvCreateStriped(self, name, size_bytes, num_stripes,
|
|
stripe_size_kb, thin_pool, tmo, create_options,
|
|
cb, cbe):
|
|
utils.validate_lv_name(VG_INTERFACE, self.Name, name)
|
|
r = RequestEntry(
|
|
tmo, Vg._lv_create_striped,
|
|
(self.state.Uuid, self.state.lvm_id, name,
|
|
round_size(size_bytes), num_stripes, stripe_size_kb,
|
|
thin_pool, create_options),
|
|
cb, cbe)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _lv_create_mirror(uuid, vg_name, name, size_bytes,
|
|
num_copies, create_options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
rc, out, err = cmdhandler.vg_lv_create_mirror(
|
|
vg_name, create_options, name, size_bytes, num_copies)
|
|
if rc == 0:
|
|
created_lv = Vg.fetch_new_lv(vg_name, name)
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
|
|
return created_lv
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='stuia{sv}',
|
|
out_signature='(oo)',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def LvCreateMirror(self, name, size_bytes, num_copies,
|
|
tmo, create_options, cb, cbe):
|
|
utils.validate_lv_name(VG_INTERFACE, self.Name, name)
|
|
r = RequestEntry(
|
|
tmo, Vg._lv_create_mirror,
|
|
(self.state.Uuid, self.state.lvm_id, name,
|
|
round_size(size_bytes), num_copies,
|
|
create_options), cb, cbe)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _lv_create_raid(uuid, vg_name, name, raid_type, size_bytes,
|
|
num_stripes, stripe_size_kb, create_options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
rc, out, err = cmdhandler.vg_lv_create_raid(
|
|
vg_name, create_options, name, raid_type, size_bytes,
|
|
num_stripes, stripe_size_kb)
|
|
if rc == 0:
|
|
created_lv = Vg.fetch_new_lv(vg_name, name)
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
|
|
return created_lv
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='sstuuia{sv}',
|
|
out_signature='(oo)',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def LvCreateRaid(self, name, raid_type, size_bytes,
|
|
num_stripes, stripe_size_kb, tmo,
|
|
create_options, cb, cbe):
|
|
utils.validate_lv_name(VG_INTERFACE, self.Name, name)
|
|
r = RequestEntry(tmo, Vg._lv_create_raid,
|
|
(self.state.Uuid, self.state.lvm_id, name,
|
|
raid_type, round_size(size_bytes), num_stripes,
|
|
stripe_size_kb, create_options), cb, cbe)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _create_pool(uuid, vg_name, meta_data_lv, data_lv,
|
|
create_options, create_method):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
# Retrieve the full names for the metadata and data lv
|
|
md = cfg.om.get_object_by_path(meta_data_lv)
|
|
data = cfg.om.get_object_by_path(data_lv)
|
|
|
|
if dbo and md and data:
|
|
|
|
new_name = data.Name
|
|
|
|
rc, out, err = create_method(
|
|
md.lv_full_name(), data.lv_full_name(), create_options)
|
|
if rc == 0:
|
|
cfg.om.remove_object(md, emit_signal=True)
|
|
cfg.om.remove_object(data, emit_signal=True)
|
|
|
|
cache_pool_lv = Vg.fetch_new_lv(vg_name, new_name)
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
|
|
else:
|
|
msg = ""
|
|
|
|
if not dbo:
|
|
msg += 'VG with uuid %s and name %s not present!' % \
|
|
(uuid, vg_name)
|
|
|
|
if not md:
|
|
msg += 'Meta data LV with object path %s not present!' % \
|
|
(meta_data_lv)
|
|
|
|
if not data_lv:
|
|
msg += 'Data LV with object path %s not present!' % \
|
|
(meta_data_lv)
|
|
|
|
raise dbus.exceptions.DBusException(VG_INTERFACE, msg)
|
|
|
|
return cache_pool_lv
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='ooia{sv}',
|
|
out_signature='(oo)',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def CreateCachePool(self, meta_data_lv, data_lv, tmo, create_options,
|
|
cb, cbe):
|
|
r = RequestEntry(
|
|
tmo, Vg._create_pool,
|
|
(self.state.Uuid, self.state.lvm_id, meta_data_lv,
|
|
data_lv, create_options, cmdhandler.vg_create_cache_pool), cb, cbe)
|
|
cfg.worker_q.put(r)
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='ooia{sv}',
|
|
out_signature='(oo)',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def CreateThinPool(self, meta_data_lv, data_lv, tmo, create_options,
|
|
cb, cbe):
|
|
r = RequestEntry(
|
|
tmo, Vg._create_pool,
|
|
(self.state.Uuid, self.state.lvm_id, meta_data_lv,
|
|
data_lv, create_options, cmdhandler.vg_create_thin_pool), cb, cbe)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _pv_add_rm_tags(uuid, vg_name, pv_object_paths, tags_add,
|
|
tags_del, tag_options):
|
|
pv_devices = []
|
|
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
# Check for existence of pv object paths
|
|
for p in pv_object_paths:
|
|
pv = cfg.om.get_object_by_path(p)
|
|
if pv:
|
|
pv_devices.append(pv.Name)
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE, 'PV object path = %s not found' % p)
|
|
|
|
rc, out, err = cmdhandler.pv_tag(
|
|
pv_devices, tags_add, tags_del, tag_options)
|
|
if rc == 0:
|
|
cfg.load()
|
|
return '/'
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='aoasia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def PvTagsAdd(self, pvs, tags, tmo, tag_options, cb, cbe):
|
|
|
|
for t in tags:
|
|
utils.validate_tag(VG_INTERFACE, t)
|
|
|
|
r = RequestEntry(tmo, Vg._pv_add_rm_tags,
|
|
(self.state.Uuid, self.state.lvm_id,
|
|
pvs, tags, None, tag_options),
|
|
cb, cbe, return_tuple=False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='aoasia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def PvTagsDel(self, pvs, tags, tmo, tag_options, cb, cbe):
|
|
|
|
for t in tags:
|
|
utils.validate_tag(VG_INTERFACE, t)
|
|
|
|
r = RequestEntry(
|
|
tmo, Vg._pv_add_rm_tags,
|
|
(self.state.Uuid, self.state.lvm_id,
|
|
pvs, None, tags, tag_options),
|
|
cb, cbe, return_tuple=False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _vg_add_rm_tags(uuid, vg_name, tags_add, tags_del, tag_options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
|
|
rc, out, err = cmdhandler.vg_tag(
|
|
vg_name, tags_add, tags_del, tag_options)
|
|
if rc == 0:
|
|
dbo.refresh()
|
|
return '/'
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='asia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def TagsAdd(self, tags, tmo, tag_options, cb, cbe):
|
|
|
|
for t in tags:
|
|
utils.validate_tag(VG_INTERFACE, t)
|
|
|
|
r = RequestEntry(tmo, Vg._vg_add_rm_tags,
|
|
(self.state.Uuid, self.state.lvm_id,
|
|
tags, None, tag_options),
|
|
cb, cbe, return_tuple=False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='asia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def TagsDel(self, tags, tmo, tag_options, cb, cbe):
|
|
|
|
for t in tags:
|
|
utils.validate_tag(VG_INTERFACE, t)
|
|
|
|
r = RequestEntry(tmo, Vg._vg_add_rm_tags,
|
|
(self.state.Uuid, self.state.lvm_id,
|
|
None, tags, tag_options),
|
|
cb, cbe, return_tuple=False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _vg_change_set(uuid, vg_name, method, value, options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
rc, out, err = method(vg_name, value, options)
|
|
if rc == 0:
|
|
dbo.refresh()
|
|
return '/'
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='sia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def AllocationPolicySet(self, policy, tmo, policy_options, cb, cbe):
|
|
r = RequestEntry(tmo, Vg._vg_change_set,
|
|
(self.state.Uuid, self.state.lvm_id,
|
|
cmdhandler.vg_allocation_policy,
|
|
policy, policy_options),
|
|
cb, cbe, return_tuple=False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='tia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def MaxPvSet(self, number, tmo, max_options, cb, cbe):
|
|
r = RequestEntry(tmo, Vg._vg_change_set,
|
|
(self.state.Uuid, self.state.lvm_id,
|
|
cmdhandler.vg_max_pv, number, max_options),
|
|
cb, cbe, return_tuple=False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='ia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def UuidGenerate(self, tmo, options, cb, cbe):
|
|
r = RequestEntry(tmo, Vg._vg_change_set,
|
|
(self.state.Uuid, self.state.lvm_id,
|
|
cmdhandler.vg_uuid_gen, None, options),
|
|
cb, cbe, return_tuple=False)
|
|
cfg.worker_q.put(r)
|
|
|
|
def _attribute(self, pos, ch):
|
|
return dbus.Boolean(self.state.attr[pos] == ch)
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='tia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def MaxLvSet(self, number, tmo, max_options, cb, cbe):
|
|
r = RequestEntry(tmo, Vg._vg_change_set,
|
|
(self.state.Uuid, self.state.lvm_id,
|
|
cmdhandler.vg_max_lv, number, max_options),
|
|
cb, cbe, return_tuple=False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@staticmethod
|
|
def _vg_activate_deactivate(uuid, vg_name, activate, control_flags,
|
|
options):
|
|
# Make sure we have a dbus object representing it
|
|
dbo = cfg.om.get_object_by_uuid_lvm_id(uuid, vg_name)
|
|
|
|
if dbo:
|
|
rc, out, err = cmdhandler.activate_deactivate(
|
|
'vgchange', vg_name, activate, control_flags, options)
|
|
if rc == 0:
|
|
cfg.load()
|
|
return '/'
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'Exit code %s, stderr = %s' % (str(rc), err))
|
|
else:
|
|
raise dbus.exceptions.DBusException(
|
|
VG_INTERFACE,
|
|
'VG with uuid %s and name %s not present!' %
|
|
(uuid, vg_name))
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='tia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def Activate(self, control_flags, tmo, activate_options, cb, cbe):
|
|
r = RequestEntry(tmo, Vg._vg_activate_deactivate,
|
|
(self.state.Uuid, self.state.lvm_id, True,
|
|
control_flags, activate_options),
|
|
cb, cbe, return_tuple=False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@dbus.service.method(
|
|
dbus_interface=VG_INTERFACE,
|
|
in_signature='tia{sv}',
|
|
out_signature='o',
|
|
async_callbacks=('cb', 'cbe'))
|
|
def Deactivate(self, control_flags, tmo, activate_options, cb, cbe):
|
|
r = RequestEntry(tmo, Vg._vg_activate_deactivate,
|
|
(self.state.Uuid, self.state.lvm_id, False,
|
|
control_flags, activate_options),
|
|
cb, cbe, return_tuple=False)
|
|
cfg.worker_q.put(r)
|
|
|
|
@property
|
|
def Tags(self):
|
|
return utils.parse_tags(self.state.tags)
|
|
|
|
@property
|
|
def Pvs(self):
|
|
return dbus.Array(self.state.Pvs, signature='o')
|
|
|
|
@property
|
|
def Lvs(self):
|
|
return dbus.Array(self.state.Lvs, signature='o')
|
|
|
|
@property
|
|
def lvm_id(self):
|
|
return self.state.lvm_id
|
|
|
|
@property
|
|
def Writeable(self):
|
|
return self._attribute(0, 'w')
|
|
|
|
@property
|
|
def Readable(self):
|
|
return self._attribute(0, 'r')
|
|
|
|
@property
|
|
def Resizeable(self):
|
|
return self._attribute(1, 'z')
|
|
|
|
@property
|
|
def Exportable(self):
|
|
return self._attribute(2, 'x')
|
|
|
|
@property
|
|
def Partial(self):
|
|
return self._attribute(3, 'p')
|
|
|
|
@property
|
|
def AllocContiguous(self):
|
|
return self._attribute(4, 'c')
|
|
|
|
@property
|
|
def AllocCling(self):
|
|
return self._attribute(4, 'l')
|
|
|
|
@property
|
|
def AllocNormal(self):
|
|
return self._attribute(4, 'n')
|
|
|
|
@property
|
|
def AllocAnywhere(self):
|
|
return self._attribute(4, 'a')
|
|
|
|
@property
|
|
def Clustered(self):
|
|
return self._attribute(5, 'c')
|