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

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