Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 7 Jul 1998 16:59:09 -0700 (PDT)
From:      Sean Eric Fagan <sef@kithrup.com>
To:        cvs-all@FreeBSD.ORG
Cc:        dg@FreeBSD.ORG, cvs-committers@FreeBSD.ORG, cvs-sys@FreeBSD.ORG
Subject:   Re: cvs commit: src/sys/kern kern_sig.c 
Message-ID:  <199807072359.QAA25406@kithrup.com>
In-Reply-To: <199807072341.QAA02595.kithrup.freebsd.cvs-all@dingo.cdrom.com>
References:  Your message of "Wed, 08 Jul 1998 00:39:33 %2B0200." <19980708003933.31278@panke.de> 

next in thread | previous in thread | raw e-mail | index | archive | help
In article <199807072341.QAA02595.kithrup.freebsd.cvs-all@dingo.cdrom.com> you write:
>> I wish we had a sysctl variable for the coredump name. Eg.
>> 
>> kern.coredump.name =
>> 
>> 0 -> disable core dumps
>> 1 -> core dump filename 'core'
>> 2 -> core dump filename 'program.core'
>> 3 -> core dump filename 'core.program'
>
>I think you should buy Sean a beer.

Indeed.  I'd just sent Mike some diffs (Jordan's seen 'em too) to do this:

He suggested changes, not all of which I've done yet.  But this gives you teh
basic idea.  Note that it allows three format specifiers:  %N == process name,
%P == process ID, %U == user ID.

Examples of ones I've tested:

	sysctl -w kern.corefilename="core"
	sysctl -w kern.corefilename="%N.core"
	sysctl -w kern.corefilename="core.%N"
	sysctl -w kern.corefilename="/tmp/%N-%P.core"
	sysctl -w kern.corefilename="/dev/null"

Index: kern/kern_sig.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.26.2.1
diff -u -r1.26.2.1 kern_sig.c
--- kern_sig.c	1996/12/21 18:57:24	1.26.2.1
+++ kern_sig.c	1998/07/04 18:25:22
@@ -61,6 +61,8 @@
 #include <sys/syslog.h>
 #include <sys/stat.h>
 #include <sys/sysent.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
 
 #include <machine/cpu.h>
 
@@ -75,6 +77,7 @@
 static int coredump     __P((struct proc *p));
 static int killpg1	__P((struct proc *cp, int signum, int pgid, int all));
 static void stop	__P((struct proc *));
+static char *expand_name	__P((const char*, int, int));
 
 /*
  * Can process p, with pcred pc, send the signal signum to process q?
@@ -1219,6 +1222,75 @@
 	/* NOTREACHED */
 }
 
+static char corefilename[MAXPATHLEN+1] = {"%N.core"};
+SYSCTL_STRING(_kern, KERN_COREFILENAME, corefilename, CTLFLAG_RW,
+	      corefilename, sizeof(corefilename), "");
+
+static char *
+expand_name(name, uid, pid)
+const char *name; int uid; int pid; {
+	char *temp;
+	char buf[11];		/* Buffer for pid/uid -- max 4B */
+	int i, n;
+	char *format = corefilename;
+
+	temp = malloc(MAXPATHLEN + 3, M_TEMP, M_NOWAIT);
+	bzero(temp, MAXPATHLEN+3);
+	for (i = 0, n = 0; i < MAXPATHLEN && format[i]; i++) {
+		int l;
+		switch (format[i]) {
+		case '%':	/* Format character */
+			i++;
+			switch (format[i]) {
+			case '%':
+				temp[n++] = '%';
+				break;
+			case 'N':	/* process name */
+				l = strlen(name);
+				if ((n + l) > MAXPATHLEN) {
+					log(LOG_ERR, "pid %d (%s), uid (%d):  Path `%s%s' is too long\n",
+					    pid, name, uid, temp, name);
+					free(temp, M_TEMP);
+					return NULL;
+				}
+				memcpy(temp+n, name, l);
+				n += l;
+				break;
+			case 'P':	/* process id */
+				sprintf(buf, "%u", pid);
+				l = strlen(buf);
+				if ((n + l) > MAXPATHLEN) {
+					log(LOG_ERR, "pid %d (%s), uid (%d):  Path `%s%s' is too long\n",
+					    pid, name, uid, temp, name);
+					free(temp, M_TEMP);
+					return NULL;
+				}
+				memcpy(temp+n, buf, l);
+				n += l;
+				break;
+			case 'U':	/* user id */
+				sprintf(buf, "%u", uid);
+				l = strlen(buf);
+				if ((n + l) > MAXPATHLEN) {
+					log(LOG_ERR, "pid %d (%s), uid (%d):  Path `%s%s' is too long\n",
+					    pid, name, uid, temp, name);
+					free(temp, M_TEMP);
+					return NULL;
+				}
+				memcpy(temp+n, buf, l);
+				n += l;
+				break;
+			default:
+			  	log(LOG_ERR, "Unknown format character %c in `%s'\n", format[i], format);
+			}
+			break;
+		default:
+			temp[n++] = format[i];
+		}
+	}
+	return temp;
+}
+
 /*
  * Dump core, into a file named "progname.core", unless the process was
  * setuid/setgid.
@@ -1233,17 +1305,21 @@
 	struct nameidata nd;
 	struct vattr vattr;
 	int error, error1;
-	char name[MAXCOMLEN+6];		/* progname.core */
+	char *name;
 
 	if (p->p_flag & P_SUGID)
 		return (EFAULT);
 	if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >=
 	    p->p_rlimit[RLIMIT_CORE].rlim_cur)
 		return (EFAULT);
-	sprintf(name, "%s.core", p->p_comm);
+
+	name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid);
+	if (name == NULL)
+		return(EFAULT);
 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
-	if ((error = vn_open(&nd,
-	    O_CREAT | FWRITE, S_IRUSR | S_IWUSR)))
+	error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IWUSR);
+	free(name, M_TEMP);
+	if (error)
 		return (error);
 	vp = nd.ni_vp;
 
Index: sys/sysctl.h
===================================================================
RCS file: /usr/cvs/src/sys/sys/sysctl.h,v
retrieving revision 1.48.2.2
diff -u -r1.48.2.2 sysctl.h
--- sysctl.h	1997/08/30 14:08:56	1.48.2.2
+++ sysctl.h	1998/07/03 19:30:28
@@ -230,7 +230,8 @@
 #define	KERN_MAXSOCKBUF		31	/* int: max size of a socket buffer */
 #define	KERN_PS_STRINGS		32	/* int: address of PS_STRINGS */
 #define	KERN_USRSTACK		33	/* int: address of USRSTACK */
-#define KERN_MAXID		34      /* number of valid kern ids */
+#define	KERN_COREFILENAME	34	/* string: name of core file */
+#define KERN_MAXID		35      /* number of valid kern ids */
 
 #define CTL_KERN_NAMES { \
 	{ 0, 0 }, \
@@ -267,6 +268,7 @@
 	{ "maxsockbuf", CTLTYPE_INT }, \
 	{ "ps_strings", CTLTYPE_INT }, \
 	{ "usrstack", CTLTYPE_INT }, \
+	{ "corefile", CTLTYPE_STRING }, \
 }
 
 /*

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199807072359.QAA25406>