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; }
static int scope_arm_timer(Scope *s, usec_t usec) { int r; assert(s); if (s->timer_event_source) { r = sd_event_source_set_time(s->timer_event_source, usec); if (r < 0) return r; return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT); } if (usec == USEC_INFINITY) return 0; r = sd_event_add_time( UNIT(s)->manager->event, &s->timer_event_source, CLOCK_MONOTONIC, usec, 0, scope_dispatch_timer, s); if (r < 0) return r; (void) sd_event_source_set_description(s->timer_event_source, "scope-timer"); return 0; }
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"); } automount_set_state(a, a->deserialized_state); } return 0; }
static int automount_start_expire(Automount *a) { int r; usec_t timeout; assert(a); if (a->timeout_idle_usec == 0) return 0; timeout = now(CLOCK_MONOTONIC) + MAX(a->timeout_idle_usec/3, USEC_PER_SEC); if (a->expire_event_source) { r = sd_event_source_set_time(a->expire_event_source, timeout); if (r < 0) return r; return sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_ONESHOT); } r = sd_event_add_time( UNIT(a)->manager->event, &a->expire_event_source, CLOCK_MONOTONIC, timeout, 0, automount_dispatch_expire, a); if (r < 0) return r; (void) sd_event_source_set_description(a->expire_event_source, "automount-expire"); return 0; }
static int curl_glue_timer_callback(CURLM *curl, long timeout_ms, void *userdata) { CurlGlue *g = userdata; usec_t usec; assert(curl); assert(g); if (timeout_ms < 0) { if (g->timer) { if (sd_event_source_set_enabled(g->timer, SD_EVENT_OFF) < 0) return -1; } return 0; } usec = now(clock_boottime_or_monotonic()) + (usec_t) timeout_ms * USEC_PER_MSEC + USEC_PER_MSEC - 1; if (g->timer) { if (sd_event_source_set_time(g->timer, usec) < 0) return -1; if (sd_event_source_set_enabled(g->timer, SD_EVENT_ONESHOT) < 0) return -1; } else { if (sd_event_add_time(g->event, &g->timer, clock_boottime_or_monotonic(), usec, 0, curl_glue_on_timer, g) < 0) return -1; (void) sd_event_source_set_description(g->timer, "curl-timer"); } 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 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; }
static int scope_arm_timer(Scope *s) { int r; assert(s); if (s->timeout_stop_usec <= 0) { s->timer_event_source = sd_event_source_unref(s->timer_event_source); return 0; } if (s->timer_event_source) { r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_stop_usec); if (r < 0) return r; return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT); } r = sd_event_add_time( UNIT(s)->manager->event, &s->timer_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + s->timeout_stop_usec, 0, scope_dispatch_timer, s); if (r < 0) return r; (void) sd_event_source_set_description(s->timer_event_source, "scope-timer"); return 0; }
static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_usec) { _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL; usec_t next_timeout, time_now; int r; assert(acd); next_timeout = usec; if (random_usec > 0) next_timeout += (usec_t) random_u64() % random_usec; assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &time_now) >= 0); r = sd_event_add_time(acd->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, acd); if (r < 0) return r; r = sd_event_source_set_priority(timer, acd->event_priority); if (r < 0) return r; (void) sd_event_source_set_description(timer, "ipv4acd-timer"); sd_event_source_unref(acd->timer_event_source); acd->timer_event_source = timer; timer = NULL; return 0; }
static int busname_arm_timer(BusName *n, usec_t usec) { int r; assert(n); if (n->timer_event_source) { r = sd_event_source_set_time(n->timer_event_source, usec); if (r < 0) return r; return sd_event_source_set_enabled(n->timer_event_source, SD_EVENT_ONESHOT); } if (usec == USEC_INFINITY) return 0; r = sd_event_add_time( UNIT(n)->manager->event, &n->timer_event_source, CLOCK_MONOTONIC, usec, 0, busname_dispatch_timer, n); if (r < 0) return r; (void) sd_event_source_set_description(n->timer_event_source, "busname-timer"); return 0; }
static int busname_arm_timer(BusName *n) { int r; assert(n); if (n->timeout_usec <= 0) { n->timer_event_source = sd_event_source_unref(n->timer_event_source); return 0; } if (n->timer_event_source) { r = sd_event_source_set_time(n->timer_event_source, now(CLOCK_MONOTONIC) + n->timeout_usec); if (r < 0) return r; return sd_event_source_set_enabled(n->timer_event_source, SD_EVENT_ONESHOT); } r = sd_event_add_time( UNIT(n)->manager->event, &n->timer_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + n->timeout_usec, 0, busname_dispatch_timer, n); if (r < 0) return r; (void) sd_event_source_set_description(n->timer_event_source, "busname-timer"); return 0; }
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 link_lldp_emit_start(Link *link) { usec_t next; int r; assert(link); if (!link->network || link->network->lldp_emit == LLDP_EMIT_NO) { link_lldp_emit_stop(link); return 0; } /* Starts the LLDP transmission in "fast" mode. If it is already started, turns "fast" mode back on again. */ link->lldp_tx_fast = LLDP_TX_FAST_INIT; next = usec_add(usec_add(now(clock_boottime_or_monotonic()), LLDP_FAST_TX_USEC), (usec_t) random_u64() % LLDP_JITTER_USEC); if (link->lldp_emit_event_source) { usec_t old; /* Lower the timeout, maybe */ r = sd_event_source_get_time(link->lldp_emit_event_source, &old); if (r < 0) return r; if (old <= next) return 0; return sd_event_source_set_time(link->lldp_emit_event_source, next); } else { r = sd_event_add_time( link->manager->event, &link->lldp_emit_event_source, clock_boottime_or_monotonic(), next, 0, on_lldp_timer, link); if (r < 0) return r; (void) sd_event_source_set_description(link->lldp_emit_event_source, "lldp-tx"); } return 0; }
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_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 lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor) { sd_lldp_neighbor *n; int r; assert(lldp); if (neighbor) lldp_neighbor_start_ttl(neighbor); n = prioq_peek(lldp->neighbor_by_expiry); if (!n) { if (lldp->timer_event_source) return sd_event_source_set_enabled(lldp->timer_event_source, SD_EVENT_OFF); return 0; } if (lldp->timer_event_source) { r = sd_event_source_set_time(lldp->timer_event_source, n->until); if (r < 0) return r; return sd_event_source_set_enabled(lldp->timer_event_source, SD_EVENT_ONESHOT); } if (!lldp->event) return 0; r = sd_event_add_time(lldp->event, &lldp->timer_event_source, clock_boottime_or_monotonic(), n->until, 0, on_timer_event, lldp); if (r < 0) return r; r = sd_event_source_set_priority(lldp->timer_event_source, lldp->event_priority); if (r < 0) return r; (void) sd_event_source_set_description(lldp->timer_event_source, "lldp-timer"); 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; }
static int ipv4acd_set_next_wakeup(sd_ipv4acd *ll, int sec, int random_sec) { _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL; usec_t next_timeout; usec_t time_now; int r; assert(sec >= 0); assert(random_sec >= 0); assert(ll); next_timeout = sec * USEC_PER_SEC; if (random_sec) next_timeout += random_u32() % (random_sec * USEC_PER_SEC); assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) >= 0); r = sd_event_add_time(ll->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, ll); if (r < 0) return r; r = sd_event_source_set_priority(timer, ll->event_priority); if (r < 0) return r; r = sd_event_source_set_description(timer, "ipv4acd-timer"); if (r < 0) return r; ll->timer = sd_event_source_unref(ll->timer); ll->timer = timer; timer = NULL; return 0; }
static int curl_glue_socket_callback(CURLM *curl, curl_socket_t s, int action, void *userdata, void *socketp) { sd_event_source *io; CurlGlue *g = userdata; uint32_t events = 0; int r; assert(curl); assert(g); io = hashmap_get(g->ios, FD_TO_PTR(s)); if (action == CURL_POLL_REMOVE) { if (io) { int fd; fd = sd_event_source_get_io_fd(io); assert(fd >= 0); sd_event_source_set_enabled(io, SD_EVENT_OFF); sd_event_source_unref(io); hashmap_remove(g->ios, FD_TO_PTR(s)); hashmap_remove(g->translate_fds, FD_TO_PTR(fd)); safe_close(fd); } return 0; } r = hashmap_ensure_allocated(&g->ios, &trivial_hash_ops); if (r < 0) { log_oom(); return -1; } r = hashmap_ensure_allocated(&g->translate_fds, &trivial_hash_ops); if (r < 0) { log_oom(); return -1; } if (action == CURL_POLL_IN) events = EPOLLIN; else if (action == CURL_POLL_OUT) events = EPOLLOUT; else if (action == CURL_POLL_INOUT) events = EPOLLIN|EPOLLOUT; if (io) { if (sd_event_source_set_io_events(io, events) < 0) return -1; if (sd_event_source_set_enabled(io, SD_EVENT_ON) < 0) return -1; } else { _cleanup_close_ int fd = -1; /* When curl needs to remove an fd from us it closes * the fd first, and only then calls into us. This is * nasty, since we cannot pass the fd on to epoll() * anymore. Hence, duplicate the fds here, and keep a * copy for epoll which we control after use. */ fd = fcntl(s, F_DUPFD_CLOEXEC, 3); if (fd < 0) return -1; if (sd_event_add_io(g->event, &io, fd, events, curl_glue_on_io, g) < 0) return -1; (void) sd_event_source_set_description(io, "curl-io"); r = hashmap_put(g->ios, FD_TO_PTR(s), io); if (r < 0) { log_oom(); sd_event_source_unref(io); return -1; } r = hashmap_put(g->translate_fds, FD_TO_PTR(fd), FD_TO_PTR(s)); if (r < 0) { log_oom(); hashmap_remove(g->ios, FD_TO_PTR(s)); sd_event_source_unref(io); return -1; } fd = -1; } return 0; }
static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, void *userdata) { sd_icmp6_nd *nd = userdata; uint64_t time_now, next_timeout; struct ether_addr unset = { }; struct ether_addr *addr = NULL; int r; assert(s); assert(nd); assert(nd->event); nd->timeout = sd_event_source_unref(nd->timeout); if (nd->nd_sent >= ICMP6_MAX_ROUTER_SOLICITATIONS) { icmp6_nd_notify(nd, ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT); nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN; } else { if (memcmp(&nd->mac_addr, &unset, sizeof(struct ether_addr))) addr = &nd->mac_addr; r = dhcp_network_icmp6_send_router_solicitation(nd->fd, addr); if (r < 0) log_icmp6_nd(nd, "Error sending Router Solicitation"); else { nd->state = ICMP6_ROUTER_SOLICITATION_SENT; log_icmp6_nd(nd, "Sent Router Solicitation"); } nd->nd_sent++; r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); if (r < 0) { icmp6_nd_notify(nd, r); return 0; } next_timeout = time_now + ICMP6_ROUTER_SOLICITATION_INTERVAL; r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(), next_timeout, 0, icmp6_router_solicitation_timeout, nd); if (r < 0) { icmp6_nd_notify(nd, r); return 0; } r = sd_event_source_set_priority(nd->timeout, nd->event_priority); if (r < 0) { icmp6_nd_notify(nd, r); return 0; } r = sd_event_source_set_description(nd->timeout, "icmp6-timeout"); if (r < 0) { icmp6_nd_notify(nd, r); return 0; } } return 0; }
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(IN_SET(ll->state, IPV4LL_STATE_INIT, IPV4LL_STATE_STOPPED), -EBUSY); ll->state = IPV4LL_STATE_INIT; 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->random_data) { uint8_t seed[8]; /* Fallback to mac */ siphash24(seed, &ll->mac_addr.ether_addr_octet, ETH_ALEN, HASH_KEY.bytes); r = sd_ipv4ll_set_address_seed(ll, seed); if (r < 0) goto out; } if (ll->address == 0) { r = ipv4ll_pick_address(ll, &ll->address); if (r < 0) goto out; } 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_source_set_description(ll->receive_message, "ipv4ll-receive-message"); if (r < 0) goto out; r = sd_event_add_time(ll->event, &ll->timer, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()), 0, ipv4ll_timer, ll); if (r < 0) goto out; r = sd_event_source_set_priority(ll->timer, ll->event_priority); if (r < 0) goto out; r = sd_event_source_set_description(ll->timer, "ipv4ll-timer"); out: if (r < 0) ipv4ll_stop(ll, IPV4LL_EVENT_STOP); return 0; }
static void ipv4ll_run_state_machine(sd_ipv4ll *ll, IPv4LLTrigger trigger, void *trigger_data) { struct ether_arp out_packet; int out_packet_ready = 0; int r = 0; assert(ll); assert(trigger < _IPV4LL_TRIGGER_MAX); if (ll->state == IPV4LL_STATE_INIT) { log_ipv4ll(ll, "PROBE"); ipv4ll_set_state(ll, IPV4LL_STATE_WAITING_PROBE, 1); ipv4ll_set_next_wakeup(ll, 0, PROBE_WAIT); } else if ((ll->state == IPV4LL_STATE_WAITING_PROBE && trigger == IPV4LL_TRIGGER_TIMEOUT) || (ll->state == IPV4LL_STATE_PROBING && trigger == IPV4LL_TRIGGER_TIMEOUT && ll->iteration < PROBE_NUM-2)) { /* Send a probe */ arp_packet_probe(&out_packet, ll->address, &ll->mac_addr); out_packet_ready = 1; ipv4ll_set_state(ll, IPV4LL_STATE_PROBING, 0); ipv4ll_set_next_wakeup(ll, PROBE_MIN, (PROBE_MAX-PROBE_MIN)); } else if (ll->state == IPV4LL_STATE_PROBING && trigger == IPV4LL_TRIGGER_TIMEOUT && ll->iteration >= PROBE_NUM-2) { /* Send the last probe */ arp_packet_probe(&out_packet, ll->address, &ll->mac_addr); out_packet_ready = 1; ipv4ll_set_state(ll, IPV4LL_STATE_WAITING_ANNOUNCE, 1); ipv4ll_set_next_wakeup(ll, ANNOUNCE_WAIT, 0); } else if ((ll->state == IPV4LL_STATE_WAITING_ANNOUNCE && trigger == IPV4LL_TRIGGER_TIMEOUT) || (ll->state == IPV4LL_STATE_ANNOUNCING && trigger == IPV4LL_TRIGGER_TIMEOUT && ll->iteration < ANNOUNCE_NUM-1)) { /* Send announcement packet */ arp_packet_announcement(&out_packet, ll->address, &ll->mac_addr); out_packet_ready = 1; ipv4ll_set_state(ll, IPV4LL_STATE_ANNOUNCING, 0); ipv4ll_set_next_wakeup(ll, ANNOUNCE_INTERVAL, 0); if (ll->iteration == 0) { log_ipv4ll(ll, "ANNOUNCE"); ll->claimed_address = ll->address; ll = ipv4ll_client_notify(ll, IPV4LL_EVENT_BIND); if (!ll || ll->state == IPV4LL_STATE_STOPPED) goto out; ll->conflict = 0; } } else if ((ll->state == IPV4LL_STATE_ANNOUNCING && trigger == IPV4LL_TRIGGER_TIMEOUT && ll->iteration >= ANNOUNCE_NUM-1)) { ipv4ll_set_state(ll, IPV4LL_STATE_RUNNING, 0); ll->next_wakeup_valid = 0; } else if (trigger == IPV4LL_TRIGGER_PACKET) { int conflicted = 0; usec_t time_now; struct ether_arp* in_packet = (struct ether_arp*)trigger_data; assert(in_packet); if (IN_SET(ll->state, IPV4LL_STATE_ANNOUNCING, IPV4LL_STATE_RUNNING)) { if (ipv4ll_arp_conflict(ll, in_packet)) { r = sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now); if (r < 0) goto out; /* Defend address */ if (time_now > ll->defend_window) { ll->defend_window = time_now + DEFEND_INTERVAL * USEC_PER_SEC; arp_packet_announcement(&out_packet, ll->address, &ll->mac_addr); out_packet_ready = 1; } else conflicted = 1; } } else if (IN_SET(ll->state, IPV4LL_STATE_WAITING_PROBE, IPV4LL_STATE_PROBING, IPV4LL_STATE_WAITING_ANNOUNCE)) { conflicted = ipv4ll_arp_probe_conflict(ll, in_packet); } if (conflicted) { log_ipv4ll(ll, "CONFLICT"); ll = ipv4ll_client_notify(ll, IPV4LL_EVENT_CONFLICT); if (!ll || ll->state == IPV4LL_STATE_STOPPED) goto out; ll->claimed_address = 0; /* Pick a new address */ r = ipv4ll_pick_address(ll, &ll->address); if (r < 0) goto out; ll->conflict++; ll->defend_window = 0; ipv4ll_set_state(ll, IPV4LL_STATE_WAITING_PROBE, 1); if (ll->conflict >= MAX_CONFLICTS) { log_ipv4ll(ll, "MAX_CONFLICTS"); ipv4ll_set_next_wakeup(ll, RATE_LIMIT_INTERVAL, PROBE_WAIT); } else ipv4ll_set_next_wakeup(ll, 0, PROBE_WAIT); } } if (out_packet_ready) { r = arp_network_send_raw_socket(ll->fd, &ll->link, &out_packet); if (r < 0) { log_ipv4ll(ll, "failed to send arp packet out"); goto out; } } if (ll->next_wakeup_valid) { ll->timer = sd_event_source_unref(ll->timer); r = sd_event_add_time(ll->event, &ll->timer, clock_boottime_or_monotonic(), ll->next_wakeup, 0, ipv4ll_timer, ll); if (r < 0) goto out; r = sd_event_source_set_priority(ll->timer, ll->event_priority); if (r < 0) goto out; r = sd_event_source_set_description(ll->timer, "ipv4ll-timer"); if (r < 0) goto out; } out: if (r < 0 && ll) ipv4ll_stop(ll, r); }
static void automount_enter_waiting(Automount *a) { _cleanup_close_ int ioctl_fd = -1; int p[2] = { -1, -1 }; char name[sizeof("systemd-")-1 + DECIMAL_STR_MAX(pid_t) + 1]; char options[sizeof("fd=,pgrp=,minproto=5,maxproto=5,direct")-1 + DECIMAL_STR_MAX(int) + DECIMAL_STR_MAX(gid_t) + 1]; bool mounted = false; int r, dev_autofs_fd; struct stat st; assert(a); assert(a->pipe_fd < 0); assert(a->where); set_clear(a->tokens); r = unit_fail_if_symlink(UNIT(a), a->where); if (r < 0) goto fail; (void) mkdir_p_label(a->where, 0555); unit_warn_if_dir_nonempty(UNIT(a), a->where); dev_autofs_fd = open_dev_autofs(UNIT(a)->manager); if (dev_autofs_fd < 0) { r = dev_autofs_fd; goto fail; } if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) { r = -errno; goto fail; } xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp()); xsprintf(name, "systemd-"PID_FMT, getpid()); if (mount(name, a->where, "autofs", 0, options) < 0) { r = -errno; goto fail; } mounted = true; p[1] = safe_close(p[1]); if (stat(a->where, &st) < 0) { r = -errno; goto fail; } ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev); if (ioctl_fd < 0) { r = ioctl_fd; goto fail; } r = autofs_protocol(dev_autofs_fd, ioctl_fd); if (r < 0) goto fail; r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, a->timeout_idle_usec); if (r < 0) goto fail; /* Autofs fun fact: * * Unless we close the ioctl fd here, for some weird reason * the direct mount will not receive events from the * kernel. */ r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a); if (r < 0) goto fail; (void) sd_event_source_set_description(a->pipe_event_source, "automount-io"); a->pipe_fd = p[0]; a->dev_id = st.st_dev; automount_set_state(a, AUTOMOUNT_WAITING); return; fail: log_unit_error_errno(UNIT(a), r, "Failed to initialize automounter: %m"); safe_close_pair(p); if (mounted) { r = repeat_unmount(a->where, MNT_DETACH); if (r < 0) log_error_errno(r, "Failed to unmount, ignoring: %m"); } automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); }