diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 31d3d765395919427385102a176aa7279be37352..c56d7ba6a1ecfb5dd4be214f32ed6099cf95666b 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -8164,8 +8164,8 @@ def _ExpandNamesForMigration(lu):
   lu.needed_locks[locking.LEVEL_NODE_RES] = []
   lu.recalculate_locks[locking.LEVEL_NODE_RES] = constants.LOCKS_REPLACE
 
-  # The node allocation lock is actually only needed for replicated instances
-  # (e.g. DRBD8) and if an iallocator is used.
+  # The node allocation lock is actually only needed for externally replicated
+  # instances (e.g. sharedfile or RBD) and if an iallocator is used.
   lu.needed_locks[locking.LEVEL_NODE_ALLOC] = []
 
 
@@ -8673,11 +8673,10 @@ class TLMigrateInstance(Tasklet):
                                  errors.ECODE_STATE)
 
     if instance.disk_template in constants.DTS_EXT_MIRROR:
-      assert locking.NAL in self.lu.owned_locks(locking.LEVEL_NODE_ALLOC)
-
       _CheckIAllocatorOrNode(self.lu, "iallocator", "target_node")
 
       if self.lu.op.iallocator:
+        assert locking.NAL in self.lu.owned_locks(locking.LEVEL_NODE_ALLOC)
         self._RunAllocator()
       else:
         # We set set self.target_node as it is required by
diff --git a/lib/constants.py b/lib/constants.py
index 3b03a0b24b70d9c12ffffedde488f65fdd4c0e76..91ca41b874569684640f8280f1fbfd59d8952c62 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -436,6 +436,7 @@ DTS_INT_MIRROR = compat.UniqueFrozenset([DT_DRBD8])
 
 # the set of externally-mirrored disk templates (e.g. SAN, NAS)
 DTS_EXT_MIRROR = compat.UniqueFrozenset([
+  DT_DISKLESS, # 'trivially' externally mirrored
   DT_SHARED_FILE,
   DT_BLOCK,
   DT_RBD,
diff --git a/lib/rapi/client.py b/lib/rapi/client.py
index e48de24b9e0b0f2b439fc99e9910f5ae06855861..b7600785c37d90aea440c3209b2ede947682cf8a 100644
--- a/lib/rapi/client.py
+++ b/lib/rapi/client.py
@@ -1196,7 +1196,8 @@ class GanetiRapiClient(object): # pylint: disable=R0904
                              ("/%s/instances/%s/export" %
                               (GANETI_RAPI_VERSION, instance)), None, body)
 
-  def MigrateInstance(self, instance, mode=None, cleanup=None):
+  def MigrateInstance(self, instance, mode=None, cleanup=None,
+                      target_node=None):
     """Migrates an instance.
 
     @type instance: string
@@ -1205,6 +1206,8 @@ class GanetiRapiClient(object): # pylint: disable=R0904
     @param mode: Migration mode
     @type cleanup: bool
     @param cleanup: Whether to clean up a previously failed migration
+    @type target_node: string
+    @param target_node: Target Node for externally mirrored instances
     @rtype: string
     @return: job id
 
@@ -1212,6 +1215,7 @@ class GanetiRapiClient(object): # pylint: disable=R0904
     body = {}
     _SetItemIf(body, mode is not None, "mode", mode)
     _SetItemIf(body, cleanup is not None, "cleanup", cleanup)
+    _SetItemIf(body, target_node is not None, "target_node", target_node)
 
     return self._SendRequest(HTTP_PUT,
                              ("/%s/instances/%s/migrate" %
diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py
index f73f3dce84d9f8ba67f8102c964044d1c96cebcd..cc8a796b8db123d47e067ca8df0512b24bd7fef5 100644
--- a/lib/rapi/rlib2.py
+++ b/lib/rapi/rlib2.py
@@ -167,7 +167,7 @@ _WFJC_TIMEOUT = 10
 
 
 # FIXME: For compatibility we update the beparams/memory field. Needs to be
-#        removed in Ganeti 2.7
+#        removed in Ganeti 2.8
 def _UpdateBeparams(inst):
   """Updates the beparams dict of inst to support the memory field.
 
diff --git a/tools/cfgupgrade b/tools/cfgupgrade
index 4fa49d98b00c209a06c0138bb40317c5d2106b34..56b36fc8f61492e7a50a76e913bc02462568a39c 100755
--- a/tools/cfgupgrade
+++ b/tools/cfgupgrade
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 #
 
-# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Google Inc.
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -334,6 +334,7 @@ def main():
     raise
 
   # test loading the config file
+  all_ok = True
   if not (options.dry_run or options.no_verify):
     logging.info("Testing the new config file...")
     cfg = config.ConfigWriter(cfg_file=options.CONFIG_DATA_PATH,
@@ -345,11 +346,17 @@ def main():
       logging.error("Errors after conversion:")
       for item in vrfy:
         logging.error(" - %s", item)
+      all_ok = False
+    else:
+      logging.info("File loaded successfully after upgrading")
     del cfg
-    logging.info("File loaded successfully")
 
-  cli.ToStderr("Configuration successfully upgraded for version %s.",
-               constants.RELEASE_VERSION)
+  if all_ok:
+    cli.ToStderr("Configuration successfully upgraded to version %s.",
+                 constants.RELEASE_VERSION)
+  else:
+    cli.ToStderr("Configuration upgraded to version %s, but there are errors."
+                 "\nPlease review the file.", constants.RELEASE_VERSION)
 
 
 if __name__ == "__main__":