#include #include #include #include #include #include #include #include #define BUFFER_LEN (1024 * (sizeof(struct inotify_event) + 16)) void handle_cgroup_event(const char *event_file) { char buffer[256]; int fd = open(event_file, O_RDONLY); if(fd < 0) { return; } ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1); close(fd); if(bytesRead < 0) { return; } buffer[bytesRead] = '\0'; if(strstr(buffer, "populated 0")) { char dir[1024]; strcpy(dir, event_file); *strrchr(dir, '/') = '\0'; rmdir(dir); } } void scan_and_clean_cgroup_directory(const char *dir) { DIR *d = opendir(dir); if (!d) { return; } struct dirent *entry; while ((entry = readdir(d)) != NULL) { if (entry->d_type == DT_DIR) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } char subdir[1024]; snprintf(subdir, sizeof(subdir), "%s/%s/cgroup.events", dir, entry->d_name); handle_cgroup_event(subdir); } } closedir(d); } void monitor_directory(const char *dir) { int inotify_fd = inotify_init(); if(inotify_fd < 0) { exit(EXIT_FAILURE); } int wd = inotify_add_watch(inotify_fd, dir, IN_CREATE); if(wd < 0) { close(inotify_fd); exit(EXIT_FAILURE); } char buffer[BUFFER_LEN]; while(1) { ssize_t length = read(inotify_fd, buffer, BUFFER_LEN); if(length < 0) { close(inotify_fd); exit(EXIT_FAILURE); } char *ptr; for(ptr = buffer; ptr < buffer + length; ptr += sizeof(struct inotify_event) + ((struct inotify_event *)ptr)->len) { struct inotify_event *event = (struct inotify_event *)ptr; if(event->mask & IN_CREATE && event->mask & IN_ISDIR) { char cgroup_event_path[1024]; snprintf(cgroup_event_path, sizeof(cgroup_event_path), "%s/%s/cgroup.events", dir, event->name); sleep(1); int cgroup_event_wd = inotify_add_watch(inotify_fd, cgroup_event_path, IN_MODIFY); if(cgroup_event_wd >= 0) { handle_cgroup_event(cgroup_event_path); } } else if(event->mask & IN_MODIFY) { char cgroup_event_path[1024]; snprintf(cgroup_event_path, sizeof(cgroup_event_path), "%s/%s/cgroup.events", dir, event->name); handle_cgroup_event(cgroup_event_path); } } } close(inotify_fd); } int main(int argc, char *argv[]) { const char *cgroup_dir = "/sys/fs/cgroup"; int run_as_daemon = (argc > 1 && strcmp(argv[1], "--daemon") == 0); scan_and_clean_cgroup_directory(cgroup_dir); if(run_as_daemon) { if(fork() > 0) exit(EXIT_SUCCESS); if(setsid() < 0) exit(EXIT_FAILURE); if(fork() > 0) exit(EXIT_SUCCESS); chdir("/"); for(int x = sysconf(_SC_OPEN_MAX); x >= 0; x--) { close(x); } open("/dev/null", O_RDWR); dup(0); dup(0); monitor_directory(cgroup_dir); } return 0; }