summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2011-05-14 03:00:55 +0000
committersobomax <sobomax@FreeBSD.org>2011-05-14 03:00:55 +0000
commit1bbc0ba66b71452ff4076c6945e569556fba45ab (patch)
treed31bdd92f519c4e5f785dab22bad97cdd25afd63 /usr.sbin
parent75eec16b783e64eec723138ac1ff86dba28c14d4 (diff)
downloadFreeBSD-src-1bbc0ba66b71452ff4076c6945e569556fba45ab.zip
FreeBSD-src-1bbc0ba66b71452ff4076c6945e569556fba45ab.tar.gz
Add new modifier - "R", when it is specified the path to pid file
will be considered as a path to a binary or a shell script to be executed after rotation has been completed instead of sending signal to the process id in that file. Sponsored by: Sippy Software, Inc. From the: FreeBSD hacking lounge at BSDCan
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/newsyslog/newsyslog.c91
-rw-r--r--usr.sbin/newsyslog/newsyslog.conf.517
2 files changed, 76 insertions, 32 deletions
diff --git a/usr.sbin/newsyslog/newsyslog.c b/usr.sbin/newsyslog/newsyslog.c
index c169dee..191f077 100644
--- a/usr.sbin/newsyslog/newsyslog.c
+++ b/usr.sbin/newsyslog/newsyslog.c
@@ -125,6 +125,7 @@ __FBSDID("$FreeBSD$");
/* process when trimming this file. */
#define CE_CREATE 0x0100 /* Create the log file if it does not exist. */
#define CE_NODUMP 0x0200 /* Set 'nodump' on newly created log file. */
+#define CE_PID2CMD 0x0400 /* Replace PID file with a shell command.*/
#define MIN_PID 5 /* Don't touch pids lower than this */
#define MAX_PID 99999 /* was lower, see /usr/include/sys/proc.h */
@@ -154,7 +155,7 @@ const struct compress_types compress_type[COMPRESS_TYPES] = {
struct conf_entry {
STAILQ_ENTRY(conf_entry) cf_nextp;
char *log; /* Name of the log */
- char *pid_file; /* PID file */
+ char *pid_cmd_file; /* PID or command file */
char *r_reason; /* The reason this file is being rotated */
int firstcreate; /* Creating log for the first time (-C). */
int rotate; /* Non-zero if this file should be rotated */
@@ -178,7 +179,8 @@ struct sigwork_entry {
int sw_pidok; /* true if pid value is valid */
pid_t sw_pid; /* the process id from the PID file */
const char *sw_pidtype; /* "daemon" or "process group" */
- char sw_fname[1]; /* file the PID was read from */
+ int run_cmd; /* run command or send PID to signal */
+ char sw_fname[1]; /* file the PID was read from or shell cmd */
};
struct zipwork_entry {
@@ -384,9 +386,9 @@ init_entry(const char *fname, struct conf_entry *src_entry)
err(1, "strdup for %s", fname);
if (src_entry != NULL) {
- tempwork->pid_file = NULL;
- if (src_entry->pid_file)
- tempwork->pid_file = strdup(src_entry->pid_file);
+ tempwork->pid_cmd_file = NULL;
+ if (src_entry->pid_cmd_file)
+ tempwork->pid_cmd_file = strdup(src_entry->pid_cmd_file);
tempwork->r_reason = NULL;
tempwork->firstcreate = 0;
tempwork->rotate = 0;
@@ -406,7 +408,7 @@ init_entry(const char *fname, struct conf_entry *src_entry)
tempwork->def_cfg = src_entry->def_cfg;
} else {
/* Initialize as a "do-nothing" entry */
- tempwork->pid_file = NULL;
+ tempwork->pid_cmd_file = NULL;
tempwork->r_reason = NULL;
tempwork->firstcreate = 0;
tempwork->rotate = 0;
@@ -441,9 +443,9 @@ free_entry(struct conf_entry *ent)
ent->log = NULL;
}
- if (ent->pid_file != NULL) {
- free(ent->pid_file);
- ent->pid_file = NULL;
+ if (ent->pid_cmd_file != NULL) {
+ free(ent->pid_cmd_file);
+ ent->pid_cmd_file = NULL;
}
if (ent->r_reason != NULL) {
@@ -1291,6 +1293,9 @@ no_trimat:
case 'n':
working->flags |= CE_NOSIGNAL;
break;
+ case 'r':
+ working->flags |= CE_PID2CMD;
+ break;
case 'u':
working->flags |= CE_SIGNALGROUP;
break;
@@ -1324,10 +1329,10 @@ no_trimat:
*parse = '\0';
}
- working->pid_file = NULL;
+ working->pid_cmd_file = NULL;
if (q && *q) {
if (*q == '/')
- working->pid_file = strdup(q);
+ working->pid_cmd_file = strdup(q);
else if (isdigit(*q))
goto got_sig;
else
@@ -1364,16 +1369,16 @@ no_trimat:
if ((working->flags & CE_NOSIGNAL) == CE_NOSIGNAL) {
/*
* This config-entry specified 'n' for nosignal,
- * see if it also specified an explicit pid_file.
+ * see if it also specified an explicit pid_cmd_file.
* This would be a pretty pointless combination.
*/
- if (working->pid_file != NULL) {
+ if (working->pid_cmd_file != NULL) {
warnx("Ignoring '%s' because flag 'n' was specified in line:\n%s",
- working->pid_file, errline);
- free(working->pid_file);
- working->pid_file = NULL;
+ working->pid_cmd_file, errline);
+ free(working->pid_cmd_file);
+ working->pid_cmd_file = NULL;
}
- } else if (working->pid_file == NULL) {
+ } else if (working->pid_cmd_file == NULL) {
/*
* This entry did not specify the 'n' flag, which
* means it should signal syslogd unless it had
@@ -1388,7 +1393,7 @@ no_trimat:
working->flags &= ~CE_SIGNALGROUP;
}
if (needroot)
- working->pid_file = strdup(path_syslogpid);
+ working->pid_cmd_file = strdup(path_syslogpid);
}
/*
@@ -1826,7 +1831,7 @@ do_rotate(const struct conf_entry *ent)
* multiple log files had to be rotated.
*/
swork = NULL;
- if (ent->pid_file != NULL)
+ if (ent->pid_cmd_file != NULL)
swork = save_sigwork(ent);
if (ent->numlogs > 0 && ent->compress > COMPRESS_NONE) {
/*
@@ -1845,6 +1850,7 @@ do_sigwork(struct sigwork_entry *swork)
{
struct sigwork_entry *nextsig;
int kres, secs;
+ char *tmp;
if (!(swork->sw_pidok) || swork->sw_pid == 0)
return; /* no work to do... */
@@ -1887,6 +1893,24 @@ do_sigwork(struct sigwork_entry *swork)
return;
}
+ if (swork->run_cmd) {
+ asprintf(&tmp, "%s %d", swork->sw_fname, swork->sw_signum);
+ if (tmp == NULL) {
+ warn("can't allocate memory to run %s",
+ swork->sw_fname);
+ return;
+ }
+ if (verbose)
+ printf("Run command: %s\n", tmp);
+ kres = system(tmp);
+ if (kres) {
+ warnx("%s: returned non-zero exit code: %d",
+ tmp, kres);
+ }
+ free(tmp);
+ return;
+ }
+
kres = kill(swork->sw_pid, swork->sw_signum);
if (kres != 0) {
/*
@@ -2016,7 +2040,7 @@ save_sigwork(const struct conf_entry *ent)
sprev = NULL;
ndiff = 1;
SLIST_FOREACH(stmp, &swhead, sw_nextp) {
- ndiff = strcmp(ent->pid_file, stmp->sw_fname);
+ ndiff = strcmp(ent->pid_cmd_file, stmp->sw_fname);
if (ndiff > 0)
break;
if (ndiff == 0) {
@@ -2032,11 +2056,18 @@ save_sigwork(const struct conf_entry *ent)
if (stmp != NULL && ndiff == 0)
return (stmp);
- tmpsiz = sizeof(struct sigwork_entry) + strlen(ent->pid_file) + 1;
+ tmpsiz = sizeof(struct sigwork_entry) + strlen(ent->pid_cmd_file) + 1;
stmp = malloc(tmpsiz);
- set_swpid(stmp, ent);
+
+ stmp->run_cmd = 0;
+ /* If this is a command to run we just set the flag and run command */
+ if (ent->flags & CE_PID2CMD) {
+ stmp->run_cmd = 1;
+ } else {
+ set_swpid(stmp, ent);
+ }
stmp->sw_signum = ent->sig;
- strcpy(stmp->sw_fname, ent->pid_file);
+ strcpy(stmp->sw_fname, ent->pid_cmd_file);
if (sprev == NULL)
SLIST_INSERT_HEAD(&swhead, stmp, sw_nextp);
else
@@ -2113,7 +2144,7 @@ set_swpid(struct sigwork_entry *swork, const struct conf_entry *ent)
swork->sw_pidtype = "process-group";
}
- f = fopen(ent->pid_file, "r");
+ f = fopen(ent->pid_cmd_file, "r");
if (f == NULL) {
if (errno == ENOENT && enforcepid == 0) {
/*
@@ -2124,9 +2155,9 @@ set_swpid(struct sigwork_entry *swork, const struct conf_entry *ent)
* files that the process would have been using.
*/
swork->sw_pidok = 1;
- warnx("pid file doesn't exist: %s", ent->pid_file);
+ warnx("pid file doesn't exist: %s", ent->pid_cmd_file);
} else
- warn("can't open pid file: %s", ent->pid_file);
+ warn("can't open pid file: %s", ent->pid_cmd_file);
return;
}
@@ -2139,9 +2170,9 @@ set_swpid(struct sigwork_entry *swork, const struct conf_entry *ent)
*/
if (feof(f) && enforcepid == 0) {
swork->sw_pidok = 1;
- warnx("pid file is empty: %s", ent->pid_file);
+ warnx("pid/cmd file is empty: %s", ent->pid_cmd_file);
} else
- warn("can't read from pid file: %s", ent->pid_file);
+ warn("can't read from pid file: %s", ent->pid_cmd_file);
(void)fclose(f);
return;
}
@@ -2154,10 +2185,10 @@ set_swpid(struct sigwork_entry *swork, const struct conf_entry *ent)
rval = strtol(linep, &endp, 10);
if (*endp != '\0' && !isspacech(*endp)) {
warnx("pid file does not start with a valid number: %s",
- ent->pid_file);
+ ent->pid_cmd_file);
} else if (rval < minok || rval > maxok) {
warnx("bad value '%ld' for process number in %s",
- rval, ent->pid_file);
+ rval, ent->pid_cmd_file);
if (verbose)
warnx("\t(expecting value between %ld and %ld)",
minok, maxok);
diff --git a/usr.sbin/newsyslog/newsyslog.conf.5 b/usr.sbin/newsyslog/newsyslog.conf.5
index aa18313..e1aa20b 100644
--- a/usr.sbin/newsyslog/newsyslog.conf.5
+++ b/usr.sbin/newsyslog/newsyslog.conf.5
@@ -301,9 +301,16 @@ log file using
.It Cm N
indicates that there is no process which needs to be signaled
when this log file is rotated.
+.It Cm R
+if this flag is set the
+.Xr newsyslog 8
+will run shell command defined in
+.Ar path_to_pid_cmd_file
+after rotation instead of trying to send signal to a process id
+stored in the file.
.It Cm U
indicates that the file specified by
-.Ar path_to_pid_file
+.Ar path_to_pid_cmd_file
will contain the ID for a process group instead of a process.
This option also requires that the first line in that file
be a negative value to distinguish it from a process ID.
@@ -319,7 +326,7 @@ can be used as a placeholder to create a
.Ar flags
field when you need to specify any of the following fields.
.El
-.It Ar path_to_pid_file
+.It Ar path_to_pid_cmd_file
This optional field specifies the file name containing a daemon's
process ID or to find a group process ID if the
.Cm U
@@ -340,6 +347,12 @@ switch.
This field must start with
.Ql /
in order to be recognized properly.
+When used with the
+.Cm R
+flag, the file is treated as a path to a binary to be executed
+by the
+.Xr newsyslog 8
+after rotation instead of sending the signal out.
.It Ar signal_number
This optional field specifies the signal number that will be sent
to the daemon process (or to all processes in a process group, if the
OpenPOWER on IntegriCloud