From 1a13003efe953b88b34fcadef536bb09859bad34 Mon Sep 17 00:00:00 2001 From: Pasha Date: Mon, 17 Jul 2023 20:05:02 +0000 Subject: initial release --- src/main.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 src/main.c (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..bc10112 --- /dev/null +++ b/src/main.c @@ -0,0 +1,269 @@ +/* + Copyright (C) 2023 Pasha + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "../lib/cgroup_file_handle.h" +#include +#include +#include +#include +#include +#include + +enum output_pref { DEFAULT = 0, PATH = 1, CGROUPID = 2 }; + +static inline void print_cgroup_file_handle(const char *pathname, + enum output_pref output_type) { + + unsigned char *cgroupfhp = + (unsigned char *)malloc(sizeof(unsigned char) * CGROUP_FILE_HANDLE_BYTES); + if (!cgroupfhp) { + fprintf(stderr, "Cannot allocate memory for cgroup file handle\n"); + return; + } + + if (!get_cgroup_file_handle(pathname, cgroupfhp)) { + printf("unable to get cgroup file handle for path %s\n", pathname); + free(cgroupfhp); + return; + } + + if (output_type != CGROUPID) { + printf("cgroupid:\t"); + } + + for (int i = 0; i < CGROUP_FILE_HANDLE_BYTES; ++i) { + printf("%02x%s", (unsigned char)cgroupfhp[i], i == 7 ? "\n" : " "); + } + + free(cgroupfhp); +} + +static void print_info(struct cgroup_file_info *info, int len, + const char *ctr_path, enum output_pref output_type) { + char buffer[FILENAME_MAX]; + if (info->type == CGROUP_FILE_TYPE_DIR) { + if (info->full_path[len] == '/') { + snprintf(buffer, FILENAME_MAX, "%s%s", ctr_path, &info->full_path[len]); + } else { + snprintf(buffer, FILENAME_MAX, "%s/%s", ctr_path, &info->full_path[len]); + } + + if (output_type == DEFAULT) { + printf("cgroup path:\t"); + } + + if (output_type != CGROUPID) { + printf("%s\n", buffer); + } + + if (output_type != PATH) { + print_cgroup_file_handle(buffer, output_type); + } + } +} + +static inline void trim_path(char *path) { + int len = strlen(path) - 1; + while (path[len] == '/') { + len--; + } + path[len + 1] = '\0'; +} + +static inline int compare_cgroup_search_name(const char *info_path, + const char *cgroup_search_name) { + int info_path_len = strlen(info_path); + int search_name_len = strlen(cgroup_search_name); + int start_comp_idx = 0; + + if (info_path_len < search_name_len) { + return 0; + } else if (info_path_len > search_name_len) { + start_comp_idx = info_path_len - search_name_len; + } + + if (!strcmp(&info_path[start_comp_idx], cgroup_search_name)) { + return 1; + } + + return 0; +} + +static int display_controller_data(char *ctr_name, char *ctr_path, + char *cgroup_search_name, + enum output_pref output_type) { + void *handle; + int ret, base_level, len, depth; + struct cgroup_file_info info; + char base_path[FILENAME_MAX]; + char cgroup_dir_path[FILENAME_MAX]; + + base_path[0] = '/'; + base_path[1] = '\0'; + depth = 0; + + ret = + cgroup_walk_tree_begin(ctr_name, base_path, depth, &handle, &info, &base_level); + if (ret != 0) + return ret; + + strncpy(cgroup_dir_path, info.full_path, FILENAME_MAX); + cgroup_dir_path[sizeof(cgroup_dir_path) - 1] = '\0'; + trim_path(cgroup_dir_path); + + base_path[sizeof(base_path) - 1] = '\0'; + trim_path(base_path); + + len = strlen(cgroup_dir_path) - strlen(base_path); + + if (compare_cgroup_search_name(info.path, cgroup_search_name)) { + print_info(&info, len, ctr_path, output_type); + cgroup_walk_tree_end(&handle); + return 1; + } + + while ((ret = cgroup_walk_tree_next(depth, &handle, &info, base_level)) == 0) { + if (compare_cgroup_search_name(info.path, cgroup_search_name)) { + print_info(&info, len, ctr_path, output_type); + break; + } + } + + cgroup_walk_tree_end(&handle); + if (ret == ECGEOF) + ret = 0; + + return ret; +} + +int print_cgroup(char *cgroup_search_name, enum output_pref output_type) { + void *handle; + int ret = 0; + int output = 0; + struct cgroup_mount_point cg_mount_point; + char ctr_path[FILENAME_MAX]; + char ctr_name[FILENAME_MAX]; + ctr_path[0] = '\0'; + ctr_name[0] = '\0'; + + ret = cgroup_get_controller_begin(&handle, &cg_mount_point); + + while (ret == 0) { + if (strcmp(ctr_path, cg_mount_point.path)) { + // new mount point + strncpy(ctr_name, cg_mount_point.name, FILENAME_MAX); + ctr_name[sizeof(ctr_name) - 1] = '\0'; + + strncpy(ctr_path, cg_mount_point.path, FILENAME_MAX); + ctr_path[sizeof(ctr_path) - 1] = '\0'; + + ret = display_controller_data(ctr_name, ctr_path, cgroup_search_name, + output_type); + if (ret) + break; + } + /* + else { + printf("same mount point found with name:%s\n", cg_mount_point.name); + } + */ + + ret = cgroup_get_controller_next(&handle, &cg_mount_point); + } + + cgroup_get_controller_end(&handle); + if (ret == ECGEOF) + ret = 0; + + return ret; +} + +void print_version() { printf("v0.1a\n"); } + +void usage() { + printf("Usage: " + "containercgroup container_id\n\n"); + printf("containercgroup path container_id\n\n"); + printf("containercgroup cgroupid container_id\n\n"); + printf("Example: containercgroup " + "ac7c62839226963db81ecae66be4457d944b99e1d937ce069225bf3b57bee6f6\n"); + printf(" containercgroup $(docker inspect " + "--format=\"{{.Id}}\" 6aa6f3065e1c)\n"); + printf(" containercgroup path $(docker inspect " + "--format=\"{{.Id}}\" 6aa6f3065e1c)\n"); + printf(" containercgroup id $(docker inspect " + "--format=\"{{.Id}}\" 6aa6f3065e1c)\n"); + printf(" containercgroup $(kubectl get pods -o jsonpath='{range " + ".items[*].status.containerStatuses[*]}{.containerID}{\"\\n\"}{end}' " + "--field-selector metadata.name=test-deployment-7f456874f4-mxjg4 | " + "cut -b 10-)\n"); + printf("\n"); +} + +int main(int argc, char **argv) { + int ret = 0; + enum output_pref output_type = DEFAULT; + + if (argc < 2) { + usage(); + exit(1); + } + + if (argc == 2 && !strcmp(argv[1], "-v")) { + print_version(); + } + + if (argc == 3) { + if (strcmp(argv[1], "path") == 0) { + output_type = PATH; + } else if (strcmp(argv[1], "id") == 0) { + output_type = CGROUPID; + } else { + usage(); + exit(1); + } + } + + const char *input_search_name = (argc == 3) ? argv[2] : argv[1]; + + unsigned int input_search_len = strlen(input_search_name); + if (input_search_len > FILENAME_MAX) { + fprintf(stderr, "invalid container_id\n"); + return ret; + } + + // ".scope" 6 + null 1 = 7 + char *cgroup_search_name = (char *)malloc(input_search_len + 7); + if (!cgroup_search_name) { + fprintf(stderr, "Cannot allocate memory.\n"); + exit(1); + } + strcpy(cgroup_search_name, input_search_name); + strcat(cgroup_search_name, ".scope"); + + ret = cgroup_init(); + if (ret) { + fprintf(stderr, "cgroup initialization failed: %s\n", cgroup_strerror(ret)); + free(cgroup_search_name); + return ret; + } + + print_cgroup(cgroup_search_name, output_type); + free(cgroup_search_name); + + return 0; +} -- cgit v1.2.1