Posts: 13
Pumukli
Joined: 03 Jan 2014
#1
Hello All,

As I am setting up a new antiX system (which will eventually retire the old HP Brio from"production machine" status to"tinkerer machine") I try to document the most important steps of what I do.

AntiX 13.1 core is the choosen version and it has installed without any problems. After that I installed 9-10 more programs what I would need and they all went up fine too.

You might remember from my earlier ramblings that I use ramdisks and need to save the important parts of their content before reboot and restore their directory and file structure on start-up.

Here comes my problem:
I do the reconstruction in rc.local. But this"script" or whatever is the last to run in the startup sequence. So I get these error messages from various programs (lighttpd being the most notorious one) in which they complain about non-existent files... Of course, they are nonexistent because they are created in the last stage of the startup.

What would be the most elegant solution? Starting the ramdisk file structure reconstruction at an earlier stage (where?) or postponing the startup of these programs what I run from the ramdisks and complain about non-existent files and dirs to a later stage (e.g. in the last few lines in rc.local)?

(It is not a critical error because I can start these servers at the end of rc.local and they will run fine but it is not too elegant.)

Thanks in advance,

Pumukli
Posts: 1,308
BitJam
Joined: 31 Aug 2009
#2
The standard way to deal with things like this is to set up your custom filesystem layout in an initramfs (also called an initrd).

For example, for decades it has been a standard Unix practice to mount /usr on its own partition. This is why there are separate /bin and /usr/bin directories (same with /sbin and /lib). The stuff directly on / is supposed to be the bare minimum needed to boot the system. Extra stuff for"users" is under /usr. A huge controversy erupted when the udev developers added a requirement that /usr must be mounted *before* the udev service started. This forced people who mount /usr separately to use an initrd/initramfs to mount /usr before the system services start. There was a large outbreak of people thinking other people were very stupid.

One of the primary purposes of initramfs/initrd is to mount filesystems before system services are initialized, just like what you want to do. Unlike the /usr situation, your use of initrd would be entirely uncontroversial. The initrd file to be loaded is usually specified in bootloaders with the word"initrd" although technically the technology is now called initramfs (IMO, the name change was not well thought out). It loads a small compressed filesystem-on-a-file usually called initrd.gz or initramfs.gz or something like that. This entire file system gets loaded into RAM and the script /init in the filesystem gets run. The job of that script is to do all of the mounting needed before turning control over to the /sbin/init process of the real root filesystem.

Another reason people will use an initrd is to allow users to specify the root partition by label or uuid as in"root=LABEL=some-label" or"root=UUID=some-long-uuid". The Linux kernel does not support these boot parameters (although it does support"root=/dev/sd-whatever"). An initrd can be programmed to deal with this kind of boot parameter and make it look to the user as if the kernel was doing it.

You should be able to piggy-back off of the standard Debian initrd that comes with antiX. The three tricks you need are:
  • unpack the initrd file
  • edit the init script that got unpacked
  • repack the initrd file
Unpack the initrd file

Code: Select all

mkdir my-initrd
cd my-initrd
gunzip -c /boot/initrd-[...] | cpio -idum
Replace [...] with the rest of the actual file name. The name will depend on the version of the kernel you are using. If you get permission errors with the cpio command then just prepend it with the"sudo" command:"sudo cpio -idum".

Edit the init script that got unpacked
You probably want to add code to mount your partitions after the"mountroot" command gets executed. I think this mounts the root filesystem at /root. So if you wanted to mount /usr as tmpfs (this is just an example) then you would mount it at /root/usr. When the script finishes, it will get magically moved from /root/usr to /usr (via the switch_root command near the end of the script). Before adding your mounting code, you might want to start out with just adding the lines:

Code: Select all

echo"Hello World"
sleep 10
in order to be sure your version of the initrd and the init script are running.

Repack the initrd file
When you are still in the my-initrd directory you created, run the following:

Code: Select all

 find . | cpio -o -H newc --owner root:root | gzip -9 > ../new-initrd.gz
sudo cp ../new-initrd.gz /boot/initrd-[...]-2.gz
I think it is best to not overwrite the original initrd but this means you need to edit your bootloader configuration to use your new initrd. An alternative is to first save the original initrd before overwriting it:

Code: Select all

sudo cp /boot/initrd-[...] boot/initrd-[...].orig
sudo cp ../new-initrd.gz /boot/initrd-[...]
If you do it this way then you won't have to make changes to your bootloader configuration.
Posts: 13
Pumukli
Joined: 03 Jan 2014
#3
Hello,

Thank you for the detailed description BitJam!
I tried the suggested method and it"sort of" worked: I made a new initrd.gz and was able to boot it to realize that it says something about"cant create directory - directory already exists" - which is strange because those directories should be on a tmpfs and right after reboot... So I re-edited the initrd.gz to include 20 sec sleep time after the directory creation part hoping I could read it.
But I made a typo in the name when renamed it to be in accordance with grub. A dot instead of a dash. You can imagine. I effectively prevented the system from boot. __{{emoticon}}__

So I tried to revive the installation, booted from the pendrive again, and to made a long story short: I ended up reinstalling the whole system. __{{emoticon}}__ Fortunately it was just a fresh (yesterday) install anyway so I was back in business within 30 minutes.

But it was a good lesson to look after some sort of"non-lethal" method.

I found an article at debian administration about making scripts run at boot time (
========= SCRAPER REMOVED AN EMBEDDED LINK HERE ===========
url was:"http://www.debian-administration.org/articles/28"
linktext was:"http://www.debian-administration.org/articles/28"
====================================
) and I tried to digest and follow that.

It seems to work. I wrote those two scripts (save and restore) and put them in the appropriate S and K groups of different runlevels. Now when the system reboots the important files are saved and restored on boot. And lighttpd does not complain about nonexistent files too. The only"problem" that arose is that the message on the screen"lighttpd ... started" and"vsftpd ... started" are now on the same line, concatenated, as if a CR/LF went missing somewhere.

Is my solution a good one or just started to walk the path to hell (in the long run) unwary to something in the background? Any tips would be welcome! And thanks again BitJam, even if I chose another route.
Posts: 325
male
Joined: 04 Nov 2011
#4
@BitJam

Thanks for the excellent explanation.
I hope to have understood something.

My problem is to start the ISO using Grub2. It fails m.E. to the rights of the initrd / initramfs at the time. Therefore, the USB stick (sdb1) with"antiX / linuxfs" not found.

Examples:
snip >grub2.cfg<

Code: Select all

...
menuentry"Mageia-4-RC-dual-DVD.iso" {
      set isofile="/boot/isos/Mageia-4-RC-dual-DVD.iso"
      loopback loop $isofile
      linux (loop)/isolinux/x86_64/vmlinuz from=$isofile ro rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 lang=de xmode=800x600 xrandr 
      initrd (loop)/isolinux/x86_64/all.rdz
}

menuentry"MX-14-i386-xfce.iso" {
      set isofile="/boot/isos/MX.iso"
      loopback loop $isofile
      linux (loop)/antiX/vmlinuz antiX=MLX lang=de_DE
      initrd (loop)/antiX/initrd.gz 
}
This command alone would correct this?
BitJam wrote:

Code: Select all

find . | cpio -o -H newc --owner root:root | gzip -9 > ../new-initrd.gz
Posts: 1,308
BitJam
Joined: 31 Aug 2009
#5
@male, I don't have a lot of time and energy for this now because I'm trying to make a final push to get MX-14 out the door. A quick suggestion is to try the"fromiso=$isofile" boot parameter.
Posts: 1,308
BitJam
Joined: 31 Aug 2009
#6
Pumukli wrote:Is my solution a good one or just started to walk the path to hell (in the long run) unwary to something in the background?
I'm sorry I did not warn you about the possibility of borking your system. In future, the problem you had could have been fixed by booting via the pen drive and then mounting the root partition of your installed system and then restoring the original initrd file. Another, safer, route is to add an entry in your bootloader for the new initrd while leaving the old entry in place.

From my perspective the Debian init system has been both brain-dead and changing so it is hard for me to keep track of it in my head.although I believe the most recent incarnation has fixed some of the brain damage. That was why I gave you instructions about something I know about. If your init scripts work then it is a good solution. There is a possibility there will be a conflict with udev or systemd down the road but it is also possible there won't be. I don't think your solution is the path to Redmond so you should be fine.
Posts: 325
male
Joined: 04 Nov 2011
#7
@BitJam

BINGO __{{emoticon}}__ __{{emoticon}}__

Although I have now used antiX and come up to the cli-installer.
I use a manually created grub.cfg

Code: Select all

menuentry"antiX-13.2_x64-full.iso" {
      set isofile="/boot/isos/antiX-13.2_x64-full.iso"
      loopback loop $isofile
      linux (loop)/antiX/vmlinuz fromiso=$isofile antiX=MLX lang=de_DE
      initrd (loop)/antiX/initrd.gz
}
As I already wrote anti - it is not trivial, because each ISO behaves differently.

Thanks again, BitJam!

@Pumukli
please excuse that I used your thread.