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>
