gofumpt (mvdan.cc/gofumpt) is a fork of gofmt with stricter rules.
Brought to you by
git ls-files \*.go | grep -v ^vendor/ | xargs gofumpt -s -w
Looking at the diff, all these changes make sense.
Also, replace gofmt with gofumpt in golangci.yml.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Commit 88e8350de2, among the other things, replaced filepath.Join with
securejoin.SecureJoin for both reads and writes to cgroupfs.
Commits e76ac1c054 and 31f0f5b7e0 switched more code to use
fscommon.ReadFile (and thus securejoin). Commit 0228226e6d introduced
fscommon.OpenFile (which uses securejoin as the fallback if openat2(2)
is not available, which is the case for older kernels), and commit
c95e69007c switched most of cgroup/fs[2] code to use it.
As a result, fs.GetStats() method became noticeable slower, mostly due
to securejoin calling os.Lstat and filepath.Clean.
Using securejoin as a security measure for cgroupfs files is
not well justified, as cgroupfs do not contain symlinks, and none of the
code using it have uncleaned paths. In particular, fs/fs2/systemd
managers do check and sanitize their paths.
This commit modifies the code to not use securejoin. Instead, it checks
that the opened file is indeed on cgroupfs.
Using BenchmarkGetStats on a CentOS 8 VM, I see the following
improvement:
Before:
> BenchmarkGetStats-8 8376 625135 ns/op
After:
> BenchmarkGetStats-8 12226 485015 ns/op
An intermediate version, with no fstatfs to check fstype:
> BenchmarkGetStats-8 13162 452281 ns/op
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
In case openat2() is not available, it does not make sense to calculate
relpath (and check if path has /sys/fs/cgroup prefix).
Reverse the order of checks to not do that in case openat2 is not
available.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
In case we get ENOSYS from openat2(2), this is expected, so log that
we're falling back to using securejoin as debug.
Otherwise, log it as a warning (as the error is unexpected, but we're
still good to go).
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
In case openat2 is available, it will be used to guarantee
that we're not accessing anything other than cgroupfs[2] files.
In cases when openat2 is not available, or when cgroup has a
non-standard prefix (not "/sys/fs/cgroup", which might theoretically
be the case on some very old installs and/or very custom systems),
fall back to using securejoin + os.Open like we did before.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
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>