10
10
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
13
#include "daemon-shared.h"
13
#include "daemon-io.h"
14
#include "config-util.h"
14
15
#include "daemon-server.h"
16
#include "daemon-log.h"
69
71
# define OOM_SCORE_ADJ_MIN (-1000)
71
73
/* Systemd on-demand activation support */
74
# define SD_ACTIVATION_ENV_VAR_NAME "SD_ACTIVATION"
72
75
# define SD_LISTEN_PID_ENV_VAR_NAME "LISTEN_PID"
73
76
# define SD_LISTEN_FDS_ENV_VAR_NAME "LISTEN_FDS"
74
77
# define SD_LISTEN_FDS_START 3
128
131
static int _handle_preloaded_socket(int fd, const char *path)
130
133
struct stat st_fd;
131
union sockaddr_union sockaddr;
134
union sockaddr_union sockaddr = { .sa.sa_family = 0 };
133
136
socklen_t len = sizeof(type);
134
137
size_t path_len = strlen(path);
143
146
len != sizeof(type) || type != SOCK_STREAM)
146
memset(&sockaddr, 0, sizeof(sockaddr));
147
149
len = sizeof(sockaddr);
148
150
if (getsockname(fd, &sockaddr.sa, &len) < 0 ||
149
151
len < sizeof(sa_family_t) ||
164
166
unsigned long env_pid, env_listen_fds;
169
/* SD_ACTIVATION must be set! */
170
if (!(e = getenv(SD_ACTIVATION_ENV_VAR_NAME)) || strcmp(e, "1"))
167
173
/* LISTEN_PID must be equal to our PID! */
168
174
if (!(e = getenv(SD_LISTEN_PID_ENV_VAR_NAME)))
172
178
env_pid = strtoul(e, &p, 10);
173
179
if (errno || !p || *p || env_pid <= 0 ||
174
180
getpid() != (pid_t) env_pid)
177
183
/* LISTEN_FDS must be 1 and the fd must be a socket! */
178
184
if (!(e = getenv(SD_LISTEN_FDS_ENV_VAR_NAME)))
198
205
static int _open_socket(daemon_state s)
201
struct sockaddr_un sockaddr;
208
struct sockaddr_un sockaddr = { .sun_family = AF_UNIX };
204
211
(void) dm_prepare_selinux_context(s.socket_path, S_IFSOCK);
214
221
/* Set Close-on-exec & non-blocking */
215
222
if (fcntl(fd, F_SETFD, 1))
216
223
fprintf(stderr, "setting CLOEXEC on socket fd %d failed: %s\n", fd, strerror(errno));
217
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
224
if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK))
225
fprintf(stderr, "setting O_NONBLOCK on socket fd %d failed: %s\n", fd, strerror(errno));
219
227
fprintf(stderr, "[D] creating %s\n", s.socket_path);
220
memset(&sockaddr, 0, sizeof(sockaddr));
221
strcpy(sockaddr.sun_path, s.socket_path);
222
sockaddr.sun_family = AF_UNIX;
228
if (!dm_strncpy(sockaddr.sun_path, s.socket_path, sizeof(sockaddr.sun_path))) {
229
fprintf(stderr, "%s: daemon socket path too long.\n", s.socket_path);
224
233
if (bind(fd, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
225
234
perror("can't bind local socket.");
325
334
va_start(ap, id);
327
if (!(res.buffer = format_buffer("response", id, ap)))
336
buffer_init(&res.buffer);
337
if (!buffer_append_f(&res.buffer, "response = %s", id, NULL)) {
341
if (!buffer_append_vf(&res.buffer, ap)) {
337
353
client_handle client;
340
static int buffer_rewrite(char **buf, const char *format, const char *string) {
342
int r = dm_asprintf(buf, format, *buf, string);
346
return (r < 0) ? 0 : 1;
349
static int buffer_line(const char *line, void *baton) {
353
if (!buffer_rewrite(&r->buffer, "%s\n%s", line))
355
} else if (dm_asprintf(&r->buffer, "%s\n", line) < 0)
361
356
static response builtin_handler(daemon_state s, client_handle h, request r)
363
358
const char *rq = daemon_request_str(r, "request", "NONE");
359
response res = { .error = EPROTO };
365
361
if (!strcmp(rq, "hello")) {
366
362
return daemon_reply_simple("OK", "protocol = %s", s.protocol ?: "default",
367
"version = %d", s.protocol_version, NULL);
363
"version = %" PRId64, (int64_t) s.protocol_version, NULL);
370
response res = { .buffer = NULL, .error = EPROTO };
366
buffer_init(&res.buffer);
376
buffer_init(&req.buffer);
381
if (!read_buffer(b->client.socket_fd, &req.buffer))
379
if (!buffer_read(b->client.socket_fd, &req.buffer))
384
req.cft = dm_config_from_string(req.buffer);
382
req.cft = dm_config_from_string(req.buffer.mem);
386
fprintf(stderr, "error parsing request:\n %s\n", req.buffer);
385
fprintf(stderr, "error parsing request:\n %s\n", req.buffer.mem);
387
daemon_log_cft(b->s.log, DAEMON_LOG_WIRE, "<- ", req.cft->root);
388
389
res = builtin_handler(b->s, b->client, req);
390
391
if (res.error == EPROTO) /* Not a builtin, delegate to the custom handler. */
391
392
res = b->s.handler(b->s, b->client, req);
394
dm_config_write_node(res.cft->root, buffer_line, &res);
395
if (!buffer_rewrite(&res.buffer, "%s\n\n", NULL))
394
if (!res.buffer.mem) {
395
dm_config_write_node(res.cft->root, buffer_line, &res.buffer);
396
if (!buffer_append(&res.buffer, "\n\n"))
397
398
dm_config_destroy(res.cft);
401
402
dm_config_destroy(req.cft);
404
write_buffer(b->client.socket_fd, res.buffer, strlen(res.buffer));
403
buffer_destroy(&req.buffer);
405
daemon_log_multi(b->s.log, DAEMON_LOG_WIRE, "-> ", res.buffer.mem);
406
buffer_write(b->client.socket_fd, &res.buffer);
408
buffer_destroy(&res.buffer);
409
411
/* TODO what should we really do here? */
410
412
if (close(b->client.socket_fd))
414
buffer_destroy(&req.buffer);
441
444
void daemon_start(daemon_state s)
447
log_state _log = { { 0 } };
445
450
* Switch to C locale to avoid reading large locale-archive file used by
446
451
* some glibc (on some distributions it takes over 100MB). Some daemons
456
461
if (!s.foreground)
459
/* TODO logging interface should be somewhat more elaborate */
460
openlog(s.name, LOG_PID, LOG_DAEMON);
462
(void) dm_prepare_selinux_context(s.pidfile, S_IFREG);
465
* NB. Take care to not keep stale locks around. Best not exit(...)
468
if (dm_create_lockfile(s.pidfile) == 0)
471
(void) dm_prepare_selinux_context(NULL, 0);
465
s.log->name = s.name;
467
/* Log important things to syslog by default. */
468
daemon_log_enable(s.log, DAEMON_LOG_OUTLET_SYSLOG, DAEMON_LOG_FATAL, 1);
469
daemon_log_enable(s.log, DAEMON_LOG_OUTLET_SYSLOG, DAEMON_LOG_ERROR, 1);
472
(void) dm_prepare_selinux_context(s.pidfile, S_IFREG);
475
* NB. Take care to not keep stale locks around. Best not exit(...)
478
if (dm_create_lockfile(s.pidfile) == 0)
481
(void) dm_prepare_selinux_context(NULL, 0);
473
484
/* Set normal exit signals to request shutdown instead of dying. */
474
485
signal(SIGINT, &_exit_handler);
482
493
/* Systemd has adjusted oom killer for us already */
483
494
if (s.avoid_oom && !_systemd_activation && !_protect_against_oom_killer())
484
syslog(LOG_ERR, "Failed to protect against OOM killer");
495
ERROR(&s, "Failed to protect against OOM killer");
487
498
if (!_systemd_activation && s.socket_path) {
504
516
if (select(FD_SETSIZE, &in, NULL, NULL, NULL) < 0 && errno != EINTR)
505
517
perror("select error");
506
518
if (FD_ISSET(s.socket_fd, &in))
507
if (!handle_connect(s))
508
syslog(LOG_ERR, "Failed to handle a client connection.");
519
if (!_shutdown_requested && !handle_connect(s))
520
ERROR(&s, "Failed to handle a client connection.");
511
if (s.socket_fd >= 0)
523
/* If activated by systemd, do not unlink the socket - systemd takes care of that! */
524
if (!_systemd_activation && s.socket_fd >= 0)
512
525
if (unlink(s.socket_path))
513
526
perror("unlink error");
515
528
if (s.daemon_fini)
518
syslog(LOG_NOTICE, "%s shutting down", s.name);
520
remove_lockfile(s.pidfile);
529
if (!s.daemon_fini(&s))
532
INFO(&s, "%s shutting down", s.name);
534
closelog(); /* FIXME */
536
remove_lockfile(s.pidfile);