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

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