#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);
}
enum {
- GC_OFFSET_IN_PATH, /* This one is on the path we were travelling */
+ GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */
GC_OFFSET_UNSURE, /* No clue */
GC_OFFSET_GOOD, /* We still need this unit */
GC_OFFSET_BAD, /* We don't need this unit anymore */
/* Tries to delete one item in the linked list
* j->transaction_next->transaction_next->... that conflicts
- * whith another one, in an attempt to make an inconsistent
+ * with another one, in an attempt to make an inconsistent
* transaction work. */
/* We rely here on the fact that if a merged with b does not
break;
if (r != -EAGAIN) {
- log_warning("Requested transaction contains unmergable jobs: %s", bus_error(e, r));
+ log_warning("Requested transaction contains unmergeable jobs: %s", bus_error(e, r));
goto rollback;
}
assert(m);
assert(unit);
- /* Looks for an axisting prospective job and returns that. If
+ /* Looks for an existing prospective job and returns that. If
* it doesn't exist it is created and added to the prospective
* jobs list. */
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) {
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);
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"