30 #include <linux/virgo_queue.h>
31 #include <linux/virgo_mempool.h>
32 #include <linux/virgocloudexecmempoolsvc.h>
33 #include <linux/virgo_config.h>
35 #include <linux/string.h>
36 #include <linux/kallsyms.h>
136 int mempool_func(
void* args)
174 char buffer[BUF_SIZE];
178 char* mempoolFunction = (
char*)args;
179 struct virgo_mempool_args* vmargs=parse_virgomempool_command(kstrdup(mempoolFunction,GFP_KERNEL));
180 void* virgo_mempool_ret;
182 if (parameterIsExecutable==2)
184 if(use_as_kingcobra_service==1)
186 printk(
"mempool_func(): VIRGO cloudexec mempool is used as KingCobra service, invoking push_request() in kernelspace for data: %s\n",mempoolFunction);
188 vrq->data=kstrdup(mempoolFunction,GFP_ATOMIC);
198 struct task_struct *task;
200 printk(KERN_INFO
"mempool_func(): creating kernel thread and waking up, parameterIsExecutable=%d\n", parameterIsExecutable);
201 printk(KERN_INFO
"Creating Kernel Thread for %s in virgo_cloud_mempool_kernelspace mempool driver module with mempool_args[0]=%s, mempool_args[1]=%s\n",vmargs->mempool_cmd,vmargs->mempool_args[0],vmargs->mempool_args[1]);
211 virgo_mempool_ret=toFuncPtr(kstrdup(strcat(kstrdup(vmargs->mempool_cmd,GFP_KERNEL),
"_kernelspace"),GFP_KERNEL))(vmargs);
213 printk(KERN_INFO
"mempool_func(): virgo mempool kernelspace module returns value virgo_mempool_ret=%p\n", (
char*)virgo_mempool_ret);
219 else if(parameterIsExecutable==1)
221 file_stdout=filp_open(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/mempooling/virgocloudexec_mempool/virgo_cloudexec_mempool_upcall_usermode_log.txt", O_RDWR|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR);
222 fd_install(1,file_stdout);
223 fd_install(2,file_stdout);
224 argv[0]=kstrdup(mempoolFunction,GFP_KERNEL);
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/mempooling/virgocloudexec_mempool/";
230 envp[1]=
"HOME=/home/kashrinivaasan";
234 printk(
"mempool_func(): executing call_usermodehelper for data from virgo_malloc: %s - parameterIsExecutable=%d\n",mempoolFunction, parameterIsExecutable);
235 ret=call_usermodehelper(mempoolFunction, argv, envp, UMH_WAIT_EXEC);
237 printk(
"mempool_func(): call_usermodehelper() for binary %s returns ret=%d\n", mempoolFunction, ret);
238 filp_close(file_stdout,NULL);
240 else if (parameterIsExecutable==0)
242 file_stdout=filp_open(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/mempooling/virgocloudexec_mempool/virgo_cloudexec_mempool_upcall_usermode_log.txt", O_RDWR|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR);
243 fd_install(1,file_stdout);
244 fd_install(2,file_stdout);
245 argv[0]=kstrdup(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/mempooling/virgocloudexec_mempool/virgo_kernelupcall_plugin",GFP_KERNEL);
246 argv[1]=kstrdup(mempoolFunction,GFP_KERNEL);
248 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/mempooling/virgocloudexec_mempool/";
249 envp[1]=
"HOME=/home/kashrinivaasan";
251 printk(KERN_INFO
"mempool_func(): executing the virgo_malloc() syscall function parameter in cloud - parameterIsExecutable=%d, mempoolFunction=%s\n",parameterIsExecutable,mempoolFunction);
252 ret=call_usermodehelper(
"/home/kashrinivaasan/linux-3.7.8/drivers/virgo/mempooling/virgocloudexec_mempool/virgo_kernelupcall_plugin",argv,envp,UMH_WAIT_EXEC);
266 printk(
"mempool_func(): call_usermodehelper() for virgo_kernelupcall_plugin returns ret=%d\n", ret);
271 strcpy(buffer,
"mempool_func(): cloudclonethread executed for mempool_func(), sending message to virgo_malloc() remote syscall client");
272 filp_close(file_stdout,NULL);
275 return virgo_mempool_ret;
278 char* strip_control_M(
char* str)
280 printk(
"strip_control_M(): str=%s before strsep\n",str);
281 char* dupstr=kstrdup(str, GFP_KERNEL);
282 char* newstr=strsep(&dupstr,
"\r\n ");
283 printk(
"strip_control_M(): newstr=%s after carriage return newline strsep\n",newstr);
287 int kernel_space_func(
void* args)
289 printk(KERN_INFO
"kernel_space_func(): parameterIsExecutable=2; executing function in kernel address space\n");
293 void read_virgo_config()
318 f=filp_open(
"/etc/virgo_cloud.conf", O_RDONLY, 0);
327 for(k=0; k < num_cloud_nodes; k++)
328 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]);
330 printk(KERN_INFO
"read_virgo_config(): virgo_cloud config file being read \n");
336 bytesread=vfs_read(f, buf, 256, &pos);
338 printk(KERN_INFO
"do_virgo_cloud_init(): virgo_cloud config file string of comma separated IPs : %s \n",buf);
345 char* bufdup=kstrdup(buf,GFP_KERNEL);
346 printk(KERN_INFO
"tokenize_list_of_ip_addrs(): bufdup = %s\n",bufdup);
347 while(bufdup != NULL)
349 token=strsep(&bufdup, delim);
350 printk(KERN_INFO
"tokenize_list_of_ip_addrs(): %s\n",token);
351 node_ip_addrs_in_cloud[i]=kstrdup(token,GFP_KERNEL);
352 printk(KERN_INFO
"tokenize_list_of_ip_addrs(): node_ip_addrs_in_cloud[%d] = %s\n",i,node_ip_addrs_in_cloud[i]);
363 int tokenize_list_of_ip_addrs(
char* buf)
367 char* bufdup=kstrdup(buf,GFP_KERNEL);
368 printk(KERN_INFO,
"tokenize_list_of_ip_addrs(): bufdup = %s\n",bufdup);
370 while(bufdup != NULL)
372 token=strsep(&bufdup, delim);
373 printk(KERN_INFO,
"tokenize_list_of_ip_addrs(): %s\n",token);
388 virgocloudexec_mempool_init(
void)
391 static struct sockaddr_in sin;
393 printk(KERN_INFO
"virgocloudexec_mempool_init(): doing init() of virgocloudexec_mempool kernel module\n");
394 printk(KERN_INFO
"virgocloudexec_mempool_init(): starting virgo cloudexec service kernel thread\n");
396 printk(KERN_INFO
"virgocloudexec_mempool_init(): invoking read_virgo_config()\n");
399 memset(&sin, 0,
sizeof(
struct sockaddr_in));
400 sin.sin_family=AF_INET;
401 sin.sin_addr.s_addr=htonl(INADDR_ANY);
402 sin.sin_port=htons(30000);
405 error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
406 printk(KERN_INFO
"virgocloudexec_mempool_init(): sock_create() returns error code: %d\n",error);
408 error = kernel_bind(sock, (
struct sockaddr*)&sin,
sizeof(
struct sockaddr_in));
409 printk(KERN_INFO
"virgocloudexec_mempool_init(): kernel_bind() returns error code: %d\n",error);
411 error = kernel_listen(sock, 2);
412 printk(KERN_INFO
"virgocloudexec_mempool_init(): kernel_listen() returns error code: %d\n", error);
414 virgo_cloudexec_mempool_service(NULL);
423 EXPORT_SYMBOL(virgocloudexec_mempool_init);
425 int virgocloudexec_mempool_create(
void)
439 struct socket *clientsock;
442 error = kernel_accept(sock, &clientsock, 0);
467 EXPORT_SYMBOL(virgocloudexec_mempool_create);
469 void* virgocloudexec_mempool_recvfrom(
struct socket* clsock)
471 char* mempoolFunction;
472 struct sockaddr_in sin;
473 void* virgo_mempool_func_ret;
479 struct socket *clientsock=clsock;
481 struct msghdr msg = { NULL, };
486 struct task_struct *task;
488 char buffer[BUF_SIZE];
499 if(clientsock != NULL )
501 printk(KERN_INFO
"virgocloudexec_mempool_recvfrom(): before kernel_recvmsg()\n");
502 memset(buffer, 0, BUF_SIZE);
503 iov.iov_base=(
void*)buffer;
505 iov.iov_len=BUF_SIZE;
506 msg.msg_name = (
struct sockaddr *) &sin;
507 msg.msg_namelen =
sizeof(
struct sockaddr);
508 msg.msg_iov = (
struct iovec *) &iov;
510 msg.msg_control = NULL;
511 msg.msg_controllen = 0;
513 msg.msg_flags=MSG_NOSIGNAL;
518 len = kernel_recvmsg(clientsock, &msg, &iov, 1, buflen, msg.msg_flags);
519 printk(KERN_INFO
"virgocloudexec_mempool_recvfrom(): kernel_recvmsg() returns len: %d\n",len);
524 mempoolFunction = strip_control_M(kstrdup(buffer,GFP_KERNEL));
526 if(use_as_kingcobra_service==1)
528 client_ip_str=kmalloc(BUF_SIZE,GFP_ATOMIC);
529 struct sockaddr_in* ipaddr=(
struct sockaddr_in*)clientsock;
530 long ipaddr_int = ntohl(ipaddr->sin_addr.s_addr);
532 sprintf(client_ip_str,
"%x",ipaddr_int);
533 printk(KERN_INFO
"virgocloudexec_mempool_recvfrom(): client_ip_str = %s\n",client_ip_str);
534 client_ip_str=kstrdup(strcat(client_ip_str,
"#"),GFP_ATOMIC);
535 printk(KERN_INFO
"virgocloudexec_mempool_recvfrom(): client_ip_str with # appended = %s\n",client_ip_str);
536 char* request_header=kmalloc(BUF_SIZE,GFP_ATOMIC);
537 sprintf(request_header,
"REQUEST#");
538 request_header=kstrdup(strcat(request_header,client_ip_str),GFP_ATOMIC);
539 char* logicaltimestamp=generate_logical_timestamp();
540 request_header=kstrdup(strcat(request_header,logicaltimestamp),GFP_ATOMIC);
541 mempoolFunction = kstrdup(strcat(request_header,mempoolFunction),GFP_ATOMIC);
542 printk(KERN_INFO
"virgocloudexec_mempool_recvfrom(): use_as_kingcobra_service=1, mempoolFunction with prepended request header and client ip=%s\n",mempoolFunction);
546 printk(KERN_INFO
"virgocloudexec_mempool_recvfrom(): kernel_recvmsg() returns in recv: iov.iov_base=%s, buffer: %s\n", iov.iov_base, buffer);
547 print_buffer(buffer);
548 le32_to_cpus(buffer);
549 printk(KERN_INFO
"virgocloudexec_mempool_recvfrom(): kernel_recvmsg() le32 to cpu %s\n", buffer);
550 printk(KERN_INFO
"virgocloudexec_mempool_recvfrom(): mempoolFunction : %s \n", mempoolFunction);
553 args=(
void*)mempoolFunction;
561 virgo_mempool_func_ret=mempool_func((
void*)args);
573 return virgo_mempool_func_ret;
575 EXPORT_SYMBOL(virgocloudexec_mempool_recvfrom);
577 void print_buffer(
char* buffer)
579 printk(KERN_INFO
"virgo_cloudexec_mempool: print_buffer(): ");
581 for(i=0; i < BUF_SIZE; i++)
582 printk(KERN_INFO
"%c", buffer[i]);
583 printk(KERN_INFO
"\n");
586 int virgocloudexec_mempool_sendto(
struct socket* clsock,
void* virgo_mempool_ret)
594 struct sockaddr_in sin;
595 struct socket *clientsock=clsock;
597 struct msghdr msg = { NULL, };
602 struct task_struct *task;
604 char buffer[BUF_SIZE];
610 if(clientsock != NULL)
616 printk(KERN_INFO
"virgocloudexec_mempool_sendto(): virgo_mempool_ret=%s\n",virgo_mempool_ret);
617 if(strncmp(virgo_mempool_ret,
"virgodata:",10)==0)
620 printk(KERN_INFO
"virgocloudexec_mempool_sendto(): data sent=%s\n",virgo_mempool_ret+10);
621 strcpy(buffer,kstrdup(virgo_mempool_ret+10,GFP_KERNEL));
626 printk(KERN_INFO
"virgocloudexec_mempool_sendto(): address sent=%p\n",virgo_mempool_ret);
627 strcpy(buffer,toAddressString(virgo_mempool_ret));
630 iov.iov_len=BUF_SIZE;
632 msg.msg_name = (
struct sockaddr *) &sin;
633 msg.msg_namelen =
sizeof(
struct sockaddr);
634 msg.msg_iov = (
struct iovec *) &iov;
636 msg.msg_control = NULL;
637 msg.msg_controllen = 0;
641 printk(KERN_INFO
"virgocloudexec_mempool_sendto(): before kernel_sendmsg() for send buffer: %s\n", buffer);
642 ret = kernel_sendmsg(clientsock, &msg, &iov, 1, buflen);
645 printk(KERN_INFO
"virgocloudexec_mempool_sendto(): kernel_sendmsg() returns ret: %d\n",ret);
655 sock_release(clientsock);
656 printk(KERN_INFO
"virgocloudexec_mempool_sendto(): sock_release invoked on client socket \n");
720 EXPORT_SYMBOL(virgocloudexec_mempool_sendto);
724 virgocloudexec_mempool_exit(
void)
726 printk(KERN_INFO
"exiting virgocloudexec_mempool kernel module \n");
730 EXPORT_SYMBOL(virgocloudexec_mempool_exit);
740 vmargs->mempool_cmd=kstrdup(strsep(&mempoolFunction,
"("),GFP_KERNEL);
741 printk(KERN_INFO
"parse_virgomempool_command: vmargs->mempool_cmd: %s\n", vmargs->mempool_cmd);
743 if(strcmp(vmargs->mempool_cmd,
"virgo_cloud_malloc")==0 || strcmp(vmargs->mempool_cmd,
"virgo_cloud_free")==0 || strcmp(vmargs->mempool_cmd,
"virgo_cloud_get")==0)
745 vmargs->mempool_args[0]=kstrdup(strsep(&mempoolFunction,
")"),GFP_KERNEL);
746 printk(KERN_INFO
"parse_virgomempool_command: vmargs->mempool_args[0]: %s\n", vmargs->mempool_args[0]);
748 vmargs->mempool_args[1]=NULL;
753 vmargs->mempool_args[0]=kstrdup(strsep(&mempoolFunction,
","),GFP_KERNEL);
754 vmargs->mempool_args[1]=kstrdup(strsep(&mempoolFunction,
")"),GFP_KERNEL);
755 printk(KERN_INFO
"parse_virgomempool_command: vmargs->mempool_args[0]: %s\n", vmargs->mempool_args[0]);
756 printk(KERN_INFO
"parse_virgomempool_command: vmargs->mempool_args[1]: %s\n", vmargs->mempool_args[1]);
757 vmargs->mempool_args[2]=NULL;
762 FPTR toFuncPtr(
char* functionName)
764 if(strcmp(functionName,
"virgo_cloud_malloc_kernelspace")==0)
765 return virgo_cloud_malloc_kernelspace;
766 if(strcmp(functionName,
"virgo_cloud_free_kernelspace")==0)
767 return virgo_cloud_free_kernelspace;
768 if(strcmp(functionName,
"virgo_cloud_set_kernelspace")==0)
769 return virgo_cloud_set_kernelspace;
770 if(strcmp(functionName,
"virgo_cloud_get_kernelspace")==0)
771 return virgo_cloud_get_kernelspace;
774 char* toAddressString(
char* ptr)
776 char* strAddress=kmalloc(BUF_SIZE, GFP_KERNEL);
777 sprintf(strAddress,
"%p",ptr);
778 printk(KERN_INFO
"toAddressString(): address=%p, sprintf strAddress=[%s]\n", ptr, strAddress);
782 char* generate_logical_timestamp(
void)
784 char* logicaltimestamp=NULL;
785 if(EventNet_timestamp==1)
787 return "notimplemented#";
789 else if(machine_timestamp==1)
791 logicaltimestamp=kmalloc(BUF_SIZE, GFP_KERNEL);
793 sprintf(logicaltimestamp,
"%ld:%ld#",CURRENT_TIME,CURRENT_TIME_SEC);
794 printk(KERN_INFO
"generate_logical_timestamp(): machine_timestamp=1, generating timestamp for this request as %s",logicaltimestamp);
795 return logicaltimestamp;
798 else if(other_timestamp_cloudservice==1)
800 return "notimplemented#";
804 MODULE_LICENSE(
"GPL");
805 module_init(virgocloudexec_mempool_init);
806 module_exit(virgocloudexec_mempool_exit);