Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_sig.c
Show First 20 Lines • Show All 3,208 Lines • ▼ Show 20 Lines | childproc_exited(struct proc *p) | ||||
} | } | ||||
/* | /* | ||||
* XXX avoid calling wakeup(p->p_pptr), the work is | * XXX avoid calling wakeup(p->p_pptr), the work is | ||||
* done in exit1(). | * done in exit1(). | ||||
*/ | */ | ||||
sigparent(p, reason, status); | sigparent(p, reason, status); | ||||
} | } | ||||
/* | #define MAX_NUM_CORE_FILES 100000 | ||||
* We only have 1 character for the core count in the format | |||||
* string, so the range will be 0-9 | |||||
*/ | |||||
#define MAX_NUM_CORE_FILES 10 | |||||
#ifndef NUM_CORE_FILES | #ifndef NUM_CORE_FILES | ||||
#define NUM_CORE_FILES 5 | #define NUM_CORE_FILES 5 | ||||
#endif | #endif | ||||
CTASSERT(NUM_CORE_FILES >= 0 && NUM_CORE_FILES <= MAX_NUM_CORE_FILES); | CTASSERT(NUM_CORE_FILES >= 0 && NUM_CORE_FILES <= MAX_NUM_CORE_FILES); | ||||
static int num_cores = NUM_CORE_FILES; | static int num_cores = NUM_CORE_FILES; | ||||
static int | static int | ||||
sysctl_debug_num_cores_check (SYSCTL_HANDLER_ARGS) | sysctl_debug_num_cores_check (SYSCTL_HANDLER_ARGS) | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | vnode_close_locked(struct thread *td, struct vnode *vp) | ||||
VOP_UNLOCK(vp, 0); | VOP_UNLOCK(vp, 0); | ||||
vn_close(vp, FWRITE, td->td_ucred, td); | vn_close(vp, FWRITE, td->td_ucred, td); | ||||
} | } | ||||
/* | /* | ||||
* If the core format has a %I in it, then we need to check | * If the core format has a %I in it, then we need to check | ||||
* for existing corefiles before defining a name. | * for existing corefiles before defining a name. | ||||
* To do this we iterate over 0..num_cores to find a | * To do this we iterate over 0..ncores to find a | ||||
* non-existing core file name to use. If all core files are | * non-existing core file name to use. If all core files are | ||||
* already used we choose the oldest one. | * already used we choose the oldest one. | ||||
*/ | */ | ||||
static int | static int | ||||
corefile_open_last(struct thread *td, char *name, int indexpos, | corefile_open_last(struct thread *td, char *name, int indexpos, | ||||
struct vnode **vpp) | int indexlen, int ncores, struct vnode **vpp) | ||||
{ | { | ||||
struct vnode *oldvp, *nextvp, *vp; | struct vnode *oldvp, *nextvp, *vp; | ||||
struct vattr vattr; | struct vattr vattr; | ||||
struct nameidata nd; | struct nameidata nd; | ||||
int error, i, flags, oflags, cmode; | int error, i, flags, oflags, cmode; | ||||
char ch; | |||||
struct timespec lasttime; | struct timespec lasttime; | ||||
nextvp = oldvp = NULL; | nextvp = oldvp = NULL; | ||||
cmode = S_IRUSR | S_IWUSR; | cmode = S_IRUSR | S_IWUSR; | ||||
oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE | | oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE | | ||||
(capmode_coredump ? VN_OPEN_NOCAPCHECK : 0); | (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0); | ||||
for (i = 0; i < num_cores; i++) { | for (i = 0; i < ncores; i++) { | ||||
flags = O_CREAT | FWRITE | O_NOFOLLOW; | flags = O_CREAT | FWRITE | O_NOFOLLOW; | ||||
name[indexpos] = '0' + i; | |||||
ch = name[indexpos + indexlen]; | |||||
(void)snprintf(name + indexpos, indexlen + 1, "%.*u", indexlen, | |||||
i); | |||||
name[indexpos + indexlen] = ch; | |||||
NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td); | NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td); | ||||
error = vn_open_cred(&nd, &flags, cmode, oflags, td->td_ucred, | error = vn_open_cred(&nd, &flags, cmode, oflags, td->td_ucred, | ||||
NULL); | NULL); | ||||
if (error != 0) | if (error != 0) | ||||
break; | break; | ||||
vp = nd.ni_vp; | vp = nd.ni_vp; | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
corefile_open(const char *comm, uid_t uid, pid_t pid, struct thread *td, | corefile_open(const char *comm, uid_t uid, pid_t pid, struct thread *td, | ||||
int compress, struct vnode **vpp, char **namep) | int compress, struct vnode **vpp, char **namep) | ||||
{ | { | ||||
struct sbuf sb; | struct sbuf sb; | ||||
struct nameidata nd; | struct nameidata nd; | ||||
const char *format; | const char *format; | ||||
char *hostname, *name; | char *hostname, *name; | ||||
int cmode, error, flags, i, indexpos, oflags; | int cmode, error, flags, i, indexpos, indexlen, oflags, ncores; | ||||
hostname = NULL; | hostname = NULL; | ||||
format = corefilename; | format = corefilename; | ||||
name = malloc(MAXPATHLEN, M_TEMP, M_WAITOK | M_ZERO); | name = malloc(MAXPATHLEN, M_TEMP, M_WAITOK | M_ZERO); | ||||
indexlen = 0; | |||||
indexpos = -1; | indexpos = -1; | ||||
ncores = num_cores; | |||||
(void)sbuf_new(&sb, name, MAXPATHLEN, SBUF_FIXEDLEN); | (void)sbuf_new(&sb, name, MAXPATHLEN, SBUF_FIXEDLEN); | ||||
sx_slock(&corefilename_lock); | sx_slock(&corefilename_lock); | ||||
for (i = 0; format[i] != '\0'; i++) { | for (i = 0; format[i] != '\0'; i++) { | ||||
switch (format[i]) { | switch (format[i]) { | ||||
case '%': /* Format character */ | case '%': /* Format character */ | ||||
i++; | i++; | ||||
switch (format[i]) { | switch (format[i]) { | ||||
case '%': | case '%': | ||||
sbuf_putc(&sb, '%'); | sbuf_putc(&sb, '%'); | ||||
break; | break; | ||||
case 'H': /* hostname */ | case 'H': /* hostname */ | ||||
if (hostname == NULL) { | if (hostname == NULL) { | ||||
hostname = malloc(MAXHOSTNAMELEN, | hostname = malloc(MAXHOSTNAMELEN, | ||||
M_TEMP, M_WAITOK); | M_TEMP, M_WAITOK); | ||||
} | } | ||||
getcredhostname(td->td_ucred, hostname, | getcredhostname(td->td_ucred, hostname, | ||||
MAXHOSTNAMELEN); | MAXHOSTNAMELEN); | ||||
sbuf_printf(&sb, "%s", hostname); | sbuf_printf(&sb, "%s", hostname); | ||||
break; | break; | ||||
case 'I': /* autoincrementing index */ | case 'I': /* autoincrementing index */ | ||||
sbuf_printf(&sb, "0"); | if (indexpos != -1) { | ||||
indexpos = sbuf_len(&sb) - 1; | sbuf_printf(&sb, "%%I"); | ||||
break; | break; | ||||
} | |||||
indexpos = sbuf_len(&sb); | |||||
sbuf_printf(&sb, "%u", ncores - 1); | |||||
indexlen = sbuf_len(&sb) - indexpos; | |||||
break; | |||||
case 'N': /* process name */ | case 'N': /* process name */ | ||||
sbuf_printf(&sb, "%s", comm); | sbuf_printf(&sb, "%s", comm); | ||||
break; | break; | ||||
case 'P': /* process id */ | case 'P': /* process id */ | ||||
sbuf_printf(&sb, "%u", pid); | sbuf_printf(&sb, "%u", pid); | ||||
break; | break; | ||||
case 'U': /* user id */ | case 'U': /* user id */ | ||||
sbuf_printf(&sb, "%u", uid); | sbuf_printf(&sb, "%u", uid); | ||||
Show All 22 Lines | if (sbuf_error(&sb) != 0) { | ||||
sbuf_delete(&sb); | sbuf_delete(&sb); | ||||
free(name, M_TEMP); | free(name, M_TEMP); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
sbuf_finish(&sb); | sbuf_finish(&sb); | ||||
sbuf_delete(&sb); | sbuf_delete(&sb); | ||||
if (indexpos != -1) { | if (indexpos != -1) { | ||||
error = corefile_open_last(td, name, indexpos, vpp); | error = corefile_open_last(td, name, indexpos, indexlen, ncores, | ||||
vpp); | |||||
if (error != 0) { | if (error != 0) { | ||||
log(LOG_ERR, | log(LOG_ERR, | ||||
"pid %d (%s), uid (%u): Path `%s' failed " | "pid %d (%s), uid (%u): Path `%s' failed " | ||||
"on initial open test, error = %d\n", | "on initial open test, error = %d\n", | ||||
pid, comm, uid, name, error); | pid, comm, uid, name, error); | ||||
} | } | ||||
} else { | } else { | ||||
cmode = S_IRUSR | S_IWUSR; | cmode = S_IRUSR | S_IWUSR; | ||||
▲ Show 20 Lines • Show All 326 Lines • Show Last 20 Lines |