1TIME_NAMESPACES(7) Linux Programmer's Manual TIME_NAMESPACES(7)
2
3
4
6 time_namespaces - overview of Linux time namespaces
7
9 Time namespaces virtualize the values of two system clocks:
10
11 • CLOCK_MONOTONIC (and likewise CLOCK_MONOTONIC_COARSE and CLOCK_MONO‐
12 TONIC_RAW), a nonsettable clock that represents monotonic time
13 since—as described by POSIX—"some unspecified point in the past".
14
15 • CLOCK_BOOTTIME (and likewise CLOCK_BOOTTIME_ALARM), a nonsettable
16 clock that is identical to CLOCK_MONOTONIC, except that it also in‐
17 cludes any time that the system is suspended.
18
19 Thus, the processes in a time namespace share per-namespace values for
20 these clocks. This affects various APIs that measure against these
21 clocks, including: clock_gettime(2), clock_nanosleep(2), nanosleep(2),
22 timer_settime(2), timerfd_settime(2), and /proc/uptime.
23
24 Currently, the only way to create a time namespace is by calling un‐
25 share(2) with the CLONE_NEWTIME flag. This call creates a new time
26 namespace but does not place the calling process in the new namespace.
27 Instead, the calling process's subsequently created children are placed
28 in the new namespace. This allows clock offsets (see below) for the
29 new namespace to be set before the first process is placed in the name‐
30 space. The /proc/[pid]/ns/time_for_children symbolic link shows the
31 time namespace in which the children of a process will be created. (A
32 process can use a file descriptor opened on this symbolic link in a
33 call to setns(2) in order to move into the namespace.)
34
35 /proc/PID/timens_offsets
36 Associated with each time namespace are offsets, expressed with respect
37 to the initial time namespace, that define the values of the monotonic
38 and boot-time clocks in that namespace. These offsets are exposed via
39 the file /proc/PID/timens_offsets. Within this file, the offsets are
40 expressed as lines consisting of three space-delimited fields:
41
42 <clock-id> <offset-secs> <offset-nanosecs>
43
44 The clock-id is a string that identifies the clock whose offsets are
45 being shown. This field is either monotonic, for CLOCK_MONOTONIC, or
46 boottime, for CLOCK_BOOTTIME. The remaining fields express the offset
47 (seconds plus nanoseconds) for the clock in this time namespace. These
48 offsets are expressed relative to the clock values in the initial time
49 namespace. The offset-secs value can be negative, subject to restric‐
50 tions noted below; offset-nanosecs is an unsigned value.
51
52 In the initial time namespace, the contents of the timens_offsets file
53 are as follows:
54
55 $ cat /proc/self/timens_offsets
56 monotonic 0 0
57 boottime 0 0
58
59 In a new time namespace that has had no member processes, the clock
60 offsets can be modified by writing newline-terminated records of the
61 same form to the timens_offsets file. The file can be written to mul‐
62 tiple times, but after the first process has been created in or has en‐
63 tered the namespace, write(2)s on this file fail with the error EACCES.
64 In order to write to the timens_offsets file, a process must have the
65 CAP_SYS_TIME capability in the user namespace that owns the time name‐
66 space.
67
68 Writes to the timens_offsets file can fail with the following errors:
69
70 EINVAL An offset-nanosecs value is greater than 999,999,999.
71
72 EINVAL A clock-id value is not valid.
73
74 EPERM The caller does not have the CAP_SYS_TIME capability.
75
76 ERANGE An offset-secs value is out of range. In particular;
77
78 • offset-secs can't be set to a value which would make the cur‐
79 rent time on the corresponding clock inside the namespace a
80 negative value; and
81
82 • offset-secs can't be set to a value such that the time on the
83 corresponding clock inside the namespace would exceed half of
84 the value of the kernel constant KTIME_SEC_MAX (this limits
85 the clock value to a maximum of approximately 146 years).
86
87 In a new time namespace created by unshare(2), the contents of the
88 timens_offsets file are inherited from the time namespace of the creat‐
89 ing process.
90
92 Use of time namespaces requires a kernel that is configured with the
93 CONFIG_TIME_NS option.
94
95 Note that time namespaces do not virtualize the CLOCK_REALTIME clock.
96 Virtualization of this clock was avoided for reasons of complexity and
97 overhead within the kernel.
98
99 For compatibility with the initial implementation, when writing a
100 clock-id to the /proc/[pid]/timens_offsets file, the numerical values
101 of the IDs can be written instead of the symbolic names show above;
102 i.e., 1 instead of monotonic, and 7 instead of boottime. For redabil‐
103 ity, the use of the symbolic names over the numbers is preferred.
104
105 The motivation for adding time namespaces was to allow the monotonic
106 and boot-time clocks to maintain consistent values during container mi‐
107 gration and checkpoint/restore.
108
110 The following shell session demonstrates the operation of time name‐
111 spaces. We begin by displaying the inode number of the time namespace
112 of a shell in the initial time namespace:
113
114 $ readlink /proc/$$/ns/time
115 time:[4026531834]
116
117 Continuing in the initial time namespace, we display the system uptime
118 using uptime(1) and use the clock_times example program shown in
119 clock_getres(2) to display the values of various clocks:
120
121 $ uptime --pretty
122 up 21 hours, 17 minutes
123 $ ./clock_times
124 CLOCK_REALTIME : 1585989401.971 (18356 days + 8h 36m 41s)
125 CLOCK_TAI : 1585989438.972 (18356 days + 8h 37m 18s)
126 CLOCK_MONOTONIC: 56338.247 (15h 38m 58s)
127 CLOCK_BOOTTIME : 76633.544 (21h 17m 13s)
128
129 We then use unshare(1) to create a time namespace and execute a bash(1)
130 shell. From the new shell, we use the built-in echo command to write
131 records to the timens_offsets file adjusting the offset for the
132 CLOCK_MONOTONIC clock forward 2 days and the offset for the CLOCK_BOOT‐
133 TIME clock forward 7 days:
134
135 $ PS1="ns2# " sudo unshare -T -- bash --norc
136 ns2# echo "monotonic $((2*24*60*60)) 0" > /proc/$$/timens_offsets
137 ns2# echo "boottime $((7*24*60*60)) 0" > /proc/$$/timens_offsets
138
139 Above, we started the bash(1) shell with the --norc options so that no
140 start-up scripts were executed. This ensures that no child processes
141 are created from the shell before we have a chance to update the
142 timens_offsets file.
143
144 We then use cat(1) to display the contents of the timens_offsets file.
145 The execution of cat(1) creates the first process in the new time name‐
146 space, after which further attempts to update the timens_offsets file
147 produce an error.
148
149 ns2# cat /proc/$$/timens_offsets
150 monotonic 172800 0
151 boottime 604800 0
152 ns2# echo "boottime $((9*24*60*60)) 0" > /proc/$$/timens_offsets
153 bash: echo: write error: Permission denied
154
155 Continuing in the new namespace, we execute uptime(1) and the
156 clock_times example program:
157
158 ns2# uptime --pretty
159 up 1 week, 21 hours, 18 minutes
160 ns2# ./clock_times
161 CLOCK_REALTIME : 1585989457.056 (18356 days + 8h 37m 37s)
162 CLOCK_TAI : 1585989494.057 (18356 days + 8h 38m 14s)
163 CLOCK_MONOTONIC: 229193.332 (2 days + 15h 39m 53s)
164 CLOCK_BOOTTIME : 681488.629 (7 days + 21h 18m 8s)
165
166 From the above output, we can see that the monotonic and boot-time
167 clocks have different values in the new time namespace.
168
169 Examining the /proc/[pid]/ns/time and /proc/[pid]/ns/time_for_children
170 symbolic links, we see that the shell is a member of the initial time
171 namespace, but its children are created in the new namespace.
172
173
174 ns2# readlink /proc/$$/ns/time
175 time:[4026531834]
176 ns2# readlink /proc/$$/ns/time_for_children
177 time:[4026532900]
178 ns2# readlink /proc/self/ns/time # Creates a child process
179 time:[4026532900]
180
181 Returning to the shell in the initial time namespace, we see that the
182 monotonic and boot-time clocks are unaffected by the timens_offsets
183 changes that were made in the other time namespace:
184
185 $ uptime --pretty
186 up 21 hours, 19 minutes
187 $ ./clock_times
188 CLOCK_REALTIME : 1585989401.971 (18356 days + 8h 38m 51s)
189 CLOCK_TAI : 1585989438.972 (18356 days + 8h 39m 28s)
190 CLOCK_MONOTONIC: 56338.247 (15h 41m 8s)
191 CLOCK_BOOTTIME : 76633.544 (21h 19m 23s)
192
194 nsenter(1), unshare(1), clock_settime(2), setns(2), unshare(2), name‐
195 spaces(7), time(7)
196
198 This page is part of release 5.10 of the Linux man-pages project. A
199 description of the project, information about reporting bugs, and the
200 latest version of this page, can be found at
201 https://www.kernel.org/doc/man-pages/.
202
203
204
205Linux 2020-06-09 TIME_NAMESPACES(7)