Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Debian Kernel (http://www.linux-archive.org/debian-kernel/)
-   -   Bug#590744: Fails to boot if /sbin/init is a symlink (http://www.linux-archive.org/debian-kernel/405478-bug-590744-fails-boot-if-sbin-init-symlink.html)

Michael Biebl 07-29-2010 12:16 AM

Bug#590744: Fails to boot if /sbin/init is a symlink
 
reopen 590744
retitle 590744 Fails to boot if /sbin/init is a non-relative symlink
thanks

On 29.07.2010 01:37, Michael Prokop wrote:
> * Michael Biebl <biebl@debian.org> [Thu Jul 29, 2010 at 01:13:01AM +0200]:
>
>> for testing purposes, I installed the upstart binary as /sbin/upstart and
>> created a symlink /sbin/init → /sbin/upstart
>> This causes a boot failure, due to this check in /usr/share/initramfs-
>> tools/init
>
>> # Check init bootarg
>> if [ -n "${init}" ] && [ ! -x "${rootmnt}${init}" ]; then
>> echo "Target filesystem doesn't have ${init}."
>> init=
>> fi
>
>> To quote Mithrandir (from irc):
>> <Mithrandir> -x follows symlinks
>> <Mithrandir> but that means it'll look for symlinks in the initramfs, so the
>> check is buggy.
>
> You shouldn't use an absolut symlink here, use a relative one instead.
> See Debian policy 10.5 for details.

Well, changing it to /sbin/init -> upstart did indeed work for this particular
case. But I still get the problem when the link is absolute, as is specified by
the policy for symlinks not in the same directory.

To be a bit more specific what I was doing:
I tested the new systemd init system, which installs the binary in /bin/systemd
(note the "/bin"). So I moved /sbin/init from upstart to /sbin/upstart and made
/sbin/init a symlink so I could easily test both systems. Using a relative
symlink for /sbin/upstart does work, but an absolute symlink /sbin/init ->
/bin/systemd does not.
So I'm reopening the bug report and retitling appropriately.

Cheers,
Michael


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

Michael Prokop 07-29-2010 01:01 AM

Bug#590744: Fails to boot if /sbin/init is a symlink
 
* Michael Biebl <biebl@debian.org> [Thu Jul 29, 2010 at 02:16:32AM +0200]:
> On 29.07.2010 01:37, Michael Prokop wrote:
> > * Michael Biebl <biebl@debian.org> [Thu Jul 29, 2010 at 01:13:01AM +0200]:

> >> for testing purposes, I installed the upstart binary as /sbin/upstart and
> >> created a symlink /sbin/init → /sbin/upstart
> >> This causes a boot failure, due to this check in /usr/share/initramfs-
> >> tools/init

> >> # Check init bootarg
> >> if [ -n "${init}" ] && [ ! -x "${rootmnt}${init}" ]; then
> >> echo "Target filesystem doesn't have ${init}."
> >> init=
> >> fi

> >> To quote Mithrandir (from irc):
> >> <Mithrandir> -x follows symlinks
> >> <Mithrandir> but that means it'll look for symlinks in the initramfs, so the
> >> check is buggy.

> > You shouldn't use an absolut symlink here, use a relative one instead.
> > See Debian policy 10.5 for details.

> Well, changing it to /sbin/init -> upstart did indeed work for this particular
> case. But I still get the problem when the link is absolute, as is specified by
> the policy for symlinks not in the same directory.

> To be a bit more specific what I was doing:
> I tested the new systemd init system, which installs the binary in /bin/systemd
> (note the "/bin").

This isn't an existing + available Debian package yet, right?
Why is it installing itself to /bin/systemd? Is it supposed to be
executed by non-root users as well?

> So I moved /sbin/init from upstart to /sbin/upstart and made
> /sbin/init a symlink so I could easily test both systems. Using a relative
> symlink for /sbin/upstart does work, but an absolute symlink /sbin/init ->
> /bin/systemd does not.
> So I'm reopening the bug report and retitling appropriately.

If systemd really uses /bin for a reason we could use something like
the following in initramfs-tools' init:

# Check init bootarg
if [ -n "${init}" ] ; then

# Work around absolute symlinks
initsymlinktarget="${init}"
if [ -d "${rootmnt}" ] && [ -h "${rootmnt}${init}" ] ; then
case $(readlink "${rootmnt}${init}") in /*)
initsymlinktarget=$(chroot "${rootmnt}" readlink "${init}")
;;
esac
fi

if [ ! -x "${rootmnt}${init}" ] || [ ! -x "${rootmnt}${initsymlinktarget}" ] ; then
echo "Target filesystem doesn't have ${init}."
init=
fi
fi

Can you please give that a try?

regards,
-mika-

Michael Biebl 07-30-2010 01:53 AM

Bug#590744: Fails to boot if /sbin/init is a symlink
 
On 29.07.2010 03:01, Michael Prokop wrote:
> * Michael Biebl <biebl@debian.org> [Thu Jul 29, 2010 at 02:16:32AM +0200]:
>> On 29.07.2010 01:37, Michael Prokop wrote:
>>> * Michael Biebl <biebl@debian.org> [Thu Jul 29, 2010 at 01:13:01AM +0200]:
>
>>>> for testing purposes, I installed the upstart binary as /sbin/upstart and
>>>> created a symlink /sbin/init → /sbin/upstart
>>>> This causes a boot failure, due to this check in /usr/share/initramfs-
>>>> tools/init
>
>>>> # Check init bootarg
>>>> if [ -n "${init}" ] && [ ! -x "${rootmnt}${init}" ]; then
>>>> echo "Target filesystem doesn't have ${init}."
>>>> init=
>>>> fi
>
>>>> To quote Mithrandir (from irc):
>>>> <Mithrandir> -x follows symlinks
>>>> <Mithrandir> but that means it'll look for symlinks in the initramfs, so the
>>>> check is buggy.
>
>>> You shouldn't use an absolut symlink here, use a relative one instead.
>>> See Debian policy 10.5 for details.
>
>> Well, changing it to /sbin/init -> upstart did indeed work for this particular
>> case. But I still get the problem when the link is absolute, as is specified by
>> the policy for symlinks not in the same directory.
>
>> To be a bit more specific what I was doing:
>> I tested the new systemd init system, which installs the binary in /bin/systemd
>> (note the "/bin").
>
> This isn't an existing + available Debian package yet, right?

It's in experimental currently.

> Why is it installing itself to /bin/systemd? Is it supposed to be
> executed by non-root users as well?

Indeed. The idea is, that systemd is also started by regular users and helps
track their user session (replacement/extension for e.g. gnome-session)

>> So I moved /sbin/init from upstart to /sbin/upstart and made
>> /sbin/init a symlink so I could easily test both systems. Using a relative
>> symlink for /sbin/upstart does work, but an absolute symlink /sbin/init ->
>> /bin/systemd does not.
>> So I'm reopening the bug report and retitling appropriately.
>
> If systemd really uses /bin for a reason we could use something like
> the following in initramfs-tools' init:
>
> # Check init bootarg
> if [ -n "${init}" ] ; then
>
> # Work around absolute symlinks
> initsymlinktarget="${init}"
> if [ -d "${rootmnt}" ] && [ -h "${rootmnt}${init}" ] ; then
> case $(readlink "${rootmnt}${init}") in /*)
> initsymlinktarget=$(chroot "${rootmnt}" readlink "${init}")
> ;;
> esac
> fi
>
> if [ ! -x "${rootmnt}${init}" ] || [ ! -x "${rootmnt}${initsymlinktarget}" ] ; then
> echo "Target filesystem doesn't have ${init}."
> init=
> fi
> fi

Does not work. For one, I guess this check
if [ ! -x "${rootmnt}${init}" ] || [ ! -x "${rootmnt}${initsymlinktarget}" ] ;

should be using &&.

Even after fixing that, we run into the same problem, later again, at:

# No init on rootmount
if [ ! -x "${rootmnt}${init}" ]; then
panic "No init found. Try passing init= bootarg."
fi

Cheers,
Michael



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

Michael Prokop 07-30-2010 01:57 AM

Bug#590744: Fails to boot if /sbin/init is a symlink
 
* Michael Biebl <biebl@debian.org> [Fri Jul 30, 2010 at 03:53:03AM +0200]:
> On 29.07.2010 03:01, Michael Prokop wrote:
> > * Michael Biebl <biebl@debian.org> [Thu Jul 29, 2010 at 02:16:32AM +0200]:

> > Why is it installing itself to /bin/systemd? Is it supposed to be
> > executed by non-root users as well?

> Indeed. The idea is, that systemd is also started by regular users and helps
> track their user session (replacement/extension for e.g. gnome-session)

Ok.

> >> So I moved /sbin/init from upstart to /sbin/upstart and made
> >> /sbin/init a symlink so I could easily test both systems. Using a relative
> >> symlink for /sbin/upstart does work, but an absolute symlink /sbin/init ->
> >> /bin/systemd does not.
> >> So I'm reopening the bug report and retitling appropriately.

> > If systemd really uses /bin for a reason we could use something like
> > the following in initramfs-tools' init:

> > # Check init bootarg
> > if [ -n "${init}" ] ; then

> > # Work around absolute symlinks
> > initsymlinktarget="${init}"
> > if [ -d "${rootmnt}" ] && [ -h "${rootmnt}${init}" ] ; then
> > case $(readlink "${rootmnt}${init}") in /*)
> > initsymlinktarget=$(chroot "${rootmnt}" readlink "${init}")
> > ;;
> > esac
> > fi

> > if [ ! -x "${rootmnt}${init}" ] || [ ! -x "${rootmnt}${initsymlinktarget}" ] ; then
> > echo "Target filesystem doesn't have ${init}."
> > init=
> > fi
> > fi

> Does not work. For one, I guess this check
> if [ ! -x "${rootmnt}${init}" ] || [ ! -x "${rootmnt}${initsymlinktarget}" ] ;

> should be using &&.

> Even after fixing that, we run into the same problem, later again, at:

> # No init on rootmount
> if [ ! -x "${rootmnt}${init}" ]; then
> panic "No init found. Try passing init= bootarg."
> fi

You have to drop the old "No init on rootmount" stuff of course, so
just replace the "No init on rootmount" part with above code.

regards,
-mika-

Michael Biebl 07-30-2010 02:15 AM

Bug#590744: Fails to boot if /sbin/init is a symlink
 
On 30.07.2010 03:57, Michael Prokop wrote:
> * Michael Biebl <biebl@debian.org> [Fri Jul 30, 2010 at 03:53:03AM +0200]:
>> On 29.07.2010 03:01, Michael Prokop wrote:
>>> * Michael Biebl <biebl@debian.org> [Thu Jul 29, 2010 at 02:16:32AM +0200]:
>
>>> Why is it installing itself to /bin/systemd? Is it supposed to be
>>> executed by non-root users as well?
>
>> Indeed. The idea is, that systemd is also started by regular users and helps
>> track their user session (replacement/extension for e.g. gnome-session)
>
> Ok.
>
>>>> So I moved /sbin/init from upstart to /sbin/upstart and made
>>>> /sbin/init a symlink so I could easily test both systems. Using a relative
>>>> symlink for /sbin/upstart does work, but an absolute symlink /sbin/init ->
>>>> /bin/systemd does not.
>>>> So I'm reopening the bug report and retitling appropriately.
>
>>> If systemd really uses /bin for a reason we could use something like
>>> the following in initramfs-tools' init:
>
>>> # Check init bootarg
>>> if [ -n "${init}" ] ; then
>
>>> # Work around absolute symlinks
>>> initsymlinktarget="${init}"
>>> if [ -d "${rootmnt}" ] && [ -h "${rootmnt}${init}" ] ; then
>>> case $(readlink "${rootmnt}${init}") in /*)
>>> initsymlinktarget=$(chroot "${rootmnt}" readlink "${init}")
>>> ;;
>>> esac
>>> fi
>
>>> if [ ! -x "${rootmnt}${init}" ] || [ ! -x "${rootmnt}${initsymlinktarget}" ] ; then
>>> echo "Target filesystem doesn't have ${init}."
>>> init=
>>> fi
>>> fi
>
>> Does not work. For one, I guess this check
>> if [ ! -x "${rootmnt}${init}" ] || [ ! -x "${rootmnt}${initsymlinktarget}" ] ;
>
>> should be using &&.
>
>> Even after fixing that, we run into the same problem, later again, at:
>
>> # No init on rootmount
>> if [ ! -x "${rootmnt}${init}" ]; then
>> panic "No init found. Try passing init= bootarg."
>> fi
>
> You have to drop the old "No init on rootmount" stuff of course, so
> just replace the "No init on rootmount" part with above code.

I think this check is required if "# Search for valid init" does not find a
valid init?

Besides, I noticed that if no valid init is found, I get a kernel panic, but I
assume I should get a rescue shell.

I also noticed, that initsymlinktarget is set (ie. we run and expensive chroot
call), even if I pass init=/bin/systemd on the kernel command line.

Michael


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

Michael Biebl 07-30-2010 02:26 AM

Bug#590744: Fails to boot if /sbin/init is a symlink
 
On 30.07.2010 04:15, Michael Biebl wrote:

>
> Besides, I noticed that if no valid init is found, I get a kernel panic, but I
> assume I should get a rescue shell.

I guess this might be due to the following:
# Search for valid init
if [ -z "${init}" ] ; then
for init in /sbin/init /etc/init /bin/init /bin/sh; do
if [ ! -x "${rootmnt}${init}" ]; then
continue
fi
break
done
fi

Upstart stores its configuration files in /etc/init/. This means, the loop above
exits at /etc/init, and the init variable is set to the /etc/init directory.
Is there a good resp. historical reason to search for init in /etc (or /bin ftm)?




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

Michael Prokop 07-30-2010 02:44 AM

Bug#590744: Fails to boot if /sbin/init is a symlink
 
* Michael Biebl <biebl@debian.org> [Fri Jul 30, 2010 at 04:26:16AM +0200]:
> On 30.07.2010 04:15, Michael Biebl wrote:

> > Besides, I noticed that if no valid init is found, I get a kernel panic, but I
> > assume I should get a rescue shell.

> I guess this might be due to the following:
> # Search for valid init
> if [ -z "${init}" ] ; then
> for init in /sbin/init /etc/init /bin/init /bin/sh; do
> if [ ! -x "${rootmnt}${init}" ]; then
> continue
> fi
> break
> done
> fi

> Upstart stores its configuration files in /etc/init/.

D'oh.

> This means, the loop above exits at /etc/init, and the init
> variable is set to the /etc/init directory. Is there a good resp.
> historical reason to search for init in /etc (or /bin ftm)?

The kernel uses /sbin/init, /etc/init, /bin/init and /bin/sh
for its run_init_process().

regards,
-mika-

Michael Prokop 07-30-2010 04:21 AM

Bug#590744: Fails to boot if /sbin/init is a symlink
 
* Michael Biebl <biebl@debian.org> [Fri Jul 30, 2010 at 04:15:44AM +0200]:
> On 30.07.2010 03:57, Michael Prokop wrote:

> >> Does not work. For one, I guess this check
> >> if [ ! -x "${rootmnt}${init}" ] || [ ! -x "${rootmnt}${initsymlinktarget}" ] ;

> >> should be using &&.

> >> Even after fixing that, we run into the same problem, later again, at:

> >> # No init on rootmount
> >> if [ ! -x "${rootmnt}${init}" ]; then
> >> panic "No init found. Try passing init= bootarg."
> >> fi

> > You have to drop the old "No init on rootmount" stuff of course, so
> > just replace the "No init on rootmount" part with above code.

[...]
> I also noticed, that initsymlinktarget is set (ie. we run and expensive chroot
> call), even if I pass init=/bin/systemd on the kernel command line.

No, initsymlinktarget is set to $init, but evaluated only if
${rootmnt}${init} is a symlink.

Can you please give the following snapshot version a try:

http://people.debian.org/~mika/initramfs-tools/initramfs-tools_0.97.3~1.gbp8d572e_all.deb

(sha1sum and gpg-signed sha1sum in the same directory) and report
back whether this works for all the situations you expect to work?

regards,
-mika-

Michael Biebl 07-30-2010 09:31 AM

Bug#590744: Fails to boot if /sbin/init is a symlink
 
On 30.07.2010 06:21, Michael Prokop wrote:

>
> Can you please give the following snapshot version a try:
>
> http://people.debian.org/~mika/initramfs-tools/initramfs-tools_0.97.3~1.gbp8d572e_all.deb
>

I've tested the following:
- /sbin/init being a relative symlink: works
- /sbin/init being an absolute symlink: works
- /sbin/init missing: correctly dropped to rescue shell, even if upstart
installed (/etc/init/)
- passing init=/bin/systemd on the boot command line: works
- passing bogus init=/sbin/foo on the boot command line: warning message that
requested init was not found, is displayed, but continues booting with /sbin/init.

So yes, it works correctly now for all cases I tested and expect.

Thanks!

Michael

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

Michael Biebl 07-30-2010 09:49 AM

Bug#590744: Fails to boot if /sbin/init is a symlink
 
On 30.07.2010 11:31, Michael Biebl wrote:
> On 30.07.2010 06:21, Michael Prokop wrote:
>
>>
>> Can you please give the following snapshot version a try:
>>
>> http://people.debian.org/~mika/initramfs-tools/initramfs-tools_0.97.3~1.gbp8d572e_all.deb
>>
>
> I've tested the following:
> - /sbin/init being a relative symlink: works
> - /sbin/init being an absolute symlink: works
> - /sbin/init missing: correctly dropped to rescue shell, even if upstart
> installed (/etc/init/)
> - passing init=/bin/systemd on the boot command line: works
> - passing bogus init=/sbin/foo on the boot command line: warning message that
> requested init was not found, is displayed, but continues booting with /sbin/init.
>
> So yes, it works correctly now for all cases I tested and expect.

Looking at the code, the only issue I see, is that validate_init is *always*
executed at least twice, even if we find a valid init at the first try.
This means, for most cases we unnecessarily execute validate_init at
"""
# No init on rootmount
if ! validate_init "${init}" ; then
"""
Not that much of an issue, just an idea for a small optimization.

Michael

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


All times are GMT. The time now is 10:42 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.