]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph: retry new-style mon command if we get EINVAL from the old-style command
authorSage Weil <sage@inktank.com>
Fri, 9 Aug 2013 22:14:56 +0000 (15:14 -0700)
committerSage Weil <sage@inktank.com>
Fri, 9 Aug 2013 22:38:39 +0000 (15:38 -0700)
We can race with a mon upgrade:

- get command descriptions, get EINVAL
- mons upgrade, new quorum
- send old-style command
- get EINVAL

In this case, we should try one last time to get the command descriptions.

Fixes: #5788
Reviewed-by: Dan Mick <dan.mick@inktank.com>
Signed-off-by: Sage Weil <sage@inktank.com>
src/ceph.in

index 38150ed07d721ae6781dec3f079699d84ecac907..fa79a720656f9bdb4872148dc3032d9134e0c891 100755 (executable)
@@ -691,26 +691,34 @@ def main():
                 childargs.extend(['--format', parsed_args.output_format])
             ret, outbuf, outs = send_command(cluster_handle, target, childargs,
                                              inbuf)
-        elif ret:
-            if ret < 0:
-                outs = 'problem getting command descriptions from {0}.{1}'.format(*target)
-        else:
-            sigdict = parse_json_funcsigs(outbuf, 'cli')
 
-            if parsed_args.completion:
-                return complete(sigdict, childargs, target)
+            if ret == -errno.EINVAL:
+                # did we race with a mon upgrade?  try again!
+                ret, outbuf, outs = json_command(cluster_handle, target=target,
+                                                 prefix='get_command_descriptions')
+                if ret == 0:
+                    compat = False  # yep, carry on
+        if not compat:
+            if ret:
+                if ret < 0:
+                    outs = 'problem getting command descriptions from {0}.{1}'.format(*target)
+            else:
+                sigdict = parse_json_funcsigs(outbuf, 'cli')
 
-            ret, outbuf, outs = new_style_command(parsed_args, childargs, target,
-                                                  sigdict, inbuf, verbose)
+                if parsed_args.completion:
+                    return complete(sigdict, childargs, target)
 
-            # debug tool: send any successful command *again* to
-            # verify that it is idempotent.
-            if not ret and 'CEPH_CLI_TEST_DUP_COMMAND' in os.environ:
                 ret, outbuf, outs = new_style_command(parsed_args, childargs, target,
                                                       sigdict, inbuf, verbose)
-                if ret < 0:
-                    ret = -ret
-                    print >> sys.stderr, prefix + 'Second attempt of previously successful command failed with {0}: {1}'.format(errno.errorcode[ret], outs)
+
+                # debug tool: send any successful command *again* to
+                # verify that it is idempotent.
+                if not ret and 'CEPH_CLI_TEST_DUP_COMMAND' in os.environ:
+                    ret, outbuf, outs = new_style_command(parsed_args, childargs, target,
+                                                          sigdict, inbuf, verbose)
+                    if ret < 0:
+                        ret = -ret
+                        print >> sys.stderr, prefix + 'Second attempt of previously successful command failed with {0}: {1}'.format(errno.errorcode[ret], outs)
 
         if ret < 0:
             ret = -ret