Page MenuHomeFreeBSD

D41477.diff
No OneTemporary

D41477.diff

diff --git a/usr.sbin/syslogd/syslogd.h b/usr.sbin/syslogd/syslogd.h
--- a/usr.sbin/syslogd/syslogd.h
+++ b/usr.sbin/syslogd/syslogd.h
@@ -161,6 +161,7 @@
struct {
char f_pname[MAXPATHLEN];
int f_procdesc;
+ struct deadq_entry *f_dq;
}; /* F_PIPE */
};
diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -329,6 +329,7 @@
static bool needdofsync = true; /* Are any file(s) waiting to be fsynced? */
static struct pidfh *pfh;
static bool RFC3164OutputFormat = true; /* Use legacy format by default. */
+static int kq; /* kqueue(2) descriptor. */
struct iovlist;
@@ -337,7 +338,7 @@
static void addsock(const char *, const char *, mode_t);
static nvlist_t *cfline(const char *, const char *, const char *, const char *);
static const char *cvthname(struct sockaddr *);
-static void deadq_enter(int);
+static struct deadq_entry *deadq_enter(int);
static void deadq_remove(struct deadq_entry *);
static int decode(const char *, const CODE *);
static void die(int) __dead2;
@@ -349,6 +350,7 @@
static void init(bool);
static void logmsg(int, const struct logtime *, const char *, const char *,
const char *, const char *, const char *, const char *, int);
+static void log_deadchild(int, int, const struct filed *);
static void markit(void);
static struct socklist *socksetup(struct addrinfo *, const char *, mode_t);
static int socklist_recv_file(struct socklist *);
@@ -386,9 +388,21 @@
f->f_type = F_UNUSED;
break;
case F_PIPE:
- if (f->f_procdesc >= 0) {
- deadq_enter(f->f_procdesc);
+ if (f->f_procdesc != -1) {
+ /*
+ * Close the procdesc, killing the underlying
+ * process (if it is still alive).
+ */
+ (void)close(f->f_procdesc);
f->f_procdesc = -1;
+ /*
+ * The pipe process is guaranteed to be dead now,
+ * so remove it from the deadq.
+ */
+ if (f->f_dq != NULL) {
+ deadq_remove(f->f_dq);
+ f->f_dq = NULL;
+ }
}
break;
default:
@@ -492,7 +506,7 @@
struct kevent ev;
struct socklist *sl;
pid_t spid;
- int ch, kq, ppipe_w = -1, s;
+ int ch, ppipe_w = -1, s;
char *p;
bool bflag = false, pflag = false, Sflag = false;
@@ -794,6 +808,12 @@
break;
}
break;
+ case EVFILT_PROCDESC:
+ if ((ev.fflags & NOTE_EXIT) != 0) {
+ log_deadchild(ev.ident, ev.data, ev.udata);
+ close_filed(ev.udata);
+ }
+ break;
}
}
}
@@ -1833,6 +1853,7 @@
dprintf(" %s\n", f->f_pname);
iovlist_append(il, "\n");
if (f->f_procdesc == -1) {
+ struct kevent ev;
struct filed *f_in_list;
int i = 0;
@@ -1847,10 +1868,16 @@
logerror(f->f_pname);
break;
}
+ EV_SET(&ev, f->f_procdesc, EVFILT_PROCDESC, EV_ADD,
+ NOTE_EXIT, 0, f);
+ if (kevent(kq, &ev, 1, NULL, 0, NULL) == -1) {
+ logerror("failed to add procdesc kevent");
+ exit(1);
+ }
}
if (writev(f->f_file, il->iov, il->iovcnt) < 0) {
logerror(f->f_pname);
- close_filed(f);
+ f->f_dq = deadq_enter(f->f_procdesc);
}
break;
@@ -2218,7 +2245,7 @@
/* flush any pending output */
if (f->f_prevcount)
fprintlog_successive(f, 0);
- /* close our end of the pipe */
+ /* terminate existing pipe processes */
if (f->f_type == F_PIPE)
close_filed(f);
}
@@ -2459,7 +2486,23 @@
case F_FORW:
case F_CONSOLE:
case F_TTY:
+ close_filed(f);
+ break;
case F_PIPE:
+ if (f->f_procdesc != -1) {
+ struct kevent ev;
+ /*
+ * This filed is going to be freed.
+ * Delete procdesc kevents that reference it.
+ */
+ EV_SET(&ev, f->f_procdesc, EVFILT_PROCDESC,
+ EV_DELETE, NOTE_EXIT, 0, f);
+ if (kevent(kq, &ev, 1, NULL, 0, NULL) == -1) {
+ logerror("failed to delete procdesc"
+ "kevent");
+ exit(1);
+ }
+ }
close_filed(f);
break;
default:
@@ -3125,15 +3168,11 @@
case 0:
/* Already signalled once, try harder now. */
(void)pdkill(dq->dq_procdesc, SIGKILL);
- (void)deadq_remove(dq);
break;
case 1:
- if (pdkill(dq->dq_procdesc, SIGTERM) != 0)
- (void)deadq_remove(dq);
- else
- dq->dq_timeout--;
- break;
+ (void)pdkill(dq->dq_procdesc, SIGTERM);
+ /* FALLTHROUGH. */
default:
dq->dq_timeout--;
}
@@ -3546,13 +3585,13 @@
return (pfd[1]);
}
-static void
+static struct deadq_entry *
deadq_enter(int pd)
{
struct deadq_entry *dq;
if (pd == -1)
- return;
+ return (NULL);
dq = malloc(sizeof(*dq));
if (dq == NULL) {
@@ -3563,16 +3602,42 @@
dq->dq_procdesc = pd;
dq->dq_timeout = DQ_TIMO_INIT;
TAILQ_INSERT_TAIL(&deadq_head, dq, dq_entries);
+ return (dq);
}
static void
deadq_remove(struct deadq_entry *dq)
{
TAILQ_REMOVE(&deadq_head, dq, dq_entries);
- close(dq->dq_procdesc);
free(dq);
}
+static void
+log_deadchild(int pd, int status, const struct filed *f)
+{
+ pid_t pid;
+ int code;
+ char buf[256];
+ const char *reason;
+
+ errno = 0; /* Keep strerror() stuff out of logerror messages. */
+ if (WIFSIGNALED(status)) {
+ reason = "due to signal";
+ code = WTERMSIG(status);
+ } else {
+ reason = "with status";
+ code = WEXITSTATUS(status);
+ if (code == 0)
+ return;
+ }
+ if (pdgetpid(pd, &pid) == -1)
+ err(1, "pdgetpid");
+ (void)snprintf(buf, sizeof(buf),
+ "Logging subprocess %d (%s) exited %s %d.",
+ pid, f->f_pname, reason, code);
+ logerror(buf);
+}
+
static struct socklist *
socksetup(struct addrinfo *ai, const char *name, mode_t mode)
{

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 8, 2:59 AM (21 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14526267
Default Alt Text
D41477.diff (5 KB)

Event Timeline