]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph.in: Add blocking mode for scrub and deep-scrub
authorBrad Hubbard <bhubbard@redhat.com>
Wed, 22 Nov 2017 08:47:43 +0000 (18:47 +1000)
committerBrad Hubbard <bhubbard@redhat.com>
Fri, 5 Jan 2018 08:50:57 +0000 (18:50 +1000)
Signed-off-by: Brad Hubbard <bhubbard@redhat.com>
src/ceph.in

index 79bec56261dc05beb01557fc8aca1b310ed66f8a..011cdcefc6962a003bfff716182c1934f09d9167 100755 (executable)
@@ -23,6 +23,8 @@ from __future__ import print_function
 import codecs
 import os
 import sys
+import subprocess
+import time
 import platform
 
 try:
@@ -312,6 +314,9 @@ def parse_cmdargs(args=None, target=''):
                         type=int,
                         help='set a timeout for connecting to the cluster')
 
+    parser.add_argument('--block', action='store_true',
+                        help='block until completion (scrub and deep-scrub only)')
+
     # returns a Namespace with the parsed args, and a list of all extras
     parsed_args, extras = parser.parse_known_args(args)
 
@@ -780,6 +785,40 @@ def daemonperf(childargs, sockpath):
 
     return 0
 
+def get_scrub_timestamps(childargs):
+    last_scrub_stamp = "last_" + childargs[1].replace('-', '_') + "_stamp"
+    results = dict()
+    scruball = False
+    if childargs[2] in ['all', 'any', '*']:
+        scruball = True
+    devnull = open(os.devnull, 'w')
+    out = subprocess.check_output(['ceph', 'pg', 'dump', '--format=json-pretty'],
+                                  stderr=devnull)
+    for stat in json.loads(out)['pg_stats']:
+        if scruball or stat['up_primary'] == int(childargs[2]):
+            scrub_tuple = (stat['up_primary'], stat[last_scrub_stamp])
+            results[stat['pgid']] = scrub_tuple
+    return results
+
+def check_scrub_stamps(waitdata, currdata):
+    for pg in waitdata.keys():
+       # Try to handle the case where a pg may not exist in current results
+       if pg in currdata and waitdata[pg][1] == currdata[pg][1]:
+           return False
+    return True
+
+def waitscrub(childargs, waitdata):
+    print(u'Waiting for {0} to complete...'.format(childargs[1]), file=sys.stdout)
+    currdata = get_scrub_timestamps(childargs)
+    while not check_scrub_stamps(waitdata, currdata):
+        time.sleep(3)
+        currdata = get_scrub_timestamps(childargs)
+    print(u'{0} completed'.format(childargs[1]), file=sys.stdout)
+
+def wait(childargs, waitdata):
+    if childargs[1] in ['scrub', 'deep-scrub']:
+        waitscrub(childargs, waitdata)
+
 
 def main():
     ceph_args = os.environ.get('CEPH_ARGS')
@@ -889,6 +928,15 @@ def main():
               file=sys.stderr)
         return 1
 
+    block = False
+    waitdata = dict()
+    if parsed_args.block:
+        if (len(childargs) >= 2 and
+                childargs[0] == 'osd' and
+                childargs[1] in ['deep-scrub', 'scrub']):
+            block = True
+            waitdata = get_scrub_timestamps(childargs)
+
     if parsed_args.help:
         # short default timeout for -h
         if not timeout:
@@ -1113,6 +1161,10 @@ def main():
 
         sys.stdout.flush()
 
+    # Block until command completion (currently scrub and deep_scrub only)
+    if block:
+        wait(childargs, waitdata)
+
     if parsed_args.output_file and parsed_args.output_file != '-':
         outf.close()