aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/blktap2/drivers/tapdisk-image.c11
-rw-r--r--tools/blktap2/drivers/tapdisk-image.h1
-rw-r--r--tools/memshr/interface.c20
-rw-r--r--tools/memshr/memshr.h2
-rw-r--r--tools/memshr/shm.c85
-rw-r--r--tools/memshr/shm.h23
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__ */