2

I have an TI DaVinci-based (ARM architecture kin to OMAP) system which netboots using TFTP and NFS-mounted root filesystem, and am trying to make it boot standalone without a netboot server.

The basic approach is to copy the kernel image to the NAND flash and the root filesystem to a connected SATA disk (NAND flash is nowhere near big enough for the whole system), then configure u-boot to load the kernel from NAND flash and pass an appropriate root= argument.

I'm stuck on the step of copying the filesystem. This question is relevant, but none of the recommendations work because I have only busybox versions of the cp and cpio tools, and the --one-file-system option is unsupported by busybox.

How can I clone the root filesystem when I only have the tool capabilities provided by busybox? Would it help to run archive creation commands on the NFS server (x64 architecture running Ubuntu) and then unpack on the target?

slm
  • 363,520
  • 117
  • 767
  • 871
Ben Voigt
  • 289
  • 3
  • 14
  • When you say "clone" do you mean the entire drive or just the data on it from a filesystem perspective? – slm Jul 30 '13 at 20:01
  • @slm: I mean that I get all the files and special files, so the result can be used as a root filesystem. There isn't really any concept of *entire drive* here, because the existing filesystem is mounted on NFS, so its physical representation is as a subset of a filesystem and partition on the NFS server. – Ben Voigt Jul 30 '13 at 20:03

4 Answers4

1

You should mount (or bind mount) to some directory :

mount /dev/mmcblk0p1 /mnt
cd /mnt
tar cjf /otherdisk/archive.tar.bz2 *

You can also send the result by ssh (if enabled in your busybox config) instead of storing locally, and by the way use the target host computing power/installed tools to perform compression :

tar cf - * | ssh user@host "bzip2 | cat > archive.tar.bz2"

Adapt compression tool, archive name and so on to your wishes :)

Nathael Pajani
  • 314
  • 2
  • 6
  • Yes, it seems like I should have used `mount / /mnt/srcsystem -o bind` and that would have had the single-filesystem effect because "Note that when you mount a filesystem somewhere else, any filesystems that were mounted to mount points inside the bind-mounted filesystem will not be moved along" – Ben Voigt Oct 16 '19 at 20:07
1

I'd think you'd be able to do what you want using cp. From the busybox.net website:

cp
Usage: cp [OPTION]... SOURCE DEST

           or: cp [OPTION]... SOURCE... DIRECTORY

Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.

Options:

            -a      Same as -dpR
            -d      Preserve links
            -p      Preserve file attributes if possible
            -R      Copy directories recursively

Example

$ cp -a / /mnt/newroot

tar

If cp can't handle any devices such as /dev/zero which I'm pretty sure it can't you might be able to use tar which is also included with BusyBox.

$ (cd /; tar cf - .)|(cd /mnt/newroot; tar pxvf -)
slm
  • 363,520
  • 117
  • 767
  • 871
  • Mounting is not a problem. The NFS share is mounted, I am currently using it as the root filesystem. I want to migrate (non-destructively to the NFS share) the entire content of `/` to a local SATA disk and begin using it as the root filesystem instead of the NFS share. – Ben Voigt Jul 30 '13 at 20:10
  • @BenVoigt - why can't you use `cp -a`? This does a `cp -dpR`. – slm Jul 30 '13 at 20:13
  • I'm not sure if that handles special files correctly. The `cp` commands I see offered as solutions usually involve `-ax` options, and `-x` is not supported by busybox `cp`. – Ben Voigt Jul 30 '13 at 20:14
  • Working on it. In your new answer though, you're copying into the root, and I want to copy *from* `/` to a newly initialized filesystem at `/mnt/newroot`. But regardless of the mountpoint for the source, I expect problems from e.g. `/nfs/mnt/share/dev/zero`. Will `-p` cause creation of a special file instead of opening `dev/zero` and reading its (infinite) content? Having `/sys` and `/mnt/newroot` mountpoints in the source tree also seems problematic. – Ben Voigt Jul 30 '13 at 20:22
  • I think you could use tar to do this: `(cd /; tar cf - .)|(cd /mnt/newroot; tar pxvf -)` I always forget about this trick, had to think for a sec to recall it. – slm Jul 30 '13 at 20:26
  • That recurses down into `/sys` and aborts with "tar: short read" – Ben Voigt Jul 30 '13 at 20:29
  • @BenVoigt - stubborn isn't it 8-) – slm Jul 30 '13 at 20:30
  • Yeah, I'm wondering if I should create a loopback filesystem on the NFS server, perform the copy there, then move the filesystem image into the share so I can see it from the target, and use `dd` after all to get it to the destination disk. Just wondering if `cp -ax` will behave correctly on the server, when it sees a whole bunch of broken symlinks. – Ben Voigt Jul 30 '13 at 20:33
  • @BenVoigt - take a look at this blog post: http://emreboy.wordpress.com/2012/12/20/building-a-root-file-system-using-busybox/ – slm Jul 30 '13 at 20:37
  • It looks like `dd` is viable after all, for actually writing to the destination. One can use the NFS server with a full set of archival tools to create an image in a target-appropriate filesystem, using a loopback file to store it. – Ben Voigt Jul 30 '13 at 21:30
1

It seems that using busybox-crippled tools for this is far more trouble than it's worth, because single-filesystem processing really is needed for this and it's missing from busybox cp. Possibly find could be used to copy files individually and avoid recursing into mountpoints, but that would involve a lot of individual processes and be very slow.

Preparing the filesystem on the NFS server is a much more viable alternative. Calculate the partition size in bytes using fdisk -l, then

truncate -s N the-root-image
mkf.ext3 the-root-image
sudo mount -o loop the-root-image /mnt/somewhere

Now copy the content using this command found in the linked question

sudo rsync --archive --inplace --hard-links --acls --xattrs --devices --specials --one-file-system --8-bit-output --human-readable --progress path/to/nfs/share /mnt/somewhere

Put the image in a network location where the target can access it:

sudo umount /mnt/somewhere
mv the-root-image path/to/nfs/share

Finally, from the target place the image onto the destination disk

dd if=/the-root-image of=/dev/sda1 bs=16M
Ben Voigt
  • 289
  • 3
  • 14
1

BusyBox's find supports the -xdev option, so you can make a cpio archive of the root filesystem that way. Unlike tar, cpio does not archive a directory's contents when it archives that directory.

find . -xdev | cpio -H newc -o |
{ cd /mnt && cpio -m -i; }

I don't quite understand why you're building the image from a device though. I'd expect to build a filesystem image using your build scripts on a development machine, and deploy that image.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • The problem with `find`+`cpio` under busybox isn't `find`, it's `cpio`, which is badly hobbled. "Extract or list files from a cpio archive". No options to create an archive or pass-through. I have customizations of an image originally built by others. But yes, making a disk image from the NFS server turned out to be much easier. – Ben Voigt Jul 31 '13 at 13:29
  • @BenVoigt Oh. BusyBox cpio *can* build archives, but like almost everything in BusyBox it's an optional feature, which apparently wasn't turned on in your build. In any case I do think building the image on the server is the better solution for your scenario. – Gilles 'SO- stop being evil' Jul 31 '13 at 15:50
  • Still, yours is the correct answer to the question I asked, which is how to copy a root filesystem using busybox without descending into mountpoints, even thought it wasn't what I actually ended up doing. – Ben Voigt Jul 31 '13 at 16:07