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)
9 * (c) Peter Dinda, 2012 (updated interface, textfile)
13 #include <linux/file.h>
14 #include <linux/uaccess.h>
15 #include <linux/namei.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
57 each stream. A key maps to an expanding memory buffer.
58 Data is stored in a buffer like:
60 [boundarytag][taglen][tag][datalen][data]
61 [boundarytag][taglen][tag][datalen][data]
64 "file:" Streams are stored in files. Each high-level
65 open corresponds to a directory, while a key corresponds to
66 a distinct file in that directory. Data is stored in a file
69 [boundarytag][taglen][tag][datalen][data]
70 [boundarytag][taglen][tag][datalen][data]
73 "textfile:" Same as file, but data is stored in text format, like a
74 windows style .ini file. A key maps to a file, and data is stored
81 This format makes it possible to concentenate the files to
82 produce a single "ini" file with "sections".
85 "net:" Streams are carried over the network. Each
86 high level open corresponds to a TCP connection, while
87 each key corresponds to a context on the stream.
88 "net:a:<ip>:<port>" => Bind to <ip>:<port> and accept a connection
89 "net:c:<ip>:<port>" => Connect to <ip>:<port>
95 open_key: send [keylen-lastbyte-high-bit][key] (writer)
96 or recv (same format as above) (reader)
97 close_key: send [keylen-lastbyte-high-bit][key] (writer)
98 or recv (same format as above) (reader)
99 write_key: send [boundarytag][taglen][tag][datalen][data]
100 read_key: recv (same format as above)
101 close_stream: close socket
103 "user:" Stream requests are bounced to user space to be
104 handled there. A rendezvous approach similar to the host
105 device userland support is used
107 All keyed streams store the tags.
111 #define STREAM_GENERIC 0
113 #define STREAM_FILE 2
114 #define STREAM_USER 3
115 #define STREAM_NETWORK 4
116 #define STREAM_TEXTFILE 5
119 All keyed streams and streams indicate their implementation type within the first field
121 struct generic_keyed_stream {
125 struct generic_stream {
130 boundary tags are used for some othe raw formats.
132 static uint32_t BOUNDARY_TAG=0xabcd0123;
135 /****************************************************************************************
136 Memory-based implementation ("mem:")
137 ****************************************************************************************/
139 #define DEF_NUM_STREAMS 16
140 #define DEF_NUM_KEYS 128
144 A memory keyed stream is a pointer to the underlying hash table
145 while a memory stream contains an extensible buffer for the stream
147 struct mem_keyed_stream {
149 v3_keyed_stream_open_t ot;
150 struct hashtable *ht;
161 static struct mem_stream *create_mem_stream_internal(uint64_t size)
163 struct mem_stream *m = palacios_alloc(sizeof(struct mem_stream));
170 m->data = palacios_valloc(size);
177 m->stype = STREAM_MEM;
186 static struct mem_stream *create_mem_stream(void)
188 return create_mem_stream_internal(DEF_SIZE);
191 static void destroy_mem_stream(struct mem_stream *m)
195 palacios_vfree(m->data);
202 static int expand_mem_stream(struct mem_stream *m, uint32_t new_size)
204 void *data = palacios_valloc(new_size);
211 nc = (new_size<m->data_max) ? new_size : m->data_max;
213 memcpy(data,m->data,nc);
215 palacios_vfree(m->data);
219 if (m->size<m->data_max) {
226 static uint32_t write_mem_stream(struct mem_stream *m,
230 if ((m->ptr + len) > m->size) {
231 if (expand_mem_stream(m,m->ptr + len)) {
235 memcpy(m->data+m->ptr,data,len);
245 static uint32_t read_mem_stream(struct mem_stream *m,
249 if ((m->ptr + len) > m->data_max) {
252 memcpy(data,m->data+m->ptr,len);
260 static void reset_mem_stream(struct mem_stream *m)
266 static inline uint_t hash_func(addr_t key)
268 return palacios_hash_buffer((uchar_t*)key,strlen((uchar_t*)key));
271 static inline int hash_comp(addr_t k1, addr_t k2)
273 return strcasecmp((char*)k1,(char*)k2)==0;
277 // This stores all the memory keyed streams streams
278 static struct hashtable *mem_streams=0;
281 static v3_keyed_stream_t open_stream_mem(char *url,
282 v3_keyed_stream_open_t ot)
285 if (strncasecmp(url,"mem:",4)) {
286 WARNING("illegitimate attempt to open memory stream \"%s\"\n",url);
292 case V3_KS_WR_ONLY: {
293 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) palacios_htable_search(mem_streams,(addr_t)(url+4));
297 return (v3_keyed_stream_t) mks;
301 case V3_KS_WR_ONLY_CREATE: {
302 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) palacios_htable_search(mem_streams,(addr_t)(url+4));
306 mykey = palacios_alloc(strlen(url+4)+1);
309 ERROR("cannot allocate space for new in-memory keyed stream %s\n",url);
313 strcpy(mykey,url+4); // will fit
315 mks = (struct mem_keyed_stream *) palacios_alloc(sizeof(struct mem_keyed_stream));
318 palacios_free(mykey);
319 ERROR("cannot allocate in-memory keyed stream %s\n",url);
323 mks->ht = (void*) palacios_create_htable(DEF_NUM_KEYS,hash_func,hash_comp);
326 palacios_free(mykey);
327 ERROR("cannot allocate in-memory keyed stream %s\n",url);
332 if (!palacios_htable_insert(mem_streams,(addr_t)(mykey),(addr_t)mks)) {
333 palacios_free_htable(mks->ht,1,1);
335 palacios_free(mykey);
336 ERROR("cannot insert in-memory keyed stream %s\n",url);
339 mks->stype=STREAM_MEM;
342 mks->ot=V3_KS_WR_ONLY;
350 ERROR("unsupported open type in open_stream_mem\n");
360 static void close_stream_mem(v3_keyed_stream_t stream)
367 static v3_keyed_stream_key_t open_key_mem(v3_keyed_stream_t stream,
370 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
371 struct hashtable *s = mks->ht;
373 struct mem_stream *m;
375 m = (struct mem_stream *) palacios_htable_search(s,(addr_t)key);
378 char *mykey = palacios_alloc(strlen(key)+1);
381 ERROR("cannot allocate copy of key for key %s\n",key);
385 strcpy(mykey,key); // will fit
387 m = create_mem_stream();
390 palacios_free(mykey);
391 ERROR("cannot allocate mem keyed stream for key %s\n",key);
395 if (!palacios_htable_insert(s,(addr_t)mykey,(addr_t)m)) {
396 destroy_mem_stream(m);
397 palacios_free(mykey);
398 ERROR("cannot insert mem keyed stream for key %s\n",key);
409 static void preallocate_hint_key_mem(v3_keyed_stream_t stream,
413 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
414 struct hashtable *s = mks->ht;
416 struct mem_stream *m;
418 if (mks->ot != V3_KS_WR_ONLY) {
422 m = (struct mem_stream *) palacios_htable_search(s,(addr_t)key);
427 mykey=palacios_alloc(strlen(key)+1);
430 ERROR("cannot allocate key space for preallocte for key %s\n",key);
434 strcpy(mykey,key); // will fit
436 m = create_mem_stream_internal(size);
439 ERROR("cannot preallocate mem keyed stream for key %s\n",key);
443 if (!palacios_htable_insert(s,(addr_t)mykey,(addr_t)m)) {
444 ERROR("cannot insert preallocated mem keyed stream for key %s\n",key);
445 destroy_mem_stream(m);
449 if (m->data_max < size) {
450 if (expand_mem_stream(m,size)) {
451 ERROR("cannot expand key for preallocation for key %s\n",key);
461 static void close_key_mem(v3_keyed_stream_t stream,
462 v3_keyed_stream_key_t key)
468 static sint64_t write_key_mem(v3_keyed_stream_t stream,
469 v3_keyed_stream_key_t key,
475 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
476 struct mem_stream *m = (struct mem_stream *) key;
480 if (mks->ot!=V3_KS_WR_ONLY) {
484 if (taglen<0 || len<0) {
485 ERROR("Negative taglen or data len\n");
489 if (taglen>0xffffffffULL || len>0xffffffffULL) {
490 ERROR("taglen or data len is too large\n");
494 writelen=write_mem_stream(m,&BOUNDARY_TAG,sizeof(BOUNDARY_TAG));
496 if (writelen!=sizeof(BOUNDARY_TAG)) {
497 ERROR("failed to write all data for boundary tag\n");
501 writelen=write_mem_stream(m,&taglen,sizeof(taglen));
503 if (writelen!=sizeof(taglen)) {
504 ERROR("failed to write taglen\n");
508 mylen = (uint32_t) taglen;
510 writelen=write_mem_stream(m,tag,mylen);
512 if (writelen!=mylen) {
513 ERROR("failed to write all data for tag\n");
517 writelen=write_mem_stream(m,&len,sizeof(len));
519 if (writelen!=sizeof(len)) {
520 ERROR("failed to write datalen\n");
524 mylen = (uint32_t) len;
526 writelen=write_mem_stream(m,buf,mylen);
528 if (writelen!=mylen) {
529 ERROR("failed to write all data for key\n");
532 return (sint64_t)writelen;
536 static sint64_t read_key_mem(v3_keyed_stream_t stream,
537 v3_keyed_stream_key_t key,
543 struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
544 struct mem_stream *m = (struct mem_stream *) key;
552 if (mks->ot!=V3_KS_RD_ONLY) {
556 if (len<0 || taglen<0) {
557 ERROR("taglen or data len is negative\n");
561 if (len>0xffffffffULL || taglen>0xffffffffULL) {
562 ERROR("taglen or data len is too large\n");
566 readlen=read_mem_stream(m,&tempbt,sizeof(tempbt));
568 if (readlen!=sizeof(tempbt)) {
569 ERROR("failed to read all data for boundary tag\n");
573 if (tempbt!=BOUNDARY_TAG) {
574 ERROR("boundary tag not found (read 0x%x)\n",tempbt);
578 readlen=read_mem_stream(m,&templen,sizeof(templen));
580 if (readlen!=sizeof(templen)) {
581 ERROR("failed to read all data for taglen\n");
585 if (templen!=taglen) {
586 ERROR("tag size mismatch (requested=%lld, actual=%lld)\n",taglen,templen);
590 temptag = palacios_alloc(taglen);
593 ERROR("cannot allocate temporary tag\n");
597 mylen = (uint32_t) len;
599 readlen=read_mem_stream(m,temptag,mylen);
601 if (readlen!=mylen) {
602 ERROR("failed to read all data for tag\n");
603 palacios_free(temptag);
607 if (memcmp(tag,temptag,taglen)) {
608 ERROR("tag mismatch\n");
609 palacios_free(temptag);
613 palacios_free(temptag);
615 readlen=read_mem_stream(m,&templen,sizeof(templen));
617 if (readlen!=sizeof(templen)) {
618 ERROR("failed to read all data for data len\n");
623 ERROR("data size mismatch (requested=%lld, actual=%lld)\n",len,templen);
627 mylen = (uint32_t) len;
629 readlen=read_mem_stream(m,buf,mylen);
631 if (readlen!=mylen) {
632 ERROR("failed to read all data for key\n");
635 return (sint64_t)readlen;
640 /***************************************************************************************************
641 File-based implementation ("file:")
642 *************************************************************************************************/
645 A file keyed stream contains the fd of the directory
649 struct file_keyed_stream {
651 v3_keyed_stream_open_t ot;
657 struct file *f; // the opened file
661 static v3_keyed_stream_t open_stream_file(char *url,
662 v3_keyed_stream_open_t ot)
664 struct file_keyed_stream *fks;
667 if (strncasecmp(url,"file:",5)) {
668 WARNING("illegitimate attempt to open file stream \"%s\"\n",url);
672 fks = palacios_alloc(sizeof(struct file_keyed_stream));
675 ERROR("cannot allocate space for file stream\n");
679 fks->path = (char*)palacios_alloc(strlen(url+5)+1);
682 ERROR("cannot allocate space for file stream\n");
687 strcpy(fks->path,url+5); // will fit
689 fks->stype=STREAM_FILE;
691 fks->ot= ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
693 // Does the directory exist, and can we read/write it?
695 if (path_lookup(fks->path,LOOKUP_DIRECTORY|LOOKUP_FOLLOW,&nd)) {
697 // directory does does not exist.
699 if (ot==V3_KS_RD_ONLY || ot==V3_KS_WR_ONLY) {
701 // we are not being asked to create it
702 ERROR("attempt to open %s, which does not exist\n",fks->path);
707 // We are being asked to create it
713 if (path_lookup(fks->path,LOOKUP_PARENT|LOOKUP_FOLLOW,&nd)) {
714 ERROR("attempt to create %s failed because its parent cannot be looked up\n",fks->path);
718 // Can we write to the parent?
720 if (inode_permission(nd.path.dentry->d_inode, MAY_WRITE | MAY_EXEC)) {
721 ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",fks->path);
725 // OK, we can, so let's create it
727 de = lookup_create(&nd,1);
729 if (!de || IS_ERR(de)) {
730 ERROR("cannot allocate dentry\n");
734 err = vfs_mkdir(nd.path.dentry->d_inode, de, 0700);
736 // lookup_create locks this for us!
738 mutex_unlock(&(nd.path.dentry->d_inode->i_mutex));
741 ERROR("attempt to create %s failed because mkdir failed\n",fks->path);
745 // now the directory should exist and have reasonable permissions
746 return (v3_keyed_stream_t) fks;
751 // we must be in V3_KS_RD_ONLY or V3_KS_WR_ONLY,
752 // and the directory exists, so we must check the permissions
754 if (inode_permission(nd.path.dentry->d_inode, MAY_EXEC | (ot==V3_KS_RD_ONLY ? MAY_READ : MAY_WRITE))) {
755 ERROR("attempt to open %s, which has the wrong permissions\n",fks->path);
758 return (v3_keyed_stream_t) fks;
763 palacios_free(fks->path);
769 static void close_stream_file(v3_keyed_stream_t stream)
771 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
773 palacios_free(fks->path);
778 static void preallocate_hint_key_file(v3_keyed_stream_t stream,
785 static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream,
788 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
789 struct file_stream *fs;
792 // the path is the stream's path plus the key name
793 // file:/home/foo + "regext" => "/home/foo/regext"
794 path = (char *) palacios_alloc(strlen(fks->path)+strlen(key)+2);
796 ERROR("cannot allocate file keyed stream for key %s\n",key);
799 // this sequence will fit and terminate with a zero
800 strcpy(path,fks->path);
804 fs = (struct file_stream *) palacios_alloc(sizeof(struct file_stream));
807 ERROR("cannot allocate file keyed stream for key %s\n",key);
812 fs->stype=STREAM_FILE;
814 fs->f = filp_open(path,O_RDWR|O_CREAT|O_LARGEFILE,0600);
816 if (!fs->f || IS_ERR(fs->f)) {
817 ERROR("cannot open relevent file \"%s\" for stream \"file:%s\" and key \"%s\"\n",path,fks->path,key);
829 static void close_key_file(v3_keyed_stream_t stream,
830 v3_keyed_stream_key_t key)
832 struct file_stream *fs = (struct file_stream *) key;
834 filp_close(fs->f,NULL);
840 static sint64_t write_file(struct file_stream *fs, void *buf, sint64_t len)
842 ssize_t done, left, total;
851 done = fs->f->f_op->write(fs->f, buf+(total-left), left, &(fs->f->f_pos));
863 static sint64_t write_key_file(v3_keyed_stream_t stream,
864 v3_keyed_stream_key_t key,
870 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
871 struct file_stream *fs = (struct file_stream *) key;
874 if (fks->ot!=V3_KS_WR_ONLY) {
878 if (taglen<0 || len<0) {
879 ERROR("Negative taglen or data len\n");
883 writelen=write_file(fs,&BOUNDARY_TAG,sizeof(BOUNDARY_TAG));
885 if (writelen!=sizeof(BOUNDARY_TAG)) {
886 ERROR("failed to write all data for boundary tag\n");
890 writelen=write_file(fs,&taglen,sizeof(taglen));
892 if (writelen!=sizeof(taglen)) {
893 ERROR("failed to write taglen\n");
897 if (write_file(fs,tag,taglen)!=taglen) {
898 ERROR("failed to write tag\n");
902 writelen=write_file(fs,&len,sizeof(len));
904 if (writelen!=sizeof(len)) {
905 ERROR("failed to write data len\n");
909 return write_file(fs,buf,len);
912 static sint64_t read_file(struct file_stream *fs, void *buf, sint64_t len)
914 ssize_t done, left, total;
924 done = fs->f->f_op->read(fs->f, buf+(total-left), left, &(fs->f->f_pos));
937 static sint64_t read_key_file(v3_keyed_stream_t stream,
938 v3_keyed_stream_key_t key,
944 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
945 struct file_stream *fs = (struct file_stream *) key;
951 if (fks->ot!=V3_KS_RD_ONLY) {
955 if (len<0 || taglen<0) {
956 ERROR("taglen or data len is negative\n");
960 readlen=read_file(fs,&tempbt,sizeof(tempbt));
962 if (readlen!=sizeof(tempbt)) {
963 ERROR("failed to read all data for boundary tag\n");
967 if (tempbt!=BOUNDARY_TAG) {
968 ERROR("boundary tag not found (read 0x%x)\n",tempbt);
972 readlen=read_file(fs,&templen,sizeof(templen));
974 if (readlen!=sizeof(templen)) {
975 ERROR("failed to read all data for tag len\n");
979 if (templen!=taglen) {
980 ERROR("tag size mismatch (requested=%lld, actual=%lld)\n",taglen,templen);
984 temptag=palacios_alloc(taglen);
987 ERROR("Cannot allocate temptag\n");
991 if (read_file(fs,temptag,taglen)!=taglen) {
992 ERROR("Cannot read tag\n");
993 palacios_free(temptag);
997 if (memcmp(temptag,tag,taglen)) {
998 ERROR("Tag mismatch\n");
999 palacios_free(temptag);
1003 palacios_free(temptag);
1005 readlen=read_file(fs,&templen,sizeof(templen));
1007 if (readlen!=sizeof(templen)) {
1008 ERROR("failed to read all data for data len\n");
1013 ERROR("datasize mismatch (requested=%lld, actual=%lld)\n",len,templen);
1017 return read_file(fs,buf,len);
1022 /***************************************************************************************************
1023 Textfile-based implementation ("textfile:")
1025 Note that this implementation uses the internal structure and functions of the
1026 "file:" implementation
1027 *************************************************************************************************/
1029 // optimize the reading and decoding of hex data
1030 // this weakens the parser, so that:
1034 // will not. Note the leading whitespace
1035 #define TEXTFILE_OPT_HEX 0
1038 // The number of bytes handled at a time by the hex putter and getter
1040 #define MAX_HEX_SEQ 64
1043 A text file keyed stream is a file_keyed_stream,
1044 only with a different stype
1048 //#define PAUSE() ssleep(5)
1051 typedef struct file_keyed_stream textfile_keyed_stream;
1053 typedef struct file_stream textfile_stream;
1056 static v3_keyed_stream_t open_stream_textfile(char *url,
1057 v3_keyed_stream_open_t ot)
1059 textfile_keyed_stream *me;
1061 if (strncasecmp(url,"textfile:",9)) {
1062 WARNING("illegitimate attempt to open textfile stream \"%s\"\n",url);
1066 me = (textfile_keyed_stream *) open_stream_file(url+4, ot);
1069 ERROR("could not create underlying file stream\n");
1073 me->stype=STREAM_TEXTFILE;
1080 static void close_stream_textfile(v3_keyed_stream_t stream)
1082 textfile_keyed_stream *me = stream;
1084 me->stype=STREAM_FILE;
1086 close_stream_file(me);
1090 static void preallocate_hint_key_textfile(v3_keyed_stream_t stream,
1094 textfile_keyed_stream *me = stream;
1096 me->stype=STREAM_FILE;
1098 preallocate_hint_key_file(me,key,size);
1100 me->stype=STREAM_TEXTFILE;
1105 static inline int isoneof(char c, char *sl, int m)
1118 static char get_next_char(textfile_stream *s)
1121 if (read_file(s,&buf,1)!=1) {
1127 static char hexify_nybble(char c)
1131 } else if (c>=0xa && c<=0xf) {
1138 static int hexify_byte(char *c, char b)
1141 n = hexify_nybble( (b >> 4) & 0xf);
1146 n = hexify_nybble( b & 0xf);
1155 static char dehexify_nybble(char c)
1157 if (c>='0' && c<='9') {
1159 } else if (c>='a' && c<='f') {
1160 return 0xa + (c-'a');
1161 } else if (c>='A' && c<='F') {
1162 return 0xa + (c-'A');
1168 static int dehexify_byte(char *c, char *b)
1171 n = dehexify_nybble(c[0]);
1176 n = dehexify_nybble(c[1]);
1185 #if TEXTFILE_OPT_HEX
1188 // Here the sl array, of length m is the number
1189 static int get_hexbytes_as_data(textfile_stream *s, char *buf, int n)
1191 char rbuf[MAX_HEX_SEQ*2];
1198 cur = left > MAX_HEX_SEQ ? MAX_HEX_SEQ : left;
1199 if (read_file(s,rbuf,cur*2)!=cur*2) {
1200 ERROR("Cannot read data in getting hexbytes as data\n");
1204 for (i=0;i<cur;i++) {
1205 if (dehexify_byte(rbuf+(i*2),buf+off+i)==-1) {
1206 ERROR("Cannot decode data as hex in getting hexbytes as data\n");
1219 // Here the sl array, of length m is the set of characters to skip (e.g., whitespace)
1220 static int get_hexbytes_as_data_skip(textfile_stream *s, char *buf, int n, char *sl, int m)
1229 rbuf[which] = get_next_char(s);
1230 if (rbuf[which]==-1) {
1231 ERROR("Cannot read char in getting hexbytes as data with skiplist");
1234 if (isoneof(rbuf[which],sl,m)) {
1240 if (dehexify_byte(rbuf,buf+cur)==-1) {
1241 ERROR("Cannot decode data as hex in getting hexbytes as data with skiplist\n");
1251 static int put_next_char(textfile_stream *s, char d)
1253 return write_file(s,&d,1);
1258 static int put_data_as_hexbytes(textfile_stream *s, char *buf, int n)
1260 char rbuf[MAX_HEX_SEQ*2];
1267 cur = left > MAX_HEX_SEQ ? MAX_HEX_SEQ : left;
1268 for (i=0;i<cur;i++) {
1269 if (hexify_byte(rbuf+(i*2),*(buf+off+i))==-1) {
1270 ERROR("Cannot encode data as hex in putting data as hexbytes\n");
1274 if (write_file(s,rbuf,cur*2)!=cur*2) {
1275 ERROR("Cannot write data in putting data as hexbytes\n");
1286 static int put_string_n(textfile_stream *s, char *buf, int n)
1290 rc = write_file(s,buf,n);
1299 static int put_string(textfile_stream *s, char *buf)
1303 return put_string_n(s,buf,n);
1308 static int search_for(textfile_stream *s, char d)
1313 } while (c!=-1 && c!=d);
1323 static int skip_matching(textfile_stream *s, char *m, int n)
1346 return rc; // unknown
1353 static int token_scan(textfile_stream *s, char *token, int n, char *sl, int m)
1362 ERROR("Failed to get character during token scan (preceding whitespace)\n");
1365 } while (isoneof(c,sl,m));
1375 ERROR("Failed to get character during token scan (token)\n");
1378 if (isoneof(c,sl,m)) {
1391 static v3_keyed_stream_key_t open_key_textfile(v3_keyed_stream_t stream,
1394 textfile_keyed_stream *mks = stream;
1395 textfile_stream *ms;
1397 mks->stype=STREAM_FILE;
1399 ms = open_key_file(mks,key);
1402 ERROR("cannot open underlying file keyed stream for key %s\n",key);
1403 mks->stype=STREAM_TEXTFILE;
1407 if (mks->ot==V3_KS_WR_ONLY) {
1409 // Now we write the section header
1411 ms->stype=STREAM_FILE;
1413 if (put_string(ms,"[")) {
1414 close_key_file(mks,ms);
1415 mks->stype=STREAM_TEXTFILE;
1419 if (put_string(ms,key)) {
1420 close_key_file(mks,ms);
1421 mks->stype=STREAM_TEXTFILE;
1425 if (put_string(ms,"]\n")) {
1426 close_key_file(mks,ms);
1427 mks->stype=STREAM_TEXTFILE;
1432 mks->stype=STREAM_TEXTFILE;
1433 ms->stype=STREAM_TEXTFILE;
1437 } else if (mks->ot == V3_KS_RD_ONLY) {
1438 // Now we readthe section header
1439 int keylen=strlen(key);
1440 char *tempkey = palacios_alloc(keylen+3);
1442 ms->stype=STREAM_FILE;
1445 ERROR("Allocation failed in opening key\n");
1446 close_key_file(mks,ms);
1447 mks->stype=STREAM_FILE;
1452 if (token_scan(ms,tempkey,keylen+3,"\t\r\n",3)) {
1453 ERROR("Cannot scan for token (key search)\n");
1454 close_key_file(mks,ms);
1455 mks->stype=STREAM_TEXTFILE;
1456 palacios_free(tempkey);
1460 tempkey[keylen+2] = 0;
1462 // Should now have [key]0
1464 if (tempkey[0]!='[' ||
1465 tempkey[keylen+1]!=']' ||
1466 memcmp(key,tempkey+1,keylen)) {
1467 ERROR("key mismatch: target key=%s, found %s\n",key,tempkey);
1468 palacios_free(tempkey);
1469 close_key_file(mks,ms);
1470 mks->stype=STREAM_TEXTFILE;
1474 // key match done, success
1476 mks->stype=STREAM_TEXTFILE;
1477 ms->stype=STREAM_TEXTFILE;
1479 palacios_free(tempkey);
1484 ERROR("Unknown open type in open_key_textfile\n");
1485 ms->stype=STREAM_FILE;
1486 close_key_file(mks,ms);
1494 static void close_key_textfile(v3_keyed_stream_t stream,
1495 v3_keyed_stream_key_t key)
1497 textfile_keyed_stream *mks = stream;
1498 textfile_stream *ms=key;
1500 mks->stype=STREAM_FILE;
1501 ms->stype=STREAM_FILE;
1503 close_key_file(mks,ms);
1505 mks->stype=STREAM_TEXTFILE;
1510 static sint64_t read_key_textfile(v3_keyed_stream_t stream,
1511 v3_keyed_stream_key_t key,
1517 textfile_stream *ms = (textfile_stream *) key;
1523 memcpy(tags,tag,taglen<31 ? taglen : 31);
1524 tags[taglen<32? taglen : 31 ]=0;
1526 temptag=palacios_alloc(taglen+1);
1528 ERROR("Unable to allocate temptag in textfile read key\n");
1532 ms->stype=STREAM_FILE;
1534 if (token_scan(ms,temptag,taglen+1," \t\r\n=",5)) {
1535 ERROR("Cannot scan for token (tag search)\n");
1536 ms->stype=STREAM_TEXTFILE;
1537 palacios_free(temptag);
1541 if (memcmp(tag,temptag,taglen)) {
1542 ERROR("Tag mismatch in reading tag from textfile: desired tag=%s, actual tag=%s\n",tags,temptag);
1543 ms->stype=STREAM_TEXTFILE;
1544 palacios_free(temptag);
1548 // tag matches, let's go and find our =
1549 palacios_free(temptag);
1551 if (search_for(ms,'=')) {
1552 ERROR("Unable to find = sign in tag data parse (tag=%s)\n", tags);
1553 ms->stype=STREAM_TEXTFILE;
1558 #if TEXTFILE_OPT_HEX
1559 if (get_hexbytes_as_data(ms,buf,len)) {
1560 ERROR("Cannot read data in hex format (opt path) in textfile for tag %s\n",tags);
1561 ms->stype=STREAM_TEXTFILE;
1565 if (get_hexbytes_as_data_skip(ms,buf,len," \t\r\n",4)) {
1566 ERROR("Cannot read data in hex format (unopt path) in textfile for tag %s\n",tags);
1567 ms->stype=STREAM_TEXTFILE;
1572 ms->stype=STREAM_TEXTFILE;
1577 static sint64_t write_key_textfile(v3_keyed_stream_t stream,
1578 v3_keyed_stream_key_t key,
1584 textfile_stream *ms = (textfile_stream *) key;
1589 memcpy(tags,tag,taglen<31 ? taglen : 31);
1590 tags[taglen<32? taglen : 31 ]=0;
1592 /* if (taglen>100000 || len>100000) {
1598 ms->stype=STREAM_FILE;
1600 if (put_string_n(ms,tag,taglen)) {
1601 ERROR("Cannot write tag %s in textfile\n",tags);
1602 ms->stype=STREAM_TEXTFILE;
1606 if (put_string(ms,"=")) {
1607 ERROR("Cannot write = in textfile for tag %s\n",tags);
1608 ms->stype=STREAM_TEXTFILE;
1612 if (put_data_as_hexbytes(ms,buf,len)) {
1613 ERROR("Cannot write data in hex format in textfile for tag %s\n",tags);
1614 ms->stype=STREAM_TEXTFILE;
1618 if (put_string(ms,"\n")) {
1619 ERROR("Cannot write trailing lf in textfile for tag %s\n",tags);
1620 ms->stype=STREAM_TEXTFILE;
1624 ms->stype=STREAM_TEXTFILE;
1631 /***************************************************************************************************
1632 User implementation ("user:")
1633 *************************************************************************************************/
1636 // List of all user keyed stream connections for the guest
1637 struct user_keyed_streams {
1639 struct list_head streams;
1643 // A single keyed stream connection to user space
1644 struct user_keyed_stream {
1646 v3_keyed_stream_open_t otype;
1652 wait_queue_head_t user_wait_queue;
1653 wait_queue_head_t host_wait_queue;
1655 struct palacios_user_keyed_stream_op *op;
1657 struct list_head node;
1662 // List of all of the user streams
1664 static struct user_keyed_streams *user_streams;
1668 static int resize_op(struct palacios_user_keyed_stream_op **op, uint64_t buf_len)
1670 struct palacios_user_keyed_stream_op *old = *op;
1671 struct palacios_user_keyed_stream_op *new;
1674 new = palacios_alloc(sizeof(struct palacios_user_keyed_stream_op)+buf_len);
1678 new->len=sizeof(struct palacios_user_keyed_stream_op)+buf_len;
1679 new->buf_len=buf_len;
1684 if ((old->len-sizeof(struct palacios_user_keyed_stream_op)) >= buf_len) {
1685 old->buf_len=buf_len;
1690 return resize_op(op,buf_len);
1696 // The assumption is that we enter this with the stream locked
1697 // and we will return with it locked; additionally, the op structure
1698 // will be overwritten with the response
1700 static int do_request_to_response(struct user_keyed_stream *s, unsigned long *flags)
1704 ERROR("user keyed stream request attempted while one is already in progress on %s\n",s->url);
1708 // we are now waiting for a response
1711 // release the stream
1712 palacios_spinlock_unlock_irqrestore(&(s->lock), *flags);
1714 // wake up anyone waiting on it
1715 wake_up_interruptible(&(s->user_wait_queue));
1717 // wait for someone to give us a response
1718 while (wait_event_interruptible(s->host_wait_queue, (s->waiting == 0)) != 0) {}
1720 // reacquire the lock for our called
1721 palacios_spinlock_lock_irqsave(&(s->lock), *flags);
1727 // The assumption is that we enter this with the stream locked
1728 // and we will return with it UNlocked
1730 static int do_response_to_request(struct user_keyed_stream *s, unsigned long *flags)
1733 if (!(s->waiting)) {
1734 ERROR("user keyed stream response while no request is in progress on %s\n",s->url);
1738 // we are now waiting for a request
1741 // release the stream
1742 palacios_spinlock_unlock_irqrestore(&(s->lock), *flags);
1744 // wake up anyone waiting on it
1745 wake_up_interruptible(&(s->host_wait_queue));
1752 static unsigned int keyed_stream_poll_user(struct file *filp, poll_table *wait)
1754 struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
1755 unsigned long flags;
1761 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1763 poll_wait(filp, &(s->user_wait_queue), wait);
1766 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1767 return POLLIN | POLLRDNORM;
1770 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1775 static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsigned long arg)
1777 void __user *argp = (void __user *)arg;
1778 unsigned long flags;
1781 struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
1785 case V3_KSTREAM_REQUEST_SIZE_IOCTL:
1787 // inform request size
1789 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1791 if (!(s->waiting)) {
1792 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1796 size = sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
1798 if (copy_to_user((void * __user) argp, &size, sizeof(uint64_t))) {
1799 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1800 ERROR("palacios user key size request failed to copy data\n");
1804 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1810 case V3_KSTREAM_REQUEST_PULL_IOCTL:
1814 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1816 if (!(s->waiting)) {
1817 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1818 ERROR("palacios user key pull request when not waiting\n");
1822 size = sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
1825 if (copy_to_user((void __user *) argp, s->op, size)) {
1826 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1827 ERROR("palacios user key pull request failed to copy data\n");
1831 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1838 case V3_KSTREAM_RESPONSE_PUSH_IOCTL:
1840 // push the response
1842 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1844 if (!(s->waiting)) {
1845 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1846 ERROR("palacios user key push response when not waiting\n");
1850 if (copy_from_user(&size, (void __user *) argp, sizeof(uint64_t))) {
1851 ERROR("palacios user key push response failed to copy size\n");
1852 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1856 if (resize_op(&(s->op),size-sizeof(struct palacios_user_keyed_stream_op))) {
1857 ERROR("unable to resize op in user key push response\n");
1858 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1862 if (copy_from_user(s->op, (void __user *) argp, size)) {
1863 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1867 do_response_to_request(s,&flags);
1868 // this will have unlocked s for us
1875 ERROR("unknown ioctl in user keyed stream\n");
1885 static int keyed_stream_release_user(struct inode *inode, struct file *filp)
1887 struct user_keyed_stream *s = filp->private_data;
1888 unsigned long f1,f2;
1890 palacios_spinlock_lock_irqsave(&(user_streams->lock),f1);
1891 palacios_spinlock_lock_irqsave(&(s->lock), f2);
1893 list_del(&(s->node));
1895 palacios_spinlock_unlock_irqrestore(&(s->lock), f2);
1896 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), f1);
1898 palacios_free(s->url);
1904 static struct file_operations user_keyed_stream_fops = {
1905 .poll = keyed_stream_poll_user,
1906 .compat_ioctl = keyed_stream_ioctl_user,
1907 .unlocked_ioctl = keyed_stream_ioctl_user,
1908 .release = keyed_stream_release_user,
1913 user_keyed_streams are allocated on user connect, and deallocated on user release
1915 palacios-side opens and closes only manipulate the open type
1918 int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned long arg, void *priv_data)
1921 unsigned long flags;
1924 struct user_keyed_stream *s;
1926 if (!user_streams) {
1927 ERROR("no user space keyed streams!\n");
1932 if (copy_from_user(&len,(void __user *)arg,sizeof(len))) {
1933 ERROR("cannot copy url len from user\n");
1937 url = palacios_alloc(len);
1940 ERROR("cannot allocate url for user keyed stream\n");
1944 if (copy_from_user(url,((void __user *)arg)+sizeof(len),len)) {
1945 ERROR("cannot copy url from user\n");
1951 // Check for duplicate handler
1952 palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
1953 list_for_each_entry(s, &(user_streams->streams), node) {
1954 if (!strncasecmp(url, s->url, len)) {
1955 ERROR("user keyed stream connection with url \"%s\" already exists\n", url);
1960 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
1962 // Create connection
1963 s = palacios_alloc(sizeof(struct user_keyed_stream));
1966 ERROR("cannot allocate new user keyed stream for %s\n",url);
1972 // Get file descriptor
1973 fd = anon_inode_getfd("v3-kstream", &user_keyed_stream_fops, s, 0);
1976 ERROR("cannot allocate file descriptor for new user keyed stream for %s\n",url);
1982 memset(s, 0, sizeof(struct user_keyed_stream));
1984 s->stype=STREAM_USER;
1987 init_waitqueue_head(&(s->user_wait_queue));
1988 init_waitqueue_head(&(s->host_wait_queue));
1990 // Insert connection into list
1991 palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
1992 list_add(&(s->node), &(user_streams->streams));
1993 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
1998 static struct user_keyed_stream *keyed_stream_user_find(char *url)
2000 unsigned long flags;
2001 struct user_keyed_stream *s;
2003 if (!user_streams) {
2004 ERROR("no user space keyed streams available\n");
2008 palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
2009 list_for_each_entry(s, &(user_streams->streams), node) {
2010 if (!strcasecmp(url, s->url)) {
2011 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
2016 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
2022 static v3_keyed_stream_t open_stream_user(char *url, v3_keyed_stream_open_t ot)
2024 unsigned long flags;
2025 struct user_keyed_stream *s;
2027 s = keyed_stream_user_find(url);
2030 ERROR("cannot open user stream %s as it does not exist yet\n",url);
2034 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2037 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
2038 ERROR("cannot open user stream %s as it is already in waiting state\n",url);
2042 s->otype = ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
2044 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
2050 // close stream does not do anything. Creation of the stream and its cleanup
2051 // are driven by the user side, not the palacios side
2052 // might eventually want to reference count this, though
2053 static void close_stream_user(v3_keyed_stream_t stream)
2058 static void preallocate_hint_key_user(v3_keyed_stream_t stream,
2068 static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key)
2070 unsigned long flags;
2071 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2072 uint64_t len = strlen(key)+1;
2075 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2078 if (resize_op(&(s->op),len)) {
2079 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2080 ERROR("cannot resize op in opening key %s on user keyed stream %s\n",key,s->url);
2084 s->op->type = PALACIOS_KSTREAM_OPEN_KEY;
2085 s->op->buf_len = len;
2086 strncpy(s->op->buf,key,len); // will terminate buffer
2088 // enter with it locked
2089 if (do_request_to_response(s,&flags)) {
2090 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2091 ERROR("request/response handling failed\n");
2094 // return with it locked
2096 user_key=s->op->user_key;
2098 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2103 static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key)
2105 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2107 unsigned long flags;
2109 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2111 if (resize_op(&(s->op),len)) {
2112 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2113 ERROR("cannot resize op in closing key 0x%p on user keyed stream %s\n",key,s->url);
2117 s->op->type = PALACIOS_KSTREAM_CLOSE_KEY;
2118 s->op->buf_len = len;
2119 s->op->user_key = key;
2121 // enter with it locked
2122 if (do_request_to_response(s,&flags)) {
2123 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2124 ERROR("request/response handling failed\n");
2127 // return with it locked
2129 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2136 static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2139 void *buf, sint64_t rlen)
2142 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2143 uint64_t len = taglen ;
2145 unsigned long flags;
2147 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2149 if (s->otype != V3_KS_RD_ONLY) {
2150 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2151 ERROR("attempt to read key from stream that is not in read state on %s\n",s->url);
2155 if (resize_op(&(s->op),len)) {
2156 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2157 ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
2161 s->op->type = PALACIOS_KSTREAM_READ_KEY;
2162 s->op->buf_len = len ;
2164 s->op->user_key = key;
2165 s->op->data_off = taglen;
2167 memcpy(s->op->buf,tag,taglen);
2169 // enter with it locked
2170 if (do_request_to_response(s,&flags)) {
2171 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2172 ERROR("request/response handling failed\n");
2175 // return with it locked
2178 if (s->op->xfer>0) {
2179 // data_off must be zero
2180 memcpy(buf,s->op->buf,s->op->xfer);
2185 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2191 static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2194 void *buf, sint64_t wlen)
2197 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2198 uint64_t len = taglen + wlen ;
2200 unsigned long flags;
2203 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2205 if (s->otype != V3_KS_WR_ONLY) {
2206 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2207 ERROR("attempt to write key on stream that is not in write state on %s\n",s->url);
2210 if (resize_op(&(s->op),len)) {
2211 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2212 ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
2216 s->op->type = PALACIOS_KSTREAM_WRITE_KEY;
2217 s->op->buf_len = len;
2219 s->op->user_key = key;
2220 s->op->data_off = taglen;
2222 memcpy(s->op->buf,tag,taglen);
2223 memcpy(s->op->buf+taglen,buf,wlen);
2225 // enter with it locked
2226 if (do_request_to_response(s,&flags)) {
2227 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2228 ERROR("request/response handling failed\n");
2231 // return with it locked
2233 // no data comes back, xfer should be size of data write (not tag)
2237 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2244 /****************************************************************************************
2245 * Network-based implementation ("net:")
2246 *****************************************************************************************/
2249 #define NET_MAX_KEY_LEN 128
2251 struct net_keyed_stream {
2254 struct net_stream * ns;
2259 struct socket *sock;
2263 //ignore the arguments given here currently
2264 static struct net_stream * create_net_stream(void)
2266 struct net_stream * ns = NULL;
2268 ns = palacios_alloc(sizeof(struct net_stream));
2271 ERROR("Cannot allocate a net_stream\n");
2275 memset(ns, 0, sizeof(struct net_stream));
2277 ns->stype = STREAM_NETWORK;
2282 static void close_socket(v3_keyed_stream_t stream)
2284 struct net_keyed_stream *nks = (struct net_keyed_stream *) stream;
2287 struct net_stream *ns = nks->ns;
2290 ns->sock->ops->release(ns->sock);
2292 ERROR("Close Socket\n");
2300 static void close_stream_net(v3_keyed_stream_t stream)
2302 close_socket(stream);
2305 static int connect_to_ip(struct net_stream *ns, int hostip, int port)
2307 struct sockaddr_in client;
2313 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&(ns->sock))<0) {
2314 ERROR("Cannot create accept socket\n");
2319 client.sin_family = AF_INET;
2320 client.sin_port = htons(port);
2321 client.sin_addr.s_addr = hostip;//in_aton(hostip);
2323 return ns->sock->ops->connect(ns->sock, (struct sockaddr *)&client, sizeof(client), 0);
2326 static int send_msg(struct net_stream *ns, char * buf, int len)
2331 ERROR("Send message on null net_stream\n");
2336 ERROR("Send message on net_stream without socket\n");
2348 msg.msg_flags = MSG_NOSIGNAL;//MSG_DONTWAIT;
2350 msg.msg_namelen = 0;
2351 msg.msg_control = NULL;
2352 msg.msg_controllen = 0;
2356 iov.iov_base = (char *)&(buf[len-left]);
2357 iov.iov_len = (size_t)left;
2362 err = sock_sendmsg(ns->sock, &msg, (size_t)left);
2367 ERROR("Send msg error %d\n",err);
2379 static int recv_msg(struct net_stream *ns, char * buf, int len)
2385 ERROR("Receive message on null net_stream\n");
2390 ERROR("Receive message on net_stream without socket\n");
2404 msg.msg_namelen = 0;
2405 msg.msg_control = NULL;
2406 msg.msg_controllen = 0;
2410 iov.iov_base = (void *)&(buf[len-left]);
2411 iov.iov_len = (size_t)left;
2416 err = sock_recvmsg(ns->sock, &msg, (size_t)left, 0);
2429 static struct net_stream * accept_once(struct net_stream * ns, const int port)
2431 struct socket *accept_sock;
2432 struct sockaddr_in addr;
2436 ERROR("Accept called on null net_stream\n");
2440 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&accept_sock)<0) {
2441 ERROR("Cannot create accept socket\n");
2446 addr.sin_family = AF_INET;
2447 addr.sin_port = htons(port);
2448 addr.sin_addr.s_addr = INADDR_ANY;
2450 err = accept_sock->ops->bind(accept_sock, (struct sockaddr *)&addr, sizeof(addr));
2453 ERROR("Bind err: %d\n",err);
2457 err = accept_sock->ops->listen(accept_sock,2);
2460 ERROR("Listen err: %d\n",err);
2464 // Init the socket in the network strream
2466 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&(ns->sock))<0) {
2467 ERROR("Cannot create socket\n");
2472 // Do the actual accept
2474 if (accept_sock->ops->accept(accept_sock,ns->sock,0)<0) {
2475 ERROR("accept failed");
2479 // close the accept socket
2480 accept_sock->ops->release(accept_sock);
2481 palacios_free(accept_sock);
2487 static struct v3_keyed_stream_t * open_stream_net(char * url,v3_keyed_stream_open_t ot)
2489 struct net_keyed_stream * nks;
2498 nks = palacios_alloc(sizeof(struct net_keyed_stream));
2501 ERROR("Could not allocate space in open_stream_net\n");
2505 nks->ot = ot == V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
2507 nks->stype = STREAM_NETWORK;
2509 nks->ns = create_net_stream();
2512 ERROR("Could not create network stream\n");
2517 url_len=strlen(url);
2521 for(i = 0; i < url_len;i++){
2528 mode = url[delimit[0] + 1];
2529 ip_len = delimit[2] - delimit[1];
2530 port_len = url_len - delimit[2];
2535 char port[port_len];
2540 strncpy(ip,url + delimit[1]+1,ip_len-1);
2543 host_ip = in_aton(ip);
2545 strncpy(port,url+ delimit[2]+1,port_len-1);
2546 port[port_len-1]='\0';
2548 host_port = simple_strtol(port,NULL,10);
2550 INFO("ip is %s\n",ip);
2551 INFO("host_ip is %x\n", host_ip);
2552 INFO("port is %s (%d)\n",port,host_port);
2556 INFO("Accepting Connection on INADDR_ANY port:%d\n",host_port);
2557 nks->ns = accept_once(nks->ns, host_port);
2558 } else if (mode == 'c'){
2559 // call connect to ip
2560 INFO("Connecting to %s:%d\n",ip,host_port);
2561 connect_to_ip(nks->ns,host_ip, host_port);
2563 ERROR("Mode not recognized\n");
2568 return (v3_keyed_stream_t)nks;
2572 static void preallocate_hint_key_net(v3_keyed_stream_t stream, char *key,uint64_t size)
2577 static v3_keyed_stream_key_t open_key_net(v3_keyed_stream_t stream,char *key)
2579 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2581 // reciever of the key name
2582 if (nks->ot==V3_KS_WR_ONLY)
2584 unsigned short keylen = strlen(key);
2586 if (keylen>NET_MAX_KEY_LEN || keylen>=32768) {
2587 ERROR("Key is too long\n");
2592 // on-stack allocation here demands that we
2593 // keep key length low...
2597 // Opening a key for writing sends a notice of the
2598 // key length and the key name on the channel
2600 msg[next++]=keylen & 0xFF;
2601 msg[next]=(keylen>>8) & 0xFF;
2603 msg[next]=msg[next] | 0x80; // 0x80 is 128 and OR will flip leading bit to 1
2605 strncpy(msg+2,key,keylen); // will also copy trailing zero
2607 if (send_msg(nks->ns,msg,keylen+2) != keylen+2) {
2608 ERROR("Unable to open key for writing on net_stream (send key len+name)\n");
2614 if (nks->ot==V3_KS_RD_ONLY) {
2619 if (recv_msg(nks->ns,msg_info,2) != 2) {
2620 ERROR("Unable to open key for reading on net_stream (recv key len)\n");
2627 keylen |= msg_info[next++];
2629 if ((msg_info[next] & 0x80) != 0x80) {
2630 ERROR("Flag bit not set on receive of key length\n");
2633 msg_info[next] &= 0x7F; // flip the msb back to zero (clear flag)
2636 keylen |= msg_info[next]<<8;
2638 if (keylen > NET_MAX_KEY_LEN) {
2639 ERROR("Received key length is too big\n");
2647 if (recv_msg(nks->ns,msg,keylen) != keylen) {
2648 ERROR("Unable to receive key\n");
2653 if (strncmp(key,msg,keylen)!=0) {
2654 ERROR("Key mismatch in open_key_net - expect %s but got %s\n",key,msg);
2660 return (v3_keyed_stream_key_t)key;
2663 static void close_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t input_key)
2665 char * key = (char*)input_key;
2666 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2669 if (nks->ot==V3_KS_WR_ONLY) {
2670 unsigned short keylen = strlen(key);
2672 if (keylen > NET_MAX_KEY_LEN || keylen>=32768) {
2673 ERROR("Key length too long in close_key_net\n");
2681 msg[next++]=keylen & 0xFF;
2682 msg[next]=(keylen>>8) & 0xFF;
2684 msg[next]=msg[next] | 0x80; // 0x80 is 128 and OR will filp leading bit to 1
2685 strncpy(msg+2,key,keylen); // will copy the zero
2687 if (send_msg(nks->ns,msg,keylen+2)!=keylen+2) {
2688 ERROR("Cannot send key on close_key_net\n");
2694 if (nks->ot==V3_KS_RD_ONLY) {
2699 if (recv_msg(nks->ns,msg_info,2) != 2) {
2700 ERROR("Cannot recv key length on close_key_net\n");
2707 keylen |= msg_info[next++];
2709 if ((msg_info[next] & 0x80) != 0x80) {
2710 ERROR("Missing flag in close_key_net receive\n");
2714 msg_info[next] &= 0x7F; // flip the msb back to zero
2716 keylen |= msg_info[next]<<8;
2721 if (recv_msg(nks->ns,msg,keylen)!=keylen) {
2722 ERROR("Did not receive all of key in close_key_net receive\n");
2728 if (strncmp(key,msg,keylen)!=0) {
2729 ERROR("Key mismatch in close_key_net - expect %s but got %s\n",key,msg);
2736 static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2739 void *buf, sint64_t len)
2741 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2744 ERROR("Buf is NULL in write_key_net\n");
2749 ERROR("Tag is NULL in write_key_net\n");
2754 ERROR("len is negative in write_key_net\n");
2759 ERROR("taglen is negative in write_key_net\n");
2764 ERROR("write_key: key is NULL in write_key_net\n");
2770 ERROR("nks is NULL in write_key_net\n");
2774 if (nks->ot==V3_KS_WR_ONLY) {
2775 if (send_msg(nks->ns,(char*)(&BOUNDARY_TAG),sizeof(BOUNDARY_TAG))!=sizeof(BOUNDARY_TAG)) {
2776 ERROR("Could not send boundary tag in write_key_net\n");
2779 if (send_msg(nks->ns,(char*)(&taglen),sizeof(taglen))!=sizeof(taglen)) {
2780 ERROR("Could not send tag length in write_key_net\n");
2783 if (send_msg(nks->ns,tag,taglen)!=taglen) {
2784 ERROR("Could not send tag in write_key_net\n");
2787 if (send_msg(nks->ns,(char*)(&len),sizeof(len))!=sizeof(len)) {
2788 ERROR("Could not send data length in write_key_net\n");
2791 if (send_msg(nks->ns,buf,len)!=len) {
2792 ERROR("Could not send data in write_key_net\n");
2796 ERROR("Permission not correct in write_key_net\n");
2804 static sint64_t read_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2807 void *buf, sint64_t len)
2809 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2813 ERROR("Buf is NULL in read_key_net\n");
2818 ERROR("Tag is NULL in read_key_net\n");
2823 ERROR("len is negative in read_key_net\n");
2828 ERROR("taglen is negative in read_key_net\n");
2833 ERROR("read_key: key is NULL in read_key_net\n");
2838 if (nks->ot==V3_KS_RD_ONLY) {
2843 if (recv_msg(nks->ns,(char*)(&tempbt),sizeof(tempbt))!=sizeof(tempbt)) {
2844 ERROR("Cannot receive boundary tag in read_key_net\n");
2848 if (tempbt!=BOUNDARY_TAG) {
2849 ERROR("Invalid boundary tag (received 0x%x\n",tempbt);
2853 temptag=palacios_alloc(taglen);
2855 ERROR("failed to allocate temptag\n");
2859 if (recv_msg(nks->ns,(char*)(&slen),sizeof(slen))!=sizeof(slen)) {
2860 ERROR("Cannot receive tag len in read_key_net\n");
2861 palacios_free(temptag);
2866 ERROR("Tag len expected does not matched tag len decoded in read_key_net\n");
2867 palacios_free(temptag);
2871 if (recv_msg(nks->ns,temptag,taglen)!=taglen) {
2872 ERROR("Cannot recieve tag in read_key_net\n");
2873 palacios_free(temptag);
2877 if (memcmp(temptag,tag,taglen)) {
2878 ERROR("Tag mismatch\n");
2879 palacios_free(temptag);
2883 if (recv_msg(nks->ns,(char*)(&slen),sizeof(slen))!=sizeof(slen)) {
2884 ERROR("Cannot receive data len in read_key_net\n");
2885 palacios_free(temptag);
2890 ERROR("Data len expected does not matched data len decoded in read_key_net\n");
2891 palacios_free(temptag);
2895 if (recv_msg(nks->ns,buf,len)!=len) {
2896 ERROR("Cannot recieve data in read_key_net\n");
2897 palacios_free(temptag);
2901 palacios_free(temptag);
2904 ERROR("Permissions incorrect for the stream in read_key_net\n");
2913 /***************************************************************************************************
2915 *************************************************************************************************/
2917 static v3_keyed_stream_t open_stream(char *url,
2918 v3_keyed_stream_open_t ot)
2920 if (!strncasecmp(url,"mem:",4)) {
2921 return open_stream_mem(url,ot);
2922 } else if (!strncasecmp(url,"file:",5)) {
2923 return open_stream_file(url,ot);
2924 } else if (!strncasecmp(url,"user:",5)) {
2925 return open_stream_user(url,ot);
2926 } else if (!strncasecmp(url,"net:",4)){
2927 return open_stream_net(url,ot);
2928 } else if (!strncasecmp(url,"textfile:",9)) {
2929 return open_stream_textfile(url,ot);
2931 ERROR("unsupported type in attempt to open keyed stream \"%s\"\n",url);
2936 static void close_stream(v3_keyed_stream_t stream)
2938 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2939 switch (gks->stype){
2941 return close_stream_mem(stream);
2944 return close_stream_file(stream);
2946 case STREAM_TEXTFILE:
2947 return close_stream_textfile(stream);
2950 return close_stream_user(stream);
2952 case STREAM_NETWORK:
2953 return close_stream_net(stream);
2956 ERROR("unknown stream type %d in close\n",gks->stype);
2961 static void preallocate_hint_key(v3_keyed_stream_t stream,
2965 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2966 switch (gks->stype){
2968 preallocate_hint_key_mem(stream,key,size);
2971 preallocate_hint_key_file(stream,key,size);
2973 case STREAM_TEXTFILE:
2974 preallocate_hint_key_textfile(stream,key,size);
2977 return preallocate_hint_key_user(stream,key,size);
2979 case STREAM_NETWORK:
2980 return preallocate_hint_key_net(stream,key,size);
2983 ERROR("unknown stream type %d in preallocate_hint_key\n",gks->stype);
2990 static v3_keyed_stream_key_t open_key(v3_keyed_stream_t stream,
2993 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2994 switch (gks->stype){
2996 return open_key_mem(stream,key);
2999 return open_key_file(stream,key);
3001 case STREAM_TEXTFILE:
3002 return open_key_textfile(stream,key);
3005 return open_key_user(stream,key);
3007 case STREAM_NETWORK:
3008 return open_key_net(stream, key);
3011 ERROR("unknown stream type %d in open_key\n",gks->stype);
3018 static void close_key(v3_keyed_stream_t stream,
3019 v3_keyed_stream_key_t key)
3021 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3022 switch (gks->stype){
3024 return close_key_mem(stream,key);
3027 return close_key_file(stream,key);
3029 case STREAM_TEXTFILE:
3030 return close_key_textfile(stream,key);
3033 return close_key_user(stream,key);
3035 case STREAM_NETWORK:
3036 return close_key_net(stream, key);
3039 ERROR("unknown stream type %d in close_key\n",gks->stype);
3046 static sint64_t write_key(v3_keyed_stream_t stream,
3047 v3_keyed_stream_key_t key,
3053 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3054 switch (gks->stype){
3056 return write_key_mem(stream,key,tag,taglen,buf,len);
3059 return write_key_file(stream,key,tag,taglen,buf,len);
3061 case STREAM_TEXTFILE:
3062 return write_key_textfile(stream,key,tag,taglen,buf,len);
3065 return write_key_user(stream,key,tag,taglen,buf,len);
3067 case STREAM_NETWORK:
3068 return write_key_net(stream,key,tag,taglen,buf,len);
3071 ERROR("unknown stream type %d in write_key\n",gks->stype);
3079 static sint64_t read_key(v3_keyed_stream_t stream,
3080 v3_keyed_stream_key_t key,
3086 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3087 switch (gks->stype){
3089 return read_key_mem(stream,key,tag,taglen,buf,len);
3092 return read_key_file(stream,key,tag,taglen,buf,len);
3094 case STREAM_TEXTFILE:
3095 return read_key_textfile(stream,key,tag,taglen,buf,len);
3098 return read_key_user(stream,key,tag,taglen,buf,len);
3100 case STREAM_NETWORK:
3101 return read_key_net(stream,key,tag,taglen,buf,len);
3104 ERROR("unknown stream type %d in read_key\n",gks->stype);
3114 /***************************************************************************************************
3115 Hooks to palacios and inititialization
3116 *************************************************************************************************/
3119 static struct v3_keyed_stream_hooks hooks = {
3120 .open = open_stream,
3121 .close = close_stream,
3122 .preallocate_hint_key = preallocate_hint_key,
3123 .open_key = open_key,
3124 .close_key = close_key,
3125 .read_key = read_key,
3126 .write_key = write_key
3130 static int init_keyed_streams( void )
3132 mem_streams = palacios_create_htable(DEF_NUM_STREAMS,hash_func,hash_comp);
3135 ERROR("failed to allocated stream pool for in-memory streams\n");
3139 user_streams = palacios_alloc(sizeof(struct user_keyed_streams));
3141 if (!user_streams) {
3142 ERROR("failed to allocated list for user streams\n");
3146 INIT_LIST_HEAD(&(user_streams->streams));
3148 palacios_spinlock_init(&(user_streams->lock));
3150 V3_Init_Keyed_Streams(&hooks);
3156 static int deinit_keyed_streams( void )
3158 palacios_free_htable(mem_streams,1,1);
3160 palacios_spinlock_deinit(&(user_streams->lock));
3162 palacios_free(user_streams);
3164 WARNING("Deinit of Palacios Keyed Streams likely leaked memory\n");
3170 static int guest_init_keyed_streams(struct v3_guest * guest, void ** vm_data )
3173 add_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT, keyed_stream_connect_user, 0);
3179 static int guest_deinit_keyed_streams(struct v3_guest * guest, void * vm_data)
3181 remove_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT);
3189 static struct linux_ext key_stream_ext = {
3190 .name = "KEYED_STREAM_INTERFACE",
3191 .init = init_keyed_streams,
3192 .deinit = deinit_keyed_streams,
3193 .guest_init = guest_init_keyed_streams,
3194 .guest_deinit = guest_deinit_keyed_streams,
3198 register_extension(&key_stream_ext);