Subject: Re: @booted_kernel magic symlink?
To: None <tech-kern@NetBSD.org>
From: Chapman Flack <nblists@anastigmatix.net>
List: tech-kern
Date: 04/24/2006 19:11:49
Hubert Feyrer wrote:
> What programs do you have in mind?
> While magic symlinks are all nice & dandy, I don't really feel 
> confortable of relying on them...
> (weren't they even backed out?)

They don't seem to have been backed out - at least they are in
-current (needing an option or sysctl to turn them on).

The program that's been irritating me is savecore. It has been
consistently complaining:
  /netbsd: kvmopenfiles: /netbsd: No such file or directory
when the name of the kernel I booted is, for example, test1.

This is a little surprising, because looking in savecore.c
just now I see it uses getbootfile(3).  So it should at least
be coming up with the file name test1.

Even that is not quite right, because my bootstraps and
kernels don't live in /.  They live in a very small dedicated
fs at the front of the disk, and once booted that fs is
visible mounted readonly at /stand.  It is included in
critical_filesystems_local in rc.conf, so is definitely
mounted before savecore runs.  But of course the proper
name for the kernel is now /stand/test1 rather than simply
/test1.  What had thrown me off the track briefly was that
when getbootfile(3) can't stat /test1 (for secure_path checks),
it returns the fixed string /netbsd instead, which led me
to think savecore was completely naive.

Understanding that behavior, I ought to be able to get dumb
symlinks to work - I would only need
  ln -s /stand/netbsd /netbsd
  ln -s /stand/test1  /test1
  ln -s /stand/test2  /test2
and so on.  Or I could use one smart symlink
  ln -s /stand/@booted_kernel /netbsd
which would work because getbootfile() would give up on
the original name and hit the single symlink /netbsd,
which would recover the correct name again.

Garrett's point is well taken ...

> platforms don't actually necessarily have the kernel in the root
> filesystem.  For example, evbmips kernels use yamon to TFTP their
> kernel, and have the root filesystem in NFS.

but this is in fact another situation where a smart symlink might
conveniently do the trick--and where there aren't many other
attractive options except to rewrite all grovelers: here again,
just as in my case, getbootfile() trips on its own assumptions.

In my case one could imagine trying to do something smarter:
the kernel knows not only the name of the booted file but the
partition it was read from; it could find in the mount table
that the partition is now mounted as /stand, and the sysctl
helper function could prefix that when queried for the booted
kernel (or getbootfile() could do the same in userspace but
with a little more work).  Perhaps that would even be a good
idea - but it wouldn't be good enough to address Garrett's
TFTP/NFS example, whereas a symlink might work well there too.

Garrett's other point, about not making a friendlier interface
for grovelers so that people will feel pressure to rewrite them,
is also well taken--but there will be certain days when an admin
does not really want to feel pressure to rewrite programs he
didn't write to begin with, and would welcome a system feature
that could be used to just make them work. It's partly about making
a friendlier interface for him (or her) too. ;)

-Chap

ps I do agree there's something about smart symlinks that does
make me uneasy, in that they impose new interpretation on what
could be perfectly valid ordinary file names in existing links.
I wouldn't mind seeing them selectable per fs, as suid exec and
device node recognition are now; they could be enabled on a few
file systems not generally writable, where the admin knows where
they're needed and what's going on.