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; }
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; }
_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; }
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; }
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; }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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 */ }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }