Add the CLOCK_BOOTTIME clockid for use with clock_gettime(2)
authorcheloha <cheloha@openbsd.org>
Mon, 18 Dec 2017 05:51:53 +0000 (05:51 +0000)
committercheloha <cheloha@openbsd.org>
Mon, 18 Dec 2017 05:51:53 +0000 (05:51 +0000)
and put it to use in userspace in lieu of the kern.boottime
sysctl.

Its absolute value is the time that has elapsed since the
system booted, i.e., the system uptime.

Use in top(1), w(1), and snmpd(8) eliminates a race with
settimeofday(2), adjtime(2), etc. inherent to deriving the
system uptime via the kern.boottime sysctl.

Product of a great deal of discussion/revision with jca@, tb@,
and guenther@.

ok tb@ jca@ guenther@ dlg@ mlarkin@ tom@

lib/libc/sys/clock_gettime.2
sys/kern/kern_time.c
sys/sys/_time.h
usr.bin/top/display.c
usr.bin/w/w.c
usr.sbin/snmpd/mib.c

index 1e4c93e..cb06d8d 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: clock_gettime.2,v 1.27 2015/09/10 17:55:21 schwarze Exp $
+.\"    $OpenBSD: clock_gettime.2,v 1.28 2017/12/18 05:51:53 cheloha Exp $
 .\"
 .\" Copyright (c) 1980, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -27,7 +27,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: September 10 2015 $
+.Dd $Mdocdate: December 18 2017 $
 .Dt CLOCK_GETTIME 2
 .Os
 .Sh NAME
@@ -73,6 +73,9 @@ time that increments as a wall clock should but whose absolute value
 is meaningless and cannot jump,
 providing accurate realtime interval measurement,
 even across suspend and resume
+.It Dv CLOCK_BOOTTIME
+time whose absolute value is the time that has elapsed since the
+system was booted
 .It Dv CLOCK_UPTIME
 time whose absolute value is the time the system has been running
 and not suspended,
@@ -157,8 +160,10 @@ functions conform to
 .St -p1003.1-2008 .
 .Pp
 The
+.Dv CLOCK_BOOTTIME
+and
 .Dv CLOCK_UPTIME
-clock is an extension to that.
+clocks are extensions to that.
 .Sh HISTORY
 The
 .Dv CLOCK_PROCESS_CPUTIME_ID
@@ -174,3 +179,11 @@ and was added to
 .Ox
 in
 .Ox 5.5 .
+The
+.Dv CLOCK_BOOTTIME
+clock first appeared in
+Linux 2.6.39
+and was added to
+.Ox
+in
+.Ox 6.3 .
index 8193c4e..61a9b55 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_time.c,v 1.99 2017/01/24 00:58:55 mpi Exp $      */
+/*     $OpenBSD: kern_time.c,v 1.100 2017/12/18 05:51:53 cheloha Exp $ */
 /*     $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $      */
 
 /*
@@ -124,6 +124,7 @@ clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp)
                bintime2timespec(&bt, tp);
                break;
        case CLOCK_MONOTONIC:
+       case CLOCK_BOOTTIME:
                nanouptime(tp);
                break;
        case CLOCK_PROCESS_CPUTIME_ID:
@@ -223,6 +224,7 @@ sys_clock_getres(struct proc *p, void *v, register_t *retval)
        switch (clock_id) {
        case CLOCK_REALTIME:
        case CLOCK_MONOTONIC:
+       case CLOCK_BOOTTIME:
        case CLOCK_UPTIME:
        case CLOCK_PROCESS_CPUTIME_ID:
        case CLOCK_THREAD_CPUTIME_ID:
index e188212..a8ac94e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: _time.h,v 1.8 2016/09/03 15:06:06 akfaew Exp $        */
+/*     $OpenBSD: _time.h,v 1.9 2017/12/18 05:51:53 cheloha Exp $       */
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -37,6 +37,7 @@
 #define CLOCK_MONOTONIC                        3
 #define CLOCK_THREAD_CPUTIME_ID                4
 #define CLOCK_UPTIME                   5
+#define CLOCK_BOOTTIME                 6
 
 #if __BSD_VISIBLE
 /*
index 30b20b0..2b2e678 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: display.c,v 1.52 2017/03/15 04:24:14 deraadt Exp $         */
+/* $OpenBSD: display.c,v 1.53 2017/12/18 05:51:53 cheloha Exp $         */
 
 /*
  *  Top users/processes display for Unix
@@ -57,7 +57,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <sys/sysctl.h>
 
 #include "screen.h"            /* interface to screen package */
 #include "layout.h"            /* defines for screen position layout */
@@ -209,22 +208,15 @@ display_init(struct statics * statics)
 static void
 format_uptime(char *buf, size_t buflen)
 {
-       time_t now, uptime;
+       time_t uptime;
        int days, hrs, mins;
-       int mib[2];
-       size_t size;
-       struct timeval boottime;
+       struct timespec boottime;
 
-       now = time(NULL);
        /*
         * Print how long system has been up.
-        * (Found by getting "boottime" from the kernel)
         */
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_BOOTTIME;
-       size = sizeof(boottime);
-       if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) {
-               uptime = now - boottime.tv_sec;
+       if (clock_gettime(CLOCK_BOOTTIME, &boottime) != -1) {
+               uptime = boottime.tv_sec;
                uptime += 30;
                days = uptime / (3600 * 24);
                uptime %= (3600 * 24);
index e85784a..5642197 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: w.c,v 1.64 2017/12/14 18:03:03 jasper Exp $   */
+/*     $OpenBSD: w.c,v 1.65 2017/12/18 05:51:53 cheloha Exp $  */
 
 /*-
  * Copyright (c) 1980, 1991, 1993, 1994
@@ -66,7 +66,6 @@
 
 #include "extern.h"
 
-struct timeval boottime;
 struct utmp    utmp;
 struct winsize ws;
 kvm_t         *kd;
@@ -426,10 +425,9 @@ static void
 pr_header(time_t *nowp, int nusers)
 {
        double avenrun[3];
+       struct timespec boottime;
        time_t uptime;
        int days, hrs, i, mins;
-       int mib[2];
-       size_t size;
        char buf[256];
 
        /*
@@ -441,13 +439,9 @@ pr_header(time_t *nowp, int nusers)
 
        /*
         * Print how long system has been up.
-        * (Found by getting "boottime" from the kernel)
         */
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_BOOTTIME;
-       size = sizeof(boottime);
-       if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) {
-               uptime = now - boottime.tv_sec;
+       if (clock_gettime(CLOCK_BOOTTIME, &boottime) != -1) {
+               uptime = boottime.tv_sec;
                if (uptime > 59) {
                        uptime += 30;
                        days = uptime / SECSPERDAY;
index 995f887..47940c9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mib.c,v 1.84 2017/06/01 14:38:28 patrick Exp $        */
+/*     $OpenBSD: mib.c,v 1.85 2017/12/18 05:51:53 cheloha Exp $        */
 
 /*
  * Copyright (c) 2012 Joel Knight <joel@openbsd.org>
@@ -451,18 +451,13 @@ static struct oid hr_mib[] = {
 int
 mib_hrsystemuptime(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
 {
-       struct timeval   boottime;
-       int              mib[] = { CTL_KERN, KERN_BOOTTIME };
-       time_t           now;
-       size_t           len;
+       struct timespec  uptime;
+       long long        ticks;
 
-       (void)time(&now);
-       len = sizeof(boottime);
-
-       if (sysctl(mib, 2, &boottime, &len, NULL, 0) == -1)
+       if (clock_gettime(CLOCK_BOOTTIME, &uptime) == -1)
                return (-1);
-
-       *elm = ber_add_integer(*elm, (now - boottime.tv_sec) * 100);
+       ticks = uptime.tv_sec * 100 + uptime.tv_nsec / 10000000;
+       *elm = ber_add_integer(*elm, ticks);
        ber_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
 
        return (0);