toaruScar
Regular Contributor
I recently ran into a full JFFS2 system at
.
The right way to fix it is to reconstruct a JFFS2 system.
Requriement
SSH access to the router is enabled before
Merlin is not required.
Dump the
Get an external storage device, be it a USB stick or HDD, connect it to the router. Then this storage device should be automatically mounted in /mnt. For the sake of discussion, let's say it's mounted as
Then we dump the filesystem to a dd image.
To do so, we need to find the corresponding block device on which
. Then we can dump the file system with
Fetch the dd image
Now on your own PC running some version of linux, fetch the
For example, if the private key is in ~/.ssh/id, and ssh server on the router is running on port 78, and the username (same as GUI login name) is admin, router's IP is 192.168.50.1, then the command would be
Alternatively, just use sneakernet.
Mount the dd image
Now that the image file is on your PC, you can mount it. To play with JFFS, you will need to install mtd-utils, on Debian, it's done by running
The tutorial can be found here https://wiki.emacinc.com/wiki/Mounting_JFFS2_Images_on_a_Linux_PC (the "Mounting JFFS2 Images using RAM" section).
Here are explanations of some magic numbers:
50000: This is the number that's slightly bigger than than size of
128: This can be obtained from running
Remove unnecessary files
Now, the
Create new JFFS
Then we can recreate a slim JFFS2 volume from
The value for eraseblock and pad sould be copied from the output running
For example, on my router, the output is
We know that
Restore the new JFFS to the router
After this command, there should be a
Then just use
Then do a reboot, and
/jffs
due to bloated /jffs/.sys/TrafficAnalyzer
folder.df
reports that /jffs
is 100% used on my router, and due to the design of JFFS, files can't be removed or edited if the disk if full. Therefore following commands are useless in this case:
Code:
TrafficAnalyzer -d 30720
rm -rf /jffs/.sys/TrafficAnalyzer/
echo "" > /jffs/.sys/TrafficAnalyzer/TrafficAnalyzer.db
The right way to fix it is to reconstruct a JFFS2 system.
Requriement
SSH access to the router is enabled before
/jffs
is full.Merlin is not required.
Dump the
/jffs
Get an external storage device, be it a USB stick or HDD, connect it to the router. Then this storage device should be automatically mounted in /mnt. For the sake of discussion, let's say it's mounted as
/mnt/External
.Then we dump the filesystem to a dd image.
To do so, we need to find the corresponding block device on which
/jffs
resides. To do so, run cat /proc/mounts
, and observe the output:
Code:
$ cat /proc/mounts
...
/dev/mtdblock9 /jffs jffs2 rw,noatime 0 0
dd if=/dev/mtdblock9 of=/mnt/External/original.jffs2
.Fetch the dd image
Now on your own PC running some version of linux, fetch the
original.jffs2
with scp -i [ssh_key] -P [ssh port] [username]@[router's ip]:/mnt/External/original.jffs2 .
command.For example, if the private key is in ~/.ssh/id, and ssh server on the router is running on port 78, and the username (same as GUI login name) is admin, router's IP is 192.168.50.1, then the command would be
scp -i ~/.ssh/id -P 78 admin@192.168.50.1:/mnt/External/original.jffs2 .
.Alternatively, just use sneakernet.
Mount the dd image
Now that the image file is on your PC, you can mount it. To play with JFFS, you will need to install mtd-utils, on Debian, it's done by running
apt install mtd-utils
.The tutorial can be found here https://wiki.emacinc.com/wiki/Mounting_JFFS2_Images_on_a_Linux_PC (the "Mounting JFFS2 Images using RAM" section).
Code:
# cleanup if necessary
umount /dev/mtdblock0
modprobe -r mtdram
modprobe -r mtdblock
modprobe mtdram total_size=50000 erase_size=128
modprobe mtdblock
dd if=original.jffs2 of=/dev/mtdblock0
mkdir jffs_mount
mount -t jffs2 /dev/mtdblock0 jffs_mount
50000: This is the number that's slightly bigger than than size of
original.jffs2
, in KiB. For example, the size of original.jffs2
in my case is 49283072B, or 48128KiB, so I used 50000.128: This can be obtained from running
cat /proc/mtd
on router, read the tutorial for more information.Remove unnecessary files
Now, the
/jffs
on your router should be available in the jffs_mount
folder, and you can remove the bloated TrafficAnalyzer by running rm -r jffs_mount/.sys/TrafficAnalyzer
.Create new JFFS
Then we can recreate a slim JFFS2 volume from
jffs_mount
.
Code:
mkfs.jffs2 -r jffs_mount --eraseblock=0x20000 --pad=0x2f00000 -o trimmed.jffs2
cat /proc/mtd
on router.For example, on my router, the output is
Code:
cat /proc/mtd
dev: size erasesize name
mtd0: 05f00000 00020000 "rootfs"
mtd1: 05f00000 00020000 "rootfs_update"
mtd2: 00800000 00020000 "data"
mtd3: 00100000 00020000 "nvram"
mtd4: 05f00000 00020000 "image"
mtd5: 05f00000 00020000 "image_update"
mtd6: 10000000 00020000 "dummy1"
mtd7: 10000000 00020000 "dummy2"
mtd8: 00100000 00020000 "misc3"
mtd9: 02f00000 00020000 "misc2"
mtd10: 00800000 00020000 "misc1"
mtd11: 05638000 0001f000 "rootfs_ubifs"
mtd12: 0001f000 0001f000 "METADATA"
mtd13: 0001f000 0001f000 "METADATACOPY"
mtd14: 003421d0 0001f000 "filestruct_full.bin"
mtd15: 006c8000 0001f000 "data"
/jffs
is on /dev/mtdblock9
, then according to mtd9: 02f00000 00020000 "misc2"
, the eraseblock is set to 0x20000, and the pad is set to 0x2f00000.Restore the new JFFS to the router
After this command, there should be a
trimmed.jffs2
in the current directory, and its size should be exactly the same as original.jffs2
.Then just use
scp
to copy trimmed.jffs2
back to the storage device, and use dd again to dump the image to the block devicedd if=/mnt/External/trimmed.jffs2 of=/dev/mtdblock9
.Then do a reboot, and
/jffs
should be writable again.
Last edited: