multipathd: measure path check time
authorHannes Reinecke <hare@suse.de>
Tue, 26 Nov 2013 11:41:30 +0000 (12:41 +0100)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Sat, 30 Nov 2013 14:56:21 +0000 (15:56 +0100)
Instrument code to measure path check time.

Signed-off-by: Hannes Reinecke <hare@suse.de>
multipathd/main.c

index 9b4e7c0..7c0e313 100644 (file)
@@ -1104,7 +1104,7 @@ int update_path_groups(struct multipath *mpp, struct vectors *vecs, int refresh)
        return 0;
 }
 
-void
+int
 check_path (struct vectors * vecs, struct path * pp)
 {
        int newstate;
@@ -1113,10 +1113,10 @@ check_path (struct vectors * vecs, struct path * pp)
        int oldchkrstate = pp->chkrstate;
 
        if (!pp->mpp)
-               return;
+               return 0;
 
        if (pp->tick && --pp->tick)
-               return; /* don't check this path yet */
+               return 0; /* don't check this path yet */
 
        /*
         * provision a next check soonest,
@@ -1131,7 +1131,7 @@ check_path (struct vectors * vecs, struct path * pp)
        if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) {
                condlog(2, "%s: unusable path", pp->dev);
                pathinfo(pp, conf->hwtable, 0);
-               return;
+               return 1;
        }
        /*
         * Async IO in flight. Keep the previous path state
@@ -1139,7 +1139,7 @@ check_path (struct vectors * vecs, struct path * pp)
         */
        if (newstate == PATH_PENDING) {
                pp->tick = 1;
-               return;
+               return 0;
        }
        /*
         * Synchronize with kernel state
@@ -1177,7 +1177,7 @@ check_path (struct vectors * vecs, struct path * pp)
                        pp->mpp->failback_tick = 0;
 
                        pp->mpp->stat_path_failures++;
-                       return;
+                       return 1;
                }
 
                if(newstate == PATH_UP || newstate == PATH_GHOST){
@@ -1262,6 +1262,7 @@ check_path (struct vectors * vecs, struct path * pp)
                         (chkr_new_path_up && followover_should_failback(pp)))
                        switch_pathgroup(pp->mpp);
        }
+       return 1;
 }
 
 static void *
@@ -1284,6 +1285,11 @@ checkerloop (void *ap)
        }
 
        while (1) {
+               struct timeval diff_time, start_time, end_time;
+               int num_paths = 0;
+
+               if (gettimeofday(&start_time, NULL) != 0)
+                       start_time.tv_sec = 0;
                pthread_cleanup_push(cleanup_lock, &vecs->lock);
                lock(vecs->lock);
                pthread_testcancel();
@@ -1291,7 +1297,7 @@ checkerloop (void *ap)
 
                if (vecs->pathvec) {
                        vector_foreach_slot (vecs->pathvec, pp, i) {
-                               check_path(vecs, pp);
+                               num_paths += check_path(vecs, pp);
                        }
                }
                if (vecs->mpvec) {
@@ -1307,6 +1313,14 @@ checkerloop (void *ap)
                }
 
                lock_cleanup_pop(vecs->lock);
+               if (start_time.tv_sec &&
+                   gettimeofday(&end_time, NULL) == 0 &&
+                   num_paths) {
+                       timersub(&end_time, &start_time, &diff_time);
+                       condlog(3, "checked %d path%s in %lu.%06lu secs",
+                               num_paths, num_paths > 1 ? "s" : "",
+                               diff_time.tv_sec, diff_time.tv_usec);
+               }
                sleep(1);
        }
        return NULL;