Create symlinks to intances' block devices
[ganeti-local] / lib / backend.py
index 2d7f63a..2a483db 100644 (file)
@@ -733,7 +733,38 @@ def _GetVGInfo(vg_name):
   return retdic
 
 
-def _GatherBlockDevs(instance):
+def _SymlinkBlockDev(instance_name, device_path, device_name):
+  """Set up symlinks to a instance's block device.
+
+  This is an auxiliary function run when an instance is start (on the primary
+  node) or when an instance is migrated (on the target node).
+
+  Args:
+    instance_name: the name of the target instance
+    device_path: path of the physical block device, on the node
+    device_name: 'virtual' name of the device
+
+  Returns:
+    absolute path to the disk's symlink
+
+  """
+  link_basename = "%s-%s" % (instance_name, device_name)
+  link_name = os.path.join(constants.DISK_LINKS_DIR, link_basename)
+  try:
+    os.symlink(device_path, link_name)
+  except OSError, e:
+    if e.errno == errno.EEXIST:
+      if (not os.path.islink(link_name) or
+          os.readlink(link_name) != device_path):
+        os.remove(link_name)
+        os.symlink(device_path, link_name)
+    else:
+      raise
+
+  return link_name
+
+
+def _GatherAndLinkBlockDevs(instance):
   """Set up an instance's block device(s).
 
   This is run on the primary node at instance startup. The block
@@ -741,18 +772,26 @@ def _GatherBlockDevs(instance):
 
   @type instance: L{objects.Instance}
   @param instance: the instance whose disks we shoul assemble
-  @rtype: list of L{bdev.BlockDev}
-  @return: list of the block devices
+  @rtype: list
+  @return: list of (disk_object, device_path)
 
   """
   block_devices = []
-  for disk in instance.disks:
+  for idx, disk in enumerate(instance.disks):
     device = _RecursiveFindBD(disk)
     if device is None:
       raise errors.BlockDeviceError("Block device '%s' is not set up." %
                                     str(disk))
     device.Open()
-    block_devices.append((disk, device))
+    try:
+      link_name = _SymlinkBlockDev(instance.name, device.dev_path,
+                                   "disk%d" % idx)
+    except OSError, e:
+      raise errors.BlockDeviceError("Cannot create block device symlink: %s" %
+                                    e.strerror)
+
+    block_devices.append((disk, link_name))
+
   return block_devices
 
 
@@ -770,7 +809,7 @@ def StartInstance(instance, extra_args):
   if instance.name in running_instances:
     return True
 
-  block_devices = _GatherBlockDevs(instance)
+  block_devices = _GatherAndLinkBlockDevs(instance)
   hyper = hypervisor.GetHypervisor(instance.hypervisor)
 
   try:
@@ -1990,7 +2029,7 @@ def JobQueueRename(old, new):
   if not (_IsJobQueueFile(old) and _IsJobQueueFile(new)):
     return False
 
-  os.rename(old, new)
+  utils.RenameFile(old, new, mkdir=True)
 
   return True