mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
c84a878cac
Apparently Write (and WriteString) must return an error (apparently io.ErrShortWrite) on short writes (see [1], [2]), so no explicit check for a short write is needed. While at it, use (*os.File).WriteString directly rather than io.WriteString. [1]: https://pkg.go.dev/os#File.Write [2]: https://pkg.go.dev/io#Writer Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
51 lines
1.3 KiB
Go
51 lines
1.3 KiB
Go
package sys
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"golang.org/x/sys/unix"
|
|
|
|
"github.com/cyphar/filepath-securejoin/pathrs-lite"
|
|
"github.com/cyphar/filepath-securejoin/pathrs-lite/procfs"
|
|
)
|
|
|
|
func procfsOpenRoot(proc *procfs.Handle, subpath string, flags int) (*os.File, error) {
|
|
handle, err := proc.OpenRoot(subpath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer handle.Close()
|
|
|
|
return pathrs.Reopen(handle, flags)
|
|
}
|
|
|
|
// WriteSysctls sets the given sysctls to the requested values.
|
|
func WriteSysctls(sysctls map[string]string) error {
|
|
// We are going to write multiple sysctls, which require writing to an
|
|
// unmasked procfs which is not going to be cached. To avoid creating a new
|
|
// procfs instance for each one, just allocate one handle for all of them.
|
|
proc, err := procfs.OpenUnsafeProcRoot()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer proc.Close()
|
|
|
|
for key, value := range sysctls {
|
|
keyPath := strings.ReplaceAll(key, ".", "/")
|
|
|
|
sysctlFile, err := procfsOpenRoot(proc, "sys/"+keyPath, unix.O_WRONLY|unix.O_TRUNC|unix.O_CLOEXEC)
|
|
if err != nil {
|
|
return fmt.Errorf("open sysctl %s file: %w", key, err)
|
|
}
|
|
defer sysctlFile.Close()
|
|
|
|
_, err = sysctlFile.WriteString(value)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to write sysctl %s = %q: %w", key, value, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|