Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cgroup_event_listener.c
Go to the documentation of this file.
1 /*
2  * cgroup_event_listener.c - Simple listener of cgroup events
3  *
4  * Copyright (C) Kirill A. Shutemov <[email protected]>
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <libgen.h>
11 #include <limits.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <unistd.h>
15 
16 #include <sys/eventfd.h>
17 
18 #define USAGE_STR "Usage: cgroup_event_listener <path-to-control-file> <args>\n"
19 
20 int main(int argc, char **argv)
21 {
22  int efd = -1;
23  int cfd = -1;
24  int event_control = -1;
25  char event_control_path[PATH_MAX];
26  char line[LINE_MAX];
27  int ret;
28 
29  if (argc != 3) {
30  fputs(USAGE_STR, stderr);
31  return 1;
32  }
33 
34  cfd = open(argv[1], O_RDONLY);
35  if (cfd == -1) {
36  fprintf(stderr, "Cannot open %s: %s\n", argv[1],
37  strerror(errno));
38  goto out;
39  }
40 
41  ret = snprintf(event_control_path, PATH_MAX, "%s/cgroup.event_control",
42  dirname(argv[1]));
43  if (ret >= PATH_MAX) {
44  fputs("Path to cgroup.event_control is too long\n", stderr);
45  goto out;
46  }
47 
48  event_control = open(event_control_path, O_WRONLY);
49  if (event_control == -1) {
50  fprintf(stderr, "Cannot open %s: %s\n", event_control_path,
51  strerror(errno));
52  goto out;
53  }
54 
55  efd = eventfd(0, 0);
56  if (efd == -1) {
57  perror("eventfd() failed");
58  goto out;
59  }
60 
61  ret = snprintf(line, LINE_MAX, "%d %d %s", efd, cfd, argv[2]);
62  if (ret >= LINE_MAX) {
63  fputs("Arguments string is too long\n", stderr);
64  goto out;
65  }
66 
67  ret = write(event_control, line, strlen(line) + 1);
68  if (ret == -1) {
69  perror("Cannot write to cgroup.event_control");
70  goto out;
71  }
72 
73  while (1) {
75 
76  ret = read(efd, &result, sizeof(result));
77  if (ret == -1) {
78  if (errno == EINTR)
79  continue;
80  perror("Cannot read from eventfd");
81  break;
82  }
83  assert(ret == sizeof(result));
84 
85  ret = access(event_control_path, W_OK);
86  if ((ret == -1) && (errno == ENOENT)) {
87  puts("The cgroup seems to have removed.");
88  ret = 0;
89  break;
90  }
91 
92  if (ret == -1) {
93  perror("cgroup.event_control "
94  "is not accessible any more");
95  break;
96  }
97 
98  printf("%s %s: crossed\n", argv[1], argv[2]);
99  }
100 
101 out:
102  if (efd >= 0)
103  close(efd);
104  if (event_control >= 0)
105  close(event_control);
106  if (cfd >= 0)
107  close(cfd);
108 
109  return (ret != 0);
110 }