From patchwork Wed Apr 27 11:10:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 8955311 Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 47996BF29F for ; Wed, 27 Apr 2016 11:15:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3A336200CC for ; Wed, 27 Apr 2016 11:15:20 +0000 (UTC) Received: from mx4-phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 461E72022A for ; Wed, 27 Apr 2016 11:15:14 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id u3RBC9VV005731; Wed, 27 Apr 2016 07:12:10 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id u3RBBPv7012562 for ; Wed, 27 Apr 2016 07:11:25 -0400 Received: from mx1.redhat.com (ext-mx03.extmail.prod.ext.phx2.redhat.com [10.5.110.27]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u3RBBPWA025805 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 27 Apr 2016 07:11:25 -0400 Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CA18772D3B; Wed, 27 Apr 2016 11:11:22 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 04575ADE7; Wed, 27 Apr 2016 11:11:11 +0000 (UTC) From: Hannes Reinecke To: Christophe Varoqui Date: Wed, 27 Apr 2016 13:10:58 +0200 Message-Id: <1461755458-29225-58-git-send-email-hare@suse.de> In-Reply-To: <1461755458-29225-1-git-send-email-hare@suse.de> References: <1461755458-29225-1-git-send-email-hare@suse.de> X-RedHat-Spam-Score: -0.607 (BAYES_50, DCC_REPUT_00_12, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, SPF_PASS) 195.135.220.15 mx2.suse.de 195.135.220.15 mx2.suse.de X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Scanned-By: MIMEDefang 2.76 on 10.5.110.27 X-loop: dm-devel@redhat.com Cc: dm-devel@redhat.com, Mike Snitzer Subject: [dm-devel] [PATCH 57/57] Allow specific CLI commands to run unlocked X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When multipath is busy with checking paths or processing udev events it'll take the vector lock, causing the CLI to become unresponsive. This patch allows certain CLI commands to not wait for the vector lock, so that those commands will always succeed. Signed-off-by: Hannes Reinecke --- multipathd/cli.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- multipathd/cli.h | 4 +++- multipathd/main.c | 26 ++++++++++++-------------- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/multipathd/cli.c b/multipathd/cli.c index 3c9cdbf..d991cd0 100644 --- a/multipathd/cli.c +++ b/multipathd/cli.c @@ -1,9 +1,13 @@ /* * Copyright (c) 2005 Christophe Varoqui */ +#include #include +#include #include #include +#include +#include #include #include #include @@ -100,6 +104,19 @@ set_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *)) if (!h) return 1; h->fn = fn; + h->locked = 1; + return 0; +} + +int +set_unlocked_handler_callback (unsigned long fp,int (*fn)(void *, char **, int *, void *)) +{ + struct handler * h = find_handler(fp); + + if (!h) + return 1; + h->fn = fn; + h->locked = 0; return 0; } @@ -430,11 +447,13 @@ genhelp_handler (const char *cmd, int error) } int -parse_cmd (char * cmd, char ** reply, int * len, void * data) +parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout ) { int r; struct handler * h; vector cmdvec = NULL; + struct timespec tmo; + struct timeval now; r = get_cmdvec(cmd, &cmdvec); @@ -456,7 +475,30 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data) /* * execute handler */ - r = h->fn(cmdvec, reply, len, data); + if (gettimeofday(&now, NULL) == 0) { + tmo.tv_sec = now.tv_sec + timeout; + tmo.tv_nsec = now.tv_usec * 1000; + } else { + tmo.tv_sec = 0; + } + if (h->locked) { + struct vectors * vecs = (struct vectors *)data; + + pthread_cleanup_push(cleanup_lock, &vecs->lock); + if (tmo.tv_sec) { + vecs->lock.depth++; + r = pthread_mutex_timedlock(vecs->lock.mutex, &tmo); + } else { + lock(vecs->lock); + r = 0; + } + if (r == 0) { + pthread_testcancel(); + r = h->fn(cmdvec, reply, len, data); + } + lock_cleanup_pop(vecs->lock); + } else + r = h->fn(cmdvec, reply, len, data); free_keys(cmdvec); return r; diff --git a/multipathd/cli.h b/multipathd/cli.h index 2aa19d5..84ca40f 100644 --- a/multipathd/cli.h +++ b/multipathd/cli.h @@ -100,13 +100,15 @@ struct key { struct handler { uint64_t fingerprint; + int locked; int (*fn)(void *, char **, int *, void *); }; int alloc_handlers (void); int add_handler (uint64_t fp, int (*fn)(void *, char **, int *, void *)); int set_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *)); -int parse_cmd (char * cmd, char ** reply, int * len, void *); +int set_unlocked_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *)); +int parse_cmd (char * cmd, char ** reply, int * len, void *, int); int load_keys (void); char * get_keyparam (vector v, uint64_t code); void free_keys (vector vec); diff --git a/multipathd/main.c b/multipathd/main.c index 132101f..dc788c5 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -974,14 +974,13 @@ uxsock_trigger (char * str, char ** reply, int * len, void * trigger_data) *len = 0; vecs = (struct vectors *)trigger_data; - pthread_cleanup_push(cleanup_lock, &vecs->lock); - lock(vecs->lock); - pthread_testcancel(); - - r = parse_cmd(str, reply, len, vecs); + r = parse_cmd(str, reply, len, vecs, uxsock_timeout / 1000); if (r > 0) { - *reply = STRDUP("fail\n"); + if (r == ETIMEDOUT) + *reply = STRDUP("timeout\n"); + else + *reply = STRDUP("fail\n"); *len = strlen(*reply) + 1; r = 1; } @@ -992,7 +991,6 @@ uxsock_trigger (char * str, char ** reply, int * len, void * trigger_data) } /* else if (r < 0) leave *reply alone */ - lock_cleanup_pop(vecs->lock); return r; } @@ -1112,8 +1110,8 @@ uxlsnrloop (void * ap) set_handler_callback(LIST+PATHS+RAW+FMT, cli_list_paths_raw); set_handler_callback(LIST+PATH, cli_list_path); set_handler_callback(LIST+MAPS, cli_list_maps); - set_handler_callback(LIST+STATUS, cli_list_status); - set_handler_callback(LIST+DAEMON, cli_list_daemon); + set_unlocked_handler_callback(LIST+STATUS, cli_list_status); + set_unlocked_handler_callback(LIST+DAEMON, cli_list_daemon); set_handler_callback(LIST+MAPS+STATUS, cli_list_maps_status); set_handler_callback(LIST+MAPS+STATS, cli_list_maps_stats); set_handler_callback(LIST+MAPS+FMT, cli_list_maps_fmt); @@ -1123,8 +1121,8 @@ uxlsnrloop (void * ap) set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology); set_handler_callback(LIST+MAP+FMT, cli_list_map_fmt); set_handler_callback(LIST+MAP+RAW+FMT, cli_list_map_fmt); - set_handler_callback(LIST+CONFIG, cli_list_config); - set_handler_callback(LIST+BLACKLIST, cli_list_blacklist); + set_unlocked_handler_callback(LIST+CONFIG, cli_list_config); + set_unlocked_handler_callback(LIST+BLACKLIST, cli_list_blacklist); set_handler_callback(LIST+DEVICES, cli_list_devices); set_handler_callback(LIST+WILDCARDS, cli_list_wildcards); set_handler_callback(ADD+PATH, cli_add_path); @@ -1132,7 +1130,7 @@ uxlsnrloop (void * ap) set_handler_callback(ADD+MAP, cli_add_map); set_handler_callback(DEL+MAP, cli_del_map); set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group); - set_handler_callback(RECONFIGURE, cli_reconfigure); + set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure); set_handler_callback(SUSPEND+MAP, cli_suspend); set_handler_callback(RESUME+MAP, cli_resume); set_handler_callback(RESIZE+MAP, cli_resize); @@ -1144,8 +1142,8 @@ uxlsnrloop (void * ap) set_handler_callback(RESTOREQ+MAP, cli_restore_queueing); set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing); set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing); - set_handler_callback(QUIT, cli_quit); - set_handler_callback(SHUTDOWN, cli_shutdown); + set_unlocked_handler_callback(QUIT, cli_quit); + set_unlocked_handler_callback(SHUTDOWN, cli_shutdown); set_handler_callback(GETPRSTATUS+MAP, cli_getprstatus); set_handler_callback(SETPRSTATUS+MAP, cli_setprstatus); set_handler_callback(UNSETPRSTATUS+MAP, cli_unsetprstatus);