2

Background

I have a system that runs Linux. It's a NAS, and does not have any monitor, keyboard, or serial port. It does have a network port. I'm not happy with the software running on it, and am trying to get a different distro to run.

What I have

On the existing system, I can manage to get a new kernel and initrd booted, by using the web interface to upgrade the ROM, but that upgrade is a specially crafted image, that does nothing more than unpack a kernel, initrd, kexec, and runs kexec with the required arguments to boot the new kernel.

The initrd sets up a network connection, starts an SSH server (dropbear), and waits for it to end. It then runs a different script. Using this, I can do some testing: I can boot into that kernel/initrd, log in via SSH, customise the stage-2 script, kill dropbear, and hope for the best.

Using this approach, I have managed to install a functional OS on the hard disk. (For now, it's NixOS, if it matters, but I may change that in the future. My question isn't about any specific distro though.) I have intentionally not made it bootable. I wish to keep the flash memory as it is, so that aside from the data on the hard disk, the NAS remains "official". I have, however, obtained the distro's own kernel and initrd, that I would want to put in an upgrade image.

The problem

Using that kernel and initrd, the system does not start.

My attempts

I have put together a shared initrd, containing the distro's setup as well as my own, which continues to boot into dropbear. In an SSH shell, I then attempt to run the distro's init scripts. This fails, however, because it relies on being run as PID 1.

I then attempted to make PID 1 take arbitrary commands: I made it run scripts from a pipe, and wrote to that pipe from my remote shell, intending to inspect manually whether the command had the desired effect. However, that doesn't work: the init-shell (PID 1) sees EOF after the very first command, and immediately exits. Hello kernel panic.

I also attempted to test what would happen if I made it not care whether it was being run as PID 1, by passing systemd's --system option, and then run the distro's init script from my shell. In that form, I was unable to reproduce the problem: it just worked.

My question: What now?

At this point I'm looking back at the pipe approach for an alternative, something that actually works to run more than one command. Preferably something that also lets me see the commands' output.

Basically: I want to know how I can remotely see the output of the boot programs that run from PID 1, that cannot run in an SSH session, without actually attaching a monitor or serial cable.

Answers that take a completely different approach are also welcome, but please keep in mind the system restrictions I'm dealing with. I don't just not have a monitor or serial cable, I don't even have a VGA or serial port. I have one USB port that I could plug a keyboard into, if needed, but I am of course not able to see anything I type.

  • This is kinda hard as-is. Can you replace init completely? – Joshua Jul 29 '14 at 23:44
  • Can you provide more details on this box? Manufacturer? Vendor? Versioning information? Simply crashing in on a Linux based application from another Vendor/Manufacturer is not a good idea as there may be internal system modifications that make your changes either dangerous or not effective. – mdpc Jul 30 '14 at 4:35
  • @Joshua Yes, I can continue to use my own init, but I'd like to use the distro's. It will make updates a lot easier. – hvd Jul 30 '14 at 8:03
  • @mdpc I already managed to get a running system, with a clean kernel. That's not the problem. The vendor's kernel does have some modifications, but they aren't anything I need, all I'm missing in a clean kernel is the ability to display a message on the LED display. But, to answer your question anyway, it's a Thecus box, and their kernel is a patched 2.6.33, and mine is 3.15.6. – hvd Jul 30 '14 at 8:07
0

The general idea to accomplish this is to replace the init with a script that spawns the initrd-based bootscript in the background, proceeds to mount the system root, and does [ -x /root/sbini/init ] && exec chroot /root /sbin/init. (Place some code below to handle it not existing.)

  • I'm sorry, I don't understand your answer. This seems more like an answer on how to replace the distro's initrd with a custom one. I already know how to do that. What I'd like to do is figure out why the distro's initrd doesn't work for me, and keep the required changes to a minimum. – hvd Jul 30 '14 at 16:03
  • This probably is the smallest possible change. – Joshua Jul 30 '14 at 16:40
  • No, the smallest possible change cannot ever be "recreate it from scratch". Recreating it from scratch might, depending on the situation, take less time than the smallest possible change would, but that doesn't make it a smaller change. Either way, your answer clearly doesn't address either my direct question or what I'm hoping to accomplish, and although it's fine if you don't intend to provide an answer that does, it's not fine to provide a non-answer that just repeats what I already know. Not only does it not help me, but it's not even in sufficient detail to be useful to others. – hvd Jul 31 '14 at 9:51
  • I've been down the other path. My experience says it's a dead end. – Joshua Jul 31 '14 at 15:12
0

After starting an SSH session, other sessions can write there too, by writing to /dev/pts/<N>. So to see what is happening, since I'm already able to control what PID 1 will end up running, I just need to make it write there. Using exec 0<>/dev/pts/0 1<>/dev/pts/0 2<>/dev/pts/0 from PID 1 and making sure nothing else is reading/writing there I can see what's happening. When it eventually fails, the distro's init script prompts to ask what to do, and even properly responds to me entering R to reboot.

The actual problem I was having seems to be caused by required kernel modules not getting loaded. Although I was able to get everything working manually, which obviously means the block, RAID and filesystem modules were available and getting loaded, the distro's initscript relies on udev, and it turns out that requires a few additional modules, in particular unix (which I'd never have chosen myself to not build into the kernel).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.