예제 #1
0
void DbusApiInit(int sock)
{
	fd = sock;
	sd_event_source *busSource = NULL;
	sd_bus_slot *slot = NULL;

	int ret = sd_event_default(&event);
	char tmp = '0';
	read(fd, &tmp, sizeof(char));

	ret = sd_bus_open_system(&bus);

	ret = sd_bus_add_object_vtable(bus, &slot, "/org/watchdogd1",
				"org.watchdogd1", watchdogPmon, NULL);

	ret = sd_bus_request_name(bus, "org.watchdogd1", 0);

	if (ret < 0) {
		ReloadDbusDaemon();
		ret = sd_bus_request_name(bus, "org.watchdogd1", 0);
	}

	sd_event_add_io(event, &busSource, sd_bus_get_fd(bus), EPOLLIN, BusHandler, NULL);

	sd_event_loop(event);
}
예제 #2
0
static int client_run(int ifindex, const char *seed_str, const struct ether_addr *ha, sd_event *e) {
        sd_ipv4ll *ll;

        assert_se(sd_ipv4ll_new(&ll) >= 0);
        assert_se(sd_ipv4ll_attach_event(ll, e, 0) >= 0);

        assert_se(sd_ipv4ll_set_index(ll, ifindex) >= 0);
        assert_se(sd_ipv4ll_set_mac(ll, ha) >= 0);
        assert_se(sd_ipv4ll_set_callback(ll, ll_handler, NULL) >= 0);

        if (seed_str) {
                unsigned seed;

                assert_se(safe_atou(seed_str, &seed) >= 0);

                assert_se(sd_ipv4ll_set_address_seed(ll, seed) >= 0);
        }

        log_info("starting IPv4LL client");

        assert_se(sd_ipv4ll_start(ll) >= 0);

        assert_se(sd_event_loop(e) >= 0);

        assert_se(!sd_ipv4ll_unref(ll));

        return EXIT_SUCCESS;
}
예제 #3
0
static void test_rs(sd_event *e) {
        usec_t time_now = now(CLOCK_MONOTONIC);
        sd_icmp6_nd *nd;

        if (verbose)
                printf("* %s\n", __FUNCTION__);

        assert(sd_icmp6_nd_new(&nd) >= 0);
        assert(nd);

        assert(sd_icmp6_nd_attach_event(nd, e, 0) >= 0);

        assert(sd_icmp6_nd_set_index(nd, 42) >= 0);
        assert(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0);
        assert(sd_icmp6_nd_set_callback(nd, test_rs_done, e) >= 0);

        assert(sd_event_add_time(e, &test_hangcheck, CLOCK_MONOTONIC,
                                 time_now + 2 *USEC_PER_SEC, 0,
                                 test_rs_hangcheck, NULL) >= 0);

        assert(sd_icmp6_nd_stop(nd) >= 0);
        assert(sd_icmp6_router_solicitation_start(nd) >= 0);
        assert(sd_icmp6_nd_stop(nd) >= 0);

        assert(sd_icmp6_router_solicitation_start(nd) >= 0);

        sd_event_loop(e);

        test_hangcheck = sd_event_source_unref(test_hangcheck);

        nd = sd_icmp6_nd_unref(nd);
        assert(!nd);

        close(test_fd[1]);
}
예제 #4
0
int cli_run(void)
{
	if (!cli_event)
		return cli_EINVAL();

	return sd_event_loop(cli_event);
}
예제 #5
0
static void test_prefixes(void) {
        sd_event *e;
        sd_icmp6_nd *nd;

        if (verbose)
                printf("* %s\n", __FUNCTION__);

        send_ra_function = send_ra_prefixes;

        assert_se(sd_event_new(&e) >= 0);

        assert_se(sd_icmp6_nd_new(&nd) >= 0);
        assert_se(nd);

        assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0);

        assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0);
        assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0);
        assert_se(sd_icmp6_nd_set_callback(nd, test_prefixes_cb, e) >= 0);

        assert_se(sd_icmp6_router_solicitation_start(nd) >= 0);

        sd_event_loop(e);

        nd = sd_icmp6_nd_unref(nd);
        assert_se(!nd);

        close(test_fd[1]);

        sd_event_unref(e);
}
예제 #6
0
int main(int argc, char *argv[]) {
        Context context = {};
        int r, n, fd;

        log_parse_environment();
        log_open();

        r = parse_argv(argc, argv);
        if (r <= 0)
                goto finish;

        r = sd_event_default(&context.event);
        if (r < 0) {
                log_error_errno(r, "Failed to allocate event loop: %m");
                goto finish;
        }

        r = sd_resolve_default(&context.resolve);
        if (r < 0) {
                log_error_errno(r, "Failed to allocate resolver: %m");
                goto finish;
        }

        r = sd_resolve_attach_event(context.resolve, context.event, 0);
        if (r < 0) {
                log_error_errno(r, "Failed to attach resolver: %m");
                goto finish;
        }

        sd_event_set_watchdog(context.event, true);

        n = sd_listen_fds(1);
        if (n < 0) {
                log_error("Failed to receive sockets from parent.");
                r = n;
                goto finish;
        } else if (n == 0) {
                log_error("Didn't get any sockets passed in.");
                r = -EINVAL;
                goto finish;
        }

        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
                r = add_listen_socket(&context, fd);
                if (r < 0)
                        goto finish;
        }

        r = sd_event_loop(context.event);
        if (r < 0) {
                log_error_errno(r, "Failed to run event loop: %m");
                goto finish;
        }

finish:
        context_free(&context);

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
예제 #7
0
int main(int argc, char *argv[]) {
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
        _cleanup_(sd_bus_track_unrefp) sd_bus_track *x = NULL, *y = NULL;
        _cleanup_(sd_bus_unrefp) sd_bus *a = NULL, *b = NULL;
        const char *unique;
        int r;

        r = sd_event_default(&event);
        assert_se(r >= 0);

        r = sd_bus_open_system(&a);
        if (IN_SET(r, -ECONNREFUSED, -ENOENT)) {
                log_info("Failed to connect to bus, skipping tests.");
                return EXIT_TEST_SKIP;
        }
        assert_se(r >= 0);

        r = sd_bus_attach_event(a, event, SD_EVENT_PRIORITY_NORMAL);
        assert_se(r >= 0);

        r = sd_bus_open_system(&b);
        assert_se(r >= 0);

        r = sd_bus_attach_event(b, event, SD_EVENT_PRIORITY_NORMAL);
        assert_se(r >= 0);

        /* Watch b's name from a */
        r = sd_bus_track_new(a, &x, track_cb_x, NULL);
        assert_se(r >= 0);

        r = sd_bus_get_unique_name(b, &unique);
        assert_se(r >= 0);

        r = sd_bus_track_add_name(x, unique);
        assert_se(r >= 0);

        /* Watch's a's own name from a */
        r = sd_bus_track_new(a, &y, track_cb_y, NULL);
        assert_se(r >= 0);

        r = sd_bus_get_unique_name(a, &unique);
        assert_se(r >= 0);

        r = sd_bus_track_add_name(y, unique);
        assert_se(r >= 0);

        /* Now make b's name disappear */
        sd_bus_close(b);

        r = sd_event_loop(event);
        assert_se(r >= 0);

        assert_se(track_cb_called_x);
        assert_se(track_cb_called_y);

        return 0;
}
예제 #8
0
static void run_parent(Pty *pty) {
        int r;

        /* write message to pty, ECHO mode guarantees that we get it back
         * twice: once via ECHO, once from the run_child() fn */
        assert_se(pty_write(pty, sndmsg, strlen(sndmsg)) >= 0);

        r = sd_event_loop(event);
        assert_se(r >= 0);
}
예제 #9
0
파일: udev-util.c 프로젝트: dm0-/systemd
int device_wait_for_initialization(sd_device *device, const char *subsystem, sd_device **ret) {
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
        struct DeviceMonitorData data = {};
        int r;

        assert(device);
        assert(subsystem);

        if (sd_device_get_is_initialized(device) > 0) {
                if (ret)
                        *ret = sd_device_ref(device);
                return 0;
        }

        assert_se(sd_device_get_sysname(device, &data.sysname) >= 0);

        /* Wait until the device is initialized, so that we can get access to the ID_PATH property */

        r = sd_event_new(&event);
        if (r < 0)
                return log_error_errno(r, "Failed to get default event: %m");

        r = sd_device_monitor_new(&monitor);
        if (r < 0)
                return log_error_errno(r, "Failed to acquire monitor: %m");

        r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, subsystem, NULL);
        if (r < 0)
                return log_error_errno(r, "Failed to add %s subsystem match to monitor: %m", subsystem);

        r = sd_device_monitor_attach_event(monitor, event);
        if (r < 0)
                return log_error_errno(r, "Failed to attach event to device monitor: %m");

        r = sd_device_monitor_start(monitor, device_monitor_handler, &data);
        if (r < 0)
                return log_error_errno(r, "Failed to start device monitor: %m");

        /* Check again, maybe things changed. Udev will re-read the db if the device wasn't initialized
         * yet. */
        if (sd_device_get_is_initialized(device) > 0) {
                if (ret)
                        *ret = sd_device_ref(device);
                return 0;
        }

        r = sd_event_loop(event);
        if (r < 0)
                return log_error_errno(r, "Event loop failed: %m");

        if (ret)
                *ret = TAKE_PTR(data.device);
        return 0;
}
예제 #10
0
int main(int argc, char *argv[]) {
        _cleanup_(manager_freep) Manager *m = NULL;
        int r;

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        r = parse_argv(argc, argv);
        if (r <= 0)
                return r;

        if (arg_quiet)
                log_set_max_level(LOG_WARNING);

        assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);

        r = manager_new(&m, arg_interfaces, arg_ignore, arg_timeout);
        if (r < 0) {
                log_error_errno(r, "Could not create manager: %m");
                goto finish;
        }

        if (manager_all_configured(m)) {
                r = 0;
                goto finish;
        }

        sd_notify(false,
                  "READY=1\n"
                  "STATUS=Waiting for network connections...");

        r = sd_event_loop(m->event);
        if (r < 0) {
                log_error_errno(r, "Event loop failed: %m");
                goto finish;
        }

finish:
        strv_free(arg_interfaces);
        strv_free(arg_ignore);

        if (r >= 0) {
                sd_notify(false, "STATUS=All interfaces configured...");

                return EXIT_SUCCESS;
        } else {
                sd_notify(false, "STATUS=Failed waiting for network connectivity...");

                return EXIT_FAILURE;
        }
}
예제 #11
0
int main(int argc, char *argv[]) {
        _cleanup_manager_free_ Manager *m = NULL;
        int r;

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        if (argc != 1) {
                log_error("This program takes no arguments.");
                r = -EINVAL;
                goto out;
        }

        r = manager_new(&m);
        if (r < 0)
                goto out;

        r = manager_load_config(m);
        if (r < 0)
                return EXIT_FAILURE;

        r = manager_udev_listen(m);
        if (r < 0)
                goto out;

        r = manager_udev_enumerate_links(m);
        if (r < 0)
                goto out;

        r = manager_rtnl_listen(m);
        if (r < 0)
                goto out;

        sd_notify(false,
                  "READY=1\n"
                  "STATUS=Processing requests...");

        r = sd_event_loop(m->event);
        if (r < 0)
                goto out;

out:
        sd_notify(false,
                  "STATUS=Shutting down...");

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
int manager_run(Manager *m) {
        int r;

        assert(m);

        r = sysview_context_start(m->sysview, manager_sysview_fn, m);
        if (r < 0)
                return r;

        r = sd_event_loop(m->event);

        sysview_context_stop(m->sysview);
        return r;
}
예제 #13
0
static int test_client_solicit(sd_event *e) {
        sd_dhcp6_client *client;
        usec_t time_now = now(clock_boottime_or_monotonic());
        struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
        int val;

        if (verbose)
                printf("* %s\n", __FUNCTION__);

        assert_se(sd_dhcp6_client_new(&client) >= 0);
        assert_se(client);

        assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);

        assert_se(sd_dhcp6_client_set_ifindex(client, test_index) == 0);
        assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
                                          sizeof (mac_addr),
                                          ARPHRD_ETHER) >= 0);
        assert_se(sd_dhcp6_client_set_fqdn(client, "host.lab.intra") == 1);

        assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
        assert_se(val == 0);
        assert_se(sd_dhcp6_client_set_information_request(client, 42) >= 0);
        assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
        assert_se(val);

        assert_se(sd_dhcp6_client_set_callback(client,
                                               test_client_information_cb, e) >= 0);

        assert_se(sd_event_add_time(e, &hangcheck, clock_boottime_or_monotonic(),
                                    time_now + 2 * USEC_PER_SEC, 0,
                                    test_hangcheck, NULL) >= 0);

        assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);

        assert_se(sd_dhcp6_client_start(client) >= 0);

        sd_event_loop(e);

        hangcheck = sd_event_source_unref(hangcheck);

        assert_se(!sd_dhcp6_client_unref(client));

        test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]);

        return 0;
}
예제 #14
0
static void test_addr_acq(sd_event *e) {
        usec_t time_now = now(CLOCK_MONOTONIC);
        sd_dhcp_client *client;
        int res, r;

        if (verbose)
                printf("* %s\n", __FUNCTION__);

        r = sd_dhcp_client_new(&client);
        assert_se(r >= 0);
        assert_se(client);

        r = sd_dhcp_client_attach_event(client, e, 0);
        assert_se(r >= 0);

        assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
        assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0);

        assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e)
                >= 0);

        callback_recv = test_addr_acq_recv_discover;

        assert_se(sd_event_add_time(e, &test_hangcheck,
                                    CLOCK_MONOTONIC,
                                    time_now + 2 * USEC_PER_SEC, 0,
                                    test_dhcp_hangcheck, NULL) >= 0);

        res = sd_dhcp_client_start(client);
        assert_se(res == 0 || res == -EINPROGRESS);

        sd_event_loop(e);

        test_hangcheck = sd_event_source_unref(test_hangcheck);

        sd_dhcp_client_set_callback(client, NULL, NULL);
        sd_dhcp_client_stop(client);
        sd_dhcp_client_unref(client);

        test_fd[1] = safe_close(test_fd[1]);

        callback_recv = NULL;
        xid = 0;
}
예제 #15
0
static void test_addr_acq(sd_event *e) {
        usec_t time_now = now(clock_boottime_or_monotonic());
        sd_dhcp_client *client;
        int res, r;

        if (verbose)
                printf("* %s\n", __FUNCTION__);

        r = sd_dhcp_client_new(&client, false);
        assert_se(r >= 0);
        assert_se(client);

        r = sd_dhcp_client_attach_event(client, e, 0);
        assert_se(r >= 0);

        assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0);
        assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);

        assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e) >= 0);

        callback_recv = test_addr_acq_recv_discover;

        assert_se(sd_event_add_time(e, &test_hangcheck,
                                    clock_boottime_or_monotonic(),
                                    time_now + 2 * USEC_PER_SEC, 0,
                                    test_dhcp_hangcheck, NULL) >= 0);

        res = sd_dhcp_client_start(client);
        assert_se(IN_SET(res, 0, -EINPROGRESS));

        assert_se(sd_event_loop(e) >= 0);

        test_hangcheck = sd_event_source_unref(test_hangcheck);

        assert_se(sd_dhcp_client_set_callback(client, NULL, NULL) >= 0);
        assert_se(sd_dhcp_client_stop(client) >= 0);
        sd_dhcp_client_unref(client);

        test_fd[1] = safe_close(test_fd[1]);

        callback_recv = NULL;
        xid = 0;
}
예제 #16
0
static void test_rs(void) {
        sd_event *e;
        sd_icmp6_nd *nd;
        usec_t time_now = now(clock_boottime_or_monotonic());

        if (verbose)
                printf("* %s\n", __FUNCTION__);

        send_ra_function = send_ra;

        assert_se(sd_event_new(&e) >= 0);

        assert_se(sd_icmp6_nd_new(&nd) >= 0);
        assert_se(nd);

        assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0);

        assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0);
        assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0);
        assert_se(sd_icmp6_nd_set_callback(nd, test_rs_done, e) >= 0);

        assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
                                 time_now + 2 *USEC_PER_SEC, 0,
                                 test_rs_hangcheck, NULL) >= 0);

        assert_se(sd_icmp6_nd_stop(nd) >= 0);
        assert_se(sd_icmp6_router_solicitation_start(nd) >= 0);
        assert_se(sd_icmp6_nd_stop(nd) >= 0);

        assert_se(sd_icmp6_router_solicitation_start(nd) >= 0);

        sd_event_loop(e);

        test_hangcheck = sd_event_source_unref(test_hangcheck);

        nd = sd_icmp6_nd_unref(nd);
        assert_se(!nd);

        close(test_fd[1]);

        sd_event_unref(e);
}
예제 #17
0
static int evcat_run(Evcat *e) {
        struct termios in_attr, saved_attr;
        int r;

        assert(e);

        if (!e->managed && geteuid() > 0)
                log_warning("You run in unmanaged mode without being root. This is likely to produce no output..");

        printf("evcat - Read and catenate events from selected input devices\n"
               "        Running on seat '%s' in user-session '%s'\n"
               "        Exit by pressing ^C or 'q'\n\n",
               e->seat ? : "seat0", e->session ? : "<none>");

        r = sysview_context_start(e->sysview, evcat_sysview_fn, e);
        if (r < 0)
                goto out;

        r = tcgetattr(0, &in_attr);
        if (r < 0) {
                r = -errno;
                goto out;
        }

        saved_attr = in_attr;
        in_attr.c_lflag &= ~ECHO;

        r = tcsetattr(0, TCSANOW, &in_attr);
        if (r < 0) {
                r = -errno;
                goto out;
        }

        r = sd_event_loop(e->event);
        tcsetattr(0, TCSANOW, &saved_attr);
        printf("exiting..\n");

out:
        sysview_context_stop(e->sysview);
        return r;
}
예제 #18
0
파일: test-acd.c 프로젝트: AOSC-Dev/systemd
static int client_run(int ifindex, const struct in_addr *pa, const struct ether_addr *ha, sd_event *e) {
        sd_ipv4acd *acd;

        assert_se(sd_ipv4acd_new(&acd) >= 0);
        assert_se(sd_ipv4acd_attach_event(acd, e, 0) >= 0);

        assert_se(sd_ipv4acd_set_index(acd, ifindex) >= 0);
        assert_se(sd_ipv4acd_set_mac(acd, ha) >= 0);
        assert_se(sd_ipv4acd_set_address(acd, pa) >= 0);
        assert_se(sd_ipv4acd_set_callback(acd, acd_handler, NULL) >= 0);

        log_info("starting IPv4ACD client");

        assert_se(sd_ipv4acd_start(acd) >= 0);

        assert_se(sd_event_loop(e) >= 0);

        assert_se(!sd_ipv4acd_unref(acd));

        return EXIT_SUCCESS;
}
예제 #19
0
static int show_timesync_status(int argc, char **argv, void *userdata) {
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
        sd_bus *bus = userdata;
        int r;

        assert(bus);

        r = show_timesync_status_once(bus);
        if (r < 0)
                return r;

        if (!arg_monitor)
                return 0;

        r = sd_event_default(&event);
        if (r < 0)
                return log_error_errno(r, "Failed to get event loop: %m");

        r = sd_bus_match_signal(bus,
                                NULL,
                                "org.freedesktop.timesync1",
                                "/org/freedesktop/timesync1",
                                "org.freedesktop.DBus.Properties",
                                "PropertiesChanged",
                                on_properties_changed, NULL);
        if (r < 0)
                return log_error_errno(r, "Failed to request match for PropertiesChanged signal: %m");

        r = sd_bus_attach_event(bus, event, SD_EVENT_PRIORITY_NORMAL);
        if (r < 0)
                return log_error_errno(r, "Failed to attach bus to event loop: %m");

        r = sd_event_loop(event);
        if (r < 0)
                return log_error_errno(r, "Failed to run event loop: %m");

        return 0;
}
예제 #20
0
static int client_run(const char *client_name, sd_event *e) {
        sd_pppoe *pppoe;
        int client_ifindex;

        client_ifindex = (int) if_nametoindex(client_name);
        assert_se(client_ifindex > 0);

        assert_se(sd_pppoe_new(&pppoe) >= 0);
        assert_se(sd_pppoe_attach_event(pppoe, e, 0) >= 0);

        assert_se(sd_pppoe_set_ifname(pppoe, "pppoe-client") >= 0);
        assert_se(sd_pppoe_set_ifindex(pppoe, client_ifindex) >= 0);
        assert_se(sd_pppoe_set_callback(pppoe, pppoe_handler, e) >= 0);

        log_info("starting PPPoE client, it will exit when the server times out and sends PADT");

        assert_se(sd_pppoe_start(pppoe) >= 0);

        assert_se(sd_event_loop(e) >= 0);

        assert_se(!sd_pppoe_unref(pppoe));

        return EXIT_SUCCESS;
}
예제 #21
0
int main(int argc, char * argv[]) {
        int r;
        _cleanup_(sd_event_unrefp) sd_event *event;
        ClockState state = {
                .timerfd_fd = -1,
                .inotify_fd = -1,
                .run_systemd_wd = -1,
                .run_systemd_timesync_wd = -1,
        };

        assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);

        r = sd_event_default(&event);
        if (r < 0) {
                log_error_errno(r, "Failed to allocate event loop: %m");
                goto finish;
        }

        r = sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
        if (r < 0) {
                log_error_errno(r, "Failed to create sigterm event source: %m");
                goto finish;
        }

        r = sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
        if (r < 0) {
                log_error_errno(r, "Failed to create sigint event source: %m");
                goto finish;
        }

        r = sd_event_set_watchdog(event, true);
        if (r < 0) {
                log_error_errno(r, "Failed to create watchdog event source: %m");
                goto finish;
        }

        r = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
        if (r < 0) {
                log_error_errno(errno, "Failed to create inotify descriptor: %m");
                goto finish;
        }
        state.inotify_fd = r;

        r = sd_event_add_io(event, &state.inotify_event_source, state.inotify_fd,
                            EPOLLIN, inotify_handler, &state);
        if (r < 0) {
                log_error_errno(r, "Failed to create notify event source: %m");
                goto finish;
        }

        r = inotify_add_watch(state.inotify_fd, "/run/systemd/", IN_CREATE);
        if (r < 0) {
                log_error_errno(errno, "Failed to watch /run/systemd/: %m");
                goto finish;
        }
        state.run_systemd_wd = r;

        (void) update_notify_run_systemd_timesync(&state);

        r = clock_state_update(&state, event);
        if (r > 0) {
                r = sd_event_loop(event);
                if (r < 0)
                        log_error_errno(r, "Failed in event loop: %m");
        }

        if (state.has_watchfile)
                log_debug("Exit enabled by: /run/systemd/timesync/synchonized");

        if (state.adjtime_state == TIME_ERROR)
                log_info("Exit without adjtimex synchronized.");

 finish:
        clock_state_release(&state);
        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
예제 #22
0
파일: resolved.c 프로젝트: arthur-c/systemd
int main(int argc, char *argv[]) {
        _cleanup_(manager_freep) Manager *m = NULL;
        const char *user = "******";
        uid_t uid;
        gid_t gid;
        int r;

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        if (argc != 1) {
                log_error("This program takes no arguments.");
                r = -EINVAL;
                goto finish;
        }

        umask(0022);

        r = mac_selinux_init(NULL);
        if (r < 0) {
                log_error_errno(r, "SELinux setup failed: %m");
                goto finish;
        }

        r = get_user_creds(&user, &uid, &gid, NULL, NULL);
        if (r < 0) {
                log_error_errno(r, "Cannot resolve user name %s: %m", user);
                goto finish;
        }

        /* Always create the directory where resolv.conf will live */
        r = mkdir_safe_label("/run/systemd/resolve", 0755, uid, gid);
        if (r < 0) {
                log_error_errno(r, "Could not create runtime directory: %m");
                goto finish;
        }

        r = drop_privileges(uid, gid, 0);
        if (r < 0)
                goto finish;

        assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGUSR1, -1) >= 0);

        r = manager_new(&m);
        if (r < 0) {
                log_error_errno(r, "Could not create manager: %m");
                goto finish;
        }

        r = manager_start(m);
        if (r < 0) {
                log_error_errno(r, "Failed to start manager: %m");
                goto finish;
        }

        /* Write finish default resolv.conf to avoid a dangling
         * symlink */
        r = manager_write_resolv_conf(m);
        if (r < 0)
                log_warning_errno(r, "Could not create resolv.conf: %m");

        sd_notify(false,
                  "READY=1\n"
                  "STATUS=Processing requests...");

        r = sd_event_loop(m->event);
        if (r < 0) {
                log_error_errno(r, "Event loop failed: %m");
                goto finish;
        }

        sd_event_get_exit_code(m->event, &r);

finish:
        sd_notify(false,
                  "STOPPING=1\n"
                  "STATUS=Shutting down...");

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
예제 #23
0
파일: networkd.c 프로젝트: ariscop/systemd
int main(int argc, char *argv[]) {
        _cleanup_manager_free_ Manager *m = NULL;
        int r;

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        if (argc != 1) {
                log_error("This program takes no arguments.");
                r = -EINVAL;
                goto out;
        }

        r = manager_new(&m);
        if (r < 0) {
                log_error("Could not create manager: %s", strerror(-r));
                goto out;
        }

        r = manager_load_config(m);
        if (r < 0) {
                log_error("Could not load configuration files: %s", strerror(-r));
                goto out;
        }

        r = manager_udev_listen(m);
        if (r < 0) {
                log_error("Could not connect to udev: %s", strerror(-r));
                goto out;
        }

        r = manager_udev_enumerate_links(m);
        if (r < 0) {
                log_error("Could not enumerate links: %s", strerror(-r));
                goto out;
        }

        r = manager_rtnl_listen(m);
        if (r < 0) {
                log_error("Could not connect to rtnl: %s", strerror(-r));
                goto out;
        }

        r = manager_bus_listen(m);
        if (r < 0) {
                log_error("Could not connect to system bus: %s", strerror(-r));
                goto out;
        }

        /* write out empty resolv.conf to avoid a
         * dangling symlink */
        r = manager_update_resolv_conf(m);
        if (r < 0) {
                log_error("Could not create resolv.conf: %s", strerror(-r));
                goto out;
        }

        sd_notify(false,
                  "READY=1\n"
                  "STATUS=Processing requests...");

        r = sd_event_loop(m->event);
        if (r < 0) {
                log_error("Event loop failed: %s", strerror(-r));
                goto out;
        }

out:
        sd_notify(false,
                  "STATUS=Shutting down...");

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
int main(int argc, char *argv[]) {
        sd_event *e = NULL;
        sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL, *t = NULL;
        static const char ch = 'x';
        int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1}, k[2] = { -1, -1 };

        assert_se(pipe(a) >= 0);
        assert_se(pipe(b) >= 0);
        assert_se(pipe(d) >= 0);
        assert_se(pipe(k) >= 0);

        assert_se(sd_event_default(&e) >= 0);

        assert_se(sd_event_set_watchdog(e, true) >= 0);

        /* Test whether we cleanly can destroy an io event source from its own handler */
        got_unref = false;
        assert_se(sd_event_add_io(e, &t, k[0], EPOLLIN, unref_handler, NULL) >= 0);
        assert_se(write(k[1], &ch, 1) == 1);
        assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
        assert_se(got_unref);

        got_a = false, got_b = false, got_c = false, got_d = 0;

        /* Add a oneshot handler, trigger it, re-enable it, and trigger
         * it again. */
        assert_se(sd_event_add_io(e, &w, d[0], EPOLLIN, io_handler, INT_TO_PTR('d')) >= 0);
        assert_se(sd_event_source_set_enabled(w, SD_EVENT_ONESHOT) >= 0);
        assert_se(write(d[1], &ch, 1) >= 0);
        assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
        assert_se(got_d == 1);
        assert_se(write(d[1], &ch, 1) >= 0);
        assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
        assert_se(got_d == 2);

        assert_se(sd_event_add_io(e, &x, a[0], EPOLLIN, io_handler, INT_TO_PTR('a')) >= 0);
        assert_se(sd_event_add_io(e, &y, b[0], EPOLLIN, io_handler, INT_TO_PTR('b')) >= 0);
        assert_se(sd_event_add_time(e, &z, CLOCK_MONOTONIC, 0, 0, time_handler, INT_TO_PTR('c')) >= 0);
        assert_se(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')) >= 0);

        assert_se(sd_event_source_set_priority(x, 99) >= 0);
        assert_se(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT) >= 0);
        assert_se(sd_event_source_set_prepare(x, prepare_handler) >= 0);
        assert_se(sd_event_source_set_priority(z, 50) >= 0);
        assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
        assert_se(sd_event_source_set_prepare(z, prepare_handler) >= 0);

        /* Test for floating event sources */
        assert_se(sigprocmask_many(SIG_BLOCK, SIGRTMIN+1, -1) == 0);
        assert_se(sd_event_add_signal(e, NULL, SIGRTMIN+1, NULL, NULL) >= 0);

        assert_se(write(a[1], &ch, 1) >= 0);
        assert_se(write(b[1], &ch, 1) >= 0);

        assert_se(!got_a && !got_b && !got_c);

        assert_se(sd_event_run(e, (uint64_t) -1) >= 1);

        assert_se(!got_a && got_b && !got_c);

        assert_se(sd_event_run(e, (uint64_t) -1) >= 1);

        assert_se(!got_a && got_b && got_c);

        assert_se(sd_event_run(e, (uint64_t) -1) >= 1);

        assert_se(got_a && got_b && got_c);

        sd_event_source_unref(x);
        sd_event_source_unref(y);

        do_quit = true;
        assert_se(sd_event_source_set_time(z, now(CLOCK_MONOTONIC) + 200 * USEC_PER_MSEC) >= 0);
        assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);

        assert_se(sd_event_loop(e) >= 0);

        sd_event_source_unref(z);
        sd_event_source_unref(q);

        sd_event_source_unref(w);

        sd_event_unref(e);

        safe_close_pair(a);
        safe_close_pair(b);
        safe_close_pair(d);
        safe_close_pair(k);

        return 0;
}
예제 #25
0
int main(int argc, char *argv[])
{
    int result = 0;
    struct cc_event_context *context = NULL;
    sd_event *event = NULL;
    struct cc_server_Calculator *instance1 = NULL, *instance2 = NULL;

    CC_LOG_OPEN("simpleserver");
    printf("Started simpleserver\n");

    result = cc_backend_startup();
    if (result < 0) {
        printf("unable to startup backend: %s\n", strerror(-result));
        goto fail;
    }
    result = cc_server_Calculator_new(
        "org.genivi.capic.Server:/instance1:org.genivi.capic.Calculator",
        &impl1, NULL, &instance1);
    if (result < 0) {
        printf("unable to create server instance '/instance1': %s\n", strerror(-result));
        goto fail;
    }
    result = cc_server_Calculator_new(
        "org.genivi.capic.Server:/instance2:org.genivi.capic.Calculator",
        &impl2, NULL, &instance2);
    if (result < 0) {
        printf("unable to create server instance '/instance2': %s\n", strerror(-result));
        goto fail;
    }

    result = cc_backend_get_event_context(&context);
    if (result < 0) {
        printf("unable to get backend event context: %s\n", strerror(-result));
        goto fail;
    }
    event = (sd_event *) cc_event_get_native(context);
    assert(event);
    sd_event_ref(event);
    result = setup_signals(event);
    if (result < 0) {
        printf("unable to setup signal sources: %s\n", strerror(-result));
        goto fail;
    }

    printf("entering main loop...\n");
    result = sd_event_loop(event);
    if (result < 0) {
        printf("unable to run event loop: %s\n", strerror(-result));
        goto fail;
    }

fail:
    if (event)
        sd_event_unref(event);
    instance2 = cc_server_Calculator_free(instance2);
    instance1 = cc_server_Calculator_free(instance1);
    cc_backend_shutdown();

    CC_LOG_CLOSE();
    printf("exiting simpleserver\n");

    return result;
}
예제 #26
0
파일: import.c 프로젝트: pwaller/systemd
static int pull_dck(int argc, char *argv[], void *userdata) {
        _cleanup_(dck_import_unrefp) DckImport *import = NULL;
        _cleanup_event_unref_ sd_event *event = NULL;
        const char *name, *tag, *local;
        int r;

        tag = strchr(argv[1], ':');
        if (tag) {
                name = strndupa(argv[1], tag - argv[1]);
                tag++;
        } else {
                name = argv[1];
                tag = "latest";
        }

        if (argc >= 3)
                local = argv[2];
        else {
                local = strchr(name, '/');
                if (local)
                        local++;
                else
                        local = name;
        }

        if (streq(local, "-") || isempty(local))
                local = NULL;

        if (!dck_name_is_valid(name)) {
                log_error("Remote name '%s' is not valid.", name);
                return -EINVAL;
        }

        if (!dck_tag_is_valid(tag)) {
                log_error("Tag name '%s' is not valid.", tag);
                return -EINVAL;
        }

        if (local) {
                const char *p;

                if (!machine_name_is_valid(tag)) {
                        log_error("Local image name '%s' is not valid.", local);
                        return -EINVAL;
                }

                p = strappenda("/var/lib/container/", local);
                if (laccess(p, F_OK) >= 0) {
                        if (!arg_force) {
                                log_info("Image '%s' already exists.", local);
                                return 0;
                        }
                } else if (errno != ENOENT)
                        return log_error_errno(errno, "Can't check if image '%s' already exists: %m", local);

                log_info("Pulling '%s' with tag '%s', saving as '%s'.", name, tag, local);
        } else
                log_info("Pulling '%s' with tag '%s'.", name, tag);

        r = sd_event_default(&event);
        if (r < 0)
                return log_error_errno(r, "Failed to allocate event loop: %m");

        assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
        sd_event_add_signal(event, NULL, SIGTERM, NULL,  NULL);
        sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);

        r = dck_import_new(&import, event, on_finished, event);
        if (r < 0)
                return log_error_errno(r, "Failed to allocate importer: %m");

        r = dck_import_pull(import, name, tag, local, arg_force);
        if (r < 0)
                return log_error_errno(r, "Failed to pull image: %m");

        r = sd_event_loop(event);
        if (r < 0)
                return log_error_errno(r, "Failed to run event loop: %m");

        log_info("Exiting.");

        return 0;
}
예제 #27
0
파일: networkd.c 프로젝트: chenyf/systemd
int main(int argc, char *argv[]) {
        _cleanup_manager_free_ Manager *m = NULL;
        const char *user = "******";
        uid_t uid;
        gid_t gid;
        int r;

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        if (argc != 1) {
                log_error("This program takes no arguments.");
                r = -EINVAL;
                goto out;
        }

        r = get_user_creds(&user, &uid, &gid, NULL, NULL);
        if (r < 0) {
                log_error("Cannot resolve user name %s: %s", user, strerror(-r));
                goto out;
        }

        /* Always create the directories people can create inotify
         * watches in. */
        r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid);
        if (r < 0)
                log_error("Could not create runtime directory: %s",
                          strerror(-r));

        r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid);
        if (r < 0)
                log_error("Could not create runtime directory 'links': %s",
                          strerror(-r));

        r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid);
        if (r < 0)
                log_error("Could not create runtime directory 'leases': %s",
                          strerror(-r));

        r = drop_privileges(uid, gid,
                            (1ULL << CAP_NET_ADMIN) |
                            (1ULL << CAP_NET_BIND_SERVICE) |
                            (1ULL << CAP_NET_BROADCAST) |
                            (1ULL << CAP_NET_RAW));
        if (r < 0)
                goto out;

        assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);

        r = manager_new(&m);
        if (r < 0) {
                log_error("Could not create manager: %s", strerror(-r));
                goto out;
        }

        r = manager_udev_listen(m);
        if (r < 0) {
                log_error("Could not connect to udev: %s", strerror(-r));
                goto out;
        }

        r = manager_rtnl_listen(m);
        if (r < 0) {
                log_error("Could not connect to rtnl: %s", strerror(-r));
                goto out;
        }

        r = manager_bus_listen(m);
        if (r < 0) {
                log_error("Could not connect to system bus: %s", strerror(-r));
                goto out;
        }

        r = manager_load_config(m);
        if (r < 0) {
                log_error("Could not load configuration files: %s", strerror(-r));
                goto out;
        }

        r = manager_rtnl_enumerate_links(m);
        if (r < 0) {
                log_error("Could not enumerate links: %s", strerror(-r));
                goto out;
        }

        sd_notify(false,
                  "READY=1\n"
                  "STATUS=Processing requests...");

        r = sd_event_loop(m->event);
        if (r < 0) {
                log_error("Event loop failed: %s", strerror(-r));
                goto out;
        }

out:
        sd_notify(false,
                  "STOPPING=1\n"
                  "STATUS=Shutting down...");

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
예제 #28
0
파일: resolved.c 프로젝트: OpenDZ/systemd
int main(int argc, char *argv[]) {
        _cleanup_(manager_freep) Manager *m = NULL;
        const char *user = "******";
        uid_t uid;
        gid_t gid;
        int r;

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        if (argc != 1) {
                log_error("This program takes no arguments.");
                r = -EINVAL;
                goto finish;
        }

        umask(0022);

        r = mac_selinux_init();
        if (r < 0) {
                log_error_errno(r, "SELinux setup failed: %m");
                goto finish;
        }

        r = get_user_creds(&user, &uid, &gid, NULL, NULL);
        if (r < 0) {
                log_error_errno(r, "Cannot resolve user name %s: %m", user);
                goto finish;
        }

        /* Always create the directory where resolv.conf will live */
        r = mkdir_safe_label("/run/systemd/resolve", 0755, uid, gid, false);
        if (r < 0) {
                log_error_errno(r, "Could not create runtime directory: %m");
                goto finish;
        }

        /* Drop privileges, but only if we have been started as root. If we are not running as root we assume all
         * privileges are already dropped. */
        if (getuid() == 0) {

                /* Drop privileges, but keep three caps. Note that we drop those too, later on (see below) */
                r = drop_privileges(uid, gid,
                                    (UINT64_C(1) << CAP_NET_RAW)|          /* needed for SO_BINDTODEVICE */
                                    (UINT64_C(1) << CAP_NET_BIND_SERVICE)| /* needed to bind on port 53 */
                                    (UINT64_C(1) << CAP_SETPCAP)           /* needed in order to drop the caps later */);
                if (r < 0)
                        goto finish;
        }

        assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGUSR1, SIGUSR2, SIGRTMIN+1, -1) >= 0);

        r = manager_new(&m);
        if (r < 0) {
                log_error_errno(r, "Could not create manager: %m");
                goto finish;
        }

        r = manager_start(m);
        if (r < 0) {
                log_error_errno(r, "Failed to start manager: %m");
                goto finish;
        }

        /* Write finish default resolv.conf to avoid a dangling symlink */
        (void) manager_write_resolv_conf(m);

        /* Let's drop the remaining caps now */
        r = capability_bounding_set_drop(0, true);
        if (r < 0) {
                log_error_errno(r, "Failed to drop remaining caps: %m");
                goto finish;
        }

        sd_notify(false,
                  "READY=1\n"
                  "STATUS=Processing requests...");

        r = sd_event_loop(m->event);
        if (r < 0) {
                log_error_errno(r, "Event loop failed: %m");
                goto finish;
        }

        sd_event_get_exit_code(m->event, &r);

finish:
        sd_notify(false,
                  "STOPPING=1\n"
                  "STATUS=Shutting down...");

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
예제 #29
0
int main(int argc, char *argv[]) {
        _cleanup_(manager_freep) Manager *m = NULL;
        const char *user = "******";
        uid_t uid;
        gid_t gid;
        int r;

        log_set_target(LOG_TARGET_AUTO);
        log_set_facility(LOG_CRON);
        log_parse_environment();
        log_open();

        umask(0022);

        if (argc != 1) {
                log_error("This program does not take arguments.");
                r = -EINVAL;
                goto finish;
        }

        r = get_user_creds(&user, &uid, &gid, NULL, NULL);
        if (r < 0) {
                log_error_errno(r, "Cannot resolve user name %s: %m", user);
                goto finish;
        }

        r = load_clock_timestamp(uid, gid);
        if (r < 0)
                goto finish;

        r = drop_privileges(uid, gid, (1ULL << CAP_SYS_TIME));
        if (r < 0)
                goto finish;

        /* We need one process for ourselves, plus one thread for the asynchronous resolver */
        if (setrlimit(RLIMIT_NPROC, &RLIMIT_MAKE_CONST(2)) < 0)
                log_warning_errno(errno, "Failed to lower RLIMIT_NPROC to 2: %m");

        assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);

        r = manager_new(&m);
        if (r < 0) {
                log_error_errno(r, "Failed to allocate manager: %m");
                goto finish;
        }

        if (clock_is_localtime() > 0) {
                log_info("The system is configured to read the RTC time in the local time zone. "
                         "This mode can not be fully supported. All system time to RTC updates are disabled.");
                m->rtc_local_time = true;
        }

        r = manager_parse_config_file(m);
        if (r < 0)
                log_warning_errno(r, "Failed to parse configuration file: %m");

        log_debug("systemd-timesyncd running as pid %lu", (unsigned long) getpid());
        sd_notify(false,
                  "READY=1\n"
                  "STATUS=Daemon is running");

        if (network_is_online()) {
                r = manager_connect(m);
                if (r < 0)
                        goto finish;
        }

        r = sd_event_loop(m->event);
        if (r < 0) {
                log_error_errno(r, "Failed to run event loop: %m");
                goto finish;
        }

        /* if we got an authoritative time, store it in the file system */
        if (m->sync)
                touch("/var/lib/systemd/clock");

        sd_event_get_exit_code(m->event, &r);

finish:
        sd_notify(false,
                  "STOPPING=1\n"
                  "STATUS=Shutting down...");

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
예제 #30
0
파일: import.c 프로젝트: josephgbr/systemd
static int import_tar(int argc, char *argv[], void *userdata) {
        _cleanup_(tar_import_unrefp) TarImport *import = NULL;
        _cleanup_event_unref_ sd_event *event = NULL;
        const char *path = NULL, *local = NULL;
        _cleanup_free_ char *ll = NULL;
        _cleanup_close_ int open_fd = -1;
        int r, fd;

        if (argc >= 2)
                path = argv[1];
        if (isempty(path) || streq(path, "-"))
                path = NULL;

        if (argc >= 3)
                local = argv[2];
        else if (path)
                local = basename(path);
        if (isempty(local) || streq(local, "-"))
                local = NULL;

        if (local) {
                r = tar_strip_suffixes(local, &ll);
                if (r < 0)
                        return log_oom();

                local = ll;

                if (!machine_name_is_valid(local)) {
                        log_error("Local image name '%s' is not valid.", local);
                        return -EINVAL;
                }

                if (!arg_force) {
                        r = image_find(local, NULL);
                        if (r < 0)
                                return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
                        else if (r > 0) {
                                log_error_errno(EEXIST, "Image '%s' already exists.", local);
                                return -EEXIST;
                        }
                }
        } else
                local = "imported";

        if (path) {
                open_fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
                if (open_fd < 0)
                        return log_error_errno(errno, "Failed to open tar image to import: %m");

                fd = open_fd;

                log_info("Importing '%s', saving as '%s'.", path, local);
        } else {
                _cleanup_free_ char *pretty = NULL;

                fd = STDIN_FILENO;

                (void) readlink_malloc("/proc/self/fd/0", &pretty);
                log_info("Importing '%s', saving as '%s'.", strna(pretty), local);
        }

        r = sd_event_default(&event);
        if (r < 0)
                return log_error_errno(r, "Failed to allocate event loop: %m");

        assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
        (void) sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler,  NULL);
        (void) sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);

        r = tar_import_new(&import, event, arg_image_root, on_tar_finished, event);
        if (r < 0)
                return log_error_errno(r, "Failed to allocate importer: %m");

        r = tar_import_start(import, fd, local, arg_force, arg_read_only);
        if (r < 0)
                return log_error_errno(r, "Failed to import image: %m");

        r = sd_event_loop(event);
        if (r < 0)
                return log_error_errno(r, "Failed to run event loop: %m");

        log_info("Exiting.");
        return -r;
}