Comment 7 for bug 14927

Revision history for this message
In , Thomas Hood (jdthood-aglu) wrote : Re: Bug #302519: ifupdown: postinst fails

Thanks a lot for the input.

On Fri, 2005-04-01 at 23:13 +0100, Henning Makholm wrote:
> To the submitter: A better short-term workaround if you prefer not to
> edit conffiles that are hopefully going to be fixed soon, is to do
>
> # mkdir /var/run/network
> # ln -sf /var/run/network/ /etc/network/run
>
> Otherwise the underlying bug might show up next time you boot, anyway.

That can be done as a workaround. It can't be the default because on
some systems /var/ is network mounted.

> The problem is that "readlink -f /etc/network/run" returns nothing and
> exits with failure when /etc/network/run is a dangling symlink, so the
> mkdir that is the point of this code never gets a chance to run.

The code depends on the presence of a "correctly" working readlink
program. Woody debianutils readlink did the right thing and so does
upstream-unreleased coreutils 5.3.0. To work around the fact that
sarge/sid coreutils 5.2.1 does the wrong thing when the ultimate target
of the symlink chain does not exist, we use the
substitute /lib/init/readlink program included in current initscripts
packages.

jdthood@thanatos:~$ cd /tmp
jdthood@thanatos:/tmp$ ln -s foo bar
jdthood@thanatos:/tmp$ /bin/readlink -f bar
jdthood@thanatos:/tmp$ echo $?
1
jdthood@thanatos:/tmp$ /lib/init/readlink -f bar
/tmp/foo
jdthood@thanatos:/tmp$ echo $?
0

The postinst sets

    PATH=/lib/init:/sbin:/bin:/usr/sbin:/usr/bin

so that the substitute version of the program gets run.

The submitter has an appropriate version of initscripts installed, so he
should be getting the right version of the readlink program.

ifupdown is missing a versioned Dependency on initscripts so we will
need to make a new version for sarge which adds it, but this doesn't
seem to have been the cause of the failure on the submitter's system.

> Code that depends on readlink -f being able to stop at a dangling
> symlink also appears in /etc/init.d/{ifupdown,ifupdown-clean}
> and will abort the boot initialization on systems where
> /etc/network/run refers to a ramdisk. (Which I suppose is the default,
> as I do not remember having done anything to redirect /etc/network/run
> myself).

/etc/init.d/ifupdown also set the PATH in order to get the fixed
readlink program.

/etc/init.d/ifupdown-clean does not set the PATH because it does not
need the fixed readlink program; the current coreutils readlink program
only deviates in its behavior if the ultimate target does not exist,
whereas ifupdown-clean only calls the readlink program if the ultimate
target does exist.

> Refusing to work with dangling links is the documented behavior in GNU
> readlink, so coreutils probably cannot be faulted for this.

Well, upstream changed the behavior back to the old way for 5.3.0.

> A
> quick-and-dirty workaround that should work in the most common cases
> would be to say
>
> $(readlink -f /etc/network/run || readlink /etc/network/run)
>
> instead of just
>
> $(readlink -f /etc/network/run)
>
> in all three affected files.

Interesting idea, but it isn't that simple. For one thing, readlink
without -f prints a relative path rather than a canonical one. Second,
we have to make sure that we don't end up deleting the second symlink in
a chain, etc.

--
Thomas Hood <email address hidden>