Browse code

Update libcontainer to 28cb5f9dfd6f3352c610a4f1502

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Michael Crosby authored on 2014/11/18 05:16:37
Showing 16 changed files
... ...
@@ -66,7 +66,7 @@ if [ "$1" = '--go' ]; then
66 66
 	mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
67 67
 fi
68 68
 
69
-clone git github.com/docker/libcontainer 4ae31b6ceb2c2557c9f05f42da61b0b808faa5a4
69
+clone git github.com/docker/libcontainer 28cb5f9dfd6f3352c610a4f1502b5df4f69389ea
70 70
 # see src/github.com/docker/libcontainer/update-vendor.sh which is the "source of truth" for libcontainer deps (just like this file)
71 71
 rm -rf src/github.com/docker/libcontainer/vendor
72 72
 eval "$(grep '^clone ' src/github.com/docker/libcontainer/update-vendor.sh | grep -v 'github.com/codegangsta/cli')"
... ...
@@ -1,7 +1,7 @@
1 1
 FROM crosbymichael/golang
2 2
 
3 3
 RUN apt-get update && apt-get install -y gcc make
4
-RUN go get code.google.com/p/go.tools/cmd/cover
4
+RUN go get golang.org/x/tools/cmd/cover
5 5
 
6 6
 ENV GOPATH $GOPATH:/go/src/github.com/docker/libcontainer/vendor
7 7
 RUN go get github.com/docker/docker/pkg/term
... ...
@@ -10,7 +10,7 @@ RUN go get github.com/docker/docker/pkg/term
10 10
 RUN mkdir /busybox && \
11 11
     curl -sSL 'https://github.com/jpetazzo/docker-busybox/raw/buildroot-2014.02/rootfs.tar' | tar -xC /busybox
12 12
 
13
-RUN curl -sSL https://raw.githubusercontent.com/docker/docker/master/hack/dind -o /dind && \
13
+RUN curl -sSL https://raw.githubusercontent.com/docker/docker/master/project/dind -o /dind && \
14 14
     chmod +x /dind
15 15
 
16 16
 COPY . /go/src/github.com/docker/libcontainer
... ...
@@ -5,30 +5,17 @@ package libcontainer
5 5
 
6 6
 import (
7 7
 	"github.com/docker/libcontainer/cgroups/fs"
8
-	"github.com/docker/libcontainer/cgroups/systemd"
9 8
 	"github.com/docker/libcontainer/network"
10 9
 )
11 10
 
12 11
 // TODO(vmarmol): Complete Stats() in final libcontainer API and move users to that.
13 12
 // DEPRECATED: The below portions are only to be used during the transition to the official API.
14 13
 // Returns all available stats for the given container.
15
-func GetStats(container *Config, state *State) (*ContainerStats, error) {
16
-	var (
17
-		err   error
18
-		stats = &ContainerStats{}
19
-	)
20
-
21
-	if systemd.UseSystemd() {
22
-		stats.CgroupStats, err = systemd.GetStats(container.Cgroups)
23
-	} else {
24
-		stats.CgroupStats, err = fs.GetStats(container.Cgroups)
25
-	}
26
-
27
-	if err != nil {
14
+func GetStats(container *Config, state *State) (stats *ContainerStats, err error) {
15
+	stats = &ContainerStats{}
16
+	if stats.CgroupStats, err = fs.GetStats(state.CgroupPaths); err != nil {
28 17
 		return stats, err
29 18
 	}
30
-
31 19
 	stats.NetworkStats, err = network.GetStats(&state.NetworkState)
32
-
33 20
 	return stats, err
34 21
 }
... ...
@@ -53,8 +53,3 @@ type Cgroup struct {
53 53
 	Freezer           FreezerState      `json:"freezer,omitempty"`            // set the freeze value for the process
54 54
 	Slice             string            `json:"slice,omitempty"`              // Parent slice to use for systemd
55 55
 }
56
-
57
-type ActiveCgroup interface {
58
-	Cleanup() error
59
-	Paths() (map[string]string, error)
60
-}
61 56
deleted file mode 100644
... ...
@@ -1,264 +0,0 @@
1
-package main
2
-
3
-import (
4
-	"encoding/json"
5
-	"fmt"
6
-	"log"
7
-	"os"
8
-	"syscall"
9
-	"time"
10
-
11
-	"github.com/codegangsta/cli"
12
-	"github.com/docker/libcontainer/cgroups"
13
-	"github.com/docker/libcontainer/cgroups/fs"
14
-	"github.com/docker/libcontainer/cgroups/systemd"
15
-)
16
-
17
-var createCommand = cli.Command{
18
-	Name:  "create",
19
-	Usage: "Create a cgroup container using the supplied configuration and initial process.",
20
-	Flags: []cli.Flag{
21
-		cli.StringFlag{Name: "config, c", Value: "cgroup.json", Usage: "path to container configuration (cgroups.Cgroup object)"},
22
-		cli.IntFlag{Name: "pid, p", Value: 0, Usage: "pid of the initial process in the container"},
23
-	},
24
-	Action: createAction,
25
-}
26
-
27
-var destroyCommand = cli.Command{
28
-	Name:  "destroy",
29
-	Usage: "Destroy an existing cgroup container.",
30
-	Flags: []cli.Flag{
31
-		cli.StringFlag{Name: "name, n", Value: "", Usage: "container name"},
32
-		cli.StringFlag{Name: "parent, p", Value: "", Usage: "container parent"},
33
-	},
34
-	Action: destroyAction,
35
-}
36
-
37
-var statsCommand = cli.Command{
38
-	Name:  "stats",
39
-	Usage: "Get stats for cgroup",
40
-	Flags: []cli.Flag{
41
-		cli.StringFlag{Name: "name, n", Value: "", Usage: "container name"},
42
-		cli.StringFlag{Name: "parent, p", Value: "", Usage: "container parent"},
43
-	},
44
-	Action: statsAction,
45
-}
46
-
47
-var pauseCommand = cli.Command{
48
-	Name:  "pause",
49
-	Usage: "Pause cgroup",
50
-	Flags: []cli.Flag{
51
-		cli.StringFlag{Name: "name, n", Value: "", Usage: "container name"},
52
-		cli.StringFlag{Name: "parent, p", Value: "", Usage: "container parent"},
53
-	},
54
-	Action: pauseAction,
55
-}
56
-
57
-var resumeCommand = cli.Command{
58
-	Name:  "resume",
59
-	Usage: "Resume a paused cgroup",
60
-	Flags: []cli.Flag{
61
-		cli.StringFlag{Name: "name, n", Value: "", Usage: "container name"},
62
-		cli.StringFlag{Name: "parent, p", Value: "", Usage: "container parent"},
63
-	},
64
-	Action: resumeAction,
65
-}
66
-
67
-var psCommand = cli.Command{
68
-	Name:  "ps",
69
-	Usage: "Get list of pids for a cgroup",
70
-	Flags: []cli.Flag{
71
-		cli.StringFlag{Name: "name, n", Value: "", Usage: "container name"},
72
-		cli.StringFlag{Name: "parent, p", Value: "", Usage: "container parent"},
73
-	},
74
-	Action: psAction,
75
-}
76
-
77
-func getConfigFromFile(c *cli.Context) (*cgroups.Cgroup, error) {
78
-	f, err := os.Open(c.String("config"))
79
-	if err != nil {
80
-		return nil, err
81
-	}
82
-	defer f.Close()
83
-
84
-	var config *cgroups.Cgroup
85
-	if err := json.NewDecoder(f).Decode(&config); err != nil {
86
-		log.Fatal(err)
87
-	}
88
-	return config, nil
89
-}
90
-
91
-func openLog(name string) error {
92
-	f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0755)
93
-	if err != nil {
94
-		return err
95
-	}
96
-
97
-	log.SetOutput(f)
98
-	return nil
99
-}
100
-
101
-func getConfig(context *cli.Context) (*cgroups.Cgroup, error) {
102
-	name := context.String("name")
103
-	if name == "" {
104
-		log.Fatal(fmt.Errorf("Missing container name"))
105
-	}
106
-	parent := context.String("parent")
107
-	return &cgroups.Cgroup{
108
-		Name:   name,
109
-		Parent: parent,
110
-	}, nil
111
-}
112
-
113
-func killAll(config *cgroups.Cgroup) {
114
-	// We could use freezer here to prevent process spawning while we are trying
115
-	// to kill everything. But going with more portable solution of retrying for
116
-	// now.
117
-	pids := getPids(config)
118
-	retry := 10
119
-	for len(pids) != 0 || retry > 0 {
120
-		killPids(pids)
121
-		time.Sleep(100 * time.Millisecond)
122
-		retry--
123
-		pids = getPids(config)
124
-	}
125
-	if len(pids) != 0 {
126
-		log.Fatal(fmt.Errorf("Could not kill existing processes in the container."))
127
-	}
128
-}
129
-
130
-func getPids(config *cgroups.Cgroup) []int {
131
-	pids, err := fs.GetPids(config)
132
-	if err != nil {
133
-		log.Fatal(err)
134
-	}
135
-	return pids
136
-}
137
-
138
-func killPids(pids []int) {
139
-	for _, pid := range pids {
140
-		// pids might go away on their own. Ignore errors.
141
-		syscall.Kill(pid, syscall.SIGKILL)
142
-	}
143
-}
144
-
145
-func setFreezerState(context *cli.Context, state cgroups.FreezerState) {
146
-	config, err := getConfig(context)
147
-	if err != nil {
148
-		log.Fatal(err)
149
-	}
150
-
151
-	if systemd.UseSystemd() {
152
-		err = systemd.Freeze(config, state)
153
-	} else {
154
-		err = fs.Freeze(config, state)
155
-	}
156
-	if err != nil {
157
-		log.Fatal(err)
158
-	}
159
-}
160
-
161
-func createAction(context *cli.Context) {
162
-	config, err := getConfigFromFile(context)
163
-	if err != nil {
164
-		log.Fatal(err)
165
-	}
166
-	pid := context.Int("pid")
167
-	if pid <= 0 {
168
-		log.Fatal(fmt.Errorf("Invalid pid : %d", pid))
169
-	}
170
-	if systemd.UseSystemd() {
171
-		_, err := systemd.Apply(config, pid)
172
-		if err != nil {
173
-			log.Fatal(err)
174
-		}
175
-	} else {
176
-		_, err := fs.Apply(config, pid)
177
-		if err != nil {
178
-			log.Fatal(err)
179
-		}
180
-	}
181
-}
182
-
183
-func destroyAction(context *cli.Context) {
184
-	config, err := getConfig(context)
185
-	if err != nil {
186
-		log.Fatal(err)
187
-	}
188
-
189
-	killAll(config)
190
-	// Systemd will clean up cgroup state for empty container.
191
-	if !systemd.UseSystemd() {
192
-		err := fs.Cleanup(config)
193
-		if err != nil {
194
-			log.Fatal(err)
195
-		}
196
-	}
197
-}
198
-
199
-func statsAction(context *cli.Context) {
200
-	config, err := getConfig(context)
201
-	if err != nil {
202
-		log.Fatal(err)
203
-	}
204
-	stats, err := fs.GetStats(config)
205
-	if err != nil {
206
-		log.Fatal(err)
207
-	}
208
-
209
-	out, err := json.MarshalIndent(stats, "", "\t")
210
-	if err != nil {
211
-		log.Fatal(err)
212
-	}
213
-	fmt.Printf("Usage stats for '%s':\n %v\n", config.Name, string(out))
214
-}
215
-
216
-func pauseAction(context *cli.Context) {
217
-	setFreezerState(context, cgroups.Frozen)
218
-}
219
-
220
-func resumeAction(context *cli.Context) {
221
-	setFreezerState(context, cgroups.Thawed)
222
-}
223
-
224
-func psAction(context *cli.Context) {
225
-	config, err := getConfig(context)
226
-	if err != nil {
227
-		log.Fatal(err)
228
-	}
229
-
230
-	pids, err := fs.GetPids(config)
231
-	if err != nil {
232
-		log.Fatal(err)
233
-	}
234
-
235
-	fmt.Printf("Pids in '%s':\n", config.Name)
236
-	fmt.Println(pids)
237
-}
238
-
239
-func main() {
240
-	logPath := os.Getenv("log")
241
-	if logPath != "" {
242
-		if err := openLog(logPath); err != nil {
243
-			log.Fatal(err)
244
-		}
245
-	}
246
-
247
-	app := cli.NewApp()
248
-	app.Name = "cgutil"
249
-	app.Usage = "Test utility for libcontainer cgroups package"
250
-	app.Version = "0.1"
251
-
252
-	app.Commands = []cli.Command{
253
-		createCommand,
254
-		destroyCommand,
255
-		statsCommand,
256
-		pauseCommand,
257
-		resumeCommand,
258
-		psCommand,
259
-	}
260
-
261
-	if err := app.Run(os.Args); err != nil {
262
-		log.Fatal(err)
263
-	}
264
-}
265 1
deleted file mode 100644
... ...
@@ -1,10 +0,0 @@
1
-{
2
-	"name": "luke",
3
-	"parent": "darth",
4
-	"allow_all_devices": true,
5
-	"memory": 1073741824,
6
-	"memory_swap": -1,
7
-	"cpu_shares": 2048,
8
-	"cpu_quota": 500000,
9
-	"cpu_period": 250000
10
-}
... ...
@@ -57,20 +57,35 @@ type data struct {
57 57
 	pid    int
58 58
 }
59 59
 
60
-func Apply(c *cgroups.Cgroup, pid int) (cgroups.ActiveCgroup, error) {
60
+func Apply(c *cgroups.Cgroup, pid int) (map[string]string, error) {
61 61
 	d, err := getCgroupData(c, pid)
62 62
 	if err != nil {
63 63
 		return nil, err
64 64
 	}
65 65
 
66
-	for _, sys := range subsystems {
66
+	paths := make(map[string]string)
67
+	defer func() {
68
+		if err != nil {
69
+			cgroups.RemovePaths(paths)
70
+		}
71
+	}()
72
+	for name, sys := range subsystems {
67 73
 		if err := sys.Set(d); err != nil {
68
-			d.Cleanup()
69 74
 			return nil, err
70 75
 		}
76
+		// FIXME: Apply should, ideally, be reentrant or be broken up into a separate
77
+		// create and join phase so that the cgroup hierarchy for a container can be
78
+		// created then join consists of writing the process pids to cgroup.procs
79
+		p, err := d.path(name)
80
+		if err != nil {
81
+			if cgroups.IsNotFound(err) {
82
+				continue
83
+			}
84
+			return nil, err
85
+		}
86
+		paths[name] = p
71 87
 	}
72
-
73
-	return d, nil
88
+	return paths, nil
74 89
 }
75 90
 
76 91
 // Symmetrical public function to update device based cgroups.  Also available
... ...
@@ -86,33 +101,13 @@ func ApplyDevices(c *cgroups.Cgroup, pid int) error {
86 86
 	return devices.Set(d)
87 87
 }
88 88
 
89
-func Cleanup(c *cgroups.Cgroup) error {
90
-	d, err := getCgroupData(c, 0)
91
-	if err != nil {
92
-		return fmt.Errorf("Could not get Cgroup data %s", err)
93
-	}
94
-	return d.Cleanup()
95
-}
96
-
97
-func GetStats(c *cgroups.Cgroup) (*cgroups.Stats, error) {
89
+func GetStats(systemPaths map[string]string) (*cgroups.Stats, error) {
98 90
 	stats := cgroups.NewStats()
99
-
100
-	d, err := getCgroupData(c, 0)
101
-	if err != nil {
102
-		return nil, fmt.Errorf("getting CgroupData %s", err)
103
-	}
104
-
105
-	for sysname, sys := range subsystems {
106
-		path, err := d.path(sysname)
107
-		if err != nil {
108
-			// Don't fail if a cgroup hierarchy was not found, just skip this subsystem
109
-			if cgroups.IsNotFound(err) {
110
-				continue
111
-			}
112
-
113
-			return nil, err
91
+	for name, path := range systemPaths {
92
+		sys, ok := subsystems[name]
93
+		if !ok {
94
+			continue
114 95
 		}
115
-
116 96
 		if err := sys.GetStats(path, stats); err != nil {
117 97
 			return nil, err
118 98
 		}
... ...
@@ -176,26 +171,6 @@ func (raw *data) parent(subsystem string) (string, error) {
176 176
 	return filepath.Join(raw.root, subsystem, initPath), nil
177 177
 }
178 178
 
179
-func (raw *data) Paths() (map[string]string, error) {
180
-	paths := make(map[string]string)
181
-
182
-	for sysname := range subsystems {
183
-		path, err := raw.path(sysname)
184
-		if err != nil {
185
-			// Don't fail if a cgroup hierarchy was not found, just skip this subsystem
186
-			if cgroups.IsNotFound(err) {
187
-				continue
188
-			}
189
-
190
-			return nil, err
191
-		}
192
-
193
-		paths[sysname] = path
194
-	}
195
-
196
-	return paths, nil
197
-}
198
-
199 179
 func (raw *data) path(subsystem string) (string, error) {
200 180
 	// If the cgroup name/path is absolute do not look relative to the cgroup of the init process.
201 181
 	if filepath.IsAbs(raw.cgroup) {
... ...
@@ -234,13 +209,6 @@ func (raw *data) join(subsystem string) (string, error) {
234 234
 	return path, nil
235 235
 }
236 236
 
237
-func (raw *data) Cleanup() error {
238
-	for _, sys := range subsystems {
239
-		sys.Remove(raw)
240
-	}
241
-	return nil
242
-}
243
-
244 237
 func writeFile(dir, file, data string) error {
245 238
 	return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
246 239
 }
... ...
@@ -27,7 +27,7 @@ type CpuUsage struct {
27 27
 
28 28
 type CpuStats struct {
29 29
 	CpuUsage       CpuUsage       `json:"cpu_usage,omitempty"`
30
-	ThrottlingData ThrottlingData `json:"throlling_data,omitempty"`
30
+	ThrottlingData ThrottlingData `json:"throttling_data,omitempty"`
31 31
 }
32 32
 
33 33
 type MemoryStats struct {
... ...
@@ -12,7 +12,7 @@ func UseSystemd() bool {
12 12
 	return false
13 13
 }
14 14
 
15
-func Apply(c *cgroups.Cgroup, pid int) (cgroups.ActiveCgroup, error) {
15
+func Apply(c *cgroups.Cgroup, pid int) (map[string]string, error) {
16 16
 	return nil, fmt.Errorf("Systemd not supported")
17 17
 }
18 18
 
... ...
@@ -27,7 +27,3 @@ func ApplyDevices(c *cgroups.Cgroup, pid int) error {
27 27
 func Freeze(c *cgroups.Cgroup, state cgroups.FreezerState) error {
28 28
 	return fmt.Errorf("Systemd not supported")
29 29
 }
30
-
31
-func GetStats(c *cgroups.Cgroup) (*cgroups.Stats, error) {
32
-	return nil, fmt.Errorf("Systemd not supported")
33
-}
... ...
@@ -31,16 +31,6 @@ var (
31 31
 	connLock              sync.Mutex
32 32
 	theConn               *systemd.Conn
33 33
 	hasStartTransientUnit bool
34
-	subsystems            = map[string]subsystem{
35
-		"devices":    &fs.DevicesGroup{},
36
-		"memory":     &fs.MemoryGroup{},
37
-		"cpu":        &fs.CpuGroup{},
38
-		"cpuset":     &fs.CpusetGroup{},
39
-		"cpuacct":    &fs.CpuacctGroup{},
40
-		"blkio":      &fs.BlkioGroup{},
41
-		"perf_event": &fs.PerfEventGroup{},
42
-		"freezer":    &fs.FreezerGroup{},
43
-	}
44 34
 )
45 35
 
46 36
 func newProp(name string, units interface{}) systemd.Property {
... ...
@@ -91,7 +81,7 @@ func getIfaceForUnit(unitName string) string {
91 91
 	return "Unit"
92 92
 }
93 93
 
94
-func Apply(c *cgroups.Cgroup, pid int) (cgroups.ActiveCgroup, error) {
94
+func Apply(c *cgroups.Cgroup, pid int) (map[string]string, error) {
95 95
 	var (
96 96
 		unitName   = getUnitName(c)
97 97
 		slice      = "system.slice"
... ...
@@ -159,45 +149,32 @@ func Apply(c *cgroups.Cgroup, pid int) (cgroups.ActiveCgroup, error) {
159 159
 		}
160 160
 	}
161 161
 
162
-	return res, nil
163
-}
164
-
165
-func writeFile(dir, file, data string) error {
166
-	return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
167
-}
168
-
169
-func (c *systemdCgroup) Paths() (map[string]string, error) {
170 162
 	paths := make(map[string]string)
171
-
172
-	for sysname := range subsystems {
173
-		subsystemPath, err := getSubsystemPath(c.cgroup, sysname)
163
+	for _, sysname := range []string{
164
+		"devices",
165
+		"memory",
166
+		"cpu",
167
+		"cpuset",
168
+		"cpuacct",
169
+		"blkio",
170
+		"perf_event",
171
+		"freezer",
172
+	} {
173
+		subsystemPath, err := getSubsystemPath(res.cgroup, sysname)
174 174
 		if err != nil {
175 175
 			// Don't fail if a cgroup hierarchy was not found, just skip this subsystem
176 176
 			if cgroups.IsNotFound(err) {
177 177
 				continue
178 178
 			}
179
-
180 179
 			return nil, err
181 180
 		}
182
-
183 181
 		paths[sysname] = subsystemPath
184 182
 	}
185
-
186 183
 	return paths, nil
187 184
 }
188 185
 
189
-func (c *systemdCgroup) Cleanup() error {
190
-	// systemd cleans up, we don't need to do much
191
-	paths, err := c.Paths()
192
-	if err != nil {
193
-		return err
194
-	}
195
-
196
-	for _, path := range paths {
197
-		os.RemoveAll(path)
198
-	}
199
-
200
-	return nil
186
+func writeFile(dir, file, data string) error {
187
+	return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
201 188
 }
202 189
 
203 190
 func joinFreezer(c *cgroups.Cgroup, pid int) error {
... ...
@@ -267,35 +244,6 @@ func getUnitName(c *cgroups.Cgroup) string {
267 267
 	return fmt.Sprintf("%s-%s.scope", c.Parent, c.Name)
268 268
 }
269 269
 
270
-/*
271
- * This would be nicer to get from the systemd API when accounting
272
- * is enabled, but sadly there is no way to do that yet.
273
- * The lack of this functionality in the API & the approach taken
274
- * is guided by
275
- * http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/#readingaccountinginformation.
276
- */
277
-func GetStats(c *cgroups.Cgroup) (*cgroups.Stats, error) {
278
-	stats := cgroups.NewStats()
279
-
280
-	for sysname, sys := range subsystems {
281
-		subsystemPath, err := getSubsystemPath(c, sysname)
282
-		if err != nil {
283
-			// Don't fail if a cgroup hierarchy was not found, just skip this subsystem
284
-			if cgroups.IsNotFound(err) {
285
-				continue
286
-			}
287
-
288
-			return nil, err
289
-		}
290
-
291
-		if err := sys.GetStats(subsystemPath, stats); err != nil {
292
-			return nil, err
293
-		}
294
-	}
295
-
296
-	return stats, nil
297
-}
298
-
299 270
 // Atm we can't use the systemd device support because of two missing things:
300 271
 // * Support for wildcards to allow mknod on any device
301 272
 // * Support for wildcards to allow /dev/pts support
... ...
@@ -189,6 +189,17 @@ func EnterPid(cgroupPaths map[string]string, pid int) error {
189 189
 			}
190 190
 		}
191 191
 	}
192
-
193 192
 	return nil
194 193
 }
194
+
195
+// RemovePaths iterates over the provided paths removing them.
196
+// If an error is encountered the removal proceeds and the first error is
197
+// returned to ensure a partial removal is not possible.
198
+func RemovePaths(paths map[string]string) (err error) {
199
+	for _, path := range paths {
200
+		if rerr := os.RemoveAll(path); err == nil {
201
+			err = rerr
202
+		}
203
+	}
204
+	return err
205
+}
... ...
@@ -60,16 +60,11 @@ func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Wri
60 60
 
61 61
 	// Do this before syncing with child so that no children
62 62
 	// can escape the cgroup
63
-	cgroupRef, err := SetupCgroups(container, command.Process.Pid)
64
-	if err != nil {
65
-		return terminate(err)
66
-	}
67
-	defer cgroupRef.Cleanup()
68
-
69
-	cgroupPaths, err := cgroupRef.Paths()
63
+	cgroupPaths, err := SetupCgroups(container, command.Process.Pid)
70 64
 	if err != nil {
71 65
 		return terminate(err)
72 66
 	}
67
+	defer cgroups.RemovePaths(cgroupPaths)
73 68
 
74 69
 	var networkState network.NetworkState
75 70
 	if err := InitializeNetworking(container, command.Process.Pid, &networkState); err != nil {
... ...
@@ -153,18 +148,15 @@ func DefaultCreateCommand(container *libcontainer.Config, console, dataPath, ini
153 153
 
154 154
 // SetupCgroups applies the cgroup restrictions to the process running in the container based
155 155
 // on the container's configuration
156
-func SetupCgroups(container *libcontainer.Config, nspid int) (cgroups.ActiveCgroup, error) {
156
+func SetupCgroups(container *libcontainer.Config, nspid int) (map[string]string, error) {
157 157
 	if container.Cgroups != nil {
158 158
 		c := container.Cgroups
159
-
160 159
 		if systemd.UseSystemd() {
161 160
 			return systemd.Apply(c, nspid)
162 161
 		}
163
-
164 162
 		return fs.Apply(c, nspid)
165 163
 	}
166
-
167
-	return nil, nil
164
+	return map[string]string{}, nil
168 165
 }
169 166
 
170 167
 // InitializeNetworking creates the container's network stack outside of the namespace and moves
... ...
@@ -111,7 +111,7 @@ func FinalizeSetns(container *libcontainer.Config, args []string) error {
111 111
 		}
112 112
 	}
113 113
 
114
-	if err := system.Execv(args[0], args[0:], container.Env); err != nil {
114
+	if err := system.Execv(args[0], args[0:], os.Environ()); err != nil {
115 115
 		return err
116 116
 	}
117 117
 
... ...
@@ -100,7 +100,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, pip
100 100
 
101 101
 	if container.Hostname != "" {
102 102
 		if err := syscall.Sethostname([]byte(container.Hostname)); err != nil {
103
-			return fmt.Errorf("sethostname %s", err)
103
+			return fmt.Errorf("unable to sethostname %q: %s", container.Hostname, err)
104 104
 		}
105 105
 	}
106 106
 
... ...
@@ -1004,7 +1004,7 @@ func AddRoute(destination, source, gateway, device string) error {
1004 1004
 
1005 1005
 	if source != "" {
1006 1006
 		srcIP := net.ParseIP(source)
1007
-		if err != nil {
1007
+		if srcIP == nil {
1008 1008
 			return fmt.Errorf("source IP %s couldn't be parsed", source)
1009 1009
 		}
1010 1010
 		srcFamily := getIpFamily(srcIP)
... ...
@@ -7,7 +7,7 @@ import (
7 7
 
8 8
 // Setuid sets the uid of the calling thread to the specified uid.
9 9
 func Setuid(uid int) (err error) {
10
-	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0)
10
+	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID32, uintptr(uid), 0, 0)
11 11
 	if e1 != 0 {
12 12
 		err = e1
13 13
 	}