libcontainer/cgroups/fscommon: introduce OpenFile

Move the functionality of opening a cgroup file into a separate
function, OpenFile, which, similar to ReadFile and WriteFile,
use separate dir and file arguments.

Change ReadFile and WriteFile to rely on OpenFile, and use lower-level
read and write instead of ones from ioutil.

It changes the semantics of WriteFile a bit -- it no longer uses
O_CREAT flag. This is good for real cgroup as there is no need to try
creating the files in there, but can potentially break WriteFile users
-- previously, EPERM error was returned for non-existing files, and
now it's ENOENT.

This also breaks the fs/fs2 unit tests since they write to pseudo-cgroup
files inside a test directory (not to a real cgroup fs), and now
fscommon.WriteFile do not create or truncate files, so we have to add a
variable that is set by the unit tests.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin
2020-09-22 19:59:18 -07:00
parent 0a9af3949f
commit 0228226e6d
3 changed files with 49 additions and 16 deletions
+33
View File
@@ -0,0 +1,33 @@
package fscommon
import (
"os"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/pkg/errors"
)
var (
// Set to true by fs unit tests
TestMode bool
)
// OpenFile opens a cgroup file in a given dir with given flags.
// It is supposed to be used for cgroup files only.
func OpenFile(dir, file string, flags int) (*os.File, error) {
if dir == "" {
return nil, errors.Errorf("no directory specified for %s", file)
}
mode := os.FileMode(0)
if TestMode && flags&os.O_WRONLY != 0 {
// "emulate" cgroup fs for unit tests
flags |= os.O_TRUNC | os.O_CREATE
mode = 0o600
}
path, err := securejoin.SecureJoin(dir, file)
if err != nil {
return nil, err
}
return os.OpenFile(path, flags, mode)
}