6 #include <sys/select.h>
14 #define sint64_t int64_t
16 #include "v3_user_keyed_stream.h"
20 fprintf(stderr,"v3_user_keyed_stream_file /dev/v3-vm0 user:file:stream\n");
25 int dir_setup(char *dir)
31 char buf[strlen(dir)+strlen("/.palacios_keyed_stream_user_file")+1];
35 strcat(buf,"/.palacios_keyed_stream_user_file");
39 // does the directory exist or can we create it
43 if (mkdir(dir,0700)<0) {
44 perror("cannot create directory");
51 // can we write to it?
53 fd = open(buf,O_RDWR | O_CREAT,0600);
56 perror("cannot write directory");
72 int handle_open_key(struct palacios_user_keyed_stream_op *req,
73 struct palacios_user_keyed_stream_op **resp,
77 char fn[strlen(dir)+req->buf_len+1];
84 fd = open(fn,O_RDWR | O_CREAT,0600);
86 (*resp) = malloc(sizeof(struct palacios_user_keyed_stream_op)+0);
92 (*resp)->len=sizeof(struct palacios_user_keyed_stream_op);
93 (*resp)->type=req->type;
95 (*resp)->user_key=(void*)(uint64_t)fd;
103 int handle_close_key(struct palacios_user_keyed_stream_op *req,
104 struct palacios_user_keyed_stream_op **resp,
110 fd = (int) (uint64_t) (req->user_key);
114 (*resp) = malloc(sizeof(struct palacios_user_keyed_stream_op)+0);
120 (*resp)->len=sizeof(struct palacios_user_keyed_stream_op);
121 (*resp)->type=req->type;
123 (*resp)->user_key=(void*)(uint64_t)fd;
131 int read_all(int fd, char *buf, int len)
139 xfer=read(fd, buf+len-left,left);
141 perror("cannot read file");
150 int write_all(int fd, char *buf, int len)
158 xfer=write(fd, buf+len-left,left);
160 perror("cannot write file");
170 int handle_write_key(struct palacios_user_keyed_stream_op *req,
171 struct palacios_user_keyed_stream_op **resp,
176 sint64_t taglen = req->data_off;
177 sint64_t datalen = req->buf_len - req->data_off;
179 if (datalen != req->xfer) {
180 fprintf(stderr,"Odd, xfer=%lld but datalen computed is %lld\n",req->xfer,datalen);
181 if (datalen > req->xfer) {
186 fd = (int) (uint64_t) (req->user_key);
189 rc = write_all(fd,req->buf,taglen);
192 // failed to write tag, lets report as negative error
193 fprintf(stderr,"Failed to write tag (taglen=%lld, rc=%d)\n",taglen,rc);
197 rc = write_all(fd,req->buf+taglen,datalen);
199 fprintf(stderr,"Failed to write data (datalen=%lld, rc=%d)\n",datalen,rc);
203 (*resp) = malloc(sizeof(struct palacios_user_keyed_stream_op)+0);
209 (*resp)->len=sizeof(struct palacios_user_keyed_stream_op);
210 (*resp)->type=req->type;
212 (*resp)->user_key=(void*)(uint64_t)fd;
221 int handle_read_key(struct palacios_user_keyed_stream_op *req,
222 struct palacios_user_keyed_stream_op **resp,
227 sint64_t taglen = req->data_off;
228 char temptag[taglen];
230 fd = (int) (uint64_t) (req->user_key);
232 (*resp) = malloc(sizeof(struct palacios_user_keyed_stream_op)+req->xfer);
238 // read key and compare
239 rc = read_all(fd,temptag,taglen);
243 fprintf(stderr,"Failed to read tag (taglen=%lld, rc=%d)\n",taglen,rc);
247 if (memcmp(temptag,req->buf,taglen)) {
249 fprintf(stderr,"Tag mismatch in read tag\n");
253 rc = read_all(fd,(*resp)->buf,req->xfer);
257 (*resp)->len=sizeof(struct palacios_user_keyed_stream_op) + (rc>0 ? rc : 0);
258 (*resp)->type=req->type;
260 (*resp)->user_key=(void*)(uint64_t)fd;
261 (*resp)->buf_len=rc>0 ? rc : 0;
262 (*resp)->data_off = 0;
271 int handle_request(struct palacios_user_keyed_stream_op *req,
272 struct palacios_user_keyed_stream_op **resp,
278 case PALACIOS_KSTREAM_OPEN:
279 case PALACIOS_KSTREAM_CLOSE:
280 fprintf(stderr,"unsupported stream open or close\n");
284 case PALACIOS_KSTREAM_OPEN_KEY:
285 return handle_open_key(req,resp,dir);
287 case PALACIOS_KSTREAM_CLOSE_KEY:
288 return handle_close_key(req,resp,dir);
290 case PALACIOS_KSTREAM_READ_KEY:
291 return handle_read_key(req,resp,dir);
293 case PALACIOS_KSTREAM_WRITE_KEY:
294 return handle_write_key(req,resp,dir);
297 fprintf(stderr,"unknown request type\n");
306 int run(int devfd, char *dir)
308 struct palacios_user_keyed_stream_op *req;
309 struct palacios_user_keyed_stream_op *resp;
315 FD_SET(devfd,&readset);
317 rc = select(devfd+1, &readset, 0, 0, 0);
320 if (FD_ISSET(devfd,&readset)) {
324 if (v3_user_keyed_stream_pull_request(devfd, &req)) {
325 fprintf(stderr, "could not get request\n");
330 err=handle_request(req, &resp, dir);
332 if (v3_user_keyed_stream_push_response(devfd, resp)) {
333 fprintf(stderr,"could not send response\n");
340 fprintf(stderr, "request handling resulted in an error, continuing\n");
354 int main(int argc, char *argv[])
368 if (strncmp(url,"user:file:",10)) {
369 fprintf(stderr, "Url %s is not a user:file: url\n",url);
375 if (dir_setup(dir)) {
376 fprintf(stderr,"Unable to open or create directory %s\n",dir);
380 fprintf(stderr,"Attempting to attach to vm %s as url %s\n", vm, url);
382 if ((devfd = v3_user_keyed_stream_attach(vm,url))<0) {
383 perror("failed to attach");
387 fprintf(stderr,"Attached and running\n");
391 v3_user_keyed_stream_detach(devfd);