Quellcode durchsuchen

Merge pull request #10189 from crosbymichael/update-libcontainer-jan16

Update to libcontainer eb74393a3d2daeafbef4f5f27c0
Tianon Gravi vor 10 Jahren
Ursprung
Commit
2feb2d07b6

+ 1 - 1
project/vendor.sh

@@ -68,7 +68,7 @@ if [ "$1" = '--go' ]; then
 	mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
 fi
 
-clone git github.com/docker/libcontainer 1d3b2589d734dc94a1719a3af40b87ed8319f329
+clone git github.com/docker/libcontainer eb74393a3d2daeafbef4f5f27c0821cbdd67559c
 # see src/github.com/docker/libcontainer/update-vendor.sh which is the "source of truth" for libcontainer deps (just like this file)
 rm -rf src/github.com/docker/libcontainer/vendor
 eval "$(grep '^clone ' src/github.com/docker/libcontainer/update-vendor.sh | grep -v 'github.com/codegangsta/cli')"

+ 7 - 1
vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go

@@ -124,11 +124,17 @@ func Freeze(c *cgroups.Cgroup, state cgroups.FreezerState) error {
 		return err
 	}
 
+	prevState := c.Freezer
 	c.Freezer = state
 
 	freezer := subsystems["freezer"]
+	err = freezer.Set(d)
+	if err != nil {
+		c.Freezer = prevState
+		return err
+	}
 
-	return freezer.Set(d)
+	return nil
 }
 
 func GetPids(c *cgroups.Cgroup) ([]int, error) {

+ 5 - 0
vendor/src/github.com/docker/libcontainer/namespaces/execin.go

@@ -73,6 +73,11 @@ func ExecIn(container *libcontainer.Config, state *libcontainer.State, userArgs
 		return terminate(err)
 	}
 
+	// finish cgroups' setup, unblock the child process.
+	if _, err := parent.WriteString("1"); err != nil {
+		return terminate(err)
+	}
+
 	if err := json.NewEncoder(parent).Encode(container); err != nil {
 		return terminate(err)
 	}

+ 13 - 8
vendor/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter.c

@@ -28,7 +28,6 @@ void get_args(int *argc, char ***argv)
 		pr_perror("Unable to open /proc/self/cmdline");
 		exit(1);
 	}
-
 	// Read the whole commandline.
 	ssize_t contents_size = 0;
 	ssize_t contents_offset = 0;
@@ -98,13 +97,12 @@ void nsenter()
 	if (strncmp(argv[0], kNsEnter, strlen(kNsEnter)) != 0) {
 		return;
 	}
-
-	#ifdef PR_SET_CHILD_SUBREAPER
+#ifdef PR_SET_CHILD_SUBREAPER
 	if (prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) == -1) {
 		pr_perror("Failed to set child subreaper");
 		exit(1);
 	}
-	#endif
+#endif
 
 	static const struct option longopts[] = {
 		{"nspid", required_argument, NULL, 'n'},
@@ -134,7 +132,7 @@ void nsenter()
 	init_pid = strtol(init_pid_str, NULL, 10);
 	if ((init_pid == 0 && errno == EINVAL) || errno == ERANGE) {
 		pr_perror("Failed to parse PID from \"%s\" with output \"%d\"",
-			init_pid_str, init_pid);
+			  init_pid_str, init_pid);
 		print_usage();
 		exit(1);
 	}
@@ -155,6 +153,12 @@ void nsenter()
 			exit(1);
 		}
 	}
+	// blocking until the parent placed the process inside correct cgroups.
+	unsigned char s;
+	if (read(3, &s, 1) != 1 || s != '1') {
+		pr_perror("failed to receive synchronization data from parent");
+		exit(1);
+	}
 	// Setns on all supported namespaces.
 	char ns_dir[PATH_MAX];
 	memset(ns_dir, 0, PATH_MAX);
@@ -173,18 +177,19 @@ void nsenter()
 	for (i = 0; i < num; i++) {
 		// A zombie process has links on namespaces, but they can't be opened
 		struct stat st;
-		if (fstatat(ns_dir_fd, namespaces[i], &st, AT_SYMLINK_NOFOLLOW) == -1) {
+		if (fstatat(ns_dir_fd, namespaces[i], &st, AT_SYMLINK_NOFOLLOW)
+		    == -1) {
 			if (errno == ENOENT)
 				continue;
 			pr_perror("Failed to stat ns file %s for ns %s",
-				ns_dir, namespaces[i]);
+				  ns_dir, namespaces[i]);
 			exit(1);
 		}
 
 		int fd = openat(ns_dir_fd, namespaces[i], O_RDONLY);
 		if (fd == -1) {
 			pr_perror("Failed to open ns file %s for ns %s",
-				ns_dir, namespaces[i]);
+				  ns_dir, namespaces[i]);
 			exit(1);
 		}
 		// Set the namespace.

+ 19 - 5
vendor/src/github.com/docker/libcontainer/namespaces/nsenter/nsenter_test.go

@@ -12,15 +12,29 @@ import (
 
 func TestNsenterAlivePid(t *testing.T) {
 	args := []string{"nsenter-exec", "--nspid", fmt.Sprintf("%d", os.Getpid())}
+	r, w, err := os.Pipe()
+	if err != nil {
+		t.Fatalf("failed to create pipe %v", err)
+	}
 
 	cmd := &exec.Cmd{
-		Path: os.Args[0],
-		Args: args,
+		Path:       os.Args[0],
+		Args:       args,
+		ExtraFiles: []*os.File{r},
 	}
 
-	err := cmd.Run()
-	if err != nil {
-		t.Fatal("nsenter exits with a non-zero exit status")
+	if err := cmd.Start(); err != nil {
+		t.Fatalf("nsenter failed to start %v", err)
+	}
+	r.Close()
+
+	// unblock the child process
+	if _, err := w.WriteString("1"); err != nil {
+		t.Fatalf("parent failed to write synchronization data %v", err)
+	}
+
+	if err := cmd.Wait(); err != nil {
+		t.Fatalf("nsenter exits with a non-zero exit status")
 	}
 }