+ format_timespan(sum, sizeof(sum), total_usec));
+ }
+
+ bus_broadcast_finished(m, kernel_usec, initrd_usec, userspace_usec, total_usec);
+
+ sd_notifyf(false,
+ "READY=1\nSTATUS=Startup finished in %s.",
+ format_timespan(sum, sizeof(sum), total_usec));
+}
+
+void manager_run_generators(Manager *m) {
+ DIR *d = NULL;
+ const char *generator_path;
+ const char *argv[3];
+ mode_t u;
+
+ assert(m);
+
+ generator_path = m->running_as == MANAGER_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
+ if (!(d = opendir(generator_path))) {
+
+ if (errno == ENOENT)
+ return;
+
+ log_error("Failed to enumerate generator directory: %m");
+ return;
+ }
+
+ if (!m->generator_unit_path) {
+ const char *p;
+ char user_path[] = "/tmp/systemd-generator-XXXXXX";
+
+ if (m->running_as == MANAGER_SYSTEM && getpid() == 1) {
+ p = "/run/systemd/generator";
+
+ if (mkdir_p(p, 0755) < 0) {
+ log_error("Failed to create generator directory: %m");
+ goto finish;
+ }
+
+ } else {
+ if (!(p = mkdtemp(user_path))) {
+ log_error("Failed to create generator directory: %m");
+ goto finish;
+ }
+ }
+
+ if (!(m->generator_unit_path = strdup(p))) {
+ log_error("Failed to allocate generator unit path.");
+ goto finish;
+ }
+ }
+
+ argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
+ argv[1] = m->generator_unit_path;
+ argv[2] = NULL;
+
+ u = umask(0022);
+ execute_directory(generator_path, d, (char**) argv);
+ umask(u);
+
+ if (rmdir(m->generator_unit_path) >= 0) {
+ /* Uh? we were able to remove this dir? I guess that
+ * means the directory was empty, hence let's shortcut
+ * this */
+
+ free(m->generator_unit_path);
+ m->generator_unit_path = NULL;
+ goto finish;
+ }
+
+ if (!strv_find(m->lookup_paths.unit_path, m->generator_unit_path)) {
+ char **l;
+
+ if (!(l = strv_append(m->lookup_paths.unit_path, m->generator_unit_path))) {
+ log_error("Failed to add generator directory to unit search path: %m");
+ goto finish;
+ }
+
+ strv_free(m->lookup_paths.unit_path);
+ m->lookup_paths.unit_path = l;
+
+ log_debug("Added generator unit path %s to search path.", m->generator_unit_path);
+ }
+
+finish:
+ if (d)
+ closedir(d);
+}
+
+void manager_undo_generators(Manager *m) {
+ assert(m);
+
+ if (!m->generator_unit_path)
+ return;
+
+ strv_remove(m->lookup_paths.unit_path, m->generator_unit_path);
+ rm_rf(m->generator_unit_path, false, true, false);
+
+ free(m->generator_unit_path);
+ m->generator_unit_path = NULL;
+}
+
+int manager_set_default_controllers(Manager *m, char **controllers) {
+ char **l;
+
+ assert(m);
+
+ if (!(l = strv_copy(controllers)))
+ return -ENOMEM;
+
+ strv_free(m->default_controllers);
+ m->default_controllers = l;
+
+ return 0;
+}
+
+void manager_recheck_journal(Manager *m) {
+ Unit *u;
+
+ assert(m);
+
+ if (m->running_as != MANAGER_SYSTEM)
+ return;
+
+ u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
+ if (u && SOCKET(u)->state != SOCKET_RUNNING) {
+ log_close_journal();
+ return;
+ }
+
+ u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
+ if (u && SERVICE(u)->state != SERVICE_RUNNING) {
+ log_close_journal();
+ return;
+ }
+
+ /* Hmm, OK, so the socket is fully up and the service is up
+ * too, then let's make use of the thing. */
+ log_open();
+}
+
+void manager_set_show_status(Manager *m, bool b) {
+ assert(m);
+
+ if (m->running_as != MANAGER_SYSTEM)
+ return;
+
+ m->show_status = b;
+
+ if (b)
+ touch("/run/systemd/show-status");
+ else
+ unlink("/run/systemd/show-status");
+}
+
+bool manager_get_show_status(Manager *m) {
+ assert(m);
+
+ if (m->running_as != MANAGER_SYSTEM)
+ return false;
+
+ if (m->show_status)
+ return true;
+
+ /* If Plymouth is running make sure we show the status, so
+ * that there's something nice to see when people press Esc */