JFFS2 no udef, all char/block devices hardlinked to /dev/console


yocto@...
 

Hi

I'm doing a Yocto Zeus build for a very old Linux Kernel (The Kernel is built
outside of Yocto). Since my target CPU, based on mips32 little endian, was
removed from Linux mainline I've opted to use musl to keep at least the
user space up to date.

I'm building a JFFS2 root fs using --devtable= since my kernel does not have
devfs/udev. The file looks like:
/dev/console c 640 0 0 5 1 - - -
/dev/full c 640 0 0 1 7 - - -
/dev/mtd c 640 0 0 90 0 0 2 8
/dev/mtdblock b 640 0 0 31 0 0 1 8
/dev/null c 666 0 0 1 3 - - -
...

Running mkfs.jffs2 outside Yocto works. Running mkfs.jffs2 as part of the
default image build step breaks my char/block devices. All device files are
hard linked to the first one. Moreover the permissions are also reset.

Example Output of ls /dev/*:
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/console
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/full
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtd0
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtd1
...
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtdblock0
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtdblock1
..
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtdchar
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/null

It looks like add_host_filesystem_entry calls lstat for all files added to the
JFFS2 including files that do not exist. For some reason I do not yet understand
lstat returns garbage instead of just failing on my system (Ubuntu 18.04). This
in turn leads to the hard linking and permisson issues described above. I
suggest to disable lstat for device files to counter this issue:

---
jffsX-utils/mkfs.jffs2.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/jffsX-utils/mkfs.jffs2.c b/jffsX-utils/mkfs.jffs2.c
index 9afd920..2779706 100644
--- a/jffsX-utils/mkfs.jffs2.c
+++ b/jffsX-utils/mkfs.jffs2.c
@@ -219,14 +219,18 @@ static struct filesystem_entry *add_host_filesystem_entry(const char *name,
const char *path, unsigned long uid, unsigned long gid,
unsigned long mode, dev_t rdev, struct filesystem_entry *parent)
{
- int status;
+ int status = -1;
char *tmp;
struct stat sb;
time_t timestamp = time(NULL);
struct filesystem_entry *entry;

memset(&sb, 0, sizeof(struct stat));
- status = lstat(path, &sb);
+
+ //Do not call lstat for char- and block-devices
+ if (major(rdev) == 0) {
+ status = lstat(path, &sb);
+ }

if (status >= 0) {
/* It is ok for some types of files to not exit on disk (such as
--
2.17.1

Andreas


Andreas Dröscher <yocto@...>
 

Hi

I'm doing a Yocto Zeus build for a very old Linux Kernel (The Kernel is built
outside of Yocto). Since my target CPU, based on mips32 little endian, was
removed from Linux mainline I've opted to use musl to keep at least the
user space up to date.

I'm building a JFFS2 root fs using --devtable= since my kernel does not have
devfs/udev. The file looks like:
/dev/console c 640 0 0 5 1 - - -
/dev/full c 640 0 0 1 7 - - -
/dev/mtd c 640 0 0 90 0 0 2 8
/dev/mtdblock b 640 0 0 31 0 0 1 8
/dev/null c 666 0 0 1 3 - - -
...

Running mkfs.jffs2 outside Yocto works. Running mkfs.jffs2 as part of the
default image build step breaks my char/block devices. All device files are
hard linked to the first one. Moreover the permissions are also reset.

Example Output of ls /dev/*:
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/console
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/full
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtd0
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtd1
...
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtdblock0
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtdblock1
..
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtdchar
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/null

It looks like add_host_filesystem_entry calls lstat for all files added to the
JFFS2 including files that do not exist. For some reason I do not yet understand
lstat returns garbage instead of just failing on my system (Ubuntu 18.04). This
in turn leads to the hard linking and permisson issues described above. I
suggest to disable lstat for device files to counter this issue:

---
jffsX-utils/mkfs.jffs2.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/jffsX-utils/mkfs.jffs2.c b/jffsX-utils/mkfs.jffs2.c
index 9afd920..2779706 100644
--- a/jffsX-utils/mkfs.jffs2.c
+++ b/jffsX-utils/mkfs.jffs2.c
@@ -219,14 +219,18 @@ static struct filesystem_entry *add_host_filesystem_entry(const char *name,
const char *path, unsigned long uid, unsigned long gid,
unsigned long mode, dev_t rdev, struct filesystem_entry *parent)
{
- int status;
+ int status = -1;
char *tmp;
struct stat sb;
time_t timestamp = time(NULL);
struct filesystem_entry *entry;

memset(&sb, 0, sizeof(struct stat));
- status = lstat(path, &sb);
+
+ //Do not call lstat for char- and block-devices
+ if (major(rdev) == 0) {
+ status = lstat(path, &sb);
+ }

if (status >= 0) {
/* It is ok for some types of files to not exit on disk (such as
--
2.17.1

Andreas


Khem Raj
 

On 4/3/20 1:45 AM, Andreas Dröscher wrote:
Hi
I'm doing a Yocto Zeus build for a very old Linux Kernel (The Kernel is built
outside of Yocto). Since my target CPU, based on mips32 little endian, was
removed from Linux mainline I've opted to use musl to keep at least the
user space up to date.
I'm building a JFFS2 root fs using --devtable= since my kernel does not have
devfs/udev. The file looks like:
/dev/console    c   640      0       0        5      1       - -       -
/dev/full       c   640      0       0        1      7       - -       -
/dev/mtd        c   640      0       0       90      0       0 2       8
/dev/mtdblock   b   640      0       0       31      0       0 1       8
/dev/null       c   666      0       0        1      3       - -       -
...
Running mkfs.jffs2 outside Yocto works. Running mkfs.jffs2 as part of the
default image build step breaks my char/block devices. All device files are
hard linked to the first one. Moreover the permissions are also reset.
are you running same mkfs.jffs2 utility in and outside yocto experiment ? if not then lets fix that first, it could be a problem in the native package that yocto build system produces.

Example Output of ls /dev/*:
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/console
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/full
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtd0
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtd1
...
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtdblock0
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtdblock1
..
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/mtdchar
crw-r----- 16 root root 5, 1, Jan 1 1970 /dev/null
It looks like add_host_filesystem_entry calls lstat for all files added to the
JFFS2 including files that do not exist. For some reason I do not yet understand
lstat returns garbage instead of just failing on my system (Ubuntu 18.04). This
in turn leads to the hard linking and permisson issues described above. I
suggest to disable lstat for device files to counter this issue:
the fact that it works outside yocto, I think it might be premature to disable it, we should see if we can find the real cause for the issue, it could be fixed rightly then


---
 jffsX-utils/mkfs.jffs2.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/jffsX-utils/mkfs.jffs2.c b/jffsX-utils/mkfs.jffs2.c
index 9afd920..2779706 100644
--- a/jffsX-utils/mkfs.jffs2.c
+++ b/jffsX-utils/mkfs.jffs2.c
@@ -219,14 +219,18 @@ static struct filesystem_entry *add_host_filesystem_entry(const char *name,
         const char *path, unsigned long uid, unsigned long gid,
         unsigned long mode, dev_t rdev, struct filesystem_entry *parent)
 {
-    int status;
+    int status = -1;
     char *tmp;
     struct stat sb;
     time_t timestamp = time(NULL);
     struct filesystem_entry *entry;
     memset(&sb, 0, sizeof(struct stat));
-    status = lstat(path, &sb);
+
+    //Do not call lstat for char- and  block-devices
+    if (major(rdev) == 0) {
+        status = lstat(path, &sb);
+    }
     if (status >= 0) {
         /* It is ok for some types of files to not exit on disk (such as


Andreas Dröscher <yocto@...>
 

Am 03.04.20 um 19:26 schrieb Khem Raj:


Running mkfs.jffs2 outside Yocto works. Running mkfs.jffs2 as part of the
default image build step breaks my char/block devices. All device files are
hard linked to the first one. Moreover the permissions are also reset.
are you running same mkfs.jffs2 utility in and outside yocto experiment ? if not then lets fix that first, it could be a problem in the native package that yocto build system produces.
I hope so. Steps I took for debugging.

I changed EXTRA_IMAGECMD_jffs2:

EXTRA_IMAGECMD_jffs2="-p -l -e 0x20000 -D /data/my-device-table.txt -v; exit 1"

This on one hand enables verbose mkfs.jffs2 and on other hand breaks the step. Therefore the root-fs folder is not cleaned up and I can reraun the comand from the run.do_image script.

Trimmed verbose output of:

$ bitbake core-image-minimal

ERROR: core-image-minimal-1.0-r0 do_image_jffs2: Execution of '/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/temp/run.do_image_jffs2.24583' failed with exit code 1:
/
d 0755 0 0:0 bin
d 0755 0 0:0 boot
d 0755 0 0:0 dev
d 0755 0 0:0 etc
d 0755 0 0:0 home
d 0755 0 0:0 lib
d 0755 0 0:0 media
d 0755 0 0:0 mnt
d 0555 0 0:0 proc
d 0755 0 0:0 run
d 0755 0 0:0 sbin
d 0555 0 0:0 sys
d 1777 0 0:0 tmp
d 0755 0 0:0 usr
d 0755 0 0:0 var
/bin
l 0777 19 0:0 ash -> /bin/busybox.nosuid
l 0777 14 0:0 busybox -> busybox.nosuid
f 0755 914688 ( 551963) 0:0 busybox.nosuid
f 4755 68204 ( 39081) 0:0 busybox.suid
l 0777 19 0:0 cat -> /bin/busybox.nosuid
l 0777 19 0:0 chattr -> /bin/busybox.nosuid
...
/boot
/dev
c 0640 5, 1 0:0 console
L 0640 81 0:0 full
L 0640 81 0:0 mtd0
L 0640 81 0:0 mtd1
L 0640 81 0:0 mtd2
L 0640 81 0:0 mtd3
L 0640 81 0:0 mtd4
L 0640 81 0:0 mtd5
L 0640 81 0:0 mtd6
L 0640 81 0:0 mtd7
L 0640 81 0:0 mtdblock0
L 0640 81 0:0 mtdblock1
L 0640 81 0:0 mtdblock2
L 0640 81 0:0 mtdblock3
L 0640 81 0:0 mtdblock4
L 0640 81 0:0 mtdblock5

grep "PATH=" run.do_image_jffs2 returns:

export PATH="/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/recipe-sysroot/usr/bin/crossscripts:/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/recipe-sysroot/opt/poky/3.0.2/sysroots/x86_64-pokysdk-linux/usr/bin/crossscripts:/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/recipe-sysroot/usr/bin/crossscripts:/data/oe-core/poky/build-au1100-hw/tmp/sysroots-uninative/x86_64-linux/usr/bin:/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/recipe-sysroot-native/usr/bin/python3-native:/data/oe-core/poky/scripts:/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/recipe-sysroot-native/usr/bin/mipsel-poky-linux-musl:/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/recipe-sysroot/usr/bin/crossscripts:/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/recipe-sysroot-native/usr/sbin:/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/recipe-sysroot-native/usr/bin:/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/recipe-sysroot-native/sbin:/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/recipe-sysroot-native/bin:/data/oe-core/poky/bitbake/bin:/data/oe-core/poky/build-au1100-hw/tmp/hosttools"

So I do export the PATH above, result:
$ mkfs.jffs2 --version
mkfs.jffs2 (mtd-utils) 2.1.1

Note my Ubuntu has:
$ mkfs.jffs2 --version
mkfs.jffs2 (mtd-utils) 2.0.1

Finaly I run:
$ mkfs.jffs2 --root=/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/rootfs --faketime --output=/data/oe-core/poky/build-au1100-hw/tmp/work/au1100_hw-poky-linux-musl/core-image-minimal/1.0-r0/deploy-core-image-minimal-image-complete/core-image-minimal-au1100-hw-20200403193756.rootfs.jffs2 -p -l -e 0x20000 -D /data/my-device-table.txt -v;

Output:
/
d 0755 0 1000:1000 bin
d 0755 0 1000:1000 boot
d 0755 0 1000:1000 dev
d 0755 0 1000:1000 etc
d 0755 0 1000:1000 home
d 0755 0 1000:1000 lib
d 0755 0 1000:1000 media
d 0755 0 1000:1000 mnt
d 0755 0 1000:1000 proc
d 0755 0 1000:1000 run
d 0755 0 1000:1000 sbin
d 0755 0 1000:1000 sys
d 1755 0 1000:1000 tmp
d 0755 0 1000:1000 usr
d 0755 0 1000:1000 var
/bin
l 0777 19 0:0 ash -> /bin/busybox.nosuid
l 0777 14 0:0 busybox -> busybox.nosuid
f 0755 914688 ( 551963) 0:0 busybox.nosuid
f 4755 68204 ( 39081) 0:0 busybox.suid
l 0777 19 0:0 cat -> /bin/busybox.nosuid
l 0777 19 0:0 chattr -> /bin/busybox.nosuid
...
/boot
/dev
c 0640 5, 1 0:0 console
c 0640 1, 7 0:0 full
c 0640 90, 0 0:0 mtd0
c 0640 90, 2 0:0 mtd1
c 0640 90, 4 0:0 mtd2
c 0640 90, 6 0:0 mtd3
c 0640 90, 8 0:0 mtd4
c 0640 90, 10 0:0 mtd5
c 0640 90, 12 0:0 mtd6
c 0640 90, 14 0:0 mtd7
b 0640 31, 0 0:0 mtdblock0
b 0640 31, 1 0:0 mtdblock1
b 0640 31, 2 0:0 mtdblock2
b 0640 31, 3 0:0 mtdblock3
b 0640 31, 4 0:0 mtdblock4
b 0640 31, 5 0:0 mtdblock5
b 0640 31, 6 0:0 mtdblock6
b 0640 31, 7 0:0 mtdblock7