Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


6068b0cf31863859571775face61a8f9b4d55a75
[palacios.git] / linux_usr / v3_user_keyed_stream_example.c
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <stdint.h>
5 #include <string.h>
6 #include <sys/select.h>
7 #include <malloc.h>
8
9 #define sint64_t int64_t
10
11 #include "v3_user_keyed_stream.h"
12
13 void usage()
14 {
15     fprintf(stderr,"v3_user_keyed_stream_example /dev/v3-vm0 user:mystreamtype:mystream busywait|select\n");
16 }
17
18
19 int do_work(struct palacios_user_keyed_stream_op *req, 
20             struct palacios_user_keyed_stream_op **resp)
21 {
22     uint64_t datasize;
23     
24     //
25     //
26     // Process request here
27     // 
28     // req->len      : total structure length
29     // req->type     : request type (currently open/close key and read/write key
30     // req->xfer     : unused
31     // req->user_key : the opaque key previously provided by you by an open key
32     // req->buf_len  : length of data
33     // req->data_off : start of data within the buffer 
34     //                 buf[0..data_off-1] is a tag (for read or write key)
35     //                 buf[data_off..buf_len-1] is data (for write key)
36     // req->buf      : buffer 
37     //                    open key:   key name (open key)
38     //                    read key:   tag
39     //                    write key:  tag and data
40  
41     // now built a response
42     *resp = malloc(sizeof(struct palacios_user_keyed_stream_op) + datasize);
43     if (!*resp) {
44         fprintf(stderr, "ERROR: could not allocate space for response\n");
45         return -1;
46     }
47
48     (*resp)->len = sizeof(struct palacios_user_keyed_stream_op) + datasize;
49     (*resp)->buf_len = datasize;
50     (*resp)->data_off = 0; // always the case for a response
51     (*resp)->type = req->type;
52     (*resp)->user_key = req->user_key;
53
54     //
55     // The response 
56     // 
57     // resp->len      : total structure length 
58     // resp->type     : response type - must match the request
59     // resp->xfer     : contains the size of data read or written (in read key or write key)
60     // resp->user_key : unused
61     // resp->buf_len  : length of data following
62     // resp->data_off : offset of the data in the buffer
63     // resp->buf      : buffer (contains the data (read key))
64     //                    read key:   data
65     //                    write key:  nothing
66     
67
68     return 0;
69 }
70
71 int main(int argc, char *argv[])
72 {
73     int devfd;
74     int mode=0;
75     char *vm, *url;
76
77     if (argc!=4) { 
78         usage();
79         exit(-1);
80     }
81     
82     vm=argv[1];
83     url=argv[2];
84     mode = argv[3][0]=='s';
85
86     // The URL should begin with user:
87     // the remainder can be used to demultiplex internally
88     // for example user:file:foo might refer to a user-side file-based implementation
89     //
90
91     if (strncmp(url,"user:",5)) { 
92         fprintf(stderr, "URL %s is not a user: url\n");
93         exit(-1);
94     }
95
96     fprintf(stderr,"Attempting to attach to vm %s as url %s\n", vm, url);
97     
98     if ((devfd = v3_user_keyed_stream_attach(vm,url))<0) { 
99         perror("failed to attach");
100         exit(-1);
101     }
102     
103     fprintf(stderr,"Attachment succeeded, I will now operate in %s mode\n", mode==0 ? "busywait" : "select");
104     
105     if (mode==0) { 
106         //busywait
107
108         struct palacios_user_keyed_stream_op *req;
109         struct palacios_user_keyed_stream_op *resp;
110         uint64_t datasize;
111
112         while (1) { 
113             while (!(v3_user_keyed_stream_have_request(devfd))) { 
114             }
115             v3_user_keyed_stream_pull_request(devfd, &req);
116
117             do_work(req, &resp);
118             
119             v3_user_keyed_stream_push_response(devfd, resp);
120
121             free(resp);
122             free(req);
123         }
124     } else {
125
126         struct palacios_user_keyed_stream_op *req;
127         struct palacios_user_keyed_stream_op *resp;
128         uint64_t datasize;
129         fd_set   readset;
130         int rc;
131
132         // select-based operation so that you can wait for multiple things
133         
134         while (1) { 
135             FD_ZERO(&readset);
136             FD_SET(devfd,&readset);
137
138             rc = select(devfd+1, &readset, 0, 0, 0);  // pick whatever you want to select on, just include devfd
139
140             if (rc>0) { 
141                 if (FD_ISSET(devfd,&readset)) { 
142                     // a request is read for us!
143                     v3_user_keyed_stream_pull_request(devfd, &req);
144
145                     do_work(req, &resp);
146                     
147                     v3_user_keyed_stream_push_response(devfd, resp);
148                     
149                     free(resp);
150                     free(req);
151                 }
152             }
153         }
154     }
155
156     v3_user_keyed_stream_detatch(devfd);
157
158     return 0;
159                     
160 }