• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/Documentation/cgroups/
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>
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
20int 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) {
74		uint64_t result;
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 accessable any more");
95			break;
96		}
97
98		printf("%s %s: crossed\n", argv[1], argv[2]);
99	}
100
101out:
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}
111