diff options
author | Igor Galić <me+git@igalic.co> | 2020-01-10 05:06:06 +0100 |
---|---|---|
committer | Chad Smith <chad.smith@canonical.com> | 2020-01-09 21:06:06 -0700 |
commit | c911afbfe5a38823971e9cdbd4d1848c6e5c16de (patch) | |
tree | 4c6f04f883e0394b6bfc1d24d94c7db294e76fdd /cloudinit/util.py | |
parent | 6e7f8590402967bffbdd0bb0ae241180910fcd2c (diff) | |
download | vyos-cloud-init-c911afbfe5a38823971e9cdbd4d1848c6e5c16de.tar.gz vyos-cloud-init-c911afbfe5a38823971e9cdbd4d1848c6e5c16de.zip |
util: move uptime's else branch into its own boottime function (#53)
Also fix bugs:
- pass binary instead of string to sysctlbyname(), and
- unpack the "return value" in a struct, rather than in single integer.
LP: #1853160
Co-Authored-By: Ryan Harper <ryan.harper@canonical.com>
Diffstat (limited to 'cloudinit/util.py')
-rw-r--r-- | cloudinit/util.py | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/cloudinit/util.py b/cloudinit/util.py index 830c8e54..76d7db78 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -10,7 +10,6 @@ import contextlib import copy as obj_copy -import ctypes import email import glob import grp @@ -1807,6 +1806,33 @@ def time_rfc2822(): return ts +def boottime(): + """Use sysctlbyname(3) via ctypes to find kern.boottime + + kern.boottime is of type struct timeval. Here we create a + private class to easier unpack it. + + @return boottime: float to be compatible with linux + """ + import ctypes + + NULL_BYTES = b"\x00" + + class timeval(ctypes.Structure): + _fields_ = [ + ("tv_sec", ctypes.c_int64), + ("tv_usec", ctypes.c_int64) + ] + libc = ctypes.CDLL('/lib/libc.so.7') + size = ctypes.c_size_t() + size.value = ctypes.sizeof(timeval) + buf = timeval() + if libc.sysctlbyname(b"kern.boottime" + NULL_BYTES, ctypes.byref(buf), + ctypes.byref(size), None, 0) != -1: + return buf.tv_sec + buf.tv_usec / 1000000.0 + raise RuntimeError("Unable to retrieve kern.boottime on this system") + + def uptime(): uptime_str = '??' method = 'unknown' @@ -1818,15 +1844,8 @@ def uptime(): uptime_str = contents.split()[0] else: method = 'ctypes' - libc = ctypes.CDLL('/lib/libc.so.7') - size = ctypes.c_size_t() - buf = ctypes.c_int() - size.value = ctypes.sizeof(buf) - libc.sysctlbyname("kern.boottime", ctypes.byref(buf), - ctypes.byref(size), None, 0) - now = time.time() - bootup = buf.value - uptime_str = now - bootup + # This is the *BSD codepath + uptime_str = str(time.time() - boottime()) except Exception: logexc(LOG, "Unable to read uptime using method: %s" % method) |