diff options
-rw-r--r-- | tools/blktap2/drivers/tapdisk-image.c | 11 | ||||
-rw-r--r-- | tools/blktap2/drivers/tapdisk-image.h | 1 | ||||
-rw-r--r-- | tools/memshr/interface.c | 20 | ||||
-rw-r--r-- | tools/memshr/memshr.h | 2 | ||||
-rw-r--r-- | tools/memshr/shm.c | 85 | ||||
-rw-r--r-- | tools/memshr/shm.h | 23 |
6 files changed, 132 insertions, 10 deletions
diff --git a/tools/blktap2/drivers/tapdisk-image.c b/tools/blktap2/drivers/tapdisk-image.c index 6da7f48bd8..400c467583 100644 --- a/tools/blktap2/drivers/tapdisk-image.c +++ b/tools/blktap2/drivers/tapdisk-image.c @@ -28,6 +28,7 @@ #include <errno.h> #include <unistd.h> #include <stdlib.h> +#include <memshr.h> #include "tapdisk-image.h" #include "tapdisk-driver.h" @@ -52,10 +53,11 @@ tapdisk_image_allocate(char *file, int type, int storage, return NULL; } - image->type = type; - image->flags = flags; - image->storage = storage; - image->private = private; + image->type = type; + image->flags = flags; + image->storage = storage; + image->private = private; + image->memshr_id = memshr_vbd_image_get(file); INIT_LIST_HEAD(&image->next); return image; @@ -69,6 +71,7 @@ tapdisk_image_free(td_image_t *image) list_del(&image->next); + memshr_vbd_image_put(image->memshr_id); free(image->name); tapdisk_driver_free(image->driver); free(image); diff --git a/tools/blktap2/drivers/tapdisk-image.h b/tools/blktap2/drivers/tapdisk-image.h index 8779dff8b7..33b1b851c3 100644 --- a/tools/blktap2/drivers/tapdisk-image.h +++ b/tools/blktap2/drivers/tapdisk-image.h @@ -34,6 +34,7 @@ struct td_image_handle { int type; char *name; + uint16_t memshr_id; td_flag_t flags; int storage; diff --git a/tools/memshr/interface.c b/tools/memshr/interface.c index 2c2f45423b..ad14bbf2a0 100644 --- a/tools/memshr/interface.c +++ b/tools/memshr/interface.c @@ -106,3 +106,23 @@ void memshr_vbd_initialize(void) vbd_info.enabled = 1; } +uint16_t memshr_vbd_image_get(char* file) +{ + uint16_t id; + + if(pthread_mutex_lock(&SHARED_INFO->lock)) goto error_out; + id = shm_vbd_image_get(file, SHARED_INFO->vbd_images); + if(pthread_mutex_unlock(&SHARED_INFO->lock)) goto error_out; + + return id; +error_out: + return 0; +} + +void memshr_vbd_image_put(uint16_t memshr_id) +{ + if(pthread_mutex_lock(&SHARED_INFO->lock)) return; + shm_vbd_image_put(memshr_id, SHARED_INFO->vbd_images); + if(pthread_mutex_unlock(&SHARED_INFO->lock)) return; +} + diff --git a/tools/memshr/memshr.h b/tools/memshr/memshr.h index 351323715c..1292d494f5 100644 --- a/tools/memshr/memshr.h +++ b/tools/memshr/memshr.h @@ -26,5 +26,7 @@ typedef uint64_t xen_mfn_t; extern void memshr_set_domid(int domid); extern void memshr_daemon_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); #endif /* __MEMSHR_H__ */ diff --git a/tools/memshr/shm.c b/tools/memshr/shm.c index 6489f61466..dcbea1e223 100644 --- a/tools/memshr/shm.c +++ b/tools/memshr/shm.c @@ -92,10 +92,11 @@ shared_memshr_info_t * shm_shared_info_open(int unlink) { shared_memshr_info_t *shared_info; pthread_mutexattr_t lock_attr; + int nr_pages, i; - assert(sizeof(shared_memshr_info_t) < XC_PAGE_SIZE); + nr_pages = (sizeof(shared_memshr_info_t) >> XC_PAGE_SHIFT) + 1; if(shm_area_open(MEMSHR_INFO_SHM_FILE, - XC_PAGE_SIZE, + nr_pages * XC_PAGE_SIZE, unlink, &(shm_info.shared_info_area)) < 0) { @@ -115,6 +116,12 @@ shared_memshr_info_t * shm_shared_info_open(int unlink) DPRINTF("Failed to init shared info lock.\n"); return NULL; } + strcpy(shared_info->vbd_images[0].file, "list-head"); + for(i=1; i<MAX_NR_VBD_IMAGES; i++) + { + shared_info->vbd_images[i].next = i; + shared_info->vbd_images[i].prev = i; + } shared_info->magic = MEMSHR_INFO_MAGIC; } else @@ -180,3 +187,77 @@ struct blockshr_hash * shm_blockshr_hash_open(int unlink) return h; } +uint16_t shm_vbd_image_get(char* file, vbd_image_info_t *vbd_imgs) +{ + vbd_image_info_t *img, *next_img; + int i, img_id; + + /* Try to find the file in the existing list first */ + img = vbd_imgs; + while(img->next != 0) + { + img = vbd_imgs + img->next; + if(strncmp(img->file, file, MAX_NAME_LEN) == 0) + { + img->ref_cnt++; + return (uint16_t)(img - vbd_imgs); + } + } + + /* Couldn't find an existing entry. We need to add one. Find empty slot */ + for(i=1; i<MAX_NR_VBD_IMAGES; i++) + { + img = vbd_imgs + i; + if((img->next == i) && (img->prev == i)) + break; + } + /* No entries left! */ + if(i == MAX_NR_VBD_IMAGES) + { + DPRINTF("No space in vbds table.\n"); + return 0; + } + if(strlen(file) > MAX_NAME_LEN) + { + DPRINTF("Filename: %s too long (>%d).\n", file, MAX_NAME_LEN); + return 0; + } + /* Init the entry */ + img_id = (img - vbd_imgs); + next_img = vbd_imgs + vbd_imgs[0].next; + strcpy(img->file, file); + img->ref_cnt = 1; + img->next = vbd_imgs[0].next; + img->prev = 0; + next_img->prev = img_id; + vbd_imgs[0].next = img_id; + + return img_id; +} + + +void shm_vbd_image_put(uint16_t memshr_id, vbd_image_info_t *vbd_imgs) +{ + vbd_image_info_t *img, *next_img, *prev_img; + + img = vbd_imgs + memshr_id; + if(img->ref_cnt == 0) + { + DPRINTF("Incorrect image put.\n"); + return; + } + + img->ref_cnt--; + + /* Remove from list if ref_cnt is zero */ + if(img->ref_cnt == 0) + { + next_img = vbd_imgs + img->next; + prev_img = vbd_imgs + img->prev; + prev_img->next = img->next; + next_img->prev = img->prev; + img->next = img->prev = (img - vbd_imgs); + memset(img->file, 0, MAX_NAME_LEN); + } +} + diff --git a/tools/memshr/shm.h b/tools/memshr/shm.h index 0f6f665c6d..0d849ff787 100644 --- a/tools/memshr/shm.h +++ b/tools/memshr/shm.h @@ -20,16 +20,31 @@ #define __SHM_H__ #include <pthread.h> +#include <unistd.h> +#define MAX_NAME_LEN 1000 + +typedef struct vbd_image_info { + char file[MAX_NAME_LEN]; + int ref_cnt; + uint16_t next; + uint16_t prev; +} vbd_image_info_t; + +#define MAX_NR_VBD_IMAGES 4096 + typedef struct shared_memshr_info { - unsigned long magic; - pthread_mutex_t lock; - int fgprtshr_hash_inited; - int blockshr_hash_inited; + unsigned long magic; + pthread_mutex_t lock; + int fgprtshr_hash_inited; + int blockshr_hash_inited; + vbd_image_info_t vbd_images[MAX_NR_VBD_IMAGES]; } shared_memshr_info_t; shared_memshr_info_t * shm_shared_info_open(int unlink); struct fgprtshr_hash * shm_fgprtshr_hash_open(int unlink); struct blockshr_hash * shm_blockshr_hash_open(int unlink); +uint16_t shm_vbd_image_get(char* file, vbd_image_info_t *vbd_imgs); +void shm_vbd_image_put(uint16_t memshr_id, vbd_image_info_t *vbd_imgs); #endif /* __SHM_H__ */ |