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);