[lxc-devel] [libresource/master] Adding process related information
rahuyada on Github
lxc-bot at linuxcontainers.org
Sat Jun 22 01:53:53 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 451 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190621/41fca4df/attachment-0001.bin>
-------------- next part --------------
From 659843a9e0679dfd0f56b936d6d970f3ff5548aa Mon Sep 17 00:00:00 2001
From: Rahul Yadav <rahul.x.yadav at 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.yadav at 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.yadav at 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.yadav at 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.yadav at 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.yadav at 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.yadav at 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.yadav at 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.yadav at 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.yadav at 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,
More information about the lxc-devel
mailing list