[CRIU] [PATCH v2 18/30] files: Choose file master with enough permissions
Andrei Vagin
avagin at virtuozzo.com
Thu Jun 15 09:32:48 MSK 2017
On Wed, Jun 07, 2017 at 02:28:53PM +0300, Kirill Tkhai wrote:
> 1)Find such fle, and link it at the beginning of list.
> 2)Order by pid, where possible, if it does not contradict (1)
Why do we need to order by pid?
> 3)If there is no a master, leave fdesc in fake_master_head.
>
> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
> criu/files.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 42 insertions(+), 1 deletion(-)
>
> diff --git a/criu/files.c b/criu/files.c
> index a46dcf330..a2b57ca01 100644
> --- a/criu/files.c
> +++ b/criu/files.c
> @@ -84,6 +84,13 @@ int file_desc_add(struct file_desc *d, u32 id, struct file_desc_ops *ops)
> hlist_add_head(&d->hash, &file_desc_hash[id % FDESC_HASH_SIZE]);
> if (d->ops->get_user_ns) {
> d->ops->get_user_ns(d, &file_user_ns, &d->setns_userns);
> + /*
> + * Hash file_desc in the fake_master_list. Later it will
> + * be removed in collect_desc_fle() from there, if a fle
> + * with enough permissions is found.
> + */
> + if (d->setns_userns)
> + list_add(&d->fake_master_list, &fake_master_head);
> }
> return 0; /* this is to make tail-calls in collect_one_foo look nice */
> }
> @@ -717,12 +724,46 @@ static struct fdinfo_list_entry *alloc_fle(int pid, FdinfoEntry *fe)
> static void collect_desc_fle(struct fdinfo_list_entry *new_le, struct file_desc *fdesc)
> {
> struct fdinfo_list_entry *le;
> + struct ns_id *task_ns = NULL;
> + bool first = true;
>
> new_le->desc = fdesc;
>
> - list_for_each_entry(le, &fdesc->fd_info_head, desc_list)
> + /*
> + * First fle in fdesc->fd_info_head list (i.e., master)
> + * must have enough permissions to restore file.
> + * Sort the rest of list and cases by pid if it's possible.
> + */
> + list_for_each_entry(le, &fdesc->fd_info_head, desc_list) {
> + if (!fdesc->setns_userns || !first ||
> + le->task->ids->user_ns_id == new_le->task->ids->user_ns_id)
> + goto compare_pid;
> +
> + task_ns = lookup_ns_by_id(new_le->task->ids->user_ns_id, &user_ns_desc);
> + if (is_subns(fdesc->setns_userns, task_ns))
> + break;
> + task_ns = NULL;
> +
> + if (list_empty(&fdesc->fake_master_list)) {
> + /* Current master has perms, leave it on the place */
> + first = false;
> + continue;
> + }
> +compare_pid:
> if (pid_rst_prio(new_le->pid, le->pid))
> break;
> + first = false;
> + }
> +
> + if (fdesc->setns_userns && list_empty(&fdesc->fd_info_head)) {
> + /* First fle is hashing */
> + task_ns = lookup_ns_by_id(new_le->task->ids->user_ns_id, &user_ns_desc);
> + if (!is_subns(fdesc->setns_userns, task_ns))
> + task_ns = NULL;
> + }
> + if (task_ns)
> + list_del_init(&fdesc->fake_master_list);
> +
> list_add_tail(&new_le->desc_list, &le->desc_list);
> }
>
>
More information about the CRIU
mailing list