#define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
/* Where clients shall send notification messages to */
-#define NOTIFY_SOCKET "/org/freedesktop/systemd1/notify"
+#define NOTIFY_SOCKET_SYSTEM "/run/systemd/notify"
+#define NOTIFY_SOCKET_USER "@/org/freedesktop/systemd1/notify"
static int manager_setup_notify(Manager *m) {
union {
sa.sa.sa_family = AF_UNIX;
if (getpid() != 1)
- snprintf(sa.un.sun_path+1, sizeof(sa.un.sun_path)-1, NOTIFY_SOCKET "/%llu", random_ull());
- else
- strncpy(sa.un.sun_path+1, NOTIFY_SOCKET, sizeof(sa.un.sun_path)-1);
+ snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET_USER "/%llu", random_ull());
+ else {
+ unlink(NOTIFY_SOCKET_SYSTEM);
+ strncpy(sa.un.sun_path, NOTIFY_SOCKET_SYSTEM, sizeof(sa.un.sun_path));
+ }
+
+ if (sa.un.sun_path[0] == '@')
+ sa.un.sun_path[0] = 0;
if (bind(m->notify_watch.fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
log_error("bind() failed: %m");
if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0)
return -errno;
- if (!(m->notify_socket = strdup(sa.un.sun_path+1)))
+ if (sa.un.sun_path[0] == 0)
+ sa.un.sun_path[0] = '@';
+
+ if (!(m->notify_socket = strdup(sa.un.sun_path)))
return -ENOMEM;
log_debug("Using notification socket %s", m->notify_socket);
}
static int enable_special_signals(Manager *m) {
- char fd;
+ int fd;
assert(m);
log_error("Failed to connect to audit log: %m");
#endif
+ m->taint_usr = dir_is_empty("/usr") > 0;
+
*_m = m;
return 0;
assert(m);
for (;;) {
+ char *p = NULL;
+
if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) {
if (n >= 0)
return -errno;
}
- log_debug("Received SIG%s", strna(signal_to_string(sfsi.ssi_signo)));
+ if (sfsi.ssi_pid > 0)
+ get_process_name(sfsi.ssi_pid, &p);
+
+ log_debug("Received SIG%s from PID %lu (%s)",
+ strna(signal_to_string(sfsi.ssi_signo)),
+ (unsigned long) sfsi.ssi_pid, strna(p));
+ free(p);
switch (sfsi.ssi_signo) {
int manager_loop(Manager *m) {
int r;
- RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 1000);
+ RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
assert(m);
m->exit_code = MANAGER_RUNNING;
if (m->n_deserializing > 0)
return;
+ if (m->running_as != MANAGER_SYSTEM)
+ return;
+
+ if (u->meta.type != UNIT_SERVICE)
+ return;
+
if (!(p = unit_name_to_prefix_and_instance(u->meta.id))) {
log_error("Failed to allocate unit name for audit message: %s", strerror(ENOMEM));
return;
}
- if (audit_log_user_comm_message(m->audit_fd, type, "", p, NULL, NULL, NULL, success) < 0)
- log_error("Failed to send audit message: %m");
+ if (audit_log_user_comm_message(m->audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) {
+ log_warning("Failed to send audit message: %m");
+
+ if (errno == EPERM) {
+ /* We aren't allowed to send audit messages?
+ * Then let's not retry again, to avoid
+ * spamming the user with the same and same
+ * messages over and over. */
+
+ audit_close(m->audit_fd);
+ m->audit_fd = -1;
+ }
+ }
free(p);
#endif
}
int manager_open_serialization(Manager *m, FILE **_f) {
- char *path;
+ char *path = NULL;
mode_t saved_umask;
int fd;
FILE *f;
assert(_f);
- if (m->running_as == MANAGER_SYSTEM) {
- mkdir_p("/dev/.systemd", 0755);
+ if (m->running_as == MANAGER_SYSTEM)
+ asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid());
+ else
+ asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid());
- if (asprintf(&path, "/dev/.systemd/dump-%lu-XXXXXX", (unsigned long) getpid()) < 0)
- return -ENOMEM;
- } else {
- if (asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid()) < 0)
- return -ENOMEM;
- }
+ if (!path)
+ return -ENOMEM;
saved_umask = umask(0077);
fd = mkostemp(path, O_RDWR|O_CLOEXEC);
log_debug("Serializing state to %s", path);
free(path);
- if (!(f = fdopen(fd, "w+")) < 0)
+ if (!(f = fdopen(fd, "w+")))
return -errno;
*_f = f;
dual_timestamp_get(&m->finish_timestamp);
- if (m->running_as == MANAGER_SYSTEM) {
+ if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0) {
+
if (dual_timestamp_is_set(&m->initrd_timestamp)) {
log_info("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
format_timespan(kernel, sizeof(kernel),
if (!m->generator_unit_path) {
char *p;
- char system_path[] = "/dev/.systemd/generator-XXXXXX",
+ char system_path[] = "/run/systemd/generator-XXXXXX",
user_path[] = "/tmp/systemd-generator-XXXXXX";
if (!(p = mkdtemp(m->running_as == MANAGER_SYSTEM ? system_path : user_path))) {
return 0;
}
+void manager_recheck_syslog(Manager *m) {
+ Unit *u;
+
+ assert(m);
+
+ if (m->running_as != MANAGER_SYSTEM)
+ return;
+
+ if ((u = manager_get_unit(m, SPECIAL_SYSLOG_SOCKET))) {
+ SocketState state;
+
+ state = SOCKET(u)->state;
+
+ if (state != SOCKET_DEAD &&
+ state != SOCKET_FAILED &&
+ state != SOCKET_RUNNING) {
+
+ /* Hmm, the socket is not set up, or is still
+ * listening, let's better not try to use
+ * it. Note that we have no problem if the
+ * socket is completely down, since there
+ * might be a foreign /dev/log socket around
+ * and we want to make use of that.
+ */
+
+ log_close_syslog();
+ return;
+ }
+ }
+
+ if ((u = manager_get_unit(m, SPECIAL_SYSLOG_TARGET)))
+ if (TARGET(u)->state != TARGET_ACTIVE) {
+ log_close_syslog();
+ return;
+ }
+
+ /* Hmm, OK, so the socket is either fully up, or fully down,
+ * and the target is up, then let's make use of the socket */
+ log_open();
+}
+
static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
[MANAGER_SYSTEM] = "system",
[MANAGER_USER] = "user"