static int connect_bus(void) { int r; sd_bus *bus = NULL; struct source_ctx *s; r = sd_bus_default_system(&bus); SOL_INT_CHECK(r, < 0, r); s = sol_mainloop_source_get_data(_ctx.mainloop_source); r = sd_bus_attach_event(bus, s->event, SD_EVENT_PRIORITY_NORMAL); SOL_INT_CHECK_GOTO(r, < 0, fail); r = sd_bus_add_match(bus, NULL, "type='signal'," "sender='org.freedesktop.DBus.Local'," "interface='org.freedesktop.DBus.Local'," "member='Disconnected'", _match_disconnected, &_ctx); SOL_INT_CHECK_GOTO(r, < 0, fail); _ctx.bus = bus; return 0; fail: sd_bus_unref(bus); return r; }
static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; assert(c); assert(event); assert(_bus); r = sd_bus_default_system(&bus); if (r < 0) return log_error_errno(r, "Failed to get system bus connection: %m"); r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/hostname1", "org.freedesktop.hostname1", hostname_vtable, c); if (r < 0) return log_error_errno(r, "Failed to register object: %m"); r = sd_bus_request_name(bus, "org.freedesktop.hostname1", 0); if (r < 0) return log_error_errno(r, "Failed to register name: %m"); r = sd_bus_attach_event(bus, event, 0); if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop: %m"); *_bus = bus; bus = NULL; return 0; }
int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) { int r; assert(transport >= 0); assert(transport < _BUS_TRANSPORT_MAX); assert(bus); assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL); assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -ENOTSUP); switch (transport) { case BUS_TRANSPORT_LOCAL: if (user) r = sd_bus_default_user(bus); else r = sd_bus_default_system(bus); break; case BUS_TRANSPORT_REMOTE: r = sd_bus_open_system_remote(bus, host); break; case BUS_TRANSPORT_CONTAINER: r = sd_bus_open_system_container(bus, host); break; default: assert_not_reached("Hmm, unknown transport type."); } return r; }
int manager_new(Manager **ret) { _cleanup_manager_free_ Manager *m = NULL; int r; m = new0(Manager, 1); if (!m) return -ENOMEM; r = sd_event_default(&m->event); if (r < 0) return r; sd_event_set_watchdog(m->event, true); r = sd_rtnl_open(&m->rtnl, RTMGRP_LINK | RTMGRP_IPV4_IFADDR); if (r < 0) return r; r = sd_bus_default_system(&m->bus); if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */ return r; r = setup_signals(m); if (r < 0) return r; m->udev = udev_new(); if (!m->udev) return -ENOMEM; /* udev does not initialize devices inside containers, * so we rely on them being already initialized before * entering the container */ if (detect_container(NULL) > 0) { m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "kernel"); if (!m->udev_monitor) return -ENOMEM; } else { m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); if (!m->udev_monitor) return -ENOMEM; } m->links = hashmap_new(uint64_hash_func, uint64_compare_func); if (!m->links) return -ENOMEM; m->netdevs = hashmap_new(string_hash_func, string_compare_func); if (!m->netdevs) return -ENOMEM; LIST_HEAD_INIT(m->networks); *ret = m; m = NULL; return 0; }
int manager_new(Manager **ret) { _cleanup_manager_free_ Manager *m = NULL; int r; m = new0(Manager, 1); if (!m) return -ENOMEM; r = sd_event_default(&m->event); if (r < 0) return r; sd_event_set_watchdog(m->event, true); r = sd_rtnl_open(RTMGRP_LINK | RTMGRP_IPV4_IFADDR, &m->rtnl); if (r < 0) return r; r = sd_bus_default_system(&m->bus); if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */ return r; m->udev = udev_new(); if (!m->udev) return -ENOMEM; m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); if (!m->udev_monitor) return -ENOMEM; m->links = hashmap_new(uint64_hash_func, uint64_compare_func); if (!m->links) return -ENOMEM; m->bridges = hashmap_new(string_hash_func, string_compare_func); if (!m->bridges) return -ENOMEM; LIST_HEAD_INIT(m->networks); *ret = m; m = NULL; return 0; }
static int manager_connect_bus(Manager *m) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; assert(m); assert(!m->bus); r = sd_bus_default_system(&m->bus); if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m); if (r < 0) return log_error_errno(r, "Failed to add manager object vtable: %m"); r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m); if (r < 0) return log_error_errno(r, "Failed to add machine object vtable: %m"); r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/machine", machine_node_enumerator, m); if (r < 0) return log_error_errno(r, "Failed to add machine enumerator: %m"); r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/image", "org.freedesktop.machine1.Image", image_vtable, image_object_find, m); if (r < 0) return log_error_errno(r, "Failed to add image object vtable: %m"); r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/image", image_node_enumerator, m); if (r < 0) return log_error_errno(r, "Failed to add image enumerator: %m"); r = sd_bus_add_match(m->bus, NULL, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.systemd1.Manager'," "member='JobRemoved'," "path='/org/freedesktop/systemd1'", match_job_removed, m); if (r < 0) return log_error_errno(r, "Failed to add match for JobRemoved: %m"); r = sd_bus_add_match(m->bus, NULL, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.systemd1.Manager'," "member='UnitRemoved'," "path='/org/freedesktop/systemd1'", match_unit_removed, m); if (r < 0) return log_error_errno(r, "Failed to add match for UnitRemoved: %m"); r = sd_bus_add_match(m->bus, NULL, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'," "arg0='org.freedesktop.systemd1.Unit'", match_properties_changed, m); if (r < 0) return log_error_errno(r, "Failed to add match for PropertiesChanged: %m"); r = sd_bus_add_match(m->bus, NULL, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.systemd1.Manager'," "member='Reloading'," "path='/org/freedesktop/systemd1'", match_reloading, m); if (r < 0) return log_error_errno(r, "Failed to add match for Reloading: %m"); r = sd_bus_call_method( m->bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Subscribe", &error, NULL, NULL); if (r < 0) { log_error("Failed to enable subscription: %s", bus_error_message(&error, r)); return r; } r = sd_bus_request_name(m->bus, "org.freedesktop.machine1", 0); if (r < 0) return log_error_errno(r, "Failed to register name: %m"); r = sd_bus_attach_event(m->bus, m->event, 0); if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop: %m"); return 0; }
int main(int argc, char *argv[]) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_close_unref_ sd_bus *bus = NULL; int r; log_parse_environment(); log_open(); r = parse_argv(argc, argv); if (r < 0) return EXIT_FAILURE; if (r == 0) return EXIT_SUCCESS; r = sd_bus_default_system(&bus); if (r < 0) { log_error("Failed to connect to bus: %s", strerror(-r)); return EXIT_FAILURE; } if (arg_action == ACTION_LIST) { r = print_inhibitors(bus, &error); if (r < 0) { log_error("Failed to list inhibitors: %s", bus_error_message(&error, -r)); return EXIT_FAILURE; } } else { _cleanup_close_ int fd = -1; _cleanup_free_ char *w = NULL; pid_t pid; if (!arg_who) arg_who = w = strv_join(argv + optind, " "); fd = inhibit(bus, &error); if (fd < 0) { log_error("Failed to inhibit: %s", bus_error_message(&error, -r)); return EXIT_FAILURE; } pid = fork(); if (pid < 0) { log_error("Failed to fork: %m"); return EXIT_FAILURE; } if (pid == 0) { /* Child */ close_all_fds(NULL, 0); execvp(argv[optind], argv + optind); log_error("Failed to execute %s: %m", argv[optind]); _exit(EXIT_FAILURE); } r = wait_for_terminate_and_warn(argv[optind], pid); return r < 0 ? EXIT_FAILURE : r; } return 0; }
int main(int argc, char *argv[]) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *copy = NULL; int r, boolean; const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature; uint8_t u, v; void *buffer = NULL; size_t sz; char *h; const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array; char *s; _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL; _cleanup_fclose_ FILE *ms = NULL; size_t first_size = 0, second_size = 0, third_size = 0; _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; double dbl; uint64_t u64; r = sd_bus_default_system(&bus); if (r < 0) return EXIT_TEST_SKIP; r = sd_bus_message_new_method_call(bus, &m, "foobar.waldo", "/", "foobar.waldo", "Piep"); assert_se(r >= 0); r = sd_bus_message_append(m, ""); assert_se(r >= 0); r = sd_bus_message_append(m, "s", "a string"); assert_se(r >= 0); r = sd_bus_message_append(m, "s", NULL); assert_se(r >= 0); r = sd_bus_message_append(m, "asg", 2, "string #1", "string #2", "sba(tt)ss"); assert_se(r >= 0); r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after"); assert_se(r >= 0); r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo"); assert_se(r >= 0); r = sd_bus_message_append(m, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10); assert_se(r >= 0); r = sd_bus_message_append(m, "()"); assert_se(r >= 0); r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3"); assert_se(r >= 0); r = sd_bus_message_open_container(m, 'a', "s"); assert_se(r >= 0); r = sd_bus_message_append_basic(m, 's', "foobar"); assert_se(r >= 0); r = sd_bus_message_append_basic(m, 's', "waldo"); assert_se(r >= 0); r = sd_bus_message_close_container(m); assert_se(r >= 0); r = sd_bus_message_append_string_space(m, 5, &s); assert_se(r >= 0); strcpy(s, "hallo"); r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array)); assert_se(r >= 0); r = sd_bus_message_append_array(m, 'u', NULL, 0); assert_se(r >= 0); r = sd_bus_message_append(m, "a(stdo)", 1, "foo", 815ULL, 47.0, "/"); assert_se(r >= 0); r = bus_message_seal(m, 4711, 0); assert_se(r >= 0); bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER); ms = open_memstream(&first, &first_size); bus_message_dump(m, ms, 0); fflush(ms); assert_se(!ferror(ms)); r = bus_message_get_blob(m, &buffer, &sz); assert_se(r >= 0); h = hexmem(buffer, sz); assert_se(h); log_info("message size = %zu, contents =\n%s", sz, h); free(h); #ifdef HAVE_GLIB { GDBusMessage *g; char *p; #if !defined(GLIB_VERSION_2_36) g_type_init(); #endif g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL); p = g_dbus_message_print(g, 0); log_info("%s", p); g_free(p); g_object_unref(g); } #endif #ifdef HAVE_DBUS { DBusMessage *w; DBusError error; dbus_error_init(&error); w = dbus_message_demarshal(buffer, sz, &error); if (!w) log_error("%s", error.message); else dbus_message_unref(w); dbus_error_free(&error); } #endif m = sd_bus_message_unref(m); r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, &m); assert_se(r >= 0); bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER); fclose(ms); ms = open_memstream(&second, &second_size); bus_message_dump(m, ms, 0); fflush(ms); assert_se(!ferror(ms)); assert_se(first_size == second_size); assert_se(memcmp(first, second, first_size) == 0); assert_se(sd_bus_message_rewind(m, true) >= 0); r = sd_bus_message_read(m, "ssasg", &x, &x2, 2, &y, &z, &a_signature); assert_se(r > 0); assert_se(streq(x, "a string")); assert_se(streq(x2, "")); assert_se(streq(y, "string #1")); assert_se(streq(z, "string #2")); assert_se(streq(a_signature, "sba(tt)ss")); r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d); assert_se(r > 0); assert_se(streq(x, "foobar")); assert_se(streq(y, "foo")); assert_se(streq(z, "bar")); assert_se(streq(a, "waldo")); assert_se(streq(b, "piep")); assert_se(streq(c, "pap")); assert_se(streq(d, "after")); r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y); assert_se(r > 0); assert_se(u == 3); assert_se(streq(x, "foo")); assert_se(v == 5); assert_se(streq(y, "waldo")); r = sd_bus_message_read(m, "y(ty)", &v, &u64, &u); assert_se(r > 0); assert_se(v == 8); assert_se(u64 == 777); assert_se(u == 7); r = sd_bus_message_read(m, "y(yt)", &v, &u, &u64); assert_se(r > 0); assert_se(v == 9); assert_se(u == 77); assert_se(u64 == 7777); r = sd_bus_message_read(m, "y", &v); assert_se(r > 0); assert_se(v == 10); r = sd_bus_message_read(m, "()"); assert_se(r > 0); r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d); assert_se(r > 0); assert_se(boolean); assert_se(streq(x, "aaa")); assert_se(streq(y, "1")); assert_se(streq(a, "bbb")); assert_se(streq(b, "2")); assert_se(streq(c, "ccc")); assert_se(streq(d, "3")); assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0); r = sd_bus_message_read(m, "as", 2, &x, &y); assert_se(r > 0); assert_se(streq(x, "foobar")); assert_se(streq(y, "waldo")); r = sd_bus_message_read_basic(m, 's', &s); assert_se(r > 0); assert_se(streq(s, "hallo")); r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz); assert_se(r > 0); assert_se(sz == sizeof(integer_array)); assert_se(memcmp(integer_array, return_array, sz) == 0); r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz); assert_se(r > 0); assert_se(sz == 0); r = sd_bus_message_read(m, "a(stdo)", 1, &x, &u64, &dbl, &y); assert_se(r > 0); assert_se(streq(x, "foo")); assert_se(u64 == 815ULL); assert_se(fabs(dbl - 47.0) < 0.1); assert_se(streq(y, "/")); r = sd_bus_message_peek_type(m, NULL, NULL); assert_se(r == 0); r = sd_bus_message_new_method_call(bus, ©, "foobar.waldo", "/", "foobar.waldo", "Piep"); assert_se(r >= 0); r = sd_bus_message_rewind(m, true); assert_se(r >= 0); r = sd_bus_message_copy(copy, m, true); assert_se(r >= 0); r = bus_message_seal(copy, 4712, 0); assert_se(r >= 0); fclose(ms); ms = open_memstream(&third, &third_size); bus_message_dump(copy, ms, 0); fflush(ms); assert_se(!ferror(ms)); printf("<%.*s>\n", (int) first_size, first); printf("<%.*s>\n", (int) third_size, third); assert_se(first_size == third_size); assert_se(memcmp(first, third, third_size) == 0); r = sd_bus_message_rewind(m, true); assert_se(r >= 0); assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0); r = sd_bus_message_skip(m, "ssasg"); assert_se(r > 0); assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0); r = sd_bus_message_skip(m, "sass"); assert_se(r >= 0); assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0); r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()"); assert_se(r >= 0); assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0); r = sd_bus_message_read(m, "b", &boolean); assert_se(r > 0); assert_se(boolean); r = sd_bus_message_enter_container(m, 0, NULL); assert_se(r > 0); r = sd_bus_message_read(m, "(ss)", &x, &y); assert_se(r > 0); r = sd_bus_message_read(m, "(ss)", &a, &b); assert_se(r > 0); r = sd_bus_message_read(m, "(ss)", &c, &d); assert_se(r > 0); r = sd_bus_message_read(m, "(ss)", &x, &y); assert_se(r == 0); r = sd_bus_message_exit_container(m); assert_se(r >= 0); assert_se(streq(x, "aaa")); assert_se(streq(y, "1")); assert_se(streq(a, "bbb")); assert_se(streq(b, "2")); assert_se(streq(c, "ccc")); assert_se(streq(d, "3")); test_bus_label_escape(); test_bus_path_encode(); test_bus_path_encode_unique(); test_bus_path_encode_many(); return 0; }
int register_machine( const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, bool keep_unit) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; r = sd_bus_default_system(&bus); if (r < 0) return log_error_errno(r, "Failed to open system bus: %m"); if (keep_unit) { r = sd_bus_call_method( bus, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", "RegisterMachineWithNetwork", &error, NULL, "sayssusai", machine_name, SD_BUS_MESSAGE_APPEND_ID128(uuid), "nspawn", "container", (uint32_t) pid, strempty(directory), local_ifindex > 0 ? 1 : 0, local_ifindex); } else { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; char **i; unsigned j; r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", "CreateMachineWithNetwork"); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_append( m, "sayssusai", machine_name, SD_BUS_MESSAGE_APPEND_ID128(uuid), "nspawn", "container", (uint32_t) pid, strempty(directory), local_ifindex > 0 ? 1 : 0, local_ifindex); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return bus_log_create_error(r); if (!isempty(slice)) { r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice); if (r < 0) return bus_log_create_error(r); } r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "strict"); if (r < 0) return bus_log_create_error(r); /* If you make changes here, also make sure to update * [email protected], to keep the device * policies in sync regardless if we are run with or * without the --keep-unit switch. */ r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 9, /* Allow the container to * access and create the API * device nodes, so that * PrivateDevices= in the * container can work * fine */ "/dev/null", "rwm", "/dev/zero", "rwm", "/dev/full", "rwm", "/dev/random", "rwm", "/dev/urandom", "rwm", "/dev/tty", "rwm", "/dev/net/tun", "rwm", /* Allow the container * access to ptys. However, * do not permit the * container to ever create * these device nodes. */ "/dev/pts/ptmx", "rw", "char-pts", "rw"); if (r < 0) return bus_log_create_error(r); for (j = 0; j < n_mounts; j++) { CustomMount *cm = mounts + j; if (cm->type != CUSTOM_MOUNT_BIND) continue; r = is_device_node(cm->source); if (r < 0) return log_error_errno(r, "Failed to stat %s: %m", cm->source); if (r) { r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1, cm->source, cm->read_only ? "r" : "rw"); if (r < 0) return log_error_errno(r, "Failed to append message arguments: %m"); } } if (kill_signal != 0) { r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed"); if (r < 0) return bus_log_create_error(r); } STRV_FOREACH(i, properties) { r = sd_bus_message_open_container(m, 'r', "sv"); if (r < 0) return bus_log_create_error(r); r = bus_append_unit_property_assignment(m, *i); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); } r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); r = sd_bus_call(bus, m, 0, &error, NULL); }
static int manager_connect_bus(Manager *m) { int r; assert(m); assert(!m->bus); r = sd_bus_default_system(&m->bus); if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m); if (r < 0) return log_error_errno(r, "Failed to add manager object vtable: %m"); r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m); if (r < 0) return log_error_errno(r, "Failed to add machine object vtable: %m"); r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/machine", machine_node_enumerator, m); if (r < 0) return log_error_errno(r, "Failed to add machine enumerator: %m"); r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/image", "org.freedesktop.machine1.Image", image_vtable, image_object_find, m); if (r < 0) return log_error_errno(r, "Failed to add image object vtable: %m"); r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/image", image_node_enumerator, m); if (r < 0) return log_error_errno(r, "Failed to add image enumerator: %m"); r = sd_bus_match_signal_async( m->bus, NULL, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "JobRemoved", match_job_removed, NULL, m); if (r < 0) return log_error_errno(r, "Failed to add match for JobRemoved: %m"); r = sd_bus_match_signal_async( m->bus, NULL, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitRemoved", match_unit_removed, NULL, m); if (r < 0) return log_error_errno(r, "Failed to request match for UnitRemoved: %m"); r = sd_bus_match_signal_async( m->bus, NULL, "org.freedesktop.systemd1", NULL, "org.freedesktop.DBus.Properties", "PropertiesChanged", match_properties_changed, NULL, m); if (r < 0) return log_error_errno(r, "Failed to request match for PropertiesChanged: %m"); r = sd_bus_match_signal_async( m->bus, NULL, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading", match_reloading, NULL, m); if (r < 0) return log_error_errno(r, "Failed to request match for Reloading: %m"); r = sd_bus_call_method_async( m->bus, NULL, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Subscribe", NULL, NULL, NULL); if (r < 0) return log_error_errno(r, "Failed to enable subscription: %m"); r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.machine1", 0, NULL, NULL); if (r < 0) return log_error_errno(r, "Failed to request name: %m"); r = sd_bus_attach_event(m->bus, m->event, 0); if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop: %m"); return 0; }
int main(int argc, char *argv[]) { static const char *matchfmt = "type='signal'," "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'," "arg0='org.openbmc.control.Power'," "path='%s'," "sender='%s'"; static const char *usage = "Usage: %s OBJECTPATH on|off\n"; static const size_t LEN = 256; sd_bus *conn = NULL; sd_event *loop = NULL; sd_bus_slot *slot = NULL; sd_bus_error error = SD_BUS_ERROR_NULL; char *service = NULL; int r, dest = -1, state; char match[LEN]; if(argc < 3) { fprintf(stderr, usage, argv[0]); exit(EXIT_FAILURE); } if(!strcmp(argv[2], "on")) dest = 1; if(!strcmp(argv[2], "off")) dest = 0; if(dest != 0 && dest != 1) { fprintf(stderr, usage, argv[0]); exit(EXIT_FAILURE); } r = sd_bus_default_system(&conn); if(r < 0) { fprintf(stderr, "Error connecting to system bus: %s\n", strerror(-r)); goto finish; } r = mapper_get_service(conn, argv[1], &service); if (r < 0) { fprintf(stderr, "Error obtaining host service: %s\n", strerror(-r)); goto finish; } r = sd_event_default(&loop); if (r < 0) { fprintf(stderr, "Error obtaining event loop: %s\n", strerror(-r)); goto finish; } r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL); if (r < 0) { fprintf(stderr, "Failed to attach system " "bus to event loop: %s\n", strerror(-r)); goto finish; } if(strlen(matchfmt) + strnlen(argv[1], LEN) > LEN) { r = -E2BIG; fprintf(stderr, "Error adding match rule: %s\n", strerror(-r)); goto finish; } sprintf(match, matchfmt, argv[1], service); r = sd_bus_add_match(conn, &slot, match, callback, loop); if(r < 0) { fprintf(stderr, "Error adding match rule: %s\n", strerror(-r)); goto finish; } r = sd_bus_get_property_trivial(conn, service, argv[1], "org.openbmc.control.Power", "pgood", &error, 'i', &state); if(r < 0) { fprintf(stderr, "Error getting property: %s\n", strerror(-r)); goto finish; } if(dest == state) goto finish; r = sd_event_loop(loop); if(r < 0) { fprintf(stderr, "Error starting event loop: %s\n", strerror(-r)); goto finish; } finish: exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); }
static int manager_new(struct manager **out) { struct manager *m; static const int sigs[] = { SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGPIPE, SIGCHLD, 0 }; unsigned int i; sigset_t mask; int r; m = calloc(1, sizeof(*m)); if (!m) return log_ENOMEM(); shl_htable_init_uint(&m->links); r = sd_event_default(&m->event); if (r < 0) { log_vERR(r); goto error; } r = sd_event_set_watchdog(m->event, true); if (r < 0) { log_vERR(r); goto error; } r = sd_bus_default_system(&m->bus); if (r < 0) { log_error("cannot connect to system bus: %d", r); goto error; } r = sd_bus_attach_event(m->bus, m->event, 0); if (r < 0) { log_vERR(r); goto error; } for (i = 0; sigs[i]; ++i) { sigemptyset(&mask); sigaddset(&mask, sigs[i]); sigprocmask(SIG_BLOCK, &mask, NULL); r = sd_event_add_signal(m->event, &m->sigs[i], sigs[i], manager_signal_fn, m); if (r < 0) { log_vERR(r); goto error; } /* low-priority to allow others to handle it first */ sd_event_source_set_priority(m->sigs[i], 100); } m->udev = udev_new(); if (!m->udev) { r = log_ENOMEM(); goto error; } m->udev_mon = udev_monitor_new_from_netlink(m->udev, "udev"); if (!m->udev_mon) { r = log_ENOMEM(); goto error; } r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_mon, "net", "wlan"); if (r < 0) { log_vERR(r); goto error; } r = udev_monitor_enable_receiving(m->udev_mon); if (r < 0) { log_vERR(r); goto error; } r = sd_event_add_io(m->event, &m->udev_mon_source, udev_monitor_get_fd(m->udev_mon), EPOLLHUP | EPOLLERR | EPOLLIN, manager_udev_fn, m); if (r < 0) { log_vERR(r); goto error; } r = manager_dbus_connect(m); if (r < 0) goto error; if (out) *out = m; return 0; error: manager_free(m); return r; }
static int start_transient_service( sd_bus *bus, char **argv, int *retval) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; _cleanup_free_ char *service = NULL, *pty_path = NULL; _cleanup_close_ int master = -1; int r; assert(bus); assert(argv); assert(retval); if (arg_pty) { if (arg_transport == BUS_TRANSPORT_LOCAL) { master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY); if (master < 0) return log_error_errno(errno, "Failed to acquire pseudo tty: %m"); r = ptsname_malloc(master, &pty_path); if (r < 0) return log_error_errno(r, "Failed to determine tty name: %m"); if (unlockpt(master) < 0) return log_error_errno(errno, "Failed to unlock tty: %m"); } else if (arg_transport == BUS_TRANSPORT_MACHINE) { _cleanup_(sd_bus_unrefp) sd_bus *system_bus = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *pty_reply = NULL; const char *s; r = sd_bus_default_system(&system_bus); if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); r = sd_bus_call_method(system_bus, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", "OpenMachinePTY", &error, &pty_reply, "s", arg_host); if (r < 0) { log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r)); return r; } r = sd_bus_message_read(pty_reply, "hs", &master, &s); if (r < 0) return bus_log_parse_error(r); master = fcntl(master, F_DUPFD_CLOEXEC, 3); if (master < 0) return log_error_errno(errno, "Failed to duplicate master fd: %m"); pty_path = strdup(s); if (!pty_path) return log_oom(); } else assert_not_reached("Can't allocate tty via ssh"); } if (!arg_no_block) { r = bus_wait_for_jobs_new(bus, &w); if (r < 0) return log_error_errno(r, "Could not watch jobs: %m"); } if (arg_unit) { r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".service", &service); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); } else { r = make_unit_name(bus, UNIT_SERVICE, &service); if (r < 0) return r; } r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartTransientUnit"); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); if (r < 0) return bus_log_create_error(r); /* Name and mode */ r = sd_bus_message_append(m, "ss", service, "fail"); if (r < 0) return bus_log_create_error(r); /* Properties */ r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return bus_log_create_error(r); r = transient_service_set_properties(m, argv, pty_path); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); /* Auxiliary units */ r = sd_bus_message_append(m, "a(sa(sv))", 0); if (r < 0) return bus_log_create_error(r); polkit_agent_open_if_enabled(); r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) return log_error_errno(r, "Failed to start transient service unit: %s", bus_error_message(&error, r)); if (w) { const char *object; r = sd_bus_message_read(reply, "o", &object); if (r < 0) return bus_log_parse_error(r); r = bus_wait_for_jobs_one(w, object, arg_quiet); if (r < 0) return r; } if (!arg_quiet) log_info("Running as unit: %s", service); if (arg_wait || master >= 0) { _cleanup_(run_context_free) RunContext c = {}; c.bus = sd_bus_ref(bus); r = sd_event_default(&c.event); if (r < 0) return log_error_errno(r, "Failed to get event loop: %m"); if (master >= 0) { assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGWINCH, SIGTERM, SIGINT, -1) >= 0); (void) sd_event_add_signal(c.event, NULL, SIGINT, NULL, NULL); (void) sd_event_add_signal(c.event, NULL, SIGTERM, NULL, NULL); if (!arg_quiet) log_info("Press ^] three times within 1s to disconnect TTY."); r = pty_forward_new(c.event, master, PTY_FORWARD_IGNORE_INITIAL_VHANGUP, &c.forward); if (r < 0) return log_error_errno(r, "Failed to create PTY forwarder: %m"); pty_forward_set_handler(c.forward, pty_forward_handler, &c); } if (arg_wait) { _cleanup_free_ char *path = NULL; const char *mt; path = unit_dbus_path_from_name(service); if (!path) return log_oom(); mt = strjoina("type='signal'," "sender='org.freedesktop.systemd1'," "path='", path, "'," "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'"); r = sd_bus_add_match(bus, &c.match, mt, on_properties_changed, &c); if (r < 0) return log_error_errno(r, "Failed to add properties changed signal."); r = sd_bus_attach_event(bus, c.event, 0); if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop."); } r = sd_event_loop(c.event); if (r < 0) return log_error_errno(r, "Failed to run event loop: %m"); if (c.forward) { char last_char = 0; r = pty_forward_get_last_char(c.forward, &last_char); if (r >= 0 && !arg_quiet && last_char != '\n') fputc('\n', stdout); } if (!arg_quiet) { if (!isempty(c.result)) log_info("Finished with result: %s", strna(c.result)); if (c.exit_code == CLD_EXITED) log_info("Main processes terminated with: code=%s/status=%i", sigchld_code_to_string(c.exit_code), c.exit_status); else if (c.exit_code > 0) log_info("Main processes terminated with: code=%s/status=%s", sigchld_code_to_string(c.exit_code), signal_to_string(c.exit_status)); if (c.inactive_enter_usec > 0 && c.inactive_enter_usec != USEC_INFINITY && c.inactive_exit_usec > 0 && c.inactive_exit_usec != USEC_INFINITY && c.inactive_enter_usec > c.inactive_exit_usec) { char ts[FORMAT_TIMESPAN_MAX]; log_info("Service runtime: %s", format_timespan(ts, sizeof(ts), c.inactive_enter_usec - c.inactive_exit_usec, USEC_PER_MSEC)); } if (c.cpu_usage_nsec > 0 && c.cpu_usage_nsec != NSEC_INFINITY) { char ts[FORMAT_TIMESPAN_MAX]; log_info("CPU time consumed: %s", format_timespan(ts, sizeof(ts), (c.cpu_usage_nsec + NSEC_PER_USEC - 1) / NSEC_PER_USEC, USEC_PER_MSEC)); } } /* Try to propagate the service's return value */ if (c.result && STR_IN_SET(c.result, "success", "exit-code") && c.exit_code == CLD_EXITED) *retval = c.exit_status; else *retval = EXIT_FAILURE; } return 0; }