2 * linux/kernel/vserver/namespace.c
4 * Virtual Server: Context Namespace Support
6 * Copyright (C) 2003-2004 Herbert Pötzl
8 * V0.01 broken out from context.c 0.07
9 * V0.02 added task locking for namespace
13 #include <linux/config.h>
14 #include <linux/utsname.h>
15 #include <linux/vserver/namespace.h>
16 #include <linux/vs_base.h>
17 #include <linux/vs_context.h>
18 #include <linux/namespace.h>
19 #include <linux/dcache.h>
22 #include <asm/errno.h>
23 #include <asm/uaccess.h>
26 int vx_check_vfsmount(struct vx_info *vxi, struct vfsmount *mnt)
28 struct vfsmount *root_mnt, *altroot_mnt;
29 struct dentry *root, *altroot, *point;
30 int r1, r2, s1, s2, ret = 0;
35 spin_lock(&dcache_lock);
36 altroot_mnt = current->fs->rootmnt;
37 altroot = current->fs->root;
41 root_mnt = vxi->vx_fs->rootmnt;
42 root = vxi->vx_fs->root;
44 root_mnt = altroot_mnt;
47 /* printk("··· %p:%p/%p:%p ",
48 root_mnt, root, altroot_mnt, altroot); */
50 while ((mnt != mnt->mnt_parent) &&
51 (mnt != root_mnt) && (mnt != altroot_mnt)) {
52 point = mnt->mnt_mountpoint;
53 mnt = mnt->mnt_parent;
56 r1 = (mnt == root_mnt);
57 s1 = is_subdir(point, root);
58 r2 = (mnt == altroot_mnt);
59 s2 = is_subdir(point, altroot);
61 ret = (((mnt == root_mnt) && is_subdir(point, root)) ||
62 ((mnt == altroot_mnt) && is_subdir(point, altroot)));
63 /* printk("··· for %p:%p -> %d:%d/%d:%d = %d\n",
64 mnt, point, r1, s1, r2, s2, ret); */
65 spin_unlock(&dcache_lock);
71 /* virtual host info names */
73 static char * vx_vhi_name(struct vx_info *vxi, int id)
79 return vxi->cvirt.utsname.sysname;
81 return vxi->cvirt.utsname.nodename;
83 return vxi->cvirt.utsname.release;
85 return vxi->cvirt.utsname.version;
87 return vxi->cvirt.utsname.machine;
89 return vxi->cvirt.utsname.domainname;
96 int vc_set_vhi_name(uint32_t id, void __user *data)
99 struct vcmd_vx_vhi_name_v0 vc_data;
102 if (!capable(CAP_SYS_ADMIN))
104 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
107 vxi = locate_vx_info(id);
111 name = vx_vhi_name(vxi, vc_data.field);
113 memcpy(name, vc_data.name, 65);
115 return (name ? 0 : -EFAULT);
118 int vc_get_vhi_name(uint32_t id, void __user *data)
121 struct vcmd_vx_vhi_name_v0 vc_data;
124 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
127 vxi = locate_vx_info(id);
131 name = vx_vhi_name(vxi, vc_data.field);
135 memcpy(vc_data.name, name, 65);
136 if (copy_to_user (data, &vc_data, sizeof(vc_data)))
140 return (name ? 0 : -EFAULT);
143 /* namespace functions */
145 #include <linux/namespace.h>
147 int vx_set_namespace(struct vx_info *vxi, struct namespace *ns, struct fs_struct *fs)
149 struct fs_struct *fs_copy;
151 if (vxi->vx_namespace)
156 fs_copy = copy_fs_struct(fs);
161 vxi->vx_namespace = ns;
162 vxi->vx_fs = fs_copy;
166 int vc_enter_namespace(uint32_t id, void *data)
169 struct fs_struct *old_fs, *fs;
170 struct namespace *old_ns;
173 if (!vx_check(0, VX_ADMIN))
176 vxi = locate_vx_info(id);
181 if (!vxi->vx_namespace)
185 fs = copy_fs_struct(vxi->vx_fs);
191 old_ns = current->namespace;
192 old_fs = current->fs;
193 get_namespace(vxi->vx_namespace);
194 current->namespace = vxi->vx_namespace;
196 task_unlock(current);
198 put_namespace(old_ns);
199 put_fs_struct(old_fs);
205 int vc_cleanup_namespace(uint32_t id, void *data)
207 down_write(¤t->namespace->sem);
208 spin_lock(&vfsmount_lock);
209 umount_unused(current->namespace->root, current->fs);
210 spin_unlock(&vfsmount_lock);
211 up_write(¤t->namespace->sem);
215 int vc_set_namespace(uint32_t id, void __user *data)
217 struct fs_struct *fs;
218 struct namespace *ns;
222 if (vx_check(0, VX_ADMIN|VX_WATCH))
226 vxi = get_vx_info(current->vx_info);
228 atomic_inc(&fs->count);
229 ns = current->namespace;
230 get_namespace(current->namespace);
231 task_unlock(current);
233 ret = vx_set_namespace(vxi, ns, fs);