On Fri, Feb 20, 2026 at 6:53 PM T.J. Mercier <[email protected]> wrote:
>
> On Fri, Feb 20, 2026 at 9:46 AM T.J. Mercier <[email protected]> wrote:
> >
> > 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?
>
> Oh, very intentional:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/notify/inotify/inotify_fsnotify.c?h=v6.19#n109

LOL yeh ok :)

Thanks for checking

Amir.

Reply via email to