svn commit: r340237 - in stable/11: . sys/kern
Mariusz Zaborski
oshogbo at FreeBSD.org
Wed Nov 7 20:31:38 UTC 2018
Author: oshogbo
Date: Wed Nov 7 20:31:36 2018
New Revision: 340237
URL: https://svnweb.freebsd.org/changeset/base/340237
Log:
MFC r335844:
core(5): overwrite the oldest core dump
The '%I' format in the kern.corefile sysctl limits the number of
core files that a process can generate to the number stored in the
debug.ncores sysctl. The '%I' format is replaced by the single digit
index. Previously, if all indexes were taken the kernel would overwrite
only a core file with the highest index in a filename.
Currently the system will create a new core file if there is a free
index or if all slots are taken it will overwrite the oldest one.
Reviewed by: kib(code), bcr (updating)
Differential Revision: https://reviews.freebsd.org/D15991
Differential Revision: https://reviews.freebsd.org/D16084
Modified:
stable/11/UPDATING
stable/11/sys/kern/kern_sig.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/UPDATING
==============================================================================
--- stable/11/UPDATING Wed Nov 7 19:31:48 2018 (r340236)
+++ stable/11/UPDATING Wed Nov 7 20:31:36 2018 (r340237)
@@ -16,6 +16,15 @@ from older versions of FreeBSD, try WITHOUT_CLANG and
the tip of head, and then rebuild without this option. The bootstrap process
from older version of current across the gcc/clang cutover is a bit fragile.
+20181107:
+ The '%I' format in the kern.corefile sysctl limits the number of
+ core files that a process can generate to the number stored in the
+ debug.ncores sysctl. The '%I' format is replaced by the single digit
+ index. Previously, if all indexes were taken the kernel would overwrite
+ only a core file with the highest index in a filename.
+ Currently the system will create a new core file if there is a free
+ index or if all slots are taken it will overwrite the oldest one.
+
20180818:
WITH_OFED option now only enables the build for the OFED libraries
and some fundamental client utilities. OpenSM and rest of the
Modified: stable/11/sys/kern/kern_sig.c
==============================================================================
--- stable/11/sys/kern/kern_sig.c Wed Nov 7 19:31:48 2018 (r340236)
+++ stable/11/sys/kern/kern_sig.c Wed Nov 7 20:31:36 2018 (r340237)
@@ -3304,7 +3304,89 @@ SYSCTL_PROC(_kern, OID_AUTO, corefile, CTLTYPE_STRING
CTLFLAG_MPSAFE, 0, 0, sysctl_kern_corefile, "A",
"Process corefile name format string");
+static void
+vnode_close_locked(struct thread *td, struct vnode *vp)
+{
+
+ VOP_UNLOCK(vp, 0);
+ vn_close(vp, FWRITE, td->td_ucred, td);
+}
+
/*
+ * If the core format has a %I in it, then we need to check
+ * for existing corefiles before defining a name.
+ * To do this we iterate over 0..num_cores to find a
+ * non-existing core file name to use. If all core files are
+ * already used we choose the oldest one.
+ */
+static int
+corefile_open_last(struct thread *td, char *name, int indexpos,
+ struct vnode **vpp)
+{
+ struct vnode *oldvp, *nextvp, *vp;
+ struct vattr vattr;
+ struct nameidata nd;
+ int error, i, flags, oflags, cmode;
+ struct timespec lasttime;
+
+ nextvp = oldvp = NULL;
+ cmode = S_IRUSR | S_IWUSR;
+ oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE |
+ (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0);
+
+ for (i = 0; i < num_cores; i++) {
+ flags = O_CREAT | FWRITE | O_NOFOLLOW;
+ name[indexpos] = '0' + i;
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td);
+ error = vn_open_cred(&nd, &flags, cmode, oflags, td->td_ucred,
+ NULL);
+ if (error != 0)
+ break;
+
+ vp = nd.ni_vp;
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ if ((flags & O_CREAT) == O_CREAT) {
+ nextvp = vp;
+ break;
+ }
+
+ error = VOP_GETATTR(vp, &vattr, td->td_ucred);
+ if (error != 0) {
+ vnode_close_locked(td, vp);
+ break;
+ }
+
+ if (oldvp == NULL ||
+ lasttime.tv_sec > vattr.va_mtime.tv_sec ||
+ (lasttime.tv_sec == vattr.va_mtime.tv_sec &&
+ lasttime.tv_nsec >= vattr.va_mtime.tv_nsec)) {
+ if (oldvp != NULL)
+ vnode_close_locked(td, oldvp);
+ oldvp = vp;
+ lasttime = vattr.va_mtime;
+ } else {
+ vnode_close_locked(td, vp);
+ }
+ }
+
+ if (oldvp != NULL) {
+ if (nextvp == NULL)
+ nextvp = oldvp;
+ else
+ vnode_close_locked(td, oldvp);
+ }
+ if (error != 0) {
+ if (nextvp != NULL)
+ vnode_close_locked(td, oldvp);
+ } else {
+ *vpp = nextvp;
+ }
+
+ return (error);
+}
+
+/*
* corefile_open(comm, uid, pid, td, compress, vpp, namep)
* Expand the name described in corefilename, using name, uid, and pid
* and open/create core file.
@@ -3320,11 +3402,11 @@ static int
corefile_open(const char *comm, uid_t uid, pid_t pid, struct thread *td,
int compress, struct vnode **vpp, char **namep)
{
- struct nameidata nd;
struct sbuf sb;
+ struct nameidata nd;
const char *format;
char *hostname, *name;
- int indexpos, i, error, cmode, flags, oflags;
+ int cmode, error, flags, i, indexpos, oflags;
hostname = NULL;
format = corefilename;
@@ -3388,48 +3470,36 @@ corefile_open(const char *comm, uid_t uid, pid_t pid,
sbuf_finish(&sb);
sbuf_delete(&sb);
- cmode = S_IRUSR | S_IWUSR;
- oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE |
- (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0);
-
- /*
- * If the core format has a %I in it, then we need to check
- * for existing corefiles before returning a name.
- * To do this we iterate over 0..num_cores to find a
- * non-existing core file name to use.
- */
if (indexpos != -1) {
- for (i = 0; i < num_cores; i++) {
- flags = O_CREAT | O_EXCL | FWRITE | O_NOFOLLOW;
- name[indexpos] = '0' + i;
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td);
- error = vn_open_cred(&nd, &flags, cmode, oflags,
- td->td_ucred, NULL);
- if (error) {
- if (error == EEXIST)
- continue;
- log(LOG_ERR,
- "pid %d (%s), uid (%u): Path `%s' failed "
- "on initial open test, error = %d\n",
- pid, comm, uid, name, error);
- }
- goto out;
+ error = corefile_open_last(td, name, indexpos, vpp);
+ if (error != 0) {
+ log(LOG_ERR,
+ "pid %d (%s), uid (%u): Path `%s' failed "
+ "on initial open test, error = %d\n",
+ pid, comm, uid, name, error);
}
+ } else {
+ cmode = S_IRUSR | S_IWUSR;
+ oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE |
+ (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0);
+ flags = O_CREAT | FWRITE | O_NOFOLLOW;
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td);
+ error = vn_open_cred(&nd, &flags, cmode, oflags, td->td_ucred,
+ NULL);
+ if (error == 0) {
+ *vpp = nd.ni_vp;
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ }
}
- flags = O_CREAT | FWRITE | O_NOFOLLOW;
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td);
- error = vn_open_cred(&nd, &flags, cmode, oflags, td->td_ucred, NULL);
-out:
- if (error) {
+ if (error != 0) {
#ifdef AUDIT
audit_proc_coredump(td, name, error);
#endif
free(name, M_TEMP);
return (error);
}
- NDFREE(&nd, NDF_ONLY_PNBUF);
- *vpp = nd.ni_vp;
*namep = name;
return (0);
}
More information about the svn-src-stable
mailing list