Browse code

Bump libcontainer to 6c198ae2d065c37f44316e0de3df7f3b88950923

Signed-off-by: Tibor Vass <tibor@docker.com>

Tibor Vass authored on 2015/10/14 03:30:19
Showing 9 changed files
... ...
@@ -44,7 +44,7 @@ clone git github.com/endophage/gotuf 9bcdad0308e34a49f38448b8ad436ad8860825ce
44 44
 clone git github.com/jfrazelle/go 6e461eb70cb4187b41a84e9a567d7137bdbe0f16
45 45
 clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
46 46
 
47
-clone git github.com/opencontainers/runc f152edcb1ca7877dd6e3febddd1b03ad4335e7bb # libcontainer
47
+clone git github.com/opencontainers/runc 6c198ae2d065c37f44316e0de3df7f3b88950923 # libcontainer
48 48
 # libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
49 49
 clone git github.com/coreos/go-systemd v3
50 50
 clone git github.com/godbus/dbus v2
... ...
@@ -213,7 +213,7 @@ func (m *Manager) GetPids() ([]int, error) {
213 213
 		return nil, err
214 214
 	}
215 215
 
216
-	return cgroups.ReadProcsFile(dir)
216
+	return cgroups.GetPids(dir)
217 217
 }
218 218
 
219 219
 func getCgroupData(c *configs.Cgroup, pid int) (*data, error) {
... ...
@@ -411,12 +411,11 @@ func (m *Manager) Freeze(state configs.FreezerState) error {
411 411
 }
412 412
 
413 413
 func (m *Manager) GetPids() ([]int, error) {
414
-	path, err := getSubsystemPath(m.Cgroups, "cpu")
414
+	path, err := getSubsystemPath(m.Cgroups, "devices")
415 415
 	if err != nil {
416 416
 		return nil, err
417 417
 	}
418
-
419
-	return cgroups.ReadProcsFile(path)
418
+	return cgroups.GetPids(path)
420 419
 }
421 420
 
422 421
 func (m *Manager) GetStats() (*cgroups.Stats, error) {
... ...
@@ -193,7 +193,7 @@ func GetInitCgroupDir(subsystem string) (string, error) {
193 193
 	return getControllerPath(subsystem, cgroups)
194 194
 }
195 195
 
196
-func ReadProcsFile(dir string) ([]int, error) {
196
+func readProcsFile(dir string) ([]int, error) {
197 197
 	f, err := os.Open(filepath.Join(dir, "cgroup.procs"))
198 198
 	if err != nil {
199 199
 		return nil, err
... ...
@@ -322,3 +322,26 @@ func GetHugePageSize() ([]string, error) {
322 322
 
323 323
 	return pageSizes, nil
324 324
 }
325
+
326
+// GetPids returns all pids, that were added to cgroup at path and to all its
327
+// subcgroups.
328
+func GetPids(path string) ([]int, error) {
329
+	var pids []int
330
+	// collect pids from all sub-cgroups
331
+	err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error {
332
+		dir, file := filepath.Split(p)
333
+		if file != "cgroup.procs" {
334
+			return nil
335
+		}
336
+		if iErr != nil {
337
+			return iErr
338
+		}
339
+		cPids, err := readProcsFile(dir)
340
+		if err != nil {
341
+			return err
342
+		}
343
+		pids = append(pids, cPids...)
344
+		return nil
345
+	})
346
+	return pids, err
347
+}
... ...
@@ -289,24 +289,56 @@ func addArgsFromEnv(evar string, args *[]string) {
289 289
 	fmt.Printf(">>> criu %v\n", *args)
290 290
 }
291 291
 
292
-func (c *linuxContainer) checkCriuVersion() error {
293
-	var x, y, z int
292
+// check Criu version greater than or equal to min_version
293
+func (c *linuxContainer) checkCriuVersion(min_version string) error {
294
+	var x, y, z, versionReq int
294 295
 
295
-	out, err := exec.Command(c.criuPath, "-V").Output()
296
+	_, err := fmt.Sscanf(min_version, "%d.%d.%d\n", &x, &y, &z) // 1.5.2
296 297
 	if err != nil {
297
-		return fmt.Errorf("Unable to execute CRIU command: %s", c.criuPath)
298
+		_, err = fmt.Sscanf(min_version, "Version: %d.%d\n", &x, &y) // 1.6
298 299
 	}
300
+	versionReq = x*10000 + y*100 + z
299 301
 
300
-	n, err := fmt.Sscanf(string(out), "Version: %d.%d.%d\n", &x, &y, &z) // 1.5.2
302
+	out, err := exec.Command(c.criuPath, "-V").Output()
301 303
 	if err != nil {
302
-		n, err = fmt.Sscanf(string(out), "Version: %d.%d\n", &x, &y) // 1.6
304
+		return fmt.Errorf("Unable to execute CRIU command: %s", c.criuPath)
303 305
 	}
304
-	if n < 2 || err != nil {
305
-		return fmt.Errorf("Unable to parse the CRIU version: %s %d %s", out, n, err)
306
+
307
+	x = 0
308
+	y = 0
309
+	z = 0
310
+	if ep := strings.Index(string(out), "-"); ep >= 0 {
311
+		// criu Git version format
312
+		var version string
313
+		if sp := strings.Index(string(out), "GitID"); sp > 0 {
314
+			version = string(out)[sp:ep]
315
+		} else {
316
+			return fmt.Errorf("Unable to parse the CRIU version: %s", c.criuPath)
317
+		}
318
+
319
+		n, err := fmt.Sscanf(string(version), "GitID: v%d.%d.%d", &x, &y, &z) // 1.5.2
320
+		if err != nil {
321
+			n, err = fmt.Sscanf(string(version), "GitID: v%d.%d", &x, &y) // 1.6
322
+			y++
323
+		} else {
324
+			z++
325
+		}
326
+		if n < 2 || err != nil {
327
+			return fmt.Errorf("Unable to parse the CRIU version: %s %d %s", version, n, err)
328
+		}
329
+	} else {
330
+		// criu release version format
331
+		n, err := fmt.Sscanf(string(out), "Version: %d.%d.%d\n", &x, &y, &z) // 1.5.2
332
+		if err != nil {
333
+			n, err = fmt.Sscanf(string(out), "Version: %d.%d\n", &x, &y) // 1.6
334
+		}
335
+		if n < 2 || err != nil {
336
+			return fmt.Errorf("Unable to parse the CRIU version: %s %d %s", out, n, err)
337
+		}
306 338
 	}
307 339
 
308
-	if x*10000+y*100+z < 10502 {
309
-		return fmt.Errorf("CRIU version must be 1.5.2 or higher")
340
+	if x*10000+y*100+z < versionReq {
341
+		return fmt.Errorf("CRIU version must be %s or higher", min_version)
310 342
 	}
311 343
 
312 344
 	return nil
... ...
@@ -331,7 +363,7 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
331 331
 	c.m.Lock()
332 332
 	defer c.m.Unlock()
333 333
 
334
-	if err := c.checkCriuVersion(); err != nil {
334
+	if err := c.checkCriuVersion("1.5.2"); err != nil {
335 335
 		return err
336 336
 	}
337 337
 
... ...
@@ -389,6 +421,14 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
389 389
 		}
390 390
 	}
391 391
 
392
+	// append optional manage cgroups mode
393
+	if criuOpts.ManageCgroupsMode != 0 {
394
+		if err := c.checkCriuVersion("1.7"); err != nil {
395
+			return err
396
+		}
397
+		rpcOpts.ManageCgroupsMode = proto.Uint32(uint32(criuOpts.ManageCgroupsMode))
398
+	}
399
+
392 400
 	t := criurpc.CriuReqType_DUMP
393 401
 	req := &criurpc.CriuReq{
394 402
 		Type: &t,
... ...
@@ -448,7 +488,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
448 448
 	c.m.Lock()
449 449
 	defer c.m.Unlock()
450 450
 
451
-	if err := c.checkCriuVersion(); err != nil {
451
+	if err := c.checkCriuVersion("1.5.2"); err != nil {
452 452
 		return err
453 453
 	}
454 454
 
... ...
@@ -553,6 +593,14 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
553 553
 		req.Opts.Veths = append(req.Opts.Veths, veth)
554 554
 	}
555 555
 
556
+	// append optional manage cgroups mode
557
+	if criuOpts.ManageCgroupsMode != 0 {
558
+		if err := c.checkCriuVersion("1.7"); err != nil {
559
+			return err
560
+		}
561
+		req.Opts.ManageCgroupsMode = proto.Uint32(uint32(criuOpts.ManageCgroupsMode))
562
+	}
563
+
556 564
 	var (
557 565
 		fds    []string
558 566
 		fdJSON []byte
... ...
@@ -1,5 +1,15 @@
1 1
 package libcontainer
2 2
 
3
+// cgroup restoring strategy provided by criu
4
+type cg_mode uint32
5
+
6
+const (
7
+	CRIU_CG_MODE_SOFT    cg_mode = 3 + iota // restore cgroup properties if only dir created by criu
8
+	CRIU_CG_MODE_FULL                       // always restore all cgroups and their properties
9
+	CRIU_CG_MODE_STRICT                     // restore all, requiring them to not present in the system
10
+	CRIU_CG_MODE_DEFAULT                    // the same as CRIU_CG_MODE_SOFT
11
+)
12
+
3 13
 type CriuPageServerInfo struct {
4 14
 	Address string // IP address of CRIU page server
5 15
 	Port    int32  // port number of CRIU page server
... ...
@@ -20,4 +30,5 @@ type CriuOpts struct {
20 20
 	FileLocks               bool               // handle file locks, for safety
21 21
 	PageServer              CriuPageServerInfo // allow to dump to criu page server
22 22
 	VethPairs               []VethPairName     // pass the veth to criu when restore
23
+	ManageCgroupsMode       cg_mode            // dump or restore cgroup mode
23 24
 }
... ...
@@ -2,15 +2,33 @@
2 2
 // source: criurpc.proto
3 3
 // DO NOT EDIT!
4 4
 
5
+/*
6
+Package criurpc is a generated protocol buffer package.
7
+
8
+It is generated from these files:
9
+	criurpc.proto
10
+
11
+It has these top-level messages:
12
+	CriuPageServerInfo
13
+	CriuVethPair
14
+	ExtMountMap
15
+	InheritFd
16
+	CgroupRoot
17
+	UnixSk
18
+	CriuOpts
19
+	CriuDumpResp
20
+	CriuRestoreResp
21
+	CriuNotify
22
+	CriuReq
23
+	CriuResp
24
+*/
5 25
 package criurpc
6 26
 
7 27
 import proto "github.com/golang/protobuf/proto"
8
-import json "encoding/json"
9 28
 import math "math"
10 29
 
11
-// Reference proto, json, and math imports to suppress error if they are not otherwise used.
30
+// Reference imports to suppress errors if they are not otherwise used.
12 31
 var _ = proto.Marshal
13
-var _ = &json.SyntaxError{}
14 32
 var _ = math.Inf
15 33
 
16 34
 type CriuReqType int32
... ...
@@ -58,9 +76,6 @@ func (x CriuReqType) Enum() *CriuReqType {
58 58
 func (x CriuReqType) String() string {
59 59
 	return proto.EnumName(CriuReqType_name, int32(x))
60 60
 }
61
-func (x CriuReqType) MarshalJSON() ([]byte, error) {
62
-	return json.Marshal(x.String())
63
-}
64 61
 func (x *CriuReqType) UnmarshalJSON(data []byte) error {
65 62
 	value, err := proto.UnmarshalJSONEnum(CriuReqType_value, data, "CriuReqType")
66 63
 	if err != nil {
... ...
@@ -206,35 +221,58 @@ func (m *CgroupRoot) GetPath() string {
206 206
 	return ""
207 207
 }
208 208
 
209
+type UnixSk struct {
210
+	Inode            *uint32 `protobuf:"varint,1,req,name=inode" json:"inode,omitempty"`
211
+	XXX_unrecognized []byte  `json:"-"`
212
+}
213
+
214
+func (m *UnixSk) Reset()         { *m = UnixSk{} }
215
+func (m *UnixSk) String() string { return proto.CompactTextString(m) }
216
+func (*UnixSk) ProtoMessage()    {}
217
+
218
+func (m *UnixSk) GetInode() uint32 {
219
+	if m != nil && m.Inode != nil {
220
+		return *m.Inode
221
+	}
222
+	return 0
223
+}
224
+
209 225
 type CriuOpts struct {
210
-	ImagesDirFd      *int32              `protobuf:"varint,1,req,name=images_dir_fd" json:"images_dir_fd,omitempty"`
211
-	Pid              *int32              `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"`
212
-	LeaveRunning     *bool               `protobuf:"varint,3,opt,name=leave_running" json:"leave_running,omitempty"`
213
-	ExtUnixSk        *bool               `protobuf:"varint,4,opt,name=ext_unix_sk" json:"ext_unix_sk,omitempty"`
214
-	TcpEstablished   *bool               `protobuf:"varint,5,opt,name=tcp_established" json:"tcp_established,omitempty"`
215
-	EvasiveDevices   *bool               `protobuf:"varint,6,opt,name=evasive_devices" json:"evasive_devices,omitempty"`
216
-	ShellJob         *bool               `protobuf:"varint,7,opt,name=shell_job" json:"shell_job,omitempty"`
217
-	FileLocks        *bool               `protobuf:"varint,8,opt,name=file_locks" json:"file_locks,omitempty"`
218
-	LogLevel         *int32              `protobuf:"varint,9,opt,name=log_level,def=2" json:"log_level,omitempty"`
219
-	LogFile          *string             `protobuf:"bytes,10,opt,name=log_file" json:"log_file,omitempty"`
220
-	Ps               *CriuPageServerInfo `protobuf:"bytes,11,opt,name=ps" json:"ps,omitempty"`
221
-	NotifyScripts    *bool               `protobuf:"varint,12,opt,name=notify_scripts" json:"notify_scripts,omitempty"`
222
-	Root             *string             `protobuf:"bytes,13,opt,name=root" json:"root,omitempty"`
223
-	ParentImg        *string             `protobuf:"bytes,14,opt,name=parent_img" json:"parent_img,omitempty"`
224
-	TrackMem         *bool               `protobuf:"varint,15,opt,name=track_mem" json:"track_mem,omitempty"`
225
-	AutoDedup        *bool               `protobuf:"varint,16,opt,name=auto_dedup" json:"auto_dedup,omitempty"`
226
-	WorkDirFd        *int32              `protobuf:"varint,17,opt,name=work_dir_fd" json:"work_dir_fd,omitempty"`
227
-	LinkRemap        *bool               `protobuf:"varint,18,opt,name=link_remap" json:"link_remap,omitempty"`
228
-	Veths            []*CriuVethPair     `protobuf:"bytes,19,rep,name=veths" json:"veths,omitempty"`
229
-	CpuCap           *uint32             `protobuf:"varint,20,opt,name=cpu_cap,def=4294967295" json:"cpu_cap,omitempty"`
230
-	ForceIrmap       *bool               `protobuf:"varint,21,opt,name=force_irmap" json:"force_irmap,omitempty"`
231
-	ExecCmd          []string            `protobuf:"bytes,22,rep,name=exec_cmd" json:"exec_cmd,omitempty"`
232
-	ExtMnt           []*ExtMountMap      `protobuf:"bytes,23,rep,name=ext_mnt" json:"ext_mnt,omitempty"`
233
-	ManageCgroups    *bool               `protobuf:"varint,24,opt,name=manage_cgroups" json:"manage_cgroups,omitempty"`
234
-	CgRoot           []*CgroupRoot       `protobuf:"bytes,25,rep,name=cg_root" json:"cg_root,omitempty"`
235
-	RstSibling       *bool               `protobuf:"varint,26,opt,name=rst_sibling" json:"rst_sibling,omitempty"`
236
-	InheritFd        []*InheritFd        `protobuf:"bytes,27,rep,name=inherit_fd" json:"inherit_fd,omitempty"`
237
-	XXX_unrecognized []byte              `json:"-"`
226
+	ImagesDirFd       *int32              `protobuf:"varint,1,req,name=images_dir_fd" json:"images_dir_fd,omitempty"`
227
+	Pid               *int32              `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"`
228
+	LeaveRunning      *bool               `protobuf:"varint,3,opt,name=leave_running" json:"leave_running,omitempty"`
229
+	ExtUnixSk         *bool               `protobuf:"varint,4,opt,name=ext_unix_sk" json:"ext_unix_sk,omitempty"`
230
+	TcpEstablished    *bool               `protobuf:"varint,5,opt,name=tcp_established" json:"tcp_established,omitempty"`
231
+	EvasiveDevices    *bool               `protobuf:"varint,6,opt,name=evasive_devices" json:"evasive_devices,omitempty"`
232
+	ShellJob          *bool               `protobuf:"varint,7,opt,name=shell_job" json:"shell_job,omitempty"`
233
+	FileLocks         *bool               `protobuf:"varint,8,opt,name=file_locks" json:"file_locks,omitempty"`
234
+	LogLevel          *int32              `protobuf:"varint,9,opt,name=log_level,def=2" json:"log_level,omitempty"`
235
+	LogFile           *string             `protobuf:"bytes,10,opt,name=log_file" json:"log_file,omitempty"`
236
+	Ps                *CriuPageServerInfo `protobuf:"bytes,11,opt,name=ps" json:"ps,omitempty"`
237
+	NotifyScripts     *bool               `protobuf:"varint,12,opt,name=notify_scripts" json:"notify_scripts,omitempty"`
238
+	Root              *string             `protobuf:"bytes,13,opt,name=root" json:"root,omitempty"`
239
+	ParentImg         *string             `protobuf:"bytes,14,opt,name=parent_img" json:"parent_img,omitempty"`
240
+	TrackMem          *bool               `protobuf:"varint,15,opt,name=track_mem" json:"track_mem,omitempty"`
241
+	AutoDedup         *bool               `protobuf:"varint,16,opt,name=auto_dedup" json:"auto_dedup,omitempty"`
242
+	WorkDirFd         *int32              `protobuf:"varint,17,opt,name=work_dir_fd" json:"work_dir_fd,omitempty"`
243
+	LinkRemap         *bool               `protobuf:"varint,18,opt,name=link_remap" json:"link_remap,omitempty"`
244
+	Veths             []*CriuVethPair     `protobuf:"bytes,19,rep,name=veths" json:"veths,omitempty"`
245
+	CpuCap            *uint32             `protobuf:"varint,20,opt,name=cpu_cap,def=4294967295" json:"cpu_cap,omitempty"`
246
+	ForceIrmap        *bool               `protobuf:"varint,21,opt,name=force_irmap" json:"force_irmap,omitempty"`
247
+	ExecCmd           []string            `protobuf:"bytes,22,rep,name=exec_cmd" json:"exec_cmd,omitempty"`
248
+	ExtMnt            []*ExtMountMap      `protobuf:"bytes,23,rep,name=ext_mnt" json:"ext_mnt,omitempty"`
249
+	ManageCgroups     *bool               `protobuf:"varint,24,opt,name=manage_cgroups" json:"manage_cgroups,omitempty"`
250
+	CgRoot            []*CgroupRoot       `protobuf:"bytes,25,rep,name=cg_root" json:"cg_root,omitempty"`
251
+	RstSibling        *bool               `protobuf:"varint,26,opt,name=rst_sibling" json:"rst_sibling,omitempty"`
252
+	InheritFd         []*InheritFd        `protobuf:"bytes,27,rep,name=inherit_fd" json:"inherit_fd,omitempty"`
253
+	AutoExtMnt        *bool               `protobuf:"varint,28,opt,name=auto_ext_mnt" json:"auto_ext_mnt,omitempty"`
254
+	ExtSharing        *bool               `protobuf:"varint,29,opt,name=ext_sharing" json:"ext_sharing,omitempty"`
255
+	ExtMasters        *bool               `protobuf:"varint,30,opt,name=ext_masters" json:"ext_masters,omitempty"`
256
+	SkipMnt           []string            `protobuf:"bytes,31,rep,name=skip_mnt" json:"skip_mnt,omitempty"`
257
+	EnableFs          []string            `protobuf:"bytes,32,rep,name=enable_fs" json:"enable_fs,omitempty"`
258
+	UnixSkIno         []*UnixSk           `protobuf:"bytes,33,rep,name=unix_sk_ino" json:"unix_sk_ino,omitempty"`
259
+	ManageCgroupsMode *uint32             `protobuf:"varint,34,opt,name=manage_cgroups_mode" json:"manage_cgroups_mode,omitempty"`
260
+	XXX_unrecognized  []byte              `json:"-"`
238 261
 }
239 262
 
240 263
 func (m *CriuOpts) Reset()         { *m = CriuOpts{} }
... ...
@@ -433,6 +471,55 @@ func (m *CriuOpts) GetInheritFd() []*InheritFd {
433 433
 	return nil
434 434
 }
435 435
 
436
+func (m *CriuOpts) GetAutoExtMnt() bool {
437
+	if m != nil && m.AutoExtMnt != nil {
438
+		return *m.AutoExtMnt
439
+	}
440
+	return false
441
+}
442
+
443
+func (m *CriuOpts) GetExtSharing() bool {
444
+	if m != nil && m.ExtSharing != nil {
445
+		return *m.ExtSharing
446
+	}
447
+	return false
448
+}
449
+
450
+func (m *CriuOpts) GetExtMasters() bool {
451
+	if m != nil && m.ExtMasters != nil {
452
+		return *m.ExtMasters
453
+	}
454
+	return false
455
+}
456
+
457
+func (m *CriuOpts) GetSkipMnt() []string {
458
+	if m != nil {
459
+		return m.SkipMnt
460
+	}
461
+	return nil
462
+}
463
+
464
+func (m *CriuOpts) GetEnableFs() []string {
465
+	if m != nil {
466
+		return m.EnableFs
467
+	}
468
+	return nil
469
+}
470
+
471
+func (m *CriuOpts) GetUnixSkIno() []*UnixSk {
472
+	if m != nil {
473
+		return m.UnixSkIno
474
+	}
475
+	return nil
476
+}
477
+
478
+func (m *CriuOpts) GetManageCgroupsMode() uint32 {
479
+	if m != nil && m.ManageCgroupsMode != nil {
480
+		return *m.ManageCgroupsMode
481
+	}
482
+	return 0
483
+}
484
+
436 485
 type CriuDumpResp struct {
437 486
 	Restored         *bool  `protobuf:"varint,1,opt,name=restored" json:"restored,omitempty"`
438 487
 	XXX_unrecognized []byte `json:"-"`
... ...
@@ -509,7 +596,7 @@ func (m *CriuReq) GetType() CriuReqType {
509 509
 	if m != nil && m.Type != nil {
510 510
 		return *m.Type
511 511
 	}
512
-	return 0
512
+	return CriuReqType_EMPTY
513 513
 }
514 514
 
515 515
 func (m *CriuReq) GetOpts() *CriuOpts {
... ...
@@ -552,7 +639,7 @@ func (m *CriuResp) GetType() CriuReqType {
552 552
 	if m != nil && m.Type != nil {
553 553
 		return *m.Type
554 554
 	}
555
-	return 0
555
+	return CriuReqType_EMPTY
556 556
 }
557 557
 
558 558
 func (m *CriuResp) GetSuccess() bool {
... ...
@@ -25,6 +25,10 @@ message cgroup_root {
25 25
 	required string		path	= 2;
26 26
 };
27 27
 
28
+message unix_sk {
29
+	required uint32		inode 	= 1;
30
+};
31
+
28 32
 message criu_opts {
29 33
 	required int32			images_dir_fd	= 1;
30 34
 	optional int32			pid		= 2; /* if not set on dump, will dump requesting process */
... ...
@@ -56,11 +60,22 @@ message criu_opts {
56 56
 	repeated string			exec_cmd	= 22;
57 57
 
58 58
 	repeated ext_mount_map		ext_mnt		= 23;
59
-	optional bool			manage_cgroups	= 24;
59
+	optional bool			manage_cgroups	= 24; /* backward compatibility */
60 60
 	repeated cgroup_root		cg_root		= 25;
61 61
 
62 62
 	optional bool			rst_sibling	= 26; /* swrk only */
63
-	repeated inherit_fd		inherit_fd	= 27;
63
+	repeated inherit_fd		inherit_fd	= 27; /* swrk only */
64
+
65
+	optional bool			auto_ext_mnt	= 28;
66
+	optional bool			ext_sharing 	= 29;
67
+	optional bool			ext_masters	= 30;
68
+
69
+	repeated string			skip_mnt	= 31;
70
+	repeated string			enable_fs	= 32;
71
+
72
+	repeated unix_sk                unix_sk_ino     = 33;
73
+
74
+	optional uint32                 manage_cgroups_mode = 34;
64 75
 }
65 76
 
66 77
 message criu_dump_resp {
... ...
@@ -9,6 +9,15 @@ import (
9 9
 	"github.com/opencontainers/runc/libcontainer/selinux"
10 10
 )
11 11
 
12
+// Valid Label Options
13
+var validOptions = map[string]bool{
14
+	"disable": true,
15
+	"type":    true,
16
+	"user":    true,
17
+	"role":    true,
18
+	"level":   true,
19
+}
20
+
12 21
 var ErrIncompatibleLabel = fmt.Errorf("Bad SELinux option z and Z can not be used together")
13 22
 
14 23
 // InitLabels returns the process label and file labels to be used within
... ...
@@ -28,9 +37,13 @@ func InitLabels(options []string) (string, string, error) {
28 28
 				return "", "", nil
29 29
 			}
30 30
 			if i := strings.Index(opt, ":"); i == -1 {
31
-				return "", "", fmt.Errorf("Bad SELinux Option")
31
+				return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type' followed by ':' and a value", opt)
32 32
 			}
33 33
 			con := strings.SplitN(opt, ":", 2)
34
+			if !validOptions[con[0]] {
35
+				return "", "", fmt.Errorf("Bad label option %q, valid options 'disable, user, role, level, type'", con[0])
36
+
37
+			}
34 38
 			pcon[con[0]] = con[1]
35 39
 			if con[0] == "level" || con[0] == "user" {
36 40
 				mcon[con[0]] = con[1]