dirname(3) is allowed to modify its argument in place, and the libc implementations do: after building event_control_path, argv[1] has been truncated to the parent directory. Every subsequent "crossed" event line therefore reports the cgroup directory instead of the monitored file, and the two-listener setup taught by Documentation/admin-guide/cgroup-v1/memory.rst (usage_in_bytes plus memsw.usage_in_bytes) produces indistinguishable output lines. Work on a strdup() copy so event reports keep naming the monitored file. Fixes: 60433a9d038d ("samples: introduce new samples subdir for cgroup") Signed-off-by: Song Hu --- samples/cgroup/cgroup_event_listener.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/samples/cgroup/cgroup_event_listener.c b/samples/cgroup/cgroup_event_listener.c index 3d70dc831a76..308cacec80a8 100644 --- a/samples/cgroup/cgroup_event_listener.c +++ b/samples/cgroup/cgroup_event_listener.c @@ -26,17 +26,27 @@ int main(int argc, char **argv) int event_control = -1; char event_control_path[PATH_MAX]; char line[LINE_MAX]; + char *path; int ret; if (argc != 3) errx(1, "%s", USAGE_STR); - cfd = open(argv[1], O_RDONLY); + /* + * dirname(3) may modify its argument in place; work on a copy so + * argv[1] still refers to the monitored file when events are + * reported. + */ + path = strdup(argv[1]); + if (!path) + err(1, "Cannot duplicate %s", argv[1]); + + cfd = open(path, O_RDONLY); if (cfd == -1) - err(1, "Cannot open %s", argv[1]); + err(1, "Cannot open %s", path); ret = snprintf(event_control_path, PATH_MAX, "%s/cgroup.event_control", - dirname(argv[1])); + dirname(path)); if (ret >= PATH_MAX) errx(1, "Path to cgroup.event_control is too long"); @@ -76,7 +86,7 @@ int main(int argc, char **argv) if (ret == -1) err(1, "cgroup.event_control is not accessible any more"); - printf("%s %s: crossed\n", argv[1], argv[2]); + printf("%s %s: crossed\n", path, argv[2]); } return 0; -- 2.53.0