| # 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 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_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): |
| 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') |