...

Source file src/github.com/Microsoft/hcsshim/internal/tools/uvmboot/main.go

Documentation: github.com/Microsoft/hcsshim/internal/tools/uvmboot

     1  //go:build windows
     2  
     3  package main
     4  
     5  import (
     6  	"fmt"
     7  	"log"
     8  	"os"
     9  	"sync"
    10  	"time"
    11  
    12  	"github.com/Microsoft/hcsshim/internal/uvm"
    13  	"github.com/Microsoft/hcsshim/internal/winapi"
    14  	"github.com/sirupsen/logrus"
    15  	"github.com/urfave/cli"
    16  )
    17  
    18  const (
    19  	cpusArgName                 = "cpus"
    20  	memoryArgName               = "memory"
    21  	allowOvercommitArgName      = "allow-overcommit"
    22  	enableDeferredCommitArgName = "enable-deferred-commit"
    23  	measureArgName              = "measure"
    24  	parallelArgName             = "parallel"
    25  	countArgName                = "count"
    26  
    27  	execCommandLineArgName = "exec"
    28  )
    29  
    30  var (
    31  	debug  bool
    32  	useGCS bool
    33  )
    34  
    35  type uvmRunFunc func(string) error
    36  
    37  func main() {
    38  	app := cli.NewApp()
    39  	app.Name = "uvmboot"
    40  	app.Usage = "Boot a utility VM"
    41  
    42  	app.Flags = []cli.Flag{
    43  		cli.Uint64Flag{
    44  			Name:  cpusArgName,
    45  			Usage: "Number of CPUs on the UVM. Uses hcsshim default if not specified",
    46  		},
    47  		cli.UintFlag{
    48  			Name:  memoryArgName,
    49  			Usage: "Amount of memory on the UVM, in MB. Uses hcsshim default if not specified",
    50  		},
    51  		cli.BoolFlag{
    52  			Name:  measureArgName,
    53  			Usage: "Measure wall clock time of the UVM run",
    54  		},
    55  		cli.IntFlag{
    56  			Name:  parallelArgName,
    57  			Value: 1,
    58  			Usage: "Number of UVMs to boot in parallel",
    59  		},
    60  		cli.IntFlag{
    61  			Name:  countArgName,
    62  			Value: 1,
    63  			Usage: "Total number of UVMs to run",
    64  		},
    65  		cli.BoolFlag{
    66  			Name:  allowOvercommitArgName,
    67  			Usage: "Allow memory overcommit on the UVM",
    68  		},
    69  		cli.BoolFlag{
    70  			Name:  enableDeferredCommitArgName,
    71  			Usage: "Enable deferred commit on the UVM",
    72  		},
    73  		cli.BoolFlag{
    74  			Name:        "debug",
    75  			Usage:       "Enable debug information",
    76  			Destination: &debug,
    77  		},
    78  		cli.BoolFlag{
    79  			Name:        "gcs",
    80  			Usage:       "Launch the GCS and perform requested operations via its RPC interface",
    81  			Destination: &useGCS,
    82  		},
    83  	}
    84  
    85  	app.Commands = []cli.Command{
    86  		lcowCommand,
    87  		wcowCommand,
    88  	}
    89  
    90  	app.Before = func(c *cli.Context) error {
    91  		if !winapi.IsElevated() {
    92  			log.Fatal(c.App.Name + " must be run in an elevated context")
    93  		}
    94  
    95  		if debug {
    96  			logrus.SetLevel(logrus.DebugLevel)
    97  		} else {
    98  			logrus.SetLevel(logrus.WarnLevel)
    99  		}
   100  
   101  		return nil
   102  	}
   103  
   104  	if err := app.Run(os.Args); err != nil {
   105  		logrus.Fatalf("%v\n", err)
   106  	}
   107  }
   108  
   109  func setGlobalOptions(c *cli.Context, options *uvm.Options) {
   110  	if c.GlobalIsSet(cpusArgName) {
   111  		options.ProcessorCount = int32(c.GlobalUint64(cpusArgName))
   112  	}
   113  	if c.GlobalIsSet(memoryArgName) {
   114  		options.MemorySizeInMB = c.GlobalUint64(memoryArgName)
   115  	}
   116  	if c.GlobalIsSet(allowOvercommitArgName) {
   117  		options.AllowOvercommit = c.GlobalBool(allowOvercommitArgName)
   118  	}
   119  	if c.GlobalIsSet(enableDeferredCommitArgName) {
   120  		options.EnableDeferredCommit = c.GlobalBool(enableDeferredCommitArgName)
   121  	}
   122  }
   123  
   124  // todo: add a context here to propagate cancel/timeouts to runFunc uvm
   125  
   126  func runMany(c *cli.Context, runFunc uvmRunFunc) {
   127  	parallelCount := c.GlobalInt(parallelArgName)
   128  
   129  	var wg sync.WaitGroup
   130  	wg.Add(parallelCount)
   131  	workChan := make(chan int)
   132  	for i := 0; i < parallelCount; i++ {
   133  		go func() {
   134  			for i := range workChan {
   135  				id := fmt.Sprintf("uvmboot-%d", i)
   136  				if err := runFunc(id); err != nil {
   137  					logrus.WithField("uvm-id", id).WithError(err).Error("failed to run UVM")
   138  				}
   139  			}
   140  			wg.Done()
   141  		}()
   142  	}
   143  
   144  	start := time.Now()
   145  	for i := 0; i < c.GlobalInt(countArgName); i++ {
   146  		workChan <- i
   147  	}
   148  
   149  	close(workChan)
   150  	wg.Wait()
   151  	if c.GlobalBool(measureArgName) {
   152  		fmt.Println("Elapsed time:", time.Since(start))
   153  	}
   154  }
   155  
   156  func unrecognizedError(name, value string) error {
   157  	return fmt.Errorf("unrecognized value '%s' for option %s", name, value)
   158  }
   159  

View as plain text