github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/integration/generic-tests/kexec_test.go (about)

     1  // Copyright 2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !race
     6  // +build !race
     7  
     8  package integration
     9  
    10  import (
    11  	"os/exec"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/mvdan/u-root-coreutils/pkg/qemu"
    16  	"github.com/mvdan/u-root-coreutils/pkg/uroot"
    17  	"github.com/mvdan/u-root-coreutils/pkg/vmtest"
    18  )
    19  
    20  // TestMountKexec tests that kexec occurs correctly by checking the kernel cmdline.
    21  // This is possible because the generic initramfs ensures that we mount the
    22  // testdata directory containing the initramfs and kernel used in the VM.
    23  func TestMountKexec(t *testing.T) {
    24  	// TODO: support arm
    25  	if vmtest.TestArch() != "amd64" && vmtest.TestArch() != "arm64" {
    26  		t.Skipf("test not supported on %s", vmtest.TestArch())
    27  	}
    28  
    29  	q, cleanup := vmtest.QEMUTest(t, &vmtest.Options{
    30  		TestCmds: []string{
    31  			"var CMDLINE = (cat /proc/cmdline)",
    32  			"var SUFFIX = $CMDLINE[-7..]",
    33  			"echo SAW $SUFFIX",
    34  			"kexec -i /testdata/initramfs.cpio -c $CMDLINE' KEXEC=Y' /testdata/kernel",
    35  		},
    36  		QEMUOpts: qemu.Options{
    37  			Timeout: 20 * time.Second,
    38  			Devices: []qemu.Device{
    39  				qemu.ArbitraryArgs{"-m", "8192"},
    40  			},
    41  		},
    42  	})
    43  	defer cleanup()
    44  
    45  	if err := q.Expect("SAW KEXEC=Y"); err != nil {
    46  		t.Fatal(err)
    47  	}
    48  }
    49  
    50  // TestMountKexecLoad is same as TestMountKexec except it test calling
    51  // kexec_load syscall than file load.
    52  func TestMountKexecLoad(t *testing.T) {
    53  	// TODO: support arm
    54  	if vmtest.TestArch() != "amd64" && vmtest.TestArch() != "arm64" {
    55  		t.Skipf("test not supported on %s", vmtest.TestArch())
    56  	}
    57  
    58  	gzipP, err := exec.LookPath("gzip")
    59  	if err != nil {
    60  		t.Skipf("no gzip found, skip it as it won't be able to de-compress kernel")
    61  	}
    62  
    63  	q, cleanup := vmtest.QEMUTest(t, &vmtest.Options{
    64  		BuildOpts: uroot.Opts{
    65  			ExtraFiles: []string{gzipP},
    66  		},
    67  		TestCmds: []string{
    68  			"var CMDLINE = (cat /proc/cmdline)",
    69  			"var SUFFIX = $CMDLINE[-7..]",
    70  			"echo SAW $SUFFIX",
    71  			"kexec -d -i /testdata/initramfs.cpio --loadsyscall -c $CMDLINE' KEXEC=Y' /testdata/kernel",
    72  		},
    73  		QEMUOpts: qemu.Options{
    74  			Timeout: 20 * time.Second,
    75  			Devices: []qemu.Device{
    76  				qemu.ArbitraryArgs{"-m", "8192"},
    77  			},
    78  		},
    79  	})
    80  	defer cleanup()
    81  
    82  	if err := q.Expect("SAW KEXEC=Y"); err != nil {
    83  		t.Fatal(err)
    84  	}
    85  }
    86  
    87  // TestMountKexecLoadOnly test kexec loads without a kexec reboot.
    88  func TestMountKexecLoadOnly(t *testing.T) {
    89  	// TODO: support arm
    90  	if vmtest.TestArch() != "amd64" && vmtest.TestArch() != "arm64" {
    91  		t.Skipf("test not supported on %s", vmtest.TestArch())
    92  	}
    93  
    94  	gzipP, err := exec.LookPath("gzip")
    95  	if err != nil {
    96  		t.Skipf("no gzip found, skip it as it won't be able to de-compress kernel")
    97  	}
    98  
    99  	q, cleanup := vmtest.QEMUTest(t, &vmtest.Options{
   100  		BuildOpts: uroot.Opts{
   101  			ExtraFiles: []string{gzipP},
   102  		},
   103  		TestCmds: []string{
   104  			"var CMDLINE = (cat /proc/cmdline)",
   105  			"echo kexecloadresult ?(kexec -d -l -i /testdata/initramfs.cpio --loadsyscall -c $CMDLINE /testdata/kernel)",
   106  		},
   107  		QEMUOpts: qemu.Options{
   108  			Timeout: 20 * time.Second,
   109  			Devices: []qemu.Device{
   110  				qemu.ArbitraryArgs{"-m", "8192"},
   111  			},
   112  		},
   113  	})
   114  	defer cleanup()
   115  
   116  	if err := q.Expect("kexecloadresult $ok"); err != nil {
   117  		t.Fatal(err)
   118  	}
   119  }
   120  
   121  // TestMountKexecLoadCustomDTB test kexec_load a Arm64 Image with a user provided dtb.
   122  func TestMountKexecLoadCustomDTB(t *testing.T) {
   123  	if vmtest.TestArch() != "arm64" {
   124  		t.Skipf("test not supported on %s", vmtest.TestArch())
   125  	}
   126  	q, cleanup := vmtest.QEMUTest(t, &vmtest.Options{
   127  		TestCmds: []string{
   128  			"var CMDLINE = (cat /proc/cmdline)",
   129  			"var SUFFIX = $CMDLINE[-7..]",
   130  			"echo SAW $SUFFIX",
   131  			"cp /sys/firmware/fdt /tmp/userfdt",
   132  			"kexec -d --dtb /tmp/userfdt   -i /testdata/initramfs.cpio --loadsyscall -c $CMDLINE' KEXEC=Y' /testdata/kernel",
   133  		},
   134  		QEMUOpts: qemu.Options{
   135  			Timeout: 20 * time.Second,
   136  			Devices: []qemu.Device{
   137  				qemu.ArbitraryArgs{"-m", "8192"},
   138  			},
   139  		},
   140  	})
   141  	defer cleanup()
   142  
   143  	if err := q.Expect("SAW KEXEC=Y"); err != nil {
   144  		t.Fatal(err)
   145  	}
   146  }