Blame SOURCES/0064-RHBZ-1010040-fix-ID_FS-attrs.patch

4728c8
---
4728c8
 libmultipath/defaults.h       |    3 -
4728c8
 libmultipath/file.c           |   89 +++++++++++++++++++++++++++++++++++++++++-
4728c8
 libmultipath/file.h           |    3 +
4728c8
 libmultipath/wwids.c          |    7 ++-
4728c8
 multipath/main.c              |   36 +++++++++++++++-
4728c8
 multipath/multipath.rules     |   26 +++++++++---
4728c8
 multipathd/main.c             |    4 +
4728c8
 multipathd/multipathd.service |    2 
4728c8
 multipathd/pidfile.c          |    3 +
4728c8
 9 files changed, 160 insertions(+), 13 deletions(-)
4728c8
4728c8
Index: multipath-tools-130222/libmultipath/defaults.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/defaults.h
4728c8
+++ multipath-tools-130222/libmultipath/defaults.h
4728c8
@@ -24,7 +24,8 @@
4728c8
 #define MAX_CHECKINT(a)		(a << 2)
4728c8
 
4728c8
 #define MAX_DEV_LOSS_TMO	0x7FFFFFFF
4728c8
-#define DEFAULT_PIDFILE		"/var/run/multipathd.pid"
4728c8
+#define DEFAULT_PIDFILE		"/var/run/multipathd/multipathd.pid"
4728c8
+#define DEFAULT_TIMESTAMP_FILE	"/var/run/multipathd/timestamp"
4728c8
 #define DEFAULT_SOCKET		"/org/kernel/linux/storage/multipathd"
4728c8
 #define DEFAULT_CONFIGFILE	"/etc/multipath.conf"
4728c8
 #define DEFAULT_BINDINGS_FILE	"/etc/multipath/bindings"
4728c8
Index: multipath-tools-130222/libmultipath/file.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/file.c
4728c8
+++ multipath-tools-130222/libmultipath/file.c
4728c8
@@ -12,10 +12,12 @@
4728c8
 #include <limits.h>
4728c8
 #include <stdio.h>
4728c8
 #include <signal.h>
4728c8
+#include <time.h>
4728c8
 
4728c8
 #include "file.h"
4728c8
 #include "debug.h"
4728c8
 #include "uxsock.h"
4728c8
+#include "defaults.h"
4728c8
 
4728c8
 
4728c8
 /*
4728c8
@@ -36,8 +38,8 @@
4728c8
  * See the file COPYING included with this distribution for more details.
4728c8
  */
4728c8
 
4728c8
-static int
4728c8
-ensure_directories_exist(char *str, mode_t dir_mode)
4728c8
+int
4728c8
+ensure_directories_exist(const char *str, mode_t dir_mode)
4728c8
 {
4728c8
 	char *pathname;
4728c8
 	char *end;
4728c8
@@ -178,3 +180,86 @@ fail:
4728c8
 	close(fd);
4728c8
 	return -1;
4728c8
 }
4728c8
+
4728c8
+/* If you can't get the timestamp, return equal to just keep using the
4728c8
+ * existing value.
4728c8
+ */
4728c8
+int timestamp_equal(long int chk_timestamp)
4728c8
+{
4728c8
+	char buf[4096];
4728c8
+	FILE *file;
4728c8
+	long int file_timestamp;
4728c8
+	int ret = 1;
4728c8
+
4728c8
+	if ((file = fopen(DEFAULT_TIMESTAMP_FILE, "r")) == NULL) {
4728c8
+		if (errno != ENOENT)
4728c8
+			condlog(2, "Cannot open timestamp file [%s]: %s",
4728c8
+				DEFAULT_TIMESTAMP_FILE, strerror(errno));
4728c8
+		goto out;
4728c8
+	}
4728c8
+	errno = 0;
4728c8
+	if (fgets(buf, sizeof(buf), file) == NULL) {
4728c8
+		if (errno)
4728c8
+			condlog(2, "Cannot read from timestamp file: %s",
4728c8
+				strerror(errno));
4728c8
+		goto out;
4728c8
+	}
4728c8
+	if (sscanf(buf, "DM_MULTIPATH_TIMESTAMP=%ld", &file_timestamp) != 1) {
4728c8
+		if (errno)
4728c8
+			condlog(0, "Cannot get timestamp: %s", strerror(errno));
4728c8
+		else
4728c8
+			condlog(0, "invalid timestamp file [%s]: %s",
4728c8
+				DEFAULT_TIMESTAMP_FILE, strerror(errno));
4728c8
+		goto out;
4728c8
+	}
4728c8
+	if (file_timestamp != chk_timestamp) {
4728c8
+		condlog(3, "timestamp has changed");
4728c8
+		ret = 0;
4728c8
+	}
4728c8
+	else
4728c8
+		condlog(3, "timestamp has not changed");
4728c8
+out:
4728c8
+	if (file)
4728c8
+		fclose(file);
4728c8
+	return ret;
4728c8
+}
4728c8
+
4728c8
+int update_timestamp(int create)
4728c8
+{
4728c8
+	char buf[44];
4728c8
+	time_t timestamp;
4728c8
+	int fd;
4728c8
+	int flags = O_WRONLY;
4728c8
+	if (create)
4728c8
+		flags |= O_CREAT;
4728c8
+	if((fd = open(DEFAULT_TIMESTAMP_FILE, flags,
4728c8
+		      (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
4728c8
+		if (errno == ENOENT)
4728c8
+			return 0;
4728c8
+		condlog(0, "Cannot open timestamp file [%s]: %s",
4728c8
+			DEFAULT_TIMESTAMP_FILE, strerror(errno));
4728c8
+		return 1;
4728c8
+	}
4728c8
+	if (ftruncate(fd, 0) < 0) {
4728c8
+		condlog(0, "Cannot truncate timestamp file [%s]: %s",
4728c8
+			DEFAULT_TIMESTAMP_FILE, strerror(errno));
4728c8
+		goto fail;
4728c8
+	}
4728c8
+	if (time(&timestamp) == -1) {
4728c8
+		condlog(0, "Cannot get current time: %s", strerror(errno));
4728c8
+		goto fail;
4728c8
+	}
4728c8
+	memset(buf, 0, sizeof(buf));
4728c8
+	snprintf(buf, sizeof(buf)-1, "DM_MULTIPATH_TIMESTAMP=%ld\n",
4728c8
+		 timestamp);
4728c8
+	if (write(fd, buf, strlen(buf)) != strlen(buf)) {
4728c8
+		condlog(0, "Cannot write out timestamp to %s: %s",
4728c8
+			DEFAULT_TIMESTAMP_FILE, strerror(errno));
4728c8
+		goto fail;
4728c8
+	}
4728c8
+	close(fd);
4728c8
+	return 0;
4728c8
+fail:
4728c8
+	close(fd);
4728c8
+	return 1;
4728c8
+}
4728c8
Index: multipath-tools-130222/libmultipath/file.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/file.h
4728c8
+++ multipath-tools-130222/libmultipath/file.h
4728c8
@@ -7,5 +7,8 @@
4728c8
 
4728c8
 #define FILE_TIMEOUT 30
4728c8
 int open_file(char *file, int *can_write, char *header);
4728c8
+int ensure_directories_exist(const char *str, mode_t dir_mode);
4728c8
+int update_timestamp(int create);
4728c8
+int timestamp_equal(long int chk_timestamp);
4728c8
 
4728c8
 #endif /* _FILE_H */
4728c8
Index: multipath-tools-130222/multipathd/pidfile.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipathd/pidfile.c
4728c8
+++ multipath-tools-130222/multipathd/pidfile.c
4728c8
@@ -9,6 +9,7 @@
4728c8
 #include <fcntl.h>     /* for fcntl() */
4728c8
 
4728c8
 #include <debug.h>
4728c8
+#include <file.h>
4728c8
 
4728c8
 #include "pidfile.h"
4728c8
 
4728c8
@@ -18,6 +19,8 @@ int pidfile_create(const char *pidFile,
4728c8
 	struct flock lock;
4728c8
 	int fd, value;
4728c8
 
4728c8
+	if (ensure_directories_exist(pidFile, 0700))
4728c8
+		return 1;
4728c8
 	if((fd = open(pidFile, O_WRONLY | O_CREAT,
4728c8
 		       (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
4728c8
 		condlog(0, "Cannot open pidfile [%s], error was [%s]",
4728c8
Index: multipath-tools-130222/libmultipath/wwids.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/wwids.c
4728c8
+++ multipath-tools-130222/libmultipath/wwids.c
4728c8
@@ -125,6 +125,7 @@ replace_wwids(vector mp)
4728c8
 			goto out_file;
4728c8
 	}
4728c8
 	ret = 0;
4728c8
+	update_timestamp(0);
4728c8
 out_file:
4728c8
 	close(fd);
4728c8
 out:
4728c8
@@ -209,6 +210,8 @@ remove_wwid(char *wwid) {
4728c8
 		goto out_file;
4728c8
 	}
4728c8
 	ret = do_remove_wwid(fd, str);
4728c8
+	if (!ret)
4728c8
+		update_timestamp(0);
4728c8
 
4728c8
 out_file:
4728c8
 	close(fd);
4728c8
@@ -294,8 +297,10 @@ remember_wwid(char *wwid)
4728c8
 		condlog(3, "failed writing wwid %s to wwids file", wwid);
4728c8
 		return -1;
4728c8
 	}
4728c8
-	if (ret == 1)
4728c8
+	if (ret == 1) {
4728c8
 		condlog(3, "wrote wwid %s to wwids file", wwid);
4728c8
+		update_timestamp(0);
4728c8
+	}
4728c8
 	else
4728c8
 		condlog(4, "wwid %s already in wwids file", wwid);
4728c8
 	return 0;
4728c8
Index: multipath-tools-130222/multipath/multipath.rules
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipath/multipath.rules
4728c8
+++ multipath-tools-130222/multipath/multipath.rules
4728c8
@@ -4,18 +4,34 @@ SUBSYSTEM!="block", GOTO="end_mpath"
4728c8
 
4728c8
 IMPORT{cmdline}="nompath"
4728c8
 ENV{nompath}=="?*", GOTO="end_mpath"
4728c8
+ENV{DEVTYPE}=="partition", GOTO="end_mpath"
4728c8
 ENV{MPATH_SBIN_PATH}="/sbin"
4728c8
 TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
4728c8
+TEST!="/etc/multipath.conf", GOTO="check_kpartx"
4728c8
 
4728c8
-ACTION=="add", ENV{DEVTYPE}!="partition", \
4728c8
-	ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
4728c8
-	TEST=="/etc/multipath.conf", \
4728c8
+ACTION=="add", ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
4728c8
 	PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -c $tempnode", \
4728c8
-	ENV{DM_MULTIPATH_DEVICE_PATH}="1" ENV{ID_FS_TYPE}="mpath_member"
4728c8
+	ENV{DM_MULTIPATH_DEVICE_PATH}="1", ENV{ID_FS_TYPE}="mpath_member"
4728c8
 
4728c8
-ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DEVTYPE}!="partition", \
4728c8
+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", \
4728c8
 	RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
4728c8
 
4728c8
+ACTION!="change", GOTO="update_timestamp"
4728c8
+IMPORT{db}="DM_MULTIPATH_TIMESTAMP"
4728c8
+IMPORT{db}="DM_MULTIPATH_DEVICE_PATH"
4728c8
+# Check if the device is part of a multipath device. the -T option just keeps
4728c8
+# the old result if the timestamp hasn't changed.
4728c8
+PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -T $env{DM_MULTIPATH_TIMESTAMP}:$env{DM_MULTIPATH_DEVICE_PATH} -c $env{DEVNAME}", \
4728c8
+	ENV{DM_MULTIPATH_DEVICE_PATH}="1", ENV{ID_FS_TYPE}="mpath_member", \
4728c8
+	GOTO="update_timestamp"
4728c8
+
4728c8
+# If the device isn't part of a multipath device, clear this
4728c8
+ENV{DM_MULTIPATH_DEVICE_PATH}=""
4728c8
+
4728c8
+LABEL="update_timestamp"
4728c8
+IMPORT{file}="/run/multipathd/timestamp"
4728c8
+
4728c8
+LABEL="check_kpartx"
4728c8
 KERNEL!="dm-*", GOTO="end_mpath"
4728c8
 ENV{DM_UUID}=="mpath-?*|part[0-9]*-mpath-?*", OPTIONS+="link_priority=10"
4728c8
 ACTION!="change", GOTO="end_mpath"
4728c8
Index: multipath-tools-130222/multipathd/main.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipathd/main.c
4728c8
+++ multipath-tools-130222/multipathd/main.c
4728c8
@@ -54,6 +54,7 @@
4728c8
 #include <pgpolicies.h>
4728c8
 #include <uevent.h>
4728c8
 #include <log.h>
4728c8
+#include <file.h>
4728c8
 
4728c8
 #include "main.h"
4728c8
 #include "pidfile.h"
4728c8
@@ -1417,6 +1418,7 @@ reconfigure (struct vectors * vecs)
4728c8
 		free_config(old);
4728c8
 		retval = 0;
4728c8
 	}
4728c8
+	update_timestamp(0);
4728c8
 
4728c8
 	return retval;
4728c8
 }
4728c8
@@ -1709,6 +1711,7 @@ child (void * param)
4728c8
 
4728c8
 	/* Startup complete, create logfile */
4728c8
 	pid_rc = pidfile_create(DEFAULT_PIDFILE, daemon_pid);
4728c8
+	update_timestamp(1);
4728c8
 	/* Ignore errors, we can live without */
4728c8
 
4728c8
 	running_state = DAEMON_RUNNING;
4728c8
@@ -1758,6 +1761,7 @@ child (void * param)
4728c8
 	if (!pid_rc) {
4728c8
 		condlog(3, "unlink pidfile");
4728c8
 		unlink(DEFAULT_PIDFILE);
4728c8
+		unlink(DEFAULT_TIMESTAMP_FILE);
4728c8
 	}
4728c8
 
4728c8
 	condlog(2, "--------shut down-------");
4728c8
Index: multipath-tools-130222/multipathd/multipathd.service
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipathd/multipathd.service
4728c8
+++ multipath-tools-130222/multipathd/multipathd.service
4728c8
@@ -9,7 +9,7 @@ Conflicts=shutdown.target
4728c8
 
4728c8
 [Service]
4728c8
 Type=forking
4728c8
-PIDFile=/var/run/multipathd.pid
4728c8
+PIDFile=/var/run/multipathd/multipathd.pid
4728c8
 ExecStartPre=/sbin/modprobe dm-multipath
4728c8
 ExecStart=/sbin/multipathd
4728c8
 ExecReload=/sbin/multipathd reconfigure
4728c8
Index: multipath-tools-130222/multipath/main.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipath/main.c
4728c8
+++ multipath-tools-130222/multipath/main.c
4728c8
@@ -55,6 +55,7 @@
4728c8
 #include <sys/time.h>
4728c8
 #include <sys/resource.h>
4728c8
 #include <wwids.h>
4728c8
+#include <file.h>
4728c8
 #include "dev_t.h"
4728c8
 
4728c8
 int logsink;
4728c8
@@ -84,7 +85,7 @@ usage (char * progname)
4728c8
 {
4728c8
 	fprintf (stderr, VERSION_STRING);
4728c8
 	fprintf (stderr, "Usage:\n");
4728c8
-	fprintf (stderr, "  %s [-c|-w|-W] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
4728c8
+	fprintf (stderr, "  %s [-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
4728c8
 	fprintf (stderr, "  %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
4728c8
 	fprintf (stderr, "  %s -F [-v lvl]\n", progname);
4728c8
 	fprintf (stderr, "  %s -t\n", progname);
4728c8
@@ -98,6 +99,9 @@ usage (char * progname)
4728c8
 		"  -f      flush a multipath device map\n" \
4728c8
 		"  -F      flush all multipath device maps\n" \
4728c8
 		"  -c      check if a device should be a path in a multipath device\n" \
4728c8
+		"  -T tm:val\n" \
4728c8
+		"          check if tm matches the multipathd timestamp. If so val is\n" \
4728c8
+		"          whether or not the device is a path in a multipath device\n" \
4728c8
 		"  -q      allow queue_if_no_path when multipathd is not running\n"\
4728c8
 		"  -d      dry run, do not create or update devmaps\n" \
4728c8
 		"  -t      dump internal hardware table\n" \
4728c8
@@ -441,7 +445,31 @@ main (int argc, char *argv[])
4728c8
 	extern char *optarg;
4728c8
 	extern int optind;
4728c8
 	int r = 1;
4728c8
-
4728c8
+	long int timestamp = -1;
4728c8
+	int valid = -1;
4728c8
+	while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
4728c8
+		switch(arg) {
4728c8
+		case 'T':
4728c8
+			if (optarg[0] == ':')
4728c8
+				sscanf(optarg, ":%d", &valid);
4728c8
+			else
4728c8
+				sscanf(optarg, "%ld:%d", &timestamp, &valid);
4728c8
+			if (timestamp_equal(timestamp))
4728c8
+				return (valid != 1);
4728c8
+			break;
4728c8
+		case ':':
4728c8
+			fprintf(stderr, "Missing option argument\n");
4728c8
+			usage(argv[0]);
4728c8
+			exit(1);
4728c8
+		case '?':
4728c8
+			fprintf(stderr, "Unknown switch: %s\n", optarg);
4728c8
+			usage(argv[0]);
4728c8
+			exit(1);
4728c8
+		default:
4728c8
+			break;
4728c8
+		}
4728c8
+	}
4728c8
+	optind = 1;
4728c8
 	if (getuid() != 0) {
4728c8
 		fprintf(stderr, "need to be root\n");
4728c8
 		exit(1);
4728c8
@@ -455,7 +483,7 @@ main (int argc, char *argv[])
4728c8
 	if (dm_prereq())
4728c8
 		exit(1);
4728c8
 
4728c8
-	while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtqwW")) != EOF ) {
4728c8
+	while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
4728c8
 		switch(arg) {
4728c8
 		case 1: printf("optarg : %s\n",optarg);
4728c8
 			break;
4728c8
@@ -517,6 +545,8 @@ main (int argc, char *argv[])
4728c8
 		case 't':
4728c8
 			r = dump_config();
4728c8
 			goto out;
4728c8
+		case 'T':
4728c8
+			break;
4728c8
 		case 'h':
4728c8
 			usage(argv[0]);
4728c8
 			exit(0);