Based on kernel version 3.8. Page generated on 2013-02-20 21:47 EST.
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 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) { 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 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 }