X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_module%2Fiface-keyed-stream.c;h=a6fb960a93ba92daaf456ad8215eebd084ac0788;hb=88a3605446744969abe6f193a7bc20e62d5aa555;hp=41da2fba69242eec752c5c7a230ee594a7e9e61d;hpb=07aa8f3c18a33af0961e7546980a63ab5f6fba4f;p=palacios.git diff --git a/linux_module/iface-keyed-stream.c b/linux_module/iface-keyed-stream.c index 41da2fb..a6fb960 100644 --- a/linux_module/iface-keyed-stream.c +++ b/linux_module/iface-keyed-stream.c @@ -6,13 +6,13 @@ * (c) Peter Dinda, 2011 (interface, mem + file implementations + recooked user impl) * (c) Clint Sbisa, 2011 (initial user space implementation on which this is based) * (c) Diana Palsetia & Steve Rangel, 2012 (network based implementation) + * (c) Peter Dinda, 2012 (updated interface, textfile) */ #include #include #include #include -#include #include #include @@ -54,21 +54,57 @@ "mem:" Streams are stored in a hash table The values for this hash table are hash tables associated with - each stream. + each stream. A key maps to an expanding memory buffer. + Data is stored in a buffer like: + + [boundarytag][taglen][tag][datalen][data] + [boundarytag][taglen][tag][datalen][data] + ... "file:" Streams are stored in files. Each high-level open corresponds to a directory, while a key corresponds to - a distinct file in that directory. + a distinct file in that directory. Data is stored in a file + like: + + [boundarytag][taglen][tag][datalen][data] + [boundarytag][taglen][tag][datalen][data] + ... + + "textfile:" Same as file, but data is stored in text format, like a + windows style .ini file. A key maps to a file, and data is stored + in a file like: + + [key] + tag=data_in_hex + tag=data_in_hex + + This format makes it possible to concentenate the files to + produce a single "ini" file with "sections". + "net:" Streams are carried over the network. Each high level open corresponds to a TCP connection, while each key corresponds to a context on the stream. "net:a::" => Bind to : and accept a connection "net:c::" => Connect to : + "c" (client) + open_stream: connect + "a" (server) + open_stream: accept + "c" or "a": + open_key: send [keylen-lastbyte-high-bit][key] (writer) + or recv (same format as above) (reader) + close_key: send [keylen-lastbyte-high-bit][key] (writer) + or recv (same format as above) (reader) + write_key: send [boundarytag][taglen][tag][datalen][data] + read_key: recv (same format as above) + close_stream: close socket "user:" Stream requests are bounced to user space to be handled there. A rendezvous approach similar to the host device userland support is used + + All keyed streams store the tags. */ @@ -77,6 +113,7 @@ #define STREAM_FILE 2 #define STREAM_USER 3 #define STREAM_NETWORK 4 +#define STREAM_TEXTFILE 5 /* All keyed streams and streams indicate their implementation type within the first field @@ -89,7 +126,10 @@ struct generic_stream { int stype; }; - +/* + boundary tags are used for some othe raw formats. +*/ +static uint32_t BOUNDARY_TAG=0xabcd0123; /**************************************************************************************** @@ -127,7 +167,7 @@ static struct mem_stream *create_mem_stream_internal(uint64_t size) } - m->data = vmalloc(size); + m->data = palacios_valloc(size); if (!m->data) { palacios_free(m); @@ -152,7 +192,7 @@ static void destroy_mem_stream(struct mem_stream *m) { if (m) { if (m->data) { - vfree(m->data); + palacios_vfree(m->data); } m->data=0; palacios_free(m); @@ -161,7 +201,7 @@ static void destroy_mem_stream(struct mem_stream *m) static int expand_mem_stream(struct mem_stream *m, uint32_t new_size) { - void *data = vmalloc(new_size); + void *data = palacios_valloc(new_size); uint32_t nc; if (!data) { @@ -172,7 +212,7 @@ static int expand_mem_stream(struct mem_stream *m, uint32_t new_size) memcpy(data,m->data,nc); - vfree(m->data); + palacios_vfree(m->data); m->data=data; m->size=new_size; @@ -200,6 +240,8 @@ static uint32_t write_mem_stream(struct mem_stream *m, } + + static uint32_t read_mem_stream(struct mem_stream *m, void *data, uint32_t len) @@ -268,7 +310,7 @@ static v3_keyed_stream_t open_stream_mem(char *url, return 0; } - strcpy(mykey,url+4); + strcpy(mykey,url+4); // will fit mks = (struct mem_keyed_stream *) palacios_alloc(sizeof(struct mem_keyed_stream)); @@ -340,7 +382,7 @@ static v3_keyed_stream_key_t open_key_mem(v3_keyed_stream_t stream, return 0; } - strcpy(mykey,key); + strcpy(mykey,key); // will fit m = create_mem_stream(); @@ -389,7 +431,7 @@ static void preallocate_hint_key_mem(v3_keyed_stream_t stream, return; } - strcpy(mykey,key); + strcpy(mykey,key); // will fit m = create_mem_stream_internal(size); @@ -425,62 +467,173 @@ static void close_key_mem(v3_keyed_stream_t stream, static sint64_t write_key_mem(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, void *buf, sint64_t len) { - struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream; - struct mem_stream *m = (struct mem_stream *) key; - uint32_t mylen; - uint32_t writelen; - - if (mks->ot!=V3_KS_WR_ONLY) { - return -1; - } + struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream; + struct mem_stream *m = (struct mem_stream *) key; + uint32_t mylen; + uint32_t writelen; + + if (mks->ot!=V3_KS_WR_ONLY) { + return -1; + } + + if (taglen<0 || len<0) { + ERROR("Negative taglen or data len\n"); + return -1; + } + + if (taglen>0xffffffffULL || len>0xffffffffULL) { + ERROR("taglen or data len is too large\n"); + return -1; + } + + writelen=write_mem_stream(m,&BOUNDARY_TAG,sizeof(BOUNDARY_TAG)); + + if (writelen!=sizeof(BOUNDARY_TAG)) { + ERROR("failed to write all data for boundary tag\n"); + return -1; + } + + writelen=write_mem_stream(m,&taglen,sizeof(taglen)); + + if (writelen!=sizeof(taglen)) { + ERROR("failed to write taglen\n"); + return -1; + } + + mylen = (uint32_t) taglen; + + writelen=write_mem_stream(m,tag,mylen); + + if (writelen!=mylen) { + ERROR("failed to write all data for tag\n"); + return -1; + } - if (len<0) { - return -1; - } - - mylen = (uint32_t) len; + writelen=write_mem_stream(m,&len,sizeof(len)); + + if (writelen!=sizeof(len)) { + ERROR("failed to write datalen\n"); + return -1; + } + + mylen = (uint32_t) len; - writelen=write_mem_stream(m,buf,mylen); + writelen=write_mem_stream(m,buf,mylen); - if (writelen!=mylen) { - ERROR("failed to write all data for key\n"); - return -1; - } else { - return (sint64_t)writelen; - } + if (writelen!=mylen) { + ERROR("failed to write all data for key\n"); + return -1; + } else { + return (sint64_t)writelen; + } } static sint64_t read_key_mem(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, void *buf, sint64_t len) { - struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream; - struct mem_stream *m = (struct mem_stream *) key; - uint32_t mylen; - uint32_t readlen; - - if (mks->ot!=V3_KS_RD_ONLY) { - return -1; - } + struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream; + struct mem_stream *m = (struct mem_stream *) key; + uint32_t mylen; + uint32_t readlen; + void *temptag; + uint32_t tempbt; + sint64_t templen; + + + if (mks->ot!=V3_KS_RD_ONLY) { + return -1; + } + + if (len<0 || taglen<0) { + ERROR("taglen or data len is negative\n"); + return -1; + } - if (len<0) { - return -1; - } + if (len>0xffffffffULL || taglen>0xffffffffULL) { + ERROR("taglen or data len is too large\n"); + return -1; + } + + readlen=read_mem_stream(m,&tempbt,sizeof(tempbt)); + + if (readlen!=sizeof(tempbt)) { + ERROR("failed to read all data for boundary tag\n"); + return -1; + } + + if (tempbt!=BOUNDARY_TAG) { + ERROR("boundary tag not found (read 0x%x)\n",tempbt); + return -1; + } + + readlen=read_mem_stream(m,&templen,sizeof(templen)); + + if (readlen!=sizeof(templen)) { + ERROR("failed to read all data for taglen\n"); + return -1; + } + + if (templen!=taglen) { + ERROR("tag size mismatch (requested=%lld, actual=%lld)\n",taglen,templen); + return -1; + } + + temptag = palacios_alloc(taglen); - mylen = (uint32_t) len; + if (!temptag) { + ERROR("cannot allocate temporary tag\n"); + return -1; + } + + mylen = (uint32_t) len; - readlen=read_mem_stream(m,buf,mylen); + readlen=read_mem_stream(m,temptag,mylen); - if (readlen!=mylen) { - ERROR("failed to read all data for key\n"); - return -1; - } else { - return (sint64_t)readlen; - } + if (readlen!=mylen) { + ERROR("failed to read all data for tag\n"); + palacios_free(temptag); + return -1; + } + + if (memcmp(tag,temptag,taglen)) { + ERROR("tag mismatch\n"); + palacios_free(temptag); + return -1; + } + + palacios_free(temptag); + + readlen=read_mem_stream(m,&templen,sizeof(templen)); + + if (readlen!=sizeof(templen)) { + ERROR("failed to read all data for data len\n"); + return -1; + } + + if (templen!=len) { + ERROR("data size mismatch (requested=%lld, actual=%lld)\n",len,templen); + return -1; + } + + mylen = (uint32_t) len; + + readlen=read_mem_stream(m,buf,mylen); + + if (readlen!=mylen) { + ERROR("failed to read all data for key\n"); + return -1; + } else { + return (sint64_t)readlen; + } } @@ -531,7 +684,7 @@ static v3_keyed_stream_t open_stream_file(char *url, return 0; } - strcpy(fks->path,url+5); + strcpy(fks->path,url+5); // will fit fks->stype=STREAM_FILE; @@ -573,7 +726,7 @@ static v3_keyed_stream_t open_stream_file(char *url, de = lookup_create(&nd,1); - if (IS_ERR(de)) { + if (!de || IS_ERR(de)) { ERROR("cannot allocate dentry\n"); goto fail_out; } @@ -643,11 +796,12 @@ static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream, ERROR("cannot allocate file keyed stream for key %s\n",key); return 0; } + // this sequence will fit and terminate with a zero strcpy(path,fks->path); strcat(path,"/"); strcat(path,key); - fs = (struct file_stream *) palacios_alloc(sizeof(struct file_stream *)); + fs = (struct file_stream *) palacios_alloc(sizeof(struct file_stream)); if (!fs) { ERROR("cannot allocate file keyed stream for key %s\n",key); @@ -657,9 +811,9 @@ static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream, fs->stype=STREAM_FILE; - fs->f = filp_open(path,O_RDWR|O_CREAT,0600); - - if (IS_ERR(fs->f)) { + fs->f = filp_open(path,O_RDWR|O_CREAT|O_LARGEFILE,0600); + + if (!fs->f || IS_ERR(fs->f)) { ERROR("cannot open relevent file \"%s\" for stream \"file:%s\" and key \"%s\"\n",path,fks->path,key); palacios_free(fs); palacios_free(path); @@ -682,83 +836,795 @@ static void close_key_file(v3_keyed_stream_t stream, palacios_free(fs); } + +static sint64_t write_file(struct file_stream *fs, void *buf, sint64_t len) +{ + ssize_t done, left, total; + mm_segment_t old_fs; + + total=len; + left=len; + + while (left>0) { + old_fs = get_fs(); + set_fs(get_ds()); + done = fs->f->f_op->write(fs->f, buf+(total-left), left, &(fs->f->f_pos)); + set_fs(old_fs); + if (done<=0) { + return -1; + } else { + left -= done; + } + } + + return len; +} + static sint64_t write_key_file(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, void *buf, sint64_t len) { - struct file_keyed_stream *fks = (struct file_keyed_stream *) stream; - struct file_stream *fs = (struct file_stream *) key; - mm_segment_t old_fs; + struct file_keyed_stream *fks = (struct file_keyed_stream *) stream; + struct file_stream *fs = (struct file_stream *) key; + sint64_t writelen; + + if (fks->ot!=V3_KS_WR_ONLY) { + return -1; + } + + if (taglen<0 || len<0) { + ERROR("Negative taglen or data len\n"); + return -1; + } + + writelen=write_file(fs,&BOUNDARY_TAG,sizeof(BOUNDARY_TAG)); + + if (writelen!=sizeof(BOUNDARY_TAG)) { + ERROR("failed to write all data for boundary tag\n"); + return -1; + } + + writelen=write_file(fs,&taglen,sizeof(taglen)); + + if (writelen!=sizeof(taglen)) { + ERROR("failed to write taglen\n"); + return -1; + } + + if (write_file(fs,tag,taglen)!=taglen) { + ERROR("failed to write tag\n"); + return -1; + } + + writelen=write_file(fs,&len,sizeof(len)); + + if (writelen!=sizeof(len)) { + ERROR("failed to write data len\n"); + return -1; + } + + return write_file(fs,buf,len); +} + +static sint64_t read_file(struct file_stream *fs, void *buf, sint64_t len) +{ ssize_t done, left, total; - - if (fks->ot!=V3_KS_WR_ONLY) { - return -1; - } - - if (len<0) { - return -1; - } + mm_segment_t old_fs; total=len; left=len; - old_fs = get_fs(); - set_fs(get_ds()); while (left>0) { - done = fs->f->f_op->write(fs->f, buf+(total-left), left, &(fs->f->f_pos)); + old_fs = get_fs(); + set_fs(get_ds()); + done = fs->f->f_op->read(fs->f, buf+(total-left), left, &(fs->f->f_pos)); + set_fs(old_fs); if (done<=0) { return -1; } else { left -= done; } } - set_fs(old_fs); return len; } - static sint64_t read_key_file(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, void *buf, sint64_t len) { - struct file_keyed_stream *fks = (struct file_keyed_stream *) stream; - struct file_stream *fs = (struct file_stream *) key; - mm_segment_t old_fs; - ssize_t done, left, total; - - if (fks->ot!=V3_KS_RD_ONLY) { + struct file_keyed_stream *fks = (struct file_keyed_stream *) stream; + struct file_stream *fs = (struct file_stream *) key; + void *temptag; + uint32_t tempbt; + sint64_t templen; + sint64_t readlen; + + if (fks->ot!=V3_KS_RD_ONLY) { + return -1; + } + + if (len<0 || taglen<0) { + ERROR("taglen or data len is negative\n"); + return -1; + } + + readlen=read_file(fs,&tempbt,sizeof(tempbt)); + + if (readlen!=sizeof(tempbt)) { + ERROR("failed to read all data for boundary tag\n"); + return -1; + } + + if (tempbt!=BOUNDARY_TAG) { + ERROR("boundary tag not found (read 0x%x)\n",tempbt); + return -1; + } + + readlen=read_file(fs,&templen,sizeof(templen)); + + if (readlen!=sizeof(templen)) { + ERROR("failed to read all data for tag len\n"); + return -1; + } + + if (templen!=taglen) { + ERROR("tag size mismatch (requested=%lld, actual=%lld)\n",taglen,templen); + return -1; + } + + temptag=palacios_alloc(taglen); + + if (!temptag) { + ERROR("Cannot allocate temptag\n"); + return -1; + } + + if (read_file(fs,temptag,taglen)!=taglen) { + ERROR("Cannot read tag\n"); + palacios_free(temptag); + return -1; + } + + if (memcmp(temptag,tag,taglen)) { + ERROR("Tag mismatch\n"); + palacios_free(temptag); + return -1; + } + + palacios_free(temptag); + + readlen=read_file(fs,&templen,sizeof(templen)); + + if (readlen!=sizeof(templen)) { + ERROR("failed to read all data for data len\n"); + return -1; + } + + if (templen!=len) { + ERROR("datasize mismatch (requested=%lld, actual=%lld)\n",len,templen); + return -1; + } + + return read_file(fs,buf,len); + +} + + +/*************************************************************************************************** + Textfile-based implementation ("textfile:") + + Note that this implementation uses the internal structure and functions of the + "file:" implementation +*************************************************************************************************/ + +// optimize the reading and decoding of hex data +// this weakens the parser, so that: +// tag =0A0B0D +// will work, but +// tag = 0A 0B 0D +// will not. Note the leading whitespace +#define TEXTFILE_OPT_HEX 0 + +// +// The number of bytes handled at a time by the hex putter and getter +// +#define MAX_HEX_SEQ 64 + +/* + A text file keyed stream is a file_keyed_stream, + only with a different stype +*/ + +#define PAUSE() +//#define PAUSE() ssleep(5) + + +typedef struct file_keyed_stream textfile_keyed_stream; + +typedef struct file_stream textfile_stream; + + +static v3_keyed_stream_t open_stream_textfile(char *url, + v3_keyed_stream_open_t ot) +{ + textfile_keyed_stream *me; + + if (strncasecmp(url,"textfile:",9)) { + WARNING("illegitimate attempt to open textfile stream \"%s\"\n",url); + return 0; + } + + me = (textfile_keyed_stream *) open_stream_file(url+4, ot); + + if (!me) { + ERROR("could not create underlying file stream\n"); + return 0; + } + + me->stype=STREAM_TEXTFILE; + + return me; +} + + + +static void close_stream_textfile(v3_keyed_stream_t stream) +{ + textfile_keyed_stream *me = stream; + + me->stype=STREAM_FILE; + + close_stream_file(me); + +} + +static void preallocate_hint_key_textfile(v3_keyed_stream_t stream, + char *key, + uint64_t size) +{ + textfile_keyed_stream *me = stream; + + me->stype=STREAM_FILE; + + preallocate_hint_key_file(me,key,size); + + me->stype=STREAM_TEXTFILE; + +} + + +static inline int isoneof(char c, char *sl, int m) +{ + int i; + + for (i=0;i=0 && c<=9) { + return '0'+c; + } else if (c>=0xa && c<=0xf) { + return 'a'+(c-0xa); + } else { + return -1; + } +} + +static int hexify_byte(char *c, char b) +{ + char n; + n = hexify_nybble( (b >> 4) & 0xf); + if (n==-1) { + return -1; + } + c[0] = n; + n = hexify_nybble( b & 0xf); + if (n==-1) { + return -1; + } + c[1] = n; + return 0; +} + + +static char dehexify_nybble(char c) +{ + if (c>='0' && c<='9') { + return c-'0'; + } else if (c>='a' && c<='f') { + return 0xa + (c-'a'); + } else if (c>='A' && c<='F') { + return 0xa + (c-'A'); + } else { + return -1; + } +} + +static int dehexify_byte(char *c, char *b) +{ + char n; + n = dehexify_nybble(c[0]); + if (n==-1) { + return -1; + } + *b = n << 4; + n = dehexify_nybble(c[1]); + if (n==-1) { + return -1; + } + *b |= n; + return 0; +} + + +#if TEXTFILE_OPT_HEX + + +// Here the sl array, of length m is the number +static int get_hexbytes_as_data(textfile_stream *s, char *buf, int n) +{ + char rbuf[MAX_HEX_SEQ*2]; + int left = n; + int off = 0; + int cur = 0; + int i; + + while (left>0) { + cur = left > MAX_HEX_SEQ ? MAX_HEX_SEQ : left; + if (read_file(s,rbuf,cur*2)!=cur*2) { + ERROR("Cannot read data in getting hexbytes as data\n"); + return -1; + } + + for (i=0;i0) { - done = fs->f->f_op->read(fs->f, buf+(total-left), left, &(fs->f->f_pos)); - if (done<=0) { - return -1; - } else { - left -= done; - } +static int put_data_as_hexbytes(textfile_stream *s, char *buf, int n) +{ + char rbuf[MAX_HEX_SEQ*2]; + int left = n; + int off = 0; + int cur = 0; + int i; + + while (left>0) { + cur = left > MAX_HEX_SEQ ? MAX_HEX_SEQ : left; + for (i=0;istype=STREAM_FILE; + + ms = open_key_file(mks,key); + + if (!ms) { + ERROR("cannot open underlying file keyed stream for key %s\n",key); + mks->stype=STREAM_TEXTFILE; + return 0; + } + + if (mks->ot==V3_KS_WR_ONLY) { + + // Now we write the section header + + ms->stype=STREAM_FILE; + + if (put_string(ms,"[")) { + close_key_file(mks,ms); + mks->stype=STREAM_TEXTFILE; + return 0; + } + + if (put_string(ms,key)) { + close_key_file(mks,ms); + mks->stype=STREAM_TEXTFILE; + return 0; + } + + if (put_string(ms,"]\n")) { + close_key_file(mks,ms); + mks->stype=STREAM_TEXTFILE; + return 0; + } + + + mks->stype=STREAM_TEXTFILE; + ms->stype=STREAM_TEXTFILE; + + return ms; + + } else if (mks->ot == V3_KS_RD_ONLY) { + // Now we readthe section header + int keylen=strlen(key); + char *tempkey = palacios_alloc(keylen+3); + + ms->stype=STREAM_FILE; + + if (!tempkey) { + ERROR("Allocation failed in opening key\n"); + close_key_file(mks,ms); + mks->stype=STREAM_FILE; + return 0; + } + + + if (token_scan(ms,tempkey,keylen+3,"\t\r\n",3)) { + ERROR("Cannot scan for token (key search)\n"); + close_key_file(mks,ms); + mks->stype=STREAM_TEXTFILE; + palacios_free(tempkey); + return 0; + } + + tempkey[keylen+2] = 0; + + // Should now have [key]0 + + if (tempkey[0]!='[' || + tempkey[keylen+1]!=']' || + memcmp(key,tempkey+1,keylen)) { + ERROR("key mismatch: target key=%s, found %s\n",key,tempkey); + palacios_free(tempkey); + close_key_file(mks,ms); + mks->stype=STREAM_TEXTFILE; + return 0; + } + + // key match done, success + + mks->stype=STREAM_TEXTFILE; + ms->stype=STREAM_TEXTFILE; + + palacios_free(tempkey); + + return ms; + + } else { + ERROR("Unknown open type in open_key_textfile\n"); + ms->stype=STREAM_FILE; + close_key_file(mks,ms); + return 0; + } + +} + + + +static void close_key_textfile(v3_keyed_stream_t stream, + v3_keyed_stream_key_t key) +{ + textfile_keyed_stream *mks = stream; + textfile_stream *ms=key; + + mks->stype=STREAM_FILE; + ms->stype=STREAM_FILE; + + close_key_file(mks,ms); + + mks->stype=STREAM_TEXTFILE; + +} + + +static sint64_t read_key_textfile(v3_keyed_stream_t stream, + v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, + void *buf, + sint64_t len) +{ + textfile_stream *ms = (textfile_stream *) key; + char tags[32]; + char *temptag; + + + + memcpy(tags,tag,taglen<31 ? taglen : 31); + tags[taglen<32? taglen : 31 ]=0; + + temptag=palacios_alloc(taglen+1); + if (!temptag) { + ERROR("Unable to allocate temptag in textfile read key\n"); + return -1; + } + + ms->stype=STREAM_FILE; + + if (token_scan(ms,temptag,taglen+1," \t\r\n=",5)) { + ERROR("Cannot scan for token (tag search)\n"); + ms->stype=STREAM_TEXTFILE; + palacios_free(temptag); + return -1; + } + + if (memcmp(tag,temptag,taglen)) { + ERROR("Tag mismatch in reading tag from textfile: desired tag=%s, actual tag=%s\n",tags,temptag); + ms->stype=STREAM_TEXTFILE; + palacios_free(temptag); + return -1; + } + + // tag matches, let's go and find our = + palacios_free(temptag); + + if (search_for(ms,'=')) { + ERROR("Unable to find = sign in tag data parse (tag=%s)\n", tags); + ms->stype=STREAM_TEXTFILE; + return -1; + } + + +#if TEXTFILE_OPT_HEX + if (get_hexbytes_as_data(ms,buf,len)) { + ERROR("Cannot read data in hex format (opt path) in textfile for tag %s\n",tags); + ms->stype=STREAM_TEXTFILE; + return -1; + } +#else + if (get_hexbytes_as_data_skip(ms,buf,len," \t\r\n",4)) { + ERROR("Cannot read data in hex format (unopt path) in textfile for tag %s\n",tags); + ms->stype=STREAM_TEXTFILE; + return -1; + } +#endif + + ms->stype=STREAM_TEXTFILE; + + return len; +} + +static sint64_t write_key_textfile(v3_keyed_stream_t stream, + v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, + void *buf, + sint64_t len) +{ + textfile_stream *ms = (textfile_stream *) key; + char tags[32]; + + + + memcpy(tags,tag,taglen<31 ? taglen : 31); + tags[taglen<32? taglen : 31 ]=0; + + /* if (taglen>100000 || len>100000) { + ERROR("Too big\n"); + return -1; + } + */ + + ms->stype=STREAM_FILE; + + if (put_string_n(ms,tag,taglen)) { + ERROR("Cannot write tag %s in textfile\n",tags); + ms->stype=STREAM_TEXTFILE; + return -1; + } + + if (put_string(ms,"=")) { + ERROR("Cannot write = in textfile for tag %s\n",tags); + ms->stype=STREAM_TEXTFILE; + return -1; + } + + if (put_data_as_hexbytes(ms,buf,len)) { + ERROR("Cannot write data in hex format in textfile for tag %s\n",tags); + ms->stype=STREAM_TEXTFILE; + return -1; + } + + if (put_string(ms,"\n")) { + ERROR("Cannot write trailing lf in textfile for tag %s\n",tags); + ms->stype=STREAM_TEXTFILE; + return -1; + } + + ms->stype=STREAM_TEXTFILE; + + return len; +} @@ -843,7 +1709,7 @@ static int do_request_to_response(struct user_keyed_stream *s, unsigned long *fl s->waiting = 1; // release the stream - spin_unlock_irqrestore(&(s->lock), *flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), *flags); // wake up anyone waiting on it wake_up_interruptible(&(s->user_wait_queue)); @@ -852,7 +1718,7 @@ static int do_request_to_response(struct user_keyed_stream *s, unsigned long *fl while (wait_event_interruptible(s->host_wait_queue, (s->waiting == 0)) != 0) {} // reacquire the lock for our called - spin_lock_irqsave(&(s->lock), *flags); + palacios_spinlock_lock_irqsave(&(s->lock), *flags); return 0; } @@ -873,7 +1739,7 @@ static int do_response_to_request(struct user_keyed_stream *s, unsigned long *fl s->waiting = 0; // release the stream - spin_unlock_irqrestore(&(s->lock), *flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), *flags); // wake up anyone waiting on it wake_up_interruptible(&(s->host_wait_queue)); @@ -892,16 +1758,16 @@ static unsigned int keyed_stream_poll_user(struct file *filp, poll_table *wait) return POLLERR; } - spin_lock_irqsave(&(s->lock), flags); + palacios_spinlock_lock_irqsave(&(s->lock), flags); + + poll_wait(filp, &(s->user_wait_queue), wait); if (s->waiting) { - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); return POLLIN | POLLRDNORM; } - - poll_wait(filp, &(s->user_wait_queue), wait); - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); return 0; } @@ -920,22 +1786,22 @@ static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsi // inform request size - spin_lock_irqsave(&(s->lock), flags); + palacios_spinlock_lock_irqsave(&(s->lock), flags); if (!(s->waiting)) { - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); return 0; } size = sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len; if (copy_to_user((void * __user) argp, &size, sizeof(uint64_t))) { - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); ERROR("palacios user key size request failed to copy data\n"); return -EFAULT; } - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); return 1; @@ -945,10 +1811,10 @@ static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsi // pull the request - spin_lock_irqsave(&(s->lock), flags); + palacios_spinlock_lock_irqsave(&(s->lock), flags); if (!(s->waiting)) { - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); ERROR("palacios user key pull request when not waiting\n"); return 0; } @@ -957,12 +1823,12 @@ static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsi if (copy_to_user((void __user *) argp, s->op, size)) { - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); ERROR("palacios user key pull request failed to copy data\n"); return -EFAULT; } - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); return 1; @@ -973,28 +1839,28 @@ static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsi // push the response - spin_lock_irqsave(&(s->lock), flags); + palacios_spinlock_lock_irqsave(&(s->lock), flags); if (!(s->waiting)) { - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); ERROR("palacios user key push response when not waiting\n"); return 0; } if (copy_from_user(&size, (void __user *) argp, sizeof(uint64_t))) { ERROR("palacios user key push response failed to copy size\n"); - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); return -EFAULT; } if (resize_op(&(s->op),size-sizeof(struct palacios_user_keyed_stream_op))) { ERROR("unable to resize op in user key push response\n"); - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); return -EFAULT; } if (copy_from_user(s->op, (void __user *) argp, size)) { - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); return -EFAULT; } @@ -1021,13 +1887,13 @@ static int keyed_stream_release_user(struct inode *inode, struct file *filp) struct user_keyed_stream *s = filp->private_data; unsigned long f1,f2; - spin_lock_irqsave(&(user_streams->lock),f1); - spin_lock_irqsave(&(s->lock), f2); + palacios_spinlock_lock_irqsave(&(user_streams->lock),f1); + palacios_spinlock_lock_irqsave(&(s->lock), f2); list_del(&(s->node)); - spin_unlock_irqrestore(&(s->lock), f2); - spin_unlock_irqrestore(&(user_streams->lock), f1); + palacios_spinlock_unlock_irqrestore(&(s->lock), f2); + palacios_spinlock_unlock_irqrestore(&(user_streams->lock), f1); palacios_free(s->url); palacios_free(s); @@ -1083,7 +1949,7 @@ int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned // Check for duplicate handler - spin_lock_irqsave(&(user_streams->lock), flags); + palacios_spinlock_lock_irqsave(&(user_streams->lock), flags); list_for_each_entry(s, &(user_streams->streams), node) { if (!strncasecmp(url, s->url, len)) { ERROR("user keyed stream connection with url \"%s\" already exists\n", url); @@ -1091,7 +1957,7 @@ int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned return -1; } } - spin_unlock_irqrestore(&(user_streams->lock), flags); + palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags); // Create connection s = palacios_alloc(sizeof(struct user_keyed_stream)); @@ -1122,9 +1988,9 @@ int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned init_waitqueue_head(&(s->host_wait_queue)); // Insert connection into list - spin_lock_irqsave(&(user_streams->lock), flags); + palacios_spinlock_lock_irqsave(&(user_streams->lock), flags); list_add(&(s->node), &(user_streams->streams)); - spin_unlock_irqrestore(&(user_streams->lock), flags); + palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags); return fd; } @@ -1139,15 +2005,15 @@ static struct user_keyed_stream *keyed_stream_user_find(char *url) return NULL; } - spin_lock_irqsave(&(user_streams->lock), flags); + palacios_spinlock_lock_irqsave(&(user_streams->lock), flags); list_for_each_entry(s, &(user_streams->streams), node) { if (!strcasecmp(url, s->url)) { - spin_unlock_irqrestore(&(user_streams->lock), flags); + palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags); return s; } } - spin_unlock_irqrestore(&(user_streams->lock), flags); + palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags); return NULL; } @@ -1165,17 +2031,17 @@ static v3_keyed_stream_t open_stream_user(char *url, v3_keyed_stream_open_t ot) return NULL; } - spin_lock_irqsave(&(s->lock), flags); + palacios_spinlock_lock_irqsave(&(s->lock), flags); if (s->waiting) { - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); ERROR("cannot open user stream %s as it is already in waiting state\n",url); return NULL; } s->otype = ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot; - spin_unlock_irqrestore(&(s->lock), flags); + palacios_spinlock_unlock_irqrestore(&(s->lock), flags); return s; @@ -1206,22 +2072,22 @@ static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key) uint64_t len = strlen(key)+1; void *user_key; - spin_lock_irqsave(&(s->lock), flags); + palacios_spinlock_lock_irqsave(&(s->lock), flags); if (resize_op(&(s->op),len)) { - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); ERROR("cannot resize op in opening key %s on user keyed stream %s\n",key,s->url); return NULL; } s->op->type = PALACIOS_KSTREAM_OPEN_KEY; s->op->buf_len = len; - strncpy(s->op->buf,key,len); + strncpy(s->op->buf,key,len); // will terminate buffer // enter with it locked if (do_request_to_response(s,&flags)) { - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); ERROR("request/response handling failed\n"); return NULL; } @@ -1229,7 +2095,7 @@ static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key) user_key=s->op->user_key; - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); return user_key; } @@ -1240,10 +2106,10 @@ static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key) uint64_t len = 0; unsigned long flags; - spin_lock_irqsave(&(s->lock), flags); + palacios_spinlock_lock_irqsave(&(s->lock), flags); if (resize_op(&(s->op),len)) { - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); ERROR("cannot resize op in closing key 0x%p on user keyed stream %s\n",key,s->url); return; } @@ -1254,13 +2120,13 @@ static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key) // enter with it locked if (do_request_to_response(s,&flags)) { - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); ERROR("request/response handling failed\n"); return; } // return with it locked - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); return; } @@ -1268,23 +2134,26 @@ static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key) static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, void *buf, sint64_t rlen) { struct user_keyed_stream *s = (struct user_keyed_stream *) stream; - uint64_t len = 0 ; + uint64_t len = taglen ; sint64_t xfer; unsigned long flags; - spin_lock_irqsave(&(s->lock), flags); + palacios_spinlock_lock_irqsave(&(s->lock), flags); if (s->otype != V3_KS_RD_ONLY) { - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); ERROR("attempt to read key from stream that is not in read state on %s\n",s->url); } + if (resize_op(&(s->op),len)) { - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url); return -1; } @@ -1293,10 +2162,13 @@ static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t ke s->op->buf_len = len ; s->op->xfer = rlen; s->op->user_key = key; + s->op->data_off = taglen; + + memcpy(s->op->buf,tag,taglen); // enter with it locked if (do_request_to_response(s,&flags)) { - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); ERROR("request/response handling failed\n"); return -1; } @@ -1304,60 +2176,65 @@ static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t ke if (s->op->xfer>0) { + // data_off must be zero memcpy(buf,s->op->buf,s->op->xfer); } xfer=s->op->xfer; - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); return xfer; } static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, void *buf, sint64_t wlen) { struct user_keyed_stream *s = (struct user_keyed_stream *) stream; - struct palacios_user_keyed_stream_op *op; - uint64_t len = wlen ; + uint64_t len = taglen + wlen ; sint64_t xfer; unsigned long flags; - - spin_lock_irqsave(&(s->lock), flags); + + + palacios_spinlock_lock_irqsave(&(s->lock), flags); if (s->otype != V3_KS_WR_ONLY) { - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); ERROR("attempt to write key on stream that is not in write state on %s\n",s->url); } if (resize_op(&(s->op),len)) { - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url); return -1; } - op = s->op; - s->op->type = PALACIOS_KSTREAM_WRITE_KEY; s->op->buf_len = len; s->op->xfer = wlen; s->op->user_key = key; + s->op->data_off = taglen; - memcpy(s->op->buf,buf,wlen); + memcpy(s->op->buf,tag,taglen); + memcpy(s->op->buf+taglen,buf,wlen); // enter with it locked if (do_request_to_response(s,&flags)) { - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); ERROR("request/response handling failed\n"); return -1; } // return with it locked + // no data comes back, xfer should be size of data write (not tag) + xfer=s->op->xfer; - spin_unlock_irqrestore(&(s->lock),flags); + palacios_spinlock_unlock_irqrestore(&(s->lock),flags); return xfer; } @@ -1856,7 +2733,10 @@ static void close_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t input_ } } -static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, void *buf, sint64_t len) +static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, + void *buf, sint64_t len) { struct net_keyed_stream * nks = (struct net_keyed_stream *)stream; @@ -1865,10 +2745,20 @@ static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t ke return -1; } + if (!tag) { + ERROR("Tag is NULL in write_key_net\n"); + return -1; + } + if (len<0) { ERROR("len is negative in write_key_net\n"); return -1; } + + if (taglen<0) { + ERROR("taglen is negative in write_key_net\n"); + return -1; + } if (!key){ ERROR("write_key: key is NULL in write_key_net\n"); @@ -1882,6 +2772,18 @@ static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t ke } if (nks->ot==V3_KS_WR_ONLY) { + if (send_msg(nks->ns,(char*)(&BOUNDARY_TAG),sizeof(BOUNDARY_TAG))!=sizeof(BOUNDARY_TAG)) { + ERROR("Could not send boundary tag in write_key_net\n"); + return -1; + } + if (send_msg(nks->ns,(char*)(&taglen),sizeof(taglen))!=sizeof(taglen)) { + ERROR("Could not send tag length in write_key_net\n"); + return -1; + } + if (send_msg(nks->ns,tag,taglen)!=taglen) { + ERROR("Could not send tag in write_key_net\n"); + return -1; + } if (send_msg(nks->ns,(char*)(&len),sizeof(len))!=sizeof(len)) { ERROR("Could not send data length in write_key_net\n"); return -1; @@ -1899,19 +2801,33 @@ static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t ke } -static sint64_t read_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, void *buf, sint64_t len) +static sint64_t read_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, + void *buf, sint64_t len) { struct net_keyed_stream * nks = (struct net_keyed_stream *)stream; + void *temptag; if (!buf) { ERROR("Buf is NULL in read_key_net\n"); return -1; } + + if (!tag) { + ERROR("Tag is NULL in read_key_net\n"); + return -1; + } if(len<0) { ERROR("len is negative in read_key_net\n"); return -1; } + + if(taglen<0) { + ERROR("taglen is negative in read_key_net\n"); + return -1; + } if (!key) { ERROR("read_key: key is NULL in read_key_net\n"); @@ -1920,23 +2836,69 @@ static sint64_t read_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key if (nks->ot==V3_KS_RD_ONLY) { + + sint64_t slen; + uint32_t tempbt; + + if (recv_msg(nks->ns,(char*)(&tempbt),sizeof(tempbt))!=sizeof(tempbt)) { + ERROR("Cannot receive boundary tag in read_key_net\n"); + return -1; + } - sint64_t slen; + if (tempbt!=BOUNDARY_TAG) { + ERROR("Invalid boundary tag (received 0x%x\n",tempbt); + return -1; + } + temptag=palacios_alloc(taglen); + if (!temptag) { + ERROR("failed to allocate temptag\n"); + return -1; + } + + if (recv_msg(nks->ns,(char*)(&slen),sizeof(slen))!=sizeof(slen)) { + ERROR("Cannot receive tag len in read_key_net\n"); + palacios_free(temptag); + return -1; + } + + if (slen!=taglen) { + ERROR("Tag len expected does not matched tag len decoded in read_key_net\n"); + palacios_free(temptag); + return -1; + } + + if (recv_msg(nks->ns,temptag,taglen)!=taglen) { + ERROR("Cannot recieve tag in read_key_net\n"); + palacios_free(temptag); + return -1; + } + + if (memcmp(temptag,tag,taglen)) { + ERROR("Tag mismatch\n"); + palacios_free(temptag); + return -1; + } + if (recv_msg(nks->ns,(char*)(&slen),sizeof(slen))!=sizeof(slen)) { ERROR("Cannot receive data len in read_key_net\n"); + palacios_free(temptag); return -1; } if (slen!=len) { ERROR("Data len expected does not matched data len decoded in read_key_net\n"); + palacios_free(temptag); return -1; } if (recv_msg(nks->ns,buf,len)!=len) { ERROR("Cannot recieve data in read_key_net\n"); + palacios_free(temptag); return -1; } + + palacios_free(temptag); } else { ERROR("Permissions incorrect for the stream in read_key_net\n"); @@ -1961,8 +2923,10 @@ static v3_keyed_stream_t open_stream(char *url, return open_stream_file(url,ot); } else if (!strncasecmp(url,"user:",5)) { return open_stream_user(url,ot); - } else if(!strncasecmp(url,"net:",4)){ + } else if (!strncasecmp(url,"net:",4)){ return open_stream_net(url,ot); + } else if (!strncasecmp(url,"textfile:",9)) { + return open_stream_textfile(url,ot); } else { ERROR("unsupported type in attempt to open keyed stream \"%s\"\n",url); return 0; @@ -1979,6 +2943,9 @@ static void close_stream(v3_keyed_stream_t stream) case STREAM_FILE: return close_stream_file(stream); break; + case STREAM_TEXTFILE: + return close_stream_textfile(stream); + break; case STREAM_USER: return close_stream_user(stream); break; @@ -2003,6 +2970,9 @@ static void preallocate_hint_key(v3_keyed_stream_t stream, case STREAM_FILE: preallocate_hint_key_file(stream,key,size); break; + case STREAM_TEXTFILE: + preallocate_hint_key_textfile(stream,key,size); + break; case STREAM_USER: return preallocate_hint_key_user(stream,key,size); break; @@ -2028,6 +2998,9 @@ static v3_keyed_stream_key_t open_key(v3_keyed_stream_t stream, case STREAM_FILE: return open_key_file(stream,key); break; + case STREAM_TEXTFILE: + return open_key_textfile(stream,key); + break; case STREAM_USER: return open_key_user(stream,key); break; @@ -2053,6 +3026,9 @@ static void close_key(v3_keyed_stream_t stream, case STREAM_FILE: return close_key_file(stream,key); break; + case STREAM_TEXTFILE: + return close_key_textfile(stream,key); + break; case STREAM_USER: return close_key_user(stream,key); break; @@ -2069,22 +3045,27 @@ static void close_key(v3_keyed_stream_t stream, static sint64_t write_key(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, void *buf, sint64_t len) { struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream; switch (gks->stype){ case STREAM_MEM: - return write_key_mem(stream,key,buf,len); + return write_key_mem(stream,key,tag,taglen,buf,len); break; case STREAM_FILE: - return write_key_file(stream,key,buf,len); + return write_key_file(stream,key,tag,taglen,buf,len); + break; + case STREAM_TEXTFILE: + return write_key_textfile(stream,key,tag,taglen,buf,len); break; case STREAM_USER: - return write_key_user(stream,key,buf,len); + return write_key_user(stream,key,tag,taglen,buf,len); break; case STREAM_NETWORK: - return write_key_net(stream,key,buf,len); + return write_key_net(stream,key,tag,taglen,buf,len); break; default: ERROR("unknown stream type %d in write_key\n",gks->stype); @@ -2097,22 +3078,27 @@ static sint64_t write_key(v3_keyed_stream_t stream, static sint64_t read_key(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, + void *tag, + sint64_t taglen, void *buf, sint64_t len) { struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream; switch (gks->stype){ case STREAM_MEM: - return read_key_mem(stream,key,buf,len); + return read_key_mem(stream,key,tag,taglen,buf,len); break; case STREAM_FILE: - return read_key_file(stream,key,buf,len); + return read_key_file(stream,key,tag,taglen,buf,len); + break; + case STREAM_TEXTFILE: + return read_key_textfile(stream,key,tag,taglen,buf,len); break; case STREAM_USER: - return read_key_user(stream,key,buf,len); + return read_key_user(stream,key,tag,taglen,buf,len); break; case STREAM_NETWORK: - return read_key_net(stream,key,buf,len); + return read_key_net(stream,key,tag,taglen,buf,len); break; default: ERROR("unknown stream type %d in read_key\n",gks->stype); @@ -2159,7 +3145,7 @@ static int init_keyed_streams( void ) INIT_LIST_HEAD(&(user_streams->streams)); - spin_lock_init(&(user_streams->lock)); + palacios_spinlock_init(&(user_streams->lock)); V3_Init_Keyed_Streams(&hooks); @@ -2171,6 +3157,8 @@ static int deinit_keyed_streams( void ) { palacios_free_htable(mem_streams,1,1); + palacios_spinlock_deinit(&(user_streams->lock)); + palacios_free(user_streams); WARNING("Deinit of Palacios Keyed Streams likely leaked memory\n"); @@ -2190,6 +3178,7 @@ static int guest_init_keyed_streams(struct v3_guest * guest, void ** vm_data ) static int guest_deinit_keyed_streams(struct v3_guest * guest, void * vm_data) { + remove_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT); return 0; }