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 }