Commit 084f05a5 authored by Iustin Pop's avatar Iustin Pop
Browse files

export: add meaningful exit code

Currently ‘gnt-backup export’ always returns exit code zero, even in the
face of complete failure during backup (only failure to stop/start the
instance will cause job failure and thus non-zero exit code). This is
bad, since one cannot script the backup.

This patch adds some simple results from the LU so that the command line
script can return good exit code. It will:
  - return zero for full success (snapshot removal errors are ignored
  - return one for full failure (finalize export failure or all disks
  - return two for partial failure (some disks backed up, some not)
Signed-off-by: default avatarIustin Pop <>
Reviewed-by: default avatarMichael Hanselmann <>
parent a48b08bf
......@@ -6472,6 +6472,8 @@ class LUExportInstance(LogicalUnit):
for disk in instance.disks:
self.cfg.SetDiskID(disk, src_node)
# per-disk results
dresults = []
for idx, disk in enumerate(instance.disks):
# new_dev_name will be a snapshot of an lvm leaf of the one we passed
......@@ -6505,15 +6507,22 @@ class LUExportInstance(LogicalUnit):
if result.failed or not
self.LogWarning("Could not export disk/%d from node %s to"
" node %s", idx, src_node,
msg = self.rpc.call_blockdev_remove(src_node, dev).RemoteFailMsg()
if msg:
self.LogWarning("Could not remove snapshot for disk/%d from node"
" %s: %s", idx, src_node, msg)
result = self.rpc.call_finalize_export(, instance, snap_disks)
fin_resu = True
if result.failed or not
self.LogWarning("Could not finalize export for instance %s on node %s",,
fin_resu = False
nodelist = self.cfg.GetNodeList()
......@@ -6530,6 +6539,7 @@ class LUExportInstance(LogicalUnit):
if not self.rpc.call_export_remove(node,
self.LogWarning("Could not remove older export for instance %s"
" on node %s",, node)
return fin_resu, dresults
class LURemoveExport(NoHooksLU):
......@@ -82,6 +82,16 @@
in the exported dump.
The exit code of the command is 0 if all disks were backed up
successfully, 1 if no data was backed up or if the
configuration export failed, and 2 if just some of the disks
failed to backup. The exact details of the failures will be
shown during the command execution (and will be stored in the
job log). It is recommended that for any non-zero exit code,
the backup is considered invalid, and retried.
......@@ -74,8 +74,27 @@ def ExportInstance(opts, args):
fin_resu, dlist = SubmitOpCode(op)
if not isinstance(dlist, list):
ToStderr("Cannot parse execution results")
return 1
tot_dsk = len(dlist)
# TODO: handle diskless instances
if dlist.count(False) == 0:
# all OK
rcode = 0
elif dlist.count(True) == 0:
ToStderr("Error: No disks were backed up successfully."
" The export doesn't have any valid data,"
" it is recommended to retry the operation.")
rcode = 1
ToStderr("Partial export failure: %d disks backed up, %d disks failed.",
dlist.count(True), dlist.count(False))
rcode = 2
if not fin_resu:
rcode = 1
return rcode
def ImportInstance(opts, args):
"""Add an instance to the cluster.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment