30 #include <linux/virgo_queue.h>
31 #include <linux/virgocloudexecsvc.h>
32 #include <linux/virgo_config.h>
33 #include <linux/string.h>
34 #include <linux/kallsyms.h>
131 int clone_func(
void* args)
173 if (parameterIsExecutable==2)
175 struct task_struct *task;
177 printk(
"clone_func(): creating kernel thread and waking up, parameterIsExecutable=%d\n", parameterIsExecutable);
182 if(use_as_kingcobra_service==1)
184 printk(
"clone_func(): VIRGO cloudexec is used as KingCobra service, invoking push_request() in kernelspace for data: %s\n",cloneFunction);
186 vrq->data=kstrdup(cloneFunction,GFP_ATOMIC);
196 task=kthread_create(virgo_cloud_test_kernelspace, (
void*)args,
"cloneFunction thread");
197 woken_up_2=wake_up_process(task);
200 else if(parameterIsExecutable==1)
202 file_stdout=filp_open(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/cpupooling/virgocloudexec/virgo_cloudexec_upcall_usermode_log.txt", O_RDWR|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR);
203 fd_install(1,file_stdout);
204 fd_install(2,file_stdout);
205 argv[0]=kstrdup(cloneFunction,GFP_ATOMIC);
210 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/cpupooling/virgocloudexec/";
211 envp[1]=
"HOME=/home/kashrinivaasan";
215 printk(
"clone_func(): executing call_usermodehelper for data from virgo_clone: %s - parameterIsExecutable=%d\n",cloneFunction, parameterIsExecutable);
216 ret=call_usermodehelper(cloneFunction, argv, envp, UMH_WAIT_EXEC);
218 printk(
"clone_func(): call_usermodehelper() for binary %s returns ret=%d\n", cloneFunction, ret);
219 filp_close(file_stdout,NULL);
221 else if (parameterIsExecutable==0)
223 file_stdout=filp_open(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/cpupooling/virgocloudexec/virgo_cloudexec_upcall_usermode_log.txt", O_RDWR|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR);
224 fd_install(1,file_stdout);
225 fd_install(2,file_stdout);
226 argv[0]=kstrdup(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/cpupooling/virgocloudexec/virgo_kernelupcall_plugin",GFP_ATOMIC);
227 argv[1]=kstrdup(cloneFunction,GFP_ATOMIC);
229 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/cpupooling/virgocloudexec/";
230 envp[1]=
"HOME=/home/kashrinivaasan";
232 printk(KERN_INFO
"clone_func(): executing the virgo_clone() syscall function parameter in cloud - parameterIsExecutable=%d, cloneFunction=%s\n",parameterIsExecutable,cloneFunction);
233 ret=call_usermodehelper(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/cpupooling/virgocloudexec/virgo_kernelupcall_plugin",argv,envp,UMH_WAIT_EXEC);
247 printk(
"clone_func(): call_usermodehelper() for virgo_kernelupcall_plugin returns ret=%d\n", ret);
252 strcpy(buffer,
"clone_func(): cloudclonethread executed for clone_func(), sending message to virgo_clone() remote syscall client");
253 filp_close(file_stdout,NULL);
258 char* strip_control_M(
char* str)
260 char* dupstr=kstrdup(str, GFP_ATOMIC);
261 char* newstr=strsep(&dupstr,
"\r\n ");
265 int kernel_space_func(
void* args)
267 printk(KERN_INFO
"kernel_space_func(): parameterIsExecutable=2; executing function in kernel address space\n");
271 void read_virgo_config()
296 f=filp_open(
"/etc/virgo_cloud.conf", O_RDONLY, 0);
305 for(k=0; k < num_cloud_nodes; k++)
306 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]);
308 printk(KERN_INFO
"read_virgo_config(): virgo_cloud config file being read \n");
314 bytesread=vfs_read(f, buf, 256, &pos);
316 printk(KERN_INFO
"do_virgo_cloud_init(): virgo_cloud config file string of comma separated IPs : %s \n",buf);
323 char* bufdup=kstrdup(buf,GFP_ATOMIC);
324 printk(KERN_INFO
"tokenize_list_of_ip_addrs(): bufdup = %s\n",bufdup);
325 while(bufdup != NULL)
327 token=strsep(&bufdup, delim);
328 printk(KERN_INFO
"tokenize_list_of_ip_addrs(): %s\n",token);
329 node_ip_addrs_in_cloud[i]=kstrdup(token,GFP_ATOMIC);
330 printk(KERN_INFO
"tokenize_list_of_ip_addrs(): node_ip_addrs_in_cloud[%d] = %s\n",i,node_ip_addrs_in_cloud[i]);
341 int tokenize_list_of_ip_addrs(
char* buf)
345 char* bufdup=kstrdup(buf,GFP_ATOMIC);
346 printk(KERN_INFO,
"tokenize_list_of_ip_addrs(): bufdup = %s\n",bufdup);
348 while(bufdup != NULL)
350 token=strsep(&bufdup, delim);
351 printk(KERN_INFO,
"tokenize_list_of_ip_addrs(): %s\n",token);
366 virgocloudexec_init(
void)
368 printk(KERN_INFO
"virgocloudexec_init(): doing init() of virgocloudexec kernel module\n");
369 printk(KERN_INFO
"virgocloudexec_init(): starting virgo cloudexec service kernel thread\n");
371 printk(KERN_INFO
"virgocloudexec_init(): invoking read_virgo_config()\n");
374 memset(&sin, 0,
sizeof(
struct sockaddr_in));
375 sin.sin_family=AF_INET;
376 sin.sin_addr.s_addr=htonl(INADDR_ANY);
377 sin.sin_port=htons(10000);
380 error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
381 printk(KERN_INFO
"virgocloudexec_init(): sock_create() returns error code: %d\n",error);
383 error = kernel_bind(sock, (
struct sockaddr*)&sin,
sizeof(
struct sockaddr_in));
384 printk(KERN_INFO
"virgocloudexec_init(): kernel_bind() returns error code: %d\n",error);
386 error = kernel_listen(sock, 2);
387 printk(KERN_INFO
"virgocloudexec_init(): kernel_listen() returns error code: %d\n", error);
389 virgo_cloudexec_service(NULL);
398 EXPORT_SYMBOL(virgocloudexec_init);
400 int virgocloudexec_create(
void)
412 struct socket *clientsock;
415 error = kernel_accept(sock, &clientsock, 0);
440 EXPORT_SYMBOL(virgocloudexec_create);
442 int virgocloudexec_recvfrom(
struct socket* clsock)
448 struct socket *clientsock=clsock;
450 struct msghdr msg = { NULL, };
455 struct task_struct *task;
457 char buffer[BUF_SIZE];
467 if(clientsock != NULL )
469 printk(KERN_INFO
"virgocloudexec_recvfrom(): before kernel_recvmsg()\n");
470 memset(buffer, 0,
sizeof(buffer));
471 iov.iov_base=(
void*)buffer;
472 iov.iov_len=
sizeof(buffer);
473 msg.msg_name = (
struct sockaddr *) &sin;
474 msg.msg_namelen =
sizeof(
struct sockaddr);
475 msg.msg_iov = (
struct iovec *) &iov;
477 msg.msg_control = NULL;
478 msg.msg_controllen = 0;
480 msg.msg_flags=MSG_NOSIGNAL;
485 len = kernel_recvmsg(clientsock, &msg, &iov, 1, buflen, msg.msg_flags);
486 printk(KERN_INFO
"virgocloudexec_recvfrom(): kernel_recvmsg() returns len: %d\n",len);
491 cloneFunction = strip_control_M(kstrdup(buffer,GFP_ATOMIC));
492 if(use_as_kingcobra_service==1)
494 client_ip_str=kmalloc(BUF_SIZE,GFP_ATOMIC);
495 struct sockaddr_in* ipaddr=(
struct sockaddr_in*)clientsock;
496 long ipaddr_int = ipaddr->sin_addr.s_addr;
498 sprintf(client_ip_str,
"%x",ipaddr_int);
499 printk(KERN_INFO
"virgocloudexec_recvfrom(): client_ip_str = %s\n",client_ip_str);
500 client_ip_str=kstrdup(strcat(client_ip_str,
"#"),GFP_ATOMIC);
501 printk(KERN_INFO
"virgocloudexec_recvfrom(): client_ip_str with # appended = %s\n",client_ip_str);
502 cloneFunction = kstrdup(strcat(client_ip_str,cloneFunction),GFP_ATOMIC);
503 printk(KERN_INFO
"virgocloudexec_recvfrom(): use_as_kingcobra_service=1, cloneFunction with prepended client ip=%s\n",cloneFunction);
507 printk(KERN_INFO
"virgocloudexec_recvfrom(): kernel_recvmsg() returns in recv buffer: %s\n", buffer);
508 print_buffer(buffer);
509 le32_to_cpus(buffer);
510 printk(KERN_INFO
"virgocloudexec_recvfrom(): kernel_recvmsg() le32 to cpu %s\n", buffer);
511 printk(KERN_INFO
"virgocloudexec_recvfrom(): cloneFunction : %s \n", cloneFunction);
514 task=kthread_create(clone_func, (
void*)args,
"clone_func thread");
515 int woken_up=wake_up_process(task);
516 printk(KERN_INFO
"virgocloudexec_recvfrom(): clone thread woken_up : %d\n",woken_up);
524 EXPORT_SYMBOL(virgocloudexec_recvfrom);
526 void print_buffer(
char* buffer)
528 printk(KERN_INFO
"print_buffer(): ");
530 for(i=0; i <
sizeof(buffer); i++)
531 printk(KERN_INFO
"%c", buffer[i]);
532 printk(KERN_INFO
"\n");
535 int virgocloudexec_sendto(
struct socket* clsock)
542 struct socket *clientsock=clsock;
544 struct msghdr msg = { NULL, };
549 struct task_struct *task;
551 char buffer[BUF_SIZE];
557 if(clientsock != NULL)
559 strcpy(buffer,
"virgo_cloudexec_sendto(): cloudclonethread executed for clone_func(), sending message to virgo_clone() remote syscall client\n");
564 iov.iov_len=
sizeof(buffer);
565 msg.msg_name = (
struct sockaddr *) &sin;
566 msg.msg_namelen =
sizeof(
struct sockaddr);
567 msg.msg_iov = (
struct iovec *) &iov;
569 msg.msg_control = NULL;
570 msg.msg_controllen = 0;
574 printk(KERN_INFO
"virgocloudexec_sendto(): before kernel_sendmsg() for send buffer: %s\n", buffer);
575 ret = kernel_sendmsg(clientsock, &msg, &iov, 1, buflen);
578 printk(KERN_INFO
"virgocloudexec_sendto(): kernel_sendmsg() returns ret: %d\n",ret);
583 kernel_sock_shutdown(clientsock,SOCK_WAKE_URG);
584 printk(KERN_INFO
"virgocloudexec_sendto(): Shut down Kernel Side Client Socket with SOCK_WAKE_URG after sendmsg \n");
585 sock_release(clientsock);
586 printk(KERN_INFO
"virgocloudexec_sendto(): sock_release invoked on client socket \n");
650 EXPORT_SYMBOL(virgocloudexec_sendto);
654 virgocloudexec_exit(
void)
656 printk(KERN_INFO
"exiting virgocloudexec kernel module \n");
660 EXPORT_SYMBOL(virgocloudexec_exit);
663 MODULE_LICENSE(
"GPL");
664 module_init(virgocloudexec_init);
665 module_exit(virgocloudexec_exit);