From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751952AbdAXBHq (ORCPT ); Mon, 23 Jan 2017 20:07:46 -0500 Received: from out02.mta.xmission.com ([166.70.13.232]:44808 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751113AbdAXBHm (ORCPT ); Mon, 23 Jan 2017 20:07:42 -0500 From: ebiederm@xmission.com (Eric W. Biederman) To: Andrei Vagin Cc: Alexander Viro , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, Ram Pai References: <1485214628-23812-1-git-send-email-avagin@openvz.org> Date: Tue, 24 Jan 2017 14:03:23 +1300 In-Reply-To: <1485214628-23812-1-git-send-email-avagin@openvz.org> (Andrei Vagin's message of "Mon, 23 Jan 2017 15:37:08 -0800") Message-ID: <87wpdlz2uc.fsf@xmission.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-XM-SPF: eid=1cVpaA-0007S1-Qm;;;mid=<87wpdlz2uc.fsf@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=101.100.131.98;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1+YA/ZwKzxUr0HzHAas3E73D0A8ry1RxrM= X-SA-Exim-Connect-IP: 101.100.131.98 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Report: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP * 0.7 XMSubLong Long Subject * 0.0 T_TM2_M_HEADER_IN_MSG BODY: No description available. * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa02 1397; Body=1 Fuz1=1 Fuz2=1] * 0.1 XMSolicitRefs_0 Weightloss drug X-Spam-DCC: XMission; sa02 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: ;Andrei Vagin X-Spam-Relay-Country: X-Spam-Timing: total 5763 ms - load_scoreonly_sql: 0.06 (0.0%), signal_user_changed: 4.8 (0.1%), b_tie_ro: 3.7 (0.1%), parse: 1.41 (0.0%), extract_message_metadata: 39 (0.7%), get_uri_detail_list: 6 (0.1%), tests_pri_-1000: 18 (0.3%), tests_pri_-950: 2.1 (0.0%), tests_pri_-900: 1.73 (0.0%), tests_pri_-400: 44 (0.8%), check_bayes: 42 (0.7%), b_tokenize: 17 (0.3%), b_tok_get_all: 11 (0.2%), b_comp_prob: 5 (0.1%), b_tok_touch_all: 4.1 (0.1%), b_finish: 0.91 (0.0%), tests_pri_0: 742 (12.9%), check_dkim_signature: 0.96 (0.0%), check_dkim_adsp: 4.7 (0.1%), tests_pri_500: 4904 (85.1%), poll_dns_idle: 4895 (84.9%), rewrite_mail: 0.00 (0.0%) Subject: Re: [PATCH] mnt: allow to add a mount into an existing group X-Spam-Flag: No X-SA-Exim-Version: 4.2.1 (built Thu, 05 May 2016 13:38:54 -0600) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Andrei Vagin writes: > Now a shared group can be only inherited from a source mount. > This patch adds an ability to add a mount into an existing shared > group. This sounds like a lot of the discussion on bind mounts accross namespaces. I am going to stay out of this for a bit until we resolve my latest patch. Eric > mount(source, target, NULL, MS_SET_GROUP, NULL) > > mount() with the MS_SET_GROUP flag adds the "target" mount into a group > of the "source" mount. The calling process has to have the CAP_SYS_ADMIN > capability in namespaces of these mounts. The source and the target > mounts have to have the same super block. > > This new functionality together with "mnt: Tuck mounts under others > instead of creating shadow/side mounts." allows CRIU to dump and restore > any set of mount namespaces. > > Currently we have a lot of issues about dumping and restoring mount > namespaces. The bigest problem is that we can't construct mount trees > directly due to several reasons: > * groups can't be set, they can be only inherited > * file systems has to be mounted from the specified user namespaces > * the mount() syscall doesn't just create one mount -- the mount is > also propagated to all members of a parent group > * umount() doesn't detach mounts from all members of a group > (mounts with children are not umounted) > * mounts are propagated underneath of existing mounts > * mount() doesn't allow to make bind-mounts between two namespaces > * processes can have opened file descriptors to overmounted files > > All these operations are non-trivial, making the task of restoring > a mount namespace practically unsolvable for reasonable time. The > proposed change allows to restore a mount namespace in a direct > manner, without any super complex logic. > > Cc: Eric W. Biederman > Cc: Alexander Viro > Signed-off-by: Andrei Vagin > --- > fs/namespace.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ > include/uapi/linux/fs.h | 1 + > 2 files changed, 54 insertions(+) > > diff --git a/fs/namespace.c b/fs/namespace.c > index b5b1259..df52fd4 100644 > --- a/fs/namespace.c > +++ b/fs/namespace.c > @@ -2301,6 +2301,57 @@ static inline int tree_contains_unbindable(struct mount *mnt) > return 0; > } > > +static int do_set_group(struct path *path, const char *sibling_name) > +{ > + struct mount *sibling, *mnt; > + struct path sibling_path; > + int err; > + > + if (!sibling_name || !*sibling_name) > + return -EINVAL; > + > + err = kern_path(sibling_name, LOOKUP_FOLLOW, &sibling_path); > + if (err) > + return err; > + > + sibling = real_mount(sibling_path.mnt); > + mnt = real_mount(path->mnt); > + > + namespace_lock(); > + > + err = -EPERM; > + if (!sibling->mnt_ns || > + !ns_capable(sibling->mnt_ns->user_ns, CAP_SYS_ADMIN)) > + goto out_unlock; > + > + err = -EINVAL; > + if (sibling->mnt.mnt_sb != mnt->mnt.mnt_sb) > + goto out_unlock; > + > + if (IS_MNT_SHARED(mnt) || IS_MNT_SLAVE(mnt)) > + goto out_unlock; > + > + if (IS_MNT_SLAVE(sibling)) { > + struct mount *m = sibling->mnt_master; > + > + list_add(&mnt->mnt_slave, &m->mnt_slave_list); > + mnt->mnt_master = m; > + } > + > + if (IS_MNT_SHARED(sibling)) { > + mnt->mnt_group_id = sibling->mnt_group_id; > + list_add(&mnt->mnt_share, &sibling->mnt_share); > + set_mnt_shared(mnt); > + } > + > + err = 0; > +out_unlock: > + namespace_unlock(); > + > + path_put(&sibling_path); > + return err; > +} > + > static int do_move_mount(struct path *path, const char *old_name) > { > struct path old_path, parent_path; > @@ -2779,6 +2830,8 @@ long do_mount(const char *dev_name, const char __user *dir_name, > retval = do_change_type(&path, flags); > else if (flags & MS_MOVE) > retval = do_move_mount(&path, dev_name); > + else if (flags & MS_SET_GROUP) > + retval = do_set_group(&path, dev_name); > else > retval = do_new_mount(&path, type_page, flags, mnt_flags, > dev_name, data_page); > diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h > index 36da93f..6e6e37d 100644 > --- a/include/uapi/linux/fs.h > +++ b/include/uapi/linux/fs.h > @@ -130,6 +130,7 @@ struct inodes_stat_t { > #define MS_I_VERSION (1<<23) /* Update inode I_version field */ > #define MS_STRICTATIME (1<<24) /* Always perform atime updates */ > #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ > +#define MS_SET_GROUP (1<<26) /* Add a mount into a shared group */ > > /* These sb flags are internal to the kernel */ > #define MS_NOREMOTELOCK (1<<27)