Blame SOURCES/mdmon-get-safe-mode-delay-file.patch

2c1b57
commit c76242c56efb4d799bb15af1035a5f503cb4b8f3
2c1b57
Author: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
2c1b57
Date:   Wed Oct 4 10:18:21 2017 +0200
2c1b57
2c1b57
    mdmon: get safe mode delay file descriptor early
2c1b57
    
2c1b57
    After switch root new mdmon is started. It sends initrd mdmon a signal
2c1b57
    to terminate. initrd mdmon receives it and switches the safe mode delay
2c1b57
    to 1 ms in order to get array to clean state and flush last version of
2c1b57
    metadata. The problem is sysfs filesystem is not available to initrd mdmon
2c1b57
    after switch root so the original safe mode delay is unchanged. The delay
2c1b57
    is set to few seconds - if there is a lot of traffic on the filesystem,
2c1b57
    initrd mdmon doesn't terminate for a long time (no clean state). There
2c1b57
    are 2 instances of mdmon. initrd mdmon flushes metadata when array goes
2c1b57
    to clean state but this metadata might be already outdated.
2c1b57
    
2c1b57
    Use file descriptor obtained on mdmon start to change safe mode delay.
2c1b57
    
2c1b57
    Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
2c1b57
    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
2c1b57
2c1b57
diff --git a/managemon.c b/managemon.c
2c1b57
index cc3c6f1..4e85398 100644
2c1b57
--- a/managemon.c
2c1b57
+++ b/managemon.c
2c1b57
@@ -129,6 +129,8 @@ static void close_aa(struct active_array *aa)
2c1b57
 		close(aa->metadata_fd);
2c1b57
 	if (aa->sync_completed_fd >= 0)
2c1b57
 		close(aa->sync_completed_fd);
2c1b57
+	if (aa->safe_mode_delay_fd >= 0)
2c1b57
+		close(aa->safe_mode_delay_fd);
2c1b57
 }
2c1b57
 
2c1b57
 static void free_aa(struct active_array *aa)
2c1b57
@@ -532,9 +534,15 @@ static void manage_member(struct mdstat_ent *mdstat,
2c1b57
 	if (a->container == NULL)
2c1b57
 		return;
2c1b57
 
2c1b57
-	if (sigterm && a->info.safe_mode_delay != 1) {
2c1b57
-		sysfs_set_safemode(&a->info, 1);
2c1b57
-		a->info.safe_mode_delay = 1;
2c1b57
+	if (sigterm && a->info.safe_mode_delay != 1 &&
2c1b57
+	    a->safe_mode_delay_fd >= 0) {
2c1b57
+		long int new_delay = 1;
2c1b57
+		char delay[10];
2c1b57
+		ssize_t len;
2c1b57
+
2c1b57
+		len = snprintf(delay, sizeof(delay), "0.%03ld\n", new_delay);
2c1b57
+		if (write(a->safe_mode_delay_fd, delay, len) == len)
2c1b57
+			a->info.safe_mode_delay = new_delay;
2c1b57
 	}
2c1b57
 
2c1b57
 	/* We don't check the array while any update is pending, as it
2c1b57
@@ -734,6 +742,8 @@ static void manage_new(struct mdstat_ent *mdstat,
2c1b57
 	new->resync_start_fd = sysfs_open2(new->info.sys_name, NULL, "resync_start");
2c1b57
 	new->metadata_fd = sysfs_open2(new->info.sys_name, NULL, "metadata_version");
2c1b57
 	new->sync_completed_fd = sysfs_open2(new->info.sys_name, NULL, "sync_completed");
2c1b57
+	new->safe_mode_delay_fd = sysfs_open2(new->info.sys_name, NULL,
2c1b57
+					      "safe_mode_delay");
2c1b57
 
2c1b57
 	dprintf("inst: %s action: %d state: %d\n", inst,
2c1b57
 		new->action_fd, new->info.state_fd);
2c1b57
diff --git a/mdmon.h b/mdmon.h
2c1b57
index 0b08c3d..818367c 100644
2c1b57
--- a/mdmon.h
2c1b57
+++ b/mdmon.h
2c1b57
@@ -35,6 +35,7 @@ struct active_array {
2c1b57
 	int resync_start_fd;
2c1b57
 	int metadata_fd; /* for monitoring rw/ro status */
2c1b57
 	int sync_completed_fd; /* for checkpoint notification events */
2c1b57
+	int safe_mode_delay_fd;
2c1b57
 	unsigned long long last_checkpoint; /* sync_completed fires for many
2c1b57
 					     * reasons this field makes sure the
2c1b57
 					     * kernel has made progress before