[Patch] Resend due to build error

Florian Delizy <florian.delizy-rqUfCgT54qdWk0Htik3J/[email protected]> Wed, 20 Sep 2006 18:32:24 +0200
Newsgroups gmane.linux.cluster.openmosix.devel
Message-ID <[email protected]>
I resend all patches (updated) because there were some build problems 
... it now build fine as a module.

I start now debugging ...

Florian

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

_______________________________________________
openMosix-devel mailing list
openMosix-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/openmosix-devel
openmosix-cleanup.patch (text/x-patch, 4.3 KB)
Index: linux/hpc/kcomd.c
===================================================================
--- linux.orig/hpc/kcomd.c	2006-09-18 11:11:58.000000000 +0200
+++ linux/hpc/kcomd.c	2006-09-18 17:59:51.000000000 +0200
@@ -34,27 +34,30 @@
 
 	ret = sock_create(saddr->sa_family, SOCK_STREAM, IPPROTO_TCP, &sock);
 	if (ret < 0)
-		return -1;
+		goto err_fd;
 
 	fd = sock_map_fd(sock);
 	if (fd < 0)
-		goto err;
+		goto err_fd;
 
 	ret = sock->ops->bind(sock, saddr, sizeof(*saddr));
 	if (ret < 0)
-		goto err_fd;
+		goto err_bind;
 
 	ret = sock->ops->listen(sock, SOMAXCONN);
 	if (ret < 0)
-		goto err_fd;
+		goto err_listen;
 	*res = sock;
 	return fd;
-err_fd:
-	sys_close(fd);
-err:
+
+err_listen:
 	sock_release(sock);
+err_bind:
+	sys_close(fd);
+err_fd:
 	*res = NULL;
 	return -1;
+
 }
 
 /**
@@ -260,33 +263,45 @@
 {
 	struct socket *sock;
 	int ret, fd;
+	int len;
+	struct sockaddr_in address;
 
 	sock = sock_alloc();
-	if (!sock)
+	if (!sock) {
+		printk(KERN_ERR "openMosix: Unable to allocate socket.\n");
 		return -1;
+	}
+
+	sock->type = lsock->type;
+	sock->ops = lsock->ops;
 
 	ret = lsock->ops->accept(lsock, sock, 0);
-	if (ret)
-		goto err;
-	/*
-	if (!sock->ops || !sock->ops->getname)
-		goto err;
+	if (ret) {
+		printk(KERN_ERR "openMosix: Error accepting connection\n");
+		goto err_accept;
+	}
 
-	ret = sock->ops->getname
-	check if it's already in node list.
-	*/
+	ret = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 1);
+	if (ret)
+		goto err_accept;
 
 	fd = sock_map_fd(sock);
-	if (fd < 0)
-		goto err;
+	if (fd < 0) {
+		printk(KERN_ERR "openMosix: Error mapping socket to file descriptor\n");
+		goto err_accept;
+	}
 
 	ret = kcom_node_add(fd, sock);
-	if (ret < 0)
+	if ( ret < 0 ) {
+		printk(KERN_ERR "openMosix: Error adding new node\n");
 		goto errfd;
+	}
+
 	return fd;
+
 errfd:
 	sys_close(fd);
-err:
+err_accept:
 	sock_release(sock);
 	return -1;
 }
Index: linux/include/hpc/hpc.h
===================================================================
--- linux.orig/include/hpc/hpc.h	2006-09-18 12:00:40.000000000 +0200
+++ linux/include/hpc/hpc.h	2006-09-18 12:08:04.000000000 +0200
@@ -71,4 +71,5 @@
 				char __user *__user *envp,
 				struct pt_regs * regs);
 
+int remote_handle_user(task_t *p, int endtype);
 #endif /* _HPC_HPC_H */
Index: linux/include/hpc/mig.h
===================================================================
--- linux.orig/include/hpc/mig.h	2006-09-18 14:33:12.000000000 +0200
+++ linux/include/hpc/mig.h	2006-09-18 14:34:27.000000000 +0200
@@ -25,6 +25,10 @@
 #include <hpc/comm.h>
 
 #define REMOTE_DAEMON_PORT  0x3412
+/* Define some linux functions (remove warnings) */
+
+
+void reparent_to_init(void);
 
 /* PROTOTYPES */
 int openmosix_mig_daemon(void *);
Index: linux/hpc/migrecv.c
===================================================================
--- linux.orig/hpc/migrecv.c	2006-09-18 16:20:13.000000000 +0200
+++ linux/hpc/migrecv.c	2006-09-18 16:44:12.000000000 +0200
@@ -408,4 +408,7 @@
 		if (error < 0)
 			comm_close(mlink);
 	}
+
+	/* Not reached, just to prevent warning on recent gcc: */
+	return 0;
 }
Index: linux/include/net/sock.h
===================================================================
--- linux.orig/include/net/sock.h	2006-09-18 16:23:07.000000000 +0200
+++ linux/include/net/sock.h	2006-09-18 16:23:51.000000000 +0200
@@ -774,6 +774,7 @@
 						     unsigned long size,
 						     int noblock,
 						     int *errcode);
+extern struct socket 		*sock_alloc(void);
 extern void *sock_kmalloc(struct sock *sk, int size,
 			  gfp_t priority);
 extern void sock_kfree_s(struct sock *sk, void *mem, int size);
Index: linux/include/linux/compiler.h
===================================================================
--- linux.orig/include/linux/compiler.h	2006-09-18 17:54:29.000000000 +0200
+++ linux/include/linux/compiler.h	2006-09-18 17:59:51.000000000 +0200
@@ -1,6 +1,8 @@
 #ifndef __LINUX_COMPILER_H
 #define __LINUX_COMPILER_H
 
+#include <linux/config.h>
+
 #ifndef __ASSEMBLY__
 
 #ifdef __CHECKER__
Index: linux/net/socket.c
===================================================================
--- linux.orig/net/socket.c	2006-09-18 18:13:09.000000000 +0200
+++ linux/net/socket.c	2006-09-18 18:13:13.000000000 +0200
@@ -511,7 +511,7 @@
  *	NULL is returned.
  */
 
-KCOMD_NSTATIC struct socket *sock_alloc(void)
+struct socket *sock_alloc(void)
 {
 	struct inode * inode;
 	struct socket * sock;
openmosix-documentation.patch (text/x-patch, 10.7 KB)
Index: linux/hpc/copyuser.c
===================================================================
--- linux.orig/hpc/copyuser.c	2006-09-18 21:24:38.000000000 +0200
+++ linux/hpc/copyuser.c	2006-09-18 23:29:14.000000000 +0200
@@ -21,7 +21,13 @@
 /********** DEPUTY PART **********/
 
 /**
- * deputy_copy_from_user - Copy from remote when running on deputy
+ * deputy_copy_from_user -
+ * @to:     kernelspace address to copy to
+ * @from:   userspace address to copy from
+ * @n:      size of data to copy
+ *
+ * Description:
+ *    Copy from remote when running on deputy
  **/
 unsigned long deputy_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
@@ -52,7 +58,13 @@
 EXPORT_SYMBOL(deputy_copy_from_user);
 
 /**
- * deputy_strncpy_from_user - strncpy on remote when running on deputy
+ * deputy_strncpy_from_user
+ * @dst:     kernelspace address to copy to
+ * @src:   userspace address to copy from
+ * @count:      size of data to copy
+ *
+ * Description:
+ *    strncpy on remote when running on deputy
  **/
 unsigned long deputy_strncpy_from_user(char *dst, const char __user *src,
 							long count)
@@ -79,7 +91,13 @@
 }
 
 /**
- * deputy_copy_to_user - copy to remote when running on deputy
+ * deputy_copy_to_user -
+ * @to:     userspace address to copy to
+ * @from:   kernelspace address to copy from
+ * @count:      size of data to copy
+ *
+ * Description:
+ *    copy to remote when running on deputy
  **/
 unsigned long deputy_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
@@ -110,7 +128,12 @@
 EXPORT_SYMBOL(deputy_copy_to_user);
 
 /**
- * deputy_strnlen_user - strnlen on remote when running on deputy
+ * deputy_strnlen_user -
+ * @s:     string address
+ * @n:     size
+ *
+ * Description:
+ *    strnlen on remote when running on deputy
  **/
 unsigned long deputy_strnlen_user(const char *s, long n)
 {
@@ -138,7 +161,13 @@
 EXPORT_SYMBOL(deputy_strnlen_user);
 
 /**
- * deputy_put_userX - put a value of 64 bit or less to remote
+ * deputy_put_userX
+ * @value:
+ * @addr:
+ * @size:
+ *
+ * Description:
+ *    put a value of 64 bit or less to remote
  **/
 static inline long deputy_put_userX(s64 value, const void *addr, size_t size)
 {
@@ -161,7 +190,13 @@
 }
 
 /**
- * deputy_put_user - put a long value to remote
+ * deputy_put_user
+ * @value:
+ * @addr:
+ * @size:
+ *
+ * Description:
+ *    put a long value to remote
  **/
 long deputy_put_user(long value, const void *addr, size_t size)
 {
@@ -172,7 +207,13 @@
 
 #if BITS_PER_LONG < 64
 /**
- * deputy_put_user - put a 64 bit value to remote
+ * deputy_put_user
+ * @value:
+ * @addr:
+ * @size:
+ *
+ * Description:
+ *    put a long value to remote
  **/
 long deputy_put_user64(s64 value, const void *addr)
 {
Index: linux/hpc/kcomd.c
===================================================================
--- linux.orig/hpc/kcomd.c	2006-09-18 21:24:38.000000000 +0200
+++ linux/hpc/kcomd.c	2006-09-18 23:28:27.000000000 +0200
@@ -21,11 +21,17 @@
 #include <net/sock.h>
 #include <net/tcp.h>
 
+/**
+ * socket_listen
+ *
+ * Description:
+ *    Creates the network socket and maps it to a file descriptor
+ **/
 static int socket_listen(struct sockaddr *saddr, struct socket **res)
 {
 	struct socket *sock;
 	int ret, fd;
-	
+
 	ret = sock_create(saddr->sa_family, SOCK_STREAM, IPPROTO_TCP, &sock);
 	if (ret < 0)
 		return -1;
@@ -51,6 +57,12 @@
 	return -1;
 }
 
+/**
+ * socket_listen_ip4
+ *
+ * Description:
+ *    IPv4
+ **/
 static int socket_listen_ip4(int port, struct socket **res)
 {
 	struct sockaddr_in saddr4 = {
@@ -62,6 +74,12 @@
 	return socket_listen((struct sockaddr *) &saddr4, res);
 }
 
+/**
+ * socket_listen_ip6
+ *
+ * Description:
+ *    IPv6
+ **/
 static int socket_listen_ip6(int port, struct socket **res)
 {
 	struct sockaddr_in6 saddr6 = {
@@ -96,7 +114,7 @@
 	pid_t pid;              /* pid of the process owning this struct */
 	struct kcom_node *node; /* node of the process to send/recv */
 	struct list_head list;  /* list of process using some node */
-	
+
 	struct list_head out_packs;
 	struct kcom_pkt in_packs;
 };
@@ -193,7 +211,7 @@
 	ret = sock->ops->getname
 	check if it's already in node list.
 	*/
-	
+
 	spin_lock(&kcom_nodes_lock);
 	list_add(&node->list, &kcom_nodes);
 	spin_unlock(&kcom_nodes_lock);
@@ -229,6 +247,15 @@
 int comm_iovec(void);
 int comm_iovec_ack(void);
 
+/**
+ * accept_connection
+ *
+ * Description:
+ *    Once kcomd's sockets receive a new connection attempt,
+ *    the connection is accepted, the remote IP address is
+ *    retrieved, the file descriptor is mapped and the
+ *    kcom node is created with this information.
+ **/
 static int accept_connection(struct socket *lsock)
 {
 	struct socket *sock;
@@ -269,6 +296,14 @@
 	return 0;
 }
 
+/**
+ * data_write
+ *
+ * Description:
+ *    Loops through all tasks that have processes on the node that
+ *    has data to send, and sends the pkts.
+ *    Once the pkt has been sent, its memory is freed.
+ **/
 int data_write(struct kcom_node *node)
 {
 	return 0;
@@ -288,7 +323,7 @@
 		kctask->pid = pid;
 		kctask->node = node;
 		INIT_LIST_HEAD(&kctask->list);
-		
+
 		list_add(&kctask->list, &node->tasks);
 	}
 	return kctask;
@@ -337,7 +372,7 @@
 	tsk = kcom_task_find(pid);
 	if (!tsk)
 		return -ENODEV;
-	
+
 	/* put pkt in kcom_task */
 	pkt = kcom_pkt_create(0, 0, NULL);
 	if (!pkt)
@@ -346,11 +381,24 @@
 
 	/* go to sleep */
 	/* wait reply */
-	
+
 	return 0;
 }
 
 
+/**
+ * kcomd_thread
+ *
+ * Description:
+ *    kcomd - kernel thread that handles the communications.
+ *    Creates the memory slabs.
+ *    Once the pkt has been sent, its memory is freed.
+ *    Maps new connections to file descriptors.
+ *    Waits for incoming data, signals from processes
+ *    or any data that is ready to be sent.
+ *    Also cleans up memory and any open sockets and
+ *    file descriptors on exit.
+ **/
 static int kcomd_thread(void *nothing)
 {
 	int ret;
@@ -381,7 +429,7 @@
 		zero_fd_set(n, sockets_fds.in);
 		zero_fd_set(n, sockets_fds.out);
 		zero_fd_set(n, sockets_fds.ex);
-	
+
 		/* add listening sockets to the set */
 		set_bit(fd4, sockets_fds.in);
 		set_bit(fd6, sockets_fds.in);
Index: linux/hpc/migctrl.c
===================================================================
--- linux.orig/hpc/migctrl.c	2006-09-18 21:24:38.000000000 +0200
+++ linux/hpc/migctrl.c	2006-09-18 23:28:25.000000000 +0200
@@ -31,8 +31,11 @@
 #include <hpc/protocol.h>
 
 /**
- * task_remote_expel - call from REMOTE to send a task to DEPUTY
+ * task_remote_expel
  * @p:		task which will come back
+ *
+ * Description:
+ *    Call from REMOTE to send a task to DEPUTY
  **/
 int task_remote_expel(task_t *p)
 {
@@ -58,8 +61,11 @@
 }
 
 /**
- * task_remote_wait_expel - call from REMOTE to send a task to DEPUTY
+ * task_remote_wait_expel
  * @p:		task which will come back
+ *
+ * Description:
+ *    Call from REMOTE to send a task to DEPUTY
  **/
 int task_remote_wait_expel(task_t *p)
 {
@@ -80,10 +86,13 @@
 }
 
 /**
- * task_local_send - Send a local task to remote
+ * task_local_send
  * @p:		task to send
  * @whereto:	destination sockaddr
  * @reason:	reason to send there (if any)
+ *
+ * Description:
+ *    Send a local task to remote
  **/
 static int task_local_send(task_t *p, struct sockaddr *whereto, int reason)
 {
@@ -127,9 +136,12 @@
 
 
 /**
- * task_local_bring - Receive task back in the deputy stub
+ * task_local_bring
  * @p:		deputy task to receive
  * @reason:	reason to send (if any)
+ *
+ * Description:
+ *    Receive task back in the deputy stub
  **/
 static int task_local_bring(task_t *p, int reason)
 {
@@ -166,10 +178,13 @@
 }
 
 /**
- * task_move_remote2remote - migrate a task from remote to remote
+ * task_move_remote2remote
  * @p:		task to send
  * @whereto:	whereto
  * @reason:	reason to send (if any)
+ *
+ * Description:
+ *    Migrate a task from remote to remote
  **/
 static int task_move_remote2remote(task_t *p, struct sockaddr * whereto,
 								int reason)
@@ -179,10 +194,13 @@
 }
 
 /**
- * task_move_to_node - send a task to a node
+ * task_move_to_node
  * @p:		task to send
  * @whereto:	destination sockaddr
  * @reason:	why
+ *
+ * Description:
+ *    Send a task to a node
  **/
 static int __task_move_to_node(struct task_struct *p,
                                struct sockaddr * whereto,
@@ -217,8 +235,14 @@
 }
 
 /**
- * task_go_home - Migrate task to home
- **/
+ * task_go_home
+ * @p:		task to send
+ * @whereto:	destination sockaddr
+ * @reason:	why
+ *
+ * Description:
+ *    Migrate task to home
+**/
 int task_go_home(task_t *p)
 {
 	if (!task_test_dflags(p, DMIGRATED)) {
@@ -235,7 +259,12 @@
 }
 
 /**
- * task_go_home_for_reason - Migrate back a task for a reason
+ * task_go_home_for_reason
+ * @p:		task to send
+ * @reason:	why
+ *
+ * Description:
+ *    Migrate back a task for a reason
  **/
 int task_go_home_for_reason(task_t *p, int reason)
 {
Index: linux/hpc/migsend.c
===================================================================
--- linux.orig/hpc/migsend.c	2006-09-18 21:24:38.000000000 +0200
+++ linux/hpc/migsend.c	2006-09-18 23:28:26.000000000 +0200
@@ -68,6 +68,12 @@
 	return 0;
 }
 
+/**
+ * mig_send_fp
+ *
+ * Description:
+ *    Sends the process floating point information(?) to the other node.
+ **/
 static int mig_send_fp(task_t *p)
 {
 	struct omp_mig_fp m;
@@ -80,6 +86,13 @@
 }
 
 
+/**
+ * mig_send_mm
+ *
+ * Description:
+ *    Sends the process memory map information to the other node.
+ *    Wait for an acknowledgement
+ **/
 static int mig_send_mm(task_t *p)
 {
 	struct omp_mig_mm s;
@@ -89,6 +102,13 @@
 	return comm_send_hd(p->om.contact, MIG_MM, &s, sizeof(s));
 }
 
+/**
+ * mig_send_vma_file
+ *
+ * Description:
+ *    Called by mig_send_vmas.
+ *    FIXME:  file vmas ??
+ **/
 static inline void mig_send_vma_file(task_t *p, struct vm_area_struct *vma,
 							struct omp_mig_vma *m)
 {
@@ -108,6 +128,14 @@
 	}
 }
 
+/**
+ * mig_send_vmas
+ *
+ * Description:
+ *    loops through and sends all process vmas to the other node.
+ *    vma's are the virtual memory structs.  They hold the lists of
+ *    mapped pages and page permissions.
+ **/
 static int mig_send_vmas(task_t *p)
 {
 	struct vm_area_struct *vma;
@@ -135,6 +163,13 @@
 }
 
 
+/**
+ * mig_send_pages
+ *
+ * Description:
+ *    loops through and sends all process pages to the other node.
+ *    All the process's memory space is sent, one page at a time.
+ **/
 static int mig_send_pages(task_t *p)
 {
 	struct vm_area_struct * vma;
@@ -165,6 +200,13 @@
 }
 
 
+/**
+ * mig_send_proc_context
+ *
+ * Description:
+ *    Sends the 'important' part of the process context.
+ *
+ **/
 static int mig_send_proc_context(task_t *p)
 {
 	struct omp_mig_task m;
@@ -220,6 +262,13 @@
 	return -1;
 }
 
+/**
+ * mig_do_send
+ *
+ * Description:
+ *    Main loop for sending the process to the other node.
+ *
+ **/
 int mig_do_send(task_t *p)
 {
 	arch_mig_send_pre(p);
openmosix-git.patch (text/x-patch, 270.7 KB) - not displayed
openmosix-kcomd-base-functions.patch (text/x-patch, 27.7 KB)
Index: linux/hpc/kcomd.c
===================================================================
--- linux.orig/hpc/kcomd.c	2006-09-18 23:29:28.000000000 +0200
+++ linux/hpc/kcomd.c	2006-09-20 17:06:58.000000000 +0200
@@ -21,6 +21,12 @@
 #include <net/sock.h>
 #include <net/tcp.h>
 
+#include <linux/inet.h>
+#include <hpc/kcom.h>
+#include <hpc/prototype.h>
+
+static int kcomd_done=0;
+
 /**
  * socket_listen
  *
@@ -93,162 +99,6 @@
 	return socket_listen((struct sockaddr *) &saddr6, res);
 }
 
-struct kcom_pkt
-{
-	pid_t pid;    /* pid of the process */
-	int len;      /* len of data */
-	int type;     /* type of data */
-	char *data;   /* ptr of data */
-	struct list_head list;
-};
-
-struct kcom_node
-{
-	int fd;                 /* fd to send packet */
-	struct socket *sock;    /* socket */
-	struct sockaddr addr;   /* addr of this node */
-	spinlock_t tasks_lock;  /* lock for the list */
-	struct list_head tasks; /* list of task */
-	struct list_head list; /* list of nodes */
-};
-
-struct kcom_task
-{
-	pid_t pid;              /* pid of the process owning this struct */
-	struct kcom_node *node; /* node of the process to send/recv */
-	struct list_head list;  /* list of process using some node */
-
-	struct list_head out_packs;
-	struct kcom_pkt in_packs;
-};
-
-static DEFINE_SPINLOCK(kcom_nodes_lock);
-struct list_head kcom_nodes = LIST_HEAD_INIT(kcom_nodes);
-
-fd_set_bits sockets_fds;
-char *sockets_fds_bitmap = NULL;
-int maxfds = -1;
-
-static int alloc_fd_bitmap(int fd4, int fd6)
-{
-	struct kcom_node *node;
-	int n, size;
-
-	n = max(fd4, fd6);
-
-	spin_lock(&kcom_nodes_lock);
-	list_for_each_entry(node, &kcom_nodes, list)
-		n = max(node->fd, n);
-	spin_unlock(&kcom_nodes_lock);
-
-	/* we don't need to reallocate the bitmap */
-	if (n <= maxfds)
-		return 0;
-	maxfds = n;
-
-	kfree(sockets_fds_bitmap);
-
-	size = FDS_BYTES(n);
-	sockets_fds_bitmap = kmalloc(6 * size, GFP_KERNEL);
-	if (!sockets_fds_bitmap)
-		return ENOMEM;
-
-	sockets_fds.in      = (unsigned long *)  sockets_fds_bitmap;
-	sockets_fds.out     = (unsigned long *) (sockets_fds_bitmap +   size);
-	sockets_fds.ex      = (unsigned long *) (sockets_fds_bitmap + 2*size);
-	sockets_fds.res_in  = (unsigned long *) (sockets_fds_bitmap + 3*size);
-	sockets_fds.res_out = (unsigned long *) (sockets_fds_bitmap + 4*size);
-	sockets_fds.res_ex  = (unsigned long *) (sockets_fds_bitmap + 5*size);
-
-	return 0;
-}
-
-struct kcom_pkt *kcom_pkt_create(int len, int type, char *data)
-{
-	struct kcom_pkt *pkt;
-	pkt = kzalloc(sizeof(struct kcom_pkt), GFP_KERNEL);
-	if (pkt) {
-		pkt->len = len;
-		pkt->type = type;
-		pkt->data = data;
-	}
-	return pkt;
-}
-
-struct kcom_node *__kcom_node_find(struct sockaddr *saddr)
-{
-	struct kcom_node *tmp;
-
-	list_for_each_entry(tmp, &kcom_nodes, list) {
-		/* FIXME compare fields, no memcmp */
-		if (memcmp(saddr, tmp, sizeof(struct sockaddr)) == 0)
-			return tmp;
-	}
-	return NULL;
-}
-
-struct kcom_node *kcom_node_find(struct sockaddr *saddr)
-{
-	struct kcom_node *node;
-
-	spin_lock(&kcom_nodes_lock);
-	node = __kcom_node_find(saddr);
-	spin_unlock(&kcom_nodes_lock);
-	return node;
-}
-
-int kcom_node_add(int fd, struct socket *sock)
-{
-	struct kcom_node *node;
-
-	node = kzalloc(sizeof(struct kcom_node), GFP_KERNEL);
-	if (!node)
-		return -ENOMEM;
-	INIT_LIST_HEAD(&node->list);
-	node->sock = sock;
-	node->fd = fd;
-	/*
-	if (!sock->ops || !sock->ops->getname)
-		goto err;
-
-	ret = sock->ops->getname
-	check if it's already in node list.
-	*/
-
-	spin_lock(&kcom_nodes_lock);
-	list_add(&node->list, &kcom_nodes);
-	spin_unlock(&kcom_nodes_lock);
-	return 0;
-}
-
-int kcom_node_del(struct sockaddr *addr)
-{
-	struct kcom_node *node;
-
-	/* remove the node from the list */
-	spin_lock(&kcom_nodes_lock);
-	node = __kcom_node_find(addr);
-	if (!node) {
-		spin_unlock(&kcom_nodes_lock);
-		return -ENOENT;
-	}
-	list_del(&node->list);
-	spin_unlock(&kcom_nodes_lock);
-
-	/* release and free structure */
-	sys_close(node->fd);
-	sock_release(node->sock);
-	kfree(node);
-	return 0;
-}
-
-int comm_simple(int type, char * data)
-{
-	return 0;
-}
-int comm_ack(void);
-int comm_iovec(void);
-int comm_iovec_ack(void);
 
 /**
  * accept_connection
@@ -262,6 +112,7 @@
 static int accept_connection(struct socket *lsock)
 {
 	struct socket *sock;
+	struct kcom_node *node;
 	int ret, fd;
 	int len;
 	struct sockaddr_in address;
@@ -291,11 +142,16 @@
 		goto err_accept;
 	}
 
-	ret = kcom_node_add(fd, sock);
-	if ( ret < 0 ) {
+	node = kcom_node_add(sock);
+	if (node==NULL) {
 		printk(KERN_ERR "openMosix: Error adding new node\n");
 		goto errfd;
 	}
+	// Store the IP addr.
+	memcpy(&node->addr, &address, sizeof(address));
+	node->fd=fd;
+	// Allocated file descriptor bitmap for do_select
+	alloc_fd_bitmap(fd);
 
 	return fd;
 
@@ -306,12 +162,262 @@
 	return -1;
 }
 
-int data_read(struct kcom_node *node)
+/**
+ * data_send
+ *
+ * Description:
+ *    Sends the kcom pkt header and the data, if any.
+ **/
+int data_send(struct socket *sock, void *data, int len)
+{
+	struct iovec iov;
+	int i=-1;
+	struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, MSG_WAITALL | MSG_NOSIGNAL };
+	mm_segment_t oldfs;
+	struct kcom_pkt *send_pkt;
+	char buf[32];
+	struct timeval start,stop;
+
+	do_gettimeofday(&start);
+	send_pkt=data;
+
+
+   	/* Send kcom_pkt header */
+	iov.iov_base = send_pkt;
+	iov.iov_len = sizeof(*send_pkt);
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	while (iov.iov_len > 0) {
+		printk("sock_sendmsg hdr\n");
+		i = sock_sendmsg(sock, &msg, iov.iov_len);
+		if ((i == -ENOSPC) || (i == -EAGAIN)) {
+			printk("Retrying hdr...error %d\n", i);
+			schedule_timeout(HZ/1000);
+			continue;
+		}
+		if (i == -EFAULT) {
+			printk("Error %d sending data. Unable to access data.\n", i);
+			printk("Data may need to be copied into a temporary buffer to be sent.\n");
+		}
+
+		if (i < 0) {
+			set_fs(oldfs);
+			return -1;
+		}
+		iov.iov_base += i;
+		iov.iov_len -= i;
+ 	}
+	set_fs(oldfs);
+
+	/* Sending too small a data packet, delays.  */
+	if ((send_pkt->len > 0) && (send_pkt->len < 32)) {
+		memset(&buf, 0, 32);
+		memcpy(&buf, send_pkt->data, send_pkt->len);
+		iov.iov_base = &buf;
+		iov.iov_len = 32;
+	} else {
+		iov.iov_base = send_pkt->data;
+		iov.iov_len = send_pkt->len;
+	}
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	while (iov.iov_len > 0) {
+		printk("sock_sendmsg data\n");
+		i = sock_sendmsg(sock, &msg, iov.iov_len);
+
+		if ((i == -ENOSPC) || (i == -EAGAIN)) {
+
+			printk(KERN_DEBUG "Retrying data...error %d\n", i);
+			schedule_timeout(HZ/1000);
+			continue;
+		}
+		if (i < 0) {
+			printk(KERN_ERR"openMosix: ERROR %d sending data\n", i);
+			set_fs(oldfs);
+			return -1;
+		}
+		iov.iov_base += i;
+		iov.iov_len -= i;
+ 	}
+	set_fs(oldfs);
+	do_gettimeofday(&stop);
+	return i;
+
+}
+
+/**
+ * data_exception
+ *
+ * Description:
+ *    Dropped connections need to be cleaned up.  Memory freed,
+ *    file descriptors unmapped, etc.  This function does that.
+ *    FIXME:  Supposed to, but doesn't work yet.  Dropped connections
+ *    are seen as data, of length 0, is available for read.
+ **/
+int data_exception(struct kcom_node *node)
 {
+
+	sock_release(node->sock);
+	sys_close(node->fd);
+	/* kfree(node->sock);*/
+	list_del(&node->list);
+	kmem_cache_free(kcom_node_cachep, node);
+	/* kfree(node);*/
 	return 0;
 }
 
 /**
+ * append_in_packs
+ *
+ * Description:
+ *    Packets are either new pkts, or responses or (n)acks to new pkts.
+ *    If a pkt isn't new, a function is waiting on it (wait_for_ack/response),
+ *    so we can just add this pkt to the task in_packs list.
+ **/
+int append_in_packs(struct kcom_pkt *recv_kcom_pkt)
+{
+	struct kcom_task *tsk;
+	task_t *sltsk;
+
+	/* FIXME : should spinlock/unlock */
+
+	if ((recv_kcom_pkt->type & NODE_MASK) == DEP_FLG) {
+		/* command from dep to remote? */
+
+		tsk=kcom_remote_task_find(recv_kcom_pkt->rpid);
+		if (tsk) {
+			/* spin_lock(&tsk->spinlock); */
+			list_add_tail(&recv_kcom_pkt->list, &tsk->in_packs);
+			/* spin_unlock(&tsk->spinlock); */
+		} else {
+			printk(KERN_ERR "unable to find remote pid %u\n", recv_kcom_pkt->rpid);
+			return -1;
+
+		}
+		/* read_lock(&tasklist_lock); */
+		sltsk=find_task_by_pid(recv_kcom_pkt->rpid);
+		/* read_unlock(&tasklist_lock); */
+		if (sltsk) {
+			wake_up_process(sltsk);
+		} else {
+			printk(KERN_ERR "Unable to find remote pid %u to wake up\n", recv_kcom_pkt->rpid);
+			return -1;
+		}
+
+	} else {
+		tsk=kcom_home_task_find(recv_kcom_pkt->hpid);
+		if (tsk) {
+			/* spin_lock(&tsk->spinlock); */
+			list_add_tail(&recv_kcom_pkt->list, &tsk->in_packs);
+			/* spin_unlock(&tsk->spinlock); */
+		} else {
+			printk(KERN_ERR "unable to find home pid %u\n", recv_kcom_pkt->hpid);
+			return -1;
+		}
+		/* read_lock(&tasklist_lock); */
+		sltsk=find_task_by_pid(recv_kcom_pkt->hpid);
+		/* read_unlock(&tasklist_lock); */
+		if (sltsk) {
+			wake_up_process(sltsk);
+		} else {
+			printk(KERN_ERR "Unable to find home pid %u to wake up\n", recv_kcom_pkt->hpid);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/**
+ * pkt_read
+ *
+ * Description:
+ *    Reads the packet header and, if exists, data,  and put in appropriate task's
+ *    in_pack list.
+ *    All but 3 pkts an be handled by the task itself.
+ *    MIG_INIT creates a new process and task
+ *    MIG_GO/COME_HOME - migration command.
+ **/
+int pkt_read(struct kcom_node *node)
+{
+	struct kcom_pkt *recv_kcom_pkt;
+	int i=0;
+	task_t *sltsk;
+
+	// read in hdr
+	recv_kcom_pkt=pkt_hdr_read(node);
+	if (recv_kcom_pkt==NULL) {
+		printk("ERROR: incomplete header pkt\n");
+		goto error_recv;
+	}
+
+	// read in any data
+	if (recv_kcom_pkt->len > 0) {
+		if ((recv_kcom_pkt->type & MSG_MASK) == PKT_NEW_MSG) {
+			recv_kcom_pkt->data=kzalloc(recv_kcom_pkt->len, GFP_KERNEL);
+			i=pkt_data_read(node, recv_kcom_pkt, recv_kcom_pkt->len, recv_kcom_pkt->data);
+		} else {
+			i=pkt_data_read(node, recv_kcom_pkt, recv_kcom_pkt->len, recv_kcom_pkt->resp);
+		}
+		if (i<recv_kcom_pkt->len) {
+			printk("ERROR: incomplete data pkt\n");
+			goto error_recv;
+		}
+	}
+
+
+	if ((recv_kcom_pkt->type & MSG_MASK) == PKT_NEW_MSG) {
+		switch (recv_kcom_pkt->type & MIG_MASK) {
+			case MIG_INIT:
+				mig_do_receive_init(node, recv_kcom_pkt);
+				break;
+			case MIG_GO_HOME:
+				mig_do_receive_home(node, recv_kcom_pkt);
+				break;
+			case MIG_COME_HOME:
+				sltsk=find_task_by_pid(recv_kcom_pkt->rpid);
+				task_register_migration(sltsk);
+				break;
+			default:
+				append_in_packs(recv_kcom_pkt);
+
+				break;
+		}
+	} else { // PKT_ACK and PKT_RESP go straight to in_packs
+		append_in_packs(recv_kcom_pkt);
+	}
+
+	return 0;
+
+error_recv:
+	printk("sock_close\n");
+	sys_close(node->fd);
+	printk("sock_release\n");
+	sock_release(node->sock);
+
+	#if 0
+	node->fd=-1;
+	printk("kfree(data)\n");
+	kfree(pkt);
+	printk("kfree(node->sock)\n");
+	kfree(node->sock);
+	printk("list_del\n");
+	#endif
+
+	list_del(&node->list);
+	kmem_cache_free(kcom_node_cachep, node);
+
+	#if 0
+	kfree(node);
+	#endif
+	return -1;
+
+}
+
+
+
+/**
  * data_write
  *
  * Description:
@@ -321,6 +427,19 @@
  **/
 int data_write(struct kcom_node *node)
 {
+	struct kcom_task *task, *task_next;
+	struct kcom_pkt *pkt, *pkt_next;
+
+	list_for_each_entry_safe(task, task_next, &node->tasks, list)
+		list_for_each_entry_safe(pkt, pkt_next, &task->out_packs, list) {
+			data_send(node->sock, (void *)pkt, pkt->len);
+
+			list_del(&pkt->list);
+			if (((pkt->type|PKT_ACK)==PKT_ACK) && (pkt->len > 0))
+				kmem_cache_free(kcom_data_cachep, pkt->data);
+			kmem_cache_free(kcom_pkt_cachep, pkt);
+		}
+
 	return 0;
 }
 
@@ -417,28 +536,53 @@
 static int kcomd_thread(void *nothing)
 {
 	int ret;
-	struct socket *lsock4, *lsock6;
-	int fd4, fd6;
-
+	struct kcom_node *node, *node_next;
+	struct kcom_task *task, *task_next;
+	struct kcom_pkt *pkt, *pkt_next;
+	s64 timeout = -1;
+	int n = -1;
+	siginfo_t info; /* matt*/
+	int sig;
+	int outpkt_cnt, inpkt_cnt, tsk_cnt;
+	int err;
+	struct timeval start,stop;
+
+	fd4=-1;
+	fd6=-1;
+	kcomd_done=0;
 	printk(KERN_INFO "kcomd: init\n");
+
+	kcom_data_cachep=kmem_cache_create("kcom_data_cache", 1024, 0, 0, NULL, NULL); /* for now help chase down memory leaks*/
+	kcom_pkt_cachep=kmem_cache_create("kcom_pkt_cache", sizeof(struct kcom_pkt), 0, 0, NULL, NULL);
+	kcom_task_cachep=kmem_cache_create("kcom_task_cache", sizeof(struct kcom_task), 0, 0, NULL, NULL);
+	kcom_node_cachep=kmem_cache_create("kcom_node_cache", sizeof(struct kcom_node), 0, 0, NULL, NULL);
+	/* kcom_saddr_cachep=kmem_cache_create("kcom_saddr_cache", sizeof(struct sockaddr), 0, 0, NULL, NULL);*/
+
 	daemonize("kcomd", 0);
+	sigfillset(&current->blocked);
+
+	/* kcom_pid=current->pid;*/
+	/* read_lock(&tasklist_lock);*/
+	/* kcomd_task = find_task_by_pid(current->pid);*/
+	/* read_unlock(&tasklist_lock);*/
+	kcomd_task=current;
 
 retry_listen:
-	fd4 = socket_listen_ip4(0xb55, &lsock4);
-	fd6 = socket_listen_ip6(0xb56, &lsock6);
+	fd4 = socket_listen_ip4(DAEMON_IP4_PORT, &lsock4);
+	fd6 = socket_listen_ip6(DAEMON_IP6_PORT, &lsock6);
 
 	if (fd4 == -1 && fd6 == -1) {
 		schedule_timeout_interruptible(HZ);
 		goto retry_listen;
 	}
 
-	while (1)
+
+	n=alloc_fd_bitmap(max(fd4, fd6));
+
+	while (kcomd_done==0)
 	{
-		s64 timeout = -1;
-		int n = -1;
-		struct kcom_node *node;
 
-		alloc_fd_bitmap(fd4, fd6);
+
 		n = maxfds;
 
 		zero_fd_set(n, sockets_fds.in);
@@ -446,61 +590,221 @@
 		zero_fd_set(n, sockets_fds.ex);
 
 		/* add listening sockets to the set */
-		set_bit(fd4, sockets_fds.in);
-		set_bit(fd6, sockets_fds.in);
+		if (fd4!=-1)
+			set_bit(fd4, sockets_fds.in);
+		if (fd6!=-1)
+			set_bit(fd6, sockets_fds.in);
 
 		/* for each nodes (set fds.in && fds.out) */
-		spin_lock(&kcom_nodes_lock);
+		/* printk("spin_lock\n");*/
+		/* spin_lock(&kcom_nodes_lock);*/
+		/* printk("Setting bits for select (n=%d, maxfds=%d).\n", n, maxfds);*/
+	do_gettimeofday(&start);
 		list_for_each_entry(node, &kcom_nodes, list) {
-			struct kcom_task *task;
+			/* printk("node->fd=%d\n", node->fd);*/
 
-			if (node->fd == -1 || node->fd > maxfds)
+			if (node->fd == -1 || node->fd > maxfds) {
+				/* spin_unlock(&kcom_nodes_lock);*/
 				continue;
+			}
+
+			/* if a file descriptor is open, we want select to pay attention.*/
+			/* printk("Setting in bit for fd%d\n", node->fd);*/
 			set_bit(node->fd, sockets_fds.in);
+			set_bit(node->fd, sockets_fds.ex);
+
+			/* if there are packets to be sent, select should pay attention.*/
 			list_for_each_entry(task, &node->tasks, list)
-				if (!list_empty(&task->out_packs))
+				if (!list_empty(&task->out_packs)) {
+					/* printk("Setting out bit for fd%d\n", node->fd);*/
 					set_bit(node->fd, sockets_fds.out);
+				}
 		}
-		spin_unlock(&kcom_nodes_lock);
+	do_gettimeofday(&stop);
+	if (stop.tv_sec==start.tv_sec)
+		printk("node_loopB: time %lu usecs\n", stop.tv_usec-start.tv_usec);
+	else
+		printk("node_loopB: time %lu usecs\n", ((stop.tv_sec*USEC_PER_SEC)+stop.tv_usec)-((start.tv_sec*USEC_PER_SEC)+start.tv_usec));
+		/* spin_unlock(&kcom_nodes_lock);*/
+		/* printk("Done setting bits for select.\n");*/
+
+
 
 		zero_fd_set(n, sockets_fds.res_in);
 		zero_fd_set(n, sockets_fds.res_out);
 		zero_fd_set(n, sockets_fds.res_ex);
 
+	do_gettimeofday(&start);
+		allow_signal (SIGHUP);
+		timeout=-1;
+		printk("............DO_SELECT...........");
 		ret = do_select(n + 1, &sockets_fds, &timeout);
-		if (ret < 0)
+		printk(" returned %d.\n", ret);
+		/* SIGHUP is sent by kcom_send to wake up kcomd so it can send the packet*/
+		while (signal_pending (current)) {
+			printk("[kcomd] dequeueing signal\n");
+			sig = dequeue_signal (current, &current->blocked, &info);
+		}
+		disallow_signal (SIGHUP);
+		if (ret == 0) { /* -1=error; 0=signal*/
+			/* New kernel security, prohibits sharing file descriptors between kernel threads.*/
+			/* We have to allocate them here.*/
+			/* We'll do that for the signal so we don't have to do it every iteration.*/
+
+			list_for_each_entry(node, &kcom_nodes, list)
+				if (node->fd==0) { /* unmapped*/
+					/* printk("Found unmapped socket\n");*/
+					node->fd = sock_map_fd(node->sock);
+					alloc_fd_bitmap(node->fd);
+				}
 			continue;
+		} else if (ret < 0) {/* -1=error; 0=signal*/
+			printk("do_select returned an error. \n");
+			schedule_timeout_interruptible(HZ);
+		}
+	do_gettimeofday(&stop);
+	if (stop.tv_sec==start.tv_sec)
+		printk("do_select: time %lu usecs\n", stop.tv_usec-start.tv_usec);
+	else
+		printk("do_select: time %lu usecs\n", ((stop.tv_sec*USEC_PER_SEC)+stop.tv_usec)-((start.tv_sec*USEC_PER_SEC)+start.tv_usec));
 
 		/* test listening sockets */
-		if (fd4 != -1 && test_bit(fd4, sockets_fds.res_in))
+		if (fd4 != -1 && test_bit(fd4, sockets_fds.res_in)) {
 			accept_connection(lsock4);
-		if (fd6 != -1 && test_bit(fd6, sockets_fds.res_in))
+			continue;
+		}
+
+		if (fd6 != -1 && test_bit(fd6, sockets_fds.res_in)) {
 			accept_connection(lsock6);
+			continue;
+		}
 
 		/* for each nodes { test bit, in, out and do stuff } */
-		spin_lock(&kcom_nodes_lock);
-		list_for_each_entry(node, &kcom_nodes, list) {
-			if (test_bit(node->fd, sockets_fds.res_in))
-				data_read(node);
-			if (test_bit(node->fd, sockets_fds.res_out))
+		/* spin_lock(&kcom_nodes_lock);*/
+restart:
+		list_for_each_entry_safe(node, node_next, &kcom_nodes, list) {
+			/*
+			if (test_bit(node->fd, sockets_fds.res_ex)) {
+				data_exception(node);
+				goto restart;
+			}
+			*/
+			if (test_bit(node->fd, sockets_fds.res_in)) {
+				do_gettimeofday(&start);
+				err=pkt_read(node);
+				do_gettimeofday(&stop);
+				if (stop.tv_sec==start.tv_sec)
+					printk("pkt_read: time %lu usecs\n", stop.tv_usec-start.tv_usec);
+				else
+					printk("pkt_read: time %lu usecs\n", ((stop.tv_sec*USEC_PER_SEC)+stop.tv_usec)-((start.tv_sec*USEC_PER_SEC)+start.tv_usec));
+				if (err!=0) {
+					kcomd_done=1;
+					printk("ERROR receiving data.\nQuitting.\n");
+					continue;
+				}
+			}
+			if (node->fd!=-1 && test_bit(node->fd, sockets_fds.res_out)) {
+				do_gettimeofday(&start);
 				data_write(node);
+				do_gettimeofday(&stop);
+				if (stop.tv_sec==start.tv_sec)
+					printk("data_write: time %lu usecs\n", stop.tv_usec-start.tv_usec);
+				else
+					printk("data_write: time %lu usecs\n", ((stop.tv_sec*USEC_PER_SEC)+stop.tv_usec)-((start.tv_sec*USEC_PER_SEC)+start.tv_usec));
+			}
 		}
-		spin_unlock(&kcom_nodes_lock);
+		/* spin_unlock(&kcom_nodes_lock);*/
 	}
 
-	return -1;
+/* DONE*/
+	printk(KERN_INFO "kcomd: cleaning up.\n");
+	/* spin_lock(&kcom_nodes_lock);*/
+	if (fd4!=-1) {
+		printk("fd4=%d\n", fd4);
+		printk("sys_close(fd4)\n");
+		sys_close(fd4);
+		if (lsock4) {  /* doesn't like this.  Help????????*/
+			printk("sock_release(lsock4)\n");
+			sock_release(lsock4);
+		}
+	}
+
+	if (fd6!=-1) {
+		printk("fd6=%d\n", fd6);
+		if (lsock6) { /* doesn't like this.  Help????????*/
+			printk("sock_release(lsock6)\n");
+			sock_release(lsock6);
+		}
+		printk("sys_close(fd6)\n");
+		sys_close(fd6);
+	}
+	printk("Stopped accepting new connections.\n");
+
+	list_for_each_entry_safe(node, node_next, &kcom_nodes, list) {
+		list_for_each_entry_safe(task, task_next, &node->tasks, list) {
+			list_for_each_entry_safe(pkt, pkt_next, &task->in_packs, list) {
+				if ((pkt->len) > 0)
+					kfree(pkt->data);
+				kmem_cache_free(kcom_pkt_cachep, pkt);
+				list_del(&pkt->list);
+			}
+			list_for_each_entry_safe(pkt, pkt_next, &task->out_packs, list) {
+				if ((pkt->len) > 0)
+					kfree(pkt->data);
+				kmem_cache_free(kcom_pkt_cachep, pkt);
+				list_del(&pkt->list);
+			}
+			list_del(&task->list);
+			kmem_cache_free(kcom_task_cachep, task);
+		}
+
+
+		printk("sock_release, %d\n", node->fd);
+		sock_release(node->sock);
+		printk("sys_close\n");
+		sys_close(node->fd);
+		/* kfree(node->sock);*/
+		printk("list_del\n");
+		list_del(&node->list);
+		printk("kmem_cache_free\n");
+		kmem_cache_free(kcom_node_cachep, node);
+		/* kfree(node);*/
+	}
+	/* spin_unlock(&kcom_nodes_lock);*/
+	kfree(sockets_fds_bitmap);
+
+	kmem_cache_destroy(kcom_data_cachep);
+	kmem_cache_destroy(kcom_pkt_cachep);
+	kmem_cache_destroy(kcom_task_cachep);
+	kmem_cache_destroy(kcom_node_cachep);
+
+	kcomd_task=NULL;
+	printk(KERN_INFO "kcomd: exit\n");
+	return 0;
 }
 
 static int __init kcomd_init(void)
 {
 	long ret;
 
-	ret = kernel_thread(kcomd_thread, NULL, 0);
+	ret = kernel_thread(kcomd_thread, NULL, CLONE_FS | CLONE_FILES);
 	return ret;
 }
 
 static void __exit kcomd_exit(void)
 {
+
+	/*
+	 * Set the exit condition and signal kcomd
+	 * kcomd cleans up after itself
+	 */
+	kcomd_done=1;
+
+	if (kcomd_task)
+		send_sig(SIGHUP, kcomd_task, 0);
+	else
+		printk(KERN_WARNING "Unable to to find kcomd daemon\n");
+
 }
 
 module_init(kcomd_init);
Index: linux/hpc/Makefile
===================================================================
--- linux.orig/hpc/Makefile	2006-09-18 23:28:26.000000000 +0200
+++ linux/hpc/Makefile	2006-09-18 23:29:28.000000000 +0200
@@ -2,7 +2,7 @@
 obj-$(CONFIG_KCOMD)     += kcomd.o
 
 # core part
-obj-$(CONFIG_OPENMOSIX)		+= kernel.o task.o comm.o
+obj-$(CONFIG_OPENMOSIX)		+= kernel.o task.o comm.o kcom.o
 obj-$(CONFIG_OPENMOSIX)		+= remote.o deputy.o copyuser.o files.o syscalls.o
 obj-$(CONFIG_OPENMOSIX)		+= migrecv.o migsend.o migctrl.o
 obj-$(CONFIG_OPENMOSIX)		+= service.o
Index: linux/include/hpc/protocol.h
===================================================================
--- linux.orig/include/hpc/protocol.h	2006-09-18 23:28:26.000000000 +0200
+++ linux/include/hpc/protocol.h	2006-09-18 23:29:28.000000000 +0200
@@ -34,12 +34,12 @@
 	int personality;	/* of process to be sent */
 };
 /* handshake types */
+
 #define HSHAKE_MIG_REQUEST	0x01
 #define HSHAKE_DEPUTY_PROBE	0x02
 #define HSHAKE_REPLY		0x04
 #define HSHAKE_NOTOK		0x08
 
-
 /* main structure for passing messages between
  * DEPUTY and REMOTE. Denotes the type of request,
  * and the length of it */
@@ -48,30 +48,68 @@
 	int type;
 	int dlen;
 };
+// pkt type
 
-#define DEP_FLG		0x100
-#define MIG_FLG		0x200
-#define REM_FLG		0x400
-#define REPLY		0x800
+// bits 3:0 - ACK
+#define MSG_MASK 		0xF
+#define PKT_NEW_MSG	0x0
+#define PKT_ACK		0x1
+#define PKT_RESP		0x2
+#define PKT_NACK		0x3
+
+#define NODE_MASK		0xF000
+#define DEP_FLG		0x1000
+#define MIG_FLG		0x2000
+#define REM_FLG		0x4000
+#define REPLY			0x8000
+
+#define DEP_PKT_NEW_MSG	(DEP_FLAG | PKT_NEW_MSG)
+#define DEP_PKT_ACK		(DEP_FLAG | PKT_ACK)
+#define DEP_PKT_RESP		(DEP_FLAG | PKT_RESP)
+#define DEP_PKT_NACK		(DEP_FLAG | PKT_NACK)
+
+#define REM_PKT_NEW_MSG	(REM_FLAG | PKT_NEW_MSG)
+#define REM_PKT_ACK		(REM_FLAG | PKT_ACK)
+#define REM_PKT_RESP		(REM_FLAG | PKT_RESP)
+#define REM_PKT_NACK		(REM_FLAG | PKT_NACK)
 
 /* commands sent during migration */
-#define MIG_MM		(MIG_FLG | 0x10)
-#define MIG_VMA		(MIG_FLG | 0x11)
-#define MIG_PAGE	(MIG_FLG | 0x12)
-#define MIG_FP		(MIG_FLG | 0x13)
-#define MIG_ARCH	(MIG_FLG | 0x14)
-#define MIG_TASK	(MIG_FLG | 0x15)
-#define MIG_ABORT	(MIG_FLG | 0x16)
+// #define MIG_MM		(MIG_FLG | 0x10)
+// #define MIG_VMA		(MIG_FLG | 0x11)
+// #define MIG_PAGE	(MIG_FLG | 0x12)
+// #define MIG_FP		(MIG_FLG | 0x13)
+// #define MIG_ARCH	(MIG_FLG | 0x14)
+// #define MIG_TASK	(MIG_FLG | 0x15)
+// #define MIG_ABORT	(MIG_FLG | 0x16)
+
+// PKT_TYPES
+#define MIG_MASK	0xF0
+#define MIG_PING	0x10
+#define MIG_INIT	0x20
+#define MIG_MM		0x30
+#define MIG_VMA	0x40
+#define MIG_PAGE	0x50
+#define MIG_FP		0x60
+#define MIG_ARCH	0x70
+#define MIG_TASK	0x80
+#define MIG_GO_HOME	0x90
+#define MIG_COME_HOME	0xA0
+#define MIG_ABORT	0xB0
+#define MIG_SYSCALL	0xC0
+
+#define MIG_HOME	MIG_GO_HOME
 
 /* commands sent by deputy to remote */
-#define DEP_COPY_FROM_USER	(DEP_FLG | 0x01)
-#define DEP_COPY_TO_USER	(DEP_FLG | 0x02)
-#define DEP_STRNCPY_FROM_USER	(DEP_FLG | 0x03)
-#define DEP_STRNLEN_USER	(DEP_FLG | 0x04)
-#define DEP_GET_USER		(DEP_FLG | 0x05)
-#define DEP_PUT_USER		(DEP_FLG | 0x06)
-#define DEP_SIGNAL		(DEP_FLG | 0x07)
-#define DEP_COMING_HOME		(DEP_FLG | 0x10)
+#define SYSCALL_MASK 0xF00
+#define DEP_COPY_FROM_USER	0x100
+#define DEP_COPY_TO_USER	0x200
+#define DEP_STRNCPY_FROM_USER	0x300
+#define DEP_STRNLEN_USER	0x400
+#define DEP_GET_USER		0x500
+#define DEP_PUT_USER		0x600
+#define DEP_SIGNAL		0x700
+#define DEP_COMING_HOME		0x800
+#define SYSCALL_DONE		0x900
 
 /* commands sent by remote to deputy */
 #define REM_BRING_HOME	(REM_FLG | 0x10)
@@ -107,7 +145,7 @@
 	struct pt_regs regs;
 
 	struct omp_mig_arch_task arch;
-	char comm[TASK_COMM_LEN]; 
+	char comm[TASK_COMM_LEN];
 };
 
 /* mm_struct values */
Index: linux/include/hpc/prototype.h
===================================================================
--- linux.orig/include/hpc/prototype.h	2006-09-18 23:28:26.000000000 +0200
+++ linux/include/hpc/prototype.h	2006-09-20 17:07:33.000000000 +0200
@@ -28,6 +28,8 @@
 
 #define OMBUG(f, a...)	printk(KERN_ERR "[OMBUG] %s: " f, __FUNCTION__, ## a)
 
+#include <linux/in.h>
+#include <hpc/kcom.h>
 
 NORET_TYPE void		deputy_die_on_communication(void);
 void			deputy_main_loop(void);
@@ -83,4 +85,39 @@
 				struct vm_area_struct *vma);
 int		remote_readpage(struct file *file, struct page *page);
 
+int remote_handle_user(task_t *, int);
+
+int alloc_fd_bitmap(int);
+
+struct kcom_pkt *kcom_pkt_create(int, int, int, char *);
+
+int kcom_send(int, int, char *, unsigned long, struct sockaddr_in *);
+int kcom_send_with_ack(int, int, char *, unsigned long, struct sockaddr_in *);
+int kcom_send_with_response(int, int, char *, unsigned long, char *, struct sockaddr_in *);
+int wait_for_ack(struct kcom_task *, unsigned int);
+int wait_for_response(struct kcom_task *, unsigned int);
+int kcom_send_ack(task_t *, struct kcom_pkt *);
+int kcom_send_resp(task_t *, int , char *, struct kcom_pkt *);
+
+struct kcom_node *kcom_node_add(struct socket *);
+struct kcom_node *kcom_node_find(struct sockaddr *);
+
+struct kcom_task *kcom_task_create(struct kcom_node *, int);
+struct kcom_task *kcom_task_find(int);
+int kcom_task_send(struct kcom_task *, int, int, char *, char *, unsigned long);
+int kcom_task_delete(int);
+
+int mig_handle_migration(int *);
+int user_thread(int (*fn)(void *), void * arg, unsigned long flags);
+int mig_init(struct kcom_node *,struct kcom_pkt *);
+
+struct kcom_pkt* pkt_hdr_read(struct kcom_node *);
+int pkt_data_read(struct kcom_node *, struct kcom_pkt *, int, char *);
+
+struct kcom_task *kcom_remote_task_find(int);
+struct kcom_task *kcom_home_task_find(int);
+int mig_do_receive_home(struct kcom_node *node, struct kcom_pkt *recv_kcom_pkt);
+int mig_do_receive_init(struct kcom_node *node, struct kcom_pkt *recv_kcom_pkt);
+
+int remote_do_signal(task_t *,  struct kcom_pkt *);
 #endif /* _HPC_PROTOTYPE_H */
Index: linux/include/hpc/task.h
===================================================================
--- linux.orig/include/hpc/task.h	2006-09-18 23:28:26.000000000 +0200
+++ linux/include/hpc/task.h	2006-09-18 23:29:28.000000000 +0200
@@ -142,7 +142,7 @@
 void task_do_request(void);
 
 struct sockaddr;
-int task_register_migration(task_t *p, struct sockaddr *);
+int task_register_migration(task_t *p);
 
 struct inode;
 int task_maps_inode(task_t *p, struct inode *);
Index: linux/net/socket.c
===================================================================
--- linux.orig/net/socket.c	2006-09-18 23:29:28.000000000 +0200
+++ linux/net/socket.c	2006-09-18 23:29:28.000000000 +0200
@@ -530,7 +530,7 @@
 	put_cpu_var(sockets_in_use);
 	return sock;
 }
-#ifdef CONFIG_KCOMD
+#if defined(CONFIG_KCOMD) || defined (CONFIG_KCOMD_MODULE)
 EXPORT_SYMBOL_GPL(sock_alloc);
 #endif
 
Index: linux/fs/select.c
===================================================================
--- linux.orig/fs/select.c	2006-09-18 23:28:26.000000000 +0200
+++ linux/fs/select.c	2006-09-18 23:29:28.000000000 +0200
@@ -294,7 +294,7 @@
 
 	return retval;
 }
-#ifdef CONFIG_KCOMD
+#ifdef CONFIG_KCOMD_MODULE
 EXPORT_SYMBOL_GPL(do_select);
 #endif
 
Index: linux/include/linux/compiler.h
===================================================================
--- linux.orig/include/linux/compiler.h	2006-09-18 23:54:41.000000000 +0200
+++ linux/include/linux/compiler.h	2006-09-18 23:55:05.000000000 +0200
@@ -44,7 +44,7 @@
 #define OM_NSTATIC static
 #endif
 
-#ifdef CONFIG_KCOMD
+#if defined(CONFIG_KCOMD) || defined(CONFIG_KCOMD_MODULE)
 #define KCOMD_NSTATIC
 #else
 #define KCOMD_NSTATIC static
openmosix-kcomd-daemon-code.patch (text/x-patch, 29.8 KB)
Index: linux/hpc/kcom.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux/hpc/kcom.c	2006-09-20 17:48:20.000000000 +0200
@@ -0,0 +1,1061 @@
+/*
+ *	Copyright (C) 2006 Matt Dew <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/net.h>
+#include <linux/syscalls.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+#define _HPC_KCOMC_H 1
+#include <hpc/kcom.h>
+#include <hpc/prototype.h>
+
+
+/**
+ * pkt_data_read
+ *
+ * Description:
+ * 	read the data that was send following the pkt header.
+ * 	wait until all data has been read.
+ * 	The ->len field = size of the data in bytes.
+ **/
+int pkt_data_read(struct kcom_node *node, struct kcom_pkt *pkt, int len, char *data)
+{
+	struct socket *sock=node->sock;
+	struct iovec iov;
+	struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, MSG_WAITALL | MSG_NOSIGNAL };
+	mm_segment_t oldfs;
+	int i;
+	char buf[32];
+
+	iov.iov_base = data;
+	iov.iov_len = len;
+
+	// Too small of a packet gets delayed before being sent. Even with TCP_NODELAY
+	if (len < 32) {
+		iov.iov_base = &buf;
+		iov.iov_len = 32;
+	}
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	while (iov.iov_len > 0) {
+		i = sock_recvmsg(sock, &msg, iov.iov_len, msg.msg_flags);
+		if ((i == -ENOSPC) || (i == -EAGAIN)) {
+			schedule_timeout(HZ/1000);
+			continue;
+		}
+		if (i < 0) {
+			printk("ERROR %d receiving data.\n", i);
+			set_fs(oldfs);
+			return -1;
+		}
+		iov.iov_base += i;
+ 	}
+
+	set_fs(oldfs);
+
+	if (len < 32) {
+		memcpy(data, buf, len);
+	}
+
+	return len;
+}
+EXPORT_SYMBOL_GPL(pkt_data_read);
+
+/**
+ * pkt_hdr_read
+ *
+ * Description:
+ * 	read the pkt header of the data transmission.
+ * 	The hdr indicates the type and size of the data.
+ * 	All packet headers are the same size.
+ **/
+struct kcom_pkt* pkt_hdr_read(struct kcom_node *node)
+{
+	struct iovec iov;
+	struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, MSG_WAITALL | MSG_NOSIGNAL };
+	struct kcom_pkt *recv_kcom_pkt;
+	mm_segment_t oldfs;
+	struct socket *sock=node->sock;
+	int i;
+
+	recv_kcom_pkt=kmem_cache_alloc(kcom_pkt_cachep, SLAB_KERNEL);
+	iov.iov_base = recv_kcom_pkt;
+	iov.iov_len = sizeof(*recv_kcom_pkt);
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	while ( iov.iov_len > 0 ) {
+		i = sock_recvmsg(sock, &msg, iov.iov_len, msg.msg_flags);
+		if ((i == -ENOSPC) || (i == -EAGAIN)) {
+			schedule_timeout(HZ/1000);
+			continue;
+		}
+		if (i < 0) {
+			printk("ERROR %d receiving header.\n", i);
+			set_fs(oldfs);
+			return NULL;
+		}
+		iov.iov_base += i;
+ 	}
+	set_fs(oldfs);
+
+	if (iov.iov_len==0) // all expected data received.
+		return recv_kcom_pkt;
+	else
+		return NULL;
+}
+EXPORT_SYMBOL_GPL(pkt_hdr_read);
+
+
+/**
+ * alloc_fd_bitmap
+ *
+ * Description:
+ * 	Allocate a large enough file descriptor bitmap
+ * 	for the do_select function to operate correctly
+ * 	on all open sockets.
+ *    If more space needs to be allocated, it will be
+ **/
+int alloc_fd_bitmap(int fd)
+{
+	struct kcom_node *node;
+	int size;
+	int n=fd;
+
+	if (fd <= maxfds)
+		return 0;
+
+	n = max(fd,max(fd4, fd6));
+	// spin_lock(&kcom_nodes_lock);
+	list_for_each_entry(node, &kcom_nodes, list)
+		n = max(node->fd, n);
+	// spin_unlock(&kcom_nodes_lock);
+
+
+	maxfds = n;
+
+	kfree(sockets_fds_bitmap);
+
+	size = FDS_BYTES(n);
+	sockets_fds_bitmap = kmalloc(6 * size, GFP_KERNEL);
+	if (!sockets_fds_bitmap)
+		return ENOMEM;
+
+	sockets_fds.in      = (unsigned long *)  sockets_fds_bitmap;
+	sockets_fds.out     = (unsigned long *) (sockets_fds_bitmap +   size);
+	sockets_fds.ex      = (unsigned long *) (sockets_fds_bitmap + 2*size);
+	sockets_fds.res_in  = (unsigned long *) (sockets_fds_bitmap + 3*size);
+	sockets_fds.res_out = (unsigned long *) (sockets_fds_bitmap + 4*size);
+	sockets_fds.res_ex  = (unsigned long *) (sockets_fds_bitmap + 5*size);
+
+	return 0;
+
+}
+EXPORT_SYMBOL_GPL(alloc_fd_bitmap);
+
+/**
+ * kcom_pkt_create
+ *
+ * Description:
+ * 	Allocate a kcom pkt from the slab.
+ * 	Initialize the pkt len,type and data ptr.
+ *    If this is a new packet, increment the global msgid counter.
+ **/
+struct kcom_pkt *kcom_pkt_create(int len, int type, int ack, char *data)
+{
+	struct kcom_pkt *pkt;
+
+	pkt=kmem_cache_alloc(kcom_pkt_cachep, SLAB_KERNEL);
+	if (pkt) {
+		pkt->len = len;
+		pkt->type = type;
+
+		if (len > 0)
+			pkt->data=data;
+		else
+			pkt->data=NULL;
+
+		// acks and responses don't get new a msgid
+		// FIXME:  is this inc SMP safe?
+		if ((type & MSG_MASK) == PKT_NEW_MSG)
+			pkt->msgid = kcom_msgid++;
+
+		return pkt;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(kcom_pkt_create);
+
+/**
+ * __kcom_node_find
+ *
+ * Description:
+ * 	Does the actual work of finding, if it exists,
+ * 	an existing node connection.
+ *    The IP address is the determiner.
+ **/
+struct kcom_node *__kcom_node_find(struct sockaddr *saddr)
+{
+	struct kcom_node *tmp;
+	struct sockaddr_in *saddr_tmp;
+	struct sockaddr_in *saddr_in=(struct sockaddr_in *)saddr;
+	unsigned long int node_addr, find_addr;
+
+	find_addr=saddr_in->sin_addr.s_addr;
+
+	list_for_each_entry(tmp, &kcom_nodes, list) {
+		saddr_tmp=(struct sockaddr_in *)&tmp->addr;
+		node_addr=saddr_tmp->sin_addr.s_addr;
+
+		if ((saddr_in->sin_family == saddr_tmp->sin_family) &&
+			(find_addr == node_addr))
+			return tmp;
+	}
+	return NULL;
+}
+
+
+/**
+ * kcom_node_find
+ *
+ * Description:
+ * 	calls __kcom_node_find
+ *    ,  which searches for a node
+ **/
+struct kcom_node *kcom_node_find(struct sockaddr *saddr)
+{
+	task_t *p=current;
+	struct kcom_node *node;
+	struct sockaddr_in *addr_tmp;
+	unsigned int addr;
+
+	addr_tmp=(struct sockaddr_in *)p->om.whereto;
+	addr=addr_tmp->sin_addr.s_addr;
+	// spin_lock(&kcom_nodes_lock);
+	node = __kcom_node_find(saddr);
+	// spin_unlock(&kcom_nodes_lock);
+	return node;
+}
+EXPORT_SYMBOL_GPL(kcom_node_find);
+
+/**
+ * kcom_node_add
+ *
+ * Description:
+ * 	adds a new node connection.
+ *    signals kcomd that it needs to watch this node's socket.
+ *    the file descriptor belonging to this socket is mapped in
+ *    kcomd, but the function sock_map_fd. Due to a kernel security
+ *    check file descriptors are not shared between kernel threads.
+ **/
+struct kcom_node *kcom_node_add(struct socket *sock)
+{
+	struct kcom_node *node;
+
+	node=kmem_cache_alloc(kcom_node_cachep, SLAB_KERNEL);
+	if (!node) {
+		printk("Unable to allocate node space.\n");
+		return NULL; //-ENOMEM;
+	}
+	INIT_LIST_HEAD(&node->list);
+	INIT_LIST_HEAD(&node->tasks);
+	node->sock=sock;
+	node->fd = 0; // kcomd will see this and assign a fd properly.
+
+	/*
+	if (!sock->ops || !sock->ops->getname)
+		goto err;
+
+	ret = sock->ops->getname
+	check if it's already in node list.
+	*/
+
+	spin_lock(&kcom_nodes_lock);
+	list_add_tail(&node->list, &kcom_nodes);
+	spin_unlock(&kcom_nodes_lock);
+
+	if (kcomd_task)
+		send_sig(SIGHUP,kcomd_task,0);
+	else {
+		printk("Unable to find kcomd daemon.\n");
+		return NULL;
+	}
+	printk("leaving kcom_node_add\n");
+	return node;
+
+}
+EXPORT_SYMBOL_GPL(kcom_node_add);
+
+/**
+ * kcom_node_del
+ *
+ * Description:
+ * 	removes this node from the list of connected nodes.
+ *    releases the corresponding socket and file descriptor.
+ **/
+int kcom_node_del(struct sockaddr *addr)
+{
+	struct kcom_node *node;
+
+	/* remove the node from the list */
+	spin_lock(&kcom_nodes_lock);
+	node = __kcom_node_find(addr);
+	if (!node) {
+		spin_unlock(&kcom_nodes_lock);
+		return -ENOENT;
+	}
+	list_del(&node->list);
+	spin_unlock(&kcom_nodes_lock);
+
+	/* release and free structure */
+	sys_close(node->fd);
+	sock_release(node->sock);
+	kfree(node);
+	return 0;
+}
+
+/**
+ * set_sockopts
+ *
+ * Description:
+ * 	sets the socket options.  TCP_NODELAY (send tcp packet immediately),
+ *    keepalive intervals, retries, etc.
+ **/
+int set_sockopts(struct socket *sock)
+{
+	int val;
+	int ret;
+	char __user *pval;
+	mm_segment_t oldfs;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	pval = (char __user *) &val;
+
+	val = 1;
+	ret = sock_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+		pval, sizeof(val));
+	if (ret) {
+		printk("unable to setsock SO_KEEPALIVE ERROR %d\n", ret);
+		return -1;
+	}
+
+	/* FIXME: check on these, old COMM_MIGD */
+	val = OPENMOSIX_CONNECTION_KEEPALIVE_INTERVAL;
+	ret = sock->ops->setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL,
+		pval, sizeof(val));
+	if (ret) {
+		printk("Unable to setsock TCP_KEEPINTVL ERROR %d\n", ret);
+		return -1;
+	}
+
+	val = OPENMOSIX_CONNECTION_KEEPALIVE_MAXTRIES;
+	ret = sock->ops->setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT,
+		pval, sizeof(val));
+	if (ret) {
+		printk("unable to setsock TCP_KEEPCNT ERROR %d\n", ret);
+		return -1;
+	}
+
+	val = OPENMOSIX_CONNECTION_KEEPALIVE_TOTAL;
+	ret = sock->ops->setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE,
+		pval, sizeof(val));
+	if (ret) {
+		printk("unable to setsock TCP_KEEPIDLE ERROR %d\n", ret);
+		return -1;
+	}
+
+	val=1;
+	ret = sock->ops->setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, pval, sizeof(val));
+	if (ret < 0) {
+		printk("Unable to setsockopt ERROR: %d\n", ret);
+		return -1;
+	}
+	set_fs(oldfs);
+	return 0;
+
+}
+
+/**
+ * create_connection
+ *
+ * Description:
+ * 	creates the network connection to other nodes and creates
+ *    a node that holds this connection. Stores the corresponding
+ *    IP address in the node as well.
+ **/
+struct kcom_node *create_connection(struct sockaddr *saddr)
+{
+
+	struct socket *sock;
+	// int fd;
+	int ret;
+	int error;
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long timo=MAX_SCHEDULE_TIMEOUT;
+
+	struct kcom_node *node;
+
+	ret = sock_create(saddr->sa_family, SOCK_STREAM, IPPROTO_TCP, &sock);
+	if (ret < 0) {
+		printk("Unable to sock_create. ret=%d\n", ret);
+		return NULL;
+	}
+
+	error = sock->ops->connect(sock, saddr, sizeof(struct sockaddr_in), O_NONBLOCK);
+	add_wait_queue(sock->sk->sk_sleep, &wait);
+	while (sock->state != SS_CONNECTED) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		error = sock->ops->connect(sock, saddr, sizeof(struct sockaddr_in), O_NONBLOCK);
+		if (error != -EALREADY || (error = sock_error(sock->sk)))
+			break;
+		timo = schedule_timeout(timo);
+		if (timo <= 0) {
+			error = -EAGAIN;
+			break;
+		}
+	}
+	remove_wait_queue(sock->sk->sk_sleep, &wait);
+	set_current_state(TASK_RUNNING);
+
+	if (error < 0) {
+		printk("Unable to create connection. Err %d\n", error);
+		return NULL;
+	}
+
+	node = kcom_node_find(saddr);
+	if (!node) {
+		node = kcom_node_add(sock);
+		if (!node) {
+			printk("Unable to add node\n");
+			return NULL;
+		}
+		memcpy(&node->addr, saddr, sizeof(*saddr));
+		ret=set_sockopts(node->sock);
+		if (ret) {
+			printk("Unable to set socket options.\n");
+			return NULL;
+		}
+	} else
+		printk("Connection already exists. Not creating new node.\n");
+
+	return node;
+
+}
+EXPORT_SYMBOL_GPL(create_connection);
+
+/**
+ * kcom_task_create
+ *
+ * Description:
+ * 	creates the kcom task related to this process.
+ *    initializes the linked lists for incoming and outgoing
+ *    pkts.  Also links this task to the corresponding node
+ *    since only migrated(ing) processes need kcom tasks.
+ **/
+struct kcom_task *kcom_task_create(struct kcom_node *node, int pid)
+{
+	struct kcom_task *kctask;
+	task_t *p;
+
+	kctask=kmem_cache_alloc(kcom_task_cachep, SLAB_KERNEL);
+
+	if (kctask) {
+		if (pid==0) { // this only occurs when remote node is creating new proc.
+				kctask->rpid = 0;
+				kctask->hpid = pid;
+		} else {
+			// read_lock(&tasklist_lock);
+			p = find_task_by_pid(pid);
+			// read_unlock(&tasklist_lock);
+			if (p) {
+				if (task_test_dflags(p, DREMOTE)) {
+					kctask->rpid = pid;
+					kctask->hpid = 0;
+				} else {
+					kctask->hpid = pid;
+					kctask->rpid = 0;
+				}
+			} else {
+				printk("ERROR creating kcom task.\n");
+				return NULL;
+			}
+		}
+
+		kctask->node = node;
+		INIT_LIST_HEAD(&kctask->list);
+		INIT_LIST_HEAD(&kctask->out_packs);
+		INIT_LIST_HEAD(&kctask->in_packs);
+		spin_lock_init(&kctask->spinlock);
+
+		list_add_tail(&kctask->list, &node->tasks);
+	} else
+		return NULL;
+	return kctask;
+}
+EXPORT_SYMBOL_GPL(kcom_task_create);
+
+/**
+ * kcom_task_delete
+ *
+ * Description:
+ * 	deletes the kcom task and frees the memory.
+ *    Lookins that dflags to see if this is a process is a
+ *    remote process corresponding to a migrated process or
+ *    if its a 'home' process.
+ *    This is needed since both process ID's are kept in the
+ *    kcom task.
+ **/
+int kcom_task_delete(pid_t pid)
+{
+	struct kcom_node *tmp;
+	struct kcom_task *tmp2;
+	struct kcom_task *tsk;
+
+	// Can't delete task until all pkts are sent.
+	tsk=kcom_task_find(pid);
+	// FIXME:  SMP safety
+	while (!list_empty(&tsk->out_packs))
+			schedule_timeout(HZ/1000);
+
+
+	list_for_each_entry(tmp, &kcom_nodes, list)
+		list_for_each_entry(tmp2, &tmp->tasks, list)
+			if (task_test_dflags(current, DREMOTE)) {
+				if (tmp2->rpid == pid) {
+					printk("Deleting remote kcom task %u.\n", pid);
+					list_del(&tmp2->list);
+					kfree(tmp2);
+					break;
+				}
+			 } else {
+				if (tmp2->hpid == pid) {
+					printk("Deleting home kcom task %u.\n", pid);
+					list_del(&tmp2->list);
+					kfree(tmp2);
+					break;
+				}
+			}
+	return 0;
+}
+
+/**
+ * __kcom_task_find
+ *
+ * Description:
+ * 	Searches all nodes for a specific task, by pid.
+ *    Lookins that dflags to see if this is a process is a
+ *    remote process corresponding to a migrated process or
+ *    if its a 'home' process.
+ *    This is needed since both process ID's are kept in the
+ *    kcom task.
+ **/
+struct kcom_task *__kcom_task_find(pid_t pid, int where)
+{
+	struct kcom_node *tmp;
+	struct kcom_task *tmp2;
+	task_t *p;
+
+	// read_lock(&tasklist_lock);
+	p = find_task_by_pid(pid);
+	// read_unlock(&tasklist_lock);
+	if (!p) {
+		printk("Unable to find pid %u\n", pid);
+		return NULL;
+	}
+
+	if (where == 0) {
+		// printk("FUNCTION: kcom_task_find\n");
+		list_for_each_entry(tmp, &kcom_nodes, list)
+			list_for_each_entry(tmp2, &tmp->tasks, list)
+				// One remote node, we're interested in rpid
+				// One home node, we're interested in hpid
+				if (task_test_dflags(p, DREMOTE)) {
+					// printk("kcom_task_find: dremote\n");
+					if (tmp2->rpid == pid)
+						return tmp2;
+				} else {
+					// printk("kcom_task_find: ddeputy\n");
+					if (tmp2->hpid == pid)
+						return tmp2;
+				}
+	} else if (where == 1) { // home
+		list_for_each_entry(tmp, &kcom_nodes, list)
+			list_for_each_entry(tmp2, &tmp->tasks, list)
+				if (tmp2->hpid == pid)
+					return tmp2;
+	} else if (where == 2) { // remote
+		list_for_each_entry(tmp, &kcom_nodes, list)
+			list_for_each_entry(tmp2, &tmp->tasks, list)
+				if (tmp2->rpid == pid)
+					return tmp2;
+
+	}
+	// printk("leaving FUNCTION: kcom_task_find\n");
+	return NULL;
+}
+
+/**
+ * kcom_task_find
+ *
+ * Description:
+ * 	calls __kcom_task_find, specifically looking
+ *    for a home pid.
+ **/
+struct kcom_task *kcom_home_task_find(pid_t pid)
+{
+	struct kcom_task *tmp;
+
+	tmp = __kcom_task_find(pid, 1);
+	return tmp;
+
+}
+EXPORT_SYMBOL_GPL(kcom_home_task_find);
+
+/**
+ * kcom_remote_task_find
+ *
+ * Description:
+ * 	calls __kcom_task_find, specifically looking
+ *    for a remote pid.
+ **/
+struct kcom_task *kcom_remote_task_find(pid_t pid)
+{
+	struct kcom_task *tmp;
+
+	tmp = __kcom_task_find(pid, 2);
+	return tmp;
+
+}
+EXPORT_SYMBOL_GPL(kcom_remote_task_find);
+
+
+/**
+ * kcom_task_find
+ *
+ * Description:
+ * 	calls __kcom_task_find,  which looks
+ *    at dflags to determine for itself if this is
+ *    a home or remote pid.
+ **/
+struct kcom_task *kcom_task_find(pid_t pid)
+{
+	struct kcom_task *tmp;
+
+	tmp = __kcom_task_find(pid, 0);
+	return tmp;
+}
+EXPORT_SYMBOL_GPL(kcom_task_find);
+
+/**
+ * kcom_task_send
+ *
+ * Description:
+ * 	Creates a packet to send and adds it to the task's outbound list.
+ *    No acknowledgement or reply is expected.
+ **/
+int kcom_task_send(struct kcom_task *tsk, int type, int datasize, char *data, char *resp, unsigned long addr)
+{
+	// struct kcom_task *tsk;
+	struct kcom_pkt *pkt;
+
+	// printk("kcom_task_send:\n");
+	// tsk = kcom_task_find(pid);
+	if (!tsk)
+		return -ENODEV;
+
+	/* put pkt in kcom_task */
+	pkt = kcom_pkt_create(datasize, type, PKT_NEW_MSG, data);
+	if (!pkt)
+		return -1;
+
+	if (!resp)
+		pkt->resp=data;
+	else
+		pkt->resp=resp;
+
+	pkt->hpid=tsk->hpid;
+	pkt->rpid=tsk->rpid;
+	pkt->addr=addr; // used by vma_pages
+
+	// spin_lock(&tsk->spinlock);
+	list_add_tail(&pkt->list, &tsk->out_packs);
+	// spin_unlock(&tsk->spinlock);
+
+	return pkt->msgid;
+}
+
+/**
+ * kcom_send
+ *
+ * Description:
+ *    Tell this function what type of pkt, the data and where to send it and
+ *    it finds the corresponding node, creating a new connection if necessary
+ *    Finds the corresponding tsk, creating it if necessary.
+ * 	creates a packet to send and adds it to the task's outbound list.
+ *    No acknowledgement or reply is expected.
+ **/
+int kcom_send(int type, int datasize, char *data, unsigned long addr, struct sockaddr_in *saddr)
+{
+
+	struct kcom_node *node;
+	struct kcom_task *tsk;
+	task_t *p = current;
+	unsigned int msgid;
+
+	node=kcom_node_find((struct sockaddr *)saddr);
+	if (node==NULL) {
+		printk("node not found, creating new connection.\n");
+		node=create_connection((struct sockaddr *)saddr);
+		if (node==NULL)
+			return -1;
+	}
+
+	tsk=kcom_task_find(p->pid);
+	if (tsk==NULL) {
+		printk("Task not found. creating new.\n");
+		tsk=kcom_task_create(node, p->pid);
+		if (tsk==NULL)
+			return -1;
+	}
+
+	msgid=kcom_task_send(tsk, type, datasize, data, NULL, addr);
+
+	if (kcomd_task != NULL)
+		send_sig(SIGHUP,kcomd_task,0);
+
+	return 0;
+}
+/**
+ * kcom_send_nack
+ *
+ * Description:
+ *    Send an ack to the other node.  This is the matching function for kcom_send_with_ack.
+ *    An ack is the acknowledgement that the kcom pkt was received correctly.
+ **/
+int kcom_send_nack(task_t *p, struct kcom_pkt *recv_pkt)
+{
+	// task_t *kcomd_task;
+	int mig_flag;
+	int syscall_flag;
+	int node_flag;
+	struct kcom_pkt *send_pkt;
+	struct kcom_task *send_tsk;
+
+	mig_flag=recv_pkt->type & MIG_MASK;
+	syscall_flag=recv_pkt->type & SYSCALL_MASK;
+
+	send_tsk=kcom_task_find(p->pid);
+
+	if (task_test_dflags(p, DREMOTE))
+		node_flag = REM_FLG;
+	else
+		node_flag = DEP_FLG;
+	send_pkt=kcom_pkt_create(0, mig_flag | syscall_flag | PKT_NACK | node_flag, PKT_NACK, NULL);
+
+	send_pkt->msgid=recv_pkt->msgid; // responses have same msg id as pkt they are responding to.
+	send_pkt->hpid=recv_pkt->hpid;
+	send_pkt->rpid=recv_pkt->rpid;
+	send_pkt->resp=recv_pkt->resp;
+
+	// spin_lock(&send_tsk->spinlock); // done outside this function
+	list_add_tail(&send_pkt->list, &send_tsk->out_packs);
+	// spin_unlock(&send_tsk->spinlock);
+
+	if (kcomd_task)
+		send_sig(SIGHUP,kcomd_task,0);
+	else {
+		printk("Unable to signal kcomd\n");
+		return -1;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(kcom_send_nack);
+
+
+/**
+ * kcom_send_ack
+ *
+ * Description:
+ *    Send an ack to the other node.  This is the matching function for kcom_send_with_ack.
+ *    An ack is the acknowledgement that the kcom pkt was received correctly.
+ **/
+int kcom_send_ack(task_t *p, struct kcom_pkt *recv_pkt)
+{
+	// task_t *kcomd_task;
+	int mig_flag;
+	int syscall_flag;
+	int node_flag;
+	struct kcom_pkt *send_pkt;
+	struct kcom_task *send_tsk;
+
+	mig_flag=recv_pkt->type & MIG_MASK;
+	syscall_flag=recv_pkt->type & SYSCALL_MASK;
+
+	send_tsk=kcom_task_find(p->pid);
+
+	if (task_test_dflags(p, DREMOTE))
+		node_flag = REM_FLG;
+	else
+		node_flag = DEP_FLG;
+	send_pkt=kcom_pkt_create(0, mig_flag | syscall_flag | PKT_ACK | node_flag, PKT_ACK, NULL);
+
+	send_pkt->msgid=recv_pkt->msgid; // responses have same msg id as pkt they are responding to.
+	send_pkt->hpid=recv_pkt->hpid;
+	send_pkt->rpid=recv_pkt->rpid;
+	send_pkt->resp=recv_pkt->resp;
+
+	// spin_lock(&send_tsk->spinlock); // done outside this function
+	list_add_tail(&send_pkt->list, &send_tsk->out_packs);
+	// spin_unlock(&send_tsk->spinlock);
+
+	if (kcomd_task)
+		send_sig(SIGHUP,kcomd_task,0);
+	else {
+		printk("Unable to signal kcomd\n");
+		return -1;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(kcom_send_ack);
+
+/**
+ * kcom_send_resp
+ *
+ * Description:
+ *    Send an response to the other node.  This is the matching function for kcom_send_with_response.
+ *    An response is both the acknowledgement that the kcom pkt was received correctly (or not) and
+ *    the expected response data.
+ **/
+int kcom_send_resp(task_t *p, int len, char *buf, struct kcom_pkt *recv_pkt)
+{
+	int mig_flag;
+	int syscall_flag;
+	int node_flag;
+	struct kcom_pkt *send_pkt;
+	struct kcom_task *send_tsk;
+
+	mig_flag=recv_pkt->type & MIG_MASK;
+	syscall_flag=recv_pkt->type & SYSCALL_MASK;
+
+	send_tsk=kcom_task_find(p->pid);
+
+	if (task_test_dflags(p, DREMOTE))
+		node_flag = REM_FLG;
+	else
+		node_flag = DEP_FLG;
+
+	send_pkt=kcom_pkt_create(len, mig_flag | syscall_flag | PKT_ACK | node_flag, PKT_ACK, buf);
+
+	send_pkt->msgid=recv_pkt->msgid;
+	send_pkt->hpid=send_tsk->hpid;
+	send_pkt->rpid=send_tsk->rpid;
+	send_pkt->resp=recv_pkt->resp;
+
+	list_add_tail(&send_pkt->list, &send_tsk->out_packs);
+	if (kcomd_task) {
+		printk("Signaling kcomd\n");
+		send_sig(SIGHUP, kcomd_task, 0);
+	} else {
+		printk("Unable to signal kcomd\n");
+		return -1;
+	}
+	return 0;
+
+}
+EXPORT_SYMBOL(kcom_send_resp);
+
+/**
+ * wait_for_ack
+ *
+ * Description:
+ *    This actually checks the task's incoming pkt list for the matching msgid.
+ *    If the matching pkt is found, it is removed from the list and the function
+ *    returns success, else returns failure.
+ **/
+int wait_for_ack(struct kcom_task *task, unsigned int msgid)
+{
+	struct kcom_pkt *pkt, *pkt_next;
+
+	// spin_lock(&task->spinlock);
+	if (!list_empty(&task->in_packs)) {
+		list_for_each_entry_safe(pkt, pkt_next, &task->in_packs, list) {
+			if ((msgid==pkt->msgid) && ((pkt->type & MSG_MASK) == PKT_ACK)) {
+				list_del(&pkt->list);
+				kmem_cache_free(kcom_pkt_cachep, pkt);
+
+				// FIXME:  this doesn't belong here.
+				// init packet has rpid
+				if ((pkt->type & MIG_MASK) == MIG_INIT)
+					task->rpid=pkt->rpid;
+
+				// spin_unlock(&task->spinlock);
+
+				return 0;
+			}  // FIXME:  what about nacks?
+
+		}
+	}
+
+	// spin_unlock(&task->spinlock);
+	return -1;
+
+}
+
+/**
+ * wait_for_response
+ *
+ * Description:
+ *    This actually checks the task's incoming pkt list for the matching msgid.
+ *    If the matching pkt is found, it is removed from the list and the function
+ *    returns success, else returns failure.
+ *    FIXME: very similar to wait_for_ack,  merge??
+ **/
+int wait_for_response(struct kcom_task *task, unsigned int msgid)
+{
+	struct kcom_pkt *pkt, *pkt_next;
+	int i=-1;
+
+	printk("wait_for_response...for msgid %u\n", msgid);
+		list_for_each_entry_safe(pkt, pkt_next, &task->in_packs, list)
+			// FIXME:  check for resp or ack, too.
+			if (msgid==pkt->msgid) {
+				i=pkt->len;
+				list_del(&pkt->list);
+				kmem_cache_free(kcom_pkt_cachep, pkt);
+				printk("wait_for_response: i=%d, addr=%lu pkt->resp=%s\n", i, pkt->addr, pkt->resp);
+			}
+	return i;
+
+}
+
+/**
+ * kcom_send_with_ack
+ *
+ * Description:
+ *    Same as kcom_send except this function waits until an (n)ack is received.
+ **/
+int kcom_send_with_ack(int type, int datasize, char *data, unsigned long addr, struct sockaddr_in *saddr)
+{
+	struct kcom_node *node;
+	struct kcom_task *tsk;
+	task_t *p = current;
+	unsigned int msgid;
+
+	node=kcom_node_find((struct sockaddr *)saddr);
+	if (node==NULL) {
+		printk("Node not found, creating new connection.\n");
+		node=create_connection((struct sockaddr *)saddr);
+		if (!node) {
+			printk("ERROR: Unable to create new connection.\n");
+			return -1;
+		}
+	}
+
+	tsk=kcom_task_find(p->pid);
+	if (tsk==NULL) {
+		printk("Task not found. creating new.\n");
+		tsk=kcom_task_create(node, p->pid);
+		if (!tsk) {
+			printk("ERROR: Unable to create task.\n");
+			return -1;
+		}
+	}
+
+	// FIXME:  what if tsk is deleted between kcom_task_send and wait_for_ack ?
+	msgid=kcom_task_send(tsk, type, datasize, data, NULL, addr);
+
+	if (kcomd_task)
+		send_sig(SIGHUP,kcomd_task,0);
+	else {
+		printk("Unable to find kcomd daemon.\n");
+		return -1;
+	}
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	while (wait_for_ack(tsk, msgid)!=0) {
+		schedule();
+		set_current_state(TASK_INTERRUPTIBLE);
+	}
+	set_current_state(TASK_RUNNING);
+	printk("Done waiting. msgid %d received...\n", msgid);
+
+
+	return 0;
+}
+
+/**
+ * kcom_send_with_response
+ *
+ * Description:
+ *    Same as kcom_send except this function waits until an response is received.
+ **/
+int kcom_send_with_response(int type, int datasize, char *data, unsigned long addr, char *resp, struct sockaddr_in *saddr)
+{
+	struct kcom_node *node;
+	struct kcom_task *tsk;
+	task_t *p = current;
+	unsigned int msgid;
+	int i=-1;
+
+	node=kcom_node_find((struct sockaddr *)saddr);
+	if (node==NULL) {
+		printk("node not found, creating new connection.\n");
+		node=create_connection((struct sockaddr *)saddr);
+		if (node==NULL) {
+			return -1;
+		}
+	}
+
+	tsk=kcom_task_find(p->pid);
+	if (!tsk) {
+		printk("Task not found. Creating new.\n");
+		tsk=kcom_task_create(node, p->pid);
+		if (!tsk) {
+			printk("Unable to create task\n");
+			return -1;
+		}
+	}
+
+	msgid=kcom_task_send(tsk, type, datasize, data, resp, addr);
+
+	if (kcomd_task)
+		send_sig(SIGHUP,kcomd_task,0);
+	else {
+		printk("Unable to find kcomd daemon.\n");
+		return -1;
+	}
+
+	set_current_state(TASK_INTERRUPTIBLE);
+retry:
+	i=wait_for_response(tsk, msgid);
+	if (i < 0) {
+		set_current_state(TASK_INTERRUPTIBLE); // Not the correct packet. go back to sleep
+		schedule();
+		goto retry;
+	}
+	printk("Done waiting. msgid %d received...\n", msgid);
+
+	return i;
+}
Index: linux/include/hpc/kcom.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux/include/hpc/kcom.h	2006-09-20 17:50:41.000000000 +0200
@@ -0,0 +1,140 @@
+/*
+ *	Copyright (C) 2006 Matt Dew <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 only.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _HPC_KCOM_H
+#define _HPC_KCOM_H
+
+#include <linux/sched.h>
+#include <net/sock.h>
+#include <hpc/comm.h>
+
+#include <linux/in.h>
+
+#include <hpc/protocol.h>
+
+#define DAEMON_IP4_PORT	0xB55 // 2901
+#define DAEMON_IP6_PORT	0xB56 // 2902
+
+/* PROTOTYPES */
+#ifdef _HPC_KCOMC_H
+	DEFINE_SPINLOCK(kcom_nodes_lock);
+	EXPORT_SYMBOL(kcom_nodes_lock);
+
+	struct list_head kcom_nodes = LIST_HEAD_INIT(kcom_nodes);
+	EXPORT_SYMBOL(kcom_nodes);
+
+	fd_set_bits sockets_fds;
+	EXPORT_SYMBOL(sockets_fds);
+
+	char *sockets_fds_bitmap = NULL;
+	EXPORT_SYMBOL(sockets_fds_bitmap);
+
+	int maxfds = -1;
+	EXPORT_SYMBOL(maxfds);
+
+	struct socket *lsock4=NULL, *lsock6=NULL;
+	EXPORT_SYMBOL(lsock4);
+	EXPORT_SYMBOL(lsock6);
+
+	int fd4, fd6;
+	EXPORT_SYMBOL(fd4);
+	EXPORT_SYMBOL(fd6);
+
+	// pid_t kcom_pid;
+	// EXPORT_SYMBOL(kcom_pid);
+
+	task_t *kcomd_task=NULL;
+	EXPORT_SYMBOL(kcomd_task);
+
+	unsigned int kcom_msgid=0;
+	EXPORT_SYMBOL(kcom_msgid);
+
+	kmem_cache_t *kcom_data_cachep;
+	EXPORT_SYMBOL(kcom_data_cachep);
+
+	kmem_cache_t *kcom_pkt_cachep;
+	EXPORT_SYMBOL(kcom_pkt_cachep);
+
+	kmem_cache_t *kcom_task_cachep;
+	EXPORT_SYMBOL(kcom_task_cachep);
+
+	kmem_cache_t *kcom_node_cachep;
+	EXPORT_SYMBOL(kcom_node_cachep);
+
+	kmem_cache_t *kcom_saddr_cachep;
+	EXPORT_SYMBOL(kcom_saddr_cachep);
+
+
+#else /* _HPC_KCOMC_H */
+	extern int maxfds;
+	extern spinlock_t kcom_nodes_lock;
+	extern struct list_head kcom_nodes;
+
+	extern fd_set_bits sockets_fds;
+	extern char *sockets_fds_bitmap;
+	extern struct socket *lsock4;
+	extern struct socket *lsock6;
+	extern int fd4;
+	extern int fd6;
+
+	//extern pid_t kcom_pid;
+	extern task_t *kcomd_task;
+	extern kmem_cache_t *kcom_data_cachep;
+	extern kmem_cache_t *kcom_pkt_cachep;
+	extern kmem_cache_t *kcom_task_cachep;
+	extern kmem_cache_t *kcom_node_cachep;
+	extern kmem_cache_t *kcom_saddr_cachep;
+#endif /* _HPC_KCOMC_H */
+
+
+struct kcom_pkt
+{
+	pid_t hpid;     /* home pid of the this process */
+	pid_t rpid;     /* remote pid of 'that' other node process */
+	int len;      /* len of data */
+	int type;     /* type of data */
+	// int ack;      /* new msg, ack or response */
+	unsigned long addr; /* used by mm pages */
+	unsigned int msgid;
+	struct list_head list;
+	char *data;   /* ptr of data */
+	char *resp;   /* ptr of response */
+};
+
+struct kcom_node
+{
+	int fd;                 /* fd to send packet */
+	struct socket *sock;    /* socket */
+	struct sockaddr addr;   /* addr of this node */
+	spinlock_t tasks_lock;  /* lock for the list */
+	struct list_head tasks; /* list of task */
+	struct list_head list; /* list of nodes */
+	spinlock_t spinlock;
+};
+
+struct kcom_task
+{
+        pid_t hpid;          /* pid of the home node process owning this struct */
+        pid_t rpid;          /* pid of remote node process */
+        struct kcom_node *node; /* node of the process to send/recv */
+        struct list_head list;  /* list of process using some node */
+
+        struct list_head out_packs;
+        // struct kcom_pkt in_packs;
+        struct list_head in_packs;
+			spinlock_t spinlock; // FIXME:   ?? two spinlocks?  in_packs, out_packs
+};
+
+extern int kcom_send_nack(task_t *p, struct kcom_pkt *recv_pkt);
+#endif /* _HPC_KCOM_H */
openmosix-kcomd-debug.patch (text/x-patch, 15.1 KB)
Index: linux/hpc/arch-i386.c
===================================================================
--- linux.orig/hpc/arch-i386.c	2006-09-20 18:04:32.000000000 +0200
+++ linux/hpc/arch-i386.c	2006-09-20 18:04:59.000000000 +0200
@@ -245,10 +245,12 @@
 	syscall_func_t fct;
 	extern void * sys_call_table[];
 
-	OMDEBUG_SYS(4, "exec_sys[%d](%lx, %lx, %lx, %lx, %lx, %lx)\n", n,
+	/* OMDEBUG_SYS(4, "exec_sys[%d](%lx, %lx, %lx, %lx, %lx, %lx)\n", n,*/
+	printk("exec_sys[%d](%lx, %lx, %lx, %lx, %lx, %lx)\n", n,
 			args->arg[0], args->arg[1], args->arg[2],
 			args->arg[3], args->arg[4], args->arg[5]);
 	fct = (syscall_func_t) sys_call_table[n];
+	printk("arch_exec_syscall: debug1\n");
 	return fct(*((syscall_parameter_t *) args));
 }
 
Index: linux/hpc/comm.c
===================================================================
--- linux.orig/hpc/comm.c	2006-09-20 18:04:32.000000000 +0200
+++ linux/hpc/comm.c	2006-09-20 18:04:59.000000000 +0200
@@ -42,6 +42,7 @@
  **/
 static void comm_shutdown(struct socket *sock)
 {
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	if (sock && sock->ops)
 		sock->ops->shutdown(sock, SEND_SHUTDOWN);
 }
@@ -56,6 +57,7 @@
 {
 	int val, ret;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	val = sizeof(struct sockaddr);
 	if (!sock->ops || !sock->ops->getname)
 		return -1;
@@ -72,6 +74,7 @@
  **/
 void comm_data_ready(struct sock *sk, int len)
 {
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	wake_up_interruptible(sk->sk_sleep);
 }
 
@@ -82,6 +85,7 @@
 	int error;
 	mm_segment_t oldfs;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	oldfs = get_fs();
 	set_fs(KERNEL_DS);
 
@@ -129,6 +133,7 @@
 	int error;
 	struct socket *sock;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	error = sock_create(family, type, proto, &sock);
 	if (error < 0)
 		return NULL;
@@ -140,6 +145,7 @@
 {
 	int error;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	error = sock->ops->bind(sock, saddr, sizeof(*saddr));
 	if (error == -EADDRINUSE)
 		printk("comm_bind() Already in use\n");
@@ -151,6 +157,7 @@
 {
 	int error;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	error = sock->ops->listen(sock, SOMAXCONN);
 
 	return error;
@@ -162,6 +169,7 @@
 	int error;
 	DECLARE_WAITQUEUE(wait, current);
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	if (!timo)
 		timo = MAX_SCHEDULE_TIMEOUT;
 
@@ -207,6 +215,7 @@
 {
 	BUG_ON(!sock);
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	sock_release(sock);
 }
 
@@ -217,6 +226,7 @@
 {
 	int mask;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	mask = sock->ops->poll(NULL, sock, NULL);
 	return (mask & POLLIN_SET) ? 1 : 0;
 }
@@ -238,6 +248,7 @@
 	static struct file sighfile = {.f_count = ATOMIC_INIT(1)};
 	DECLARE_WAITQUEUE(wait, current);
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	/*
 	 * sighfile: we are required to supply a file to "hold" while we poll.
 	 * a bit ridiculous in this context, but nobody will notice because
@@ -262,6 +273,7 @@
 	remove_wait_queue(sock->sk->sk_sleep, &wait);
 	set_current_state(TASK_RUNNING);
 
+	printk("ERROR: COMM FUNCTION %s leaving\n", __FUNCTION__);
 	return (pollmask & mask) ? 1 : 0;
 }
 
@@ -293,6 +305,7 @@
 
 	*mlp = NULL;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	sock = sock_alloc();
 	if (!sock)
 		return error;
@@ -315,6 +328,7 @@
 		goto failed;
 
 	*mlp = sock;
+	printk("ERROR: COMM FUNCTION %s leaving\n", __FUNCTION__);
 	return error;
 
 failed:
@@ -338,6 +352,7 @@
 	int n = 0;
 	int left = len;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	do {
 		n = sock_recvmsg(sock, msg, left, msg->msg_flags);
 		if (n <= 0) {
@@ -367,6 +382,7 @@
 			}
 		}
 	} while (left);
+	printk("ERROR: COMM FUNCTION %s leaving\n", __FUNCTION__);
 	return len;
 }
 
@@ -387,6 +403,7 @@
 	BUG_ON(len > PAGE_SIZE);
 	BUG_ON(!mlink);
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	iov.iov_base = data;
 	iov.iov_len = len;
 
@@ -403,6 +420,7 @@
 
 	set_fs(oldfs);
 
+	printk("ERROR: COMM FUNCTION %s leaving\n", __FUNCTION__);
 	return error;
 }
 
@@ -421,6 +439,7 @@
 	mm_segment_t oldfs;
 	int error;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	BUG_ON(!mlink);
 
 	iov.iov_base = data;
@@ -435,6 +454,7 @@
 
 	set_fs(oldfs);
 
+	printk("ERROR: COMM FUNCTION %s leaving\n", __FUNCTION__);
 	return error;
 }
 
@@ -465,6 +485,7 @@
 	struct socket *link;
 	int error;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	link = comm_socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP);
 	if (!link)
 		return NULL;
@@ -477,6 +498,7 @@
 	if (error < 0)
 		goto fail;
 
+	printk("ERROR: COMM FUNCTION %s leaving\n", __FUNCTION__);
 	return link;
 
 fail:
@@ -488,6 +510,7 @@
 {
 	struct socket *link;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	link = comm_socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP);
 	if (!link)
 		return NULL;
@@ -495,6 +518,7 @@
 	if (comm_connect(link, sa, timo))
 		goto fail;
 
+	printk("ERROR: COMM FUNCTION %s leaving\n", __FUNCTION__);
 	return link;
 
 fail:
@@ -507,6 +531,7 @@
 	struct omp_req req;
 	int error;
 
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	req.type = type;
 	req.dlen = dlen;
 
@@ -518,6 +543,7 @@
 	if (error < 0)
 		return -1;
 
+	printk("ERROR: COMM FUNCTION %s leaving\n", __FUNCTION__);
 	return 0;
 }
 
@@ -526,5 +552,6 @@
 {
 	struct omp_req req;
 	req.type = type;
+	printk("ERROR: COMM FUNCTION %s\n", __FUNCTION__);
 	return comm_send(link, &req, sizeof(req));
 }
Index: linux/hpc/copyuser.c
===================================================================
--- linux.orig/hpc/copyuser.c	2006-09-20 18:04:59.000000000 +0200
+++ linux/hpc/copyuser.c	2006-09-20 18:04:59.000000000 +0200
@@ -177,6 +177,7 @@
 long deputy_put_user(long value, const void *addr, size_t size)
 {
 	BUG_ON(size > sizeof(long));
+	printk(KERN_DEBUG "FUNCTION: deputy_put_user\n");
 	return deputy_put_userX((s64) value, addr, size);
 }
 EXPORT_SYMBOL(deputy_put_user);
@@ -193,6 +194,7 @@
  **/
 long deputy_put_user64(s64 value, const void *addr)
 {
+	printk(KERN_DEBUG "FUNCTION: deputy_put_user64\n");
 	return deputy_put_userX(value, addr, 8);
 }
 EXPORT_SYMBOL(deputy_put_user64);
@@ -226,6 +228,7 @@
 long deputy_get_user(long *value, const void *addr, size_t size)
 {
 	BUG_ON(size > sizeof(long));
+	printk(KERN_DEBUG "FUNCTION: deputy_get_user\n");
 	return deputy_get_userX((u64 *) value, addr, size);
 }
 EXPORT_SYMBOL(deputy_get_user);
@@ -236,6 +239,7 @@
  **/
 long deputy_get_user64(s64 *value, const void *addr)
 {
+	printk(KERN_DEBUG "FUNCTION: deputy_get_user64\n");
 	return deputy_get_userX(value, addr, 8);
 }
 EXPORT_SYMBOL(deputy_get_user64);
@@ -308,7 +312,7 @@
 /**
  * remote_strnlen_from_user - strnlen from user for deputy
  **/
-static int remote_strnlen_user(task_t *p, struct kcom_pkt *pkt)
+/*static*/ int remote_strnlen_user(task_t *p, struct kcom_pkt *pkt)
 {
 	struct omp_usercopy_req u;
 	long *ret_ptr;
@@ -360,6 +364,7 @@
 	memcpy(&u, pkt->data, sizeof(struct omp_usercopy_req));
 	ret=kzalloc(sizeof(*ret), GFP_KERNEL);
 
+	printk("KERN_DEBUG remote_get_user; addr=%lu, len=%lu\n", u.addr, u.len);
 
 	switch (u.len) {
 	case 1: get_user(*ret, (u8 *) u.addr); break;
@@ -390,6 +395,9 @@
 		set_current_state(TASK_INTERRUPTIBLE);
 		list_for_each_entry_safe(pkt, pkt_next, &task->in_packs, list) {
 
+			printk(KERN_DEBUG "openMosix %s Checking pkt list for pid %u, type:0x%x\n"
+			      , __FUNCTION__, p->pid, pkt->type);
+
 			switch ( pkt->type & SYSCALL_MASK ) {
 
 				case DEP_STRNCPY_FROM_USER :
@@ -422,6 +430,7 @@
 					list_add_tail(&send_pkt->list, &task->out_packs);
 
 					if (kcomd_task) {
+						printk(KERN_DEBUG "Signaling kcomd\n");
 						send_sig(SIGHUP, kcomd_task, 0);
 					} else
 						printk("Unable to signal kcomd\n");
@@ -431,6 +440,7 @@
 					kmem_cache_free(kcom_pkt_cachep, pkt);
 					set_current_state(TASK_RUNNING);
 					schedule();
+					printk(KERN_DEBUG "leaving FUNCTION: remote_handle_user\n");
 					return ret;
 					break;
 
@@ -441,12 +451,14 @@
 		}
 
 		if (list_empty(&task->in_packs)) {
+			printk(KERN_DEBUG "remote_handle_user, sleeping\n");
 			schedule();
+			printk(KERN_DEBUG "remote_handle_user, waking\n");
 		}
 
 	}
 
-	printk( KERN_ERR "openMosix: %s is not supposed to end that way ! (%s:%n)\n"
+	printk( KERN_ERR "openMosix: %s is not supposed to end that way ! (%s:%d)\n"
 	      , __FUNCTION__, __FILE__, __LINE__);
 
 	return -1;
Index: linux/hpc/deputy.c
===================================================================
--- linux.orig/hpc/deputy.c	2006-09-20 18:04:59.000000000 +0200
+++ linux/hpc/deputy.c	2006-09-20 18:04:59.000000000 +0200
@@ -69,7 +69,7 @@
 		send_sig(SIGHUP,kcomd_task,0);
 
 	if (sizeof(struct omp_syscall_req) != pkt->len)
-		printk("ERROR in deputy_do_syscall.  data size of %d does not match expected %d\n", pkt->len, sizeof(struct omp_syscall_req));
+		printk("ERROR in deputy_do_syscall.  data size of %d does not match expected %lu\n", pkt->len, sizeof(struct omp_syscall_req));
 	memcpy(&s, pkt->data, pkt->len);
 	
 	OMDEBUG_SYS(1, "[deputy] receive syscall %d\n", s.n);
@@ -79,6 +79,7 @@
 	
 	kcom_send_with_ack(MIG_SYSCALL | PKT_NEW_MSG | SYSCALL_DONE | DEP_FLG, 0, NULL, r.ret, dest_ptr);
 
+	printk(KERN_DEBUG "[deputy] replied to syscall %d with %ld\n", s.n, r.ret);
 
 	return 0;
 }
@@ -94,6 +95,8 @@
 	task_t *child;
 	struct socket *childsock;
 
+	printk(KERN_DEBUG "openmosix %s\n", __FUNCTION__);
+
 	error = comm_recv(p->om.contact, &m, sizeof(m));
 	if (error < 0)
 		return -1;
@@ -356,6 +359,7 @@
 	int sz;
 	char *data = NULL;
 
+	printk(KERN_DEBUG "openmosix %s\n", __FUNCTION__);
 	error = comm_recv(p->om.contact, &m, sizeof(m));
 	if (error < 0)
 		goto error;
@@ -508,8 +512,11 @@
 
 			list_for_each_entry_safe(pkt, pkt_next, &mytsk->in_packs, list) {
 
+				printk(KERN_DEBUG "packet found.\n");
+
 				if ((pkt->type & MIG_MASK) == MIG_SYSCALL) {
 
+					printk(KERN_DEBUG "SYSCALL pkt found.\n");
 
 					error = deputy_do_syscall(p, pkt);
 					list_del(&pkt->list);
@@ -521,6 +528,9 @@
 		deputy_process_misc(current);
 		schedule();
 	}
+
+	printk(KERN_DEBUG "leaving FUNCTION: deputy_main_loop\n");
+	printk(KERN_DEBUG "Process %u has fully migrated home.\n", p->pid);
 }
 
 void exit_mm(task_t *);
Index: linux/hpc/kcomd.c
===================================================================
--- linux.orig/hpc/kcomd.c	2006-09-20 18:04:49.000000000 +0200
+++ linux/hpc/kcomd.c	2006-09-20 18:06:15.000000000 +0200
@@ -243,6 +243,17 @@
  	}
 	set_fs(oldfs);
 	do_gettimeofday(&stop);
+	if (stop.tv_sec==start.tv_sec)
+		printk(KERN_DEBUG"openMosix data_send: time %lu usecs\n", stop.tv_usec-start.tv_usec);
+	else
+		printk(KERN_DEBUG"openMosix data_send: time %lu usecs\n", ((stop.tv_sec*USEC_PER_SEC)+stop.tv_usec)-((start.tv_sec*USEC_PER_SEC)+start.tv_usec));
+
+	if ((send_pkt->type & MSG_MASK) ==PKT_NEW_MSG)
+		printk(KERN_DEBUG"FUNCTION: data_send: sent NEW msgid:%u type:0x%x len:%d\n", send_pkt->msgid, send_pkt->type, send_pkt->len);
+	else if ((send_pkt->type & MSG_MASK) ==PKT_ACK)
+		printk(KERN_DEBUG"FUNCTION: data_send: sent ACK msgid:%u type:0x%x len:%d\n", send_pkt->msgid, send_pkt->type, send_pkt->len);
+	else if ((send_pkt->type & MSG_MASK) ==PKT_RESP)
+		printk(KERN_DEBUG"FUNCTION: data_send: sent RESP msgid:%u type:0x%x len:%d\n", send_pkt->msgid, send_pkt->type, send_pkt->len);
 	return i;
 
 }
@@ -291,6 +302,7 @@
 			/* spin_lock(&tsk->spinlock); */
 			list_add_tail(&recv_kcom_pkt->list, &tsk->in_packs);
 			/* spin_unlock(&tsk->spinlock); */
+ 			printk("pkt (msgid: %u) added to remote pid %u in_packs list.\n", recv_kcom_pkt->msgid, tsk->rpid);
 		} else {
 			printk(KERN_ERR "unable to find remote pid %u\n", recv_kcom_pkt->rpid);
 			return -1;
@@ -300,6 +312,7 @@
 		sltsk=find_task_by_pid(recv_kcom_pkt->rpid);
 		/* read_unlock(&tasklist_lock); */
 		if (sltsk) {
+ 			printk("Waking up process %u\n", sltsk->pid);
 			wake_up_process(sltsk);
 		} else {
 			printk(KERN_ERR "Unable to find remote pid %u to wake up\n", recv_kcom_pkt->rpid);
@@ -312,6 +325,7 @@
 			/* spin_lock(&tsk->spinlock); */
 			list_add_tail(&recv_kcom_pkt->list, &tsk->in_packs);
 			/* spin_unlock(&tsk->spinlock); */
+			printk(KERN_DEBUG "pkt (msgid: %u) adding to home pid %u in_packs list.\n", recv_kcom_pkt->msgid, tsk->hpid);
 		} else {
 			printk(KERN_ERR "unable to find home pid %u\n", recv_kcom_pkt->hpid);
 			return -1;
@@ -320,6 +334,7 @@
 		sltsk=find_task_by_pid(recv_kcom_pkt->hpid);
 		/* read_unlock(&tasklist_lock); */
 		if (sltsk) {
+			printk(KERN_DEBUG "Waking up process %u\n", sltsk->pid);
 			wake_up_process(sltsk);
 		} else {
 			printk(KERN_ERR "Unable to find home pid %u to wake up\n", recv_kcom_pkt->hpid);
@@ -366,16 +381,25 @@
 		}
 	}
 
+ 	if ((recv_kcom_pkt->type & MSG_MASK) ==PKT_NEW_MSG)
+ 		printk("FUNCTION: pkt_read: received NEW msgid:%u type:0x%x len:%d rpid:%u hpid:%u\n", recv_kcom_pkt->msgid, recv_kcom_pkt->type, recv_kcom_pkt->len, recv_kcom_pkt->rpid, recv_kcom_pkt->hpid);
+ 	else if ((recv_kcom_pkt->type & MSG_MASK) ==PKT_ACK)
+ 		printk("FUNCTION: pkt_read: received ACK msgid:%u type:0x%x len:%d rpid:%u hpid:%u\n", recv_kcom_pkt->msgid, recv_kcom_pkt->type, recv_kcom_pkt->len, recv_kcom_pkt->rpid, recv_kcom_pkt->hpid);
+ 	else if ((recv_kcom_pkt->type & MSG_MASK) ==PKT_RESP)
+ 		printk("FUNCTION: pkt_read: received RESP msgid:%u type:0x%x len:%d rpid:%u hpid:%u\n", recv_kcom_pkt->msgid, recv_kcom_pkt->type, recv_kcom_pkt->len, recv_kcom_pkt->rpid, recv_kcom_pkt->hpid);
 
 	if ((recv_kcom_pkt->type & MSG_MASK) == PKT_NEW_MSG) {
 		switch (recv_kcom_pkt->type & MIG_MASK) {
 			case MIG_INIT:
+ 				printk("case MIG_INIT\n");
 				mig_do_receive_init(node, recv_kcom_pkt);
 				break;
 			case MIG_GO_HOME:
+ 				printk("case MIG_GO_HOME\n");
 				mig_do_receive_home(node, recv_kcom_pkt);
 				break;
 			case MIG_COME_HOME:
+ 				printk("case MIG_COME_HOME\n");
 				sltsk=find_task_by_pid(recv_kcom_pkt->rpid);
 				task_register_migration(sltsk);
 				break;
Index: linux/hpc/syscalls.c
===================================================================
--- linux.orig/hpc/syscalls.c	2006-09-20 18:04:32.000000000 +0200
+++ linux/hpc/syscalls.c	2006-09-20 18:04:59.000000000 +0200
@@ -27,12 +27,15 @@
 #include <hpc/syscalls.h>
 #include <hpc/debug.h>
 #include <hpc/hpc.h>
+#include <hpc/kcom.h>
+#include <hpc/prototype.h>
 
 /* generic multiplexer */
 asmlinkage long om_sys_local(struct pt_regs regs)
 {
 	long ret;
 
+	printk("[remote] local syscall %d\n", SYSNB());
 	OMDEBUG_SYS(1, "[remote] local syscall %d\n", SYSNB());
 
 	ret = arch_exec_syscall(SYSNB(), (syscall_parameter_t *) &regs);
@@ -41,17 +44,20 @@
 
 asmlinkage long om_sys_remote(struct pt_regs regs)
 {
+	printk("om_sys_gettid syscall\n");
 	return remote_do_syscall(SYSNB(), &regs);
 }
 
 /* specific remote syscalls */
 asmlinkage int om_sys_gettid(struct pt_regs regs)
 {
+	printk("om_sys_getpid syscall\n");
 	return current->om.pid;
 }
 
 asmlinkage int om_sys_getpid(struct pt_regs regs)
 {
+	printk("om_sys_execve syscall\n");
 	return current->om.tgid;
 }
 
Index: linux/hpc/migctrl.c
===================================================================
--- linux.orig/hpc/migctrl.c	2006-09-20 18:04:58.000000000 +0200
+++ linux/hpc/migctrl.c	2006-09-20 18:04:59.000000000 +0200
@@ -129,6 +129,7 @@
 	set_current_state(TASK_RUNNING);
 	schedule();
 
+	printk("leaving FUNCTION: task_local_bring\n");
 	return 0;
 failed:
 	OMBUG("failed\n");
openmosix-kcomd-migctl-to-kcomd.patch (text/x-patch, 3.5 KB)
Index: linux/hpc/migctrl.c
===================================================================
--- linux.orig/hpc/migctrl.c	2006-09-18 23:40:22.000000000 +0200
+++ linux/hpc/migctrl.c	2006-09-18 23:47:35.000000000 +0200
@@ -26,6 +26,9 @@
 #include <hpc/hpc.h>
 #include <hpc/debug.h>
 #include <hpc/service.h>
+#include <linux/in.h>
+#include <hpc/omtask.h>
+#include <hpc/kcom.h>
 #include <hpc/prototype.h>
 #include <hpc/mig.h>
 #include <hpc/protocol.h>
@@ -39,20 +42,12 @@
  **/
 int task_remote_expel(task_t *p)
 {
-	struct socket *link;
-
 	BUG_ON(!task_test_dflags(p, DREMOTE));
 
-	if (mig_send_hshake(p, p->om.contact, HSHAKE_MIG_REQUEST))
-		goto failed;
-
 	if (mig_do_send(p)) {
 		goto failed;
 	}
 
-	link = task_set_comm(p, NULL);
-	comm_close(link);
-
 	do_exit(SIGKILL);
 	return 0;
 failed:
@@ -69,19 +64,6 @@
  **/
 int task_remote_wait_expel(task_t *p)
 {
-	int error;
-	struct omp_req req;
-
-	comm_send_req(p->om.contact, REM_BRING_HOME);
-
-	error = comm_recv(p->om.contact, &req, sizeof(req));
-	if (error < 0)
-		return -1;
-	if (req.type != DEP_COMING_HOME) {
-		OMBUG("!DEP_COMING_HOME\n");
-		return -1;
-	}
-
 	return task_remote_expel(p);
 }
 
@@ -96,27 +78,12 @@
  **/
 static int task_local_send(task_t *p, struct sockaddr *whereto, int reason)
 {
-	struct socket *mlink;
 	int error = 0;
 
 	if (task_test_dflags(p, DDEPUTY))
 		return 0;
-	sockaddr_setup_port(whereto, REMOTE_DAEMON_PORT);
-	mlink = comm_setup_connect(whereto, 0);
-	if (!mlink) {
-		OMBUG("error\n");
-
-		error = -1;
-		goto failed;
-	}
-
-	task_set_comm(p, mlink);
 	task_set_dflags(p, DDEPUTY);
 
-	/* see if other part is with on this */
-	if (mig_send_hshake(p, mlink, HSHAKE_MIG_REQUEST))
-		goto failed;
-
 	if (mig_do_send(p)) {
 		error = -1;
 		goto failed;
@@ -128,8 +95,6 @@
 failed:
 	OMBUG("failed\n");
 	task_clear_dflags(p, DDEPUTY);
-	if (mlink)
-		comm_close(mlink);
 	return error;
 }
 
@@ -146,7 +111,6 @@
 static int task_local_bring(task_t *p, int reason)
 {
 	int error;
-	struct socket *link;
 
 	if (!task_test_dflags(p, DDEPUTY))
 		return 0;
@@ -155,21 +119,15 @@
 		goto failed;
 	}
 
-	/* send remote request */
-	comm_send_req(p->om.contact, DEP_COMING_HOME);
-
-	/* see if other part is with on this */
-	if (mig_recv_hshake(p->om.contact))
-		goto failed;
-
 	/* receive the process back */
 	error = mig_do_receive(p);
 	if (error)
 		goto failed;
 
 	task_clear_dflags(p, DDEPUTY);
-	link = task_set_comm(p, NULL);
-	comm_close(link);
+
+	set_current_state(TASK_RUNNING);
+	schedule();
 
 	return 0;
 failed:
@@ -206,21 +164,29 @@
                                struct sockaddr * whereto,
                                int reason)
 {
-	int error;
 
 	task_set_dflags(p, DPASSING);
 
-	error = (task_test_dflags(p, DREMOTE))
-		? (whereto)
-			? task_move_remote2remote(p, whereto, reason)
-			: task_remote_wait_expel(p)
-		: (whereto)
-			? task_local_send(p, whereto, reason)
-			: task_local_bring(p, reason);
+	/*
+	 * Ok, if DREMOTE flag set, then this is a remote process
+	 * if DDEPUTY is set, then this is a deputy
+	 * if neither is set, then this is a home process going out.
+	 * FIXME:  remote to remote?
+	 */
+
+	if (task_test_dflags(p, DREMOTE))
+		task_remote_wait_expel(p);
+	else if (task_test_dflags(p, DDEPUTY))
+		task_local_bring(p, reason);
+	else
+		task_local_send(p, whereto, reason);	/*
+							 * if neither flag is set then
+							 * home process going out
+							 */
 
 	task_clear_dflags(p, DPASSING);
 
-	return error;
+	return 0;
 }
 
 int task_move_to_node(struct task_struct *p, struct sockaddr * whereto,
openmosix-kcomd-migrecv-to-kcomd.patch (text/x-patch, 21.4 KB)
Index: linux/hpc/migrecv.c
===================================================================
--- linux.orig/hpc/migrecv.c	2006-09-20 17:06:59.000000000 +0200
+++ linux/hpc/migrecv.c	2006-09-20 17:53:11.000000000 +0200
@@ -25,6 +25,7 @@
 #include <linux/stddef.h>
 #include <linux/highmem.h>
 #include <linux/personality.h>
+#include <linux/syscalls.h>
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
 #include <hpc/comm.h>
@@ -34,10 +35,12 @@
 #include <hpc/mig.h>
 #include <hpc/debug.h>
 #include <hpc/protocol.h>
+#include <hpc/kcom.h>
 #include <hpc/prototype.h>
 #include <hpc/version.h>
 #include <hpc/arch.h>
 
+#include <linux/inet.h>  /* in_aton*/
 /* handshake with the remote part */
 int mig_recv_hshake(struct socket *mlink)
 {
@@ -66,110 +69,316 @@
 	return 0;
 }
 
+/**
+ * mig_do_receive_home
+ *
+ * Description:
+ *    Called by kcomd when it receives a MIG_GO_HOME pkt.
+ *    Task_register_migration is called to inform the process that the
+ *    remote process is coming home.
+ **/
+int mig_do_receive_home(struct kcom_node *node, struct kcom_pkt *recv_kcom_pkt)
+{
+	struct kcom_task *recv_tsk;
+	struct kcom_pkt *send_pkt;
+	task_t *sltsk;
+
+	printk("FUNCTION: mig_do_receive_home\n");
+
+	if ((recv_kcom_pkt->type & MSG_MASK)==PKT_NEW_MSG) {
+		printk("Received MIG_GO_HOME NEW_MSG packet.\n");
+
+		recv_tsk=kcom_task_find(recv_kcom_pkt->hpid);
+		if (!recv_tsk) {
+			printk("Unable to find home pid %u\n", recv_kcom_pkt->hpid);
+			return -1;
+		}
+
+		send_pkt=kcom_pkt_create(0, MIG_GO_HOME | PKT_ACK | DEP_FLG, 0,  NULL);
+
+		send_pkt->msgid=recv_kcom_pkt->msgid; /* responses have same msg id as pkt they are responding to.*/
+		send_pkt->hpid=recv_kcom_pkt->hpid;
+		send_pkt->rpid=recv_kcom_pkt->rpid;;
+		send_pkt->resp=recv_kcom_pkt->resp;
+		/* spin_lock(&recv_tsk->spinlock);*/
+		list_add_tail(&send_pkt->list, &recv_tsk->out_packs);
+		/* spin_unlock(&recv_tsk->spinlock);*/
+
+		/* Ok, tell task migration is coming*/
+		/* read_lock(&tasklist_lock);*/
+		sltsk=find_task_by_pid(recv_kcom_pkt->hpid); /* only home node will receive MIG_GO_HOME NEW_MSG*/
+		/* read_unlock(&tasklist_lock);*/
+		if (sltsk) {
+			printk("Registering task migration\n");
+			task_register_migration(sltsk);
+		} else {
+			printk("Failed to register task migration\n");
+			return -1;
+		}
+
+
+	} else {
+		printk("Received MIG_GO_HOME PKT_ACK packet.\n");
+
+		recv_tsk=kcom_task_find(recv_kcom_pkt->rpid);
+		if (!recv_tsk) {
+			printk("Unable to find remote pid %u\n", recv_kcom_pkt->rpid);
+			return -1;
+		}
+
+		/* spin_lock(&recv_tsk->spinlock);*/
+		list_add_tail(&recv_kcom_pkt->list, &recv_tsk->in_packs);
+		/* spin_unlock(&recv_tsk->spinlock);*/
+		sltsk=find_task_by_pid(recv_kcom_pkt->rpid); /* only remote node will receive MIG_GO_HOME ack*/
+		if (sltsk) {
+			printk("Waking up process %u\n", sltsk->pid);
+			wake_up_process(sltsk);
+		} else {
+			printk("Unable to wake up process %u\n", recv_kcom_pkt->rpid);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mig_do_receive_home);
+
+/**
+ * mig_do_receive_init
+ *
+ * Description:
+ *    Called by kcomd when it receives a MIG_INIT pkt.
+ *    Creates a new process and sets up the associated task.
+ **/
+int mig_do_receive_init(struct kcom_node *node, struct kcom_pkt *recv_kcom_pkt)
+{
+	struct kcom_task *send_tsk;
+	struct kcom_pkt *send_pkt;
+
+	pid_t rpid;
+	struct sockaddr_in *saddr;
+	const unsigned int LO_IP=in_aton("127.0.0.1");
+	printk("Received MIG_INIT packet.\n");
+
+	if ((recv_kcom_pkt->type & MSG_MASK)==PKT_NEW_MSG) {	 /* incoming process*/
+		printk("Creating new process.\n");
+		rpid=0;
+
+		send_pkt=kcom_pkt_create(0, MIG_INIT | PKT_ACK | REM_FLG, 0,  NULL);
+
+		if (!send_pkt) {
+			printk("ERROR creating pkt in mig_do_receive_init\n");
+			return -1;
+		}
+		/* responses have same msg id as pkt they are responding to.*/
+		send_pkt->msgid=recv_kcom_pkt->msgid;
+
+		send_pkt->hpid=recv_kcom_pkt->hpid;
+		send_pkt->resp=recv_kcom_pkt->resp;
+
+		/* spin_lock();*/
+		saddr=(struct sockaddr_in *)&node->addr;
+		if (saddr->sin_addr.s_addr==LO_IP) { /* this allows loopback migration to work.*/
+			printk("Loopback migration.\n"); /* both home and remote processes use same task.  better idea?*/
+			send_tsk=kcom_home_task_find(recv_kcom_pkt->hpid);
+		} else {
+			send_tsk=kcom_task_create(node, 0);
+			/* spin_unlock();*/
+			if (!send_tsk) {
+				printk("ERROR: creating new kcom_task.\n");
+				return -1;
+			}
+			send_tsk->hpid=recv_kcom_pkt->hpid;
+		}
+		/* Delete init packet before starting new process.*/
+		/* spin_lock(&send_tsk->spinlock);*/
+		list_del(&recv_kcom_pkt->list);
+		/* spin_unlock(&send_tsk->spinlock);*/
+
+		/* send_pkt->rpid=0; // set this to 0 or if same process migrates second time here, it'll keep old rpid*/
+		user_thread(mig_handle_migration, &rpid, 0);
+		while (rpid==0) {
+			schedule_timeout_interruptible(HZ/1000);
+		}
+
+		if (rpid < 0) {
+			printk("Error creating new process.\n");
+			send_pkt->type=MIG_INIT | PKT_NACK | REM_FLG;
+
+			/* spin_lock(&send_tsk->spinlock);*/
+			list_add_tail(&send_pkt->list, &send_tsk->out_packs);
+			/* spin_unlock(&send_tsk->spinlock);*/
+			return -1;
+		} else
+			printk("New process: %u\n", rpid);
+
+		send_pkt->rpid=rpid;
+
+		/* spin_lock(&send_tsk->spinlock);*/
+		list_add_tail(&send_pkt->list, &send_tsk->out_packs);
+		/* spin_unlock(&send_tsk->spinlock);*/
+
+		send_tsk->rpid=rpid;
+
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mig_do_receive_init);
+
+
 /*****************************************************************************/
 
 /**
- * mig_do_receive_mig_mm - Receive some parameters for a mm
+ * mig_do_receive_mm
+ *
+ * Description:
+ *    Receives the process mmap info.
  **/
-static void mig_do_receive_mm(task_t *p, struct omp_mig_mm *s)
+KCOMD_NSTATIC void mig_do_receive_mm(task_t *p, struct kcom_pkt *pkt)
 {
+
 	OMDEBUG_MIG(2, "MIG_MM\n");
-	/* copy all mm's parameter from start_code to env_end */
-	memcpy(&p->mm->start_code, s, sizeof(*s));
+	printk("FUNCTION: mig_do_receive_mm\n");
+
+	down_write(&p->mm->mmap_sem);
+	memcpy(&p->mm->start_code, pkt->data, pkt->len);
+	p->mm->exec_vm=0; /* MSD debug*/
+	up_write(&p->mm->mmap_sem);
+
+	kcom_send_ack(p, pkt);
+
+	printk("leaving FUNCTION: mig_do_receive_mm\n");
+
 }
+EXPORT_SYMBOL_GPL(mig_do_receive_mm);
 
 /**
- * mig_do_receive_mm_area - Set up an mmap
+ * mig_do_receive_vma
+ *
+ * Description:
+ *    Receives the process vma info.
  **/
-static int mig_do_receive_vma(task_t *p, struct omp_mig_vma *a)
+KCOMD_NSTATIC int mig_do_receive_vma(task_t *p, struct kcom_pkt *pkt)
 {
+	struct omp_mig_vma *a;
 	unsigned long result, prot, flags;
 	struct file *file = NULL;
 	extern asmlinkage long sys_madvise(unsigned long, size_t, int);
 
+
+	printk("FUNCTION: mig_do_receive_vma\n");
+
+	a = (struct omp_mig_vma *)pkt->data;
+
 	OMDEBUG_MIG(2, "MIG_VMA [%lx, %ld]\n", a->vm_start, a->vm_size);
 
-	/* FIXME : Temporary disabled */
-	if (0 && a->vm_file) {
-		file = (task_test_dflags(p, DREMOTE))
-			? task_rfiles_get(p, a->vm_file, -1, a->i_size)
-			: a->vm_file;
-	}
+		/* FIXME : Temporary disabled */
+		if (0 && a->vm_file) {
+			file = (task_test_dflags(p, DREMOTE))
+				? task_rfiles_get(p, a->vm_file, -1, a->i_size)
+				: a->vm_file;
+		}
 
-	/* unconvert prot+flags: */
-	flags = MAP_FIXED | MAP_PRIVATE;
-	prot = 0;
-	if (a->vm_flags & VM_GROWSDOWN)
-		flags |= MAP_GROWSDOWN;
-	if (a->vm_flags & VM_DENYWRITE)
-		flags |= MAP_DENYWRITE;
-	if (a->vm_flags & VM_EXECUTABLE)
-		flags |= MAP_EXECUTABLE;
-
-	/* copy VM_(READ|WRITE|EXEC) bits to prot */
-	prot |= (a->vm_flags & (VM_READ | VM_WRITE | VM_EXEC));
-
-	/* mmap stuff */
-	result = do_mmap_pgoff(file, a->vm_start, a->vm_size, prot,
-						flags, a->vm_pgoff);
-	if (IS_ERR((const void *) result))
-		return PTR_ERR((const void *) result);
-
-	if (a->vm_flags & VM_READHINTMASK) {
-		int behavior = (a->vm_flags & VM_SEQ_READ)
-				? MADV_RANDOM
-				: MADV_SEQUENTIAL;
-		sys_madvise(a->vm_start, a->vm_size, behavior);
-	}
+		/* unconvert prot+flags: */
+		flags = MAP_FIXED | MAP_PRIVATE;
+		prot = 0;
+		if (a->vm_flags & VM_GROWSDOWN)
+			flags |= MAP_GROWSDOWN;
+		if (a->vm_flags & VM_DENYWRITE)
+			flags |= MAP_DENYWRITE;
+		if (a->vm_flags & VM_EXECUTABLE)
+			flags |= MAP_EXECUTABLE;
+
+	/* VM_GROWSDOWN =  0x0100*/
+	/* VM_DENYWRITE =  0x0800*/
+	/* VM_EXECUTABLE = 0x1000*/
+
+	/* MAP_GROWSDOWN =  0x0100*/
+	/* MAP_DENYWRITE =  0x0800*/
+	/* MAP_EXECUTABLE = 0x1000*/
+
+
+	/* flags=a->vm_flags;*/
+
+		/* copy VM_(READ|WRITE|EXEC) bits to prot */
+		/* prot |= (a->vm_flags & (VM_READ | VM_WRITE | VM_EXEC));*/
+		prot = (VM_READ | VM_WRITE | VM_EXEC);
+		/* VM_READ =  0x1*/
+		/* VM_WRITE = 0x2*/
+		/* VM_EXEC =  0x4*/
+
+		/* mmap stuff */
+		down_write(&p->mm->mmap_sem);
+		result = do_mmap_pgoff(file, a->vm_start, a->vm_size, prot,
+							flags, a->vm_pgoff);
+		up_write(&p->mm->mmap_sem);
+
+		if (IS_ERR((const void *) result))
+			return PTR_ERR((const void *) result);
+
+		if (a->vm_flags & VM_READHINTMASK) {
+			int behavior = (a->vm_flags & VM_SEQ_READ)
+					? MADV_RANDOM
+					: MADV_SEQUENTIAL;
+			result=sys_madvise(a->vm_start, a->vm_size, behavior);
+			if (result)
+				kcom_send_nack(p, pkt);
+				return result;
+		}
+
+
+	kcom_send_ack(p, pkt);
+
+	printk("leaving FUNCTION: mig_do_receive_vma\n");
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mig_do_receive_vma);
 
 
 /**
- * mig_do_receive_page - Receive one page
+ * mig_do_receive_page
+ *
+ * Description:
+ *    Receives one process memory page.
+ *    FIXME:   remote node segfaults on system calls because
+ *    of a bug in this function.   HELP!!!
  **/
-static int mig_do_receive_page(task_t *p, unsigned long addr)
+KCOMD_NSTATIC int mig_do_receive_page(task_t *p, struct kcom_pkt *pkt)
 {
 	struct mm_struct *mm = p->mm;
 	struct vm_area_struct *vma;
 	struct page *recv_page = NULL;
-	void *kmpage; /* kmapped page */
-	int error;
+	unsigned long addr;
+	void *kmpage;
 	pgd_t * pgd;
 	pud_t * pud;
 	pmd_t * pmd;
 	pte_t * pte;
 
-	OMDEBUG_MIG(3, "MIG_PAGE [%lx]\n", addr);
+	/* FIXME:   another way?*/
+	/* Must be done from process context.*/
+
+	/* recv_page = alloc_page(GFP_HIGHUSER);*/
+	/* kfree(pkt->data);*/
 
+
+	addr=pkt->addr;
 	vma = find_vma(mm, addr);
 	if (!vma) {
 		OMBUG("vma not found (addr: %p)\n", (void *) addr);
+		kcom_send_nack(p, pkt);
 		return -1;
 	}
-
-	/* check if enough memory */
-
-	/* alloc page */
-	recv_page = alloc_page(GFP_HIGHUSER);
-	if (!recv_page) {
-		OMBUG("unable to allocate page\n");
-		return -ENOMEM;
-	}
-
-	kmpage = kmap(recv_page);
-
-	/* receive the data into the page */
-	error = comm_recv(p->om.contact, kmpage, PAGE_SIZE);
-
+	recv_page=alloc_zeroed_user_highpage(vma, addr);
+	kmpage=kmap(recv_page);
+	memcpy(kmpage, pkt->data, pkt->len);
 	kunmap(recv_page);
-	if (error < 0) {
-		OMBUG("failed to receive data\n");
-		goto out;
-	}
+	/**/
 
 	/* add the page at correct place */
+
 	pgd = pgd_offset(mm, addr);
+
 	pud = pud_alloc(mm, pgd, addr);
 	if (!pud)
 		goto out;
@@ -187,30 +396,69 @@
 	page_dup_rmap(recv_page);
 	inc_mm_counter(mm, file_rss);
 
+
+/*
+	down_write(&mm->mmap_sem);
+	install_arg_page(vma, recv_page, pkt->addr);
+	up_write(&mm->mmap_sem);
+*/
+	/* make_pages_present(pkt->addr, pkt->addr+PAGE_SIZE); // NOPE*/
+
+	kcom_send_ack(p, pkt);
+
 	return 0;
+
 out:
+	printk("receive page failed at addr %p\n", (void *) addr);
 	OMBUG("receive page failed at addr %p\n", (void *) addr);
 	__free_page(recv_page);
 	return -1;
+
 }
 
 /**
- * mig_do_receive_fp - Receive floating points registers
+ * mig_do_receive_fp
  * @p:		task
- * @fpr:	floating point registers
+ * @pkt: ->data: floating point registers.
+ *
+ * Description:
+ *    Receive floating points registers
  **/
-static void mig_do_receive_fp(task_t *p, struct omp_mig_fp *fp)
+KCOMD_NSTATIC int mig_do_receive_fp(task_t *p, struct kcom_pkt *pkt)
 {
+	struct omp_mig_fp *fp;
+
+	printk("FUNCTION: mig_do_receive_fp\n");
+	fp=(void *)pkt->data;
+
 	OMDEBUG_MIG(2, "MIG_FP\n");
 	set_used_math();
 	arch_mig_receive_fp(p, fp);
+
+	kcom_send_ack(p, pkt);
+
+	printk("leaving FUNCTION: mig_do_receive_fp\n");
+
+	return 0;
 }
 
 /**
- * mig_do_receive_misc - Receive normal registers, limits
+ * mig_do_receive_misc
+ **/
+/**
+ * mig_do_receive_proc_context
+ * @p:		task
+ * @pkt:		->data: normal registers, limits.
+ *
+ * Description:
+ *    Receive normal registers, limits
  **/
-static void mig_do_receive_proc_context(task_t *p, struct omp_mig_task *m)
+KCOMD_NSTATIC int mig_do_receive_proc_context(task_t *p, struct kcom_pkt *pkt)
 {
+	struct omp_mig_task *m;
+
+	m=(struct omp_mig_task *)pkt->data;
+
 	OMDEBUG_MIG(1, "MIG_TASK\n");
 	/* arch specific proc receive context */
 	arch_mig_receive_proc_context(p, m);
@@ -220,15 +468,12 @@
 	p->om.tgid = m->tgid;
 
 	/* copy credentials */
-	p->uid = m->uid;
-	p->euid = m->euid;
-	p->suid = m->suid;
-	p->fsuid = m->fsuid;
-
-	p->gid = m->gid;
-	p->egid = m->egid;
-	p->sgid = m->sgid;
-	p->fsgid = m->fsgid;
+	sys_setuid(m->uid);
+	sys_setresuid(m->uid,m->euid,m->suid);
+	sys_setfsuid(m->fsuid);
+	sys_setgid(m->gid);
+	sys_setresgid(m->gid, m->egid, m->sgid);
+	sys_setfsgid(m->fsgid);
 
 	/* signals stuffs */
 	p->blocked = m->blocked;
@@ -238,177 +483,196 @@
 	memcpy(p->sighand->action, m->sighand, sizeof(struct k_sigaction)
 								* _NSIG);
 
-	/* FIXME we don't trust the other node anyway so copy rlimit from node[nr] */
-
-	memcpy(p->comm, m->comm, sizeof(m->comm));
+  	/* FIXME we don't trust the other node anyway so copy rlimit from node[nr] */
 
-	p->personality = m->personality;
+  	memcpy(p->comm, m->comm, sizeof(m->comm));
+	/* p->personality = m->personality;*/
+	set_personality(m->personality);
 	arch_pick_mmap_layout(p->mm);
+
+	kcom_send_ack(p, pkt);
+	printk("leaving FUNCTION: mig_do_receive_proc_context\n");
+
+	return 0;
 }
 
 /**
- * mig_do_receive - Receive all process stuff (mm, pages, fpr, ..)
+ * mig_do_receive
+ * @p:		task
+ *
+ * Description:
+ *    Main loop to receive all process stuff (mm, pages, fpr, ..)
  **/
 int mig_do_receive(task_t *p)
 {
-	int error;
-	unsigned int got_not_coming = 0;
-	unsigned long data;
-	struct omp_req req;
+	struct kcom_task *mytsk=NULL;
+	struct kcom_pkt *pkt, *pkt_next;
+	int ret;
 
-	data = __get_free_page(GFP_KERNEL);
-	if (!data)
-		goto fail;
 
 	task_set_dflags(p, DINCOMING);
-	clear_used_math();
+	/* clear_used_math();*/
 
-	while (1) {
-		error = comm_recv(p->om.contact, &req, sizeof(req));
-		if (error < 0)
-			goto fail;
-
-		BUG_ON(req.dlen > PAGE_SIZE);
-		error = comm_recv(p->om.contact, (void *) data, req.dlen);
-		if (error < 0)
-			goto fail;
-
-		switch (req.type) {
-		case MIG_MM:
-			mig_do_receive_mm(p, (struct omp_mig_mm *) data);
-			break;
-		case MIG_VMA:
-			if (mig_do_receive_vma(p, (struct omp_mig_vma *) data))
-				goto fail;
-			break;
-		case MIG_PAGE:
-			if (mig_do_receive_page(p, *((unsigned long *) data)))
-				goto fail;
-			break;
-		case MIG_FP:
-			mig_do_receive_fp(p, (struct omp_mig_fp *) data);
-			break;
-		case MIG_ARCH:
-			if (arch_mig_receive_specific(p, (struct omp_mig_arch *) data))
-				goto fail;
-			break;
-		/* this is the last thing we do in the chain of receiving,
-		 * so return 0 after we're done */
-		case MIG_TASK:
-			mig_do_receive_proc_context(p, (struct omp_mig_task *) data);
-			comm_send_req(p->om.contact, MIG_TASK | REPLY);
-			task_clear_dflags(p, DINCOMING);
-
-			flush_tlb_mm(p->mm); /* for all the new pages */
-			return 0;
-		case MIG_ABORT:
-			printk("mig_do_recv(): got MIG_ABORT\n");
-			got_not_coming = 1;
-			goto fail;
-		default:
-			printk("mig_do_recv(): got default\n");
-			goto fail;
-		}
+	/* Wait for kcomd to set up the kcom_task struct*/
+	while (mytsk==NULL) {
+		schedule_timeout_interruptible(HZ/1000);
+	/*spin_lock();*/
+		mytsk=kcom_task_find(p->pid);
+	/*spin_unlock();*/
 	}
-fail:
-	task_clear_dflags(p, DINCOMING);
-	free_page(data);
 
-	OMBUG("failed\n");
-	return -1;
-}
-
-static NORET_TYPE int mig_handle_migration(void *ptr)
-{
-	task_t *p = current;
-	/* link against the other end */
-	struct socket *link = (struct socket *) ptr;
-	int error;
+	/* Initialize remote proc's whereto*/
+	if (task_test_dflags(p, DREMOTE)) {
+		memcpy(p->om.whereto, &mytsk->node->addr, sizeof(mytsk->node->addr));
+		printk("Setting mytsk->rpid (currently: %u) = p->pid (%u)\n", mytsk->rpid, p->pid);
+	}
 
-	OM_VERBOSE_MIG("[OM] receiving new process\n");
+	set_current_state(TASK_INTERRUPTIBLE);
+	/* spin_lock(&mytsk->spinlock);*/
+	while (1) {
 
-	task_set_comm(p, link);
+		if (!list_empty(&mytsk->in_packs))
+			list_for_each_entry_safe(pkt, pkt_next, &mytsk->in_packs, list) {
+				printk("mig_do_receive:  msgid=%u\n", pkt->msgid);
+
+				switch (pkt->type & MIG_MASK) {
+
+					case MIG_MM:
+						mig_do_receive_mm(p, pkt);
+						list_del(&pkt->list);
+						kmem_cache_free(kcom_pkt_cachep, pkt);
+						break;
+
+					case MIG_VMA:
+						ret=mig_do_receive_vma(p, pkt);
+						list_del(&pkt->list);
+						kmem_cache_free(kcom_pkt_cachep, pkt);
+						if (ret)
+							return ret;
+						break;
+
+					case MIG_PAGE:
+						ret=mig_do_receive_page(p, pkt);
+						list_del(&pkt->list);
+						kmem_cache_free(kcom_pkt_cachep, pkt);
+						if (ret)
+							return ret;
+						break;
+
+					case MIG_FP:
+						ret=mig_do_receive_fp(p, pkt);
+						list_del(&pkt->list);
+						kmem_cache_free(kcom_pkt_cachep, pkt);
+						if (ret)
+							return ret;
+						break;
+
+					/* this is the last thing we do in the chain of receiving,
+					 * so return 0 after we're done */
+					case MIG_TASK:
+						ret=mig_do_receive_proc_context(p, pkt);
+
+						task_clear_dflags(p, DINCOMING);
+						flush_tlb_mm(p->mm); /* for all the new pages */
+
+						list_del(&pkt->list);
+						kmem_cache_free(kcom_pkt_cachep, pkt);
+						/* spin_unlock(&mytsk->spinlock);*/
+
+						if (ret)
+							return ret;
+						set_current_state(TASK_RUNNING);
+						return 0;
+
+					default:
+						printk("[pid: %u] Unknown packet type 0x%x received.\n", p->pid, pkt->type);
+						break;
 
-	error = obtain_mm(p);
-	if (error)
-		goto fail;
-	if (mig_recv_hshake(link))
-		goto fail;
+				}
 
-	error = mig_do_receive(p);
+			}
 
-	if (error)
-		goto fail;
+	/* spin_unlock(&mytsk->spinlock);*/
+	printk("process %u going to sleep.\n", p->pid);
+	schedule();
+	printk("process %u waking up.\n", p->pid);
+	set_current_state(TASK_INTERRUPTIBLE);
+	/* spin_lock(&mytsk->spinlock);*/
+	}
+	/* spin_unlock(&mytsk->spinlock);*/
 
-	OM_VERBOSE_MIG("[OM] starting process(%d)\n", p->pid);
-	reparent_to_init();
-	arch_kickstart(p);
-	/*NOTREACHED*/
 
-fail:
-	OMBUG("failed\n");
-	do_exit(SIGKILL);
-	/*NOTREACHED*/
 }
 
 /**
- * openmosix_mig_daemon - openMosix migration daemon
- * @nothing:	unused
+ * mig_handle_migration
+ * @*pid:		address to pid used in mig_do_receive_init.
+ *             mig_do_receive_init waits until pid!=0, before setting
+ *             up task and sending ack back to home node.
  *
  * Description:
- * 	start the migration daemon.
- * 	wait for communication, and if it is a remote request
- * 	then start a user-thread with the new program to run
+ *    This is the newly created process.
  **/
-int openmosix_mig_daemon(void *nothing)
+KCOMD_NSTATIC NORET_TYPE int mig_handle_migration(pid_t *pid)
 {
 	task_t *p = current;
 	int error;
-	struct socket *mlink;
-	struct sockaddr saddr;
 
-	om_daemonize("omkmigd", 0);
+	/* reparent before anything real happens to the process so nothing gets*/
+	/* re-initialized.*/
+	reparent_to_init();
+	error = obtain_mm(p);
+	if (error)
+		goto fail;
+	/* clear_used_math(); // not really sure what this does?*/
 
-	task_set_dflags(p, DREMOTEDAEMON);
+	task_set_dflags(p, DREMOTE);
+	*pid=p->pid;
 
-	set_our_addr(AF_INET, &saddr, REMOTE_DAEMON_PORT);
+	OM_VERBOSE_MIG("[OM] receiving new process\n");
 
-restart:
-	if (!p->om.contact) {
-		p->om.contact = comm_setup_listen(&saddr);
-		if (!p->om.contact) {
-			printk(KERN_WARNING
-				"omkmigd: failed to open mig service\n");
-			flush_signals(p);
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(HZ);
-			goto restart;
-		}
-	}
+	error = mig_do_receive(p);
+	if (error)
+		goto fail;
 
-	/* migration daemon loop */
-	while (1)
-	{
-		error = comm_accept(p->om.contact, &mlink, &saddr, 0UL);
-		if (error == -EINTR || error == -ERESTART || error == -EAGAIN
-		   || error == -ERESTARTSYS)
-		{
-			if (sigismember(&(p->pending.signal), SIGCHLD)) {
-				printk("omigd: SIGCHLD caught\n");
-			}
-			flush_signals(p);
-			continue;
-		} else if (error) {
-			OMBUG("failed to accept\n");
-			comm_close(mlink);
-			goto restart;
-		}
+	/* clear_tsk_thread_flag(p, TIF_SIGPENDING); // Added by MSD ???*/
+	/* init_sigpending(&p->pending); // Added by MSD ????*/
+
+	/* OM_VERBOSE_MIG("[OM] starting process(%d)\n", p->pid);*/
+	set_current_state(TASK_RUNNING);
+	/* set_current_state(TASK_INTERRUPTIBLE);*/
+	schedule();
+	if (task_test_dflags(p, DREMOTE))
+	printk("[OM] starting remote process(%d)\n", p->pid);
+	else
+	printk("[OM] starting local process(%d)\n", p->pid);
+
+	#if 0
+	flush_signals(p); //MSDMSD
+	reparent_to_init(); //MSD
+	cap_clear(p->cap_permitted);
+	cap_clear(p->cap_effective);
+	cap_task_reparent_to_init(p);
+	p->cap_permitted=0;
+	p->cap_effective=0;
+	#endif
 
-		error = user_thread(mig_handle_migration, (void *) mlink, 0);
-		if (error < 0)
-			comm_close(mlink);
+	clear_thread_flag(TIF_SIGPENDING);
+	/* flush_thread();*/
+	arch_kickstart(p);
+	/*NOTREACHED*/
+
+	printk("process %u, waking up. YOU SHOULD NOT SEE THIS!!!!!\n", p->pid);
+	while (1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
 	}
 
-	/* Not reached, just to prevent warning on recent gcc: */
-	return 0;
+
+fail:
+	printk("mig_handle_migration failed with %d\n", error);
+	OMBUG("failed\n");
+	do_exit(SIGKILL);
+	/*NOTREACHED*/
 }
+
openmosix-kcomd-migsend-to-kcomd.patch (text/x-patch, 5.4 KB)
Index: linux/hpc/migsend.c
===================================================================
--- linux.orig/hpc/migsend.c	2006-09-20 17:07:00.000000000 +0200
+++ linux/hpc/migsend.c	2006-09-20 18:00:28.000000000 +0200
@@ -31,6 +31,8 @@
 #include <hpc/hpc.h>
 #include <hpc/debug.h>
 #include <hpc/service.h>
+#include <linux/in.h>
+#include <hpc/kcom.h>
 #include <hpc/prototype.h>
 #include <hpc/mig.h>
 #include <hpc/protocol.h>
@@ -63,7 +65,7 @@
 		/* it's a no go ... */
 		OMBUG("no go\n");
 		return -1;
-	}			
+	}
 
 	return 0;
 }
@@ -77,12 +79,20 @@
 static int mig_send_fp(task_t *p)
 {
 	struct omp_mig_fp m;
+	struct sockaddr_in *dest_ptr;
 
-	if (!used_math())
+	dest_ptr=(void *)p->om.whereto;
+	if (!used_math()) {
+		printk("leaving FUNCTION: mig_send_fp, !used_math\n");
 		return 0;
+	}
 
 	arch_mig_send_fp(p, &m);
-	return comm_send_hd(p->om.contact, MIG_FP, &m, sizeof(m));
+	if (task_test_dflags(p, DREMOTE))
+		kcom_send_with_ack(MIG_FP | REM_FLG, sizeof(m), (char *)&m, 0, dest_ptr);
+	else
+		kcom_send_with_ack(MIG_FP | DEP_FLG, sizeof(m), (char *)&m, 0, dest_ptr);
+	return 0;
 }
 
 
@@ -95,11 +105,18 @@
  **/
 static int mig_send_mm(task_t *p)
 {
-	struct omp_mig_mm s;
+	struct sockaddr_in *dest_ptr;
+	int ret;
 
-	memcpy(&s, &p->mm->start_code, sizeof(s));
+	dest_ptr=(void *)p->om.whereto;
+	printk("FUNCTION: mig_send_mm.\n");
+	if (task_test_dflags(p, DREMOTE))
+		ret=kcom_send_with_ack(MIG_MM | REM_FLG, sizeof(struct omp_mig_mm), (char *)&p->mm->start_code, 0, dest_ptr);
+	else
+		ret=kcom_send_with_ack(MIG_MM | DEP_FLG, sizeof(struct omp_mig_mm), (char *)&p->mm->start_code, 0, dest_ptr);
+	printk("leaving FUNCTION: mig_send_mm\n");
 
-	return comm_send_hd(p->om.contact, MIG_MM, &s, sizeof(s));
+	return ret;
 }
 
 /**
@@ -141,23 +158,29 @@
 	struct vm_area_struct *vma;
 	struct omp_mig_vma m;
 	int ret = 0;
+	struct sockaddr_in *dest_ptr;
 
+	dest_ptr=(void *)p->om.whereto;
 	for (vma = p->mm->mmap; vma; vma = vma->vm_next)
 	{
 		m.vm_start= vma->vm_start;
 		m.vm_size = vma->vm_end - vma->vm_start;
 		m.vm_flags = vma->vm_flags;
 		m.vm_file = vma->vm_file;
-		m.vm_pgoff = 0;
+		// m.vm_pgoff = 0;
+		m.vm_pgoff = vma->vm_pgoff;
 		if (vma->vm_file)
 			mig_send_vma_file(p, vma, &m);
 
-		ret = comm_send_hd(p->om.contact, MIG_VMA, &m, sizeof(m));
-		if (ret < 0) {
-			OMBUG("send vma failed\n");
-			break;
+		if (task_test_dflags(p, DREMOTE))
+			ret=kcom_send_with_ack(MIG_VMA | REM_FLG, sizeof(m), (char *)&m, 0, dest_ptr);
+		else
+			ret=kcom_send_with_ack(MIG_VMA | DEP_FLG, sizeof(m), (char *)&m, 0, dest_ptr);
+
+		if (ret != 0) {
+			printk("ERROR sending vmas\n");
+			return -1;
 		}
-
 	}
 	return ret;
 }
@@ -174,29 +197,30 @@
 {
 	struct vm_area_struct * vma;
 	unsigned long addr;
-	int error;
+	struct sockaddr_in *dest_ptr;
+	char *data;
+
+	printk("FUNCTION: mig_send_pages\n");
+	data=kzalloc(PAGE_SIZE, GFP_KERNEL);
 
+	dest_ptr=(void *)p->om.whereto;
 	for (vma = p->mm->mmap; vma; vma = vma->vm_next)
 	{
 		if (!(vma->vm_flags & VM_READ))
 			continue;
 		for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE)
 		{
-			error = comm_send_hd(p->om.contact, MIG_PAGE, &addr,
-								sizeof(addr));
-			if (error < 0)
-				goto fail;
-
-			error = comm_send(p->om.contact, (void *) addr,
-								PAGE_SIZE);
-			if (error < 0)
-				goto fail;
+			// FIXME:   mem pages need to be copied into a buffer, then send the buffer.   ???
+			memcpy(data, (void *)addr, PAGE_SIZE);
+			if (task_test_dflags(p, DREMOTE))
+				kcom_send_with_ack(MIG_PAGE | REM_FLG, PAGE_SIZE, (char *)data, addr, dest_ptr);
+			else
+				kcom_send_with_ack(MIG_PAGE | DEP_FLG, PAGE_SIZE, (char *)data, addr, dest_ptr);
+
 		}
 	}
+	kfree(data);
 	return 0;
-fail:
-	OMBUG("failed (addr: %p)\n", (void *) addr);
-	return -1;
 }
 
 
@@ -210,8 +234,9 @@
 static int mig_send_proc_context(task_t *p)
 {
 	struct omp_mig_task m;
-	struct omp_req req;
-	int error;
+	struct sockaddr_in* dest_ptr;
+
+	dest_ptr=(void *)p->om.whereto;
 
 	m.ptrace = p->ptrace;
 
@@ -248,18 +273,13 @@
 
 	arch_mig_send_proc_context(p, &m);
 
-	error = comm_send_hd(p->om.contact, MIG_TASK, &m, sizeof(m));
-	if (error < 0)
-		goto fail;
-
-	error = comm_recv(p->om.contact, &req, sizeof(req));
+	if (task_test_dflags(p, DREMOTE))
+		kcom_send_with_ack(MIG_TASK | REM_FLG, sizeof(m), (char *)&m, 0, dest_ptr);
+	else
+		kcom_send_with_ack(MIG_TASK | DEP_FLG, sizeof(m), (char *)&m, 0, dest_ptr);
 
-	if (req.type == (MIG_TASK | REPLY))
-		return 0; /* commit point */
+	return 0;
 
-fail:
-	OMBUG("failed\n");
-	return -1;
 }
 
 /**
@@ -271,8 +291,20 @@
  **/
 int mig_do_send(task_t *p)
 {
+	struct sockaddr_in* dest_ptr=(void *)p->om.whereto;
+	unsigned int addr=dest_ptr->sin_addr.s_addr;
 	arch_mig_send_pre(p);
 
+	if (task_test_dflags(p, DREMOTE))  {
+		printk("Sending MIG_GO_HOME\n");
+		if (kcom_send_with_ack(MIG_GO_HOME | REM_FLG, 0, NULL, 0, dest_ptr))
+			goto fail_mig;
+	} else {
+		printk("Sending MIG_INIT\n");
+		if (kcom_send_with_ack(MIG_INIT | DEP_FLG, 0, NULL, 0, dest_ptr))
+			goto fail_mig;
+	}
+
 	if (mig_send_mm(p)) goto fail_mig;
 	if (mig_send_vmas(p)) goto fail_mig;
 	if (mig_send_pages(p)) goto fail_mig;
@@ -282,9 +314,13 @@
 
 	arch_mig_send_post(p);
 
+	printk("Process %u now migrated to %u.%u.%u.%u\n", p->pid,
+					(0x000000FF & addr), (0x0000FF00 & addr)>>8,
+					(0x00FF0000 & addr)>>16, (0xFF000000 & addr) >> 24);
+
 	return 0;
 fail_mig:
+	printk("error FUNCTION: mig_do_send\n");
 	OMBUG("failed\n");
-	comm_send_req(p->om.contact, MIG_ABORT);
 	return -1;
 }
openmosix-kcomd-move-copy-to-user-to-kcomd-api.patch (text/x-patch, 12.1 KB)
Index: linux/hpc/copyuser.c
===================================================================
--- linux.orig/hpc/copyuser.c	2006-09-18 23:29:14.000000000 +0200
+++ linux/hpc/copyuser.c	2006-09-18 23:35:45.000000000 +0200
@@ -15,6 +15,8 @@
 #include <linux/sched.h>
 #include <hpc/protocol.h>
 #include <hpc/debug.h>
+#include <linux/in.h>
+#include <hpc/kcom.h>
 #include <hpc/prototype.h>
 #include <hpc/hpc.h>
 
@@ -32,7 +34,9 @@
 unsigned long deputy_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
 	struct omp_usercopy_req u;
-	int error;
+	task_t *p=current;
+	struct sockaddr_in *dest_ptr=(struct sockaddr_in *)p->om.whereto;
+	int i;
 
 	if (in_atomic())
 		return n;
@@ -42,18 +46,10 @@
 
 	OMDEBUG_CPYUSER(1, "copy user[0x%p]->[0x%p][%ld]\n", from, to, n);
 
-	error = comm_send_hd(current->om.contact, DEP_COPY_FROM_USER, &u, sizeof(u));
-	if (error < 0)
-		goto error;
-
-	error = comm_recv(current->om.contact, to, n);
-	if (error < 0)
-		goto error;
+	i=kcom_send_with_response(DEP_COPY_FROM_USER | PKT_NEW_MSG | DEP_FLG, sizeof(u), (char *)&u, 0, (char *)to, dest_ptr);
+
 
 	return 0;
-error:
-	OMBUG("error %d\n", error);
-	return -1;
 }
 EXPORT_SYMBOL(deputy_copy_from_user);
 
@@ -69,25 +65,21 @@
 unsigned long deputy_strncpy_from_user(char *dst, const char __user *src,
 							long count)
 {
-	struct omp_usercopy_req u;
-	int error;
+	task_t *p=current;
+	struct omp_usercopy_req *u;
+	struct sockaddr_in *dest_ptr=(struct sockaddr_in *)p->om.whereto;
+	int i;
 
 	OMDEBUG_CPYUSER(1, "strcpy user[0x%p]->[0x%p][%ld]\n", src, dst, count);
-	u.addr = (unsigned long) src;
-	u.len = count;
-	error = comm_send_hd(current->om.contact, DEP_STRNCPY_FROM_USER, &u,
-								sizeof(u));
-	if (error < 0)
-		goto error;
-
-	error = comm_recv(current->om.contact, dst, count);
-	if (error < 0)
-		goto error;
+	u=kzalloc(sizeof(*u), GFP_KERNEL);
+
+	u->addr = (unsigned long) src;
+	u->len = count;
+
+	i=kcom_send_with_response(DEP_STRNCPY_FROM_USER | PKT_NEW_MSG | DEP_FLG, sizeof(*u), (char *)u, 0, dst, dest_ptr);
 
 	return 0;
-error:
-	OMBUG("error %d\n", error);
-	return -1;
+
 }
 
 /**
@@ -101,29 +93,22 @@
  **/
 unsigned long deputy_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
-	struct omp_usercopy_req u;
-	int error;
+	int i;
+	char *buf;
+	task_t *p=current;
+	struct sockaddr_in *dest_ptr=(struct sockaddr_in *)p->om.whereto;
 
 	if (in_atomic())
 		return n;
 
-	OMDEBUG_CPYUSER(1, "copy [0x%p]->user[0x%p][%ld]\n", from, to, n);
-	u.addr = (unsigned long) to;
-	u.len = n;
+	// Instead of sending two packets, we create one larger packet and send it.
+	buf=kzalloc(n, GFP_KERNEL);
+	memcpy(buf, from, n);
 
-	error = comm_send_hd(current->om.contact, DEP_COPY_TO_USER, &u,
-							sizeof(u));
-	if (error < 0)
-		goto error;
-
-	error = comm_send(current->om.contact, (void *) from, n);
-	if (error < 0)
-		goto error;
+	i=kcom_send_with_ack(DEP_COPY_TO_USER | PKT_NEW_MSG | DEP_FLG, n, buf, (unsigned long) to, dest_ptr);
 
 	return 0;
-error:
-	OMBUG("error %d\n", error);
-	return -1;
+
 }
 EXPORT_SYMBOL(deputy_copy_to_user);
 
@@ -138,25 +123,18 @@
 unsigned long deputy_strnlen_user(const char *s, long n)
 {
 	struct omp_usercopy_req u;
-	int error;
 	long ret;
+	int i;
+	task_t *p=current;
+	struct sockaddr_in *dest_ptr=(struct sockaddr_in *)p->om.whereto;
 
 	OMDEBUG_CPYUSER(1, "strlen user[0x%p][%ld]\n", s, n);
 	u.addr = (unsigned long) s;
 	u.len = n;
 
-	error = comm_send_hd(current->om.contact, DEP_STRNLEN_USER, &u, sizeof(u));
-	if (error < 0)
-		goto out;
-
-	error = comm_recv(current->om.contact, &ret, sizeof(ret));
-	if (error < 0)
-		goto out;
+	i=kcom_send_with_response(DEP_STRNLEN_USER | PKT_NEW_MSG | DEP_FLG, sizeof(u), (char *)&u, 0, (char *)&ret, dest_ptr);
 
 	return ret;
-out:
-	OMBUG("error %d\n", error);
-	return 0;
 }
 EXPORT_SYMBOL(deputy_strnlen_user);
 
@@ -172,7 +150,9 @@
 static inline long deputy_put_userX(s64 value, const void *addr, size_t size)
 {
 	struct omp_usercopy_emb u;
-	int error;
+	int i;
+	task_t *p=current;
+	struct sockaddr_in *dest_ptr=(struct sockaddr_in *)p->om.whereto;
 
 	OMDEBUG_CPYUSER(1, "put (%lld)->user[0x%p][%zd]\n", value, addr, size);
 
@@ -180,13 +160,9 @@
 	u.len = size;
 	u.val = value;
 
-	error = comm_send_hd(current->om.contact, DEP_PUT_USER, &u, sizeof(u));
-	if (error < 0)
-		goto out;
+	i=kcom_send_with_ack(DEP_PUT_USER | PKT_NEW_MSG | DEP_FLG, sizeof(u), (char *)&u, 0, dest_ptr);
+
 	return 0;
-out:
-	OMBUG("error %d\n", error);
-	return -EFAULT;
 }
 
 /**
@@ -227,32 +203,21 @@
  **/
 static inline long deputy_get_userX(s64 *value, const void *addr, size_t size)
 {
+	task_t *p=current;
 	struct omp_usercopy_req u;
-	int error;
 	s64 ret;
+	struct sockaddr_in *dest_ptr=(struct sockaddr_in *)p->om.whereto;
+	int i;
 
 	OMDEBUG_CPYUSER(1, "get user[0x%p][%zd]\n", addr, size);
 	u.addr = (unsigned long) addr;
 	u.len = size;
 
-	error = comm_send_hd(current->om.contact, DEP_GET_USER, &u, sizeof(u));
-	if (error < 0)
-		goto out;
+	i=kcom_send_with_response(DEP_GET_USER | PKT_NEW_MSG | DEP_FLG, sizeof(u), (char *)&u, 0, (void *)&ret, dest_ptr);
 
-	error = comm_recv(current->om.contact, &ret, sizeof(ret));
-	if (error < 0)
-		goto out;
+	*value=ret;
 
-	switch (size) {
-	case 1: { s8 *v = (s8 *) value; *v = (s8) ret; break; }
-	case 2: { s16 *v = (s16 *) value; *v = (s16) ret; break; }
-	case 4: { s32 *v = (s32 *) value; *v = (s32) ret; break; }
-	case 8: *value = ret; break;
-	}
 	return 0;
-out:
-	OMBUG("error %d\n", error);
-	return -EFAULT;
 }
 
 /**
@@ -281,105 +246,95 @@
 /**
  * remote_copy_user - Copy to or from user for deputy
  **/
-static int remote_copy_user(task_t *p, int request)
+static int remote_copy_from_user(task_t *p, struct kcom_pkt *pkt)
 {
 	struct omp_usercopy_req u;
 	void *buf = NULL;
-	int error;
+	int ret;
 
-	error = comm_recv(p->om.contact, &u, sizeof(u));
-	if (error < 0)
-		goto out;
+	memcpy(&u, pkt->data, pkt->len);
 
 	buf = kmalloc(u.len, GFP_KERNEL);
 	if (!buf)
 		goto out;
 
-	switch (request) {
-	case DEP_COPY_FROM_USER:
-		copy_from_user(buf, (const void __user *) u.addr, u.len);
-
-		error = comm_send(p->om.contact, buf, u.len);
-		if (error < 0)
-			goto out;
-		break;
-	case DEP_COPY_TO_USER:
-		error = comm_recv(p->om.contact, buf, u.len);
-		if (error < 0)
-			goto out;
+	ret=copy_from_user(buf, (const void __user *) u.addr, u.len);
+
+	kcom_send_resp(p, u.len, buf, pkt);
+
+	return ret;
 
-		copy_to_user((void __user *) u.addr, buf, u.len);
-		break;
-	}
 out:
 	kfree(buf);
-	return error;
+	return -1;
 }
 
+static int remote_copy_to_user(task_t *p, struct kcom_pkt *pkt)
+{
+	int ret;
+	ret=copy_to_user((void __user *) pkt->addr, pkt->data, pkt->len);
+
+	kcom_send_ack(p, pkt);
+
+	return ret;
+
+}
 /**
  * remote_strncpy_from_user - strncpy from user for deputy
  **/
-static int remote_strncpy_from_user(task_t *p)
+static int remote_strncpy_from_user(task_t *p, struct kcom_pkt *pkt)
 {
 	struct omp_usercopy_req u;
 	void *buf = NULL;
-	int error;
+	int ret;
 
-	error = comm_recv(p->om.contact, &u, sizeof(u));
-	if (error < 0)
-		goto out;
+	memcpy(&u, pkt->data, sizeof(u));
 
 	buf = kmalloc(u.len, GFP_KERNEL);
 	if (!buf)
 		goto out;
 
-	strncpy_from_user(buf, (const char __user *) u.addr, u.len);
+	ret=strncpy_from_user(buf, (const char __user *) u.addr, u.len);
 
-	error = comm_send(p->om.contact, buf, u.len);
-	if (error < 0)
-		goto out;
+	kcom_send_resp(p, u.len, buf, pkt);
+
+	return ret;
 
 out:
-	kfree(buf);
-	return error;
+	return -1;
+
 }
 
 /**
  * remote_strnlen_from_user - strnlen from user for deputy
  **/
-static int remote_strnlen_user(task_t *p)
+static int remote_strnlen_user(task_t *p, struct kcom_pkt *pkt)
 {
 	struct omp_usercopy_req u;
-	long ret;
-	int error;
+	long *ret_ptr;
 
-	error = comm_recv(p->om.contact, &u, sizeof(u));
-	if (error < 0)
-		goto out;
+	memcpy(&u, pkt->data, pkt->len);
+
+	ret_ptr=kzalloc(sizeof(long), GFP_KERNEL);
 
-	ret = (u.len)
+	*ret_ptr = (u.len)
 		? strnlen_user((const char __user *) u.addr, u.len)
 		: strlen_user((const char __user *) u.addr);
 
-	error = comm_send(p->om.contact, &ret, sizeof(ret));
-	if (error < 0)
-		goto out;
-out:
-	return error;
+	kcom_send_resp(p, sizeof(*ret_ptr), (char *)ret_ptr, pkt);
+
+	return 0;
 }
 
 /**
  * remote_put_user - put user for deputy
  **/
-static int remote_put_user(task_t *p)
+static int remote_put_user(task_t *p, struct kcom_pkt *pkt)
 {
 	struct omp_usercopy_emb u;
 	long ret;
-	int error;
 
-	error = comm_recv(p->om.contact, &u, sizeof(u));
-	if (error < 0)
-		goto out;
+	memcpy(&u, pkt->data, pkt->len);
 
 	switch (u.len) {
 	case 1: ret = put_user(u.val, (u8 *) u.addr); break;
@@ -388,81 +343,112 @@
 	case 8: ret = put_user(u.val, (u64 *) u.addr); break;
 	default: ret = -EFAULT;
 	}
+
+	kcom_send_ack(p, pkt);
+
 	return ret;
-out:
-	return error;
 }
 
 /**
  * remote_get_user - get user for deputy
  **/
-static int remote_get_user(task_t *p)
+static int remote_get_user(task_t *p, struct kcom_pkt *pkt)
 {
 	struct omp_usercopy_req u;
-	s64 ret;
-	int error;
+	s64 *ret;
+
+	memcpy(&u, pkt->data, sizeof(struct omp_usercopy_req));
+	ret=kzalloc(sizeof(*ret), GFP_KERNEL);
 
-	error = comm_recv(p->om.contact, &u, sizeof(u));
-	if (error < 0)
-		goto out;
 
 	switch (u.len) {
-	case 1: get_user(ret, (u8 *) u.addr); break;
-	case 2: get_user(ret, (u16 *) u.addr); break;
-	case 4: get_user(ret, (u32 *) u.addr); break;
+	case 1: get_user(*ret, (u8 *) u.addr); break;
+	case 2: get_user(*ret, (u16 *) u.addr); break;
+	case 4: get_user(*ret, (u32 *) u.addr); break;
 #if BITS_PER_LONG == 64
-	case 8: get_user(ret, (u64 *) u.addr); break;
+	case 8: get_user(*ret, (u64 *) u.addr); break;
 #endif
 	}
 
-	error = comm_send(p->om.contact, &ret, sizeof(ret));
-	if (error < 0)
-		goto out;
-out:
-	return error;
+	kcom_send_resp(p, sizeof(*ret), (char *)ret, pkt);
+return 0;
 }
 
-
 /**
  * remote_handle_user - Handle user copy until receiving @endtype
  **/
 int remote_handle_user(task_t *p, int endtype)
 {
-	struct omp_req req;
-	int ret = 1;
-	int error;
-
-	while (ret != 0) {
-		error = comm_recv(p->om.contact, &req, sizeof(req));
-		if (error < 0)
-			return error;
-		if (req.type == endtype) {
-			ret = 0;
-			break;
+	int ret = 0;
+	struct kcom_pkt *pkt, *pkt_next, *send_pkt;
+	struct kcom_task *task;
+
+	task=kcom_task_find(p->pid);
+
+	while (1) {
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		list_for_each_entry_safe(pkt, pkt_next, &task->in_packs, list) {
+
+			switch ( pkt->type & SYSCALL_MASK ) {
+
+				case DEP_STRNCPY_FROM_USER :
+					remote_strncpy_from_user(p, pkt);
+					break;
+
+			 	case DEP_GET_USER :
+					remote_get_user(p, pkt);
+					break;
+
+				case DEP_COPY_FROM_USER :
+					remote_copy_from_user(p, pkt);
+					break;
+
+				case DEP_COPY_TO_USER :
+					remote_copy_to_user(p, pkt);
+					break;
+
+				case DEP_PUT_USER :
+					remote_put_user(p, pkt);
+					break;
+
+			 	case SYSCALL_DONE :
+					send_pkt=kcom_pkt_create(0, MIG_SYSCALL | PKT_ACK | SYSCALL_DONE | REM_FLG, PKT_ACK, NULL);
+					send_pkt->msgid=pkt->msgid;
+					send_pkt->hpid=task->hpid;
+					send_pkt->rpid=task->rpid;
+					send_pkt->resp=pkt->resp;
+
+					list_add_tail(&send_pkt->list, &task->out_packs);
+
+					if (kcomd_task) {
+						send_sig(SIGHUP, kcomd_task, 0);
+					} else
+						printk("Unable to signal kcomd\n");
+
+					ret=pkt->addr;  /* the return value is stored in the addr field */
+					list_del(&pkt->list);
+					kmem_cache_free(kcom_pkt_cachep, pkt);
+					set_current_state(TASK_RUNNING);
+					schedule();
+					return ret;
+					break;
+
+			}
+
+			list_del(&pkt->list);
+			kmem_cache_free(kcom_pkt_cachep, pkt);
 		}
 
-		switch (req.type) {
-		case DEP_COPY_FROM_USER:
-		case DEP_COPY_TO_USER:
-			remote_copy_user(p, req.type);
-			break;
-		case DEP_STRNCPY_FROM_USER:
-			remote_strncpy_from_user(p);
-			break;
-		case DEP_STRNLEN_USER:
-			remote_strnlen_user(p);
-			break;
-		case DEP_PUT_USER:
-			remote_put_user(p);
-			break;
-		case DEP_GET_USER:
-			remote_get_user(p);
-			break;
-		default:
-			OMBUG("unexpected type [%x]\n", req.type);
-			remote_disappear();
-			break;
+		if (list_empty(&task->in_packs)) {
+			schedule();
 		}
+
 	}
-	return ret;
+
+	printk( KERN_ERR "openMosix: %s is not supposed to end that way ! (%s:%n)\n"
+	      , __FUNCTION__, __FILE__, __LINE__);
+
+	return -1;
+
 }
openmosix-kcomd-move-deputy-to-kcomd-api.patch (text/x-patch, 4.1 KB)
Index: linux/hpc/deputy.c
===================================================================
--- linux.orig/hpc/deputy.c	2006-09-14 11:40:48.000000000 +0200
+++ linux/hpc/deputy.c	2006-09-14 12:01:31.000000000 +0200
@@ -29,6 +29,7 @@
 #include <hpc/arch.h>
 #include <hpc/syscalls.h>
 #include <hpc/debug.h>
+#include <hpc/kcom.h>
 #include <hpc/prototype.h>
 #include <hpc/hpc.h>
 
@@ -41,26 +42,43 @@
 /**
  * deputy_do_syscall - process a syscall coming from remote
  **/
-static int deputy_do_syscall(task_t *p)
+static int deputy_do_syscall(task_t *p, struct kcom_pkt *pkt)
 {
 	struct omp_syscall_req s;
 	struct omp_syscall_ret r;
-	int error;
+	struct sockaddr_in *dest_ptr=(struct sockaddr_in *)p->om.whereto;
+	struct kcom_task *send_tsk;
+	struct kcom_pkt *send_pkt;
+	// task_t *kcomd_task;
+
+	// Send MIG_SYSCALL ack
+	send_tsk=kcom_task_find(p->pid);
+
+	send_pkt=kcom_pkt_create(0, MIG_SYSCALL | PKT_ACK | DEP_FLG, PKT_ACK, NULL);
+
+	send_pkt->msgid=pkt->msgid; // responses have same msg id as pkt they are responding to.
+	send_pkt->hpid=pkt->hpid;
+	send_pkt->rpid=pkt->rpid;
+	send_pkt->resp=pkt->resp;
+
+	// spin_lock(&send_tsk->spinlock);
+	list_add_tail(&send_pkt->list, &send_tsk->out_packs);
+	// spin_unlock(&send_tsk->spinlock);
+
+	if (kcomd_task != NULL)
+		send_sig(SIGHUP,kcomd_task,0);
+
+	if (sizeof(struct omp_syscall_req) != pkt->len)
+		printk("ERROR in deputy_do_syscall.  data size of %d does not match expected %d\n", pkt->len, sizeof(struct omp_syscall_req));
+	memcpy(&s, pkt->data, pkt->len);
 	
-	error = comm_recv(p->om.contact, &s, sizeof(s));
-	if (error < 0)
-		return -1;
-
 	OMDEBUG_SYS(1, "[deputy] receive syscall %d\n", s.n);
 
 	/* do the syscall and put reply in r */
 	r.ret = arch_exec_syscall(s.n, (syscall_parameter_t *) &s.arg);
 	
-	error = comm_send_hd(p->om.contact, REM_SYSCALL | REPLY, &r, sizeof(r));
-	if (error < 0)
-		return -1;
+	kcom_send_with_ack(MIG_SYSCALL | PKT_NEW_MSG | SYSCALL_DONE | DEP_FLG, 0, NULL, r.ret, dest_ptr);
 
-	OMDEBUG_SYS(2, "[deputy] replied to syscall %d\n", s.n);
 
 	return 0;
 }
@@ -379,25 +397,38 @@
 static inline void deputy_do_sigpending(task_t *p)
 {
 	siginfo_t info;
+
+	#if 0
 	struct omp_signal s;
-	int signr, error;
+	struct sockaddr_in *dest_ptr=p->om.whereto;
+	#endif
+
+	int signr;
 
 	do_signal(ARCH_TASK_GET_USER_REGS(p), NULL);
 	
-	return;
-	
-	for (;;) {
+
+	printk(KERN_WARNING "%s does not yet know how to process signals ... \n", __FUNCTION__ );
+
+	while (signal_pending (p)) {
 		signr = dequeue_signal(p, &p->blocked, &info);
-		if (!signr)
-			break;
 
-		s.signr = signr;
-		memcpy(&s.siginfo, &info, sizeof(siginfo_t));
+	/* FIXME:   was kinda working, not now. */
+	#if 0
+		if (signr != SIGKILL) {
+			s.signr = signr;
+			memcpy(&s.siginfo, &info, sizeof(siginfo_t));
+
+			kcom_send_with_ack(MIG_SYSCALL | PKT_NEW_MSG | DEP_SIGNAL | DEP_FLG, sizeof(struct omp_signal), &s, 0, dest_ptr);
+			printk("Signal %d sent to remote.\n", signr);
+		} else
+			printk("Signal %d discarded.\n", signr);
+	#endif
 
-		error = comm_send_hd(p->om.contact, DEP_SIGNAL, &s, sizeof(s));
-		if (error < 0)
-			OMBUG("error %d\n", error);
 	}
+
+	return;
+
 }
 
 /**
@@ -413,6 +444,7 @@
 	}
 }
 
+#if 0
 /**
  * deputy_process_communication - process has receive communication in deputy
  **/
@@ -455,20 +487,39 @@
 	if (error < 0)
 		deputy_die_on_communication();
 }
+#endif
 
 /**
  * deputy_main_loop - process loop when process is deputy
  **/
 void deputy_main_loop(void)
 {
-	int has_communication;
+	task_t *p=current;
+	struct kcom_task *mytsk;
+	int error=0;
+	struct kcom_pkt *pkt, *pkt_next;
 	
+	mytsk=kcom_task_find(p->pid);
 	while (task_test_dflags(current, DDEPUTY))
 	{
-		has_communication = comm_wait(current->om.contact);
-		if (has_communication)
-			deputy_process_communication(current);
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (!list_empty(&mytsk->in_packs)) {
+
+			list_for_each_entry_safe(pkt, pkt_next, &mytsk->in_packs, list) {
+
+				if ((pkt->type & MIG_MASK) == MIG_SYSCALL) {
+
+
+					error = deputy_do_syscall(p, pkt);
+					list_del(&pkt->list);
+				}
+			}
+
+		}
+
 		deputy_process_misc(current);
+		schedule();
 	}
 }
openmosix-kcomd-proc-to-kcomd.patch (text/x-patch, 3.1 KB)
Index: linux/hpc/proc.c
===================================================================
--- linux.orig/hpc/proc.c	2006-09-15 00:45:00.000000000 +0200
+++ linux/hpc/proc.c	2006-09-15 00:48:12.000000000 +0200
@@ -27,6 +27,9 @@
 #include <hpc/proc.h>
 #include <hpc/version.h>
 #include <hpc/service.h>
+#include <linux/inet.h>
+#include <linux/in.h>
+#include <hpc/kcom.h>
 #include <hpc/prototype.h>
 #include <hpc/task.h>
 #include <hpc/debug.h>
@@ -37,29 +40,77 @@
  */
 static int proc_pid_set_where(struct task_struct *p, char *buf, size_t size)
 {
-	int ret;
-	struct sockaddr destination;
+	struct sockaddr_in* dest_ptr=(struct sockaddr_in *)p->om.whereto;
+	struct sockaddr_in *cur_addr;
+	struct kcom_task *tsk;
+	struct kcom_node *node;
+	/* task_t *kcomd_task;*/
+
+	buf[size-1]='\0';	 /* ensures no trailing crap in 'where' file*/
 
 	if (size >= 4 && strnicmp(buf, "home", 4) == 0) {
-		printk("HOME detected\n");
-		ret = task_register_migration(p, NULL);
+		printk("HOME detected - ");
+		/* p->om.whereto=NULL;*/
+		/* ret = task_register_migration(p, NULL);*/
+		if (task_test_dflags(p, DDEPUTY)) { /* if already migrated and this is home node*/
+			printk("on deputy node\n");
+			node=kcom_node_find((struct sockaddr *)dest_ptr);
+			if (node==NULL)
+				return 1;
+			tsk=kcom_task_find(p->pid);
+			if (tsk==NULL)
+				return 1;
+			kcom_task_send(tsk, MIG_COME_HOME | PKT_NEW_MSG | DEP_FLG, 0, NULL, NULL, 0);
+
+			#if 0
+			read_lock(&tasklist_lock);
+			kcomd_task = find_task_by_pid(kcom_pid);
+			read_unlock(&tasklist_lock);
+			#endif
+
+			if (kcomd_task != NULL)
+				send_sig(SIGHUP,kcomd_task,0);
+			/* kcom_send(MIG_COME_HOME | PKT_NEW_MSG | DEP_FLG, 0, NULL, 0, dest_ptr);*/
+		} else {
+			printk("on remote node\n");
+			task_register_migration(p);
+		}
 	} else {
-		ret = string_to_sockaddr(buf, &destination);
-		if (ret >= 0)
-			task_register_migration(p, &destination);
+		if (task_test_dflags(p, DDEPUTY)) {
+			tsk=kcom_task_find(p->pid);
+			if (tsk) {
+				cur_addr=(struct sockaddr_in *)&tsk->node->addr;
+
+				if ( in_aton(buf) == cur_addr->sin_addr.s_addr) { /* home -> remote - redundant migration;*/
+					printk("Process already migrated to %s\n", buf);
+					return size;
+				} /* FIXME:  remote to remote migration*/
+			}
+		} else {
+
+			dest_ptr->sin_family=AF_INET;
+			dest_ptr->sin_port=htons(DAEMON_IP4_PORT);
+			dest_ptr->sin_addr.s_addr=in_aton(buf);
+
+			task_register_migration(p);
+		}
 	}
+
 	return size;
 }
 
 static int proc_pid_get_where(struct task_struct *p, char *buf, size_t size)
 {
 	int length;
-	struct sockaddr address;
+	struct sockaddr_in *saddr;
+	unsigned int addr;
 
-	if (p->om.contact && task_test_dflags(p, DMIGRATED)) {
-		comm_getname(p->om.contact, &address, 1);
-		length = sockaddr_to_string(&address, buf);
-		length += sprintf(buf + length, "\n");
+	if (task_test_dflags(p, DMIGRATED)) {
+	/* FIXME:  what if process is currently migrating? */
+		saddr=(struct sockaddr_in *)p->om.whereto;
+		addr=saddr->sin_addr.s_addr;
+		length=sprintf(buf, "%u.%u.%u.%u\n", (0x000000FF & addr), (0x0000FF00 & addr)>>8,
+							(0x00FF0000 & addr)>>16, (0xFF000000 & addr) >> 24);
 	} else
 		length = sprintf(buf, "home\n");
openmosix-kcomd-remote-preuser-to-kcomd-api.patch (text/x-patch, 1.3 KB)
Index: linux/hpc/kernel.c
===================================================================
--- linux.orig/hpc/kernel.c	2006-09-14 22:54:29.000000000 +0200
+++ linux/hpc/kernel.c	2006-09-14 22:55:47.000000000 +0200
@@ -26,6 +26,9 @@
 #include <hpc/comm.h>
 #include <hpc/mig.h>
 
+#include <hpc/kcom.h>
+#include <hpc/prototype.h>
+
 struct openmosix_options om_opts;
 EXPORT_SYMBOL_GPL(om_opts);
 
@@ -157,11 +160,26 @@
 
 static inline int remote_pre_usermode(void)
 {
-	task_t *p = current;
-
-	if (p->om.contact && comm_peek(p->om.contact))
-		remote_do_comm(p);
+	task_t *p=current;
+	struct kcom_task *mytsk;
+	struct kcom_pkt *pkt, *pkt_next;
+
+	
+	/* FIXME:  should we just add a *kcom_task to the proc struct, and speed this up? */
+	mytsk=kcom_task_find(p->pid);
+		if (!list_empty(&mytsk->in_packs))
+			list_for_each_entry_safe(pkt, pkt_next, &mytsk->in_packs, list) {
+				printk("packet found.\n");
+				if ((pkt->type & MIG_MASK) == MIG_SYSCALL) {
+					if ((pkt->type & SYSCALL_MASK) == DEP_SIGNAL) {
+						printk("Signal pkt found.\n");
+						remote_do_signal(p, pkt);
+						list_del(&pkt->list);
+					}
+				}
+			}
 	return 0;
+	
 }
 
 static inline int deputy_pre_usermode(void)
@@ -206,7 +224,6 @@
 static int __init openmosix_init(void)
 {
 	/* kick off the kernel threads: */
-	kernel_thread(openmosix_mig_daemon, NULL, 0);
 
 	return 0;
 }
openmosix-kcomd-remote-to-kcomd.patch (text/x-patch, 3.5 KB)
Index: linux/hpc/remote.c
===================================================================
--- linux.orig/hpc/remote.c	2006-09-15 00:49:59.000000000 +0200
+++ linux/hpc/remote.c	2006-09-15 00:52:26.000000000 +0200
@@ -28,10 +28,12 @@
 #include <hpc/comm.h>
 #include <hpc/task.h>
 #include <hpc/arch.h>
+#include <hpc/kcom.h>
 #include <hpc/prototype.h>
 #include <hpc/service.h>
 #include <hpc/hpc.h>
 #include <hpc/debug.h>
+#include <asm/unistd.h>
 
 
 NORET_TYPE void remote_disappear(void)
@@ -149,19 +151,47 @@
 	return -1;
 }
 
-static int remote_do_signal(task_t *p)
+int remote_do_signal(task_t *p,  struct kcom_pkt *pkt)
 {
 	struct omp_signal s;
 	unsigned long flags;
 	int error;
-
-	error = comm_recv(p->om.contact, &s, sizeof(s));
+	struct kcom_pkt *send_pkt;
+	struct kcom_task *send_tsk;
+	// task_t *kcomd_task;
+
+	printk("FUNCTION: remote_do_signal\n");
+	memcpy(&s, pkt->data, pkt->len);
+	// error = comm_recv(p->om.contact, &s, sizeof(s));
 	printk("received signal %d\n", s.signr);
 
+	
 	spin_lock_irqsave(&p->sighand->siglock, flags);
 	error = __group_send_sig_info(s.signr, &s.siginfo, p);
 	spin_unlock_irqrestore(&p->sighand->siglock, flags);
+	
 
+	send_tsk=kcom_task_find(p->pid);
+	send_pkt=kcom_pkt_create(0, MIG_SYSCALL | PKT_ACK | DEP_SIGNAL | REM_FLG, PKT_ACK, NULL);
+	send_pkt->msgid=pkt->msgid;
+	send_pkt->hpid=send_tsk->hpid;
+	send_pkt->rpid=send_tsk->rpid;
+	send_pkt->resp=pkt->resp;
+
+	list_add_tail(&send_pkt->list, &send_tsk->out_packs);
+
+	#if 0
+	read_lock(&tasklist_lock);
+	kcomd_task=find_task_by_pid(kcom_pid);
+	read_unlock(&tasklist_lock);
+	#endif
+
+	if (kcomd_task) {
+		printk("Signaling kcomd\n");
+		send_sig(SIGHUP, kcomd_task, 0);
+	} else
+		printk("Unable to signal kcomd\n");
+	printk("leaving FUNCTION: remote_do_signal\n");
 	return 0;
 }
 
@@ -179,7 +209,9 @@
 
 	switch (req.type) {
 	case DEP_SIGNAL:
+		#if 0
 		error = remote_do_signal(p);
+		#endif
 		break;
 	case DEP_COMING_HOME:
 		printk("remote_do_comm(): got DEP_COMING_HOME\n");
@@ -207,7 +239,10 @@
 	task_t *p = current;
 	struct omp_syscall_req s;
 	struct omp_syscall_ret r;
-	int error, i;
+	int i;
+	struct sockaddr_in *dest_ptr=(struct sockaddr_in *)p->om.whereto;
+
+	printk("FUNCTION: remote_do_syscall\n");
 
 	OMDEBUG_SYS(1, "[remote] remote syscall %d\n", n);
 
@@ -215,23 +250,29 @@
 	for (i = 0; i < NR_MAX_SYSCALL_ARG; i++)
 		s.arg[i] = arch_get_sys_arg(i, regs);
 
-	error = comm_send_hd(p->om.contact, REM_SYSCALL, &s, sizeof(s));
-	if (error < 0)
-		goto error;
+	printk("syscall: [%d]\n", s.n);
+	kcom_send_with_ack(MIG_SYSCALL | REM_FLG, sizeof(s), (char *)&s, 0, dest_ptr);
+
+	// Set interruptible so we can sleep, but if the remote sends syscall info requests (COPY_TO/FROM_USER, etc), then we have to answer those before sleeping.
+	set_current_state(TASK_INTERRUPTIBLE);
 
 	OMDEBUG_SYS(3, "[remote] waiting deputy answer\n");
 
-	error = remote_handle_user(p, REM_SYSCALL|REPLY);
-	if (error < 0)
+	// if exitting, no need for remote_handle_user
+	if ((n != __NR_exit_group) && (n != __NR_exit))
+		r.ret = remote_handle_user(p, REM_SYSCALL|REPLY);
+	else { // exit 
+		printk("leaving FUNCTION: remote_do_syscall; exit\n");
 		goto error;
+	}
 
-	error = comm_recv(p->om.contact, &r, sizeof(r));
-	if (error < 0)
-		goto error;
 
-	OMDEBUG_SYS(2, "[remote] sys[%d] = %ld\n", n, r.ret);
+	// OMDEBUG_SYS(2, "[remote] sys[%d] = %ld\n", n, r.ret);
+	printk("[remote] sys[%d] = %ld\n", n, r.ret);
 
+	printk("leaving FUNCTION: remote_do_syscall\n");
 	return r.ret;
+
 error:
 	remote_disappear();
 	return -1;
openmosix-kcomd-task-to-kcomd.patch (text/x-patch, 2.6 KB)
Index: linux/hpc/task.c
===================================================================
--- linux.orig/hpc/task.c	2006-09-18 23:40:22.000000000 +0200
+++ linux/hpc/task.c	2006-09-18 23:52:48.000000000 +0200
@@ -23,8 +23,9 @@
 #include <hpc/task.h>
 #include <hpc/comm.h>
 #include <hpc/mig.h>
-#include <hpc/prototype.h>
 #include <hpc/hpc.h>
+#include <hpc/kcom.h>
+#include <hpc/prototype.h>
 
 /**
  * task_set_comm - swap openMosix link for a process (return old one)
@@ -124,14 +125,26 @@
  **/
 void task_request_move(task_t *p)
 {
-	struct sockaddr *addr;
+	struct sockaddr *dest_ptr=p->om.whereto;
+
+/*
+ * FIXME:
+ *  1) home -> remote - fresh migration; *
+ *  2) home -> remote - redundant migration; *
+ *  3) home -> 'home';
+ *  4) home -> new remote;
+ *  5) remote -> 'home' - fresh migration; *
+ *  6) remote -> home ip address;
+ *  7) remote -> remote ip address;
+ *  8) remote -> new remote - initiated from remote;
+ *  9) remote -> new remote - initiated from home;
+ *  10) remote -> home - bring home initiated from home;
+ */
 
 	task_clear_dreqs(p, DREQ_MOVE);
-	addr = p->om.whereto;
-	p->om.whereto = NULL;
 
-	task_move_to_node(p, addr, 0);
-	kfree(addr);
+	task_move_to_node(p, dest_ptr, 0);
+
 }
 
 /**
@@ -142,7 +155,8 @@
 	task_t *parent = current;
 
 	memset(&p->om, 0, sizeof(om_task_t));
-	
+	printk("leaving FUNCTION: task_local_bring\n");
+
 	if (p->pid == 1)
 		task_set_stay(p, DSTAY_SYSTEM);
 
@@ -154,7 +168,7 @@
 		task_set_dflags(p, DDEPUTY);
 
 	INIT_LIST_HEAD(&p->om.rfiles);
-	
+
 	return 0;
 }
 
@@ -164,14 +178,19 @@
 int openmosix_task_exit(void)
 {
 	task_t *p = current;
-	
+
 	if (!task_test_dflags(p, DDEPUTY | DREMOTE))
 		return 0;
 
+	dump_stack();
+	kcom_task_delete(p->pid);
 	task_heldfiles_clear(p);
-	
+	kfree(p->om.whereto);
+
+	#if 0
 	if (p->om.contact)
-		comm_close(p->om.contact);
+		 comm_close(p->om.contact);
+	#endif
 	return 0;
 }
 
@@ -195,21 +214,15 @@
 /**
  * task_register_migration - register a migration for this process
  * @p:		task to migrate
- * @dest:	destination of the migration (NULL == home)
  **/
-int task_register_migration(task_t *p, struct sockaddr *dest)
+int task_register_migration(task_t *p)
 {
-	if (dest) {
-		p->om.whereto = kmalloc(sizeof(struct sockaddr), GFP_KERNEL);
-		if (!p->om.whereto)
-			return -1;
-		memcpy(p->om.whereto, dest, sizeof(struct sockaddr));
-	}
 	task_set_dreqs(p, DREQ_MOVE);
 	wake_up_process(p);
 	set_ti_thread_flag(p->thread_info, TIF_NEED_RESCHED);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(task_register_migration);
 
 /**
  * task_do_request - current task processes requests coming from other tasks