Revision 2435f63b lib/cmdlib.py

b/lib/cmdlib.py
8724 8724
    results.append("%s%s" % (new_id, val))
8725 8725
  return results
8726 8726

  
8727
def _GetPCIInfo(lu, dev_type):
8728

  
8729
  if (hasattr(lu, 'op') and lu.op.hotplug):
8730
    # case of InstanceCreate()
8731
    if hasattr(lu, 'hotplug_info'):
8732
      if lu.hotplug_info is not None:
8733
        idx = getattr(lu.hotplug_info, dev_type)
8734
        setattr(lu.hotplug_info, dev_type, idx+1)
8735
        if dev_type == 'disks' and idx == 0:
8736
          lu.LogInfo("Disk 0 cannot be hotpluggable.")
8737
          return None, None
8738
        pci = lu.hotplug_info.pci_pool.pop()
8739
        lu.LogInfo("Choosing pci slot %d" % pci)
8740
        return idx, pci
8741
    # case of InstanceSetParams()
8742
    elif lu.instance.hotplug_info is not None:
8743
      idx, pci = lu.cfg.GetPCIInfo(lu.instance, dev_type)
8744
      lu.LogInfo("Choosing pci slot %d" % pci)
8745
      return idx, pci
8746

  
8747
  lu.LogWarning("Hotplug not supported for this instance.")
8748
  return None, None
8727

  
8728
def _GetHotplugIndex(lu, dev_type):
8729

  
8730
  # case of InstanceCreate()
8731
  # keep backwards compat and naming
8732
  if hasattr(lu, 'hotplug_info'):
8733
    if lu.hotplug_info is not None:
8734
      idx = getattr(lu.hotplug_info, dev_type)
8735
      setattr(lu.hotplug_info, dev_type, idx + 1)
8736
      return idx
8737
  # case of InstanceSetParams()
8738
  # give every device a idx so that it can be hotplugable
8739
  elif lu.instance.hotplug_info is not None:
8740
    idx = lu.cfg.GetHotplugIndex(lu.instance, dev_type)
8741
    return idx
8742

  
8743
  return None
8744

  
8745

  
8746
def _DeviceHotplugable(dev):
8747

  
8748
  return dev.idx is not None
8749

  
8750

  
8751
def _HotplugEnabled(instance):
8752

  
8753
  return instance.hotplug_info is not None
8749 8754

  
8750 8755

  
8751 8756
def _GenerateDRBD8Branch(lu, primary, secondary, size, vgnames, names,
......
8764 8769
                          logical_id=(vgnames[1], names[1]),
8765 8770
                          params={})
8766 8771

  
8767
  disk_idx, pci = _GetPCIInfo(lu, 'disks')
8768
  drbd_dev = objects.Disk(idx=disk_idx, pci=pci,
8769
                          dev_type=constants.LD_DRBD8, size=size,
8772
  drbd_dev = objects.Disk(dev_type=constants.LD_DRBD8, size=size,
8770 8773
                          logical_id=(primary, secondary, port,
8771 8774
                                      p_minor, s_minor,
8772 8775
                                      shared_secret),
8773 8776
                          children=[dev_data, dev_meta],
8774 8777
                          iv_name=iv_name, params={})
8778
  if lu.op.hotplug:
8779
    drbd_dev.idx = _GetHotplugIndex(lu, 'disks')
8780

  
8775 8781
  return drbd_dev
8776 8782

  
8777 8783

  
......
8876 8882
      feedback_fn("* disk %s, size %s" %
8877 8883
                  (disk_index, utils.FormatUnit(size, "h")))
8878 8884

  
8879
      disk_idx, pci = _GetPCIInfo(lu, 'disks')
8885
      disk_obj = objects.Disk(dev_type=dev_type, size=size,
8886
                              logical_id=logical_id_fn(idx, disk_index, disk),
8887
                              iv_name="disk/%d" % disk_index,
8888
                              mode=disk[constants.IDISK_MODE],
8889
                              params={})
8890
      if lu.op.hotplug:
8891
        disk_obj.idx = _GetHotplugIndex(lu, 'disks')
8880 8892

  
8881
      disks.append(objects.Disk(dev_type=dev_type, size=size,
8882
                                logical_id=logical_id_fn(idx, disk_index, disk),
8883
                                iv_name="disk/%d" % disk_index,
8884
                                mode=disk[constants.IDISK_MODE],
8885
                                params={}, idx=disk_idx, pci=pci))
8893
      disks.append(disk_obj)
8886 8894

  
8887 8895
  return disks
8888 8896

  
......
9774 9782
    self.hotplug_info = None
9775 9783
    if self.op.hotplug:
9776 9784
      self.LogInfo("Enabling hotplug.")
9777
      self.hotplug_info = objects.HotplugInfo(disks=0, nics=0,
9778
                                              pci_pool=list(range(16,32)))
9785
      self.hotplug_info = objects.HotplugInfo(disks=0, nics=0)
9786

  
9779 9787
    # NIC buildup
9780 9788
    self.nics = []
9781 9789
    for idx, nic in enumerate(self.op.nics):
......
9835 9843

  
9836 9844
      check_params = cluster.SimpleFillNIC(nicparams)
9837 9845
      objects.NIC.CheckParameterSyntax(check_params)
9838
      nic_idx, pci = _GetPCIInfo(self, 'nics')
9839
      self.nics.append(objects.NIC(idx=nic_idx, pci=pci,
9840
                                   mac=mac, ip=nic_ip,
9841
                                   nicparams=check_params))
9846
      nic_obj = objects.NIC(mac=mac, ip=nic_ip, nicparams=check_params)
9847
      if self.op.hotplug:
9848
        nic_obj.idx = _GetHotplugIndex(self, 'nics')
9849

  
9850
      self.nics.append(nic_obj)
9842 9851

  
9843 9852
    # disk checks/pre-build
9844 9853
    default_vg = self.cfg.GetVGName()
......
12833 12842
        self.LogWarning("Failed to create volume %s (%s) on node '%s': %s",
12834 12843
                        disk.iv_name, disk, node, err)
12835 12844

  
12836
    if self.op.hotplug and disk.pci and _InstanceRunning(self, self.instance):
12845
    if self.op.hotplug and _HotplugEnabled(self.instance):
12837 12846
      self.LogInfo("Trying to hotplug device.")
12838 12847
      _, device_info = _AssembleInstanceDisks(self, self.instance,
12839 12848
                                                    [disk], check=False)
12840 12849
      _, _, dev_path = device_info[0]
12841 12850
      #TODO: handle result
12842
      self.rpc.call_hot_add_disk(self.instance.primary_node,
12843
                                 self.instance, disk, dev_path, idx)
12851
      result = self.rpc.call_hot_add_disk(self.instance.primary_node,
12852
                                          self.instance, disk, dev_path, idx)
12853
      result.Raise("Could not hotplug device.")
12854
      disk.pci = result.payload
12855

  
12844 12856
    return (disk, [
12845 12857
      ("disk/%d" % idx, "add:size=%s,mode=%s" % (disk.size, disk.mode)),
12846 12858
      ])
......
12862 12874
    """
12863 12875
    #TODO: log warning in case hotplug is not possible
12864 12876
    #      handle errors
12865
    if root.pci and not self.op.hotplug:
12866
      raise errors.OpPrereqError("Cannot remove a disk that has"
12867
                                 " been hotplugged"
12868
                                 " without removing it with hotplug",
12869
                                 errors.ECODE_INVAL)
12870
    if self.op.hotplug and root.pci:
12871
      if _InstanceRunning(self, self.instance):
12872
        self.LogInfo("Trying to hotplug device.")
12873
        self.rpc.call_hot_del_disk(self.instance.primary_node,
12874
                                   self.instance, root, idx)
12875
        _ShutdownInstanceDisks(self, self.instance, [root])
12876
      self.cfg.UpdatePCIInfo(self.instance, root.pci)
12877
    if self.op.hotplug and _DeviceHotplugable(root):
12878
      self.LogInfo("Trying to hotplug device.")
12879
      result = self.rpc.call_hot_del_disk(self.instance.primary_node,
12880
                                          self.instance, root, idx)
12881
      result.Raise("Could not hotplug device.")
12882
      self.LogInfo("Hotplug done.")
12883
      _ShutdownInstanceDisks(self, self.instance, [root])
12877 12884

  
12878 12885
    (anno_disk,) = _AnnotateDiskParams(self.instance, [root], self.cfg)
12879 12886
    for node, disk in anno_disk.ComputeNodeTree(self.instance.primary_node):
......
12901 12908
    #TODO: log warning in case hotplug is not possible
12902 12909
    #      handle errors
12903 12910
    #      return changes
12904
    if self.op.hotplug:
12905
      nic.idx, nic.pci = _GetPCIInfo(self, 'nics')
12906
      if nic.pci is not None and _InstanceRunning(self, self.instance):
12907
        self.rpc.call_hot_add_nic(self.instance.primary_node,
12908
                                  self.instance, nic, idx)
12911
    if self.op.hotplug and _HotplugEnabled(self.instance):
12912
      nic.idx = _GetHotplugIndex(self, 'nics')
12913
      result = self.rpc.call_hot_add_nic(self.instance.primary_node,
12914
                                         self.instance, nic, idx)
12915
      result.Raise("Could not hotplug device")
12916
      nic.pci = result.payload
12917
      self.Log("Hotplug done.")
12918

  
12909 12919
    desc =  [
12910 12920
      ("nic.%d" % idx,
12911 12921
       "add:mac=%s,ip=%s,mode=%s,link=%s" %
......
12933 12943

  
12934 12944
    #TODO: log warning in case hotplug is not possible
12935 12945
    #      handle errors
12936
    if self.op.hotplug and nic.pci and _InstanceRunning(self, self.instance):
12946
    if self.op.hotplug and _DeviceHotplugable(nic):
12937 12947
      self.LogInfo("Trying to hotplug device.")
12938
      self.rpc.call_hot_del_nic(self.instance.primary_node,
12939
                                self.instance, nic, idx)
12940
      self.rpc.call_hot_add_nic(self.instance.primary_node,
12941
                                self.instance, nic, idx)
12948
      result = self.rpc.call_hot_del_nic(self.instance.primary_node,
12949
                                         self.instance, nic, idx)
12950
      result.Raise("Could not hotplug device.")
12951

  
12952
      result = self.rpc.call_hot_add_nic(self.instance.primary_node,
12953
                                         self.instance, nic, idx)
12954
      result.Raise("Could not hotplug device.")
12955
      self.Log("Hotplug done.")
12956
      nic.pci = result.payload
12957

  
12942 12958
    return changes
12943 12959

  
12944 12960
  def _RemoveNic(self, idx, nic, _):
12945
    if nic.pci and not self.op.hotplug:
12946
      raise errors.OpPrereqError("Cannot remove a nic that has been hotplugged"
12947
                                 " without removing it with hotplug",
12948
                                 errors.ECODE_INVAL)
12949 12961
    #TODO: log warning in case hotplug is not possible
12950 12962
    #      handle errors
12951
    if self.op.hotplug and nic.pci:
12952
      if _InstanceRunning(self, self.instance):
12953
        self.LogInfo("Trying to hotplug device.")
12954
        self.rpc.call_hot_del_nic(self.instance.primary_node,
12955
                                  self.instance, nic, idx)
12956
      self.cfg.UpdatePCIInfo(self.instance, nic.pci)
12963
    if self.op.hotplug and _DeviceHotplugable(nic):
12964
      self.LogInfo("Trying to hotplug device.")
12965
      result = self.rpc.call_hot_del_nic(self.instance.primary_node,
12966
                                         self.instance, nic, idx)
12967
      result.Raise("Could not hotplug device.")
12968
      self.Log("Hotplug done.")
12957 12969

  
12958 12970

  
12959 12971
  def Exec(self, feedback_fn):

Also available in: Unified diff