Compare commits

2 Commits

Author SHA1 Message Date
jane400
20ba9e4131 misc: also check wheter binaries from /{s,}bin are /usr
This should hopefully avoid failing to build the initramfs
when important binaries like /bin/busybox get moved to /usr.

Also complain loudly when there's a path mismatch, so people notice
it.
2025-02-04 15:07:16 +01:00
Clayton Craft
e5f14d70a6 doc: add archive compression formats/levels (MR 50)
fixes #28
2024-03-20 10:08:18 -07:00
2 changed files with 91 additions and 27 deletions

View File

@@ -54,6 +54,36 @@ a bare minimum, and to require only variables that don't hold lists of things.
necessary tools to extract the configured archive format are in the initramfs necessary tools to extract the configured archive format are in the initramfs
archive. archive.
# ARCHIVE COMPRESSION
Archive compression parameters are specified in the
*deviceinfo_initfs_compression* and *deviceinfo_initfs_extra_compression*
deviceinfo variables. Their values do not have to match, but special
consideration should be taken since some formats may require additional kernel
options or tools in the initramfs to support it.
Supported compression *formats* for mkinitfs are:
- gzip
- lz4
- lzma
- none
- zstd
Supported compression *levels* for mkinitfs:
- best
- default
- fast
The value of these variables follows this syntax: *<format>:<level>*. For
example, *zstd* with the *fast* compression level would be:
*deviceinfo_initfs_compression="zstd:fast"*
Defaults to *gzip* and *default* for both archives if format and/or level is
unsupported or omitted.
# DIRECTORIES # DIRECTORIES
The following directories are used by mkinitfs to generate the initramfs and The following directories are used by mkinitfs to generate the initramfs and

View File

@@ -5,6 +5,8 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"log"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/osutil" "gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/osutil"
) )
@@ -22,39 +24,51 @@ func GetFiles(list []string, required bool) (files []string, err error) {
return return
} }
func getFile(file string, required bool) (files []string, err error) { // This function doesn't handle globs, use getFile() instead.
// Expand glob expression func getFileNormalized(file string, required bool) (files []string, err error) {
expanded, err := filepath.Glob(file) fileInfo, err := os.Stat(file)
// Trying some fallbacks...
if err != nil { if err != nil {
return type triedResult struct {
} file string
if len(expanded) > 0 && expanded[0] != file { err error
for _, path := range expanded { }
if globFiles, err := getFile(path, required); err != nil {
return files, err triedFiles := make([]triedResult, 0, 1)
// Temporary fallback until alpine/pmOS usr-merge happened
// If a path starts with /bin or /sbin, also try /usr equivalent before giving up
if strings.HasPrefix(file, "/bin/") || strings.HasPrefix(file, "/sbin/") {
fileUsr := filepath.Join("/usr", file)
_, err := os.Stat(fileUsr);
if err == nil {
log.Printf("getFile: failed to find %q, but found it in %q. Please adjust the path.", file, fileUsr)
return getFileNormalized(fileUsr, required)
} else { } else {
files = append(files, globFiles...) triedFiles = append(triedFiles, triedResult{fileUsr, err})
} }
} }
return RemoveDuplicates(files), nil
}
fileInfo, err := os.Stat(file) {
if err != nil { // Check if there is a Zstd-compressed version of the file
// Check if there is a Zstd-compressed version of the file fileZstd := file + ".zst" // .zst is the extension used by linux-firmware
fileZstd := file + ".zst" // .zst is the extension used by linux-firmware _, err := os.Stat(fileZstd);
fileInfoZstd, errZstd := os.Stat(fileZstd) if err == nil {
return getFileNormalized(fileZstd, required)
if errZstd == nil { } else {
file = fileZstd triedFiles = append(triedFiles, triedResult{fileZstd, err})
fileInfo = fileInfoZstd
// Unset nil so we don't retain the error from the os.Stat call for the uncompressed version.
err = nil
} else {
if required {
return files, fmt.Errorf("getFile: failed to stat file %q: %w (also tried %q: %w)", file, err, fileZstd, errZstd)
} }
}
// Failed to find anything
if required {
failStrings := make([]string, 0, 2)
for _, result := range triedFiles {
failStrings = append(failStrings, fmt.Sprintf("\n - also tried %q: %v", result.file, result.err))
}
return files, fmt.Errorf("getFile: failed to stat file %q: %v%q", file, err, strings.Join(failStrings, ""))
} else {
return files, nil return files, nil
} }
} }
@@ -95,6 +109,26 @@ func getFile(file string, required bool) (files []string, err error) {
return return
} }
func getFile(file string, required bool) (files []string, err error) {
// Expand glob expression
expanded, err := filepath.Glob(file)
if err != nil {
return
}
if len(expanded) > 0 && expanded[0] != file {
for _, path := range expanded {
if globFiles, err := getFile(path, required); err != nil {
return files, err
} else {
files = append(files, globFiles...)
}
}
return RemoveDuplicates(files), nil
}
return getFileNormalized(file, required)
}
func getDeps(file string, parents map[string]struct{}) (files []string, err error) { func getDeps(file string, parents map[string]struct{}) (files []string, err error) {
if _, found := parents[file]; found { if _, found := parents[file]; found {