From patchwork Thu Mar 14 14:08:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 2271401 Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by patchwork1.kernel.org (Postfix) with ESMTP id 02A1E3FC8A for ; Thu, 14 Mar 2013 14:12: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 r2EE906T013631; Thu, 14 Mar 2013 10:09:01 -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 r2EE8xs3021398 for ; Thu, 14 Mar 2013 10:08:59 -0400 Received: from mx1.redhat.com (ext-mx16.extmail.prod.ext.phx2.redhat.com [10.5.110.21]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r2EE8xOW018054 for ; Thu, 14 Mar 2013 10:08:59 -0400 Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2EE8ohI021404 for ; Thu, 14 Mar 2013 10:08:51 -0400 Received: from relay1.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id E7B62A522F; Thu, 14 Mar 2013 15:08:49 +0100 (CET) From: Hannes Reinecke To: dm-devel@redhat.com Date: Thu, 14 Mar 2013 15:08:46 +0100 Message-Id: <1363270128-20900-5-git-send-email-hare@suse.de> In-Reply-To: <1363270128-20900-1-git-send-email-hare@suse.de> References: <1363270128-20900-1-git-send-email-hare@suse.de> X-RedHat-Spam-Score: -9.302 (BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, URIBL_BLOCKED) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-Scanned-By: MIMEDefang 2.68 on 10.5.110.21 X-loop: dm-devel@redhat.com Cc: Christophe Varoqui Subject: [dm-devel] [PATCH 4/6] libmultipath: Implement sysfs_attr_get_value() 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 When we've modified an sysfs attribute via sysfs_attr_set_value() we cannot use libudev-provided functions to read the current value from that attribute, as libudev will return the stale cached value here. Signed-off-by: Hannes Reinecke --- libmultipath/sysfs.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ libmultipath/sysfs.h | 2 ++ 2 files changed, 58 insertions(+) diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c index da228e4..22b73b1 100644 --- a/libmultipath/sysfs.c +++ b/libmultipath/sysfs.c @@ -38,6 +38,62 @@ #include "debug.h" #include "devmapper.h" +/* + * When we modify an attribute value we cannot rely on libudev for now, + * as libudev lacks the capability to update an attribute value. + * So for modified attributes we need to implement our own function. + */ +ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + char * value, size_t value_len) +{ + char devpath[PATH_SIZE]; + struct stat statbuf; + int fd; + ssize_t size = -1; + + if (!dev || !attr_name || !value) + return 0; + + snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), + attr_name); + condlog(4, "open '%s'", devpath); + if (stat(devpath, &statbuf) != 0) { + condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); + return 0; + } + + /* skip directories */ + if (S_ISDIR(statbuf.st_mode)) { + condlog(4, "%s is a directory", devpath); + return 0; + } + + /* skip non-writeable files */ + if ((statbuf.st_mode & S_IRUSR) == 0) { + condlog(4, "%s is not readable", devpath); + return 0; + } + + /* read attribute value */ + fd = open(devpath, O_RDONLY); + if (fd < 0) { + condlog(4, "attribute '%s' can not be opened: %s", + devpath, strerror(errno)); + return 0; + } + size = read(fd, value, value_len); + if (size < 0) { + condlog(4, "read from %s failed: %s", devpath, strerror(errno)); + size = 0; + } else if (size == value_len) { + condlog(4, "overflow while reading from %s", devpath); + size = 0; + } + + close(fd); + return size; +} + ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, char * value, size_t value_len) { diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h index 13d7545..34f3e00 100644 --- a/libmultipath/sysfs.h +++ b/libmultipath/sysfs.h @@ -7,6 +7,8 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, char * value, size_t value_len); +ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + char * value, size_t value_len); int sysfs_get_size (struct path *pp, unsigned long long * size); int sysfs_check_holders(char * check_devt, char * new_devt); #endif