From patchwork Fri Mar 28 21:01:14 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Stewart, Sean" X-Patchwork-Id: 3907151 X-Patchwork-Delegate: christophe.varoqui@free.fr 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.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 08410BF540 for ; Fri, 28 Mar 2014 21:07:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 10F852034F for ; Fri, 28 Mar 2014 21:07:00 +0000 (UTC) Received: from mx3-phx2.redhat.com (mx5-phx2.redhat.com [209.132.183.37]) by mail.kernel.org (Postfix) with ESMTP id B17002034E for ; Fri, 28 Mar 2014 21:06:58 +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.14.4/8.14.4) with ESMTP id s2SL1s2b018270; Fri, 28 Mar 2014 17:01:55 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s2SL1qDT002816 for ; Fri, 28 Mar 2014 17:01:52 -0400 Received: from mx1.redhat.com (ext-mx11.extmail.prod.ext.phx2.redhat.com [10.5.110.16]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s2SL1pC4023186; Fri, 28 Mar 2014 17:01:51 -0400 Received: from mx12.netapp.com (mx12.netapp.com [216.240.18.77]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s2SL1Xw9020755; Fri, 28 Mar 2014 17:01:37 -0400 X-IronPort-AV: E=Sophos;i="4.97,752,1389772800"; d="scan'208";a="153874277" Received: from vmwexceht05-prd.hq.netapp.com ([10.106.77.35]) by mx12-out.netapp.com with ESMTP; 28 Mar 2014 14:01:16 -0700 Received: from SACEXCMBX04-PRD.hq.netapp.com ([169.254.6.187]) by vmwexceht05-prd.hq.netapp.com ([10.106.77.35]) with mapi id 14.03.0123.003; Fri, 28 Mar 2014 14:01:15 -0700 From: "Stewart, Sean" To: "dm-devel@redhat.com" Thread-Topic: [PATCH] libmultipath: Use existing user friendly name if possible Thread-Index: Ac9KyGUM8565NHeRQ/2ydKizLLoUzA== Date: Fri, 28 Mar 2014 21:01:14 +0000 Message-ID: <8255ED565A0EAA4A960625E27D49DBF24AC9EB61@SACEXCMBX04-PRD.hq.netapp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.106.53.53] MIME-Version: 1.0 X-RedHat-Spam-Score: -7.375 (BAYES_00, DCC_REPUT_13_19, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS, URIBL_BLOCKED) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-Scanned-By: MIMEDefang 2.68 on 10.5.110.16 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id s2SL1qDT002816 X-loop: dm-devel@redhat.com Subject: [dm-devel] [PATCH] libmultipath: Use existing user friendly name if possible 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: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,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 a system is booted to the SAN, a condition can occur where one user friendly name is given to a disk during boot, but multipathd tries to allocate a different one after boot. If the second alias is already used by another device, multipathd can't rename it. Multipathd then has incorrect information about the alias/wwid relationships, which can result in paths being added to the wrong map. This patch works around this problem by first trying to use the alias already bound to a device during boot. If the bindings file has that alias bound to a different device, it'll auto generate a new alias to rename it to. The alias prioritization is: 1. multipath.conf per-device alias 2. Currently bound alias 3. New auto-generated alias 4. wwid Signed-off-by: Sean Stewart Reviewed-by: Shiva Krishna Merla --- libmultipath/alias.c | 64 +++++++++++++++++++++++++++++++++++++++++++--- libmultipath/alias.h | 2 ++ libmultipath/propsel.c | 32 +++++++++++++++-------- libmultipath/structs_vec.c | 15 +++++++++++ 4 files changed, 100 insertions(+), 13 deletions(-) diff --git a/libmultipath/alias.c b/libmultipath/alias.c index ab15185..008396e 100644 --- a/libmultipath/alias.c +++ b/libmultipath/alias.c @@ -145,7 +145,7 @@ lookup_binding(FILE *f, char *map_wwid, char **map_alias, char *prefix) } static int -rlookup_binding(FILE *f, char *buff, char *map_alias) +rlookup_binding(FILE *f, char *buff, char *map_alias, char *prefix) { char line[LINE_MAX]; unsigned int line_nr = 0; @@ -164,7 +164,7 @@ rlookup_binding(FILE *f, char *buff, char *map_alias) alias = strtok(line, " \t"); if (!alias) /* blank line */ continue; - curr_id = scan_devname(alias, NULL); /* TBD: Why this call? */ + curr_id = scan_devname(alias, prefix); if (curr_id >= id) id = curr_id + 1; wwid = strtok(NULL, " \t"); @@ -188,6 +188,11 @@ rlookup_binding(FILE *f, char *buff, char *map_alias) } } condlog(3, "No matching alias [%s] in bindings file.", map_alias); + + /* Get the theoretical id for this map alias. + * Used by use_existing_alias + */ + id = scan_devname(map_alias, prefix); return id; } @@ -237,6 +242,59 @@ allocate_binding(int fd, char *wwid, int id, char *prefix) } char * +use_existing_alias (char *wwid, char *file, char *alias_old, + char *prefix, int bindings_read_only) +{ + char *alias = NULL; + int id = 0; + int fd, can_write; + char buff[WWID_SIZE]; + FILE *f; + + fd = open_file(file, &can_write, BINDINGS_FILE_HEADER); + if (fd < 0) + return NULL; + + f = fdopen(fd, "r"); + if (!f) { + condlog(0, "cannot fdopen on bindings file descriptor"); + close(fd); + return NULL; + } + /* lookup the binding. if it exsists, the wwid will be in buff + * either way, id contains the id for the alias + */ + id = rlookup_binding(f , buff, alias_old, prefix); + if (id < 0) + goto out; + + if (strlen(buff) > 0) { + /* if buff is our wwid, it's already + * allocated correctly + */ + if (strcmp(buff, wwid) == 0) + alias = STRDUP(alias_old); + else { + alias = NULL; + condlog(0, "alias %s already bound to wwid %s, cannot reuse", + alias_old, buff); + } + goto out; + } + + /* allocate the existing alias in the bindings file */ + if (can_write && id && !bindings_read_only) { + alias = allocate_binding(fd, wwid, id, prefix); + condlog(0, "Allocated existing binding [%s] for WWID [%s]", + alias, wwid); + } + +out: + fclose(f); + return alias; +} + +char * get_user_friendly_alias(char *wwid, char *file, char *prefix, int bindings_read_only) { @@ -305,7 +363,7 @@ get_user_friendly_wwid(char *alias, char *buff, char *file) return -1; } - rlookup_binding(f, buff, alias); + rlookup_binding(f, buff, alias, NULL); if (!strlen(buff)) { fclose(f); return -1; diff --git a/libmultipath/alias.h b/libmultipath/alias.h index 8ddd0b5..9cb3e8f 100644 --- a/libmultipath/alias.h +++ b/libmultipath/alias.h @@ -10,3 +10,5 @@ char *get_user_friendly_alias(char *wwid, char *file, char *prefix, int bindings_readonly); int get_user_friendly_wwid(char *alias, char *buff, char *file); +char *use_existing_alias (char *wwid, char *file, char *alias_old, + char *prefix, int bindings_read_only); diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c index 7b7944d..2859e3e 100644 --- a/libmultipath/propsel.c +++ b/libmultipath/propsel.c @@ -253,19 +253,31 @@ want_user_friendly_names(struct multipath * mp) extern int select_alias (struct multipath * mp) { - if (mp->mpe && mp->mpe->alias) + if (mp->mpe && mp->mpe->alias) { mp->alias = STRDUP(mp->mpe->alias); - else { - mp->alias = NULL; - if (want_user_friendly_names(mp)) { - select_alias_prefix(mp); - mp->alias = get_user_friendly_alias(mp->wwid, - conf->bindings_file, mp->alias_prefix, conf->bindings_read_only); - } - if (mp->alias == NULL) - mp->alias = STRDUP(mp->wwid); + goto out; } + mp->alias = NULL; + if (!want_user_friendly_names(mp)) + goto out; + + select_alias_prefix(mp); + + if (strlen(mp->alias_old) > 0) { + mp->alias = use_existing_alias(mp->wwid, conf->bindings_file, + mp->alias_old, mp->alias_prefix, + conf->bindings_read_only); + memset (mp->alias_old, 0, WWID_SIZE); + } + + if (mp->alias == NULL) + mp->alias = get_user_friendly_alias(mp->wwid, + conf->bindings_file, mp->alias_prefix, conf->bindings_read_only); +out: + if (mp->alias == NULL) + mp->alias = STRDUP(mp->wwid); + return mp->alias ? 0 : 1; } diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c index 76c7e02..8cdbe3d 100644 --- a/libmultipath/structs_vec.c +++ b/libmultipath/structs_vec.c @@ -403,6 +403,20 @@ out: return NULL; } +static void +find_existing_alias (struct multipath * mpp, + struct vectors *vecs) +{ + struct multipath * mp; + int i; + + vector_foreach_slot (vecs->mpvec, mp, i) + if (strcmp(mp->wwid, mpp->wwid) == 0) { + strncpy(mpp->alias_old, mp->alias, WWID_SIZE); + return; + } +} + extern struct multipath * add_map_with_path (struct vectors * vecs, struct path * pp, int add_vec) @@ -416,6 +430,7 @@ add_map_with_path (struct vectors * vecs, mpp->hwe = pp->hwe; strcpy(mpp->wwid, pp->wwid); + find_existing_alias(mpp, vecs); if (select_alias(mpp)) goto out; mpp->size = pp->size;