57

My computer says:

$ uptime
 10:20:35 up  1:46,  3 users,  load average: 0,03, 0,10, 0,13

And if I check last I see:

reboot   system boot  3.19.0-51-generi Tue Apr 12 08:34 - 10:20  (01:45)    

And then I check:

$ ls -l /var/log/boot.log 
-rw-r--r-- 1 root root 4734 Apr 12 08:34 boot.log

Then I see in /var/log/syslog the first line of today being:

Apr 12 08:34:39 PC... rsyslogd: [origin software="rsyslogd" swVersion="7.4.4" x-pid="820" x-info="http://www.rsyslog.com"] start

So all seems to converge in 8:34 being the time when my machine has booted.

However, I wonder: what is the exact time uptime uses? Is uptime a process that launches and checks some file or is it something on the hardware?

I'm running Ubuntu 14.04.

user
  • 28,161
  • 13
  • 75
  • 138
fedorqui
  • 7,603
  • 7
  • 35
  • 71
  • I'm pretty sure the time stamp you see at the top of the log from the boot is the time when the syslog daemon received the message to be logged. That's not the same thing as when the system was powered on, or even the same thing as when the kernel was initialized. – user Apr 12 '16 at 21:23
  • As far as I know `systemd-analyze blame` also contains the time before Kernel init, at least on uefi. – bot47 Apr 13 '16 at 12:13
  • With tuptime you get a clear and simple output. – rfmoz Apr 13 '16 at 12:28
  • 1
    @Rikr interesting! However, I cannot find this command in my machine. Is it this [github project](https://github.com/rfrail3/tuptime)? – fedorqui Apr 13 '16 at 12:32
  • @fedorqui Yes, it is in https://github.com/rfrail3/tuptime/ or inside Debian in Stretch or Sid – rfmoz Apr 13 '16 at 12:36

3 Answers3

87

On my system it gets the uptime from /proc/uptime:

$ strace -eopen uptime
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/libproc-3.2.8.so", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/proc/version", O_RDONLY)         = 3
open("/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3
open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 3
open("/proc/uptime", O_RDONLY)          = 3
open("/var/run/utmp", O_RDONLY|O_CLOEXEC) = 4
open("/proc/loadavg", O_RDONLY)         = 4
 10:52:38 up 3 days, 23:38,  4 users,  load average: 0.00, 0.02, 0.05

From the proc manpage:

   /proc/uptime
          This file contains two numbers: the uptime of the system
          (seconds), and the amount of time spent in idle process
          (seconds).

The proc filesystem contains a set of pseudo files. Those are not real files, they just look like files, but they contain values that are provided directly by the kernel. Every time you read a file, such as /proc/uptime, its contents are regenerated on the fly. The proc filesystem is an interface to the kernel.


In the linux kernel source code of the file fs/proc/uptime.c at line 49, you see a function call:

proc_create("uptime", 0, NULL, &uptime_proc_fops);

This creates a proc filesystem entry called uptime (the procfs is usually mounted under /proc), and associates a function to it, which defines valid file operations on that pseudo file and the functions associated to them. In case of uptime it's just read() and open() operations. However, if you trace the functions back you will end up here, where the uptime is calculated.


Internally, there is a timer-interupt which updates periodically the systems uptime (besides other values). The interval, in which the timer-interupt ticks, is defined by the preprocessor-macro HZ, whose exact value is defined in the kernel config file and applied at compilation time.

The idle time and the number of CPU cycles, combined with the frequency HZ (cycles per second) can be calculated in a number (of seconds) since the last boot.


To address your question: When does “uptime” start counting from?

Since the uptime is a kernel internal value, which ticks up every cycle, it starts counting when the kernel has initialized. That is, when the first cycle has ended. Even before anything is mounted, directly after the bootloader gives control to the kernel image.

chaos
  • 47,463
  • 11
  • 118
  • 144
  • 2
    +1 , @chaos , would it be more accurate to say that uptime counter starts when the timer interrupt handler is installed ? Does the kernel configure this handler ? – Prem Apr 12 '16 at 13:11
  • 3
    @Prem It's part of the kernel initialization. Right before the scheduler initialization, the timer interrupt will be registered. It's the timer interrupt which calls the first iteration of the scheduler code (just by a function call). If you're interessted, this is a good read: https://github.com/0xAX/linux-insides/blob/master/Initialization/README.md – chaos Apr 12 '16 at 13:43
  • But sometimes the uptime value returned from the kernel isn't always the same. As is calculated on the fly, not at boot, if the server is runing some time sync, or is under heavy load, this value can change, due the shifts on the HZ. – rfmoz Apr 13 '16 at 12:33
11

As long as I know, uptime uses /proc/uptime to calculate system uptime. You can see it more clearly in the source code uptime.c

  FILE *fp;

  fp = fopen ("/proc/uptime", "r");
  if (fp != NULL)
    {
      char buf[BUFSIZ];
      char *b = fgets (buf, BUFSIZ, fp);
      if (b == buf)
        {
          char *end_ptr;
          double upsecs = c_strtod (buf, &end_ptr);
          if (buf != end_ptr)
            uptime = (0 <= upsecs && upsecs < TYPE_MAXIMUM (time_t)
                      ? upsecs : -1);
        }

      fclose (fp);
    }
Inclooder
  • 378
  • 1
  • 6
8

On a standard UNIX system (based on the original sources *), uptime reads /var/adm/utmpx and checks for the last time of reboot entry.

In other words: this is retrieving the date you also get with who -b and then computes the time since then.

*) uptime is a link to the w program and was introduced by BSD around 1980.

schily
  • 18,806
  • 5
  • 38
  • 60
  • Uhms, I cannot find `/var/adm/utmpx` in my system. In fact, not even `/var/adm` – fedorqui Apr 12 '16 at 12:40
  • 4
    In such a case, you should mention what kind of OS you are using. – schily Apr 12 '16 at 17:02
  • My fault! It is Ubuntu 14.04. – fedorqui Apr 12 '16 at 21:09
  • OK, on Solaris, AIX, HP-UX and *BSD where the original `w` implementation is used things are this way, but Linux usually does things a bit different. – schily Apr 13 '16 at 08:23
  • 6
    I think by _standard_, you mean _traditional_. The Unix standard doesn't specify the `uptime` command, let alone how it should be implemented. AFAICT, OS/X doesn't have a /var/adm/utmpx either. And some Linux-based systems have received Unix-compliance certification. – Stéphane Chazelas Apr 13 '16 at 11:29
  • Mac OS X just renamed "adm" to "run", so check: `/var/run/utmpx` and verify the behavior of `uptime` on MAC OS X using `dtruss`. Given that Linux does not come with a POSIX compliant `waitid()`, there is no Linux based platform that is POSIX compliant. – schily Apr 13 '16 at 17:36