diff --git a/Documentation/tuning.md b/Documentation/tuning.md new file mode 100644 index 00000000..bc786d88 --- /dev/null +++ b/Documentation/tuning.md @@ -0,0 +1,36 @@ +# tuning plugin + +## Overview + +This plugin can change some system controls (sysctls) in the network namespace. +It does not create any network interfaces and therefore does not bring connectivity by itself. +It is only useful when used in addition to other plugins. + +## Operation +The following network configuration file +``` +{ + "name": "mytuning", + "type": "tuning", + "sysctl": { + "net.core.somaxconn": "500" + } +} +``` +will set /proc/sys/net/core/somaxconn to 500. +Other sysctls can be modified as long as they belong to the network namespace (`/proc/sys/net/*`). + +A successful result would simply be: +``` +{ + "cniVersion": "0.1.0" +} +``` + +## Network sysctls documentation + +Some network sysctls are documented in the Linux sources: + +- [Documentation/sysctl/net.txt](https://www.kernel.org/doc/Documentation/sysctl/net.txt) +- [Documentation/networking/ip-sysctl.txt](https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt) +- [Documentation/networking/](https://www.kernel.org/doc/Documentation/networking/) diff --git a/plugins/meta/tuning/tuning.go b/plugins/meta/tuning/tuning.go new file mode 100644 index 00000000..91118dfb --- /dev/null +++ b/plugins/meta/tuning/tuning.go @@ -0,0 +1,83 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This is a "meta-plugin". It reads in its own netconf, it does not create +// any network interface but just changes the network sysctl. + +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/appc/cni/pkg/ns" + "github.com/appc/cni/pkg/skel" + "github.com/appc/cni/pkg/types" +) + +// TuningConf represents the network tuning configuration. +type TuningConf struct { + types.NetConf + SysCtl map[string]string `json:"sysctl"` +} + +func cmdAdd(args *skel.CmdArgs) error { + tuningConf := TuningConf{} + if err := json.Unmarshal(args.StdinData, &tuningConf); err != nil { + return fmt.Errorf("failed to load netconf: %v", err) + } + + // The directory /proc/sys/net is per network namespace. Enter in the + // network namespace before writing on it. + + err := ns.WithNetNSPath(args.Netns, false, func(hostNS *os.File) error { + for key, value := range tuningConf.SysCtl { + fileName := filepath.Join("/proc/sys", strings.Replace(key, ".", "/", -1)) + fileName = filepath.Clean(fileName) + + // Refuse to modify sysctl parameters that don't belong + // to the network subsystem. + if !strings.HasPrefix(fileName, "/proc/sys/net/") { + return fmt.Errorf("invalid net sysctl key: %q", key) + } + content := []byte(value) + err := ioutil.WriteFile(fileName, content, 0644) + if err != nil { + return err + } + } + return nil + }) + if err != nil { + return err + } + + result := types.Result{} + return result.Print() +} + +func cmdDel(args *skel.CmdArgs) error { + // TODO: the settings are not reverted to the previous values. Reverting the + // settings is not useful when the whole container goes away but it could be + // useful in scenarios where plugins are added and removed at runtime. + return nil +} + +func main() { + skel.PluginMain(cmdAdd, cmdDel) +} diff --git a/test b/test index bd123ff6..6085cfe2 100755 --- a/test +++ b/test @@ -12,7 +12,7 @@ set -e source ./build TESTABLE="plugins/ipam/dhcp" -FORMATTABLE="$TESTABLE libcni pkg/ip pkg/ns pkg/invoke pkg/types pkg/ipam pkg/skel plugins/ipam/host-local plugins/main/bridge plugins/meta/flannel" +FORMATTABLE="$TESTABLE libcni pkg/ip pkg/ns pkg/invoke pkg/types pkg/ipam pkg/skel plugins/ipam/host-local plugins/main/bridge plugins/meta/flannel plugins/meta/tuning" # user has not provided PKG override if [ -z "$PKG" ]; then