Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
sysctl: Add complete sysctl support
Browse files Browse the repository at this point in the history
We support most of the namespaced sysctls today as we pass them to
libcontainer as part of the OCI spec. libcontainer then applies them
for the container after veryfing they can be applied.
However, the verification fails for network related sysctls as
libcontainer expects a separate network namespace for network
sysctls. This check fails for us as we create network namspace on
the host side. To fix these, apply the network sysctls manually
and purge them from the spec, leaving other sysctls to be applied
by libcontainer.

Fixes #472

Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
  • Loading branch information
amshinde committed Mar 6, 2019
1 parent a2037c0 commit 4f249bf
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,10 @@ func (a *agentGRPC) CreateContainer(ctx context.Context, req *pb.CreateContainer
ociSpec.Linux.Resources.CPU.Cpus = availableCpuset
}

if err := a.applyNetworkSysctls(ociSpec); err != nil {
return emptyResp, err
}

if a.sandbox.guestHooksPresent {
// Add any custom OCI hooks to the spec
a.sandbox.addGuestHooks(ociSpec)
Expand Down Expand Up @@ -699,6 +703,41 @@ func (a *agentGRPC) CreateContainer(ctx context.Context, req *pb.CreateContainer
return a.finishCreateContainer(ctr, req, config)
}

// Path overridden in unit tests
var procSysDir = "/proc/sys"

// writeSystemProperty writes the value to a path under /proc/sys as determined from the key.
// For e.g. net.ipv4.ip_forward translated to /proc/sys/net/ipv4/ip_forward.
func writeSystemProperty(key, value string) error {
keyPath := strings.Replace(key, ".", "/", -1)
return ioutil.WriteFile(filepath.Join(procSysDir, keyPath), []byte(value), 0644)
}

func isNetworkSysctl(sysctl string) bool {
return strings.HasPrefix(sysctl, "net.")
}

// libcontainer checks if the container is running in a separate network namespace
// before applying the network related sysctls. If it sees that the network namespace of the container
// is the same as the "host", it errors out. Since we do no create a new net namespace inside the guest,
// libcontainer would error out while verifying network sysctls. To overcome this, we dont pass
// network sysctls to libcontainer, we instead have the agent directly apply them. All other namespaced
// sysctls are applied by libcontainer.
func (a *agentGRPC) applyNetworkSysctls(ociSpec *specs.Spec) error {
sysctls := ociSpec.Linux.Sysctl
for key, value := range sysctls {
if isNetworkSysctl(key) {
if err := writeSystemProperty(key, value); err != nil {
return err
}
delete(sysctls, key)
}
}

ociSpec.Linux.Sysctl = sysctls
return nil
}

func posixRlimitsToRlimits(posixRlimits []specs.POSIXRlimit) []configs.Rlimit {
var rlimits []configs.Rlimit

Expand Down

0 comments on commit 4f249bf

Please sign in to comment.