Software Archive
Read-only legacy content
17061 Discussions

Overlay is not integrated into initrd (MPSS 3.4.2)

Anselm_B_
Beginner
337 Views

Hello,

I just upgrade to the MPSS 3.4.2 and since filelists are not supported anymore for the base initrd, I tried the overlay feature with a filelist. However, I quickly realized that the files I wanted to add are not ending up in the final initrd image. So I investigated the problem and took a look at the final CPIO. What I found was the following structure:

(base file A content)[filename A]
(base file B content)[filename B]
[...]
(base file Z content)[filename Z]
(magic number for cpio end)[TRAILER!!!]
(overlay file a content)[filename a]
[...]
(overlay file z content)[filename z]
(magic number for cpio end)[TRAILER!!!]

Obviously the magic number indicating the end of the cpio after the default content and before the overlay files in line 5 is an issue. Then I took a look in the source code of the micctrl receptively the libmpssconfig. The problem seems to be that when adding the overlay it simply extracts the base initrd and appends the overlay at the end of the cpio leaving the file end indicator where it is and adding a second one at then end. To have a quick fix, I patched the genfs.c file to move back before the end indicator of the original initrd and let it simply overwrite it by the overlay files (see patch at the end). This does the trick for me now.

However, it would be great if this bug gets fixed in the next release of MPSS as I only have a very crude fix and it might also affect other users.

 	oldmask = umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
-	if ((cpiofp = fopen(cpioname, "a")) == NULL) {
+	if ((cpiofp = fopen(cpioname, "r+")) == NULL) {
 		umask(oldmask);
 		return errno;
 	}

+	// find end of cpio and set file pointer before magic number
+	buffer[9] = '\0';
+	fseek(cpiofp, -9, SEEK_END);
+	do{
+		fread(buffer, sizeof(char), 9, cpiofp);
+		fseek(cpiofp, -10, SEEK_CUR);
+	} while(strncmp(buffer,"TRAILER!!!",9));
+
+	fseek(cpiofp, -109, SEEK_CUR);
+
 	follow_dir(menv, top->subdir, "", cpiofp, &inode, &offset, perrs);
 	cpio_trailer(cpiofp, &inode, &offset);

 

0 Kudos
2 Replies
Frances_R_Intel
Employee
337 Views

If the file you were looking at when you saw the two cpio terminators was /var/mpss/micX.image.gz, where X is the coprocessor number, then that was correct. This file contains the base cpio file and a cpio file containing the files from /var/mpss/micX, /var/mpss/common and any overlays. It will, indeed, have two cpio terminators and overlays should show up in the final ramfs on the coprocessor.

With MPSS 3.3 and 3.4, if what you want to do is change a file that is in the base cpio file, you can extract the files from /usr/share/mpss/boot/initramfs-knightscorner.cpio.gz into a directory, then directly change the file in that directory and, in the future, boot using the contents of that directory as your base. The 'micctl --base=dir --new=<directory_name>' should extract the contents of /usr/share/mpss/boot/initramfs-knightscorner.cpio.gz into that directory and change the micX.conf file so that this directory will be used at boot time.

Could you provide an example where the overlay didn't work, so we can figure out what went wrong and get it fixed?

0 Kudos
Evan_P_Intel
Employee
337 Views

Anselm B. wrote:

Obviously the magic number indicating the end of the cpio after the default content and before the overlay files in line 5 is an issue.

Actually, it's not an issue, or at least not obviously; the file in question is not a cpio archive per se, but rather the exact sequence of bytes to be loaded into memory by the bootloader as the Linux kernel's initramfs buffer (as implemented, the buffer contents are built in a file on the host by micctrl, then the kernel module reads this one file into card memory; rather than the kernel module knowing how to take multiple files as input directly). You may recall that Linux bootloaders often allow one to specify more than one initramfs file for a single boot entry (e.g. "INITRD file1,file2" with SYSLINUX, or using the "initrd" directive more than once with GRUB); this concatenation-with-padding within the initramfs buffer is how they're all communicated to the kernel during boot. Even mixing plain cpios and gzipped ones is supported[1], because the Linux kernel expands them into the initial rootfs filesystem more-or-less independently, not as a single naively-concatenated cpio file (the required padding helps it identify file boundaries). So, seeing more than one "TRAILER!!!" is not, in itself, indicative of a problem.

Might the true problem be that the amount of zero-byte padding between the (extracted) base cpio file and the overlay file is incorrect? (The appended overlay cpio must begin at a file offset that is a multiple of four.)

Problems with the initramfs buffer sometimes produce warnings in the card's "dmesg" output that can help with debug, assuming you're able to boot the card and login to read them without the overlay working.

Anselm B. wrote:

I patched the genfs.c file to move back before the end indicator of the original initrd and let it simply overwrite it by the overlay files (see patch at the end).

One reason Linux supports multiple initramfs cpios in the way it does is that combining two arbitrary cpio files by stripping the first's "TRAILER!!!" and concatenating, as you do in your patch, is unsafe—the result may be malformed. The "New ASCII" (a.k.a. "newc") cpio format that Linux expects records hard links by setting the file size to zero for all but the last link; entries with a file size of zero are connected to the entry that holds the actual file content by having the same inode number. Unless the two cpio files happen to use disjoint sets of inode numbers[2], extracting the combined file can result in files from the first archive being erroneously hard linked to random files from the second or an extraction error, depending on how picky about the format the particular implementation is.

The Linux kernel's implementation isn't very strict, so if your overlay doesn't contain hard links, using your patch may not produce any problems. But you should be aware of the possibility.

[1] You noted that micctrl gunzips the base cpio (if it is compressed) before appending the overlay cpio; this support does indeed mean that first step is entirely unnecessary. I'm not sure why micctrl does that.

[2] Some implementations—in particular, the Linux kernel's gen_init_cpio tool—just increment the inode number once for each archived file, so overlapping inode numbers may be guaranteed.

0 Kudos
Reply