From patchwork Wed Dec 11 06:43:03 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Marzinski X-Patchwork-Id: 3322581 X-Patchwork-Delegate: christophe.varoqui@free.fr Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B0B349F37C for ; Wed, 11 Dec 2013 06:47:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CAF682075A for ; Wed, 11 Dec 2013 06:47:17 +0000 (UTC) Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by mail.kernel.org (Postfix) with ESMTP id E804D20749 for ; Wed, 11 Dec 2013 06:47:16 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id rBB6hnVt018565; Wed, 11 Dec 2013 01:43:49 -0500 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 rBB6hWJS021169 for ; Wed, 11 Dec 2013 01:43:32 -0500 Received: from dhcp80-209.msp.redhat.com (octiron.msp.redhat.com [10.15.80.209]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rBB6hVvc009291 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 11 Dec 2013 01:43:32 -0500 Received: from dhcp80-209.msp.redhat.com (localhost [127.0.0.1]) by dhcp80-209.msp.redhat.com (8.14.7/8.14.7) with ESMTP id rBB6hUNW001372; Wed, 11 Dec 2013 00:43:31 -0600 Received: (from bmarzins@localhost) by dhcp80-209.msp.redhat.com (8.14.7/8.14.7/Submit) id rBB6hUrX001371; Wed, 11 Dec 2013 00:43:30 -0600 From: Benjamin Marzinski To: device-mapper development Date: Wed, 11 Dec 2013 00:43:03 -0600 Message-Id: <1386744190-1295-10-git-send-email-bmarzins@redhat.com> In-Reply-To: <1386744190-1295-1-git-send-email-bmarzins@redhat.com> References: <1386744190-1295-1-git-send-email-bmarzins@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-loop: dm-devel@redhat.com Cc: Christophe Varoqui Subject: [dm-devel] [PATCH 09/16] libmultipath: try to deal with bindings file hand editting X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk Reply-To: device-mapper development 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.1 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 Unfortunately, instead of adding aliases to /etc/multipath.conf like they should, some users add aliases to the bindings file. If they add aliases that look like user_friendly_names, like mpathfoo, they interfere with the code to find the next available user_friendly_name (giving you mpathfop as the next user_friendly_name in this case). This patch will fix this by giving the next name available name after an unbroken string of names starting with the smallest possible name. It order to keep the choice quick, it won't handle situation where the list of names starting at the smallest possible is not in order. There are a number of ways to do a better job finding the smallest possible name, but this will fix most of the cases I've seen, without slowing things down at all. Signed-off-by: Benjamin Marzinski --- libmultipath/alias.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/libmultipath/alias.c b/libmultipath/alias.c index d913294..ab15185 100644 --- a/libmultipath/alias.c +++ b/libmultipath/alias.c @@ -46,11 +46,11 @@ format_devname(char *name, int id, int len, char *prefix) memset(name,0, len); strcpy(name, prefix); for (pos = len - 1; pos >= prefix_len; pos--) { + id--; name[pos] = 'a' + id % 26; if (id < 26) break; id /= 26; - id--; } memmove(name + prefix_len, name + pos, len - pos); name[prefix_len + len - pos] = '\0'; @@ -66,13 +66,22 @@ scan_devname(char *alias, char *prefix) if (!prefix || strncmp(alias, prefix, strlen(prefix))) return -1; + if (strlen(alias) == strlen(prefix)) + return -1; + + if (strlen(alias) > strlen(prefix) + 7) + /* id of 'aaaaaaaa' overflows int */ + return -1; + c = alias + strlen(prefix); while (*c != '\0' && *c != ' ' && *c != '\t') { + if (*c < 'a' || *c > 'z') + return -1; i = *c - 'a'; n = ( n * 26 ) + i; + if (n < 0) + return -1; c++; - if (*c < 'a' || *c > 'z') - break; n++; } @@ -84,7 +93,9 @@ lookup_binding(FILE *f, char *map_wwid, char **map_alias, char *prefix) { char buf[LINE_MAX]; unsigned int line_nr = 0; - int id = 0; + int id = 1; + int biggest_id = 1; + int smallest_bigger_id = INT_MAX; *map_alias = NULL; @@ -100,8 +111,12 @@ lookup_binding(FILE *f, char *map_wwid, char **map_alias, char *prefix) if (!alias) /* blank line */ continue; curr_id = scan_devname(alias, prefix); - if (curr_id >= id) - id = curr_id + 1; + if (curr_id == id) + id++; + if (curr_id > biggest_id) + biggest_id = curr_id; + if (curr_id > id && curr_id < smallest_bigger_id) + smallest_bigger_id = curr_id; wwid = strtok(NULL, " \t"); if (!wwid){ condlog(3, @@ -116,11 +131,17 @@ lookup_binding(FILE *f, char *map_wwid, char **map_alias, char *prefix) if (*map_alias == NULL) condlog(0, "Cannot copy alias from bindings " "file : %s", strerror(errno)); - return id; + return 0; } } condlog(3, "No matching wwid [%s] in bindings file.", map_wwid); - return id; + if (id < 0) { + condlog(0, "no more available user_friendly_names"); + return 0; + } + if (id < smallest_bigger_id) + return id; + return biggest_id + 1; } static int @@ -254,7 +275,7 @@ get_user_friendly_alias(char *wwid, char *file, char *prefix, return NULL; } - if (!alias && can_write && !bindings_read_only) + if (!alias && can_write && !bindings_read_only && id) alias = allocate_binding(fd, wwid, id, prefix); fclose(f);