1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 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/>.
28 #include "sd-messages.h"
31 #include "path-util.h"
33 #include "fileio-label.h"
36 #include "unit-name.h"
38 #include "bus-common-errors.h"
39 #include "time-util.h"
40 #include "cgroup-util.h"
41 #include "machine-image.h"
42 #include "image-dbus.h"
44 #include "machine-dbus.h"
46 static int method_get_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
47 _cleanup_free_ char *p = NULL;
48 Manager *m = userdata;
57 r = sd_bus_message_read(message, "s", &name);
61 machine = hashmap_get(m->machines, name);
63 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
65 p = machine_bus_path(machine);
69 return sd_bus_reply_method_return(message, "o", p);
72 static int method_get_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
73 _cleanup_free_ char *p = NULL;
74 Manager *m = userdata;
82 r = sd_bus_message_read(message, "s", &name);
86 r = image_find(name, NULL);
88 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
92 p = image_bus_path(name);
96 return sd_bus_reply_method_return(message, "o", p);
99 static int method_get_machine_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
100 _cleanup_free_ char *p = NULL;
101 Manager *m = userdata;
102 Machine *machine = NULL;
110 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
112 r = sd_bus_message_read(message, "u", &pid);
117 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
119 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
123 r = sd_bus_creds_get_pid(creds, &pid);
128 r = manager_get_machine_by_pid(m, pid, &machine);
132 return sd_bus_error_setf(error, BUS_ERROR_NO_MACHINE_FOR_PID, "PID "PID_FMT" does not belong to any known machine", pid);
134 p = machine_bus_path(machine);
138 return sd_bus_reply_method_return(message, "o", p);
141 static int method_list_machines(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
142 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
143 Manager *m = userdata;
152 r = sd_bus_message_new_method_return(message, &reply);
154 return sd_bus_error_set_errno(error, r);
156 r = sd_bus_message_open_container(reply, 'a', "(ssso)");
158 return sd_bus_error_set_errno(error, r);
160 HASHMAP_FOREACH(machine, m->machines, i) {
161 _cleanup_free_ char *p = NULL;
163 p = machine_bus_path(machine);
167 r = sd_bus_message_append(reply, "(ssso)",
169 strempty(machine_class_to_string(machine->class)),
173 return sd_bus_error_set_errno(error, r);
176 r = sd_bus_message_close_container(reply);
178 return sd_bus_error_set_errno(error, r);
180 return sd_bus_send(bus, reply, NULL);
183 static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, bool read_network, Machine **_m, sd_bus_error *error) {
184 const char *name, *service, *class, *root_directory;
185 const int32_t *netif = NULL;
191 size_t n, n_netif = 0;
198 r = sd_bus_message_read(message, "s", &name);
201 if (!machine_name_is_valid(name))
202 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine name");
204 r = sd_bus_message_read_array(message, 'y', &v, &n);
212 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine ID parameter");
214 r = sd_bus_message_read(message, "ssus", &service, &class, &leader, &root_directory);
221 r = sd_bus_message_read_array(message, 'i', (const void**) &netif, &n_netif);
225 n_netif /= sizeof(int32_t);
227 for (i = 0; i < n_netif; i++) {
229 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid network interface index %i", netif[i]);
234 c = _MACHINE_CLASS_INVALID;
236 c = machine_class_from_string(class);
238 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine class parameter");
242 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
244 if (!isempty(root_directory) && !path_is_absolute(root_directory))
245 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root directory must be empty or an absolute path");
248 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
250 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
254 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
256 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
261 if (hashmap_get(manager->machines, name))
262 return sd_bus_error_setf(error, BUS_ERROR_MACHINE_EXISTS, "Machine '%s' already exists", name);
264 r = manager_add_machine(manager, name, &m);
272 if (!isempty(service)) {
273 m->service = strdup(service);
280 if (!isempty(root_directory)) {
281 m->root_directory = strdup(root_directory);
282 if (!m->root_directory) {
289 assert_cc(sizeof(int32_t) == sizeof(int));
290 m->netif = memdup(netif, sizeof(int32_t) * n_netif);
296 m->n_netif = n_netif;
304 machine_add_to_gc_queue(m);
308 static int method_create_machine_internal(sd_bus *bus, sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
309 Manager *manager = userdata;
313 r = method_create_or_register_machine(manager, message, read_network, &m, error);
317 r = sd_bus_message_enter_container(message, 'a', "(sv)");
321 r = machine_start(m, message, error);
325 m->create_message = sd_bus_message_ref(message);
329 machine_add_to_gc_queue(m);
333 static int method_create_machine_with_network(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
334 return method_create_machine_internal(bus, message, true, userdata, error);
337 static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
338 return method_create_machine_internal(bus, message, false, userdata, error);
341 static int method_register_machine_internal(sd_bus *bus, sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
342 Manager *manager = userdata;
343 _cleanup_free_ char *p = NULL;
347 r = method_create_or_register_machine(manager, message, read_network, &m, error);
351 r = cg_pid_get_unit(m->leader, &m->unit);
353 r = sd_bus_error_set_errnof(error, r, "Failed to determine unit of process "PID_FMT" : %s", m->leader, strerror(-r));
357 r = machine_start(m, NULL, error);
361 p = machine_bus_path(m);
367 return sd_bus_reply_method_return(message, "o", p);
370 machine_add_to_gc_queue(m);
374 static int method_register_machine_with_network(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
375 return method_register_machine_internal(bus, message, true, userdata, error);
378 static int method_register_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
379 return method_register_machine_internal(bus, message, false, userdata, error);
382 static int method_terminate_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
383 Manager *m = userdata;
392 r = sd_bus_message_read(message, "s", &name);
394 return sd_bus_error_set_errno(error, r);
396 machine = hashmap_get(m->machines, name);
398 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
400 return bus_machine_method_terminate(bus, message, machine, error);
403 static int method_kill_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
404 Manager *m = userdata;
413 r = sd_bus_message_read(message, "s", &name);
415 return sd_bus_error_set_errno(error, r);
417 machine = hashmap_get(m->machines, name);
419 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
421 return bus_machine_method_kill(bus, message, machine, error);
424 static int method_get_machine_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
425 Manager *m = userdata;
434 r = sd_bus_message_read(message, "s", &name);
436 return sd_bus_error_set_errno(error, r);
438 machine = hashmap_get(m->machines, name);
440 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
442 return bus_machine_method_get_addresses(bus, message, machine, error);
445 static int method_get_machine_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
446 Manager *m = userdata;
455 r = sd_bus_message_read(message, "s", &name);
457 return sd_bus_error_set_errno(error, r);
459 machine = hashmap_get(m->machines, name);
461 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
463 return bus_machine_method_get_os_release(bus, message, machine, error);
466 static int method_list_images(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
467 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
468 _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
469 Manager *m = userdata;
478 images = hashmap_new(&string_hash_ops);
482 r = image_discover(images);
486 r = sd_bus_message_new_method_return(message, &reply);
490 r = sd_bus_message_open_container(reply, 'a', "(ssbttto)");
494 HASHMAP_FOREACH(image, images, i) {
495 _cleanup_free_ char *p = NULL;
497 p = image_bus_path(image->name);
501 r = sd_bus_message_append(reply, "(ssbttto)",
503 image_type_to_string(image->type),
513 r = sd_bus_message_close_container(reply);
517 return sd_bus_send(bus, reply, NULL);
520 static int method_open_machine_pty(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
521 Manager *m = userdata;
530 r = sd_bus_message_read(message, "s", &name);
532 return sd_bus_error_set_errno(error, r);
534 machine = hashmap_get(m->machines, name);
536 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
538 return bus_machine_method_open_pty(bus, message, machine, error);
541 static int method_open_machine_login(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
542 Manager *m = userdata;
551 r = sd_bus_message_read(message, "s", &name);
555 machine = hashmap_get(m->machines, name);
557 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
559 return bus_machine_method_open_login(bus, message, machine, error);
562 static int method_bind_mount_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
563 Manager *m = userdata;
572 r = sd_bus_message_read(message, "s", &name);
576 machine = hashmap_get(m->machines, name);
578 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
580 return bus_machine_method_bind_mount(bus, message, machine, error);
583 static int method_copy_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
584 Manager *m = userdata;
593 r = sd_bus_message_read(message, "s", &name);
597 machine = hashmap_get(m->machines, name);
599 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
601 return bus_machine_method_copy(bus, message, machine, error);
604 static int method_remove_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
605 _cleanup_(image_unrefp) Image* i = NULL;
612 r = sd_bus_message_read(message, "s", &name);
616 if (!image_name_is_valid(name))
617 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
619 r = image_find(name, &i);
623 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
625 i->userdata = userdata;
626 return bus_image_method_remove(bus, message, i, error);
629 static int method_rename_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
630 _cleanup_(image_unrefp) Image* i = NULL;
631 const char *old_name;
637 r = sd_bus_message_read(message, "s", &old_name);
641 if (!image_name_is_valid(old_name))
642 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name);
644 r = image_find(old_name, &i);
648 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", old_name);
650 i->userdata = userdata;
651 return bus_image_method_rename(bus, message, i, error);
654 static int method_clone_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
655 _cleanup_(image_unrefp) Image *i = NULL;
656 const char *old_name;
660 r = sd_bus_message_read(message, "s", &old_name);
664 if (!image_name_is_valid(old_name))
665 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name);
667 r = image_find(old_name, &i);
671 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", old_name);
673 i->userdata = userdata;
674 return bus_image_method_clone(bus, message, i, error);
677 static int method_mark_image_read_only(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
678 _cleanup_(image_unrefp) Image *i = NULL;
683 r = sd_bus_message_read(message, "s", &name);
687 if (!image_name_is_valid(name))
688 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
690 r = image_find(name, &i);
694 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
696 i->userdata = userdata;
697 return bus_image_method_mark_read_only(bus, message, i, error);
700 const sd_bus_vtable manager_vtable[] = {
701 SD_BUS_VTABLE_START(0),
702 SD_BUS_METHOD("GetMachine", "s", "o", method_get_machine, SD_BUS_VTABLE_UNPRIVILEGED),
703 SD_BUS_METHOD("GetImage", "s", "o", method_get_image, SD_BUS_VTABLE_UNPRIVILEGED),
704 SD_BUS_METHOD("GetMachineByPID", "u", "o", method_get_machine_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
705 SD_BUS_METHOD("ListMachines", NULL, "a(ssso)", method_list_machines, SD_BUS_VTABLE_UNPRIVILEGED),
706 SD_BUS_METHOD("ListImages", NULL, "a(ssbttto)", method_list_images, SD_BUS_VTABLE_UNPRIVILEGED),
707 SD_BUS_METHOD("CreateMachine", "sayssusa(sv)", "o", method_create_machine, 0),
708 SD_BUS_METHOD("CreateMachineWithNetwork", "sayssusaia(sv)", "o", method_create_machine_with_network, 0),
709 SD_BUS_METHOD("RegisterMachine", "sayssus", "o", method_register_machine, 0),
710 SD_BUS_METHOD("RegisterMachineWithNetwork", "sayssusai", "o", method_register_machine_with_network, 0),
711 SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, SD_BUS_VTABLE_UNPRIVILEGED),
712 SD_BUS_METHOD("KillMachine", "ssi", NULL, method_kill_machine, SD_BUS_VTABLE_UNPRIVILEGED),
713 SD_BUS_METHOD("GetMachineAddresses", "s", "a(iay)", method_get_machine_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
714 SD_BUS_METHOD("GetMachineOSRelease", "s", "a{ss}", method_get_machine_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
715 SD_BUS_METHOD("OpenMachinePTY", "s", "hs", method_open_machine_pty, 0),
716 SD_BUS_METHOD("OpenMachineLogin", "s", "hs", method_open_machine_login, SD_BUS_VTABLE_UNPRIVILEGED),
717 SD_BUS_METHOD("BindMountMachine", "sssbb", NULL, method_bind_mount_machine, SD_BUS_VTABLE_UNPRIVILEGED),
718 SD_BUS_METHOD("CopyFromMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
719 SD_BUS_METHOD("CopyToMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
720 SD_BUS_METHOD("RemoveImage", "s", NULL, method_remove_image, SD_BUS_VTABLE_UNPRIVILEGED),
721 SD_BUS_METHOD("RenameImage", "ss", NULL, method_rename_image, SD_BUS_VTABLE_UNPRIVILEGED),
722 SD_BUS_METHOD("CloneImage", "ssb", NULL, method_clone_image, SD_BUS_VTABLE_UNPRIVILEGED),
723 SD_BUS_METHOD("MarkImageReadOnly", "sb", NULL, method_mark_image_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
724 SD_BUS_SIGNAL("MachineNew", "so", 0),
725 SD_BUS_SIGNAL("MachineRemoved", "so", 0),
729 int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
730 const char *path, *result, *unit;
731 Manager *m = userdata;
740 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
742 bus_log_parse_error(r);
746 machine = hashmap_get(m->machine_units, unit);
750 if (streq_ptr(path, machine->scope_job)) {
751 free(machine->scope_job);
752 machine->scope_job = NULL;
754 if (machine->started) {
755 if (streq(result, "done"))
756 machine_send_create_reply(machine, NULL);
758 _cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
760 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
762 machine_send_create_reply(machine, &e);
765 machine_save(machine);
768 machine_add_to_gc_queue(machine);
772 int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
773 _cleanup_free_ char *unit = NULL;
774 Manager *m = userdata;
783 path = sd_bus_message_get_path(message);
787 r = unit_name_from_dbus_path(path, &unit);
788 if (r == -EINVAL) /* not for a unit */
793 machine = hashmap_get(m->machine_units, unit);
795 machine_add_to_gc_queue(machine);
800 int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
801 const char *path, *unit;
802 Manager *m = userdata;
810 r = sd_bus_message_read(message, "so", &unit, &path);
812 bus_log_parse_error(r);
816 machine = hashmap_get(m->machine_units, unit);
818 machine_add_to_gc_queue(machine);
823 int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
824 Manager *m = userdata;
831 r = sd_bus_message_read(message, "b", &b);
833 bus_log_parse_error(r);
839 /* systemd finished reloading, let's recheck all our machines */
840 log_debug("System manager has been reloaded, rechecking machines...");
842 HASHMAP_FOREACH(machine, m->machines, i)
843 machine_add_to_gc_queue(machine);
848 int manager_start_scope(
853 const char *description,
854 sd_bus_message *more_properties,
858 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
865 r = sd_bus_message_new_method_call(
868 "org.freedesktop.systemd1",
869 "/org/freedesktop/systemd1",
870 "org.freedesktop.systemd1.Manager",
871 "StartTransientUnit");
875 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
879 r = sd_bus_message_open_container(m, 'a', "(sv)");
883 if (!isempty(slice)) {
884 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
889 if (!isempty(description)) {
890 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
895 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
899 r = sd_bus_message_append(m, "(sv)", "Delegate", "b", 1);
903 if (more_properties) {
904 r = sd_bus_message_copy(m, more_properties, true);
909 r = sd_bus_message_close_container(m);
913 r = sd_bus_message_append(m, "a(sa(sv))", 0);
917 r = sd_bus_call(manager->bus, m, 0, error, &reply);
925 r = sd_bus_message_read(reply, "o", &j);
939 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
940 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
946 r = sd_bus_call_method(
948 "org.freedesktop.systemd1",
949 "/org/freedesktop/systemd1",
950 "org.freedesktop.systemd1.Manager",
956 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
957 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
962 sd_bus_error_free(error);
973 r = sd_bus_message_read(reply, "o", &j);
987 int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error) {
991 return sd_bus_call_method(
993 "org.freedesktop.systemd1",
994 "/org/freedesktop/systemd1",
995 "org.freedesktop.systemd1.Manager",
999 "ssi", unit, "all", signo);
1002 int manager_unit_is_active(Manager *manager, const char *unit) {
1003 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1004 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1005 _cleanup_free_ char *path = NULL;
1012 path = unit_dbus_path_from_name(unit);
1016 r = sd_bus_get_property(
1018 "org.freedesktop.systemd1",
1020 "org.freedesktop.systemd1.Unit",
1026 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
1027 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
1030 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
1031 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
1037 r = sd_bus_message_read(reply, "s", &state);
1041 return !streq(state, "inactive") && !streq(state, "failed");
1044 int manager_job_is_active(Manager *manager, const char *path) {
1045 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1046 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1052 r = sd_bus_get_property(
1054 "org.freedesktop.systemd1",
1056 "org.freedesktop.systemd1.Job",
1062 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
1063 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
1066 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
1072 /* We don't actually care about the state really. The fact
1073 * that we could read the job state is enough for us */
1078 int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) {
1079 _cleanup_free_ char *unit = NULL;
1087 r = cg_pid_get_unit(pid, &unit);
1089 mm = hashmap_get(m->machine_leaders, UINT_TO_PTR(pid));
1091 mm = hashmap_get(m->machine_units, unit);
1100 int manager_add_machine(Manager *m, const char *name, Machine **_machine) {
1106 machine = hashmap_get(m->machines, name);
1108 machine = machine_new(m, name);
1114 *_machine = machine;