diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7382d09..deca292 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -25,7 +25,7 @@ jobs:
       - name: Install Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.16.x'
+          go-version: '1.17.x'
 
       - name: Set env
         shell: bash
@@ -90,7 +90,7 @@ jobs:
       - name: Install Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.16.x'
+          go-version: '1.17.x'
 
       - name: Set env
         shell: bash
diff --git a/README.md b/README.md
index fc2c7a9..eccb9d9 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ uses the v1 implementation of cgroups.
 ```go
 shares := uint64(100)
 control, err := cgroups.New(cgroups.V1, cgroups.StaticPath("/test"), &specs.LinuxResources{
-    CPU: &specs.CPU{
+    CPU: &specs.LinuxCPU{
         Shares: &shares,
     },
 })
diff --git a/Vagrantfile b/Vagrantfile
index 4596ad8..9a4aac8 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -3,19 +3,19 @@
 
 Vagrant.configure("2") do |config|
 # Fedora box is used for testing cgroup v2 support
-  config.vm.box = "fedora/32-cloud-base"
+  config.vm.box = "fedora/35-cloud-base"
   config.vm.provider :virtualbox do |v|
-    v.memory = 2048
+    v.memory = 4096
     v.cpus = 2
   end
   config.vm.provider :libvirt do |v|
-    v.memory = 2048
+    v.memory = 4096
     v.cpus = 2
   end
   config.vm.provision "shell", inline: <<-SHELL
     set -eux -o pipefail
     # configuration
-    GO_VERSION="1.15"
+    GO_VERSION="1.17.7"
 
     # install gcc and Golang
     dnf -y install gcc
diff --git a/debian/changelog b/debian/changelog
index 3599af6..e579c42 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang-github-containerd-cgroups (1.0.3+git20220301.1.2e502f6-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Thu, 17 Mar 2022 02:30:38 -0000
+
 golang-github-containerd-cgroups (1.0.3-1) unstable; urgency=medium
 
   * Team upload.
diff --git a/debian/patches/0001-add-gogoproto-options-taken-from-gogoctrd.patch b/debian/patches/0001-add-gogoproto-options-taken-from-gogoctrd.patch
index cf17636..1094a6d 100644
--- a/debian/patches/0001-add-gogoproto-options-taken-from-gogoctrd.patch
+++ b/debian/patches/0001-add-gogoproto-options-taken-from-gogoctrd.patch
@@ -12,10 +12,10 @@ Forwarded: not-needed
  v2/stats/metrics.proto | 8 ++++++++
  2 files changed, 16 insertions(+)
 
-diff --git a/stats/v1/metrics.proto b/stats/v1/metrics.proto
-index b3f6cc3..0674c35 100644
---- a/stats/v1/metrics.proto
-+++ b/stats/v1/metrics.proto
+Index: golang-github-containerd-cgroups/stats/v1/metrics.proto
+===================================================================
+--- golang-github-containerd-cgroups.orig/stats/v1/metrics.proto
++++ golang-github-containerd-cgroups/stats/v1/metrics.proto
 @@ -2,6 +2,14 @@ syntax = "proto3";
  
  package io.containerd.cgroups.v1;
@@ -31,10 +31,10 @@ index b3f6cc3..0674c35 100644
  import "gogoproto/gogo.proto";
  
  message Metrics {
-diff --git a/v2/stats/metrics.proto b/v2/stats/metrics.proto
-index 8ac472e..b99de76 100644
---- a/v2/stats/metrics.proto
-+++ b/v2/stats/metrics.proto
+Index: golang-github-containerd-cgroups/v2/stats/metrics.proto
+===================================================================
+--- golang-github-containerd-cgroups.orig/v2/stats/metrics.proto
++++ golang-github-containerd-cgroups/v2/stats/metrics.proto
 @@ -2,6 +2,14 @@ syntax = "proto3";
  
  package io.containerd.cgroups.v2;
diff --git a/debian/patches/0002-skip-TestSystemd240.patch b/debian/patches/0002-skip-TestSystemd240.patch
index ec963e0..b2aa05d 100644
--- a/debian/patches/0002-skip-TestSystemd240.patch
+++ b/debian/patches/0002-skip-TestSystemd240.patch
@@ -7,10 +7,10 @@ Forwarded: not-needed
  paths_test.go | 1 +
  1 file changed, 1 insertion(+)
 
-diff --git a/paths_test.go b/paths_test.go
-index 9dd2898..5d7caaa 100644
---- a/paths_test.go
-+++ b/paths_test.go
+Index: golang-github-containerd-cgroups/paths_test.go
+===================================================================
+--- golang-github-containerd-cgroups.orig/paths_test.go
++++ golang-github-containerd-cgroups/paths_test.go
 @@ -114,6 +114,7 @@ func TestEmptySubsystem(t *testing.T) {
  }
  
diff --git a/debian/patches/0003-Disable-tests-which-needs-cgroupv2.patch b/debian/patches/0003-Disable-tests-which-needs-cgroupv2.patch
index befaee5..ca14764 100644
--- a/debian/patches/0003-Disable-tests-which-needs-cgroupv2.patch
+++ b/debian/patches/0003-Disable-tests-which-needs-cgroupv2.patch
@@ -11,10 +11,10 @@ Forwarded: not-needed
  v2/testutils_test.go | 1 +
  2 files changed, 4 insertions(+)
 
-diff --git a/v2/manager_test.go b/v2/manager_test.go
-index 35d104c..8b29c64 100644
---- a/v2/manager_test.go
-+++ b/v2/manager_test.go
+Index: golang-github-containerd-cgroups/v2/manager_test.go
+===================================================================
+--- golang-github-containerd-cgroups.orig/v2/manager_test.go
++++ golang-github-containerd-cgroups/v2/manager_test.go
 @@ -1,3 +1,6 @@
 +//go:build ignore
 +// +build ignore
@@ -22,10 +22,10 @@ index 35d104c..8b29c64 100644
  /*
     Copyright The containerd Authors.
  
-diff --git a/v2/testutils_test.go b/v2/testutils_test.go
-index a329ce8..abfb9c0 100644
---- a/v2/testutils_test.go
-+++ b/v2/testutils_test.go
+Index: golang-github-containerd-cgroups/v2/testutils_test.go
+===================================================================
+--- golang-github-containerd-cgroups.orig/v2/testutils_test.go
++++ golang-github-containerd-cgroups/v2/testutils_test.go
 @@ -28,6 +28,7 @@ import (
  )
  
diff --git a/debian/patches/0004-Add-v2.ErrCgroupDeleted-back.patch b/debian/patches/0004-Add-v2.ErrCgroupDeleted-back.patch
index 0eb7254..45ad188 100644
--- a/debian/patches/0004-Add-v2.ErrCgroupDeleted-back.patch
+++ b/debian/patches/0004-Add-v2.ErrCgroupDeleted-back.patch
@@ -6,10 +6,10 @@ Subject: Add v2.ErrCgroupDeleted back
  v2/errors.go | 3 +++
  1 file changed, 3 insertions(+)
 
-diff --git a/v2/errors.go b/v2/errors.go
-index eeae362..5dc19f9 100644
---- a/v2/errors.go
-+++ b/v2/errors.go
+Index: golang-github-containerd-cgroups/v2/errors.go
+===================================================================
+--- golang-github-containerd-cgroups.orig/v2/errors.go
++++ golang-github-containerd-cgroups/v2/errors.go
 @@ -18,9 +18,12 @@ package v2
  
  import (
diff --git a/v2/cpuv2_test.go b/v2/cpuv2_test.go
index 4f75f7c..91b726a 100644
--- a/v2/cpuv2_test.go
+++ b/v2/cpuv2_test.go
@@ -68,6 +68,25 @@ func TestSystemdCgroupCpuController(t *testing.T) {
 	checkFileContent(t, c.path, "cpu.weight", strconv.FormatUint(weight, 10))
 }
 
+func TestSystemdCgroupCpuController_NilWeight(t *testing.T) {
+	checkCgroupMode(t)
+	group := "testingCpuNilWeight.slice"
+	// nil weight defaults to 100
+	var quota int64 = 10000
+	var period uint64 = 8000
+	cpuMax := NewCPUMax(&quota, &period)
+	res := Resources{
+		CPU: &CPU{
+			Weight: nil,
+			Max:    cpuMax,
+		},
+	}
+	_, err := NewSystemd("/", group, -1, &res)
+	if err != nil {
+		t.Fatal("failed to init new cgroup systemd manager: ", err)
+	}
+}
+
 func TestExtractQuotaAndPeriod(t *testing.T) {
 	var (
 		period uint64
diff --git a/v2/manager.go b/v2/manager.go
index afed14c..240a0ad 100644
--- a/v2/manager.go
+++ b/v2/manager.go
@@ -701,12 +701,39 @@ func setDevices(path string, devices []specs.LinuxDeviceCgroup) error {
 	return nil
 }
 
+// getSystemdFullPath returns the full systemd path when creating a systemd slice group.
+// the reason this is necessary is because the "-" character has a special meaning in
+// systemd slice. For example, when creating a slice called "my-group-112233.slice",
+// systemd will create a hierarchy like this:
+//      /sys/fs/cgroup/my.slice/my-group.slice/my-group-112233.slice
+func getSystemdFullPath(slice, group string) string {
+	return filepath.Join(defaultCgroup2Path, dashesToPath(slice), dashesToPath(group))
+}
+
+// dashesToPath converts a slice name with dashes to it's corresponding systemd filesystem path.
+func dashesToPath(in string) string {
+	path := ""
+	if strings.HasSuffix(in, ".slice") && strings.Contains(in, "-") {
+		parts := strings.Split(in, "-")
+		for i := range parts {
+			s := strings.Join(parts[0:i+1], "-")
+			if !strings.HasSuffix(s, ".slice") {
+				s += ".slice"
+			}
+			path = filepath.Join(path, s)
+		}
+	} else {
+		path = filepath.Join(path, in)
+	}
+	return path
+}
+
 func NewSystemd(slice, group string, pid int, resources *Resources) (*Manager, error) {
 	if slice == "" {
 		slice = defaultSlice
 	}
 	ctx := context.TODO()
-	path := filepath.Join(defaultCgroup2Path, slice, group)
+	path := getSystemdFullPath(slice, group)
 	conn, err := systemdDbus.NewWithContext(ctx)
 	if err != nil {
 		return &Manager{}, err
@@ -734,12 +761,17 @@ func NewSystemd(slice, group string, pid int, resources *Resources) (*Manager, e
 		properties = append(properties, newSystemdProperty("PIDs", []uint32{uint32(pid)}))
 	}
 
-	if resources.Memory != nil && *resources.Memory.Max != 0 {
+	if resources.Memory != nil && resources.Memory.Min != nil && *resources.Memory.Min != 0 {
+		properties = append(properties,
+			newSystemdProperty("MemoryMin", uint64(*resources.Memory.Min)))
+	}
+
+	if resources.Memory != nil && resources.Memory.Max != nil && *resources.Memory.Max != 0 {
 		properties = append(properties,
 			newSystemdProperty("MemoryMax", uint64(*resources.Memory.Max)))
 	}
 
-	if resources.CPU != nil && *resources.CPU.Weight != 0 {
+	if resources.CPU != nil && resources.CPU.Weight != nil && *resources.CPU.Weight != 0 {
 		properties = append(properties,
 			newSystemdProperty("CPUWeight", *resources.CPU.Weight))
 	}
@@ -796,9 +828,9 @@ func LoadSystemd(slice, group string) (*Manager, error) {
 	if slice == "" {
 		slice = defaultSlice
 	}
-	group = filepath.Join(defaultCgroup2Path, slice, group)
+	path := getSystemdFullPath(slice, group)
 	return &Manager{
-		path: group,
+		path: path,
 	}, nil
 }
 
diff --git a/v2/manager_test.go b/v2/manager_test.go
index 35d104c..650af28 100644
--- a/v2/manager_test.go
+++ b/v2/manager_test.go
@@ -22,6 +22,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/stretchr/testify/assert"
 	"go.uber.org/goleak"
 )
 
@@ -74,3 +75,67 @@ func TestEventChanCleanupOnCgroupRemoval(t *testing.T) {
 	}
 	goleak.VerifyNone(t)
 }
+
+func TestSystemdFullPath(t *testing.T) {
+	tests := []struct {
+		inputSlice  string
+		inputGroup  string
+		expectedOut string
+	}{
+		{
+			inputSlice:  "user.slice",
+			inputGroup:  "myGroup.slice",
+			expectedOut: "/sys/fs/cgroup/user.slice/myGroup.slice",
+		},
+		{
+			inputSlice:  "/",
+			inputGroup:  "myGroup.slice",
+			expectedOut: "/sys/fs/cgroup/myGroup.slice",
+		},
+		{
+			inputSlice:  "system.slice",
+			inputGroup:  "myGroup.slice",
+			expectedOut: "/sys/fs/cgroup/system.slice/myGroup.slice",
+		},
+		{
+			inputSlice:  "user.slice",
+			inputGroup:  "my-group.slice",
+			expectedOut: "/sys/fs/cgroup/user.slice/my.slice/my-group.slice",
+		},
+		{
+			inputSlice:  "user.slice",
+			inputGroup:  "my-group-more-dashes.slice",
+			expectedOut: "/sys/fs/cgroup/user.slice/my.slice/my-group.slice/my-group-more.slice/my-group-more-dashes.slice",
+		},
+		{
+			inputSlice:  "user.slice",
+			inputGroup:  "my-group-dashes.slice",
+			expectedOut: "/sys/fs/cgroup/user.slice/my.slice/my-group.slice/my-group-dashes.slice",
+		},
+		{
+			inputSlice:  "user.slice",
+			inputGroup:  "myGroup.scope",
+			expectedOut: "/sys/fs/cgroup/user.slice/myGroup.scope",
+		},
+		{
+			inputSlice:  "user.slice",
+			inputGroup:  "my-group-dashes.scope",
+			expectedOut: "/sys/fs/cgroup/user.slice/my-group-dashes.scope",
+		},
+		{
+			inputSlice:  "test-waldo.slice",
+			inputGroup:  "my-group.slice",
+			expectedOut: "/sys/fs/cgroup/test.slice/test-waldo.slice/my.slice/my-group.slice",
+		},
+		{
+			inputSlice:  "test-waldo.slice",
+			inputGroup:  "my.service",
+			expectedOut: "/sys/fs/cgroup/test.slice/test-waldo.slice/my.service",
+		},
+	}
+
+	for _, test := range tests {
+		actual := getSystemdFullPath(test.inputSlice, test.inputGroup)
+		assert.Equal(t, test.expectedOut, actual)
+	}
+}
diff --git a/v2/memory.go b/v2/memory.go
index 72f94b7..6f4733b 100644
--- a/v2/memory.go
+++ b/v2/memory.go
@@ -18,6 +18,7 @@ package v2
 
 type Memory struct {
 	Swap *int64
+	Min  *int64
 	Max  *int64
 	Low  *int64
 	High *int64
@@ -30,6 +31,12 @@ func (r *Memory) Values() (o []Value) {
 			value:    *r.Swap,
 		})
 	}
+	if r.Min != nil {
+		o = append(o, Value{
+			filename: "memory.min",
+			value:    *r.Min,
+		})
+	}
 	if r.Max != nil {
 		o = append(o, Value{
 			filename: "memory.max",
diff --git a/v2/memoryv2_test.go b/v2/memoryv2_test.go
index 58703a9..ada7c64 100644
--- a/v2/memoryv2_test.go
+++ b/v2/memoryv2_test.go
@@ -56,6 +56,7 @@ func TestSystemdCgroupMemoryController(t *testing.T) {
 	group := fmt.Sprintf("testing-memory-%d.scope", os.Getpid())
 	res := Resources{
 		Memory: &Memory{
+			Min: pointerInt64(16384),
 			Max: pointerInt64(629145600),
 		},
 	}
@@ -63,5 +64,6 @@ func TestSystemdCgroupMemoryController(t *testing.T) {
 	if err != nil {
 		t.Fatal("failed to init new cgroup systemd manager: ", err)
 	}
+	checkFileContent(t, c.path, "memory.min", "16384")
 	checkFileContent(t, c.path, "memory.max", "629145600")
 }
diff --git a/v2/utils.go b/v2/utils.go
index 902466f..240c926 100644
--- a/v2/utils.go
+++ b/v2/utils.go
@@ -227,7 +227,7 @@ func ToResources(spec *specs.LinuxResources) *Resources {
 	if i := spec.Rdma; i != nil {
 		resources.RDMA = &RDMA{}
 		for device, value := range spec.Rdma {
-			if device != "" && (value.HcaHandles != nil || value.HcaObjects != nil) {
+			if device != "" && (value.HcaHandles != nil && value.HcaObjects != nil) {
 				resources.RDMA.Limit = append(resources.RDMA.Limit, RDMAEntry{
 					Device:     device,
 					HcaHandles: *value.HcaHandles,