Linux root file systen change while kernel running

When a Linux system running, there are two critical things: kernel and root file system. They are working together to provide services to user.

In Cisco IR800 platform, I have a need to run a linux which has kind of luxury file system, which includes gcc, make, gdb, dpdk package etc.. When the box boots, it runs a min-linux which has a busybox based very minimum root file system inside DRAM. Since the box BIOS has been closed to have option to boot USB stick, it is not an option to install GRUB, kernel and root file system in USB memory stick to boot distribution like ubuntu.

The solution is to install a new root file system in 8GB USB meory stick and swap to new root file using chroot.

Linux root fs

Build a nice root file system using yocto project

I ended up to use yocto project to build a core-image-lsb-sdk image.

iot@iot-UCSC-C240-M3S:~/yocto-proj$ source oe-init-build-env
iot@iot-UCSC-C240-M3S:~/yocto-proj/build$ bitbake core-image-lsb-sdk
.................................................
.................................................
iot@iot-UCSC-C240-M3S:~/yocto-proj/build$ ls -l tmp/deploy/images/qemux86-64/core-image-lsb-sdk-qemux86-64-20160728211755.rootfs.ext4
-rw-r--r-- 1 iot iot 2747091968 Aug  3 10:54 tmp/deploy/images/qemux86-64/core-image-lsb-sdk-qemux86-64-20160728211755.rootfs.ext4
iot@iot-UCSC-C240-M3S:~/yocto-proj/build$

Push root file system into USB memory stick

Plug a 8GB USB memory stick into UCS box, and mount ext4 file and USB stick, copy it over

[root@sg-centos-hv1 dpdk]# mkdir /mnt/ext4_rfs/
[root@sg-centos-hv1 dpdk]# losetup /dev/loop0 /home/scratch/dpdk/core-image-lsb-sdk-qemux86-64-20160728211755.rootfs.ext4
[root@sg-centos-hv1 dpdk]# mount /dev/loop0 /mnt/ext4_rfs/
[root@sg-centos-hv1 dpdk]# ls /mnt/ext4_rfs/
bin  boot  dev  downloads  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  run  sbin  software  sys  tmp  usr  var  www
[root@sg-centos-hv1 dpdk]# cd /mnt/ext4_rfs/
[root@sg-centos-hv1 ext4_rfs]# du -sh
2.0G    .
[root@sg-centos-hv1 ext4_rfs]#

[root@sg-centos-hv1 ext4_rfs]# dmesg | tail -10
sd 20:0:0:0: Attached scsi generic sg10 type 0
sd 20:0:0:0: [sdb] 15663104 512-byte logical blocks: (8.01 GB/7.46 GiB)
sd 20:0:0:0: [sdb] Write Protect is off
sd 20:0:0:0: [sdb] Mode Sense: 43 00 00 00
sd 20:0:0:0: [sdb] Assuming drive cache: write through
sd 20:0:0:0: [sdb] Assuming drive cache: write through
 sdb: sdb1
sd 20:0:0:0: [sdb] Assuming drive cache: write through
sd 20:0:0:0: [sdb] Attached SCSI removable disk

[root@sg-centos-hv1 ext4_rfs]# fdisk -l /dev/sdb

Disk /dev/sdb: 8019 MB, 8019509248 bytes
255 heads, 63 sectors/track, 974 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0007c493

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         974     7823623+  83  Linux


[root@sg-centos-hv1 ext4_rfs]# ls /mnt/usb/
[root@sg-centos-hv1 ext4_rfs]# mount /dev/sdb1 /mnt/usb/
[root@sg-centos-hv1 ext4_rfs]# rm -rf /mnt/usb/*
[root@sg-centos-hv1 ext4_rfs]# cp -rf /mnt/ext4_rfs/* /mnt/usb; sync; sync; sync
[root@sg-centos-hv1 ext4_rfs]# cd
[root@sg-centos-hv1 ~]# umount /mnt/usb
[root@sg-centos-hv1 ~]# umount /mnt/ext4_rfs/
[root@sg-centos-hv1 ~]# losetup -d /dev/loop0
[root@sg-centos-hv1 ~]#

plug into IR800 box to run as new root file system

# uname -a
Linux gemini 3.17.8 #3 SMP Wed Mar 25 16:35:59 PDT 2015 x86_64 GNU/Linux
# fdisk -l

Disk /dev/loop0: 953.7 MiB, 999967744 bytes, 1953062 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000


Disk /dev/loop1: 244.1 MiB, 255967744 bytes, 499937 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000


Disk /dev/sda: 7.5 GiB, 8019509248 bytes, 15663104 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0007c493

Device     Boot Start      End  Sectors  Size Id Type
/dev/sda1          63 15647309 15647247  7.5G 83 Linux

Disk /dev/sdb: 3.7 GiB, 3909091328 bytes, 7634944 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x000938d2

Device     Boot   Start     End Sectors   Size Id Type
/dev/sdb1  *         63  500062  500000 244.1M 83 Linux
/dev/sdb2        500063 1000062  500000 244.1M  6 FAT16
/dev/sdb3       1000063 2953187 1953125 953.7M  6 FAT16
/dev/sdb4       2953188 7630874 4677687   2.2G  f W95 Ext'd (LBA)
/dev/sdb5       2953251 5941531 2988281   1.4G 83 Linux
/dev/sdb6       5941533 7630874 1689342 824.9M 83 Linux

#
# mkdir /new_rootfs_usb
# mount /dev/sda1 /new_rootfs_usb/

#
# mount --move /sys /new_rootfs_usb/sys
# mount --move /proc /new_rootfs_usb/proc
# mount --move /dev /new_rootfs_usb/dev
# chroot /new_rootfs_usb /bin/bash
# pwd
/
# ls
bin   dev        etc   lib    lost+found  mnt  proc  sbin      sys  usr  www
boot  downloads  home  lib64  media       opt  run   software  tmp  var
# ls -l
total 64
drwxr-xr-x  2 root root 4096 Aug  4  2016 bin
drwxr-xr-x  2 root root 4096 Aug  4  2016 boot
drwxr-xr-x  8 root root 2540 Aug 29 19:48 dev
drwxr-xr-x  2 root root 4096 Aug  4  2016 downloads
drwxr-xr-x 67 root root 4096 Aug  4  2016 etc
drwxr-xr-x  6 root root 4096 Aug  4  2016 home
drwxr-xr-x  9 root root 4096 Aug  4  2016 lib
lrwxrwxrwx  1 root root    3 Aug  4  2016 lib64 -> lib
drwx------  2 root root 4096 Aug  4  2016 lost+found
drwxr-xr-x  2 root root 4096 Aug  4  2016 media
drwxr-xr-x  3 root root 4096 Aug  4  2016 mnt
drwxr-xr-x  4 root root 4096 Aug  4  2016 opt
dr-xr-xr-x 59 root root    0 Aug 29 19:48 proc
drwxr-xr-x  3 root root 4096 Aug  4  2016 run
drwxr-xr-x  3 root root 4096 Aug  4  2016 sbin
drwxr-xr-x  4 root root 4096 Aug  4  2016 software
dr-xr-xr-x 11 root root    0 Aug 29 19:48 sys
lrwxrwxrwx  1 root root    8 Aug  4  2016 tmp -> /var/tmp
drwxr-xr-x 11 root root 4096 Aug  4  2016 usr
drwxr-xr-x  9 root root 4096 Aug  4  2016 var
drwxr-xr-x  3 root root 4096 Aug  4  2016 www
# which gcc
/usr/bin/gcc
# which make
/usr/bin/make
# which ldd
/usr/bin/ldd
# uname -a
Linux gemini 3.17.8 #3 SMP Wed Mar 25 16:35:59 PDT 2015 x86_64 GNU/Linux
# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       7.3G  2.0G  4.9G  29% /
devtmpfs        952M     0  952M   0% /dev
tmpfs           956M     0  956M   0% /dev/shm
#

Now the box is happily running the same kernel, but with a luxury root file system.

Note: I tried pivot_root and switch_root, both didn’t work. Googling around I didn’t find any solution.