Re: [PATCHv6 01/36] ns: Introduce Time Namespace
From: Thomas Gleixner <hidden>
Date: 2019-08-16 06:35:03
Also in:
lkml
Andrei, On Thu, 15 Aug 2019, Andrei Vagin wrote:
On Thu, Aug 15, 2019 at 07:19:12PM +0200, Thomas Gleixner wrote:quoted
quoted
+static int timens_install(struct nsproxy *nsproxy, struct ns_common *new) +{ + struct time_namespace *ns = to_time_ns(new); + + if (!current_is_single_threaded()) + return -EUSERS; + + if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) || + !ns_capable(current_user_ns(), CAP_SYS_ADMIN)) + return -EPERM; + + get_time_ns(ns); + get_time_ns(ns);Why is this a double get?Because we change nsproxy->time_ns and nsproxy->time_ns_for_children. Probably, I need to reorgonize the code this way: get_time_ns(ns); put_time_ns(nsproxy->time_ns); nsproxy->time_ns = ns; get_time_ns(ns); put_time_ns(nsproxy->time_ns_for_children); nsproxy->time_ns_for_children = ns;
That's better. A few comments about refcounting might be useful as well.
quoted
quoted
+ put_time_ns(nsproxy->time_ns); + put_time_ns(nsproxy->time_ns_for_children); + nsproxy->time_ns = ns; + nsproxy->time_ns_for_children = ns; + ns->initialized = true; + return 0; +} + +int timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk) +{ + struct ns_common *nsc = &nsproxy->time_ns_for_children->ns; + struct time_namespace *ns = to_time_ns(nsc); + + if (nsproxy->time_ns == nsproxy->time_ns_for_children) + return 0;
Doesn't this need to take a refcount on fork? Maybe not, but see below.
quoted
quoted
+ + get_time_ns(ns); + put_time_ns(nsproxy->time_ns); + nsproxy->time_ns = ns; + ns->initialized = true;Isn't that one initialized already?When we discussed time namespaces last year, we decided that clock offsets can be set only before any task enters a namespace. When a namespace is created, ns->initialized is set to false. When a task enters the namespace, ns->initialized is set to true.
Right. I'm probably just hopelessly confused by this nsproxy->time_ns vs. nsproxy->time_ns_for_children->ns thing.
Namespace clock offsets can be changed only if ns->initialized is false. A new task can be forked to a specified time namespace or it can call setns, so we set ns->initialized to true in timens_on_fork and timens_install.
Some comments explaining that logic above would be really helpful. Thanks, tglx