Andrey Borzenkov wrote:
В Wed, 02 Jan 2013 02:28:19 -0700
JB <gene...@itpsg.com> пишет:
Here's the service file:
*******************************************
[Unit]
Description=Webrick Test Service
After=network.target
[Service]
Type=forking
ExecStart=/usr/bin/ruby /home/rtuser/test.rb
[Install]
WantedBy=multi-user.target
*******************************************
I put this in /etc/systemd/system/webrickd.service
Then ran systemctl --system daemon-reload
Then ran systemctl start webrickd.service
Running it from the command line runs as it should. Web server starts
and test.rb is running in the background as a daemon returning me back
to the shell.
But as soon as I try to use systemd, it starts but as soon as the
WEBrick::Daemon.start call is made, everything is killed.
That is because of ...
webrickd.service - Webrick Test Service
Loaded: loaded (/etc/systemd/system/webrickd.service)
Active: inactive (dead) since Wed, 02 Jan 2013 01:23:01 -0700;
9min ago
Process: 1605 ExecStart=/usr/bin/ruby /home/rtuser/test.rb
(code=exited, status=0/SUCCESS)
Main PID: 1607 (code=exited, status=0/SUCCESS)
^^^^^^
CGroup: name=systemd:/system/webrickd.service
You daemon forks too much. This would be a problem with some of
implementations of initscript as well. Even worse, it may sometimes
work due to race condition and sometimes it may fail.
As far as I know, it forks once. You sure it forks "too much?" I
should pull an strace just to see exactly how many times it's forking so
I can be sure. Who decided how much forking was too much? Pretty sure
that's always been a "feature" of unix to be used at the discretion of
the programmer. Albeit an expensive one but a feature nonetheless. Not
trying to argue but I'm hoping you see my point. Systemd decided that
it would by default *only* allow daemon processes to fork once, yet
accommodate through special configuration (RemainAfterExit) what I would
consider normal unix programming behavior? Init doesn't care how many
times you fork because it's flexible that way. Now systemd came along
and decided that was somehow a programming error?
I'm really trying to understand systemd but it is times like this when
do long for the simpler days of init.
initscripts often hide design or programming errors when systemd makes
them obvious. Do not shoot the messenger.
Not interested in shooting anyone but I am interested in the
interpretation of "programming error." Seems like you're assuming the
systemd assumptions and paradigm are perfect. Pretty sure Unix never
dictated default forking limits, at least not until things like fork
bombs came about and security issues were considered. Forking more than
once could hardly be considered a programming error. I think systemd
folks came up with that one all by themselves :) My point is that
assuming systemd's default allow one fork approach is "pure" and then
passing the rigid inflexibility off as design flaws and programming
errors on the part of daemon developers, IMHO goes too far.
If someone could tell me the "right way" to make this work with systemd,
I would love to use it but I've been at this on and off for weeks and it
isn't getting any easier. From my perspective systemd appears rigid and
quite unforgiving. I can't call it buggy yet because I don't know that
I've found any but it sure doesn't seem nearly as simple and easy to get
something running at startup as the documentation would have me believe.
Currently systemd assumes "one service - one main process" model. This
process - main process - represents service for systemd. Service is
alive as long as it runs. When process exits (or terminates) systemd
considers service stopped (gracefully or ungracefully - it is another
matter).
Systemd also expects that program does what you say it does. When you
say that service is "simple" it expects that process is started and does
not fork. If you say that service is "forking" it expects that process
forks exactly once and child remains. It does not expect that child
itself forks yet again and exits.
That's what I meant when I said I tried "Simple." I took out all
daemonize calls. Started ruby and made just one call to server.start
using only an instance of WEBrick::HTTPServer (confirming it did not
form) and it still failed. Although I just tried it again with the over
simplified example I had in my previous email and it worked. I'm now
going to have to figure out what else this ruby beast is doing that
systemd doesn't like but if I find out it's another "normally supported"
feature of Unix that systemd decided is no good it'll be very
frustrating. I'm not saying systemd is bad, but rather a little more on
the inflexible side than I'd prefer. It seems to force a bit more
default big-brother type behavior than I like. Flexibility is one of
the things that has always drawn me to Unix.
So, if I proceed using "Simple" and then later as a result of one of the
web service calls made to the server either use fork/exec or system() to
launch another process that runs for anywhere from 30 seconds to several
hours, then that process exits but not the one that originally started,
will systemd have a problem with that?
In your case obvious workaround is to declare RemainAfterExit=true. In
this case systemd will not consider service dead as soon as main
process exited as long as it did not fail (i.e. exit code was 0).
That may work as well. I'm fine with Simple and not daemonizing
anything. It does simplify my code which is nice, but it won't be worth
it if it imposes restrictions on what the process can do after it's
running in order for systemd to stay happy with it.
Does your daemon need to keep internal state between different HTTP
requests? If not, you could make it to be socket-activated on demand.
Yes, unfortunately it does.
_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel