X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=socket.c;h=aafe43987ad9b9d85281101f8e9913280179fee7;hb=4f4a1dbf2171aa62da04d2e3b6945e8992139d14;hp=63346a2bfc7c71630fa6a360d432d7e307e30602;hpb=a16e112358ea8fea381ee106b89e645aed8b0a8c;p=elogind.git diff --git a/socket.c b/socket.c index 63346a2bf..aafe43987 100644 --- a/socket.c +++ b/socket.c @@ -119,9 +119,14 @@ static bool have_non_accept_socket(Socket *s) { if (!s->accept) return true; - LIST_FOREACH(port, p, s->ports) + LIST_FOREACH(port, p, s->ports) { + + if (p->type != SOCKET_SOCKET) + return true; + if (!socket_address_can_accept(&p->address)) return true; + } return false; } @@ -140,6 +145,79 @@ static int socket_verify(Socket *s) { return 0; } +static bool socket_needs_mount(Socket *s, const char *prefix) { + SocketPort *p; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + + if (p->type == SOCKET_SOCKET) { + if (socket_address_needs_mount(&p->address, prefix)) + return true; + } else { + assert(p->type == SOCKET_FIFO); + if (path_startswith(p->path, prefix)) + return true; + } + } + + return false; +} + +int socket_add_one_mount_link(Socket *s, Mount *m) { + int r; + + assert(s); + assert(m); + + if (s->meta.load_state != UNIT_LOADED || + m->meta.load_state != UNIT_LOADED) + return 0; + + if (!socket_needs_mount(s, m->where)) + return 0; + + if ((r = unit_add_dependency(UNIT(m), UNIT_BEFORE, UNIT(s), true)) < 0) + return r; + + if ((r = unit_add_dependency(UNIT(s), UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; + + return 0; +} + +static int socket_add_mount_links(Socket *s) { + Meta *other; + int r; + + assert(s); + + LIST_FOREACH(units_per_type, other, s->meta.manager->units_per_type[UNIT_MOUNT]) + if ((r = socket_add_one_mount_link(s, (Mount*) other)) < 0) + return r; + + return 0; +} + +static int socket_add_device_link(Socket *s) { + char *t; + int r; + + assert(s); + + if (!s->bind_to_device) + return 0; + + if (asprintf(&t, "/sys/subsystem/net/devices/%s", s->bind_to_device) < 0) + return -ENOMEM; + + r = unit_add_node_link(UNIT(s), t, false); + free(t); + + return r; +} + static int socket_load(Unit *u) { Socket *s = SOCKET(u); int r; @@ -157,10 +235,16 @@ static int socket_load(Unit *u) { if ((r = unit_load_related_unit(u, ".service", (Unit**) &s->service))) return r; - if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service))) < 0) + if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service), true)) < 0) return r; } + if ((r = socket_add_mount_links(s)) < 0) + return r; + + if ((r = socket_add_device_link(s)) < 0) + return r; + if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0) return r; @@ -251,7 +335,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { if (!s->exec_command[c]) continue; - fprintf(f, "%s→ %s:\n", + fprintf(f, "%s-> %s:\n", prefix, socket_exec_command_to_string(c)); exec_command_dump_list(s->exec_command[c], f, prefix2); @@ -448,8 +532,9 @@ static int socket_watch_fds(Socket *s) { if (p->fd < 0) continue; - p->fd_watch.data.socket_accept = + p->fd_watch.socket_accept = s->accept && + p->type == SOCKET_SOCKET && socket_address_can_accept(&p->address); if ((r = unit_watch_fd(UNIT(s), p->fd, EPOLLIN, &p->fd_watch)) < 0) @@ -496,7 +581,7 @@ static void socket_set_state(Socket *s, SocketState state) { socket_close_fds(s); if (state != old_state) - log_debug("%s changed %s → %s", + log_debug("%s changed %s -> %s", s->meta.id, socket_state_to_string(old_state), socket_state_to_string(state)); @@ -572,6 +657,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { argv, &s->exec_context, NULL, 0, + s->meta.manager->environment, true, true, UNIT(s)->meta.manager->confirm_spawn, @@ -661,7 +747,7 @@ static void socket_enter_signal(Socket *s, SocketState state, bool success) { } } - if (sent) { + if (sent && s->control_pid > 0) { if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) goto fail; @@ -1088,7 +1174,7 @@ static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { goto fail; } - if (w->data.socket_accept) { + if (w->socket_accept) { for (;;) { if ((cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK)) < 0) { @@ -1104,7 +1190,6 @@ static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { } } - log_debug("cfd=%i", cfd); socket_enter_running(s, cfd); return;