mirror of
https://github.com/ipxe/ipxe
synced 2026-02-11 05:38:16 +03:00
[cpio] Allow for construction of parent directories as needed
iPXE allows individual raw files to be automatically wrapped with suitable CPIO headers and injected into the magic initrd image as exposed to a booted Linux kernel. This feature is currently limited to placing files within directories that already exist in the initrd filesystem. Remove this limitation by adding the ability for iPXE to construct CPIO headers for parent directories as needed, under control of the "mkdir=<n>" command-line argument. For example: initrd config.ign /usr/share/oem/config.ign mkdir=1 will create CPIO headers for the "/usr/share/oem" directory as well as for the "/usr/share/oem/config.ign" file itself. This simplifies the process of booting operating systems such as Flatcar Linux, which otherwise require the single "config.ign" file to be manually wrapped up as a CPIO archive solely in order to create the relevant parent directory entries. The value <n> may be used to control the number of parent directory entries that are created. For example, "mkdir=2" would cause up to two parent directories to be created (i.e. "/usr/share" and "/usr/share/oem" in the above example). A negative value such as "mkdir=-1" may be used to create all parent directories up to the root of the tree. Do not create any parent directory entries by default, since doing so would potentially cause the modes and ownership information for existing directories to be overwritten. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -353,24 +353,35 @@ static size_t bzimage_load_initrd ( struct image *image,
|
||||
const char *filename = cpio_name ( initrd );
|
||||
struct cpio_header cpio;
|
||||
size_t offset;
|
||||
size_t cpio_len;
|
||||
size_t pad_len;
|
||||
size_t len;
|
||||
unsigned int i;
|
||||
|
||||
/* Skip hidden images */
|
||||
if ( initrd->flags & IMAGE_HIDDEN )
|
||||
return 0;
|
||||
|
||||
/* Create cpio header for non-prebuilt images */
|
||||
offset = cpio_header ( initrd, &cpio );
|
||||
/* Determine length of cpio headers for non-prebuilt images */
|
||||
len = 0;
|
||||
for ( i = 0 ; ( cpio_len = cpio_header ( initrd, i, &cpio ) ) ; i++ )
|
||||
len += ( cpio_len + cpio_pad_len ( cpio_len ) );
|
||||
|
||||
/* Copy in initrd image body (and cpio header if applicable) */
|
||||
/* Copy in initrd image body and construct any cpio headers */
|
||||
if ( address ) {
|
||||
memmove_user ( address, offset, initrd->data, 0, initrd->len );
|
||||
if ( offset ) {
|
||||
memset_user ( address, 0, 0, offset );
|
||||
copy_to_user ( address, 0, &cpio, sizeof ( cpio ) );
|
||||
copy_to_user ( address, sizeof ( cpio ), filename,
|
||||
cpio_name_len ( initrd ) );
|
||||
memmove_user ( address, len, initrd->data, 0, initrd->len );
|
||||
memset_user ( address, 0, 0, len );
|
||||
offset = 0;
|
||||
for ( i = 0 ; ( cpio_len = cpio_header ( initrd, i, &cpio ) ) ;
|
||||
i++ ) {
|
||||
copy_to_user ( address, offset, &cpio,
|
||||
sizeof ( cpio ) );
|
||||
copy_to_user ( address, ( offset + sizeof ( cpio ) ),
|
||||
filename,
|
||||
( cpio_len - sizeof ( cpio ) ) );
|
||||
offset += ( cpio_len + cpio_pad_len ( cpio_len ) );
|
||||
}
|
||||
assert ( offset == len );
|
||||
DBGC ( image, "bzImage %p initrd %p [%#08lx,%#08lx,%#08lx)"
|
||||
"%s%s\n", image, initrd, user_to_phys ( address, 0 ),
|
||||
user_to_phys ( address, offset ),
|
||||
@@ -379,14 +390,14 @@ static size_t bzimage_load_initrd ( struct image *image,
|
||||
DBGC2_MD5A ( image, user_to_phys ( address, offset ),
|
||||
user_to_virt ( address, offset ), initrd->len );
|
||||
}
|
||||
offset += initrd->len;
|
||||
len += initrd->len;
|
||||
|
||||
/* Zero-pad to next INITRD_ALIGN boundary */
|
||||
pad_len = ( ( -offset ) & ( INITRD_ALIGN - 1 ) );
|
||||
pad_len = ( ( -len ) & ( INITRD_ALIGN - 1 ) );
|
||||
if ( address )
|
||||
memset_user ( address, offset, 0, pad_len );
|
||||
memset_user ( address, len, 0, pad_len );
|
||||
|
||||
return offset;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user