[PATCH] syncing disk in a subprocess with a 60 seconds timeout.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



sync() can take excessive long time, up to hours in some circumstances.
(eg. running badblocks on slow disk, dd'ing disk images, packet-writing on optical media)
Running a prune is usually expected to start (and complete) soon, especially
if it is initiated from a cron-script.

This patch forks the sync() in a background process and waits at most 60 seconds for
it's completion. If the sync doesnt complete in time or any other error occurs, prunning
is aborted and can be tried again a later time. Note that the sync() process will get
orphaned and sit around until syncing eventually completes.
---
 builtin-prune-packed.c |   35 +++++++++++++++++++++++++++++++++--
 1 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/builtin-prune-packed.c b/builtin-prune-packed.c
index 24e3b0a..05ac696 100644
--- a/builtin-prune-packed.c
+++ b/builtin-prune-packed.c
@@ -1,5 +1,7 @@
 #include "builtin.h"
 #include "cache.h"
+#include <time.h>
+#include <sys/wait.h>
 
 static const char prune_packed_usage[] =
 "git-prune-packed [-n]";
@@ -53,11 +55,16 @@ void prune_packed_objects(int dryrun)
 	}
 }
 
+void sig_nop(int unused){(void)unused;};
+
 int cmd_prune_packed(int argc, const char **argv, const char *prefix)
 {
 	int i;
 	int dryrun = 0;
-
+	pid_t syncpid;
+	struct timespec synctimeout;
+	int sleeping;
+		
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 
@@ -71,7 +78,31 @@ int cmd_prune_packed(int argc, const cha
 		/* Handle arguments here .. */
 		usage(prune_packed_usage);
 	}
-	sync();
+	
+	synctimeout.tv_sec = 60;
+	synctimeout.tv_nsec = 0;
+		
+	signal(SIGCLD, sig_nop);
+	syncpid = fork();
+	if (syncpid == 0) {
+		sync();
+		return 0;
+	}
+	else if (syncpid > 0) {
+		do {
+			if (waitpid(syncpid, NULL, WNOHANG) > 0)
+				break;
+			sleeping = nanosleep(&synctimeout, &synctimeout);
+			if (sleeping == -1) {
+				if (errno != EINTR)
+					die ("nanosleep error");
+			}
+			else
+				die ("coudn't sync within 60 seconds, nothing pruned");
+		} while (1);
+	}
+	else die("failed to fork sync process");
+	signal(SIGCLD, SIG_DFL);
 	prune_packed_objects(dryrun);
 	return 0;
 }
-- 
1.4.3.2

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]