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
660 /* lookup directory, see if it is writeable, and if so, create it if asked*/
662 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,41)
664 static int lookup_check_mkdir(const char *path, int need_write, int create, unsigned short perms)
668 if (path_lookup(path,LOOKUP_DIRECTORY|LOOKUP_FOLLOW,&nd)) {
670 // directory does does not exist.
673 // we are not being asked to create it
674 ERROR("attempt to open %s, which does not exist\n",path);
677 // We are being asked to create it
683 if (path_lookup(path,LOOKUP_PARENT|LOOKUP_FOLLOW,&nd)) {
684 ERROR("attempt to create %s failed because its parent cannot be looked up\n",path);
688 // Can we write to the parent?
690 if (inode_permission(nd.path.dentry->d_inode, MAY_WRITE | MAY_EXEC)) {
691 ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",path);
695 // OK, we can, so let's create it
697 de = lookup_create(&nd,1);
699 if (!de || IS_ERR(de)) {
700 ERROR("cannot allocate dentry\n");
704 err = vfs_mkdir(nd.path.dentry->d_inode, de, perms);
706 // lookup_create locks this for us!
708 mutex_unlock(&(nd.path.dentry->d_inode->i_mutex));
711 ERROR("attempt to create %s failed because mkdir failed\n",path);
715 // successfully created it.
722 // it exists, can we read (and write, if needed) to it?
724 if (inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_READ | need_write ? MAY_WRITE : 0 )) {
725 ERROR("attempt to open %s, which has the wrong permissions\n",path);
734 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,41)
735 static int lookup_check_mkdir(const char *path, int need_write, int create, unsigned short perms)
739 if (kern_path(path, LOOKUP_DIRECTORY|LOOKUP_FOLLOW, &p)) {
741 // directory does does not exist.
744 // we are not being asked to create it
745 ERROR("attempt to open %s, which does not exist\n",path);
748 // We are being asked to create it
754 if (kern_path(path,LOOKUP_PARENT|LOOKUP_FOLLOW,&p)) {
755 ERROR("attempt to create %s failed because its parent cannot be looked up\n",path);
759 // Can we write to the parent?
761 if (inode_permission(p.dentry->d_inode, MAY_WRITE | MAY_EXEC)) {
762 ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",path);
766 // OK, we can, so let's create it
768 de = kern_path_create(AT_FDCWD,path,&p,1);
770 if (!de || IS_ERR(de)) {
771 ERROR("cannot allocate dentry\n");
775 err = vfs_mkdir(p.dentry->d_inode, de, perms);
777 // lookup_create locks this for us!
779 mutex_unlock(&(p.dentry->d_inode->i_mutex));
782 ERROR("attempt to create %s failed because mkdir failed\n",path);
786 // successfully created it.
793 // it exists, can we read (and write, if needed) to it?
795 if (inode_permission(p.dentry->d_inode, MAY_EXEC | MAY_READ | need_write ? MAY_WRITE : 0 )) {
796 ERROR("attempt to open %s, which has the wrong permissions\n",path);
807 static v3_keyed_stream_t open_stream_file(char *url,
808 v3_keyed_stream_open_t ot)
810 struct file_keyed_stream *fks;
812 if (strncasecmp(url,"file:",5)) {
813 WARNING("illegitimate attempt to open file stream \"%s\"\n",url);
817 fks = palacios_alloc(sizeof(struct file_keyed_stream));
820 ERROR("cannot allocate space for file stream\n");
824 fks->path = (char*)palacios_alloc(strlen(url+5)+1);
827 ERROR("cannot allocate space for file stream\n");
832 strcpy(fks->path,url+5); // will fit
834 fks->stype=STREAM_FILE;
836 fks->ot= ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
838 if (lookup_check_mkdir(fks->path,ot!=V3_KS_RD_ONLY,ot==V3_KS_WR_ONLY_CREATE,0700)) {
839 ERROR("cannot find or create directory for stream\n");
846 palacios_free(fks->path);
852 static void close_stream_file(v3_keyed_stream_t stream)
854 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
856 palacios_free(fks->path);
861 static void preallocate_hint_key_file(v3_keyed_stream_t stream,
868 static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream,
871 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
872 struct file_stream *fs;
875 // the path is the stream's path plus the key name
876 // file:/home/foo + "regext" => "/home/foo/regext"
877 path = (char *) palacios_alloc(strlen(fks->path)+strlen(key)+2);
879 ERROR("cannot allocate file keyed stream for key %s\n",key);
882 // this sequence will fit and terminate with a zero
883 strcpy(path,fks->path);
887 fs = (struct file_stream *) palacios_alloc(sizeof(struct file_stream));
890 ERROR("cannot allocate file keyed stream for key %s\n",key);
895 fs->stype=STREAM_FILE;
897 fs->f = filp_open(path,O_RDWR|O_CREAT|O_LARGEFILE,0600);
899 if (!fs->f || IS_ERR(fs->f)) {
900 ERROR("cannot open relevent file \"%s\" for stream \"file:%s\" and key \"%s\"\n",path,fks->path,key);
912 static void close_key_file(v3_keyed_stream_t stream,
913 v3_keyed_stream_key_t key)
915 struct file_stream *fs = (struct file_stream *) key;
917 filp_close(fs->f,NULL);
923 static sint64_t write_file(struct file_stream *fs, void *buf, sint64_t len)
925 ssize_t done, left, total;
934 done = fs->f->f_op->write(fs->f, buf+(total-left), left, &(fs->f->f_pos));
946 static sint64_t write_key_file(v3_keyed_stream_t stream,
947 v3_keyed_stream_key_t key,
953 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
954 struct file_stream *fs = (struct file_stream *) key;
957 if (fks->ot!=V3_KS_WR_ONLY) {
961 if (taglen<0 || len<0) {
962 ERROR("Negative taglen or data len\n");
966 writelen=write_file(fs,&BOUNDARY_TAG,sizeof(BOUNDARY_TAG));
968 if (writelen!=sizeof(BOUNDARY_TAG)) {
969 ERROR("failed to write all data for boundary tag\n");
973 writelen=write_file(fs,&taglen,sizeof(taglen));
975 if (writelen!=sizeof(taglen)) {
976 ERROR("failed to write taglen\n");
980 if (write_file(fs,tag,taglen)!=taglen) {
981 ERROR("failed to write tag\n");
985 writelen=write_file(fs,&len,sizeof(len));
987 if (writelen!=sizeof(len)) {
988 ERROR("failed to write data len\n");
992 return write_file(fs,buf,len);
995 static sint64_t read_file(struct file_stream *fs, void *buf, sint64_t len)
997 ssize_t done, left, total;
1007 done = fs->f->f_op->read(fs->f, buf+(total-left), left, &(fs->f->f_pos));
1020 static sint64_t read_key_file(v3_keyed_stream_t stream,
1021 v3_keyed_stream_key_t key,
1027 struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
1028 struct file_stream *fs = (struct file_stream *) key;
1034 if (fks->ot!=V3_KS_RD_ONLY) {
1038 if (len<0 || taglen<0) {
1039 ERROR("taglen or data len is negative\n");
1043 readlen=read_file(fs,&tempbt,sizeof(tempbt));
1045 if (readlen!=sizeof(tempbt)) {
1046 ERROR("failed to read all data for boundary tag\n");
1050 if (tempbt!=BOUNDARY_TAG) {
1051 ERROR("boundary tag not found (read 0x%x)\n",tempbt);
1055 readlen=read_file(fs,&templen,sizeof(templen));
1057 if (readlen!=sizeof(templen)) {
1058 ERROR("failed to read all data for tag len\n");
1062 if (templen!=taglen) {
1063 ERROR("tag size mismatch (requested=%lld, actual=%lld)\n",taglen,templen);
1067 temptag=palacios_alloc(taglen);
1070 ERROR("Cannot allocate temptag\n");
1074 if (read_file(fs,temptag,taglen)!=taglen) {
1075 ERROR("Cannot read tag\n");
1076 palacios_free(temptag);
1080 if (memcmp(temptag,tag,taglen)) {
1081 ERROR("Tag mismatch\n");
1082 palacios_free(temptag);
1086 palacios_free(temptag);
1088 readlen=read_file(fs,&templen,sizeof(templen));
1090 if (readlen!=sizeof(templen)) {
1091 ERROR("failed to read all data for data len\n");
1096 ERROR("datasize mismatch (requested=%lld, actual=%lld)\n",len,templen);
1100 return read_file(fs,buf,len);
1105 /***************************************************************************************************
1106 Textfile-based implementation ("textfile:")
1108 Note that this implementation uses the internal structure and functions of the
1109 "file:" implementation
1110 *************************************************************************************************/
1112 // optimize the reading and decoding of hex data
1113 // this weakens the parser, so that:
1117 // will not. Note the leading whitespace
1118 #define TEXTFILE_OPT_HEX 0
1121 // The number of bytes handled at a time by the hex putter and getter
1123 #define MAX_HEX_SEQ 64
1126 A text file keyed stream is a file_keyed_stream,
1127 only with a different stype
1131 //#define PAUSE() ssleep(5)
1134 typedef struct file_keyed_stream textfile_keyed_stream;
1136 typedef struct file_stream textfile_stream;
1139 static v3_keyed_stream_t open_stream_textfile(char *url,
1140 v3_keyed_stream_open_t ot)
1142 textfile_keyed_stream *me;
1144 if (strncasecmp(url,"textfile:",9)) {
1145 WARNING("illegitimate attempt to open textfile stream \"%s\"\n",url);
1149 me = (textfile_keyed_stream *) open_stream_file(url+4, ot);
1152 ERROR("could not create underlying file stream\n");
1156 me->stype=STREAM_TEXTFILE;
1163 static void close_stream_textfile(v3_keyed_stream_t stream)
1165 textfile_keyed_stream *me = stream;
1167 me->stype=STREAM_FILE;
1169 close_stream_file(me);
1173 static void preallocate_hint_key_textfile(v3_keyed_stream_t stream,
1177 textfile_keyed_stream *me = stream;
1179 me->stype=STREAM_FILE;
1181 preallocate_hint_key_file(me,key,size);
1183 me->stype=STREAM_TEXTFILE;
1188 static inline int isoneof(char c, char *sl, int m)
1201 static char get_next_char(textfile_stream *s)
1204 if (read_file(s,&buf,1)!=1) {
1210 static char hexify_nybble(char c)
1214 } else if (c>=0xa && c<=0xf) {
1221 static int hexify_byte(char *c, char b)
1224 n = hexify_nybble( (b >> 4) & 0xf);
1229 n = hexify_nybble( b & 0xf);
1238 static char dehexify_nybble(char c)
1240 if (c>='0' && c<='9') {
1242 } else if (c>='a' && c<='f') {
1243 return 0xa + (c-'a');
1244 } else if (c>='A' && c<='F') {
1245 return 0xa + (c-'A');
1251 static int dehexify_byte(char *c, char *b)
1254 n = dehexify_nybble(c[0]);
1259 n = dehexify_nybble(c[1]);
1268 #if TEXTFILE_OPT_HEX
1271 // Here the sl array, of length m is the number
1272 static int get_hexbytes_as_data(textfile_stream *s, char *buf, int n)
1274 char rbuf[MAX_HEX_SEQ*2];
1281 cur = left > MAX_HEX_SEQ ? MAX_HEX_SEQ : left;
1282 if (read_file(s,rbuf,cur*2)!=cur*2) {
1283 ERROR("Cannot read data in getting hexbytes as data\n");
1287 for (i=0;i<cur;i++) {
1288 if (dehexify_byte(rbuf+(i*2),buf+off+i)==-1) {
1289 ERROR("Cannot decode data as hex in getting hexbytes as data\n");
1302 // Here the sl array, of length m is the set of characters to skip (e.g., whitespace)
1303 static int get_hexbytes_as_data_skip(textfile_stream *s, char *buf, int n, char *sl, int m)
1312 rbuf[which] = get_next_char(s);
1313 if (rbuf[which]==-1) {
1314 ERROR("Cannot read char in getting hexbytes as data with skiplist");
1317 if (isoneof(rbuf[which],sl,m)) {
1323 if (dehexify_byte(rbuf,buf+cur)==-1) {
1324 ERROR("Cannot decode data as hex in getting hexbytes as data with skiplist\n");
1334 static int put_next_char(textfile_stream *s, char d)
1336 return write_file(s,&d,1);
1341 static int put_data_as_hexbytes(textfile_stream *s, char *buf, int n)
1343 char rbuf[MAX_HEX_SEQ*2];
1350 cur = left > MAX_HEX_SEQ ? MAX_HEX_SEQ : left;
1351 for (i=0;i<cur;i++) {
1352 if (hexify_byte(rbuf+(i*2),*(buf+off+i))==-1) {
1353 ERROR("Cannot encode data as hex in putting data as hexbytes\n");
1357 if (write_file(s,rbuf,cur*2)!=cur*2) {
1358 ERROR("Cannot write data in putting data as hexbytes\n");
1369 static int put_string_n(textfile_stream *s, char *buf, int n)
1373 rc = write_file(s,buf,n);
1382 static int put_string(textfile_stream *s, char *buf)
1386 return put_string_n(s,buf,n);
1391 static int search_for(textfile_stream *s, char d)
1396 } while (c!=-1 && c!=d);
1406 static int skip_matching(textfile_stream *s, char *m, int n)
1429 return rc; // unknown
1436 static int token_scan(textfile_stream *s, char *token, int n, char *sl, int m)
1445 ERROR("Failed to get character during token scan (preceding whitespace)\n");
1448 } while (isoneof(c,sl,m));
1458 ERROR("Failed to get character during token scan (token)\n");
1461 if (isoneof(c,sl,m)) {
1474 static v3_keyed_stream_key_t open_key_textfile(v3_keyed_stream_t stream,
1477 textfile_keyed_stream *mks = stream;
1478 textfile_stream *ms;
1480 mks->stype=STREAM_FILE;
1482 ms = open_key_file(mks,key);
1485 ERROR("cannot open underlying file keyed stream for key %s\n",key);
1486 mks->stype=STREAM_TEXTFILE;
1490 if (mks->ot==V3_KS_WR_ONLY) {
1492 // Now we write the section header
1494 ms->stype=STREAM_FILE;
1496 if (put_string(ms,"[")) {
1497 close_key_file(mks,ms);
1498 mks->stype=STREAM_TEXTFILE;
1502 if (put_string(ms,key)) {
1503 close_key_file(mks,ms);
1504 mks->stype=STREAM_TEXTFILE;
1508 if (put_string(ms,"]\n")) {
1509 close_key_file(mks,ms);
1510 mks->stype=STREAM_TEXTFILE;
1515 mks->stype=STREAM_TEXTFILE;
1516 ms->stype=STREAM_TEXTFILE;
1520 } else if (mks->ot == V3_KS_RD_ONLY) {
1521 // Now we readthe section header
1522 int keylen=strlen(key);
1523 char *tempkey = palacios_alloc(keylen+3);
1525 ms->stype=STREAM_FILE;
1528 ERROR("Allocation failed in opening key\n");
1529 close_key_file(mks,ms);
1530 mks->stype=STREAM_FILE;
1535 if (token_scan(ms,tempkey,keylen+3,"\t\r\n",3)) {
1536 ERROR("Cannot scan for token (key search)\n");
1537 close_key_file(mks,ms);
1538 mks->stype=STREAM_TEXTFILE;
1539 palacios_free(tempkey);
1543 tempkey[keylen+2] = 0;
1545 // Should now have [key]0
1547 if (tempkey[0]!='[' ||
1548 tempkey[keylen+1]!=']' ||
1549 memcmp(key,tempkey+1,keylen)) {
1550 ERROR("key mismatch: target key=%s, found %s\n",key,tempkey);
1551 palacios_free(tempkey);
1552 close_key_file(mks,ms);
1553 mks->stype=STREAM_TEXTFILE;
1557 // key match done, success
1559 mks->stype=STREAM_TEXTFILE;
1560 ms->stype=STREAM_TEXTFILE;
1562 palacios_free(tempkey);
1567 ERROR("Unknown open type in open_key_textfile\n");
1568 ms->stype=STREAM_FILE;
1569 close_key_file(mks,ms);
1577 static void close_key_textfile(v3_keyed_stream_t stream,
1578 v3_keyed_stream_key_t key)
1580 textfile_keyed_stream *mks = stream;
1581 textfile_stream *ms=key;
1583 mks->stype=STREAM_FILE;
1584 ms->stype=STREAM_FILE;
1586 close_key_file(mks,ms);
1588 mks->stype=STREAM_TEXTFILE;
1593 static sint64_t read_key_textfile(v3_keyed_stream_t stream,
1594 v3_keyed_stream_key_t key,
1600 textfile_stream *ms = (textfile_stream *) key;
1606 memcpy(tags,tag,taglen<31 ? taglen : 31);
1607 tags[taglen<32? taglen : 31 ]=0;
1609 temptag=palacios_alloc(taglen+1);
1611 ERROR("Unable to allocate temptag in textfile read key\n");
1615 ms->stype=STREAM_FILE;
1617 if (token_scan(ms,temptag,taglen+1," \t\r\n=",5)) {
1618 ERROR("Cannot scan for token (tag search)\n");
1619 ms->stype=STREAM_TEXTFILE;
1620 palacios_free(temptag);
1624 if (memcmp(tag,temptag,taglen)) {
1625 ERROR("Tag mismatch in reading tag from textfile: desired tag=%s, actual tag=%s\n",tags,temptag);
1626 ms->stype=STREAM_TEXTFILE;
1627 palacios_free(temptag);
1631 // tag matches, let's go and find our =
1632 palacios_free(temptag);
1634 if (search_for(ms,'=')) {
1635 ERROR("Unable to find = sign in tag data parse (tag=%s)\n", tags);
1636 ms->stype=STREAM_TEXTFILE;
1641 #if TEXTFILE_OPT_HEX
1642 if (get_hexbytes_as_data(ms,buf,len)) {
1643 ERROR("Cannot read data in hex format (opt path) in textfile for tag %s\n",tags);
1644 ms->stype=STREAM_TEXTFILE;
1648 if (get_hexbytes_as_data_skip(ms,buf,len," \t\r\n",4)) {
1649 ERROR("Cannot read data in hex format (unopt path) in textfile for tag %s\n",tags);
1650 ms->stype=STREAM_TEXTFILE;
1655 ms->stype=STREAM_TEXTFILE;
1660 static sint64_t write_key_textfile(v3_keyed_stream_t stream,
1661 v3_keyed_stream_key_t key,
1667 textfile_stream *ms = (textfile_stream *) key;
1672 memcpy(tags,tag,taglen<31 ? taglen : 31);
1673 tags[taglen<32? taglen : 31 ]=0;
1675 /* if (taglen>100000 || len>100000) {
1681 ms->stype=STREAM_FILE;
1683 if (put_string_n(ms,tag,taglen)) {
1684 ERROR("Cannot write tag %s in textfile\n",tags);
1685 ms->stype=STREAM_TEXTFILE;
1689 if (put_string(ms,"=")) {
1690 ERROR("Cannot write = in textfile for tag %s\n",tags);
1691 ms->stype=STREAM_TEXTFILE;
1695 if (put_data_as_hexbytes(ms,buf,len)) {
1696 ERROR("Cannot write data in hex format in textfile for tag %s\n",tags);
1697 ms->stype=STREAM_TEXTFILE;
1701 if (put_string(ms,"\n")) {
1702 ERROR("Cannot write trailing lf in textfile for tag %s\n",tags);
1703 ms->stype=STREAM_TEXTFILE;
1707 ms->stype=STREAM_TEXTFILE;
1714 /***************************************************************************************************
1715 User implementation ("user:")
1716 *************************************************************************************************/
1719 // List of all user keyed stream connections for the guest
1720 struct user_keyed_streams {
1722 struct list_head streams;
1726 // A single keyed stream connection to user space
1727 struct user_keyed_stream {
1729 v3_keyed_stream_open_t otype;
1735 wait_queue_head_t user_wait_queue;
1736 wait_queue_head_t host_wait_queue;
1738 struct palacios_user_keyed_stream_op *op;
1740 struct list_head node;
1745 // List of all of the user streams
1747 static struct user_keyed_streams *user_streams;
1751 static int resize_op(struct palacios_user_keyed_stream_op **op, uint64_t buf_len)
1753 struct palacios_user_keyed_stream_op *old = *op;
1754 struct palacios_user_keyed_stream_op *new;
1757 new = palacios_alloc(sizeof(struct palacios_user_keyed_stream_op)+buf_len);
1761 new->len=sizeof(struct palacios_user_keyed_stream_op)+buf_len;
1762 new->buf_len=buf_len;
1767 if ((old->len-sizeof(struct palacios_user_keyed_stream_op)) >= buf_len) {
1768 old->buf_len=buf_len;
1773 return resize_op(op,buf_len);
1779 // The assumption is that we enter this with the stream locked
1780 // and we will return with it locked; additionally, the op structure
1781 // will be overwritten with the response
1783 static int do_request_to_response(struct user_keyed_stream *s, unsigned long *flags)
1787 ERROR("user keyed stream request attempted while one is already in progress on %s\n",s->url);
1791 // we are now waiting for a response
1794 // release the stream
1795 palacios_spinlock_unlock_irqrestore(&(s->lock), *flags);
1797 // wake up anyone waiting on it
1798 wake_up_interruptible(&(s->user_wait_queue));
1800 // wait for someone to give us a response
1801 while (wait_event_interruptible(s->host_wait_queue, (s->waiting == 0)) != 0) {}
1803 // reacquire the lock for our called
1804 palacios_spinlock_lock_irqsave(&(s->lock), *flags);
1810 // The assumption is that we enter this with the stream locked
1811 // and we will return with it UNlocked
1813 static int do_response_to_request(struct user_keyed_stream *s, unsigned long *flags)
1816 if (!(s->waiting)) {
1817 ERROR("user keyed stream response while no request is in progress on %s\n",s->url);
1821 // we are now waiting for a request
1824 // release the stream
1825 palacios_spinlock_unlock_irqrestore(&(s->lock), *flags);
1827 // wake up anyone waiting on it
1828 wake_up_interruptible(&(s->host_wait_queue));
1835 static unsigned int keyed_stream_poll_user(struct file *filp, poll_table *wait)
1837 struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
1838 unsigned long flags;
1844 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1846 poll_wait(filp, &(s->user_wait_queue), wait);
1849 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1850 return POLLIN | POLLRDNORM;
1853 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1858 static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsigned long arg)
1860 void __user *argp = (void __user *)arg;
1861 unsigned long flags;
1864 struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
1868 case V3_KSTREAM_REQUEST_SIZE_IOCTL:
1870 // inform request size
1872 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1874 if (!(s->waiting)) {
1875 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1879 size = sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
1881 if (copy_to_user((void * __user) argp, &size, sizeof(uint64_t))) {
1882 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1883 ERROR("palacios user key size request failed to copy data\n");
1887 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1893 case V3_KSTREAM_REQUEST_PULL_IOCTL:
1897 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1899 if (!(s->waiting)) {
1900 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1901 ERROR("palacios user key pull request when not waiting\n");
1905 size = sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
1908 if (copy_to_user((void __user *) argp, s->op, size)) {
1909 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1910 ERROR("palacios user key pull request failed to copy data\n");
1914 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1921 case V3_KSTREAM_RESPONSE_PUSH_IOCTL:
1923 // push the response
1925 palacios_spinlock_lock_irqsave(&(s->lock), flags);
1927 if (!(s->waiting)) {
1928 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1929 ERROR("palacios user key push response when not waiting\n");
1933 if (copy_from_user(&size, (void __user *) argp, sizeof(uint64_t))) {
1934 ERROR("palacios user key push response failed to copy size\n");
1935 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1939 // overflow possible here for very large request
1940 if (resize_op(&(s->op),size-sizeof(struct palacios_user_keyed_stream_op))) {
1941 ERROR("unable to resize op in user key push response\n");
1942 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1946 if (copy_from_user(s->op, (void __user *) argp, size)) {
1947 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
1951 do_response_to_request(s,&flags);
1952 // this will have unlocked s for us
1959 ERROR("unknown ioctl in user keyed stream\n");
1969 static int keyed_stream_release_user(struct inode *inode, struct file *filp)
1971 struct user_keyed_stream *s = filp->private_data;
1972 unsigned long f1,f2;
1974 palacios_spinlock_lock_irqsave(&(user_streams->lock),f1);
1975 palacios_spinlock_lock_irqsave(&(s->lock), f2);
1977 list_del(&(s->node));
1979 palacios_spinlock_unlock_irqrestore(&(s->lock), f2);
1980 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), f1);
1982 palacios_free(s->url);
1988 static struct file_operations user_keyed_stream_fops = {
1989 .poll = keyed_stream_poll_user,
1990 .compat_ioctl = keyed_stream_ioctl_user,
1991 .unlocked_ioctl = keyed_stream_ioctl_user,
1992 .release = keyed_stream_release_user,
1997 user_keyed_streams are allocated on user connect, and deallocated on user release
1999 palacios-side opens and closes only manipulate the open type
2002 int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned long arg, void *priv_data)
2005 unsigned long flags;
2008 struct user_keyed_stream *s;
2010 if (!user_streams) {
2011 ERROR("no user space keyed streams!\n");
2016 if (copy_from_user(&len,(void __user *)arg,sizeof(len))) {
2017 ERROR("cannot copy url len from user\n");
2021 // overflow possible here, but only if this is a huge guest request (>4GB)
2022 url = palacios_alloc(len);
2025 ERROR("cannot allocate url for user keyed stream\n");
2029 if (copy_from_user(url,((void __user *)arg)+sizeof(len),len)) {
2030 ERROR("cannot copy url from user\n");
2036 // Check for duplicate handler
2037 palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
2038 list_for_each_entry(s, &(user_streams->streams), node) {
2039 if (!strncasecmp(url, s->url, len)) {
2040 ERROR("user keyed stream connection with url \"%s\" already exists\n", url);
2045 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
2047 // Create connection
2048 s = palacios_alloc(sizeof(struct user_keyed_stream));
2051 ERROR("cannot allocate new user keyed stream for %s\n",url);
2057 // Get file descriptor
2058 fd = anon_inode_getfd("v3-kstream", &user_keyed_stream_fops, s, 0);
2061 ERROR("cannot allocate file descriptor for new user keyed stream for %s\n",url);
2067 memset(s, 0, sizeof(struct user_keyed_stream));
2069 s->stype=STREAM_USER;
2072 init_waitqueue_head(&(s->user_wait_queue));
2073 init_waitqueue_head(&(s->host_wait_queue));
2075 // Insert connection into list
2076 palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
2077 list_add(&(s->node), &(user_streams->streams));
2078 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
2083 static struct user_keyed_stream *keyed_stream_user_find(char *url)
2085 unsigned long flags;
2086 struct user_keyed_stream *s;
2088 if (!user_streams) {
2089 ERROR("no user space keyed streams available\n");
2093 palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
2094 list_for_each_entry(s, &(user_streams->streams), node) {
2095 if (!strcasecmp(url, s->url)) {
2096 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
2101 palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
2107 static v3_keyed_stream_t open_stream_user(char *url, v3_keyed_stream_open_t ot)
2109 unsigned long flags;
2110 struct user_keyed_stream *s;
2112 s = keyed_stream_user_find(url);
2115 ERROR("cannot open user stream %s as it does not exist yet\n",url);
2119 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2122 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
2123 ERROR("cannot open user stream %s as it is already in waiting state\n",url);
2127 s->otype = ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
2129 palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
2135 // close stream does not do anything. Creation of the stream and its cleanup
2136 // are driven by the user side, not the palacios side
2137 // might eventually want to reference count this, though
2138 static void close_stream_user(v3_keyed_stream_t stream)
2143 static void preallocate_hint_key_user(v3_keyed_stream_t stream,
2153 static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key)
2155 unsigned long flags;
2156 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2157 uint64_t len = strlen(key)+1;
2160 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2163 if (resize_op(&(s->op),len)) {
2164 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2165 ERROR("cannot resize op in opening key %s on user keyed stream %s\n",key,s->url);
2169 s->op->type = PALACIOS_KSTREAM_OPEN_KEY;
2170 s->op->buf_len = len;
2171 strncpy(s->op->buf,key,len); // will terminate buffer
2173 // enter with it locked
2174 if (do_request_to_response(s,&flags)) {
2175 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2176 ERROR("request/response handling failed\n");
2179 // return with it locked
2181 user_key=s->op->user_key;
2183 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2188 static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key)
2190 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2192 unsigned long flags;
2194 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2196 if (resize_op(&(s->op),len)) {
2197 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2198 ERROR("cannot resize op in closing key 0x%p on user keyed stream %s\n",key,s->url);
2202 s->op->type = PALACIOS_KSTREAM_CLOSE_KEY;
2203 s->op->buf_len = len;
2204 s->op->user_key = key;
2206 // enter with it locked
2207 if (do_request_to_response(s,&flags)) {
2208 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2209 ERROR("request/response handling failed\n");
2212 // return with it locked
2214 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2221 static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2224 void *buf, sint64_t rlen)
2227 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2228 uint64_t len = taglen ;
2230 unsigned long flags;
2232 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2234 if (s->otype != V3_KS_RD_ONLY) {
2235 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2236 ERROR("attempt to read key from stream that is not in read state on %s\n",s->url);
2240 if (resize_op(&(s->op),len)) {
2241 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2242 ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
2246 s->op->type = PALACIOS_KSTREAM_READ_KEY;
2247 s->op->buf_len = len ;
2249 s->op->user_key = key;
2250 s->op->data_off = taglen;
2252 memcpy(s->op->buf,tag,taglen);
2254 // enter with it locked
2255 if (do_request_to_response(s,&flags)) {
2256 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2257 ERROR("request/response handling failed\n");
2260 // return with it locked
2263 if (s->op->xfer>0) {
2264 // data_off must be zero
2265 memcpy(buf,s->op->buf,s->op->xfer);
2270 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2276 static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2279 void *buf, sint64_t wlen)
2282 struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
2283 uint64_t len = taglen + wlen ;
2285 unsigned long flags;
2288 palacios_spinlock_lock_irqsave(&(s->lock), flags);
2290 if (s->otype != V3_KS_WR_ONLY) {
2291 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2292 ERROR("attempt to write key on stream that is not in write state on %s\n",s->url);
2295 if (resize_op(&(s->op),len)) {
2296 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2297 ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
2301 s->op->type = PALACIOS_KSTREAM_WRITE_KEY;
2302 s->op->buf_len = len;
2304 s->op->user_key = key;
2305 s->op->data_off = taglen;
2307 memcpy(s->op->buf,tag,taglen);
2308 memcpy(s->op->buf+taglen,buf,wlen);
2310 // enter with it locked
2311 if (do_request_to_response(s,&flags)) {
2312 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2313 ERROR("request/response handling failed\n");
2316 // return with it locked
2318 // no data comes back, xfer should be size of data write (not tag)
2322 palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
2329 /****************************************************************************************
2330 * Network-based implementation ("net:")
2331 *****************************************************************************************/
2334 #define NET_MAX_KEY_LEN 128
2336 struct net_keyed_stream {
2339 struct net_stream * ns;
2344 struct socket *sock;
2348 //ignore the arguments given here currently
2349 static struct net_stream * create_net_stream(void)
2351 struct net_stream * ns = NULL;
2353 ns = palacios_alloc(sizeof(struct net_stream));
2356 ERROR("Cannot allocate a net_stream\n");
2360 memset(ns, 0, sizeof(struct net_stream));
2362 ns->stype = STREAM_NETWORK;
2367 static void close_socket(v3_keyed_stream_t stream)
2369 struct net_keyed_stream *nks = (struct net_keyed_stream *) stream;
2372 struct net_stream *ns = nks->ns;
2375 ns->sock->ops->release(ns->sock);
2377 ERROR("Close Socket\n");
2385 static void close_stream_net(v3_keyed_stream_t stream)
2387 close_socket(stream);
2390 static int connect_to_ip(struct net_stream *ns, int hostip, int port)
2392 struct sockaddr_in client;
2398 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&(ns->sock))<0) {
2399 ERROR("Cannot create accept socket\n");
2404 client.sin_family = AF_INET;
2405 client.sin_port = htons(port);
2406 client.sin_addr.s_addr = hostip;//in_aton(hostip);
2408 return ns->sock->ops->connect(ns->sock, (struct sockaddr *)&client, sizeof(client), 0);
2411 static int send_msg(struct net_stream *ns, char * buf, int len)
2416 ERROR("Send message on null net_stream\n");
2421 ERROR("Send message on net_stream without socket\n");
2433 msg.msg_flags = MSG_NOSIGNAL;//MSG_DONTWAIT;
2435 msg.msg_namelen = 0;
2436 msg.msg_control = NULL;
2437 msg.msg_controllen = 0;
2438 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
2442 iov_iter_init(&(msg.msg_iter),WRITE,&iov,1,0);
2445 iov.iov_base = (char *)&(buf[len-left]);
2446 iov.iov_len = (size_t)left;
2451 err = sock_sendmsg(ns->sock, &msg, (size_t)left);
2456 ERROR("Send msg error %d\n",err);
2468 static int recv_msg(struct net_stream *ns, char * buf, int len)
2474 ERROR("Receive message on null net_stream\n");
2479 ERROR("Receive message on net_stream without socket\n");
2493 msg.msg_namelen = 0;
2494 msg.msg_control = NULL;
2495 msg.msg_controllen = 0;
2496 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
2500 iov_iter_init(&(msg.msg_iter),READ,&iov,1,0);
2503 iov.iov_base = (void *)&(buf[len-left]);
2504 iov.iov_len = (size_t)left;
2509 err = sock_recvmsg(ns->sock, &msg, (size_t)left, 0);
2522 static struct net_stream * accept_once(struct net_stream * ns, const int port)
2524 struct socket *accept_sock;
2525 struct sockaddr_in addr;
2529 ERROR("Accept called on null net_stream\n");
2533 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&accept_sock)<0) {
2534 ERROR("Cannot create accept socket\n");
2539 addr.sin_family = AF_INET;
2540 addr.sin_port = htons(port);
2541 addr.sin_addr.s_addr = INADDR_ANY;
2543 err = accept_sock->ops->bind(accept_sock, (struct sockaddr *)&addr, sizeof(addr));
2546 ERROR("Bind err: %d\n",err);
2550 err = accept_sock->ops->listen(accept_sock,2);
2553 ERROR("Listen err: %d\n",err);
2557 // Init the socket in the network strream
2559 if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&(ns->sock))<0) {
2560 ERROR("Cannot create socket\n");
2565 // Do the actual accept
2567 if (accept_sock->ops->accept(accept_sock,ns->sock,0)<0) {
2568 ERROR("accept failed");
2572 // close the accept socket
2573 accept_sock->ops->release(accept_sock);
2574 palacios_free(accept_sock);
2580 static struct v3_keyed_stream_t * open_stream_net(char * url,v3_keyed_stream_open_t ot)
2582 struct net_keyed_stream * nks;
2591 nks = palacios_alloc(sizeof(struct net_keyed_stream));
2594 ERROR("Could not allocate space in open_stream_net\n");
2598 nks->ot = ot == V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
2600 nks->stype = STREAM_NETWORK;
2602 nks->ns = create_net_stream();
2605 ERROR("Could not create network stream\n");
2610 url_len=strlen(url);
2614 for(i = 0; i < url_len;i++){
2621 mode = url[delimit[0] + 1];
2622 ip_len = delimit[2] - delimit[1];
2623 port_len = url_len - delimit[2];
2628 char port[port_len];
2633 strncpy(ip,url + delimit[1]+1,ip_len-1);
2636 host_ip = in_aton(ip);
2638 strncpy(port,url+ delimit[2]+1,port_len-1);
2639 port[port_len-1]='\0';
2641 host_port = simple_strtol(port,NULL,10);
2643 INFO("ip is %s\n",ip);
2644 INFO("host_ip is %x\n", host_ip);
2645 INFO("port is %s (%d)\n",port,host_port);
2649 INFO("Accepting Connection on INADDR_ANY port:%d\n",host_port);
2650 nks->ns = accept_once(nks->ns, host_port);
2651 } else if (mode == 'c'){
2652 // call connect to ip
2653 INFO("Connecting to %s:%d\n",ip,host_port);
2654 connect_to_ip(nks->ns,host_ip, host_port);
2656 ERROR("Mode not recognized\n");
2661 return (v3_keyed_stream_t)nks;
2665 static void preallocate_hint_key_net(v3_keyed_stream_t stream, char *key,uint64_t size)
2670 static v3_keyed_stream_key_t open_key_net(v3_keyed_stream_t stream,char *key)
2672 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2674 // reciever of the key name
2675 if (nks->ot==V3_KS_WR_ONLY)
2677 unsigned short keylen = strlen(key);
2679 if (keylen>NET_MAX_KEY_LEN || keylen>=32768) {
2680 ERROR("Key is too long\n");
2685 // on-stack allocation here demands that we
2686 // keep key length low...
2690 // Opening a key for writing sends a notice of the
2691 // key length and the key name on the channel
2693 msg[next++]=keylen & 0xFF;
2694 msg[next]=(keylen>>8) & 0xFF;
2696 msg[next]=msg[next] | 0x80; // 0x80 is 128 and OR will flip leading bit to 1
2698 strncpy(msg+2,key,keylen); // will also copy trailing zero
2700 if (send_msg(nks->ns,msg,keylen+2) != keylen+2) {
2701 ERROR("Unable to open key for writing on net_stream (send key len+name)\n");
2707 if (nks->ot==V3_KS_RD_ONLY) {
2712 if (recv_msg(nks->ns,msg_info,2) != 2) {
2713 ERROR("Unable to open key for reading on net_stream (recv key len)\n");
2720 keylen |= msg_info[next++];
2722 if ((msg_info[next] & 0x80) != 0x80) {
2723 ERROR("Flag bit not set on receive of key length\n");
2726 msg_info[next] &= 0x7F; // flip the msb back to zero (clear flag)
2729 keylen |= msg_info[next]<<8;
2731 if (keylen > NET_MAX_KEY_LEN) {
2732 ERROR("Received key length is too big\n");
2740 if (recv_msg(nks->ns,msg,keylen) != keylen) {
2741 ERROR("Unable to receive key\n");
2746 if (strncmp(key,msg,keylen)!=0) {
2747 ERROR("Key mismatch in open_key_net - expect %s but got %s\n",key,msg);
2753 return (v3_keyed_stream_key_t)key;
2756 static void close_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t input_key)
2758 char * key = (char*)input_key;
2759 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2762 if (nks->ot==V3_KS_WR_ONLY) {
2763 unsigned short keylen = strlen(key);
2765 if (keylen > NET_MAX_KEY_LEN || keylen>=32768) {
2766 ERROR("Key length too long in close_key_net\n");
2774 msg[next++]=keylen & 0xFF;
2775 msg[next]=(keylen>>8) & 0xFF;
2777 msg[next]=msg[next] | 0x80; // 0x80 is 128 and OR will filp leading bit to 1
2778 strncpy(msg+2,key,keylen); // will copy the zero
2780 if (send_msg(nks->ns,msg,keylen+2)!=keylen+2) {
2781 ERROR("Cannot send key on close_key_net\n");
2787 if (nks->ot==V3_KS_RD_ONLY) {
2792 if (recv_msg(nks->ns,msg_info,2) != 2) {
2793 ERROR("Cannot recv key length on close_key_net\n");
2800 keylen |= msg_info[next++];
2802 if ((msg_info[next] & 0x80) != 0x80) {
2803 ERROR("Missing flag in close_key_net receive\n");
2807 msg_info[next] &= 0x7F; // flip the msb back to zero
2809 keylen |= msg_info[next]<<8;
2814 if (recv_msg(nks->ns,msg,keylen)!=keylen) {
2815 ERROR("Did not receive all of key in close_key_net receive\n");
2821 if (strncmp(key,msg,keylen)!=0) {
2822 ERROR("Key mismatch in close_key_net - expect %s but got %s\n",key,msg);
2829 static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2832 void *buf, sint64_t len)
2834 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2837 ERROR("Buf is NULL in write_key_net\n");
2842 ERROR("Tag is NULL in write_key_net\n");
2847 ERROR("len is negative in write_key_net\n");
2852 ERROR("taglen is negative in write_key_net\n");
2857 ERROR("write_key: key is NULL in write_key_net\n");
2863 ERROR("nks is NULL in write_key_net\n");
2867 if (nks->ot==V3_KS_WR_ONLY) {
2868 if (send_msg(nks->ns,(char*)(&BOUNDARY_TAG),sizeof(BOUNDARY_TAG))!=sizeof(BOUNDARY_TAG)) {
2869 ERROR("Could not send boundary tag in write_key_net\n");
2872 if (send_msg(nks->ns,(char*)(&taglen),sizeof(taglen))!=sizeof(taglen)) {
2873 ERROR("Could not send tag length in write_key_net\n");
2876 if (send_msg(nks->ns,tag,taglen)!=taglen) {
2877 ERROR("Could not send tag in write_key_net\n");
2880 if (send_msg(nks->ns,(char*)(&len),sizeof(len))!=sizeof(len)) {
2881 ERROR("Could not send data length in write_key_net\n");
2884 if (send_msg(nks->ns,buf,len)!=len) {
2885 ERROR("Could not send data in write_key_net\n");
2889 ERROR("Permission not correct in write_key_net\n");
2897 static sint64_t read_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
2900 void *buf, sint64_t len)
2902 struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
2906 ERROR("Buf is NULL in read_key_net\n");
2911 ERROR("Tag is NULL in read_key_net\n");
2916 ERROR("len is negative in read_key_net\n");
2921 ERROR("taglen is negative in read_key_net\n");
2926 ERROR("read_key: key is NULL in read_key_net\n");
2931 if (nks->ot==V3_KS_RD_ONLY) {
2936 if (recv_msg(nks->ns,(char*)(&tempbt),sizeof(tempbt))!=sizeof(tempbt)) {
2937 ERROR("Cannot receive boundary tag in read_key_net\n");
2941 if (tempbt!=BOUNDARY_TAG) {
2942 ERROR("Invalid boundary tag (received 0x%x\n",tempbt);
2946 temptag=palacios_alloc(taglen);
2948 ERROR("failed to allocate temptag\n");
2952 if (recv_msg(nks->ns,(char*)(&slen),sizeof(slen))!=sizeof(slen)) {
2953 ERROR("Cannot receive tag len in read_key_net\n");
2954 palacios_free(temptag);
2959 ERROR("Tag len expected does not matched tag len decoded in read_key_net\n");
2960 palacios_free(temptag);
2964 if (recv_msg(nks->ns,temptag,taglen)!=taglen) {
2965 ERROR("Cannot recieve tag in read_key_net\n");
2966 palacios_free(temptag);
2970 if (memcmp(temptag,tag,taglen)) {
2971 ERROR("Tag mismatch\n");
2972 palacios_free(temptag);
2976 if (recv_msg(nks->ns,(char*)(&slen),sizeof(slen))!=sizeof(slen)) {
2977 ERROR("Cannot receive data len in read_key_net\n");
2978 palacios_free(temptag);
2983 ERROR("Data len expected does not matched data len decoded in read_key_net\n");
2984 palacios_free(temptag);
2988 if (recv_msg(nks->ns,buf,len)!=len) {
2989 ERROR("Cannot recieve data in read_key_net\n");
2990 palacios_free(temptag);
2994 palacios_free(temptag);
2997 ERROR("Permissions incorrect for the stream in read_key_net\n");
3006 /***************************************************************************************************
3008 *************************************************************************************************/
3010 static v3_keyed_stream_t open_stream(char *url,
3011 v3_keyed_stream_open_t ot)
3013 if (!strncasecmp(url,"mem:",4)) {
3014 return open_stream_mem(url,ot);
3015 } else if (!strncasecmp(url,"file:",5)) {
3016 return open_stream_file(url,ot);
3017 } else if (!strncasecmp(url,"user:",5)) {
3018 return open_stream_user(url,ot);
3019 } else if (!strncasecmp(url,"net:",4)){
3020 return open_stream_net(url,ot);
3021 } else if (!strncasecmp(url,"textfile:",9)) {
3022 return open_stream_textfile(url,ot);
3024 ERROR("unsupported type in attempt to open keyed stream \"%s\"\n",url);
3029 static void close_stream(v3_keyed_stream_t stream)
3031 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3032 switch (gks->stype){
3034 return close_stream_mem(stream);
3037 return close_stream_file(stream);
3039 case STREAM_TEXTFILE:
3040 return close_stream_textfile(stream);
3043 return close_stream_user(stream);
3045 case STREAM_NETWORK:
3046 return close_stream_net(stream);
3049 ERROR("unknown stream type %d in close\n",gks->stype);
3054 static void preallocate_hint_key(v3_keyed_stream_t stream,
3058 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3059 switch (gks->stype){
3061 preallocate_hint_key_mem(stream,key,size);
3064 preallocate_hint_key_file(stream,key,size);
3066 case STREAM_TEXTFILE:
3067 preallocate_hint_key_textfile(stream,key,size);
3070 return preallocate_hint_key_user(stream,key,size);
3072 case STREAM_NETWORK:
3073 return preallocate_hint_key_net(stream,key,size);
3076 ERROR("unknown stream type %d in preallocate_hint_key\n",gks->stype);
3083 static v3_keyed_stream_key_t open_key(v3_keyed_stream_t stream,
3086 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3087 switch (gks->stype){
3089 return open_key_mem(stream,key);
3092 return open_key_file(stream,key);
3094 case STREAM_TEXTFILE:
3095 return open_key_textfile(stream,key);
3098 return open_key_user(stream,key);
3100 case STREAM_NETWORK:
3101 return open_key_net(stream, key);
3104 ERROR("unknown stream type %d in open_key\n",gks->stype);
3111 static void close_key(v3_keyed_stream_t stream,
3112 v3_keyed_stream_key_t key)
3114 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3115 switch (gks->stype){
3117 return close_key_mem(stream,key);
3120 return close_key_file(stream,key);
3122 case STREAM_TEXTFILE:
3123 return close_key_textfile(stream,key);
3126 return close_key_user(stream,key);
3128 case STREAM_NETWORK:
3129 return close_key_net(stream, key);
3132 ERROR("unknown stream type %d in close_key\n",gks->stype);
3139 static sint64_t write_key(v3_keyed_stream_t stream,
3140 v3_keyed_stream_key_t key,
3146 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3147 switch (gks->stype){
3149 return write_key_mem(stream,key,tag,taglen,buf,len);
3152 return write_key_file(stream,key,tag,taglen,buf,len);
3154 case STREAM_TEXTFILE:
3155 return write_key_textfile(stream,key,tag,taglen,buf,len);
3158 return write_key_user(stream,key,tag,taglen,buf,len);
3160 case STREAM_NETWORK:
3161 return write_key_net(stream,key,tag,taglen,buf,len);
3164 ERROR("unknown stream type %d in write_key\n",gks->stype);
3172 static sint64_t read_key(v3_keyed_stream_t stream,
3173 v3_keyed_stream_key_t key,
3179 struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
3180 switch (gks->stype){
3182 return read_key_mem(stream,key,tag,taglen,buf,len);
3185 return read_key_file(stream,key,tag,taglen,buf,len);
3187 case STREAM_TEXTFILE:
3188 return read_key_textfile(stream,key,tag,taglen,buf,len);
3191 return read_key_user(stream,key,tag,taglen,buf,len);
3193 case STREAM_NETWORK:
3194 return read_key_net(stream,key,tag,taglen,buf,len);
3197 ERROR("unknown stream type %d in read_key\n",gks->stype);
3207 /***************************************************************************************************
3208 Hooks to palacios and inititialization
3209 *************************************************************************************************/
3212 static struct v3_keyed_stream_hooks hooks = {
3213 .open = open_stream,
3214 .close = close_stream,
3215 .preallocate_hint_key = preallocate_hint_key,
3216 .open_key = open_key,
3217 .close_key = close_key,
3218 .read_key = read_key,
3219 .write_key = write_key
3223 static int init_keyed_streams( void )
3225 mem_streams = palacios_create_htable(DEF_NUM_STREAMS,hash_func,hash_comp);
3228 ERROR("failed to allocated stream pool for in-memory streams\n");
3232 user_streams = palacios_alloc(sizeof(struct user_keyed_streams));
3234 if (!user_streams) {
3235 ERROR("failed to allocated list for user streams\n");
3239 INIT_LIST_HEAD(&(user_streams->streams));
3241 palacios_spinlock_init(&(user_streams->lock));
3243 V3_Init_Keyed_Streams(&hooks);
3249 static int deinit_keyed_streams( void )
3251 palacios_free_htable(mem_streams,1,1);
3253 palacios_spinlock_deinit(&(user_streams->lock));
3255 palacios_free(user_streams);
3257 WARNING("Deinit of Palacios Keyed Streams likely leaked memory\n");
3263 static int guest_init_keyed_streams(struct v3_guest * guest, void ** vm_data )
3266 add_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT, keyed_stream_connect_user, 0);
3272 static int guest_deinit_keyed_streams(struct v3_guest * guest, void * vm_data)
3274 remove_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT);
3282 static struct linux_ext key_stream_ext = {
3283 .name = "KEYED_STREAM_INTERFACE",
3284 .init = init_keyed_streams,
3285 .deinit = deinit_keyed_streams,
3286 .guest_init = guest_init_keyed_streams,
3287 .guest_deinit = guest_deinit_keyed_streams,
3291 register_extension(&key_stream_ext);