diff -Nru lxcfs-2.0.6/bindings.c lxcfs-2.0.7/bindings.c --- lxcfs-2.0.6/bindings.c 2017-01-23 17:48:17.000000000 +0000 +++ lxcfs-2.0.7/bindings.c 2017-05-11 17:01:42.000000000 +0000 @@ -72,8 +72,8 @@ int cached; }; -/* reserve buffer size, for cpuall in /proc/stat */ -#define BUF_RESERVE_SIZE 256 +/* Reserve buffer size to account for file size changes. */ +#define BUF_RESERVE_SIZE 512 /* * A table caching which pid is init for a pid namespace. @@ -863,11 +863,11 @@ fnam = alloca(len); ret = snprintf(fnam, len, "%s%s/%s", *cgroup == '/' ? "." : "", cgroup, file); if (ret < 0 || (size_t)ret >= len) - return NULL; + return false; fd = openat(cfd, fnam, O_RDONLY); if (fd < 0) - return NULL; + return false; *value = slurp_file(fnam, fd); return *value != NULL; @@ -2908,7 +2908,7 @@ if (initpid <= 0) initpid = fc->pid; if (!caller_is_in_ancestor(initpid, controller, cgroup, &next)) { - if (!last || strcmp(next, last) == 0) + if (!last || (next && (strcmp(next, last) == 0))) ret = -EBUSY; else ret = -ENOENT; @@ -3086,7 +3086,8 @@ *memswlimit_str = NULL, *memswusage_str = NULL; unsigned long memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0, cached = 0, hosttotal = 0, active_anon = 0, inactive_anon = 0, - active_file = 0, inactive_file = 0, unevictable = 0; + active_file = 0, inactive_file = 0, unevictable = 0, + hostswtotal = 0; char *line = NULL; size_t linelen = 0, total_len = 0, rv = 0; char *cache = d->buf; @@ -3148,7 +3149,7 @@ memset(lbuf, 0, 100); if (startswith(line, "MemTotal:")) { - sscanf(line+14, "%lu", &hosttotal); + sscanf(line+sizeof("MemTotal:")-1, "%lu", &hosttotal); if (hosttotal < memlimit) memlimit = hosttotal; snprintf(lbuf, 100, "MemTotal: %8lu kB\n", memlimit); @@ -3160,6 +3161,9 @@ snprintf(lbuf, 100, "MemAvailable: %8lu kB\n", memlimit - memusage); printme = lbuf; } else if (startswith(line, "SwapTotal:") && memswlimit > 0) { + sscanf(line+sizeof("SwapTotal:")-1, "%lu", &hostswtotal); + if (hostswtotal < memswlimit - memlimit) + memswlimit = hostswtotal + memlimit; snprintf(lbuf, 100, "SwapTotal: %8lu kB\n", memswlimit - memlimit); printme = lbuf; } else if (startswith(line, "SwapFree:") && memswlimit > 0 && memswusage > 0) { @@ -3450,6 +3454,28 @@ return rv; } +static long int getreaperctime(pid_t pid) +{ + char fnam[100]; + struct stat sb; + int ret; + pid_t qpid; + + qpid = lookup_initpid_in_store(pid); + if (qpid <= 0) + return 0; + + ret = snprintf(fnam, 100, "/proc/%d", qpid); + if (ret < 0 || ret >= 100) + return 0; + + if (lstat(fnam, &sb) < 0) + return 0; + + return sb.st_ctime; +} + +#define CPUALL_MAX_SIZE (BUF_RESERVE_SIZE / 2) static int proc_stat_read(char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { @@ -3460,10 +3486,9 @@ char *line = NULL; size_t linelen = 0, total_len = 0, rv = 0; int curcpu = -1; /* cpu numbering starts at 0 */ - unsigned long user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0, steal = 0, guest = 0; + unsigned long user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0, steal = 0, guest = 0, guest_nice = 0; unsigned long user_sum = 0, nice_sum = 0, system_sum = 0, idle_sum = 0, iowait_sum = 0, - irq_sum = 0, softirq_sum = 0, steal_sum = 0, guest_sum = 0; -#define CPUALL_MAX_SIZE BUF_RESERVE_SIZE + irq_sum = 0, softirq_sum = 0, steal_sum = 0, guest_sum = 0, guest_nice_sum = 0; char cpuall[CPUALL_MAX_SIZE]; /* reserve for cpu all */ char *cache = d->buf + CPUALL_MAX_SIZE; @@ -3513,7 +3538,10 @@ continue; if (sscanf(line, "cpu%9[^ ]", cpu_char) != 1) { /* not a ^cpuN line containing a number N, just print it */ - l = snprintf(cache, cache_size, "%s", line); + if (strncmp(line, "btime", 5) == 0) + l = snprintf(cache, cache_size, "btime %ld\n", getreaperctime(fc->pid)); + else + l = snprintf(cache, cache_size, "%s", line); if (l < 0) { perror("Error writing to cache"); rv = 0; @@ -3556,8 +3584,17 @@ cache_size -= l; total_len += l; - if (sscanf(line, "%*s %lu %lu %lu %lu %lu %lu %lu %lu %lu", &user, &nice, &system, &idle, &iowait, &irq, - &softirq, &steal, &guest) != 9) + if (sscanf(line, "%*s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", + &user, + &nice, + &system, + &idle, + &iowait, + &irq, + &softirq, + &steal, + &guest, + &guest_nice) != 10) continue; user_sum += user; nice_sum += nice; @@ -3568,16 +3605,26 @@ softirq_sum += softirq; steal_sum += steal; guest_sum += guest; + guest_nice_sum += guest_nice; } cache = d->buf; - int cpuall_len = snprintf(cpuall, CPUALL_MAX_SIZE, "%s %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", - "cpu ", user_sum, nice_sum, system_sum, idle_sum, iowait_sum, irq_sum, softirq_sum, steal_sum, guest_sum); - if (cpuall_len > 0 && cpuall_len < CPUALL_MAX_SIZE){ + int cpuall_len = snprintf(cpuall, CPUALL_MAX_SIZE, "cpu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", + user_sum, + nice_sum, + system_sum, + idle_sum, + iowait_sum, + irq_sum, + softirq_sum, + steal_sum, + guest_sum, + guest_nice_sum); + if (cpuall_len > 0 && cpuall_len < CPUALL_MAX_SIZE) { memcpy(cache, cpuall, cpuall_len); cache += cpuall_len; - } else{ + } else { /* shouldn't happen */ lxcfs_error("proc_stat_read copy cpuall failed, cpuall_len=%d.", cpuall_len); cpuall_len = 0; @@ -3587,7 +3634,8 @@ total_len += cpuall_len; d->cached = 1; d->size = total_len; - if (total_len > size ) total_len = size; + if (total_len > size) + total_len = size; memcpy(buf, d->buf, total_len); rv = total_len; @@ -3603,23 +3651,12 @@ static long int getreaperage(pid_t pid) { - char fnam[100]; - struct stat sb; - int ret; - pid_t qpid; - - qpid = lookup_initpid_in_store(pid); - if (qpid <= 0) - return 0; - - ret = snprintf(fnam, 100, "/proc/%d", qpid); - if (ret < 0 || ret >= 100) - return 0; - - if (lstat(fnam, &sb) < 0) - return 0; + long int ctime; - return time(NULL) - sb.st_ctime; + ctime = getreaperctime(pid); + if (ctime) + return time(NULL) - ctime; + return ctime; } static unsigned long get_reaper_busy(pid_t task) @@ -4450,7 +4487,7 @@ goto out; } - fd_hierarchies = malloc(sizeof(int *) * num_hierarchies); + fd_hierarchies = malloc(sizeof(int) * num_hierarchies); if (!fd_hierarchies) { lxcfs_error("%s\n", strerror(errno)); goto out; diff -Nru lxcfs-2.0.6/config/init/systemd/Makefile.in lxcfs-2.0.7/config/init/systemd/Makefile.in --- lxcfs-2.0.6/config/init/systemd/Makefile.in 2017-01-23 17:48:22.000000000 +0000 +++ lxcfs-2.0.7/config/init/systemd/Makefile.in 2017-05-11 17:01:59.000000000 +0000 @@ -362,8 +362,8 @@ maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -@INIT_SCRIPT_SYSTEMD_FALSE@install-data-local: @INIT_SCRIPT_SYSTEMD_FALSE@uninstall-local: +@INIT_SCRIPT_SYSTEMD_FALSE@install-data-local: clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am diff -Nru lxcfs-2.0.6/config/init/upstart/Makefile.in lxcfs-2.0.7/config/init/upstart/Makefile.in --- lxcfs-2.0.6/config/init/upstart/Makefile.in 2017-01-23 17:48:22.000000000 +0000 +++ lxcfs-2.0.7/config/init/upstart/Makefile.in 2017-05-11 17:01:59.000000000 +0000 @@ -361,8 +361,8 @@ maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -@INIT_SCRIPT_UPSTART_FALSE@uninstall-local: @INIT_SCRIPT_UPSTART_FALSE@install-data-local: +@INIT_SCRIPT_UPSTART_FALSE@uninstall-local: clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am diff -Nru lxcfs-2.0.6/configure lxcfs-2.0.7/configure --- lxcfs-2.0.6/configure 2017-01-23 17:48:22.000000000 +0000 +++ lxcfs-2.0.7/configure 2017-05-11 17:01:58.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for lxcfs 2.0.6. +# Generated by GNU Autoconf 2.69 for lxcfs 2.0.7. # # Report bugs to . # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='lxcfs' PACKAGE_TARNAME='lxcfs' -PACKAGE_VERSION='2.0.6' -PACKAGE_STRING='lxcfs 2.0.6' +PACKAGE_VERSION='2.0.7' +PACKAGE_STRING='lxcfs 2.0.7' PACKAGE_BUGREPORT='lxc-devel@lists.linuxcontainers.org' PACKAGE_URL='' @@ -1368,7 +1368,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures lxcfs 2.0.6 to adapt to many kinds of systems. +\`configure' configures lxcfs 2.0.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1439,7 +1439,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of lxcfs 2.0.6:";; + short | recursive ) echo "Configuration of lxcfs 2.0.7:";; esac cat <<\_ACEOF @@ -1569,7 +1569,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -lxcfs configure 2.0.6 +lxcfs configure 2.0.7 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1938,7 +1938,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by lxcfs $as_me 2.0.6, which was +It was created by lxcfs $as_me 2.0.7, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2805,7 +2805,7 @@ # Define the identity of the package. PACKAGE='lxcfs' - VERSION='2.0.6' + VERSION='2.0.7' cat >>confdefs.h <<_ACEOF @@ -14519,7 +14519,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by lxcfs $as_me 2.0.6, which was +This file was extended by lxcfs $as_me 2.0.7, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14585,7 +14585,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -lxcfs config.status 2.0.6 +lxcfs config.status 2.0.7 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -Nru lxcfs-2.0.6/configure.ac lxcfs-2.0.7/configure.ac --- lxcfs-2.0.6/configure.ac 2017-01-23 17:48:17.000000000 +0000 +++ lxcfs-2.0.7/configure.ac 2017-05-11 17:01:42.000000000 +0000 @@ -1,7 +1,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([lxcfs], [2.0.6], [lxc-devel@lists.linuxcontainers.org]) +AC_INIT([lxcfs], [2.0.7], [lxc-devel@lists.linuxcontainers.org]) AC_SUBST(ACLOCAL_AMFLAGS, "-I m4") AC_CONFIG_MACRO_DIR([m4]) diff -Nru lxcfs-2.0.6/debian/changelog lxcfs-2.0.7/debian/changelog --- lxcfs-2.0.6/debian/changelog 2017-01-24 11:38:18.000000000 +0000 +++ lxcfs-2.0.7/debian/changelog 2017-05-12 16:01:13.000000000 +0000 @@ -1,3 +1,9 @@ +lxcfs (2.0.7-0ubuntu1) artful; urgency=medium + + * New upstream version 2.0.7 + + -- Stéphane Graber Fri, 12 May 2017 12:01:13 -0400 + lxcfs (2.0.6-1) unstable; urgency=medium * New upstream version 2.0.6 diff -Nru lxcfs-2.0.6/debian/control lxcfs-2.0.7/debian/control --- lxcfs-2.0.6/debian/control 2016-12-03 14:33:44.000000000 +0000 +++ lxcfs-2.0.7/debian/control 2017-05-12 16:01:13.000000000 +0000 @@ -1,7 +1,8 @@ Source: lxcfs Section: admin Priority: optional -Maintainer: pkg-lxc +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: pkg-lxc Uploaders: Adnan Hodzic , Evgeni Golov Build-Depends: autotools-dev, debhelper (>= 9), diff -Nru lxcfs-2.0.6/pam/pam_cgfs.c lxcfs-2.0.7/pam/pam_cgfs.c --- lxcfs-2.0.6/pam/pam_cgfs.c 2017-01-23 17:48:17.000000000 +0000 +++ lxcfs-2.0.7/pam/pam_cgfs.c 2017-05-11 17:01:42.000000000 +0000 @@ -346,7 +346,7 @@ { size_t len = strlen(s); - while (s[len - 1] == '\n') + while ((len > 0) && s[len - 1] == '\n') s[--len] = '\0'; } @@ -1318,11 +1318,11 @@ static bool cgv2_init(uid_t uid, gid_t gid) { char *mountpoint; - bool ret = false; FILE *f = NULL; char *current_cgroup = NULL, *init_cgroup = NULL; char * line = NULL; size_t len = 0; + int ret = false; current_cgroup = cgv2_get_current_cgroup(getpid()); if (!current_cgroup) { @@ -1366,7 +1366,7 @@ f = fopen("/proc/self/mountinfo", "r"); if (!f) - return false; + goto cleanup; /* we support simple cgroup mounts and lxcfs mounts */ while (getline(&line, &len, f) != -1) { @@ -1401,7 +1401,7 @@ fclose(f); free(line); - return true; + return ret; } /* Detect and store information about mounted cgroupfs v1 hierarchies and the @@ -1652,11 +1652,14 @@ size_t sep_len = strlen(sep); size_t result_len = use_as_prefix * sep_len; + if (!parts) + return NULL; + /* calculate new string length */ for (p = (char **)parts; *p; p++) result_len += (p > (char **)parts) * sep_len + strlen(*p); - result = calloc(result_len + 1, 1); + result = calloc(result_len + 1, sizeof(char)); if (!result) return NULL; @@ -1712,8 +1715,6 @@ if (!c1 && !c2) c1 = maxcpus; - else if (c1 > c2) - c2 = c1; else if (c1 < c2) c1 = c2; @@ -2100,8 +2101,6 @@ it = h; for (controller = it->controllers; controller && *controller; controller++) { - created = false; - if (!cgv1_handle_cpuset_hierarchy(it, cgroup)) return false; @@ -2159,10 +2158,7 @@ break; } - if (!created) - return false; - - return true; + return created; } /* Try to remove @cgroup for all given controllers in a cgroupfs v1 hierarchy