diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go
index b9318f99e7..1e96caa7e3 100644
--- a/pkg/cgroups/cgroups.go
+++ b/pkg/cgroups/cgroups.go
@@ -5,10 +5,23 @@ import (
 	"fmt"
 	"github.com/dotcloud/docker/pkg/mount"
 	"io"
+	"io/ioutil"
 	"os"
+	"path/filepath"
+	"strconv"
 	"strings"
 )
 
+type Cgroup struct {
+	Name   string `json:"name,omitempty"`
+	Parent string `json:"parent,omitempty"`
+
+	DeviceAccess bool  `json:"device_access,omitempty"` // name of parent cgroup or slice
+	Memory       int64 `json:"memory,omitempty"`        // Memory limit (in bytes)
+	MemorySwap   int64 `json:"memory_swap,omitempty"`   // Total memory usage (memory + swap); set `-1' to disable swap
+	CpuShares    int64 `json:"cpu_shares,omitempty"`    // CPU shares (relative weight vs. other containers)
+}
+
 // https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt
 func FindCgroupMountpoint(subsystem string) (string, error) {
 	mounts, err := mount.GetMounts()
@@ -25,7 +38,6 @@ func FindCgroupMountpoint(subsystem string) (string, error) {
 			}
 		}
 	}
-
 	return "", fmt.Errorf("cgroup mountpoint not found for %s", subsystem)
 }
 
@@ -50,9 +62,50 @@ func GetInitCgroupDir(subsystem string) (string, error) {
 	return parseCgroupFile(subsystem, f)
 }
 
+func (c *Cgroup) Path(root, subsystem string) (string, error) {
+	cgroup := c.Name
+	if c.Parent != "" {
+		cgroup = filepath.Join(c.Parent, cgroup)
+	}
+	initPath, err := GetInitCgroupDir(subsystem)
+	if err != nil {
+		return "", err
+	}
+	return filepath.Join(root, subsystem, initPath, cgroup), nil
+}
+
+func (c *Cgroup) Join(root, subsystem string, pid int) (string, error) {
+	path, err := c.Path(root, subsystem)
+	if err != nil {
+		return "", err
+	}
+	if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) {
+		return "", err
+	}
+	if err := writeFile(path, "tasks", strconv.Itoa(pid)); err != nil {
+		return "", err
+	}
+	return path, nil
+}
+
+func (c *Cgroup) Cleanup(root string) error {
+	get := func(subsystem string) string {
+		path, _ := c.Path(root, subsystem)
+		return path
+	}
+
+	for _, path := range []string{
+		get("memory"),
+		get("devices"),
+		get("cpu"),
+	} {
+		os.RemoveAll(path)
+	}
+	return nil
+}
+
 func parseCgroupFile(subsystem string, r io.Reader) (string, error) {
 	s := bufio.NewScanner(r)
-
 	for s.Scan() {
 		if err := s.Err(); err != nil {
 			return "", err
@@ -67,3 +120,7 @@ func parseCgroupFile(subsystem string, r io.Reader) (string, error) {
 	}
 	return "", fmt.Errorf("cgroup '%s' not found in /proc/self/cgroup", subsystem)
 }
+
+func writeFile(dir, file, data string) error {
+	return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
+}
diff --git a/pkg/libcontainer/cgroup/cgroup.go b/pkg/libcontainer/cgroup/cgroup.go
index e30262ca50..5f27ac3ffb 100644
--- a/pkg/libcontainer/cgroup/cgroup.go
+++ b/pkg/libcontainer/cgroup/cgroup.go
@@ -10,71 +10,46 @@ import (
 	"strconv"
 )
 
-// We have two implementation of cgroups support, one is based on
-// systemd and the dbus api, and one is based on raw cgroup fs operations
-// following the pre-single-writer model docs at:
-// http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups/
-const (
-	cgroupRoot = "/sys/fs/cgroup"
-)
-
-func useSystemd() bool {
-	return false
-}
-
-func applyCgroupSystemd(container *libcontainer.Container, pid int) error {
-	return fmt.Errorf("not supported yet")
-}
-
-func writeFile(dir, file, data string) error {
-	return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
-}
-
-func getCgroup(subsystem string, container *libcontainer.Container) (string, error) {
-	cgroup := container.CgroupName
-	if container.CgroupParent != "" {
-		cgroup = filepath.Join(container.CgroupParent, cgroup)
+func ApplyCgroup(container *libcontainer.Container, pid int) (err error) {
+	if container.Cgroups == nil {
+		return nil
 	}
 
-	initPath, err := cgroups.GetInitCgroupDir(subsystem)
+	// We have two implementation of cgroups support, one is based on
+	// systemd and the dbus api, and one is based on raw cgroup fs operations
+	// following the pre-single-writer model docs at:
+	// http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups/
+	//
+	// we can pick any subsystem to find the root
+	cgroupRoot, err := cgroups.FindCgroupMountpoint("memory")
 	if err != nil {
-		return "", err
+		return err
 	}
-
-	path := filepath.Join(cgroupRoot, subsystem, initPath, cgroup)
-
-	return path, nil
-}
-
-func joinCgroup(subsystem string, container *libcontainer.Container, pid int) (string, error) {
-	path, err := getCgroup(subsystem, container)
-	if err != nil {
-		return "", err
-	}
-
-	if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) {
-		return "", err
-	}
-
-	if err := writeFile(path, "tasks", strconv.Itoa(pid)); err != nil {
-		return "", err
-	}
-
-	return path, nil
-}
-
-func applyCgroupRaw(container *libcontainer.Container, pid int) (retErr error) {
+	cgroupRoot = filepath.Dir(cgroupRoot)
 	if _, err := os.Stat(cgroupRoot); err != nil {
 		return fmt.Errorf("cgroups fs not found")
 	}
+	if err := setupDevices(container, cgroupRoot, pid); err != nil {
+		return err
+	}
+	if err := setupMemory(container, cgroupRoot, pid); err != nil {
+		return err
+	}
+	if err := setupCpu(container, cgroupRoot, pid); err != nil {
+		return err
+	}
+	return nil
+}
 
-	if !container.DeviceAccess {
-		dir, err := joinCgroup("devices", container, pid)
+func setupDevices(container *libcontainer.Container, cgroupRoot string, pid int) (err error) {
+	if !container.Cgroups.DeviceAccess {
+		dir, err := container.Cgroups.Join(cgroupRoot, "devices", pid)
 		if err != nil {
 			return err
 		}
+
 		defer func() {
-			if retErr != nil {
+			if err != nil {
 				os.RemoveAll(dir)
 			}
 		}()
@@ -113,65 +88,53 @@ func applyCgroupRaw(container *libcontainer.Container, pid int) (retErr error) {
 			}
 		}
 	}
+	return nil
+}
 
-	if container.Memory != 0 || container.MemorySwap != 0 {
-		dir, err := joinCgroup("memory", container, pid)
+func setupMemory(container *libcontainer.Container, cgroupRoot string, pid int) (err error) {
+	if container.Cgroups.Memory != 0 || container.Cgroups.MemorySwap != 0 {
+		dir, err := container.Cgroups.Join(cgroupRoot, "memory", pid)
 		if err != nil {
 			return err
 		}
 		defer func() {
-			if retErr != nil {
+			if err != nil {
 				os.RemoveAll(dir)
 			}
 		}()
 
-		if container.Memory != 0 {
-			if err := writeFile(dir, "memory.limit_in_bytes", strconv.FormatInt(container.Memory, 10)); err != nil {
+		if container.Cgroups.Memory != 0 {
+			if err := writeFile(dir, "memory.limit_in_bytes", strconv.FormatInt(container.Cgroups.Memory, 10)); err != nil {
 				return err
 			}
-			if err := writeFile(dir, "memory.soft_limit_in_bytes", strconv.FormatInt(container.Memory, 10)); err != nil {
+			if err := writeFile(dir, "memory.soft_limit_in_bytes", strconv.FormatInt(container.Cgroups.Memory, 10)); err != nil {
 				return err
 			}
 		}
-		if container.MemorySwap != 0 {
-			if err := writeFile(dir, "memory.memsw.limit_in_bytes", strconv.FormatInt(container.MemorySwap, 10)); err != nil {
+		if container.Cgroups.MemorySwap != 0 {
+			if err := writeFile(dir, "memory.memsw.limit_in_bytes", strconv.FormatInt(container.Cgroups.MemorySwap, 10)); err != nil {
 				return err
 			}
 		}
 	}
+	return nil
+}
 
+func setupCpu(container *libcontainer.Container, cgroupRoot string, pid int) (err error) {
 	// We always want to join the cpu group, to allow fair cpu scheduling
 	// on a container basis
-	dir, err := joinCgroup("cpu", container, pid)
+	dir, err := container.Cgroups.Join(cgroupRoot, "cpu", pid)
 	if err != nil {
 		return err
 	}
-	if container.CpuShares != 0 {
-		if err := writeFile(dir, "cpu.shares", strconv.FormatInt(container.CpuShares, 10)); err != nil {
+	if container.Cgroups.CpuShares != 0 {
+		if err := writeFile(dir, "cpu.shares", strconv.FormatInt(container.Cgroups.CpuShares, 10)); err != nil {
 			return err
 		}
 	}
 	return nil
 }
 
-func CleanupCgroup(container *libcontainer.Container) error {
-	path, _ := getCgroup("memory", container)
-	os.RemoveAll(path)
-	path, _ = getCgroup("devices", container)
-	os.RemoveAll(path)
-	path, _ = getCgroup("cpu", container)
-	os.RemoveAll(path)
-	return nil
-}
-
-func ApplyCgroup(container *libcontainer.Container, pid int) error {
-	if container.CgroupName == "" {
-		return nil
-	}
-
-	if useSystemd() {
-		return applyCgroupSystemd(container, pid)
-	} else {
-		return applyCgroupRaw(container, pid)
-	}
+func writeFile(dir, file, data string) error {
+	return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
 }
diff --git a/pkg/libcontainer/container.go b/pkg/libcontainer/container.go
index b34ac8b351..4c0e39a798 100644
--- a/pkg/libcontainer/container.go
+++ b/pkg/libcontainer/container.go
@@ -1,23 +1,21 @@
 package libcontainer
 
+import (
+	"github.com/dotcloud/docker/pkg/cgroups"
+)
+
 // Container defines configuration options for how a
 // container is setup inside a directory and how a process should be executed
 type Container struct {
-	Hostname     string       `json:"hostname,omitempty"`     // hostname
-	ReadonlyFs   bool         `json:"readonly_fs,omitempty"`  // set the containers rootfs as readonly
-	User         string       `json:"user,omitempty"`         // user to execute the process as
-	WorkingDir   string       `json:"working_dir,omitempty"`  // current working directory
-	Env          []string     `json:"environment,omitempty"`  // environment to set
-	Namespaces   Namespaces   `json:"namespaces,omitempty"`   // namespaces to apply
-	Capabilities Capabilities `json:"capabilities,omitempty"` // capabilities to drop
-	Network      *Network     `json:"network,omitempty"`      // nil for host's network stack
-
-	CgroupName   string `json:"cgroup_name,omitempty"`   // name of cgroup
-	CgroupParent string `json:"cgroup_parent,omitempty"` // name of parent cgroup or slice
-	DeviceAccess bool   `json:"device_access,omitempty"` // name of parent cgroup or slice
-	Memory       int64  `json:"memory,omitempty"`        // Memory limit (in bytes)
-	MemorySwap   int64  `json:"memory_swap,omitempty"`   // Total memory usage (memory + swap); set `-1' to disable swap
-	CpuShares    int64  `json:"cpu_shares,omitempty"`    // CPU shares (relative weight vs. other containers)
+	Hostname     string          `json:"hostname,omitempty"`     // hostname
+	ReadonlyFs   bool            `json:"readonly_fs,omitempty"`  // set the containers rootfs as readonly
+	User         string          `json:"user,omitempty"`         // user to execute the process as
+	WorkingDir   string          `json:"working_dir,omitempty"`  // current working directory
+	Env          []string        `json:"environment,omitempty"`  // environment to set
+	Namespaces   Namespaces      `json:"namespaces,omitempty"`   // namespaces to apply
+	Capabilities Capabilities    `json:"capabilities,omitempty"` // capabilities to drop
+	Network      *Network        `json:"network,omitempty"`      // nil for host's network stack
+	Cgroups      *cgroups.Cgroup `json:"cgroups,omitempty"`
 }
 
 // Network defines configuration for a container's networking stack
diff --git a/pkg/libcontainer/container.json b/pkg/libcontainer/container.json
index 3e23600630..2207543bd0 100644
--- a/pkg/libcontainer/container.json
+++ b/pkg/libcontainer/container.json
@@ -35,7 +35,9 @@
         "bridge": "docker0",
         "mtu": 1500
     },
-    "cgroup_name": "docker-koye",
-    "cgroup_parent": "docker",
-    "memory": 524800
+    "cgroups": {
+        "name": "docker-koye",
+        "parent": "docker",
+        "memory": 524800
+    }
 }