aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorPasha <pasha@member.fsf.org>2023-07-17 20:05:02 +0000
committerPasha <pasha@member.fsf.org>2023-07-17 20:05:02 +0000
commit1a13003efe953b88b34fcadef536bb09859bad34 (patch)
tree847fbf10983d549f2ba5cca20145707a11364a22 /src/main.c
downloadcontainercgroup-1a13003efe953b88b34fcadef536bb09859bad34.tar.gz
containercgroup-1a13003efe953b88b34fcadef536bb09859bad34.tar.bz2
initial release
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c269
1 files changed, 269 insertions, 0 deletions
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 <pasha@bell01.com>
+
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "../lib/cgroup_file_handle.h"
+#include <getopt.h>
+#include <libcgroup.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+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;
+}