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 <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger 2023-01-05 16:44:26 +01:00
parent 480dfbe653
commit 2fae6d9fd6
3 changed files with 20 additions and 15 deletions

View File

@ -18,10 +18,12 @@ import (
"github.com/containers/common/libnetwork/types" "github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
"github.com/containers/storage/pkg/lockfile" "github.com/containers/storage/pkg/lockfile"
"github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
) )
const defaultRootLockPath = "/run/lock/podman-cni.lock"
type cniNetwork struct { type cniNetwork struct {
// cniConfigDir is directory where the cni config files are stored. // cniConfigDir is directory where the cni config files are stored.
cniConfigDir string cniConfigDir string
@ -81,19 +83,15 @@ type InitConfig struct {
// NewCNINetworkInterface creates the ContainerNetwork interface for the CNI backend. // NewCNINetworkInterface creates the ContainerNetwork interface for the CNI backend.
// Note: The networks are not loaded from disk until a method is called. // Note: The networks are not loaded from disk until a method is called.
func NewCNINetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { func NewCNINetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) {
// TODO: consider using a shared memory lock // root needs to use a globally unique lock because there is only one host netns
lock, err := lockfile.GetLockFile(filepath.Join(conf.CNIConfigDir, "cni.lock")) lockPath := defaultRootLockPath
if unshare.IsRootless() {
lockPath = filepath.Join(conf.CNIConfigDir, "cni.lock")
}
lock, err := lockfile.GetLockFile(lockPath)
if err != nil { if err != nil {
// If we're on a read-only filesystem, there is no risk of return nil, err
// 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
}
} }
defaultNetworkName := conf.DefaultNetwork defaultNetworkName := conf.DefaultNetwork

View File

@ -4,3 +4,5 @@
package netavark package netavark
const defaultBridgeName = "podman" const defaultBridgeName = "podman"
const defaultRootLockPath = "/run/lock/netavark.lock"

View File

@ -94,8 +94,13 @@ type InitConfig struct {
// NewNetworkInterface creates the ContainerNetwork interface for the netavark backend. // NewNetworkInterface creates the ContainerNetwork interface for the netavark backend.
// Note: The networks are not loaded from disk until a method is called. // Note: The networks are not loaded from disk until a method is called.
func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) {
// TODO: consider using a shared memory lock // root needs to use a globally unique lock because there is only one host netns
lock, err := lockfile.GetLockFile(filepath.Join(conf.NetworkConfigDir, "netavark.lock")) lockPath := defaultRootLockPath
if unshare.IsRootless() {
lockPath = filepath.Join(conf.NetworkConfigDir, "netavark.lock")
}
lock, err := lockfile.GetLockFile(lockPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }