Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
2b642765
Commit
2b642765
authored
Dec 17, 2018
by
Seth Jennings
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vendor: bump runc to f000fe11
parent
f77a0706
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
38 changed files
with
744 additions
and
496 deletions
+744
-496
Godeps.json
Godeps/Godeps.json
+32
-32
BUILD
vendor/github.com/opencontainers/runc/libcontainer/BUILD
+1
-0
README.md
vendor/github.com/opencontainers/runc/libcontainer/README.md
+4
-3
SPEC.md
vendor/github.com/opencontainers/runc/libcontainer/SPEC.md
+69
-36
BUILD
...hub.com/opencontainers/runc/libcontainer/cgroups/fs/BUILD
+2
-0
apply_raw.go
.../opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
+48
-12
cpu.go
...ub.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
+2
-10
cpuset.go
...com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
+2
-6
kmem.go
...b.com/opencontainers/runc/libcontainer/cgroups/fs/kmem.go
+55
-0
kmem_disabled.go
...ncontainers/runc/libcontainer/cgroups/fs/kmem_disabled.go
+11
-0
memory.go
...com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
+2
-45
apply_systemd.go
...ainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
+20
-7
utils.go
...hub.com/opencontainers/runc/libcontainer/cgroups/utils.go
+13
-12
config.go
...ub.com/opencontainers/runc/libcontainer/configs/config.go
+15
-7
intelrdt.go
....com/opencontainers/runc/libcontainer/configs/intelrdt.go
+4
-0
rootless.go
...containers/runc/libcontainer/configs/validate/rootless.go
+9
-37
validator.go
...ontainers/runc/libcontainer/configs/validate/validator.go
+27
-6
container_linux.go
...b.com/opencontainers/runc/libcontainer/container_linux.go
+0
-0
factory_linux.go
...hub.com/opencontainers/runc/libcontainer/factory_linux.go
+42
-10
init_linux.go
...github.com/opencontainers/runc/libcontainer/init_linux.go
+21
-19
intelrdt.go
...com/opencontainers/runc/libcontainer/intelrdt/intelrdt.go
+0
-0
stats.go
...ub.com/opencontainers/runc/libcontainer/intelrdt/stats.go
+16
-0
BUILD
...or/github.com/opencontainers/runc/libcontainer/keys/BUILD
+1
-0
keyctl.go
...ithub.com/opencontainers/runc/libcontainer/keys/keyctl.go
+4
-6
message_linux.go
...hub.com/opencontainers/runc/libcontainer/message_linux.go
+10
-10
network_linux.go
...hub.com/opencontainers/runc/libcontainer/network_linux.go
+0
-157
process.go
...or/github.com/opencontainers/runc/libcontainer/process.go
+3
-0
process_linux.go
...hub.com/opencontainers/runc/libcontainer/process_linux.go
+12
-11
rootfs_linux.go
...thub.com/opencontainers/runc/libcontainer/rootfs_linux.go
+30
-8
setns_init_linux.go
....com/opencontainers/runc/libcontainer/setns_init_linux.go
+17
-5
standard_init_linux.go
...m/opencontainers/runc/libcontainer/standard_init_linux.go
+37
-20
sync.go
vendor/github.com/opencontainers/runc/libcontainer/sync.go
+1
-4
BUILD
.../github.com/opencontainers/runc/libcontainer/system/BUILD
+35
-0
linux.go
...thub.com/opencontainers/runc/libcontainer/system/linux.go
+23
-15
unsupported.go
...om/opencontainers/runc/libcontainer/system/unsupported.go
+18
-0
lookup_unix.go
....com/opencontainers/runc/libcontainer/user/lookup_unix.go
+28
-0
user.go
.../github.com/opencontainers/runc/libcontainer/user/user.go
+130
-3
utils.go
...ithub.com/opencontainers/runc/libcontainer/utils/utils.go
+0
-15
No files found.
Godeps/Godeps.json
View file @
2b642765
...
@@ -2795,83 +2795,83 @@
...
@@ -2795,83 +2795,83 @@
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/apparmor"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/apparmor"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/cgroups"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/cgroups"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/configs"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/configs"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/configs/validate"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/configs/validate"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/criurpc"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/criurpc"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/intelrdt"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/intelrdt"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/keys"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/keys"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/mount"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/mount"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/seccomp"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/seccomp"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/stacktrace"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/stacktrace"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/system"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/system"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/user"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/user"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/utils"
,
"ImportPath"
:
"github.com/opencontainers/runc/libcontainer/utils"
,
"Comment"
:
"v1.0.0-rc5-
46-g871ba2e58e2431
"
,
"Comment"
:
"v1.0.0-rc5-
176-gf000fe11ece1b7
"
,
"Rev"
:
"
871ba2e58e24314d1fab4517a80410191ba5ad01
"
"Rev"
:
"
f000fe11ece1b79f744edd9c8e1a53ba0f5e0f24
"
},
},
{
{
"ImportPath"
:
"github.com/opencontainers/runtime-spec/specs-go"
,
"ImportPath"
:
"github.com/opencontainers/runtime-spec/specs-go"
,
...
...
vendor/github.com/opencontainers/runc/libcontainer/BUILD
View file @
2b642765
...
@@ -53,6 +53,7 @@ go_library(
...
@@ -53,6 +53,7 @@ go_library(
"//vendor/github.com/opencontainers/runc/libcontainer/system:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/system:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
"//vendor/github.com/opencontainers/selinux/go-selinux/label:go_default_library",
"//vendor/github.com/opencontainers/selinux/go-selinux/label:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library",
"//vendor/github.com/syndtr/gocapability/capability:go_default_library",
"//vendor/github.com/syndtr/gocapability/capability:go_default_library",
"//vendor/github.com/vishvananda/netlink:go_default_library",
"//vendor/github.com/vishvananda/netlink:go_default_library",
...
...
vendor/github.com/opencontainers/runc/libcontainer/README.md
View file @
2b642765
...
@@ -323,6 +323,7 @@ generated when building libcontainer with docker.
...
@@ -323,6 +323,7 @@ generated when building libcontainer with docker.
## Copyright and license
## Copyright and license
Code and documentation copyright 2014 Docker, inc. Code released under the Apache 2.0 license.
Code and documentation copyright 2014 Docker, inc.
Docs released under Creative commons.
The code and documentation are released under the
[
Apache 2.0 license
](
../LICENSE
)
.
The documentation is also released under Creative Commons Attribution 4.0 International License.
You may obtain a copy of the license, titled CC-BY-4.0, at http://creativecommons.org/licenses/by/4.0/.
vendor/github.com/opencontainers/runc/libcontainer/SPEC.md
View file @
2b642765
...
@@ -156,17 +156,21 @@ init process will block waiting for the parent to finish setup.
...
@@ -156,17 +156,21 @@ init process will block waiting for the parent to finish setup.
### IntelRdt
### IntelRdt
Intel platforms with new Xeon CPU support
Intel Resource Director Technology
Intel platforms with new Xeon CPU support
Resource Director Technology (RDT).
(RDT). Cache Allocation Technology (CAT) is a sub-feature of RDT, which
Cache Allocation Technology (CAT) and Memory Bandwidth Allocation (MBA) are
currently supports L3 cache resource allocation
.
two sub-features of RDT
.
This feature provides a way for the software to restrict cache allocation to a
Cache Allocation Technology (CAT) provides a way for the software to restrict
defined 'subset' of L3 cache which may be overlapping with other 'subsets'.
cache allocation to a defined 'subset' of L3 cache which may be overlapping
The different subsets are identified by class of service (CLOS) and each CLOS
with other 'subsets'. The different subsets are identified by class of
has a capacity bitmask (CBM).
service (CLOS) and each CLOS
has a capacity bitmask (CBM).
It can be used to handle L3 cache resource allocation for containers if
Memory Bandwidth Allocation (MBA) provides indirect and approximate throttle
hardware and kernel support Intel RDT/CAT.
over memory bandwidth for the software. A user controls the resource by
indicating the percentage of maximum memory bandwidth.
It can be used to handle L3 cache and memory bandwidth resources allocation
for containers if hardware and kernel support Intel RDT CAT and MBA features.
In Linux 4.10 kernel or newer, the interface is defined and exposed via
In Linux 4.10 kernel or newer, the interface is defined and exposed via
"resource control" filesystem, which is a "cgroup-like" interface.
"resource control" filesystem, which is a "cgroup-like" interface.
...
@@ -175,6 +179,9 @@ Comparing with cgroups, it has similar process management lifecycle and
...
@@ -175,6 +179,9 @@ Comparing with cgroups, it has similar process management lifecycle and
interfaces in a container. But unlike cgroups' hierarchy, it has single level
interfaces in a container. But unlike cgroups' hierarchy, it has single level
filesystem layout.
filesystem layout.
CAT and MBA features are introduced in Linux 4.10 and 4.12 kernel via
"resource control" filesystem.
Intel RDT "resource control" filesystem hierarchy:
Intel RDT "resource control" filesystem hierarchy:
```
```
mount -t resctrl resctrl /sys/fs/resctrl
mount -t resctrl resctrl /sys/fs/resctrl
...
@@ -182,59 +189,85 @@ tree /sys/fs/resctrl
...
@@ -182,59 +189,85 @@ tree /sys/fs/resctrl
/sys/fs/resctrl/
/sys/fs/resctrl/
|-- info
|-- info
| |-- L3
| |-- L3
| |-- cbm_mask
| | |-- cbm_mask
| |-- min_cbm_bits
| | |-- min_cbm_bits
| | |-- num_closids
| |-- MB
| |-- bandwidth_gran
| |-- delay_linear
| |-- min_bandwidth
| |-- num_closids
| |-- num_closids
|--
cpus
|--
...
|-- schemata
|-- schemata
|-- tasks
|-- tasks
|-- <container_id>
|-- <container_id>
|--
cpus
|--
...
|-- schemata
|-- schemata
|-- tasks
|-- tasks
```
```
For runc, we can make use of
`tasks`
and
`schemata`
configuration for L3
cache
For runc, we can make use of
`tasks`
and
`schemata`
configuration for L3
resource
constraints.
cache and memory bandwidth resources
constraints.
The file
`tasks`
has a list of tasks that belongs to this group (e.g.,
The file
`tasks`
has a list of tasks that belongs to this group (e.g.,
<container
_id
>
" group). Tasks can be added to a group by writing the task ID
<container
_id
>
" group). Tasks can be added to a group by writing the task ID
to the "tasks" file
(which will automatically remove them from the previous
to the "tasks" file (which will automatically remove them from the previous
group to which they belonged). New tasks created by fork(2) and clone(2) are
group to which they belonged). New tasks created by fork(2) and clone(2) are
added to the same group as their parent. If a pid is not in any sub group, it
added to the same group as their parent.
is in root group.
The file
`schemata`
has allocation masks/values for L3 cache on each socket,
The file
`schemata`
has a list of all the resources available to this group.
which contains L3 cache id and capacity bitmask (CBM).
Each resource (L3 cache, memory bandwidth) has its own line and format.
L3 cache schema:
It has allocation bitmasks/values for L3 cache on each socket, which
contains L3 cache id and capacity bitmask (CBM).
```
```
Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
```
```
For example, on a two-socket machine,
L3's schema line could be
`L3:0=ff;1=c0`
For example, on a two-socket machine,
the schema line could be "L3:0=ff;1=c0"
W
hich means L3 cache id 0's CBM is 0xff, and L3 cache id 1's CBM is 0xc0.
w
hich means L3 cache id 0's CBM is 0xff, and L3 cache id 1's CBM is 0xc0.
The valid L3 cache CBM is a
*contiguous bits set*
and number of bits that can
The valid L3 cache CBM is a
*contiguous bits set*
and number of bits that can
be set is less than the max bit. The max bits in the CBM is varied among
be set is less than the max bit. The max bits in the CBM is varied among
supported Intel Xeon platforms. In Intel RDT "resource control" filesystem
supported Intel CPU models. Kernel will check if it is valid when writing.
layout, the CBM in a group should be a subset of the CBM in root. Kernel will
e.g., default value 0xfffff in root indicates the max bits of CBM is 20
check if it is valid when writing. e.g., 0xfffff in root indicates the max bits
bits, which mapping to entire L3 cache capacity. Some valid CBM values to
of CBM is 20 bits, which mapping to entire L3 cache capacity. Some valid CBM
set in a group: 0xf, 0xf0, 0x3ff, 0x1f00 and etc.
values to set in a group: 0xf, 0xf0, 0x3ff, 0x1f00 and etc.
Memory bandwidth schema:
It has allocation values for memory bandwidth on each socket, which contains
L3 cache id and memory bandwidth percentage.
```
Format: "MB:<cache_id0>=bandwidth0;<cache_id1>=bandwidth1;..."
```
For example, on a two-socket machine, the schema line could be "MB:0=20;1=70"
The minimum bandwidth percentage value for each CPU model is predefined and
can be looked up through "info/MB/min_bandwidth". The bandwidth granularity
that is allocated is also dependent on the CPU model and can be looked up at
"info/MB/bandwidth_gran". The available bandwidth control steps are:
min_bw + N
*
bw_gran. Intermediate values are rounded to the next control
step available on the hardware.
For more information about Intel RDT
/CAT
kernel interface:
For more information about Intel RDT kernel interface:
https://www.kernel.org/doc/Documentation/x86/intel_rdt_ui.txt
https://www.kernel.org/doc/Documentation/x86/intel_rdt_ui.txt
An example for runc:
```
```
An example for runc:
Consider a two-socket machine with two L3 caches where the default CBM is
Consider a two-socket machine with two L3 caches where the default CBM is
0xfffff and the max CBM length is 20 bits. With this configuration, tasks
0x7ff and the max CBM length is 11 bits, and minimum memory bandwidth of 10%
inside the container only have access to the "upper" 80% of L3 cache id 0 and
with a memory bandwidth granularity of 10%.
the "lower" 50% L3 cache id 1:
Tasks inside the container only have access to the "upper" 7/11 of L3 cache
on socket 0 and the "lower" 5/11 L3 cache on socket 1, and may use a
maximum memory bandwidth of 20% on socket 0 and 70% on socket 1.
"linux": {
"linux": {
"intelRdt": {
"intelRdt": {
"l3CacheSchema": "L3:0=ffff0;1=3ff"
"closID": "guaranteed_group",
}
"l3CacheSchema": "L3:0=7f0;1=1f",
"memBwSchema": "MB:0=20;1=70"
}
}
}
```
```
...
...
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/BUILD
View file @
2b642765
...
@@ -12,6 +12,7 @@ go_library(
...
@@ -12,6 +12,7 @@ go_library(
"freezer.go",
"freezer.go",
"fs_unsupported.go",
"fs_unsupported.go",
"hugetlb.go",
"hugetlb.go",
"kmem.go",
"memory.go",
"memory.go",
"name.go",
"name.go",
"net_cls.go",
"net_cls.go",
...
@@ -29,6 +30,7 @@ go_library(
...
@@ -29,6 +30,7 @@ go_library(
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/system:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/system:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/utils:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/utils:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library",
],
],
"//conditions:default": [],
"//conditions:default": [],
...
...
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
View file @
2b642765
...
@@ -3,7 +3,6 @@
...
@@ -3,7 +3,6 @@
package
fs
package
fs
import
(
import
(
"errors"
"fmt"
"fmt"
"io"
"io"
"io/ioutil"
"io/ioutil"
...
@@ -14,6 +13,8 @@ import (
...
@@ -14,6 +13,8 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/configs"
libcontainerUtils
"github.com/opencontainers/runc/libcontainer/utils"
libcontainerUtils
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
)
)
var
(
var
(
...
@@ -35,7 +36,7 @@ var (
...
@@ -35,7 +36,7 @@ var (
HugePageSizes
,
_
=
cgroups
.
GetHugePageSize
()
HugePageSizes
,
_
=
cgroups
.
GetHugePageSize
()
)
)
var
errSubsystemDoesNotExist
=
errors
.
New
(
"cgroup: subsystem does not exist"
)
var
errSubsystemDoesNotExist
=
fmt
.
Errorf
(
"cgroup: subsystem does not exist"
)
type
subsystemSet
[]
subsystem
type
subsystemSet
[]
subsystem
...
@@ -62,9 +63,10 @@ type subsystem interface {
...
@@ -62,9 +63,10 @@ type subsystem interface {
}
}
type
Manager
struct
{
type
Manager
struct
{
mu
sync
.
Mutex
mu
sync
.
Mutex
Cgroups
*
configs
.
Cgroup
Cgroups
*
configs
.
Cgroup
Paths
map
[
string
]
string
Rootless
bool
// ignore permission-related errors
Paths
map
[
string
]
string
}
}
// The absolute path to the root of the cgroup hierarchies.
// The absolute path to the root of the cgroup hierarchies.
...
@@ -100,6 +102,33 @@ type cgroupData struct {
...
@@ -100,6 +102,33 @@ type cgroupData struct {
pid
int
pid
int
}
}
// isIgnorableError returns whether err is a permission error (in the loose
// sense of the word). This includes EROFS (which for an unprivileged user is
// basically a permission error) and EACCES (for similar reasons) as well as
// the normal EPERM.
func
isIgnorableError
(
rootless
bool
,
err
error
)
bool
{
// We do not ignore errors if we are root.
if
!
rootless
{
return
false
}
// Is it an ordinary EPERM?
if
os
.
IsPermission
(
errors
.
Cause
(
err
))
{
return
true
}
// Try to handle other errnos.
var
errno
error
switch
err
:=
errors
.
Cause
(
err
)
.
(
type
)
{
case
*
os
.
PathError
:
errno
=
err
.
Err
case
*
os
.
LinkError
:
errno
=
err
.
Err
case
*
os
.
SyscallError
:
errno
=
err
.
Err
}
return
errno
==
unix
.
EROFS
||
errno
==
unix
.
EPERM
||
errno
==
unix
.
EACCES
}
func
(
m
*
Manager
)
Apply
(
pid
int
)
(
err
error
)
{
func
(
m
*
Manager
)
Apply
(
pid
int
)
(
err
error
)
{
if
m
.
Cgroups
==
nil
{
if
m
.
Cgroups
==
nil
{
return
nil
return
nil
...
@@ -145,11 +174,11 @@ func (m *Manager) Apply(pid int) (err error) {
...
@@ -145,11 +174,11 @@ func (m *Manager) Apply(pid int) (err error) {
m
.
Paths
[
sys
.
Name
()]
=
p
m
.
Paths
[
sys
.
Name
()]
=
p
if
err
:=
sys
.
Apply
(
d
);
err
!=
nil
{
if
err
:=
sys
.
Apply
(
d
);
err
!=
nil
{
if
os
.
IsPermission
(
err
)
&&
m
.
Cgroups
.
Path
==
""
{
// In the case of rootless (including euid=0 in userns), where an explicit cgroup path hasn't
// If we didn't set a cgroup path, then let's defer the error here
// been set, we don't bail on error in case of permission problems.
// until we know whether we have set limits or not.
// Cases where limits have been set (and we couldn't create our own
// If we hadn't set limits, then it's ok that we couldn't join this cgroup, because
// cgroup) are handled by Set.
// it will have the same limits as its parent.
if
isIgnorableError
(
m
.
Rootless
,
err
)
&&
m
.
Cgroups
.
Path
==
""
{
delete
(
m
.
Paths
,
sys
.
Name
())
delete
(
m
.
Paths
,
sys
.
Name
())
continue
continue
}
}
...
@@ -207,9 +236,16 @@ func (m *Manager) Set(container *configs.Config) error {
...
@@ -207,9 +236,16 @@ func (m *Manager) Set(container *configs.Config) error {
for
_
,
sys
:=
range
subsystems
{
for
_
,
sys
:=
range
subsystems
{
path
:=
paths
[
sys
.
Name
()]
path
:=
paths
[
sys
.
Name
()]
if
err
:=
sys
.
Set
(
path
,
container
.
Cgroups
);
err
!=
nil
{
if
err
:=
sys
.
Set
(
path
,
container
.
Cgroups
);
err
!=
nil
{
if
m
.
Rootless
&&
sys
.
Name
()
==
"devices"
{
continue
}
// When m.Rootless is true, errors from the device subsystem are ignored because it is really not expected to work.
// However, errors from other subsystems are not ignored.
// see @test "runc create (rootless + limits + no cgrouppath + no permission) fails with informative error"
if
path
==
""
{
if
path
==
""
{
// cgroup never applied
// We never created a path for this cgroup, so we cannot set
return
fmt
.
Errorf
(
"cannot set limits on the %s cgroup, as the container has not joined it"
,
sys
.
Name
())
// limits for it (though we have already tried at this point).
return
fmt
.
Errorf
(
"cannot set %s limit: container could not join or create cgroup"
,
sys
.
Name
())
}
}
return
err
return
err
}
}
...
...
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go
View file @
2b642765
...
@@ -46,11 +46,7 @@ func (s *CpuGroup) ApplyDir(path string, cgroup *configs.Cgroup, pid int) error
...
@@ -46,11 +46,7 @@ func (s *CpuGroup) ApplyDir(path string, cgroup *configs.Cgroup, pid int) error
}
}
// because we are not using d.join we need to place the pid into the procs file
// because we are not using d.join we need to place the pid into the procs file
// unlike the other subsystems
// unlike the other subsystems
if
err
:=
cgroups
.
WriteCgroupProc
(
path
,
pid
);
err
!=
nil
{
return
cgroups
.
WriteCgroupProc
(
path
,
pid
)
return
err
}
return
nil
}
}
func
(
s
*
CpuGroup
)
SetRtSched
(
path
string
,
cgroup
*
configs
.
Cgroup
)
error
{
func
(
s
*
CpuGroup
)
SetRtSched
(
path
string
,
cgroup
*
configs
.
Cgroup
)
error
{
...
@@ -83,11 +79,7 @@ func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error {
...
@@ -83,11 +79,7 @@ func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error {
return
err
return
err
}
}
}
}
if
err
:=
s
.
SetRtSched
(
path
,
cgroup
);
err
!=
nil
{
return
s
.
SetRtSched
(
path
,
cgroup
)
return
err
}
return
nil
}
}
func
(
s
*
CpuGroup
)
Remove
(
d
*
cgroupData
)
error
{
func
(
s
*
CpuGroup
)
Remove
(
d
*
cgroupData
)
error
{
...
...
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go
View file @
2b642765
...
@@ -77,18 +77,14 @@ func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) erro
...
@@ -77,18 +77,14 @@ func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) erro
// The logic is, if user specified cpuset configs, use these
// The logic is, if user specified cpuset configs, use these
// specified configs, otherwise, inherit from parent. This makes
// specified configs, otherwise, inherit from parent. This makes
// cpuset configs work correctly with 'cpuset.cpu_exclusive', and
// cpuset configs work correctly with 'cpuset.cpu_exclusive', and
// keep backward compatbility.
// keep backward compat
i
bility.
if
err
:=
s
.
ensureCpusAndMems
(
dir
,
cgroup
);
err
!=
nil
{
if
err
:=
s
.
ensureCpusAndMems
(
dir
,
cgroup
);
err
!=
nil
{
return
err
return
err
}
}
// because we are not using d.join we need to place the pid into the procs file
// because we are not using d.join we need to place the pid into the procs file
// unlike the other subsystems
// unlike the other subsystems
if
err
:=
cgroups
.
WriteCgroupProc
(
dir
,
pid
);
err
!=
nil
{
return
cgroups
.
WriteCgroupProc
(
dir
,
pid
)
return
err
}
return
nil
}
}
func
(
s
*
CpusetGroup
)
getSubsystemSettings
(
parent
string
)
(
cpus
[]
byte
,
mems
[]
byte
,
err
error
)
{
func
(
s
*
CpusetGroup
)
getSubsystemSettings
(
parent
string
)
(
cpus
[]
byte
,
mems
[]
byte
,
err
error
)
{
...
...
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/kmem.go
0 → 100644
View file @
2b642765
// +build linux,!nokmem
package
fs
import
(
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"syscall"
// for Errno type only
"github.com/opencontainers/runc/libcontainer/cgroups"
"golang.org/x/sys/unix"
)
const
cgroupKernelMemoryLimit
=
"memory.kmem.limit_in_bytes"
func
EnableKernelMemoryAccounting
(
path
string
)
error
{
// Check if kernel memory is enabled
// We have to limit the kernel memory here as it won't be accounted at all
// until a limit is set on the cgroup and limit cannot be set once the
// cgroup has children, or if there are already tasks in the cgroup.
for
_
,
i
:=
range
[]
int64
{
1
,
-
1
}
{
if
err
:=
setKernelMemory
(
path
,
i
);
err
!=
nil
{
return
err
}
}
return
nil
}
func
setKernelMemory
(
path
string
,
kernelMemoryLimit
int64
)
error
{
if
path
==
""
{
return
fmt
.
Errorf
(
"no such directory for %s"
,
cgroupKernelMemoryLimit
)
}
if
!
cgroups
.
PathExists
(
filepath
.
Join
(
path
,
cgroupKernelMemoryLimit
))
{
// kernel memory is not enabled on the system so we should do nothing
return
nil
}
if
err
:=
ioutil
.
WriteFile
(
filepath
.
Join
(
path
,
cgroupKernelMemoryLimit
),
[]
byte
(
strconv
.
FormatInt
(
kernelMemoryLimit
,
10
)),
0700
);
err
!=
nil
{
// Check if the error number returned by the syscall is "EBUSY"
// The EBUSY signal is returned on attempts to write to the
// memory.kmem.limit_in_bytes file if the cgroup has children or
// once tasks have been attached to the cgroup
if
pathErr
,
ok
:=
err
.
(
*
os
.
PathError
);
ok
{
if
errNo
,
ok
:=
pathErr
.
Err
.
(
syscall
.
Errno
);
ok
{
if
errNo
==
unix
.
EBUSY
{
return
fmt
.
Errorf
(
"failed to set %s, because either tasks have already joined this cgroup or it has children"
,
cgroupKernelMemoryLimit
)
}
}
}
return
fmt
.
Errorf
(
"failed to write %v to %v: %v"
,
kernelMemoryLimit
,
cgroupKernelMemoryLimit
,
err
)
}
return
nil
}
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/kmem_disabled.go
0 → 100644
View file @
2b642765
// +build linux,nokmem
package
fs
func
EnableKernelMemoryAccounting
(
path
string
)
error
{
return
nil
}
func
setKernelMemory
(
path
string
,
kernelMemoryLimit
int64
)
error
{
return
nil
}
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
View file @
2b642765
...
@@ -5,23 +5,18 @@ package fs
...
@@ -5,23 +5,18 @@ package fs
import
(
import
(
"bufio"
"bufio"
"fmt"
"fmt"
"io/ioutil"
"os"
"os"
"path/filepath"
"path/filepath"
"strconv"
"strconv"
"strings"
"strings"
"syscall"
// only for Errno
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/configs"
"golang.org/x/sys/unix"
)
)
const
(
const
(
cgroupKernelMemoryLimit
=
"memory.kmem.limit_in_bytes"
cgroupMemorySwapLimit
=
"memory.memsw.limit_in_bytes"
cgroupMemorySwapLimit
=
"memory.memsw.limit_in_bytes"
cgroupMemoryLimit
=
"memory.limit_in_bytes"
cgroupMemoryLimit
=
"memory.limit_in_bytes"
)
)
type
MemoryGroup
struct
{
type
MemoryGroup
struct
{
...
@@ -67,44 +62,6 @@ func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
...
@@ -67,44 +62,6 @@ func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
return
nil
return
nil
}
}
func
EnableKernelMemoryAccounting
(
path
string
)
error
{
// Check if kernel memory is enabled
// We have to limit the kernel memory here as it won't be accounted at all
// until a limit is set on the cgroup and limit cannot be set once the
// cgroup has children, or if there are already tasks in the cgroup.
for
_
,
i
:=
range
[]
int64
{
1
,
-
1
}
{
if
err
:=
setKernelMemory
(
path
,
i
);
err
!=
nil
{
return
err
}
}
return
nil
}
func
setKernelMemory
(
path
string
,
kernelMemoryLimit
int64
)
error
{
if
path
==
""
{
return
fmt
.
Errorf
(
"no such directory for %s"
,
cgroupKernelMemoryLimit
)
}
if
!
cgroups
.
PathExists
(
filepath
.
Join
(
path
,
cgroupKernelMemoryLimit
))
{
// kernel memory is not enabled on the system so we should do nothing
return
nil
}
if
err
:=
ioutil
.
WriteFile
(
filepath
.
Join
(
path
,
cgroupKernelMemoryLimit
),
[]
byte
(
strconv
.
FormatInt
(
kernelMemoryLimit
,
10
)),
0700
);
err
!=
nil
{
// Check if the error number returned by the syscall is "EBUSY"
// The EBUSY signal is returned on attempts to write to the
// memory.kmem.limit_in_bytes file if the cgroup has children or
// once tasks have been attached to the cgroup
if
pathErr
,
ok
:=
err
.
(
*
os
.
PathError
);
ok
{
if
errNo
,
ok
:=
pathErr
.
Err
.
(
syscall
.
Errno
);
ok
{
if
errNo
==
unix
.
EBUSY
{
return
fmt
.
Errorf
(
"failed to set %s, because either tasks have already joined this cgroup or it has children"
,
cgroupKernelMemoryLimit
)
}
}
}
return
fmt
.
Errorf
(
"failed to write %v to %v: %v"
,
kernelMemoryLimit
,
cgroupKernelMemoryLimit
,
err
)
}
return
nil
}
func
setMemoryAndSwap
(
path
string
,
cgroup
*
configs
.
Cgroup
)
error
{
func
setMemoryAndSwap
(
path
string
,
cgroup
*
configs
.
Cgroup
)
error
{
// If the memory update is set to -1 we should also
// If the memory update is set to -1 we should also
// set swap to -1, it means unlimited memory.
// set swap to -1, it means unlimited memory.
...
...
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
View file @
2b642765
...
@@ -5,6 +5,7 @@ package systemd
...
@@ -5,6 +5,7 @@ package systemd
import
(
import
(
"errors"
"errors"
"fmt"
"fmt"
"math"
"os"
"os"
"path/filepath"
"path/filepath"
"strings"
"strings"
...
@@ -295,13 +296,19 @@ func (m *Manager) Apply(pid int) error {
...
@@ -295,13 +296,19 @@ func (m *Manager) Apply(pid int) error {
// cpu.cfs_quota_us and cpu.cfs_period_us are controlled by systemd.
// cpu.cfs_quota_us and cpu.cfs_period_us are controlled by systemd.
if
c
.
Resources
.
CpuQuota
!=
0
&&
c
.
Resources
.
CpuPeriod
!=
0
{
if
c
.
Resources
.
CpuQuota
!=
0
&&
c
.
Resources
.
CpuPeriod
!=
0
{
cpuQuotaPerSecUSec
:=
uint64
(
c
.
Resources
.
CpuQuota
*
1000000
)
/
c
.
Resources
.
CpuPeriod
// corresponds to USEC_INFINITY in systemd
// systemd converts CPUQuotaPerSecUSec (microseconds per CPU second) to CPUQuota
// if USEC_INFINITY is provided, CPUQuota is left unbound by systemd
// (integer percentage of CPU) internally. This means that if a fractional percent of
// always setting a property value ensures we can apply a quota and remove it later
// CPU is indicated by Resources.CpuQuota, we need to round up to the nearest
cpuQuotaPerSecUSec
:=
uint64
(
math
.
MaxUint64
)
// 10ms (1% of a second) such that child cgroups can set the cpu.cfs_quota_us they expect.
if
c
.
Resources
.
CpuQuota
>
0
{
if
cpuQuotaPerSecUSec
%
10000
!=
0
{
// systemd converts CPUQuotaPerSecUSec (microseconds per CPU second) to CPUQuota
cpuQuotaPerSecUSec
=
((
cpuQuotaPerSecUSec
/
10000
)
+
1
)
*
10000
// (integer percentage of CPU) internally. This means that if a fractional percent of
// CPU is indicated by Resources.CpuQuota, we need to round up to the nearest
// 10ms (1% of a second) such that child cgroups can set the cpu.cfs_quota_us they expect.
cpuQuotaPerSecUSec
=
uint64
(
c
.
Resources
.
CpuQuota
*
1000000
)
/
c
.
Resources
.
CpuPeriod
if
cpuQuotaPerSecUSec
%
10000
!=
0
{
cpuQuotaPerSecUSec
=
((
cpuQuotaPerSecUSec
/
10000
)
+
1
)
*
10000
}
}
}
properties
=
append
(
properties
,
properties
=
append
(
properties
,
newProp
(
"CPUQuotaPerSecUSec"
,
cpuQuotaPerSecUSec
))
newProp
(
"CPUQuotaPerSecUSec"
,
cpuQuotaPerSecUSec
))
...
@@ -312,6 +319,12 @@ func (m *Manager) Apply(pid int) error {
...
@@ -312,6 +319,12 @@ func (m *Manager) Apply(pid int) error {
newProp
(
"BlockIOWeight"
,
uint64
(
c
.
Resources
.
BlkioWeight
)))
newProp
(
"BlockIOWeight"
,
uint64
(
c
.
Resources
.
BlkioWeight
)))
}
}
if
c
.
Resources
.
PidsLimit
>
0
{
properties
=
append
(
properties
,
newProp
(
"TasksAccounting"
,
true
),
newProp
(
"TasksMax"
,
uint64
(
c
.
Resources
.
PidsLimit
)))
}
// We have to set kernel memory here, as we can't change it once
// We have to set kernel memory here, as we can't change it once
// processes have been attached to the cgroup.
// processes have been attached to the cgroup.
if
c
.
Resources
.
KernelMemory
!=
0
{
if
c
.
Resources
.
KernelMemory
!=
0
{
...
...
vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
View file @
2b642765
...
@@ -13,7 +13,7 @@ import (
...
@@ -13,7 +13,7 @@ import (
"strings"
"strings"
"time"
"time"
"github.com/docker/go-units"
units
"github.com/docker/go-units"
)
)
const
(
const
(
...
@@ -103,7 +103,7 @@ func FindCgroupMountpointDir() (string, error) {
...
@@ -103,7 +103,7 @@ func FindCgroupMountpointDir() (string, error) {
}
}
if
postSeparatorFields
[
0
]
==
"cgroup"
{
if
postSeparatorFields
[
0
]
==
"cgroup"
{
// Check that the mount is properly formated.
// Check that the mount is properly format
t
ed.
if
numPostFields
<
3
{
if
numPostFields
<
3
{
return
""
,
fmt
.
Errorf
(
"Error found less than 3 fields post '-' in %q"
,
text
)
return
""
,
fmt
.
Errorf
(
"Error found less than 3 fields post '-' in %q"
,
text
)
}
}
...
@@ -151,19 +151,20 @@ func getCgroupMountsHelper(ss map[string]bool, mi io.Reader, all bool) ([]Mount,
...
@@ -151,19 +151,20 @@ func getCgroupMountsHelper(ss map[string]bool, mi io.Reader, all bool) ([]Mount,
Root
:
fields
[
3
],
Root
:
fields
[
3
],
}
}
for
_
,
opt
:=
range
strings
.
Split
(
fields
[
len
(
fields
)
-
1
],
","
)
{
for
_
,
opt
:=
range
strings
.
Split
(
fields
[
len
(
fields
)
-
1
],
","
)
{
if
!
ss
[
opt
]
{
seen
,
known
:=
ss
[
opt
]
if
!
known
||
(
!
all
&&
seen
)
{
continue
continue
}
}
ss
[
opt
]
=
true
if
strings
.
HasPrefix
(
opt
,
cgroupNamePrefix
)
{
if
strings
.
HasPrefix
(
opt
,
cgroupNamePrefix
)
{
m
.
Subsystems
=
append
(
m
.
Subsystems
,
opt
[
len
(
cgroupNamePrefix
)
:
])
opt
=
opt
[
len
(
cgroupNamePrefix
)
:
]
}
else
{
m
.
Subsystems
=
append
(
m
.
Subsystems
,
opt
)
}
if
!
all
{
numFound
++
}
}
m
.
Subsystems
=
append
(
m
.
Subsystems
,
opt
)
numFound
++
}
if
len
(
m
.
Subsystems
)
>
0
||
all
{
res
=
append
(
res
,
m
)
}
}
res
=
append
(
res
,
m
)
}
}
if
err
:=
scanner
.
Err
();
err
!=
nil
{
if
err
:=
scanner
.
Err
();
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -187,7 +188,7 @@ func GetCgroupMounts(all bool) ([]Mount, error) {
...
@@ -187,7 +188,7 @@ func GetCgroupMounts(all bool) ([]Mount, error) {
allMap
:=
make
(
map
[
string
]
bool
)
allMap
:=
make
(
map
[
string
]
bool
)
for
s
:=
range
allSubsystems
{
for
s
:=
range
allSubsystems
{
allMap
[
s
]
=
tru
e
allMap
[
s
]
=
fals
e
}
}
return
getCgroupMountsHelper
(
allMap
,
f
,
all
)
return
getCgroupMountsHelper
(
allMap
,
f
,
all
)
}
}
...
@@ -262,7 +263,7 @@ func getCgroupPathHelper(subsystem, cgroup string) (string, error) {
...
@@ -262,7 +263,7 @@ func getCgroupPathHelper(subsystem, cgroup string) (string, error) {
}
}
// This is needed for nested containers, because in /proc/self/cgroup we
// This is needed for nested containers, because in /proc/self/cgroup we
// see path
e
s from host, which don't exist in container.
// see paths from host, which don't exist in container.
relCgroup
,
err
:=
filepath
.
Rel
(
root
,
cgroup
)
relCgroup
,
err
:=
filepath
.
Rel
(
root
,
cgroup
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
...
...
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
View file @
2b642765
...
@@ -141,9 +141,10 @@ type Config struct {
...
@@ -141,9 +141,10 @@ type Config struct {
// OomScoreAdj specifies the adjustment to be made by the kernel when calculating oom scores
// OomScoreAdj specifies the adjustment to be made by the kernel when calculating oom scores
// for a process. Valid values are between the range [-1000, '1000'], where processes with
// for a process. Valid values are between the range [-1000, '1000'], where processes with
// higher scores are preferred for being killed.
// higher scores are preferred for being killed. If it is unset then we don't touch the current
// value.
// More information about kernel oom score calculation here: https://lwn.net/Articles/317814/
// More information about kernel oom score calculation here: https://lwn.net/Articles/317814/
OomScoreAdj
int
`json:"oom_score_adj
"`
OomScoreAdj
*
int
`json:"oom_score_adj,omitempty
"`
// UidMappings is an array of User ID mappings for User Namespaces
// UidMappings is an array of User ID mappings for User Namespaces
UidMappings
[]
IDMap
`json:"uid_mappings"`
UidMappings
[]
IDMap
`json:"uid_mappings"`
...
@@ -185,12 +186,19 @@ type Config struct {
...
@@ -185,12 +186,19 @@ type Config struct {
// callers keyring in this case.
// callers keyring in this case.
NoNewKeyring
bool
`json:"no_new_keyring"`
NoNewKeyring
bool
`json:"no_new_keyring"`
// Rootless specifies whether the container is a rootless container.
// IntelRdt specifies settings for Intel RDT group that the container is placed into
Rootless
bool
`json:"rootless"`
// to limit the resources (e.g., L3 cache, memory bandwidth) the container has available
// IntelRdt specifies settings for Intel RDT/CAT group that the container is placed into
// to limit the resources (e.g., L3 cache) the container has available
IntelRdt
*
IntelRdt
`json:"intel_rdt,omitempty"`
IntelRdt
*
IntelRdt
`json:"intel_rdt,omitempty"`
// RootlessEUID is set when the runc was launched with non-zero EUID.
// Note that RootlessEUID is set to false when launched with EUID=0 in userns.
// When RootlessEUID is set, runc creates a new userns for the container.
// (config.json needs to contain userns settings)
RootlessEUID
bool
`json:"rootless_euid,omitempty"`
// RootlessCgroups is set when unlikely to have the full access to cgroups.
// When RootlessCgroups is set, cgroups errors are ignored.
RootlessCgroups
bool
`json:"rootless_cgroups,omitempty"`
}
}
type
Hooks
struct
{
type
Hooks
struct
{
...
...
vendor/github.com/opencontainers/runc/libcontainer/configs/intelrdt.go
View file @
2b642765
...
@@ -4,4 +4,8 @@ type IntelRdt struct {
...
@@ -4,4 +4,8 @@ type IntelRdt struct {
// The schema for L3 cache id and capacity bitmask (CBM)
// The schema for L3 cache id and capacity bitmask (CBM)
// Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
// Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
L3CacheSchema
string
`json:"l3_cache_schema,omitempty"`
L3CacheSchema
string
`json:"l3_cache_schema,omitempty"`
// The schema of memory bandwidth percentage per L3 cache id
// Format: "MB:<cache_id0>=bandwidth0;<cache_id1>=bandwidth1;..."
MemBwSchema
string
`json:"memBwSchema,omitempty"`
}
}
vendor/github.com/opencontainers/runc/libcontainer/configs/validate/rootless.go
View file @
2b642765
...
@@ -2,23 +2,18 @@ package validate
...
@@ -2,23 +2,18 @@ package validate
import
(
import
(
"fmt"
"fmt"
"os"
"reflect"
"strings"
"strings"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/configs"
)
)
var
(
// rootlessEUID makes sure that the config can be applied when runc
geteuid
=
os
.
Geteuid
// is being executed as a non-root user (euid != 0) in the current user namespace.
getegid
=
os
.
Getegid
func
(
v
*
ConfigValidator
)
rootlessEUID
(
config
*
configs
.
Config
)
error
{
)
if
err
:=
rootlessEUIDMappings
(
config
);
err
!=
nil
{
func
(
v
*
ConfigValidator
)
rootless
(
config
*
configs
.
Config
)
error
{
if
err
:=
rootlessMappings
(
config
);
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
rootlessMount
(
config
);
err
!=
nil
{
if
err
:=
rootless
EUID
Mount
(
config
);
err
!=
nil
{
return
err
return
err
}
}
...
@@ -38,11 +33,9 @@ func hasIDMapping(id int, mappings []configs.IDMap) bool {
...
@@ -38,11 +33,9 @@ func hasIDMapping(id int, mappings []configs.IDMap) bool {
return
false
return
false
}
}
func
rootlessMappings
(
config
*
configs
.
Config
)
error
{
func
rootlessEUIDMappings
(
config
*
configs
.
Config
)
error
{
if
euid
:=
geteuid
();
euid
!=
0
{
if
!
config
.
Namespaces
.
Contains
(
configs
.
NEWUSER
)
{
if
!
config
.
Namespaces
.
Contains
(
configs
.
NEWUSER
)
{
return
fmt
.
Errorf
(
"rootless container requires user namespaces"
)
return
fmt
.
Errorf
(
"rootless containers require user namespaces"
)
}
}
}
if
len
(
config
.
UidMappings
)
==
0
{
if
len
(
config
.
UidMappings
)
==
0
{
...
@@ -51,34 +44,13 @@ func rootlessMappings(config *configs.Config) error {
...
@@ -51,34 +44,13 @@ func rootlessMappings(config *configs.Config) error {
if
len
(
config
.
GidMappings
)
==
0
{
if
len
(
config
.
GidMappings
)
==
0
{
return
fmt
.
Errorf
(
"rootless containers requires at least one GID mapping"
)
return
fmt
.
Errorf
(
"rootless containers requires at least one GID mapping"
)
}
}
return
nil
}
// cgroup verifies that the user isn't trying to set any cgroup limits or paths.
func
rootlessCgroup
(
config
*
configs
.
Config
)
error
{
// Nothing set at all.
if
config
.
Cgroups
==
nil
||
config
.
Cgroups
.
Resources
==
nil
{
return
nil
}
// Used for comparing to the zero value.
left
:=
reflect
.
ValueOf
(
*
config
.
Cgroups
.
Resources
)
right
:=
reflect
.
Zero
(
left
.
Type
())
// This is all we need to do, since specconv won't add cgroup options in
// rootless mode.
if
!
reflect
.
DeepEqual
(
left
.
Interface
(),
right
.
Interface
())
{
return
fmt
.
Errorf
(
"cannot specify resource limits in rootless container"
)
}
return
nil
return
nil
}
}
// mount verifies that the user isn't trying to set up any mounts they don't have
// mount verifies that the user isn't trying to set up any mounts they don't have
// the rights to do. In addition, it makes sure that no mount has a `uid=` or
// the rights to do. In addition, it makes sure that no mount has a `uid=` or
// `gid=` option that doesn't resolve to root.
// `gid=` option that doesn't resolve to root.
func
rootlessMount
(
config
*
configs
.
Config
)
error
{
func
rootless
EUID
Mount
(
config
*
configs
.
Config
)
error
{
// XXX: We could whitelist allowed devices at this point, but I'm not
// XXX: We could whitelist allowed devices at this point, but I'm not
// convinced that's a good idea. The kernel is the best arbiter of
// convinced that's a good idea. The kernel is the best arbiter of
// access control.
// access control.
...
...
vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go
View file @
2b642765
...
@@ -44,8 +44,8 @@ func (v *ConfigValidator) Validate(config *configs.Config) error {
...
@@ -44,8 +44,8 @@ func (v *ConfigValidator) Validate(config *configs.Config) error {
if
err
:=
v
.
intelrdt
(
config
);
err
!=
nil
{
if
err
:=
v
.
intelrdt
(
config
);
err
!=
nil
{
return
err
return
err
}
}
if
config
.
Rootless
{
if
config
.
Rootless
EUID
{
if
err
:=
v
.
rootless
(
config
);
err
!=
nil
{
if
err
:=
v
.
rootless
EUID
(
config
);
err
!=
nil
{
return
err
return
err
}
}
}
}
...
@@ -151,6 +151,16 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error {
...
@@ -151,6 +151,16 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error {
return
fmt
.
Errorf
(
"sysctl %q is not allowed in the hosts network namespace"
,
s
)
return
fmt
.
Errorf
(
"sysctl %q is not allowed in the hosts network namespace"
,
s
)
}
}
}
}
if
config
.
Namespaces
.
Contains
(
configs
.
NEWUTS
)
{
switch
s
{
case
"kernel.domainname"
:
// This is namespaced and there's no explicit OCI field for it.
continue
case
"kernel.hostname"
:
// This is namespaced but there's a conflicting (dedicated) OCI field for it.
return
fmt
.
Errorf
(
"sysctl %q is not allowed as it conflicts with the OCI %q field"
,
s
,
"hostname"
)
}
}
return
fmt
.
Errorf
(
"sysctl %q is not in a separate kernel namespace"
,
s
)
return
fmt
.
Errorf
(
"sysctl %q is not in a separate kernel namespace"
,
s
)
}
}
...
@@ -159,11 +169,22 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error {
...
@@ -159,11 +169,22 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error {
func
(
v
*
ConfigValidator
)
intelrdt
(
config
*
configs
.
Config
)
error
{
func
(
v
*
ConfigValidator
)
intelrdt
(
config
*
configs
.
Config
)
error
{
if
config
.
IntelRdt
!=
nil
{
if
config
.
IntelRdt
!=
nil
{
if
!
intelrdt
.
IsEnabled
()
{
if
!
intelrdt
.
IsCatEnabled
()
&&
!
intelrdt
.
IsMbaEnabled
()
{
return
fmt
.
Errorf
(
"intelRdt is specified in config, but Intel RDT feature is not supported or enabled"
)
return
fmt
.
Errorf
(
"intelRdt is specified in config, but Intel RDT is not supported or enabled"
)
}
if
!
intelrdt
.
IsCatEnabled
()
&&
config
.
IntelRdt
.
L3CacheSchema
!=
""
{
return
fmt
.
Errorf
(
"intelRdt.l3CacheSchema is specified in config, but Intel RDT/CAT is not enabled"
)
}
if
!
intelrdt
.
IsMbaEnabled
()
&&
config
.
IntelRdt
.
MemBwSchema
!=
""
{
return
fmt
.
Errorf
(
"intelRdt.memBwSchema is specified in config, but Intel RDT/MBA is not enabled"
)
}
if
intelrdt
.
IsCatEnabled
()
&&
config
.
IntelRdt
.
L3CacheSchema
==
""
{
return
fmt
.
Errorf
(
"Intel RDT/CAT is enabled and intelRdt is specified in config, but intelRdt.l3CacheSchema is empty"
)
}
}
if
config
.
IntelRdt
.
L3Cache
Schema
==
""
{
if
intelrdt
.
IsMbaEnabled
()
&&
config
.
IntelRdt
.
MemBw
Schema
==
""
{
return
fmt
.
Errorf
(
"
intelRdt is specified in config, but intelRdt.l3Cache
Schema is empty"
)
return
fmt
.
Errorf
(
"
Intel RDT/MBA is enabled and intelRdt is specified in config, but intelRdt.memBw
Schema is empty"
)
}
}
}
}
...
...
vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
View file @
2b642765
This diff is collapsed.
Click to expand it.
vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go
View file @
2b642765
...
@@ -11,6 +11,7 @@ import (
...
@@ -11,6 +11,7 @@ import (
"runtime/debug"
"runtime/debug"
"strconv"
"strconv"
"github.com/cyphar/filepath-securejoin"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
...
@@ -59,9 +60,9 @@ func SystemdCgroups(l *LinuxFactory) error {
...
@@ -59,9 +60,9 @@ func SystemdCgroups(l *LinuxFactory) error {
return
nil
return
nil
}
}
// Cgroupfs is an options func to configure a LinuxFactory to return
// Cgroupfs is an options func to configure a LinuxFactory to return
containers
//
containers that use the native cgroups filesystem implementation to
//
that use the native cgroups filesystem implementation to create and manage
// c
reate and manage c
groups.
// cgroups.
func
Cgroupfs
(
l
*
LinuxFactory
)
error
{
func
Cgroupfs
(
l
*
LinuxFactory
)
error
{
l
.
NewCgroupsManager
=
func
(
config
*
configs
.
Cgroup
,
paths
map
[
string
]
string
)
cgroups
.
Manager
{
l
.
NewCgroupsManager
=
func
(
config
*
configs
.
Cgroup
,
paths
map
[
string
]
string
)
cgroups
.
Manager
{
return
&
fs
.
Manager
{
return
&
fs
.
Manager
{
...
@@ -72,9 +73,26 @@ func Cgroupfs(l *LinuxFactory) error {
...
@@ -72,9 +73,26 @@ func Cgroupfs(l *LinuxFactory) error {
return
nil
return
nil
}
}
// RootlessCgroupfs is an options func to configure a LinuxFactory to return
// containers that use the native cgroups filesystem implementation to create
// and manage cgroups. The difference between RootlessCgroupfs and Cgroupfs is
// that RootlessCgroupfs can transparently handle permission errors that occur
// during rootless container (including euid=0 in userns) setup (while still allowing cgroup usage if
// they've been set up properly).
func
RootlessCgroupfs
(
l
*
LinuxFactory
)
error
{
l
.
NewCgroupsManager
=
func
(
config
*
configs
.
Cgroup
,
paths
map
[
string
]
string
)
cgroups
.
Manager
{
return
&
fs
.
Manager
{
Cgroups
:
config
,
Rootless
:
true
,
Paths
:
paths
,
}
}
return
nil
}
// IntelRdtfs is an options func to configure a LinuxFactory to return
// IntelRdtfs is an options func to configure a LinuxFactory to return
// containers that use the Intel RDT "resource control" filesystem to
// containers that use the Intel RDT "resource control" filesystem to
// create and manage Intel
Xeon platform shared resources (e.g., L3 cache
).
// create and manage Intel
RDT resources (e.g., L3 cache, memory bandwidth
).
func
IntelRdtFs
(
l
*
LinuxFactory
)
error
{
func
IntelRdtFs
(
l
*
LinuxFactory
)
error
{
l
.
NewIntelRdtManager
=
func
(
config
*
configs
.
Config
,
id
string
,
path
string
)
intelrdt
.
Manager
{
l
.
NewIntelRdtManager
=
func
(
config
*
configs
.
Config
,
id
string
,
path
string
)
intelrdt
.
Manager
{
return
&
intelrdt
.
IntelRdtManager
{
return
&
intelrdt
.
IntelRdtManager
{
...
@@ -178,7 +196,10 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
...
@@ -178,7 +196,10 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
if
err
:=
l
.
Validator
.
Validate
(
config
);
err
!=
nil
{
if
err
:=
l
.
Validator
.
Validate
(
config
);
err
!=
nil
{
return
nil
,
newGenericError
(
err
,
ConfigInvalid
)
return
nil
,
newGenericError
(
err
,
ConfigInvalid
)
}
}
containerRoot
:=
filepath
.
Join
(
l
.
Root
,
id
)
containerRoot
,
err
:=
securejoin
.
SecureJoin
(
l
.
Root
,
id
)
if
err
!=
nil
{
return
nil
,
err
}
if
_
,
err
:=
os
.
Stat
(
containerRoot
);
err
==
nil
{
if
_
,
err
:=
os
.
Stat
(
containerRoot
);
err
==
nil
{
return
nil
,
newGenericError
(
fmt
.
Errorf
(
"container with id exists: %v"
,
id
),
IdInUse
)
return
nil
,
newGenericError
(
fmt
.
Errorf
(
"container with id exists: %v"
,
id
),
IdInUse
)
}
else
if
!
os
.
IsNotExist
(
err
)
{
}
else
if
!
os
.
IsNotExist
(
err
)
{
...
@@ -201,7 +222,7 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
...
@@ -201,7 +222,7 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
newgidmapPath
:
l
.
NewgidmapPath
,
newgidmapPath
:
l
.
NewgidmapPath
,
cgroupManager
:
l
.
NewCgroupsManager
(
config
.
Cgroups
,
nil
),
cgroupManager
:
l
.
NewCgroupsManager
(
config
.
Cgroups
,
nil
),
}
}
if
intelrdt
.
IsEnabled
()
{
if
intelrdt
.
Is
CatEnabled
()
||
intelrdt
.
IsMba
Enabled
()
{
c
.
intelRdtManager
=
l
.
NewIntelRdtManager
(
config
,
id
,
""
)
c
.
intelRdtManager
=
l
.
NewIntelRdtManager
(
config
,
id
,
""
)
}
}
c
.
state
=
&
stoppedState
{
c
:
c
}
c
.
state
=
&
stoppedState
{
c
:
c
}
...
@@ -212,7 +233,14 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
...
@@ -212,7 +233,14 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
if
l
.
Root
==
""
{
if
l
.
Root
==
""
{
return
nil
,
newGenericError
(
fmt
.
Errorf
(
"invalid root"
),
ConfigInvalid
)
return
nil
,
newGenericError
(
fmt
.
Errorf
(
"invalid root"
),
ConfigInvalid
)
}
}
containerRoot
:=
filepath
.
Join
(
l
.
Root
,
id
)
//when load, we need to check id is valid or not.
if
err
:=
l
.
validateID
(
id
);
err
!=
nil
{
return
nil
,
err
}
containerRoot
,
err
:=
securejoin
.
SecureJoin
(
l
.
Root
,
id
)
if
err
!=
nil
{
return
nil
,
err
}
state
,
err
:=
l
.
loadState
(
containerRoot
,
id
)
state
,
err
:=
l
.
loadState
(
containerRoot
,
id
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -240,7 +268,7 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
...
@@ -240,7 +268,7 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
if
err
:=
c
.
refreshState
();
err
!=
nil
{
if
err
:=
c
.
refreshState
();
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
if
intelrdt
.
IsEnabled
()
{
if
intelrdt
.
Is
CatEnabled
()
||
intelrdt
.
IsMba
Enabled
()
{
c
.
intelRdtManager
=
l
.
NewIntelRdtManager
(
&
state
.
Config
,
id
,
state
.
IntelRdtPath
)
c
.
intelRdtManager
=
l
.
NewIntelRdtManager
(
&
state
.
Config
,
id
,
state
.
IntelRdtPath
)
}
}
return
c
,
nil
return
c
,
nil
...
@@ -322,7 +350,11 @@ func (l *LinuxFactory) StartInitialization() (err error) {
...
@@ -322,7 +350,11 @@ func (l *LinuxFactory) StartInitialization() (err error) {
}
}
func
(
l
*
LinuxFactory
)
loadState
(
root
,
id
string
)
(
*
State
,
error
)
{
func
(
l
*
LinuxFactory
)
loadState
(
root
,
id
string
)
(
*
State
,
error
)
{
f
,
err
:=
os
.
Open
(
filepath
.
Join
(
root
,
stateFilename
))
stateFilePath
,
err
:=
securejoin
.
SecureJoin
(
root
,
stateFilename
)
if
err
!=
nil
{
return
nil
,
err
}
f
,
err
:=
os
.
Open
(
stateFilePath
)
if
err
!=
nil
{
if
err
!=
nil
{
if
os
.
IsNotExist
(
err
)
{
if
os
.
IsNotExist
(
err
)
{
return
nil
,
newGenericError
(
fmt
.
Errorf
(
"container %q does not exist"
,
id
),
ContainerNotExists
)
return
nil
,
newGenericError
(
fmt
.
Errorf
(
"container %q does not exist"
,
id
),
ContainerNotExists
)
...
@@ -338,7 +370,7 @@ func (l *LinuxFactory) loadState(root, id string) (*State, error) {
...
@@ -338,7 +370,7 @@ func (l *LinuxFactory) loadState(root, id string) (*State, error) {
}
}
func
(
l
*
LinuxFactory
)
validateID
(
id
string
)
error
{
func
(
l
*
LinuxFactory
)
validateID
(
id
string
)
error
{
if
!
idRegex
.
MatchString
(
id
)
{
if
!
idRegex
.
MatchString
(
id
)
||
string
(
os
.
PathSeparator
)
+
id
!=
utils
.
CleanPath
(
string
(
os
.
PathSeparator
)
+
id
)
{
return
newGenericError
(
fmt
.
Errorf
(
"invalid id format: %v"
,
id
),
InvalidIdFormat
)
return
newGenericError
(
fmt
.
Errorf
(
"invalid id format: %v"
,
id
),
InvalidIdFormat
)
}
}
...
...
vendor/github.com/opencontainers/runc/libcontainer/init_linux.go
View file @
2b642765
...
@@ -6,6 +6,7 @@ import (
...
@@ -6,6 +6,7 @@ import (
"encoding/json"
"encoding/json"
"fmt"
"fmt"
"io"
"io"
"io/ioutil"
"net"
"net"
"os"
"os"
"strings"
"strings"
...
@@ -20,6 +21,7 @@ import (
...
@@ -20,6 +21,7 @@ import (
"github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/user"
"github.com/opencontainers/runc/libcontainer/user"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netlink"
)
)
...
@@ -64,7 +66,8 @@ type initConfig struct {
...
@@ -64,7 +66,8 @@ type initConfig struct {
CreateConsole
bool
`json:"create_console"`
CreateConsole
bool
`json:"create_console"`
ConsoleWidth
uint16
`json:"console_width"`
ConsoleWidth
uint16
`json:"console_width"`
ConsoleHeight
uint16
`json:"console_height"`
ConsoleHeight
uint16
`json:"console_height"`
Rootless
bool
`json:"rootless"`
RootlessEUID
bool
`json:"rootless_euid,omitempty"`
RootlessCgroups
bool
`json:"rootless_cgroups,omitempty"`
}
}
type
initer
interface
{
type
initer
interface
{
...
@@ -121,7 +124,7 @@ func finalizeNamespace(config *initConfig) error {
...
@@ -121,7 +124,7 @@ func finalizeNamespace(config *initConfig) error {
// inherited are marked close-on-exec so they stay out of the
// inherited are marked close-on-exec so they stay out of the
// container
// container
if
err
:=
utils
.
CloseExecFrom
(
config
.
PassedFilesCount
+
3
);
err
!=
nil
{
if
err
:=
utils
.
CloseExecFrom
(
config
.
PassedFilesCount
+
3
);
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"close exec fds"
)
}
}
capabilities
:=
&
configs
.
Capabilities
{}
capabilities
:=
&
configs
.
Capabilities
{}
...
@@ -136,20 +139,20 @@ func finalizeNamespace(config *initConfig) error {
...
@@ -136,20 +139,20 @@ func finalizeNamespace(config *initConfig) error {
}
}
// drop capabilities in bounding set before changing user
// drop capabilities in bounding set before changing user
if
err
:=
w
.
ApplyBoundingSet
();
err
!=
nil
{
if
err
:=
w
.
ApplyBoundingSet
();
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"apply bounding set"
)
}
}
// preserve existing capabilities while we change users
// preserve existing capabilities while we change users
if
err
:=
system
.
SetKeepCaps
();
err
!=
nil
{
if
err
:=
system
.
SetKeepCaps
();
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"set keep caps"
)
}
}
if
err
:=
setupUser
(
config
);
err
!=
nil
{
if
err
:=
setupUser
(
config
);
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"setup user"
)
}
}
if
err
:=
system
.
ClearKeepCaps
();
err
!=
nil
{
if
err
:=
system
.
ClearKeepCaps
();
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"clear keep caps"
)
}
}
if
err
:=
w
.
ApplyCaps
();
err
!=
nil
{
if
err
:=
w
.
ApplyCaps
();
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"apply caps"
)
}
}
if
config
.
Cwd
!=
""
{
if
config
.
Cwd
!=
""
{
if
err
:=
unix
.
Chdir
(
config
.
Cwd
);
err
!=
nil
{
if
err
:=
unix
.
Chdir
(
config
.
Cwd
);
err
!=
nil
{
...
@@ -217,11 +220,7 @@ func syncParentReady(pipe io.ReadWriter) error {
...
@@ -217,11 +220,7 @@ func syncParentReady(pipe io.ReadWriter) error {
}
}
// Wait for parent to give the all-clear.
// Wait for parent to give the all-clear.
if
err
:=
readSync
(
pipe
,
procRun
);
err
!=
nil
{
return
readSync
(
pipe
,
procRun
)
return
err
}
return
nil
}
}
// syncParentHooks sends to the given pipe a JSON payload which indicates that
// syncParentHooks sends to the given pipe a JSON payload which indicates that
...
@@ -234,11 +233,7 @@ func syncParentHooks(pipe io.ReadWriter) error {
...
@@ -234,11 +233,7 @@ func syncParentHooks(pipe io.ReadWriter) error {
}
}
// Wait for parent to give the all-clear.
// Wait for parent to give the all-clear.
if
err
:=
readSync
(
pipe
,
procResume
);
err
!=
nil
{
return
readSync
(
pipe
,
procResume
)
return
err
}
return
nil
}
}
// setupUser changes the groups, gid, and uid for the user inside the container
// setupUser changes the groups, gid, and uid for the user inside the container
...
@@ -282,7 +277,7 @@ func setupUser(config *initConfig) error {
...
@@ -282,7 +277,7 @@ func setupUser(config *initConfig) error {
return
fmt
.
Errorf
(
"cannot set gid to unmapped user in user namespace"
)
return
fmt
.
Errorf
(
"cannot set gid to unmapped user in user namespace"
)
}
}
if
config
.
Rootless
{
if
config
.
Rootless
EUID
{
// We cannot set any additional groups in a rootless container and thus
// We cannot set any additional groups in a rootless container and thus
// we bail if the user asked us to do so. TODO: We currently can't do
// we bail if the user asked us to do so. TODO: We currently can't do
// this check earlier, but if libcontainer.Process.User was typesafe
// this check earlier, but if libcontainer.Process.User was typesafe
...
@@ -298,11 +293,18 @@ func setupUser(config *initConfig) error {
...
@@ -298,11 +293,18 @@ func setupUser(config *initConfig) error {
return
err
return
err
}
}
setgroups
,
err
:=
ioutil
.
ReadFile
(
"/proc/self/setgroups"
)
if
err
!=
nil
&&
!
os
.
IsNotExist
(
err
)
{
return
err
}
// This isn't allowed in an unprivileged user namespace since Linux 3.19.
// This isn't allowed in an unprivileged user namespace since Linux 3.19.
// There's nothing we can do about /etc/group entries, so we silently
// There's nothing we can do about /etc/group entries, so we silently
// ignore setting groups here (since the user didn't explicitly ask us to
// ignore setting groups here (since the user didn't explicitly ask us to
// set the group).
// set the group).
if
!
config
.
Rootless
{
allowSupGroups
:=
!
config
.
RootlessEUID
&&
strings
.
TrimSpace
(
string
(
setgroups
))
!=
"deny"
if
allowSupGroups
{
suppGroups
:=
append
(
execUser
.
Sgids
,
addGroups
...
)
suppGroups
:=
append
(
execUser
.
Sgids
,
addGroups
...
)
if
err
:=
unix
.
Setgroups
(
suppGroups
);
err
!=
nil
{
if
err
:=
unix
.
Setgroups
(
suppGroups
);
err
!=
nil
{
return
err
return
err
...
...
vendor/github.com/opencontainers/runc/libcontainer/intelrdt/intelrdt.go
View file @
2b642765
This diff is collapsed.
Click to expand it.
vendor/github.com/opencontainers/runc/libcontainer/intelrdt/stats.go
View file @
2b642765
...
@@ -8,6 +8,13 @@ type L3CacheInfo struct {
...
@@ -8,6 +8,13 @@ type L3CacheInfo struct {
NumClosids
uint64
`json:"num_closids,omitempty"`
NumClosids
uint64
`json:"num_closids,omitempty"`
}
}
type
MemBwInfo
struct
{
BandwidthGran
uint64
`json:"bandwidth_gran,omitempty"`
DelayLinear
uint64
`json:"delay_linear,omitempty"`
MinBandwidth
uint64
`json:"min_bandwidth,omitempty"`
NumClosids
uint64
`json:"num_closids,omitempty"`
}
type
Stats
struct
{
type
Stats
struct
{
// The read-only L3 cache information
// The read-only L3 cache information
L3CacheInfo
*
L3CacheInfo
`json:"l3_cache_info,omitempty"`
L3CacheInfo
*
L3CacheInfo
`json:"l3_cache_info,omitempty"`
...
@@ -17,6 +24,15 @@ type Stats struct {
...
@@ -17,6 +24,15 @@ type Stats struct {
// The L3 cache schema in 'container_id' group
// The L3 cache schema in 'container_id' group
L3CacheSchema
string
`json:"l3_cache_schema,omitempty"`
L3CacheSchema
string
`json:"l3_cache_schema,omitempty"`
// The read-only memory bandwidth information
MemBwInfo
*
MemBwInfo
`json:"mem_bw_info,omitempty"`
// The read-only memory bandwidth schema in root
MemBwSchemaRoot
string
`json:"mem_bw_schema_root,omitempty"`
// The memory bandwidth schema in 'container_id' group
MemBwSchema
string
`json:"mem_bw_schema,omitempty"`
}
}
func
NewStats
()
*
Stats
{
func
NewStats
()
*
Stats
{
...
...
vendor/github.com/opencontainers/runc/libcontainer/keys/BUILD
View file @
2b642765
...
@@ -8,6 +8,7 @@ go_library(
...
@@ -8,6 +8,7 @@ go_library(
visibility = ["//visibility:public"],
visibility = ["//visibility:public"],
deps = select({
deps = select({
"@io_bazel_rules_go//go/platform:linux": [
"@io_bazel_rules_go//go/platform:linux": [
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library",
],
],
"//conditions:default": [],
"//conditions:default": [],
...
...
vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go
View file @
2b642765
...
@@ -7,6 +7,8 @@ import (
...
@@ -7,6 +7,8 @@ import (
"strconv"
"strconv"
"strings"
"strings"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
"golang.org/x/sys/unix"
)
)
...
@@ -15,7 +17,7 @@ type KeySerial uint32
...
@@ -15,7 +17,7 @@ type KeySerial uint32
func
JoinSessionKeyring
(
name
string
)
(
KeySerial
,
error
)
{
func
JoinSessionKeyring
(
name
string
)
(
KeySerial
,
error
)
{
sessKeyId
,
err
:=
unix
.
KeyctlJoinSessionKeyring
(
name
)
sessKeyId
,
err
:=
unix
.
KeyctlJoinSessionKeyring
(
name
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
fmt
.
Errorf
(
"could not create session key: %v"
,
err
)
return
0
,
errors
.
Wrap
(
err
,
"create session key"
)
}
}
return
KeySerial
(
sessKeyId
),
nil
return
KeySerial
(
sessKeyId
),
nil
}
}
...
@@ -42,9 +44,5 @@ func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
...
@@ -42,9 +44,5 @@ func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
perm
:=
(
uint32
(
perm64
)
&
mask
)
|
setbits
perm
:=
(
uint32
(
perm64
)
&
mask
)
|
setbits
if
err
:=
unix
.
KeyctlSetperm
(
int
(
ringId
),
perm
);
err
!=
nil
{
return
unix
.
KeyctlSetperm
(
int
(
ringId
),
perm
)
return
err
}
return
nil
}
}
vendor/github.com/opencontainers/runc/libcontainer/message_linux.go
View file @
2b642765
...
@@ -10,16 +10,16 @@ import (
...
@@ -10,16 +10,16 @@ import (
// list of known message types we want to send to bootstrap program
// list of known message types we want to send to bootstrap program
// The number is randomly chosen to not conflict with known netlink types
// The number is randomly chosen to not conflict with known netlink types
const
(
const
(
InitMsg
uint16
=
62000
InitMsg
uint16
=
62000
CloneFlagsAttr
uint16
=
27281
CloneFlagsAttr
uint16
=
27281
NsPathsAttr
uint16
=
27282
NsPathsAttr
uint16
=
27282
UidmapAttr
uint16
=
27283
UidmapAttr
uint16
=
27283
GidmapAttr
uint16
=
27284
GidmapAttr
uint16
=
27284
SetgroupAttr
uint16
=
27285
SetgroupAttr
uint16
=
27285
OomScoreAdjAttr
uint16
=
27286
OomScoreAdjAttr
uint16
=
27286
Rootless
Attr
uint16
=
27287
Rootless
EUIDAttr
uint16
=
27287
UidmapPathAttr
uint16
=
27288
UidmapPathAttr
uint16
=
27288
GidmapPathAttr
uint16
=
27289
GidmapPathAttr
uint16
=
27289
)
)
type
Int32msg
struct
{
type
Int32msg
struct
{
...
...
vendor/github.com/opencontainers/runc/libcontainer/network_linux.go
View file @
2b642765
...
@@ -5,18 +5,15 @@ package libcontainer
...
@@ -5,18 +5,15 @@ package libcontainer
import
(
import
(
"fmt"
"fmt"
"io/ioutil"
"io/ioutil"
"net"
"path/filepath"
"path/filepath"
"strconv"
"strconv"
"strings"
"strings"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netlink"
)
)
var
strategies
=
map
[
string
]
networkStrategy
{
var
strategies
=
map
[
string
]
networkStrategy
{
"veth"
:
&
veth
{},
"loopback"
:
&
loopback
{},
"loopback"
:
&
loopback
{},
}
}
...
@@ -103,157 +100,3 @@ func (l *loopback) attach(n *configs.Network) (err error) {
...
@@ -103,157 +100,3 @@ func (l *loopback) attach(n *configs.Network) (err error) {
func
(
l
*
loopback
)
detach
(
n
*
configs
.
Network
)
(
err
error
)
{
func
(
l
*
loopback
)
detach
(
n
*
configs
.
Network
)
(
err
error
)
{
return
nil
return
nil
}
}
// veth is a network strategy that uses a bridge and creates
// a veth pair, one that is attached to the bridge on the host and the other
// is placed inside the container's namespace
type
veth
struct
{
}
func
(
v
*
veth
)
detach
(
n
*
configs
.
Network
)
(
err
error
)
{
return
netlink
.
LinkSetMaster
(
&
netlink
.
Device
{
LinkAttrs
:
netlink
.
LinkAttrs
{
Name
:
n
.
HostInterfaceName
}},
nil
)
}
// attach a container network interface to an external network
func
(
v
*
veth
)
attach
(
n
*
configs
.
Network
)
(
err
error
)
{
brl
,
err
:=
netlink
.
LinkByName
(
n
.
Bridge
)
if
err
!=
nil
{
return
err
}
br
,
ok
:=
brl
.
(
*
netlink
.
Bridge
)
if
!
ok
{
return
fmt
.
Errorf
(
"Wrong device type %T"
,
brl
)
}
host
,
err
:=
netlink
.
LinkByName
(
n
.
HostInterfaceName
)
if
err
!=
nil
{
return
err
}
if
err
:=
netlink
.
LinkSetMaster
(
host
,
br
);
err
!=
nil
{
return
err
}
if
err
:=
netlink
.
LinkSetMTU
(
host
,
n
.
Mtu
);
err
!=
nil
{
return
err
}
if
n
.
HairpinMode
{
if
err
:=
netlink
.
LinkSetHairpin
(
host
,
true
);
err
!=
nil
{
return
err
}
}
if
err
:=
netlink
.
LinkSetUp
(
host
);
err
!=
nil
{
return
err
}
return
nil
}
func
(
v
*
veth
)
create
(
n
*
network
,
nspid
int
)
(
err
error
)
{
tmpName
,
err
:=
v
.
generateTempPeerName
()
if
err
!=
nil
{
return
err
}
n
.
TempVethPeerName
=
tmpName
if
n
.
Bridge
==
""
{
return
fmt
.
Errorf
(
"bridge is not specified"
)
}
veth
:=
&
netlink
.
Veth
{
LinkAttrs
:
netlink
.
LinkAttrs
{
Name
:
n
.
HostInterfaceName
,
TxQLen
:
n
.
TxQueueLen
,
},
PeerName
:
n
.
TempVethPeerName
,
}
if
err
:=
netlink
.
LinkAdd
(
veth
);
err
!=
nil
{
return
err
}
defer
func
()
{
if
err
!=
nil
{
netlink
.
LinkDel
(
veth
)
}
}()
if
err
:=
v
.
attach
(
&
n
.
Network
);
err
!=
nil
{
return
err
}
child
,
err
:=
netlink
.
LinkByName
(
n
.
TempVethPeerName
)
if
err
!=
nil
{
return
err
}
return
netlink
.
LinkSetNsPid
(
child
,
nspid
)
}
func
(
v
*
veth
)
generateTempPeerName
()
(
string
,
error
)
{
return
utils
.
GenerateRandomName
(
"veth"
,
7
)
}
func
(
v
*
veth
)
initialize
(
config
*
network
)
error
{
peer
:=
config
.
TempVethPeerName
if
peer
==
""
{
return
fmt
.
Errorf
(
"peer is not specified"
)
}
child
,
err
:=
netlink
.
LinkByName
(
peer
)
if
err
!=
nil
{
return
err
}
if
err
:=
netlink
.
LinkSetDown
(
child
);
err
!=
nil
{
return
err
}
if
err
:=
netlink
.
LinkSetName
(
child
,
config
.
Name
);
err
!=
nil
{
return
err
}
// get the interface again after we changed the name as the index also changes.
if
child
,
err
=
netlink
.
LinkByName
(
config
.
Name
);
err
!=
nil
{
return
err
}
if
config
.
MacAddress
!=
""
{
mac
,
err
:=
net
.
ParseMAC
(
config
.
MacAddress
)
if
err
!=
nil
{
return
err
}
if
err
:=
netlink
.
LinkSetHardwareAddr
(
child
,
mac
);
err
!=
nil
{
return
err
}
}
ip
,
err
:=
netlink
.
ParseAddr
(
config
.
Address
)
if
err
!=
nil
{
return
err
}
if
err
:=
netlink
.
AddrAdd
(
child
,
ip
);
err
!=
nil
{
return
err
}
if
config
.
IPv6Address
!=
""
{
ip6
,
err
:=
netlink
.
ParseAddr
(
config
.
IPv6Address
)
if
err
!=
nil
{
return
err
}
if
err
:=
netlink
.
AddrAdd
(
child
,
ip6
);
err
!=
nil
{
return
err
}
}
if
err
:=
netlink
.
LinkSetMTU
(
child
,
config
.
Mtu
);
err
!=
nil
{
return
err
}
if
err
:=
netlink
.
LinkSetUp
(
child
);
err
!=
nil
{
return
err
}
if
config
.
Gateway
!=
""
{
gw
:=
net
.
ParseIP
(
config
.
Gateway
)
if
err
:=
netlink
.
RouteAdd
(
&
netlink
.
Route
{
Scope
:
netlink
.
SCOPE_UNIVERSE
,
LinkIndex
:
child
.
Attrs
()
.
Index
,
Gw
:
gw
,
});
err
!=
nil
{
return
err
}
}
if
config
.
IPv6Gateway
!=
""
{
gw
:=
net
.
ParseIP
(
config
.
IPv6Gateway
)
if
err
:=
netlink
.
RouteAdd
(
&
netlink
.
Route
{
Scope
:
netlink
.
SCOPE_UNIVERSE
,
LinkIndex
:
child
.
Attrs
()
.
Index
,
Gw
:
gw
,
});
err
!=
nil
{
return
err
}
}
return
nil
}
vendor/github.com/opencontainers/runc/libcontainer/process.go
View file @
2b642765
...
@@ -72,6 +72,9 @@ type Process struct {
...
@@ -72,6 +72,9 @@ type Process struct {
// ConsoleSocket provides the masterfd console.
// ConsoleSocket provides the masterfd console.
ConsoleSocket
*
os
.
File
ConsoleSocket
*
os
.
File
// Init specifies whether the process is the first process in the container.
Init
bool
ops
processOperations
ops
processOperations
}
}
...
...
vendor/github.com/opencontainers/runc/libcontainer/process_linux.go
View file @
2b642765
...
@@ -46,15 +46,16 @@ type parentProcess interface {
...
@@ -46,15 +46,16 @@ type parentProcess interface {
}
}
type
setnsProcess
struct
{
type
setnsProcess
struct
{
cmd
*
exec
.
Cmd
cmd
*
exec
.
Cmd
parentPipe
*
os
.
File
parentPipe
*
os
.
File
childPipe
*
os
.
File
childPipe
*
os
.
File
cgroupPaths
map
[
string
]
string
cgroupPaths
map
[
string
]
string
intelRdtPath
string
rootlessCgroups
bool
config
*
initConfig
intelRdtPath
string
fds
[]
string
config
*
initConfig
process
*
Process
fds
[]
string
bootstrapData
io
.
Reader
process
*
Process
bootstrapData
io
.
Reader
}
}
func
(
p
*
setnsProcess
)
startTime
()
(
uint64
,
error
)
{
func
(
p
*
setnsProcess
)
startTime
()
(
uint64
,
error
)
{
...
@@ -86,7 +87,7 @@ func (p *setnsProcess) start() (err error) {
...
@@ -86,7 +87,7 @@ func (p *setnsProcess) start() (err error) {
return
newSystemErrorWithCause
(
err
,
"executing setns process"
)
return
newSystemErrorWithCause
(
err
,
"executing setns process"
)
}
}
if
len
(
p
.
cgroupPaths
)
>
0
{
if
len
(
p
.
cgroupPaths
)
>
0
{
if
err
:=
cgroups
.
EnterPid
(
p
.
cgroupPaths
,
p
.
pid
());
err
!=
nil
{
if
err
:=
cgroups
.
EnterPid
(
p
.
cgroupPaths
,
p
.
pid
());
err
!=
nil
&&
!
p
.
rootlessCgroups
{
return
newSystemErrorWithCausef
(
err
,
"adding pid %d to cgroups"
,
p
.
pid
())
return
newSystemErrorWithCausef
(
err
,
"adding pid %d to cgroups"
,
p
.
pid
())
}
}
}
}
...
@@ -537,7 +538,7 @@ func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) {
...
@@ -537,7 +538,7 @@ func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) {
}
}
fds
=
append
(
fds
,
r
.
Fd
(),
w
.
Fd
())
fds
=
append
(
fds
,
r
.
Fd
(),
w
.
Fd
())
p
.
Stderr
,
i
.
Stderr
=
w
,
r
p
.
Stderr
,
i
.
Stderr
=
w
,
r
// change ownership of the pipes incase we are in a user namespace
// change ownership of the pipes in
case we are in a user namespace
for
_
,
fd
:=
range
fds
{
for
_
,
fd
:=
range
fds
{
if
err
:=
unix
.
Fchown
(
int
(
fd
),
rootuid
,
rootgid
);
err
!=
nil
{
if
err
:=
unix
.
Fchown
(
int
(
fd
),
rootuid
,
rootgid
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
...
vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go
View file @
2b642765
...
@@ -46,6 +46,7 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
...
@@ -46,6 +46,7 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
return
newSystemErrorWithCause
(
err
,
"preparing rootfs"
)
return
newSystemErrorWithCause
(
err
,
"preparing rootfs"
)
}
}
setupDev
:=
needsSetupDev
(
config
)
for
_
,
m
:=
range
config
.
Mounts
{
for
_
,
m
:=
range
config
.
Mounts
{
for
_
,
precmd
:=
range
m
.
PremountCmds
{
for
_
,
precmd
:=
range
m
.
PremountCmds
{
if
err
:=
mountCmd
(
precmd
);
err
!=
nil
{
if
err
:=
mountCmd
(
precmd
);
err
!=
nil
{
...
@@ -64,8 +65,6 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
...
@@ -64,8 +65,6 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
}
}
}
}
setupDev
:=
needsSetupDev
(
config
)
if
setupDev
{
if
setupDev
{
if
err
:=
createDevices
(
config
);
err
!=
nil
{
if
err
:=
createDevices
(
config
);
err
!=
nil
{
return
newSystemErrorWithCause
(
err
,
"creating device nodes"
)
return
newSystemErrorWithCause
(
err
,
"creating device nodes"
)
...
@@ -153,6 +152,26 @@ func finalizeRootfs(config *configs.Config) (err error) {
...
@@ -153,6 +152,26 @@ func finalizeRootfs(config *configs.Config) (err error) {
return
nil
return
nil
}
}
// /tmp has to be mounted as private to allow MS_MOVE to work in all situations
func
prepareTmp
(
topTmpDir
string
)
(
string
,
error
)
{
tmpdir
,
err
:=
ioutil
.
TempDir
(
topTmpDir
,
"runctop"
)
if
err
!=
nil
{
return
""
,
err
}
if
err
:=
unix
.
Mount
(
tmpdir
,
tmpdir
,
"bind"
,
unix
.
MS_BIND
,
""
);
err
!=
nil
{
return
""
,
err
}
if
err
:=
unix
.
Mount
(
""
,
tmpdir
,
""
,
uintptr
(
unix
.
MS_PRIVATE
),
""
);
err
!=
nil
{
return
""
,
err
}
return
tmpdir
,
nil
}
func
cleanupTmp
(
tmpdir
string
)
error
{
unix
.
Unmount
(
tmpdir
,
0
)
return
os
.
RemoveAll
(
tmpdir
)
}
func
mountCmd
(
cmd
configs
.
Command
)
error
{
func
mountCmd
(
cmd
configs
.
Command
)
error
{
command
:=
exec
.
Command
(
cmd
.
Path
,
cmd
.
Args
[
:
]
...
)
command
:=
exec
.
Command
(
cmd
.
Path
,
cmd
.
Args
[
:
]
...
)
command
.
Env
=
cmd
.
Env
command
.
Env
=
cmd
.
Env
...
@@ -200,7 +219,12 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
...
@@ -200,7 +219,12 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
}
}
}
}
if
copyUp
{
if
copyUp
{
tmpDir
,
err
=
ioutil
.
TempDir
(
"/tmp"
,
"runctmpdir"
)
tmpdir
,
err
:=
prepareTmp
(
"/tmp"
)
if
err
!=
nil
{
return
newSystemErrorWithCause
(
err
,
"tmpcopyup: failed to setup tmpdir"
)
}
defer
cleanupTmp
(
tmpdir
)
tmpDir
,
err
=
ioutil
.
TempDir
(
tmpdir
,
"runctmpdir"
)
if
err
!=
nil
{
if
err
!=
nil
{
return
newSystemErrorWithCause
(
err
,
"tmpcopyup: failed to create tmpdir"
)
return
newSystemErrorWithCause
(
err
,
"tmpcopyup: failed to create tmpdir"
)
}
}
...
@@ -397,6 +421,7 @@ func checkMountDestination(rootfs, dest string) error {
...
@@ -397,6 +421,7 @@ func checkMountDestination(rootfs, dest string) error {
"/proc/stat"
,
"/proc/stat"
,
"/proc/swaps"
,
"/proc/swaps"
,
"/proc/uptime"
,
"/proc/uptime"
,
"/proc/loadavg"
,
"/proc/net/dev"
,
"/proc/net/dev"
,
}
}
for
_
,
valid
:=
range
validDestinations
{
for
_
,
valid
:=
range
validDestinations
{
...
@@ -413,7 +438,7 @@ func checkMountDestination(rootfs, dest string) error {
...
@@ -413,7 +438,7 @@ func checkMountDestination(rootfs, dest string) error {
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
path
==
"."
||
!
strings
.
HasPrefix
(
path
,
".."
)
{
if
path
!=
"."
&&
!
strings
.
HasPrefix
(
path
,
".."
)
{
return
fmt
.
Errorf
(
"%q cannot be mounted because it is located inside %q"
,
dest
,
invalid
)
return
fmt
.
Errorf
(
"%q cannot be mounted because it is located inside %q"
,
dest
,
invalid
)
}
}
}
}
...
@@ -803,10 +828,7 @@ func remount(m *configs.Mount, rootfs string) error {
...
@@ -803,10 +828,7 @@ func remount(m *configs.Mount, rootfs string) error {
if
!
strings
.
HasPrefix
(
dest
,
rootfs
)
{
if
!
strings
.
HasPrefix
(
dest
,
rootfs
)
{
dest
=
filepath
.
Join
(
rootfs
,
dest
)
dest
=
filepath
.
Join
(
rootfs
,
dest
)
}
}
if
err
:=
unix
.
Mount
(
m
.
Source
,
dest
,
m
.
Device
,
uintptr
(
m
.
Flags
|
unix
.
MS_REMOUNT
),
""
);
err
!=
nil
{
return
unix
.
Mount
(
m
.
Source
,
dest
,
m
.
Device
,
uintptr
(
m
.
Flags
|
unix
.
MS_REMOUNT
),
""
)
return
err
}
return
nil
}
}
// Do the mount operation followed by additional mounts required to take care
// Do the mount operation followed by additional mounts required to take care
...
...
vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go
View file @
2b642765
...
@@ -5,12 +5,14 @@ package libcontainer
...
@@ -5,12 +5,14 @@ package libcontainer
import
(
import
(
"fmt"
"fmt"
"os"
"os"
"runtime"
"github.com/opencontainers/runc/libcontainer/apparmor"
"github.com/opencontainers/runc/libcontainer/apparmor"
"github.com/opencontainers/runc/libcontainer/keys"
"github.com/opencontainers/runc/libcontainer/keys"
"github.com/opencontainers/runc/libcontainer/seccomp"
"github.com/opencontainers/runc/libcontainer/seccomp"
"github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
"golang.org/x/sys/unix"
)
)
...
@@ -28,10 +30,19 @@ func (l *linuxSetnsInit) getSessionRingName() string {
...
@@ -28,10 +30,19 @@ func (l *linuxSetnsInit) getSessionRingName() string {
}
}
func
(
l
*
linuxSetnsInit
)
Init
()
error
{
func
(
l
*
linuxSetnsInit
)
Init
()
error
{
runtime
.
LockOSThread
()
defer
runtime
.
UnlockOSThread
()
if
!
l
.
config
.
Config
.
NoNewKeyring
{
if
!
l
.
config
.
Config
.
NoNewKeyring
{
//
do not inherit the parent's session keyring
//
Do not inherit the parent's session keyring.
if
_
,
err
:=
keys
.
JoinSessionKeyring
(
l
.
getSessionRingName
());
err
!=
nil
{
if
_
,
err
:=
keys
.
JoinSessionKeyring
(
l
.
getSessionRingName
());
err
!=
nil
{
return
err
// Same justification as in standart_init_linux.go as to why we
// don't bail on ENOSYS.
//
// TODO(cyphar): And we should have logging here too.
if
errors
.
Cause
(
err
)
!=
unix
.
ENOSYS
{
return
errors
.
Wrap
(
err
,
"join session keyring"
)
}
}
}
}
}
if
l
.
config
.
CreateConsole
{
if
l
.
config
.
CreateConsole
{
...
@@ -47,6 +58,10 @@ func (l *linuxSetnsInit) Init() error {
...
@@ -47,6 +58,10 @@ func (l *linuxSetnsInit) Init() error {
return
err
return
err
}
}
}
}
if
err
:=
label
.
SetProcessLabel
(
l
.
config
.
ProcessLabel
);
err
!=
nil
{
return
err
}
defer
label
.
SetProcessLabel
(
""
)
// Without NoNewPrivileges seccomp is a privileged operation, so we need to
// Without NoNewPrivileges seccomp is a privileged operation, so we need to
// do this before dropping capabilities; otherwise do it as late as possible
// do this before dropping capabilities; otherwise do it as late as possible
// just before execve so as few syscalls take place after it as possible.
// just before execve so as few syscalls take place after it as possible.
...
@@ -61,9 +76,6 @@ func (l *linuxSetnsInit) Init() error {
...
@@ -61,9 +76,6 @@ func (l *linuxSetnsInit) Init() error {
if
err
:=
apparmor
.
ApplyProfile
(
l
.
config
.
AppArmorProfile
);
err
!=
nil
{
if
err
:=
apparmor
.
ApplyProfile
(
l
.
config
.
AppArmorProfile
);
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
label
.
SetProcessLabel
(
l
.
config
.
ProcessLabel
);
err
!=
nil
{
return
err
}
// Set seccomp as close to execve as possible, so as few syscalls take
// Set seccomp as close to execve as possible, so as few syscalls take
// place afterward (reducing the amount of syscalls that users need to
// place afterward (reducing the amount of syscalls that users need to
// enable in their seccomp profiles).
// enable in their seccomp profiles).
...
...
vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go
View file @
2b642765
...
@@ -6,6 +6,7 @@ import (
...
@@ -6,6 +6,7 @@ import (
"fmt"
"fmt"
"os"
"os"
"os/exec"
"os/exec"
"runtime"
"syscall"
//only for Exec
"syscall"
//only for Exec
"github.com/opencontainers/runc/libcontainer/apparmor"
"github.com/opencontainers/runc/libcontainer/apparmor"
...
@@ -14,6 +15,7 @@ import (
...
@@ -14,6 +15,7 @@ import (
"github.com/opencontainers/runc/libcontainer/seccomp"
"github.com/opencontainers/runc/libcontainer/seccomp"
"github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
"golang.org/x/sys/unix"
)
)
...
@@ -43,17 +45,31 @@ func (l *linuxStandardInit) getSessionRingParams() (string, uint32, uint32) {
...
@@ -43,17 +45,31 @@ func (l *linuxStandardInit) getSessionRingParams() (string, uint32, uint32) {
}
}
func
(
l
*
linuxStandardInit
)
Init
()
error
{
func
(
l
*
linuxStandardInit
)
Init
()
error
{
runtime
.
LockOSThread
()
defer
runtime
.
UnlockOSThread
()
if
!
l
.
config
.
Config
.
NoNewKeyring
{
if
!
l
.
config
.
Config
.
NoNewKeyring
{
ringname
,
keepperms
,
newperms
:=
l
.
getSessionRingParams
()
ringname
,
keepperms
,
newperms
:=
l
.
getSessionRingParams
()
// Do not inherit the parent's session keyring.
// Do not inherit the parent's session keyring.
sessKeyId
,
err
:=
keys
.
JoinSessionKeyring
(
ringname
)
if
sessKeyId
,
err
:=
keys
.
JoinSessionKeyring
(
ringname
);
err
!=
nil
{
if
err
!=
nil
{
// If keyrings aren't supported then it is likely we are on an
return
err
// older kernel (or inside an LXC container). While we could bail,
}
// the security feature we are using here is best-effort (it only
// Make session keyring searcheable.
// really provides marginal protection since VFS credentials are
if
err
:=
keys
.
ModKeyringPerm
(
sessKeyId
,
keepperms
,
newperms
);
err
!=
nil
{
// the only significant protection of keyrings).
return
err
//
// TODO(cyphar): Log this so people know what's going on, once we
// have proper logging in 'runc init'.
if
errors
.
Cause
(
err
)
!=
unix
.
ENOSYS
{
return
errors
.
Wrap
(
err
,
"join session keyring"
)
}
}
else
{
// Make session keyring searcheable. If we've gotten this far we
// bail on any error -- we don't want to have a keyring with bad
// permissions.
if
err
:=
keys
.
ModKeyringPerm
(
sessKeyId
,
keepperms
,
newperms
);
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"mod keyring permissions"
)
}
}
}
}
}
...
@@ -76,7 +92,7 @@ func (l *linuxStandardInit) Init() error {
...
@@ -76,7 +92,7 @@ func (l *linuxStandardInit) Init() error {
return
err
return
err
}
}
if
err
:=
system
.
Setctty
();
err
!=
nil
{
if
err
:=
system
.
Setctty
();
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"setctty"
)
}
}
}
}
...
@@ -89,46 +105,47 @@ func (l *linuxStandardInit) Init() error {
...
@@ -89,46 +105,47 @@ func (l *linuxStandardInit) Init() error {
if
hostname
:=
l
.
config
.
Config
.
Hostname
;
hostname
!=
""
{
if
hostname
:=
l
.
config
.
Config
.
Hostname
;
hostname
!=
""
{
if
err
:=
unix
.
Sethostname
([]
byte
(
hostname
));
err
!=
nil
{
if
err
:=
unix
.
Sethostname
([]
byte
(
hostname
));
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"sethostname"
)
}
}
}
}
if
err
:=
apparmor
.
ApplyProfile
(
l
.
config
.
AppArmorProfile
);
err
!=
nil
{
if
err
:=
apparmor
.
ApplyProfile
(
l
.
config
.
AppArmorProfile
);
err
!=
nil
{
return
err
return
errors
.
Wrap
(
err
,
"apply apparmor profile"
)
}
if
err
:=
label
.
SetProcessLabel
(
l
.
config
.
ProcessLabel
);
err
!=
nil
{
return
err
}
}
for
key
,
value
:=
range
l
.
config
.
Config
.
Sysctl
{
for
key
,
value
:=
range
l
.
config
.
Config
.
Sysctl
{
if
err
:=
writeSystemProperty
(
key
,
value
);
err
!=
nil
{
if
err
:=
writeSystemProperty
(
key
,
value
);
err
!=
nil
{
return
err
return
err
ors
.
Wrapf
(
err
,
"write sysctl key %s"
,
key
)
}
}
}
}
for
_
,
path
:=
range
l
.
config
.
Config
.
ReadonlyPaths
{
for
_
,
path
:=
range
l
.
config
.
Config
.
ReadonlyPaths
{
if
err
:=
readonlyPath
(
path
);
err
!=
nil
{
if
err
:=
readonlyPath
(
path
);
err
!=
nil
{
return
err
return
err
ors
.
Wrapf
(
err
,
"readonly path %s"
,
path
)
}
}
}
}
for
_
,
path
:=
range
l
.
config
.
Config
.
MaskPaths
{
for
_
,
path
:=
range
l
.
config
.
Config
.
MaskPaths
{
if
err
:=
maskPath
(
path
,
l
.
config
.
Config
.
MountLabel
);
err
!=
nil
{
if
err
:=
maskPath
(
path
,
l
.
config
.
Config
.
MountLabel
);
err
!=
nil
{
return
err
return
err
ors
.
Wrapf
(
err
,
"mask path %s"
,
path
)
}
}
}
}
pdeath
,
err
:=
system
.
GetParentDeathSignal
()
pdeath
,
err
:=
system
.
GetParentDeathSignal
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"get pdeath signal"
)
}
}
if
l
.
config
.
NoNewPrivileges
{
if
l
.
config
.
NoNewPrivileges
{
if
err
:=
unix
.
Prctl
(
unix
.
PR_SET_NO_NEW_PRIVS
,
1
,
0
,
0
,
0
);
err
!=
nil
{
if
err
:=
unix
.
Prctl
(
unix
.
PR_SET_NO_NEW_PRIVS
,
1
,
0
,
0
,
0
);
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"set nonewprivileges"
)
}
}
}
}
// Tell our parent that we're ready to Execv. This must be done before the
// Tell our parent that we're ready to Execv. This must be done before the
// Seccomp rules have been applied, because we need to be able to read and
// Seccomp rules have been applied, because we need to be able to read and
// write to a socket.
// write to a socket.
if
err
:=
syncParentReady
(
l
.
pipe
);
err
!=
nil
{
if
err
:=
syncParentReady
(
l
.
pipe
);
err
!=
nil
{
return
err
return
errors
.
Wrap
(
err
,
"sync ready"
)
}
if
err
:=
label
.
SetProcessLabel
(
l
.
config
.
ProcessLabel
);
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"set process label"
)
}
}
defer
label
.
SetProcessLabel
(
""
)
// Without NoNewPrivileges seccomp is a privileged operation, so we need to
// Without NoNewPrivileges seccomp is a privileged operation, so we need to
// do this before dropping capabilities; otherwise do it as late as possible
// do this before dropping capabilities; otherwise do it as late as possible
// just before execve so as few syscalls take place after it as possible.
// just before execve so as few syscalls take place after it as possible.
...
@@ -143,7 +160,7 @@ func (l *linuxStandardInit) Init() error {
...
@@ -143,7 +160,7 @@ func (l *linuxStandardInit) Init() error {
// finalizeNamespace can change user/group which clears the parent death
// finalizeNamespace can change user/group which clears the parent death
// signal, so we restore it here.
// signal, so we restore it here.
if
err
:=
pdeath
.
Restore
();
err
!=
nil
{
if
err
:=
pdeath
.
Restore
();
err
!=
nil
{
return
err
return
err
ors
.
Wrap
(
err
,
"restore pdeath signal"
)
}
}
// Compare the parent from the initial start of the init process and make
// Compare the parent from the initial start of the init process and make
// sure that it did not change. if the parent changes that means it died
// sure that it did not change. if the parent changes that means it died
...
...
vendor/github.com/opencontainers/runc/libcontainer/sync.go
View file @
2b642765
...
@@ -41,10 +41,7 @@ type syncT struct {
...
@@ -41,10 +41,7 @@ type syncT struct {
// writeSync is used to write to a synchronisation pipe. An error is returned
// writeSync is used to write to a synchronisation pipe. An error is returned
// if there was a problem writing the payload.
// if there was a problem writing the payload.
func
writeSync
(
pipe
io
.
Writer
,
sync
syncType
)
error
{
func
writeSync
(
pipe
io
.
Writer
,
sync
syncType
)
error
{
if
err
:=
utils
.
WriteJSON
(
pipe
,
syncT
{
sync
});
err
!=
nil
{
return
utils
.
WriteJSON
(
pipe
,
syncT
{
sync
})
return
err
}
return
nil
}
}
// readSync is used to read from a synchronisation pipe. An error is returned
// readSync is used to read from a synchronisation pipe. An error is returned
...
...
vendor/github.com/opencontainers/runc/libcontainer/system/BUILD
View file @
2b642765
...
@@ -17,6 +17,41 @@ go_library(
...
@@ -17,6 +17,41 @@ go_library(
importpath = "github.com/opencontainers/runc/libcontainer/system",
importpath = "github.com/opencontainers/runc/libcontainer/system",
visibility = ["//visibility:public"],
visibility = ["//visibility:public"],
deps = select({
deps = select({
"@io_bazel_rules_go//go/platform:android": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"@io_bazel_rules_go//go/platform:darwin": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"@io_bazel_rules_go//go/platform:dragonfly": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"@io_bazel_rules_go//go/platform:freebsd": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"@io_bazel_rules_go//go/platform:linux": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"@io_bazel_rules_go//go/platform:nacl": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"@io_bazel_rules_go//go/platform:netbsd": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"@io_bazel_rules_go//go/platform:openbsd": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"@io_bazel_rules_go//go/platform:plan9": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"@io_bazel_rules_go//go/platform:solaris": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"@io_bazel_rules_go//go/platform:windows": [
"//vendor/github.com/opencontainers/runc/libcontainer/user:go_default_library",
],
"//conditions:default": [],
}) + select({
"@io_bazel_rules_go//go/platform:linux_386": [
"@io_bazel_rules_go//go/platform:linux_386": [
"//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library",
],
],
...
...
vendor/github.com/opencontainers/runc/libcontainer/system/linux.go
View file @
2b642765
...
@@ -3,13 +3,12 @@
...
@@ -3,13 +3,12 @@
package
system
package
system
import
(
import
(
"bufio"
"fmt"
"os"
"os"
"os/exec"
"os/exec"
"syscall"
// only for exec
"syscall"
// only for exec
"unsafe"
"unsafe"
"github.com/opencontainers/runc/libcontainer/user"
"golang.org/x/sys/unix"
"golang.org/x/sys/unix"
)
)
...
@@ -102,34 +101,43 @@ func Setctty() error {
...
@@ -102,34 +101,43 @@ func Setctty() error {
}
}
// RunningInUserNS detects whether we are currently running in a user namespace.
// RunningInUserNS detects whether we are currently running in a user namespace.
//
C
opied from github.com/lxc/lxd/shared/util.go
//
Originally c
opied from github.com/lxc/lxd/shared/util.go
func
RunningInUserNS
()
bool
{
func
RunningInUserNS
()
bool
{
file
,
err
:=
os
.
Open
(
"/proc/self/uid_map"
)
uidmap
,
err
:=
user
.
CurrentProcessUIDMap
(
)
if
err
!=
nil
{
if
err
!=
nil
{
// This kernel-provided file only exists if user namespaces are supported
// This kernel-provided file only exists if user namespaces are supported
return
false
return
false
}
}
defer
file
.
Close
()
return
UIDMapInUserNS
(
uidmap
)
}
buf
:=
bufio
.
NewReader
(
file
)
l
,
_
,
err
:=
buf
.
ReadLine
()
if
err
!=
nil
{
return
false
}
line
:=
string
(
l
)
func
UIDMapInUserNS
(
uidmap
[]
user
.
IDMap
)
bool
{
var
a
,
b
,
c
int64
fmt
.
Sscanf
(
line
,
"%d %d %d"
,
&
a
,
&
b
,
&
c
)
/*
/*
* We assume we are in the initial user namespace if we have a full
* We assume we are in the initial user namespace if we have a full
* range - 4294967295 uids starting at uid 0.
* range - 4294967295 uids starting at uid 0.
*/
*/
if
a
==
0
&&
b
==
0
&&
c
==
4294967295
{
if
len
(
uidmap
)
==
1
&&
uidmap
[
0
]
.
ID
==
0
&&
uidmap
[
0
]
.
ParentID
==
0
&&
uidmap
[
0
]
.
Count
==
4294967295
{
return
false
return
false
}
}
return
true
return
true
}
}
// GetParentNSeuid returns the euid within the parent user namespace
func
GetParentNSeuid
()
int64
{
euid
:=
int64
(
os
.
Geteuid
())
uidmap
,
err
:=
user
.
CurrentProcessUIDMap
()
if
err
!=
nil
{
// This kernel-provided file only exists if user namespaces are supported
return
euid
}
for
_
,
um
:=
range
uidmap
{
if
um
.
ID
<=
euid
&&
euid
<=
um
.
ID
+
um
.
Count
-
1
{
return
um
.
ParentID
+
euid
-
um
.
ID
}
}
return
euid
}
// SetSubreaper sets the value i as the subreaper setting for the calling process
// SetSubreaper sets the value i as the subreaper setting for the calling process
func
SetSubreaper
(
i
int
)
error
{
func
SetSubreaper
(
i
int
)
error
{
return
unix
.
Prctl
(
PR_SET_CHILD_SUBREAPER
,
uintptr
(
i
),
0
,
0
,
0
)
return
unix
.
Prctl
(
PR_SET_CHILD_SUBREAPER
,
uintptr
(
i
),
0
,
0
,
0
)
...
...
vendor/github.com/opencontainers/runc/libcontainer/system/unsupported.go
View file @
2b642765
...
@@ -2,8 +2,26 @@
...
@@ -2,8 +2,26 @@
package
system
package
system
import
(
"os"
"github.com/opencontainers/runc/libcontainer/user"
)
// RunningInUserNS is a stub for non-Linux systems
// RunningInUserNS is a stub for non-Linux systems
// Always returns false
// Always returns false
func
RunningInUserNS
()
bool
{
func
RunningInUserNS
()
bool
{
return
false
return
false
}
}
// UIDMapInUserNS is a stub for non-Linux systems
// Always returns false
func
UIDMapInUserNS
(
uidmap
[]
user
.
IDMap
)
bool
{
return
false
}
// GetParentNSeuid returns the euid within the parent user namespace
// Always returns os.Geteuid on non-linux
func
GetParentNSeuid
()
int
{
return
os
.
Geteuid
()
}
vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go
View file @
2b642765
...
@@ -5,6 +5,7 @@ package user
...
@@ -5,6 +5,7 @@ package user
import
(
import
(
"io"
"io"
"os"
"os"
"strconv"
"golang.org/x/sys/unix"
"golang.org/x/sys/unix"
)
)
...
@@ -114,3 +115,30 @@ func CurrentUser() (User, error) {
...
@@ -114,3 +115,30 @@ func CurrentUser() (User, error) {
func
CurrentGroup
()
(
Group
,
error
)
{
func
CurrentGroup
()
(
Group
,
error
)
{
return
LookupGid
(
unix
.
Getgid
())
return
LookupGid
(
unix
.
Getgid
())
}
}
func
currentUserSubIDs
(
fileName
string
)
([]
SubID
,
error
)
{
u
,
err
:=
CurrentUser
()
if
err
!=
nil
{
return
nil
,
err
}
filter
:=
func
(
entry
SubID
)
bool
{
return
entry
.
Name
==
u
.
Name
||
entry
.
Name
==
strconv
.
Itoa
(
u
.
Uid
)
}
return
ParseSubIDFileFilter
(
fileName
,
filter
)
}
func
CurrentUserSubUIDs
()
([]
SubID
,
error
)
{
return
currentUserSubIDs
(
"/etc/subuid"
)
}
func
CurrentUserSubGIDs
()
([]
SubID
,
error
)
{
return
currentUserSubIDs
(
"/etc/subgid"
)
}
func
CurrentProcessUIDMap
()
([]
IDMap
,
error
)
{
return
ParseIDMapFile
(
"/proc/self/uid_map"
)
}
func
CurrentProcessGIDMap
()
([]
IDMap
,
error
)
{
return
ParseIDMapFile
(
"/proc/self/gid_map"
)
}
vendor/github.com/opencontainers/runc/libcontainer/user/user.go
View file @
2b642765
...
@@ -75,12 +75,29 @@ func groupFromOS(g *user.Group) (Group, error) {
...
@@ -75,12 +75,29 @@ func groupFromOS(g *user.Group) (Group, error) {
return
newGroup
,
nil
return
newGroup
,
nil
}
}
// SubID represents an entry in /etc/sub{u,g}id
type
SubID
struct
{
Name
string
SubID
int64
Count
int64
}
// IDMap represents an entry in /proc/PID/{u,g}id_map
type
IDMap
struct
{
ID
int64
ParentID
int64
Count
int64
}
func
parseLine
(
line
string
,
v
...
interface
{})
{
func
parseLine
(
line
string
,
v
...
interface
{})
{
if
line
==
""
{
parseParts
(
strings
.
Split
(
line
,
":"
),
v
...
)
}
func
parseParts
(
parts
[]
string
,
v
...
interface
{})
{
if
len
(
parts
)
==
0
{
return
return
}
}
parts
:=
strings
.
Split
(
line
,
":"
)
for
i
,
p
:=
range
parts
{
for
i
,
p
:=
range
parts
{
// Ignore cases where we don't have enough fields to populate the arguments.
// Ignore cases where we don't have enough fields to populate the arguments.
// Some configuration files like to misbehave.
// Some configuration files like to misbehave.
...
@@ -96,6 +113,8 @@ func parseLine(line string, v ...interface{}) {
...
@@ -96,6 +113,8 @@ func parseLine(line string, v ...interface{}) {
case
*
int
:
case
*
int
:
// "numbers", with conversion errors ignored because of some misbehaving configuration files.
// "numbers", with conversion errors ignored because of some misbehaving configuration files.
*
e
,
_
=
strconv
.
Atoi
(
p
)
*
e
,
_
=
strconv
.
Atoi
(
p
)
case
*
int64
:
*
e
,
_
=
strconv
.
ParseInt
(
p
,
10
,
64
)
case
*
[]
string
:
case
*
[]
string
:
// Comma-separated lists.
// Comma-separated lists.
if
p
!=
""
{
if
p
!=
""
{
...
@@ -105,7 +124,7 @@ func parseLine(line string, v ...interface{}) {
...
@@ -105,7 +124,7 @@ func parseLine(line string, v ...interface{}) {
}
}
default
:
default
:
// Someone goof'd when writing code using this function. Scream so they can hear us.
// Someone goof'd when writing code using this function. Scream so they can hear us.
panic
(
fmt
.
Sprintf
(
"parseLine only accepts {*string, *int, *[]string} as arguments! %#v is not a pointer!"
,
e
))
panic
(
fmt
.
Sprintf
(
"parseLine only accepts {*string, *int, *
int64, *
[]string} as arguments! %#v is not a pointer!"
,
e
))
}
}
}
}
}
}
...
@@ -479,3 +498,111 @@ func GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int
...
@@ -479,3 +498,111 @@ func GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int
}
}
return
GetAdditionalGroups
(
additionalGroups
,
group
)
return
GetAdditionalGroups
(
additionalGroups
,
group
)
}
}
func
ParseSubIDFile
(
path
string
)
([]
SubID
,
error
)
{
subid
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
return
nil
,
err
}
defer
subid
.
Close
()
return
ParseSubID
(
subid
)
}
func
ParseSubID
(
subid
io
.
Reader
)
([]
SubID
,
error
)
{
return
ParseSubIDFilter
(
subid
,
nil
)
}
func
ParseSubIDFileFilter
(
path
string
,
filter
func
(
SubID
)
bool
)
([]
SubID
,
error
)
{
subid
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
return
nil
,
err
}
defer
subid
.
Close
()
return
ParseSubIDFilter
(
subid
,
filter
)
}
func
ParseSubIDFilter
(
r
io
.
Reader
,
filter
func
(
SubID
)
bool
)
([]
SubID
,
error
)
{
if
r
==
nil
{
return
nil
,
fmt
.
Errorf
(
"nil source for subid-formatted data"
)
}
var
(
s
=
bufio
.
NewScanner
(
r
)
out
=
[]
SubID
{}
)
for
s
.
Scan
()
{
if
err
:=
s
.
Err
();
err
!=
nil
{
return
nil
,
err
}
line
:=
strings
.
TrimSpace
(
s
.
Text
())
if
line
==
""
{
continue
}
// see: man 5 subuid
p
:=
SubID
{}
parseLine
(
line
,
&
p
.
Name
,
&
p
.
SubID
,
&
p
.
Count
)
if
filter
==
nil
||
filter
(
p
)
{
out
=
append
(
out
,
p
)
}
}
return
out
,
nil
}
func
ParseIDMapFile
(
path
string
)
([]
IDMap
,
error
)
{
r
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
return
nil
,
err
}
defer
r
.
Close
()
return
ParseIDMap
(
r
)
}
func
ParseIDMap
(
r
io
.
Reader
)
([]
IDMap
,
error
)
{
return
ParseIDMapFilter
(
r
,
nil
)
}
func
ParseIDMapFileFilter
(
path
string
,
filter
func
(
IDMap
)
bool
)
([]
IDMap
,
error
)
{
r
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
return
nil
,
err
}
defer
r
.
Close
()
return
ParseIDMapFilter
(
r
,
filter
)
}
func
ParseIDMapFilter
(
r
io
.
Reader
,
filter
func
(
IDMap
)
bool
)
([]
IDMap
,
error
)
{
if
r
==
nil
{
return
nil
,
fmt
.
Errorf
(
"nil source for idmap-formatted data"
)
}
var
(
s
=
bufio
.
NewScanner
(
r
)
out
=
[]
IDMap
{}
)
for
s
.
Scan
()
{
if
err
:=
s
.
Err
();
err
!=
nil
{
return
nil
,
err
}
line
:=
strings
.
TrimSpace
(
s
.
Text
())
if
line
==
""
{
continue
}
// see: man 7 user_namespaces
p
:=
IDMap
{}
parseParts
(
strings
.
Fields
(
line
),
&
p
.
ID
,
&
p
.
ParentID
,
&
p
.
Count
)
if
filter
==
nil
||
filter
(
p
)
{
out
=
append
(
out
,
p
)
}
}
return
out
,
nil
}
vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go
View file @
2b642765
package
utils
package
utils
import
(
import
(
"crypto/rand"
"encoding/hex"
"encoding/json"
"encoding/json"
"io"
"io"
"os"
"os"
...
@@ -17,19 +15,6 @@ const (
...
@@ -17,19 +15,6 @@ const (
exitSignalOffset
=
128
exitSignalOffset
=
128
)
)
// GenerateRandomName returns a new name joined with a prefix. This size
// specified is used to truncate the randomly generated value
func
GenerateRandomName
(
prefix
string
,
size
int
)
(
string
,
error
)
{
id
:=
make
([]
byte
,
32
)
if
_
,
err
:=
io
.
ReadFull
(
rand
.
Reader
,
id
);
err
!=
nil
{
return
""
,
err
}
if
size
>
64
{
size
=
64
}
return
prefix
+
hex
.
EncodeToString
(
id
)[
:
size
],
nil
}
// ResolveRootfs ensures that the current working directory is
// ResolveRootfs ensures that the current working directory is
// not a symlink and returns the absolute path to the rootfs
// not a symlink and returns the absolute path to the rootfs
func
ResolveRootfs
(
uncleanRootfs
string
)
(
string
,
error
)
{
func
ResolveRootfs
(
uncleanRootfs
string
)
(
string
,
error
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment