From 2fae6d9fd65ebd0f582a4d49eeb4846b7d6eb387 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 5 Jan 2023 16:44:26 +0100 Subject: [PATCH] libnetwork: change lock path to tmpfs for root The default /etc/containers/networks location might not be writeable, while this breaks podman network create it does not need to break all podman commands since the lock is created on libpod initialization. ref https://github.com/containers/common/pull/1270 Signed-off-by: Paul Holzinger --- common/libnetwork/cni/network.go | 24 +++++++++++------------- common/libnetwork/netavark/const.go | 2 ++ common/libnetwork/netavark/network.go | 9 +++++++-- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/common/libnetwork/cni/network.go b/common/libnetwork/cni/network.go index 38ead2ddf8..ad0f10166a 100644 --- a/common/libnetwork/cni/network.go +++ b/common/libnetwork/cni/network.go @@ -18,10 +18,12 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/storage/pkg/lockfile" + "github.com/containers/storage/pkg/unshare" "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" ) +const defaultRootLockPath = "/run/lock/podman-cni.lock" + type cniNetwork struct { // cniConfigDir is directory where the cni config files are stored. cniConfigDir string @@ -81,19 +83,15 @@ type InitConfig struct { // NewCNINetworkInterface creates the ContainerNetwork interface for the CNI backend. // Note: The networks are not loaded from disk until a method is called. func NewCNINetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { - // TODO: consider using a shared memory lock - lock, err := lockfile.GetLockFile(filepath.Join(conf.CNIConfigDir, "cni.lock")) + // root needs to use a globally unique lock because there is only one host netns + lockPath := defaultRootLockPath + if unshare.IsRootless() { + lockPath = filepath.Join(conf.CNIConfigDir, "cni.lock") + } + + lock, err := lockfile.GetLockFile(lockPath) if err != nil { - // If we're on a read-only filesystem, there is no risk of - // contention. Fall back to a local lockfile. - if errors.Is(err, unix.EROFS) { - lock, err = lockfile.GetLockFile(filepath.Join(conf.RunDir, "cni.lock")) - if err != nil { - return nil, err - } - } else { - return nil, err - } + return nil, err } defaultNetworkName := conf.DefaultNetwork diff --git a/common/libnetwork/netavark/const.go b/common/libnetwork/netavark/const.go index b375acd1be..70c50b1a80 100644 --- a/common/libnetwork/netavark/const.go +++ b/common/libnetwork/netavark/const.go @@ -4,3 +4,5 @@ package netavark const defaultBridgeName = "podman" + +const defaultRootLockPath = "/run/lock/netavark.lock" diff --git a/common/libnetwork/netavark/network.go b/common/libnetwork/netavark/network.go index b14f4d0fd6..ca57df3000 100644 --- a/common/libnetwork/netavark/network.go +++ b/common/libnetwork/netavark/network.go @@ -94,8 +94,13 @@ type InitConfig struct { // NewNetworkInterface creates the ContainerNetwork interface for the netavark backend. // Note: The networks are not loaded from disk until a method is called. func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { - // TODO: consider using a shared memory lock - lock, err := lockfile.GetLockFile(filepath.Join(conf.NetworkConfigDir, "netavark.lock")) + // root needs to use a globally unique lock because there is only one host netns + lockPath := defaultRootLockPath + if unshare.IsRootless() { + lockPath = filepath.Join(conf.NetworkConfigDir, "netavark.lock") + } + + lock, err := lockfile.GetLockFile(lockPath) if err != nil { return nil, err }