{"id":4047,"date":"2022-12-20T17:28:49","date_gmt":"2022-12-20T20:28:49","guid":{"rendered":"http:\/\/lode.uno\/linux-man\/index.php\/2022\/12\/20\/time_namespaces-man7\/"},"modified":"2022-12-20T17:28:49","modified_gmt":"2022-12-20T20:28:49","slug":"time_namespaces-man7","status":"publish","type":"post","link":"https:\/\/lode.uno\/linux-man\/2022\/12\/20\/time_namespaces-man7\/","title":{"rendered":"TIME_NAMESPACES (man7)"},"content":{"rendered":"<h1 align=\"center\">TIME_NAMESPACES<\/h1>\n<p> <a href=\"#NAME\">NAME<\/a><br \/> <a href=\"#DESCRIPTION\">DESCRIPTION<\/a><br \/> <a href=\"#NOTES\">NOTES<\/a><br \/> <a href=\"#EXAMPLES\">EXAMPLES<\/a><br \/> <a href=\"#SEE ALSO\">SEE ALSO<\/a><br \/> <a href=\"#COLOPHON\">COLOPHON<\/a> <\/p>\n<hr>\n<h2>NAME <a name=\"NAME\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">time_namespaces \u2212 overview of Linux time namespaces<\/p>\n<h2>DESCRIPTION <a name=\"DESCRIPTION\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">Time namespaces virtualize the values of two system clocks:<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"1%\">\n<p>\u2022<\/p>\n<\/td>\n<td width=\"2%\"><\/td>\n<td width=\"86%\">\n<p><b>CLOCK_MONOTONIC<\/b> (and likewise <b>CLOCK_MONOTONIC_COARSE<\/b> and <b>CLOCK_MONOTONIC_RAW<\/b>), a nonsettable clock that represents monotonic time since\u2014as described by POSIX\u2014&#8221;some unspecified point in the past&#8221;.<\/p>\n<\/td>\n<\/tr>\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"1%\">\n<p>\u2022<\/p>\n<\/td>\n<td width=\"2%\"><\/td>\n<td width=\"86%\">\n<p><b>CLOCK_BOOTTIME<\/b> (and likewise <b>CLOCK_BOOTTIME_ALARM<\/b>), a nonsettable clock that is identical to <b>CLOCK_MONOTONIC<\/b>, except that it also includes any time that the system is suspended.<\/p>\n<\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:11%; margin-top: 1em\">Thus, the processes in a time namespace share per-namespace values for these clocks. This affects various APIs that measure against these clocks, including: <b>clock_gettime<\/b>(2), <b>clock_nanosleep<\/b>(2), <b>nanosleep<\/b>(2), <b>timer_settime<\/b>(2), <b>timerfd_settime<\/b>(2), and <i>\/proc\/uptime<\/i>.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">Currently, the only way to create a time namespace is by calling <b>unshare<\/b>(2) with the <b>CLONE_NEWTIME<\/b> flag. This call creates a new time namespace but does <i>not<\/i> place the calling process in the new namespace. Instead, the calling process\u2019s subsequently created children are placed in the new namespace. This allows clock offsets (see below) for the new namespace to be set before the first process is placed in the namespace. The <i>\/proc\/[pid]\/ns\/time_for_children<\/i> symbolic link shows the time namespace in which the children of a process will be created. (A process can use a file descriptor opened on this symbolic link in a call to <b>setns<\/b>(2) in order to move into the namespace.)<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>\/proc\/PID\/timens_offsets<\/b> <br \/> Associated with each time namespace are offsets, expressed with respect to the initial time namespace, that define the values of the monotonic and boot-time clocks in that namespace. These offsets are exposed via the file <i>\/proc\/PID\/timens_offsets<\/i>. Within this file, the offsets are expressed as lines consisting of three space-delimited fields:<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\"><clock-id> <offset-secs> <offset-nanosecs><\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The <i>clock-id<\/i> is a string that identifies the clock whose offsets are being shown. This field is either <i>monotonic<\/i>, for <b>CLOCK_MONOTONIC<\/b>, or <i>boottime<\/i>, for <b>CLOCK_BOOTTIME<\/b>. The remaining fields express the offset (seconds plus nanoseconds) for the clock in this time namespace. These offsets are expressed relative to the clock values in the initial time namespace. The <i>offset-secs<\/i> value can be negative, subject to restrictions noted below; <i>offset-nanosecs<\/i> is an unsigned value.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">In the initial time namespace, the contents of the <i>timens_offsets<\/i> file are as follows:<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">$ <b>cat \/proc\/self\/timens_offsets<\/b> <br \/> monotonic 0 0 <br \/> boottime 0 0<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">In a new time namespace that has had no member processes, the clock offsets can be modified by writing newline-terminated records of the same form to the <i>timens_offsets<\/i> file. The file can be written to multiple times, but after the first process has been created in or has entered the namespace, <b>write<\/b>(2)s on this file fail with the error <b>EACCES<\/b>. In order to write to the <i>timens_offsets<\/i> file, a process must have the <b>CAP_SYS_TIME<\/b> capability in the user namespace that owns the time namespace.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">Writes to the <i>timens_offsets<\/i> file can fail with the following errors:<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"9%\">\n<p style=\"margin-top: 1em\"><b>EINVAL<\/b><\/p>\n<\/td>\n<td width=\"2%\"><\/td>\n<td width=\"78%\">\n<p style=\"margin-top: 1em\">An <i>offset-nanosecs<\/i> value is greater than 999,999,999.<\/p>\n<\/td>\n<\/tr>\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"9%\">\n<p><b>EINVAL<\/b><\/p>\n<\/td>\n<td width=\"2%\"><\/td>\n<td width=\"78%\">\n<p>A <i>clock-id<\/i> value is not valid.<\/p>\n<\/td>\n<\/tr>\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"9%\">\n<p><b>EPERM<\/b><\/p>\n<\/td>\n<td width=\"2%\"><\/td>\n<td width=\"78%\">\n<p>The caller does not have the <b>CAP_SYS_TIME<\/b> capability.<\/p>\n<\/td>\n<\/tr>\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"9%\">\n<p><b>ERANGE<\/b><\/p>\n<\/td>\n<td width=\"2%\"><\/td>\n<td width=\"78%\">\n<p>An <i>offset-secs<\/i> value is out of range. In particular;<\/p>\n<\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:22%;\">\u2022<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"22%\"><\/td>\n<td width=\"1%\"><\/td>\n<td width=\"2%\"><\/td>\n<td width=\"75%\">\n<p style=\"margin-top: 1em\"><i>offset-secs<\/i> can\u2019t be set to a value which would make the current time on the corresponding clock inside the namespace a negative value; and<\/p>\n<\/td>\n<\/tr>\n<tr valign=\"top\" align=\"left\">\n<td width=\"22%\"><\/td>\n<td width=\"1%\">\n<p>\u2022<\/p>\n<\/td>\n<td width=\"2%\"><\/td>\n<td width=\"75%\">\n<p><i>offset-secs<\/i> can\u2019t be set to a value such that the time on the corresponding clock inside the namespace would exceed half of the value of the kernel constant <b>KTIME_SEC_MAX<\/b> (this limits the clock value to a maximum of approximately 146 years).<\/p>\n<\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:11%; margin-top: 1em\">In a new time namespace created by <b>unshare<\/b>(2), the contents of the <i>timens_offsets<\/i> file are inherited from the time namespace of the creating process.<\/p>\n<h2>NOTES <a name=\"NOTES\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">Use of time namespaces requires a kernel that is configured with the <b>CONFIG_TIME_NS<\/b> option.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">Note that time namespaces do not virtualize the <b>CLOCK_REALTIME<\/b> clock. Virtualization of this clock was avoided for reasons of complexity and overhead within the kernel.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">For compatibility with the initial implementation, when writing a <i>clock-id<\/i> to the <i>\/proc\/[pid]\/timens_offsets<\/i> file, the numerical values of the IDs can be written instead of the symbolic names show above; i.e., 1 instead of <i>monotonic<\/i>, and 7 instead of <i>boottime<\/i>. For redability, the use of the symbolic names over the numbers is preferred.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The motivation for adding time namespaces was to allow the monotonic and boot-time clocks to maintain consistent values during container migration and checkpoint\/restore.<\/p>\n<h2>EXAMPLES <a name=\"EXAMPLES\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">The following shell session demonstrates the operation of time namespaces. We begin by displaying the inode number of the time namespace of a shell in the initial time namespace:<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">$ <b>readlink \/proc\/$$\/ns\/time<\/b> <br \/> time:[4026531834]<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">Continuing in the initial time namespace, we display the system uptime using <b>uptime<\/b>(1) and use the <i>clock_times<\/i> example program shown in <b>clock_getres<\/b>(2) to display the values of various clocks:<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">$ <b>uptime \u2212\u2212pretty<\/b> <br \/> up 21 hours, 17 minutes <br \/> $ <b>.\/clock_times<\/b> <br \/> CLOCK_REALTIME : 1585989401.971 (18356 days + 8h 36m 41s) <br \/> CLOCK_TAI : 1585989438.972 (18356 days + 8h 37m 18s) <br \/> CLOCK_MONOTONIC: 56338.247 (15h 38m 58s) <br \/> CLOCK_BOOTTIME : 76633.544 (21h 17m 13s)<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">We then use <b>unshare<\/b>(1) to create a time namespace and execute a <b>bash<\/b>(1) shell. From the new shell, we use the built-in <b>echo<\/b> command to write records to the <i>timens_offsets<\/i> file adjusting the offset for the <b>CLOCK_MONOTONIC<\/b> clock forward 2 days and the offset for the <b>CLOCK_BOOTTIME<\/b> clock forward 7 days:<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">$ <b>PS1=&#8221;ns2# &#8221; sudo unshare \u2212T \u2212\u2212 bash \u2212\u2212norc<\/b> <br \/> ns2# <b>echo &#8220;monotonic $((2*24*60*60)) 0&#8221; > \/proc\/$$\/timens_offsets<\/b> <br \/> ns2# <b>echo &#8220;boottime $((7*24*60*60)) 0&#8221; > \/proc\/$$\/timens_offsets<\/b><\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">Above, we started the <b>bash<\/b>(1) shell with the <b>\u2212\u2212norc<\/b> options so that no start-up scripts were executed. This ensures that no child processes are created from the shell before we have a chance to update the <i>timens_offsets<\/i> file.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">We then use <b>cat<\/b>(1) to display the contents of the <i>timens_offsets<\/i> file. The execution of <b>cat<\/b>(1) creates the first process in the new time namespace, after which further attempts to update the <i>timens_offsets<\/i> file produce an error.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">ns2# <b>cat \/proc\/$$\/timens_offsets<\/b> <br \/> monotonic 172800 0 <br \/> boottime 604800 0 <br \/> ns2# <b>echo &#8220;boottime $((9*24*60*60)) 0&#8221; > \/proc\/$$\/timens_offsets<\/b> <br \/> bash: echo: write error: Permission denied<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">Continuing in the new namespace, we execute <b>uptime<\/b>(1) and the <i>clock_times<\/i> example program:<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">ns2# <b>uptime \u2212\u2212pretty<\/b> <br \/> up 1 week, 21 hours, 18 minutes <br \/> ns2# <b>.\/clock_times<\/b> <br \/> CLOCK_REALTIME : 1585989457.056 (18356 days + 8h 37m 37s) <br \/> CLOCK_TAI : 1585989494.057 (18356 days + 8h 38m 14s) <br \/> CLOCK_MONOTONIC: 229193.332 (2 days + 15h 39m 53s) <br \/> CLOCK_BOOTTIME : 681488.629 (7 days + 21h 18m 8s)<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">From the above output, we can see that the monotonic and boot-time clocks have different values in the new time namespace.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">Examining the <i>\/proc\/[pid]\/ns\/time<\/i> and <i>\/proc\/[pid]\/ns\/time_for_children<\/i> symbolic links, we see that the shell is a member of the initial time namespace, but its children are created in the new namespace.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">ns2# <b>readlink \/proc\/$$\/ns\/time<\/b> <br \/> time:[4026531834] <br \/> ns2# <b>readlink \/proc\/$$\/ns\/time_for_children<\/b> <br \/> time:[4026532900] <br \/> ns2# <b>readlink \/proc\/self\/ns\/time<\/b> # Creates a child process <br \/> time:[4026532900]<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">Returning to the shell in the initial time namespace, we see that the monotonic and boot-time clocks are unaffected by the <i>timens_offsets<\/i> changes that were made in the other time namespace:<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">$ <b>uptime \u2212\u2212pretty<\/b> <br \/> up 21 hours, 19 minutes <br \/> $ <b>.\/clock_times<\/b> <br \/> CLOCK_REALTIME : 1585989401.971 (18356 days + 8h 38m 51s) <br \/> CLOCK_TAI : 1585989438.972 (18356 days + 8h 39m 28s) <br \/> CLOCK_MONOTONIC: 56338.247 (15h 41m 8s) <br \/> CLOCK_BOOTTIME : 76633.544 (21h 19m 23s)<\/p>\n<h2>SEE ALSO <a name=\"SEE ALSO\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>nsenter<\/b>(1), <b>unshare<\/b>(1), <b>clock_settime<\/b>(2), <b>setns<\/b>(2), <b>unshare<\/b>(2), <b>namespaces<\/b>(7), <b>time<\/b>(7)<\/p>\n<h2>COLOPHON <a name=\"COLOPHON\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">This page is part of release 5.10 of the Linux <i>man-pages<\/i> project. A description of the project, information about reporting bugs, and the latest version of this page, can be found at https:\/\/www.kernel.org\/doc\/man\u2212pages\/.<\/p>\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>  time_namespaces \u2212 overview of Linux time namespaces <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[971],"tags":[973,972,1129],"class_list":["post-4047","post","type-post","status-publish","format-standard","hentry","category-7-miscelanea","tag-973","tag-man7","tag-time_namespaces"],"gutentor_comment":0,"_links":{"self":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/posts\/4047","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/comments?post=4047"}],"version-history":[{"count":0,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/posts\/4047\/revisions"}],"wp:attachment":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/media?parent=4047"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/categories?post=4047"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/tags?post=4047"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}