From: Lennart Poettering Date: Tue, 2 Feb 2010 11:51:04 +0000 (+0100) Subject: Merge remote branch 'kay/master' X-Git-Tag: v1~732 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=0acb83e9e63206af9a2c6a35ca054453d235458a;hp=ef886c6ab86436f0d8b5128799a8f801c62d859a Merge remote branch 'kay/master' --- diff --git a/dbus-job.c b/dbus-job.c index 0ac11bc1f..fd84aa6ab 100644 --- a/dbus-job.c +++ b/dbus-job.c @@ -1,5 +1,7 @@ /*-*- Mode: C; c-basic-offset: 8 -*-*/ +#include + #include "dbus.h" #include "log.h" @@ -7,13 +9,99 @@ static const char introspection[] = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "" " " + " " + " " + " " + " " " " BUS_PROPERTIES_INTERFACE BUS_INTROSPECTABLE_INTERFACE ""; +static int bus_job_append_state(Manager *m, DBusMessageIter *i, const char *property, void *data) { + Job *j = data; + const char *state; + + assert(m); + assert(i); + assert(property); + assert(j); + + state = job_state_to_string(j->state); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int bus_job_append_type(Manager *m, DBusMessageIter *i, const char *property, void *data) { + Job *j = data; + const char *type; + + assert(m); + assert(i); + assert(property); + assert(j); + + type = job_type_to_string(j->type); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &type)) + return -ENOMEM; + + return 0; +} + +static int bus_job_append_unit(Manager *m, DBusMessageIter *i, const char *property, void *data) { + Job *j = data; + DBusMessageIter sub; + char *p; + const char *id; + + assert(m); + assert(i); + assert(property); + assert(j); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (!(p = unit_dbus_path(j->unit))) + return -ENOMEM; + + id = unit_id(j->unit); + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusMessage *message) { + + const BusProperty properties[] = { + { "org.freedesktop.systemd1.Job", "Id", bus_property_append_uint32, "u", &j->id }, + { "org.freedesktop.systemd1.Job", "State", bus_job_append_state, "s", j }, + { "org.freedesktop.systemd1.Job", "Type", bus_job_append_type, "s", j }, + { "org.freedesktop.systemd1.Job", "Unit", bus_job_append_unit, "(so)", j }, + { NULL, NULL, NULL, NULL, NULL } + }; + + return bus_default_message_handler(j->manager, message, introspection, properties); +} + DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { Manager *m = data; + Job *j; + int r; assert(connection); assert(message); @@ -24,7 +112,18 @@ DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBusMessa dbus_message_get_member(message), dbus_message_get_path(message)); - return bus_default_message_handler(m, message, introspection, NULL); + if ((r = manager_get_job_from_dbus_path(m, dbus_message_get_path(message), &j)) < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + return bus_send_error_reply(m, message, NULL, r); + } + + return bus_job_message_dispatch(j, message); } const DBusObjectPathVTable bus_job_vtable = { diff --git a/dbus-unit.c b/dbus-unit.c index d47408265..0bdf16202 100644 --- a/dbus-unit.c +++ b/dbus-unit.c @@ -14,6 +14,12 @@ static const char introspection[] = " " " " " " + " " + " " + " " + " " + " " + " " " " BUS_PROPERTIES_INTERFACE BUS_INTROSPECTABLE_INTERFACE @@ -87,13 +93,101 @@ static int bus_unit_append_active_state(Manager *m, DBusMessageIter *i, const ch return 0; } +static int bus_unit_append_can_reload(Manager *m, DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(m); + assert(i); + assert(property); + assert(u); + + b = unit_can_reload(u); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_can_start(Manager *m, DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(m); + assert(i); + assert(property); + assert(u); + + b = unit_can_start(u); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_job(Manager *m, DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + DBusMessageIter sub; + char *p; + + assert(m); + assert(i); + assert(property); + assert(u); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (u->meta.job) { + + if (!(p = job_dbus_path(u->meta.job))) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->meta.job->id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + } else { + uint32_t id = 0; + + /* No job, so let's fill in some placeholder + * data. Since we need to fill in a valid path we + * simple point to ourselves. */ + + if (!(p = unit_dbus_path(u))) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message) { const BusProperty properties[] = { - { "org.freedesktop.systemd1.Unit", "Id", bus_unit_append_id, "s", u }, - { "org.freedesktop.systemd1.Unit", "Description", bus_unit_append_description, "s", u }, - { "org.freedesktop.systemd1.Unit", "LoadState", bus_unit_append_load_state, "s", u }, - { "org.freedesktop.systemd1.Unit", "ActiveState", bus_unit_append_active_state, "s", u }, + { "org.freedesktop.systemd1.Unit", "Id", bus_unit_append_id, "s", u }, + { "org.freedesktop.systemd1.Unit", "Description", bus_unit_append_description, "s", u }, + { "org.freedesktop.systemd1.Unit", "LoadState", bus_unit_append_load_state, "s", u }, + { "org.freedesktop.systemd1.Unit", "ActiveState", bus_unit_append_active_state, "s", u }, + { "org.freedesktop.systemd1.Unit", "LoadPath", bus_property_append_string, "s", u->meta.load_path }, + { "org.freedesktop.systemd1.Unit", "ActiveEnterTimestamp", bus_property_append_uint64, "t", &u->meta.active_enter_timestamp }, + { "org.freedesktop.systemd1.Unit", "ActiveExitTimestamp", bus_property_append_uint64, "t", &u->meta.active_exit_timestamp }, + { "org.freedesktop.systemd1.Unit", "CanReload", bus_unit_append_can_reload, "b", u }, + { "org.freedesktop.systemd1.Unit", "CanStart", bus_unit_append_can_start, "b", u }, + { "org.freedesktop.systemd1.Unit", "Job", bus_unit_append_job, "(uo)", u }, { NULL, NULL, NULL, NULL, NULL } }; diff --git a/dbus.c b/dbus.c index 84b8fbf09..caafc9757 100644 --- a/dbus.c +++ b/dbus.c @@ -561,7 +561,9 @@ int bus_property_append_string(Manager *m, DBusMessageIter *i, const char *prope assert(m); assert(i); assert(property); - assert(t); + + if (!t) + t = ""; if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) return -ENOMEM; @@ -606,3 +608,27 @@ int bus_property_append_bool(Manager *m, DBusMessageIter *i, const char *propert return 0; } + +int bus_property_append_uint64(Manager *m, DBusMessageIter *i, const char *property, void *data) { + assert(m); + assert(i); + assert(property); + assert(data); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, data)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_uint32(Manager *m, DBusMessageIter *i, const char *property, void *data) { + assert(m); + assert(i); + assert(property); + assert(data); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, data)) + return -ENOMEM; + + return 0; +} diff --git a/dbus.h b/dbus.h index 6a769c916..51023b08b 100644 --- a/dbus.h +++ b/dbus.h @@ -52,6 +52,8 @@ DBusHandlerResult bus_send_error_reply(Manager *m, DBusMessage *message, DBusErr int bus_property_append_string(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_property_append_strv(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_property_append_bool(Manager *m, DBusMessageIter *i, const char *property, void *data); +int bus_property_append_uint32(Manager *m, DBusMessageIter *i, const char *property, void *data); +int bus_property_append_uint64(Manager *m, DBusMessageIter *i, const char *property, void *data); extern const DBusObjectPathVTable bus_manager_vtable; extern const DBusObjectPathVTable bus_job_vtable; diff --git a/execute.c b/execute.c index ae32bcada..65a7fbba1 100644 --- a/execute.c +++ b/execute.c @@ -347,7 +347,8 @@ int exec_spawn(const ExecCommand *command, const ExecContext *context, int *fds, zero(param); param.sched_priority = context->cpu_sched_priority; - if (sched_setscheduler(0, context->cpu_sched_policy, ¶m) < 0) { + if (sched_setscheduler(0, context->cpu_sched_policy | + (context->cpu_sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0), ¶m) < 0) { r = EXIT_SETSCHEDULER; goto fail; } @@ -563,9 +564,11 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { if (c->cpu_sched_set) fprintf(f, "%sCPUSchedulingPolicy: %s\n" - "%sCPUSchedulingPriority: %i\n", + "%sCPUSchedulingPriority: %i\n" + "%sCPUSchedulingResetOnFork: %s\n", prefix, sched_policy_to_string(c->cpu_sched_policy), - prefix, c->cpu_sched_priority); + prefix, c->cpu_sched_priority, + prefix, yes_no(c->cpu_sched_reset_on_fork)); if (c->cpu_affinity_set) { fprintf(f, "%sCPUAffinity:", prefix); diff --git a/execute.h b/execute.h index 09e436797..4f700efd4 100644 --- a/execute.h +++ b/execute.h @@ -70,6 +70,8 @@ struct ExecContext { bool cpu_affinity_set:1; bool timer_slack_ns_set:1; + bool cpu_sched_reset_on_fork; + ExecInput input; ExecOutput output; int syslog_priority; diff --git a/load-fragment.c b/load-fragment.c index 4bb1ef010..c271ce5a5 100644 --- a/load-fragment.c +++ b/load-fragment.c @@ -1024,6 +1024,7 @@ static int load_from_path(Unit *u, const char *path) { { "IOSchedulingPriority", config_parse_io_priority, &(context), section }, \ { "CPUSchedulingPolicy", config_parse_cpu_sched_policy,&(context), section }, \ { "CPUSchedulingPriority", config_parse_cpu_sched_prio, &(context), section }, \ + { "CPUSchedulingResetOnFork", config_parse_bool, &(context).cpu_sched_reset_on_fork, section }, \ { "CPUAffinity", config_parse_cpu_affinity, &(context), section }, \ { "UMask", config_parse_umask, &(context).umask, section }, \ { "Environment", config_parse_strv, &(context).environment, section }, \ diff --git a/manager.c b/manager.c index 3bbc85542..b574c6380 100644 --- a/manager.c +++ b/manager.c @@ -1257,3 +1257,26 @@ int manager_get_unit_from_dbus_path(Manager *m, const char *s, Unit **_u) { return 0; } + +int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) { + Job *j; + unsigned id; + int r; + + assert(m); + assert(s); + assert(_j); + + if (!startswith(s, "/org/freedesktop/systemd1/job/")) + return -EINVAL; + + if ((r = safe_atou(s + 30, &id)) < 0) + return r; + + if (!(j = manager_get_job(m, id))) + return -ENOENT; + + *_j = j; + + return 0; +} diff --git a/manager.h b/manager.h index c30bf765b..b2b93e9b4 100644 --- a/manager.h +++ b/manager.h @@ -109,6 +109,7 @@ Job *manager_get_job(Manager *m, uint32_t id); Unit *manager_get_unit(Manager *m, const char *name); int manager_get_unit_from_dbus_path(Manager *m, const char *s, Unit **_u); +int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j); int manager_load_unit(Manager *m, const char *path_or_name, Unit **_ret); int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool force, Job **_ret);