From 87d55ae018f4298fed4c223c5f8fca9750b6d868 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 26 Jan 2022 07:51:17 +0100 Subject: [PATCH 31/31] procd: add service measurement Signed-off-by: John Crispin --- ...service-resource-measurement-support.patch | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 package/system/procd/patches/0002-add-service-resource-measurement-support.patch diff --git a/package/system/procd/patches/0002-add-service-resource-measurement-support.patch b/package/system/procd/patches/0002-add-service-resource-measurement-support.patch new file mode 100644 index 0000000000..de3e767eac --- /dev/null +++ b/package/system/procd/patches/0002-add-service-resource-measurement-support.patch @@ -0,0 +1,165 @@ +From b34b9a29cff6de4487586cae6d09bac45b9a9e59 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Wed, 26 Jan 2022 07:43:55 +0100 +Subject: [PATCH] add service resource measurement support + +Signed-off-by: John Crispin +--- + service/instance.c | 106 ++++++++++++++++++++++++++++++++++++++++++++- + service/instance.h | 1 + + service/service.c | 1 + + 3 files changed, 107 insertions(+), 1 deletion(-) + +diff --git a/service/instance.c b/service/instance.c +index 9c74265..bf2b597 100644 +--- a/service/instance.c ++++ b/service/instance.c +@@ -28,6 +28,10 @@ + #include + #define SYSLOG_NAMES + #include ++#include ++#include ++#include ++#include + + #include + +@@ -189,6 +193,102 @@ static const struct rlimit_name rlimit_names[] = { + { NULL, 0 } + }; + ++static regex_t pat_vmdata, pat_vmstk; ++struct sysinfo info; ++long systick; ++ ++static void __attribute__((constructor)) ++measure_init() ++{ ++ regcomp(&pat_vmdata, "VmData:[ \t]*([0-9]*) kB", REG_EXTENDED); ++ regcomp(&pat_vmstk, "VmStk:[ \t]*([0-9]*) kB", REG_EXTENDED); ++} ++ ++static char * ++strnchr(char *buf, int c, int i) ++{ ++ while (*buf && i) { ++ buf = strchr(buf, c); ++ buf++; ++ i--; ++ } ++ return buf; ++} ++ ++void ++measure_start(void) ++{ ++ sysinfo(&info); ++ systick = sysconf(_SC_CLK_TCK); ++} ++ ++static int ++measure_process(struct blob_buf *b, pid_t pid) ++{ ++ int fd; ++ char buffer[512] = ""; ++ ssize_t rxed; ++ regmatch_t matches[2]; ++ glob_t gl; ++ size_t i; ++ char *ch; ++ uint32_t fdcount = 0; ++ uint32_t mem = 0; ++ ++ snprintf(buffer, sizeof(buffer), "/proc/%i/fd/*", (int)pid); ++ ++ if (glob(buffer, GLOB_NOESCAPE | GLOB_MARK, NULL, &gl)) ++ return -1; ++ ++ for (i = 0; i < gl.gl_pathc; i++) ++ if (isdigit(basename(gl.gl_pathv[i])[0])) ++ fdcount = fdcount + 1; ++ globfree(&gl); ++ blobmsg_add_u32(b, "fds", fdcount); ++ ++ snprintf(buffer, sizeof(buffer), "/proc/%i/stat", (int)pid); ++ fd = open(buffer, O_RDONLY); ++ if (fd == -1) ++ return -1; ++ ++ rxed = read(fd, buffer, sizeof(buffer) - 1); ++ close(fd); ++ if (rxed == -1) ++ return -1; ++ ++ buffer[rxed] = 0; ++ ++ ch = strnchr(buffer, ' ', 14); ++ if (ch) ++ blobmsg_add_u64(b, "load", atoll(ch)); ++ ++ ch = strnchr(buffer, ' ', 21); ++ if (ch) ++ blobmsg_add_u64(b, "age", info.uptime - atol(ch) / systick); ++ ++ snprintf(buffer, sizeof(buffer), "/proc/%i/status", (int)pid); ++ fd = open(buffer, O_RDONLY); ++ if (fd == -1) ++ return -1; ++ ++ rxed = read(fd, buffer, sizeof(buffer) - 1); ++ close(fd); ++ if (rxed == -1) ++ return -1; ++ ++ buffer[rxed] = 0; ++ ++ if (!regexec(&pat_vmdata, buffer, 2, matches, 0)) ++ mem += atoi(buffer + matches[1].rm_so) * 1024; ++ ++ if (!regexec(&pat_vmstk, buffer, 2, matches, 0)) ++ mem += atoi(buffer + matches[1].rm_so) * 1024; ++ ++ blobmsg_add_u64(b, "meminfo", mem); ++ ++ return 0; ++} ++ + static void closefd(int fd) + { + if (fd > STDERR_FILENO) +@@ -1795,5 +1896,8 @@ void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose) + blobmsg_close_table(b, r); + } + ++ if (in->proc.pending) ++ measure_process(b, in->proc.pid); ++ + blobmsg_close_table(b, i); + } +diff --git a/service/instance.h b/service/instance.h +index 15eb997..1606eed 100644 +--- a/service/instance.h ++++ b/service/instance.h +@@ -122,5 +122,6 @@ void instance_update(struct service_instance *in, struct service_instance *in_ne + void instance_init(struct service_instance *in, struct service *s, struct blob_attr *config); + void instance_free(struct service_instance *in); + void instance_dump(struct blob_buf *b, struct service_instance *in, int debug); ++void measure_start(void); + + #endif +diff --git a/service/service.c b/service/service.c +index bb3e121..9cd8886 100644 +--- a/service/service.c ++++ b/service/service.c +@@ -497,6 +497,7 @@ service_handle_list(struct ubus_context *ctx, struct ubus_object *obj, + if (tb[SERVICE_LIST_ATTR_NAME]) + name = blobmsg_get_string(tb[SERVICE_LIST_ATTR_NAME]); + ++ measure_start(); + blob_buf_init(&b, 0); + avl_for_each_element(tree, s, avl) { + if (name && strcmp(s->name, name) != 0) +-- +2.25.1 + -- 2.25.1