[PATCH 4/4] fsck: Add support for "completion" scripts.

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

 



Add support for scripts that are run when each individual fsck
completes.  This allows certain general or file- or device-specific
actions to be taken when each fsck finishes.

Signed-off-by: Frank Mayhar <fmayhar@xxxxxxxxxx>

 fsck/fsck.8 |   60
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fsck/fsck.c |   62
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fsck/fsck.h |    4 ++-
 3 files changed, 125 insertions(+), 1 deletions(-)

diff --git a/fsck/fsck.8 b/fsck/fsck.8
index d56b0d7..7e5b55b 100644
--- a/fsck/fsck.8
+++ b/fsck/fsck.8
@@ -413,6 +413,60 @@ and
 do not support the
 .B -y
 option as of this writing.
+.SH COMPLETION SCRIPTS
+.B fsck
+has a mechanism available by which to run a script when each check
completes.
+If when
+.B fsck
+starts the directory
+.IR /etc/fsck.d
+(or see FSCK_COMPLETION_PATH below) exists and is readable,
+.B fsck
+will use it to find such scripts.  Scripts there must be named one of
+.IR /etc/fsck.d/device/name ", " /etc/fsck.d/fstype/name ,
+or
+.IR /etc/fsck.d/completion ,
+where
+.I name
+is either the last component of the device path (e.g.
+.IR /etc/fsck.d/device/hda1 )
+or a file system type (e.g.
+.IR /etc/fsck.d/fstype/ext4 ).
+.PP
+When a file system check completes,
+.B fsck
+looks for a script that corresponds to the device that was checked; if
such
+a script is not found it looks for a script that corresponds to the
+type of that file system.  If neither of those is found it looks for a
+script named
+.IR /etc/fsck.d/completion .
+When
+.B fsck
+finds such a script and if the script is executable (and the
+.B \-N
+option was not specified), it runs the script via the
+.I system(3)
+function, passing the following set of parameters on the command line:
+.br
+\	device\	\-\ Device path of the device checked
+.br
+\	type\	\	\-\ File system type
+.br
+\	status\	\-\ Exit status
+.br
+\	elapsed\	\-\ Elapsed wall-clock time
+.br
+\	utime\	\-\ User CPU time
+.br
+\	stime\	\-\ System CPU time
+.br
+\	maxrss\	\-\ Maximum run-set-size
+.br
+\	logpath\	\-\ Path to logfile if the \-L option was specified
+.PP
+For example:
+.br
+  /etc/fsck.d/device/hdc1 /dev/hdc1 ext4 0 1.60470 0.41193 0.76588 9828
 .SH AUTHOR
 .UR tytso\@mit.edu
 Theodore Ts'o
@@ -429,6 +483,12 @@ The
 .B fsck
 program's behavior is affected by the following environment variables:
 .TP
+.B FSCK_COMPLETION_PATH
+If this environment variable is set,
+.B fsck
+will look for completion scripts in the indicated directory rather than
in
+.IR /etc/fsck.d .
+.TP
 .B FSCK_FORCE_ALL_PARALLEL
 If this environment variable is set,
 .B fsck
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 28b7016..58c7183 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -135,6 +135,8 @@ struct fsck_instance *instance_list;
 const char fsck_prefix_path[] = FS_SEARCH_PATH;
 char *fsck_path = 0;
 
+char *completion_path = COMPLETION_PATH;
+
 int force_timeout = 0;
 int timeout_secs = 0;
 int timeout_active = 0;
@@ -567,6 +569,59 @@ static int timeval_diff(struct timeval *result,
 		(x->tv_sec == y->tv_sec && x->tv_usec < y->tv_usec);
 }
 
+/*
+ * Choose and run a completion script for the completed fsck instance
+ * Prefer device match, then file system type, then generic script.
+ */
+static void run_completion(struct fsck_instance *inst)
+{
+	char *cmd, *cp, *devc;
+	struct timeval time_diff;
+
+	/*
+	 * If we're not actually doing fsck or we don't have a completion
+	 * path, don't run completions.
+	 */
+	if (noexecute || !completion_path)
+		return;
+	if ((devc = strrchr(inst->fs->device, '/')) == NULL)
+		devc = inst->fs->device;
+	else
+		devc++;
+	if ((cmd = malloc(1024)) == NULL)
+		return;
+	cp = cmd;
+	cp += sprintf(cmd, "%s/device/%s", completion_path, devc);
+	if (access(cmd, R_OK|X_OK) < 0) {
+		cp = cmd;
+		cp += sprintf(cmd, "%s/fstype/%s", completion_path, inst->fs->type);
+		if (access(cmd, R_OK|X_OK) < 0) {
+			cp = cmd;
+			cp += sprintf(cmd, "%s/completion", completion_path);
+			if (access(cmd, R_OK|X_OK) < 0) {
+				free(cmd);
+				return;
+			}
+		}
+	}
+	cp += sprintf(cp, " %s", inst->fs->device);
+	cp += sprintf(cp, " %s", inst->fs->type);
+	cp += sprintf(cp, " %d", inst->exit_status);
+	timeval_diff(&time_diff, &inst->end_time, &inst->start_time);
+	cp += sprintf(cp, " %d.%06d", (int)time_diff.tv_sec,
+			(int)time_diff.tv_usec);
+	cp += sprintf(cp, " %d.%06d", (int)inst->rusage.ru_utime.tv_sec,
+			(int)inst->rusage.ru_utime.tv_usec);
+	cp += sprintf(cp, " %d.%06d", (int)inst->rusage.ru_stime.tv_sec,
+			(int)inst->rusage.ru_stime.tv_usec);
+	cp += sprintf(cp, " %ld", inst->rusage.ru_maxrss);
+	if (log_output)
+		cp += sprintf(cp, " %s", inst->log_file);
+	if (system(cmd) < 0)
+		perror(cmd);
+	free(cmd);
+}
+
 /* Forward reference. */
 static void restart_earliest_timeout(NOARGS);
 
@@ -962,6 +1017,7 @@ ret_inst:
 		prev->next = inst->next;
 	else
 		instance_list = inst->next;
+	run_completion(inst);
 	report_fsck_stats(inst);
 	if (inst->log_fd)
 		close(inst->log_fd);
@@ -1694,6 +1750,12 @@ int main(int argc, char *argv[])
 		fstab = _PATH_MNTTAB;
 	load_fs_info(fstab);
 
+	completion_path = getenv("FSCK_COMPLETION_PATH");
+	if (!completion_path)
+		completion_path = COMPLETION_PATH;
+	if (access(completion_path, R_OK|X_OK) < 0)
+		completion_path = NULL;
+
 	/* Update our search path to include uncommon directories. */
 	if (oldpath) {
 		fsck_path = xmalloc (strlen (fsck_prefix_path) + 1 +
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 6e41f40..93356bc 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -33,8 +33,10 @@
 #define EXIT_TIMEOUT     64
 #define EXIT_LIBRARY     128
 
+#define COMPLETION_PATH	"/etc/fsck.d/"
+
 /*
- * Internal structure for mount tabel entries.
+ * Internal structure for mount table entries.
  */
 
 struct fs_info {

-- 
Frank Mayhar
fmayhar@xxxxxxxxxx

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


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux