Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Ported keyed stream support from monolithic embedding
Peter Dinda [Thu, 5 May 2011 18:10:06 +0000 (13:10 -0500)]
linux_module/palacios-keyed-stream.c [new file with mode: 0644]
linux_module/palacios-keyed-stream.h [new file with mode: 0644]

diff --git a/linux_module/palacios-keyed-stream.c b/linux_module/palacios-keyed-stream.c
new file mode 100644 (file)
index 0000000..b3fbe2b
--- /dev/null
@@ -0,0 +1,297 @@
+#include "palacios.h"
+#include "palacios-keyed-stream.h"
+#include "palacios-hashtable.h"
+
+#define sint64_t int64_t
+#include <interfaces/vmm_keyed_stream.h>
+
+/*
+  Streams are stored in a hash table
+  The values for this hash table are hash tables associted with 
+  each stream.   A keyed stream for a "mem:" stream is 
+  an instance of the structure given here 
+*/
+
+#define DEF_NUM_STREAMS 16
+#define DEF_NUM_KEYS    128
+#define DEF_SIZE        128
+
+struct mem_stream {
+    char     *data;
+    uint32_t  size;
+    uint32_t  data_max;
+    uint32_t  ptr;
+};
+
+static struct mem_stream *create_mem_stream(void)
+{
+    struct mem_stream *m = kmalloc(sizeof(struct mem_stream),GFP_KERNEL);
+
+    if (!m) {
+       return 0;
+    }
+
+    m->data = kmalloc(DEF_SIZE,GFP_KERNEL);
+    
+    if (!m->data) { 
+       kfree(m);
+       return 0;
+    }
+
+    m->size=DEF_SIZE;
+    m->ptr=0;
+    m->data_max=0;
+    
+    return m;
+}
+
+static void destroy_mem_stream(struct mem_stream *m)
+{
+    if (m) {
+       if (m->data) {
+           kfree(m->data);
+       }
+       m->data=0;
+       kfree(m);
+    }
+}
+    
+static int expand_mem_stream(struct mem_stream *m, uint32_t new_size)
+{
+    void *data = kmalloc(new_size,GFP_KERNEL);
+    uint32_t nc;
+
+    if (!data) { 
+       return -1;
+    }
+    
+    nc = (new_size<m->data_max) ? new_size : m->data_max;
+
+    memcpy(data,m->data,nc);
+
+    kfree(m->data);
+
+    m->data=data;
+    m->size=new_size;
+    if (m->size<m->data_max) { 
+       m->data_max=m->size;
+    }
+   
+    return 0;
+}
+
+static uint32_t write_mem_stream(struct mem_stream *m,
+                                void *data,
+                                uint32_t len)
+{
+    if ((m->ptr + len) > m->size) { 
+       if (expand_mem_stream(m,m->ptr + len)) { 
+           return 0;
+       }
+    }
+    memcpy(m->data+m->ptr,data,len);
+    m->ptr+=len;
+    m->data_max=m->ptr;
+    
+    return len;
+
+}
+
+static uint32_t read_mem_stream(struct mem_stream *m,
+                               void *data,
+                               uint32_t len)
+{
+    if ((m->ptr + len) > m->data_max) { 
+       return 0;
+    }
+    memcpy(data,m->data+m->ptr,len);
+    m->ptr+=len;
+    
+    return len;
+
+}
+
+
+static void reset_mem_stream(struct mem_stream *m)
+{
+    m->ptr=0;
+}
+
+
+static inline uint_t hash_func(addr_t key)
+{
+    return palacios_hash_buffer((uchar_t*)key,strlen((uchar_t*)key));
+}
+
+static inline int hash_comp(addr_t k1, addr_t k2)
+{
+    return strcasecmp((char*)k1,(char*)k2)==0;
+}
+
+
+// This stores all the streams
+static struct hashtable *streams=0;
+
+
+static v3_keyed_stream_t open_stream(char *url,
+                                    v3_keyed_stream_open_t ot)
+{
+    if (strncasecmp(url,"mem:",4)) { 
+       printk("Only in-memory streams are currently supported\n");
+       return 0;
+    }
+
+    switch (ot) { 
+       case V3_KS_RD_ONLY:
+       case V3_KS_WR_ONLY:
+           return (v3_keyed_stream_t) palacios_htable_search(streams,(addr_t)(url+4));
+           break;
+       case V3_KS_WR_ONLY_CREATE: {
+           struct hashtable *s = (struct hashtable *) palacios_htable_search(streams,(addr_t)(url+4));
+
+           if (!s) { 
+                s = palacios_create_htable(DEF_NUM_KEYS,hash_func,hash_comp);
+                if (!s) { 
+                    printk("Cannot allocate in-memory keyed stream %s\n",url);
+                    return 0;
+                }
+                if (!palacios_htable_insert(streams,(addr_t)(url+4),(addr_t)s)) { 
+                    printk("Cannot insert in-memory keyed stream %s\n",url);
+                    return 0;
+                }
+           }
+
+           return s;
+           
+       }
+
+           break;
+    }
+    
+    return 0;
+    
+}
+
+
+static void close_stream(v3_keyed_stream_t stream)
+{
+    // nothing to do
+    return;
+}
+
+static v3_keyed_stream_key_t open_key(v3_keyed_stream_t stream,
+                                     char *key)
+{
+    struct hashtable *s = (struct hashtable *) stream;
+
+    struct mem_stream *m;
+
+    m = (struct mem_stream *) palacios_htable_search(s,(addr_t)key);
+
+    if (!m) { 
+       m = create_mem_stream();
+       
+       if (!m) { 
+           printk("Cannot allocate keyed stream for key %s\n",key);
+           return 0;
+       }
+
+       if (!palacios_htable_insert(s,(addr_t)key,(addr_t)m)) {
+           printk("Cannot insert keyed stream for key %s\n",key);
+           destroy_mem_stream(m);
+           return 0;
+       }
+    }
+
+    reset_mem_stream(m);
+    return m;
+
+}
+
+static void close_key(v3_keyed_stream_t stream, 
+                     v3_keyed_stream_key_t key)
+{
+    // nothing to do
+    return;
+}
+
+static sint64_t write_key(v3_keyed_stream_t stream, 
+                         v3_keyed_stream_key_t key,
+                         void *buf,
+                         sint64_t len)
+{
+    struct mem_stream *m = (struct mem_stream *) key;
+    uint32_t mylen;
+    uint32_t writelen;
+
+    if (len<0) { 
+       return len;
+    }
+    
+    mylen = (uint32_t) len;
+
+    writelen=write_mem_stream(m,buf,mylen);
+
+    if (writelen!=mylen) { 
+       printk("Failed to write all data for key\n");
+       return -1;
+    } else {
+       return (sint64_t)writelen;
+    }
+}
+
+static sint64_t read_key(v3_keyed_stream_t stream, 
+                        v3_keyed_stream_key_t key,
+                        void *buf,
+                        sint64_t len)
+{
+    struct mem_stream *m = (struct mem_stream *) key;
+    uint32_t mylen;
+    uint32_t readlen;
+    
+    if (len<0) { 
+       return len;
+    }
+    
+    mylen = (uint32_t) len;
+
+    readlen=read_mem_stream(m,buf,mylen);
+
+    if (readlen!=mylen) { 
+       printk("Failed to read all data for key\n");
+       return -1;
+    } else {
+       return (sint64_t)readlen;
+    }
+}
+    
+static struct v3_keyed_stream_hooks hooks = {
+    .open = open_stream,
+    .close = close_stream,
+    .open_key = open_key,
+    .close_key = close_key,
+    .read_key = read_key,
+    .write_key = write_key
+};
+
+
+int palacios_init_keyed_streams()
+{
+    streams = palacios_create_htable(DEF_NUM_STREAMS,hash_func,hash_comp);
+
+    if (!streams) { 
+       printk("Failed to allocated stream pool\n");
+       return -1;
+    }
+
+    V3_Init_Keyed_Streams(&hooks);
+    
+    return 0;
+
+}
+
+int palacios_deinit_keyed_streams()
+{
+    printk("DEINIT OF PALACIOS KEYED STREAMS NOT IMPLEMENTED - WE HAVE JUST LEAKED MEMORY!\n");
+    return -1;
+}
diff --git a/linux_module/palacios-keyed-stream.h b/linux_module/palacios-keyed-stream.h
new file mode 100644 (file)
index 0000000..218ed51
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Palacios VM Keyed Stream Interface (for checkpoint/restore)
+ * Copyright (c) 2011 Peter Dinda <pdinda@northwestern.edu>
+ */
+
+#ifndef __PALACIOS_KEYED_STREAM_H__
+#define __PALACIOS_KEYED_STREAM_H__
+
+
+
+int palacios_init_keyed_streams(void);
+int palacios_deinit_keyed_streams(void);
+
+
+#endif