github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/update.go (about)

     1  // +build linux
     2  
     3  package main
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"os"
     9  	"strconv"
    10  
    11  	"github.com/docker/go-units"
    12  	"github.com/opencontainers/runtime-spec/specs-go"
    13  	"github.com/urfave/cli"
    14  )
    15  
    16  func u64Ptr(i uint64) *uint64 { return &i }
    17  func u16Ptr(i uint16) *uint16 { return &i }
    18  
    19  var updateCommand = cli.Command{
    20  	Name:      "update",
    21  	Usage:     "update container resource constraints",
    22  	ArgsUsage: `<container-id>`,
    23  	Flags: []cli.Flag{
    24  		cli.StringFlag{
    25  			Name:  "resources, r",
    26  			Value: "",
    27  			Usage: `path to the file containing the resources to update or '-' to read from the standard input
    28  
    29  The accepted format is as follow (unchanged values can be omitted):
    30  
    31  {
    32    "memory": {
    33      "limit": 0,
    34      "reservation": 0,
    35      "swap": 0,
    36      "kernel": 0,
    37      "kernelTCP": 0
    38    },
    39    "cpu": {
    40      "shares": 0,
    41      "quota": 0,
    42      "period": 0,
    43      "realtimeRuntime": 0,
    44      "realtimePeriod": 0,
    45      "cpus": "",
    46      "mems": ""
    47    },
    48    "blockIO": {
    49      "blkioWeight": 0
    50    }
    51  }
    52  
    53  Note: if data is to be read from a file or the standard input, all
    54  other options are ignored.
    55  `,
    56  		},
    57  
    58  		cli.IntFlag{
    59  			Name:  "blkio-weight",
    60  			Usage: "Specifies per cgroup weight, range is from 10 to 1000",
    61  		},
    62  		cli.StringFlag{
    63  			Name:  "cpu-period",
    64  			Usage: "CPU CFS period to be used for hardcapping (in usecs). 0 to use system default",
    65  		},
    66  		cli.StringFlag{
    67  			Name:  "cpu-quota",
    68  			Usage: "CPU CFS hardcap limit (in usecs). Allowed cpu time in a given period",
    69  		},
    70  		cli.StringFlag{
    71  			Name:  "cpu-share",
    72  			Usage: "CPU shares (relative weight vs. other containers)",
    73  		},
    74  		cli.StringFlag{
    75  			Name:  "cpu-rt-period",
    76  			Usage: "CPU realtime period to be used for hardcapping (in usecs). 0 to use system default",
    77  		},
    78  		cli.StringFlag{
    79  			Name:  "cpu-rt-runtime",
    80  			Usage: "CPU realtime hardcap limit (in usecs). Allowed cpu time in a given period",
    81  		},
    82  		cli.StringFlag{
    83  			Name:  "cpuset-cpus",
    84  			Usage: "CPU(s) to use",
    85  		},
    86  		cli.StringFlag{
    87  			Name:  "cpuset-mems",
    88  			Usage: "Memory node(s) to use",
    89  		},
    90  		cli.StringFlag{
    91  			Name:  "kernel-memory",
    92  			Usage: "Kernel memory limit (in bytes)",
    93  		},
    94  		cli.StringFlag{
    95  			Name:  "kernel-memory-tcp",
    96  			Usage: "Kernel memory limit (in bytes) for tcp buffer",
    97  		},
    98  		cli.StringFlag{
    99  			Name:  "memory",
   100  			Usage: "Memory limit (in bytes)",
   101  		},
   102  		cli.StringFlag{
   103  			Name:  "memory-reservation",
   104  			Usage: "Memory reservation or soft_limit (in bytes)",
   105  		},
   106  		cli.StringFlag{
   107  			Name:  "memory-swap",
   108  			Usage: "Total memory usage (memory + swap); set '-1' to enable unlimited swap",
   109  		},
   110  	},
   111  	Action: func(context *cli.Context) error {
   112  		container, err := getContainer(context)
   113  		if err != nil {
   114  			return err
   115  		}
   116  
   117  		r := specs.Resources{
   118  			Memory: &specs.Memory{
   119  				Limit:       u64Ptr(0),
   120  				Reservation: u64Ptr(0),
   121  				Swap:        u64Ptr(0),
   122  				Kernel:      u64Ptr(0),
   123  				KernelTCP:   u64Ptr(0),
   124  			},
   125  			CPU: &specs.CPU{
   126  				Shares:          u64Ptr(0),
   127  				Quota:           u64Ptr(0),
   128  				Period:          u64Ptr(0),
   129  				RealtimeRuntime: u64Ptr(0),
   130  				RealtimePeriod:  u64Ptr(0),
   131  				Cpus:            sPtr(""),
   132  				Mems:            sPtr(""),
   133  			},
   134  			BlockIO: &specs.BlockIO{
   135  				Weight: u16Ptr(0),
   136  			},
   137  		}
   138  
   139  		config := container.Config()
   140  
   141  		if in := context.String("resources"); in != "" {
   142  			var (
   143  				f   *os.File
   144  				err error
   145  			)
   146  			switch in {
   147  			case "-":
   148  				f = os.Stdin
   149  			default:
   150  				f, err = os.Open(in)
   151  				if err != nil {
   152  					return err
   153  				}
   154  			}
   155  			err = json.NewDecoder(f).Decode(&r)
   156  			if err != nil {
   157  				return err
   158  			}
   159  		} else {
   160  			if val := context.Int("blkio-weight"); val != 0 {
   161  				r.BlockIO.Weight = u16Ptr(uint16(val))
   162  			}
   163  			if val := context.String("cpuset-cpus"); val != "" {
   164  				r.CPU.Cpus = &val
   165  			}
   166  			if val := context.String("cpuset-mems"); val != "" {
   167  				r.CPU.Mems = &val
   168  			}
   169  
   170  			for _, pair := range []struct {
   171  				opt  string
   172  				dest *uint64
   173  			}{
   174  
   175  				{"cpu-period", r.CPU.Period},
   176  				{"cpu-quota", r.CPU.Quota},
   177  				{"cpu-rt-period", r.CPU.RealtimePeriod},
   178  				{"cpu-rt-runtime", r.CPU.RealtimeRuntime},
   179  				{"cpu-share", r.CPU.Shares},
   180  			} {
   181  				if val := context.String(pair.opt); val != "" {
   182  					var err error
   183  					*pair.dest, err = strconv.ParseUint(val, 10, 64)
   184  					if err != nil {
   185  						return fmt.Errorf("invalid value for %s: %s", pair.opt, err)
   186  					}
   187  				}
   188  			}
   189  			for _, pair := range []struct {
   190  				opt  string
   191  				dest *uint64
   192  			}{
   193  				{"kernel-memory", r.Memory.Kernel},
   194  				{"kernel-memory-tcp", r.Memory.KernelTCP},
   195  				{"memory", r.Memory.Limit},
   196  				{"memory-reservation", r.Memory.Reservation},
   197  				{"memory-swap", r.Memory.Swap},
   198  			} {
   199  				if val := context.String(pair.opt); val != "" {
   200  					v, err := units.RAMInBytes(val)
   201  					if err != nil {
   202  						return fmt.Errorf("invalid value for %s: %s", pair.opt, err)
   203  					}
   204  					*pair.dest = uint64(v)
   205  				}
   206  			}
   207  		}
   208  
   209  		// Update the value
   210  		config.Cgroups.Resources.BlkioWeight = *r.BlockIO.Weight
   211  		config.Cgroups.Resources.CpuPeriod = int64(*r.CPU.Period)
   212  		config.Cgroups.Resources.CpuQuota = int64(*r.CPU.Quota)
   213  		config.Cgroups.Resources.CpuShares = int64(*r.CPU.Shares)
   214  		config.Cgroups.Resources.CpuRtPeriod = int64(*r.CPU.RealtimePeriod)
   215  		config.Cgroups.Resources.CpuRtRuntime = int64(*r.CPU.RealtimeRuntime)
   216  		config.Cgroups.Resources.CpusetCpus = *r.CPU.Cpus
   217  		config.Cgroups.Resources.CpusetMems = *r.CPU.Mems
   218  		config.Cgroups.Resources.KernelMemory = int64(*r.Memory.Kernel)
   219  		config.Cgroups.Resources.KernelMemoryTCP = int64(*r.Memory.KernelTCP)
   220  		config.Cgroups.Resources.Memory = int64(*r.Memory.Limit)
   221  		config.Cgroups.Resources.MemoryReservation = int64(*r.Memory.Reservation)
   222  		config.Cgroups.Resources.MemorySwap = int64(*r.Memory.Swap)
   223  
   224  		if err := container.Set(config); err != nil {
   225  			return err
   226  		}
   227  		return nil
   228  	},
   229  }