enhancement: systemd socket activation, service and target files
Context
I wanted to set up service for occasional testing across 5 computers in home network, xinetd/inetd style, but systemd is the new way of doing things. A bit of reading here http://0pointer.de/blog/projects/socket-activation2.html suggests its not too hard, but its always easier to ask first.
- Version of iperf3:
3.5. But I searched issues for systemd, which any feature request would refer to. And this premature submission was accidental... updating incrementally..
- Hardware:
linux on x86 & rpi
- Operating system (and distribution, if any):
Name : iperf3 Version : 3.5 Release : 1.fc28 Architecture: x86_64 Install Date: Thu 24 May 2018 02:51:33 PM MDT
Enhancement Request
- Current behavior
xinetd operation works iirc (tried many years ago). I think this means that systemd compatibility is close to trivial.
- Desired behavior
use socket opened by systemd then various systemd features can help workaround other bugs (like too many open files) where wait/nowait (inetd vocabulary) can fix.
- Implementation notes
http://0pointer.de/blog/projects/socket-activation.html http://0pointer.de/blog/projects/socket-activation2.html
Thanks for the suggestion. Does contrib/iperf3.service not do what you need?
a .service file alone hardly is enough for socket activation, you need a .socket file and the dameon must suport it, just read the links above - the point is that PID1 ist listening and starts the process on-demand and handover the socket connection and when all works perfectly stops the .service unit when it's no longer used so that no process is running idle
to make it clear: that below is a dead simple (in that case udp) service using the systemd-socket
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <systemd/sd-daemon.h> #define MAXLINE 1024 int main() { if(sd_listen_fds(0) != 1) { fprintf(stderr, "No or too many file descriptors received\n"); exit(EXIT_FAILURE); } int len; int sockfd; char buffer[MAXLINE]; char *pong = "PONG\n"; struct sockaddr_in6 servaddr, cliaddr; sockfd = SD_LISTEN_FDS_START + 0; memset(&servaddr, 0, sizeof(servaddr)); memset(&cliaddr, 0, sizeof(cliaddr)); while(1) { recvfrom(sockfd, (char *)buffer, MAXLINE, MSG_WAITALL, (struct sockaddr *) &cliaddr, &len); sendto(sockfd, (const char *)pong, strlen(pong), MSG_CONFIRM, (const struct sockaddr *) &cliaddr, len); } }