From patchwork Sat May 23 21:00:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Seiler X-Patchwork-Id: 6470741 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 05AA79F318 for ; Sat, 23 May 2015 21:05:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D994C20503 for ; Sat, 23 May 2015 21:05:53 +0000 (UTC) Received: from mx5-phx2.redhat.com (mx5-phx2.redhat.com [209.132.183.37]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7D2D3204FF for ; Sat, 23 May 2015 21:05:49 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx5-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t4NL0ShY006137; Sat, 23 May 2015 17:00:29 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id t4NL0RHh005517 for ; Sat, 23 May 2015 17:00:27 -0400 Received: from mx1.redhat.com (ext-mx03.extmail.prod.ext.phx2.redhat.com [10.5.110.27]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t4NL0RnB002729 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 23 May 2015 17:00:27 -0400 Received: from arafel.iwakd.de (arafel.iwakd.de [78.46.72.57]) by mx1.redhat.com (Postfix) with ESMTPS id 30B1D8E4EF; Sat, 23 May 2015 21:00:19 +0000 (UTC) Received: from [IPv6:2a02:810d:25bf:e5e8:1cf9:ef6a:67af:75b3] (unknown [IPv6:2a02:810d:25bf:e5e8:1cf9:ef6a:67af:75b3]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by arafel.iwakd.de (Postfix) with ESMTPSA id 2564C9230D6; Sat, 23 May 2015 23:00:17 +0200 (CEST) Message-ID: <5560EA5C.6040001@iwakd.de> Date: Sat, 23 May 2015 23:00:12 +0200 From: Christian Seiler User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.7.0 MIME-Version: 1.0 To: dm-devel@redhat.com X-RedHat-Spam-Score: -1.909 (BAYES_00, T_RP_MATCHES_RCVD, URIBL_BLOCKED) 78.46.72.57 arafel.iwakd.de 78.46.72.57 arafel.iwakd.de X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Scanned-By: MIMEDefang 2.76 on 10.5.110.27 X-loop: dm-devel@redhat.com Subject: [dm-devel] [PATCH] libmultipath: don't lock block device but use lock files 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=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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 In recent versions udev uses flock() on the device node itself, breaking libmultipath's current locking logic. Since libmultipath doesn't actually modify anything on the device itself (and hence does not actually need an exclusive lock on the device node, unlike e.g. tools that create partitions etc.), and the reason for the lock is to guard against multipath interfering with multipathd, use lock files (named after the devices) in /run/lock/multipath instead. See the discussion under: https://www.redhat.com/archives/dm-devel/2014-December/msg00083.html Especially: https://www.redhat.com/archives/dm-devel/2014-December/msg00117.html Signed-off-by: Christian Seiler --- libmultipath/configure.c | 45 +++++++++++++++++++++++++++++++++++++++++---- libmultipath/configure.h | 2 ++ libmultipath/structs.c | 7 +++++++ libmultipath/structs.h | 3 +++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/libmultipath/configure.c b/libmultipath/configure.c index 24ad948..f77f97f 100644 --- a/libmultipath/configure.c +++ b/libmultipath/configure.c @@ -534,6 +534,8 @@ lock_multipath (struct multipath * mpp, int lock) struct path * pp; int i, j; int x, y; + char *ptr; + size_t len; if (!mpp || !mpp->pg) return 0; @@ -542,11 +544,45 @@ lock_multipath (struct multipath * mpp, int lock) if (!pgp->paths) continue; vector_foreach_slot(pgp->paths, pp, j) { - if (lock && flock(pp->fd, LOCK_EX | LOCK_NB) && + if (!pp->lock_path) { + len = sizeof(CONFIGURE_LOCK_DIRECTORY) + strlen(udev_device_get_devnode(pp->udev)) + 1; + pp->lock_path = MALLOC(len); + if (!pp->lock_path) { + condlog(0, "couldn't allocate lock path"); + goto fail; + } + if (safe_snprintf(pp->lock_path, len, "%s/%s", + CONFIGURE_LOCK_DIRECTORY, udev_device_get_devnode(pp->udev))) { + condlog(0, "couldn't allocate lock path"); + FREE(pp->lock_path); + pp->lock_path = NULL; + goto fail; + } + for (ptr = pp->lock_path + sizeof(CONFIGURE_LOCK_DIRECTORY); *ptr; ptr++) { + if ((*ptr < '0' || *ptr > '9') && (*ptr < 'A' || *ptr > 'Z') && + (*ptr < 'a' || *ptr > 'z') && *ptr != '-' && *ptr != '_' && *ptr != '.') + *ptr = '_'; + } + } + if (pp->lock_fd < 0) { + pp->lock_fd = open(pp->lock_path, O_RDWR | O_CREAT, 0600); + if (pp->lock_fd < 0 && errno == ENOENT) { + if (mkdir(CONFIGURE_LOCK_DIRECTORY, 0700) < 0) { + condlog(0, "%s: couldn't create lock directory", CONFIGURE_LOCK_DIRECTORY); + goto fail; + } + pp->lock_fd = open(pp->lock_path, O_RDWR | O_CREAT, 0600); + } + if (pp->lock_fd < 0) { + condlog(0, "%s: couldn't open lock file", pp->lock_path); + goto fail; + } + } + if (lock && flock(pp->lock_fd, LOCK_EX | LOCK_NB) && errno == EWOULDBLOCK) goto fail; - else if (!lock) - flock(pp->fd, LOCK_UN); + else if (!lock && pp->lock_fd >= 0) + flock(pp->lock_fd, LOCK_UN); } } return 0; @@ -559,7 +595,8 @@ fail: vector_foreach_slot(pgp->paths, pp, y) { if (x == i && y >= j) return 1; - flock(pp->fd, LOCK_UN); + if (pp->lock_fd >= 0) + flock(pp->fd, LOCK_UN); } } return 1; diff --git a/libmultipath/configure.h b/libmultipath/configure.h index c014b55..0415453 100644 --- a/libmultipath/configure.h +++ b/libmultipath/configure.h @@ -24,6 +24,8 @@ enum actions { #define FLUSH_ONE 1 #define FLUSH_ALL 2 +#define CONFIGURE_LOCK_DIRECTORY "/run/lock/multipath" + int setup_map (struct multipath * mpp, char * params, int params_size ); int domap (struct multipath * mpp, char * params); int reinstate_paths (struct multipath *mpp); diff --git a/libmultipath/structs.c b/libmultipath/structs.c index 0538327..ca7bcb5 100644 --- a/libmultipath/structs.c +++ b/libmultipath/structs.c @@ -95,6 +95,7 @@ alloc_path (void) pp->sg_id.scsi_id = -1; pp->sg_id.lun = -1; pp->fd = -1; + pp->lock_fd = -1; pp->priority = PRIO_UNDEF; } return pp; @@ -115,6 +116,12 @@ free_path (struct path * pp) if (pp->fd >= 0) close(pp->fd); + if (pp->lock_fd >= 0) + close(pp->lock_fd); + + if (pp->lock_path) + free(pp->lock_path); + if (pp->udev) { udev_device_unref(pp->udev); pp->udev = NULL; diff --git a/libmultipath/structs.h b/libmultipath/structs.h index c1fce04..916aea5 100644 --- a/libmultipath/structs.h +++ b/libmultipath/structs.h @@ -204,6 +204,9 @@ struct path { /* configlet pointers */ struct hwentry * hwe; + + int lock_fd; + char * lock_path; }; typedef int (pgpolicyfn) (struct multipath *);