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.


Cleanup based on cppcheck pass (GEARS)
[palacios.git] / gears / services / devfile / devfile_preload.c
1 /* 
2    Device File Virtualization Guest Preload Library
3
4    (c) Akhil Guliani and William Gross, 2015
5      
6    Adapted from MPI module (c) 2012 Peter Dinda
7
8 */
9
10 #define _GNU_SOURCE
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #include <errno.h>
16
17
18
19 #include "devfile_hc.h"
20 #include "devfile_guest_fd_tracker.h"
21
22 static int __LocalFD = 0;
23 static int __last_open_index = -1;
24
25
26 unsigned long long syscall();
27
28 int touch_ptr(volatile char* ptr, int size)
29 {
30     int i;
31     for(i=0;i<size;i+=4096){
32         // both read and write it
33         ptr[i] = ptr[i];
34     }
35     return 0;
36 }
37
38 int open(const char *path, int flags, mode_t mode)
39 {
40
41     DEBUG_PRINT("path %s %d %d\n", path, flags, mode);
42  
43     __last_open_index = check_name(path,dtrack);
44
45     if (__last_open_index>=0) {
46         DEBUG_PRINT("In our file, \n");
47         __LocalFD = dtrack[__last_open_index].devFD; 
48         if(__LocalFD >= 0) {
49             return __LocalFD;
50         } else {
51             // Execute open hypercall here
52             char buf[8192];
53             char* my_path;
54             int path_length = strlen(path)+1; 
55             //check if path is across a page boundary
56             //if so try to copy into a local buffer, that doesn't cross a page boundary
57             //if its greater than 4k, fail 
58             if (path_length > 4096){
59                 DEBUG_PRINT("Path greater than 4k, failing open\n");
60                 return -1;
61             }
62             //forcing path to be in a single page
63             my_path = (char*)((((unsigned long long)buf+4096)/4096)*4096);
64             strcpy(my_path,path); // my_path is touched via this
65             long long sys_errno;
66             int rcFD =  dev_file_syscall_hcall(SYS64_OPEN,(long long)my_path,flags,0 ,0,0,0,&sys_errno);
67             DEBUG_PRINT(" ReturnFD : %d; \n",  rcFD);
68             __LocalFD = rcFD;
69             // set global errno so caller can see
70             errno=sys_errno;
71             return rcFD;
72         }
73     } else {
74         DEBUG_PRINT("performing original open\n");
75         
76         return syscall(SYS64_OPEN, path, flags, mode);
77     }
78 }
79
80 size_t read(int fd, void *buf, size_t count)
81 {
82     //does buf+count extend pass page boundary?
83     //if so, only do up to page boundary
84     // if( (buf%4096)+count <= 4096)
85     //     normal
86
87     if (fd == __LocalFD || (check_fd(fd,dtrack)>=0)){
88         long long sys_errno;
89         //Need to handle only up to a page boundary, can't handle contiguous pages right now
90         count = MIN(count,4096-((unsigned long long)buf%4096));
91         touch_ptr(buf,count);
92         int ret =  dev_file_syscall_hcall(SYS64_READ,fd,(long long)buf,count,0,0,0,&sys_errno);
93         DEBUG_PRINT("Read of %lu bytes returned %d (errno %lld)\n",count,ret,sys_errno);
94         errno = sys_errno;
95         return ret;
96     } else {
97         DEBUG_PRINT("performing original read\n");
98         return syscall(SYS64_READ,fd, buf, count);
99     }
100 }
101
102 ssize_t write(int fd, const void *buf, size_t count)
103 {
104     if (fd == __LocalFD || (check_fd(fd,dtrack)>=0)) {
105         long long sys_errno;
106         //Need to handle only up to a page boundary, can't handle contiguous pages right now
107         count = MIN(count,4096-((unsigned long long)buf%4096));
108         touch_ptr((char*)buf,count);
109         int ret =  dev_file_syscall_hcall(SYS64_WRITE,fd, (long long)buf,count,0,0,0,&sys_errno);
110         DEBUG_PRINT("Write of %lu bytes returned %d (errno %lld)\n",count,ret,sys_errno);
111         errno=sys_errno;
112         return ret;
113     } else {
114         DEBUG_PRINT("performing original write\n");
115         return syscall(SYS64_WRITE,fd, buf, count);
116     }
117 }
118
119 int close(int fd)
120 {
121     int index = check_fd(fd,dtrack); 
122     if (fd == __LocalFD || (index>=0)) {
123         long long sys_errno;
124         int ret =  dev_file_syscall_hcall(SYS64_CLOSE,fd,0,0,0,0,0,&sys_errno);
125         if (ret >=0) {
126             dtrack[index].devFD = -1;
127             __LocalFD = -1;
128         }
129         DEBUG_PRINT("Close returned %d (errno %lld)\n",ret, sys_errno);
130         errno=sys_errno;
131         return ret;
132     } else {
133         DEBUG_PRINT("performing original close\n");
134         return syscall(SYS64_CLOSE,fd);
135     }
136 }
137
138
139 int ioctl(int fd, int request, void* data) {
140     //int sign_post;
141     int index = check_fd(fd,dtrack);
142     
143     // this is where a careful, device-specific decode is needed
144     // to figure out whether the argument or anything it points
145     // is a pointer.  
146     if (fd == __LocalFD || (index>=0)) {
147         long long sys_errno=0;
148         int ret;
149         // First cut for just the data pointer:
150         //   if (data > &sign_post){
151         //probably on stack
152         //    }
153         // if (data < brk()
154         ret = dev_file_syscall_hcall(SYS64_IOCTL,fd,request,(unsigned long long)data,0,0,0,&sys_errno);
155
156         DEBUG_PRINT("ioctl(%d) returned %d (errno %lld)\n",request,ret, sys_errno);
157         errno=sys_errno;
158         return ret;
159     }
160     else{
161         return syscall(SYS64_IOCTL,fd,request,data);
162     }
163     return -1;
164
165 }
166