[systemd-devel] Antw: [EXT] [systemd‑devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?
Wouldn't the most logical solution be?: Integrate that backup facility in your daemon (like before terminating). >>> Klaus Ebbe Grue schrieb am 07.10.2022 um 09:24 in Nachricht <91a90e97f41a4da3b7f716727262d...@di.ku.dk>: > Hi systemd‑devel, > > I have a user question which I take the liberty to send here since "about > systemd‑devel" says "... it's also OK to direct user questions to this mailing > list ...". > > I have a daemon, /usr/bin/mydaemon, which listens on one and only one TCP > port, say , and which does no more than communicating over and > creating, reading, writing and deleting files in /home/me/mydaemon/. > > Mydaemon leaves it to systemd to create a socket which listens at . > > It is unimportant whether or not mydaemon is started at boot and it is also > unimportant whether or not mydaemon is socket activated. As long as it is at > least one of the two. > > Now I want to upgrade mydaemon to a new version using a script, without race > conditions and without closing the listening socket. I want the listening > socket to stay open since otherwise there can be a one minute interval during > which it is impossible to reopen . > > If it is just a clean upgrade, the script could replace /usr/bin/mydaemon, > then stop mydaemon. If the daemon is socket activated there is no more to do. > If the daemon is activated only on boot then the script must end up > restarting mydaemon. > > But now I want to do some more while mydaemon is not running. It could be > that my script should take a backup of /home/me/mydaemon/ in case things go > wrong. It could be the script should translate some file in > /home/me/mydaemon/ to some new format required by the new mydaemon or > whatever. > > So I need to stop mydaemon in such a way that mydaemon cannot wake up while > my script fiddles with /home/me/mydaemon/. > > According to https://0pointer.de/blog/projects/three‑levels‑of‑off it seems > that that was possible in 2011: just do "systemctl disable mydaemon.service". > But when I try that, mydaemon still wakes up if I connect to using eg > netcat. > > I have also tried to mask mydaemon. But if I then connect to using > netcat, then netcat gets kicked of. And if I try again then is no longer > listening. > > QUESTION: Is it possible to let systemd create a listening socket and yet be > able to have that socket activate nothing, at least temporarily? > > Cheers, > Klaus
Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?
Hi Lennart, > Can't you run your upgrade script in idempotent way as a helper > service that is pulled in by your main daemon and ordered before it, > but conditions itself out if it already did its job? that's usually > the most robust way, since then it's sufficient to just restart your > daemon or reboot, and everything will always catch up correctly. > i.e. if you have foo-daemon.socket + foo-daemon.service then define > foo-upgrade.service that is pulled in from foo-daemon.service via > `Wants=foo-upgrade.service` + `After=foo-upgrade.service`. And then > add `ConditionFileExists=!/some/touch/file` to `foo-upgrade.service` to > make it a NOP if things have already been updated, using a touch > file. (some better, smarter condition check might work as well, see > man pages of things systemd can check for you). That is a great pattern! A Type=oneshot seems useful for the upgrade process. For the record, I have appended what ended up working. Thanks! Cheers, Klaus --- The following three unit files open a listening socket, run the myupgrade service, and only then start the /usr/bin/mydaemon service. The socket listens while the myupgrade service runs so that clients can connect. But the clients are queued until myupgrade has finished and /usr/bin/mydaemon starts accepting connections. mydeamon.service: [Unit] Description=service that does something After=mydaemon.socket Requires=mydaemon.socket After=myupgrade.service Wants=myupgrade.service [Install] WantedBy=multi-user.target [Service] Type=simple ExecStart=/usr/bin/mydaemon myupgrade.service: [Unit] Description=service to run before mydaemon [Service] Type=oneshot ExecStart=/usr/bin/bash -c "echo goodnight;sleep 60;echo goodmorning" mydeamon.socket [Unit] Description=mydaemon listen socket [Socket] ListenStream= [Install] WantedBy=sockets.target
Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?
On Fr, 07.10.22 07:24, Klaus Ebbe Grue (g...@di.ku.dk) wrote: > Hi systemd-devel, > > I have a user question which I take the liberty to send here since > "about systemd-devel" says "... it's also OK to direct user > questions to this mailing list ...". > > I have a daemon, /usr/bin/mydaemon, which listens on one and only > one TCP port, say , and which does no more than communicating > over and creating, reading, writing and deleting files in > /home/me/mydaemon/. > > Mydaemon leaves it to systemd to create a socket which listens at > . > > It is unimportant whether or not mydaemon is started at boot and it > is also unimportant whether or not mydaemon is socket activated. As > long as it is at least one of the two. > > Now I want to upgrade mydaemon to a new version using a script, > without race conditions and without closing the listening socket. I > want the listening socket to stay open since otherwise there can be > a one minute interval during which it is impossible to reopen . > > If it is just a clean upgrade, the script could replace > /usr/bin/mydaemon, then stop mydaemon. If the daemon is socket > activated there is no more to do. If the daemon is activated only on > boot then the script must end up restarting mydaemon. > > But now I want to do some more while mydaemon is not running. It > could be that my script should take a backup of /home/me/mydaemon/ > in case things go wrong. It could be the script should translate > some file in /home/me/mydaemon/ to some new format required by the > new mydaemon or whatever. > > So I need to stop mydaemon in such a way that mydaemon cannot wake > up while my script fiddles with /home/me/mydaemon/. > > According to https://0pointer.de/blog/projects/three-levels-of-off > it seems that that was possible in 2011: just do "systemctl disable > mydaemon.service". But when I try that, mydaemon still wakes up if I > connect to using eg netcat. Well, that's a misunderstanding... > I have also tried to mask mydaemon. But if I then connect to > using netcat, then netcat gets kicked of. And if I try again then > is no longer listening. > > QUESTION: Is it possible to let systemd create a listening socket > and yet be able to have that socket activate nothing, at least > temporarily? Can't you run your upgrade script in idempotent way as a helper service that is pulled in by your main daemon and ordered before it, but conditions itself out if it already did its job? that's usually the most robust way, since then it's sufficient to just restart your daemon or reboot, and everything will always catch up correctly. i.e. if you have foo-daemon.socket + foo-daemon.service then define foo-upgrade.service that is pulled in from foo-daemon.service via `Wants=foo-upgrade.service` + `After=foo-upgrade.service`. And then add `ConditionFileExists=!/some/touch/file` to `foo-upgrade.service` to make it a NOP if things have already been updated, using a touch file. (some better, smarter condition check might work as well, see man pages of things systemd can check for you). Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?
Hi Mantas, Thanks for the suggestion. I will take a look at it. When i do not want to do int flag=1; int rv=setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag)); the central problem will be to avoid the 1 minute delay Cheers, Klaus Fra: Mantas Mikulėnas Sendt: 7. oktober 2022 09:51 Til: Klaus Ebbe Grue Cc: systemd-devel@lists.freedesktop.org Emne: Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily? You don't often get email from graw...@gmail.com. Learn why this is important<https://aka.ms/LearnAboutSenderIdentification> On Fri, Oct 7, 2022 at 10:24 AM Klaus Ebbe Grue mailto:g...@di.ku.dk>> wrote: Hi systemd-devel, I have a user question which I take the liberty to send here since "about systemd-devel" says "... it's also OK to direct user questions to this mailing list ...". I have a daemon, /usr/bin/mydaemon, which listens on one and only one TCP port, say , and which does no more than communicating over and creating, reading, writing and deleting files in /home/me/mydaemon/. Mydaemon leaves it to systemd to create a socket which listens at . It is unimportant whether or not mydaemon is started at boot and it is also unimportant whether or not mydaemon is socket activated. As long as it is at least one of the two. Now I want to upgrade mydaemon to a new version using a script, without race conditions and without closing the listening socket. I want the listening socket to stay open since otherwise there can be a one minute interval during which it is impossible to reopen . If it is just a clean upgrade, the script could replace /usr/bin/mydaemon, then stop mydaemon. If the daemon is socket activated there is no more to do. If the daemon is activated only on boot then the script must end up restarting mydaemon. But now I want to do some more while mydaemon is not running. It could be that my script should take a backup of /home/me/mydaemon/ in case things go wrong. It could be the script should translate some file in /home/me/mydaemon/ to some new format required by the new mydaemon or whatever. So I need to stop mydaemon in such a way that mydaemon cannot wake up while my script fiddles with /home/me/mydaemon/. Deploy the new version of your daemon to another location (/home/me/mydaemon.new/), perform all processing/conversions that are necessary, *then* stop the socket, `mv mydaemon mydaemon.old`, stop the service, `mv mydaemon.new mydaemon`, start the socket again. The interval for this will be more like half a second than a minute. -- Mantas Mikulėnas
Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?
Hi Michael, > Unfortunately not. You'd need some kind of "maintenance" mode ... Thanks a lot. I will go with the maintenance mode without fearing to have missed some systemd feature. Cheers, Klaus
Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?
On Fri, Oct 7, 2022 at 10:24 AM Klaus Ebbe Grue wrote: > Hi systemd-devel, > > I have a user question which I take the liberty to send here since "about > systemd-devel" says "... it's also OK to direct user questions to this > mailing list ...". > > I have a daemon, /usr/bin/mydaemon, which listens on one and only one TCP > port, say , and which does no more than communicating over and > creating, reading, writing and deleting files in /home/me/mydaemon/. > > Mydaemon leaves it to systemd to create a socket which listens at . > > It is unimportant whether or not mydaemon is started at boot and it is > also unimportant whether or not mydaemon is socket activated. As long as it > is at least one of the two. > > Now I want to upgrade mydaemon to a new version using a script, without > race conditions and without closing the listening socket. I want the > listening socket to stay open since otherwise there can be a one minute > interval during which it is impossible to reopen . > > If it is just a clean upgrade, the script could replace /usr/bin/mydaemon, > then stop mydaemon. If the daemon is socket activated there is no more to > do. If the daemon is activated only on boot then the script must end up > restarting mydaemon. > > But now I want to do some more while mydaemon is not running. It could be > that my script should take a backup of /home/me/mydaemon/ in case things go > wrong. It could be the script should translate some file in > /home/me/mydaemon/ to some new format required by the new mydaemon or > whatever. > > So I need to stop mydaemon in such a way that mydaemon cannot wake up > while my script fiddles with /home/me/mydaemon/. > Deploy the new version of your daemon to another location (/home/me/mydaemon.new/), perform all processing/conversions that are necessary, *then* stop the socket, `mv mydaemon mydaemon.old`, stop the service, `mv mydaemon.new mydaemon`, start the socket again. The interval for this will be more like half a second than a minute. -- Mantas Mikulėnas
Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?
Am Fr., 7. Okt. 2022 um 09:24 Uhr schrieb Klaus Ebbe Grue : > QUESTION: Is it possible to let systemd create a listening socket and yet be > able to have that socket activate nothing, at least temporarily? Unfortunately not. You'd need some kind of "maintenance" mode you could put a service in, where systemd would keep the socket open but just queues the requests until the service is put out of maintenance mode again. There is no such feature atm although I would have found that useful for Debian as well (during package upgrades). The best you can currently do is probably to stop the .socket to avoid accidental activation during the upgrade.
[systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?
Hi systemd-devel, I have a user question which I take the liberty to send here since "about systemd-devel" says "... it's also OK to direct user questions to this mailing list ...". I have a daemon, /usr/bin/mydaemon, which listens on one and only one TCP port, say , and which does no more than communicating over and creating, reading, writing and deleting files in /home/me/mydaemon/. Mydaemon leaves it to systemd to create a socket which listens at . It is unimportant whether or not mydaemon is started at boot and it is also unimportant whether or not mydaemon is socket activated. As long as it is at least one of the two. Now I want to upgrade mydaemon to a new version using a script, without race conditions and without closing the listening socket. I want the listening socket to stay open since otherwise there can be a one minute interval during which it is impossible to reopen . If it is just a clean upgrade, the script could replace /usr/bin/mydaemon, then stop mydaemon. If the daemon is socket activated there is no more to do. If the daemon is activated only on boot then the script must end up restarting mydaemon. But now I want to do some more while mydaemon is not running. It could be that my script should take a backup of /home/me/mydaemon/ in case things go wrong. It could be the script should translate some file in /home/me/mydaemon/ to some new format required by the new mydaemon or whatever. So I need to stop mydaemon in such a way that mydaemon cannot wake up while my script fiddles with /home/me/mydaemon/. According to https://0pointer.de/blog/projects/three-levels-of-off it seems that that was possible in 2011: just do "systemctl disable mydaemon.service". But when I try that, mydaemon still wakes up if I connect to using eg netcat. I have also tried to mask mydaemon. But if I then connect to using netcat, then netcat gets kicked of. And if I try again then is no longer listening. QUESTION: Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily? Cheers, Klaus