mirror of
https://github.com/systemd/systemd.git
synced 2024-11-27 20:23:36 +08:00
manager: optionally print status updates to console on boot
This commit is contained in:
parent
fa0f4d8a3a
commit
9e58ff9c5c
@ -115,6 +115,7 @@
|
|||||||
" <property name=\"NJobs\" type=\"u\" access=\"read\"/>\n" \
|
" <property name=\"NJobs\" type=\"u\" access=\"read\"/>\n" \
|
||||||
" <property name=\"Environment\" type=\"as\" access=\"read\"/>\n" \
|
" <property name=\"Environment\" type=\"as\" access=\"read\"/>\n" \
|
||||||
" <property name=\"ConfirmSpawn\" type=\"b\" access=\"read\"/>\n" \
|
" <property name=\"ConfirmSpawn\" type=\"b\" access=\"read\"/>\n" \
|
||||||
|
" <property name=\"ShowStatus\" type=\"b\" access=\"read\"/>\n" \
|
||||||
" <property name=\"UnitPath\" type=\"as\" access=\"read\"/>\n" \
|
" <property name=\"UnitPath\" type=\"as\" access=\"read\"/>\n" \
|
||||||
" <property name=\"SysVInitPath\" type=\"as\" access=\"read\"/>\n" \
|
" <property name=\"SysVInitPath\" type=\"as\" access=\"read\"/>\n" \
|
||||||
" <property name=\"SysVRcndPath\" type=\"as\" access=\"read\"/>\n" \
|
" <property name=\"SysVRcndPath\" type=\"as\" access=\"read\"/>\n" \
|
||||||
@ -222,6 +223,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
|
|||||||
{ "org.freedesktop.systemd1.Manager", "NJobs", bus_manager_append_n_jobs, "u", NULL },
|
{ "org.freedesktop.systemd1.Manager", "NJobs", bus_manager_append_n_jobs, "u", NULL },
|
||||||
{ "org.freedesktop.systemd1.Manager", "Environment", bus_property_append_strv, "as", m->environment },
|
{ "org.freedesktop.systemd1.Manager", "Environment", bus_property_append_strv, "as", m->environment },
|
||||||
{ "org.freedesktop.systemd1.Manager", "ConfirmSpawn", bus_property_append_bool, "b", &m->confirm_spawn },
|
{ "org.freedesktop.systemd1.Manager", "ConfirmSpawn", bus_property_append_bool, "b", &m->confirm_spawn },
|
||||||
|
{ "org.freedesktop.systemd1.Manager", "ShowStatus", bus_property_append_bool, "b", &m->show_status },
|
||||||
{ "org.freedesktop.systemd1.Manager", "UnitPath", bus_property_append_strv, "as", m->lookup_paths.unit_path },
|
{ "org.freedesktop.systemd1.Manager", "UnitPath", bus_property_append_strv, "as", m->lookup_paths.unit_path },
|
||||||
{ "org.freedesktop.systemd1.Manager", "SysVInitPath", bus_property_append_strv, "as", m->lookup_paths.sysvinit_path },
|
{ "org.freedesktop.systemd1.Manager", "SysVInitPath", bus_property_append_strv, "as", m->lookup_paths.sysvinit_path },
|
||||||
{ "org.freedesktop.systemd1.Manager", "SysVRcndPath", bus_property_append_strv, "as", m->lookup_paths.sysvrcnd_path },
|
{ "org.freedesktop.systemd1.Manager", "SysVRcndPath", bus_property_append_strv, "as", m->lookup_paths.sysvrcnd_path },
|
||||||
|
@ -483,6 +483,9 @@ int job_finish_and_invalidate(Job *j, bool success) {
|
|||||||
t = j->type;
|
t = j->type;
|
||||||
job_free(j);
|
job_free(j);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
unit_status_printf(u, "Starting %s... " ANSI_HIGHLIGHT_ON "failed" ANSI_HIGHLIGHT_OFF ".\n", unit_description(u));
|
||||||
|
|
||||||
/* Fail depending jobs on failure */
|
/* Fail depending jobs on failure */
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
|
||||||
|
56
src/main.c
56
src/main.c
@ -59,6 +59,7 @@ static bool arg_crash_shell = false;
|
|||||||
static int arg_crash_chvt = -1;
|
static int arg_crash_chvt = -1;
|
||||||
static bool arg_confirm_spawn = false;
|
static bool arg_confirm_spawn = false;
|
||||||
static bool arg_nomodules = false;
|
static bool arg_nomodules = false;
|
||||||
|
static bool arg_show_status = true;
|
||||||
|
|
||||||
static FILE* serialization = NULL;
|
static FILE* serialization = NULL;
|
||||||
|
|
||||||
@ -236,6 +237,7 @@ static int parse_proc_cmdline_word(const char *word) {
|
|||||||
"4", SPECIAL_RUNLEVEL4_TARGET,
|
"4", SPECIAL_RUNLEVEL4_TARGET,
|
||||||
"5", SPECIAL_RUNLEVEL5_TARGET
|
"5", SPECIAL_RUNLEVEL5_TARGET
|
||||||
};
|
};
|
||||||
|
bool ignore_quiet = false;
|
||||||
|
|
||||||
if (startswith(word, "systemd.unit="))
|
if (startswith(word, "systemd.unit="))
|
||||||
return set_default_unit(word + 13);
|
return set_default_unit(word + 13);
|
||||||
@ -292,6 +294,16 @@ static int parse_proc_cmdline_word(const char *word) {
|
|||||||
else
|
else
|
||||||
arg_crash_chvt = k;
|
arg_crash_chvt = k;
|
||||||
|
|
||||||
|
} else if (startswith(word, "systemd.show_status=")) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if ((r = parse_boolean(word + 20)) < 0)
|
||||||
|
log_warning("Failed to parse show status switch %s, Ignoring.", word + 20);
|
||||||
|
else {
|
||||||
|
arg_show_status = r;
|
||||||
|
ignore_quiet = true;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (startswith(word, "systemd.")) {
|
} else if (startswith(word, "systemd.")) {
|
||||||
|
|
||||||
log_warning("Unknown kernel switch %s. Ignoring.", word);
|
log_warning("Unknown kernel switch %s. Ignoring.", word);
|
||||||
@ -304,13 +316,17 @@ static int parse_proc_cmdline_word(const char *word) {
|
|||||||
"systemd.log_color=0|1 Highlight important log messages\n"
|
"systemd.log_color=0|1 Highlight important log messages\n"
|
||||||
"systemd.log_location=0|1 Include code location in log messages\n"
|
"systemd.log_location=0|1 Include code location in log messages\n"
|
||||||
"systemd.dump_core=0|1 Dump core on crash\n"
|
"systemd.dump_core=0|1 Dump core on crash\n"
|
||||||
"systemd.crash_shell=0|1 On crash run shell\n"
|
"systemd.crash_shell=0|1 Run shell on crash\n"
|
||||||
"systemd.crash_chvt=N Change to VT #N on crash\n"
|
"systemd.crash_chvt=N Change to VT #N on crash\n"
|
||||||
"systemd.confirm_spawn=0|1 Confirm every process spawn");
|
"systemd.confirm_spawn=0|1 Confirm every process spawn\n"
|
||||||
|
"systemd.show_status=0|1 Show status updates on the console during bootup\n");
|
||||||
|
|
||||||
} else if (streq(word, "nomodules"))
|
} else if (streq(word, "nomodules"))
|
||||||
arg_nomodules = true;
|
arg_nomodules = true;
|
||||||
else {
|
else if (streq(word, "quiet")) {
|
||||||
|
if (!ignore_quiet)
|
||||||
|
arg_show_status = false;
|
||||||
|
} else {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/* SysV compatibility */
|
/* SysV compatibility */
|
||||||
@ -367,7 +383,10 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_RUNNING_AS,
|
ARG_RUNNING_AS,
|
||||||
ARG_TEST,
|
ARG_TEST,
|
||||||
ARG_DUMP_CONFIGURATION_ITEMS,
|
ARG_DUMP_CONFIGURATION_ITEMS,
|
||||||
|
ARG_DUMP_CORE,
|
||||||
|
ARG_CRASH_SHELL,
|
||||||
ARG_CONFIRM_SPAWN,
|
ARG_CONFIRM_SPAWN,
|
||||||
|
ARG_SHOW_STATUS,
|
||||||
ARG_DESERIALIZE,
|
ARG_DESERIALIZE,
|
||||||
ARG_INTROSPECT
|
ARG_INTROSPECT
|
||||||
};
|
};
|
||||||
@ -382,7 +401,10 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "test", no_argument, NULL, ARG_TEST },
|
{ "test", no_argument, NULL, ARG_TEST },
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
|
{ "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
|
||||||
|
{ "dump-core", no_argument, NULL, ARG_DUMP_CORE },
|
||||||
|
{ "crash-shell", no_argument, NULL, ARG_CRASH_SHELL },
|
||||||
{ "confirm-spawn", no_argument, NULL, ARG_CONFIRM_SPAWN },
|
{ "confirm-spawn", no_argument, NULL, ARG_CONFIRM_SPAWN },
|
||||||
|
{ "show-status", no_argument, NULL, ARG_SHOW_STATUS },
|
||||||
{ "deserialize", required_argument, NULL, ARG_DESERIALIZE },
|
{ "deserialize", required_argument, NULL, ARG_DESERIALIZE },
|
||||||
{ "introspect", optional_argument, NULL, ARG_INTROSPECT },
|
{ "introspect", optional_argument, NULL, ARG_INTROSPECT },
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
@ -467,10 +489,22 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
|
arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_DUMP_CORE:
|
||||||
|
arg_dump_core = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG_CRASH_SHELL:
|
||||||
|
arg_crash_shell = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case ARG_CONFIRM_SPAWN:
|
case ARG_CONFIRM_SPAWN:
|
||||||
arg_confirm_spawn = true;
|
arg_confirm_spawn = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_SHOW_STATUS:
|
||||||
|
arg_show_status = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case ARG_DESERIALIZE: {
|
case ARG_DESERIALIZE: {
|
||||||
int fd;
|
int fd;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@ -543,14 +577,17 @@ static int help(void) {
|
|||||||
printf("%s [OPTIONS...]\n\n"
|
printf("%s [OPTIONS...]\n\n"
|
||||||
"Starts up and maintains the system or a session.\n\n"
|
"Starts up and maintains the system or a session.\n\n"
|
||||||
" -h --help Show this help\n"
|
" -h --help Show this help\n"
|
||||||
" --unit=UNIT Set default unit\n"
|
|
||||||
" --running-as=AS Set running as (system, session)\n"
|
|
||||||
" --test Determine startup sequence, dump it and exit\n"
|
" --test Determine startup sequence, dump it and exit\n"
|
||||||
" --dump-configuration-items Dump understood unit configuration items\n"
|
" --dump-configuration-items Dump understood unit configuration items\n"
|
||||||
" --confirm-spawn Ask for confirmation when spawning processes\n"
|
|
||||||
" --introspect[=INTERFACE] Extract D-Bus interface data\n"
|
" --introspect[=INTERFACE] Extract D-Bus interface data\n"
|
||||||
" --log-level=LEVEL Set log level\n"
|
" --unit=UNIT Set default unit\n"
|
||||||
|
" --running-as=AS Set running as (system, session)\n"
|
||||||
|
" --dump-core Dump core on crash\n"
|
||||||
|
" --crash-shell Run shell on crash\n"
|
||||||
|
" --confirm-spawn Ask for confirmation when spawning processes\n"
|
||||||
|
" --show-status Show status updates on the console during bootup\n"
|
||||||
" --log-target=TARGET Set log target (console, syslog, kmsg, syslog-or-kmsg, null)\n"
|
" --log-target=TARGET Set log target (console, syslog, kmsg, syslog-or-kmsg, null)\n"
|
||||||
|
" --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
|
||||||
" --log-color[=0|1] Highlight important log messages\n"
|
" --log-color[=0|1] Highlight important log messages\n"
|
||||||
" --log-location[=0|1] Include code location in log messages\n",
|
" --log-location[=0|1] Include code location in log messages\n",
|
||||||
program_invocation_short_name);
|
program_invocation_short_name);
|
||||||
@ -734,11 +771,14 @@ int main(int argc, char *argv[]) {
|
|||||||
loopback_setup();
|
loopback_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = manager_new(arg_running_as, arg_confirm_spawn, &m)) < 0) {
|
if ((r = manager_new(arg_running_as, &m)) < 0) {
|
||||||
log_error("Failed to allocate manager object: %s", strerror(-r));
|
log_error("Failed to allocate manager object: %s", strerror(-r));
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m->confirm_spawn = arg_confirm_spawn;
|
||||||
|
m->show_status = arg_show_status;
|
||||||
|
|
||||||
if ((r = manager_startup(m, serialization, fds)) < 0)
|
if ((r = manager_startup(m, serialization, fds)) < 0)
|
||||||
log_error("Failed to fully start up daemon: %s", strerror(-r));
|
log_error("Failed to fully start up daemon: %s", strerror(-r));
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ static int manager_setup_signals(Manager *m) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
|
int manager_new(ManagerRunningAs running_as, Manager **_m) {
|
||||||
Manager *m;
|
Manager *m;
|
||||||
int r = -ENOMEM;
|
int r = -ENOMEM;
|
||||||
char *p;
|
char *p;
|
||||||
@ -197,7 +197,6 @@ int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
|
|||||||
dual_timestamp_get(&m->startup_timestamp);
|
dual_timestamp_get(&m->startup_timestamp);
|
||||||
|
|
||||||
m->running_as = running_as;
|
m->running_as = running_as;
|
||||||
m->confirm_spawn = confirm_spawn;
|
|
||||||
m->name_data_slot = m->subscribed_data_slot = -1;
|
m->name_data_slot = m->subscribed_data_slot = -1;
|
||||||
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
|
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
|
||||||
m->pin_cgroupfs_fd = -1;
|
m->pin_cgroupfs_fd = -1;
|
||||||
@ -2336,6 +2335,22 @@ finish:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool manager_is_booting_or_shutting_down(Manager *m) {
|
||||||
|
Unit *u;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
/* Is the initial job still around? */
|
||||||
|
if (manager_get_job(m, 1))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* Is there a job for the shutdown target? */
|
||||||
|
if (((u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET))))
|
||||||
|
return !!u->meta.job;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
|
static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
|
||||||
[MANAGER_SYSTEM] = "system",
|
[MANAGER_SYSTEM] = "system",
|
||||||
[MANAGER_SESSION] = "session"
|
[MANAGER_SESSION] = "session"
|
||||||
|
@ -192,10 +192,11 @@ struct Manager {
|
|||||||
|
|
||||||
bool utmp_reboot_written:1;
|
bool utmp_reboot_written:1;
|
||||||
|
|
||||||
|
bool show_status;
|
||||||
bool confirm_spawn;
|
bool confirm_spawn;
|
||||||
};
|
};
|
||||||
|
|
||||||
int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **m);
|
int manager_new(ManagerRunningAs running_as, Manager **m);
|
||||||
void manager_free(Manager *m);
|
void manager_free(Manager *m);
|
||||||
|
|
||||||
int manager_enumerate(Manager *m);
|
int manager_enumerate(Manager *m);
|
||||||
@ -240,6 +241,8 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds);
|
|||||||
|
|
||||||
int manager_reload(Manager *m);
|
int manager_reload(Manager *m);
|
||||||
|
|
||||||
|
bool manager_is_booting_or_shutting_down(Manager *m);
|
||||||
|
|
||||||
const char *manager_running_as_to_string(ManagerRunningAs i);
|
const char *manager_running_as_to_string(ManagerRunningAs i);
|
||||||
ManagerRunningAs manager_running_as_from_string(const char *s);
|
ManagerRunningAs manager_running_as_from_string(const char *s);
|
||||||
|
|
||||||
|
@ -1548,6 +1548,7 @@ const UnitVTable mount_vtable = {
|
|||||||
.no_alias = true,
|
.no_alias = true,
|
||||||
.no_instances = true,
|
.no_instances = true,
|
||||||
.no_isolate = true,
|
.no_isolate = true,
|
||||||
|
.show_status = true,
|
||||||
|
|
||||||
.init = mount_init,
|
.init = mount_init,
|
||||||
.load = mount_load,
|
.load = mount_load,
|
||||||
|
@ -2671,6 +2671,7 @@ DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess);
|
|||||||
|
|
||||||
const UnitVTable service_vtable = {
|
const UnitVTable service_vtable = {
|
||||||
.suffix = ".service",
|
.suffix = ".service",
|
||||||
|
.show_status = true,
|
||||||
|
|
||||||
.init = service_init,
|
.init = service_init,
|
||||||
.done = service_done,
|
.done = service_done,
|
||||||
|
@ -547,6 +547,7 @@ const UnitVTable swap_vtable = {
|
|||||||
|
|
||||||
.no_instances = true,
|
.no_instances = true,
|
||||||
.no_isolate = true,
|
.no_isolate = true,
|
||||||
|
.show_status = true,
|
||||||
|
|
||||||
.init = swap_init,
|
.init = swap_init,
|
||||||
.load = swap_load,
|
.load = swap_load,
|
||||||
|
@ -33,7 +33,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
assert_se(set_unit_path("test2") >= 0);
|
assert_se(set_unit_path("test2") >= 0);
|
||||||
|
|
||||||
assert_se(manager_new(MANAGER_SYSTEM, false, &m) >= 0);
|
assert_se(manager_new(MANAGER_SYSTEM, &m) >= 0);
|
||||||
|
|
||||||
printf("Load1:\n");
|
printf("Load1:\n");
|
||||||
assert_se(manager_load_unit(m, "a.service", NULL, &a) >= 0);
|
assert_se(manager_load_unit(m, "a.service", NULL, &a) >= 0);
|
||||||
|
48
src/unit.c
48
src/unit.c
@ -776,6 +776,9 @@ int unit_start(Unit *u) {
|
|||||||
* before it will start again. */
|
* before it will start again. */
|
||||||
|
|
||||||
unit_add_to_dbus_queue(u);
|
unit_add_to_dbus_queue(u);
|
||||||
|
|
||||||
|
unit_status_printf(u, "Starting %s...\n", unit_description(u));
|
||||||
|
|
||||||
return UNIT_VTABLE(u)->start(u);
|
return UNIT_VTABLE(u)->start(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,6 +806,9 @@ int unit_stop(Unit *u) {
|
|||||||
return -EBADR;
|
return -EBADR;
|
||||||
|
|
||||||
unit_add_to_dbus_queue(u);
|
unit_add_to_dbus_queue(u);
|
||||||
|
|
||||||
|
unit_status_printf(u, "Stopping %s...\n", unit_description(u));
|
||||||
|
|
||||||
return UNIT_VTABLE(u)->stop(u);
|
return UNIT_VTABLE(u)->stop(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -939,7 +945,6 @@ static void retroactively_stop_dependencies(Unit *u) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
|
void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
|
||||||
bool unexpected = false;
|
|
||||||
dual_timestamp ts;
|
dual_timestamp ts;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
@ -969,6 +974,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
|
|||||||
path_unit_notify(u, ns);
|
path_unit_notify(u, ns);
|
||||||
|
|
||||||
if (u->meta.job) {
|
if (u->meta.job) {
|
||||||
|
bool unexpected = false;
|
||||||
|
|
||||||
if (u->meta.job->state == JOB_WAITING)
|
if (u->meta.job->state == JOB_WAITING)
|
||||||
|
|
||||||
@ -1028,16 +1034,17 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
|
|||||||
default:
|
default:
|
||||||
assert_not_reached("Job type unknown");
|
assert_not_reached("Job type unknown");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* If this state change happened without being requested by a
|
/* If this state change happened without being
|
||||||
* job, then let's retroactively start or stop dependencies */
|
* requested by a job, then let's retroactively start
|
||||||
|
* or stop dependencies */
|
||||||
|
|
||||||
if (unexpected) {
|
if (unexpected) {
|
||||||
if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
|
if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
|
||||||
retroactively_start_dependencies(u);
|
retroactively_start_dependencies(u);
|
||||||
else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
|
else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
|
||||||
retroactively_stop_dependencies(u);
|
retroactively_stop_dependencies(u);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some names are special */
|
/* Some names are special */
|
||||||
@ -1997,6 +2004,29 @@ int unit_coldplug(Unit *u) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unit_status_printf(Unit *u, const char *format, ...) {
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
assert(u);
|
||||||
|
assert(format);
|
||||||
|
|
||||||
|
if (!UNIT_VTABLE(u)->show_status)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (u->meta.manager->running_as != MANAGER_SYSTEM)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!u->meta.manager->show_status)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!manager_is_booting_or_shutting_down(u->meta.manager))
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
status_vprintf(format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
|
static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
|
||||||
[UNIT_SERVICE] = "service",
|
[UNIT_SERVICE] = "service",
|
||||||
[UNIT_TIMER] = "timer",
|
[UNIT_TIMER] = "timer",
|
||||||
|
@ -335,6 +335,9 @@ struct UnitVTable {
|
|||||||
|
|
||||||
/* Exclude from isolation requests */
|
/* Exclude from isolation requests */
|
||||||
bool no_isolate:1;
|
bool no_isolate:1;
|
||||||
|
|
||||||
|
/* Show status updates on the console */
|
||||||
|
bool show_status:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];
|
extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];
|
||||||
@ -459,6 +462,8 @@ int unit_add_node_link(Unit *u, const char *what, bool wants);
|
|||||||
|
|
||||||
int unit_coldplug(Unit *u);
|
int unit_coldplug(Unit *u);
|
||||||
|
|
||||||
|
void unit_status_printf(Unit *u, const char *format, ...);
|
||||||
|
|
||||||
const char *unit_type_to_string(UnitType i);
|
const char *unit_type_to_string(UnitType i);
|
||||||
UnitType unit_type_from_string(const char *s);
|
UnitType unit_type_from_string(const char *s);
|
||||||
|
|
||||||
|
24
src/util.c
24
src/util.c
@ -2627,6 +2627,30 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void status_vprintf(const char *format, va_list ap) {
|
||||||
|
char *s = NULL;
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
assert(format);
|
||||||
|
|
||||||
|
/* This independent of logging, as status messages are
|
||||||
|
* optional and go exclusively to the console. */
|
||||||
|
|
||||||
|
if (vasprintf(&s, format, ap) < 0)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
if ((fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
write(fd, s, strlen(s));
|
||||||
|
|
||||||
|
finish:
|
||||||
|
free(s);
|
||||||
|
|
||||||
|
if (fd >= 0)
|
||||||
|
close_nointr_nofail(fd);
|
||||||
|
}
|
||||||
|
|
||||||
static const char *const ioprio_class_table[] = {
|
static const char *const ioprio_class_table[] = {
|
||||||
[IOPRIO_CLASS_NONE] = "none",
|
[IOPRIO_CLASS_NONE] = "none",
|
||||||
[IOPRIO_CLASS_RT] = "realtime",
|
[IOPRIO_CLASS_RT] = "realtime",
|
||||||
|
@ -291,6 +291,8 @@ int rm_rf(const char *path, bool only_dirs, bool delete_root);
|
|||||||
|
|
||||||
cpu_set_t* cpu_set_malloc(unsigned *ncpus);
|
cpu_set_t* cpu_set_malloc(unsigned *ncpus);
|
||||||
|
|
||||||
|
void status_vprintf(const char *format, va_list ap);
|
||||||
|
|
||||||
const char *ioprio_class_to_string(int i);
|
const char *ioprio_class_to_string(int i);
|
||||||
int ioprio_class_from_string(const char *s);
|
int ioprio_class_from_string(const char *s);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user