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);
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);
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);
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);
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 strcpy(path,fks->path);
803 fs = (struct file_stream *) palacios_alloc(sizeof(struct file_stream));
806 ERROR("cannot allocate file keyed stream for key %s\n",key);
811 fs->stype=STREAM_FILE;
813 fs->f = filp_open(path,O_RDWR|O_CREAT|O_LARGEFILE,0600);
815 if (!fs->f || IS_ERR(fs->f)) {
816 ERROR("cannot open relevent file \"%s\" for stream \"file:%s\" and key \"%s\"\n",path,fks->path,key);
828 static void close_key_file(v3_keyed_stream_t stream,
829 v3_keyed_stream_key_t key)
831 struct file_stream *fs = (struct file_stream *) key;
833 filp_close(fs->f,NULL);
839 static sint64_t write_file(struct file_stream *fs, void *buf, sint64_t len)
841 ssize_t done, left, total;
850 done = fs->f->f_op->write(fs->f, buf+(total-left), left, &(fs->f->f_pos));
862 static sint64_t write_key_file(v3_keyed_stream_t stream,
863 v3_keyed_stream_key_t key,
869 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
870 struct file_stream *fs = (struct file_stream *) key;
873 if (fks->ot!=V3_KS_WR_ONLY) {
877 if (taglen<0 || len<0) {
878 ERROR("Negative taglen or data len\n");
882 writelen=write_file(fs,&BOUNDARY_TAG,sizeof(BOUNDARY_TAG));
884 if (writelen!=sizeof(BOUNDARY_TAG)) {
885 ERROR("failed to write all data for boundary tag\n");
889 writelen=write_file(fs,&taglen,sizeof(taglen));
891 if (writelen!=sizeof(taglen)) {
892 ERROR("failed to write taglen\n");
896 if (write_file(fs,tag,taglen)!=taglen) {
897 ERROR("failed to write tag\n");
901 writelen=write_file(fs,&len,sizeof(len));
903 if (writelen!=sizeof(len)) {
904 ERROR("failed to write data len\n");
908 return write_file(fs,buf,len);
911 static sint64_t read_file(struct file_stream *fs, void *buf, sint64_t len)
913 ssize_t done, left, total;
923 done = fs->f->f_op->read(fs->f, buf+(total-left), left, &(fs->f->f_pos));
936 static sint64_t read_key_file(v3_keyed_stream_t stream,
937 v3_keyed_stream_key_t key,
943 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
944 struct file_stream *fs = (struct file_stream *) key;
950 if (fks->ot!=V3_KS_RD_ONLY) {
954 if (len<0 || taglen<0) {
955 ERROR("taglen or data len is negative\n");
959 readlen=read_file(fs,&tempbt,sizeof(tempbt));
961 if (readlen!=sizeof(tempbt)) {
962 ERROR("failed to read all data for boundary tag\n");
966 if (tempbt!=BOUNDARY_TAG) {
967 ERROR("boundary tag not found (read 0x%x)\n",tempbt);
971 readlen=read_file(fs,&templen,sizeof(templen));
973 if (readlen!=sizeof(templen)) {
974 ERROR("failed to read all data for tag len\n");
978 if (templen!=taglen) {
979 ERROR("tag size mismatch (requested=%lld, actual=%lld)\n",taglen,templen);
983 temptag=palacios_alloc(taglen);
986 ERROR("Cannot allocate temptag\n");
990 if (read_file(fs,temptag,taglen)!=taglen) {
991 ERROR("Cannot read tag\n");
992 palacios_free(temptag);
996 if (memcmp(temptag,tag,taglen)) {
997 ERROR("Tag mismatch\n");
998 palacios_free(temptag);
1002 palacios_free(temptag);
1004 readlen=read_file(fs,&templen,sizeof(templen));
1006 if (readlen!=sizeof(templen)) {
1007 ERROR("failed to read all data for data len\n");
1012 ERROR("datasize mismatch (requested=%lld, actual=%lld)\n",len,templen);
1016 return read_file(fs,buf,len);
1021 /***************************************************************************************************
1022 Textfile-based implementation ("textfile:")
1024 Note that this implementation uses the internal structure and functions of the
1025 "file:" implementation
1026 *************************************************************************************************/
1028 // optimize the reading and decoding of hex data
1029 // this weakens the parser, so that:
1033 // will not. Note the leading whitespace
1034 #define TEXTFILE_OPT_HEX 0
1037 // The number of bytes handled at a time by the hex putter and getter
1039 #define MAX_HEX_SEQ 64
1042 A text file keyed stream is a file_keyed_stream,
1043 only with a different stype
1047 //#define PAUSE() ssleep(5)
1050 typedef struct file_keyed_stream textfile_keyed_stream;
1052 typedef struct file_stream textfile_stream;
1055 static v3_keyed_stream_t open_stream_textfile(char *url,
1056 v3_keyed_stream_open_t ot)
1058 textfile_keyed_stream *me;
1060 if (strncasecmp(url,"textfile:",9)) {
1061 WARNING("illegitimate attempt to open textfile stream \"%s\"\n",url);
1065 me = (textfile_keyed_stream *) open_stream_file(url+4, ot);
1068 ERROR("could not create underlying file stream\n");
1072 me->stype=STREAM_TEXTFILE;
1079 static void close_stream_textfile(v3_keyed_stream_t stream)
1081 textfile_keyed_stream *me = stream;
1083 me->stype=STREAM_FILE;
1085 close_stream_file(me);
1089 static void preallocate_hint_key_textfile(v3_keyed_stream_t stream,
1093 textfile_keyed_stream *me = stream;
1095 me->stype=STREAM_FILE;
1097 preallocate_hint_key_file(me,key,size);
1099 me->stype=STREAM_TEXTFILE;
1104 static inline int isoneof(char c, char *sl, int m)
1117 static char get_next_char(textfile_stream *s)
1120 if (read_file(s,&buf,1)!=1) {
1126 static char hexify_nybble(char c)
1130 } else if (c>=0xa && c<=0xf) {
1137 static int hexify_byte(char *c, char b)
1140 n = hexify_nybble( (b >> 4) & 0xf);
1145 n = hexify_nybble( b & 0xf);
1154 static char dehexify_nybble(char c)
1156 if (c>='0' && c<='9') {
1158 } else if (c>='a' && c<='f') {
1159 return 0xa + (c-'a');
1160 } else if (c>='A' && c<='F') {
1161 return 0xa + (c-'A');
1167 static int dehexify_byte(char *c, char *b)
1170 n = dehexify_nybble(c[0]);
1175 n = dehexify_nybble(c[1]);
1184 #if TEXTFILE_OPT_HEX
1187 // Here the sl array, of length m is the number
1188 static int get_hexbytes_as_data(textfile_stream *s, char *buf, int n)
1190 char rbuf[MAX_HEX_SEQ*2];
1197 cur = left > MAX_HEX_SEQ ? MAX_HEX_SEQ : left;
1198 if (read_file(s,rbuf,cur*2)!=cur*2) {
1199 ERROR("Cannot read data in getting hexbytes as data\n");
1203 for (i=0;i<cur;i++) {
1204 if (dehexify_byte(rbuf+(i*2),buf+off+i)==-1) {
1205 ERROR("Cannot decode data as hex in getting hexbytes as data\n");
1218 // Here the sl array, of length m is the set of characters to skip (e.g., whitespace)
1219 static int get_hexbytes_as_data_skip(textfile_stream *s, char *buf, int n, char *sl, int m)
1228 rbuf[which] = get_next_char(s);
1229 if (rbuf[which]==-1) {
1230 ERROR("Cannot read char in getting hexbytes as data with skiplist");
1233 if (isoneof(rbuf[which],sl,m)) {
1239 if (dehexify_byte(rbuf,buf+cur)==-1) {
1240 ERROR("Cannot decode data as hex in getting hexbytes as data with skiplist\n");
1250 static int put_next_char(textfile_stream *s, char d)
1252 return write_file(s,&d,1);
1257 static int put_data_as_hexbytes(textfile_stream *s, char *buf, int n)
1259 char rbuf[MAX_HEX_SEQ*2];
1266 cur = left > MAX_HEX_SEQ ? MAX_HEX_SEQ : left;
1267 for (i=0;i<cur;i++) {
1268 if (hexify_byte(rbuf+(i*2),*(buf+off+i))==-1) {
1269 ERROR("Cannot encode data as hex in putting data as hexbytes\n");
1273 if (write_file(s,rbuf,cur*2)!=cur*2) {
1274 ERROR("Cannot write data in putting data as hexbytes\n");
1285 static int put_string_n(textfile_stream *s, char *buf, int n)
1289 rc = write_file(s,buf,n);
1298 static int put_string(textfile_stream *s, char *buf)
1302 return put_string_n(s,buf,n);
1307 static int search_for(textfile_stream *s, char d)
1312 } while (c!=-1 && c!=d);
1322 static int skip_matching(textfile_stream *s, char *m, int n)
1345 return rc; // unknown
1352 static int token_scan(textfile_stream *s, char *token, int n, char *sl, int m)
1361 ERROR("Failed to get character during token scan (preceding whitespace)\n");
1364 } while (isoneof(c,sl,m));
1374 ERROR("Failed to get character during token scan (token)\n");
1377 if (isoneof(c,sl,m)) {
1390 static v3_keyed_stream_key_t open_key_textfile(v3_keyed_stream_t stream,
1393 textfile_keyed_stream *mks = stream;
1394 textfile_stream *ms;
1396 mks->stype=STREAM_FILE;
1398 ms = open_key_file(mks,key);
1401 ERROR("cannot open underlying file keyed stream for key %s\n",key);
1402 mks->stype=STREAM_TEXTFILE;
1406 if (mks->ot==V3_KS_WR_ONLY) {
1408 // Now we write the section header
1410 ms->stype=STREAM_FILE;
1412 if (put_string(ms,"[")) {
1413 close_key_file(mks,ms);
1414 mks->stype=STREAM_TEXTFILE;
1418 if (put_string(ms,key)) {
1419 close_key_file(mks,ms);
1420 mks->stype=STREAM_TEXTFILE;
1424 if (put_string(ms,"]\n")) {
1425 close_key_file(mks,ms);
1426 mks->stype=STREAM_TEXTFILE;
1431 mks->stype=STREAM_TEXTFILE;
1432 ms->stype=STREAM_TEXTFILE;
1436 } else if (mks->ot == V3_KS_RD_ONLY) {
1437 // Now we readthe section header
1438 int keylen=strlen(key);
1439 char *tempkey = palacios_alloc(keylen+3);
1441 ms->stype=STREAM_FILE;
1444 ERROR("Allocation failed in opening key\n");
1445 close_key_file(mks,ms);
1446 mks->stype=STREAM_FILE;
1451 if (token_scan(ms,tempkey,keylen+3,"\t\r\n",3)) {
1452 ERROR("Cannot scan for token (key search)\n");
1453 close_key_file(mks,ms);
1454 mks->stype=STREAM_TEXTFILE;
1455 palacios_free(tempkey);
1459 tempkey[keylen+2] = 0;
1461 // Should now have [key]0
1463 if (tempkey[0]!='[' ||
1464 tempkey[keylen+1]!=']' ||
1465 memcmp(key,tempkey+1,keylen)) {
1466 ERROR("key mismatch: target key=%s, found %s\n",key,tempkey);
1467 palacios_free(tempkey);
1468 close_key_file(mks,ms);
1469 mks->stype=STREAM_TEXTFILE;
1473 // key match done, success
1475 mks->stype=STREAM_TEXTFILE;
1476 ms->stype=STREAM_TEXTFILE;
1478 palacios_free(tempkey);
1483 ERROR("Unknown open type in open_key_textfile\n");
1484 ms->stype=STREAM_FILE;
1485 close_key_file(mks,ms);
1493 static void close_key_textfile(v3_keyed_stream_t stream,
1494 v3_keyed_stream_key_t key)
1496 textfile_keyed_stream *mks = stream;
1497 textfile_stream *ms=key;
1499 mks->stype=STREAM_FILE;
1500 ms->stype=STREAM_FILE;
1502 close_key_file(mks,ms);
1504 mks->stype=STREAM_TEXTFILE;
1509 static sint64_t read_key_textfile(v3_keyed_stream_t stream,
1510 v3_keyed_stream_key_t key,
1516 textfile_stream *ms = (textfile_stream *) key;
1522 memcpy(tags,tag,taglen<31 ? taglen : 31);
1523 tags[taglen<32? taglen : 31 ]=0;
1525 temptag=palacios_alloc(taglen+1);
1527 ERROR("Unable to allocate temptag in textfile read key\n");
1531 ms->stype=STREAM_FILE;
1533 if (token_scan(ms,temptag,taglen+1," \t\r\n=",5)) {
1534 ERROR("Cannot scan for token (tag search)\n");
1535 ms->stype=STREAM_TEXTFILE;
1536 palacios_free(temptag);
1540 if (memcmp(tag,temptag,taglen)) {
1541 ERROR("Tag mismatch in reading tag from textfile: desired tag=%s, actual tag=%s\n",tags,temptag);
1542 ms->stype=STREAM_TEXTFILE;
1543 palacios_free(temptag);
1547 // tag matches, let's go and find our =
1548 palacios_free(temptag);
1550 if (search_for(ms,'=')) {
1551 ERROR("Unable to find = sign in tag data parse (tag=%s)\n", tags);
1552 ms->stype=STREAM_TEXTFILE;
1557 #if TEXTFILE_OPT_HEX
1558 if (get_hexbytes_as_data(ms,buf,len)) {
1559 ERROR("Cannot read data in hex format (opt path) in textfile for tag %s\n",tags);
1560 ms->stype=STREAM_TEXTFILE;
1564 if (get_hexbytes_as_data_skip(ms,buf,len," \t\r\n",4)) {
1565 ERROR("Cannot read data in hex format (unopt path) in textfile for tag %s\n",tags);
1566 ms->stype=STREAM_TEXTFILE;
1571 ms->stype=STREAM_TEXTFILE;
1576 static sint64_t write_key_textfile(v3_keyed_stream_t stream,
1577 v3_keyed_stream_key_t key,
1583 textfile_stream *ms = (textfile_stream *) key;
1588 memcpy(tags,tag,taglen<31 ? taglen : 31);
1589 tags[taglen<32? taglen : 31 ]=0;
1591 /* if (taglen>100000 || len>100000) {
1597 ms->stype=STREAM_FILE;
1599 if (put_string_n(ms,tag,taglen)) {
1600 ERROR("Cannot write tag %s in textfile\n",tags);
1601 ms->stype=STREAM_TEXTFILE;
1605 if (put_string(ms,"=")) {
1606 ERROR("Cannot write = in textfile for tag %s\n",tags);
1607 ms->stype=STREAM_TEXTFILE;
1611 if (put_data_as_hexbytes(ms,buf,len)) {
1612 ERROR("Cannot write data in hex format in textfile for tag %s\n",tags);
1613 ms->stype=STREAM_TEXTFILE;
1617 if (put_string(ms,"\n")) {
1618 ERROR("Cannot write trailing lf in textfile for tag %s\n",tags);
1619 ms->stype=STREAM_TEXTFILE;
1623 ms->stype=STREAM_TEXTFILE;
1630 /***************************************************************************************************
1631 User implementation ("user:")
1632 *************************************************************************************************/
1635 // List of all user keyed stream connections for the guest
1636 struct user_keyed_streams {
1638 struct list_head streams;
1642 // A single keyed stream connection to user space
1643 struct user_keyed_stream {
1645 v3_keyed_stream_open_t otype;
1651 wait_queue_head_t user_wait_queue;
1652 wait_queue_head_t host_wait_queue;
1654 struct palacios_user_keyed_stream_op *op;
1656 struct list_head node;
1661 // List of all of the user streams
1663 static struct user_keyed_streams *user_streams;
1667 static int resize_op(struct palacios_user_keyed_stream_op **op, uint64_t buf_len)
1669 struct palacios_user_keyed_stream_op *old = *op;
1670 struct palacios_user_keyed_stream_op *new;
1673 new = palacios_alloc(sizeof(struct palacios_user_keyed_stream_op)+buf_len);
1677 new->len=sizeof(struct palacios_user_keyed_stream_op)+buf_len;
1678 new->buf_len=buf_len;
1683 if ((old->len-sizeof(struct palacios_user_keyed_stream_op)) >= buf_len) {
1684 old->buf_len=buf_len;
1689 return resize_op(op,buf_len);
1695 // The assumption is that we enter this with the stream locked
1696 // and we will return with it locked; additionally, the op structure
1697 // will be overwritten with the response
1699 static int do_request_to_response(struct user_keyed_stream *s, unsigned long *flags)
1703 ERROR("user keyed stream request attempted while one is already in progress on %s\n",s->url);
1707 // we are now waiting for a response
1710 // release the stream
1711 palacios_spinlock_unlock_irqrestore(&(s->lock), *flags);
1713 // wake up anyone waiting on it
1714 wake_up_interruptible(&(s->user_wait_queue));
1716 // wait for someone to give us a response
1717 while (wait_event_interruptible(s->host_wait_queue, (s->waiting == 0)) != 0) {}
1719 // reacquire the lock for our called
1720 palacios_spinlock_lock_irqsave(&(s->lock), *flags);
1726 // The assumption is that we enter this with the stream locked
1727 // and we will return with it UNlocked
1729 static int do_response_to_request(struct user_keyed_stream *s, unsigned long *flags)
1732 if (!(s->waiting)) {
1733 ERROR("user keyed stream response while no request is in progress on %s\n",s->url);
1737 // we are now waiting for a request
1740 // release the stream
1741 palacios_spinlock_unlock_irqrestore(&(s->lock), *flags);
1743 // wake up anyone waiting on it
1744 wake_up_interruptible(&(s->host_wait_queue));
1751 static unsigned int keyed_stream_poll_user(struct file *filp, poll_table *wait)
1753 struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
1754 unsigned long flags;
1760 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1762 poll_wait(filp, &(s->user_wait_queue), wait);
1765 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1766 return POLLIN | POLLRDNORM;
1769 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1774 static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsigned long arg)
1776 void __user *argp = (void __user *)arg;
1777 unsigned long flags;
1780 struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
1784 case V3_KSTREAM_REQUEST_SIZE_IOCTL:
1786 // inform request size
1788 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1790 if (!(s->waiting)) {
1791 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1795 size = sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
1797 if (copy_to_user((void * __user) argp, &size, sizeof(uint64_t))) {
1798 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1799 ERROR("palacios user key size request failed to copy data\n");
1803 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1809 case V3_KSTREAM_REQUEST_PULL_IOCTL:
1813 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1815 if (!(s->waiting)) {
1816 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1817 ERROR("palacios user key pull request when not waiting\n");
1821 size = sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
1824 if (copy_to_user((void __user *) argp, s->op, size)) {
1825 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1826 ERROR("palacios user key pull request failed to copy data\n");
1830 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1837 case V3_KSTREAM_RESPONSE_PUSH_IOCTL:
1839 // push the response
1841 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1843 if (!(s->waiting)) {
1844 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1845 ERROR("palacios user key push response when not waiting\n");
1849 if (copy_from_user(&size, (void __user *) argp, sizeof(uint64_t))) {
1850 ERROR("palacios user key push response failed to copy size\n");
1851 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1855 if (resize_op(&(s->op),size-sizeof(struct palacios_user_keyed_stream_op))) {
1856 ERROR("unable to resize op in user key push response\n");
1857 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1861 if (copy_from_user(s->op, (void __user *) argp, size)) {
1862 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1866 do_response_to_request(s,&flags);
1867 // this will have unlocked s for us
1874 ERROR("unknown ioctl in user keyed stream\n");
1884 static int keyed_stream_release_user(struct inode *inode, struct file *filp)
1886 struct user_keyed_stream *s = filp->private_data;
1887 unsigned long f1,f2;
1889 palacios_spinlock_lock_irqsave(&(user_streams->lock),f1);
1890 palacios_spinlock_lock_irqsave(&(s->lock), f2);
1892 list_del(&(s->node));
1894 palacios_spinlock_unlock_irqrestore(&(s->lock), f2);
1895 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), f1);
1897 palacios_free(s->url);
1903 static struct file_operations user_keyed_stream_fops = {
1904 .poll = keyed_stream_poll_user,
1905 .compat_ioctl = keyed_stream_ioctl_user,
1906 .unlocked_ioctl = keyed_stream_ioctl_user,
1907 .release = keyed_stream_release_user,
1912 user_keyed_streams are allocated on user connect, and deallocated on user release
1914 palacios-side opens and closes only manipulate the open type
1917 int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned long arg, void *priv_data)
1920 unsigned long flags;
1923 struct user_keyed_stream *s;
1925 if (!user_streams) {
1926 ERROR("no user space keyed streams!\n");
1931 if (copy_from_user(&len,(void __user *)arg,sizeof(len))) {
1932 ERROR("cannot copy url len from user\n");
1936 url = palacios_alloc(len);
1939 ERROR("cannot allocate url for user keyed stream\n");
1943 if (copy_from_user(url,((void __user *)arg)+sizeof(len),len)) {
1944 ERROR("cannot copy url from user\n");
1950 // Check for duplicate handler
1951 palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
1952 list_for_each_entry(s, &(user_streams->streams), node) {
1953 if (!strncasecmp(url, s->url, len)) {
1954 ERROR("user keyed stream connection with url \"%s\" already exists\n", url);
1959 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
1961 // Create connection
1962 s = palacios_alloc(sizeof(struct user_keyed_stream));
1965 ERROR("cannot allocate new user keyed stream for %s\n",url);
1971 // Get file descriptor
1972 fd = anon_inode_getfd("v3-kstream", &user_keyed_stream_fops, s, 0);
1975 ERROR("cannot allocate file descriptor for new user keyed stream for %s\n",url);
1981 memset(s, 0, sizeof(struct user_keyed_stream));
1983 s->stype=STREAM_USER;
1986 init_waitqueue_head(&(s->user_wait_queue));
1987 init_waitqueue_head(&(s->host_wait_queue));
1989 // Insert connection into list
1990 palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
1991 list_add(&(s->node), &(user_streams->streams));
1992 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
1997 static struct user_keyed_stream *keyed_stream_user_find(char *url)
1999 unsigned long flags;
2000 struct user_keyed_stream *s;
2002 if (!user_streams) {
2003 ERROR("no user space keyed streams available\n");
2007 palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
2008 list_for_each_entry(s, &(user_streams->streams), node) {
2009 if (!strcasecmp(url, s->url)) {
2010 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
2015 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
2021 static v3_keyed_stream_t open_stream_user(char *url, v3_keyed_stream_open_t ot)
2023 unsigned long flags;
2024 struct user_keyed_stream *s;
2026 s = keyed_stream_user_find(url);
2029 ERROR("cannot open user stream %s as it does not exist yet\n",url);
2033 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2036 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
2037 ERROR("cannot open user stream %s as it is already in waiting state\n",url);
2041 s->otype = ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
2043 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
2049 // close stream does not do anything. Creation of the stream and its cleanup
2050 // are driven by the user side, not the palacios side
2051 // might eventually want to reference count this, though
2052 static void close_stream_user(v3_keyed_stream_t stream)
2057 static void preallocate_hint_key_user(v3_keyed_stream_t stream,
2067 static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key)
2069 unsigned long flags;
2070 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2071 uint64_t len = strlen(key)+1;
2074 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2077 if (resize_op(&(s->op),len)) {
2078 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2079 ERROR("cannot resize op in opening key %s on user keyed stream %s\n",key,s->url);
2083 s->op->type = PALACIOS_KSTREAM_OPEN_KEY;
2084 s->op->buf_len = len;
2085 strncpy(s->op->buf,key,len);
2087 // enter with it locked
2088 if (do_request_to_response(s,&flags)) {
2089 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2090 ERROR("request/response handling failed\n");
2093 // return with it locked
2095 user_key=s->op->user_key;
2097 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2102 static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key)
2104 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2106 unsigned long flags;
2108 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2110 if (resize_op(&(s->op),len)) {
2111 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2112 ERROR("cannot resize op in closing key 0x%p on user keyed stream %s\n",key,s->url);
2116 s->op->type = PALACIOS_KSTREAM_CLOSE_KEY;
2117 s->op->buf_len = len;
2118 s->op->user_key = key;
2120 // enter with it locked
2121 if (do_request_to_response(s,&flags)) {
2122 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2123 ERROR("request/response handling failed\n");
2126 // return with it locked
2128 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2135 static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2138 void *buf, sint64_t rlen)
2141 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2142 uint64_t len = taglen ;
2144 unsigned long flags;
2146 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2148 if (s->otype != V3_KS_RD_ONLY) {
2149 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2150 ERROR("attempt to read key from stream that is not in read state on %s\n",s->url);
2154 if (resize_op(&(s->op),len)) {
2155 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2156 ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
2160 s->op->type = PALACIOS_KSTREAM_READ_KEY;
2161 s->op->buf_len = len ;
2163 s->op->user_key = key;
2164 s->op->data_off = taglen;
2166 memcpy(s->op->buf,tag,taglen);
2168 // enter with it locked
2169 if (do_request_to_response(s,&flags)) {
2170 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2171 ERROR("request/response handling failed\n");
2174 // return with it locked
2177 if (s->op->xfer>0) {
2178 // data_off must be zero
2179 memcpy(buf,s->op->buf,s->op->xfer);
2184 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2190 static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2193 void *buf, sint64_t wlen)
2196 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2197 uint64_t len = taglen + wlen ;
2199 unsigned long flags;
2202 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2204 if (s->otype != V3_KS_WR_ONLY) {
2205 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2206 ERROR("attempt to write key on stream that is not in write state on %s\n",s->url);
2209 if (resize_op(&(s->op),len)) {
2210 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2211 ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
2215 s->op->type = PALACIOS_KSTREAM_WRITE_KEY;
2216 s->op->buf_len = len;
2218 s->op->user_key = key;
2219 s->op->data_off = taglen;
2221 memcpy(s->op->buf,tag,taglen);
2222 memcpy(s->op->buf+taglen,buf,wlen);
2224 // enter with it locked
2225 if (do_request_to_response(s,&flags)) {
2226 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2227 ERROR("request/response handling failed\n");
2230 // return with it locked
2232 // no data comes back, xfer should be size of data write (not tag)
2236 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2243 /****************************************************************************************
2244 * Network-based implementation ("net:")
2245 *****************************************************************************************/
2248 #define NET_MAX_KEY_LEN 128
2250 struct net_keyed_stream {
2253 struct net_stream * ns;
2258 struct socket *sock;
2262 //ignore the arguments given here currently
2263 static struct net_stream * create_net_stream(void)
2265 struct net_stream * ns = NULL;
2267 ns = palacios_alloc(sizeof(struct net_stream));
2270 ERROR("Cannot allocate a net_stream\n");
2274 memset(ns, 0, sizeof(struct net_stream));
2276 ns->stype = STREAM_NETWORK;
2281 static void close_socket(v3_keyed_stream_t stream)
2283 struct net_keyed_stream *nks = (struct net_keyed_stream *) stream;
2286 struct net_stream *ns = nks->ns;
2289 ns->sock->ops->release(ns->sock);
2291 ERROR("Close Socket\n");
2299 static void close_stream_net(v3_keyed_stream_t stream)
2301 close_socket(stream);
2304 static int connect_to_ip(struct net_stream *ns, int hostip, int port)
2306 struct sockaddr_in client;
2312 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&(ns->sock))<0) {
2313 ERROR("Cannot create accept socket\n");
2318 client.sin_family = AF_INET;
2319 client.sin_port = htons(port);
2320 client.sin_addr.s_addr = hostip;//in_aton(hostip);
2322 return ns->sock->ops->connect(ns->sock, (struct sockaddr *)&client, sizeof(client), 0);
2325 static int send_msg(struct net_stream *ns, char * buf, int len)
2330 ERROR("Send message on null net_stream\n");
2335 ERROR("Send message on net_stream without socket\n");
2347 msg.msg_flags = MSG_NOSIGNAL;//MSG_DONTWAIT;
2349 msg.msg_namelen = 0;
2350 msg.msg_control = NULL;
2351 msg.msg_controllen = 0;
2355 iov.iov_base = (char *)&(buf[len-left]);
2356 iov.iov_len = (size_t)left;
2361 err = sock_sendmsg(ns->sock, &msg, (size_t)left);
2366 ERROR("Send msg error %d\n",err);
2378 static int recv_msg(struct net_stream *ns, char * buf, int len)
2384 ERROR("Receive message on null net_stream\n");
2389 ERROR("Receive message on net_stream without socket\n");
2403 msg.msg_namelen = 0;
2404 msg.msg_control = NULL;
2405 msg.msg_controllen = 0;
2409 iov.iov_base = (void *)&(buf[len-left]);
2410 iov.iov_len = (size_t)left;
2415 err = sock_recvmsg(ns->sock, &msg, (size_t)left, 0);
2428 static struct net_stream * accept_once(struct net_stream * ns, const int port)
2430 struct socket *accept_sock;
2431 struct sockaddr_in addr;
2435 ERROR("Accept called on null net_stream\n");
2439 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&accept_sock)<0) {
2440 ERROR("Cannot create accept socket\n");
2445 addr.sin_family = AF_INET;
2446 addr.sin_port = htons(port);
2447 addr.sin_addr.s_addr = INADDR_ANY;
2449 err = accept_sock->ops->bind(accept_sock, (struct sockaddr *)&addr, sizeof(addr));
2452 ERROR("Bind err: %d\n",err);
2456 err = accept_sock->ops->listen(accept_sock,2);
2459 ERROR("Listen err: %d\n",err);
2463 // Init the socket in the network strream
2465 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&(ns->sock))<0) {
2466 ERROR("Cannot create socket\n");
2471 // Do the actual accept
2473 if (accept_sock->ops->accept(accept_sock,ns->sock,0)<0) {
2474 ERROR("accept failed");
2478 // close the accept socket
2479 accept_sock->ops->release(accept_sock);
2480 palacios_free(accept_sock);
2486 static struct v3_keyed_stream_t * open_stream_net(char * url,v3_keyed_stream_open_t ot)
2488 struct net_keyed_stream * nks;
2497 nks = palacios_alloc(sizeof(struct net_keyed_stream));
2500 ERROR("Could not allocate space in open_stream_net\n");
2504 nks->ot = ot == V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
2506 nks->stype = STREAM_NETWORK;
2508 nks->ns = create_net_stream();
2511 ERROR("Could not create network stream\n");
2516 url_len=strlen(url);
2520 for(i = 0; i < url_len;i++){
2527 mode = url[delimit[0] + 1];
2528 ip_len = delimit[2] - delimit[1];
2529 port_len = url_len - delimit[2];
2534 char port[port_len];
2539 strncpy(ip,url + delimit[1]+1,ip_len-1);
2542 host_ip = in_aton(ip);
2544 strncpy(port,url+ delimit[2]+1,port_len-1);
2545 port[port_len-1]='\0';
2547 host_port = simple_strtol(port,NULL,10);
2549 INFO("ip is %s\n",ip);
2550 INFO("host_ip is %x\n", host_ip);
2551 INFO("port is %s (%d)\n",port,host_port);
2555 INFO("Accepting Connection on INADDR_ANY port:%d\n",host_port);
2556 nks->ns = accept_once(nks->ns, host_port);
2557 } else if (mode == 'c'){
2558 // call connect to ip
2559 INFO("Connecting to %s:%d\n",ip,host_port);
2560 connect_to_ip(nks->ns,host_ip, host_port);
2562 ERROR("Mode not recognized\n");
2567 return (v3_keyed_stream_t)nks;
2571 static void preallocate_hint_key_net(v3_keyed_stream_t stream, char *key,uint64_t size)
2576 static v3_keyed_stream_key_t open_key_net(v3_keyed_stream_t stream,char *key)
2578 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2580 // reciever of the key name
2581 if (nks->ot==V3_KS_WR_ONLY)
2583 unsigned short keylen = strlen(key);
2585 if (keylen>NET_MAX_KEY_LEN || keylen>=32768) {
2586 ERROR("Key is too long\n");
2591 // on-stack allocation here demands that we
2592 // keep key length low...
2596 // Opening a key for writing sends a notice of the
2597 // key length and the key name on the channel
2599 msg[next++]=keylen & 0xFF;
2600 msg[next]=(keylen>>8) & 0xFF;
2602 msg[next]=msg[next] | 0x80; // 0x80 is 128 and OR will flip leading bit to 1
2604 strncpy(msg+2,key,keylen); // will also copy trailing zero
2606 if (send_msg(nks->ns,msg,keylen+2) != keylen+2) {
2607 ERROR("Unable to open key for writing on net_stream (send key len+name)\n");
2613 if (nks->ot==V3_KS_RD_ONLY) {
2618 if (recv_msg(nks->ns,msg_info,2) != 2) {
2619 ERROR("Unable to open key for reading on net_stream (recv key len)\n");
2626 keylen |= msg_info[next++];
2628 if ((msg_info[next] & 0x80) != 0x80) {
2629 ERROR("Flag bit not set on receive of key length\n");
2632 msg_info[next] &= 0x7F; // flip the msb back to zero (clear flag)
2635 keylen |= msg_info[next]<<8;
2637 if (keylen > NET_MAX_KEY_LEN) {
2638 ERROR("Received key length is too big\n");
2646 if (recv_msg(nks->ns,msg,keylen) != keylen) {
2647 ERROR("Unable to receive key\n");
2652 if (strncmp(key,msg,keylen)!=0) {
2653 ERROR("Key mismatch in open_key_net - expect %s but got %s\n",key,msg);
2659 return (v3_keyed_stream_key_t)key;
2662 static void close_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t input_key)
2664 char * key = (char*)input_key;
2665 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2668 if (nks->ot==V3_KS_WR_ONLY) {
2669 unsigned short keylen = strlen(key);
2671 if (keylen > NET_MAX_KEY_LEN || keylen>=32768) {
2672 ERROR("Key length too long in close_key_net\n");
2680 msg[next++]=keylen & 0xFF;
2681 msg[next]=(keylen>>8) & 0xFF;
2683 msg[next]=msg[next] | 0x80; // 0x80 is 128 and OR will filp leading bit to 1
2684 strncpy(msg+2,key,keylen); // will copy the zero
2686 if (send_msg(nks->ns,msg,keylen+2)!=keylen+2) {
2687 ERROR("Cannot send key on close_key_net\n");
2693 if (nks->ot==V3_KS_RD_ONLY) {
2698 if (recv_msg(nks->ns,msg_info,2) != 2) {
2699 ERROR("Cannot recv key length on close_key_net\n");
2706 keylen |= msg_info[next++];
2708 if ((msg_info[next] & 0x80) != 0x80) {
2709 ERROR("Missing flag in close_key_net receive\n");
2713 msg_info[next] &= 0x7F; // flip the msb back to zero
2715 keylen |= msg_info[next]<<8;
2720 if (recv_msg(nks->ns,msg,keylen)!=keylen) {
2721 ERROR("Did not receive all of key in close_key_net receive\n");
2727 if (strncmp(key,msg,keylen)!=0) {
2728 ERROR("Key mismatch in close_key_net - expect %s but got %s\n",key,msg);
2735 static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2738 void *buf, sint64_t len)
2740 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2743 ERROR("Buf is NULL in write_key_net\n");
2748 ERROR("Tag is NULL in write_key_net\n");
2753 ERROR("len is negative in write_key_net\n");
2758 ERROR("taglen is negative in write_key_net\n");
2763 ERROR("write_key: key is NULL in write_key_net\n");
2769 ERROR("nks is NULL in write_key_net\n");
2773 if (nks->ot==V3_KS_WR_ONLY) {
2774 if (send_msg(nks->ns,(char*)(&BOUNDARY_TAG),sizeof(BOUNDARY_TAG))!=sizeof(BOUNDARY_TAG)) {
2775 ERROR("Could not send boundary tag in write_key_net\n");
2778 if (send_msg(nks->ns,(char*)(&taglen),sizeof(taglen))!=sizeof(taglen)) {
2779 ERROR("Could not send tag length in write_key_net\n");
2782 if (send_msg(nks->ns,tag,taglen)!=len) {
2783 ERROR("Could not send tag in write_key_net\n");
2786 if (send_msg(nks->ns,(char*)(&len),sizeof(len))!=sizeof(len)) {
2787 ERROR("Could not send data length in write_key_net\n");
2790 if (send_msg(nks->ns,buf,len)!=len) {
2791 ERROR("Could not send data in write_key_net\n");
2795 ERROR("Permission not correct in write_key_net\n");
2803 static sint64_t read_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2806 void *buf, sint64_t len)
2808 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2812 ERROR("Buf is NULL in read_key_net\n");
2817 ERROR("Tag is NULL in read_key_net\n");
2822 ERROR("len is negative in read_key_net\n");
2827 ERROR("taglen is negative in read_key_net\n");
2832 ERROR("read_key: key is NULL in read_key_net\n");
2837 if (nks->ot==V3_KS_RD_ONLY) {
2842 if (recv_msg(nks->ns,(char*)(&tempbt),sizeof(tempbt))!=sizeof(tempbt)) {
2843 ERROR("Cannot receive boundary tag in read_key_net\n");
2847 if (tempbt!=BOUNDARY_TAG) {
2848 ERROR("Invalid boundary tag (received 0x%x\n",tempbt);
2852 temptag=palacios_alloc(taglen);
2854 ERROR("failed to allocate temptag\n");
2858 if (recv_msg(nks->ns,(char*)(&slen),sizeof(slen))!=sizeof(slen)) {
2859 ERROR("Cannot receive tag len in read_key_net\n");
2860 palacios_free(temptag);
2865 ERROR("Tag len expected does not matched tag len decoded in read_key_net\n");
2866 palacios_free(temptag);
2870 if (recv_msg(nks->ns,temptag,taglen)!=taglen) {
2871 ERROR("Cannot recieve tag in read_key_net\n");
2872 palacios_free(temptag);
2876 if (memcmp(temptag,tag,taglen)) {
2877 ERROR("Tag mismatch\n");
2878 palacios_free(temptag);
2882 if (recv_msg(nks->ns,(char*)(&slen),sizeof(slen))!=sizeof(slen)) {
2883 ERROR("Cannot receive data len in read_key_net\n");
2884 palacios_free(temptag);
2889 ERROR("Data len expected does not matched data len decoded in read_key_net\n");
2890 palacios_free(temptag);
2894 if (recv_msg(nks->ns,buf,len)!=len) {
2895 ERROR("Cannot recieve data in read_key_net\n");
2896 palacios_free(temptag);
2900 palacios_free(temptag);
2903 ERROR("Permissions incorrect for the stream in read_key_net\n");
2912 /***************************************************************************************************
2914 *************************************************************************************************/
2916 static v3_keyed_stream_t open_stream(char *url,
2917 v3_keyed_stream_open_t ot)
2919 if (!strncasecmp(url,"mem:",4)) {
2920 return open_stream_mem(url,ot);
2921 } else if (!strncasecmp(url,"file:",5)) {
2922 return open_stream_file(url,ot);
2923 } else if (!strncasecmp(url,"user:",5)) {
2924 return open_stream_user(url,ot);
2925 } else if (!strncasecmp(url,"net:",4)){
2926 return open_stream_net(url,ot);
2927 } else if (!strncasecmp(url,"textfile:",9)) {
2928 return open_stream_textfile(url,ot);
2930 ERROR("unsupported type in attempt to open keyed stream \"%s\"\n",url);
2935 static void close_stream(v3_keyed_stream_t stream)
2937 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2938 switch (gks->stype){
2940 return close_stream_mem(stream);
2943 return close_stream_file(stream);
2945 case STREAM_TEXTFILE:
2946 return close_stream_textfile(stream);
2949 return close_stream_user(stream);
2951 case STREAM_NETWORK:
2952 return close_stream_net(stream);
2955 ERROR("unknown stream type %d in close\n",gks->stype);
2960 static void preallocate_hint_key(v3_keyed_stream_t stream,
2964 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2965 switch (gks->stype){
2967 preallocate_hint_key_mem(stream,key,size);
2970 preallocate_hint_key_file(stream,key,size);
2972 case STREAM_TEXTFILE:
2973 preallocate_hint_key_textfile(stream,key,size);
2976 return preallocate_hint_key_user(stream,key,size);
2978 case STREAM_NETWORK:
2979 return preallocate_hint_key_net(stream,key,size);
2982 ERROR("unknown stream type %d in preallocate_hint_key\n",gks->stype);
2989 static v3_keyed_stream_key_t open_key(v3_keyed_stream_t stream,
2992 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2993 switch (gks->stype){
2995 return open_key_mem(stream,key);
2998 return open_key_file(stream,key);
3000 case STREAM_TEXTFILE:
3001 return open_key_textfile(stream,key);
3004 return open_key_user(stream,key);
3006 case STREAM_NETWORK:
3007 return open_key_net(stream, key);
3010 ERROR("unknown stream type %d in open_key\n",gks->stype);
3017 static void close_key(v3_keyed_stream_t stream,
3018 v3_keyed_stream_key_t key)
3020 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3021 switch (gks->stype){
3023 return close_key_mem(stream,key);
3026 return close_key_file(stream,key);
3028 case STREAM_TEXTFILE:
3029 return close_key_textfile(stream,key);
3032 return close_key_user(stream,key);
3034 case STREAM_NETWORK:
3035 return close_key_net(stream, key);
3038 ERROR("unknown stream type %d in close_key\n",gks->stype);
3045 static sint64_t write_key(v3_keyed_stream_t stream,
3046 v3_keyed_stream_key_t key,
3052 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3053 switch (gks->stype){
3055 return write_key_mem(stream,key,tag,taglen,buf,len);
3058 return write_key_file(stream,key,tag,taglen,buf,len);
3060 case STREAM_TEXTFILE:
3061 return write_key_textfile(stream,key,tag,taglen,buf,len);
3064 return write_key_user(stream,key,tag,taglen,buf,len);
3066 case STREAM_NETWORK:
3067 return write_key_net(stream,key,tag,taglen,buf,len);
3070 ERROR("unknown stream type %d in write_key\n",gks->stype);
3078 static sint64_t read_key(v3_keyed_stream_t stream,
3079 v3_keyed_stream_key_t key,
3085 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3086 switch (gks->stype){
3088 return read_key_mem(stream,key,tag,taglen,buf,len);
3091 return read_key_file(stream,key,tag,taglen,buf,len);
3093 case STREAM_TEXTFILE:
3094 return read_key_textfile(stream,key,tag,taglen,buf,len);
3097 return read_key_user(stream,key,tag,taglen,buf,len);
3099 case STREAM_NETWORK:
3100 return read_key_net(stream,key,tag,taglen,buf,len);
3103 ERROR("unknown stream type %d in read_key\n",gks->stype);
3113 /***************************************************************************************************
3114 Hooks to palacios and inititialization
3115 *************************************************************************************************/
3118 static struct v3_keyed_stream_hooks hooks = {
3119 .open = open_stream,
3120 .close = close_stream,
3121 .preallocate_hint_key = preallocate_hint_key,
3122 .open_key = open_key,
3123 .close_key = close_key,
3124 .read_key = read_key,
3125 .write_key = write_key
3129 static int init_keyed_streams( void )
3131 mem_streams = palacios_create_htable(DEF_NUM_STREAMS,hash_func,hash_comp);
3134 ERROR("failed to allocated stream pool for in-memory streams\n");
3138 user_streams = palacios_alloc(sizeof(struct user_keyed_streams));
3140 if (!user_streams) {
3141 ERROR("failed to allocated list for user streams\n");
3145 INIT_LIST_HEAD(&(user_streams->streams));
3147 palacios_spinlock_init(&(user_streams->lock));
3149 V3_Init_Keyed_Streams(&hooks);
3155 static int deinit_keyed_streams( void )
3157 palacios_free_htable(mem_streams,1,1);
3159 palacios_spinlock_deinit(&(user_streams->lock));
3161 palacios_free(user_streams);
3163 WARNING("Deinit of Palacios Keyed Streams likely leaked memory\n");
3169 static int guest_init_keyed_streams(struct v3_guest * guest, void ** vm_data )
3172 add_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT, keyed_stream_connect_user, 0);
3178 static int guest_deinit_keyed_streams(struct v3_guest * guest, void * vm_data)
3180 remove_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT);
3188 static struct linux_ext key_stream_ext = {
3189 .name = "KEYED_STREAM_INTERFACE",
3190 .init = init_keyed_streams,
3191 .deinit = deinit_keyed_streams,
3192 .guest_init = guest_init_keyed_streams,
3193 .guest_deinit = guest_deinit_keyed_streams,
3197 register_extension(&key_stream_ext);