github.com/ratrocket/u-root@v0.0.0-20180201221235-1cf9f48ee2cf/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:       command line for kernel
    15  //     --command-line=STRING:  command line for kernel
    16  //
    17  //     --reuse-commandline:    reuse command line from running system
    18  //
    19  //     --i=FILE:       initramfs file
    20  //     --initrd=FILE:  initramfs file
    21  //     --ramdisk=FILE: initramfs file
    22  //
    23  //     -l or --load:   only load the kernel
    24  //     -e or --exec:   reboot with the currently loaded kernel
    25  package main
    26  
    27  import (
    28  	"flag"
    29  	"log"
    30  	"os"
    31  
    32  	"github.com/u-root/u-root/pkg/kexec"
    33  )
    34  
    35  type options struct {
    36  	cmdline      string
    37  	reuseCmdline bool
    38  	initramfs    string
    39  	load         bool
    40  	exec         bool
    41  }
    42  
    43  func registerFlags() *options {
    44  	o := &options{}
    45  	flag.StringVar(&o.cmdline, "cmdline", "", "Set the kernel command line")
    46  	flag.StringVar(&o.cmdline, "command-line", "", "Set the kernel command line")
    47  
    48  	flag.BoolVar(&o.reuseCmdline, "reuse-cmdline", false, "Use the kernel command line from running system")
    49  
    50  	flag.StringVar(&o.initramfs, "i", "", "Use file as the kernel's initial ramdisk")
    51  	flag.StringVar(&o.initramfs, "initrd", "", "Use file as the kernel's initial ramdisk")
    52  	flag.StringVar(&o.initramfs, "ramdisk", "", "Use file as the kernel's initial ramdisk")
    53  
    54  	flag.BoolVar(&o.load, "l", false, "Load the new kernel into the current kernel.")
    55  	flag.BoolVar(&o.load, "load", false, "Load the new kernel into the current kernel.")
    56  
    57  	flag.BoolVar(&o.exec, "e", false, "Execute a currently loaded kernel.")
    58  	flag.BoolVar(&o.exec, "exec", false, "Execute a currently loaded kernel.")
    59  	return o
    60  }
    61  
    62  func main() {
    63  	opts := registerFlags()
    64  	flag.Parse()
    65  
    66  	if opts.exec == false && len(flag.Args()) == 0 {
    67  		flag.PrintDefaults()
    68  		log.Fatalf("usage: kexec [flags] kernelname OR kexec -e")
    69  	}
    70  
    71  	if opts.cmdline != "" && opts.reuseCmdline {
    72  		flag.PrintDefaults()
    73  		log.Fatalf("--reuse-cmdline and other command line options are mutually exclusive")
    74  	}
    75  
    76  	if opts.load == false && opts.exec == false {
    77  		opts.load = true
    78  		opts.exec = true
    79  	}
    80  
    81  	cmdline := opts.cmdline
    82  	if opts.reuseCmdline {
    83  		procCmdline, err := kexec.CurrentKernelCmdline()
    84  		if err != nil {
    85  			log.Fatalf("%v", err)
    86  		}
    87  		cmdline = procCmdline
    88  	}
    89  
    90  	if opts.load {
    91  		kernelpath := flag.Args()[0]
    92  		log.Printf("Loading %s for kernel\n", kernelpath)
    93  
    94  		kernel, err := os.OpenFile(kernelpath, os.O_RDONLY, 0)
    95  		if err != nil {
    96  			log.Fatalf("open(%q): %v", kernelpath, err)
    97  		}
    98  		defer kernel.Close()
    99  
   100  		var ramfs *os.File
   101  		if opts.initramfs != "" {
   102  			ramfs, err = os.OpenFile(opts.initramfs, os.O_RDONLY, 0)
   103  			if err != nil {
   104  				log.Fatalf("open(%q): %v", opts.initramfs, err)
   105  			}
   106  			defer ramfs.Close()
   107  		}
   108  
   109  		if err := kexec.FileLoad(kernel, ramfs, cmdline); err != nil {
   110  			log.Fatalf("%v", err)
   111  		}
   112  	}
   113  
   114  	if opts.exec {
   115  		if err := kexec.Reboot(); err != nil {
   116  			log.Fatalf("%v", err)
   117  		}
   118  	}
   119  }