summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorzy <[email protected]>2023-12-04 23:03:19 -0500
committerzy <[email protected]>2023-12-04 23:03:19 -0500
commit16beb60e94aef6ed5258f6821afb41492f067d0d (patch)
tree775d106514a6a1ebc98328cbcab83b51afe1a818 /source
parent9064e9e01e0115cc3e0fe1891f3adfc06f2dad33 (diff)
run_in_host
Diffstat (limited to 'source')
-rw-r--r--source/ucli/ucli-lib.cc171
-rw-r--r--source/ucli/ucli.cc11
-rw-r--r--source/ucli/ucli.h3
3 files changed, 179 insertions, 6 deletions
diff --git a/source/ucli/ucli-lib.cc b/source/ucli/ucli-lib.cc
index 7381abd..3536d1e 100644
--- a/source/ucli/ucli-lib.cc
+++ b/source/ucli/ucli-lib.cc
@@ -3,13 +3,26 @@
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
-
#include <fstream>
+#include <assert.h>
+#include <stdio_ext.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "symbol.h"
#include "ucli.h"
#include "unwind.h"
+
+#define BUF_LEN 4096
+#define WHITESPACE " \t\n\r"
+#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
+#define streq(a,b) (strcmp((a),(b)) == 0)
+
+unsigned long run_in_host = 0;
+
using namespace std;
class pid_cmdline {
@@ -194,4 +207,158 @@ void diag_printf_proc_chains(proc_chains_detail *proc_chains) {
proc_chains->chains[i]);
}
}
-} \ No newline at end of file
+}
+
+int is_pid_1_has_environ(const char *field) {
+ bool done = false;
+ FILE *f = NULL;
+ int r = 0;
+ size_t l;
+
+ assert(field);
+
+ f = fopen("/proc/1/environ", "re");
+ if (!f)
+ return 0;
+
+ (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+ l = strlen(field);
+
+ do {
+ char line[BUF_LEN];
+ size_t i;
+
+ for (i = 0; i < sizeof(line)-1; i++) {
+ int c;
+
+ c = getc(f);
+ if ((c == EOF)) {
+ done = true;
+ break;
+ } else if (c == 0)
+ break;
+
+ line[i] = c;
+ }
+ line[i] = 0;
+
+ if (strneq(line, field, l) && line[l] == '=') {
+ r = 1;
+ goto out;
+ }
+
+ } while (!done);
+
+out:
+ fclose(f);
+ return r;
+}
+
+enum {
+ RUN_IN_HOST = 0,
+ RUN_IN_CONTAINER
+};
+
+int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) {
+ char status[BUF_LEN] = {0};
+ char *t, *f;
+ size_t len;
+ int r;
+
+ assert(terminator);
+ assert(filename);
+ assert(pattern);
+ assert(field);
+
+ int fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return -errno;
+
+ r = read(fd, &status, BUF_LEN - 1);
+ if (r < 0)
+ return r;
+
+ t = status;
+
+ do {
+ bool pattern_ok;
+
+ do {
+ t = strstr(t, pattern);
+ if (!t)
+ return -ENOENT;
+
+ /* Check that pattern occurs in beginning of line. */
+ pattern_ok = (t == status || t[-1] == '\n');
+
+ t += strlen(pattern);
+
+ } while (!pattern_ok);
+
+ t += strspn(t, " \t");
+ if (!*t)
+ return -ENOENT;
+
+ } while (*t != ':');
+
+ t++;
+
+
+ if (*t) {
+ t += strspn(t, " \t");
+
+ /* Also skip zeros, because when this is used for
+ * capabilities, we don't want the zeros. This way the
+ * same capability set always maps to the same string,
+ * irrespective of the total capability set size. For
+ * other numbers it shouldn't matter. */
+ t += strspn(t, "0");
+ /* Back off one char if there's nothing but whitespace
+ and zeros */
+ if (!*t || isspace(*t))
+ t--;
+ }
+
+ len = strcspn(t, terminator);
+
+ f = strndup(t, len);
+ if (!f)
+ return -ENOMEM;
+
+ *field = f;
+ return 0;
+}
+
+static int detect_container_by_pid_2(void) {
+ char *s = NULL;
+ int r;
+
+ r = get_proc_field("/proc/2/status", "PPid", WHITESPACE, &s);
+ if (r >= 0) {
+ if (streq(s, "0"))
+ r = RUN_IN_HOST;
+ else
+ r = RUN_IN_CONTAINER;
+ } else if (r == -ENOENT)
+ r = RUN_IN_CONTAINER;
+ else {
+ printf("Failed to read /proc/2/status: %d\n", r);
+ r = RUN_IN_HOST;
+ }
+
+ free(s);
+ return r;
+}
+
+int check_in_host(void)
+{
+ int r;
+
+ if (is_pid_1_has_environ("container"))
+ r = RUN_IN_CONTAINER;
+ else
+ r = detect_container_by_pid_2();
+
+ return r == RUN_IN_HOST;
+}
diff --git a/source/ucli/ucli.cc b/source/ucli/ucli.cc
index aacb7b9..1a98843 100644
--- a/source/ucli/ucli.cc
+++ b/source/ucli/ucli.cc
@@ -2,10 +2,8 @@
* various_monitor cli 命令行工具
*/
#include "ucli.h"
-
#include <getopt.h>
#include <string.h>
-
#include <cstdio>
static int task_info_extract(void *buf, unsigned int len, void *) {
@@ -49,7 +47,10 @@ static int task_info_extract(void *buf, unsigned int len, void *) {
tsk_info->task.state == 0 ? "R" : "D");
printk_task_brief(&tsk_info->task);
- diag_printf_raw_stack(tsk_info->task.tgid, tsk_info->task.container_tgid,
+ // diag_printf_raw_stack(tsk_info->task.tgid, tsk_info->task.container_tgid,
+ // tsk_info->task.comm, &tsk_info->raw_stack);
+ printf("run_in_host: %d\n", run_in_host);
+ diag_printf_raw_stack(run_in_host ? tsk_info->task.tgid : tsk_info->task.container_tgid, tsk_info->task.container_tgid,
tsk_info->task.comm, &tsk_info->raw_stack);
diag_printf_kern_stack(&tsk_info->kern_stack);
@@ -71,7 +72,7 @@ static void do_extract(char *buf, int len) {
static void do_dump(const char *arg) {
//!todo
- static char variant_buf[512 * 1024 * 1024];
+ static char variant_buf[256 * 1024 * 1024];
int len;
int ret = 0;
@@ -93,6 +94,8 @@ static void do_dump(const char *arg) {
}
int main(int argc, char *argv[]) {
+ run_in_host = check_in_host();
+
static const struct option long_options[] = {{"help", no_argument, 0, 0},
{"report", no_argument, 0, 0},
{"pid", required_argument, 0, 0},
diff --git a/source/ucli/ucli.h b/source/ucli/ucli.h
index f866b77..0aca6c1 100644
--- a/source/ucli/ucli.h
+++ b/source/ucli/ucli.h
@@ -124,6 +124,9 @@ void extract_variant_buffer(char *buf, unsigned int len,
int (*func)(void *, unsigned int, void *),
void *arg);
+extern unsigned long run_in_host;
+int check_in_host(void);
+
// all print fun
void printk_task_brief(task_detail *detail);
void diag_printf_raw_stack(int pid, int ns_pid, const char *comm,