30 #include <linux/kernel.h> 
   31 #include <linux/kthread.h> 
   32 #include <linux/sched.h> 
   33 #include <linux/module.h> 
   34 #include <linux/errno.h> 
   35 #include <linux/fcntl.h> 
   36 #include <linux/net.h> 
   38 #include <linux/inet.h> 
   39 #include <linux/udp.h> 
   40 #include <linux/tcp.h> 
   41 #include <linux/string.h> 
   42 #include <linux/unistd.h> 
   43 #include <linux/slab.h> 
   44 #include <linux/netdevice.h> 
   45 #include <linux/skbuff.h> 
   46 #include <linux/file.h> 
   47 #include <linux/freezer.h> 
   49 #include <net/checksum.h> 
   53 #include <net/tcp_states.h> 
   54 #include <asm/uaccess.h> 
   55 #include <asm/ioctls.h> 
   56 #include <trace/events/skb.h> 
   58 #include <linux/module.h> 
   59 #include <linux/types.h> 
   60 #include <linux/uio.h> 
   61 #include <linux/unistd.h> 
   62 #include <linux/init.h> 
   64 #include <linux/random.h> 
   66 #include <linux/virgo_config.h> 
   67 #include <linux/virgo_mempool.h> 
   71 #define PER_NODE_MALLOC_CHUNK_SIZE 1000 
   74 struct hostport* get_least_loaded_hostport_from_cloud_mempool()
 
   82     char *LBAlgorithm = 
"PRG";
 
   84     if(strcmp(LBAlgorithm, 
"Loadtrack")==0)
 
   86         char* cloud_host = get_host_from_cloud_Loadtrack_mempool();
 
   87         hopo->hostip=kstrdup(cloud_host, GFP_KERNEL);
 
   88         printk(KERN_INFO 
"get_least_loaded_hostport_from_cloud(): get_host_from_cloud_Loadtrack_mempool() returns host ip: %s \n",hopo->hostip);
 
   91     else if(strcmp(LBAlgorithm, 
"PRG")==0)
 
   93         char* cloud_host = get_host_from_cloud_PRG_mempool();
 
   94         printk(KERN_INFO 
"get_least_loaded_hostport_from_cloud(): get_host_from_cloud_PRG_mempool() - cloud_host(before kstrdup): %s \n",cloud_host);
 
   95         hopo->hostip=kstrdup(cloud_host, GFP_KERNEL);
 
   96         printk(KERN_INFO 
"get_least_loaded_hostport_from_cloud(): get_host_from_cloud_PRG_mempool() returns host ip: %s \n",hopo->hostip);
 
  106 char* get_host_from_cloud_Loadtrack_mempool()
 
  115 char* get_host_from_cloud_PRG_mempool()
 
  117     unsigned int rand_int = get_random_int();
 
  129     unsigned int rand_host_id = rand_int % num_cloud_nodes;
 
  131     printk(KERN_INFO 
"get_host_from_cloud_PRG_mempool() - get_random_int() returned %u \n",rand_int);
 
  132     printk(KERN_INFO 
"get_host_from_cloud_PRG_mempool() range mapping for %d cloud nodes(num_cloud_nodes) returns random integer %d, host ip(nodes_ip_addrs_in_cloud): %s \n",num_cloud_nodes,rand_host_id, node_ip_addrs_in_cloud[rand_host_id]);
 
  133     return node_ip_addrs_in_cloud[rand_host_id];    
 
  139 asmlinkage 
long sys_virgo_get(
unsigned long vuid, 
char __user *data_out)
 
  146     struct sockaddr_in sin;
 
  151     char tempbuf[BUF_SIZE];
 
  155     int sum_alloc_size=0;
 
  157     printk(
"virgo_get() system call: before virgo_unique_id_to_addr()\n");
 
  159     printk(
"virgo_get() system call: vuid=%ld, virgo address to retrieve data from is vaddr=%p\n",vuid, vaddr);
 
  161     sin.sin_family=AF_INET;
 
  162     in4_pton(vaddr->hstprt->hostip, strlen(vaddr->hstprt->hostip), &sin.sin_addr.s_addr, 
'\0',NULL);
 
  163         sin.sin_port=htons(vaddr->hstprt->port);
 
  166     char* vaddr_addr_str=addr_to_str(vaddr->addr);
 
  167     strcpy(tempbuf,
"virgo_cloud_get(");
 
  168     virgo_get_cmd=strcat(tempbuf,vaddr_addr_str);
 
  169     virgo_get_cmd=strcat(tempbuf, 
")");
 
  172     printk(KERN_INFO 
"virgo_get() system call: tempbuf=%s, buf=%s, virgo_get_cmd=%s\n",tempbuf,buf,virgo_get_cmd);
 
  179     iov.iov_len=strlen(buf);
 
  180     msg.msg_name = (
struct sockaddr *) &sin;
 
  181     msg.msg_namelen = 
sizeof(
struct sockaddr);
 
  182     msg.msg_iov = (
struct iovec *) &iov;
 
  184     msg.msg_control = NULL;
 
  185     msg.msg_controllen = 0;
 
  189     error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
 
  190     printk(KERN_INFO 
"virgo_get() syscall: created client kernel socket\n");
 
  191     kernel_connect(sock, (
struct sockaddr*)&sin, 
sizeof(sin) , 0);
 
  192     printk(KERN_INFO 
"virgo_get() syscall: connected kernel client to virgo cloudexec kernel service\n ");
 
  193     kernel_sendmsg(sock, &msg, &iov, nr, BUF_SIZE);
 
  194     printk(KERN_INFO 
"virgo_get() syscall: sent message: %s \n", buf);
 
  195         len  = kernel_recvmsg(sock, &msg, &iov, nr, BUF_SIZE, msg.msg_flags);
 
  196     printk(KERN_INFO 
"virgo_get() syscall: received message: %s \n", buf);
 
  199     printk(KERN_INFO 
"virgo_get() syscall: le32_to_cpus(buf): %s \n", buf);
 
  204     long ret=copy_to_user(data_out,buf,strlen(buf));
 
  205     printk(KERN_INFO 
"virgo_get() syscall: copy_to_user() returns ret=%u, data_out=%s\n",ret,data_out);
 
  210 asmlinkage 
long sys_virgo_set(
unsigned long vuid, 
const char __user *data_in)
 
  217     struct sockaddr_in sin;
 
  222     char tempbuf[BUF_SIZE];
 
  224     printk(KERN_INFO 
"virgo_set() system call: before virgo_unique_id_to_addr()\n");    
 
  226     printk(KERN_INFO 
"virgo_set() system call: after virgo_unique_id_to_addr(), vaddr=%p\n", vaddr);
 
  233     printk(KERN_INFO 
"virgo_set() system call: vuid=%ld, virgo address to set is vaddr=%p\n",vuid, vaddr);
 
  234     printk(KERN_INFO 
"virgo_set() system_call: before memcpy()\n");
 
  235     memcpy(data,data_in,
sizeof(data)-1);
 
  236     printk(KERN_INFO 
"virgo_set() system_call: after memcpy()\n");
 
  237     printk(KERN_INFO 
"virgo_set() system call: vuid=%ld, data to set=%s\n", vuid, data);
 
  239     int sum_alloc_size=0;
 
  240     sin.sin_family=AF_INET;
 
  241     in4_pton(vaddr->hstprt->hostip, strlen(vaddr->hstprt->hostip), &sin.sin_addr.s_addr, 
'\0',NULL);
 
  242         sin.sin_port=htons(vaddr->hstprt->port);
 
  245     char* vaddr_addr_str=addr_to_str(vaddr->addr);
 
  246     printk(KERN_INFO 
"virgo_set() system call: vaddr_addr_str=[%s]",vaddr_addr_str);
 
  248     strcpy(tempbuf,
"virgo_cloud_set(");
 
  249     virgo_set_cmd=strcat(tempbuf,vaddr_addr_str);
 
  250     printk(KERN_INFO 
"virgo_set() system call: 1. virgo_set_cmd=%s",virgo_set_cmd);
 
  252     virgo_set_cmd=strcat(tempbuf,
",");
 
  253     printk(KERN_INFO 
"virgo_set() system call: 2. virgo_set_cmd=%s,data=%s",virgo_set_cmd, data);
 
  255     virgo_set_cmd=strcat(tempbuf, data);
 
  256     printk(KERN_INFO 
"virgo_set() system call: 3. virgo_set_cmd=%s",virgo_set_cmd);
 
  258     virgo_set_cmd=strcat(tempbuf, 
")");
 
  259     printk(KERN_INFO 
"virgo_set() system call: 4. virgo_set_cmd=%s",virgo_set_cmd);
 
  262     printk(KERN_INFO 
"virgo_set() system call: tempbuf=%s, buf=%s, virgo_set_cmd = %s\n",tempbuf, buf, virgo_set_cmd);
 
  265     iov.iov_len=strlen(buf);
 
  266     msg.msg_name = (
struct sockaddr *) &sin;
 
  267     msg.msg_namelen = 
sizeof(
struct sockaddr);
 
  268     msg.msg_iov = (
struct iovec *) &iov;
 
  270     msg.msg_control = NULL;
 
  271     msg.msg_controllen = 0;
 
  276     error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
 
  277     printk(KERN_INFO 
"virgo_set() syscall: created client kernel socket\n");
 
  278     kernel_connect(sock, (
struct sockaddr*)&sin, 
sizeof(sin) , 0);
 
  279     printk(KERN_INFO 
"virgo_set() syscall: connected kernel client to virgo cloudexec kernel service\n ");
 
  280     kernel_sendmsg(sock, &msg, &iov, nr, BUF_SIZE);
 
  281     printk(KERN_INFO 
"virgo_set() syscall: sent message: %s \n", buf);
 
  282         len  = kernel_recvmsg(sock, &msg, &iov, nr, BUF_SIZE, msg.msg_flags);
 
  283     printk(KERN_INFO 
"virgo_set() syscall: received message: %s \n", buf);
 
  286     printk(KERN_INFO 
"virgo_set() syscall: le32_to_cpus(buf): %s \n", buf);
 
  297 asmlinkage 
long sys_virgo_malloc(
int size, 
unsigned long __user *vuid)
 
  348     int sum_alloc_size=0;
 
  350     int this_allocation_start_entry=next_vtable_entry;
 
  362         char tempbuf[BUF_SIZE];
 
  371         struct hostport* leastloadedhostport = get_least_loaded_hostport_from_cloud_mempool();
 
  373         struct sockaddr_in sin;
 
  374         if(leastloadedhostport->hostip==NULL)
 
  376             printk(KERN_INFO 
"virgo_malloc() syscall: leastloadedhostport->hostip == NULL, hardcoding it to loopback address");
 
  377             leastloadedhostport->hostip=
"127.0.0.1";
 
  379         if(leastloadedhostport->port != 30000)
 
  381             printk(KERN_INFO 
"virgo_malloc() syscall: leastloadedhostport->port != 30000, hardcoding it to 30000");
 
  382             leastloadedhostport->port=30000;
 
  384         printk(KERN_INFO 
"virgo_malloc() syscall: leastloadedhostport->port=%d",leastloadedhostport->port);
 
  385         printk(KERN_INFO 
"virgo_malloc() syscall: leastloadedhostport->hostip=%s",leastloadedhostport->hostip);
 
  386         in4_pton(leastloadedhostport->hostip, strlen(leastloadedhostport->hostip), &sin.sin_addr.s_addr, 
'\0',NULL);
 
  387         sin.sin_family=AF_INET;
 
  388             sin.sin_port=htons(leastloadedhostport->port);
 
  389         printk(KERN_INFO 
"virgo_malloc() syscall: after in4_pton and htons, leastloadedhostport->hostip=%s, leastloadedhostport->port=%d, sin.sin_addr.s_addr=%x, sin.sin_port=%x\n",leastloadedhostport->hostip,leastloadedhostport->port, sin.sin_addr.s_addr, sin.sin_port);
 
  390         printk(KERN_INFO 
"virgo_malloc() syscall: size=%d, sum_alloc_size=%d \n", size,sum_alloc_size);
 
  392         if(sum_alloc_size + PER_NODE_MALLOC_CHUNK_SIZE <= size)
 
  394             chunk_size=PER_NODE_MALLOC_CHUNK_SIZE;  
 
  395             printk(KERN_INFO 
"virgo_malloc() syscall: size=%d, sum_alloc_size=%d, chunk_size=1000",size,sum_alloc_size);
 
  396             strcpy(buf,
"virgo_cloud_malloc(1000)");         
 
  400             chunk_size=size-sum_alloc_size;
 
  401             printk(KERN_INFO 
"virgo_malloc() syscall: size=%d, sum_alloc_size=%d, chunk_size==%d",size,sum_alloc_size,chunk_size);
 
  405                 printk(KERN_INFO 
"virgo_malloc() syscall: size=%d, sum_alloc_size=%d, chunk_size <= 0, but this should not get printed and should have exited earlier",size,sum_alloc_size);
 
  408             strcpy(tempbuf,
"virgo_cloud_malloc(");
 
  409             char* chunk_size_str=int_to_str(chunk_size);
 
  410             malloc_cmd=strcat(tempbuf,chunk_size_str);
 
  411             malloc_cmd=strcat(tempbuf, 
")");
 
  413             printk(KERN_INFO 
"virgo_malloc() syscall: malloc_cmd=%s, buf=%s, tempbuf=%s",malloc_cmd,buf,tempbuf);
 
  416         printk(KERN_INFO 
"virgo_malloc() syscall: buf=%s, malloc_cmd=%s\n",buf, malloc_cmd);
 
  419         iov.iov_len=strlen(buf);
 
  420         msg.msg_name = (
struct sockaddr *) &sin;
 
  421         msg.msg_namelen = 
sizeof(
struct sockaddr);
 
  422         msg.msg_iov = (
struct iovec *) &iov;
 
  424         msg.msg_control = NULL;
 
  425         msg.msg_controllen = 0;
 
  430         error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
 
  431         printk(KERN_INFO 
"virgo_malloc() syscall: created client kernel socket\n");
 
  432         kernel_connect(sock, (
struct sockaddr*)&sin, 
sizeof(sin) , 0);
 
  433         printk(KERN_INFO 
"virgo_malloc() syscall: connected kernel client to virgo cloudexec kernel service\n ");
 
  434         len = kernel_sendmsg(sock, &msg, &iov, nr, BUF_SIZE);
 
  435         printk(KERN_INFO 
"virgo_malloc() syscall: sent len=%d; iov.iov_base=%s, sent message: %s \n", len, iov.iov_base, buf);
 
  436             len = kernel_recvmsg(sock, &msg, &iov, nr, BUF_SIZE, msg.msg_flags);
 
  437         printk(KERN_INFO 
"virgo_malloc() syscall: recv len=%d; received message buf: [%s] \n", len, buf);
 
  438         printk(KERN_INFO 
"virgo_malloc() syscall: received iov.iov_base: %s \n", iov.iov_base);
 
  447         vtranstable.vtable[next_vtable_entry].addr=(
void*)str_to_addr2(buf);
 
  449         printk(KERN_INFO 
"virgo_malloc() syscall: vtranstable.vtable[%d].addr=%p \n", next_vtable_entry, (
char*)vtranstable.vtable[next_vtable_entry].addr);
 
  450         vtranstable.vtable[next_vtable_entry].node_id=next_vtable_entry;
 
  451         vtranstable.vtable[next_vtable_entry].hstprt=leastloadedhostport;
 
  452         vtranstable.vtable[next_vtable_entry].cloud_alloc_id=alloc_id;
 
  453         vtranstable.vtable[next_vtable_entry].refcount=1;
 
  454         vtranstable.fragment_is_disk_persisted=0;
 
  456         printk(KERN_INFO 
"virgo_malloc() syscall: next_vtable_entry=%d, vtranstable.vtable[next_vtable_entry].node_id=%d, vtranstable.vtable[next_vtable_entry].addr=%p, vtranstable.vtable[next_vtable_entry].hstprt->hostip=%s, vtranstable.vtable[next_vtable_entry].hstprt->port=%d \n",next_vtable_entry, vtranstable.vtable[next_vtable_entry].node_id, (
char*)vtranstable.vtable[next_vtable_entry].addr, vtranstable.vtable[next_vtable_entry].hstprt->hostip, vtranstable.vtable[next_vtable_entry].hstprt->port);
 
  459         printk(KERN_INFO 
"virgo_malloc() syscall: le32_to_cpus(buf): %s \n", buf);
 
  476         sum_alloc_size+=chunk_size;
 
  479         printk(KERN_INFO 
"virgo_malloc() syscall: size to be allocated = %d, sum_alloc_size = %d \n", size, sum_alloc_size);
 
  484         if(sum_alloc_size == size)
 
  486             printk(KERN_INFO 
"virgo_malloc() syscall: sum_alloc_size == size, breaking while loop\n");
 
  493     printk(KERN_INFO 
"virgo_malloc() syscall: returning &(vtranstable.vtable[this_allocation_start_entry]) == %p\n",&(vtranstable.vtable[this_allocation_start_entry]));
 
  494     unsigned long virgo_unique_id=addr_to_virgo_unique_id(&(vtranstable.vtable[this_allocation_start_entry]));
 
  495     long copy_ret=copy_to_user(vuid,&virgo_unique_id,
sizeof(
unsigned long));
 
  500 asmlinkage 
long sys_virgo_free(
unsigned long vuid)
 
  507     struct sockaddr_in sin;
 
  512     char tempbuf[BUF_SIZE];
 
  518     sin.sin_family=AF_INET;
 
  519     in4_pton(vaddr->hstprt->hostip, strlen(vaddr->hstprt->hostip), &sin.sin_addr.s_addr, 
'\0',NULL);
 
  520         sin.sin_port=htons(vaddr->hstprt->port);
 
  522     char* vaddr_addr_str=addr_to_str(vaddr->addr);
 
  523     strcpy(tempbuf,
"virgo_cloud_free(");    
 
  524     free_cmd=strcat(tempbuf,vaddr_addr_str);
 
  525     free_cmd=strcat(tempbuf, 
")");
 
  528     printk(KERN_INFO 
"virgo_free() system call: tempbuf=%d, buf=%s, free_cmd=%s \n",tempbuf, buf, free_cmd);
 
  531     iov.iov_len=strlen(buf);
 
  532     msg.msg_name = (
struct sockaddr *) &sin;
 
  533     msg.msg_namelen = 
sizeof(
struct sockaddr);
 
  534     msg.msg_iov = (
struct iovec *) &iov;
 
  536     msg.msg_control = NULL;
 
  537     msg.msg_controllen = 0;
 
  542     error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
 
  543     printk(KERN_INFO 
"virgo_free() syscall: created client kernel socket\n");
 
  544     kernel_connect(sock, (
struct sockaddr*)&sin, 
sizeof(sin) , 0);
 
  545     printk(KERN_INFO 
"virgo_free() syscall: connected kernel client to virgo cloudexec kernel service\n ");
 
  546     kernel_sendmsg(sock, &msg, &iov, nr, BUF_SIZE);
 
  547     printk(KERN_INFO 
"virgo_free() syscall: sent message: %s \n", buf);
 
  548         len  = kernel_recvmsg(sock, &msg, &iov, nr, BUF_SIZE, msg.msg_flags);
 
  549     printk(KERN_INFO 
"virgo_free() syscall: received message: %s \n", buf);
 
  552     printk(KERN_INFO 
"virgo_free() syscall: le32_to_cpus(buf): %s \n", buf);
 
  561 char* int_to_str(
int n)
 
  563     char* ret=(
char*)kmalloc(50,GFP_KERNEL);
 
  565     printk(KERN_INFO 
"int_to_str(): n=%d\n",n);
 
  566     printk(KERN_INFO 
"int_to_str(): ret=[%s]\n",ret);
 
  570 char* addr_to_str(
char* addr)
 
  572     char* ret=(
char*)kmalloc(50,GFP_KERNEL);
 
  573     sprintf(ret,
"%p",addr);
 
  574     printk(KERN_INFO 
"addr_to_str(): addr=%p\n",addr);
 
  575     printk(KERN_INFO 
"addr_to_str(): ret=[%s]\n",ret);
 
  584 char* str_to_addr(
char* straddr)
 
  588     void *voidptr_vargs=NULL;
 
  589         sscanf(straddr,
"%p",(
void**)&ptr);
 
  590         sscanf(straddr,
"%p",&voidptr);
 
  591     var_sscanf(straddr, 
"%p", (
void**)&voidptr_vargs);
 
  592         printk(KERN_INFO 
"str_to_addr(): straddr=[%s], address scanned ptr=%p, address scanned voidptr=%p \n", straddr, ptr, voidptr);
 
  593         printk(KERN_INFO 
"str_to_addr(): after var_sscanf(): straddr=[%s], voidptr_vargs by vsscanf: %p \n", straddr, voidptr_vargs);
 
  595     var_sscanf(straddr, 
"%pK", (
void**)&voidptr_vargs);
 
  596         printk(KERN_INFO 
"str_to_addr()pK: straddr=[%s], address scanned ptr=%pK, address scanned voidptr=%pK \n", straddr, ptr, voidptr);
 
  597         printk(KERN_INFO 
"str_to_addr()pK: after var_sscanf(): straddr=[%s], voidptr_vargs by vsscanf: %pK \n", straddr, voidptr_vargs);
 
  600     var_sscanf(straddr, 
"%pF", (
void**)&voidptr_vargs);
 
  601         printk(KERN_INFO 
"str_to_addr()pF: straddr=[%s], address scanned ptr=%pF, address scanned voidptr=%pF \n", straddr, ptr, voidptr);
 
  602         printk(KERN_INFO 
"str_to_addr()pF: after var_sscanf(): straddr=[%s], voidptr_vargs by vsscanf: %pF \n", straddr, voidptr_vargs);
 
  605     var_sscanf(straddr, 
"%pS", (
void**)&voidptr_vargs);
 
  606         printk(KERN_INFO 
"str_to_addr()pS: straddr=[%s], address scanned ptr=%pS, address scanned voidptr=%pS \n", straddr, ptr, voidptr);
 
  607         printk(KERN_INFO 
"str_to_addr()pS: after var_sscanf(): straddr=[%s], voidptr_vargs by vsscanf: %pS \n", straddr, voidptr_vargs);
 
  608         return (
char*)voidptr_vargs;
 
  615 void var_sscanf(
char *str, 
const char* fmt, ...)
 
  618         va_start(vargs, fmt);
 
  619         vsscanf(str, fmt, vargs);
 
  627 char* str_to_addr2(
char* straddr)
 
  635         unsigned long ll=simple_strtoll(straddr, &endptr, 16);
 
  636         void* lltovoidptr= (
void*)ll;
 
  637         printk(KERN_INFO 
"str_to_addr2(): straddr=[%s], lltovoidptr = %p\n", straddr, lltovoidptr);
 
  638     return (
char*)lltovoidptr;
 
  653 unsigned long addr_to_virgo_unique_id(
struct virgo_address* vaddr)
 
  655     unsigned long uvid=(
unsigned long)vaddr;
 
  656     printk(KERN_INFO 
"addr_to_virgo_unique_id(): vaddr=%p, uvid=%u\n",vaddr,uvid);  
 
  660 struct virgo_address* virgo_unique_id_to_addr(
unsigned long virgo_unique_id)
 
  663     printk(KERN_INFO 
"virgo_unique_id_to_addr(): vaddr=%p, virgo_unique_id=%u\n",vaddr,virgo_unique_id);