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_fs_syscall.h>
68 #include <linux/ctype.h>
72 #define PER_NODE_MALLOC_CHUNK_SIZE 1000
74 unsigned int virgo_parse_integer(
const char *s,
unsigned int base,
unsigned long long *p);
76 struct hostport* get_least_loaded_hostport_from_cloud_fs()
84 char *LBAlgorithm =
"PRG";
86 if(strcmp(LBAlgorithm,
"Loadtrack")==0)
88 char* cloud_host = get_host_from_cloud_Loadtrack_fs();
89 hopo->hostip=kstrdup(cloud_host, GFP_ATOMIC);
90 printk(KERN_INFO
"get_least_loaded_hostport_from_cloud(): get_host_from_cloud_Loadtrack_fs() returns host ip: %s \n",hopo->hostip);
93 else if(strcmp(LBAlgorithm,
"PRG")==0)
95 char* cloud_host = get_host_from_cloud_PRG_fs();
96 printk(KERN_INFO
"get_least_loaded_hostport_from_cloud(): get_host_from_cloud_PRG_fs() - cloud_host(before kstrdup): %s \n",cloud_host);
97 hopo->hostip=kstrdup(cloud_host, GFP_ATOMIC);
98 printk(KERN_INFO
"get_least_loaded_hostport_from_cloud(): get_host_from_cloud_PRG_fs() returns host ip: %s \n",hopo->hostip);
108 char* get_host_from_cloud_Loadtrack_fs()
117 char* get_host_from_cloud_PRG_fs()
119 unsigned int rand_int = get_random_int();
131 unsigned int rand_host_id = rand_int % num_cloud_nodes;
133 printk(KERN_INFO
"get_host_from_cloud_PRG_fs() - get_random_int() returned %u \n",rand_int);
134 printk(KERN_INFO
"get_host_from_cloud_PRG_fs() 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]);
135 return node_ip_addrs_in_cloud[rand_host_id];
141 asmlinkage
long sys_virgo_read(
long vfsdesc,
char __user *data_out,
int size,
int pos)
148 struct sockaddr_in sin;
153 char tempbuf[BUF_SIZE];
157 sin.sin_family=AF_INET;
158 struct hostport* leastloadedhostip=get_least_loaded_hostport_from_cloud_fs();
159 in4_pton(leastloadedhostip->hostip, strlen(leastloadedhostip->hostip), &sin.sin_addr.s_addr,
'\0',NULL);
160 sin.sin_port=htons(leastloadedhostip->port);
162 char* virgo_read_cmd;
163 strcpy(tempbuf,
"virgo_cloud_read(");
164 virgo_read_cmd=strcat(tempbuf,long_to_str(vfsdesc));
165 virgo_read_cmd=strcat(tempbuf,
",");
166 virgo_read_cmd=strcat(tempbuf,
"\"none\",");
167 virgo_read_cmd=strcat(tempbuf,int_to_str_vfs(size));
168 virgo_read_cmd=strcat(tempbuf,
",");
169 virgo_read_cmd=strcat(tempbuf,int_to_str_vfs(pos));
170 virgo_read_cmd=strcat(tempbuf,
")");
173 printk(KERN_INFO
"virgo_read() system call: tempbuf=%s, buf=%s, virgo_read_cmd=%s\n",tempbuf,buf,virgo_read_cmd);
180 iov.iov_len=strlen(buf);
181 msg.msg_name = (
struct sockaddr *) &sin;
182 msg.msg_namelen =
sizeof(
struct sockaddr);
183 msg.msg_iov = (
struct iovec *) &iov;
185 msg.msg_control = NULL;
186 msg.msg_controllen = 0;
190 error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
191 printk(KERN_INFO
"virgo_read() syscall: created client kernel socket\n");
192 kernel_connect(sock, (
struct sockaddr*)&sin,
sizeof(sin) , 0);
193 printk(KERN_INFO
"virgo_read() syscall: connected kernel client to virgo cloudexec kernel service\n ");
194 kernel_sendmsg(sock, &msg, &iov, nr, BUF_SIZE);
195 printk(KERN_INFO
"virgo_read() syscall: sent message: %s \n", buf);
196 len = kernel_recvmsg(sock, &msg, &iov, nr, BUF_SIZE, msg.msg_flags);
197 printk(KERN_INFO
"virgo_read() syscall: received message: %s \n", buf);
200 printk(KERN_INFO
"virgo_read() syscall: le32_to_cpus(buf): %s \n", buf);
205 long ret=copy_to_user(data_out,buf,strlen(buf));
206 printk(KERN_INFO
"virgo_read() syscall: copy_to_user() returns ret=%u, data_out=%s\n",ret,data_out);
210 asmlinkage
long sys_virgo_write(
long vfsdesc,
char __user *data_in,
int size,
int pos)
217 struct sockaddr_in sin;
222 char tempbuf[BUF_SIZE];
226 printk(KERN_INFO
"virgo_write() system_call: before memcpy()\n");
228 memcpy(data,data_in,
sizeof(data)-1);
229 printk(KERN_INFO
"virgo_write() system_call: after memcpy()\n");
230 printk(KERN_INFO
"virgo_write() system call: data to set=%s\n", data);
231 sin.sin_family=AF_INET;
232 struct hostport* leastloadedhostip=get_least_loaded_hostport_from_cloud_fs();
233 in4_pton(leastloadedhostip->hostip, strlen(leastloadedhostip->hostip), &sin.sin_addr.s_addr,
'\0',NULL);
234 sin.sin_port=htons(leastloadedhostip->port);
236 char* virgo_write_cmd;
237 strcpy(tempbuf,
"virgo_cloud_write(");
238 virgo_write_cmd=strcat(tempbuf,long_to_str(vfsdesc));
239 virgo_write_cmd=strcat(tempbuf,
",");
240 virgo_write_cmd=strcat(tempbuf,data);
241 virgo_write_cmd=strcat(tempbuf,
",");
242 virgo_write_cmd=strcat(tempbuf,int_to_str_vfs(size));
243 virgo_write_cmd=strcat(tempbuf,
",");
244 virgo_write_cmd=strcat(tempbuf,int_to_str_vfs(pos));
245 virgo_write_cmd=strcat(tempbuf,
")");
248 printk(KERN_INFO
"virgo_write() system call: tempbuf=%s, buf=%s, virgo_write_cmd = %s\n",tempbuf, buf, virgo_write_cmd);
251 iov.iov_len=strlen(buf);
252 msg.msg_name = (
struct sockaddr *) &sin;
253 msg.msg_namelen =
sizeof(
struct sockaddr);
254 msg.msg_iov = (
struct iovec *) &iov;
256 msg.msg_control = NULL;
257 msg.msg_controllen = 0;
262 error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
263 printk(KERN_INFO
"virgo_write() syscall: created client kernel socket\n");
264 kernel_connect(sock, (
struct sockaddr*)&sin,
sizeof(sin) , 0);
265 printk(KERN_INFO
"virgo_write() syscall: connected kernel client to virgo cloudexec kernel service\n ");
266 kernel_sendmsg(sock, &msg, &iov, nr, BUF_SIZE);
267 printk(KERN_INFO
"virgo_write() syscall: sent message: %s \n", buf);
268 len = kernel_recvmsg(sock, &msg, &iov, nr, BUF_SIZE, msg.msg_flags);
269 printk(KERN_INFO
"virgo_write() syscall: received message: %s \n", buf);
272 printk(KERN_INFO
"virgo_write() syscall: le32_to_cpus(buf): %s \n", buf);
283 asmlinkage
long sys_virgo_open(
char* filepath)
342 char tempbuf[BUF_SIZE];
351 struct hostport* leastloadedhostport = get_least_loaded_hostport_from_cloud_fs();
353 struct sockaddr_in sin;
354 if(leastloadedhostport->hostip==NULL)
356 printk(KERN_INFO
"virgo_open() syscall: leastloadedhostport->hostip == NULL, hardcoding it to loopback address");
357 leastloadedhostport->hostip=
"127.0.0.1";
359 if(leastloadedhostport->port != 50000)
361 printk(KERN_INFO
"virgo_open() syscall: leastloadedhostport->port != 50000, hardcoding it to 50000");
362 leastloadedhostport->port=50000;
364 printk(KERN_INFO
"virgo_open() syscall: leastloadedhostport->port=%d",leastloadedhostport->port);
365 printk(KERN_INFO
"virgo_open() syscall: leastloadedhostport->hostip=%s",leastloadedhostport->hostip);
366 in4_pton(leastloadedhostport->hostip, strlen(leastloadedhostport->hostip), &sin.sin_addr.s_addr,
'\0',NULL);
367 sin.sin_family=AF_INET;
368 sin.sin_port=htons(leastloadedhostport->port);
369 printk(KERN_INFO
"virgo_open() 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);
371 strcpy(tempbuf,
"virgo_cloud_open(");
372 open_cmd=strcat(tempbuf,filepath);
373 open_cmd=strcat(tempbuf,
")");
375 printk(KERN_INFO
"virgo_open() syscall: open_cmd=%s, buf=%s, tempbuf=%s",open_cmd,buf,tempbuf);
377 printk(KERN_INFO
"virgo_open() syscall: buf=%s, open_cmd=%s\n",buf, open_cmd);
380 iov.iov_len=strlen(buf);
381 msg.msg_name = (
struct sockaddr *) &sin;
382 msg.msg_namelen =
sizeof(
struct sockaddr);
383 msg.msg_iov = (
struct iovec *) &iov;
385 msg.msg_control = NULL;
386 msg.msg_controllen = 0;
391 error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
392 printk(KERN_INFO
"virgo_open() syscall: created client kernel socket\n");
393 kernel_connect(sock, (
struct sockaddr*)&sin,
sizeof(sin) , 0);
394 printk(KERN_INFO
"virgo_open() syscall: connected kernel client to virgo cloudexec kernel service\n ");
395 len = kernel_sendmsg(sock, &msg, &iov, nr, BUF_SIZE);
396 printk(KERN_INFO
"virgo_open() syscall: sent len=%d; iov.iov_base=%s, sent message: %s \n", len, iov.iov_base, buf);
397 len = kernel_recvmsg(sock, &msg, &iov, nr, BUF_SIZE, msg.msg_flags);
398 printk(KERN_INFO
"virgo_open() syscall: recv len=%d; received message buf: [%s] \n", len, buf);
399 printk(KERN_INFO
"virgo_open() syscall: received iov.iov_base: %s \n", iov.iov_base);
402 printk(KERN_INFO
"virgo_open() syscall: le32_to_cpus(buf): %s \n", buf);
420 unsigned long long ret;
421 virgo_parse_integer(buf,10,&ret);
426 asmlinkage
long sys_virgo_close(
long vfsdesc)
433 struct sockaddr_in sin;
438 char tempbuf[BUF_SIZE];
443 sin.sin_family=AF_INET;
444 struct hostport* leastloadedhostip=get_least_loaded_hostport_from_cloud_fs();
445 in4_pton(leastloadedhostip->hostip, strlen(leastloadedhostip->hostip), &sin.sin_addr.s_addr,
'\0',NULL);
446 sin.sin_port=htons(leastloadedhostip->port);
448 strcpy(tempbuf,
"virgo_cloud_close(");
449 close_cmd=strcat(tempbuf,long_to_str(vfsdesc));
450 close_cmd=strcat(tempbuf,
")");
453 printk(KERN_INFO
"virgo_close() system call: tempbuf=%d, buf=%s, close_cmd=%s \n",tempbuf, buf, close_cmd);
456 iov.iov_len=strlen(buf);
457 msg.msg_name = (
struct sockaddr *) &sin;
458 msg.msg_namelen =
sizeof(
struct sockaddr);
459 msg.msg_iov = (
struct iovec *) &iov;
461 msg.msg_control = NULL;
462 msg.msg_controllen = 0;
467 error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
468 printk(KERN_INFO
"virgo_close() syscall: created client kernel socket\n");
469 kernel_connect(sock, (
struct sockaddr*)&sin,
sizeof(sin) , 0);
470 printk(KERN_INFO
"virgo_close() syscall: connected kernel client to virgo cloudexec kernel service\n ");
471 kernel_sendmsg(sock, &msg, &iov, nr, BUF_SIZE);
472 printk(KERN_INFO
"virgo_close() syscall: sent message: %s \n", buf);
473 len = kernel_recvmsg(sock, &msg, &iov, nr, BUF_SIZE, msg.msg_flags);
474 printk(KERN_INFO
"virgo_close() syscall: received message: %s \n", buf);
477 printk(KERN_INFO
"virgo_close() syscall: le32_to_cpus(buf): %s \n", buf);
486 char* int_to_str_vfs(
int n)
488 char* ret=(
char*)kmalloc(50,GFP_ATOMIC);
490 printk(KERN_INFO
"int_to_str_vfs(): n=%d\n",n);
491 printk(KERN_INFO
"int_to_str_vfs(): ret=[%s]\n",ret);
495 char* long_to_str(
long n)
497 char* ret=(
char*)kmalloc(50,GFP_ATOMIC);
498 sprintf(ret,
"%ld",n);
499 printk(KERN_INFO
"long_to_str(): n=%ld\n",n);
500 printk(KERN_INFO
"long_to_str(): ret=[%s]\n",ret);
577 unsigned int virgo_parse_integer(
const char *s,
unsigned int base,
unsigned long long *p)
579 unsigned long long res;
587 printk(KERN_INFO
"virgo_parse_integer(): *s=%c, res=%ld\n",*s, res);
594 if (
'0' <= *s && *s <=
'9')
596 else if (
'a' <= tolower(*s) && tolower(*s) <=
'f')
597 val = tolower(*s) -
'a' + 10;
611 res = res * base + val;