[PATCH -mm 2/10] unshare system call -v5 : system call handler function

[PATCH -mm 2/10] unshare system call -v5 : system call handler function

Post by JANAK DESA » Fri, 13 Jan 2006 13:20:16


PATCH -mm 2/10] unshare system call: system call handler function

sys_unshare system call handler function accepts the same flags as
clone system call, checks constraints on each of the flags and invokes
corresponding unshare functions to disassociate respective process
context if it was being shared with another task.

Changes since the -v4 submitted on 12/13/05:
- none

Signed-off-by: Janak Desai < XXXX@XXXXX.COM >

---

fork.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 232 insertions(+)

diff -Naurp 2.6.15-mm3/kernel/fork.c 2.6.15-mm3+unsh-base/kernel/fork.c
--- 2.6.15-mm3/kernel/fork.c 2006-01-11 20:22:20.000000000 +0000
+++ 2.6.15-mm3+unsh-base/kernel/fork.c 2006-01-11 22:46:49.000000000 +0000
@@ -1323,3 +1323,235 @@ void __init proc_caches_init(void)
sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
}
+
+
+/*
+ * Check constraints on flags passed to the unshare system call and
+ * force unsharing of additional process context as appropriate.
+ */
+static inline void check_unshare_flags(unsigned long *flags_ptr)
+{
+ /*
+ * If unsharing a thread from a thread group, must also
+ * unshare vm.
+ */
+ if (*flags_ptr & CLONE_THREAD)
+ *flags_ptr |= CLONE_VM;
+
+ /*
+ * If unsharing vm, must also unshare signal handlers.
+ */
+ if (*flags_ptr & CLONE_VM)
+ *flags_ptr |= CLONE_SIGHAND;
+
+ /*
+ * If unsharing signal handlers and the task was created
+ * using CLONE_THREAD, then must unshare the thread
+ */
+ if ((*flags_ptr & CLONE_SIGHAND) &&
+ (atomic_read(¤t->signal->count) > 1))
+ *flags_ptr |= CLONE_THREAD;
+
+ /*
+ * If unsharing namespace, must also unshare filesystem information.
+ */
+ if (*flags_ptr & CLONE_NEWNS)
+ *flags_ptr |= CLONE_FS;
+}
+
+/*
+ * Unsharing of tasks created with CLONE_THREAD is not supported yet
+ */
+static int unshare_thread(unsigned long unshare_flags)
+{
+ if (unshare_flags & CLONE_THREAD)
+ return -EINVAL;
+
+ return 0;
+}
+
+/*
+ * Unsharing of fs info for tasks created with CLONE_FS is not supported yet
+ */
+static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
+{
+ struct fs_struct *fs = current->fs;
+
+ if ((unshare_flags & CLONE_FS) &&
+ (fs && atomic_read(&fs->count) > 1))
+ return -EINVAL;
+
+ return 0;
+}
+
+/*
+ * Unsharing of namespace for tasks created without CLONE_NEWNS is not
+ * supported yet
+ */
+static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp)
+{
+ struct namespace *ns = current->namespace;
+
+ if ((unshare_flags & CLONE_NEWNS) &&
+ (ns && atomic_read(&ns->count) > 1))
+ return -EINVAL;
+
+ return 0;
+}
+
+/*
+ * Unsharing of sighand for tasks created with CLONE_SIGHAND is not
+ * supported yet
+ */
+static int unshare_sighand(unsigned long unshare_flags, struct sighand_struct **new_sighp)
+{
+ struct sighand_struct *sigh = current->sighand;
+
+ if ((unshare_flags & CLONE_SIGHAND) &&
+ (sigh && atomic_read(&sigh->count) > 1))
+ return -EINVAL;
+ else
+ return 0;
+}
+
+/*
+ * Unsharing of vm for tasks created with CLONE_VM is not supported yet
+ */
+static int unshare_vm(unsigned long unshare_flags, struct mm_struct **new_mmp)
+{
+ struct mm_struct *mm = current->mm;
+
+ if ((unshare_flags & CLONE_VM) &&
+ (mm