github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/core/watchdogd/watchdogd_linux.go (about)

     1  // Copyright 2021 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  // watchdogd is a background daemon for petting the watchdog.
     6  //
     7  // Synopsis:
     8  //
     9  //	watchdogd run [OPTIONS]
    10  //	    Run the watchdogd in a child process (does not daemonize).
    11  //	watchdogd stop
    12  //	    Send a signal to arm the running watchdog.
    13  //	watchdogd continue
    14  //	    Send a signal to disarm the running watchdog.
    15  //	watchdogd arm
    16  //	    Send a signal to arm the running watchdog.
    17  //	watchdogd disarm
    18  //	    Send a signal to disarm the running watchdog.
    19  //
    20  // Options:
    21  //
    22  //	--dev DEV: Device (default /dev/watchdog)
    23  //	--timeout: Duration before timing out (default -1)
    24  //	--pre_timeout: Duration for pretimeout (default -1)
    25  //	--keep_alive: Duration between issuing keepalive (default 10)
    26  //	--monitors: comma separated list of monitors, ex: oops
    27  package main
    28  
    29  import (
    30  	"context"
    31  	"fmt"
    32  	"log"
    33  	"os"
    34  	"strings"
    35  	"time"
    36  
    37  	flag "github.com/spf13/pflag"
    38  	"github.com/mvdan/u-root-coreutils/pkg/watchdog"
    39  	"github.com/mvdan/u-root-coreutils/pkg/watchdogd"
    40  )
    41  
    42  func usage() {
    43  	fmt.Print(`watchdogd run [--dev DEV] [--timeout N] [--pre_timeout N] [--keep_alive N] [--monitors STRING]
    44  	Run the watchdogd daemon in a child process (does not daemonize).
    45  watchdogd stop
    46  	Send a signal to arm the running watchdogd.
    47  watchdogd continue
    48  	Send a signal to disarm the running watchdogd.
    49  watchdogd arm
    50  	Send a signal to arm the running watchdogd.
    51  watchdogd disarm
    52  	Send a signal to disarm the running watchdogd.
    53  `)
    54  	os.Exit(1)
    55  }
    56  
    57  func runCommand() error {
    58  	args := os.Args[1:]
    59  	if len(args) == 0 {
    60  		usage()
    61  	}
    62  	cmd, args := args[0], args[1:]
    63  
    64  	switch cmd {
    65  	case "run":
    66  		fs := flag.NewFlagSet("watchdogd run", flag.PanicOnError)
    67  		var (
    68  			dev        = fs.String("dev", watchdog.Dev, "device")
    69  			timeout    = fs.Duration("timeout", -1, "duration before timing out")
    70  			preTimeout = fs.Duration("pre_timeout", -1, "duration for pretimeout")
    71  			keepAlive  = fs.Duration("keep_alive", 5*time.Second, "duration between issuing keepalive")
    72  			monitors   = fs.String("monitors", "", "comma seperated list of monitors, ex: oops")
    73  			uds        = fs.String("uds", "/tmp/watchdogd", "unix domain socket path for the daemon")
    74  		)
    75  		fs.Parse(args)
    76  		if fs.NArg() != 0 {
    77  			usage()
    78  		}
    79  		if *timeout == -1 {
    80  			timeout = nil
    81  		}
    82  		if *preTimeout == -1 {
    83  			preTimeout = nil
    84  		}
    85  
    86  		monitorFuncs := []func() error{}
    87  		for _, m := range strings.Split(*monitors, ",") {
    88  			if m == "oops" {
    89  				monitorFuncs = append(monitorFuncs, watchdogd.MonitorOops)
    90  			} else {
    91  				return fmt.Errorf("unrecognized monitor: %v", m)
    92  			}
    93  		}
    94  
    95  		return watchdogd.Run(context.Background(), &watchdogd.DaemonOpts{
    96  			Dev:        *dev,
    97  			Timeout:    timeout,
    98  			PreTimeout: preTimeout,
    99  			KeepAlive:  *keepAlive,
   100  			Monitors:   monitorFuncs,
   101  			UDS:        *uds,
   102  		})
   103  	default:
   104  		if len(args) != 0 {
   105  			usage()
   106  		}
   107  		d, err := watchdogd.NewClient()
   108  		if err != nil {
   109  			return fmt.Errorf("could not dial watchdog daemon: %v", err)
   110  		}
   111  		f, ok := map[string]func() error{
   112  			"stop":     d.Stop,
   113  			"continue": d.Continue,
   114  			"arm":      d.Arm,
   115  			"disarm":   d.Disarm,
   116  		}[cmd]
   117  		if !ok {
   118  			return fmt.Errorf("unrecognized command %q", cmd)
   119  		}
   120  		return f()
   121  	}
   122  }
   123  
   124  func main() {
   125  	if err := runCommand(); err != nil {
   126  		log.Fatal(err)
   127  	}
   128  }