proc.c 3.7 KB
Newer Older
N
nocjj 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/******************************************************************************
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
 * vmtop licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 * Description: get procfs data
 ********************************************************************************/
#include <stdio.h>
#include <string.h>
#include "type.h"
#include "proc.h"
#include "utils.h"

#define STAT_PATH_SIZE 40

struct file_item proc_stab[] = {
22 23
#define GDF(f)   (void *)GET_NAME(f), (void *)DELTA_NAME(f), NULL
#define GF(f)    (void *)GET_NAME(f), NULL, NULL
N
nocjj 已提交
24 25 26 27 28 29 30 31 32 33 34
    {"%c", GF(state)},
    {"%d", GF(ppid)},
    {"%d", GF(pgrd)},
    {"%d", GF(session)},
    {"%d", GF(tty)},
    {"%d", GF(tpgid)},
    {"%lu", GF(flags)},
    {"%lu", GF(min_flt)},
    {"%lu", GF(cmin_flt)},
    {"%lu", GF(maj_flt)},
    {"%lu", GF(cmaj_flt)},
N
nocjj 已提交
35 36
    {"%llu", GDF(utime)},
    {"%llu", GDF(stime)},
N
nocjj 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
    {"%llu", GF(cutime)},
    {"%llu", GF(cstime)},
    {"%ld", GF(priority)},
    {"%ld", GF(nice)},
    {"%d", GF(nlwp)},
    {"%ld", GF(alarm)},
    {"%llu", GF(start_time)},
    {"%lu", GF(vsize)},
    {"%ld", GF(rss)},
    {"%lu", GF(rss_rlim)},
    {"%lu", GF(start_code)},
    {"%lu", GF(end_code)},
    {"%lu", GF(start_stack)},
    {"%lu", GF(kstk_esp)},
    {"%lu", GF(kstk_eip)},
52 53 54 55
    {"%*s", NULL, NULL, NULL},    /* discard signal */
    {"%*s", NULL, NULL, NULL},    /* discard blocked */
    {"%*s", NULL, NULL, NULL},    /* discard sigignore */
    {"%*s", NULL, NULL, NULL},    /* discard sigcatch */
N
nocjj 已提交
56
    {"%lu", GF(wchan)},
57 58
    {"%*u", NULL, NULL, NULL},    /* dsicard nswap */
    {"%*u", NULL, NULL, NULL},    /* discard cnswap */
N
nocjj 已提交
59 60 61 62 63
    {"%d", GF(exit_signal)},
    {"%d", GF(processor)},
    {"%lu", GF(rtprio)},
    {"%lu", GF(sched)}
#undef GF
N
nocjj 已提交
64
#undef GDF
N
nocjj 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77
};

const int stat_size = sizeof(proc_stab) / sizeof(struct file_item);

int get_proc_stat(struct domain *dom)
{
    char buf[BUF_SIZE];
    char path[STAT_PATH_SIZE];
    char *tmp = NULL;
    char *p = NULL;
    char *p_next = NULL;
    int i = 0;

78
    if (dom->type == ISDOMAIN) {
79
        if (snprintf(path, STAT_PATH_SIZE, "/proc/%u/stat", dom->pid) < 0) {
80 81 82
            return -1;
        }
    } else {
83
         if (snprintf(path, STAT_PATH_SIZE, "/proc/%u/task/%u/stat",
84 85 86
                      dom->ppid, dom->pid) < 0) {
            return -1;
        }
N
nocjj 已提交
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
    }
    if (read_file(buf, BUF_SIZE, path) < 0) {
        return -1;
    }

    /* read from state item of "...) S ..." */
    tmp = strrchr(buf, ')');
    tmp = tmp + 2;

    for (p = strtok_r(tmp, " \t\r\n", &p_next); p && i < stat_size;
         p = strtok_r(NULL, " \t\r\n", &p_next)) {
        if (proc_stab[i].get_fun != NULL) {
            sscanf(p, proc_stab[i].format, (*proc_stab[i].get_fun)(dom));
        }
        ++i;
    }
    return 1;
}
N
nocjj 已提交
105 106 107 108 109 110 111 112 113

void refresh_delta_stat(struct domain *new, struct domain *old)
{
    for (int i = 0; i < stat_size; i++) {
        if (proc_stab[i].delta_fun) {
            (*proc_stab[i].delta_fun)(new, old);
        }
    }
}
114 115 116 117 118 119

int get_proc_comm(struct domain *dom)
{
    char path[STAT_PATH_SIZE];
    int len;

120
    if (snprintf(path, STAT_PATH_SIZE, "/proc/%u/comm", dom->pid) < 0) {
121 122 123 124
        return -1;
    }

    len = read_file(dom->vmname, DOMAIN_NAME_MAX, path);
125 126 127
    if (len > 1) {
        dom->vmname[len - 1] = '\0';
    }
128 129
    return len;
}