コード例 #1
0
ファイル: logind-button.c プロジェクト: nazgul77/systemd
int button_open(Button *b) {
        char *p, name[256];
        int r;

        assert(b);

        b->fd = safe_close(b->fd);

        p = strjoina("/dev/input/", b->name);

        b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
        if (b->fd < 0)
                return log_warning_errno(errno, "Failed to open %s: %m", b->name);

        if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) {
                r = log_error_errno(errno, "Failed to get input name: %m");
                goto fail;
        }

        r = sd_event_add_io(b->manager->event, &b->io_event_source, b->fd, EPOLLIN, button_dispatch, b);
        if (r < 0) {
                log_error_errno(r, "Failed to add button event: %m");
                goto fail;
        }

        log_info("Watching system buttons on /dev/input/%s (%s)", b->name, name);

        return 0;

fail:
        b->fd = safe_close(b->fd);
        return r;
}
コード例 #2
0
ファイル: automount.c プロジェクト: ariscop/systemd
static int automount_coldplug(Unit *u) {
        Automount *a = AUTOMOUNT(u);
        int r;

        assert(a);
        assert(a->state == AUTOMOUNT_DEAD);

        if (a->deserialized_state != a->state) {

                r = open_dev_autofs(u->manager);
                if (r < 0)
                        return r;

                if (a->deserialized_state == AUTOMOUNT_WAITING ||
                    a->deserialized_state == AUTOMOUNT_RUNNING) {

                        assert(a->pipe_fd >= 0);

                        r = sd_event_add_io(u->manager->event, a->pipe_fd, EPOLLIN, automount_dispatch_io, u, &a->pipe_event_source);
                        if (r < 0)
                                return r;
                }

                automount_set_state(a, a->deserialized_state);
        }

        return 0;
}
コード例 #3
0
ファイル: sd-lldp.c プロジェクト: GalliumOS/network-manager
_public_ int sd_lldp_start(sd_lldp *lldp) {
        int r;

        assert_return(lldp, -EINVAL);

        if (lldp->fd >= 0)
                return 0;

        assert(!lldp->io_event_source);

        lldp->fd = lldp_network_bind_raw_socket(lldp->ifindex);
        if (lldp->fd < 0)
                return lldp->fd;

        if (lldp->event) {
                r = sd_event_add_io(lldp->event, &lldp->io_event_source, lldp->fd, EPOLLIN, lldp_receive_datagram, lldp);
                if (r < 0)
                        goto fail;

                r = sd_event_source_set_priority(lldp->io_event_source, lldp->event_priority);
                if (r < 0)
                        goto fail;

                (void) sd_event_source_set_description(lldp->io_event_source, "lldp-io");
        }

        return 1;

fail:
        lldp->io_event_source = sd_event_source_unref(lldp->io_event_source);
        lldp->fd = safe_close(lldp->fd);

        return r;
}
コード例 #4
0
static int dns_transaction_emit(DnsTransaction *t) {
        int r;

        assert(t);

        if (t->scope->protocol == DNS_PROTOCOL_DNS && !t->server) {
                DnsServer *server = NULL;
                _cleanup_close_ int fd = -1;

                fd = dns_scope_udp_dns_socket(t->scope, &server);
                if (fd < 0)
                        return fd;

                r = sd_event_add_io(t->scope->manager->event, &t->dns_udp_event_source, fd, EPOLLIN, on_dns_packet, t);
                if (r < 0)
                        return r;

                t->dns_udp_fd = fd;
                fd = -1;
                t->server = dns_server_ref(server);
        }

        r = dns_scope_emit(t->scope, t->dns_udp_fd, t->sent);
        if (r < 0)
                return r;

        return 0;
}
コード例 #5
0
ファイル: busname.c プロジェクト: achanda/systemd
static int busname_watch_fd(BusName *n) {
        int r;

        assert(n);

        if (n->starter_fd < 0)
                return 0;

        if (n->starter_event_source) {
                r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_ON);
                if (r < 0)
                        goto fail;
        } else {
                r = sd_event_add_io(UNIT(n)->manager->event, &n->starter_event_source, n->starter_fd, EPOLLIN, busname_dispatch_io, n);
                if (r < 0)
                        goto fail;

                (void) sd_event_source_set_description(n->starter_event_source, "busname-starter");
        }

        return 0;

fail:
        log_unit_warning_errno(UNIT(n), r, "Failed to watch starter fd: %m");
        busname_unwatch_fd(n);
        return r;
}
コード例 #6
0
ファイル: dbusapi.c プロジェクト: clockley/watchdogd
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);
}
コード例 #7
0
ファイル: automount.c プロジェクト: aulanov/systemd
static int automount_coldplug(Unit *u) {
        Automount *a = AUTOMOUNT(u);
        int r;

        assert(a);
        assert(a->state == AUTOMOUNT_DEAD);

        if (a->deserialized_state != a->state) {

                r = open_dev_autofs(u->manager);
                if (r < 0)
                        return r;

                if (a->deserialized_state == AUTOMOUNT_WAITING ||
                    a->deserialized_state == AUTOMOUNT_RUNNING) {
                        assert(a->pipe_fd >= 0);

                        r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
                        if (r < 0)
                                return r;

                        (void) sd_event_source_set_description(a->pipe_event_source, "automount-io");
                        if (a->deserialized_state == AUTOMOUNT_RUNNING) {
                                r = automount_start_expire(a);
                                if (r < 0)
                                        log_unit_warning_errno(UNIT(a), r, "Failed to start expiration timer, ignoring: %m");
                        }
                }

                automount_set_state(a, a->deserialized_state);
        }

        return 0;
}
コード例 #8
0
ファイル: export-raw.c プロジェクト: vathpela/systemd
int raw_export_start(RawExport *e, const char *path, int fd, ImportCompressType compress) {
        _cleanup_close_ int sfd = -1, tfd = -1;
        int r;

        assert(e);
        assert(path);
        assert(fd >= 0);
        assert(compress < _IMPORT_COMPRESS_TYPE_MAX);
        assert(compress != IMPORT_COMPRESS_UNKNOWN);

        if (e->output_fd >= 0)
                return -EBUSY;

        r = fd_nonblock(fd, true);
        if (r < 0)
                return r;

        r = free_and_strdup(&e->path, path);
        if (r < 0)
                return r;

        sfd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
        if (sfd < 0)
                return -errno;

        if (fstat(sfd, &e->st) < 0)
                return -errno;
        r = stat_verify_regular(&e->st);
        if (r < 0)
                return r;

        /* Try to take a reflink snapshot of the file, if we can t make the export atomic */
        tfd = reflink_snapshot(sfd, path);
        if (tfd >= 0)
                e->input_fd = TAKE_FD(tfd);
        else
                e->input_fd = TAKE_FD(sfd);

        r = import_compress_init(&e->compress, compress);
        if (r < 0)
                return r;

        r = sd_event_add_io(e->event, &e->output_event_source, fd, EPOLLOUT, raw_export_on_output, e);
        if (r == -EPERM) {
                r = sd_event_add_defer(e->event, &e->output_event_source, raw_export_on_defer, e);
                if (r < 0)
                        return r;

                r = sd_event_source_set_enabled(e->output_event_source, SD_EVENT_ON);
        }
        if (r < 0)
                return r;

        e->output_fd = fd;
        return r;
}
コード例 #9
0
ファイル: journald-stream.c プロジェクト: torstehu/systemd
static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
        _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL;
        sd_id128_t id;
        int r;

        assert(s);
        assert(fd >= 0);

        r = sd_id128_randomize(&id);
        if (r < 0)
                return log_error_errno(r, "Failed to generate stream ID: %m");

        stream = new0(StdoutStream, 1);
        if (!stream)
                return log_oom();

        stream->fd = -1;
        stream->priority = LOG_INFO;

        xsprintf(stream->id_field, "_STREAM_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id));

        r = getpeercred(fd, &stream->ucred);
        if (r < 0)
                return log_error_errno(r, "Failed to determine peer credentials: %m");

        if (mac_selinux_use()) {
                r = getpeersec(fd, &stream->label);
                if (r < 0 && r != -EOPNOTSUPP)
                        (void) log_warning_errno(r, "Failed to determine peer security context: %m");
        }

        (void) shutdown(fd, SHUT_WR);

        r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLIN, stdout_stream_process, stream);
        if (r < 0)
                return log_error_errno(r, "Failed to add stream to event loop: %m");

        r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
        if (r < 0)
                return log_error_errno(r, "Failed to adjust stdout event source priority: %m");

        stream->fd = fd;

        stream->server = s;
        LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
        s->n_stdout_streams++;

        if (ret)
                *ret = stream;

        stream = NULL;

        return 0;
}
コード例 #10
0
int sd_pppoe_start(sd_pppoe *ppp) {
        union sockaddr_union link = {
                .ll = {
                        .sll_family = AF_PACKET,
                        .sll_protocol = htons(ETH_P_PPP_DISC),
                },
        };
        _cleanup_close_ int s = -1;
        _cleanup_event_source_unref_ sd_event_source *io = NULL;
        int r;

        assert_return(ppp, -EINVAL);
        assert_return(ppp->fd == -1, -EBUSY);
        assert_return(!ppp->io, -EBUSY);
        assert_return(ppp->ifindex > 0, -EUNATCH);
        assert_return(ppp->ifname, -EUNATCH);
        assert_return(ppp->event, -EUNATCH);
        assert_return(ppp->cb, -EUNATCH);

        s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
        if (s < 0)
                return -errno;

        link.ll.sll_ifindex = ppp->ifindex;

        r = bind(s, &link.sa, sizeof(link.ll));
        if (r < 0)
                return r;

        r = sd_event_add_io(ppp->event, &io,
                            s, EPOLLIN, pppoe_receive_message,
                            ppp);
        if (r < 0)
                return r;

        r = sd_event_source_set_priority(io, ppp->event_priority);
        if (r < 0)
                return r;

        ppp->fd = s;
        s = -1;
        ppp->io = io;
        io = NULL;

        r = pppoe_send_initiation(ppp);
        if (r < 0)
                return r;

        ppp->state = PPPOE_STATE_INITIALIZING;

        return 0;
}
コード例 #11
0
ファイル: journald-native.c プロジェクト: teg/systemd
int server_open_native_socket(Server*s) {

        static const union sockaddr_union sa = {
                .un.sun_family = AF_UNIX,
                .un.sun_path = "/run/systemd/journal/socket",
        };
        static const int one = 1;
        int r;

        assert(s);

        if (s->native_fd < 0) {
                s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
                if (s->native_fd < 0)
                        return log_error_errno(errno, "socket() failed: %m");

                (void) unlink(sa.un.sun_path);

                r = bind(s->native_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
                if (r < 0)
                        return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);

                (void) chmod(sa.un.sun_path, 0666);
        } else
                fd_nonblock(s->native_fd, 1);

        r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
        if (r < 0)
                return log_error_errno(errno, "SO_PASSCRED failed: %m");

#ifdef HAVE_SELINUX
        if (mac_selinux_use()) {
                r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
                if (r < 0)
                        log_warning_errno(errno, "SO_PASSSEC failed: %m");
        }
#endif

        r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
        if (r < 0)
                return log_error_errno(errno, "SO_TIMESTAMP failed: %m");

        r = sd_event_add_io(s->event, &s->native_event_source, s->native_fd, EPOLLIN, server_process_datagram, s);
        if (r < 0)
                return log_error_errno(r, "Failed to add native server fd to event loop: %m");

        r = sd_event_source_set_priority(s->native_event_source, SD_EVENT_PRIORITY_NORMAL+5);
        if (r < 0)
                return log_error_errno(r, "Failed to adjust native event source priority: %m");

        return 0;
}
コード例 #12
0
ファイル: journald-kmsg.c プロジェクト: Werkov/systemd
int server_open_dev_kmsg(Server *s) {
        mode_t mode;
        int r;

        assert(s);

        if (s->read_kmsg)
                mode = O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY;
        else
                mode = O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY;

        s->dev_kmsg_fd = open("/dev/kmsg", mode);
        if (s->dev_kmsg_fd < 0) {
                log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
                         "Failed to open /dev/kmsg, ignoring: %m");
                return 0;
        }

        if (!s->read_kmsg)
                return 0;

        r = sd_event_add_io(s->event, &s->dev_kmsg_event_source, s->dev_kmsg_fd, EPOLLIN, dispatch_dev_kmsg, s);
        if (r < 0) {

                /* This will fail with EPERM on older kernels where
                 * /dev/kmsg is not readable. */
                if (r == -EPERM) {
                        r = 0;
                        goto fail;
                }

                log_error_errno(r, "Failed to add /dev/kmsg fd to event loop: %m");
                goto fail;
        }

        r = sd_event_source_set_priority(s->dev_kmsg_event_source, SD_EVENT_PRIORITY_IMPORTANT+10);
        if (r < 0) {
                log_error_errno(r, "Failed to adjust priority of kmsg event source: %m");
                goto fail;
        }

        s->dev_kmsg_readable = true;

        return 0;

fail:
        s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);
        s->dev_kmsg_fd = safe_close(s->dev_kmsg_fd);

        return r;
}
コード例 #13
0
ファイル: socket-proxyd.c プロジェクト: floppym/systemd
static int connection_enable_event_sources(Connection *c) {
        uint32_t a = 0, b = 0;
        int r;

        assert(c);

        if (c->server_to_client_buffer_full > 0)
                b |= EPOLLOUT;
        if (c->server_to_client_buffer_full < c->server_to_client_buffer_size)
                a |= EPOLLIN;

        if (c->client_to_server_buffer_full > 0)
                a |= EPOLLOUT;
        if (c->client_to_server_buffer_full < c->client_to_server_buffer_size)
                b |= EPOLLIN;

        if (c->server_event_source)
                r = sd_event_source_set_io_events(c->server_event_source, a);
        else if (c->server_fd >= 0)
                r = sd_event_add_io(c->context->event, &c->server_event_source, c->server_fd, a, traffic_cb, c);
        else
                r = 0;

        if (r < 0)
                return log_error_errno(r, "Failed to set up server event source: %m");

        if (c->client_event_source)
                r = sd_event_source_set_io_events(c->client_event_source, b);
        else if (c->client_fd >= 0)
                r = sd_event_add_io(c->context->event, &c->client_event_source, c->client_fd, b, traffic_cb, c);
        else
                r = 0;

        if (r < 0)
                return log_error_errno(r, "Failed to set up client event source: %m");

        return 0;
}
コード例 #14
0
ファイル: sd-icmp6-nd.c プロジェクト: faizalpribadi/systemd
int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd) {
        int r;

        assert(nd);
        assert(nd->event);

        if (nd->state != ICMP6_NEIGHBOR_DISCOVERY_IDLE)
                return -EINVAL;

        if (nd->index < 1)
                return -EINVAL;

        r = dhcp_network_icmp6_bind_router_solicitation(nd->index);
        if (r < 0)
                return r;

        nd->fd = r;

        r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN,
                            icmp6_router_advertisment_recv, nd);
        if (r < 0)
                goto error;

        r = sd_event_source_set_priority(nd->recv, nd->event_priority);
        if (r < 0)
                goto error;

        r = sd_event_source_set_description(nd->recv, "icmp6-receive-message");
        if (r < 0)
                goto error;

        r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(),
                              0, 0, icmp6_router_solicitation_timeout, nd);
        if (r < 0)
                goto error;

        r = sd_event_source_set_priority(nd->timeout, nd->event_priority);
        if (r < 0)
                goto error;

        r = sd_event_source_set_description(nd->timeout, "icmp6-timeout");
error:
        if (r < 0)
                icmp6_nd_init(nd);
        else
                log_icmp6_nd(client, "Start Router Solicitation");

        return r;
}
コード例 #15
0
int server_open_dev_kmsg(Server *s) {
        int r;

        assert(s);

        s->dev_kmsg_fd = open("/dev/kmsg", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
        if (s->dev_kmsg_fd < 0) {
                log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
                         "Failed to open /dev/kmsg, ignoring: %m");
                return 0;
        }

        r = sd_event_add_io(s->event, &s->dev_kmsg_event_source, s->dev_kmsg_fd, EPOLLIN, dispatch_dev_kmsg, s);
        if (r < 0) {

                /* This will fail with EPERM on older kernels where
                 * /dev/kmsg is not readable. */
                if (r == -EPERM) {
                        r = 0;
                        goto fail;
                }

                log_error("Failed to add /dev/kmsg fd to event loop: %s", strerror(-r));
                goto fail;
        }

        r = sd_event_source_set_priority(s->dev_kmsg_event_source, SD_EVENT_PRIORITY_IMPORTANT+10);
        if (r < 0) {
                log_error("Failed to adjust priority of kmsg event source: %s", strerror(-r));
                goto fail;
        }

        s->dev_kmsg_readable = true;

        return 0;

fail:
        if (s->dev_kmsg_event_source)
                s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);

        if (s->dev_kmsg_fd >= 0) {
                close_nointr_nofail(s->dev_kmsg_fd);
                s->dev_kmsg_fd = -1;
        }

        return r;
}
コード例 #16
0
ファイル: sd-ipv4ll.c プロジェクト: MOBO-OSS/systemd-relative
int sd_ipv4ll_start (sd_ipv4ll *ll) {
        int r;

        assert_return(ll, -EINVAL);
        assert_return(ll->event, -EINVAL);
        assert_return(ll->index > 0, -EINVAL);
        assert_return(ll->state == IPV4LL_STATE_INIT, -EBUSY);

        r = arp_network_bind_raw_socket(ll->index, &ll->link);

        if (r < 0)
                goto out;

        ll->fd = r;
        ll->conflict = 0;
        ll->defend_window = 0;
        ll->claimed_address = 0;

        if (ll->address == 0)
                ll->address = ipv4ll_pick_address(ll);

        ipv4ll_set_state (ll, IPV4LL_STATE_INIT, 1);

        r = sd_event_add_io(ll->event, &ll->receive_message, ll->fd,
                            EPOLLIN, ipv4ll_receive_message, ll);
        if (r < 0)
                goto out;

        r = sd_event_source_set_priority(ll->receive_message, ll->event_priority);
        if (r < 0)
                goto out;

        r = sd_event_add_monotonic(ll->event, &ll->timer, now(CLOCK_MONOTONIC), 0,
                                   ipv4ll_timer, ll);

        if (r < 0)
                goto out;

        r = sd_event_source_set_priority(ll->timer, ll->event_priority);

out:
        if (r < 0)
                ipv4ll_stop(ll, IPV4LL_EVENT_STOP);

        return 0;
}
コード例 #17
0
int open_journal_for_upload(Uploader *u,
                            sd_journal *j,
                            const char *cursor,
                            bool after_cursor,
                            bool follow) {
    int fd, r, events;

    u->journal = j;

    sd_journal_set_data_threshold(j, 0);

    if (follow) {
        fd = sd_journal_get_fd(j);
        if (fd < 0)
            return log_error_errno(fd, "sd_journal_get_fd failed: %m");

        events = sd_journal_get_events(j);

        r = sd_journal_reliable_fd(j);
        assert(r >= 0);
        if (r > 0)
            u->timeout = -1;
        else
            u->timeout = JOURNAL_UPLOAD_POLL_TIMEOUT;

        r = sd_event_add_io(u->events, &u->input_event,
                            fd, events, dispatch_journal_input, u);
        if (r < 0)
            return log_error_errno(r, "Failed to register input event: %m");

        log_debug("Listening for journal events on fd:%d, timeout %d",
                  fd, u->timeout == (uint64_t) -1 ? -1 : (int) u->timeout);
    } else
        log_debug("Not listening for journal events.");

    if (cursor) {
        r = sd_journal_seek_cursor(j, cursor);
        if (r < 0) {
            return log_error_errno(r, "Failed to seek to cursor %s: %m",
                                   cursor);
        }
    }

    return process_journal_input(u, 1 + !!after_cursor);
}
コード例 #18
0
ファイル: socket-proxyd.c プロジェクト: floppym/systemd
static int add_listen_socket(Context *context, int fd) {
        sd_event_source *source;
        int r;

        assert(context);
        assert(fd >= 0);

        r = set_ensure_allocated(&context->listen, NULL);
        if (r < 0) {
                log_oom();
                return r;
        }

        r = sd_is_socket(fd, 0, SOCK_STREAM, 1);
        if (r < 0)
                return log_error_errno(r, "Failed to determine socket type: %m");
        if (r == 0) {
                log_error("Passed in socket is not a stream socket.");
                return -EINVAL;
        }

        r = fd_nonblock(fd, true);
        if (r < 0)
                return log_error_errno(r, "Failed to mark file descriptor non-blocking: %m");

        r = sd_event_add_io(context->event, &source, fd, EPOLLIN, accept_cb, context);
        if (r < 0)
                return log_error_errno(r, "Failed to add event source: %m");

        r = set_put(context->listen, source);
        if (r < 0) {
                log_error_errno(r, "Failed to add source to set: %m");
                sd_event_source_unref(source);
                return r;
        }

        /* Set the watcher to oneshot in case other processes are also
         * watching to accept(). */
        r = sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
        if (r < 0)
                return log_error_errno(r, "Failed to enable oneshot mode: %m");

        return 0;
}
コード例 #19
0
ファイル: ctl-sink.c プロジェクト: Happy-Ferret/miraclecast
static int sink_connect(struct ctl_sink *s)
{
	int fd, r;

	if (!s)
		return cli_EINVAL();
	if (s->fd >= 0)
		return 0;
	if (!s->addr.ss_family || !s->addr_size)
		return cli_EINVAL();

	fd = socket(s->addr.ss_family,
		    SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
		    0);
	if (fd < 0)
		return cli_ERRNO();

	r = connect(fd, (struct sockaddr*)&s->addr, s->addr_size);
	if (r < 0) {
		r = -errno;
		if (r != -EINPROGRESS) {
			cli_vERR(r);
			goto err_close;
		}
	}

	r = sd_event_add_io(s->event,
			    &s->fd_source,
			    fd,
			    EPOLLHUP | EPOLLERR | EPOLLIN | EPOLLOUT | EPOLLET,
			    sink_io_fn,
			    s);
	if (r < 0) {
		cli_vERR(r);
		goto err_close;
	}

	s->fd = fd;
	return 0;

err_close:
	close(fd);
	return r;
}
コード例 #20
0
ファイル: socket-proxyd.c プロジェクト: floppym/systemd
static int connection_start(Connection *c, struct sockaddr *sa, socklen_t salen) {
        int r;

        assert(c);
        assert(sa);
        assert(salen);

        c->client_fd = socket(sa->sa_family, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
        if (c->client_fd < 0) {
                log_error_errno(errno, "Failed to get remote socket: %m");
                goto fail;
        }

        r = connect(c->client_fd, sa, salen);
        if (r < 0) {
                if (errno == EINPROGRESS) {
                        r = sd_event_add_io(c->context->event, &c->client_event_source, c->client_fd, EPOLLOUT, connect_cb, c);
                        if (r < 0) {
                                log_error_errno(r, "Failed to add connection socket: %m");
                                goto fail;
                        }

                        r = sd_event_source_set_enabled(c->client_event_source, SD_EVENT_ONESHOT);
                        if (r < 0) {
                                log_error_errno(r, "Failed to enable oneshot event source: %m");
                                goto fail;
                        }
                } else {
                        log_error_errno(errno, "Failed to connect to remote host: %m");
                        goto fail;
                }
        } else {
                r = connection_complete(c);
                if (r < 0)
                        goto fail;
        }

        return 0;

fail:
        connection_free(c);
        return 0; /* ignore errors, continue serving */
}
コード例 #21
0
ファイル: sd-ipv4acd.c プロジェクト: TrumpOnLinux/systemd
int sd_ipv4acd_start(sd_ipv4acd *ll) {
        int r;

        assert_return(ll, -EINVAL);
        assert_return(ll->event, -EINVAL);
        assert_return(ll->index > 0, -EINVAL);
        assert_return(ll->address != 0, -EINVAL);
        assert_return(!ether_addr_is_nul(&ll->mac_addr), -EINVAL);
        assert_return(ll->state == IPV4ACD_STATE_INIT, -EBUSY);

        ll->defend_window = 0;

        r = arp_network_bind_raw_socket(ll->index, ll->address, &ll->mac_addr);
        if (r < 0)
                goto out;

        ll->fd = safe_close(ll->fd);
        ll->fd = r;

        r = sd_event_add_io(ll->event, &ll->receive_message, ll->fd,
                            EPOLLIN, ipv4acd_on_packet, ll);
        if (r < 0)
                goto out;

        r = sd_event_source_set_priority(ll->receive_message, ll->event_priority);
        if (r < 0)
                goto out;

        r = sd_event_source_set_description(ll->receive_message, "ipv4acd-receive-message");
        if (r < 0)
                goto out;

        r = ipv4acd_set_next_wakeup(ll, 0, 0);
        if (r < 0)
                goto out;
out:
        if (r < 0) {
                ipv4acd_stop(ll);
                return r;
        }

        return 0;
}
コード例 #22
0
ファイル: sd-icmp6-nd.c プロジェクト: Mathnerd314/systemd
int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd) {
        int r;

        assert(nd);
        assert(nd->event);

        if (nd->state != ICMP6_NEIGHBOR_DISCOVERY_IDLE)
                return -EINVAL;

        if (nd->index < 1)
                return -EINVAL;

        r = dhcp_network_icmp6_bind_router_solicitation(nd->index);
        if (r < 0)
                return r;

        nd->fd = r;

        r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN,
                            icmp6_router_advertisment_recv, nd);
        if (r < 0)
                goto error;

        r = sd_event_source_set_priority(nd->recv, nd->event_priority);
        if (r < 0)
                goto error;

        r = sd_event_add_time(nd->event, &nd->timeout, CLOCK_MONOTONIC,
                              0, 0, icmp6_router_solicitation_timeout, nd);
        if (r < 0)
                goto error;

        r = sd_event_source_set_priority(nd->timeout, nd->event_priority);

error:
        if (r < 0)
                icmp6_nd_init(nd);
        else
                log_icmp6_nd(client, "Start Router Solicitation");

        return r;
}
コード例 #23
0
static int busname_watch_fd(BusName *n) {
        int r;

        assert(n);

        if (n->starter_fd < 0)
                return 0;

        if (n->starter_event_source)
                r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_ON);
        else
                r = sd_event_add_io(UNIT(n)->manager->event, &n->starter_event_source, n->starter_fd, EPOLLIN, busname_dispatch_io, n);
        if (r < 0) {
                log_unit_warning_errno(UNIT(n)->id, r, "Failed to watch starter fd: %m");
                busname_unwatch_fd(n);
                return r;
        }

        return 0;
}
コード例 #24
0
ファイル: import-raw.c プロジェクト: halfline/systemd
int raw_import_start(RawImport *i, int fd, const char *local, bool force_local, bool read_only) {
        int r;

        assert(i);
        assert(fd >= 0);
        assert(local);

        if (!machine_name_is_valid(local))
                return -EINVAL;

        if (i->input_fd >= 0)
                return -EBUSY;

        r = fd_nonblock(fd, true);
        if (r < 0)
                return r;

        r = free_and_strdup(&i->local, local);
        if (r < 0)
                return r;
        i->force_local = force_local;
        i->read_only = read_only;

        if (fstat(fd, &i->st) < 0)
                return -errno;

        r = sd_event_add_io(i->event, &i->input_event_source, fd, EPOLLIN, raw_import_on_input, i);
        if (r == -EPERM) {
                /* This fd does not support epoll, for example because it is a regular file. Busy read in that case */
                r = sd_event_add_defer(i->event, &i->input_event_source, raw_import_on_defer, i);
                if (r < 0)
                        return r;

                r = sd_event_source_set_enabled(i->input_event_source, SD_EVENT_ON);
        }
        if (r < 0)
                return r;

        i->input_fd = fd;
        return r;
}
コード例 #25
0
ファイル: sd-ipv4acd.c プロジェクト: GuillaumeSeren/systemd
int sd_ipv4acd_start(sd_ipv4acd *acd) {
        int r;

        assert_return(acd, -EINVAL);
        assert_return(acd->event, -EINVAL);
        assert_return(acd->ifindex > 0, -EINVAL);
        assert_return(acd->address != 0, -EINVAL);
        assert_return(!ether_addr_is_null(&acd->mac_addr), -EINVAL);
        assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY);

        r = arp_network_bind_raw_socket(acd->ifindex, acd->address, &acd->mac_addr);
        if (r < 0)
                return r;

        safe_close(acd->fd);
        acd->fd = r;
        acd->defend_window = 0;
        acd->n_conflict = 0;

        r = sd_event_add_io(acd->event, &acd->receive_message_event_source, acd->fd, EPOLLIN, ipv4acd_on_packet, acd);
        if (r < 0)
                goto fail;

        r = sd_event_source_set_priority(acd->receive_message_event_source, acd->event_priority);
        if (r < 0)
                goto fail;

        (void) sd_event_source_set_description(acd->receive_message_event_source, "ipv4acd-receive-message");

        r = ipv4acd_set_next_wakeup(acd, 0, 0);
        if (r < 0)
                goto fail;

        ipv4acd_set_state(acd, IPV4ACD_STATE_STARTED, true);
        return 0;

fail:
        ipv4acd_reset(acd);
        return r;
}
コード例 #26
0
ファイル: sd-dhcp-client.c プロジェクト: kyoiora/systemd
static int client_initialize_events(sd_dhcp_client *client,
                                    sd_event_io_handler_t io_callback) {
        int r;

        assert(client);
        assert(client->event);

        r = sd_event_add_io(client->event, &client->receive_message,
                            client->fd, EPOLLIN, io_callback,
                            client);
        if (r < 0)
                goto error;

        r = sd_event_source_set_priority(client->receive_message,
                                         client->event_priority);
        if (r < 0)
                goto error;

        client->timeout_resend = sd_event_source_unref(client->timeout_resend);

        r = sd_event_add_time(client->event,
                              &client->timeout_resend,
                              CLOCK_MONOTONIC,
                              0, 0,
                              client_timeout_resend, client);
        if (r < 0)
                goto error;

        r = sd_event_source_set_priority(client->timeout_resend,
                                         client->event_priority);

error:
        if (r < 0)
                client_stop(client, r);

        return 0;

}
コード例 #27
0
ファイル: lldp-port.c プロジェクト: arthur-c/systemd
int lldp_port_start(lldp_port *p) {
        int r;

        assert_return(p, -EINVAL);

        r = lldp_network_bind_raw_socket(p->ifindex);
        if (r < 0)
                return r;

        p->rawfd = r;

        r = sd_event_add_io(p->event, &p->lldp_port_rx,
                            p->rawfd, EPOLLIN, lldp_receive_packet, p);
        if (r < 0) {
                log_debug_errno(r, "Failed to allocate event source: %m");
                goto fail;
        }

        r = sd_event_source_set_priority(p->lldp_port_rx, p->event_priority);
        if (r < 0) {
                log_debug_errno(r, "Failed to set event priority: %m");
                goto fail;
        }

        r = sd_event_source_set_description(p->lldp_port_rx, "lldp-port-rx");
        if (r < 0) {
                log_debug_errno(r, "Failed to set event name: %m");
                goto fail;
        }

        return 0;

fail:
        lldp_port_stop(p);

        return r;
}
コード例 #28
0
int manager_udev_listen(Manager *m) {
        int r;

        r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
        if (r < 0) {
                log_error("Could not add udev monitor filter: %s", strerror(-r));
                return r;
        }

        r = udev_monitor_enable_receiving(m->udev_monitor);
        if (r < 0) {
                log_error("Could not enable udev monitor");
                return r;
        }

        r = sd_event_add_io(m->event,
                        udev_monitor_get_fd(m->udev_monitor),
                        EPOLLIN, manager_dispatch_link_udev,
                        m, &m->udev_event_source);
        if (r < 0)
                return r;

        return 0;
}
コード例 #29
0
ファイル: ptyfwd.c プロジェクト: tblume/systemd-suse-devel
int pty_forward_new(
    sd_event *event,
    int master,
    PTYForwardFlags flags,
    PTYForward **ret) {

    _cleanup_(pty_forward_freep) PTYForward *f = NULL;
    struct winsize ws;
    int r;

    f = new0(PTYForward, 1);
    if (!f)
        return -ENOMEM;

    f->flags = flags;

    if (event)
        f->event = sd_event_ref(event);
    else {
        r = sd_event_default(&f->event);
        if (r < 0)
            return r;
    }

    if (!(flags & PTY_FORWARD_READ_ONLY)) {
        r = fd_nonblock(STDIN_FILENO, true);
        if (r < 0)
            return r;

        r = fd_nonblock(STDOUT_FILENO, true);
        if (r < 0)
            return r;
    }

    r = fd_nonblock(master, true);
    if (r < 0)
        return r;

    f->master = master;

    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0)
        (void) ioctl(master, TIOCSWINSZ, &ws);

    if (!(flags & PTY_FORWARD_READ_ONLY)) {
        if (tcgetattr(STDIN_FILENO, &f->saved_stdin_attr) >= 0) {
            struct termios raw_stdin_attr;

            f->saved_stdin = true;

            raw_stdin_attr = f->saved_stdin_attr;
            cfmakeraw(&raw_stdin_attr);
            raw_stdin_attr.c_oflag = f->saved_stdin_attr.c_oflag;
            tcsetattr(STDIN_FILENO, TCSANOW, &raw_stdin_attr);
        }

        if (tcgetattr(STDOUT_FILENO, &f->saved_stdout_attr) >= 0) {
            struct termios raw_stdout_attr;

            f->saved_stdout = true;

            raw_stdout_attr = f->saved_stdout_attr;
            cfmakeraw(&raw_stdout_attr);
            raw_stdout_attr.c_iflag = f->saved_stdout_attr.c_iflag;
            raw_stdout_attr.c_lflag = f->saved_stdout_attr.c_lflag;
            tcsetattr(STDOUT_FILENO, TCSANOW, &raw_stdout_attr);
        }

        r = sd_event_add_io(f->event, &f->stdin_event_source, STDIN_FILENO, EPOLLIN|EPOLLET, on_stdin_event, f);
        if (r < 0 && r != -EPERM)
            return r;
    }

    r = sd_event_add_io(f->event, &f->stdout_event_source, STDOUT_FILENO, EPOLLOUT|EPOLLET, on_stdout_event, f);
    if (r == -EPERM)
        /* stdout without epoll support. Likely redirected to regular file. */
        f->stdout_writable = true;
    else if (r < 0)
        return r;

    r = sd_event_add_io(f->event, &f->master_event_source, master, EPOLLIN|EPOLLOUT|EPOLLET, on_master_event, f);
    if (r < 0)
        return r;

    r = sd_event_add_signal(f->event, &f->sigwinch_event_source, SIGWINCH, on_sigwinch_event, f);
    if (r < 0)
        return r;

    *ret = f;
    f = NULL;

    return 0;
}
コード例 #30
0
ファイル: timedate-sntp.c プロジェクト: wkennington/systemd
static int sntp_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
        SNTPContext *sntp = userdata;
        unsigned char buf[sizeof(struct ntp_msg)];
        struct iovec iov = {
                .iov_base = buf,
                .iov_len = sizeof(buf),
        };
        union {
                struct cmsghdr cmsghdr;
                uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
        } control;
        struct sockaddr_in server_addr;
        struct msghdr msghdr = {
                .msg_iov = &iov,
                .msg_iovlen = 1,
                .msg_control = &control,
                .msg_controllen = sizeof(control),
                .msg_name = &server_addr,
                .msg_namelen = sizeof(server_addr),
        };
        struct cmsghdr *cmsg;
        struct timespec now_ts;
        struct timeval *recv_time;
        ssize_t len;
        struct ntp_msg *ntpmsg;
        double origin, receive, trans, dest;
        double delay, offset;
        bool spike;
        int leap_sec;
        int r;

        if (revents & (EPOLLHUP|EPOLLERR)) {
                log_debug("Server connection returned error. Closing.");
                sntp_server_disconnect(sntp);
                return -ENOTCONN;
        }

        len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
        if (len < 0) {
                log_debug("Error receiving message. Disconnecting.");
                return -EINVAL;
        }

        if (iov.iov_len < sizeof(struct ntp_msg)) {
                log_debug("Invalid response from server. Disconnecting.");
                return -EINVAL;
        }

        if (sntp->server_addr.sin_addr.s_addr != server_addr.sin_addr.s_addr) {
                log_debug("Response from unknown server. Disconnecting.");
                return -EINVAL;
        }

        recv_time = NULL;
        for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
                if (cmsg->cmsg_level != SOL_SOCKET)
                        continue;

                switch (cmsg->cmsg_type) {
                case SCM_TIMESTAMP:
                        recv_time = (struct timeval *) CMSG_DATA(cmsg);
                        break;
                }
        }
        if (!recv_time) {
                log_debug("Invalid packet timestamp. Disconnecting.");
                return -EINVAL;
        }

        ntpmsg = iov.iov_base;
        if (!sntp->pending) {
                log_debug("Unexpected reply. Ignoring.");
                return 0;
        }

        /* check our "time cookie" (we just stored nanoseconds in the fraction field) */
        if (be32toh(ntpmsg->origin_time.sec) != sntp->trans_time.tv_sec + OFFSET_1900_1970 ||
            be32toh(ntpmsg->origin_time.frac) != sntp->trans_time.tv_nsec) {
                log_debug("Invalid reply; not our transmit time. Ignoring.");
                return 0;
        }

        if (NTP_FIELD_LEAP(ntpmsg->field) == NTP_LEAP_NOTINSYNC) {
                log_debug("Server is not synchronized. Disconnecting.");
                return -EINVAL;
        }

        if (NTP_FIELD_VERSION(ntpmsg->field) != 4) {
                log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg->field));
                return -EINVAL;
        }

        if (NTP_FIELD_MODE(ntpmsg->field) != NTP_MODE_SERVER) {
                log_debug("Unsupported mode %d. Disconnecting.", NTP_FIELD_MODE(ntpmsg->field));
                return -EINVAL;
        }

        /* valid packet */
        sntp->pending = false;
        sntp->retry_interval = 0;

        /* announce leap seconds */
        if (NTP_FIELD_LEAP(ntpmsg->field) & NTP_LEAP_PLUSSEC)
                leap_sec = 1;
        else if (NTP_FIELD_LEAP(ntpmsg->field) & NTP_LEAP_MINUSSEC)
                leap_sec = -1;
        else
                leap_sec = 0;

        /*
         * "Timestamp Name          ID   When Generated
         *  ------------------------------------------------------------
         *  Originate Timestamp     T1   time request sent by client
         *  Receive Timestamp       T2   time request received by server
         *  Transmit Timestamp      T3   time reply sent by server
         *  Destination Timestamp   T4   time reply received by client
         *
         *  The round-trip delay, d, and system clock offset, t, are defined as:
         *  d = (T4 - T1) - (T3 - T2)     t = ((T2 - T1) + (T3 - T4)) / 2"
         */
        clock_gettime(CLOCK_MONOTONIC, &now_ts);
        origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&sntp->trans_time_mon)) + OFFSET_1900_1970;
        receive = ntp_ts_to_d(&ntpmsg->recv_time);
        trans = ntp_ts_to_d(&ntpmsg->trans_time);
        dest = tv_to_d(recv_time) + OFFSET_1900_1970;

        offset = ((receive - origin) + (trans - dest)) / 2;
        delay = (dest - origin) - (trans - receive);

        spike = sntp_sample_spike_detection(sntp, offset, delay);

        sntp_adjust_poll(sntp, offset, spike);

        log_debug("NTP response:\n"
                  "  leap         : %u\n"
                  "  version      : %u\n"
                  "  mode         : %u\n"
                  "  stratum      : %u\n"
                  "  precision    : %f sec (%d)\n"
                  "  reference    : %.4s\n"
                  "  origin       : %f\n"
                  "  receive      : %f\n"
                  "  transmit     : %f\n"
                  "  dest         : %f\n"
                  "  offset       : %+f sec\n"
                  "  delay        : %+f sec\n"
                  "  packet count : %"PRIu64"\n"
                  "  jitter       : %f%s\n"
                  "  poll interval: %llu\n",
                  NTP_FIELD_LEAP(ntpmsg->field),
                  NTP_FIELD_VERSION(ntpmsg->field),
                  NTP_FIELD_MODE(ntpmsg->field),
                  ntpmsg->stratum,
                  exp2(ntpmsg->precision), ntpmsg->precision,
                  ntpmsg->stratum == 1 ? ntpmsg->refid : "n/a",
                  origin - OFFSET_1900_1970,
                  receive - OFFSET_1900_1970,
                  trans - OFFSET_1900_1970,
                  dest - OFFSET_1900_1970,
                  offset, delay,
                  sntp->packet_count,
                  sntp->samples_jitter, spike ? " spike" : "",
                  sntp->poll_interval_usec / USEC_PER_SEC);

        if (sntp->report)
                sntp->report(sntp->poll_interval_usec, offset, delay, sntp->samples_jitter, spike);

        if (!spike) {
                r = sntp_adjust_clock(sntp, offset, leap_sec);
                if (r < 0)
                        log_error("Failed to call clock_adjtime(): %m");
        }

        r = sntp_arm_timer(sntp, sntp->poll_interval_usec);
        if (r < 0)
                return r;

        return 0;
}

int sntp_server_connect(SNTPContext *sntp, const char *server) {
        _cleanup_free_ char *s = NULL;

        assert(sntp);
        assert(server);
        assert(sntp->server_socket >= 0);

        s = strdup(server);
        if (!s)
                return -ENOMEM;

        free(sntp->server);
        sntp->server = s;
        s = NULL;

        zero(sntp->server_addr);
        sntp->server_addr.sin_family = AF_INET;
        sntp->server_addr.sin_addr.s_addr = inet_addr(server);

        sntp->poll_interval_usec = 2 * NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;

        return sntp_send_request(sntp);
}

void sntp_server_disconnect(SNTPContext *sntp) {
        if (!sntp->server)
                return;

        sntp->event_timer = sd_event_source_unref(sntp->event_timer);

        sntp->event_clock_watch = sd_event_source_unref(sntp->event_clock_watch);
        if (sntp->clock_watch_fd > 0)
                close(sntp->clock_watch_fd);
        sntp->clock_watch_fd = -1;

        sntp->event_receive = sd_event_source_unref(sntp->event_receive);
        if (sntp->server_socket > 0)
                close(sntp->server_socket);
        sntp->server_socket = -1;

        zero(sntp->server_addr);
        free(sntp->server);
        sntp->server = NULL;
}

static int sntp_listen_setup(SNTPContext *sntp, sd_event *e) {
        _cleanup_close_ int fd = -1;
        struct sockaddr_in addr;
        const int on = 1;
        const int tos = IPTOS_LOWDELAY;
        int r;

        fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (fd < 0)
                return -errno;

        zero(addr);
        addr.sin_family = AF_INET;
        r = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
        if (r < 0)
                return -errno;

        r = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
        if (r < 0)
                return -errno;

        r = setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
        if (r < 0)
                return -errno;

        r = sd_event_add_io(e, &sntp->event_receive, fd, EPOLLIN, sntp_receive_response, sntp);
        if (r < 0)
                return r;

        sntp->server_socket = fd;
        fd = -1;

        return 0;
}