From: Daniel Hokka Zakrisson Date: Sun, 8 Aug 2010 15:19:57 +0000 (+0000) Subject: Fix vserver-stat for memcg. X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a923f0462d73c4f46c639b8ec4eb86e189047586;hp=c9b654bfea1bbc32d36f0ff1d9960630a1910b90;p=util-vserver.git Fix vserver-stat for memcg. git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2906 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- diff --git a/lib/issupported.c b/lib/issupported.c index 3fb32e6..3f614ae 100644 --- a/lib/issupported.c +++ b/lib/issupported.c @@ -50,7 +50,7 @@ vc_isSupported(vcFeatureSet feature) case vcFEATURE_PPTAG : return conf & VC_VCI_PPTAG; case vcFEATURE_SPACES : return conf & VC_VCI_SPACES; case vcFEATURE_PIVOT_ROOT : return ver >= 0x00020304; - case vcFEATURE_PIDSPACE : return ver >= 0x00020305; + case vcFEATURE_MEMCG : return ver >= 0x00020306 && conf & VC_VCI_MEMCG; default : assert(false); } diff --git a/lib/issupportedstring.c b/lib/issupportedstring.c index 92b31bd..fa9cafe 100644 --- a/lib/issupportedstring.c +++ b/lib/issupportedstring.c @@ -35,7 +35,7 @@ static struct { DECL(MIGRATE), DECL(NAMESPACE), DECL(SCHED), DECL(VINFO), DECL(VHI), DECL(VSHELPER0), DECL(VSHELPER), DECL(VWAIT), DECL(VNET), DECL(VSTAT), DECL(PPTAG), DECL(PIDSPACE), - DECL(SPACES), DECL(PERSISTENT),DECL(PIVOT_ROOT), + DECL(SPACES), DECL(PERSISTENT),DECL(PIVOT_ROOT),DECL(MEMCG), }; bool diff --git a/lib/vserver.h b/lib/vserver.h index b705f40..9c1e820 100644 --- a/lib/vserver.h +++ b/lib/vserver.h @@ -281,8 +281,18 @@ // the VCI bit values #define VC_VCI_NO_DYNAMIC (1 << 0) +#define VC_VCI_PROC_SECURE (1 << 4) +#define VC_VCI_HARDCPU (1 << 5) +#define VC_VCI_IDLELIMIT (1 << 6) +#define VC_VCI_IDLETIME (1 << 7) +#define VC_VCI_COWBL (1 << 8) +#define VC_VCI_FULLCOWBL (1 << 9) #define VC_VCI_SPACES (1 << 10) #define VC_VCI_NETV2 (1 << 11) +#define VC_VCI_MEMCG (1 << 12) +#define VC_VCI_DEBUG (1 << 16) +#define VC_VCI_HISTORY (1 << 20) +#define VC_VCI_TAGGED (1 << 24) #define VC_VCI_PPTAG (1 << 28) @@ -980,7 +990,7 @@ extern "C" { vcFEATURE_VSHELPER0, vcFEATURE_VSHELPER, vcFEATURE_VWAIT, vcFEATURE_VNET, vcFEATURE_VSTAT, vcFEATURE_PPTAG, vcFEATURE_PIDSPACE, vcFEATURE_SPACES, vcFEATURE_PERSISTENT, - vcFEATURE_PIVOT_ROOT, + vcFEATURE_PIVOT_ROOT, vcFEATURE_MEMCG, } vcFeatureSet; diff --git a/pathconfig.h.pathsubst b/pathconfig.h.pathsubst index 4679e02..d87fbe0 100644 --- a/pathconfig.h.pathsubst +++ b/pathconfig.h.pathsubst @@ -25,6 +25,7 @@ #define SYSCONFDIR "@SYSCONFDIR@" #define LOCKDIR "/var/lock" #define PKGLIBDEFAULTDIR PKGLIBDIR "/defaults" +#define DEFAULTCONFDIR "@CONFDIR@/.defaults" #define DEFAULT_VSERVERDIR "@VSERVERDIR@" #define DEFAULT_VSERVERPKGDIR "@VSERVERPKGDIR@" diff --git a/scripts/vserver.functions b/scripts/vserver.functions index ce50019..dc6427e 100644 --- a/scripts/vserver.functions +++ b/scripts/vserver.functions @@ -1475,8 +1475,12 @@ function useCgroup { hasCgroup || return 1 test -d "$CGROUP_MNT" || return 1 + memcg="" + if $_VSERVER_INFO - FEATURE memcg; then + memcg=1 + fi test -d "$1/cgroup" -o \ - \( -d "$__CONFDIR/.defaults/cgroup" -a \ + \( \( -d "$__CONFDIR/.defaults/cgroup" -o -n "$memcg" \) -a \ ! -e "$1/nocgroup" \) } diff --git a/src/vserver-stat.c b/src/vserver-stat.c index c84f9c2..101b916 100644 --- a/src/vserver-stat.c +++ b/src/vserver-stat.c @@ -24,6 +24,7 @@ #include "vserver.h" #include "util.h" #include "internal.h" +#include "pathconfig.h" #include @@ -279,6 +280,123 @@ registerXidVstat(struct Vector *vec, unsigned long xid_l) } } +static void +registerXidCgroups(struct Vector *vec, struct process_info *process) +{ + xid_t xid = (xid_t) process->s_context; + struct XidData *res; + + switch (vc_getXIDType(xid)) { + case vcTYPE_STATIC: + case vcTYPE_DYNAMIC: + break; + default: + return; + } + + res = Vector_search(vec, &xid, cmpData); + if (res == 0) { + struct vc_rlimit_stat limit; + struct vc_virt_stat vstat; + struct vc_sched_info sched; + int cpu; + char vhi_name[65], + filename[128], + cgroup[65], + buf[30]; + int fd; + ssize_t cgroup_len; + unsigned long long rss; + char *endptr; + + if (vc_virt_stat(xid, &vstat) == -1) { + perror("vc_virt_stat()"); + return; + } + if (vc_rlimit_stat(xid, RLIMIT_NPROC, &limit) == -1) { + perror("vc_rlimit_stat(RLIMIT_NRPOC)"); + return; + } + if (vc_get_vhi_name(xid, vcVHI_CONTEXT, vhi_name, sizeof(vhi_name)) == -1) { + perror("vc_get_vhi_name(CONTEXT)"); + return; + } + + if ((fd = open(DEFAULTCONFDIR "/cgroup/mnt", O_RDONLY)) == -1) { + strcpy(cgroup, "/dev/cgroup/"); + cgroup_len = sizeof("/dev/cgroup"); + } + else { + cgroup_len = read(fd, cgroup, sizeof(cgroup)); + if (cgroup_len == -1) { + perror("read(cgroup/mnt)"); + return; + } + close(fd); + cgroup[cgroup_len] = '/'; + cgroup_len += 1; + cgroup[cgroup_len] = 0; + } + + snprintf(filename, sizeof(filename), "%s/cgroup/name", vhi_name); + if ((fd = open(filename, O_RDONLY)) == -1) { + char *dir = strrchr(vhi_name, '/'); + if (dir == NULL) { + fprintf(stderr, "invalid context name: %s\n", dir); + return; + } + snprintf(cgroup + cgroup_len, sizeof(cgroup) - cgroup_len, "%s", dir); + } + else { + ssize_t ret; + ret = read(fd, cgroup + cgroup_len, sizeof(cgroup) - cgroup_len); + if (ret == -1) { + perror("read(cgroup/name)"); + return; + } + close(fd); + } + + snprintf(filename, sizeof(filename), "%s/memory.usage_in_bytes", cgroup); + if ((fd = open(filename, O_RDONLY)) == -1) { + perror("open(memory.usage_in_bytes)"); + return; + } + if (read(fd, buf, sizeof(buf)) == -1) { + perror("read(memory.usage_in_bytes)"); + return; + } + close(fd); + if ((rss = strtoull(buf, &endptr, 0)) == ULLONG_MAX || + (*endptr != '\n' && *endptr != '\0')) { + perror("strtoull(memory.usage_in_bytes)"); + return; + } + + res = Vector_insert(vec, &xid, cmpData); + res->xid = xid; + + res->process_count = limit.value; + res->VmRSS_total = rss / 4096; + res->start_time_oldest= getUptime() - vstat.uptime/1000000; + + res->utime_total = 0; + res->stime_total = 0; + // XXX: arbitrary CPU limit. + for (cpu = 0; cpu < 1024; cpu++) { + sched.cpu_id = cpu; + sched.bucket_id = 0; + if (vc_sched_info(xid, &sched) == -1) + break; + + res->utime_total += sched.user_msec; + res->stime_total += sched.sys_msec; + } + } + + res->VmSize_total += process->VmSize; +} + static inline uint64_t toMsec(uint64_t v) { @@ -615,7 +733,7 @@ int main(int argc, char **argv) Vector_init(&xid_data, sizeof(struct XidData)); - if (vc_isSupported(vcFEATURE_VSTAT)) { + if (vc_isSupported(vcFEATURE_VSTAT) && !vc_isSupported(vcFEATURE_MEMCG)) { unsigned long xid; Echdir(PROC_VIRT_DIR_NAME); proc_dir = Eopendir("."); @@ -628,6 +746,8 @@ int main(int argc, char **argv) closedir(proc_dir); } else { + void (*handler)(struct Vector *vec, struct process_info *process); + my_pid = getpid(); if (!switchToWatchXid(&errptr)) { @@ -641,6 +761,11 @@ int main(int argc, char **argv) " procfs-security. Please read the FAQ for more details\n" " http://linux-vserver.org/Proc-Security\n"); + if (vc_isSupported(vcFEATURE_MEMCG)) + handler = registerXidCgroups; + else + handler = registerXid; + Echdir(PROC_DIR_NAME); proc_dir = Eopendir("."); while ((dir_entry = readdir(proc_dir)) != NULL) @@ -652,7 +777,7 @@ int main(int argc, char **argv) if (atoi(dir_entry->d_name) != my_pid) { struct process_info * info = get_process_info(dir_entry->d_name); if (info) - registerXid(&xid_data, info); + handler(&xid_data, info); } } closedir(proc_dir);