Revision f3e513ad

b/daemons/ganeti-noded
113 113
    return backend.RemoveBlockDevice(bdev)
114 114

  
115 115
  @staticmethod
116
  def perspective_blockdev_rename(params):
117
    """Remove a block device.
118

  
119
    """
120
    devlist = [(objects.Disk.FromDict(ds), uid) for ds, uid in params]
121
    return backend.RenameBlockDevices(devlist)
122

  
123
  @staticmethod
116 124
  def perspective_blockdev_assemble(params):
117 125
    """Assemble a block device.
118 126

  
b/lib/backend.py
1337 1337
  return True
1338 1338

  
1339 1339

  
1340
def RenameBlockDevices(devlist):
1341
  """Rename a list of block devices.
1342

  
1343
  The devlist argument is a list of tuples (disk, new_logical,
1344
  new_physical). The return value will be a combined boolean result
1345
  (True only if all renames succeeded).
1346

  
1347
  """
1348
  result = True
1349
  for disk, unique_id in devlist:
1350
    dev = _RecursiveFindBD(disk)
1351
    if dev is None:
1352
      result = False
1353
      continue
1354
    try:
1355
      dev.Rename(unique_id)
1356
    except errors.BlockDeviceError, err:
1357
      logger.Error("Can't rename device '%s' to '%s': %s" %
1358
                   (dev, unique_id, err))
1359
      result = False
1360
  return result
1361

  
1362

  
1340 1363
class HooksRunner(object):
1341 1364
  """Hook runner.
1342 1365

  
b/lib/bdev.py
172 172
    raise NotImplementedError
173 173

  
174 174

  
175
  def Rename(self, new_id):
176
    """Rename this device.
177

  
178
    This may or may not make sense for a given device type.
179

  
180
    """
181
    raise NotImplementedError
182

  
183

  
175 184
  def GetStatus(self):
176 185
    """Return the status of the device.
177 186

  
......
368 377

  
369 378
    return not result.failed
370 379

  
380
  def Rename(self, new_id):
381
    """Rename this logical volume.
382

  
383
    """
384
    if not isinstance(new_id, (tuple, list)) or len(new_id) != 2:
385
      raise errors.ProgrammerError("Invalid new logical id '%s'" % new_id)
386
    new_vg, new_name = new_id
387
    if new_vg != self._vg_name:
388
      raise errors.ProgrammerError("Can't move a logical volume across"
389
                                   " volume groups (from %s to to %s)" %
390
                                   (self._vg_name, new_vg))
391
    result = utils.RunCmd(["lvrename", new_vg, self._lv_name, new_name])
392
    if result.failed:
393
      raise errors.BlockDeviceError("Failed to rename the logical volume: %s" %
394
                                    result.output)
371 395

  
372 396
  def Attach(self):
373 397
    """Attach to an existing LV.
......
700 724
    #TODO: maybe zero superblock on child devices?
701 725
    return self.Shutdown()
702 726

  
727
  def Rename(self, new_id):
728
    """Rename a device.
729

  
730
    This is not supported for md raid1 devices.
731

  
732
    """
733
    raise errors.ProgrammerError("Can't rename a md raid1 device")
703 734

  
704 735
  def AddChildren(self, devices):
705 736
    """Add new member(s) to the md raid1.
......
1056 1087
      return False
1057 1088
    return True
1058 1089

  
1090
  def Rename(self, new_id):
1091
    """Rename a device.
1092

  
1093
    This is not supported for drbd devices.
1094

  
1095
    """
1096
    raise errors.ProgrammerError("Can't rename a drbd device")
1097

  
1059 1098

  
1060 1099
class DRBDev(BaseDRBD):
1061 1100
  """DRBD block device.
......
1562 1601
    """
1563 1602
    return self.Shutdown()
1564 1603

  
1604

  
1565 1605
class DRBD8(BaseDRBD):
1566 1606
  """DRBD v8.x block device.
1567 1607

  
......
2042 2082
    return True
2043 2083

  
2044 2084
  @classmethod
2085
  def _ShutdownNet(cls, minor):
2086
    """Disconnect from the remote peer.
2087

  
2088
    This fails if we don't have a local device.
2089

  
2090
    """
2091
    result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "disconnect"])
2092
    logger.Error("Can't shutdown network: %s" % result.output)
2093
    return not result.failed
2094

  
2095
  @classmethod
2045 2096
  def _ShutdownAll(cls, minor):
2046 2097
    """Deactivate the device.
2047 2098

  
......
2066 2117
    self.dev_path = None
2067 2118
    return True
2068 2119

  
2120
  def Rename(self, new_uid):
2121
    """Re-connect this device to another peer.
2122

  
2123
    """
2124
    if self.minor is None:
2125
      raise errors.BlockDeviceError("Device not attached during rename")
2126
    if self._rhost is not None:
2127
      # this means we did have a host when we attached, so we are connected
2128
      if not self._ShutdownNet(self.minor):
2129
        raise errors.BlockDeviceError("Can't disconnect from remote peer")
2130
      old_id = self.unique_id
2131
    else:
2132
      old_id = None
2133
    self.unique_id = new_uid
2134
    if not self._AssembleNet(self.minor, self.unique_id, "C"):
2135
      logger.Error("Can't attach to new peer!")
2136
      if self.old_id is not None:
2137
        self._AssembleNet(self.minor, old_id, "C")
2138
      self.unique_id = old_id
2139
      raise errors.BlockDeviceError("Can't attach to new peer")
2140

  
2069 2141
  def Remove(self):
2070 2142
    """Stub remove for DRBD devices.
2071 2143

  
b/lib/rpc.py
514 514
  return c.getresult().get(node, False)
515 515

  
516 516

  
517
def call_blockdev_rename(node, devlist):
518
  """Request rename of the given block devices.
519

  
520
  This is a single-node call.
521

  
522
  """
523
  params = [(d.ToDict(), uid) for d, uid in devlist]
524
  c = Client("blockdev_rename", params)
525
  c.connect(node)
526
  c.run()
527
  return c.getresult().get(node, False)
528

  
529

  
517 530
def call_blockdev_assemble(node, disk, on_primary):
518 531
  """Request assembling of a given block device.
519 532

  

Also available in: Unified diff