Commit Graph

6216 Commits

Author SHA1 Message Date
Kir Kolyshkin 5ebcfa6281 [1.1] libct: rm intelrtd.Manager interface, NewIntelRdtManager
[This is a manual port of commit dbd990d555 to release-1.1
branch. Original description follows.]

Remove intelrtd.Manager interface, since we only have a single
implementation, and do not expect another one.

Rename intelRdtManager to Manager, and modify its users accordingly.

Remove NewIntelRdtManager from factory.

Remove IntelRdtfs. Instead, make intelrdt.NewManager return nil if the
feature is not available.

Remove TestFactoryNewIntelRdt as it is now identical to TestFactoryNew.

Add internal function newManager to be used for tests (to make sure
some testing is done even when the feature is not available in
kernel/hardware).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-10 17:09:53 +08:00
Kir Kolyshkin 69473d0af9 libct: rm TestGetContainerStats, mockIntelRdtManager
TestGetContainerStats test a function that is smaller than the test
itself, and only calls a couple of other functions (which are
represented by mocks). It does not make sense to have it.

mockIntelRdtManager is only needed for TestGetContainerStats
and TestGetContainerState, which basically tests that Path
is called. Also, it does not make much sense to have it.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 85932850ec)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-10 17:09:53 +08:00
Kir Kolyshkin dfdc7d078f libct/intelrdt: explain why mountinfo is required
For the Nth time I wanted to replace parsing mountinfo with
statfs and the check for superblock magic, but it is not possible
since some code relies of mount options check which can only
be obtained via mountinfo.

Add a note about it.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 5e201e7ce2)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-10 17:09:53 +08:00
Kir Kolyshkin 5ba1b8ec43 libct/intelrdt: faster init if rdt is unsupported
In a (quite common) case RDT is not supported by the kernel/hardware,
it does not make sense to parse /proc/cpuinfo and /proc/self/mountinfo,
and yet the current code does it (on every runc exec, for example).

Fortunately, there is a quick way to check whether RDT is available --
if so, kernel creates /sys/fs/resctrl directory. Check its existence,
and skip all the other initialization if it's not present.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit edeb3b376c)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-10 17:09:53 +08:00
Kir Kolyshkin a5407b9a36 libct/intelrdt: remove findMountpointDir test
This test was written back in the day when findIntelRdtMountpointDir
was using its own mountinfo parser. Commit f1c1fdf911 changed that,
and thus this test is actually testing moby/sys/mountinfo parser, which
does not make much sense.

Remove the test, and drop the io.Reader argument since we no longer need
to parse a custom file.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 6c6b14e075)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-10 17:09:53 +08:00
Kir Kolyshkin dc8d0cc172 libct/intelrdt: wrap Root in sync.Once
In case resctrl filesystem can not be found in /proc/self/mountinfo
(which is pretty common on non-server or non-x86 hardware), subsequent
calls to Root() will result in parsing it again and again.

Use sync.Once to avoid it. Make unit tests call it so that Root() won't
actually parse mountinfo in tests.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 02e961bcf9)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-10 17:09:53 +08:00
Mrunal Patel 9c15e562c4 Merge pull request #3977 from haircommander/v2root-1.1
[1.1] libct/cg/fs2: use `file` + `anon` + `swap` for usage
2023-08-09 20:47:40 -07:00
Alexander Eldeib 929d04fc8b libct/cg/fs2: use file + anon + swap for usage
This aligns v2 usage calculations more closely with v1.
Current node-level reporting for v1 vs v2 on the same
machine under similar load may differ by ~250-750Mi.

Also return usage as combined swap + memory usage, aligned
with v1 and non-root v2 cgroups.

`mem_cgroup_usage` in the kernel counts NR_FILE_PAGES
+ NR_ANON_MAPPED + `nr_swap_pages` (if swap enabled) [^0].

Using total - free results in higher "usage" numbers.
This is likely due to various types of reclaimable
memory technically counted as in use (e.g. inactive anon).

See also https://github.com/kubernetes/kubernetes/issues/118916 for more context

[^0]: https://github.com/torvalds/linux/blob/06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5/mm/memcontrol.c#L3673-L3680

Signed-off-by: Alexander Eldeib <alexeldeib@gmail.com>
2023-08-09 19:20:15 -07:00
Mrunal Patel 1f3fa728b6 Merge pull request #3976 from kolyshkin/1.1-go-1.21-ci
[1.1] Add go 1.21 to CI
2023-08-09 18:40:37 -07:00
Kir Kolyshkin bdbfe0425f ci: bump golangci-lint, remove fixed exception
The exception was fixed by https://github.com/polyfloyd/go-errorlint/pull/12
which eventually made its way into golangci-lint.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 98317c16ed)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-09 16:44:50 -07:00
Kir Kolyshkin d398ad2a31 gha: disable setup-go cache for golangci job
Since commit e3cf217cf1 actions/setup-go@v4 uses caching
implicitly, and olangci/golangci-lint-action also uses caching.

These two caches clash, resulting in multiple warnings in CI logs.

The official golangci-lint-action solution is to disable caching
for setup-go job (see [1]). Do the same.

[1] https://github.com/golangci/golangci-lint-action/pull/704

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 62cc13ea1a)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-09 16:44:50 -07:00
Kir Kolyshkin 5888c55d75 ci/gha: rm actions/cache from validate/deps job
Since commit e3cf217cf1 actions/setup-go@v4 uses caching
implicitly, so it is no longer required.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 083e9789b8)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-09 16:44:42 -07:00
dependabot[bot] a47c15b452 build(deps): bump actions/setup-go from 3 to 4
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3 to 4.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit e3cf217cf1)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-08 18:48:40 -07:00
Kir Kolyshkin 44a53f088c ci: fix TestOpenat2 when no systemd is used
A few cases relied on the fact that systemd is used, and thus
/sys/fs/cgroup/user.slice is available.

Guess what, in case of "make unittest" it might not be.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 5c6b334c88)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-08 18:47:03 -07:00
Kir Kolyshkin cff41a893c ci: fix TestNilResources when systemd not available
Split the test into two -- for fs and systemd cgroup managers, and only
run the second one if systemd is available.

Prevents the following failure during `make unittest`:

> === RUN   TestNilResources
>     manager_test.go:27: systemd not running on this host, cannot use systemd cgroups manager
> --- FAIL: TestNilResources (0.22s)

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 962019d64e)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-08 18:46:40 -07:00
Kir Kolyshkin 37405ca009 Fix running tests under Docker/Podman and cgroup v2
For "make integration", the tests are run inside a Docker/Podman
container. Problem is, if cgroup v2 is used, the in-container
/sys/fs/cgroup/cgroup.subtree_control is empty.

The added script, used as Docker entrypoint, moves the current process
into a sub-cgroup, and then adds all controllers in top-level
cgroup.subtree_control.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit cfc801b7ed)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-08 18:46:15 -07:00
Kir Kolyshkin 1c52424228 [1.1] ci/gha: rm unsup Go 1.19.x, add 1.21.x
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-08 18:44:33 -07:00
Kir Kolyshkin ac310917d5 ci/cirrus: improve host_info
1. Do not use echo, as this results in lines like this:

	...
	echo "-----"
	-----
	...

2. Move "cat /proc/cpuinfo" to be the last one, as the output is usually
   very long.

3. Add "go version" to CentOS jobs.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit fd1a79ffc8)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-08 18:38:38 -07:00
Kir Kolyshkin ecccc4329c [1.1] ci/cirrus: use Go 1.19.x not 1.19
[XXX 1.1 note: the above subject and the rest of the commit message
is the original description from the cherry-picked commit which talks
about 1.19 -- while in fact it is now 1.20.]

This variable is used in curl to download a go release, so we are using
the initial Go 1.19 release in Cirrus CI, not the latest Go 1.19.x
release.

From the CI perspective, it makes more sense to use the latest release.

Add some jq magic to extract the latest minor release information
from the download page, and use it.

This brings Cirrus CI jobs logic in line with all the others (GHA,
Dockerfile), where by 1.20 we actually mean "latest 1.20.x".

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 873d7bb3a3)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-08 18:38:38 -07:00
Kir Kolyshkin bb2401eeef [1.1] ci/cirrus: use Go 1.20
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-08-08 18:38:30 -07:00
Kir Kolyshkin aa68c400a8 Merge pull request #3961 from lifubang/backport-ModeStricky
[1.1] Fix some file mode bits missing when doing mount syscall
2023-08-02 22:14:30 -07:00
lifubang aaed58c87b add a test case about missing stricky bit
Signed-off-by: lifubang <lifubang@acmcoder.com>
(cherry picked from commit 83137c6884)
Signed-off-by: lifubang <lifubang@acmcoder.com>
2023-08-03 11:41:34 +08:00
lifubang 3d3a2b38b4 fix some file mode bits missing when doing mount syscall
Signed-off-by: lifubang <lifubang@acmcoder.com>
(cherry picked from commit 6092a4b42d)
2023-08-03 11:31:03 +08:00
Kir Kolyshkin 0699bf314f Merge pull request #3958 from akhilerm/upgrade-deprecate-actions
[1.1] deps: Update github actions packages in validate workflow
2023-08-02 18:00:24 -07:00
Akhil Mohan 7c36375ae5 Update github actions packages in validate workflow
Resolve nodejs 12 deprecation warnings by updating
lumaxis/shellcheck-problem-matchers and actions/upload-artifact

Signed-off-by: Akhil Mohan <makhil@vmware.com>
2023-08-02 17:10:10 +05:30
Aleksa Sarai dd03bb89ed merge pr #3940 into release-1.1
Akihiro Suda (2):
  VERSION: back to development
  VERSION: release 1.1.8

LGTMs: kolyshkin AkihiroSuda cyphar lifubang
Closes #3940
2023-07-19 23:39:58 +10:00
Akihiro Suda 1fa89476d4 VERSION: back to development
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2023-07-19 14:15:36 +09:00
Akihiro Suda 82f18fe0e4 VERSION: release 1.1.8
Thanks to lifubang for suggesting the release name ("海纳百川 有容乃大")

Co-authored-by: lifubang <lifubang@acmcoder.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
v1.1.8
2023-07-19 14:15:32 +09:00
lfbzhm 096277c761 Merge pull request #3921 from jiusanzhou/1.1-bugfix/skip-update-while-frozen-faield
[1.1] libct/cg/sd/v1: do not update non-frozen cgroup after frozen failed.
2023-07-16 08:16:43 +08:00
Akihiro Suda 828eb47c39 Merge pull request #3932 from kolyshkin/1.1-3888
[1.1] runc delete: call systemd's reset-failed
2023-07-12 13:20:45 +08:00
Kir Kolyshkin ef6491ec9f tests/int/delete: make sure runc delete removes failed unit
The passing run (with the fix) looks like this:

----
delete.bats
 ✓ runc delete removes failed systemd unit [4556]
   runc spec (status=0):

   runc run -d --console-socket /tmp/bats-run-B08vu1/runc.lbQwU5/tty/sock test-failed-unit (status=0):

   Warning: The unit file, source configuration file or drop-ins of runc-cgroups-integration-test-12869.scope changed on disk. Run 'systemctl daemon-reload' to reload units.
   × runc-cgroups-integration-test-12869.scope - libcontainer container integration-test-12869
        Loaded: loaded (/run/systemd/transient/runc-cgroups-integration-test-12869.scope; transient)
     Transient: yes
       Drop-In: /run/systemd/transient/runc-cgroups-integration-test-12869.scope.d
                └─50-DevicePolicy.conf, 50-DeviceAllow.conf
        Active: failed (Result: timeout) since Tue 2023-06-13 14:41:38 PDT; 751ms ago
      Duration: 2.144s
           CPU: 8ms

   Jun 13 14:41:34 kir-rhat systemd[1]: Started runc-cgroups-integration-test-12869.scope - libcontainer container integration-test-12869.
   Jun 13 14:41:37 kir-rhat systemd[1]: runc-cgroups-integration-test-12869.scope: Scope reached runtime time limit. Stopping.
   Jun 13 14:41:38 kir-rhat systemd[1]: runc-cgroups-integration-test-12869.scope: Stopping timed out. Killing.
   Jun 13 14:41:38 kir-rhat systemd[1]: runc-cgroups-integration-test-12869.scope: Killing process 1107438 (sleep) with signal SIGKILL.
   Jun 13 14:41:38 kir-rhat systemd[1]: runc-cgroups-integration-test-12869.scope: Failed with result 'timeout'.
   runc delete test-failed-unit (status=0):

   Unit runc-cgroups-integration-test-12869.scope could not be found.
----

Before the fix, the test was failing like this:

----
delete.bats
 ✗ runc delete removes failed systemd unit
   (in test file tests/integration/delete.bats, line 194)
     `run -4 systemctl status "$SD_UNIT_NAME"' failed, expected exit code 4, got 3
  ....
----

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit ad040b1caf)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-07-08 11:58:29 -07:00
Kir Kolyshkin ebdd4fa6b1 [1.1] tests/int: add "requires systemd_vNNN"
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 58a811f6aa)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-07-08 11:57:32 -07:00
Kir Kolyshkin 1188c5a192 runc delete: call systemd's reset-failed
runc delete is supposed to remove all the container's artefacts.
In case systemd cgroup driver is used, and the systemd unit has failed
(e.g. oom-killed), systemd won't remove the unit (that is, unless the
"CollectMode: inactive-or-failed" property is set).

Call reset-failed from manager.Destroy so the failed unit will be
removed during "runc delete".

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 43564a7b55)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-07-08 11:54:41 -07:00
Kir Kolyshkin 71e7600768 libct/cg/sd: remove logging from resetFailedUnit
Sometimes we call resetFailedUnit as a cleanup measure, and we don't
care if it fails or not. So, move error reporting to its callers, and
ignore error in cases we don't really expect it to succeed.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 91b4cd25b7)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-07-08 11:54:20 -07:00
Kir Kolyshkin 3a4b3af661 tests/int/cgroups: remove useless/wrong setting
There is no such thing as linux.resources.memorySwap (the mem+swap is
set as linux.resources.memory.swap).

As it is not used in this test anyway, remove it.

Fixes: 4929c05ad1
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit dacb3aaa0d)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-07-08 11:53:51 -07:00
Zoe 6bc3f22a31 libct/cg/sd/v1: do not update non-frozen cgroup after frozen failed.
In code we have frozen the cgroup to avoid the processes get
an occasional "permission denied" error, while the systemd's application of device
rules is done disruptively. When the processes in the container can not
be frozen over 2 seconds (which defined in fs/freezer.go),
we still update the cgroup which resulting the container get an occasional
"permission denied" error in some cases.

Return error directly without updating cgroup, when freeze fails.

Fixes: #3803

Signed-off-by: Zoe <hi@zoe.im>
2023-06-30 19:23:36 +08:00
Sebastiaan van Stijn ca73c9fd4b Merge pull request #3918 from kolyshkin/1.1-3553
[1.1] ci/cirrus: enable some rootless tests on cs9
2023-06-29 01:37:36 +02:00
Akihiro Suda 3b5356155c Merge pull request #3917 from kolyshkin/1.1-3899
[1.1] docs/systemd: fix a broken link
2023-06-29 07:49:54 +09:00
Akihiro Suda 1cdfa95f39 Merge pull request #3905 from CARV-ICS-FORTH/release-1.1-riscv64
Backport riscv64 support into 1.1.x
2023-06-29 07:49:28 +09:00
Kir Kolyshkin 0d93d7d13f release: add riscv64 binary
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit a14cc4059d)
2023-06-28 22:34:45 +03:00
Akihiro Suda 9164fe17a7 libct/seccomp: add riscv64
Co-authored-by: Kir Kolyshkin <kolyshkin@gmail.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 1d7b297128)
2023-06-28 22:34:45 +03:00
Kir Kolyshkin ed47e31a05 Makefile: set CGO_ENABLED=1 when needed
It doesn't matter whether static or dynamic linking is used, runc
always needs libcontainer/nsenter, which is written in C and thus
requires cgo. Same is true for libcontainer/integration.

In addition, contrib/pkg/seccompagent also needs cgo (if seccomp build
tag is set), as it need to be linked against libseccomp C library.

By default, cgo is disabled when cross-compiling, meaning that
CGO_ENABLED=1 has to be set explicitly in such cases.

In all other cases (e.g. other contrib binaries) we do not need cgo.

Remove CGO_ENABLED=1 from GO_BUILD_STATIC (as it does not have anything
to do with static linking), and add it to all targets that require it.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit dafcacb522)
2023-06-28 22:34:45 +03:00
Kir Kolyshkin 923ae4da8c Makefile: add support for static PIE
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 21e32d47d3)
2023-06-28 22:34:45 +03:00
Kir Kolyshkin 2abca872b1 Makefile: fix GO_BUILDMODE setting
1. Set to empty value by default.

2. Assume Linux (remove GOOS check, since we do not support other OSes).

3. Instead of using a "not-supported" list, use a "supported" list
   (as Go release notes usually say which platforms are supported).
   As of today, -buildmode=pie is supported for:

 * linux/386, linux/amd64, linux/arm, linux/arm64, and linux/ppc64le
   (since Go 1.6, see https://tip.golang.org/doc/go1.6#compiler)

 * linux/s390x (since Go 1.7, which adds the initial port)

 * linux/riscv64 (since Go 1.16, see
   https://tip.golang.org/doc/go1.16#riscv)

   NOTE this does not mean we support these architectures; it is merely
   a way to see if -buildmode=pie can be used.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit ab5c60d02f)
2023-06-28 22:34:45 +03:00
Kir Kolyshkin 120ec5bda3 Makefile: add LDFLAGS_COMMON and LDFLAGS_STATIC
LDFLAGS_COMMON are used from two places, so it makes sense to dedup.

LDFLAGS_STATIC is a preparation for the next commit.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit f2f6e59937)
2023-06-28 22:34:45 +03:00
Kir Kolyshkin b994011369 Dockerfile: don't use crossbuild-essential-*
All we need is gcc, libc-dev, and binutils. In addition to that,
crossbuild-essential installs g++, libstdc++-dev, and a bunch of perl
packages and libraries which we do not need.

This should speed up image building, as well as make it smaller.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit f0f1b5f969)
2023-06-28 22:34:45 +03:00
Kir Kolyshkin 028fc57aaa Dockerfile: rm dpkg --add-architecture lines
Dockerfile used to install libseccomp-dev packages for different
architectures. This is no longer true since commit f30244ee1b, which
changed to cross-compiling libseccomp (so we can get a static library
to link against).

Thus, adding extra architectures is no longer needed.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 476aa18abe)
2023-06-28 22:34:45 +03:00
Kir Kolyshkin 4449ce8486 Dockerfile: nit
We do not use all the files from scripts, only seccomp.sh and lib.sh.

This prevents unneeded rebuild of the image if e.g.
scripts/release_build.sh has changed.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit d542ad65ba)
2023-06-28 22:34:45 +03:00
Kir Kolyshkin d375351b79 ci/cirrus: enable rootless tests on cs9
We were not running localrootlessintegration test on CentOS Stream 9
because of some failures fixed by previous commits.

Enable rootless integration with both systemd and fs drivers.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 78d31a4941)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-06-28 09:42:53 -07:00
Kir Kolyshkin e1a8b52f3a tests/int/cgroups: filter out rdma
Filter out rdma controller since systemd is unable to delegate it.
Similar to commits 05272718f4 and 601cf5825f.

(cherry picked from commit e83ca51913)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-06-28 09:41:58 -07:00