Commit | Line | Data |
---|---|---|
1d8fd973 KS |
1 | /* |
2 | * cgroup_event_listener.c - Simple listener of cgroup events | |
3 | * | |
4 | * Copyright (C) Kirill A. Shutemov <kirill@shutemov.name> | |
5 | */ | |
6 | ||
7 | #include <assert.h> | |
799105d5 | 8 | #include <err.h> |
1d8fd973 KS |
9 | #include <errno.h> |
10 | #include <fcntl.h> | |
11 | #include <libgen.h> | |
12 | #include <limits.h> | |
13 | #include <stdio.h> | |
14 | #include <string.h> | |
15 | #include <unistd.h> | |
16 | ||
17 | #include <sys/eventfd.h> | |
18 | ||
799105d5 | 19 | #define USAGE_STR "Usage: cgroup_event_listener <path-to-control-file> <args>" |
1d8fd973 KS |
20 | |
21 | int main(int argc, char **argv) | |
22 | { | |
23 | int efd = -1; | |
24 | int cfd = -1; | |
25 | int event_control = -1; | |
26 | char event_control_path[PATH_MAX]; | |
27 | char line[LINE_MAX]; | |
28 | int ret; | |
29 | ||
799105d5 GT |
30 | if (argc != 3) |
31 | errx(1, "%s", USAGE_STR); | |
1d8fd973 KS |
32 | |
33 | cfd = open(argv[1], O_RDONLY); | |
799105d5 GT |
34 | if (cfd == -1) |
35 | err(1, "Cannot open %s", argv[1]); | |
1d8fd973 KS |
36 | |
37 | ret = snprintf(event_control_path, PATH_MAX, "%s/cgroup.event_control", | |
38 | dirname(argv[1])); | |
799105d5 GT |
39 | if (ret >= PATH_MAX) |
40 | errx(1, "Path to cgroup.event_control is too long"); | |
1d8fd973 KS |
41 | |
42 | event_control = open(event_control_path, O_WRONLY); | |
799105d5 GT |
43 | if (event_control == -1) |
44 | err(1, "Cannot open %s", event_control_path); | |
1d8fd973 KS |
45 | |
46 | efd = eventfd(0, 0); | |
799105d5 GT |
47 | if (efd == -1) |
48 | err(1, "eventfd() failed"); | |
1d8fd973 KS |
49 | |
50 | ret = snprintf(line, LINE_MAX, "%d %d %s", efd, cfd, argv[2]); | |
799105d5 GT |
51 | if (ret >= LINE_MAX) |
52 | errx(1, "Arguments string is too long"); | |
1d8fd973 KS |
53 | |
54 | ret = write(event_control, line, strlen(line) + 1); | |
799105d5 GT |
55 | if (ret == -1) |
56 | err(1, "Cannot write to cgroup.event_control"); | |
1d8fd973 KS |
57 | |
58 | while (1) { | |
59 | uint64_t result; | |
60 | ||
61 | ret = read(efd, &result, sizeof(result)); | |
62 | if (ret == -1) { | |
63 | if (errno == EINTR) | |
64 | continue; | |
799105d5 | 65 | err(1, "Cannot read from eventfd"); |
1d8fd973 KS |
66 | } |
67 | assert(ret == sizeof(result)); | |
68 | ||
69 | ret = access(event_control_path, W_OK); | |
70 | if ((ret == -1) && (errno == ENOENT)) { | |
799105d5 | 71 | puts("The cgroup seems to have removed."); |
1d8fd973 KS |
72 | break; |
73 | } | |
74 | ||
799105d5 GT |
75 | if (ret == -1) |
76 | err(1, "cgroup.event_control is not accessible any more"); | |
77 | ||
1d8fd973 KS |
78 | printf("%s %s: crossed\n", argv[1], argv[2]); |
79 | } | |
80 | ||
799105d5 | 81 | return 0; |
1d8fd973 | 82 | } |