Krishna iResearch Intelligent Cloud Platform - VIRtual Generic Os - VIRGO - Linux kernel extensions for cloud
 All Classes
virgo_clone.c
1 /***************************************************************************************
2 VIRGO - a linux module extension with CPU and Memory pooling with cloud capabilities
3 
4 Copyright (C) 2009-2013 Ka.Shrinivaasan
5 
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 mail to: ka.shrinivaasan@gmail.com
20 *****************************************************************************************/
21 
22 #include <linux/kernel.h>
23 #include <linux/kthread.h>
24 #include <linux/sched.h>
25 #include <linux/module.h>
26 #include <linux/errno.h>
27 #include <linux/fcntl.h>
28 #include <linux/net.h>
29 #include <linux/in.h>
30 #include <linux/inet.h>
31 #include <linux/udp.h>
32 #include <linux/tcp.h>
33 #include <linux/string.h>
34 #include <linux/unistd.h>
35 #include <linux/slab.h>
36 #include <linux/netdevice.h>
37 #include <linux/skbuff.h>
38 #include <linux/file.h>
39 #include <linux/freezer.h>
40 #include <net/sock.h>
41 #include <net/checksum.h>
42 #include <net/ip.h>
43 #include <net/ipv6.h>
44 #include <net/tcp.h>
45 #include <net/tcp_states.h>
46 #include <asm/uaccess.h>
47 #include <asm/ioctls.h>
48 #include <trace/events/skb.h>
49 
50 #include <linux/module.h>
51 #include <linux/types.h>
52 #include <linux/uio.h>
53 #include <linux/unistd.h>
54 #include <linux/init.h>
55 
56 #include <linux/random.h>
57 
58 #include <linux/virgo_config.h>
59 /*
60 #include "netns.h"
61 */
62 
63 struct hostport
64 {
65  char* hostip;
66  int port;
67 };
68 
69 #define BUF_SIZE 3000
70 
71 /*
72 extern int num_cloud_nodes;
73 
74 extern char* node_ip_addrs_in_cloud[3000];
75 */
76 
77 
78 char* get_host_from_cloud_Loadtrack();
79 char* get_host_from_cloud_PRG();
80 
81 struct hostport* get_least_loaded_hostport_from_cloud()
82 {
83  /*
84  Either a loadtracking algorithm or a pseudorandom generator based loadbalancing algorithm is invoked to
85  get the host ip for next virgo_clone() function kernel thread execution
86  */
87 
88  /*char *LBAlgorithm = "Loadtrack";*/
89  char *LBAlgorithm = "PRG";
90  struct hostport* hopo = kmalloc(sizeof(struct hostport),GFP_KERNEL);
91  if(strcmp(LBAlgorithm, "Loadtrack")==0)
92  {
93  char* cloud_host = get_host_from_cloud_Loadtrack();
94  hopo->hostip=kstrdup(cloud_host, GFP_KERNEL);
95  printk(KERN_INFO "get_least_loaded_hostport_from_cloud(): get_host_from_cloud_Loadtrack() returns host ip: %s \n",hopo->hostip);
96  hopo->port=10000;
97  }
98  else if(strcmp(LBAlgorithm, "PRG")==0)
99  {
100  char* cloud_host = get_host_from_cloud_PRG();
101  printk(KERN_INFO "get_least_loaded_hostport_from_cloud(): get_host_from_cloud_PRG() - cloud_host(before kstrdup): %s \n",cloud_host);
102  hopo->hostip=kstrdup(cloud_host, GFP_KERNEL);
103  printk(KERN_INFO "get_least_loaded_hostport_from_cloud(): get_host_from_cloud_PRG() returns host ip: %s \n",hopo->hostip);
104  hopo->port=10000;
105  }
106  return hopo;
107 }
108 
109 /*
110  Loadtracking algorithm for nodes in the cloud
111 */
112 
113 char* get_host_from_cloud_Loadtrack()
114 {
115  return NULL;
116 }
117 
118 /*
119 Pseudorandom number generator based algorithm to distribute virgo_clone() requests amongst cloud nodes
120 */
121 
122 char* get_host_from_cloud_PRG()
123 {
124  unsigned int rand_int = get_random_int();
125  /*
126  maps a pseudo random integer in range 0 to 2^32-1 to 0 to num_of_cloud_nodes
127  - Ka.Shrinivaasan 12 July 2013
128 
129  unsigned int rand_host_id = (num_cloud_nodes) * rand_int / (65536-1);
130  */
131 
132  /*
133  Instead of range mapping, rand_int (mod) num_cloud_nodes is also sufficient
134  - Ka.Shrinivaasan 12 July 2013
135  */
136  unsigned int rand_host_id = rand_int % num_cloud_nodes;
137 
138  printk(KERN_INFO "get_host_from_cloud_PRG() - get_random_int() returned %u \n",rand_int);
139  printk(KERN_INFO "get_host_from_cloud_PRG() 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]);
140  return node_ip_addrs_in_cloud[rand_host_id];
141 
142 }
143 
144 
145 asmlinkage long sys_virgo_clone(char* func_signature, void *child_stack, int flags, void *arg)
146 {
147  /*
148  int error;
149  char buffer[3000];
150  int family=PF_INET;
151  int type=SOCK_STREAM;
152  int protocol=IPPROTO_TCP;
153  struct socket *sock;
154  struct sockaddr_in server;
155  int len;
156  struct kvec iov;
157  struct msghdr msg = {
158  .msg_flags = MSG_DONTWAIT,
159  };
160  int buflen;
161  int nr;
162 
163  char* leastloadedhost = get_least_loaded_host_from_cloud();
164  struct hostent* remotehost=gethostbyname(leastloadedhost);
165  server.sin_family=PF_INET;
166  server.sin_addr.s_addr=htonl(INADDR_ANY);
167  server.sin_port=htons(60000);
168  iov.iov_base=(void*)buffer;
169  iov.iov_len=3000;
170  strcpy(iov.iov_base, func_signature);
171  */
172 
173  int nr;
174  struct kvec iov;
175  /*
176  struct msghdr msg = {
177  .msg_flags = MSG_EOF,
178  };
179  */
180  struct msghdr msg;
181  int error;
182  struct socket *sock;
183  struct sockaddr_in sin;
184  /*
185  struct addrinfo hints;
186  struct addrinfo *result, *rp;
187  */
188  int sfd, s, j;
189  size_t len;
190  ssize_t nread;
191  char buf[BUF_SIZE];
192 
193  /*
194  memset(&hints, 0, sizeof(struct addrinfo));
195  hints.ai_family = AF_UNSPEC; / Allow IPv4 or IPv6 /
196  hints.ai_socktype = SOCK_STREAM; / Datagram socket /
197  hints.ai_flags = 0;
198  hints.ai_protocol = 0; / Any protocol /
199  */
200 
201  /*
202  struct hostport* leastloadedhostport = get_least_loaded_hostport_from_cloud();
203  s = getaddrinfo(leastloadedhostport->host, leastloadedhostport->port, &hints, &result);
204  */
205 
206  struct hostport* leastloadedhostport = get_least_loaded_hostport_from_cloud();
207  sin.sin_family=AF_INET;
208  in4_pton(leastloadedhostport->hostip, strlen(leastloadedhostport->hostip), &sin.sin_addr.s_addr, '\0',NULL);
209  sin.sin_port=htons(leastloadedhostport->port);
210 
211  iov.iov_base=buf;
212  iov.iov_len=sizeof(buf);
213  msg.msg_name = (struct sockaddr *) &sin;
214  msg.msg_namelen = sizeof(struct sockaddr);
215  msg.msg_iov = (struct iovec *) &iov;
216  msg.msg_iovlen = 1;
217  msg.msg_control = NULL;
218  msg.msg_controllen = 0;
219  msg.msg_flags = 0;
220  nr=1;
221 
222 
223  strcpy(iov.iov_base, func_signature);
224  error = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
225  printk(KERN_INFO "virgo_clone() syscall: created client kernel socket\n");
226  kernel_connect(sock, (struct sockaddr*)&sin, sizeof(sin) , 0);
227  printk(KERN_INFO "virgo_clone() syscall: connected kernel client to virgo cloudexec kernel service\n ");
228  kernel_sendmsg(sock, &msg, &iov, nr, BUF_SIZE);
229  printk(KERN_INFO "virgo_clone() syscall: sent message: %s \n", buf);
230  len = kernel_recvmsg(sock, &msg, &iov, nr, BUF_SIZE, msg.msg_flags);
231  printk(KERN_INFO "virgo_clone() syscall: received message: %s \n", buf);
232  le32_to_cpus(buf);
233  printk(KERN_INFO "virgo_clone() syscall: le32_to_cpus(buf): %s \n", buf);
234  sock_release(sock);
235  printk(KERN_INFO "virgo_clone() syscall: virgo_clone() client socket_release() invoked\n");
236 
237  return len;
238 }