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

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