From 92e015b1cfc24e3cb072385f25171b8599cc7ef3 Mon Sep 17 00:00:00 2001 From: Greg Thelen Date: Fri, 4 Jan 2013 13:05:17 -0800 Subject: cgroups: move cgroup_event_listener.c to tools/cgroup Move the cgroup_event_listener.c tool from Documentation into the new tools/cgroup directory. This change involves wiring cgroup_event_listener.c into the tools/ make system so that is can be built with: $ make tools/cgroup Signed-off-by: Greg Thelen Signed-off-by: Tejun Heo --- tools/Makefile | 19 +++--- tools/cgroup/.gitignore | 1 + tools/cgroup/Makefile | 11 ++++ tools/cgroup/cgroup_event_listener.c | 110 +++++++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 tools/cgroup/.gitignore create mode 100644 tools/cgroup/Makefile create mode 100644 tools/cgroup/cgroup_event_listener.c (limited to 'tools') diff --git a/tools/Makefile b/tools/Makefile index 1f9a529fe544..fc57a28abca1 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -3,6 +3,7 @@ include scripts/Makefile.include help: @echo 'Possible targets:' @echo '' + @echo ' cgroup - cgroup tools' @echo ' cpupower - a tool for all things x86 CPU power' @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' @echo ' lguest - a minimal 32-bit x86 hypervisor' @@ -33,7 +34,7 @@ help: cpupower: FORCE $(call descend,power/$@) -firewire lguest perf usb virtio vm: FORCE +cgroup firewire lguest perf usb virtio vm: FORCE $(call descend,$@) selftests: FORCE @@ -45,7 +46,7 @@ turbostat x86_energy_perf_policy: FORCE cpupower_install: $(call descend,power/$(@:_install=),install) -firewire_install lguest_install perf_install usb_install virtio_install vm_install: +cgroup_install firewire_install lguest_install perf_install usb_install virtio_install vm_install: $(call descend,$(@:_install=),install) selftests_install: @@ -54,14 +55,14 @@ selftests_install: turbostat_install x86_energy_perf_policy_install: $(call descend,power/x86/$(@:_install=),install) -install: cpupower_install firewire_install lguest_install perf_install \ - selftests_install turbostat_install usb_install virtio_install \ - vm_install x86_energy_perf_policy_install +install: cgroup_install cpupower_install firewire_install lguest_install \ + perf_install selftests_install turbostat_install usb_install \ + virtio_install vm_install x86_energy_perf_policy_install cpupower_clean: $(call descend,power/cpupower,clean) -firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean: +cgroup_clean firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean: $(call descend,$(@:_clean=),clean) selftests_clean: @@ -70,8 +71,8 @@ selftests_clean: turbostat_clean x86_energy_perf_policy_clean: $(call descend,power/x86/$(@:_clean=),clean) -clean: cpupower_clean firewire_clean lguest_clean perf_clean selftests_clean \ - turbostat_clean usb_clean virtio_clean vm_clean \ - x86_energy_perf_policy_clean +clean: cgroup_clean cpupower_clean firewire_clean lguest_clean perf_clean \ + selftests_clean turbostat_clean usb_clean virtio_clean \ + vm_clean x86_energy_perf_policy_clean .PHONY: FORCE diff --git a/tools/cgroup/.gitignore b/tools/cgroup/.gitignore new file mode 100644 index 000000000000..633cd9b874f9 --- /dev/null +++ b/tools/cgroup/.gitignore @@ -0,0 +1 @@ +cgroup_event_listener diff --git a/tools/cgroup/Makefile b/tools/cgroup/Makefile new file mode 100644 index 000000000000..b4286196b763 --- /dev/null +++ b/tools/cgroup/Makefile @@ -0,0 +1,11 @@ +# Makefile for cgroup tools + +CC = $(CROSS_COMPILE)gcc +CFLAGS = -Wall -Wextra + +all: cgroup_event_listener +%: %.c + $(CC) $(CFLAGS) -o $@ $^ + +clean: + $(RM) cgroup_event_listener diff --git a/tools/cgroup/cgroup_event_listener.c b/tools/cgroup/cgroup_event_listener.c new file mode 100644 index 000000000000..3e082f96dc12 --- /dev/null +++ b/tools/cgroup/cgroup_event_listener.c @@ -0,0 +1,110 @@ +/* + * cgroup_event_listener.c - Simple listener of cgroup events + * + * Copyright (C) Kirill A. Shutemov + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define USAGE_STR "Usage: cgroup_event_listener \n" + +int main(int argc, char **argv) +{ + int efd = -1; + int cfd = -1; + int event_control = -1; + char event_control_path[PATH_MAX]; + char line[LINE_MAX]; + int ret; + + if (argc != 3) { + fputs(USAGE_STR, stderr); + return 1; + } + + cfd = open(argv[1], O_RDONLY); + if (cfd == -1) { + fprintf(stderr, "Cannot open %s: %s\n", argv[1], + strerror(errno)); + goto out; + } + + ret = snprintf(event_control_path, PATH_MAX, "%s/cgroup.event_control", + dirname(argv[1])); + if (ret >= PATH_MAX) { + fputs("Path to cgroup.event_control is too long\n", stderr); + goto out; + } + + event_control = open(event_control_path, O_WRONLY); + if (event_control == -1) { + fprintf(stderr, "Cannot open %s: %s\n", event_control_path, + strerror(errno)); + goto out; + } + + efd = eventfd(0, 0); + if (efd == -1) { + perror("eventfd() failed"); + goto out; + } + + ret = snprintf(line, LINE_MAX, "%d %d %s", efd, cfd, argv[2]); + if (ret >= LINE_MAX) { + fputs("Arguments string is too long\n", stderr); + goto out; + } + + ret = write(event_control, line, strlen(line) + 1); + if (ret == -1) { + perror("Cannot write to cgroup.event_control"); + goto out; + } + + while (1) { + uint64_t result; + + ret = read(efd, &result, sizeof(result)); + if (ret == -1) { + if (errno == EINTR) + continue; + perror("Cannot read from eventfd"); + break; + } + assert(ret == sizeof(result)); + + ret = access(event_control_path, W_OK); + if ((ret == -1) && (errno == ENOENT)) { + puts("The cgroup seems to have removed."); + ret = 0; + break; + } + + if (ret == -1) { + perror("cgroup.event_control " + "is not accessible any more"); + break; + } + + printf("%s %s: crossed\n", argv[1], argv[2]); + } + +out: + if (efd >= 0) + close(efd); + if (event_control >= 0) + close(event_control); + if (cfd >= 0) + close(cfd); + + return (ret != 0); +} -- cgit v1.2.2 From 799105d514384b80cbe3182dbcb4ed30aa07e1f5 Mon Sep 17 00:00:00 2001 From: Greg Thelen Date: Mon, 7 Jan 2013 11:50:17 -0800 Subject: cgroups: fix cgroup_event_listener error handling The error handling in cgroup_event_listener.c did not correctly deal with either an error opening either or cgroup.event_control. Due to an uninitialized variable the program exit code was undefined if either of these opens failed. This patch simplifies and corrects cgroup_event_listener.c error handling by: 1. using err*() rather than printf(),exit() 2. depending on process exit to close open files With this patch failures always return non-zero error. Signed-off-by: Greg Thelen Acked-by: Li Zefan Signed-off-by: Tejun Heo --- tools/cgroup/cgroup_event_listener.c | 72 +++++++++++------------------------- 1 file changed, 22 insertions(+), 50 deletions(-) (limited to 'tools') diff --git a/tools/cgroup/cgroup_event_listener.c b/tools/cgroup/cgroup_event_listener.c index 3e082f96dc12..4eb5507205c9 100644 --- a/tools/cgroup/cgroup_event_listener.c +++ b/tools/cgroup/cgroup_event_listener.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -15,7 +16,7 @@ #include -#define USAGE_STR "Usage: cgroup_event_listener \n" +#define USAGE_STR "Usage: cgroup_event_listener " int main(int argc, char **argv) { @@ -26,49 +27,33 @@ int main(int argc, char **argv) char line[LINE_MAX]; int ret; - if (argc != 3) { - fputs(USAGE_STR, stderr); - return 1; - } + if (argc != 3) + errx(1, "%s", USAGE_STR); cfd = open(argv[1], O_RDONLY); - if (cfd == -1) { - fprintf(stderr, "Cannot open %s: %s\n", argv[1], - strerror(errno)); - goto out; - } + if (cfd == -1) + err(1, "Cannot open %s", argv[1]); ret = snprintf(event_control_path, PATH_MAX, "%s/cgroup.event_control", dirname(argv[1])); - if (ret >= PATH_MAX) { - fputs("Path to cgroup.event_control is too long\n", stderr); - goto out; - } + if (ret >= PATH_MAX) + errx(1, "Path to cgroup.event_control is too long"); event_control = open(event_control_path, O_WRONLY); - if (event_control == -1) { - fprintf(stderr, "Cannot open %s: %s\n", event_control_path, - strerror(errno)); - goto out; - } + if (event_control == -1) + err(1, "Cannot open %s", event_control_path); efd = eventfd(0, 0); - if (efd == -1) { - perror("eventfd() failed"); - goto out; - } + if (efd == -1) + err(1, "eventfd() failed"); ret = snprintf(line, LINE_MAX, "%d %d %s", efd, cfd, argv[2]); - if (ret >= LINE_MAX) { - fputs("Arguments string is too long\n", stderr); - goto out; - } + if (ret >= LINE_MAX) + errx(1, "Arguments string is too long"); ret = write(event_control, line, strlen(line) + 1); - if (ret == -1) { - perror("Cannot write to cgroup.event_control"); - goto out; - } + if (ret == -1) + err(1, "Cannot write to cgroup.event_control"); while (1) { uint64_t result; @@ -77,34 +62,21 @@ int main(int argc, char **argv) if (ret == -1) { if (errno == EINTR) continue; - perror("Cannot read from eventfd"); - break; + err(1, "Cannot read from eventfd"); } assert(ret == sizeof(result)); ret = access(event_control_path, W_OK); if ((ret == -1) && (errno == ENOENT)) { - puts("The cgroup seems to have removed."); - ret = 0; - break; - } - - if (ret == -1) { - perror("cgroup.event_control " - "is not accessible any more"); + puts("The cgroup seems to have removed."); break; } + if (ret == -1) + err(1, "cgroup.event_control is not accessible any more"); + printf("%s %s: crossed\n", argv[1], argv[2]); } -out: - if (efd >= 0) - close(efd); - if (event_control >= 0) - close(event_control); - if (cfd >= 0) - close(cfd); - - return (ret != 0); + return 0; } -- cgit v1.2.2