1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/socket.h>
24 #include "sd-daemon.h"
30 #include "path-util.h"
33 #include "unit-name.h"
36 #include "bus-error.h"
37 #include "bus-message.h"
39 #include "bus-internal.h"
41 static int name_owner_change_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
42 sd_event *e = userdata;
54 int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
55 _cleanup_free_ char *match = NULL;
63 /* We unregister the name here and then wait for the
64 * NameOwnerChanged signal for this event to arrive before we
65 * quit. We do this in order to make sure that any queued
66 * requests are still processed before we really exit. */
68 r = sd_bus_get_unique_name(bus, &unique);
73 "sender='org.freedesktop.DBus',"
75 "interface='org.freedesktop.DBus',"
76 "member='NameOwnerChanged',"
77 "path='/org/freedesktop/DBus',"
80 "arg2=''", name, unique);
84 r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e);
88 r = sd_bus_release_name(bus, name);
95 int bus_event_loop_with_idle(
100 check_idle_t check_idle,
102 bool exiting = false;
112 r = sd_event_get_state(e);
115 if (r == SD_EVENT_FINISHED)
119 idle = check_idle(userdata);
123 r = sd_event_run(e, exiting || !idle ? (uint64_t) -1 : timeout);
127 if (r == 0 && !exiting && idle) {
129 r = sd_bus_try_close(bus);
133 /* Fallback for dbus1 connections: we
134 * unregister the name and wait for the
135 * response to come through for it */
136 if (r == -EOPNOTSUPP) {
138 /* Inform the service manager that we
139 * are going down, so that it will
140 * queue all further start requests,
141 * instead of assuming we are already
143 sd_notify(false, "STOPPING=1");
145 r = bus_async_unregister_and_exit(e, bus, name);
161 r = sd_event_get_exit_code(e, &code);
168 int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
169 _cleanup_bus_message_unref_ sd_bus_message *rep = NULL;
170 int r, has_owner = 0;
175 r = sd_bus_call_method(c,
176 "org.freedesktop.DBus",
177 "/org/freedesktop/dbus",
178 "org.freedesktop.DBus",
187 r = sd_bus_message_read_basic(rep, 'b', &has_owner);
189 return sd_bus_error_set_errno(error, r);
194 static int check_good_user(sd_bus_message *m, uid_t good_user) {
195 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
201 if (good_user == UID_INVALID)
204 r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds);
208 r = sd_bus_creds_get_euid(creds, &sender_uid);
212 return sender_uid == good_user;
216 sd_bus_message *call,
228 /* Tests non-interactively! */
230 r = check_good_user(call, good_user);
234 r = sd_bus_query_sender_privilege(call, capability);
241 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
242 int authorized = false, challenge = false;
245 sender = sd_bus_message_get_sender(call);
249 r = sd_bus_call_method(
251 "org.freedesktop.PolicyKit1",
252 "/org/freedesktop/PolicyKit1/Authority",
253 "org.freedesktop.PolicyKit1.Authority",
254 "CheckAuthorization",
258 "system-bus-name", 1, "name", "s", sender,
265 /* Treat no PK available as access denied */
266 if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
267 sd_bus_error_free(e);
274 r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
278 r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
286 *_challenge = challenge;
297 typedef struct AsyncPolkitQuery {
298 sd_bus_message *request, *reply;
299 sd_bus_message_handler_t callback;
305 static void async_polkit_query_free(AsyncPolkitQuery *q) {
310 sd_bus_slot_unref(q->slot);
312 if (q->registry && q->request)
313 hashmap_remove(q->registry, q->request);
315 sd_bus_message_unref(q->request);
316 sd_bus_message_unref(q->reply);
321 static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
322 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
323 AsyncPolkitQuery *q = userdata;
330 q->slot = sd_bus_slot_unref(q->slot);
331 q->reply = sd_bus_message_ref(reply);
333 r = sd_bus_message_rewind(q->request, true);
335 r = sd_bus_reply_method_errno(q->request, r, NULL);
339 r = q->callback(bus, q->request, q->userdata, &error_buffer);
340 r = bus_maybe_reply_error(q->request, r, &error_buffer);
343 async_polkit_query_free(q);
350 int bus_verify_polkit_async(
351 sd_bus_message *call,
357 sd_bus_error *error) {
360 _cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
363 sd_bus_message_handler_t callback;
373 r = check_good_user(call, good_user);
378 q = hashmap_get(*registry, call);
380 int authorized, challenge;
382 /* This is the second invocation of this function, and
383 * there's already a response from polkit, let's
387 if (sd_bus_message_is_method_error(q->reply, NULL)) {
388 const sd_bus_error *e;
390 /* Copy error from polkit reply */
391 e = sd_bus_message_get_error(q->reply);
392 sd_bus_error_copy(error, e);
394 /* Treat no PK available as access denied */
395 if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
398 return -sd_bus_error_get_errno(e);
401 r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
403 r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
412 return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
418 r = sd_bus_query_sender_privilege(call, capability);
425 if (sd_bus_get_current_message(call->bus) != call)
428 callback = sd_bus_get_current_handler(call->bus);
432 userdata = sd_bus_get_current_userdata(call->bus);
434 sender = sd_bus_message_get_sender(call);
438 c = sd_bus_message_get_allow_interactive_authorization(call);
444 r = hashmap_ensure_allocated(registry, NULL);
448 r = sd_bus_message_new_method_call(
451 "org.freedesktop.PolicyKit1",
452 "/org/freedesktop/PolicyKit1/Authority",
453 "org.freedesktop.PolicyKit1.Authority",
454 "CheckAuthorization");
458 r = sd_bus_message_append(
461 "system-bus-name", 1, "name", "s", sender,
469 q = new0(AsyncPolkitQuery, 1);
473 q->request = sd_bus_message_ref(call);
474 q->callback = callback;
475 q->userdata = userdata;
477 r = hashmap_put(*registry, call, q);
479 async_polkit_query_free(q);
483 q->registry = *registry;
485 r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
487 async_polkit_query_free(q);
497 void bus_verify_polkit_async_registry_free(Hashmap *registry) {
501 while ((q = hashmap_steal_first(registry)))
502 async_polkit_query_free(q);
504 hashmap_free(registry);
508 int bus_check_peercred(sd_bus *c) {
515 fd = sd_bus_get_fd(c);
519 l = sizeof(struct ucred);
520 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
523 if (l != sizeof(struct ucred))
526 if (ucred.uid != 0 && ucred.uid != geteuid())
532 int bus_open_system_systemd(sd_bus **_bus) {
533 _cleanup_bus_unref_ sd_bus *bus = NULL;
539 return sd_bus_open_system(_bus);
541 /* If we are root and kdbus is not available, then let's talk
542 * directly to the system instance, instead of going via the
546 r = sd_bus_new(&bus);
550 r = sd_bus_set_address(bus, KERNEL_SYSTEM_BUS_ADDRESS);
554 bus->bus_client = true;
556 r = sd_bus_start(bus);
563 bus = sd_bus_unref(bus);
566 r = sd_bus_new(&bus);
570 r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
574 r = sd_bus_start(bus);
576 return sd_bus_open_system(_bus);
578 r = bus_check_peercred(bus);
588 int bus_open_user_systemd(sd_bus **_bus) {
589 _cleanup_bus_unref_ sd_bus *bus = NULL;
590 _cleanup_free_ char *ee = NULL;
594 /* Try via kdbus first, and then directly */
599 r = sd_bus_new(&bus);
603 if (asprintf(&bus->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()) < 0)
606 bus->bus_client = true;
608 r = sd_bus_start(bus);
615 bus = sd_bus_unref(bus);
618 e = secure_getenv("XDG_RUNTIME_DIR");
620 return sd_bus_open_user(_bus);
622 ee = bus_address_escape(e);
626 r = sd_bus_new(&bus);
630 bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL);
634 r = sd_bus_start(bus);
636 return sd_bus_open_user(_bus);
638 r = bus_check_peercred(bus);
648 int bus_print_property(const char *name, sd_bus_message *property, bool all) {
650 const char *contents;
656 r = sd_bus_message_peek_type(property, &type, &contents);
662 case SD_BUS_TYPE_STRING: {
665 r = sd_bus_message_read_basic(property, type, &s);
669 if (all || !isempty(s)) {
670 _cleanup_free_ char *escaped = NULL;
672 escaped = xescape(s, "\n");
676 printf("%s=%s\n", name, escaped);
682 case SD_BUS_TYPE_BOOLEAN: {
685 r = sd_bus_message_read_basic(property, type, &b);
689 printf("%s=%s\n", name, yes_no(b));
694 case SD_BUS_TYPE_UINT64: {
697 r = sd_bus_message_read_basic(property, type, &u);
701 /* Yes, heuristics! But we can change this check
702 * should it turn out to not be sufficient */
704 if (endswith(name, "Timestamp")) {
705 char timestamp[FORMAT_TIMESTAMP_MAX], *t;
707 t = format_timestamp(timestamp, sizeof(timestamp), u);
709 printf("%s=%s\n", name, strempty(t));
711 } else if (strstr(name, "USec")) {
712 char timespan[FORMAT_TIMESPAN_MAX];
714 printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u, 0));
716 printf("%s=%llu\n", name, (unsigned long long) u);
721 case SD_BUS_TYPE_INT64: {
724 r = sd_bus_message_read_basic(property, type, &i);
728 printf("%s=%lld\n", name, (long long) i);
733 case SD_BUS_TYPE_UINT32: {
736 r = sd_bus_message_read_basic(property, type, &u);
740 if (strstr(name, "UMask") || strstr(name, "Mode"))
741 printf("%s=%04o\n", name, u);
743 printf("%s=%u\n", name, (unsigned) u);
748 case SD_BUS_TYPE_INT32: {
751 r = sd_bus_message_read_basic(property, type, &i);
755 printf("%s=%i\n", name, (int) i);
759 case SD_BUS_TYPE_DOUBLE: {
762 r = sd_bus_message_read_basic(property, type, &d);
766 printf("%s=%g\n", name, d);
770 case SD_BUS_TYPE_ARRAY:
771 if (streq(contents, "s")) {
775 r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
779 while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
780 _cleanup_free_ char *escaped = NULL;
785 escaped = xescape(str, "\n ");
789 printf("%s%s", first ? "" : " ", escaped);
801 r = sd_bus_message_exit_container(property);
807 } else if (streq(contents, "y")) {
811 r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
820 for (i = 0; i < n; i++)
821 printf("%02x", u[i]);
828 } else if (streq(contents, "u")) {
832 r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
841 for (i = 0; i < n; i++)
842 printf("%08x", u[i]);
856 int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) {
857 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
858 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
864 r = sd_bus_call_method(bus,
867 "org.freedesktop.DBus.Properties",
875 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
879 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
881 const char *contents;
883 r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
887 if (!filter || strv_find(filter, name)) {
888 r = sd_bus_message_peek_type(reply, NULL, &contents);
892 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
896 r = bus_print_property(name, reply, all);
901 printf("%s=[unprintable]\n", name);
902 /* skip what we didn't read */
903 r = sd_bus_message_skip(reply, contents);
908 r = sd_bus_message_exit_container(reply);
912 r = sd_bus_message_skip(reply, "v");
917 r = sd_bus_message_exit_container(reply);
924 r = sd_bus_message_exit_container(reply);
931 int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
932 sd_id128_t *p = userdata;
937 r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n);
944 memcpy((*p).bytes, v, n);
951 static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
955 r = sd_bus_message_peek_type(m, &type, NULL);
960 case SD_BUS_TYPE_STRING: {
964 r = sd_bus_message_read_basic(m, type, &s);
971 r = free_and_strdup(p, s);
975 case SD_BUS_TYPE_ARRAY: {
976 _cleanup_strv_free_ char **l = NULL;
977 char ***p = userdata;
979 r = bus_message_read_strv_extend(m, &l);
990 case SD_BUS_TYPE_BOOLEAN: {
994 r = sd_bus_message_read_basic(m, type, &b);
1003 case SD_BUS_TYPE_UINT32: {
1005 uint32_t *p = userdata;
1007 r = sd_bus_message_read_basic(m, type, &u);
1016 case SD_BUS_TYPE_UINT64: {
1018 uint64_t *p = userdata;
1020 r = sd_bus_message_read_basic(m, type, &t);
1036 int bus_message_map_all_properties(sd_bus *bus,
1038 const struct bus_properties_map *map,
1040 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1047 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
1051 while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1052 const struct bus_properties_map *prop;
1054 const char *contents;
1058 r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
1062 for (i = 0, prop = NULL; map[i].member; i++)
1063 if (streq(map[i].member, member)) {
1069 r = sd_bus_message_peek_type(m, NULL, &contents);
1073 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
1077 v = (uint8_t *)userdata + prop->offset;
1079 r = prop->set(bus, member, m, &error, v);
1081 r = map_basic(bus, member, m, &error, v);
1085 r = sd_bus_message_exit_container(m);
1089 r = sd_bus_message_skip(m, "v");
1094 r = sd_bus_message_exit_container(m);
1099 return sd_bus_message_exit_container(m);
1102 int bus_message_map_properties_changed(sd_bus *bus,
1104 const struct bus_properties_map *map,
1107 int r, invalidated, i;
1113 r = bus_message_map_all_properties(bus, m, map, userdata);
1117 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
1122 while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member)) > 0)
1123 for (i = 0; map[i].member; i++)
1124 if (streq(map[i].member, member)) {
1129 r = sd_bus_message_exit_container(m);
1136 int bus_map_all_properties(sd_bus *bus,
1137 const char *destination,
1139 const struct bus_properties_map *map,
1141 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1142 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1146 assert(destination);
1150 r = sd_bus_call_method(
1154 "org.freedesktop.DBus.Properties",
1162 return bus_message_map_all_properties(bus, m, map, userdata);
1165 int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1168 assert(transport >= 0);
1169 assert(transport < _BUS_TRANSPORT_MAX);
1172 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1173 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1175 switch (transport) {
1177 case BUS_TRANSPORT_LOCAL:
1179 r = sd_bus_default_user(bus);
1181 r = sd_bus_default_system(bus);
1185 case BUS_TRANSPORT_REMOTE:
1186 r = sd_bus_open_system_remote(bus, host);
1189 case BUS_TRANSPORT_MACHINE:
1190 r = sd_bus_open_system_machine(bus, host);
1194 assert_not_reached("Hmm, unknown transport type.");
1200 int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1203 assert(transport >= 0);
1204 assert(transport < _BUS_TRANSPORT_MAX);
1207 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1208 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1210 switch (transport) {
1212 case BUS_TRANSPORT_LOCAL:
1214 r = bus_open_user_systemd(bus);
1216 r = bus_open_system_systemd(bus);
1220 case BUS_TRANSPORT_REMOTE:
1221 r = sd_bus_open_system_remote(bus, host);
1224 case BUS_TRANSPORT_MACHINE:
1225 r = sd_bus_open_system_machine(bus, host);
1229 assert_not_reached("Hmm, unknown transport type.");
1235 int bus_property_get_bool(
1238 const char *interface,
1239 const char *property,
1240 sd_bus_message *reply,
1242 sd_bus_error *error) {
1244 int b = *(bool*) userdata;
1246 return sd_bus_message_append_basic(reply, 'b', &b);
1249 #if __SIZEOF_SIZE_T__ != 8
1250 int bus_property_get_size(
1253 const char *interface,
1254 const char *property,
1255 sd_bus_message *reply,
1257 sd_bus_error *error) {
1259 uint64_t sz = *(size_t*) userdata;
1261 return sd_bus_message_append_basic(reply, 't', &sz);
1265 #if __SIZEOF_LONG__ != 8
1266 int bus_property_get_long(
1269 const char *interface,
1270 const char *property,
1271 sd_bus_message *reply,
1273 sd_bus_error *error) {
1275 int64_t l = *(long*) userdata;
1277 return sd_bus_message_append_basic(reply, 'x', &l);
1280 int bus_property_get_ulong(
1283 const char *interface,
1284 const char *property,
1285 sd_bus_message *reply,
1287 sd_bus_error *error) {
1289 uint64_t ul = *(unsigned long*) userdata;
1291 return sd_bus_message_append_basic(reply, 't', &ul);
1295 int bus_log_parse_error(int r) {
1296 return log_error_errno(r, "Failed to parse bus message: %m");
1299 int bus_log_create_error(int r) {
1300 return log_error_errno(r, "Failed to create bus message: %m");
1303 int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
1309 return sd_bus_message_read(
1324 int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) {
1328 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1329 sd_bus_reply_method_errno(m, r, error);
1331 } else if (sd_bus_error_is_set(error)) {
1332 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1333 sd_bus_reply_method_error(m, error);
1337 log_debug("Failed to process message [type=%s sender=%s path=%s interface=%s member=%s signature=%s]: %s",
1338 bus_message_type_to_string(m->header->type),
1341 strna(m->interface),
1343 strna(m->root_container.signature),
1344 bus_error_message(error, r));
1349 int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
1350 const char *eq, *field;
1356 eq = strchr(assignment, '=');
1358 log_error("Not an assignment: %s", assignment);
1362 field = strndupa(assignment, eq - assignment);
1365 if (streq(field, "CPUQuota")) {
1369 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1371 return bus_log_create_error(r);
1373 r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
1375 } else if (endswith(eq, "%")) {
1378 if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
1379 log_error("CPU quota '%s' invalid.", eq);
1383 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1385 return bus_log_create_error(r);
1387 r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
1389 log_error("CPU quota needs to be in percent.");
1394 return bus_log_create_error(r);
1399 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1401 return bus_log_create_error(r);
1403 if (STR_IN_SET(field,
1404 "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
1405 "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies")) {
1407 r = parse_boolean(eq);
1409 log_error("Failed to parse boolean assignment %s.", assignment);
1413 r = sd_bus_message_append(m, "v", "b", r);
1415 } else if (streq(field, "MemoryLimit")) {
1418 r = parse_size(eq, 1024, &bytes);
1420 log_error("Failed to parse bytes specification %s", assignment);
1424 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
1426 } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
1429 r = safe_atou64(eq, &u);
1431 log_error("Failed to parse %s value %s.", field, eq);
1435 r = sd_bus_message_append(m, "v", "t", u);
1437 } else if (STR_IN_SET(field, "User", "Group", "DevicePolicy", "KillMode"))
1438 r = sd_bus_message_append(m, "v", "s", eq);
1440 else if (streq(field, "DeviceAllow")) {
1443 r = sd_bus_message_append(m, "v", "a(ss)", 0);
1445 const char *path, *rwm, *e;
1447 e = strchr(eq, ' ');
1449 path = strndupa(eq, e - eq);
1456 if (!path_startswith(path, "/dev")) {
1457 log_error("%s is not a device file in /dev.", path);
1461 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
1464 } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1467 r = sd_bus_message_append(m, "v", "a(st)", 0);
1469 const char *path, *bandwidth, *e;
1472 e = strchr(eq, ' ');
1474 path = strndupa(eq, e - eq);
1477 log_error("Failed to parse %s value %s.", field, eq);
1481 if (!path_startswith(path, "/dev")) {
1482 log_error("%s is not a device file in /dev.", path);
1486 r = parse_size(bandwidth, 1000, &bytes);
1488 log_error("Failed to parse byte value %s.", bandwidth);
1492 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
1495 } else if (streq(field, "BlockIODeviceWeight")) {
1498 r = sd_bus_message_append(m, "v", "a(st)", 0);
1500 const char *path, *weight, *e;
1503 e = strchr(eq, ' ');
1505 path = strndupa(eq, e - eq);
1508 log_error("Failed to parse %s value %s.", field, eq);
1512 if (!path_startswith(path, "/dev")) {
1513 log_error("%s is not a device file in /dev.", path);
1517 r = safe_atou64(weight, &u);
1519 log_error("Failed to parse %s value %s.", field, weight);
1522 r = sd_bus_message_append(m, "v", "a(st)", path, u);
1525 } else if (rlimit_from_string(field) >= 0) {
1528 if (streq(eq, "infinity"))
1531 r = safe_atou64(eq, &rl);
1533 log_error("Invalid resource limit: %s", eq);
1538 r = sd_bus_message_append(m, "v", "t", rl);
1540 } else if (streq(field, "Nice")) {
1543 r = safe_atoi32(eq, &i);
1545 log_error("Failed to parse %s value %s.", field, eq);
1549 r = sd_bus_message_append(m, "v", "i", i);
1551 } else if (streq(field, "Environment")) {
1553 r = sd_bus_message_append(m, "v", "as", 1, eq);
1555 } else if (streq(field, "KillSignal")) {
1558 sig = signal_from_string_try_harder(eq);
1560 log_error("Failed to parse %s value %s.", field, eq);
1564 r = sd_bus_message_append(m, "v", "i", sig);
1566 } else if (streq(field, "AccuracySec")) {
1569 r = parse_sec(eq, &u);
1571 log_error("Failed to parse %s value %s", field, eq);
1575 r = sd_bus_message_append(m, "v", "t", u);
1578 log_error("Unknown assignment %s.", assignment);
1583 return bus_log_create_error(r);
1588 typedef struct BusWaitForJobs {
1595 sd_bus_slot *slot_job_removed;
1596 sd_bus_slot *slot_disconnected;
1599 static int match_disconnected(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
1603 log_error("Warning! D-Bus connection terminated.");
1609 static int match_job_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
1610 const char *path, *unit, *result;
1611 BusWaitForJobs *d = userdata;
1620 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1622 bus_log_parse_error(r);
1626 found = set_remove(d->jobs, (char*) path);
1632 if (!isempty(result))
1633 d->result = strdup(result);
1636 d->name = strdup(unit);
1641 void bus_wait_for_jobs_free(BusWaitForJobs *d) {
1645 set_free_free(d->jobs);
1647 sd_bus_slot_unref(d->slot_disconnected);
1648 sd_bus_slot_unref(d->slot_job_removed);
1650 sd_bus_unref(d->bus);
1658 int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
1659 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
1665 d = new0(BusWaitForJobs, 1);
1669 d->bus = sd_bus_ref(bus);
1671 /* When we are a bus client we match by sender. Direct
1672 * connections OTOH have no initialized sender field, and
1673 * hence we ignore the sender then */
1674 r = sd_bus_add_match(
1676 &d->slot_job_removed,
1679 "sender='org.freedesktop.systemd1',"
1680 "interface='org.freedesktop.systemd1.Manager',"
1681 "member='JobRemoved',"
1682 "path='/org/freedesktop/systemd1'" :
1684 "interface='org.freedesktop.systemd1.Manager',"
1685 "member='JobRemoved',"
1686 "path='/org/freedesktop/systemd1'",
1687 match_job_removed, d);
1691 r = sd_bus_add_match(
1693 &d->slot_disconnected,
1695 "sender='org.freedesktop.DBus.Local',"
1696 "interface='org.freedesktop.DBus.Local',"
1697 "member='Disconnected'",
1698 match_disconnected, d);
1708 static int bus_process_wait(sd_bus *bus) {
1712 r = sd_bus_process(bus, NULL);
1718 r = sd_bus_wait(bus, (uint64_t) -1);
1724 static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
1725 _cleanup_free_ char *dbus_path = NULL;
1731 dbus_path = unit_dbus_path_from_name(d->name);
1735 return sd_bus_get_property_string(d->bus,
1736 "org.freedesktop.systemd1",
1738 "org.freedesktop.systemd1.Service",
1744 static const struct {
1745 const char *result, *explanation;
1746 } explanations [] = {
1747 { "resources", "configured resource limit was exceeded" },
1748 { "timeout", "timeout was exceeded" },
1749 { "exit-code", "control process exited with error code" },
1750 { "signal", "fatal signal was delivered to the control process" },
1751 { "core-dump", "fatal signal was delivered to the control process. Core dumped" },
1752 { "watchdog", "service failed to send watchdog ping" },
1753 { "start-limit", "start of the service was attempted too often too quickly" }
1756 static void log_job_error_with_service_result(const char* service, const char *result) {
1758 _cleanup_free_ char *service_shell_quoted = NULL;
1763 service_shell_quoted = shell_maybe_quote(service);
1765 for (i = 0; i < ELEMENTSOF(explanations); ++i)
1766 if (streq(result, explanations[i].result))
1769 if (i < ELEMENTSOF(explanations))
1770 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1772 explanations[i].explanation,
1773 strna(service_shell_quoted));
1775 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1777 strna(service_shell_quoted));
1779 /* For some results maybe additional explanation is required */
1780 if (streq_ptr(result, "start-limit"))
1781 log_info("To force a start please invoke \"systemctl reset-failed %s\" followed by \"systemctl start %s\" again.",
1782 strna(service_shell_quoted),
1783 strna(service_shell_quoted));
1786 static int check_wait_response(BusWaitForJobs *d, bool quiet) {
1792 if (streq(d->result, "canceled"))
1793 log_error("Job for %s canceled.", strna(d->name));
1794 else if (streq(d->result, "timeout"))
1795 log_error("Job for %s timed out.", strna(d->name));
1796 else if (streq(d->result, "dependency"))
1797 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
1798 else if (streq(d->result, "invalid"))
1799 log_error("Job for %s invalid.", strna(d->name));
1800 else if (streq(d->result, "assert"))
1801 log_error("Assertion failed on job for %s.", strna(d->name));
1802 else if (streq(d->result, "unsupported"))
1803 log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
1804 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
1807 _cleanup_free_ char *result = NULL;
1809 q = bus_job_get_service_result(d, &result);
1811 log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
1813 log_job_error_with_service_result(d->name, result);
1815 log_error("Job failed. See \"journalctl -xe\" for details.");
1819 if (streq(d->result, "canceled"))
1821 else if (streq(d->result, "timeout"))
1823 else if (streq(d->result, "dependency"))
1825 else if (streq(d->result, "invalid"))
1827 else if (streq(d->result, "assert"))
1829 else if (streq(d->result, "unsupported"))
1831 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1837 int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) {
1842 while (!set_isempty(d->jobs)) {
1845 q = bus_process_wait(d->bus);
1847 return log_error_errno(q, "Failed to wait for response: %m");
1850 q = check_wait_response(d, quiet);
1851 /* Return the first error as it is most likely to be
1853 if (q < 0 && r == 0)
1856 log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
1869 int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
1874 r = set_ensure_allocated(&d->jobs, &string_hash_ops);
1878 return set_put_strdup(d->jobs, path);
1881 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet) {
1882 const char *type, *path, *source;
1885 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1887 return bus_log_parse_error(r);
1889 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1891 if (streq(type, "symlink"))
1892 log_info("Created symlink from %s to %s.", path, source);
1894 log_info("Removed symlink %s.", path);
1898 return bus_log_parse_error(r);
1900 r = sd_bus_message_exit_container(m);
1902 return bus_log_parse_error(r);