code clean
This commit is contained in:
@@ -76,13 +76,13 @@ static long device_ioctl(struct file *file, unsigned int ioctl_num,
|
||||
printk(KERN_INFO "variable_monitor IOCTL_DUMP_LOG\n");
|
||||
ret = copy_from_user(&dump_param, (ioctl_dump_param *)ioctl_param,
|
||||
sizeof(ioctl_dump_param));
|
||||
printk(KERN_INFO "dump_param: %p %d %p\n", dump_param.user_ptr_len,
|
||||
printk(KERN_INFO "dump_param: %p %lx %p\n", dump_param.user_ptr_len,
|
||||
dump_param.user_buf_len, dump_param.user_buf);
|
||||
if (!ret) {
|
||||
ret = copy_to_user_variant_buffer(
|
||||
&load_monitor_variant_buffer, dump_param.user_ptr_len,
|
||||
dump_param.user_buf, dump_param.user_buf_len);
|
||||
printk(KERN_INFO "ret %d, %d\n", ret, dump_param.user_buf_len);
|
||||
printk(KERN_INFO "ret %d, %lx\n", ret, dump_param.user_buf_len);
|
||||
}
|
||||
// printk(KERN_INFO "copy_to_user_variant_buffer \n");
|
||||
break;
|
||||
|
||||
@@ -19,7 +19,7 @@ extern int dump_reset_sec;
|
||||
|
||||
extern mm_tree mm_tree_struct;
|
||||
extern struct diag_variant_buffer load_monitor_variant_buffer; // global buffer
|
||||
#define LOAD_MONITOR_BUFFER_SIZE 256 * 1024 * 1024 // 10MB
|
||||
#define VARIABLE_MONITOR_BUFFER_SIZE 256 * 1024 * 1024 // 256MB
|
||||
|
||||
int monitor_init(void); // monitor init
|
||||
void monitor_exit(void); // monitor exit
|
||||
|
||||
@@ -270,7 +270,7 @@ int monitor_init(void) {
|
||||
ret = init_orig_fun(); // init orig_X
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = init_buffer(LOAD_MONITOR_BUFFER_SIZE); // 256M
|
||||
ret = init_buffer(VARIABLE_MONITOR_BUFFER_SIZE); // 256M
|
||||
if (ret)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
@@ -66,5 +66,6 @@ void start_all_hrTimer(void);
|
||||
void cancel_all_hrTimer(void);
|
||||
|
||||
// for work
|
||||
void init_work_all_hrTimer(void);
|
||||
void cancel_all_work(void);
|
||||
void cancel_destory_all_work(void);
|
||||
198
source/ucli/helpfun.cc
Normal file
198
source/ucli/helpfun.cc
Normal file
@@ -0,0 +1,198 @@
|
||||
#include "helpfun.h"
|
||||
|
||||
unsigned long run_in_host = 0;
|
||||
|
||||
enum { RUN_IN_HOST = 0, RUN_IN_CONTAINER };
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static const char *user_mode_str(int user_mode) {
|
||||
switch (user_mode) {
|
||||
case 1:
|
||||
return "USER MODE";
|
||||
case 0:
|
||||
return "SYSTEM MODE";
|
||||
default:
|
||||
return "UNKNOWN MODE";
|
||||
}
|
||||
}
|
||||
|
||||
std::string state_str(int __state) {
|
||||
std::vector<std::string> states;
|
||||
if (__state == TASK_RUNNING)
|
||||
states.push_back("TASK_RUNNING");
|
||||
// if (__state & TASK_RUNNING) states.push_back("TASK_RUNNING");
|
||||
if (__state & TASK_INTERRUPTIBLE)
|
||||
states.push_back("TASK_INTERRUPTIBLE");
|
||||
if (__state & TASK_UNINTERRUPTIBLE)
|
||||
states.push_back("TASK_UNINTERRUPTIBLE");
|
||||
if (__state & __TASK_STOPPED)
|
||||
states.push_back("__TASK_STOPPED");
|
||||
if (__state & __TASK_TRACED)
|
||||
states.push_back("__TASK_TRACED");
|
||||
if (__state & TASK_PARKED)
|
||||
states.push_back("TASK_PARKED");
|
||||
if (__state & TASK_DEAD)
|
||||
states.push_back("TASK_DEAD");
|
||||
if (__state == TASK_KILLABLE)
|
||||
states.push_back("TASK_KILLABLE");
|
||||
if (__state == TASK_STOPPED)
|
||||
states.push_back("TASK_STOPPED");
|
||||
if (__state == TASK_IDLE)
|
||||
states.push_back("TASK_IDLE");
|
||||
|
||||
std::string result;
|
||||
for (const auto &state : states) {
|
||||
if (!result.empty())
|
||||
result += " | ";
|
||||
result += state;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
37
source/ucli/helpfun.h
Normal file
37
source/ucli/helpfun.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef __HELP_FUN_H__
|
||||
#define __HELP_FUN_H__
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h> // for isspace
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <unistd.h> // for read
|
||||
#include <vector>
|
||||
|
||||
#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)
|
||||
|
||||
#define TASK_RUNNING 0x0000
|
||||
#define TASK_INTERRUPTIBLE 0x0001
|
||||
#define TASK_UNINTERRUPTIBLE 0x0002
|
||||
#define __TASK_STOPPED 0x0004
|
||||
#define __TASK_TRACED 0x0008
|
||||
#define TASK_PARKED 0x0040
|
||||
#define TASK_DEAD 0x0080
|
||||
#define TASK_WAKEKILL 0x0100
|
||||
#define TASK_NOLOAD 0x0200
|
||||
#define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
|
||||
#define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)
|
||||
#define TASK_IDLE (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)
|
||||
|
||||
extern unsigned long run_in_host; // 0: container, 1: host
|
||||
int check_in_host(void); // for run_in_host
|
||||
std::string state_str(int __state); // task state to string
|
||||
|
||||
#endif
|
||||
@@ -20,8 +20,6 @@
|
||||
#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 {
|
||||
@@ -61,8 +59,22 @@ std::string &pid_cmdline::get_pid_cmdline(int pid) {
|
||||
return cmdlines[pid];
|
||||
}
|
||||
|
||||
// 根据 sys_task 取值返回对应的字符串
|
||||
static const char *sys_task_str(int sys_task) {
|
||||
switch (sys_task) {
|
||||
case 0:
|
||||
return "USER_TASK";
|
||||
case 1:
|
||||
return "SYSTEM_TASK";
|
||||
case 2:
|
||||
return "IDLE_TASK";
|
||||
default:
|
||||
return "UNKNOWN_TASK";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 调用ioctl
|
||||
* @brief call ioctl
|
||||
*/
|
||||
long diag_call_ioctl(unsigned long request, unsigned long arg) {
|
||||
long ret = 0;
|
||||
@@ -91,6 +103,13 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief unwind frame callback
|
||||
*
|
||||
* @param entry
|
||||
* @param arg
|
||||
* @return int
|
||||
*/
|
||||
static int unwind_frame_callback(struct unwind_entry *entry, void *arg) {
|
||||
symbol sym;
|
||||
std::string symbol; // Use std::string instead of string
|
||||
@@ -120,6 +139,14 @@ static int unwind_frame_callback(struct unwind_entry *entry, void *arg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief extract buffer with func
|
||||
*
|
||||
* @param buf
|
||||
* @param len
|
||||
* @param func
|
||||
* @param arg
|
||||
*/
|
||||
void extract_variant_buffer(char *buf, unsigned int len,
|
||||
int (*func)(void *, unsigned int, void *),
|
||||
void *arg) {
|
||||
@@ -153,6 +180,14 @@ void extract_variant_buffer(char *buf, unsigned int len,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief printf user stack
|
||||
*
|
||||
* @param pid
|
||||
* @param ns_pid
|
||||
* @param comm
|
||||
* @param raw_stack
|
||||
*/
|
||||
void diag_printf_raw_stack(int pid, int ns_pid, const char *comm,
|
||||
raw_stack_detail *raw_stack) {
|
||||
struct perf_sample stack_sample;
|
||||
@@ -173,97 +208,11 @@ void diag_printf_raw_stack(int pid, int ns_pid, const char *comm,
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// 根据 sys_task 取值返回对应的字符串
|
||||
static const char *sys_task_str(int sys_task) {
|
||||
switch (sys_task) {
|
||||
case 0:
|
||||
return "USER_TASK";
|
||||
case 1:
|
||||
return "SYSTEM_TASK";
|
||||
case 2:
|
||||
return "IDLE_TASK";
|
||||
default:
|
||||
return "UNKNOWN_TASK";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *user_mode_str(int user_mode) {
|
||||
switch (user_mode) {
|
||||
case 1:
|
||||
return "USER MODE";
|
||||
case 0:
|
||||
return "SYSTEM MODE";
|
||||
default:
|
||||
return "UNKNOWN MODE";
|
||||
}
|
||||
}
|
||||
|
||||
// 判断 __state 具体是下面哪种状态.输出: 单个状态 | 组合状态
|
||||
// #define TASK_RUNNING 0x0000 // 正在运行
|
||||
// #define TASK_INTERRUPTIBLE 0x0001 // 等待事件阻塞 可信号唤醒
|
||||
// #define TASK_UNINTERRUPTIBLE 0x0002 // 等待事件阻塞 不可信号唤醒
|
||||
// #define __TASK_STOPPED 0x0004 // 暂停执行
|
||||
// #define __TASK_TRACED 0x0008 //调试状态
|
||||
// #define TASK_PARKED 0x0040 // parked 状态,暂停执行 保留在 cpu
|
||||
// 但不被调度 #define TASK_DEAD 0x0080 // dead #define
|
||||
// TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
|
||||
// #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)
|
||||
// #define TASK_IDLE (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)
|
||||
// static const char *state_str(int __state){
|
||||
|
||||
// }
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define TASK_RUNNING 0x0000
|
||||
#define TASK_INTERRUPTIBLE 0x0001
|
||||
#define TASK_UNINTERRUPTIBLE 0x0002
|
||||
#define __TASK_STOPPED 0x0004
|
||||
#define __TASK_TRACED 0x0008
|
||||
#define TASK_PARKED 0x0040
|
||||
#define TASK_DEAD 0x0080
|
||||
#define TASK_WAKEKILL 0x0100
|
||||
#define TASK_NOLOAD 0x0200
|
||||
#define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
|
||||
#define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)
|
||||
#define TASK_IDLE (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)
|
||||
|
||||
std::string state_str(int __state) {
|
||||
std::vector<std::string> states;
|
||||
|
||||
if (__state == TASK_RUNNING)
|
||||
states.push_back("TASK_RUNNING");
|
||||
// if (__state & TASK_RUNNING) states.push_back("TASK_RUNNING");
|
||||
if (__state & TASK_INTERRUPTIBLE)
|
||||
states.push_back("TASK_INTERRUPTIBLE");
|
||||
if (__state & TASK_UNINTERRUPTIBLE)
|
||||
states.push_back("TASK_UNINTERRUPTIBLE");
|
||||
if (__state & __TASK_STOPPED)
|
||||
states.push_back("__TASK_STOPPED");
|
||||
if (__state & __TASK_TRACED)
|
||||
states.push_back("__TASK_TRACED");
|
||||
if (__state & TASK_PARKED)
|
||||
states.push_back("TASK_PARKED");
|
||||
if (__state & TASK_DEAD)
|
||||
states.push_back("TASK_DEAD");
|
||||
if (__state == TASK_KILLABLE)
|
||||
states.push_back("TASK_KILLABLE");
|
||||
if (__state == TASK_STOPPED)
|
||||
states.push_back("TASK_STOPPED");
|
||||
if (__state == TASK_IDLE)
|
||||
states.push_back("TASK_IDLE");
|
||||
|
||||
std::string result;
|
||||
for (const auto &state : states) {
|
||||
if (!result.empty())
|
||||
result += " | ";
|
||||
result += state;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief printf task brief
|
||||
*
|
||||
* @param detail
|
||||
*/
|
||||
void printk_task_brief(task_detail *detail) {
|
||||
printf(" TASK INFO: %s [%s / %s], PID: %d / %d\n",
|
||||
sys_task_str(detail->sys_task), detail->cgroup_buf, detail->comm,
|
||||
@@ -273,6 +222,11 @@ void printk_task_brief(task_detail *detail) {
|
||||
// detail->state);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief print kernel stack
|
||||
*
|
||||
* @param kern_stack
|
||||
*/
|
||||
void diag_printf_kern_stack(kern_stack_detail *kern_stack) {
|
||||
int i;
|
||||
symbol sym;
|
||||
@@ -292,6 +246,11 @@ void diag_printf_kern_stack(kern_stack_detail *kern_stack) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief print proc chains
|
||||
*
|
||||
* @param proc_chains
|
||||
*/
|
||||
void diag_printf_proc_chains(proc_chains_detail *proc_chains) {
|
||||
int detail = 1;
|
||||
int i;
|
||||
@@ -312,154 +271,4 @@ void diag_printf_proc_chains(proc_chains_detail *proc_chains) {
|
||||
proc_chains->chains[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
* various_monitor cli 命令行工具
|
||||
*/
|
||||
#include "ucli.h"
|
||||
#include "helpfun.h"
|
||||
#include <cstdio>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
@@ -9,84 +10,6 @@
|
||||
#include <sys/ioctl.h> // for ioctl
|
||||
#include <unistd.h>
|
||||
|
||||
// #include <fcntl.h>
|
||||
// #include <sched.h>
|
||||
// // #include <unistd.h>
|
||||
// #include <stdio.h>
|
||||
// #include <stdlib.h>
|
||||
|
||||
// ioctl
|
||||
// !todo move to a header file
|
||||
#define IOCTL_MAGIC_NUMBER 'k'
|
||||
#define IOCTL_PID _IOWR(IOCTL_MAGIC_NUMBER, 2, int)
|
||||
#define IOCTL_TGID _IOWR(IOCTL_MAGIC_NUMBER, 3, int)
|
||||
|
||||
// int switch_namespace(pid_t pid, const char *ns) {
|
||||
// char ns_path[256];
|
||||
// snprintf(ns_path, sizeof(ns_path), "/proc/%d/ns/%s", pid, ns);
|
||||
|
||||
// int fd = open(ns_path, O_RDONLY);
|
||||
// if (fd == -1) {
|
||||
// perror("open");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if (setns(fd, 0) == -1) {
|
||||
// perror("setns");
|
||||
// close(fd);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// close(fd);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// int switch_to_pid_namespace(pid_t pid) {
|
||||
// return switch_namespace(pid, "pid");
|
||||
// }
|
||||
|
||||
// int switch_to_user_namespace(pid_t pid) {
|
||||
// return switch_namespace(pid, "user");
|
||||
// }
|
||||
|
||||
// void test(variable_monitor_task *tsk_info) {
|
||||
// // host
|
||||
// if (tsk_info->task.pid == tsk_info->task.container_pid){
|
||||
// printf("host\n");
|
||||
// diag_printf_raw_stack(tsk_info->task.tgid, tsk_info->task.container_tgid,
|
||||
// tsk_info->task.comm, &tsk_info->raw_stack);
|
||||
// }
|
||||
|
||||
// printf("container\n");
|
||||
|
||||
// // Save the current namespace.
|
||||
// int fd = open("/proc/self/ns/pid", O_RDONLY);
|
||||
// if (fd == -1) {
|
||||
// perror("open");
|
||||
// return;
|
||||
// }
|
||||
// // Switch to the namespace of the target process.
|
||||
// if (switch_to_pid_namespace(tsk_info->task.pid) != 0) {
|
||||
// close(fd);
|
||||
// return;
|
||||
// }
|
||||
// if (switch_to_user_namespace(tsk_info->task.pid) != 0) {
|
||||
// close(fd);
|
||||
// return;
|
||||
// }
|
||||
// // Do something with tgid...
|
||||
|
||||
// diag_printf_raw_stack(tsk_info->task.container_tgid,
|
||||
// tsk_info->task.container_tgid, tsk_info->task.comm,
|
||||
// &tsk_info->raw_stack);
|
||||
|
||||
// // Switch back to the original namespace.
|
||||
// if (!run_in_host && setns(fd, 0) == -1) {
|
||||
// perror("setns");
|
||||
// }
|
||||
// close(fd);
|
||||
// }
|
||||
|
||||
static int task_info_extract(void *buf, unsigned int len, void *) {
|
||||
int *et_type;
|
||||
variable_monitor_record *vm_record;
|
||||
@@ -128,18 +51,8 @@ static int task_info_extract(void *buf, unsigned int len, void *) {
|
||||
state_str(tsk_info->task.state).c_str(), tsk_info->task.state);
|
||||
|
||||
printk_task_brief(&tsk_info->task);
|
||||
// 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);
|
||||
// test(tsk_info);
|
||||
|
||||
// diag_printf_kern_stack(&tsk_info->kern_stack);
|
||||
|
||||
// system task no need print raw_stack
|
||||
// system task no need print user stack | just in case
|
||||
if (tsk_info->task.sys_task == 1) {
|
||||
diag_printf_kern_stack(&tsk_info->kern_stack);
|
||||
} else {
|
||||
@@ -170,7 +83,6 @@ static int task_info_extract(void *buf, unsigned int len, void *) {
|
||||
diag_printf_kern_stack(&tsk_info_system->kern_stack);
|
||||
printf("#* 0xffffffffffffff %s (UNKNOWN)\n",
|
||||
tsk_info_system->task.comm);
|
||||
// diag_printf_proc_chains(&tsk_info_system->proc_chains);
|
||||
printf("##\n");
|
||||
|
||||
break;
|
||||
@@ -187,8 +99,7 @@ static void do_extract(char *buf, int len) {
|
||||
}
|
||||
|
||||
static void do_dump(const char *arg) {
|
||||
//! todo
|
||||
static char variant_buf[256 * 1024 * 1024];
|
||||
static char variant_buf[VARIABLE_MONITOR_BUFFER_SIZE];
|
||||
int len;
|
||||
int ret = 0;
|
||||
|
||||
@@ -198,12 +109,11 @@ static void do_dump(const char *arg) {
|
||||
|
||||
struct diag_ioctl_dump_param dump_param = {
|
||||
.user_ptr_len = &len,
|
||||
.user_buf_len = 256 * 1024 * 1024,
|
||||
.user_buf_len = VARIABLE_MONITOR_BUFFER_SIZE,
|
||||
.user_buf = variant_buf,
|
||||
};
|
||||
|
||||
ret = diag_call_ioctl(IOCTL_DUMP_LOG,
|
||||
(long)&dump_param); // !todo arg -> #define
|
||||
ret = diag_call_ioctl(IOCTL_DUMP_LOG, (long)&dump_param);
|
||||
if (ret == 0) {
|
||||
do_extract(variant_buf, len);
|
||||
}
|
||||
@@ -223,7 +133,7 @@ static void do_pid(char *arg) {
|
||||
if (ret) {
|
||||
printf("Get pid info err: %d\n", ret);
|
||||
}
|
||||
sleep(3);
|
||||
sleep(3); // after 3sec
|
||||
|
||||
do_dump("");
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
// ioctl
|
||||
#define IOCTL_WATCH_VARIABLE 0
|
||||
#define IOCTL_DUMP_LOG 1
|
||||
#define IOCTL_MAGIC_NUMBER 'k'
|
||||
#define IOCTL_PID _IOWR(IOCTL_MAGIC_NUMBER, 2, int)
|
||||
#define IOCTL_TGID _IOWR(IOCTL_MAGIC_NUMBER, 3, int)
|
||||
|
||||
// dump type
|
||||
#define VARIABLE_MONITOR_RECORD_TYPE 0x0
|
||||
@@ -31,8 +34,12 @@
|
||||
#define MAX_NAME_LEN (127) // max name length
|
||||
#define TIMER_MAX_WATCH_NUM (32) // A timer max watch number at once time
|
||||
|
||||
#define VARIABLE_MONITOR_BUFFER_SIZE 256 * 1024 * 1024 // 256MB
|
||||
|
||||
#define DIAG_USER_STACK_SIZE (16 * 1024)
|
||||
|
||||
extern unsigned long run_in_host;
|
||||
|
||||
typedef struct {
|
||||
pid_t task_id; // current process id
|
||||
char name[MAX_NAME_LEN + 1]; // name
|
||||
@@ -146,6 +153,4 @@ void diag_printf_raw_stack(int pid, int ns_pid, const char *comm,
|
||||
void diag_printf_kern_stack(kern_stack_detail *kern_stack);
|
||||
void diag_printf_proc_chains(proc_chains_detail *proc_chains);
|
||||
|
||||
std::string state_str(int __state);
|
||||
|
||||
#endif /* UAPI_H */
|
||||
Reference in New Issue
Block a user