mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-22 17:35:59 +03:00
959 lines
28 KiB
Python
959 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
|
|
|
|
|
|
# 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_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_lvm_id(
|
|
pv_uuid, pv_name, pv_obj_path_generate))
|
|
return dbus.Array(rc, signature='o')
|
|
|
|
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_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):
|
|
full_name = "%s/%s" % (vg_name, lv_name)
|
|
|
|
cfg.load()
|
|
l = cfg.om.get_object_by_lvm_id(full_name)
|
|
created_lv = l.dbus_object_path()
|
|
|
|
return created_lv
|
|
|
|
@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:
|
|
dbo.refresh()
|
|
|
|
if (('activate' in change_options) or ('-a' in change_options)):
|
|
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')
|
|
def Move(self, pv_src_obj, pv_source_range, pv_dests_and_ranges,
|
|
tmo, move_options):
|
|
return background.move(
|
|
VG_INTERFACE, None, pv_src_obj, pv_source_range,
|
|
pv_dests_and_ranges, move_options, tmo)
|
|
|
|
@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):
|
|
if self.state.attr[pos] == ch:
|
|
return True
|
|
return False
|
|
|
|
@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 self.state.Pvs
|
|
|
|
@property
|
|
def Lvs(self):
|
|
return self.state.Lvs
|
|
|
|
@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')
|