diff -NurpP linux-2.6.17.7-vs2.1.1-rc27.7/drivers/block/loop.c linux-2.6.17.7-vs2.1.1-rc28/drivers/block/loop.c
--- linux-2.6.17.7-vs2.1.1-rc27.7/drivers/block/loop.c	2006-07-29 01:36:13 +0200
+++ linux-2.6.17.7-vs2.1.1-rc28/drivers/block/loop.c	2006-08-04 19:59:58 +0200
@@ -819,6 +819,7 @@ static int loop_set_fd(struct loop_devic
 	lo->lo_blocksize = lo_blocksize;
 	lo->lo_device = bdev;
 	lo->lo_flags = lo_flags;
+	lo->lo_xid = vx_current_xid();
 	lo->lo_backing_file = file;
 	lo->transfer = NULL;
 	lo->ioctl = NULL;
@@ -928,6 +929,7 @@ static int loop_clr_fd(struct loop_devic
 	lo->lo_sizelimit = 0;
 	lo->lo_encrypt_key_size = 0;
 	lo->lo_flags = 0;
+	lo->lo_xid = 0;
 	memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
 	memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
 	memset(lo->lo_file_name, 0, LO_NAME_SIZE);
@@ -1184,6 +1186,9 @@ static int lo_open(struct inode *inode, 
 {
 	struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
 
+	if (!vx_check(lo->lo_xid, VX_IDENT))
+		return -EACCES;
+
 	mutex_lock(&lo->lo_ctl_mutex);
 	lo->lo_refcnt++;
 	mutex_unlock(&lo->lo_ctl_mutex);
diff -NurpP linux-2.6.17.7-vs2.1.1-rc27.7/drivers/md/dm.c linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.c
--- linux-2.6.17.7-vs2.1.1-rc27.7/drivers/md/dm.c	2006-06-18 04:53:11 +0200
+++ linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.c	2006-08-04 20:44:02 +0200
@@ -66,6 +66,7 @@ struct mapped_device {
 	struct semaphore suspend_lock;
 	rwlock_t map_lock;
 	atomic_t holders;
+	xid_t xid;
 
 	unsigned long flags;
 
@@ -219,6 +220,8 @@ static int dm_blk_open(struct inode *ino
 	struct mapped_device *md;
 
 	md = inode->i_bdev->bd_disk->private_data;
+	if (!vx_check(md->xid, VX_IDENT))
+		return -EACCES;
 	dm_get(md);
 	return 0;
 }
@@ -850,6 +853,7 @@ static struct mapped_device *alloc_dev(u
 	rwlock_init(&md->map_lock);
 	atomic_set(&md->holders, 1);
 	atomic_set(&md->event_nr, 0);
+	md->xid = vx_current_xid();
 
 	md->queue = blk_alloc_queue(GFP_KERNEL);
 	if (!md->queue)
diff -NurpP linux-2.6.17.7-vs2.1.1-rc27.7/include/linux/loop.h linux-2.6.17.7-vs2.1.1-rc28/include/linux/loop.h
--- linux-2.6.17.7-vs2.1.1-rc27.7/include/linux/loop.h	2006-06-18 04:55:19 +0200
+++ linux-2.6.17.7-vs2.1.1-rc28/include/linux/loop.h	2006-08-04 20:07:26 +0200
@@ -45,6 +45,7 @@ struct loop_device {
 	struct loop_func_table *lo_encryption;
 	__u32           lo_init[2];
 	uid_t		lo_key_owner;	/* Who set the key */
+	xid_t		lo_xid;
 	int		(*ioctl)(struct loop_device *, int cmd, 
 				 unsigned long arg); 
 
diff -u linux-2.6.17.7-vs2.1.1-rc28.1/drivers/block/loop.c linux-2.6.17.7-vs2.1.1-rc28.1/drivers/block/loop.c
--- linux-2.6.17.7-vs2.1.1-rc28.1/drivers/block/loop.c	2006-08-06 06:10:42 +0200
+++ linux-2.6.17.7-vs2.1.1-rc28.1/drivers/block/loop.c	2006-08-06 06:10:42 +0200
@@ -951,7 +951,7 @@
 	struct loop_func_table *xfer;
 
 	if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
-	    !capable(CAP_SYS_ADMIN))
+	    !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
 		return -EPERM;
 	if (lo->lo_state != Lo_bound)
 		return -ENXIO;
@@ -1031,7 +1031,8 @@
 	memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
 	info->lo_encrypt_type =
 		lo->lo_encryption ? lo->lo_encryption->number : 0;
-	if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
+	if (lo->lo_encrypt_key_size &&
+		vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
 		info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
 		memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
 		       lo->lo_encrypt_key_size);
diff -NurpP --minimal linux-2.6.17.7-vs2.1.1-rc28/include/linux/vserver/context.h linux-2.6.17.7-vs2.1.1-rc28.1/include/linux/vserver/context.h
--- linux-2.6.17.7-vs2.1.1-rc28/include/linux/vserver/context.h	2006-07-30 16:50:15 +0200
+++ linux-2.6.17.7-vs2.1.1-rc28.1/include/linux/vserver/context.h	2006-08-06 05:52:41 +0200
@@ -78,6 +78,8 @@
 #define VXC_BINARY_MOUNT	0x00040000
 
 #define VXC_QUOTA_CTL		0x00100000
+#define VXC_ADMIN_MAPPER	0x00200000
+#define VXC_ADMIN_CLOOP		0x00400000
 
 
 /* context state changes */
diff -NurpP --minimal linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.c linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm.c
--- linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.c	2006-08-04 20:44:02 +0200
+++ linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm.c	2006-08-06 06:14:06 +0200
@@ -355,6 +355,14 @@ int dm_set_geometry(struct mapped_device
 	return 0;
 }
 
+/*
+ * Get the xid associated with a dm device
+ */
+xid_t dm_get_xid(struct mapped_device *md)
+{
+	return md->xid;
+}
+
 /*-----------------------------------------------------------------
  * CRUD START:
  *   A more elegant soln is in the works that uses the queue
diff -NurpP --minimal linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.h linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm.h
--- linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm.h	2006-06-18 04:53:11 +0200
+++ linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm.h	2006-08-06 05:21:14 +0200
@@ -92,6 +92,8 @@ int dm_suspended(struct mapped_device *m
 int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo);
 int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo);
 
+xid_t dm_get_xid(struct mapped_device *md);
+
 /*-----------------------------------------------------------------
  * Functions for manipulating a table.  Tables are also reference
  * counted.
diff -NurpP --minimal linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm-ioctl.c linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm-ioctl.c
--- linux-2.6.17.7-vs2.1.1-rc28/drivers/md/dm-ioctl.c	2006-06-18 04:53:10 +0200
+++ linux-2.6.17.7-vs2.1.1-rc28.1/drivers/md/dm-ioctl.c	2006-08-06 06:13:41 +0200
@@ -102,7 +102,8 @@ static struct hash_cell *__get_name_cell
 	unsigned int h = hash_str(str);
 
 	list_for_each_entry (hc, _name_buckets + h, name_list)
-		if (!strcmp(hc->name, str))
+		if (vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT) &&
+			!strcmp(hc->name, str))
 			return hc;
 
 	return NULL;
@@ -114,7 +115,8 @@ static struct hash_cell *__get_uuid_cell
 	unsigned int h = hash_str(str);
 
 	list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
-		if (!strcmp(hc->uuid, str))
+		if (vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT) &&
+			!strcmp(hc->uuid, str))
 			return hc;
 
 	return NULL;
@@ -344,6 +346,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl 
 
 static int remove_all(struct dm_ioctl *param, size_t param_size)
 {
+	if (!vx_check(0, VX_ADMIN))
+		return -EPERM;
+
 	dm_hash_remove_all();
 	param->data_size = 0;
 	return 0;
@@ -391,6 +396,8 @@ static int list_devices(struct dm_ioctl 
 	 */
 	for (i = 0; i < NUM_BUCKETS; i++) {
 		list_for_each_entry (hc, _name_buckets + i, name_list) {
+			if (!vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT))
+				continue;
 			needed += sizeof(struct dm_name_list);
 			needed += strlen(hc->name) + 1;
 			needed += ALIGN_MASK;
@@ -414,6 +421,8 @@ static int list_devices(struct dm_ioctl 
 	 */
 	for (i = 0; i < NUM_BUCKETS; i++) {
 		list_for_each_entry (hc, _name_buckets + i, name_list) {
+			if (!vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT))
+				continue;
 			if (old_nl)
 				old_nl->next = (uint32_t) ((void *) nl -
 							   (void *) old_nl);
@@ -1390,8 +1399,8 @@ static int ctl_ioctl(struct inode *inode
 	ioctl_fn fn = NULL;
 	size_t param_size;
 
-	/* only root can play with this */
-	if (!capable(CAP_SYS_ADMIN))
+	/* only root and certain contexts can play with this */
+	if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
 		return -EACCES;
 
 	if (_IOC_TYPE(command) != DM_IOCTL)