On Fri, Feb 20, 2026 at 9:44 AM Amir Goldstein <[email protected]> wrote: > > On Fri, Feb 20, 2026 at 6:55 AM T.J. Mercier <[email protected]> wrote: > > > > Add two new tests that verify inotify events are sent when memcg files > > or directories are removed with rmdir. > > > > Signed-off-by: T.J. Mercier <[email protected]> > > Acked-by: Tejun Heo <[email protected]> > > Acked-by: Amir Goldstein <[email protected]> > > --- > > .../selftests/cgroup/test_memcontrol.c | 112 ++++++++++++++++++ > > 1 file changed, 112 insertions(+) > > > > diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c > > b/tools/testing/selftests/cgroup/test_memcontrol.c > > index 4e1647568c5b..57726bc82757 100644 > > --- a/tools/testing/selftests/cgroup/test_memcontrol.c > > +++ b/tools/testing/selftests/cgroup/test_memcontrol.c > > @@ -10,6 +10,7 @@ > > #include <sys/stat.h> > > #include <sys/types.h> > > #include <unistd.h> > > +#include <sys/inotify.h> > > #include <sys/socket.h> > > #include <sys/wait.h> > > #include <arpa/inet.h> > > @@ -1625,6 +1626,115 @@ static int test_memcg_oom_group_score_events(const > > char *root) > > return ret; > > } > > > > +static int read_event(int inotify_fd, int expected_event, int expected_wd) > > +{ > > + struct inotify_event event; > > + ssize_t len = 0; > > + > > + len = read(inotify_fd, &event, sizeof(event)); > > + if (len < (ssize_t)sizeof(event)) > > + return -1; > > + > > + if (event.mask != expected_event || event.wd != expected_wd) { > > + fprintf(stderr, > > + "event does not match expected values: mask %d > > (expected %d) wd %d (expected %d)\n", > > + event.mask, expected_event, event.wd, expected_wd); > > + return -1; > > + } > > + > > + return 0; > > +} > > + > > +static int test_memcg_inotify_delete_file(const char *root) > > +{ > > + int ret = KSFT_FAIL; > > + char *memcg = NULL; > > + int fd, wd; > > + > > + memcg = cg_name(root, "memcg_test_0"); > > + > > + if (!memcg) > > + goto cleanup; > > + > > + if (cg_create(memcg)) > > + goto cleanup; > > + > > + fd = inotify_init1(0); > > + if (fd == -1) > > + goto cleanup; > > + > > + wd = inotify_add_watch(fd, cg_control(memcg, "memory.events"), > > IN_DELETE_SELF); > > + if (wd == -1) > > + goto cleanup; > > + > > + if (cg_destroy(memcg)) > > + goto cleanup; > > + free(memcg); > > + memcg = NULL; > > + > > + if (read_event(fd, IN_DELETE_SELF, wd)) > > + goto cleanup; > > + > > + if (read_event(fd, IN_IGNORED, wd)) > > + goto cleanup; > > + > > + ret = KSFT_PASS; > > + > > +cleanup: > > + if (fd >= 0) > > + close(fd); > > + if (memcg) > > + cg_destroy(memcg); > > + free(memcg); > > + > > + return ret; > > +} > > + > > +static int test_memcg_inotify_delete_dir(const char *root) > > +{ > > + int ret = KSFT_FAIL; > > + char *memcg = NULL; > > + int fd, wd; > > + > > + memcg = cg_name(root, "memcg_test_0"); > > + > > + if (!memcg) > > + goto cleanup; > > + > > + if (cg_create(memcg)) > > + goto cleanup; > > + > > + fd = inotify_init1(0); > > + if (fd == -1) > > + goto cleanup; > > + > > + wd = inotify_add_watch(fd, memcg, IN_DELETE_SELF); > > + if (wd == -1) > > + goto cleanup; > > + > > + if (cg_destroy(memcg)) > > + goto cleanup; > > + free(memcg); > > + memcg = NULL; > > + > > + if (read_event(fd, IN_DELETE_SELF, wd)) > > + goto cleanup; > > > Does this test pass? I expect that listener would get event mask > IN_DELETE_SELF | IN_ISDIR?
Yes, I tested on 4 different machines across different filesystems and none of them set IN_ISDIR with IN_DELETE_SELF. The inotify docs say, "may be set"... I wonder if that is wishful thinking?

