git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] syncing disk in a subprocess with a 60 seconds timeout.
@ 2006-11-07  9:07 Christian Thaeter
  0 siblings, 0 replies; only message in thread
From: Christian Thaeter @ 2006-11-07  9:07 UTC (permalink / raw)


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

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2006-11-07  9:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-07  9:07 [PATCH] syncing disk in a subprocess with a 60 seconds timeout Christian Thaeter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).