Finalize local export only if successful
authorHrvoje Ribicic <riba@google.com>
Thu, 12 Feb 2015 17:34:47 +0000 (17:34 +0000)
committerHrvoje Ribicic <riba@google.com>
Wed, 18 Feb 2015 18:20:26 +0000 (19:20 +0100)
Before commit 44247302, a failure in the transfer of a single disk
during an export was changed to make the entire transfer unsuccessful.
What did not change was an invocation of export finalization, which
removes the old backup if present and replaces it with whatever the
result of the transfer was. As a result, a failed backup of an instance
could destroy a previous backup.

This patch prevents the finalization from taking place - this leaves
some data lying around in a ".new" directory, but at least the old
backup is not deleted.

Signed-off-by: Hrvoje Ribicic <riba@google.com>
Reviewed-by: Helga Velroyen <helgav@google.com>

lib/masterd/instance.py

index 723085a..17fd3b5 100644 (file)
@@ -1267,14 +1267,22 @@ class ExportInstanceHelper(object):
 
     assert len(dresults) == len(instance.disks)
 
-    self._feedback_fn("Finalizing export on %s" % dest_node.name)
-    result = self._lu.rpc.call_finalize_export(dest_node.uuid, instance,
-                                               self._snap_disks)
-    msg = result.fail_msg
-    fin_resu = not msg
-    if msg:
-      self._lu.LogWarning("Could not finalize export for instance %s"
-                          " on node %s: %s", instance.name, dest_node.name, msg)
+    # Finalize only if all the disks have been exported successfully
+    if all(dresults):
+      self._feedback_fn("Finalizing export on %s" % dest_node.name)
+      result = self._lu.rpc.call_finalize_export(dest_node.uuid, instance,
+                                                 self._snap_disks)
+      msg = result.fail_msg
+      fin_resu = not msg
+      if msg:
+        self._lu.LogWarning("Could not finalize export for instance %s"
+                            " on node %s: %s", instance.name, dest_node.name,
+                            msg)
+    else:
+      fin_resu = False
+      self._lu.LogWarning("Some disk exports have failed; there may be "
+                          "leftover data for instance %s on node %s",
+                          instance.name, dest_node.name)
 
     return (fin_resu, dresults)