2 * Palacios keyed stream interface
4 * Plus implementations for mem, file, and user space implementations
6 * (c) Peter Dinda, 2011 (interface, mem + file implementations + recooked user impl)
7 * (c) Clint Sbisa, 2011 (initial user space implementation on which this is based)
8 * (c) Diana Palsetia & Steve Rangel, 2012 (network based implementation)
12 #include <linux/file.h>
13 #include <linux/uaccess.h>
14 #include <linux/namei.h>
15 #include <linux/vmalloc.h>
16 #include <linux/poll.h>
17 #include <linux/anon_inodes.h>
20 #include "util-hashtable.h"
21 #include "linux-exts.h"
24 #define sint64_t int64_t
25 #include <interfaces/vmm_keyed_stream.h>
27 #include "iface-keyed-stream-user.h"
29 #include <interfaces/vmm_socket.h>
31 #include <linux/spinlock.h>
32 #include <asm/uaccess.h>
33 #include <linux/inet.h>
34 #include <linux/kthread.h>
35 #include <linux/netdevice.h>
38 #include <linux/string.h>
39 #include <linux/preempt.h>
40 #include <linux/sched.h>
41 #include <linux/list.h>
42 #include <linux/syscalls.h>
44 #include <linux/module.h>
45 #include <linux/kernel.h>
46 #include <linux/socket.h>
47 #include <linux/net.h>
48 #include <linux/slab.h>
52 This is an implementation of the Palacios keyed stream interface
53 that supports four flavors of streams:
55 "mem:" Streams are stored in a hash table
56 The values for this hash table are hash tables associated with
59 "file:" Streams are stored in files. Each high-level
60 open corresponds to a directory, while a key corresponds to
61 a distinct file in that directory.
63 "net:" Streams are carried over the network. Each
64 high level open corresponds to a TCP connection, while
65 each key corresponds to a context on the stream.
66 "net:a:<ip>:<port>" => Bind to <ip>:<port> and accept a connection
67 "net:c:<ip>:<port>" => Connect to <ip>:<port>
69 "user:" Stream requests are bounced to user space to be
70 handled there. A rendezvous approach similar to the host
71 device userland support is used
75 #define STREAM_GENERIC 0
79 #define STREAM_NETWORK 4
82 All keyed streams and streams indicate their implementation type within the first field
84 struct generic_keyed_stream {
88 struct generic_stream {
95 /****************************************************************************************
96 Memory-based implementation ("mem:")
97 ****************************************************************************************/
99 #define DEF_NUM_STREAMS 16
100 #define DEF_NUM_KEYS 128
104 A memory keyed stream is a pointer to the underlying hash table
105 while a memory stream contains an extensible buffer for the stream
107 struct mem_keyed_stream {
109 v3_keyed_stream_open_t ot;
110 struct hashtable *ht;
121 static struct mem_stream *create_mem_stream_internal(uint64_t size)
123 struct mem_stream *m = palacios_alloc(sizeof(struct mem_stream));
130 m->data = vmalloc(size);
137 m->stype = STREAM_MEM;
146 static struct mem_stream *create_mem_stream(void)
148 return create_mem_stream_internal(DEF_SIZE);
151 static void destroy_mem_stream(struct mem_stream *m)
162 static int expand_mem_stream(struct mem_stream *m, uint32_t new_size)
164 void *data = vmalloc(new_size);
171 nc = (new_size<m->data_max) ? new_size : m->data_max;
173 memcpy(data,m->data,nc);
179 if (m->size<m->data_max) {
186 static uint32_t write_mem_stream(struct mem_stream *m,
190 if ((m->ptr + len) > m->size) {
191 if (expand_mem_stream(m,m->ptr + len)) {
195 memcpy(m->data+m->ptr,data,len);
203 static uint32_t read_mem_stream(struct mem_stream *m,
207 if ((m->ptr + len) > m->data_max) {
210 memcpy(data,m->data+m->ptr,len);
218 static void reset_mem_stream(struct mem_stream *m)
224 static inline uint_t hash_func(addr_t key)
226 return palacios_hash_buffer((uchar_t*)key,strlen((uchar_t*)key));
229 static inline int hash_comp(addr_t k1, addr_t k2)
231 return strcasecmp((char*)k1,(char*)k2)==0;
235 // This stores all the memory keyed streams streams
236 static struct hashtable *mem_streams=0;
239 static v3_keyed_stream_t open_stream_mem(char *url,
240 v3_keyed_stream_open_t ot)
243 if (strncasecmp(url,"mem:",4)) {
244 WARNING("illegitimate attempt to open memory stream \"%s\"\n",url);
250 case V3_KS_WR_ONLY: {
251 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) palacios_htable_search(mem_streams,(addr_t)(url+4));
255 return (v3_keyed_stream_t) mks;
259 case V3_KS_WR_ONLY_CREATE: {
260 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) palacios_htable_search(mem_streams,(addr_t)(url+4));
264 mykey = palacios_alloc(strlen(url+4)+1);
267 ERROR("cannot allocate space for new in-memory keyed stream %s\n",url);
273 mks = (struct mem_keyed_stream *) palacios_alloc(sizeof(struct mem_keyed_stream));
276 palacios_free(mykey);
277 ERROR("cannot allocate in-memory keyed stream %s\n",url);
281 mks->ht = (void*) palacios_create_htable(DEF_NUM_KEYS,hash_func,hash_comp);
284 palacios_free(mykey);
285 ERROR("cannot allocate in-memory keyed stream %s\n",url);
290 if (!palacios_htable_insert(mem_streams,(addr_t)(mykey),(addr_t)mks)) {
291 palacios_free_htable(mks->ht,1,1);
293 palacios_free(mykey);
294 ERROR("cannot insert in-memory keyed stream %s\n",url);
297 mks->stype=STREAM_MEM;
300 mks->ot=V3_KS_WR_ONLY;
308 ERROR("unsupported open type in open_stream_mem\n");
318 static void close_stream_mem(v3_keyed_stream_t stream)
325 static v3_keyed_stream_key_t open_key_mem(v3_keyed_stream_t stream,
328 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
329 struct hashtable *s = mks->ht;
331 struct mem_stream *m;
333 m = (struct mem_stream *) palacios_htable_search(s,(addr_t)key);
336 char *mykey = palacios_alloc(strlen(key)+1);
339 ERROR("cannot allocate copy of key for key %s\n",key);
345 m = create_mem_stream();
348 palacios_free(mykey);
349 ERROR("cannot allocate mem keyed stream for key %s\n",key);
353 if (!palacios_htable_insert(s,(addr_t)mykey,(addr_t)m)) {
354 destroy_mem_stream(m);
355 palacios_free(mykey);
356 ERROR("cannot insert mem keyed stream for key %s\n",key);
367 static void preallocate_hint_key_mem(v3_keyed_stream_t stream,
371 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
372 struct hashtable *s = mks->ht;
374 struct mem_stream *m;
376 if (mks->ot != V3_KS_WR_ONLY) {
380 m = (struct mem_stream *) palacios_htable_search(s,(addr_t)key);
385 mykey=palacios_alloc(strlen(key)+1);
388 ERROR("cannot allocate key space for preallocte for key %s\n",key);
394 m = create_mem_stream_internal(size);
397 ERROR("cannot preallocate mem keyed stream for key %s\n",key);
401 if (!palacios_htable_insert(s,(addr_t)mykey,(addr_t)m)) {
402 ERROR("cannot insert preallocated mem keyed stream for key %s\n",key);
403 destroy_mem_stream(m);
407 if (m->data_max < size) {
408 if (expand_mem_stream(m,size)) {
409 ERROR("cannot expand key for preallocation for key %s\n",key);
419 static void close_key_mem(v3_keyed_stream_t stream,
420 v3_keyed_stream_key_t key)
426 static sint64_t write_key_mem(v3_keyed_stream_t stream,
427 v3_keyed_stream_key_t key,
431 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
432 struct mem_stream *m = (struct mem_stream *) key;
436 if (mks->ot!=V3_KS_WR_ONLY) {
444 mylen = (uint32_t) len;
446 writelen=write_mem_stream(m,buf,mylen);
448 if (writelen!=mylen) {
449 ERROR("failed to write all data for key\n");
452 return (sint64_t)writelen;
456 static sint64_t read_key_mem(v3_keyed_stream_t stream,
457 v3_keyed_stream_key_t key,
461 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
462 struct mem_stream *m = (struct mem_stream *) key;
466 if (mks->ot!=V3_KS_RD_ONLY) {
474 mylen = (uint32_t) len;
476 readlen=read_mem_stream(m,buf,mylen);
478 if (readlen!=mylen) {
479 ERROR("failed to read all data for key\n");
482 return (sint64_t)readlen;
487 /***************************************************************************************************
488 File-based implementation ("file:")
489 *************************************************************************************************/
492 A file keyed stream contains the fd of the directory
496 struct file_keyed_stream {
498 v3_keyed_stream_open_t ot;
504 struct file *f; // the opened file
508 static v3_keyed_stream_t open_stream_file(char *url,
509 v3_keyed_stream_open_t ot)
511 struct file_keyed_stream *fks;
514 if (strncasecmp(url,"file:",5)) {
515 WARNING("illegitimate attempt to open file stream \"%s\"\n",url);
519 fks = palacios_alloc(sizeof(struct file_keyed_stream));
522 ERROR("cannot allocate space for file stream\n");
526 fks->path = (char*)palacios_alloc(strlen(url+5)+1);
529 ERROR("cannot allocate space for file stream\n");
534 strcpy(fks->path,url+5);
536 fks->stype=STREAM_FILE;
538 fks->ot= ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
540 // Does the directory exist, and can we read/write it?
542 if (path_lookup(fks->path,LOOKUP_DIRECTORY|LOOKUP_FOLLOW,&nd)) {
544 // directory does does not exist.
546 if (ot==V3_KS_RD_ONLY || ot==V3_KS_WR_ONLY) {
548 // we are not being asked to create it
549 ERROR("attempt to open %s, which does not exist\n",fks->path);
554 // We are being asked to create it
560 if (path_lookup(fks->path,LOOKUP_PARENT|LOOKUP_FOLLOW,&nd)) {
561 ERROR("attempt to create %s failed because its parent cannot be looked up\n",fks->path);
565 // Can we write to the parent?
567 if (inode_permission(nd.path.dentry->d_inode, MAY_WRITE | MAY_EXEC)) {
568 ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",fks->path);
572 // OK, we can, so let's create it
574 de = lookup_create(&nd,1);
577 ERROR("cannot allocate dentry\n");
581 err = vfs_mkdir(nd.path.dentry->d_inode, de, 0700);
583 // lookup_create locks this for us!
585 mutex_unlock(&(nd.path.dentry->d_inode->i_mutex));
588 ERROR("attempt to create %s failed because mkdir failed\n",fks->path);
592 // now the directory should exist and have reasonable permissions
593 return (v3_keyed_stream_t) fks;
598 // we must be in V3_KS_RD_ONLY or V3_KS_WR_ONLY,
599 // and the directory exists, so we must check the permissions
601 if (inode_permission(nd.path.dentry->d_inode, MAY_EXEC | (ot==V3_KS_RD_ONLY ? MAY_READ : MAY_WRITE))) {
602 ERROR("attempt to open %s, which has the wrong permissions\n",fks->path);
605 return (v3_keyed_stream_t) fks;
610 palacios_free(fks->path);
616 static void close_stream_file(v3_keyed_stream_t stream)
618 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
620 palacios_free(fks->path);
625 static void preallocate_hint_key_file(v3_keyed_stream_t stream,
632 static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream,
635 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
636 struct file_stream *fs;
639 // the path is the stream's path plus the key name
640 // file:/home/foo + "regext" => "/home/foo/regext"
641 path = (char *) palacios_alloc(strlen(fks->path)+strlen(key)+2);
643 ERROR("cannot allocate file keyed stream for key %s\n",key);
646 strcpy(path,fks->path);
650 fs = (struct file_stream *) palacios_alloc(sizeof(struct file_stream *));
653 ERROR("cannot allocate file keyed stream for key %s\n",key);
658 fs->stype=STREAM_FILE;
660 fs->f = filp_open(path,O_RDWR|O_CREAT,0600);
663 ERROR("cannot open relevent file \"%s\" for stream \"file:%s\" and key \"%s\"\n",path,fks->path,key);
675 static void close_key_file(v3_keyed_stream_t stream,
676 v3_keyed_stream_key_t key)
678 struct file_stream *fs = (struct file_stream *) key;
680 filp_close(fs->f,NULL);
685 static sint64_t write_key_file(v3_keyed_stream_t stream,
686 v3_keyed_stream_key_t key,
690 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
691 struct file_stream *fs = (struct file_stream *) key;
693 ssize_t done, left, total;
695 if (fks->ot!=V3_KS_WR_ONLY) {
710 done = fs->f->f_op->write(fs->f, buf+(total-left), left, &(fs->f->f_pos));
724 static sint64_t read_key_file(v3_keyed_stream_t stream,
725 v3_keyed_stream_key_t key,
729 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
730 struct file_stream *fs = (struct file_stream *) key;
732 ssize_t done, left, total;
734 if (fks->ot!=V3_KS_RD_ONLY) {
749 done = fs->f->f_op->read(fs->f, buf+(total-left), left, &(fs->f->f_pos));
765 /***************************************************************************************************
766 User implementation ("user:")
767 *************************************************************************************************/
770 // List of all user keyed stream connections for the guest
771 struct user_keyed_streams {
773 struct list_head streams;
777 // A single keyed stream connection to user space
778 struct user_keyed_stream {
780 v3_keyed_stream_open_t otype;
786 wait_queue_head_t user_wait_queue;
787 wait_queue_head_t host_wait_queue;
789 struct palacios_user_keyed_stream_op *op;
791 struct list_head node;
796 // List of all of the user streams
798 static struct user_keyed_streams *user_streams;
802 static int resize_op(struct palacios_user_keyed_stream_op **op, uint64_t buf_len)
804 struct palacios_user_keyed_stream_op *old = *op;
805 struct palacios_user_keyed_stream_op *new;
808 new = palacios_alloc(sizeof(struct palacios_user_keyed_stream_op)+buf_len);
812 new->len=sizeof(struct palacios_user_keyed_stream_op)+buf_len;
813 new->buf_len=buf_len;
818 if ((old->len-sizeof(struct palacios_user_keyed_stream_op)) >= buf_len) {
819 old->buf_len=buf_len;
824 return resize_op(op,buf_len);
830 // The assumption is that we enter this with the stream locked
831 // and we will return with it locked; additionally, the op structure
832 // will be overwritten with the response
834 static int do_request_to_response(struct user_keyed_stream *s, unsigned long *flags)
838 ERROR("user keyed stream request attempted while one is already in progress on %s\n",s->url);
842 // we are now waiting for a response
845 // release the stream
846 spin_unlock_irqrestore(&(s->lock), *flags);
848 // wake up anyone waiting on it
849 wake_up_interruptible(&(s->user_wait_queue));
851 // wait for someone to give us a response
852 while (wait_event_interruptible(s->host_wait_queue, (s->waiting == 0)) != 0) {}
854 // reacquire the lock for our called
855 spin_lock_irqsave(&(s->lock), *flags);
861 // The assumption is that we enter this with the stream locked
862 // and we will return with it UNlocked
864 static int do_response_to_request(struct user_keyed_stream *s, unsigned long *flags)
868 ERROR("user keyed stream response while no request is in progress on %s\n",s->url);
872 // we are now waiting for a request
875 // release the stream
876 spin_unlock_irqrestore(&(s->lock), *flags);
878 // wake up anyone waiting on it
879 wake_up_interruptible(&(s->host_wait_queue));
886 static unsigned int keyed_stream_poll_user(struct file *filp, poll_table *wait)
888 struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
895 spin_lock_irqsave(&(s->lock), flags);
898 spin_unlock_irqrestore(&(s->lock), flags);
899 return POLLIN | POLLRDNORM;
902 poll_wait(filp, &(s->user_wait_queue), wait);
904 spin_unlock_irqrestore(&(s->lock), flags);
909 static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsigned long arg)
911 void __user *argp = (void __user *)arg;
915 struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
919 case V3_KSTREAM_REQUEST_SIZE_IOCTL:
921 // inform request size
923 spin_lock_irqsave(&(s->lock), flags);
926 spin_unlock_irqrestore(&(s->lock), flags);
930 size = sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
932 if (copy_to_user((void * __user) argp, &size, sizeof(uint64_t))) {
933 spin_unlock_irqrestore(&(s->lock), flags);
934 ERROR("palacios user key size request failed to copy data\n");
938 spin_unlock_irqrestore(&(s->lock), flags);
944 case V3_KSTREAM_REQUEST_PULL_IOCTL:
948 spin_lock_irqsave(&(s->lock), flags);
951 spin_unlock_irqrestore(&(s->lock), flags);
952 ERROR("palacios user key pull request when not waiting\n");
956 size = sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
959 if (copy_to_user((void __user *) argp, s->op, size)) {
960 spin_unlock_irqrestore(&(s->lock), flags);
961 ERROR("palacios user key pull request failed to copy data\n");
965 spin_unlock_irqrestore(&(s->lock), flags);
972 case V3_KSTREAM_RESPONSE_PUSH_IOCTL:
976 spin_lock_irqsave(&(s->lock), flags);
979 spin_unlock_irqrestore(&(s->lock), flags);
980 ERROR("palacios user key push response when not waiting\n");
984 if (copy_from_user(&size, (void __user *) argp, sizeof(uint64_t))) {
985 ERROR("palacios user key push response failed to copy size\n");
986 spin_unlock_irqrestore(&(s->lock), flags);
990 if (resize_op(&(s->op),size-sizeof(struct palacios_user_keyed_stream_op))) {
991 ERROR("unable to resize op in user key push response\n");
992 spin_unlock_irqrestore(&(s->lock), flags);
996 if (copy_from_user(s->op, (void __user *) argp, size)) {
997 spin_unlock_irqrestore(&(s->lock), flags);
1001 do_response_to_request(s,&flags);
1002 // this will have unlocked s for us
1009 ERROR("unknown ioctl in user keyed stream\n");
1019 static int keyed_stream_release_user(struct inode *inode, struct file *filp)
1021 struct user_keyed_stream *s = filp->private_data;
1022 unsigned long f1,f2;
1024 spin_lock_irqsave(&(user_streams->lock),f1);
1025 spin_lock_irqsave(&(s->lock), f2);
1027 list_del(&(s->node));
1029 spin_unlock_irqrestore(&(s->lock), f2);
1030 spin_unlock_irqrestore(&(user_streams->lock), f1);
1032 palacios_free(s->url);
1038 static struct file_operations user_keyed_stream_fops = {
1039 .poll = keyed_stream_poll_user,
1040 .compat_ioctl = keyed_stream_ioctl_user,
1041 .unlocked_ioctl = keyed_stream_ioctl_user,
1042 .release = keyed_stream_release_user,
1047 user_keyed_streams are allocated on user connect, and deallocated on user release
1049 palacios-side opens and closes only manipulate the open type
1052 int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned long arg, void *priv_data)
1055 unsigned long flags;
1058 struct user_keyed_stream *s;
1060 if (!user_streams) {
1061 ERROR("no user space keyed streams!\n");
1066 if (copy_from_user(&len,(void __user *)arg,sizeof(len))) {
1067 ERROR("cannot copy url len from user\n");
1071 url = palacios_alloc(len);
1074 ERROR("cannot allocate url for user keyed stream\n");
1078 if (copy_from_user(url,((void __user *)arg)+sizeof(len),len)) {
1079 ERROR("cannot copy url from user\n");
1085 // Check for duplicate handler
1086 spin_lock_irqsave(&(user_streams->lock), flags);
1087 list_for_each_entry(s, &(user_streams->streams), node) {
1088 if (!strncasecmp(url, s->url, len)) {
1089 ERROR("user keyed stream connection with url \"%s\" already exists\n", url);
1094 spin_unlock_irqrestore(&(user_streams->lock), flags);
1096 // Create connection
1097 s = palacios_alloc(sizeof(struct user_keyed_stream));
1100 ERROR("cannot allocate new user keyed stream for %s\n",url);
1106 // Get file descriptor
1107 fd = anon_inode_getfd("v3-kstream", &user_keyed_stream_fops, s, 0);
1110 ERROR("cannot allocate file descriptor for new user keyed stream for %s\n",url);
1116 memset(s, 0, sizeof(struct user_keyed_stream));
1118 s->stype=STREAM_USER;
1121 init_waitqueue_head(&(s->user_wait_queue));
1122 init_waitqueue_head(&(s->host_wait_queue));
1124 // Insert connection into list
1125 spin_lock_irqsave(&(user_streams->lock), flags);
1126 list_add(&(s->node), &(user_streams->streams));
1127 spin_unlock_irqrestore(&(user_streams->lock), flags);
1132 static struct user_keyed_stream *keyed_stream_user_find(char *url)
1134 unsigned long flags;
1135 struct user_keyed_stream *s;
1137 if (!user_streams) {
1138 ERROR("no user space keyed streams available\n");
1142 spin_lock_irqsave(&(user_streams->lock), flags);
1143 list_for_each_entry(s, &(user_streams->streams), node) {
1144 if (!strcasecmp(url, s->url)) {
1145 spin_unlock_irqrestore(&(user_streams->lock), flags);
1150 spin_unlock_irqrestore(&(user_streams->lock), flags);
1156 static v3_keyed_stream_t open_stream_user(char *url, v3_keyed_stream_open_t ot)
1158 unsigned long flags;
1159 struct user_keyed_stream *s;
1161 s = keyed_stream_user_find(url);
1164 ERROR("cannot open user stream %s as it does not exist yet\n",url);
1168 spin_lock_irqsave(&(s->lock), flags);
1171 spin_unlock_irqrestore(&(s->lock), flags);
1172 ERROR("cannot open user stream %s as it is already in waiting state\n",url);
1176 s->otype = ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
1178 spin_unlock_irqrestore(&(s->lock), flags);
1184 // close stream does not do anything. Creation of the stream and its cleanup
1185 // are driven by the user side, not the palacios side
1186 // might eventually want to reference count this, though
1187 static void close_stream_user(v3_keyed_stream_t stream)
1192 static void preallocate_hint_key_user(v3_keyed_stream_t stream,
1202 static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key)
1204 unsigned long flags;
1205 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1206 uint64_t len = strlen(key)+1;
1209 spin_lock_irqsave(&(s->lock), flags);
1212 if (resize_op(&(s->op),len)) {
1213 spin_unlock_irqrestore(&(s->lock),flags);
1214 ERROR("cannot resize op in opening key %s on user keyed stream %s\n",key,s->url);
1218 s->op->type = PALACIOS_KSTREAM_OPEN_KEY;
1219 s->op->buf_len = len;
1220 strncpy(s->op->buf,key,len);
1222 // enter with it locked
1223 if (do_request_to_response(s,&flags)) {
1224 spin_unlock_irqrestore(&(s->lock),flags);
1225 ERROR("request/response handling failed\n");
1228 // return with it locked
1230 user_key=s->op->user_key;
1232 spin_unlock_irqrestore(&(s->lock),flags);
1237 static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key)
1239 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1241 unsigned long flags;
1243 spin_lock_irqsave(&(s->lock), flags);
1245 if (resize_op(&(s->op),len)) {
1246 spin_unlock_irqrestore(&(s->lock),flags);
1247 ERROR("cannot resize op in closing key 0x%p on user keyed stream %s\n",key,s->url);
1251 s->op->type = PALACIOS_KSTREAM_CLOSE_KEY;
1252 s->op->buf_len = len;
1253 s->op->user_key = key;
1255 // enter with it locked
1256 if (do_request_to_response(s,&flags)) {
1257 spin_unlock_irqrestore(&(s->lock),flags);
1258 ERROR("request/response handling failed\n");
1261 // return with it locked
1263 spin_unlock_irqrestore(&(s->lock),flags);
1270 static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
1271 void *buf, sint64_t rlen)
1274 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1277 unsigned long flags;
1279 spin_lock_irqsave(&(s->lock), flags);
1281 if (s->otype != V3_KS_RD_ONLY) {
1282 spin_unlock_irqrestore(&(s->lock),flags);
1283 ERROR("attempt to read key from stream that is not in read state on %s\n",s->url);
1286 if (resize_op(&(s->op),len)) {
1287 spin_unlock_irqrestore(&(s->lock),flags);
1288 ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
1292 s->op->type = PALACIOS_KSTREAM_READ_KEY;
1293 s->op->buf_len = len ;
1295 s->op->user_key = key;
1297 // enter with it locked
1298 if (do_request_to_response(s,&flags)) {
1299 spin_unlock_irqrestore(&(s->lock),flags);
1300 ERROR("request/response handling failed\n");
1303 // return with it locked
1306 if (s->op->xfer>0) {
1307 memcpy(buf,s->op->buf,s->op->xfer);
1312 spin_unlock_irqrestore(&(s->lock),flags);
1318 static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
1319 void *buf, sint64_t wlen)
1322 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1323 struct palacios_user_keyed_stream_op *op;
1324 uint64_t len = wlen ;
1326 unsigned long flags;
1328 spin_lock_irqsave(&(s->lock), flags);
1330 if (s->otype != V3_KS_WR_ONLY) {
1331 spin_unlock_irqrestore(&(s->lock),flags);
1332 ERROR("attempt to write key on stream that is not in write state on %s\n",s->url);
1335 if (resize_op(&(s->op),len)) {
1336 spin_unlock_irqrestore(&(s->lock),flags);
1337 ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
1343 s->op->type = PALACIOS_KSTREAM_WRITE_KEY;
1344 s->op->buf_len = len;
1346 s->op->user_key = key;
1348 memcpy(s->op->buf,buf,wlen);
1350 // enter with it locked
1351 if (do_request_to_response(s,&flags)) {
1352 spin_unlock_irqrestore(&(s->lock),flags);
1353 ERROR("request/response handling failed\n");
1356 // return with it locked
1360 spin_unlock_irqrestore(&(s->lock),flags);
1367 /****************************************************************************************
1368 * Network-based implementation ("net:")
1369 *****************************************************************************************/
1372 #define NET_MAX_KEY_LEN 128
1374 struct net_keyed_stream {
1377 struct net_stream * ns;
1382 struct socket *sock;
1386 //ignore the arguments given here currently
1387 static struct net_stream * create_net_stream(void)
1389 struct net_stream * ns = NULL;
1391 ns = palacios_alloc(sizeof(struct net_stream));
1394 ERROR("Cannot allocate a net_stream\n");
1398 memset(ns, 0, sizeof(struct net_stream));
1400 ns->stype = STREAM_NETWORK;
1405 static void close_socket(v3_keyed_stream_t stream)
1407 struct net_keyed_stream *nks = (struct net_keyed_stream *) stream;
1410 struct net_stream *ns = nks->ns;
1413 ns->sock->ops->release(ns->sock);
1415 ERROR("Close Socket\n");
1423 static void close_stream_net(v3_keyed_stream_t stream)
1425 close_socket(stream);
1428 static int connect_to_ip(struct net_stream *ns, int hostip, int port)
1430 struct sockaddr_in client;
1436 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&(ns->sock))<0) {
1437 ERROR("Cannot create accept socket\n");
1442 client.sin_family = AF_INET;
1443 client.sin_port = htons(port);
1444 client.sin_addr.s_addr = hostip;//in_aton(hostip);
1446 return ns->sock->ops->connect(ns->sock, (struct sockaddr *)&client, sizeof(client), 0);
1449 static int send_msg(struct net_stream *ns, char * buf, int len)
1454 ERROR("Send message on null net_stream\n");
1459 ERROR("Send message on net_stream without socket\n");
1471 msg.msg_flags = MSG_NOSIGNAL;//MSG_DONTWAIT;
1473 msg.msg_namelen = 0;
1474 msg.msg_control = NULL;
1475 msg.msg_controllen = 0;
1479 iov.iov_base = (char *)&(buf[len-left]);
1480 iov.iov_len = (size_t)left;
1485 err = sock_sendmsg(ns->sock, &msg, (size_t)left);
1490 ERROR("Send msg error %d\n",err);
1502 static int recv_msg(struct net_stream *ns, char * buf, int len)
1508 ERROR("Receive message on null net_stream\n");
1513 ERROR("Receive message on net_stream without socket\n");
1527 msg.msg_namelen = 0;
1528 msg.msg_control = NULL;
1529 msg.msg_controllen = 0;
1533 iov.iov_base = (void *)&(buf[len-left]);
1534 iov.iov_len = (size_t)left;
1539 err = sock_recvmsg(ns->sock, &msg, (size_t)left, 0);
1552 static struct net_stream * accept_once(struct net_stream * ns, const int port)
1554 struct socket *accept_sock;
1555 struct sockaddr_in addr;
1559 ERROR("Accept called on null net_stream\n");
1563 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&accept_sock)<0) {
1564 ERROR("Cannot create accept socket\n");
1569 addr.sin_family = AF_INET;
1570 addr.sin_port = htons(port);
1571 addr.sin_addr.s_addr = INADDR_ANY;
1573 err = accept_sock->ops->bind(accept_sock, (struct sockaddr *)&addr, sizeof(addr));
1576 ERROR("Bind err: %d\n",err);
1580 err = accept_sock->ops->listen(accept_sock,2);
1583 ERROR("Listen err: %d\n",err);
1587 // Init the socket in the network strream
1589 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&(ns->sock))<0) {
1590 ERROR("Cannot create socket\n");
1595 // Do the actual accept
1597 if (accept_sock->ops->accept(accept_sock,ns->sock,0)<0) {
1598 ERROR("accept failed");
1602 // close the accept socket
1603 accept_sock->ops->release(accept_sock);
1604 palacios_free(accept_sock);
1610 static struct v3_keyed_stream_t * open_stream_net(char * url,v3_keyed_stream_open_t ot)
1612 struct net_keyed_stream * nks;
1621 nks = palacios_alloc(sizeof(struct net_keyed_stream));
1624 ERROR("Could not allocate space in open_stream_net\n");
1628 nks->ot = ot == V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
1630 nks->stype = STREAM_NETWORK;
1632 nks->ns = create_net_stream();
1635 ERROR("Could not create network stream\n");
1640 url_len=strlen(url);
1644 for(i = 0; i < url_len;i++){
1651 mode = url[delimit[0] + 1];
1652 ip_len = delimit[2] - delimit[1];
1653 port_len = url_len - delimit[2];
1658 char port[port_len];
1663 strncpy(ip,url + delimit[1]+1,ip_len-1);
1666 host_ip = in_aton(ip);
1668 strncpy(port,url+ delimit[2]+1,port_len-1);
1669 port[port_len-1]='\0';
1671 host_port = simple_strtol(port,NULL,10);
1673 INFO("ip is %s\n",ip);
1674 INFO("host_ip is %x\n", host_ip);
1675 INFO("port is %s (%d)\n",port,host_port);
1679 INFO("Accepting Connection on INADDR_ANY port:%d\n",host_port);
1680 nks->ns = accept_once(nks->ns, host_port);
1681 } else if (mode == 'c'){
1682 // call connect to ip
1683 INFO("Connecting to %s:%d\n",ip,host_port);
1684 connect_to_ip(nks->ns,host_ip, host_port);
1686 ERROR("Mode not recognized\n");
1691 return (v3_keyed_stream_t)nks;
1695 static void preallocate_hint_key_net(v3_keyed_stream_t stream, char *key,uint64_t size)
1700 static v3_keyed_stream_key_t open_key_net(v3_keyed_stream_t stream,char *key)
1702 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
1704 // reciever of the key name
1705 if (nks->ot==V3_KS_WR_ONLY)
1707 unsigned short keylen = strlen(key);
1709 if (keylen>NET_MAX_KEY_LEN || keylen>=32768) {
1710 ERROR("Key is too long\n");
1715 // on-stack allocation here demands that we
1716 // keep key length low...
1720 // Opening a key for writing sends a notice of the
1721 // key length and the key name on the channel
1723 msg[next++]=keylen & 0xFF;
1724 msg[next]=(keylen>>8) & 0xFF;
1726 msg[next]=msg[next] | 0x80; // 0x80 is 128 and OR will flip leading bit to 1
1728 strncpy(msg+2,key,keylen); // will also copy trailing zero
1730 if (send_msg(nks->ns,msg,keylen+2) != keylen+2) {
1731 ERROR("Unable to open key for writing on net_stream (send key len+name)\n");
1737 if (nks->ot==V3_KS_RD_ONLY) {
1742 if (recv_msg(nks->ns,msg_info,2) != 2) {
1743 ERROR("Unable to open key for reading on net_stream (recv key len)\n");
1750 keylen |= msg_info[next++];
1752 if ((msg_info[next] & 0x80) != 0x80) {
1753 ERROR("Flag bit not set on receive of key length\n");
1756 msg_info[next] &= 0x7F; // flip the msb back to zero (clear flag)
1759 keylen |= msg_info[next]<<8;
1761 if (keylen > NET_MAX_KEY_LEN) {
1762 ERROR("Received key length is too big\n");
1770 if (recv_msg(nks->ns,msg,keylen) != keylen) {
1771 ERROR("Unable to receive key\n");
1776 if (strncmp(key,msg,keylen)!=0) {
1777 ERROR("Key mismatch in open_key_net - expect %s but got %s\n",key,msg);
1783 return (v3_keyed_stream_key_t)key;
1786 static void close_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t input_key)
1788 char * key = (char*)input_key;
1789 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
1792 if (nks->ot==V3_KS_WR_ONLY) {
1793 unsigned short keylen = strlen(key);
1795 if (keylen > NET_MAX_KEY_LEN || keylen>=32768) {
1796 ERROR("Key length too long in close_key_net\n");
1804 msg[next++]=keylen & 0xFF;
1805 msg[next]=(keylen>>8) & 0xFF;
1807 msg[next]=msg[next] | 0x80; // 0x80 is 128 and OR will filp leading bit to 1
1808 strncpy(msg+2,key,keylen); // will copy the zero
1810 if (send_msg(nks->ns,msg,keylen+2)!=keylen+2) {
1811 ERROR("Cannot send key on close_key_net\n");
1817 if (nks->ot==V3_KS_RD_ONLY) {
1822 if (recv_msg(nks->ns,msg_info,2) != 2) {
1823 ERROR("Cannot recv key length on close_key_net\n");
1830 keylen |= msg_info[next++];
1832 if ((msg_info[next] & 0x80) != 0x80) {
1833 ERROR("Missing flag in close_key_net receive\n");
1837 msg_info[next] &= 0x7F; // flip the msb back to zero
1839 keylen |= msg_info[next]<<8;
1844 if (recv_msg(nks->ns,msg,keylen)!=keylen) {
1845 ERROR("Did not receive all of key in close_key_net receive\n");
1851 if (strncmp(key,msg,keylen)!=0) {
1852 ERROR("Key mismatch in close_key_net - expect %s but got %s\n",key,msg);
1859 static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, void *buf, sint64_t len)
1861 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
1864 ERROR("Buf is NULL in write_key_net\n");
1869 ERROR("len is negative in write_key_net\n");
1874 ERROR("write_key: key is NULL in write_key_net\n");
1880 ERROR("nks is NULL in write_key_net\n");
1884 if (nks->ot==V3_KS_WR_ONLY) {
1885 if (send_msg(nks->ns,(char*)(&len),sizeof(len))!=sizeof(len)) {
1886 ERROR("Could not send data length in write_key_net\n");
1889 if (send_msg(nks->ns,buf,len)!=len) {
1890 ERROR("Could not send data in write_key_net\n");
1894 ERROR("Permission not correct in write_key_net\n");
1902 static sint64_t read_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, void *buf, sint64_t len)
1904 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
1907 ERROR("Buf is NULL in read_key_net\n");
1912 ERROR("len is negative in read_key_net\n");
1917 ERROR("read_key: key is NULL in read_key_net\n");
1922 if (nks->ot==V3_KS_RD_ONLY) {
1926 if (recv_msg(nks->ns,(char*)(&slen),sizeof(slen))!=sizeof(slen)) {
1927 ERROR("Cannot receive data len in read_key_net\n");
1932 ERROR("Data len expected does not matched data len decoded in read_key_net\n");
1936 if (recv_msg(nks->ns,buf,len)!=len) {
1937 ERROR("Cannot recieve data in read_key_net\n");
1942 ERROR("Permissions incorrect for the stream in read_key_net\n");
1951 /***************************************************************************************************
1953 *************************************************************************************************/
1955 static v3_keyed_stream_t open_stream(char *url,
1956 v3_keyed_stream_open_t ot)
1958 if (!strncasecmp(url,"mem:",4)) {
1959 return open_stream_mem(url,ot);
1960 } else if (!strncasecmp(url,"file:",5)) {
1961 return open_stream_file(url,ot);
1962 } else if (!strncasecmp(url,"user:",5)) {
1963 return open_stream_user(url,ot);
1964 } else if(!strncasecmp(url,"net:",4)){
1965 return open_stream_net(url,ot);
1967 ERROR("unsupported type in attempt to open keyed stream \"%s\"\n",url);
1972 static void close_stream(v3_keyed_stream_t stream)
1974 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1975 switch (gks->stype){
1977 return close_stream_mem(stream);
1980 return close_stream_file(stream);
1983 return close_stream_user(stream);
1985 case STREAM_NETWORK:
1986 return close_stream_net(stream);
1989 ERROR("unknown stream type %d in close\n",gks->stype);
1994 static void preallocate_hint_key(v3_keyed_stream_t stream,
1998 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1999 switch (gks->stype){
2001 preallocate_hint_key_mem(stream,key,size);
2004 preallocate_hint_key_file(stream,key,size);
2007 return preallocate_hint_key_user(stream,key,size);
2009 case STREAM_NETWORK:
2010 return preallocate_hint_key_net(stream,key,size);
2013 ERROR("unknown stream type %d in preallocate_hint_key\n",gks->stype);
2020 static v3_keyed_stream_key_t open_key(v3_keyed_stream_t stream,
2023 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2024 switch (gks->stype){
2026 return open_key_mem(stream,key);
2029 return open_key_file(stream,key);
2032 return open_key_user(stream,key);
2034 case STREAM_NETWORK:
2035 return open_key_net(stream, key);
2038 ERROR("unknown stream type %d in open_key\n",gks->stype);
2045 static void close_key(v3_keyed_stream_t stream,
2046 v3_keyed_stream_key_t key)
2048 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2049 switch (gks->stype){
2051 return close_key_mem(stream,key);
2054 return close_key_file(stream,key);
2057 return close_key_user(stream,key);
2059 case STREAM_NETWORK:
2060 return close_key_net(stream, key);
2063 ERROR("unknown stream type %d in close_key\n",gks->stype);
2070 static sint64_t write_key(v3_keyed_stream_t stream,
2071 v3_keyed_stream_key_t key,
2075 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2076 switch (gks->stype){
2078 return write_key_mem(stream,key,buf,len);
2081 return write_key_file(stream,key,buf,len);
2084 return write_key_user(stream,key,buf,len);
2086 case STREAM_NETWORK:
2087 return write_key_net(stream,key,buf,len);
2090 ERROR("unknown stream type %d in write_key\n",gks->stype);
2098 static sint64_t read_key(v3_keyed_stream_t stream,
2099 v3_keyed_stream_key_t key,
2103 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2104 switch (gks->stype){
2106 return read_key_mem(stream,key,buf,len);
2109 return read_key_file(stream,key,buf,len);
2112 return read_key_user(stream,key,buf,len);
2114 case STREAM_NETWORK:
2115 return read_key_net(stream,key,buf,len);
2118 ERROR("unknown stream type %d in read_key\n",gks->stype);
2128 /***************************************************************************************************
2129 Hooks to palacios and inititialization
2130 *************************************************************************************************/
2133 static struct v3_keyed_stream_hooks hooks = {
2134 .open = open_stream,
2135 .close = close_stream,
2136 .preallocate_hint_key = preallocate_hint_key,
2137 .open_key = open_key,
2138 .close_key = close_key,
2139 .read_key = read_key,
2140 .write_key = write_key
2144 static int init_keyed_streams( void )
2146 mem_streams = palacios_create_htable(DEF_NUM_STREAMS,hash_func,hash_comp);
2149 ERROR("failed to allocated stream pool for in-memory streams\n");
2153 user_streams = palacios_alloc(sizeof(struct user_keyed_streams));
2155 if (!user_streams) {
2156 ERROR("failed to allocated list for user streams\n");
2160 INIT_LIST_HEAD(&(user_streams->streams));
2162 spin_lock_init(&(user_streams->lock));
2164 V3_Init_Keyed_Streams(&hooks);
2170 static int deinit_keyed_streams( void )
2172 palacios_free_htable(mem_streams,1,1);
2174 palacios_free(user_streams);
2176 WARNING("Deinit of Palacios Keyed Streams likely leaked memory\n");
2182 static int guest_init_keyed_streams(struct v3_guest * guest, void ** vm_data )
2185 add_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT, keyed_stream_connect_user, 0);
2191 static int guest_deinit_keyed_streams(struct v3_guest * guest, void * vm_data)
2200 static struct linux_ext key_stream_ext = {
2201 .name = "KEYED_STREAM_INTERFACE",
2202 .init = init_keyed_streams,
2203 .deinit = deinit_keyed_streams,
2204 .guest_init = guest_init_keyed_streams,
2205 .guest_deinit = guest_deinit_keyed_streams,
2209 register_extension(&key_stream_ext);