gopkg.in/hugelgupf/u-root.v9@v9.0.0-20180831063832-3f6f1057f09b/cmds/kexec/kexec_linux.go (about) 1 // Copyright 2015-2017 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 // kexec executes a new kernel over the running kernel (u-root). 6 // 7 // Synopsis: 8 // kexec [--initrd=FILE] [--command-line=STRING] [-l] [-e] [KERNELIMAGE] 9 // 10 // Description: 11 // Loads a kernel for later execution. 12 // 13 // Options: 14 // --cmdline=STRING or -c=STRING: Set the kernel command line 15 // --reuse-commandline: Use the kernel command line from running system 16 // --i=FILE or --initrd=FILE: Use file as the kernel's initial ramdisk 17 // -l or --load: Load the new kernel into the current kernel 18 // -e or --exec: Execute a currently loaded kernel 19 package main 20 21 import ( 22 "log" 23 "os" 24 25 flag "github.com/spf13/pflag" 26 "github.com/u-root/u-root/pkg/cmdline" 27 "github.com/u-root/u-root/pkg/kexec" 28 ) 29 30 type options struct { 31 cmdline string 32 reuseCmdline bool 33 initramfs string 34 load bool 35 exec bool 36 } 37 38 func registerFlags() *options { 39 o := &options{} 40 flag.StringVarP(&o.cmdline, "cmdline", "c", "", "Set the kernel command line") 41 flag.BoolVar(&o.reuseCmdline, "reuse-cmdline", false, "Use the kernel command line from running system") 42 flag.StringVarP(&o.initramfs, "initrd", "i", "", "Use file as the kernel's initial ramdisk") 43 flag.BoolVarP(&o.load, "load", "l", false, "Load the new kernel into the current kernel") 44 flag.BoolVarP(&o.exec, "exec", "e", false, "Execute a currently loaded kernel") 45 return o 46 } 47 48 func main() { 49 opts := registerFlags() 50 flag.Parse() 51 52 if (opts.exec == false && flag.NArg() == 0) || flag.NArg() > 1 { 53 flag.PrintDefaults() 54 log.Fatalf("usage: kexec [flags] kernelname OR kexec -e") 55 } 56 57 if opts.cmdline != "" && opts.reuseCmdline { 58 flag.PrintDefaults() 59 log.Fatalf("--reuse-cmdline and other command line options are mutually exclusive") 60 } 61 62 if opts.load == false && opts.exec == false { 63 opts.load = true 64 opts.exec = true 65 } 66 67 newCmdLine := opts.cmdline 68 if opts.reuseCmdline { 69 procCmdLine := cmdline.NewCmdLine() 70 if procCmdLine.Err != nil { 71 log.Fatal("Couldn't read /proc/cmdline") 72 } else { 73 newCmdLine = procCmdLine.Raw 74 } 75 } 76 77 if opts.load { 78 kernelpath := flag.Args()[0] 79 log.Printf("Loading %s for kernel\n", kernelpath) 80 81 kernel, err := os.OpenFile(kernelpath, os.O_RDONLY, 0) 82 if err != nil { 83 log.Fatalf("open(%q): %v", kernelpath, err) 84 } 85 defer kernel.Close() 86 87 var ramfs *os.File 88 if opts.initramfs != "" { 89 ramfs, err = os.OpenFile(opts.initramfs, os.O_RDONLY, 0) 90 if err != nil { 91 log.Fatalf("open(%q): %v", opts.initramfs, err) 92 } 93 defer ramfs.Close() 94 } 95 96 if err := kexec.FileLoad(kernel, ramfs, newCmdLine); err != nil { 97 log.Fatalf("%v", err) 98 } 99 } 100 101 if opts.exec { 102 if err := kexec.Reboot(); err != nil { 103 log.Fatalf("%v", err) 104 } 105 } 106 }