30 #include <linux/virgo_fs.h>
31 #include <linux/virgocloudexecfssvc.h>
32 #include <linux/virgo_config.h>
34 #include <linux/string.h>
35 #include <linux/kallsyms.h>
48 int fs_func(
void* args)
86 char buffer[BUF_SIZE];
90 char* fsFunction = (
char*)args;
91 struct virgo_fs_args* vmargs=parse_virgofs_command(kstrdup(fsFunction,GFP_KERNEL));
94 if (parameterIsExecutable==2)
96 struct task_struct *task;
98 printk(KERN_INFO
"fs_func(): creating kernel thread and waking up, parameterIsExecutable=%d\n", parameterIsExecutable);
99 printk(KERN_INFO
"Creating Kernel Thread for %s in virgo_cloud_fs_kernelspace fs driver module with fs_args[0]=%s, fs_args[1]=%s\n",vmargs->fs_cmd,vmargs->fs_args[0],vmargs->fs_args[1]);
109 virgo_fs_ret=toFuncPtr(kstrdup(strcat(kstrdup(vmargs->fs_cmd,GFP_KERNEL),
"_kernelspace"),GFP_KERNEL))(vmargs);
111 printk(KERN_INFO
"fs_func(): virgo fs kernelspace module returns value virgo_fs_ret=%p\n", (
char*)virgo_fs_ret);
116 else if(parameterIsExecutable==1)
118 file_stdout=filp_open(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/cloudfs/virgo_cloudexec_fs_upcall_usermode_log.txt", O_RDWR|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR);
119 fd_install(1,file_stdout);
120 fd_install(2,file_stdout);
121 argv[0]=kstrdup(fsFunction,GFP_KERNEL);
123 envp[0]=
"PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/kashrinivaasan/linux-3.7.8/drivers/virgo/cloudfs/";
124 envp[1]=
"HOME=/home/kashrinivaasan";
128 printk(
"fs_func(): executing call_usermodehelper for data from virgo_fs : %s - parameterIsExecutable=%d\n",fsFunction, parameterIsExecutable);
129 ret=call_usermodehelper(fsFunction, argv, envp, UMH_WAIT_EXEC);
130 printk(
"fs_func(): call_usermodehelper() for binary %s returns ret=%d\n", fsFunction, ret);
131 filp_close(file_stdout,NULL);
133 else if (parameterIsExecutable==0)
135 file_stdout=filp_open(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/cloudfs/virgo_cloudexec_fs_upcall_usermode_log.txt", O_RDWR|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR);
145 argv[0]=kstrdup(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/cloudfs/virgo_kernelupcall_plugin",GFP_KERNEL);
146 argv[1]=kstrdup(fsFunction,GFP_KERNEL);
148 envp[0]=
"PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games::/home/kashrinivaasan/linux-3.7.8/drivers/virgo/cloudfs/";
149 envp[1]=
"HOME=/home/kashrinivaasan";
151 printk(KERN_INFO
"fs_func(): executing the virgo_fs function parameter in cloud - parameterIsExecutable=%d, fsFunction=%s\n",parameterIsExecutable,fsFunction);
152 ret=call_usermodehelper(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/cloudfs/virgo_kernelupcall_plugin",argv,envp,UMH_WAIT_EXEC);
154 printk(
"fs_func(): call_usermodehelper() for virgo_kernelupcall_plugin returns ret=%d\n", ret);
159 strcpy(buffer,
"fs_func(): cloudclonethread executed for fs_func(), sending message to virgo_malloc() remote syscall client");
160 filp_close(file_stdout,NULL);
165 char* strip_control_M(
char* str)
167 printk(
"strip_control_M(): str=%s before strsep\n",str);
168 char* dupstr=kstrdup(str, GFP_KERNEL);
169 char* newstr=strsep(&dupstr,
"\r\n");
170 printk(
"strip_control_M(): newstr=%s after carriage return newline strsep\n",newstr);
174 int kernel_space_func(
void* args)
176 printk(KERN_INFO
"kernel_space_func(): parameterIsExecutable=2; executing function in kernel address space\n");
180 void read_virgo_config()
205 f=filp_open(
"/etc/virgo_cloud.conf", O_RDONLY, 0);
214 for(k=0; k < num_cloud_nodes; k++)
215 printk(KERN_INFO
"virgo kernel service: read_virgo_config(): before reading virgo_cloud.conf - virgo_cloud ip address - %d: %s\n", k+1, node_ip_addrs_in_cloud[k]);
217 printk(KERN_INFO
"read_virgo_config(): virgo_cloud config file being read \n");
222 bytesread=vfs_read(f, buf, 256, &pos);
223 printk(KERN_INFO
"do_virgo_cloud_init(): virgo_cloud config file string of comma separated IPs : %s \n",buf);
228 char* bufdup=kstrdup(buf,GFP_KERNEL);
229 printk(KERN_INFO
"tokenize_list_of_ip_addrs(): bufdup = %s\n",bufdup);
230 while(bufdup != NULL)
232 token=strsep(&bufdup, delim);
233 printk(KERN_INFO
"tokenize_list_of_ip_addrs(): %s\n",token);
234 node_ip_addrs_in_cloud[i]=kstrdup(token,GFP_KERNEL);
235 printk(KERN_INFO
"tokenize_list_of_ip_addrs(): node_ip_addrs_in_cloud[%d] = %s\n",i,node_ip_addrs_in_cloud[i]);
246 int tokenize_list_of_ip_addrs(
char* buf)
250 char* bufdup=kstrdup(buf,GFP_KERNEL);
251 printk(KERN_INFO,
"tokenize_list_of_ip_addrs(): bufdup = %s\n",bufdup);
253 while(bufdup != NULL)
255 token=strsep(&bufdup, delim);
256 printk(KERN_INFO,
"tokenize_list_of_ip_addrs(): %s\n",token);
265 virgocloudexec_fs_init(
void)
268 static struct sockaddr_in sin;
270 printk(KERN_INFO
"virgocloudexec_fs_init(): doing init() of virgocloudexec_fs kernel module\n");
271 printk(KERN_INFO
"virgocloudexec_fs_init(): starting virgo cloudexec service kernel thread\n");
273 printk(KERN_INFO
"virgocloudexec_fs_init(): invoking read_virgo_config()\n");
276 memset(&sin, 0,
sizeof(
struct sockaddr_in));
277 sin.sin_family=AF_INET;
278 sin.sin_addr.s_addr=htonl(INADDR_ANY);
279 sin.sin_port=htons(50000);
281 error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
282 printk(KERN_INFO
"virgocloudexec_fs_init(): sock_create() returns error code: %d\n",error);
284 error = kernel_bind(sock, (
struct sockaddr*)&sin,
sizeof(
struct sockaddr_in));
285 printk(KERN_INFO
"virgocloudexec_fs_init(): kernel_bind() returns error code: %d\n",error);
287 error = kernel_listen(sock, 2);
288 printk(KERN_INFO
"virgocloudexec_fs_init(): kernel_listen() returns error code: %d\n", error);
290 virgo_cloudexec_fs_service(NULL);
294 EXPORT_SYMBOL(virgocloudexec_fs_init);
296 int virgocloudexec_fs_create(
void)
310 struct socket *clientsock;
313 error = kernel_accept(sock, &clientsock, 0);
338 EXPORT_SYMBOL(virgocloudexec_fs_create);
340 void* virgocloudexec_fs_recvfrom(
struct socket* clsock)
343 struct sockaddr_in sin;
344 void* virgo_fs_func_ret;
350 struct socket *clientsock=clsock;
352 struct msghdr msg = { NULL, };
357 struct task_struct *task;
359 char buffer[BUF_SIZE];
367 if(clientsock != NULL )
369 printk(KERN_INFO
"virgocloudexec_fs_recvfrom(): before kernel_recvmsg()\n");
370 memset(buffer, 0, BUF_SIZE);
371 iov.iov_base=(
void*)buffer;
372 iov.iov_len=BUF_SIZE;
373 msg.msg_name = (
struct sockaddr *) &sin;
374 msg.msg_namelen =
sizeof(
struct sockaddr);
375 msg.msg_iov = (
struct iovec *) &iov;
377 msg.msg_control = NULL;
378 msg.msg_controllen = 0;
379 msg.msg_flags=MSG_NOSIGNAL;
381 len = kernel_recvmsg(clientsock, &msg, &iov, 1, buflen, msg.msg_flags);
382 printk(KERN_INFO
"virgocloudexec_fs_recvfrom(): kernel_recvmsg() returns len: %d\n",len);
387 fsFunction = strip_control_M(kstrdup(buffer,GFP_KERNEL));
389 printk(KERN_INFO
"virgocloudexec_fs_recvfrom(): kernel_recvmsg() returns in recv: iov.iov_base=%s, buffer: %s\n", iov.iov_base, buffer);
390 print_buffer(buffer);
391 le32_to_cpus(buffer);
392 printk(KERN_INFO
"virgocloudexec_fs_recvfrom(): kernel_recvmsg() le32 to cpu %s\n", buffer);
393 printk(KERN_INFO
"virgocloudexec_fs_recvfrom(): fsFunction : %s \n", fsFunction);
394 args=(
void*)fsFunction;
402 virgo_fs_func_ret=fs_func((
void*)args);
410 return virgo_fs_func_ret;
412 EXPORT_SYMBOL(virgocloudexec_fs_recvfrom);
414 void print_buffer(
char* buffer)
416 printk(KERN_INFO
"virgo_cloudexec_fs: print_buffer(): ");
418 for(i=0; i < BUF_SIZE; i++)
419 printk(KERN_INFO
"%c", buffer[i]);
420 printk(KERN_INFO
"\n");
423 int virgocloudexec_fs_sendto(
struct socket* clsock,
void* virgo_fs_ret)
431 struct sockaddr_in sin;
432 struct socket *clientsock=clsock;
434 struct msghdr msg = { NULL, };
439 struct task_struct *task;
441 char buffer[BUF_SIZE];
444 if(clientsock != NULL)
447 printk(KERN_INFO
"virgocloudexec_fs_sendto(): virgo_fs_ret=%s\n",virgo_fs_ret);
448 if(virgo_fs_ret != NULL)
455 printk(KERN_INFO
"virgocloudexec_fs_sendto(): data sent=%s\n",virgo_fs_ret);
456 strcpy(buffer,virgo_fs_ret);
459 iov.iov_len=BUF_SIZE;
460 msg.msg_name = (
struct sockaddr *) &sin;
461 msg.msg_namelen =
sizeof(
struct sockaddr);
462 msg.msg_iov = (
struct iovec *) &iov;
464 msg.msg_control = NULL;
465 msg.msg_controllen = 0;
469 printk(KERN_INFO
"virgocloudexec_fs_sendto(): before kernel_sendmsg() for send buffer: %s\n", buffer);
470 ret = kernel_sendmsg(clientsock, &msg, &iov, 1, buflen);
471 printk(KERN_INFO
"virgocloudexec_fs_sendto(): kernel_sendmsg() returns ret: %d\n",ret);
472 sock_release(clientsock);
473 printk(KERN_INFO
"virgocloudexec_fs_sendto(): sock_release invoked on client socket \n");
477 EXPORT_SYMBOL(virgocloudexec_fs_sendto);
481 virgocloudexec_fs_exit(
void)
483 printk(KERN_INFO
"exiting virgocloudexec_fs kernel module \n");
486 EXPORT_SYMBOL(virgocloudexec_fs_exit);
493 struct virgo_fs_args* parse_virgofs_command(
char* fsFunction)
496 vmargs->fs_cmd=kstrdup(strsep(&fsFunction,
"("),GFP_KERNEL);
497 printk(KERN_INFO
"parse_virgofs_command: vmargs->fs_cmd: %s\n", vmargs->fs_cmd);
499 if(strcmp(vmargs->fs_cmd,
"virgo_cloud_open")==0 || strcmp(vmargs->fs_cmd,
"virgo_cloud_close")==0)
501 vmargs->fs_args[0]=kstrdup(strsep(&fsFunction,
")"),GFP_KERNEL);
502 printk(KERN_INFO
"parse_virgofs_command: vmargs->fs_args[0]: %s\n", vmargs->fs_args[0]);
503 vmargs->fs_args[1]=NULL;
507 vmargs->fs_args[0]=kstrdup(strsep(&fsFunction,
","),GFP_KERNEL);
508 vmargs->fs_args[1]=kstrdup(strsep(&fsFunction,
","),GFP_KERNEL);
509 vmargs->fs_args[2]=kstrdup(strsep(&fsFunction,
","),GFP_KERNEL);
510 vmargs->fs_args[3]=kstrdup(strsep(&fsFunction,
")"),GFP_KERNEL);
511 printk(KERN_INFO
"parse_virgofs_command: vmargs->fs_args[0]: %s\n", vmargs->fs_args[0]);
512 printk(KERN_INFO
"parse_virgofs_command: vmargs->fs_args[1]: %s\n", vmargs->fs_args[1]);
513 printk(KERN_INFO
"parse_virgofs_command: vmargs->fs_args[2]: %d\n", vmargs->fs_args[2]);
514 printk(KERN_INFO
"parse_virgofs_command: vmargs->fs_args[3]: %d\n", vmargs->fs_args[3]);
515 vmargs->fs_args[4]=NULL;
520 FPTR toFuncPtr(
char* functionName)
522 if(strcmp(functionName,
"virgo_cloud_open_kernelspace")==0)
523 return virgo_cloud_open_kernelspace;
524 if(strcmp(functionName,
"virgo_cloud_close_kernelspace")==0)
525 return virgo_cloud_close_kernelspace;
526 if(strcmp(functionName,
"virgo_cloud_read_kernelspace")==0)
527 return virgo_cloud_read_kernelspace;
528 if(strcmp(functionName,
"virgo_cloud_write_kernelspace")==0)
529 return virgo_cloud_write_kernelspace;
532 MODULE_LICENSE(
"GPL");
533 module_init(virgocloudexec_fs_init);
534 module_exit(virgocloudexec_fs_exit);