Krishna iResearch Intelligent Cloud Platform - VIRtual Generic Os - VIRGO - Linux kernel extensions for cloud
 All Classes
virgo_fs.c
1 /***************************************************************************************
2 VIRGO - VIRtual Generic Os - linux kernel extensions for cloud
3 
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18 --------------------------------------------------------------------------------------------------
19 Copyright (C):
20 Srinivasan Kannan (alias) Ka.Shrinivaasan (alias) Shrinivas Kannan
21 Independent Open Source Developer, Researcher and Consultant
22 Ph: 9789346927, 9003082186, 9791165980
23 Open Source Products Profile(Krishna iResearch): http://sourceforge.net/users/ka_shrinivaasan
24 Personal website(research): https://sites.google.com/site/kuja27/
25 emails: ka.shrinivaasan@gmail.com, shrinivas.kannan@gmail.com, kashrinivaasan@live.com
26 --------------------------------------------------------------------------------------------------
27 
28 *****************************************************************************************/
29 
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>
37 #include <linux/in.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>
48 #include <net/sock.h>
49 #include <net/checksum.h>
50 #include <net/ip.h>
51 #include <net/ipv6.h>
52 #include <net/tcp.h>
53 #include <net/tcp_states.h>
54 #include <asm/uaccess.h>
55 #include <asm/ioctls.h>
56 #include <trace/events/skb.h>
57 
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>
63 
64 #include <linux/random.h>
65 
66 #include <linux/virgo_config.h>
67 #include <linux/virgo_fs_syscall.h>
68 #include <linux/ctype.h>
69 
70 #define BUF_SIZE 3000
71 
72 #define PER_NODE_MALLOC_CHUNK_SIZE 1000
73 
74 unsigned int virgo_parse_integer(const char *s, unsigned int base, unsigned long long *p);
75 
76 struct hostport* get_least_loaded_hostport_from_cloud_fs()
77 {
78  /*
79  Either a loadtracking algorithm or a pseudorandom generator based loadbalancing algorithm is invoked to
80  get the host ip for next virgo_open() function kernel thread execution
81  */
82 
83  /*char *LBAlgorithm = "Loadtrack";*/
84  char *LBAlgorithm = "PRG";
85  struct hostport* hopo = kmalloc(sizeof(struct hostport),GFP_ATOMIC);
86  if(strcmp(LBAlgorithm, "Loadtrack")==0)
87  {
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);
91  hopo->port=50000;
92  }
93  else if(strcmp(LBAlgorithm, "PRG")==0)
94  {
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);
99  hopo->port=50000;
100  }
101  return hopo;
102 }
103 
104 /*
105  Loadtracking algorithm for nodes in the cloud
106 */
107 
108 char* get_host_from_cloud_Loadtrack_fs()
109 {
110  return NULL;
111 }
112 
113 /*
114 Pseudorandom number generator based algorithm to distribute virgo_open() requests amongst cloud nodes
115 */
116 
117 char* get_host_from_cloud_PRG_fs()
118 {
119  unsigned int rand_int = get_random_int();
120  /*
121  maps a pseudo random integer in range 0 to 2^32-1 to 0 to num_of_cloud_nodes
122  - Ka.Shrinivaasan 12 July 2013
123 
124  unsigned int rand_host_id = (num_cloud_nodes) * rand_int / (65536-1);
125  */
126 
127  /*
128  Instead of range mapping, rand_int (mod) num_cloud_nodes is also sufficient
129  - Ka.Shrinivaasan 12 July 2013
130  */
131  unsigned int rand_host_id = rand_int % num_cloud_nodes;
132 
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];
136 
137 }
138 
139 
140 /*asmlinkage char* sys_virgo_get(struct virgo_address* vaddr)*/
141 asmlinkage long sys_virgo_read(long vfsdesc, char __user *data_out, int size, int pos)
142 {
143  int nr;
144  struct kvec iov;
145  struct msghdr msg;
146  int error;
147  struct socket *sock;
148  struct sockaddr_in sin;
149  int sfd, s, j;
150  size_t len;
151  ssize_t nread;
152  char buf[BUF_SIZE];
153  char tempbuf[BUF_SIZE];
154  /*char *buf;*/
155 
156 
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);
161 
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, ")");
171  strcpy(buf,tempbuf);
172 
173  printk(KERN_INFO "virgo_read() system call: tempbuf=%s, buf=%s, virgo_read_cmd=%s\n",tempbuf,buf,virgo_read_cmd);
174 
175  /*iov.iov_base=buf;*/
176  iov.iov_base=buf;
177  /*iov.iov_base=buf;*/
178  /*iov.iov_len=sizeof(buf);*/
179  /*iov.iov_len=BUF_SIZE;*/
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;
184  msg.msg_iovlen = 1;
185  msg.msg_control = NULL;
186  msg.msg_controllen = 0;
187  msg.msg_flags = 0;
188  nr=1;
189 
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);
198 
199  le32_to_cpus(buf);
200  printk(KERN_INFO "virgo_read() syscall: le32_to_cpus(buf): %s \n", buf);
201  /*
202  sock_release(sock);
203  printk(KERN_INFO "virgo_read() syscall: virgo_read() client socket_release() invoked\n");
204  */
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);
207  return ret;
208 }
209 
210 asmlinkage long sys_virgo_write(long vfsdesc, char __user *data_in, int size, int pos)
211 {
212  int nr;
213  struct kvec iov;
214  struct msghdr msg;
215  int error;
216  struct socket *sock;
217  struct sockaddr_in sin;
218  int sfd, s, j;
219  size_t len;
220  ssize_t nread;
221  char buf[BUF_SIZE];
222  char tempbuf[BUF_SIZE];
223  /*char* buf;*/
224  char data[BUF_SIZE];
225 
226  printk(KERN_INFO "virgo_write() system_call: before memcpy()\n");
227  /*long ret=copy_from_user(buf,data_in,strlen(data_in));*/
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);
235 
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, ")");
246  strcpy(buf,tempbuf);
247 
248  printk(KERN_INFO "virgo_write() system call: tempbuf=%s, buf=%s, virgo_write_cmd = %s\n",tempbuf, buf, virgo_write_cmd);
249 
250  iov.iov_base=buf;
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;
255  msg.msg_iovlen = 1;
256  msg.msg_control = NULL;
257  msg.msg_controllen = 0;
258  msg.msg_flags = 0;
259  nr=1;
260 
261  /*strcpy(iov.iov_base, buf);*/
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);
270 
271  le32_to_cpus(buf);
272  printk(KERN_INFO "virgo_write() syscall: le32_to_cpus(buf): %s \n", buf);
273  /*
274  sock_release(sock);
275  printk(KERN_INFO "virgo_write() syscall: virgo_write() client socket_release() invoked\n");
276  */
277  /*return buf;*/
278  return 0;
279 }
280 
281 
282 /*asmlinkage struct virgo_address* sys_virgo_malloc(int size)*/
283 asmlinkage long sys_virgo_open(char* filepath)
284 {
285  /*
286  int nr;
287  struct kvec iov;
288  */
289  /*
290  struct msghdr msg = {
291  .msg_flags = MSG_EOF,
292  };
293  */
294  /*
295  struct msghdr msg;
296  int error;
297  */
298 
299  /*
300  struct socket *sock;
301  struct sockaddr_in sin;
302  */
303 
304  /*
305  struct addrinfo hints;
306  struct addrinfo *result, *rp;
307  */
308  /*
309  int sfd, s, j;
310  size_t len;
311  ssize_t nread;
312  */
313  /*char buf[BUF_SIZE];*/
314  /*
315  char *buf;
316  char *open_cmd;
317  */
318 
319  /*
320  memset(&hints, 0, sizeof(struct addrinfo));
321  hints.ai_family = AF_UNSPEC; / Allow IPv4 or IPv6 /
322  hints.ai_socktype = SOCK_STREAM; / Datagram socket /
323  hints.ai_flags = 0;
324  hints.ai_protocol = 0; / Any protocol /
325  */
326 
327  /*
328  struct hostport* leastloadedhostport = get_least_loaded_hostport_from_cloud();
329  s = getaddrinfo(leastloadedhostport->host, leastloadedhostport->port, &hints, &result);
330  */
331 
332  int i=0;
333 
334  /*
335  Mutex lock and unlock also causes a kernel panic, hence commented as of now
336  - Ka.Shrinivaasan 22October2013
337  */
338 
339  /*mutex_lock(&vtranstable.vtable_fragment_mutex);*/
340  /*char *buf;*/
341  char buf[BUF_SIZE];
342  char tempbuf[BUF_SIZE];
343  char *open_cmd;
344  int sfd, s, j;
345  size_t len;
346  ssize_t nread;
347  struct msghdr msg;
348  int error;
349  int nr;
350  struct kvec iov;
351  struct hostport* leastloadedhostport = get_least_loaded_hostport_from_cloud_fs();
352  struct socket *sock;
353  struct sockaddr_in sin;
354  if(leastloadedhostport->hostip==NULL)
355  {
356  printk(KERN_INFO "virgo_open() syscall: leastloadedhostport->hostip == NULL, hardcoding it to loopback address");
357  leastloadedhostport->hostip="127.0.0.1";
358  }
359  if(leastloadedhostport->port != 50000)
360  {
361  printk(KERN_INFO "virgo_open() syscall: leastloadedhostport->port != 50000, hardcoding it to 50000");
362  leastloadedhostport->port=50000;
363  }
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);
370  /* This should not happen and should have broken earlier in the loop*/
371  strcpy(tempbuf,"virgo_cloud_open(");
372  open_cmd=strcat(tempbuf,filepath);
373  open_cmd=strcat(tempbuf, ")");
374  strcpy(buf,tempbuf);
375  printk(KERN_INFO "virgo_open() syscall: open_cmd=%s, buf=%s, tempbuf=%s",open_cmd,buf,tempbuf);
376 
377  printk(KERN_INFO "virgo_open() syscall: buf=%s, open_cmd=%s\n",buf, open_cmd);
378 
379  iov.iov_base=buf;
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;
384  msg.msg_iovlen = 1;
385  msg.msg_control = NULL;
386  msg.msg_controllen = 0;
387  msg.msg_flags = 0;
388  nr=1;
389 
390  /*strcpy(iov.iov_base, buf);*/
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);
400 
401  le32_to_cpus(buf);
402  printk(KERN_INFO "virgo_open() syscall: le32_to_cpus(buf): %s \n", buf);
403 
404  /*
405  Mysteriously sock_release() causes kernel panic repeatedly. Hence commenting this
406  temporarily.
407  - Ka.Shrinivaasan 22October2013
408  */
409  /*
410  if(sock)
411  {
412  sock_release(sock);
413  printk(KERN_INFO "virgo_open() syscall: virgo_open() client socket_release() invoked\n");
414  }
415  else
416  printk(KERN_INFO "virgo_open() syscall: sock is NULL\n");
417  */
418 
419  /*mutex_unlock(&vtranstable.vtable_fragment_mutex);*/
420  unsigned long long ret;
421  virgo_parse_integer(buf,10,&ret);
422  return (long)ret;
423 }
424 
425 /*asmlinkage char* sys_virgo_free(struct virgo_address* vaddr)*/
426 asmlinkage long sys_virgo_close(long vfsdesc)
427 {
428  int nr;
429  struct kvec iov;
430  struct msghdr msg;
431  int error;
432  struct socket *sock;
433  struct sockaddr_in sin;
434  int sfd, s, j;
435  size_t len;
436  ssize_t nread;
437  char buf[BUF_SIZE];
438  char tempbuf[BUF_SIZE];
439  /*char* buf;*/
440  char* close_cmd;
441 
442 
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);
447 
448  strcpy(tempbuf,"virgo_cloud_close(");
449  close_cmd=strcat(tempbuf,long_to_str(vfsdesc));
450  close_cmd=strcat(tempbuf, ")");
451  strcpy(buf,tempbuf);
452 
453  printk(KERN_INFO "virgo_close() system call: tempbuf=%d, buf=%s, close_cmd=%s \n",tempbuf, buf, close_cmd);
454 
455  iov.iov_base=buf;
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;
460  msg.msg_iovlen = 1;
461  msg.msg_control = NULL;
462  msg.msg_controllen = 0;
463  msg.msg_flags = 0;
464  nr=1;
465 
466  /*strcpy(iov.iov_base, buf);*/
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);
475 
476  le32_to_cpus(buf);
477  printk(KERN_INFO "virgo_close() syscall: le32_to_cpus(buf): %s \n", buf);
478  /*
479  sock_release(sock);
480  printk(KERN_INFO "virgo_close() syscall: virgo_close() client socket_release() invoked\n");
481  */
482  /*return buf;*/
483  return 0;
484 }
485 
486 char* int_to_str_vfs(int n)
487 {
488  char* ret=(char*)kmalloc(50,GFP_ATOMIC);
489  sprintf(ret,"%d",n);
490  printk(KERN_INFO "int_to_str_vfs(): n=%d\n",n);
491  printk(KERN_INFO "int_to_str_vfs(): ret=[%s]\n",ret);
492  return ret;
493 }
494 
495 char* long_to_str(long n)
496 {
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);
501  return ret;
502 }
503 
504 /*
505 char* addr_to_str(char* addr)
506 {
507  char* ret=(char*)kmalloc(50,GFP_ATOMIC);
508  sprintf(ret,"%p",addr);
509  printk(KERN_INFO "addr_to_str(): addr=%p\n",addr);
510  printk(KERN_INFO "addr_to_str(): ret=[%s]\n",ret);
511  return ret;
512 }
513 
514 
515 /
516 This function parses the address within the string straddr and returns as the pointer address
517 Example: "0x0000ffff" to 0x0000ffff
518 /
519 char* str_to_addr(char* straddr)
520 {
521  char *ptr=NULL;
522  void *voidptr=NULL;
523  void *voidptr_vargs=NULL;
524  sscanf(straddr,"%p",(void**)&ptr);
525  sscanf(straddr,"%p",&voidptr);
526  var_sscanf(straddr, "%p", (void**)&voidptr_vargs);
527  printk(KERN_INFO "str_to_addr(): straddr=[%s], address scanned ptr=%p, address scanned voidptr=%p \n", straddr, ptr, voidptr);
528  printk(KERN_INFO "str_to_addr(): after var_sscanf(): straddr=[%s], voidptr_vargs by vsscanf: %p \n", straddr, voidptr_vargs);
529 
530  var_sscanf(straddr, "%pK", (void**)&voidptr_vargs);
531  printk(KERN_INFO "str_to_addr()pK: straddr=[%s], address scanned ptr=%pK, address scanned voidptr=%pK \n", straddr, ptr, voidptr);
532  printk(KERN_INFO "str_to_addr()pK: after var_sscanf(): straddr=[%s], voidptr_vargs by vsscanf: %pK \n", straddr, voidptr_vargs);
533 
534 
535  var_sscanf(straddr, "%pF", (void**)&voidptr_vargs);
536  printk(KERN_INFO "str_to_addr()pF: straddr=[%s], address scanned ptr=%pF, address scanned voidptr=%pF \n", straddr, ptr, voidptr);
537  printk(KERN_INFO "str_to_addr()pF: after var_sscanf(): straddr=[%s], voidptr_vargs by vsscanf: %pF \n", straddr, voidptr_vargs);
538 
539 
540  var_sscanf(straddr, "%pS", (void**)&voidptr_vargs);
541  printk(KERN_INFO "str_to_addr()pS: straddr=[%s], address scanned ptr=%pS, address scanned voidptr=%pS \n", straddr, ptr, voidptr);
542  printk(KERN_INFO "str_to_addr()pS: after var_sscanf(): straddr=[%s], voidptr_vargs by vsscanf: %pS \n", straddr, voidptr_vargs);
543  return (char*)voidptr_vargs;
544 }
545 
546 /
547 carried over from test/sscanftest.c for debugging null sscanf
548 /
549 
550 void var_sscanf(char *str, const char* fmt, ...)
551 {
552  va_list vargs;
553  va_start(vargs, fmt);
554  vsscanf(str, fmt, vargs);
555  va_end(vargs);
556 }
557 
558 /
559 carried over from test/sscanftest.c for debugging null sscanf
560 /
561 
562 char* str_to_addr2(char* straddr)
563 {
564  /
565  bit of a hack but a nice one when sscanf() doesn't work the way it is expected to be.
566  scan the pointer address in string into a unsigned long and in base 16 and reinterpret cast
567  it to void*.
568  /
569  char* endptr;
570  unsigned long ll=simple_strtoll(straddr, &endptr, 16);
571  void* lltovoidptr= (void*)ll;
572  printk(KERN_INFO "str_to_addr2(): straddr=[%s], lltovoidptr = %p\n", straddr, lltovoidptr);
573  return (char*)lltovoidptr;
574 }
575 */
576 
577 unsigned int virgo_parse_integer(const char *s, unsigned int base, unsigned long long *p)
578 {
579  unsigned long long res;
580  unsigned int rv;
581  int overflow;
582 
583  res = 0;
584  rv = 0;
585  overflow = 0;
586  while (*s) {
587  printk(KERN_INFO "virgo_parse_integer(): *s=%c, res=%ld\n",*s, res);
588  unsigned int val;
589  if(*s=='\"')
590  {
591  s++;
592  continue;
593  }
594  if ('0' <= *s && *s <= '9')
595  val = *s - '0';
596  else if ('a' <= tolower(*s) && tolower(*s) <= 'f')
597  val = tolower(*s) - 'a' + 10;
598  else
599  break;
600 
601  if (val >= base)
602  break;
603  /*
604  * Check for overflow only if we are within range of
605  * it in the max base we support (16)
606  if (unlikely(res & (~0ull << 60))) {
607  if (res > div_u64(ULLONG_MAX - val, base))
608  overflow = 1;
609  }
610  */
611  res = res * base + val;
612  rv++;
613  s++;
614  }
615  *p = res;
616  return rv;
617 }
618 
619 
620 /*
621 Follwing functions map a machine address to a unique virgo id (UVID)
622 and inversely map a unique virgo id (VID) to a machine address. These have
623 been added to hide and abstract machine address to the userspace programs.
624 
625 At present only pointer to unsigned long cast is done and more sophisticated
626 Unique ID generation scheme has to be implemented if
627 needed later.
628 
629 Such a unique id is very much necessary for scalable persistent key-value store.
630 - Ka.Shrinivaasan 25October2013
631 unsigned long addr_to_virgo_unique_id(struct virgo_address* vaddr)
632 {
633  unsigned long uvid=(unsigned long)vaddr;
634  printk(KERN_INFO "addr_to_virgo_unique_id(): vaddr=%p, uvid=%u\n",vaddr,uvid);
635  return uvid;
636 }
637 
638 struct virgo_address* virgo_unique_id_to_addr(unsigned long virgo_unique_id)
639 {
640  struct virgo_address* vaddr=(struct virgo_address*)virgo_unique_id;
641  printk(KERN_INFO "virgo_unique_id_to_addr(): vaddr=%p, virgo_unique_id=%u\n",vaddr,virgo_unique_id);
642  return vaddr;
643 }
644 */
645