Commit e8f6e8b1 authored by Edmund Smith's avatar Edmund Smith Committed by Emil Velikov
Browse files

machine: cpio: extract compressed modules



With kernel 5.13 one can have zstd compressed modules, alongside the
existing gzip and xz.

Unlike the latter two, busybox does not support zstd. Thus it will fail
to load the modules early in the boot process.

Existing init ramdisk builders like dracut and mkinitcpio explicitly
extract compressed kernel modules, so let's do the same there

[Emil Velikov]
 - Split from larger commit
 - Rebase onto modinfo series
 - Rewrite commit message
 - Remove NullDecompressor
Signed-off-by: default avatarEmil Velikov <emil.velikov@collabora.com>
parent e02551d3
package writerhelper
import (
"bytes"
"io"
"log"
"os"
......@@ -16,6 +17,8 @@ type WriterHelper struct {
*cpio.Writer
}
type Transformer func(dst io.Writer, src io.Reader) error
func NewWriterHelper(f io.Writer) *WriterHelper {
return &WriterHelper{
paths: map[string]bool{"/": true},
......@@ -148,6 +151,36 @@ func (w *WriterHelper) CopyFileTo(src, dst string) error {
return nil
}
func (w *WriterHelper) TransformFileTo(src, dst string, fn Transformer) error {
w.ensureBaseDirectory(path.Dir(dst))
f, err := os.Open(src)
if err != nil {
log.Panicf("open failed: %s - %v", src, err)
return err
}
defer f.Close()
info, err := f.Stat()
if err != nil {
return err
}
out := new(bytes.Buffer)
fn(out, f)
hdr := new(cpio.Header)
hdr.Type = cpio.TYPE_REG
hdr.Name = dst
hdr.Mode = int64(info.Mode() & ^os.ModeType)
hdr.Size = int64(out.Len())
w.WriteHeader(hdr)
io.Copy(w, out)
return nil
}
func (w *WriterHelper) CopyFile(in string) error {
return w.CopyFileTo(in, in)
}
......@@ -75,7 +75,7 @@ func getModDepends(modname string, kernelRelease string) []string {
return modlist
}
func (m *Machine) copyModules(w *writerhelper.WriterHelper, modname string, copiedModules map[string]bool) error {
func (m *Machine) copyModules(w *writerhelper.WriterHelper, modname string, suffixes map[string]writerhelper.Transformer, copiedModules map[string]bool) error {
release, _ := m.backend.HostKernelRelease()
modpath := getModPath(modname, release)
if modpath == "" {
......@@ -91,15 +91,31 @@ func (m *Machine) copyModules(w *writerhelper.WriterHelper, modname string, copi
prefix = "/usr"
}
if err := w.CopyFile(prefix + modpath); err != nil {
return err
found := false
for suffix, fn := range suffixes {
if strings.HasSuffix(modpath, suffix) {
if _, err := os.Stat(modpath); err == nil {
basepath := strings.TrimSuffix(modpath, suffix)
if err := w.TransformFileTo(modpath, prefix + basepath, fn); err != nil {
return err
}
found = true
break
}
}
}
// No compressed module found, doing a plain copy
if !found {
if err := w.CopyFile(prefix + modpath); err != nil {
return err
}
}
copiedModules[modname] = true;
deplist := getModDepends(modname, release)
for _, mod := range deplist {
if err := m.copyModules(w, mod, copiedModules); err != nil {
if err := m.copyModules(w, mod, suffixes, copiedModules); err != nil {
return err
}
}
......@@ -462,7 +478,16 @@ func (m Machine) generateFstab(w *writerhelper.WriterHelper, backend backend) {
w.WriteFile("/etc/fstab", strings.Join(fstab, "\n"), 0755)
}
func (m *Machine) buildModuleMap(moddir string) (map[string][]string, error) {
func stripModuleSuffixes(module string, suffixes []string) string {
for _, suffix := range(suffixes) {
if strings.HasSuffix(module, suffix) {
return strings.TrimSuffix(module, suffix)
}
}
return module
}
func (m *Machine) buildModuleMap(moddir string, suffixes []string) (map[string][]string, error) {
f, err := os.Open(path.Join(moddir, "modules.dep"))
if err != nil {
return nil, err
......@@ -481,12 +506,12 @@ func (m *Machine) buildModuleMap(moddir string) (map[string][]string, error) {
continue
}
var module = parts[0]
var module = stripModuleSuffixes(parts[0], suffixes)
graph[module] = make([]string, 0)
if len(parts) > 1 {
deps := strings.Split(parts[1], " ")
for _, dep := range(deps) {
graph[module] = append(graph[module], dep)
graph[module] = append(graph[module], stripModuleSuffixes(dep, suffixes))
}
}
}
......@@ -555,6 +580,12 @@ func (m *Machine) SetEnviron(environ []string) {
func (m *Machine) writerKernelModules(w *writerhelper.WriterHelper, moddir string, modules []string) error {
suffixes := map[string]writerhelper.Transformer {
".gz": GzipDecompressor,
".xz": XzDecompressor,
".zst": ZstdDecompressor,
}
if len(modules) == 0 {
return nil
}
......@@ -573,12 +604,19 @@ func (m *Machine) writerKernelModules(w *writerhelper.WriterHelper, moddir strin
copiedModules := make(map[string]bool)
for _, modname := range modules {
if err := m.copyModules(w, modname, copiedModules); err != nil {
if err := m.copyModules(w, modname, suffixes, copiedModules); err != nil {
return err
}
}
graph, err := m.buildModuleMap(moddir)
suffixKeys := make([]string, len(suffixes))
i := 0
for k := range suffixes {
suffixKeys[i] = k
i++
}
graph, err := m.buildModuleMap(moddir, suffixKeys)
if err != nil {
return err
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment