[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Reads from read only parent disk images are intercepted, and are used to detect



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1261031277 0
# Node ID 617071a8c6387a5414e22869cce585811ae27e77
# Parent  d3b569b2a2b9ba13d458acf58ef4e953808074c4
Reads from read only parent disk images are intercepted, and are used to detect
potentially sharable memory pages.

Signed-off-by: Grzegorz Milos <Grzegorz.Milos@xxxxxxxxxx>
---
 tools/blktap2/drivers/Makefile      |    3 -
 tools/blktap2/drivers/tapdisk-vbd.c |   52 +++++++++++++++++++-
 tools/blktap2/drivers/tapdisk.h     |    2 
 tools/memshr/interface.c            |   91 +++++++++++++++++++++++++++++++++++-
 tools/memshr/memshr.h               |   13 +++++
 5 files changed, 156 insertions(+), 5 deletions(-)

diff -r d3b569b2a2b9 -r 617071a8c638 tools/blktap2/drivers/Makefile
--- a/tools/blktap2/drivers/Makefile    Thu Dec 17 06:27:57 2009 +0000
+++ b/tools/blktap2/drivers/Makefile    Thu Dec 17 06:27:57 2009 +0000
@@ -14,6 +14,7 @@ CFLAGS    += -fno-strict-aliasing
 CFLAGS    += -fno-strict-aliasing
 CFLAGS    += -I../lib -I../../libxc
 CFLAGS    += -I../include -I../../include
+CFLAGS    += $(CFLAGS_libxenctrl)
 CFLAGS    += -I $(LIBAIO_DIR)
 CFLAGS    += -I $(MEMSHR_DIR)
 CFLAGS    += -D_GNU_SOURCE
@@ -37,7 +38,7 @@ CRYPT_LIB += -lcrypto
 CRYPT_LIB += -lcrypto
 endif
 
-LDFLAGS_img := $(CRYPT_LIB) -lpthread -lz -lm
+LDFLAGS_img := $(LDFLAGS_libxenctrl) $(CRYPT_LIB) -lpthread -lz -lm
 
 LIBS += -L$(LIBVHDDIR) -lvhd
 
diff -r d3b569b2a2b9 -r 617071a8c638 tools/blktap2/drivers/tapdisk-vbd.c
--- a/tools/blktap2/drivers/tapdisk-vbd.c       Thu Dec 17 06:27:57 2009 +0000
+++ b/tools/blktap2/drivers/tapdisk-vbd.c       Thu Dec 17 06:27:57 2009 +0000
@@ -1418,11 +1418,26 @@ tapdisk_vbd_complete_vbd_request(td_vbd_
        }
 }
 
+static uint64_t 
+tapdisk_vbd_breq_get_sector(blkif_request_t *breq, td_request_t treq)
+{
+    int seg, nsects; 
+    uint64_t sector_nr = breq->sector_number; 
+    
+    for(seg=0; seg < treq.sidx; seg++) {
+        nsects = breq->seg[seg].last_sect - breq->seg[seg].first_sect + 1;
+        sector_nr += nsects;
+    }
+
+    return sector_nr;
+}
+
 static void
 __tapdisk_vbd_complete_td_request(td_vbd_t *vbd, td_vbd_request_t *vreq,
                                  td_request_t treq, int res)
 {
        int err;
+    td_image_t *image = treq.image;
 
        err = (res <= 0 ? res : -res);
        vbd->secs_pending  -= treq.secs;
@@ -1440,7 +1455,18 @@ __tapdisk_vbd_complete_td_request(td_vbd
                            (treq.op == TD_OP_WRITE ? "write" : "read"),
                            treq.secs, treq.sec);
                }
-       }
+       } else 
+    if(treq.op == TD_OP_READ && td_flag_test(image->flags, TD_OPEN_RDONLY)) {
+        uint64_t         hnd  = treq.memshr_hnd;
+        uint16_t         uid  = image->memshr_id;
+        blkif_request_t *breq = &vreq->req;
+        uint64_t         sec  = tapdisk_vbd_breq_get_sector(breq, treq);
+        int              secs = breq->seg[treq.sidx].last_sect -
+                                breq->seg[treq.sidx].first_sect + 1;
+
+        if(hnd != 0)
+            memshr_vbd_complete_ro_request(hnd, uid, sec, secs);
+    }
 
        tapdisk_vbd_complete_vbd_request(vbd, vreq);
 }
@@ -1492,7 +1518,29 @@ __tapdisk_vbd_reissue_td_request(td_vbd_
                break;
 
        case TD_OP_READ:
-               td_queue_read(parent, treq);
+        if(td_flag_test(parent->flags, TD_OPEN_RDONLY))
+        {
+            int ret, seg = treq.sidx;
+            blkif_request_t *breq = &vreq->req;
+        
+            ret = memshr_vbd_issue_ro_request(treq.buf,
+                                              breq->seg[seg].gref,
+                                              parent->memshr_id,
+                                              treq.sec,
+                                              treq.secs,
+                                              &treq.memshr_hnd);
+            if(ret == 0)
+            {
+                /* Reset memshr handle. This'll prevent
+                 * memshr_vbd_complete_ro_request being called */
+                treq.memshr_hnd = 0;
+                td_complete_request(treq, 0);
+            }
+            else
+                       td_queue_read(parent, treq);
+        }
+        else
+                   td_queue_read(parent, treq);
                break;
        }
 
diff -r d3b569b2a2b9 -r 617071a8c638 tools/blktap2/drivers/tapdisk.h
--- a/tools/blktap2/drivers/tapdisk.h   Thu Dec 17 06:27:57 2009 +0000
+++ b/tools/blktap2/drivers/tapdisk.h   Thu Dec 17 06:27:57 2009 +0000
@@ -131,6 +131,8 @@ struct td_request {
        uint64_t                     id;
        int                          sidx;
        void                        *private;
+    
+    uint64_t                     memshr_hnd;
 };
 
 /* 
diff -r d3b569b2a2b9 -r 617071a8c638 tools/memshr/interface.c
--- a/tools/memshr/interface.c  Thu Dec 17 06:27:57 2009 +0000
+++ b/tools/memshr/interface.c  Thu Dec 17 06:27:57 2009 +0000
@@ -17,13 +17,17 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <string.h>
-
+#include <inttypes.h>
+
+#include "memshr.h"
 #include "memshr-priv.h"
+#include "bidir-hash.h"
 #include "shm.h"
 
 typedef struct {
     int     enabled;
     domid_t domid;
+    int     xc_handle;
 } memshr_vbd_info_t;
 
 memshr_vbd_info_t vbd_info = {0, DOMID_INVALID};
@@ -74,6 +78,8 @@ void memshr_daemon_initialize(void)
 
 void memshr_vbd_initialize(void)
 {
+    int xc_handle;
+
     memset(&memshr, 0, sizeof(private_memshr_info_t));
 
     if((SHARED_INFO = shm_shared_info_open(0)) == NULL)
@@ -103,6 +109,13 @@ void memshr_vbd_initialize(void)
     if(vbd_info.domid == DOMID_INVALID)
         return;
 
+    if((xc_handle = xc_interface_open()) < 0)
+    {
+        DPRINTF("Failed to open XC interface.\n");
+        return;
+    }
+
+    vbd_info.xc_handle = xc_handle;
     vbd_info.enabled = 1;
 }
 
@@ -125,4 +138,78 @@ void memshr_vbd_image_put(uint16_t memsh
     shm_vbd_image_put(memshr_id, SHARED_INFO->vbd_images);
     if(pthread_mutex_unlock(&SHARED_INFO->lock)) return;
 }
-
+    
+int memshr_vbd_issue_ro_request(char *buf,
+                                grant_ref_t gref,
+                                uint16_t file_id, 
+                                uint64_t sec, 
+                                int secs,
+                                uint64_t *hnd)
+{
+    vbdblk_t blk;
+    uint64_t s_hnd, c_hnd;
+    int ret;
+
+    *hnd = 0;
+    if(!vbd_info.enabled) 
+        return -1;
+
+    if(secs != 8)
+        return -2;
+
+    /* Nominate the granted page for sharing */
+    ret = xc_memshr_nominate_gref(vbd_info.xc_handle,
+                                  vbd_info.domid,
+                                  gref,
+                                  &c_hnd);
+    /* If page couldn't be made sharable, we cannot do anything about it */
+    if(ret != 0)
+        return -3;
+    *hnd = c_hnd;
+
+    /* Check if we've read matching disk block previously */
+    blk.sec     = sec;
+    blk.disk_id = file_id;
+    if(blockshr_block_lookup(memshr.blks, blk, &s_hnd) > 0)
+    {
+        ret = xc_memshr_share(vbd_info.xc_handle, s_hnd, c_hnd);
+        if(!ret) return 0;
+        /* Handles failed to be shared => at least one of them must be invalid,
+           remove the relevant ones from the map */
+        switch(ret)
+        {
+            case XEN_DOMCTL_MEM_SHARING_S_HANDLE_INVALID:
+                ret = blockshr_shrhnd_remove(memshr.blks, s_hnd, NULL);
+                if(ret) DPRINTF("Could not rm invl s_hnd: %"PRId64"\n", s_hnd);
+                break;
+            case XEN_DOMCTL_MEM_SHARING_C_HANDLE_INVALID:
+                ret = blockshr_shrhnd_remove(memshr.blks, c_hnd, NULL);
+                if(ret) DPRINTF("Could not rm invl c_hnd: %"PRId64"\n", c_hnd);
+                break;
+            default:
+                break;
+        }
+        return -5;
+    }
+
+    return -4;
+}
+
+void memshr_vbd_complete_ro_request(uint64_t hnd,
+                                    uint16_t file_id, 
+                                    uint64_t sec, 
+                                    int secs)
+{
+    vbdblk_t blk;
+    
+    if(!vbd_info.enabled) 
+        return;
+
+    if(secs != 8)
+        return;
+
+    blk.sec     = sec;
+    blk.disk_id = file_id;
+    if(blockshr_insert(memshr.blks, blk, hnd) < 0)
+        DPRINTF("Could not insert block hint into hash.\n");
+}
diff -r d3b569b2a2b9 -r 617071a8c638 tools/memshr/memshr.h
--- a/tools/memshr/memshr.h     Thu Dec 17 06:27:57 2009 +0000
+++ b/tools/memshr/memshr.h     Thu Dec 17 06:27:57 2009 +0000
@@ -20,6 +20,8 @@
 #define __MEMSHR_H__
 
 #include <stdint.h>
+#include <xen/xen.h>
+#include <xen/grant_table.h>
 
 typedef uint64_t xen_mfn_t;
 
@@ -28,5 +30,16 @@ extern void memshr_vbd_initialize(void);
 extern void memshr_vbd_initialize(void);
 extern uint16_t memshr_vbd_image_get(char* file);
 extern void memshr_vbd_image_put(uint16_t memshr_id);
+extern int memshr_vbd_issue_ro_request(char *buf,
+                                       grant_ref_t gref,
+                                       uint16_t file_id, 
+                                       uint64_t sec, 
+                                       int secs,
+                                       uint64_t *hnd);
+extern void memshr_vbd_complete_ro_request(
+                                       uint64_t hnd,
+                                       uint16_t file_id, 
+                                       uint64_t sec, 
+                                       int secs);
 
 #endif /* __MEMSHR_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.