Commit 1d8fd973a41942bc760dd21581e24117bc1dd063

Authored by Kirill A. Shutemov
Committed by Linus Torvalds
1 parent a0a4db548e

cgroups: add simple listener of cgroup events to documentation

An example of cgroup notification API usage.

Signed-off-by: Kirill A.  Shutemov <kirill@shutemov.name>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Paul Menage <menage@google.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Balbir Singh <balbir@linux.vnet.ibm.com>
Cc: Pavel Emelyanov <xemul@openvz.org>
Cc: Dan Malek <dan@embeddedalley.com>
Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 110 additions and 0 deletions Side-by-side Diff

Documentation/cgroups/cgroup_event_listener.c
  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 accessable 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 +}