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>