The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/libresource/pull/10
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === 1: Created files for process related information 2: Added a new resource id for process information. 3: Added code to get process information.
From 659843a9e0679dfd0f56b936d6d970f3ff5548aa Mon Sep 17 00:00:00 2001 From: Rahul Yadav <rahul.x.ya...@oracle.com> Date: Fri, 21 Jun 2019 17:24:29 -0700 Subject: [PATCH 1/5] Added resource to get process related info Signed-off-by: Rahul Yadav <rahul.x.ya...@oracle.com> --- resproc.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ resproc.h | 31 +++++++++ 2 files changed, 231 insertions(+) create mode 100644 resproc.c create mode 100644 resproc.h diff --git a/resproc.c b/resproc.c new file mode 100644 index 0000000..6305dc0 --- /dev/null +++ b/resproc.c @@ -0,0 +1,200 @@ +/* Copyright (C) 2018, Oracle and/or its affiliates. All rights reserved + * + * This file is part of libresource. + * + * libresource is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * libresource 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 Lesser General public License for more details. + * + * You should have received a copy of the GNU Lesser General public License + * along with libresource. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _RESOURCE_H +#include "resource.h" +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "resproc.h" +#include "resource_impl.h" +#include <errno.h> +#include <libgen.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <pwd.h> + +/* Reading information from /proc/<pid>/statm */ +static void statm_to_proc(char* buf, res_proc_infoall_t *p) { + sscanf(buf, "%ld %ld %ld %ld %ld %ld %ld", + &p->size, &p->resident, &p->share, + &p->text, &p->lib, &p->data, &p->dt); +} + +/* Reading information from /proc/<pid>/stat */ +static void stat_to_proc(char* buf, res_proc_infoall_t *p) { + unsigned int num; + char* tmp; + + /* fill in default values for older kernels */ + p->processor = 0; + p->rtprio = -1; + p->policy = -1; + p->nlwp = 0; + + /* Fill the command to run process */ + buf = strchr(buf, '(') + 1; + tmp = strrchr(buf, ')'); + num = tmp - buf; + if(num >= sizeof p->cmd) + num = sizeof p->cmd - 1; + memcpy(p->cmd, buf, num); + p->cmd[num] = '\0'; + buf = tmp + 2; + + /* Now we are just after command in the string starting from status + * of the process. + */ + sscanf(buf, + "%c " + "%d %d %d %d %d " + "%lu %lu %lu %lu %lu " + /* utime stime cutime cstime */ + "%Lu %Lu %Lu %Lu " + "%ld %ld " + "%d " + "%ld " + /* start_time */ + "%Lu " + "%lu " + "%ld " + "%lu " + /* start_code, end_code, start_stack */ + "%Lu %Lu %Lu " + "%Lu %Lu " + /* discard, no RT signals & Linux 2.1 used hex */ + "%*s %*s %*s %*s " + "%Lu " + "%*s %*s " + "%d %d " + "%lu %lu", + &p->state, + &p->ppid, &p->pgrp, &p->session, &p->tty, &p->tpgid, + &p->flags, &p->min_flt, &p->cmin_flt, &p->maj_flt, &p->cmaj_flt, + &p->utime, &p->stime, &p->cutime, &p->cstime, + &p->priority, &p->nice, + &p->nlwp, + &p->alarm, + &p->start_time, + &p->vsize, + &p->rss, + &p->rss_rlim, + &p->start_code, &p->end_code, &p->start_stack, + &p->kstk_esp, &p->kstk_eip, + /* p->signal, p->blocked, p->sigignore, p->sigcatch, can't use */ + &p->wchan, + /* &p->nswap, &p->cnswap, nswap and cnswap dead for 2.4.xx and up */ + /* -- Linux 2.0.35 ends here -- */ + &p->exit_signal, &p->processor, + /* -- Linux 2.2.8 to 2.5.17 end here -- */ + &p->rtprio, &p->policy + ); + + if(!p->nlwp){ + p->nlwp = 1; + } +} + +static void get_user_info(char *path, res_proc_infoall_t *p) { + static struct stat sb; + struct passwd *pw = NULL; + + + /* Get user id and use that to get useranme */ + if (stat(path, &sb) == -1) { + eprintf("Error in reading stat"); + } + + p->euid = sb.st_uid; + pw = getpwuid(p->euid); + if(!pw || strlen(pw->pw_name) >= RES_USR_NAME_SZ) { + sprintf(p->euser, "%u", p->euid); + } else { + strcpy(p->euser, pw->pw_name); + } +} + +/* Read resource information corresponding to res_id */ +int getprocinfo(int res_id, void *out, size_t sz, void *hint, int pid, int flags) +{ + char fstat[FNAMELEN]; + char fstatm[FNAMELEN]; + res_proc_infoall_t *p; + char buf[PROCBUF_1024]; + +#define CHECK_SIZE(sz, req_sz) \ + if (sz < req_sz) { \ + eprintf("memory (%ld) is not enough to hold data (%ld)",\ + sz, req_sz); \ + errno = ENOMEM; \ + return -1; \ + } + + + switch (res_id) { + case RES_PROC_INFOALL: + CHECK_SIZE(sz, sizeof(res_proc_infoall_t)); + + p = (res_proc_infoall_t *)out; + + if (pid) { + p->pid = pid; + snprintf(fstat, FNAMELEN, "/proc/%d/stat", pid); + snprintf(fstatm, FNAMELEN, "/proc/%d/statm", pid); + } else { + p->pid = getpid(); + snprintf(fstat, FNAMELEN, "/proc/self/stat"); + snprintf(fstatm, FNAMELEN, "/proc/self/statm"); + } + + get_user_info(fstat, p); + file_to_buf(fstat, buf, PROCBUF_1024); + stat_to_proc(buf, p); + file_to_buf(fstatm, buf, PROCBUF_1024); + statm_to_proc(buf, p); + + break; + + default: + eprintf("Resource Id is invalid"); + errno = EINVAL; + return -1; + } + +#undef CHECK_SIZE + + return 0; +} + +int populate_procinfo(res_blk_t *res, int pid, int flags) +{ + for (int i = 0; i < res->res_count; i++) { + switch (res->res_unit[i]->res_id) { + case RES_PROC_INFOALL: + getprocinfo(RES_PROC_INFOALL, + (res->res_unit[i]->data).ptr, + res->res_unit[i]->data_sz, + NULL, pid, flags); + res->res_unit[i]->status = RES_STATUS_FILLED; + } + } + return 0; +} diff --git a/resproc.h b/resproc.h new file mode 100644 index 0000000..6d01e2c --- /dev/null +++ b/resproc.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2018, Oracle and/or its affiliates. All rights reserved + * + * This file is part of libresource. + * + * libresource is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * libresource 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libresource. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _RESPROC_H +#define _RESPROC_H + +#define MEMINFO_FILE "/proc/meminfo" +#define VMINFO_FILE "/proc/vmstat" + +#define PROCBUF_1024 1024 +#define PROCBUF_2048 2048 + +extern int getprocinfo(int res_id, void *out, size_t sz, + void *hint, int pid, int flags); + +#endif /* _RESPROC_H */ From 6366143f9bacf4142f581dde0615a97723001e65 Mon Sep 17 00:00:00 2001 From: Rahul Yadav <rahul.x.ya...@oracle.com> Date: Fri, 21 Jun 2019 17:53:49 -0700 Subject: [PATCH 2/5] Added proc info Signed-off-by: Rahul Yadav <rahul.x.ya...@oracle.com> --- resproc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/resproc.h b/resproc.h index 6d01e2c..5559fdd 100644 --- a/resproc.h +++ b/resproc.h @@ -25,6 +25,7 @@ #define PROCBUF_1024 1024 #define PROCBUF_2048 2048 +extern int populate_procinfo(struct res_blk *res, int pid, int flags); extern int getprocinfo(int res_id, void *out, size_t sz, void *hint, int pid, int flags); From d74b8fd28641205f90935527710f2f78e802dfac Mon Sep 17 00:00:00 2001 From: Rahul Yadav <rahul.x.ya...@oracle.com> Date: Fri, 21 Jun 2019 17:58:35 -0700 Subject: [PATCH 3/5] Adding proc info Signed-off-by: Rahul Yadav <rahul.x.ya...@oracle.com> --- Makefile | 4 ++-- resource.c | 22 +++++++++++++++++++++ resource.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 2c71328..dcfd226 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC = gcc CFLAGS = -g -Wall -Werror -fPIC -DEPS = resource.h res_impl.h resmem.h resnet.h -OBJ = resource.o resmem.o resnet.o +DEPS = resource.h res_impl.h resmem.h resnet.h resproc.h +OBJ = resource.o resmem.o resnet.o resproc.o LIB = libresource.so TEST = test RM = rm -rf diff --git a/resource.c b/resource.c index ea8f64c..5da45be 100644 --- a/resource.c +++ b/resource.c @@ -28,6 +28,7 @@ #include "resource_impl.h" #include "resmem.h" #include "resnet.h" +#include "resproc.h" /* Allocate memory for bulk resource information and initiate it * properly. @@ -108,6 +109,18 @@ res_blk_t *res_build_blk(int *res_ids, int res_count) temp->data_sz = sizeof(res_mem_infoall_t); break; + case RES_PROC_INFOALL: + temp->data.ptr = (res_proc_infoall_t *) + malloc(sizeof(res_proc_infoall_t)); + if (temp->data.ptr == NULL) { + free(temp); + res_destroy_blk(res); + errno = ENOMEM; + return NULL; + } + temp->data_sz = sizeof(res_proc_infoall_t); + break; + default: eprintf("Invalid resource ID: %d", res_ids[i]); free(temp); @@ -133,6 +146,7 @@ void res_destroy_blk(res_blk_t *res) switch (res->res_unit[i]->res_id) { case RES_NET_IFSTAT: case RES_MEM_INFOALL: + case RES_PROC_INFOALL: free((res->res_unit[i])->data.ptr); (res->res_unit[i])->data.ptr = NULL; break; @@ -170,6 +184,9 @@ int res_read(int res_id, void *out, size_t out_sz, void *hint, int pid, int flag } } + if (res_id >= PROC_MIN && res_id < PROC_MAX) + return getprocinfo(res_id, out, out_sz, hint, pid, flags); + /* Check if memory proc file is needed to open */ if (res_id >= MEM_MIN && res_id < MEM_MAX) return getmeminfo(res_id, out, out_sz, hint, pid, flags); @@ -217,6 +234,7 @@ int res_read_blk(res_blk_t *res, int pid, int flags) { int ismeminforeq = 0; int isnetdevreq = 0; + int isprocreq = 0; struct utsname t; int ret; char *out; @@ -281,12 +299,16 @@ int res_read_blk(res_blk_t *res, int pid, int flags) case RES_NET_ALLIFSTAT: isnetdevreq = 1; break; + case RES_PROC_INFOALL: + isprocreq = 1; default: res->res_unit[i]->status = RES_STATUS_NOTSUPPORTED; } } + if(isprocreq) + populate_procinfo(res, pid, flags); if (ismeminforeq) populate_meminfo(res, pid, flags); diff --git a/resource.h b/resource.h index 6ade910..ba11fc9 100644 --- a/resource.h +++ b/resource.h @@ -51,6 +51,9 @@ */ #define RES_UNIT_OUT_SIZE 256 +/* Size of user name length */ +#define RES_USR_NAME_SZ 32 + /* This union is used to return resource information of various types */ union r_data { int i; @@ -111,6 +114,11 @@ typedef struct res_blk { #define RES_KERN_RELEASE 3074 #define KERN_MAX 3075 +#define PROC_MIN 4096 +#define RES_PROC_PPID 4097 +#define RES_PROC_INFOALL 4098 +#define PROC_MAX 4099 + /* Structure to return RES_MEM_INFOALL resource information */ typedef struct res_mem_infoall { size_t memfree; @@ -143,6 +151,55 @@ typedef struct res_net_ifstat { unsigned long tx_compressed; } res_net_ifstat_t; +typedef struct proc_info { + int pid; + char cmd[16]; + char state; + int ppid; + int pgrp; + int session; + int tty; + int tpgid; + unsigned long flags; + unsigned long min_flt; + unsigned long cmin_flt; + unsigned long maj_flt; + unsigned long cmaj_flt; + unsigned long long utime; + unsigned long long stime; + unsigned long long cutime; + unsigned long long cstime; + unsigned long long start_time; + long priority; + long nice; + int nlwp; + long alarm; + unsigned long vsize; + long rss; + unsigned long rss_rlim; + unsigned long long start_code; + unsigned long long end_code; + unsigned long long start_stack; + unsigned long long kstk_esp; + unsigned long long kstk_eip; + unsigned long long wchan; + int exit_signal; + int processor; + unsigned long rtprio; + unsigned long policy; + int euid; + char euser[RES_USR_NAME_SZ]; + + /* Information from /prco/[pid]/statm */ + unsigned long size; + unsigned long resident; + unsigned long share; + unsigned long text; + unsigned long lib; + unsigned long data; + unsigned long dt; +} res_proc_infoall_t; + /* Allocating memory and building a res_blk structure to return bulk * resource information. */ From aeb35ed2f5b6cac19b3fbcdd9cd1a64f3be5f9fe Mon Sep 17 00:00:00 2001 From: Rahul Yadav <rahul.x.ya...@oracle.com> Date: Fri, 21 Jun 2019 18:40:13 -0700 Subject: [PATCH 4/5] Little change - remove unused resource id. Signed-off-by: Rahul Yadav <rahul.x.ya...@oracle.com> --- resource.h | 1 - 1 file changed, 1 deletion(-) diff --git a/resource.h b/resource.h index ba11fc9..2664de3 100644 --- a/resource.h +++ b/resource.h @@ -115,7 +115,6 @@ typedef struct res_blk { #define KERN_MAX 3075 #define PROC_MIN 4096 -#define RES_PROC_PPID 4097 #define RES_PROC_INFOALL 4098 #define PROC_MAX 4099 From 016e2ea6535561b548aa17e16e5d4f63158ca3dd Mon Sep 17 00:00:00 2001 From: Rahul Yadav <rahul.x.ya...@oracle.com> Date: Fri, 21 Jun 2019 18:49:01 -0700 Subject: [PATCH 5/5] Remove unused header Signed-off-by: Rahul Yadav <rahul.x.ya...@oracle.com> --- resource.h | 4 ++-- resproc.c | 7 +------ resproc.h | 4 ---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/resource.h b/resource.h index 2664de3..7828cdc 100644 --- a/resource.h +++ b/resource.h @@ -115,8 +115,8 @@ typedef struct res_blk { #define KERN_MAX 3075 #define PROC_MIN 4096 -#define RES_PROC_INFOALL 4098 -#define PROC_MAX 4099 +#define RES_PROC_INFOALL 4097 +#define PROC_MAX 4098 /* Structure to return RES_MEM_INFOALL resource information */ typedef struct res_mem_infoall { diff --git a/resproc.c b/resproc.c index 6305dc0..3b25a4c 100644 --- a/resproc.c +++ b/resproc.c @@ -20,16 +20,11 @@ #include "resource.h" #endif #include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <unistd.h> +#include <string.h> #include "resproc.h" #include "resource_impl.h" -#include <errno.h> -#include <libgen.h> -#include <sys/types.h> #include <sys/stat.h> -#include <unistd.h> #include <pwd.h> /* Reading information from /proc/<pid>/statm */ diff --git a/resproc.h b/resproc.h index 5559fdd..4ecbf18 100644 --- a/resproc.h +++ b/resproc.h @@ -19,11 +19,7 @@ #ifndef _RESPROC_H #define _RESPROC_H -#define MEMINFO_FILE "/proc/meminfo" -#define VMINFO_FILE "/proc/vmstat" - #define PROCBUF_1024 1024 -#define PROCBUF_2048 2048 extern int populate_procinfo(struct res_blk *res, int pid, int flags); extern int getprocinfo(int res_id, void *out, size_t sz,
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel