X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsocket.c;h=94991a35f58fc068982b6c1b01ea9224579d060f;hb=f4c0514703d3f8cca215ee1ecde0736a7c007b21;hp=beb328657fe5eb34a5d5eabffb4922f837177872;hpb=da19d5c19f60ec80e1733b1e994311c59c6eda73;p=elogind.git diff --git a/src/socket.c b/src/socket.c index beb328657..94991a35f 100644 --- a/src/socket.c +++ b/src/socket.c @@ -366,7 +366,10 @@ static int socket_load(Unit *u) { return socket_verify(s); } -static const char* listen_lookup(int type) { +static const char* listen_lookup(int family, int type) { + + if (family == AF_NETLINK) + return "ListenNetlink"; if (type == SOCK_STREAM) return "ListenStream"; @@ -477,7 +480,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { else t = k; - fprintf(f, "%s%s: %s\n", prefix, listen_lookup(p->address.type), t); + fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t); free(k); } else fprintf(f, "%sListenFIFO: %s\n", prefix, p->path); @@ -712,7 +715,7 @@ static int fifo_address_create( r = mkfifo(path, socket_mode); umask(old_mask); - if (r < 0) { + if (r < 0 && errno != EEXIST) { r = -errno; goto fail; } @@ -771,8 +774,10 @@ static int socket_open_fds(Socket *s) { return r; if (s->service && s->service->exec_command[SERVICE_EXEC_START]) - if ((r = label_get_socket_label_from_exe(s->service->exec_command[SERVICE_EXEC_START]->path, &label)) < 0) - return r; + if ((r = label_get_socket_label_from_exe(s->service->exec_command[SERVICE_EXEC_START]->path, &label)) < 0) { + if (r != -EPERM) + return r; + } know_label = true; } @@ -1360,15 +1365,19 @@ static int socket_start(Unit *u) { /* Cannot run this without the service being around */ if (s->service) { - if (s->service->meta.load_state != UNIT_LOADED) + if (s->service->meta.load_state != UNIT_LOADED) { + log_error("Socket service %s not loaded, refusing.", s->service->meta.id); return -ENOENT; + } /* If the service is already active we cannot start the * socket */ if (s->service->state != SERVICE_DEAD && s->service->state != SERVICE_FAILED && - s->service->state != SERVICE_AUTO_RESTART) + s->service->state != SERVICE_AUTO_RESTART) { + log_error("Socket service %s already active, refusing.", s->service->meta.id); return -EBUSY; + } #ifdef HAVE_SYSV_COMPAT if (s->service->sysv_path) { @@ -1447,7 +1456,10 @@ static int socket_serialize(Unit *u, FILE *f, FDSet *fds) { if ((r = socket_address_print(&p->address, &t)) < 0) return r; - unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t); + if (socket_address_family(&p->address) == AF_NETLINK) + unit_serialize_item_format(u, f, "netlink", "%i %s", copy, t); + else + unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t); free(t); } else { assert(p->type == SOCKET_FIFO); @@ -1542,6 +1554,25 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value, } } + } else if (streq(key, "netlink")) { + int fd, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd)) + log_debug("Failed to parse socket value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (socket_address_is_netlink(&p->address, value+skip)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + } else log_debug("Unknown serialization key '%s'", key);