Repository: opencontainers/runc
Pull request #2597 (2020-09-22 22:58:25)

Fix/improve GetHugePageSize
### libct/cgroups/GetHugePageSize: use Readdirnames

ioutil.ReadFile does a stat() on every entry and returns a slice of
os.Stat structures. What we need here is just a file name.
    
This change both simplifies and speeds up the code a bit
(30% on my laptop).

### libct/cgroups: rewrite getHugePageSizeFromFilenames

This is a function to convert huge page sizes (obtained by reading
/sys/kernel/mm/hugepages directory entries) to strings user for hugetlb
cgroup controller resource files. Those strings are when used to get the
hugetlb resource statistics.

This function used external library, floating point numbers, and can
(theoretically) produce invalid values, since the kernel only uses KB,
MB, and GB suffixes.

Rewrite it to produce the same strings as used in the kernel (see [1]).
As a result, it's also faster (about 11x on my laptop -- see below), more
future-proof (entries that do not start with "hugepages-" are skipped),
and does more input sanity checks.

As a side effect, libcontainer no longer depends on docker/go-units.

While at it, improve the test logic and add more test cases.

NOTE on removing `HugePageSizeUnitList` -- this was added by commit
6f77e35da and was used by kubernetes code in [2], which was later
superceded by [3], so there are (hopefully) no external users.
If there are any, they should not be doing that.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/hugetlb_cgroup.c?id=eff48ddeab782e35e58ccc8853f7386bbae9dec4#n574
[2] https://github.com/kubernetes/kubernetes/pull/78495
[3] https://github.com/kubernetes/kubernetes/pull/84154


### Benchmarks

Before:
```
BenchmarkGetHugePageSize-8                115213              9400 ns/op
BenchmarkGetHugePageSizeImpl-8            397873              2971 ns/op
```

After:
```
BenchmarkGetHugePageSize-8                222898              4554 ns/op
BenchmarkGetHugePageSizeImpl-8           4738924               241 ns/op
```


Patch:
diff --git a/Makefile b/Makefile
index 1a4fa2de..30adba97 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 CONTAINER_ENGINE := docker
 GO := go
 
-PREFIX ?= /usr/local
+PREFIX ?= $(DESTDIR)/usr/local
 BINDIR := $(PREFIX)/sbin
 MANDIR := $(PREFIX)/share/man
 
@@ -102,14 +102,14 @@ shell: runcimage
 		$(RUNC_IMAGE) bash
 
 install:
-	install -D -m0755 runc $(DESTDIR)$(BINDIR)/runc
+	install -D -m0755 runc $(BINDIR)/runc
 
 install-bash:
-	install -D -m0644 contrib/completions/bash/runc $(DESTDIR)$(PREFIX)/share/bash-completion/completions/runc
+	install -D -m0644 contrib/completions/bash/runc $(PREFIX)/share/bash-completion/completions/runc
 
 install-man: man
-	install -d -m 755 $(DESTDIR)$(MANDIR)/man8
-	install -D -m 644 man/man8/*.8 $(DESTDIR)$(MANDIR)/man8
+	install -d -m 755 $(MANDIR)/man8
+	install -D -m 644 man/man8/*.8 $(MANDIR)/man8
 
 clean:
 	rm -f runc runc-*
diff --git a/checkpoint.go b/checkpoint.go
index d00cb044..5b473098 100644
--- a/checkpoint.go
+++ b/checkpoint.go
@@ -5,9 +5,9 @@ package main
 import (
 	"errors"
 	"fmt"
-	"net"
 	"os"
 	"strconv"
+	"strings"
 
 	criu "github.com/checkpoint-restore/go-criu/v4/rpc"
 	"github.com/opencontainers/runc/libcontainer"
@@ -15,6 +15,7 @@ import (
 	"github.com/opencontainers/runtime-spec/specs-go"
 	"github.com/sirupsen/logrus"
 	"github.com/urfave/cli"
+
 	"golang.org/x/sys/unix"
 )
 
@@ -90,17 +91,16 @@ func setPageServer(context *cli.Context, options *libcontainer.CriuOpts) {
 	// xxx following criu opts are optional
 	// The dump image can be sent to a criu page server
 	if psOpt := context.String("page-server"); psOpt != "" {
-		address, port, err := net.SplitHostPort(psOpt)
-
-		if err != nil || address == "" || port == "" {
+		addressPort := strings.Split(psOpt, ":")
+		if len(addressPort) != 2 {
 			fatal(errors.New("Use --page-server ADDRESS:PORT to specify page server"))
 		}
-		portInt, err := strconv.Atoi(port)
+		portInt, err := strconv.Atoi(addressPort[1])
 		if err != nil {
 			fatal(errors.New("Invalid port number"))
 		}
 		options.PageServer = libcontainer.CriuPageServerInfo{
-			Address: address,
+			Address: addressPort[0],
 			Port:    int32(portInt),
 		}
 	}
diff --git a/contrib/cmd/recvtty/recvtty.go b/contrib/cmd/recvtty/recvtty.go
index 99203846..00b30e1c 100644
--- a/contrib/cmd/recvtty/recvtty.go
+++ b/contrib/cmd/recvtty/recvtty.go
@@ -187,7 +187,7 @@ func main() {
 		v = append(v, version)
 	}
 	if gitCommit != "" {
-		v = append(v, "commit: "+gitCommit)
+		v = append(v, fmt.Sprintf("commit: %s", gitCommit))
 	}
 	app.Version = strings.Join(v, "\n")
 
diff --git a/go.mod b/go.mod
index b32f2528..42062bdf 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.14
 require (
 	github.com/checkpoint-restore/go-criu/v4 v4.1.0
 	github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775
-	github.com/containerd/console v1.0.1
+	github.com/containerd/console v1.0.0
 	github.com/coreos/go-systemd/v22 v22.1.0
 	github.com/cyphar/filepath-securejoin v0.2.2
 	github.com/docker/go-units v0.4.0
@@ -13,14 +13,14 @@ require (
 	github.com/golang/protobuf v1.4.2
 	github.com/moby/sys/mountinfo v0.2.0
 	github.com/mrunalp/fileutils v0.5.0
-	github.com/opencontainers/runtime-spec v1.0.3-0.20200817204227-f9c09b4ea1df
+	github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6
 	github.com/opencontainers/selinux v1.6.0
 	github.com/pkg/errors v0.9.1
 	github.com/seccomp/libseccomp-golang v0.9.1
-	github.com/sirupsen/logrus v1.7.0
+	github.com/sirupsen/logrus v1.6.0
 	github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
 	// NOTE: urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092
 	github.com/urfave/cli v1.22.1
 	github.com/vishvananda/netlink v1.1.0
-	golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f
+	golang.org/x/sys v0.0.0-20200909081042-eff7692f9009
 )
diff --git a/go.sum b/go.sum
index 22308a7b..5931b125 100644
--- a/go.sum
+++ b/go.sum
@@ -3,8 +3,8 @@ github.com/checkpoint-restore/go-criu/v4 v4.1.0 h1:WW2B2uxx9KWF6bGlHqhm8Okiafwwx
 github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
 github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775 h1:cHzBGGVew0ezFsq2grfy2RsB8hO/eNyBgOLHBCqfR1U=
 github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
-github.com/containerd/console v1.0.1 h1:u7SFAJyRqWcG6ogaMAx3KjSTy1e3hT9QxqX7Jco7dRc=
-github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
+github.com/containerd/console v1.0.0 h1:fU3UuQapBs+zLJu82NhR11Rif1ny2zfMMAyPJzSN5tQ=
+github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
 github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg=
 github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
@@ -30,14 +30,17 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/moby/sys/mountinfo v0.2.0 h1:HgYSHMWCj8D7w7TE/cQJfWrY6W3TUxs3pwGFyC5qCvE=
 github.com/moby/sys/mountinfo v0.2.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
 github.com/mrunalp/fileutils v0.5.0 h1:NKzVxiH7eSk+OQ4M+ZYW1K6h27RUV3MI6NUTsHhU6Z4=
 github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
-github.com/opencontainers/runtime-spec v1.0.3-0.20200817204227-f9c09b4ea1df h1:5AW5dMFSXVH4Mg3WYe4z7ui64bK8n66IoWK8i6T4QZ8=
-github.com/opencontainers/runtime-spec v1.0.3-0.20200817204227-f9c09b4ea1df/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
+github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6 h1:NhsM2gc769rVWDqJvapK37r+7+CBXI8xHhnfnt8uQsg=
+github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 github.com/opencontainers/selinux v1.6.0 h1:+bIAS/Za3q5FTwWym4fTB0vObnfCf3G/NC7K6Jx62mY=
 github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -48,8 +51,8 @@ github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46r
 github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
 github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
-github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
-github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
@@ -62,14 +65,13 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7Zo
 github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
 github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243 h1:R43TdZy32XXSXjJn7M/HhALJ9imq6ztLnChfYJpVDnM=
 github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM=
 golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f h1:6Sc1XOXTulBN6imkqo6XoAXDEzoQ4/ro6xy7Vn8+rOM=
-golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
diff --git a/libcontainer/apparmor/apparmor.go b/libcontainer/apparmor/apparmor.go
index 7ae9cf80..a12caaec 100644
--- a/libcontainer/apparmor/apparmor.go
+++ b/libcontainer/apparmor/apparmor.go
@@ -23,7 +23,9 @@ func IsEnabled() bool {
 func setProcAttr(attr, value string) error {
 	// Under AppArmor you can only change your own attr, so use /proc/self/
 	// instead of /proc/<tid>/ like libapparmor does
-	f, err := os.OpenFile("/proc/self/attr/"+attr, os.O_WRONLY, 0)
+	path := fmt.Sprintf("/proc/self/attr/%s", attr)
+
+	f, err := os.OpenFile(path, os.O_WRONLY, 0)
 	if err != nil {
 		return err
 	}
@@ -33,13 +35,14 @@ func setProcAttr(attr, value string) error {
 		return err
 	}
 
-	_, err = f.WriteString(value)
+	_, err = fmt.Fprintf(f, "%s", value)
 	return err
 }
 
 // changeOnExec reimplements aa_change_onexec from libapparmor in Go
 func changeOnExec(name string) error {
-	if err := setProcAttr("exec", "exec "+name); err != nil {
+	value := "exec " + name
+	if err := setProcAttr("exec", value); err != nil {
 		return fmt.Errorf("apparmor failed to apply profile: %s", err)
 	}
 	return nil
diff --git a/libcontainer/capabilities_linux.go b/libcontainer/capabilities_linux.go
index 551f9a80..9daef29e 100644
--- a/libcontainer/capabilities_linux.go
+++ b/libcontainer/capabilities_linux.go
@@ -15,55 +15,78 @@ const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS
 var capabilityMap map[string]capability.Cap
 
 func init() {
-	capabilityMap = make(map[string]capability.Cap, capability.CAP_LAST_CAP+1)
-	for _, c := range capability.List() {
-		if c > capability.CAP_LAST_CAP {
+	capabilityMap = make(map[string]capability.Cap)
+	last := capability.CAP_LAST_CAP
+	// workaround for RHEL6 which has no /proc/sys/kernel/cap_last_cap
+	if last == capability.Cap(63) {
+		last = capability.CAP_BLOCK_SUSPEND
+	}
+	for _, cap := range capability.List() {
+		if cap > last {
 			continue
 		}
-		capabilityMap["CAP_"+strings.ToUpper(c.String())] = c
+		capKey := fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String()))
+		capabilityMap[capKey] = cap
 	}
 }
 
 func newContainerCapList(capConfig *configs.Capabilities) (*containerCapabilities, error) {
-	var (
-		err  error
-		caps containerCapabilities
-	)
-
-	if caps.bounding, err = capSlice(capConfig.Bounding); err != nil {
-		return nil, err
-	}
-	if caps.effective, err = capSlice(capConfig.Effective); err != nil {
-		return nil, err
-	}
-	if caps.inheritable, err = capSlice(capConfig.Inheritable); err != nil {
-		return nil, err
-	}
-	if caps.permitted, err = capSlice(capConfig.Permitted); err != nil {
-		return nil, err
+	bounding := []capability.Cap{}
+	for _, c := range capConfig.Bounding {
+		v, ok := capabilityMap[c]
+		if !ok {
+			return nil, fmt.Errorf("unknown capability %q", c)
+		}
+		bounding = append(bounding, v)
 	}
-	if caps.ambient, err = capSlice(capConfig.Ambient); err != nil {
-		return nil, err
+	effective := []capability.Cap{}
+	for _, c := range capConfig.Effective {
+		v, ok := capabilityMap[c]
+		if !ok {
+			return nil, fmt.Errorf("unknown capability %q", c)
+		}
+		effective = append(effective, v)
 	}
-	if caps.pid, err = capability.NewPid2(0); err != nil {
-		return nil, err
+	inheritable := []capability.Cap{}
+	for _, c := range capConfig.Inheritable {
+		v, ok := capabilityMap[c]
+		if !ok {
+			return nil, fmt.Errorf("unknown capability %q", c)
+		}
+		inheritable = append(inheritable, v)
 	}
-	if err = caps.pid.Load(); err != nil {
-		return nil, err
+	permitted := []capability.Cap{}
+	for _, c := range capConfig.Permitted {
+		v, ok := capabilityMap[c]
+		if !ok {
+			return nil, fmt.Errorf("unknown capability %q", c)
+		}
+		permitted = append(permitted, v)
 	}
-	return &caps, nil
-}
-
-func capSlice(caps []string) ([]capability.Cap, error) {
-	out := make([]capability.Cap, len(caps))
-	for i, c := range caps {
+	ambient := []capability.Cap{}
+	for _, c := range capConfig.Ambient {
 		v, ok := capabilityMap[c]
 		if !ok {
 			return nil, fmt.Errorf("unknown capability %q", c)
 		}
-		out[i] = v
+		ambient = append(ambient, v)
+	}
+	pid, err := capability.NewPid2(0)
+	if err != nil {
+		return nil, err
+	}
+	err = pid.Load()
+	if err != nil {
+		return nil, err
 	}
-	return out, nil
+	return &containerCapabilities{
+		bounding:    bounding,
+		effective:   effective,
+		inheritable: inheritable,
+		permitted:   permitted,
+		ambient:     ambient,
+		pid:         pid,
+	}, nil
 }
 
 type containerCapabilities struct {
diff --git a/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go b/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
index ac77652a..b593eb43 100644
--- a/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
+++ b/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
@@ -7,8 +7,8 @@
 package devicefilter
 
 import (
+	"fmt"
 	"math"
-	"strconv"
 
 	"github.com/cilium/ebpf/asm"
 	"github.com/opencontainers/runc/libcontainer/configs"
@@ -114,11 +114,9 @@ func (p *program) appendDevice(dev *configs.DeviceRule) error {
 	// If the access is rwm, skip the check.
 	hasAccess := bpfAccess != (unix.BPF_DEVCG_ACC_READ | unix.BPF_DEVCG_ACC_WRITE | unix.BPF_DEVCG_ACC_MKNOD)
 
-	var (
-		blockSym         = "block-" + strconv.Itoa(p.blockID)
-		nextBlockSym     = "block-" + strconv.Itoa(p.blockID+1)
-		prevBlockLastIdx = len(p.insts) - 1
-	)
+	blockSym := fmt.Sprintf("block-%d", p.blockID)
+	nextBlockSym := fmt.Sprintf("block-%d", p.blockID+1)
+	prevBlockLastIdx := len(p.insts) - 1
 	if hasType {
 		p.insts = append(p.insts,
 			// if (R2 != bpfType) goto next
@@ -160,7 +158,7 @@ func (p *program) finalize() (asm.Instructions, error) {
 		// acceptBlock with asm.Return() is already inserted
 		return p.insts, nil
 	}
-	blockSym := "block-" + strconv.Itoa(p.blockID)
+	blockSym := fmt.Sprintf("block-%d", p.blockID)
 	p.insts = append(p.insts,
 		// R0 <- 0
 		asm.Mov.Imm32(asm.R0, 0).Sym(blockSym),
diff --git a/libcontainer/cgroups/fs/fs.go b/libcontainer/cgroups/fs/fs.go
index 29690dd6..98e1e342 100644
--- a/libcontainer/cgroups/fs/fs.go
+++ b/libcontainer/cgroups/fs/fs.go
@@ -218,10 +218,7 @@ func (m *manager) Apply(pid int) (err error) {
 	m.mu.Lock()
 	defer m.mu.Unlock()
 
-	c := m.cgroups
-	if c.Resources.Unified != nil {
-		return cgroups.ErrV1NoUnified
-	}
+	var c = m.cgroups
 
 	m.paths = make(map[string]string)
 	if c.Paths != nil {
@@ -312,9 +309,6 @@ func (m *manager) Set(container *configs.Config) error {
 	if m.cgroups != nil && m.cgroups.Paths != nil {
 		return nil
 	}
-	if container.Cgroups.Resources.Unified != nil {
-		return cgroups.ErrV1NoUnified
-	}
 
 	m.mu.Lock()
 	defer m.mu.Unlock()
diff --git a/libcontainer/cgroups/fs2/fs2.go b/libcontainer/cgroups/fs2/fs2.go
index 268a630e..0975064f 100644
--- a/libcontainer/cgroups/fs2/fs2.go
+++ b/libcontainer/cgroups/fs2/fs2.go
@@ -3,14 +3,11 @@
 package fs2
 
 import (
-	"fmt"
 	"io/ioutil"
-	"os"
 	"path/filepath"
 	"strings"
 
 	"github.com/opencontainers/runc/libcontainer/cgroups"
-	"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
 	"github.com/opencontainers/runc/libcontainer/configs"
 	"github.com/pkg/errors"
 )
@@ -209,40 +206,10 @@ func (m *manager) Set(container *configs.Config) error {
 	if err := setFreezer(m.dirPath, container.Cgroups.Freezer); err != nil {
 		return err
 	}
-	if err := m.setUnified(container.Cgroups.Unified); err != nil {
-		return err
-	}
 	m.config = container.Cgroups
 	return nil
 }
 
-func (m *manager) setUnified(res map[string]string) error {
-	for k, v := range res {
-		if strings.Contains(k, "/") {
-			return fmt.Errorf("unified resource %q must be a file name (no slashes)", k)
-		}
-		if err := fscommon.WriteFile(m.dirPath, k, v); err != nil {
-			errC := errors.Cause(err)
-			// Check for both EPERM and ENOENT since O_CREAT is used by WriteFile.
-			if errors.Is(errC, os.ErrPermission) || errors.Is(errC, os.ErrNotExist) {
-				// Check if a controller is available,
-				// to give more specific error if not.
-				sk := strings.SplitN(k, ".", 2)
-				if len(sk) != 2 {
-					return fmt.Errorf("unified resource %q must be in the form CONTROLLER.PARAMETER", k)
-				}
-				c := sk[0]
-				if _, ok := m.controllers[c]; !ok && c != "cgroup" {
-					return fmt.Errorf("unified resource %q can't be set: controller %q not available", k, c)
-				}
-			}
-			return errors.Wrapf(err, "can't set unified resource %q", k)
-		}
-	}
-
-	return nil
-}
-
 func (m *manager) GetPaths() map[string]string {
 	paths := make(map[string]string, 1)
 	paths[""] = m.dirPath
diff --git a/libcontainer/cgroups/fscommon/fscommon.go b/libcontainer/cgroups/fscommon/fscommon.go
index 446b9a1f..46e06dc6 100644
--- a/libcontainer/cgroups/fscommon/fscommon.go
+++ b/libcontainer/cgroups/fscommon/fscommon.go
@@ -21,7 +21,7 @@ func WriteFile(dir, file, data string) error {
 		return err
 	}
 	if err := retryingWriteFile(path, []byte(data), 0700); err != nil {
-		return errors.Wrapf(err, "failed to write %q", data)
+		return errors.Wrapf(err, "failed to write %q to %q", data, path)
 	}
 	return nil
 }
diff --git a/libcontainer/cgroups/systemd/common.go b/libcontainer/cgroups/systemd/common.go
index 41152938..b567f3e1 100644
--- a/libcontainer/cgroups/systemd/common.go
+++ b/libcontainer/cgroups/systemd/common.go
@@ -307,7 +307,7 @@ func newProp(name string, units interface{}) systemdDbus.Property {
 func getUnitName(c *configs.Cgroup) string {
 	// by default, we create a scope unless the user explicitly asks for a slice.
 	if !strings.HasSuffix(c.Name, ".slice") {
-		return c.ScopePrefix + "-" + c.Name + ".scope"
+		return fmt.Sprintf("%s-%s.scope", c.ScopePrefix, c.Name)
 	}
 	return c.Name
 }
@@ -325,9 +325,6 @@ func isUnitExists(err error) bool {
 func startUnit(dbusConnection *systemdDbus.Conn, unitName string, properties []systemdDbus.Property) error {
 	statusChan := make(chan string, 1)
 	if _, err := dbusConnection.StartTransientUnit(unitName, "replace", properties, statusChan); err == nil {
-		timeout := time.NewTimer(30 * time.Second)
-		defer timeout.Stop()
-
 		select {
 		case s := <-statusChan:
 			close(statusChan)
@@ -336,9 +333,8 @@ func startUnit(dbusConnection *systemdDbus.Conn, unitName string, properties []s
 				dbusConnection.ResetFailedUnit(unitName)
 				return errors.Errorf("error creating systemd unit `%s`: got `%s`", unitName, s)
 			}
-		case <-timeout.C:
-			dbusConnection.ResetFailedUnit(unitName)
-			return errors.New("Timeout waiting for systemd to create " + unitName)
+		case <-time.After(time.Second):
+			logrus.Warnf("Timed out while waiting for StartTransientUnit(%s) completion signal from dbus. Continuing...", unitName)
 		}
 	} else if !isUnitExists(err) {
 		return err
diff --git a/libcontainer/cgroups/systemd/v1.go b/libcontainer/cgroups/systemd/v1.go
index eeda18a9..cc2d19cd 100644
--- a/libcontainer/cgroups/systemd/v1.go
+++ b/libcontainer/cgroups/systemd/v1.go
@@ -101,10 +101,6 @@ func (m *legacyManager) Apply(pid int) error {
 		properties []systemdDbus.Property
 	)
 
-	if c.Resources.Unified != nil {
-		return cgroups.ErrV1NoUnified
-	}
-
 	m.mu.Lock()
 	defer m.mu.Unlock()
 	if c.Paths != nil {
@@ -346,9 +342,6 @@ func (m *legacyManager) Set(container *configs.Config) error {
 	if m.cgroups.Paths != nil {
 		return nil
 	}
-	if container.Cgroups.Resources.Unified != nil {
-		return cgroups.ErrV1NoUnified
-	}
 	dbusConnection, err := getDbusConnection(false)
 	if err != nil {
 		return err
diff --git a/libcontainer/cgroups/utils.go b/libcontainer/cgroups/utils.go
index 58cc4e19..bc98375e 100644
--- a/libcontainer/cgroups/utils.go
+++ b/libcontainer/cgroups/utils.go
@@ -15,7 +15,6 @@ import (
 	"sync"
 	"time"
 
-	units "github.com/docker/go-units"
 	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
@@ -30,13 +29,6 @@ var (
 	isUnified     bool
 )
 
-// HugePageSizeUnitList is a list of the units used by the linux kernel when
-// naming the HugePage control files.
-// https://www.kernel.org/doc/Documentation/cgroup-v1/hugetlb.txt
-// TODO Since the kernel only use KB, MB and GB; TB and PB should be removed,
-// depends on https://github.com/docker/go-units/commit/a09cd47f892041a4fac473133d181f5aea6fa393
-var HugePageSizeUnitList = []string{"B", "KB", "MB", "GB", "TB", "PB"}
-
 // IsCgroup2UnifiedMode returns whether we are running in cgroup v2 unified mode.
 func IsCgroup2UnifiedMode() bool {
 	isUnifiedOnce.Do(func() {
@@ -285,27 +277,50 @@ func RemovePaths(paths map[string]string) (err error) {
 }
 
 func GetHugePageSize() ([]string, error) {
-	files, err := ioutil.ReadDir("/sys/kernel/mm/hugepages")
+	dir, err := os.OpenFile("/sys/kernel/mm/hugepages", unix.O_DIRECTORY|unix.O_RDONLY, 0)
 	if err != nil {
-		return []string{}, err
+		return nil, err
 	}
-	var fileNames []string
-	for _, st := range files {
-		fileNames = append(fileNames, st.Name())
+	files, err := dir.Readdirnames(0)
+	dir.Close()
+	if err != nil {
+		return nil, err
 	}
-	return getHugePageSizeFromFilenames(fileNames)
+
+	return getHugePageSizeFromFilenames(files)
 }
 
 func getHugePageSizeFromFilenames(fileNames []string) ([]string, error) {
-	var pageSizes []string
-	for _, fileName := range fileNames {
-		nameArray := strings.Split(fileName, "-")
-		pageSize, err := units.RAMInBytes(nameArray[1])
+	pageSizes := make([]string, 0, len(fileNames))
+
+	for _, file := range fileNames {
+		// example: hugepages-1048576kB
+		val := strings.TrimPrefix(file, "hugepages-")
+		if len(val) == len(file) {
+			// unexpected file name: no prefix found
+			continue
+		}
+		// The suffix is always "kB" (as of Linux 5.9)
+		eLen := len(val) - 2
+		val = strings.TrimSuffix(val, "kB")
+		if len(val) != eLen {
+			logrus.Warnf("GetHugePageSize: %s: invalid filename suffix (expected \"kB\")", file)
+			continue
+		}
+		size, err := strconv.Atoi(val)
 		if err != nil {
-			return []string{}, err
+			return nil, err
+		}
+		// Model after https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/hugetlb_cgroup.c?id=eff48ddeab782e35e58ccc8853f7386bbae9dec4#n574
+		// but in our case the size is in KB already.
+		if size >= (1 << 20) {
+			val = strconv.Itoa(size>>20) + "GB"
+		} else if size >= (1 << 10) {
+			val = strconv.Itoa(size>>10) + "MB"
+		} else {
+			val += "KB"
 		}
-		sizeString := units.CustomSize("%g%s", float64(pageSize), 1024.0, HugePageSizeUnitList)
-		pageSizes = append(pageSizes, sizeString)
+		pageSizes = append(pageSizes, val)
 	}
 
 	return pageSizes, nil
diff --git a/libcontainer/cgroups/v1_utils.go b/libcontainer/cgroups/v1_utils.go
index 8b9275fb..a94f2086 100644
--- a/libcontainer/cgroups/v1_utils.go
+++ b/libcontainer/cgroups/v1_utils.go
@@ -23,8 +23,7 @@ const (
 )
 
 var (
-	errUnified     = errors.New("not implemented for cgroup v2 unified hierarchy")
-	ErrV1NoUnified = errors.New("invalid configuration: cannot use unified on cgroup v1")
+	errUnified = errors.New("not implemented for cgroup v2 unified hierarchy")
 )
 
 type NotFoundError struct {
diff --git a/libcontainer/configs/cgroup_linux.go b/libcontainer/configs/cgroup_linux.go
index dcc29c61..6e90ae16 100644
--- a/libcontainer/configs/cgroup_linux.go
+++ b/libcontainer/configs/cgroup_linux.go
@@ -127,9 +127,6 @@ type Resources struct {
 	// CpuWeight sets a proportional bandwidth limit.
 	CpuWeight uint64 `json:"cpu_weight"`
 
-	// Unified is cgroupv2-only key-value map.
-	Unified map[string]string `json:"unified"`
-
 	// SkipDevices allows to skip configuring device permissions.
 	// Used by e.g. kubelet while creating a parent cgroup (kubepods)
 	// common for many containers.
diff --git a/libcontainer/configs/namespaces_linux.go b/libcontainer/configs/namespaces_linux.go
index d52d6fcd..1bbaef9b 100644
--- a/libcontainer/configs/namespaces_linux.go
+++ b/libcontainer/configs/namespaces_linux.go
@@ -56,7 +56,7 @@ func IsNamespaceSupported(ns NamespaceType) bool {
 	if nsFile == "" {
 		return false
 	}
-	_, err := os.Stat("/proc/self/ns/" + nsFile)
+	_, err := os.Stat(fmt.Sprintf("/proc/self/ns/%s", nsFile))
 	// a namespace is supported if it exists and we have permissions to read it
 	supported = err == nil
 	supportedNamespaces[ns] = supported
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
index 3c4baacb..ee08c17e 100644
--- a/libcontainer/container_linux.go
+++ b/libcontainer/container_linux.go
@@ -14,7 +14,6 @@ import (
 	"os/exec"
 	"path/filepath"
 	"reflect"
-	"strconv"
 	"strings"
 	"sync"
 	"time"
@@ -364,10 +363,24 @@ func (c *linuxContainer) start(process *Process) error {
 	}
 	parent.forwardChildLogs()
 	if err := parent.start(); err != nil {
+		// terminate the process to ensure that it properly is reaped.
+		if err := ignoreTerminateErrors(parent.terminate()); err != nil {
+			logrus.Warn(err)
+		}
 		return newSystemErrorWithCause(err, "starting container process")
 	}
-
+	// generate a timestamp indicating when the container was started
+	c.created = time.Now().UTC()
 	if process.Init {
+		c.state = &createdState{
+			c: c,
+		}
+		state, err := c.updateState(parent)
+		if err != nil {
+			return err
+		}
+		c.initProcessStartTime = state.InitProcessStartTime
+
 		if c.config.Hooks != nil {
 			s, err := c.currentOCIState()
 			if err != nil {
@@ -450,7 +463,7 @@ func (c *linuxContainer) includeExecFifo(cmd *exec.Cmd) error {
 
 	cmd.ExtraFiles = append(cmd.ExtraFiles, os.NewFile(uintptr(fifoFd), fifoName))
 	cmd.Env = append(cmd.Env,
-		"_LIBCONTAINER_FIFOFD="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1))
+		fmt.Sprintf("_LIBCONTAINER_FIFOFD=%d", stdioFdCount+len(cmd.ExtraFiles)-1))
 	return nil
 }
 
@@ -493,24 +506,24 @@ func (c *linuxContainer) commandTemplate(p *Process, childInitPipe *os.File, chi
 	if cmd.SysProcAttr == nil {
 		cmd.SysProcAttr = &unix.SysProcAttr{}
 	}
-	cmd.Env = append(cmd.Env, "GOMAXPROCS="+os.Getenv("GOMAXPROCS"))
+	cmd.Env = append(cmd.Env, fmt.Sprintf("GOMAXPROCS=%s", os.Getenv("GOMAXPROCS")))
 	cmd.ExtraFiles = append(cmd.ExtraFiles, p.ExtraFiles...)
 	if p.ConsoleSocket != nil {
 		cmd.ExtraFiles = append(cmd.ExtraFiles, p.ConsoleSocket)
 		cmd.Env = append(cmd.Env,
-			"_LIBCONTAINER_CONSOLE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1),
+			fmt.Sprintf("_LIBCONTAINER_CONSOLE=%d", stdioFdCount+len(cmd.ExtraFiles)-1),
 		)
 	}
 	cmd.ExtraFiles = append(cmd.ExtraFiles, childInitPipe)
 	cmd.Env = append(cmd.Env,
-		"_LIBCONTAINER_INITPIPE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1),
-		"_LIBCONTAINER_STATEDIR="+c.root,
+		fmt.Sprintf("_LIBCONTAINER_INITPIPE=%d", stdioFdCount+len(cmd.ExtraFiles)-1),
+		fmt.Sprintf("_LIBCONTAINER_STATEDIR=%s", c.root),
 	)
 
 	cmd.ExtraFiles = append(cmd.ExtraFiles, childLogPipe)
 	cmd.Env = append(cmd.Env,
-		"_LIBCONTAINER_LOGPIPE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1),
-		"_LIBCONTAINER_LOGLEVEL="+p.LogLevel,
+		fmt.Sprintf("_LIBCONTAINER_LOGPIPE=%d", stdioFdCount+len(cmd.ExtraFiles)-1),
+		fmt.Sprintf("_LIBCONTAINER_LOGLEVEL=%s", p.LogLevel),
 	)
 
 	// NOTE: when running a container with no PID namespace and the parent process spawning the container is
@@ -2030,7 +2043,7 @@ func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.Na
 		// write oom_score_adj
 		r.AddData(&Bytemsg{
 			Type:  OomScoreAdjAttr,
-			Value: []byte(strconv.Itoa(*c.config.OomScoreAdj)),
+			Value: []byte(fmt.Sprintf("%d", *c.config.OomScoreAdj)),
 		})
 	}
 
@@ -2051,9 +2064,8 @@ func ignoreTerminateErrors(err error) error {
 		return nil
 	}
 	s := err.Error()
-	if strings.Contains(s, "signal: killed") ||
-		strings.Contains(s, "process already finished") ||
-		strings.Contains(s, "Wait was already called") {
+	switch {
+	case strings.Contains(s, "process already finished"), strings.Contains(s, "Wait was already called"):
 		return nil
 	}
 	return err
diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go
index 1402b516..cb8c724a 100644
--- a/libcontainer/process_linux.go
+++ b/libcontainer/process_linux.go
@@ -11,7 +11,6 @@ import (
 	"os/exec"
 	"path/filepath"
 	"strconv"
-	"time"
 
 	"github.com/opencontainers/runc/libcontainer/cgroups"
 	"github.com/opencontainers/runc/libcontainer/cgroups/fs2"
@@ -86,29 +85,21 @@ func (p *setnsProcess) signal(sig os.Signal) error {
 	return unix.Kill(p.pid(), s)
 }
 
-func (p *setnsProcess) start() (retErr error) {
+func (p *setnsProcess) start() (err error) {
 	defer p.messageSockPair.parent.Close()
-	err := p.cmd.Start()
+	err = p.cmd.Start()
 	// close the write-side of the pipes (controlled by child)
 	p.messageSockPair.child.Close()
 	p.logFilePair.child.Close()
 	if err != nil {
 		return newSystemErrorWithCause(err, "starting setns process")
 	}
-	defer func() {
-		if retErr != nil {
-			err := ignoreTerminateErrors(p.terminate())
-			if err != nil {
-				logrus.WithError(err).Warn("unable to terminate setnsProcess")
-			}
-		}
-	}()
 	if p.bootstrapData != nil {
 		if _, err := io.Copy(p.messageSockPair.parent, p.bootstrapData); err != nil {
 			return newSystemErrorWithCause(err, "copying bootstrap data to pipe")
 		}
 	}
-	if err := p.execSetns(); err != nil {
+	if err = p.execSetns(); err != nil {
 		return newSystemErrorWithCause(err, "executing setns process")
 	}
 	if len(p.cgroupPaths) > 0 {
@@ -321,11 +312,6 @@ func (p *initProcess) start() (retErr error) {
 	}
 	defer func() {
 		if retErr != nil {
-			// terminate the process to ensure we can remove cgroups
-			if err := ignoreTerminateErrors(p.terminate()); err != nil {
-				logrus.WithError(err).Warn("unable to terminate initProcess")
-			}
-
 			p.manager.Destroy()
 			if p.intelRdtManager != nil {
 				p.intelRdtManager.Destroy()
@@ -425,28 +411,6 @@ func (p *initProcess) start() (retErr error) {
 					}
 				}
 			}
-
-			// generate a timestamp indicating when the container was started
-			p.container.created = time.Now().UTC()
-			p.container.state = &createdState{
-				c: p.container,
-			}
-
-			// NOTE: If the procRun state has been synced and the
-			// runc-create process has been killed for some reason,
-			// the runc-init[2:stage] process will be leaky. And
-			// the runc command also fails to parse root directory
-			// because the container doesn't have state.json.
-			//
-			// In order to cleanup the runc-init[2:stage] by
-			// runc-delete/stop, we should store the status before
-			// procRun sync.
-			state, uerr := p.container.updateState(p)
-			if uerr != nil {
-				return newSystemErrorWithCause(err, "store init state")
-			}
-			p.container.initProcessStartTime = state.InitProcessStartTime
-
 			// Sync with child.
 			if err := writeSync(p.messageSockPair.parent, procRun); err != nil {
 				return newSystemErrorWithCause(err, "writing syncT 'run'")
diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go
index 6b1e9a6e..0b9cd885 100644
--- a/libcontainer/setns_init_linux.go
+++ b/libcontainer/setns_init_linux.go
@@ -3,6 +3,7 @@
 package libcontainer
 
 import (
+	"fmt"
 	"os"
 	"runtime"
 
@@ -24,7 +25,7 @@ type linuxSetnsInit struct {
 }
 
 func (l *linuxSetnsInit) getSessionRingName() string {
-	return "_ses." + l.config.ContainerId
+	return fmt.Sprintf("_ses.%s", l.config.ContainerId)
 }
 
 func (l *linuxSetnsInit) Init() error {
diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go
index 141fe84f..11235acc 100644
--- a/libcontainer/specconv/spec_linux.go
+++ b/libcontainer/specconv/spec_linux.go
@@ -224,14 +224,14 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
 	}
 	labels := []string{}
 	for k, v := range spec.Annotations {
-		labels = append(labels, k+"="+v)
+		labels = append(labels, fmt.Sprintf("%s=%s", k, v))
 	}
 	config := &configs.Config{
 		Rootfs:          rootfsPath,
 		NoPivotRoot:     opts.NoPivotRoot,
 		Readonlyfs:      spec.Root.Readonly,
 		Hostname:        spec.Hostname,
-		Labels:          append(labels, "bundle="+cwd),
+		Labels:          append(labels, fmt.Sprintf("bundle=%s", cwd)),
 		NoNewKeyring:    opts.NoNewKeyring,
 		RootlessEUID:    opts.RootlessEUID,
 		RootlessCgroups: opts.RootlessCgroups,
@@ -619,13 +619,6 @@ func CreateCgroupConfig(opts *CreateOpts, defaultDevs []*configs.Device) (*confi
 					})
 				}
 			}
-			if len(r.Unified) > 0 {
-				// copy the map
-				c.Resources.Unified = make(map[string]string, len(r.Unified))
-				for k, v := range r.Unified {
-					c.Resources.Unified[k] = v
-				}
-			}
 		}
 	}
 
diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go
index 7ec506c4..b20ce148 100644
--- a/libcontainer/standard_init_linux.go
+++ b/libcontainer/standard_init_linux.go
@@ -3,10 +3,10 @@
 package libcontainer
 
 import (
+	"fmt"
 	"os"
 	"os/exec"
 	"runtime"
-	"strconv"
 
 	"github.com/opencontainers/runc/libcontainer/apparmor"
 	"github.com/opencontainers/runc/libcontainer/configs"
@@ -40,7 +40,7 @@ func (l *linuxStandardInit) getSessionRingParams() (string, uint32, uint32) {
 
 	// Create a unique per session container name that we can join in setns;
 	// However, other containers can also join it.
-	return "_ses." + l.config.ContainerId, 0xffffffff, newperms
+	return fmt.Sprintf("_ses.%s", l.config.ContainerId), 0xffffffff, newperms
 }
 
 func (l *linuxStandardInit) Init() error {
@@ -185,7 +185,7 @@ func (l *linuxStandardInit) Init() error {
 	// user process. We open it through /proc/self/fd/$fd, because the fd that
 	// was given to us was an O_PATH fd to the fifo itself. Linux allows us to
 	// re-open an O_PATH fd through /proc.
-	fd, err := unix.Open("/proc/self/fd/"+strconv.Itoa(l.fifoFd), unix.O_WRONLY|unix.O_CLOEXEC, 0)
+	fd, err := unix.Open(fmt.Sprintf("/proc/self/fd/%d", l.fifoFd), unix.O_WRONLY|unix.O_CLOEXEC, 0)
 	if err != nil {
 		return newSystemErrorWithCause(err, "open exec fifo")
 	}
diff --git a/libcontainer/system/proc.go b/libcontainer/system/proc.go
index 0dbff54d..79232a43 100644
--- a/libcontainer/system/proc.go
+++ b/libcontainer/system/proc.go
@@ -78,7 +78,7 @@ func GetProcessStartTime(pid int) (string, error) {
 	if err != nil {
 		return "", err
 	}
-	return strconv.FormatUint(stat.StartTime, 10), nil
+	return fmt.Sprintf("%d", stat.StartTime), nil
 }
 
 func parseStat(data string) (stat Stat_t, err error) {
diff --git a/libcontainer/user/lookup_windows.go b/libcontainer/user/lookup_windows.go
index f19333e6..65cd40e9 100644
--- a/libcontainer/user/lookup_windows.go
+++ b/libcontainer/user/lookup_windows.go
@@ -3,8 +3,8 @@
 package user
 
 import (
+	"fmt"
 	"os/user"
-	"strconv"
 )
 
 func lookupUser(username string) (User, error) {
@@ -16,7 +16,7 @@ func lookupUser(username string) (User, error) {
 }
 
 func lookupUid(uid int) (User, error) {
-	u, err := user.LookupId(strconv.Itoa(uid))
+	u, err := user.LookupId(fmt.Sprintf("%d", uid))
 	if err != nil {
 		return User{}, err
 	}
@@ -32,7 +32,7 @@ func lookupGroup(groupname string) (Group, error) {
 }
 
 func lookupGid(gid int) (Group, error) {
-	g, err := user.LookupGroupId(strconv.Itoa(gid))
+	g, err := user.LookupGroupId(fmt.Sprintf("%d", gid))
 	if err != nil {
 		return Group{}, err
 	}
diff --git a/main.go b/main.go
index 3c4a5821..642f7a4f 100644
--- a/main.go
+++ b/main.go
@@ -60,10 +60,10 @@ func main() {
 		v = append(v, version)
 	}
 	if gitCommit != "" {
-		v = append(v, "commit: "+gitCommit)
+		v = append(v, fmt.Sprintf("commit: %s", gitCommit))
 	}
-	v = append(v, "spec: "+specs.Version)
-	v = append(v, "go: "+runtime.Version())
+	v = append(v, fmt.Sprintf("spec: %s", specs.Version))
+	v = append(v, fmt.Sprintf("go: %s", runtime.Version()))
 	if seccomp.IsEnabled() {
 		major, minor, micro := seccomp.Version()
 		v = append(v, fmt.Sprintf("libseccomp: %d.%d.%d", major, minor, micro))
diff --git a/notify_socket.go b/notify_socket.go
index 29f0d926..f313a7a6 100644
--- a/notify_socket.go
+++ b/notify_socket.go
@@ -4,6 +4,7 @@ package main
 
 import (
 	"bytes"
+	"fmt"
 	"net"
 	"os"
 	"path"
@@ -53,7 +54,7 @@ func (s *notifySocket) setupSpec(context *cli.Context, spec *specs.Spec) error {
 		Options:     []string{"bind", "nosuid", "noexec", "nodev", "ro"},
 	}
 	spec.Mounts = append(spec.Mounts, mount)
-	spec.Process.Env = append(spec.Process.Env, "NOTIFY_SOCKET="+pathInContainer)
+	spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", pathInContainer))
 	return nil
 }
 
@@ -161,8 +162,8 @@ func (n *notifySocket) run(pid1 int) error {
 			}
 
 			// now we can inform systemd to use pid1 as the pid to monitor
-			newPid := "MAINPID=" + strconv.Itoa(pid1)
-			client.Write([]byte(newPid + "\n"))
+			newPid := fmt.Sprintf("MAINPID=%d\n", pid1)
+			client.Write([]byte(newPid))
 			return nil
 		}
 	}
diff --git a/utils_linux.go b/utils_linux.go
index fe9f25ae..c24ee8d6 100644
--- a/utils_linux.go
+++ b/utils_linux.go
@@ -214,13 +214,13 @@ func createPidFile(path string, process *libcontainer.Process) error {
 	}
 	var (
 		tmpDir  = filepath.Dir(path)
-		tmpName = filepath.Join(tmpDir, "."+filepath.Base(path))
+		tmpName = filepath.Join(tmpDir, fmt.Sprintf(".%s", filepath.Base(path)))
 	)
 	f, err := os.OpenFile(tmpName, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0666)
 	if err != nil {
 		return err
 	}
-	_, err = f.WriteString(strconv.Itoa(pid))
+	_, err = fmt.Fprintf(f, "%d", pid)
 	f.Close()
 	if err != nil {
 		return err
@@ -284,12 +284,12 @@ func (r *runner) run(config *specs.Process) (int, error) {
 		return -1, err
 	}
 	if len(r.listenFDs) > 0 {
-		process.Env = append(process.Env, "LISTEN_FDS="+strconv.Itoa(len(r.listenFDs)), "LISTEN_PID=1")
+		process.Env = append(process.Env, fmt.Sprintf("LISTEN_FDS=%d", len(r.listenFDs)), "LISTEN_PID=1")
 		process.ExtraFiles = append(process.ExtraFiles, r.listenFDs...)
 	}
 	baseFd := 3 + len(process.ExtraFiles)
 	for i := baseFd; i < baseFd+r.preserveFDs; i++ {
-		_, err = os.Stat("/proc/self/fd/" + strconv.Itoa(i))
+		_, err = os.Stat(fmt.Sprintf("/proc/self/fd/%d", i))
 		if err != nil {
 			return -1, errors.Wrapf(err, "please check that preserved-fd %d (of %d) is present", i-baseFd, r.preserveFDs)
 		}
diff --git a/vendor/github.com/containerd/console/.golangci.yml b/vendor/github.com/containerd/console/.golangci.yml
deleted file mode 100644
index fcba5e88..00000000
--- a/vendor/github.com/containerd/console/.golangci.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-linters:
-  enable:
-    - structcheck
-    - varcheck
-    - staticcheck
-    - unconvert
-    - gofmt
-    - goimports
-    - golint
-    - ineffassign
-    - vet
-    - unused
-    - misspell
-  disable:
-    - errcheck
-
-run:
-  timeout: 3m
-  skip-dirs:
-    - vendor
diff --git a/vendor/github.com/containerd/console/.travis.yml b/vendor/github.com/containerd/console/.travis.yml
new file mode 100644
index 00000000..16827ec3
--- /dev/null
+++ b/vendor/github.com/containerd/console/.travis.yml
@@ -0,0 +1,27 @@
+language: go
+go:
+  - "1.12.x"
+  - "1.13.x"
+
+go_import_path: github.com/containerd/console
+
+env:
+  - GO111MODULE=on
+
+install:
+  - pushd ..; go get -u github.com/vbatts/git-validation; popd
+  - pushd ..; go get -u github.com/kunalkushwaha/ltag; popd
+
+before_script:
+  - pushd ..; git clone https://github.com/containerd/project; popd
+
+script:
+  - DCO_VERBOSITY=-q ../project/script/validate/dco
+  - ../project/script/validate/fileheader ../project/
+  - travis_wait ../project/script/validate/vendor
+  - go test -race
+  - GOOS=openbsd go build
+  - GOOS=openbsd go test -c
+  - GOOS=solaris go build
+  - GOOS=solaris go test -c
+  - GOOS=windows go test
diff --git a/vendor/github.com/containerd/console/console.go b/vendor/github.com/containerd/console/console.go
index f989d28a..6a36d147 100644
--- a/vendor/github.com/containerd/console/console.go
+++ b/vendor/github.com/containerd/console/console.go
@@ -61,24 +61,18 @@ type WinSize struct {
 	y     uint16
 }
 
-// Current returns the current process' console
-func Current() (c Console) {
-	var err error
-	// Usually all three streams (stdin, stdout, and stderr)
-	// are open to the same console, but some might be redirected,
-	// so try all three.
-	for _, s := range []*os.File{os.Stderr, os.Stdout, os.Stdin} {
-		if c, err = ConsoleFromFile(s); err == nil {
-			return c
-		}
+// Current returns the current processes console
+func Current() Console {
+	c, err := ConsoleFromFile(os.Stdin)
+	if err != nil {
+		// stdin should always be a console for the design
+		// of this function
+		panic(err)
 	}
-	// One of the std streams should always be a console
-	// for the design of this function.
-	panic(err)
+	return c
 }
 
 // ConsoleFromFile returns a console using the provided file
-// nolint:golint
 func ConsoleFromFile(f File) (Console, error) {
 	if err := checkConsole(f); err != nil {
 		return nil, err
diff --git a/vendor/github.com/containerd/console/console_unix.go b/vendor/github.com/containerd/console/console_unix.go
index a7868752..315f1d0c 100644
--- a/vendor/github.com/containerd/console/console_unix.go
+++ b/vendor/github.com/containerd/console/console_unix.go
@@ -1,4 +1,4 @@
-// +build darwin freebsd linux netbsd openbsd solaris
+// +build darwin freebsd linux openbsd solaris
 
 /*
    Copyright The containerd Authors.
diff --git a/vendor/github.com/containerd/console/go.mod b/vendor/github.com/containerd/console/go.mod
index 60bf028e..97b587d6 100644
--- a/vendor/github.com/containerd/console/go.mod
+++ b/vendor/github.com/containerd/console/go.mod
@@ -3,6 +3,6 @@ module github.com/containerd/console
 go 1.13
 
 require (
-	github.com/pkg/errors v0.9.1
-	golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f
+	github.com/pkg/errors v0.8.1
+	golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e
 )
diff --git a/vendor/github.com/containerd/console/go.sum b/vendor/github.com/containerd/console/go.sum
index 6b9363c4..25205cc9 100644
--- a/vendor/github.com/containerd/console/go.sum
+++ b/vendor/github.com/containerd/console/go.sum
@@ -1,4 +1,4 @@
-github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
-github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f h1:6Sc1XOXTulBN6imkqo6XoAXDEzoQ4/ro6xy7Vn8+rOM=
-golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/vendor/github.com/containerd/console/tc_darwin.go b/vendor/github.com/containerd/console/tc_darwin.go
index 78715458..b0128abb 100644
--- a/vendor/github.com/containerd/console/tc_darwin.go
+++ b/vendor/github.com/containerd/console/tc_darwin.go
@@ -19,6 +19,7 @@ package console
 import (
 	"fmt"
 	"os"
+	"unsafe"
 
 	"golang.org/x/sys/unix"
 )
@@ -28,10 +29,18 @@ const (
 	cmdTcSet = unix.TIOCSETA
 )
 
+func ioctl(fd, flag, data uintptr) error {
+	if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, flag, data); err != 0 {
+		return err
+	}
+	return nil
+}
+
 // unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
 // unlockpt should be called before opening the slave side of a pty.
 func unlockpt(f *os.File) error {
-	return unix.IoctlSetPointerInt(int(f.Fd()), unix.TIOCPTYUNLK, 0)
+	var u int32
+	return ioctl(f.Fd(), unix.TIOCPTYUNLK, uintptr(unsafe.Pointer(&u)))
 }
 
 // ptsname retrieves the name of the first available pts for the given master.
diff --git a/vendor/github.com/containerd/console/tc_linux.go b/vendor/github.com/containerd/console/tc_linux.go
index 75f8694f..1bdd68e6 100644
--- a/vendor/github.com/containerd/console/tc_linux.go
+++ b/vendor/github.com/containerd/console/tc_linux.go
@@ -19,6 +19,7 @@ package console
 import (
 	"fmt"
 	"os"
+	"unsafe"
 
 	"golang.org/x/sys/unix"
 )
@@ -31,13 +32,17 @@ const (
 // unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
 // unlockpt should be called before opening the slave side of a pty.
 func unlockpt(f *os.File) error {
-	return unix.IoctlSetPointerInt(int(f.Fd()), unix.TIOCSPTLCK, 0)
+	var u int32
+	if _, _, err := unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))); err != 0 {
+		return err
+	}
+	return nil
 }
 
 // ptsname retrieves the name of the first available pts for the given master.
 func ptsname(f *os.File) (string, error) {
-	u, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCGPTN)
-	if err != nil {
+	var u uint32
+	if _, _, err := unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.TIOCGPTN, uintptr(unsafe.Pointer(&u))); err != 0 {
 		return "", err
 	}
 	return fmt.Sprintf("/dev/pts/%d", u), nil
diff --git a/vendor/github.com/containerd/console/tc_netbsd.go b/vendor/github.com/containerd/console/tc_netbsd.go
deleted file mode 100644
index 71227aef..00000000
--- a/vendor/github.com/containerd/console/tc_netbsd.go
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-   Copyright The containerd Authors.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-*/
-
-package console
-
-import (
-	"bytes"
-	"os"
-
-	"golang.org/x/sys/unix"
-)
-
-const (
-	cmdTcGet = unix.TIOCGETA
-	cmdTcSet = unix.TIOCSETA
-)
-
-// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
-// unlockpt should be called before opening the slave side of a pty.
-// This does not exist on NetBSD, it does not allocate controlling terminals on open
-func unlockpt(f *os.File) error {
-	return nil
-}
-
-// ptsname retrieves the name of the first available pts for the given master.
-func ptsname(f *os.File) (string, error) {
-	ptm, err := unix.IoctlGetPtmget(int(f.Fd()), unix.TIOCPTSNAME)
-	if err != nil {
-		return "", err
-	}
-	return string(ptm.Sn[:bytes.IndexByte(ptm.Sn[:], 0)]), nil
-}
diff --git a/vendor/github.com/containerd/console/tc_unix.go b/vendor/github.com/containerd/console/tc_unix.go
index 5cd4c550..7ae773c5 100644
--- a/vendor/github.com/containerd/console/tc_unix.go
+++ b/vendor/github.com/containerd/console/tc_unix.go
@@ -1,4 +1,4 @@
-// +build darwin freebsd linux netbsd openbsd solaris
+// +build darwin freebsd linux openbsd solaris
 
 /*
    Copyright The containerd Authors.
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE b/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE
new file mode 100644
index 00000000..14127cd8
--- /dev/null
+++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE
@@ -0,0 +1,9 @@
+(The MIT License)
+
+Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md b/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md
new file mode 100644
index 00000000..09a4a35c
--- /dev/null
+++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md
@@ -0,0 +1,42 @@
+# Windows Terminal Sequences
+
+This library allow for enabling Windows terminal color support for Go.
+
+See [Console Virtual Terminal Sequences](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) for details.
+
+## Usage
+
+```go
+import (
+	"syscall"
+	
+	sequences "github.com/konsorten/go-windows-terminal-sequences"
+)
+
+func main() {
+	sequences.EnableVirtualTerminalProcessing(syscall.Stdout, true)
+}
+
+```
+
+## Authors
+
+The tool is sponsored by the [marvin + konsorten GmbH](http://www.konsorten.de).
+
+We thank all the authors who provided code to this library:
+
+* Felix Kollmann
+* Nicolas Perraut
+* @dirty49374
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2018 marvin + konsorten GmbH (open-source@konsorten.de)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod b/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod
new file mode 100644
index 00000000..716c6131
--- /dev/null
+++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod
@@ -0,0 +1,1 @@
+module github.com/konsorten/go-windows-terminal-sequences
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go
new file mode 100644
index 00000000..57f530ae
--- /dev/null
+++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go
@@ -0,0 +1,35 @@
+// +build windows
+
+package sequences
+
+import (
+	"syscall"
+)
+
+var (
+	kernel32Dll    *syscall.LazyDLL  = syscall.NewLazyDLL("Kernel32.dll")
+	setConsoleMode *syscall.LazyProc = kernel32Dll.NewProc("SetConsoleMode")
+)
+
+func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error {
+	const ENABLE_VIRTUAL_TERMINAL_PROCESSING uint32 = 0x4
+
+	var mode uint32
+	err := syscall.GetConsoleMode(syscall.Stdout, &mode)
+	if err != nil {
+		return err
+	}
+
+	if enable {
+		mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING
+	} else {
+		mode &^= ENABLE_VIRTUAL_TERMINAL_PROCESSING
+	}
+
+	ret, _, err := setConsoleMode.Call(uintptr(stream), uintptr(mode))
+	if ret == 0 {
+		return err
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go
new file mode 100644
index 00000000..df61a6f2
--- /dev/null
+++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go
@@ -0,0 +1,11 @@
+// +build linux darwin
+
+package sequences
+
+import (
+	"fmt"
+)
+
+func EnableVirtualTerminalProcessing(stream uintptr, enable bool) error {
+	return fmt.Errorf("windows only package")
+}
diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
index 5fceeb63..3dc9efd2 100644
--- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
@@ -60,7 +60,7 @@ type Process struct {
 	SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"`
 }
 
-// LinuxCapabilities specifies the list of allowed capabilities that are kept for a process.
+// LinuxCapabilities specifies the whitelist of capabilities that are kept for a process.
 // http://man7.org/linux/man-pages/man7/capabilities.7.html
 type LinuxCapabilities struct {
 	// Bounding is the set of capabilities checked by the kernel.
@@ -354,7 +354,7 @@ type LinuxRdma struct {
 
 // LinuxResources has container runtime resource constraints
 type LinuxResources struct {
-	// Devices configures the device allowlist.
+	// Devices configures the device whitelist.
 	Devices []LinuxDeviceCgroup `json:"devices,omitempty"`
 	// Memory restriction configuration
 	Memory *LinuxMemory `json:"memory,omitempty"`
@@ -372,8 +372,6 @@ type LinuxResources struct {
 	// Limits are a set of key value pairs that define RDMA resource limits,
 	// where the key is device name and value is resource limits.
 	Rdma map[string]LinuxRdma `json:"rdma,omitempty"`
-	// Unified resources.
-	Unified map[string]string `json:"unified,omitempty"`
 }
 
 // LinuxDevice represents the mknod information for a Linux special device file
@@ -394,8 +392,7 @@ type LinuxDevice struct {
 	GID *uint32 `json:"gid,omitempty"`
 }
 
-// LinuxDeviceCgroup represents a device rule for the devices specified to
-// the device controller
+// LinuxDeviceCgroup represents a device rule for the whitelist controller
 type LinuxDeviceCgroup struct {
 	// Allow or deny
 	Allow bool `json:"allow"`
@@ -631,7 +628,6 @@ const (
 	ArchS390X       Arch = "SCMP_ARCH_S390X"
 	ArchPARISC      Arch = "SCMP_ARCH_PARISC"
 	ArchPARISC64    Arch = "SCMP_ARCH_PARISC64"
-	ArchRISCV64     Arch = "SCMP_ARCH_RISCV64"
 )
 
 // LinuxSeccompAction taken upon Seccomp rule match
diff --git a/vendor/github.com/sirupsen/logrus/.gitignore b/vendor/github.com/sirupsen/logrus/.gitignore
index 1fb13abe..6b7d7d1e 100644
--- a/vendor/github.com/sirupsen/logrus/.gitignore
+++ b/vendor/github.com/sirupsen/logrus/.gitignore
@@ -1,4 +1,2 @@
 logrus
 vendor
-
-.idea/
diff --git a/vendor/github.com/sirupsen/logrus/buffer_pool.go b/vendor/github.com/sirupsen/logrus/buffer_pool.go
deleted file mode 100644
index 4545dec0..00000000
--- a/vendor/github.com/sirupsen/logrus/buffer_pool.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package logrus
-
-import (
-	"bytes"
-	"sync"
-)
-
-var (
-	bufferPool BufferPool
-)
-
-type BufferPool interface {
-	Put(*bytes.Buffer)
-	Get() *bytes.Buffer
-}
-
-type defaultPool struct {
-	pool *sync.Pool
-}
-
-func (p *defaultPool) Put(buf *bytes.Buffer) {
-	p.pool.Put(buf)
-}
-
-func (p *defaultPool) Get() *bytes.Buffer {
-	return p.pool.Get().(*bytes.Buffer)
-}
-
-func getBuffer() *bytes.Buffer {
-	return bufferPool.Get()
-}
-
-func putBuffer(buf *bytes.Buffer) {
-	buf.Reset()
-	bufferPool.Put(buf)
-}
-
-// SetBufferPool allows to replace the default logrus buffer pool
-// to better meets the specific needs of an application.
-func SetBufferPool(bp BufferPool) {
-	bufferPool = bp
-}
-
-func init() {
-	SetBufferPool(&defaultPool{
-		pool: &sync.Pool{
-			New: func() interface{} {
-				return new(bytes.Buffer)
-			},
-		},
-	})
-}
diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go
index 5a5cbfe7..f6e062a3 100644
--- a/vendor/github.com/sirupsen/logrus/entry.go
+++ b/vendor/github.com/sirupsen/logrus/entry.go
@@ -13,6 +13,7 @@ import (
 )
 
 var (
+	bufferPool *sync.Pool
 
 	// qualified package name, cached at first use
 	logrusPackage string
@@ -30,6 +31,12 @@ const (
 )
 
 func init() {
+	bufferPool = &sync.Pool{
+		New: func() interface{} {
+			return new(bytes.Buffer)
+		},
+	}
+
 	// start at the bottom of the stack before the package-name cache is primed
 	minimumCallerDepth = 1
 }
@@ -236,12 +243,9 @@ func (entry Entry) log(level Level, msg string) {
 
 	entry.fireHooks()
 
-	buffer = getBuffer()
-	defer func() {
-		entry.Buffer = nil
-		putBuffer(buffer)
-	}()
+	buffer = bufferPool.Get().(*bytes.Buffer)
 	buffer.Reset()
+	defer bufferPool.Put(buffer)
 	entry.Buffer = buffer
 
 	entry.write()
diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go
index 017c30ce..42b04f6c 100644
--- a/vendor/github.com/sirupsen/logrus/exported.go
+++ b/vendor/github.com/sirupsen/logrus/exported.go
@@ -134,51 +134,6 @@ func Fatal(args ...interface{}) {
 	std.Fatal(args...)
 }
 
-// TraceFn logs a message from a func at level Trace on the standard logger.
-func TraceFn(fn LogFunction) {
-	std.TraceFn(fn)
-}
-
-// DebugFn logs a message from a func at level Debug on the standard logger.
-func DebugFn(fn LogFunction) {
-	std.DebugFn(fn)
-}
-
-// PrintFn logs a message from a func at level Info on the standard logger.
-func PrintFn(fn LogFunction) {
-	std.PrintFn(fn)
-}
-
-// InfoFn logs a message from a func at level Info on the standard logger.
-func InfoFn(fn LogFunction) {
-	std.InfoFn(fn)
-}
-
-// WarnFn logs a message from a func at level Warn on the standard logger.
-func WarnFn(fn LogFunction) {
-	std.WarnFn(fn)
-}
-
-// WarningFn logs a message from a func at level Warn on the standard logger.
-func WarningFn(fn LogFunction) {
-	std.WarningFn(fn)
-}
-
-// ErrorFn logs a message from a func at level Error on the standard logger.
-func ErrorFn(fn LogFunction) {
-	std.ErrorFn(fn)
-}
-
-// PanicFn logs a message from a func at level Panic on the standard logger.
-func PanicFn(fn LogFunction) {
-	std.PanicFn(fn)
-}
-
-// FatalFn logs a message from a func at level Fatal on the standard logger then the process will exit with status set to 1.
-func FatalFn(fn LogFunction) {
-	std.FatalFn(fn)
-}
-
 // Tracef logs a message at level Trace on the standard logger.
 func Tracef(format string, args ...interface{}) {
 	std.Tracef(format, args...)
diff --git a/vendor/github.com/sirupsen/logrus/go.mod b/vendor/github.com/sirupsen/logrus/go.mod
index b3919d5e..d4132967 100644
--- a/vendor/github.com/sirupsen/logrus/go.mod
+++ b/vendor/github.com/sirupsen/logrus/go.mod
@@ -2,9 +2,10 @@ module github.com/sirupsen/logrus
 
 require (
 	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/konsorten/go-windows-terminal-sequences v1.0.3
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/stretchr/testify v1.2.2
-	golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
+	golang.org/x/sys v0.0.0-20190422165155-953cdadca894
 )
 
 go 1.13
diff --git a/vendor/github.com/sirupsen/logrus/go.sum b/vendor/github.com/sirupsen/logrus/go.sum
index 1edc143b..49c690f2 100644
--- a/vendor/github.com/sirupsen/logrus/go.sum
+++ b/vendor/github.com/sirupsen/logrus/go.sum
@@ -1,10 +1,12 @@
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go
index dbf627c9..6fdda748 100644
--- a/vendor/github.com/sirupsen/logrus/logger.go
+++ b/vendor/github.com/sirupsen/logrus/logger.go
@@ -9,11 +9,6 @@ import (
 	"time"
 )
 
-// LogFunction For big messages, it can be more efficient to pass a function
-// and only call it if the log level is actually enables rather than
-// generating the log message and then checking if the level is enabled
-type LogFunction func()[]interface{}
-
 type Logger struct {
 	// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
 	// file, or leave it default which is `os.Stderr`. You can also set this to
@@ -75,7 +70,7 @@ func (mw *MutexWrap) Disable() {
 //
 //    var log = &logrus.Logger{
 //      Out: os.Stderr,
-//      Formatter: new(logrus.TextFormatter),
+//      Formatter: new(logrus.JSONFormatter),
 //      Hooks: make(logrus.LevelHooks),
 //      Level: logrus.DebugLevel,
 //    }
@@ -200,14 +195,6 @@ func (logger *Logger) Log(level Level, args ...interface{}) {
 	}
 }
 
-func (logger *Logger) LogFn(level Level, fn LogFunction) {
-	if logger.IsLevelEnabled(level) {
-		entry := logger.newEntry()
-		entry.Log(level, fn()...)
-		logger.releaseEntry(entry)
-	}
-}
-
 func (logger *Logger) Trace(args ...interface{}) {
 	logger.Log(TraceLevel, args...)
 }
@@ -247,45 +234,6 @@ func (logger *Logger) Panic(args ...interface{}) {
 	logger.Log(PanicLevel, args...)
 }
 
-func (logger *Logger) TraceFn(fn LogFunction) {
-	logger.LogFn(TraceLevel, fn)
-}
-
-func (logger *Logger) DebugFn(fn LogFunction) {
-	logger.LogFn(DebugLevel, fn)
-}
-
-func (logger *Logger) InfoFn(fn LogFunction) {
-	logger.LogFn(InfoLevel, fn)
-}
-
-func (logger *Logger) PrintFn(fn LogFunction) {
-	entry := logger.newEntry()
-	entry.Print(fn()...)
-	logger.releaseEntry(entry)
-}
-
-func (logger *Logger) WarnFn(fn LogFunction) {
-	logger.LogFn(WarnLevel, fn)
-}
-
-func (logger *Logger) WarningFn(fn LogFunction) {
-	logger.WarnFn(fn)
-}
-
-func (logger *Logger) ErrorFn(fn LogFunction) {
-	logger.LogFn(ErrorLevel, fn)
-}
-
-func (logger *Logger) FatalFn(fn LogFunction) {
-	logger.LogFn(FatalLevel, fn)
-	logger.Exit(1)
-}
-
-func (logger *Logger) PanicFn(fn LogFunction) {
-	logger.LogFn(PanicLevel, fn)
-}
-
 func (logger *Logger) Logln(level Level, args ...interface{}) {
 	if logger.IsLevelEnabled(level) {
 		entry := logger.newEntry()
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go
index 2879eb50..572889db 100644
--- a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go
@@ -5,23 +5,30 @@ package logrus
 import (
 	"io"
 	"os"
+	"syscall"
 
-	"golang.org/x/sys/windows"
+	sequences "github.com/konsorten/go-windows-terminal-sequences"
 )
 
+func initTerminal(w io.Writer) {
+	switch v := w.(type) {
+	case *os.File:
+		sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true)
+	}
+}
+
 func checkIfTerminal(w io.Writer) bool {
+	var ret bool
 	switch v := w.(type) {
 	case *os.File:
-		handle := windows.Handle(v.Fd())
 		var mode uint32
-		if err := windows.GetConsoleMode(handle, &mode); err != nil {
-			return false
-		}
-		mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
-		if err := windows.SetConsoleMode(handle, mode); err != nil {
-			return false
-		}
-		return true
+		err := syscall.GetConsoleMode(syscall.Handle(v.Fd()), &mode)
+		ret = (err == nil)
+	default:
+		ret = false
+	}
+	if ret {
+		initTerminal(w)
 	}
-	return false
+	return ret
 }
diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go
index eddcf3a9..e2a05eed 100644
--- a/vendor/golang.org/x/sys/unix/syscall_darwin.go
+++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go
@@ -401,8 +401,6 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
 //sys	Chroot(path string) (err error)
 //sys	ClockGettime(clockid int32, time *Timespec) (err error)
 //sys	Close(fd int) (err error)
-//sys	Clonefile(src string, dst string, flags int) (err error)
-//sys	Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error)
 //sys	Dup(fd int) (nfd int, err error)
 //sys	Dup2(from int, to int) (err error)
 //sys	Exchangedata(path1 string, path2 string, options int) (err error)
@@ -414,7 +412,6 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
 //sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
 //sys	Fchown(fd int, uid int, gid int) (err error)
 //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
-//sys	Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error)
 //sys	Flock(fd int, how int) (err error)
 //sys	Fpathconf(fd int, name int) (val int, err error)
 //sys	Fsync(fd int) (err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_illumos.go b/vendor/golang.org/x/sys/unix/syscall_illumos.go
index f3d5149f..99e62dcd 100644
--- a/vendor/golang.org/x/sys/unix/syscall_illumos.go
+++ b/vendor/golang.org/x/sys/unix/syscall_illumos.go
@@ -24,7 +24,7 @@ func bytes2iovec(bs [][]byte) []Iovec {
 	return iovecs
 }
 
-//sys	readv(fd int, iovs []Iovec) (n int, err error)
+//sys   readv(fd int, iovs []Iovec) (n int, err error)
 
 func Readv(fd int, iovs [][]byte) (n int, err error) {
 	iovecs := bytes2iovec(iovs)
@@ -32,7 +32,7 @@ func Readv(fd int, iovs [][]byte) (n int, err error) {
 	return n, err
 }
 
-//sys	preadv(fd int, iovs []Iovec, off int64) (n int, err error)
+//sys   preadv(fd int, iovs []Iovec, off int64) (n int, err error)
 
 func Preadv(fd int, iovs [][]byte, off int64) (n int, err error) {
 	iovecs := bytes2iovec(iovs)
@@ -40,7 +40,7 @@ func Preadv(fd int, iovs [][]byte, off int64) (n int, err error) {
 	return n, err
 }
 
-//sys	writev(fd int, iovs []Iovec) (n int, err error)
+//sys   writev(fd int, iovs []Iovec) (n int, err error)
 
 func Writev(fd int, iovs [][]byte) (n int, err error) {
 	iovecs := bytes2iovec(iovs)
@@ -48,30 +48,10 @@ func Writev(fd int, iovs [][]byte) (n int, err error) {
 	return n, err
 }
 
-//sys	pwritev(fd int, iovs []Iovec, off int64) (n int, err error)
+//sys   pwritev(fd int, iovs []Iovec, off int64) (n int, err error)
 
 func Pwritev(fd int, iovs [][]byte, off int64) (n int, err error) {
 	iovecs := bytes2iovec(iovs)
 	n, err = pwritev(fd, iovecs, off)
 	return n, err
 }
-
-//sys	accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
-
-func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	var len _Socklen = SizeofSockaddrAny
-	nfd, err = accept4(fd, &rsa, &len, flags)
-	if err != nil {
-		return
-	}
-	if len > SizeofSockaddrAny {
-		panic("RawSockaddrAny too small")
-	}
-	sa, err = anyToSockaddr(fd, &rsa)
-	if err != nil {
-		Close(nfd)
-		nfd = 0
-	}
-	return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
index 39761472..e2ffb3be 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
@@ -958,56 +958,6 @@ func libc_close_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Clonefile(src string, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefile_trampoline()
-
-//go:linkname libc_clonefile libc_clonefile
-//go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefileat_trampoline()
-
-//go:linkname libc_clonefileat libc_clonefileat
-//go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Dup(fd int) (nfd int, err error) {
 	r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
 	nfd = int(r0)
@@ -1196,26 +1146,6 @@ func libc_fchownat_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fclonefileat_trampoline()
-
-//go:linkname libc_fclonefileat libc_fclonefileat
-//go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
index 961058db..6836a412 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
@@ -110,10 +110,6 @@ TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_clock_gettime(SB)
 TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_close(SB)
-TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefile(SB)
-TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefileat(SB)
 TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_dup(SB)
 TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
@@ -136,8 +132,6 @@ TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fchown(SB)
 TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fchownat(SB)
-TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fclonefileat(SB)
 TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_flock(SB)
 TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
@@ -170,8 +164,6 @@ TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getrusage(SB)
 TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getsid(SB)
-TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_gettimeofday(SB)
 TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getuid(SB)
 TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
@@ -274,6 +266,8 @@ TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_munmap(SB)
 TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_ptrace(SB)
+TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
 TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fstat64(SB)
 TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
index e253f438..c67e336e 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
@@ -958,56 +958,6 @@ func libc_close_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Clonefile(src string, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefile_trampoline()
-
-//go:linkname libc_clonefile libc_clonefile
-//go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefileat_trampoline()
-
-//go:linkname libc_clonefileat libc_clonefileat
-//go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Dup(fd int) (nfd int, err error) {
 	r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
 	nfd = int(r0)
@@ -1196,26 +1146,6 @@ func libc_fchownat_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fclonefileat_trampoline()
-
-//go:linkname libc_fclonefileat libc_fclonefileat
-//go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
index b8be24c6..a3fdf099 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
@@ -110,10 +110,6 @@ TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_clock_gettime(SB)
 TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_close(SB)
-TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefile(SB)
-TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefileat(SB)
 TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_dup(SB)
 TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
@@ -136,8 +132,6 @@ TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fchown(SB)
 TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fchownat(SB)
-TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fclonefileat(SB)
 TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_flock(SB)
 TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
@@ -170,8 +164,6 @@ TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getrusage(SB)
 TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getsid(SB)
-TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_gettimeofday(SB)
 TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getuid(SB)
 TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
@@ -274,6 +266,8 @@ TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_munmap(SB)
 TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_ptrace(SB)
+TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
 TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fstat64(SB)
 TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go
index be2e2831..b759757a 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go
@@ -958,56 +958,6 @@ func libc_close_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Clonefile(src string, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefile_trampoline()
-
-//go:linkname libc_clonefile libc_clonefile
-//go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefileat_trampoline()
-
-//go:linkname libc_clonefileat libc_clonefileat
-//go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Dup(fd int) (nfd int, err error) {
 	r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
 	nfd = int(r0)
@@ -1196,26 +1146,6 @@ func libc_fchownat_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fclonefileat_trampoline()
-
-//go:linkname libc_fclonefileat libc_fclonefileat
-//go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s
index 403c21f0..b67f518f 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s
@@ -110,10 +110,6 @@ TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_clock_gettime(SB)
 TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_close(SB)
-TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefile(SB)
-TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefileat(SB)
 TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_dup(SB)
 TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
@@ -136,8 +132,6 @@ TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fchown(SB)
 TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fchownat(SB)
-TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fclonefileat(SB)
 TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_flock(SB)
 TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
@@ -170,8 +164,6 @@ TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getrusage(SB)
 TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getsid(SB)
-TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_gettimeofday(SB)
 TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getuid(SB)
 TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
@@ -272,6 +264,8 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_mmap(SB)
 TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_munmap(SB)
+TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
 TEXT ·libc_fstat_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fstat(SB)
 TEXT ·libc_fstatat_trampoline(SB),NOSPLIT,$0-0
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
index 34976a4c..b2886126 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
@@ -958,56 +958,6 @@ func libc_close_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Clonefile(src string, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefile_trampoline()
-
-//go:linkname libc_clonefile libc_clonefile
-//go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(src)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_clonefileat_trampoline()
-
-//go:linkname libc_clonefileat libc_clonefileat
-//go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Dup(fd int) (nfd int, err error) {
 	r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0)
 	nfd = int(r0)
@@ -1196,26 +1146,6 @@ func libc_fchownat_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(dst)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-func libc_fclonefileat_trampoline()
-
-//go:linkname libc_fclonefileat libc_fclonefileat
-//go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
index abe7b6ed..40cce1bb 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
@@ -110,10 +110,6 @@ TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_clock_gettime(SB)
 TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_close(SB)
-TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefile(SB)
-TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_clonefileat(SB)
 TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_dup(SB)
 TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
@@ -136,8 +132,6 @@ TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fchown(SB)
 TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fchownat(SB)
-TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_fclonefileat(SB)
 TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_flock(SB)
 TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
@@ -170,8 +164,6 @@ TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getrusage(SB)
 TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getsid(SB)
-TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_gettimeofday(SB)
 TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_getuid(SB)
 TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
@@ -272,6 +264,8 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_mmap(SB)
 TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_munmap(SB)
+TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
 TEXT ·libc_fstat_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_fstat(SB)
 TEXT ·libc_fstatat_trampoline(SB),NOSPLIT,$0-0
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go
index d885ef38..92efa1da 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go
@@ -13,20 +13,17 @@ import (
 //go:cgo_import_dynamic libc_preadv preadv "libc.so"
 //go:cgo_import_dynamic libc_writev writev "libc.so"
 //go:cgo_import_dynamic libc_pwritev pwritev "libc.so"
-//go:cgo_import_dynamic libc_accept4 accept4 "libc.so"
 
 //go:linkname procreadv libc_readv
 //go:linkname procpreadv libc_preadv
 //go:linkname procwritev libc_writev
 //go:linkname procpwritev libc_pwritev
-//go:linkname procaccept4 libc_accept4
 
 var (
 	procreadv,
 	procpreadv,
 	procwritev,
-	procpwritev,
-	procaccept4 syscallFunc
+	procpwritev syscallFunc
 )
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -88,14 +85,3 @@ func pwritev(fd int, iovs []Iovec, off int64) (n int, err error) {
 	}
 	return
 }
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
-	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procaccept4)), 4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go
index f54ff90a..847e00bc 100644
--- a/vendor/golang.org/x/sys/windows/service.go
+++ b/vendor/golang.org/x/sys/windows/service.go
@@ -65,7 +65,6 @@ const (
 	SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32
 	SERVICE_ACCEPT_POWEREVENT            = 64
 	SERVICE_ACCEPT_SESSIONCHANGE         = 128
-	SERVICE_ACCEPT_PRESHUTDOWN           = 256
 
 	SERVICE_CONTROL_STOP                  = 1
 	SERVICE_CONTROL_PAUSE                 = 2
@@ -81,7 +80,6 @@ const (
 	SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12
 	SERVICE_CONTROL_POWEREVENT            = 13
 	SERVICE_CONTROL_SESSIONCHANGE         = 14
-	SERVICE_CONTROL_PRESHUTDOWN           = 15
 
 	SERVICE_ACTIVE    = 1
 	SERVICE_INACTIVE  = 2
diff --git a/vendor/modules.txt b/vendor/modules.txt
index fbaba821..db7590d5 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -9,7 +9,7 @@ github.com/cilium/ebpf/asm
 github.com/cilium/ebpf/internal
 github.com/cilium/ebpf/internal/btf
 github.com/cilium/ebpf/internal/unix
-# github.com/containerd/console v1.0.1
+# github.com/containerd/console v1.0.0
 ## explicit
 github.com/containerd/console
 # github.com/coreos/go-systemd/v22 v22.1.0
@@ -30,13 +30,15 @@ github.com/godbus/dbus/v5
 # github.com/golang/protobuf v1.4.2
 ## explicit
 github.com/golang/protobuf/proto
+# github.com/konsorten/go-windows-terminal-sequences v1.0.3
+github.com/konsorten/go-windows-terminal-sequences
 # github.com/moby/sys/mountinfo v0.2.0
 ## explicit
 github.com/moby/sys/mountinfo
 # github.com/mrunalp/fileutils v0.5.0
 ## explicit
 github.com/mrunalp/fileutils
-# github.com/opencontainers/runtime-spec v1.0.3-0.20200817204227-f9c09b4ea1df
+# github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6
 ## explicit
 github.com/opencontainers/runtime-spec/specs-go
 # github.com/opencontainers/selinux v1.6.0
@@ -54,7 +56,7 @@ github.com/russross/blackfriday/v2
 github.com/seccomp/libseccomp-golang
 # github.com/shurcooL/sanitized_anchor_name v1.0.0
 github.com/shurcooL/sanitized_anchor_name
-# github.com/sirupsen/logrus v1.7.0
+# github.com/sirupsen/logrus v1.6.0
 ## explicit
 github.com/sirupsen/logrus
 # github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
@@ -71,7 +73,7 @@ github.com/vishvananda/netlink/nl
 github.com/vishvananda/netns
 # github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243
 github.com/willf/bitset
-# golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f
+# golang.org/x/sys v0.0.0-20200909081042-eff7692f9009
 ## explicit
 golang.org/x/sys/internal/unsafeheader
 golang.org/x/sys/unix


Test patch:
diff --git a/libcontainer/cgroups/fs/hugetlb_test.go b/libcontainer/cgroups/fs/hugetlb_test.go
index 2d17ca67..9ddacfee 100644
--- a/libcontainer/cgroups/fs/hugetlb_test.go
+++ b/libcontainer/cgroups/fs/hugetlb_test.go
@@ -18,7 +18,7 @@ const (
 	hugetlbFailcnt          = "100\n"
 )
 
-const (
+var (
 	usage    = "hugetlb.%s.usage_in_bytes"
 	limit    = "hugetlb.%s.limit_in_bytes"
 	maxUsage = "hugetlb.%s.max_usage_in_bytes"
diff --git a/libcontainer/cgroups/utils_test.go b/libcontainer/cgroups/utils_test.go
index ebc38f25..4a5d95eb 100644
--- a/libcontainer/cgroups/utils_test.go
+++ b/libcontainer/cgroups/utils_test.go
@@ -4,11 +4,12 @@ package cgroups
 
 import (
 	"bytes"
-	"errors"
 	"fmt"
 	"reflect"
 	"strings"
 	"testing"
+
+	"github.com/sirupsen/logrus"
 )
 
 const fedoraMountinfo = `15 35 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw
@@ -401,37 +402,100 @@ func TestFindCgroupMountpointAndRoot(t *testing.T) {
 	}
 }
 
-func TestGetHugePageSizeImpl(t *testing.T) {
+func BenchmarkGetHugePageSize(b *testing.B) {
+	var (
+		output []string
+		err    error
+	)
+	for i := 0; i < b.N; i++ {
+		output, err = GetHugePageSize()
+	}
+	if err != nil || len(output) == 0 {
+		b.Fatal("unexpected results")
+	}
+}
+
+func BenchmarkGetHugePageSizeImpl(b *testing.B) {
+	var (
+		input  = []string{"hugepages-1048576kB", "hugepages-2048kB", "hugepages-32768kB", "hugepages-64kB"}
+		output []string
+		err    error
+	)
+	for i := 0; i < b.N; i++ {
+		output, err = getHugePageSizeFromFilenames(input)
+	}
+	if err != nil || len(output) != len(input) {
+		b.Fatal("unexpected results")
+	}
+}
 
+func TestGetHugePageSizeImpl(t *testing.T) {
 	testCases := []struct {
-		inputFiles      []string
-		outputPageSizes []string
-		err             error
+		input  []string
+		output []string
+		isErr  bool
+		isWarn bool
 	}{
 		{
-			inputFiles:      []string{"hugepages-1048576kB", "hugepages-2048kB", "hugepages-32768kB", "hugepages-64kB"},
-			outputPageSizes: []string{"1GB", "2MB", "32MB", "64KB"},
-			err:             nil,
+			input:  []string{"hugepages-1048576kB", "hugepages-2048kB", "hugepages-32768kB", "hugepages-64kB"},
+			output: []string{"1GB", "2MB", "32MB", "64KB"},
 		},
 		{
-			inputFiles:      []string{},
-			outputPageSizes: []string{},
-			err:             nil,
+			input:  []string{},
+			output: []string{},
 		},
-		{
-			inputFiles:      []string{"hugepages-a"},
-			outputPageSizes: []string{},
-			err:             errors.New("invalid size: 'a'"),
+		{ // not a number
+			input: []string{"hugepages-akB"},
+			isErr: true,
+		},
+		{ // no prefix (silently skipped)
+			input: []string{"1024kB"},
+		},
+		{ // invalid prefix (silently skipped)
+			input: []string{"whatever-1024kB"},
+		},
+		{ // invalid suffix (skipped with a warning)
+			input:  []string{"hugepages-1024gB"},
+			isWarn: true,
+		},
+		{ // no suffix (skipped with a warning)
+			input:  []string{"hugepages-1024"},
+			isWarn: true,
 		},
 	}
 
+	// Need to catch warnings.
+	savedOut := logrus.StandardLogger().Out
+	defer logrus.SetOutput(savedOut)
+	warns := new(bytes.Buffer)
+	logrus.SetOutput(warns)
+
 	for _, c := range testCases {
-		pageSizes, err := getHugePageSizeFromFilenames(c.inputFiles)
-		if len(pageSizes) != 0 && len(c.outputPageSizes) != 0 && !reflect.DeepEqual(pageSizes, c.outputPageSizes) {
-			t.Errorf("expected %s, got %s", c.outputPageSizes, pageSizes)
+		warns.Reset()
+		output, err := getHugePageSizeFromFilenames(c.input)
+		if err != nil {
+			t.Logf("(input %v, error %v)", c.input, err)
+			if !c.isErr {
+				t.Error("unexpected error ^^^^")
+			}
+			// no more checks
+			continue
+		}
+		if c.isErr {
+			t.Errorf("input %v, expected error, got error: nil, output: %v", c.input, output)
+			// no more checks
+			continue
+		}
+		// check for warnings
+		if c.isWarn && warns.Len() == 0 {
+			t.Errorf("input %v, expected a warning, got none", c.input)
+		}
+		if !c.isWarn && warns.Len() > 0 {
+			t.Errorf("input %v, unexpected warning: %s", c.input, warns.String())
 		}
-		if err != nil && err.Error() != c.err.Error() {
-			t.Errorf("expected error %s, got %s", c.err, err)
+		// check output
+		if len(output) != len(c.output) || (len(output) > 0 && !reflect.DeepEqual(output, c.output)) {
+			t.Errorf("input %v, expected %v, got %v", c.input, c.output, output)
 		}
 	}
 }
diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go
index 10ce9939..923c5797 100644
--- a/libcontainer/integration/exec_test.go
+++ b/libcontainer/integration/exec_test.go
@@ -705,155 +705,6 @@ func testRunWithKernelMemory(t *testing.T, systemd bool) {
 	}
 }
 
-func TestCgroupResourcesUnifiedErrorOnV1(t *testing.T) {
-	testCgroupResourcesUnifiedErrorOnV1(t, false)
-}
-
-func TestCgroupResourcesUnifiedErrorOnV1Systemd(t *testing.T) {
-	if !systemd.IsRunningSystemd() {
-		t.Skip("Systemd is unsupported")
-	}
-	testCgroupResourcesUnifiedErrorOnV1(t, true)
-}
-
-func testCgroupResourcesUnifiedErrorOnV1(t *testing.T, systemd bool) {
-	if testing.Short() {
-		return
-	}
-	if cgroups.IsCgroup2UnifiedMode() {
-		t.Skip("requires cgroup v1")
-	}
-	rootfs, err := newRootfs()
-	ok(t, err)
-	defer remove(rootfs)
-
-	config := newTemplateConfig(rootfs)
-	if systemd {
-		config.Cgroups.Parent = "system.slice"
-	}
-	config.Cgroups.Resources.Unified = map[string]string{
-		"memory.min": "10240",
-	}
-	_, _, err = runContainer(config, "", "true")
-	if !strings.Contains(err.Error(), cgroups.ErrV1NoUnified.Error()) {
-		t.Fatalf("expected error to contain %v, got %v", cgroups.ErrV1NoUnified, err)
-	}
-}
-
-func TestCgroupResourcesUnified(t *testing.T) {
-	testCgroupResourcesUnified(t, false)
-}
-
-func TestCgroupResourcesUnifiedSystemd(t *testing.T) {
-	if !systemd.IsRunningSystemd() {
-		t.Skip("Systemd is unsupported")
-	}
-	testCgroupResourcesUnified(t, true)
-}
-
-func testCgroupResourcesUnified(t *testing.T, systemd bool) {
-	if testing.Short() {
-		return
-	}
-	if !cgroups.IsCgroup2UnifiedMode() {
-		t.Skip("requires cgroup v2")
-	}
-	rootfs, err := newRootfs()
-	ok(t, err)
-	defer remove(rootfs)
-
-	config := newTemplateConfig(rootfs)
-	config.Cgroups.Resources.Memory = 536870912     // 512M
-	config.Cgroups.Resources.MemorySwap = 536870912 // 512M, i.e. no swap
-	config.Namespaces.Add(configs.NEWCGROUP, "")
-	config.Mounts = append(config.Mounts, &configs.Mount{
-		Destination: "/sys/fs/cgroup",
-		Device:      "cgroup",
-		Flags:       defaultMountFlags | unix.MS_RDONLY,
-	})
-	if systemd {
-		config.Cgroups.Parent = "system.slice"
-	}
-
-	testCases := []struct {
-		name     string
-		cfg      map[string]string
-		expError string
-		cmd      []string
-		exp      string
-	}{
-		{
-			name: "dummy",
-			cmd:  []string{"true"},
-			exp:  "",
-		},
-		{
-			name: "set memory.min",
-			cfg:  map[string]string{"memory.min": "131072"},
-			cmd:  []string{"cat", "/sys/fs/cgroup/memory.min"},
-			exp:  "131072\n",
-		},
-		{
-			name: "check memory.max",
-			cmd:  []string{"cat", "/sys/fs/cgroup/memory.max"},
-			exp:  strconv.Itoa(int(config.Cgroups.Resources.Memory)) + "\n",
-		},
-
-		{
-			name: "overwrite memory.max",
-			cfg:  map[string]string{"memory.max": "268435456"},
-			cmd:  []string{"cat", "/sys/fs/cgroup/memory.max"},
-			exp:  "268435456\n",
-		},
-		{
-			name:     "no such controller error",
-			cfg:      map[string]string{"privet.vsem": "vam"},
-			expError: "controller \"privet\" not available",
-		},
-		{
-			name:     "slash in key error",
-			cfg:      map[string]string{"bad/key": "val"},
-			expError: "must be a file name (no slashes)",
-		},
-		{
-			name:     "no dot in key error",
-			cfg:      map[string]string{"badkey": "val"},
-			expError: "must be in the form CONTROLLER.PARAMETER",
-		},
-		{
-			name:     "read-only parameter",
-			cfg:      map[string]string{"pids.current": "42"},
-			expError: "failed to write",
-		},
-	}
-
-	for _, tc := range testCases {
-		config.Cgroups.Resources.Unified = tc.cfg
-		buffers, ret, err := runContainer(config, "", tc.cmd...)
-		if tc.expError != "" {
-			if err == nil {
-				t.Errorf("case %q failed: expected error, got nil", tc.name)
-				continue
-			}
-			if !strings.Contains(err.Error(), tc.expError) {
-				t.Errorf("case %q failed: expected error to contain %q, got %q", tc.name, tc.expError, err)
-			}
-			continue
-		}
-		if err != nil {
-			t.Errorf("case %q failed: expected no error, got %v (command: %v, status: %d, stderr: %q)",
-				tc.name, err, tc.cmd, ret, buffers.Stderr.String())
-			continue
-		}
-		if tc.exp != "" {
-			out := buffers.Stdout.String()
-			if out != tc.exp {
-				t.Errorf("expected %q, got %q", tc.exp, out)
-			}
-		}
-	}
-}
-
 func TestContainerState(t *testing.T) {
 	if testing.Short() {
 		return
@@ -1244,7 +1095,7 @@ func TestHook(t *testing.T) {
 
 	config := newTemplateConfig(rootfs)
 	expectedBundle := bundle
-	config.Labels = append(config.Labels, "bundle="+expectedBundle)
+	config.Labels = append(config.Labels, fmt.Sprintf("bundle=%s", expectedBundle))
 
 	getRootfsFromBundle := func(bundle string) (string, error) {
 		f, err := os.Open(filepath.Join(bundle, "config.json"))
diff --git a/libcontainer/utils/utils_test.go b/libcontainer/utils/utils_test.go
index 805f8b36..395eedcf 100644
--- a/libcontainer/utils/utils_test.go
+++ b/libcontainer/utils/utils_test.go
@@ -2,6 +2,7 @@ package utils
 
 import (
 	"bytes"
+	"fmt"
 	"os"
 	"path/filepath"
 	"testing"
@@ -43,7 +44,7 @@ func TestResolveRootfs(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	if path != pwd+"/rootfs" {
+	if path != fmt.Sprintf("%s/%s", pwd, "rootfs") {
 		t.Errorf("expected rootfs to be abs and was %s", path)
 	}
 }
diff --git a/tests/integration/cgroups.bats b/tests/integration/cgroups.bats
index bb8f4e14..676655ed 100644
--- a/tests/integration/cgroups.bats
+++ b/tests/integration/cgroups.bats
@@ -3,10 +3,9 @@
 load helpers
 
 function teardown() {
+    rm -f "$BATS_TMPDIR"/runc-cgroups-integration-test.json
     teardown_running_container test_cgroups_kmem
     teardown_running_container test_cgroups_permissions
-    teardown_running_container test_cgroups_group
-    teardown_running_container test_cgroups_unified
     teardown_busybox
 }
 
@@ -79,7 +78,7 @@ function setup() {
 
     runc run -d --console-socket "$CONSOLE_SOCKET" test_cgroups_permissions
     [ "$status" -eq 1 ]
-    [[ ${lines[0]} == *"permission denied"* ]]
+    [[ ${lines[1]} == *"permission denied"* ]]
 }
 
 @test "runc create (rootless + limits + no cgrouppath + no permission) fails with informative error" {
@@ -92,7 +91,7 @@ function setup() {
 
     runc run -d --console-socket "$CONSOLE_SOCKET" test_cgroups_permissions
     [ "$status" -eq 1 ]
-    [[ ${lines[0]} == *"rootless needs no limits + no cgrouppath when no permission is granted for cgroups"* ]] || [[ ${lines[0]} == *"cannot set pids limit: container could not join or create cgroup"* ]]
+    [[ ${lines[1]} == *"rootless needs no limits + no cgrouppath when no permission is granted for cgroups"* ]] || [[ ${lines[1]} == *"cannot set pids limit: container could not join or create cgroup"* ]]
 }
 
 @test "runc create (limits + cgrouppath + permission on the cgroup dir) succeeds" {
@@ -177,64 +176,3 @@ function setup() {
     [ "$status" -eq 0 ]
 #
 }
-
-@test "runc run (cgroup v1 + unified resources should fail)" {
-    requires root cgroups_v1
-
-    set_cgroups_path "$BUSYBOX_BUNDLE"
-    set_resources_limit "$BUSYBOX_BUNDLE"
-    update_config '.linux.resources.unified |= {"memory.min": "131072"}' "$BUSYBOX_BUNDLE"
-
-    runc run -d --console-socket "$CONSOLE_SOCKET" test_cgroups_unified
-    [ "$status" -ne 0 ]
-    [[ "$output" == *'invalid configuration'* ]]
-}
-
-@test "runc run (cgroup v2 resources.unified only)" {
-    requires root cgroups_v2
-
-    set_cgroups_path "$BUSYBOX_BUNDLE"
-    update_config ' .linux.resources.unified |= {
-                      "memory.min":   "131072",
-                      "memory.low":   "524288",
-                      "memory.high": "5242880",
-                      "memory.max": "10485760",
-                      "pids.max": "99",
-                      "cpu.max": "10000 100000"
-                     }' "$BUSYBOX_BUNDLE"
-
-    runc run -d --console-socket "$CONSOLE_SOCKET" test_cgroups_unified
-    [ "$status" -eq 0 ]
-
-    runc exec test_cgroups_unified sh -c 'cd /sys/fs/cgroup && grep . *.min *.max *.low *.high'
-    [ "$status" -eq 0 ]
-    echo "$output"
-
-    echo "$output" | grep -q '^memory.min:131072$'
-    echo "$output" | grep -q '^memory.low:524288$'
-    echo "$output" | grep -q '^memory.high:5242880$'
-    echo "$output" | grep -q '^memory.max:10485760$'
-    echo "$output" | grep -q '^pids.max:99$'
-    echo "$output" | grep -q '^cpu.max:10000 100000$'
-}
-@test "runc run (cgroup v2 resources.unified override)" {
-    requires root cgroups_v2
-
-    set_cgroups_path "$BUSYBOX_BUNDLE"
-    update_config ' .linux.resources.memory |= {"limit": 33554432}
-                  | .linux.resources.memorySwap |= {"limit": 33554432}
-                  | .linux.resources.unified |=
-                      {"memory.min": "131072", "memory.max": "10485760" }' \
-        "$BUSYBOX_BUNDLE"
-
-    runc run -d --console-socket "$CONSOLE_SOCKET" test_cgroups_unified
-    [ "$status" -eq 0 ]
-
-    runc exec test_cgroups_unified cat /sys/fs/cgroup/memory.min
-    [ "$status" -eq 0 ]
-    [ "$output" = '131072' ]
-
-    runc exec test_cgroups_unified cat /sys/fs/cgroup/memory.max
-    [ "$status" -eq 0 ]
-    [ "$output" = '10485760' ]
-}
diff --git a/tests/integration/checkpoint.bats b/tests/integration/checkpoint.bats
index 5f0ea558..1a7b42a9 100644
--- a/tests/integration/checkpoint.bats
+++ b/tests/integration/checkpoint.bats
@@ -12,7 +12,6 @@ function setup() {
 
 function teardown() {
   teardown_busybox
-  teardown_running_container test_busybox_restore
 }
 
 function setup_pipes() {
@@ -318,3 +317,4 @@ function simple_cr() {
   unlink "$tmp"
   test -f ./work-dir/"$tmplog2" && unlink ./work-dir/"$tmplog2"
 }
+
diff --git a/tests/integration/delete.bats b/tests/integration/delete.bats
index 3b23bd85..95dc718f 100644
--- a/tests/integration/delete.bats
+++ b/tests/integration/delete.bats
@@ -9,7 +9,6 @@ function setup() {
 
 function teardown() {
   teardown_busybox
-  teardown_running_container testbusyboxdelete
 }
 
 @test "runc delete" {
diff --git a/tests/integration/dev.bats b/tests/integration/dev.bats
index 11c53c95..3df7958c 100644
--- a/tests/integration/dev.bats
+++ b/tests/integration/dev.bats
@@ -9,7 +9,6 @@ function setup() {
 
 function teardown() {
 	teardown_busybox
-	teardown_running_container test_dev
 }
 
 @test "runc run [redundant default /dev/tty]" {
@@ -34,73 +33,3 @@ function teardown() {
 	[ "$status" -eq 0 ]
 	[[ "${lines[0]}" =~ "crw-rw-rw".+"1".+"0".+"0".+"5,".+"2".+"/dev/ptmx" ]]
 }
-
-@test "runc run [device cgroup deny]" {
-	requires root
-
-	update_config ' .linux.resources.devices = [{"allow": false, "access": "rwm"}]
-			| .linux.devices = [{"path": "/dev/kmsg", "type": "c", "major": 1, "minor": 11}]
-			| .process.args |= ["sh"]'
-
-	runc run -d --console-socket "$CONSOLE_SOCKET" test_deny
-	[ "$status" -eq 0 ]
-
-	# test write
-	runc exec test_deny sh -c 'hostname | tee /dev/kmsg'
-	[ "$status" -eq 1 ]
-	[[ "${output}" == *'Operation not permitted'* ]]
-
-	# test read
-	runc exec test_deny sh -c 'head -n 1 /dev/kmsg'
-	[ "$status" -eq 1 ]
-	[[ "${output}" == *'Operation not permitted'* ]]
-}
-
-@test "runc run [device cgroup allow rw char device]" {
-	requires root
-
-	update_config ' .linux.resources.devices = [{"allow": false, "access": "rwm"},{"allow": true, "type": "c", "major": 1, "minor": 11, "access": "rwm"}]
-			| .linux.devices = [{"path": "/dev/kmsg", "type": "c", "major": 1, "minor": 11}]
-			| .process.args |= ["sh"]
-			| .hostname = "myhostname"'
-
-	runc run -d --console-socket "$CONSOLE_SOCKET" test_allow_char
-	[ "$status" -eq 0 ]
-
-	# test write
-	runc exec test_allow_char sh -c 'hostname | tee /dev/kmsg'
-	[ "$status" -eq 0 ]
-	[[ "${lines[0]}" == *'myhostname'* ]]
-
-	# test read
-	runc exec test_allow_char sh -c 'head -n 1 /dev/kmsg'
-	[ "$status" -eq 0 ]
-}
-
-@test "runc run [device cgroup allow rm block device]" {
-	requires root
-
-	# get first block device
-	device="/dev/$(lsblk -nd -o NAME | head -n 1)"
-	major="$(lsblk -nd -o MAJ:MIN | head -n 1 | awk -F":" '{print $1}' | sed "s/\s*//g")"
-	minor="$(lsblk -nd -o MAJ:MIN | head -n 1 | awk -F":" '{print $2}')"
-
-	update_config ' .linux.resources.devices = [{"allow": false, "access": "rwm"},{"allow": true, "type": "b", "major": '"$major"', "minor": '"$minor"', "access": "rwm"}]
-			| .linux.devices = [{"path": "'"$device"'", "type": "b", "major": '"$major"', "minor": '"$minor"'}]
-			| .process.args |= ["sh"]
-			| .process.capabilities.bounding += ["CAP_MKNOD"]
-			| .process.capabilities.effective += ["CAP_MKNOD"]
-			| .process.capabilities.inheritable += ["CAP_MKNOD"]
-			| .process.capabilities.permitted += ["CAP_MKNOD"]'
-
-	runc run -d --console-socket "$CONSOLE_SOCKET" test_allow_block
-	[ "$status" -eq 0 ]
-
-	# test mknod
-	runc exec test_allow_block sh -c 'mknod /dev/fooblock b '"$major"' '"$minor"''
-	[ "$status" -eq 0 ]
-
-	# test read
-	runc exec test_allow_block sh -c 'fdisk -l '"$device"''
-	[ "$status" -eq 0 ]
-}
diff --git a/tests/integration/helpers.bash b/tests/integration/helpers.bash
index 6bde60da..62e2a464 100644
--- a/tests/integration/helpers.bash
+++ b/tests/integration/helpers.bash
@@ -167,9 +167,9 @@ function init_cgroup_paths() {
 
 # Helper function to set cgroupsPath to the value of $OCI_CGROUPS_PATH
 function set_cgroups_path() {
-	bundle="${1:-.}"
-	init_cgroup_paths
-	update_config '.linux.cgroupsPath |= "'"${OCI_CGROUPS_PATH}"'"' $bundle
+  bundle="${1:-.}"
+  init_cgroup_paths
+  update_config '.linux.cgroupsPath |= "'"${OCI_CGROUPS_PATH}"'"' $bundle
 }
 
 # Helper to check a value in cgroups.
@@ -207,15 +207,17 @@ function check_systemd_value() {
 
 # Helper function to set a resources limit
 function set_resources_limit() {
-	bundle="${1:-.}"
-	update_config '.linux.resources.pids.limit |= 100' $bundle
+  bundle="${1:-.}"
+  update_config '.linux.resources.pids.limit |= 100' $bundle
 }
 
 # Helper function to make /sys/fs/cgroup writable
 function set_cgroup_mount_writable() {
 	bundle="${1:-.}"
-	update_config '.mounts |= map((select(.type == "cgroup") | .options -= ["ro"]) // .)' \
-		$bundle
+	cat "$bundle/config.json" \
+        |  jq '.mounts |= map((select(.type == "cgroup") | .options -= ["ro"]) // .)' \
+		>"$bundle/config.json.tmp"
+	mv "$bundle/config.json"{.tmp,}
 }
 
 # Fails the current test, providing the error given.
@@ -260,11 +262,6 @@ function requires() {
 				skip_me=1
 			fi
 			;;
-		rootless_no_features)
-			if [ "$ROOTLESS_FEATURES" != "" ]; then
-				skip_me=1
-			fi
-			;;
 		cgroups_freezer)
 			init_cgroup_paths
 			if [[ "$CGROUP_SUBSYSTEMS" != *"freezer"* ]]; then
diff --git a/tests/integration/mask.bats b/tests/integration/mask.bats
index d68252e2..827d17b3 100644
--- a/tests/integration/mask.bats
+++ b/tests/integration/mask.bats
@@ -11,7 +11,7 @@ function setup() {
 	echo "Forbidden information!" > rootfs/testfile
 
 	# add extra masked paths
-	update_config '(.. | select(.maskedPaths? != null)) .maskedPaths += ["/testdir", "/testfile"]'
+	update_config '(.. | select(.maskedPaths? != null)) .maskedPaths += ["/testdir", "/testfile"]' 
 }
 
 function teardown() {
diff --git a/tests/integration/mounts.bats b/tests/integration/mounts.bats
index 1e1b8f0d..bd41dc6e 100644
--- a/tests/integration/mounts.bats
+++ b/tests/integration/mounts.bats
@@ -9,12 +9,11 @@ function setup() {
 
 function teardown() {
 	teardown_busybox
-	teardown_running_container test_bind_mount
 }
 
 @test "runc run [bind mount]" {
-	update_config 	' .mounts += [{"source": ".", "destination": "/tmp/bind", "options": ["bind"]}]
-			| .process.args |= ["ls", "/tmp/bind/config.json"]'
+	update_config 	' .mounts += [{"source": ".", "destination": "/tmp/bind", "options": ["bind"]}] 
+			| .process.args |= ["ls", "/tmp/bind/config.json"]' 
 
 	runc run test_bind_mount
 	[ "$status" -eq 0 ]
diff --git a/tests/integration/spec.bats b/tests/integration/spec.bats
index ea5f4cd8..b6d11835 100644
--- a/tests/integration/spec.bats
+++ b/tests/integration/spec.bats
@@ -3,38 +3,97 @@
 load helpers
 
 function setup() {
-	setup_hello
+  # initial cleanup in case a prior test exited and did not cleanup
+  rm -rf "$HELLO_BUNDLE"
+
+  # setup hello-world for spec generation testing
+  mkdir -p "$HELLO_BUNDLE"/rootfs
+  tar -C "$HELLO_BUNDLE"/rootfs -xf "$HELLO_IMAGE"
 }
 
 function teardown() {
-	teardown_hello
+  rm -rf "$HELLO_BUNDLE"
 }
 
 @test "spec generation cwd" {
-	runc run test_hello
-	[ "$status" -eq 0 ]
+  cd "$HELLO_BUNDLE"
+  # note this test runs from the bundle not the integration root
+
+  # test that config.json does not exist after the above partial setup
+  [ ! -e config.json ]
+
+  # test generation of spec does not return an error
+  runc_spec
+  [ "$status" -eq 0 ]
+
+  # test generation of spec created our config.json (spec)
+  [ -e config.json ]
+
+  # test existence of required args parameter in the generated config.json
+  run bash -c "grep -A2 'args' config.json | grep 'sh'"
+  [[ "${output}" == *"sh"* ]]
+
+  # change the default args parameter from sh to hello
+  update_config '(.. | select(.? == "sh")) |= "/hello"'
+
+  # ensure the generated spec works by running hello-world
+  runc run test_hello
+  [ "$status" -eq 0 ]
 }
 
 @test "spec generation --bundle" {
-	runc run --bundle "$HELLO_BUNDLE" test_hello
-	[ "$status" -eq 0 ]
+  # note this test runs from the integration root not the bundle
+
+  # test that config.json does not exist after the above partial setup
+  [ ! -e "$HELLO_BUNDLE"/config.json ]
+
+  # test generation of spec does not return an error
+  runc_spec "$HELLO_BUNDLE"
+  [ "$status" -eq 0 ]
+
+  # test generation of spec created our config.json (spec)
+  [ -e "$HELLO_BUNDLE"/config.json ]
+
+  # change the default args parameter from sh to hello
+  update_config '(.. | select(.? == "sh")) |= "/hello"' "$HELLO_BUNDLE"
+
+  # ensure the generated spec works by running hello-world
+  runc run --bundle "$HELLO_BUNDLE" test_hello
+  [ "$status" -eq 0 ]
 }
 
 @test "spec validator" {
-	requires rootless_no_features
+  TESTDIR=$(pwd)
+  cd "$HELLO_BUNDLE"
+
+  run git clone https://github.com/opencontainers/runtime-spec.git src/runtime-spec
+  [ "$status" -eq 0 ]
+
+  SPEC_VERSION=$(grep 'github.com/opencontainers/runtime-spec' "${TESTDIR}"/../../go.mod | cut -d ' ' -f 2)
+
+  # Will look like this when not pinned to spesific tag: "v0.0.0-20190207185410-29686dbc5559", otherwise "v1.0.0"
+  SPEC_COMMIT=$(cut -d "-" -f 3 <<< "$SPEC_VERSION")
+
+  SPEC_REF=$([[ -z "$SPEC_COMMIT" ]] && echo "$SPEC_VERSION" || echo "$SPEC_COMMIT")
+
+  run bash -c "cd src/runtime-spec && git reset --hard ${SPEC_REF}"
+
+  [ "$status" -eq 0 ]
+  [ -e src/runtime-spec/schema/config-schema.json ]
+
+  run bash -c "GOPATH='$GOPATH' go get github.com/xeipuuv/gojsonschema"
+  [ "$status" -eq 0 ]
 
-	SPEC_VERSION=$(awk '$1 == "github.com/opencontainers/runtime-spec" {print $2}' "$BATS_TEST_DIRNAME"/../../go.mod)
-	# Will look like this when not pinned to specific tag: "v0.0.0-20190207185410-29686dbc5559", otherwise "v1.0.0"
-	SPEC_COMMIT=$(cut -d "-" -f 3 <<< "$SPEC_VERSION")
-	SPEC_REF=$([[ -z "$SPEC_COMMIT" ]] && echo "$SPEC_VERSION" || echo "$SPEC_COMMIT")
+  run bash -c "cd ${GOPATH}/src/github.com/xeipuuv/gojsonschema && git reset --hard 6637feb73ee44cd4640bb3def285c29774234c7f"
+  [ "$status" -eq 0 ]
 
-	git clone https://github.com/opencontainers/runtime-spec.git
-	( cd runtime-spec && git reset --hard "$SPEC_REF" )
-	SCHEMA='runtime-spec/schema/config-schema.json'
-	[ -e "$SCHEMA" ]
+  GOPATH="$GOPATH" go build src/runtime-spec/schema/validate.go
+  [ -e ./validate ]
 
-	go get github.com/xeipuuv/gojsonschema
-	go build runtime-spec/schema/validate.go
+  runc spec
+  [ -e config.json ]
 
-	./validate "$SCHEMA" config.json
+  run ./validate src/runtime-spec/schema/config-schema.json config.json
+  [ "$status" -eq 0 ]
+  [[ "${lines[0]}" == *"The document is valid"* ]]
 }
diff --git a/tests/integration/start_detached.bats b/tests/integration/start_detached.bats
index 6682628a..b55239b2 100644
--- a/tests/integration/start_detached.bats
+++ b/tests/integration/start_detached.bats
@@ -27,7 +27,7 @@ function teardown() {
   # replace "uid": 0 with "uid": 1000
   # and do a similar thing for gid.
   update_config ' (.. | select(.uid? == 0)) .uid |= 1000
-		| (.. | select(.gid? == 0)) .gid |= 100'
+		| (.. | select(.gid? == 0)) .gid |= 100' 
 
   # run busybox detached
   runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox
diff --git a/tests/integration/start_hello.bats b/tests/integration/start_hello.bats
index dd2fad78..e4200eb4 100644
--- a/tests/integration/start_hello.bats
+++ b/tests/integration/start_hello.bats
@@ -26,8 +26,8 @@ function teardown() {
 
   # replace "uid": 0 with "uid": 1000
   # and do a similar thing for gid.
-  update_config ' (.. | select(.uid? == 0)) .uid |= 1000
-		| (.. | select(.gid? == 0)) .gid |= 100'
+  update_config ' (.. | select(.uid? == 0)) .uid |= 1000	
+		| (.. | select(.gid? == 0)) .gid |= 100' 
 
   # run hello-world
   runc run test_hello
diff --git a/tests/integration/umask.bats b/tests/integration/umask.bats
index e8166cda..b927da39 100644
--- a/tests/integration/umask.bats
+++ b/tests/integration/umask.bats
@@ -12,7 +12,7 @@ function teardown() {
 }
 
 @test "umask" {
-	update_config '.process.user += {"umask":63}'
+	update_config '.process.user += {"umask":63}' 
 
 	# run busybox detached
 	runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox
diff --git a/tests/integration/update.bats b/tests/integration/update.bats
index 1c44c035..8b08f80a 100644
--- a/tests/integration/update.bats
+++ b/tests/integration/update.bats
@@ -476,7 +476,7 @@ EOF
     # Run a basic shell script that tries to write to /dev/null. If "runc
     # update" makes use of minimal transition rules, updates should not cause
     # writes to fail at any point.
-    update_config '.process.args |= ["sh", "-c", "while true; do echo >/dev/null; done"]'
+    update_config '.process.args |= ["sh", "-c", "while true; do echo >/dev/null; done"]' 
 
     # Set up a temporary console socket and recvtty so we can get the stdio.
     TMP_RECVTTY_DIR="$(mktemp -d "$BATS_TMPDIR/runc-tmp-recvtty.XXXXXX")"