1*a8c52ebaSWaiman Long // SPDX-License-Identifier: GPL-2.0
2*a8c52ebaSWaiman Long /*
3*a8c52ebaSWaiman Long * Wait until an inotify event on the given cgroup file.
4*a8c52ebaSWaiman Long */
5*a8c52ebaSWaiman Long #include <linux/limits.h>
6*a8c52ebaSWaiman Long #include <sys/inotify.h>
7*a8c52ebaSWaiman Long #include <sys/mman.h>
8*a8c52ebaSWaiman Long #include <sys/ptrace.h>
9*a8c52ebaSWaiman Long #include <sys/stat.h>
10*a8c52ebaSWaiman Long #include <sys/types.h>
11*a8c52ebaSWaiman Long #include <errno.h>
12*a8c52ebaSWaiman Long #include <fcntl.h>
13*a8c52ebaSWaiman Long #include <poll.h>
14*a8c52ebaSWaiman Long #include <stdio.h>
15*a8c52ebaSWaiman Long #include <stdlib.h>
16*a8c52ebaSWaiman Long #include <string.h>
17*a8c52ebaSWaiman Long #include <unistd.h>
18*a8c52ebaSWaiman Long
19*a8c52ebaSWaiman Long static const char usage[] = "Usage: %s [-v] <cgroup_file>\n";
20*a8c52ebaSWaiman Long static char *file;
21*a8c52ebaSWaiman Long static int verbose;
22*a8c52ebaSWaiman Long
fail_message(char * msg)23*a8c52ebaSWaiman Long static inline void fail_message(char *msg)
24*a8c52ebaSWaiman Long {
25*a8c52ebaSWaiman Long fprintf(stderr, msg, file);
26*a8c52ebaSWaiman Long exit(1);
27*a8c52ebaSWaiman Long }
28*a8c52ebaSWaiman Long
main(int argc,char * argv[])29*a8c52ebaSWaiman Long int main(int argc, char *argv[])
30*a8c52ebaSWaiman Long {
31*a8c52ebaSWaiman Long char *cmd = argv[0];
32*a8c52ebaSWaiman Long int c, fd;
33*a8c52ebaSWaiman Long struct pollfd fds = { .events = POLLIN, };
34*a8c52ebaSWaiman Long
35*a8c52ebaSWaiman Long while ((c = getopt(argc, argv, "v")) != -1) {
36*a8c52ebaSWaiman Long switch (c) {
37*a8c52ebaSWaiman Long case 'v':
38*a8c52ebaSWaiman Long verbose++;
39*a8c52ebaSWaiman Long break;
40*a8c52ebaSWaiman Long }
41*a8c52ebaSWaiman Long argv++, argc--;
42*a8c52ebaSWaiman Long }
43*a8c52ebaSWaiman Long
44*a8c52ebaSWaiman Long if (argc != 2) {
45*a8c52ebaSWaiman Long fprintf(stderr, usage, cmd);
46*a8c52ebaSWaiman Long return -1;
47*a8c52ebaSWaiman Long }
48*a8c52ebaSWaiman Long file = argv[1];
49*a8c52ebaSWaiman Long fd = open(file, O_RDONLY);
50*a8c52ebaSWaiman Long if (fd < 0)
51*a8c52ebaSWaiman Long fail_message("Cgroup file %s not found!\n");
52*a8c52ebaSWaiman Long close(fd);
53*a8c52ebaSWaiman Long
54*a8c52ebaSWaiman Long fd = inotify_init();
55*a8c52ebaSWaiman Long if (fd < 0)
56*a8c52ebaSWaiman Long fail_message("inotify_init() fails on %s!\n");
57*a8c52ebaSWaiman Long if (inotify_add_watch(fd, file, IN_MODIFY) < 0)
58*a8c52ebaSWaiman Long fail_message("inotify_add_watch() fails on %s!\n");
59*a8c52ebaSWaiman Long fds.fd = fd;
60*a8c52ebaSWaiman Long
61*a8c52ebaSWaiman Long /*
62*a8c52ebaSWaiman Long * poll waiting loop
63*a8c52ebaSWaiman Long */
64*a8c52ebaSWaiman Long for (;;) {
65*a8c52ebaSWaiman Long int ret = poll(&fds, 1, 10000);
66*a8c52ebaSWaiman Long
67*a8c52ebaSWaiman Long if (ret < 0) {
68*a8c52ebaSWaiman Long if (errno == EINTR)
69*a8c52ebaSWaiman Long continue;
70*a8c52ebaSWaiman Long perror("poll");
71*a8c52ebaSWaiman Long exit(1);
72*a8c52ebaSWaiman Long }
73*a8c52ebaSWaiman Long if ((ret > 0) && (fds.revents & POLLIN))
74*a8c52ebaSWaiman Long break;
75*a8c52ebaSWaiman Long }
76*a8c52ebaSWaiman Long if (verbose) {
77*a8c52ebaSWaiman Long struct inotify_event events[10];
78*a8c52ebaSWaiman Long long len;
79*a8c52ebaSWaiman Long
80*a8c52ebaSWaiman Long usleep(1000);
81*a8c52ebaSWaiman Long len = read(fd, events, sizeof(events));
82*a8c52ebaSWaiman Long printf("Number of events read = %ld\n",
83*a8c52ebaSWaiman Long len/sizeof(struct inotify_event));
84*a8c52ebaSWaiman Long }
85*a8c52ebaSWaiman Long close(fd);
86*a8c52ebaSWaiman Long return 0;
87*a8c52ebaSWaiman Long }
88