[patch 43/56] pkt_*read fix
Florian Delizy <[email protected]> Thu, 02 Nov 2006 22:57:09 +0100
| Newsgroups | gmane.linux.cluster.openmosix.devel |
|---|---|
| Message-ID | <[email protected]> |
fix error recognition in pkt*read calls (some caused leaks, some others caused crashes ...) ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ openMosix-devel mailing list openMosix-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/openmosix-devel
pkt_read-fix.patch
(text/x-patch, 5.7 KB)
Subject: [patch @num@/@total@] pkt_*read fix
fix error recognition in pkt*read calls (some caused leaks, some others caused crashes ...)
Index: linux/hpc/kcomd.c
===================================================================
--- linux.orig/hpc/kcomd.c 2006-11-02 22:52:39.000000000 +0100
+++ linux/hpc/kcomd.c 2006-11-02 22:52:42.000000000 +0100
@@ -329,24 +329,24 @@
{
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(KERN_ERR "ERROR: incomplete header pkt\n");
- goto error_recv;
- }
+ recv_kcom_pkt = pkt_hdr_read(node);
+
+ if (recv_kcom_pkt==NULL) 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);
+
+ 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);
+ i = pkt_data_read(node, recv_kcom_pkt, recv_kcom_pkt->len, recv_kcom_pkt->resp);
}
- if (i<recv_kcom_pkt->len) {
+
+ if (i < recv_kcom_pkt->len) {
printk(KERN_ERR "ERROR: incomplete data pkt\n");
goto error_recv;
}
@@ -362,12 +362,18 @@
mig_do_receive_home(node, recv_kcom_pkt);
break;
case MIG_COME_HOME:
- sltsk=find_task_by_pid(recv_kcom_pkt->rpid);
+ {
+ task_t *sltsk;
+ sltsk = find_task_by_pid(recv_kcom_pkt->rpid);
+ if (!sltsk) {
+ printk(KERN_ERR "openMosix: %s Unable to find the task %d ", __FUNCTION__, recv_kcom_pkt->rpid);
+ goto error_recv;
+ }
task_register_migration(sltsk);
break;
+ }
default:
append_in_packs(recv_kcom_pkt);
-
break;
}
} else { // PKT_ACK and PKT_RESP go straight to in_packs
@@ -380,21 +386,10 @@
sys_close(node->fd);
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;
}
Index: linux/hpc/kcom.c
===================================================================
--- linux.orig/hpc/kcom.c 2006-11-02 22:52:33.000000000 +0100
+++ linux/hpc/kcom.c 2006-11-02 22:52:42.000000000 +0100
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 Matt Dew <[email protected]>
+ * Copyright (C) 2006 Florian Delizy <[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
@@ -40,6 +41,7 @@
struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, MSG_WAITALL | MSG_NOSIGNAL };
mm_segment_t oldfs;
int i;
+ int nb_retries = 0;
char buf[32];
iov.iov_base = data;
@@ -55,26 +57,39 @@
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)) {
+
+ /* Prevent infinite loop 60s */
+ if (60000 > nb_retries) {
+ printk(KERN_ERR "openMosix %s too many retries\n", __FUNCTION__);
+ len = -1;
+ goto read_exit;
+ }
+
schedule_timeout(HZ/1000);
continue;
}
+
if (i < 0) {
- printk(KERN_ERR "ERROR %d receiving data.\n", i);
- set_fs(oldfs);
- return -1;
+ printk(KERN_ERR "openMosix %s: %d receiving data.\n", __FUNCTION__, i);
+ len = -1;
+ goto read_exit;
}
iov.iov_base += i;
}
- set_fs(oldfs);
if (len < 32) {
memcpy(data, buf, len);
}
+read_exit:
+ set_fs(oldfs);
+
return len;
+
}
EXPORT_SYMBOL_GPL(pkt_data_read);
@@ -94,32 +109,62 @@
mm_segment_t oldfs;
struct socket *sock=node->sock;
int i;
+ int retry = 0;
- recv_kcom_pkt=kmem_cache_alloc(kcom_pkt_cachep, SLAB_KERNEL);
+ recv_kcom_pkt = kmem_cache_alloc(kcom_pkt_cachep, SLAB_KERNEL);
iov.iov_base = recv_kcom_pkt;
- iov.iov_len = sizeof(*recv_kcom_pkt);
+ iov.iov_len = sizeof(struct 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(KERN_ERR "ERROR %d receiving header.\n", i);
- set_fs(oldfs);
- return NULL;
- }
- iov.iov_base += i;
+
+
+ receive_fragment:
+
+ i = sock_recvmsg(sock, &msg, iov.iov_len, msg.msg_flags);
+ if ((i == -ENOSPC) || (i == -EAGAIN)) {
+ /* prevent infinite loop */
+ if (60000 > retry) goto receive_timeout;
+
+ schedule_timeout(HZ/1000);
+ goto receive_fragment;
+ }
+
+ if (i < 0) {
+ printk(KERN_ERR "openMosix: %s %d receiving header.\n", __FUNCTION__, i);
+ goto receive_error;
}
+ iov.iov_base += i;
+
+ /* sock_revmsg update the iov struct, and len */
+ if (iov.iov_len > 0) goto receive_fragment;
+
+
+ if (iov.iov_len != 0) goto receive_incomplete;
+
+
set_fs(oldfs);
- if (iov.iov_len==0) // all expected data received.
- return recv_kcom_pkt;
- else
- return NULL;
+ return recv_kcom_pkt;
+
+
+receive_timeout:
+ printk(KERN_ERR "openMosix %s Can't receive header %d fragment, too many (%d)\n"
+ " retries)", __FUNCTION__, i, retry);
+ goto exit_error;
+
+receive_error:
+ printk(KERN_ERR "openMosix %s, %d receiving header.\n", __FUNCTION__, i);
+ goto exit_error;
+
+receive_incomplete:
+ printk(KERN_ERR "openMosix %s incomplete packet received\n", __FUNCTION__);
+
+exit_error:
+
+ kmem_cache_free(kcom_pkt_cachep, recv_kcom_pkt);
+ set_fs(oldfs);
+ return NULL;
}
EXPORT_SYMBOL_GPL(pkt_hdr_read);