0

I need to update a raw UBI partition with a new UBIFS image from Linux userspace with superuser rights, however I'm getting EBUSY (Device or resource busy) error whenever I'm trying to open my corresponding /dev/ubiX_Y for writing, even if the current filesystem present on it is mounted as read-only. I suspect that an usual block partition with e.g. an ext4 filesystem could be opened for writing when it's mounted as read-only, seeing that utilities like zerofree and ext4magic work that way. That doesn't seem to be the case with UBI partitions.

Theoretically I could either terminate the processes using the partition or attach to them and forcibly close all files on it before unmounting the partition completely, but seems I can do neither to the busybox init process which keeps constantly holding its /etc/inittab open. And yes, the partition in question is a root / mounted partition.

I also could implement a kernel module which would do the dirty work, but I'd like to retain as much binary forward compatibility for my update utility and basically keep it as much kernel version agnostic as I can, thus solving it in such a manner is highly undesirable. Is there any other way I can do this?

  • Wild guess: If it's mounted as read-only, it's still used, so still EBUSY. What happens if you completely unmount it? – dirkt Mar 5 '18 at 12:22
  • @dirkt It is possible to open a raw UBI partition for writing if it's unmounted, at least that works with other partitions. I haven't managed to unmount the rootfs partition so far though... – Protagores Mar 7 '18 at 13:39
1

If there a line in /etc/inittab like:

::restart:/tmp/updater_stage2

Then if you send SIGQUIT to init it will replace itself with /tmp/updater_stage2. To reload /etc/inittab after you have changed it send SIGHUP. You can replace /etc/inittab with a bind mount:

mount --bind /tmp/inittab /etc/inittab
kill -HUP 1
sleep 1
kill -QUIT 1

If there is no /etc/inittab or support for inittab in not compiled in init will run init, so you will have to replace /sbin/init like:

mkdir /tmp/old_sbin
mount --bind /sbin /tmp/old_sbin
cp -as /tmp/old_sbin /tmp/new_sbin
ln -sf /tmp/updater_stage2 /tmp/new_sbin/init
mount --bind /tmp/new_sbin /sbin
kill -QUIT 1

You can then use pivot_root and chroot to replace the root filesystem, which you then be able unmount (after moving /tmp, /proc etc).

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.