_IES_CA_FILE = "ca"
#: Valid LVS output line regex
-_LVSLINE_REGEX = re.compile("^ *([^|]+)\|([0-9.]+)\|([^|]{6})\|?$")
+_LVSLINE_REGEX = re.compile("^ *([^|]+)\|([^|]+)\|([0-9.]+)\|([^|]{6})\|?$")
class RPCFail(Exception):
if constants.NV_LVLIST in what and vm_capable:
try:
- val = GetVolumeList(what[constants.NV_LVLIST])
+ val = GetVolumeList(utils.ListVolumeGroups().keys())
except RPCFail, err:
val = str(err)
result[constants.NV_LVLIST] = val
return result
-def GetVolumeList(vg_name):
+def GetVolumeList(vg_names):
"""Compute list of logical volumes and their size.
- @type vg_name: str
- @param vg_name: the volume group whose LVs we should list
+ @type vg_names: list
+ @param vg_names: the volume groups whose LVs we should list
@rtype: dict
@return:
dictionary of all partions (key) with value being a tuple of
their size (in MiB), inactive and online status::
- {'test1': ('20.06', True, True)}
+ {'xenvg/test1': ('20.06', True, True)}
in case of errors, a string is returned with the error
details.
sep = '|'
result = utils.RunCmd(["lvs", "--noheadings", "--units=m", "--nosuffix",
"--separator=%s" % sep,
- "-olv_name,lv_size,lv_attr", vg_name])
+ "-ovg_name,lv_name,lv_size,lv_attr"] + vg_names)
if result.failed:
_Fail("Failed to list logical volumes, lvs output: %s", result.output)
if not match:
logging.error("Invalid line returned from lvs output: '%s'", line)
continue
- name, size, attr = match.groups()
+ vg_name, name, size, attr = match.groups()
inactive = attr[4] == '-'
online = attr[5] == 'o'
virtual = attr[0] == 'v'
# we don't want to report such volumes as existing, since they
# don't really hold data
continue
- lvs[name] = (size, inactive, online)
+ lvs[vg_name+"/"+name] = (size, inactive, online)
return lvs
"""
result = res_nodes, res_instances, res_missing = {}, [], {}
- vg_name = self.cfg.GetVGName()
nodes = utils.NiceSort(self.cfg.GetNodeList())
instances = [self.cfg.GetInstanceInfo(name)
for name in self.cfg.GetInstanceList()]
if not nv_dict:
return result
- node_lvs = self.rpc.call_lv_list(nodes, vg_name)
+ vg_names = self.rpc.call_vg_list(nodes)
+ vg_names.Raise("Cannot get list of VGs")
for node in nodes:
# node_volume
- node_res = node_lvs[node]
+ node_res = self.rpc.call_lv_list([node],
+ vg_names[node].payload.keys())[node]
if node_res.offline:
continue
msg = node_res.fail_msg
_CheckNodesFreeDiskPerVG(self, nodenames, req_sizes)
else: # instead, we must check the adoption data
- all_lvs = set([i["adopt"] for i in self.disks])
+ all_lvs = set([i["vg"] + "/" + i["adopt"] for i in self.disks])
if len(all_lvs) != len(self.disks):
raise errors.OpPrereqError("Duplicate volume names given for adoption",
errors.ECODE_INVAL)
for lv_name in all_lvs:
try:
- # FIXME: VG must be provided here. Else all LVs with the
- # same name will be locked on all VGs.
+ # FIXME: lv_name here is "vg/lv" need to ensure that other calls
+ # to ReserveLV uses the same syntax
self.cfg.ReserveLV(lv_name, self.proc.GetECId())
except errors.ReservationError:
raise errors.OpPrereqError("LV named %s used by another instance" %
lv_name, errors.ECODE_NOTUNIQUE)
+ vg_names = self.rpc.call_vg_list([pnode.name])
+ vg_names.Raise("Cannot get VG information from node %s" % pnode.name)
+
node_lvs = self.rpc.call_lv_list([pnode.name],
- self.cfg.GetVGName())[pnode.name]
+ vg_names[pnode.name].payload.keys()
+ )[pnode.name]
node_lvs.Raise("Cannot get LV information from node %s" % pnode.name)
node_lvs = node_lvs.payload
+
delta = all_lvs.difference(node_lvs.keys())
if delta:
raise errors.OpPrereqError("Missing logical volume(s): %s" %
errors.ECODE_STATE)
# update the size of disk based on what is found
for dsk in self.disks:
- dsk["size"] = int(float(node_lvs[dsk["adopt"]][0]))
+ dsk["size"] = int(float(node_lvs[dsk["vg"] + "/" + dsk["adopt"]][0]))
_CheckHVParams(self, nodenames, self.op.hypervisor, self.op.hvparams)
@param lvmap: optional dictionary to receive the
'node' : ['lv', ...] data.
- @return: None if lvmap arg is given, otherwise, a dictionary
- of the form { 'nodename' : ['volume1', 'volume2', ...], ... }
+ @return: None if lvmap arg is given, otherwise, a dictionary of
+ the form { 'nodename' : ['volume1', 'volume2', ...], ... };
+ volumeN is of the form "vg_name/lv_name", compatible with
+ GetVolumeList()
"""
if node == None:
for dev in devs:
if dev.dev_type == constants.LD_LV:
- lvmap[node].append(dev.logical_id[1])
+ lvmap[node].append(dev.logical_id[0]+"/"+dev.logical_id[1])
elif dev.dev_type in constants.LDS_DRBD:
if dev.children:
(False, ["gnt-cluster", "modify", "--reserved-lvs", ""]),
(False, ["lvcreate", "-L1G", "-nqa-test", "xenvg"]),
(True, CVERIFY),
- (False, ["gnt-cluster", "modify", "--reserved-lvs", "qa-test,other-test"]),
+ (False, ["gnt-cluster", "modify", "--reserved-lvs",
+ "xenvg/qa-test,.*/other-test"]),
(False, CVERIFY),
- (False, ["gnt-cluster", "modify", "--reserved-lvs", "qa-.*"]),
+ (False, ["gnt-cluster", "modify", "--reserved-lvs", ".*/qa-.*"]),
(False, CVERIFY),
(False, ["gnt-cluster", "modify", "--reserved-lvs", ""]),
(True, CVERIFY),