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.


Merge branch 'devel' of ssh://newskysaw.cs.northwestern.edu/home/palacios/palacios...
[palacios.git] / linux_usr / v3_user_keyed_stream_file.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 #include <alloca.h>
9 #include <sys/types.h>
10 #include <dirent.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13
14 #define sint64_t int64_t
15
16 #include "v3_user_keyed_stream.h"
17
18 void usage()
19 {
20     fprintf(stderr,"v3_user_keyed_stream_file /dev/v3-vm0 user:file:stream\n");
21 }
22
23 char *dir;
24
25 int dir_setup(char *dir)
26 {
27     DIR *d;
28     int created=0;
29     int fd;
30     
31     char buf[strlen(dir)+strlen("/.palacios_keyed_stream_user_file")+1];
32
33
34     strcpy(buf,dir);
35     strcat(buf,"/.palacios_keyed_stream_user_file");
36
37     d=opendir(dir);
38
39     // does the directory exist or can we create it
40     if (d) { 
41         closedir(d);
42     } else {
43         if (mkdir(dir,0700)<0) { 
44             perror("cannot create directory");
45             return -1;
46         } else {
47             created=1;
48         }
49     }
50
51     // can we write to it?
52
53     fd = open(buf,O_RDWR | O_CREAT,0600);
54
55     if (fd<0) { 
56         perror("cannot write directory");
57         if (created) { 
58             rmdir(dir);
59         }
60         return -1;
61     }
62
63     // ok, we are done
64
65     close(fd);
66
67     return 0;
68 }
69     
70
71
72 int handle_open_key(struct palacios_user_keyed_stream_op *req, 
73                     struct palacios_user_keyed_stream_op **resp,
74                     char *dir)
75 {
76     int fd;
77     char fn[strlen(dir)+req->buf_len+1];
78
79     strcpy(fn,dir);
80     strcat(fn,"/");
81     strcat(fn,req->buf);
82
83
84     fd = open(fn,O_RDWR | O_CREAT,0600);
85     
86     (*resp) = malloc(sizeof(struct palacios_user_keyed_stream_op)+0);
87     
88     if (!(*resp)) {
89         return -1;
90     }
91
92     (*resp)->len=sizeof(struct palacios_user_keyed_stream_op);
93     (*resp)->type=req->type;
94     (*resp)->xfer=0;
95     (*resp)->user_key=(void*)fd;
96     (*resp)->buf_len=0;
97     
98     return 0;
99
100 }
101
102 int handle_close_key(struct palacios_user_keyed_stream_op *req, 
103                      struct palacios_user_keyed_stream_op **resp,
104                      char *dir)
105 {
106     int fd;
107     int rc;
108  
109     fd = (int) (req->user_key);
110
111     rc = close(fd);
112
113     (*resp) = malloc(sizeof(struct palacios_user_keyed_stream_op)+0);
114     
115     if (!(*resp)) {
116         return -1;
117     }
118
119     (*resp)->len=sizeof(struct palacios_user_keyed_stream_op);
120     (*resp)->type=req->type;
121     (*resp)->xfer=rc;
122     (*resp)->user_key=(void*)fd;
123     (*resp)->buf_len=0;
124     
125     return 0;
126
127 }
128
129 int read_all(int fd, char *buf, int len)
130 {
131     int xfer;
132     int left;
133
134     left=len;
135
136     while (left>0) { 
137         xfer=read(fd, buf+len-left,left);
138         if (xfer<0) {
139             perror("cannot read file");
140             return -1;
141         } else {
142             left-=xfer;
143         }
144     }
145     return len;
146 }
147
148 int write_all(int fd, char *buf, int len)
149 {
150     int xfer;
151     int left;
152
153     left=len;
154
155     while (left>0) { 
156         xfer=write(fd, buf+len-left,left);
157         if (xfer<0) {
158             perror("cannot write file");
159             return -1;
160         } else {
161             left-=xfer;
162         }
163     }
164     return len;
165 }
166
167
168 int handle_write_key(struct palacios_user_keyed_stream_op *req, 
169                      struct palacios_user_keyed_stream_op **resp,
170                      char *dir)
171 {
172     int fd;
173     int rc;
174  
175     fd = (int) (req->user_key);
176
177     rc = write_all(fd,req->buf,req->xfer);
178
179     (*resp) = malloc(sizeof(struct palacios_user_keyed_stream_op)+0);
180     
181     if (!(*resp)) {
182         return -1;
183     }
184
185     (*resp)->len=sizeof(struct palacios_user_keyed_stream_op);
186     (*resp)->type=req->type;
187     (*resp)->xfer=rc;
188     (*resp)->user_key=(void*)fd;
189     (*resp)->buf_len=0;
190     
191
192     return 0;
193
194 }
195
196 int handle_read_key(struct palacios_user_keyed_stream_op *req, 
197                     struct palacios_user_keyed_stream_op **resp,
198                     char *dir)
199 {
200     int fd;
201     int rc;
202  
203     fd = (int) (req->user_key);
204
205     (*resp) = malloc(sizeof(struct palacios_user_keyed_stream_op)+req->xfer);
206     
207     if (!(*resp)) {
208         return -1;
209     }
210
211     rc = read_all(fd,(*resp)->buf,req->xfer);
212
213     (*resp)->len=sizeof(struct palacios_user_keyed_stream_op) + (rc>0 ? rc : 0);
214     (*resp)->type=req->type;
215     (*resp)->xfer=rc;
216     (*resp)->user_key=(void*)fd;
217     (*resp)->buf_len=rc>0 ? rc : 0;
218     
219
220     return 0;
221
222 }
223
224
225
226
227 int handle_request(struct palacios_user_keyed_stream_op *req, 
228                    struct palacios_user_keyed_stream_op **resp,
229                    char *dir)
230 {
231     uint64_t datasize;
232     
233     switch (req->type) { 
234         case PALACIOS_KSTREAM_OPEN:
235         case PALACIOS_KSTREAM_CLOSE:
236             fprintf(stderr,"unsupported stream open or close\n");
237             return -1;
238             break;
239
240         case PALACIOS_KSTREAM_OPEN_KEY:
241             return handle_open_key(req,resp,dir);
242             break;
243         case PALACIOS_KSTREAM_CLOSE_KEY:
244             return handle_close_key(req,resp,dir);
245             break;
246         case PALACIOS_KSTREAM_READ_KEY:
247             return handle_read_key(req,resp,dir);
248             break;
249         case PALACIOS_KSTREAM_WRITE_KEY:
250             return handle_write_key(req,resp,dir);
251             break;
252         default:
253             fprintf(stderr,"unknown request type\n");
254             return -1;
255             break;
256     }
257
258     return 0;
259 }
260
261
262 int run(int devfd, char *dir) 
263
264     struct palacios_user_keyed_stream_op *req;
265     struct palacios_user_keyed_stream_op *resp;
266     fd_set   readset;
267     int rc;
268     
269     while (1) { 
270         FD_ZERO(&readset);
271         FD_SET(devfd,&readset);
272         
273         rc = select(devfd+1, &readset, 0, 0, 0);  
274         
275         if (rc>0) { 
276             if (FD_ISSET(devfd,&readset)) { 
277
278                 int err;
279
280                 if (v3_user_keyed_stream_pull_request(devfd, &req)) { 
281                     fprintf(stderr, "could not get request\n");
282                     free(req);
283                     return -1;
284                 }
285                 
286                 err=handle_request(req, &resp, dir);
287
288                 if (v3_user_keyed_stream_push_response(devfd, resp)) { 
289                     fprintf(stderr,"could not send response\n");
290                     free(req);
291                     free(resp);
292                     return -1;
293                 }
294
295                 if (err) { 
296                     fprintf(stderr, "request handling resulted in an error, continuing\n");
297                 }
298                 
299                 free(req);
300                 free(resp);
301             }
302         }
303     }
304
305     return 0;
306 }
307
308
309
310 int main(int argc, char *argv[])
311 {
312     int devfd;
313     char *vm, *url;
314     char *dir;
315
316     if (argc!=3) { 
317         usage();
318         exit(-1);
319     }
320     
321     vm=argv[1];
322     url=argv[2];
323
324     if (strncmp(url,"user:file:",10)) { 
325         fprintf(stderr, "Url %s is not a user:file: url\n",url);
326         exit(-1);
327     }
328
329     dir = url+10;
330
331     if (dir_setup(dir)) { 
332         fprintf(stderr,"Unable to open or create directory %s\n",dir);
333         return -1;
334     }
335
336     fprintf(stderr,"Attempting to attach to vm %s as url %s\n", vm, url);
337     
338     if ((devfd = v3_user_keyed_stream_attach(vm,url))<0) { 
339         perror("failed to attach");
340         exit(-1);
341     }
342     
343     fprintf(stderr,"Attached and running\n");
344
345     run(devfd,dir);
346
347     v3_user_keyed_stream_detach(devfd);
348     
349     return 0;
350
351 }
352