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.


Paranoid error checking in userspace utils
[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->buf      : buffer (contains key name (open key) or value (write key))
34     //
35
36     // now built a response
37     *resp = malloc(sizeof(struct palacios_user_keyed_stream_op) + datasize);
38     if (!*resp) {
39         fprintf(stderr, "ERROR: could not allocate space for response\n");
40         return -1;
41     }
42
43     (*resp)->len = sizeof(struct palacios_user_keyed_stream_op) + datasize;
44     (*resp)->buf_len = datasize;
45     (*resp)->type = req->type;
46     (*resp)->user_key = req->user_key;
47
48     //
49     // The response 
50     // 
51     // resp->len      : total structure length 
52     // resp->type     : response type - must match the request
53     // resp->xfer     : contains the size of data read or written (in read key or write key)
54     // resp->user_key : unused
55     // resp->buf_len  : length of data following
56     // resp->buf      : buffer (contains the data (read key))
57     
58
59     return 0;
60 }
61
62 int main(int argc, char *argv[])
63 {
64     int devfd;
65     int mode=0;
66     char *vm, *url;
67
68     if (argc!=4) { 
69         usage();
70         exit(-1);
71     }
72     
73     vm=argv[1];
74     url=argv[2];
75     mode = argv[3][0]=='s';
76
77     // The URL should begin with user:
78     // the remainder can be used to demultiplex internally
79     // for example user:file:foo might refer to a user-side file-based implementation
80     //
81
82     if (strncmp(url,"user:",5)) { 
83         fprintf(stderr, "URL %s is not a user: url\n");
84         exit(-1);
85     }
86
87     fprintf(stderr,"Attempting to attach to vm %s as url %s\n", vm, url);
88     
89     if ((devfd = v3_user_keyed_stream_attach(vm,url))<0) { 
90         perror("failed to attach");
91         exit(-1);
92     }
93     
94     fprintf(stderr,"Attachment succeeded, I will now operate in %s mode\n", mode==0 ? "busywait" : "select");
95     
96     if (mode==0) { 
97         //busywait
98
99         struct palacios_user_keyed_stream_op *req;
100         struct palacios_user_keyed_stream_op *resp;
101         uint64_t datasize;
102
103         while (1) { 
104             while (!(v3_user_keyed_stream_have_request(devfd))) { 
105             }
106             v3_user_keyed_stream_pull_request(devfd, &req);
107
108             do_work(req, &resp);
109             
110             v3_user_keyed_stream_push_response(devfd, resp);
111
112             free(resp);
113             free(req);
114         }
115     } else {
116
117         struct palacios_user_keyed_stream_op *req;
118         struct palacios_user_keyed_stream_op *resp;
119         uint64_t datasize;
120         fd_set   readset;
121         int rc;
122
123         // select-based operation so that you can wait for multiple things
124         
125         while (1) { 
126             FD_ZERO(&readset);
127             FD_SET(devfd,&readset);
128
129             rc = select(devfd+1, &readset, 0, 0, 0);  // pick whatever you want to select on, just include devfd
130
131             if (rc>0) { 
132                 if (FD_ISSET(devfd,&readset)) { 
133                     // a request is read for us!
134                     v3_user_keyed_stream_pull_request(devfd, &req);
135
136                     do_work(req, &resp);
137                     
138                     v3_user_keyed_stream_push_response(devfd, resp);
139                     
140                     free(resp);
141                     free(req);
142                 }
143             }
144         }
145     }
146
147     v3_user_keyed_stream_detatch(devfd);
148
149     return 0;
150                     
151 }