Bug 217014
Summary: | Setting "user_friendly_names" to "yes" causes dm-mp to occasionally miss a mpath device during configuration | ||
---|---|---|---|
Product: | Red Hat Enterprise Linux 4 | Reporter: | NetApp filed bugzillas <xdl-redhat-bugzilla> |
Component: | device-mapper-multipath | Assignee: | Ben Marzinski <bmarzins> |
Status: | CLOSED ERRATA | QA Contact: | Corey Marthaler <cmarthal> |
Severity: | high | Docs Contact: | |
Priority: | medium | ||
Version: | 4.4 | CC: | agk, bmarzins, christophe.varoqui, dwysocha, egoggin, junichi.nomura, kueda, lmb, mbroz, prockai, tranlan, xdl-redhat-bugzilla |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | RHEA-2007-0256 | Doc Type: | Bug Fix |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2007-05-01 17:47:20 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
NetApp filed bugzillas
2006-11-23 07:18:33 UTC
The posix file byte range locks used to provide atomicity for accessing the entries in the multipath bindings file get released from whenever __any__ descriptor or FILE structure for that file is closed. This patch delays the fclose() for the FILE structures used within lookup_binding() and rlookup_binding() until there is no more need for the atomicity. Without this patch I could fairly easily get two multipath mpath0 entries in /var/lib/multipath/bindings by running 8 concurrent instances of multipath (8) while with the patch I cannot get this problem to occur. diff --git a/libmultipath/alias.c b/libmultipath/alias.c index 6d103d7..86cae9b 100644 --- a/libmultipath/alias.c +++ b/libmultipath/alias.c @@ -166,28 +166,14 @@ fail: static int -lookup_binding(int fd, char *map_wwid, char **map_alias) +lookup_binding(FILE *f, char *map_wwid, char **map_alias) { char buf[LINE_MAX]; - FILE *f; unsigned int line_nr = 0; - int scan_fd; int id = 0; *map_alias = NULL; - scan_fd = dup(fd); - if (scan_fd < 0) { - condlog(0, "Cannot dup bindings file descriptor : %s", - strerror(errno)); - return -1; - } - f = fdopen(scan_fd, "r"); - if (!f) { - condlog(0, "cannot fdopen on bindings file descriptor : %s", - strerror(errno)); - close(scan_fd); - return -1; - } + while (fgets(buf, LINE_MAX, f)) { char *c, *alias, *wwid; int curr_id; @@ -215,38 +201,22 @@ lookup_binding(int fd, char *map_wwid, c if (*map_alias == NULL) condlog(0, "Cannot copy alias from bindings " "file : %s", strerror(errno)); - fclose(f); return id; } } condlog(3, "No matching wwid [%s] in bindings file.", map_wwid); - fclose(f); return id; } static int -rlookup_binding(int fd, char **map_wwid, char *map_alias) +rlookup_binding(FILE *f, char **map_wwid, char *map_alias) { char buf[LINE_MAX]; - FILE *f; unsigned int line_nr = 0; - int scan_fd; int id = 0; *map_wwid = NULL; - scan_fd = dup(fd); - if (scan_fd < 0) { - condlog(0, "Cannot dup bindings file descriptor : %s", - strerror(errno)); - return -1; - } - f = fdopen(scan_fd, "r"); - if (!f) { - condlog(0, "cannot fdopen on bindings file descriptor : %s", - strerror(errno)); - close(scan_fd); - return -1; - } + while (fgets(buf, LINE_MAX, f)) { char *c, *alias, *wwid; int curr_id; @@ -274,12 +244,10 @@ rlookup_binding(int fd, char **map_wwid, if (*map_wwid == NULL) condlog(0, "Cannot copy alias from bindings " "file : %s", strerror(errno)); - fclose(f); return id; } } condlog(3, "No matching alias [%s] in bindings file.", map_alias); - fclose(f); return id; } @@ -327,7 +295,8 @@ char * get_user_friendly_alias(char *wwid, char *file) { char *alias; - int fd, id; + int fd, scan_fd, id; + FILE *f; if (!wwid || *wwid == '\0') { condlog(3, "Cannot find binding for empty WWID"); @@ -337,14 +306,37 @@ get_user_friendly_alias(char *wwid, char fd = open_bindings_file(file); if (fd < 0) return NULL; - id = lookup_binding(fd, wwid, &alias); + + scan_fd = dup(fd); + if (scan_fd < 0) { + condlog(0, "Cannot dup bindings file descriptor : %s", + strerror(errno)); + close(fd); + return NULL; + } + + f = fdopen(scan_fd, "r"); + if (!f) { + condlog(0, "cannot fdopen on bindings file descriptor : %s", + strerror(errno)); + close(scan_fd); + close(fd); + return NULL; + } + + id = lookup_binding(f, wwid, &alias); if (id < 0) { + fclose(f); + close(scan_fd); close(fd); return NULL; } + if (!alias) alias = allocate_binding(fd, wwid, id); + fclose(f); + close(scan_fd); close(fd); return alias; } @@ -353,7 +345,8 @@ char * get_user_friendly_wwid(char *alias, char *file) { char *wwid; - int fd, id; + int fd, scan_fd, id; + FILE *f; if (!alias || *alias == '\0') { condlog(3, "Cannot find binding for empty alias"); @@ -363,12 +356,34 @@ get_user_friendly_wwid(char *alias, char fd = open_bindings_file(file); if (fd < 0) return NULL; - id = rlookup_binding(fd, &wwid, alias); + + scan_fd = dup(fd); + if (scan_fd < 0) { + condlog(0, "Cannot dup bindings file descriptor : %s", + strerror(errno)); + close(fd); + return NULL; + } + + f = fdopen(scan_fd, "r"); + if (!f) { + condlog(0, "cannot fdopen on bindings file descriptor : %s", + strerror(errno)); + close(scan_fd); + close(fd); + return NULL; + } + + id = rlookup_binding(f, &wwid, alias); if (id < 0) { + fclose(f); + close(scan_fd); close(fd); return NULL; } + fclose(f); + close(scan_fd); close(fd); return wwid; } This patch has been applied. Does RHEL5 has this fix? Yes An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on the solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHEA-2007-0256.html |