Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

J Mo
Package: sysvinit-utils
Version: 2.88dsf-59.3
Severity: important

The last line of /lib/init/init-d-script is "exit 0".

That can't be right, can it? This overrides all other valid return codes which could be provided by the script. In almost all cases, even errors, $? is going to be 0.




-- System Information:
Debian Release: stretch/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 4.3.0-1-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)

Versions of packages sysvinit-utils depends on:
ii  init-system-helpers  1.29
ii  libc6                2.22-7
ii  startpar             0.59-3

sysvinit-utils recommends no packages.

Versions of packages sysvinit-utils suggests:
pn  bootlogd  <none>
pn  sash      <none>

-- no debconf information

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Dmitry Bogatov-3

[2016-04-26 23:41] J Mo <[hidden email]>
> Package: sysvinit-utils
> Version: 2.88dsf-59.3
> Severity: important
>
> The last line of /lib/init/init-d-script is "exit 0".

> That can't be right, can it? This overrides all other valid return
> codes which could be provid ed by the script. In almost all cases,
> even errors, $? is going to be 0.

I do agree, that this line looks strange. It was introduced at commit
`f611a05d16b3094139c2ea540817c00bdf93347a' with following comment:

        Make sure init-d-script exit at the end, to make sure init.d
        script is only sourced once.

at 20 Feb 2014. Dear co-maintainers, do you understand (or remember),
what is going on?

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Benda Xu-3
Hi Petter,

Dmitry Bogatov <[hidden email]> writes:

> I do agree, that this line looks strange. It was introduced at commit
> `f611a05d16b3094139c2ea540817c00bdf93347a' with following comment:
>
> Make sure init-d-script exit at the end, to make sure init.d
> script is only sourced once.
>
> at 20 Feb 2014. Dear co-maintainers, do you understand (or remember),
> what is going on?

Do you think init-d-script unconditionally returning 0 is a typo?
Should it be `exit $?` instead?

Yours,
Benda

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Petter Reinholdtsen

Hi Brenda,

[Benda Xu]
> Do you think init-d-script unconditionally returning 0 is a typo?
> Should it be `exit $?` instead?

Not quite sure, but as far as I know, the init.d scripts do not have a
standard for exit codes.  There is no use of exit codes from init.d
scripts in /etc/init.d/rc.  Error handling and reporting during start
and stop is supposed to take place within the init.d script itself, not
passed on to the caller as an exit code.

With that background, it is no reason not to always return 0 unless
incorrect arguments are used on the command line.

As /etc/init.d/rc is not running with 'set -e', it do not really matter
if the scripts exit with an error code.

--
Happy hacking
Petter Reinholdtsen

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Dmitry Bogatov-3
In reply to this post by J Mo

control: reopen -1

[2018-11-15 18:02] Benda Xu <[hidden email]>

> Petter Reinholdtsen <[hidden email]> writes:
>
> > [Benda Xu]
> >> Do you think init-d-script unconditionally returning 0 is a typo?
> >> Should it be `exit $?` instead?
> >
> > Not quite sure, but as far as I know, the init.d scripts do not have a
> > standard for exit codes.  There is no use of exit codes from init.d
> > scripts in /etc/init.d/rc.  Error handling and reporting during start
> > and stop is supposed to take place within the init.d script itself, not
> > passed on to the caller as an exit code.
> > [...]
> Nice explanation, thank you indeed.  So it actually does not matter what
> it returns from init-d-script.  I think we could close this bug for the
> moment.

Wait, no. There is. See #427889 and policy 9.3.2. By the way, seems
#427889 could be closed...

Also, by just common sence, program that return 0 in case of failure is
bad, very bad.  What if I want to call /etc/init.d/{foo} in my own
script?

There are scripts around, that pass exit code {rc.local, hostname}; there
are scripts around, that do not (random example - wicd).

So either we

 * violate LSB and adjust all initscripts to return 0 always.
   I strongly oppose.

 * consider script, that swallows exit code to be buggy. I support it,
   but there is a lot of scripts in wild that do so. I do /not/ volonteer
   to fix them.

All in all, let us remove last line in `init-d-script'.

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Ian Jackson-2
In reply to this post by J Mo
(re-sending with un-mangled bug address)

Dmitry Bogatov writes ("Re: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes"):
> Wait, no. There is. See #427889 and policy 9.3.2. By the way, seems
> #427889 could be closed...
>
> Also, by just common sence, program that return 0 in case of failure is
> bad, very bad.  What if I want to call /etc/init.d/{foo} in my own
> script?

A related question has been discussed in the Debian TC,

  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=904558
  What should happen when maintscripts fail to restart a service

It seems that the likely consensus there will be that at least some of
the time, a postinst ought to fail when the daemon fails to start.
Since the daemon is usually started by running the init script, that
means the init script must report a useful exit status.

> So either we
>
>  * violate LSB and adjust all initscripts to return 0 always.
>    I strongly oppose.

I don't think we should do this.  So, I agree.

>  * consider script, that swallows exit code to be buggy. I support it,
>    but there is a lot of scripts in wild that do so. I do /not/ volonteer
>    to fix them.

I agree with this.

> All in all, let us remove last line in `init-d-script'.

I haven't looked at this.  Are you happy for me to take your word for
how to implement what you suggest, or do you want me to do a code
review ?

Regards,
Ian.

--
Ian Jackson <[hidden email]>   These opinions are my own.

If I emailed you from an address @fyvzl.net or @evade.org.uk, that is
a private address which bypasses my fierce spamfilter.

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Petter Reinholdtsen
In reply to this post by J Mo
[Dmitry Bogatov]
> Can you please elaborate, what exactly would break? Probably there is
> better solution for those issues that just swallowing error codes.

I do not remember the details any more, but after reading the git
history I have vague memories of having to add the exit calls to ensure
scripts loaded via /lib/lsb/init-functions.d/ did not break.  Possibly
and probably related to systemd integration at the time.

This is the relevant commit:

commit f611a05d16b3094139c2ea540817c00bdf93347a
Author: Petter Reinholdtsen <[hidden email]>
Date:   Thu Feb 20 13:03:07 2014 +0100

    Make sure init-d-script exit at the end, to make sure init.d script
    is only sourced once.

It was added only 10 days after the script was introduced in git, so I
guess the error was fairly obvious but not triggered with every script.
Perhaps only for scripts where there is no systemd service?

--
Happy hacking
Petter Reinholdtsen

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Jonathan de Boyne Pollard
In reply to this post by J Mo
Dmitry Bogatov:

> Can you please elaborate, what exactly would break?
>

Look at the way that the init-d-script script is used.  It isn't used as
the interpreter of an rc script.  (Your manual needs fixing to show the
correct way to invoke it, by the way.)  It is invoked as:

> #!/bin/sh
> if [ true != "$INIT_D_SCRIPT_SOURCED" ] ; then
>     set "$0" "$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
> fi
>

init-d-script proceeds to source the script that sourced it. Consider
what happens if its final action is not to exit $? .  The shell returns
to the original rc script, and runs the rest of it *again*.  This
wouldn't be a problem if rc scripts were purely pseudo-declarative, as
it would just run some variable assignments and function definitions a
second time.  But in reality people are writing rc scripts like these,
cargo-cult style:

*
https://raw.githubusercontent.com/Sean-Der/fail2rest/master/init-scripts/debian.sh

* https://askubuntu.com/questions/1053107/

* https://forum.ubuntu.ru/index.php?topic=281688.msg2217941#msg2217941

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Michael Biebl-3
On Tue, 20 Nov 2018 10:15:33 +0000 Jonathan de Boyne Pollard
<[hidden email]> wrote:

> Dmitry Bogatov:
>
> > Can you please elaborate, what exactly would break?
> >
>
> Look at the way that the init-d-script script is used.  It isn't used as
> the interpreter of an rc script.  (Your manual needs fixing to show the
> correct way to invoke it, by the way.)  It is invoked as:
>
> > #!/bin/sh
> > if [ true != "$INIT_D_SCRIPT_SOURCED" ] ; then
> >     set "$0" "$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
> > fi
> >
>
> init-d-script proceeds to source the script that sourced it. Consider
> what happens if its final action is not to exit $? .  The shell returns
> to the original rc script, and runs the rest of it *again*.  This
> wouldn't be a problem if rc scripts were purely pseudo-declarative, as
> it would just run some variable assignments and function definitions a
> second time.  But in reality people are writing rc scripts like these,
> cargo-cult style:
fwiw, this is why I suggested to provide a C implementation of
init-d-script which can be used as an interpreter

See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=913247

I consider the usage of /usr/bin/env only a kludge and hope the
maintainers of /lib/init/init-d-script do reconsider, i.e. I don't
consider #913247 to be solved.

Regards,
Michael


--
Why is it that all of the instruments seeking intelligent life in the
universe are pointed away from Earth?


signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Dmitry Bogatov-3
In reply to this post by Jonathan de Boyne Pollard
[2018-11-20 10:15] Jonathan de Boyne Pollard <[hidden email]>
>
> part       text/plain                1073
> Dmitry Bogatov:
>
> > Can you please elaborate, what exactly would break?
>
> Look at the way that the init-d-script script is used.  It isn't used as
> the interpreter of an rc script.  (Your manual needs fixing to show the
> correct way to invoke it, by the way.)

I believe I already wrote in init-d-script(5) correct invocation:

        #!/usr/bin/env /lib/init/init-d-script

> It is invoked as:
> > #!/bin/sh
> > if [ true != "$INIT_D_SCRIPT_SOURCED" ] ; then
> >     set "$0" "$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
> > fi

True, many do it this way.

> init-d-script proceeds to source the script that sourced it. Consider
> what happens if its final action is not to exit $?.  The shell returns
> to the original rc script, and runs the rest of it *again*.  This
> wouldn't be a problem if rc scripts were purely pseudo-declarative, as
> it would just run some variable assignments and function definitions a
> second time.  But in reality people are writing rc scripts like these,
> cargo-cult style:

I do not object `exit $?'. But last line of `init-d-script' is `exit 0'.

But thank you for your explanation. Now I agrue to change `exit 0' to
`exit $?'.

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Ian Jackson-2
In reply to this post by Michael Biebl-3
Michael Biebl writes ("Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes"):
> I consider the usage of /usr/bin/env only a kludge

Are there practical problems with use of /usr/bin/env this way ?  This
is a very traditional technique for solving these kind of problems and
IME generally it works well.

I don't foresee any difficult-to-resolve problems with the env
technique, but maybe I don't have the right knowledge.

Ian.

--
Ian Jackson <[hidden email]>   These opinions are my own.

If I emailed you from an address @fyvzl.net or @evade.org.uk, that is
a private address which bypasses my fierce spamfilter.

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Dmitry Bogatov-3
In reply to this post by Michael Biebl-3

[2018-11-20 21:25] Michael Biebl <[hidden email]>
> fwiw, this is why I suggested to provide a C implementation of
> init-d-script which can be used as an interpreter
>
> See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=913247
>
> I consider the usage of /usr/bin/env only a kludge and hope the
> maintainers of /lib/init/init-d-script do reconsider, i.e. I don't
> consider #913247 to be solved.

I consider extra 13 chars in shebang to be less sacrifice for kFreeBSD
compatibility then need to write and maintain extra C program. Line
added, line spent.

By the way, what is your resolution about changes I proposed

        https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=913247#45

in regard systemctl forwarding?

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Jonathan de Boyne Pollard
In reply to this post by Michael Biebl-3
Michael Biebl:
> fwiw, this is why I suggested to provide a C implementation of
> init-d-script which can be used as an interpreter

That's how it was addressed in 2007.

*
https://github.com/OpenRC/openrc/commit/5af58b45146ab5253ca964738f4e45287bf963d4

*
http://www.chiark.greenend.org.uk/pipermail/debian-init-diversity/2018-November/000340.html

The OpenRC people have already learned many of the lessons through
experience here, long since.  There are the difficulties in handling rc
scripts that people have symbolically linked to a common worker script,
for example.  They also went through the exit code of the interpreter
thing in a minor way with exit 0 when starting a service in 2008 and
again in more detail in 2011.

* https://bugs.gentoo.org/show_bug.cgi?id=351160

Reply | Threaded
Open this post in threaded view
|

Bug#822753: /lib/init/init-d-script: exit 0 at end of script prevents all other exit codes

Jonathan de Boyne Pollard
In reply to this post by J Mo
Dmitry Bogatov:

> I believe I already wrote in init-d-script(5) correct invocation:
> #!/usr/bin/env /lib/init/init-d-script
>
That's not what was in the skeleton that you just got rid of; which had
more attention paid to it than the example in the manual page had, I
suspect.

The next portability bump on this road, discussed many times over the
years, is to hit platforms where env is not in /usr/bin.  This is not
the case with Debian operating systems, though, fortunately.  And I
doubt that you'll have many dealings with FreeBSD kernels from before
2005, where the #! mechanism was more like MacOS.  (-:

* https://unix.stackexchange.com/questions/29608/

* https://unix.stackexchange.com/questions/111802/

* https://unix.stackexchange.com/questions/361794/