From 76beb4e25772677ca47359105c2c3254c10a96f7 Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Mon, 16 Sep 2024 16:11:17 +0100 Subject: [PATCH 1/4] lxd/fsmonitor/drivers: Allow setting fsmonitor driver via environment. Signed-off-by: Mark Laing --- lxd/fsmonitor/drivers/load.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lxd/fsmonitor/drivers/load.go b/lxd/fsmonitor/drivers/load.go index 7df77566a25d..143ffd60715e 100644 --- a/lxd/fsmonitor/drivers/load.go +++ b/lxd/fsmonitor/drivers/load.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "os" "github.com/canonical/lxd/lxd/fsmonitor" "github.com/canonical/lxd/shared/logger" @@ -40,6 +41,11 @@ func Load(ctx context.Context, path string, events ...fsmonitor.Event) (fsmonito return d, nil } + driverName := os.Getenv("LXD_FSMONITOR_DRIVER") + if driverName != "" { + return startMonitor(driverName) + } + driver, err := startMonitor("fanotify") if err != nil { logger.Warn("Failed to initialize fanotify, falling back on inotify", logger.Ctx{"err": err}) From 9f6a328ee5009f28ff2e2e45a9013606e29c4ed5 Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Mon, 16 Sep 2024 16:11:59 +0100 Subject: [PATCH 2/4] doc: Add environment variable to documentation. Signed-off-by: Mark Laing --- doc/environment.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/environment.md b/doc/environment.md index 31a21bcb2799..4d5d57c80c31 100644 --- a/doc/environment.md +++ b/doc/environment.md @@ -40,3 +40,4 @@ Name | Description `LXD_QEMU_FW_PATH` | Path (or `:` separated list of paths) to firmware (OVMF, SeaBIOS) to be used by QEMU `LXD_IDMAPPED_MOUNTS_DISABLE` | Disable idmapped mounts support (useful when testing traditional UID shifting) `LXD_DEVMONITOR_DIR` | Path to be monitored by the device monitor. This is primarily for testing. +`LXD_FSMONITOR_DRIVER` | Driver to be used for file system monitoring. This is primarily for testing. From bdf32996b67ed3e5eb753a2b6c3b0bed167edbe9 Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Mon, 16 Sep 2024 16:12:37 +0100 Subject: [PATCH 3/4] test/suites: Test unix devices with both fsmonitor drivers. Signed-off-by: Mark Laing --- test/suites/container_devices_unix.sh | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/suites/container_devices_unix.sh b/test/suites/container_devices_unix.sh index 33259be06253..ad2636fb0189 100644 --- a/test/suites/container_devices_unix.sh +++ b/test/suites/container_devices_unix.sh @@ -1,9 +1,37 @@ test_container_devices_unix_block() { + lxdFSMonitorDriver=${LXD_FSMONITOR_DRIVER:-} + + shutdown_lxd "${LXD_DIR}" + export LXD_FSMONITOR_DRIVER="fanotify" + respawn_lxd "${LXD_DIR}" true + _container_devices_unix "unix-block" + + shutdown_lxd "${LXD_DIR}" + export LXD_FSMONITOR_DRIVER="inotify" + respawn_lxd "${LXD_DIR}" true _container_devices_unix "unix-block" + + shutdown_lxd "${LXD_DIR}" + export LXD_FSMONITOR_DRIVER="${lxdFSMonitorDriver}" + respawn_lxd "${LXD_DIR}" true } test_container_devices_unix_char() { + lxdFSMonitorDriver=${LXD_FSMONITOR_DRIVER:-} + + shutdown_lxd "${LXD_DIR}" + export LXD_FSMONITOR_DRIVER="fanotify" + respawn_lxd "${LXD_DIR}" true + _container_devices_unix "unix-char" + + shutdown_lxd "${LXD_DIR}" + export LXD_FSMONITOR_DRIVER="inotify" + respawn_lxd "${LXD_DIR}" true _container_devices_unix "unix-char" + + shutdown_lxd "${LXD_DIR}" + export LXD_FSMONITOR_DRIVER="${lxdFSMonitorDriver}" + respawn_lxd "${LXD_DIR}" true } _container_devices_unix() { From bf567a51d2f4f9684ecba9121ab9717d783e3df0 Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Mon, 16 Sep 2024 16:14:09 +0100 Subject: [PATCH 4/4] lxd/fsmonitor/drivers: Ignore some inotify events to prevent warnings. The `in.InIgnored` is fairly obvious, this is to do with watches being removed. For `in.InUnmount|in.InIsdir` I thought that this might be a missed event as it represents a directory being unmounted. I tried mapping this to `fsmonitor.EventRemove` but this broke the `container_devices_unix_char` tests. Ignoring it explicitly gets the tests passing without logging any warnings. Signed-off-by: Mark Laing --- lxd/fsmonitor/drivers/driver_inotify.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lxd/fsmonitor/drivers/driver_inotify.go b/lxd/fsmonitor/drivers/driver_inotify.go index 59553b4686e5..6df7b47bff14 100644 --- a/lxd/fsmonitor/drivers/driver_inotify.go +++ b/lxd/fsmonitor/drivers/driver_inotify.go @@ -36,6 +36,8 @@ var fsMonitorEventToINotifyEvent = map[fsmonitor.Event]uint32{ fsmonitor.EventRename: in.InMovedTo, } +var errIgnoreEvent = errors.New("Intentionally ignored event") + func (d *inotify) toFSMonitorEvent(mask uint32) (fsmonitor.Event, error) { for knownINotifyEvent, event := range inotifyEventToFSMonitorEvent { if mask&knownINotifyEvent != 0 { @@ -43,6 +45,10 @@ func (d *inotify) toFSMonitorEvent(mask uint32) (fsmonitor.Event, error) { } } + if mask&in.InIgnored != 0 || mask&(in.InUnmount|in.InIsdir) != 0 { + return -1, errIgnoreEvent + } + return -1, fmt.Errorf(`Unknown inotify event "%d"`, mask) } @@ -102,7 +108,10 @@ func (d *inotify) getEvents(ctx context.Context) { event.Name = filepath.Clean(event.Name) action, err := d.toFSMonitorEvent(event.Mask) if err != nil { - logger.Warn("Failed to match inotify event, skipping", logger.Ctx{"err": err}) + if !errors.Is(err, errIgnoreEvent) { + logger.Warn("Failed to match inotify event, skipping", logger.Ctx{"err": err}) + } + continue }