[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |