[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?

2022-10-18 Thread Ulrich Windl
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?

2022-10-11 Thread Klaus Ebbe Grue
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?

2022-10-10 Thread Lennart Poettering
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?

2022-10-07 Thread Klaus Ebbe Grue
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,,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

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?

2022-10-07 Thread Klaus Ebbe Grue
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?

2022-10-07 Thread Mantas Mikulėnas
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?

2022-10-07 Thread Michael Biebl
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?

2022-10-07 Thread Klaus Ebbe Grue
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