Revision 7c848a6a
b/lib/cmdlib/instance.py | ||
---|---|---|
1032 | 1032 |
" exclusive storage" % self.op.disk_template, |
1033 | 1033 |
errors.ECODE_STATE) |
1034 | 1034 |
for disk in self.disks: |
1035 |
CheckSpindlesExclusiveStorage(disk, excl_stor) |
|
1035 |
CheckSpindlesExclusiveStorage(disk, excl_stor, True)
|
|
1036 | 1036 |
|
1037 | 1037 |
nodenames = [pnode.name] + self.secondaries |
1038 | 1038 |
|
... | ... | |
2241 | 2241 |
if name is not None and name.lower() == constants.VALUE_NONE: |
2242 | 2242 |
params[constants.IDISK_NAME] = None |
2243 | 2243 |
|
2244 |
CheckSpindlesExclusiveStorage(params, excl_stor) |
|
2244 |
CheckSpindlesExclusiveStorage(params, excl_stor, True)
|
|
2245 | 2245 |
|
2246 | 2246 |
elif op == constants.DDM_MODIFY: |
2247 | 2247 |
if constants.IDISK_SIZE in params: |
b/lib/cmdlib/instance_storage.py | ||
---|---|---|
519 | 519 |
return disks |
520 | 520 |
|
521 | 521 |
|
522 |
def CheckSpindlesExclusiveStorage(diskdict, es_flag): |
|
522 |
def CheckSpindlesExclusiveStorage(diskdict, es_flag, required):
|
|
523 | 523 |
"""Check the presence of the spindle options with exclusive_storage. |
524 | 524 |
|
525 | 525 |
@type diskdict: dict |
526 | 526 |
@param diskdict: disk parameters |
527 | 527 |
@type es_flag: bool |
528 | 528 |
@param es_flag: the effective value of the exlusive_storage flag |
529 |
@type required: bool |
|
530 |
@param required: whether spindles are required or just optional |
|
529 | 531 |
@raise errors.OpPrereqError when spindles are given and they should not |
530 | 532 |
|
531 | 533 |
""" |
... | ... | |
534 | 536 |
raise errors.OpPrereqError("Spindles in instance disks cannot be specified" |
535 | 537 |
" when exclusive storage is not active", |
536 | 538 |
errors.ECODE_INVAL) |
539 |
if (es_flag and required and (constants.IDISK_SPINDLES not in diskdict or |
|
540 |
diskdict[constants.IDISK_SPINDLES] is None)): |
|
541 |
raise errors.OpPrereqError("You must specify spindles in instance disks" |
|
542 |
" when exclusive storage is active", |
|
543 |
errors.ECODE_INVAL) |
|
537 | 544 |
|
538 | 545 |
|
539 | 546 |
class LUInstanceRecreateDisks(LogicalUnit): |
... | ... | |
787 | 794 |
rpc.GetExclusiveStorageForNodeNames(self.cfg, nodes).values() |
788 | 795 |
) |
789 | 796 |
for new_params in self.disks.values(): |
790 |
CheckSpindlesExclusiveStorage(new_params, excl_stor) |
|
797 |
CheckSpindlesExclusiveStorage(new_params, excl_stor, False)
|
|
791 | 798 |
|
792 | 799 |
def Exec(self, feedback_fn): |
793 | 800 |
"""Recreate the disks. |
b/lib/storage/bdev.py | ||
---|---|---|
262 | 262 |
stripes = min(current_pvs, desired_stripes) |
263 | 263 |
|
264 | 264 |
if excl_stor: |
265 |
if spindles is None: |
|
266 |
base.ThrowError("Unspecified number of spindles: this is required" |
|
267 |
"when exclusive storage is enabled, try running" |
|
268 |
" gnt-cluster repair-disk-sizes") |
|
265 | 269 |
(err_msgs, _) = utils.LvmExclusiveCheckNodePvs(pvs_info) |
266 | 270 |
if err_msgs: |
267 | 271 |
for m in err_msgs: |
268 | 272 |
logging.warning(m) |
269 | 273 |
req_pvs = cls._ComputeNumPvs(size, pvs_info) |
270 |
if spindles: |
|
271 |
if spindles < req_pvs: |
|
272 |
base.ThrowError("Requested number of spindles (%s) is not enough for" |
|
273 |
" a disk of %d MB (at least %d spindles needed)", |
|
274 |
spindles, size, req_pvs) |
|
275 |
else: |
|
276 |
req_pvs = spindles |
|
274 |
if spindles < req_pvs: |
|
275 |
base.ThrowError("Requested number of spindles (%s) is not enough for" |
|
276 |
" a disk of %d MB (at least %d spindles needed)", |
|
277 |
spindles, size, req_pvs) |
|
278 |
else: |
|
279 |
req_pvs = spindles |
|
277 | 280 |
pvlist = cls._GetEmptyPvNames(pvs_info, req_pvs) |
278 | 281 |
current_pvs = len(pvlist) |
279 | 282 |
if current_pvs < req_pvs: |
b/qa/qa_instance.py | ||
---|---|---|
630 | 630 |
print qa_utils.FormatInfo("Instance doesn't support disks, skipping test") |
631 | 631 |
return |
632 | 632 |
|
633 |
size = qa_config.GetDiskOptions()[-1].get("size") |
|
633 |
disk_conf = qa_config.GetDiskOptions()[-1] |
|
634 |
size = disk_conf.get("size") |
|
634 | 635 |
name = instance.name |
635 | 636 |
build_cmd = lambda arg: ["gnt-instance", "modify", "--disk", arg, name] |
636 |
AssertCommand(build_cmd("add:size=%s" % size)) |
|
637 |
if qa_config.AreSpindlesSupported(): |
|
638 |
spindles = disk_conf.get("spindles") |
|
639 |
spindles_supported = True |
|
640 |
else: |
|
641 |
# Any number is good for spindles in this case |
|
642 |
spindles = 1 |
|
643 |
spindles_supported = False |
|
644 |
AssertCommand(build_cmd("add:size=%s,spindles=%s" % (size, spindles)), |
|
645 |
fail=not spindles_supported) |
|
646 |
AssertCommand(build_cmd("add:size=%s" % size), |
|
647 |
fail=spindles_supported) |
|
648 |
# Exactly one of the above commands has succeded, so we need one remove |
|
637 | 649 |
AssertCommand(build_cmd("remove")) |
638 | 650 |
|
639 | 651 |
|
... | ... | |
681 | 693 |
for dev_type in ["disk", "net"]: |
682 | 694 |
if dev_type == "disk": |
683 | 695 |
options = ",size=512M" |
696 |
if qa_config.AreSpindlesSupported(): |
|
697 |
options += ",spindles=1" |
|
684 | 698 |
else: |
685 | 699 |
options = "" |
686 | 700 |
# succeed in adding a device named 'test_device' |
... | ... | |
806 | 820 |
AssertCommand(["gnt-instance", "deactivate-disks", instance.name]) |
807 | 821 |
|
808 | 822 |
|
823 |
def _BuildRecreateDisksOpts(en_disks, with_spindles, with_growth, |
|
824 |
spindles_supported): |
|
825 |
if with_spindles: |
|
826 |
if spindles_supported: |
|
827 |
if with_growth: |
|
828 |
build_spindles_opt = (lambda disk: |
|
829 |
",spindles=%s" % |
|
830 |
(disk["spindles"] + disk["spindles-growth"])) |
|
831 |
else: |
|
832 |
build_spindles_opt = (lambda disk: |
|
833 |
",spindles=%s" % disk["spindles"]) |
|
834 |
else: |
|
835 |
build_spindles_opt = (lambda _: ",spindles=1") |
|
836 |
else: |
|
837 |
build_spindles_opt = (lambda _: "") |
|
838 |
if with_growth: |
|
839 |
build_size_opt = (lambda disk: |
|
840 |
"size=%s" % (utils.ParseUnit(disk["size"]) + |
|
841 |
utils.ParseUnit(disk["growth"]))) |
|
842 |
else: |
|
843 |
build_size_opt = (lambda disk: "size=%s" % disk["size"]) |
|
844 |
build_disk_opt = (lambda (idx, disk): |
|
845 |
"--disk=%s:%s%s" % (idx, build_size_opt(disk), |
|
846 |
build_spindles_opt(disk))) |
|
847 |
return map(build_disk_opt, en_disks) |
|
848 |
|
|
849 |
|
|
809 | 850 |
@InstanceCheck(INST_UP, INST_UP, FIRST_ARG) |
810 | 851 |
def TestRecreateDisks(instance, inodes, othernodes): |
811 | 852 |
"""gnt-instance recreate-disks |
... | ... | |
845 | 886 |
# Move disks back |
846 | 887 |
_AssertRecreateDisks(["-n", orig_seq], instance) |
847 | 888 |
# Recreate resized disks |
889 |
# One of the two commands fails because either spindles are given when they |
|
890 |
# should not or vice versa |
|
848 | 891 |
alldisks = qa_config.GetDiskOptions() |
849 |
if qa_config.AreSpindlesSupported(): |
|
850 |
build_disks_opt = (lambda idx, disk: |
|
851 |
("--disk=%s:size=%s,spindles=%s" % |
|
852 |
(idx, (utils.ParseUnit(disk["size"]) + |
|
853 |
utils.ParseUnit(disk["growth"])), |
|
854 |
disk["spindles"] + disk["spindles-growth"]))) |
|
855 |
else: |
|
856 |
build_disks_opt = (lambda idx, disk: |
|
857 |
("--disk=%s:size=%s" % |
|
858 |
(idx, (utils.ParseUnit(disk["size"]) + |
|
859 |
utils.ParseUnit(disk["growth"]))))) |
|
860 |
disk_opts = map(build_disks_opt, range(0, len(alldisks)), (alldisks)) |
|
861 |
_AssertRecreateDisks(disk_opts, instance) |
|
892 |
spindles_supported = qa_config.AreSpindlesSupported() |
|
893 |
disk_opts = _BuildRecreateDisksOpts(enumerate(alldisks), True, True, |
|
894 |
spindles_supported) |
|
895 |
_AssertRecreateDisks(disk_opts, instance, destroy=True, |
|
896 |
fail=not spindles_supported) |
|
897 |
disk_opts = _BuildRecreateDisksOpts(enumerate(alldisks), False, True, |
|
898 |
spindles_supported) |
|
899 |
_AssertRecreateDisks(disk_opts, instance, destroy=False, |
|
900 |
fail=spindles_supported) |
|
862 | 901 |
# Recreate the disks one by one (with the original size) |
863 |
if qa_config.AreSpindlesSupported(): |
|
864 |
build_disks_opt = lambda idx, disk: ("--disk=%s:size=%s,spindles=%s" % |
|
865 |
(idx, disk["size"], disk["spindles"])) |
|
866 |
else: |
|
867 |
build_disks_opt = lambda idx, disk: ("--disk=%s:size=%s" % |
|
868 |
(idx, disk["size"])) |
|
869 | 902 |
for (idx, disk) in enumerate(alldisks): |
870 | 903 |
# Only the first call should destroy all the disk |
871 | 904 |
destroy = (idx == 0) |
872 |
_AssertRecreateDisks([build_disks_opt(idx, disk)], instance, |
|
873 |
destroy=destroy, check=False) |
|
905 |
# Again, one of the two commands is expected to fail |
|
906 |
disk_opts = _BuildRecreateDisksOpts([(idx, disk)], True, False, |
|
907 |
spindles_supported) |
|
908 |
_AssertRecreateDisks(disk_opts, instance, destroy=destroy, check=False, |
|
909 |
fail=not spindles_supported) |
|
910 |
disk_opts = _BuildRecreateDisksOpts([(idx, disk)], False, False, |
|
911 |
spindles_supported) |
|
912 |
_AssertRecreateDisks(disk_opts, instance, destroy=False, check=False, |
|
913 |
fail=spindles_supported) |
|
874 | 914 |
# This and InstanceCheck decoration check that the disks are working |
875 | 915 |
AssertCommand(["gnt-instance", "reinstall", "-f", instance.name]) |
876 | 916 |
AssertCommand(["gnt-instance", "start", instance.name]) |
Also available in: Unified diff