Subject: savecore -n option
To: None <tech-userlevel@netbsd.org>
From: Dave Sainty <dave@dtsp.co.nz>
List: tech-userlevel
Date: 10/09/2004 19:35:10
I propose to add a -n option to savecore(8), which would change the
behaviour of savecore(8) to do nothing, but exit(0) if a dump is
present, and exit(1) if it isn't.

I've used this feature locally for many months on a couple of machines
that usually boot with read-only disks (rc.d script and savecore
changes below), but are sometimes used for kernel debugging.

I'm _not_ (currently) suggesting replacing the standard rc.d/savecore
script with the below, but the "-n" extension to savecore(8) seems
harmless and may have other uses.

I'm not aware of prior art elsewhere for the naming of the option, so
I chose "-n" - the universally accepted option for "say what I'm going
to do, but don't do it" (like make, sh, and I'm pretty sure a million
other commands, but I'm having trouble thinking of them :)

Does anyone disagree (with the proposed change, or the implementation)?

Cheers,

Dave

--------------------- Replacement savecore rc.d script ---------------------

#!/bin/sh
#
# $NetBSD$
#

# PROVIDE: netclient_savecore
# REQUIRE: syslogd
# BEFORE:  SERVERS

$_rc_subr_loaded . /etc/rc.subr

name="netclient_savecore"
rcvar=$name
start_cmd="netclient_savecore_start"
stop_cmd=":"

getmountflags()
{
	findmnt=$1
	mount | while read dev on mnt type fstype flags; do
		case "$mnt" in "$findmnt") echo "$flags"; findmnt=.;; esac
	done
}

dosavecore()
{
	set -- x `df -P "${savecore_dir}/." | (read title && read dev blk used avail cap mnt && echo "$mnt")`
	mnt=$2

	flags=`getmountflags "$mnt"`

	readonly=false
	case "$flags" in *read-only*) readonly=true;; esac

	if $readonly; then
		echo "savecore: re-mounting $mnt writable"
		mount -uw "$mnt" || return 1
	fi

	savecore $rc_flags "${savecore_dir}"

	if $readonly; then
		echo "savecore: re-mounting $mnt read-only"
		mount -ur "$mnt" || return 1
	fi

	return 0
}

netclient_savecore_start()
{
	#	/var/crash should be a directory or a symbolic link
	#	to the crash directory if core dumps are to be saved.
	#
	if [ -d "${savecore_dir}/." ]; then
		if savecore -n; then
			# exit level 0 indicates a dump is present
			dosavecore
		fi
	else
		warn "No crash dump directory; savecore not run."
	fi
}

load_rc_config $name
run_rc_command "$1"

--------------------- savecore patch ---------------------

Add feature to savecore to test for a dump, but nothing else...

--- src/sbin/savecore/savecore.c.orig	Tue Sep  9 23:33:33 2003
+++ src/sbin/savecore/savecore.c	Thu Jan  1 18:51:42 2004
@@ -148,17 +148,18 @@
 int
 main(int argc, char *argv[])
 {
-	int ch, level;
+	int ch, level, testonly;
 	char *ep;
 
 	dirname = NULL;
 	kernel = NULL;
 	level = 1;		/* default to fastest gzip compression */
+	testonly = 0;
 	gzmode[0] = 'w';
 
 	openlog("savecore", LOG_PERROR, LOG_DAEMON);
 
-	while ((ch = getopt(argc, argv, "cdfN:vzZ:")) != -1)
+	while ((ch = getopt(argc, argv, "cdfnN:vzZ:")) != -1)
 		switch(ch) {
 		case 'c':
 			clear = 1;
@@ -170,6 +171,9 @@
 		case 'f':
 			force = 1;
 			break;
+		case 'n':
+			testonly = 1;
+			break;
 		case 'N':
 			kernel = optarg;
 			break;
@@ -191,7 +195,7 @@
 	argc -= optind;
 	argv += optind;
 
-	if (argc != (clear ? 0 : 1))
+	if (argc != ((clear || testonly) ? 0 : 1))
 		usage();
 
 	gzmode[1] = level + '0';
@@ -205,7 +209,7 @@
 	(void)time(&now);
 	kmem_setup();
 
-	if (clear) {
+	if (clear && !testonly) {
 		clear_dump();
 		exit(0);
 	}
@@ -213,6 +217,10 @@
 	if (!dump_exists() && !force)
 		exit(1);
 
+	if (testonly)
+		/* If -n was passed and there was a dump, exit at level 0 */
+		exit(0);
+
 	check_kmem();
 
 	if (panicstr)
@@ -793,6 +801,6 @@
 usage(void)
 {
 	(void)syslog(LOG_ERR,
-	    "usage: savecore [-cfvz] [-N system] [-Z level] directory");
+	    "usage: savecore [-cfnvz] [-N system] [-Z level] directory");
 	exit(1);
 }