[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Configuring foreign packages without qemu in order to boot a system



First of all, thanks to everyone who responded!

On Sunday 02 September 2012 11:05:54 Neil Williams wrote:
> On Sun, 2 Sep 2012 01:40:45 +0100
>
> Wookey <wookey@wookware.org> wrote:
> > On Sun, 2 Sep 2012 01:07:11 +0200
> >
> > Paul Boddie <paul@boddie.org.uk> wrote:
> > > This configuration step appears to be the necessary measure to permit
> > > the init mechanism and various related activities to function.
>
> Principally it is to run ldconfig, to setup the system shell and to
> initialise some data caches. Take a look
> at /var/lib/dpkg/info/*.postinst to see what some of the packages need
> to do in this phase. Note that the preinst scripts are *not* run by
> multistrap (whether using qemu or not) unless your configscript
> explicitly calls them (as the wiki recommends it does for at least the
> dash preinst). Note that many packages will simply fail to operate if
> ldconfig has not been run and many shared libraries have more than just
> a call to ldconfig as their postinst.
>
> http://wiki.debian.org/Multistrap#Steps_for_Squeeze_and_later

Right, I can see straight away that /sbin/init might have a hard time doing 
anything useful because the symbolic links within /etc/rcS.d don't exist. The 
problem I've been experiencing is getting a shell to run at all, I think, 
making it difficult to run a configscript like the one described.

What I've done that appears to resolve this issue is to install busybox-static 
in the rootfs and to provide a link from /usr/local/lib/busybox/sh 
to /bin/busybox, and then to mention the former as the interpreter in a 
script that the kernel tries to run as the init program, this being in the 
location of the OpenWrt /etc/preinit script but with Debian-specific 
contents.

This appears to provide a working shell that can then run the different 
configscript commands. The preinit script can then hand off to the real init 
program.

> I'm not aware of a safe & robust method to restrict ldconfig to only
> certain shared libraries from out of a much larger set of shared
> libraries awaiting configuration on the system. Configuring all shared
> libraries via dpkg to suit ldconfig will involve running the maintainer
> scripts for all shared libraries which will themselves require
> executables from other packages to be configured.
>
> dpkg can work all this out but only when given the entire set.

I can see that this can be troublesome. I can envisage having different kinds 
of scripts that can do things like make symbolic links, update databases, and 
so on, all without reference to specific host facilities, but I imagine that 
this requires a level of separation (and discipline) that isn't currently 
supported in Debian.

> > > I suppose that not all
> > > packages need to be configured, but some configuration seems to make
> > > the difference between a functioning and non-functioning system.
>
> In order for this to work, you have to at least have the ability to
> chroot into the semi-configured rootfs *and* you need enough
> non-packaging data (/etc/inittab, /etc/fstab) provided by the
> setupscript to allow the kernel to use the rootfs for init. That
> generally means that shared libraries have to be configured (ldconfig),
> a shell must be fully operational (dash preinst and postinst) and dpkg
> itself as well as all of the dependencies of these.

The latter part of this paragraph was particularly helpful in pushing me 
towards trying busybox as a helper in getting configuration to occur.

> Note: It is *not* advisable to manually force these steps. dpkg does
> not take kindly to someone second-guessing the *order* in which
> packages are configured even if you manage to identify the set itself.
>
> dpkg assumes that the configure step is either:
>
> a) system-wide with no external ordering, or
> b) single-upgrade mode where everything that this package needs
> is already configured or within the scope of the current upgrade.
>
> Breaking these assumptions will do horrible things to the system in
> ways that might be recoverable by reinstalling the package but as this
> is completely untested maybe not ....

I really don't want to mess with dpkg, no.

> It's one of the principle differences between multistrap and other
> bootstrap tools. Multistrap can handle all the dependencies because it
> handles all packages at the same time. debootstrap breaks the system
> into two halves and fully configures the first before trying to go back
> for the later packages without full dependency calculation support.
> debootstrap does allow that later packages have a fully configured base
> beneath them but this means that debootstrap *cannot* offer the chance
> to trim the base system itself as it has no way of knowing what the
> later packages will need. Multistrap combines both phases and gives a
> smaller package set at the cost of having to do all processes in a
> single step. It is this single-step approach which allows multistrap to
> work with multiple repositories at the same time - apt needs to know
> about all the packages at the same time for dependency calculations
> just as dpkg needs to be able to work on all packages in whatever
> order it calculates.
>
> Multistrap can easily take a rootfs all the way up to a full package
> set with a UI and customisations and give you a tarball with absolutely
> everything setup and ready to run. The cost of that is that the rather
> arbitrary division line with which people have become familiar from the
> debootstrap model simply doesn't exist. This has advantages in package
> selection but also has requirements about package configuration.

I'm not quite sure I follow this last paragraph. I've tried to use multistrap 
to deploy a rootfs that I want to be able to boot into, but it isn't ready to 
run, even with a minimal configuration.

[...]

> > > Obviously, in my situation, I can't boot into Emdebian without
> > > having first performed the configuration step, so this supposedly
> > > leaves me with the fairly undesirable option of using qemu.
>
> ... or a rescue init system stuffed somewhere else. A second partition
> maybe. A minimal system which is created once, packed up as a tarball
> and then used repeatedly. This is roughly equivalent to Debian
> Installer except that that image is created in RAM. It only needs to be
> enough for the kernel to be able to sort out init and chroot in.
> buildroot is often used for this. It only needs to be 4Mb with
> buildroot (uClibc & busybox) or you can have a second Emdebian system
> with ~50Mb. Recent versions of buildroot (>= 2011-05) are much improved
> and build and run without the need for third-party patches.

It's a shame that there aren't any prominent recipes out there for this. What 
you're suggesting (uClibc and busybox) is what the OpenWrt distribution on my 
NanoNote provides, and that's how I managed to get Emdebian bootable 
initially, but it would be preferable to be able to drop the requirement on 
OpenWrt, buildroot or other systems.

> That rescue system can then be scripted to mount the other partition,
> chroot in, run all of the configuration stages, remove the script from
> the rescue system to take itself out of the boot sequence and reboot -
> just like Debian Installer - directly into the full system.

Indeed.

> > > I did wonder, however, whether there are any known techniques for
> > > configuring just enough of a system on the build host so that the init
> > > mechanism can complete its work on the target system and then allow the
> > > proper configuration to occur.
>
> "just enough of a system to run init (and chroot)" sounds a lot like
> a description of buildroot.

Yes, but it would be great to drop the need for buildroot. I think deploying 
busybox-static might be sufficient for that, at least when deploying a 
system. I also want to look into building Debian kernel packages.

> > Multistrap provides a (fairly low-tech) mechanism for this. In your
> > multistrap config provide a
> > setupscript=/path/to/setup.sh
> > which does any tweaking necessary to make the image bootable (e.g.
> > setting /etc/fstab, inittab, /etc/modules to something useful).
>
> Whether packages work correctly when unconfigured - even with support
> from static files created in /etc/ - is a little bit of a wild guess.
> It's completely untested because packages are not required to operate
> when in the state installed-ok-unpacked, only in installed-ok-installed
> and dpkg only sets that state after the configure step.

[...]

> Getting the kernel to boot is the first barrier. Once that is done,
> getting the kernel to use the init available and successfully hand-off
> to it is the next barrier. Once you're at that point, the configscript
> can be executed by that init process and that process could be
> buildroot.

I like the idea of setupscript and configscript: if you're going to end up 
copying things into a rootfs, you might as well make it easy to automate and 
manage. I did try using configscript but multistrap didn't seem to copy the 
script into the rootfs, and I'm not sure where it would put it or how it 
would make it run on the target system, anyway.

[...]

> It's embedded, there will always be room for complications just as
> there is always room for documentation.
>
> The key is to not break the underlying models in order to simplify the
> documentation/setup at the cost of making the system fragile.

Well, I'd like to be able to write something up that neither involves tens of 
manually invoked steps nor something that just points to a rootfs that has 
been magically constructed according to a set of forgotten instructions (or 
worse, trial and error), that also helps people troubleshoot if the 
infrastructure changes or if they're trying to do something similar but not 
identical.

I think I've found some kind of solution for package configuration, though, so 
I'll attempt to write this up and let you take a look. There will surely be a 
lot of room for improvement in what I'm doing.

Paul


Reply to: