Revision 3f3ea14c

b/lib/cmdlib/instance.py
54 54
  CheckNodesFreeDiskPerVG, WipeDisks, WipeOrCleanupDisks, WaitForSync, \
55 55
  IsExclusiveStorageEnabledNodeName, CreateSingleBlockDev, ComputeDisks, \
56 56
  CheckRADOSFreeSpace, ComputeDiskSizePerVG, GenerateDiskTemplate, \
57
  StartInstanceDisks, ShutdownInstanceDisks, AssembleInstanceDisks
57
  StartInstanceDisks, ShutdownInstanceDisks, AssembleInstanceDisks, \
58
  CheckSpindlesExclusiveStorage
58 59
from ganeti.cmdlib.instance_utils import BuildInstanceHookEnvByObject, \
59 60
  GetClusterDomainSecret, BuildInstanceHookEnv, NICListToTuple, \
60 61
  NICToTuple, CheckNodeNotDrained, RemoveInstance, CopyLockList, \
......
1025 1026
    if self.op.disk_template in constants.DTS_INT_MIRROR:
1026 1027
      nodes.append(snode)
1027 1028
    has_es = lambda n: IsExclusiveStorageEnabledNode(self.cfg, n)
1028
    if compat.any(map(has_es, nodes)):
1029
      if not self.op.disk_template in constants.DTS_EXCL_STORAGE:
1030
        raise errors.OpPrereqError("Disk template %s not supported with"
1031
                                   " exclusive storage" % self.op.disk_template,
1032
                                   errors.ECODE_STATE)
1029
    excl_stor = compat.any(map(has_es, nodes))
1030
    if excl_stor and not self.op.disk_template in constants.DTS_EXCL_STORAGE:
1031
      raise errors.OpPrereqError("Disk template %s not supported with"
1032
                                 " exclusive storage" % self.op.disk_template,
1033
                                 errors.ECODE_STATE)
1034
    for disk in self.disks:
1035
      CheckSpindlesExclusiveStorage(disk, excl_stor)
1033 1036

  
1034 1037
    nodenames = [pnode.name] + self.secondaries
1035 1038

  
......
2212 2215
        raise errors.ProgrammerError("Unhandled operation '%s'" % op)
2213 2216

  
2214 2217
  @staticmethod
2215
  def _VerifyDiskModification(op, params):
2218
  def _VerifyDiskModification(op, params, excl_stor):
2216 2219
    """Verifies a disk modification.
2217 2220

  
2218 2221
    """
......
2238 2241
      if name is not None and name.lower() == constants.VALUE_NONE:
2239 2242
        params[constants.IDISK_NAME] = None
2240 2243

  
2244
      CheckSpindlesExclusiveStorage(params, excl_stor)
2245

  
2241 2246
    elif op == constants.DDM_MODIFY:
2242 2247
      if constants.IDISK_SIZE in params:
2243 2248
        raise errors.OpPrereqError("Disk size change not possible, use"
......
2614 2619
    instance = self.instance
2615 2620
    self.diskparams = self.cfg.GetInstanceDiskParams(instance)
2616 2621

  
2622
    excl_stor = compat.any(
2623
      rpc.GetExclusiveStorageForNodeNames(self.cfg, instance.all_nodes).values()
2624
      )
2625

  
2617 2626
    # Check disk modifications. This is done here and not in CheckArguments
2618 2627
    # (as with NICs), because we need to know the instance's disk template
2628
    ver_fn = lambda op, par: self._VerifyDiskModification(op, par, excl_stor)
2619 2629
    if instance.disk_template == constants.DT_EXT:
2620
      self._CheckMods("disk", self.op.disks, {},
2621
                      self._VerifyDiskModification)
2630
      self._CheckMods("disk", self.op.disks, {}, ver_fn)
2622 2631
    else:
2623 2632
      self._CheckMods("disk", self.op.disks, constants.IDISK_PARAMS_TYPES,
2624
                      self._VerifyDiskModification)
2633
                      ver_fn)
2625 2634

  
2626 2635
    self.diskmod = _PrepareContainerMods(self.op.disks, None)
2627 2636

  
b/lib/cmdlib/instance_storage.py
343 343
      constants.IDISK_NAME: name,
344 344
      }
345 345

  
346
    if constants.IDISK_METAVG in disk:
347
      new_disk[constants.IDISK_METAVG] = disk[constants.IDISK_METAVG]
348
    if constants.IDISK_ADOPT in disk:
349
      new_disk[constants.IDISK_ADOPT] = disk[constants.IDISK_ADOPT]
346
    for key in [
347
      constants.IDISK_METAVG,
348
      constants.IDISK_ADOPT,
349
      constants.IDISK_SPINDLES,
350
      ]:
351
      if key in disk:
352
        new_disk[key] = disk[key]
350 353

  
351 354
    # For extstorage, demand the `provider' option and add any
352 355
    # additional parameters (ext-params) to the dict
......
515 518
  return disks
516 519

  
517 520

  
521
def CheckSpindlesExclusiveStorage(diskdict, es_flag):
522
  """Check the presence of the spindle options with exclusive_storage.
523

  
524
  @type diskdict: dict
525
  @param diskdict: disk parameters
526
  @type es_flag: bool
527
  @param es_flag: the effective value of the exlusive_storage flag
528
  @raise errors.OpPrereqError when spindles are given and they should not
529

  
530
  """
531
  if (not es_flag and constants.IDISK_SPINDLES in diskdict and
532
      diskdict[constants.IDISK_SPINDLES] is not None):
533
    raise errors.OpPrereqError("Spindles in instance disks cannot be specified"
534
                               " when exclusive storage is not active",
535
                               errors.ECODE_INVAL)
536

  
537

  
518 538
class LUInstanceRecreateDisks(LogicalUnit):
519 539
  """Recreate an instance's missing disks.
520 540

  
......
758 778

  
759 779
    assert not self.glm.is_owned(locking.LEVEL_NODE_ALLOC)
760 780

  
781
    if self.op.nodes:
782
      nodes = self.op.nodes
783
    else:
784
      nodes = instance.all_nodes
785
    excl_stor = compat.any(
786
      rpc.GetExclusiveStorageForNodeNames(self.cfg, nodes).values()
787
      )
788
    for new_params in self.disks.values():
789
      CheckSpindlesExclusiveStorage(new_params, excl_stor)
790

  
761 791
  def Exec(self, feedback_fn):
762 792
    """Recreate the disks.
763 793

  

Also available in: Unified diff