]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kernel test module
authorpatiencew <patiencew@29311d96-e01e-0410-9327-a35deaab8ce9>
Mon, 19 Nov 2007 19:58:50 +0000 (19:58 +0000)
committerpatiencew <patiencew@29311d96-e01e-0410-9327-a35deaab8ce9>
Mon, 19 Nov 2007 19:58:50 +0000 (19:58 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2083 29311d96-e01e-0410-9327-a35deaab8ce9

trunk/ceph/kernel/test/Makefile [new file with mode: 0644]
trunk/ceph/kernel/test/kernclient.c [new file with mode: 0644]
trunk/ceph/kernel/test/ktcp.c [new file with mode: 0644]
trunk/ceph/kernel/test/ktcp.h [new file with mode: 0644]
trunk/ceph/kernel/test/messenger.h [new file with mode: 0644]
trunk/ceph/kernel/test/messenger_mini.c [new file with mode: 0644]
trunk/ceph/kernel/test/threadtest.c [new file with mode: 0644]
trunk/ceph/kernel/test/userclient.c [new file with mode: 0644]
trunk/ceph/kernel/test/userserver.c [new file with mode: 0644]

diff --git a/trunk/ceph/kernel/test/Makefile b/trunk/ceph/kernel/test/Makefile
new file mode 100644 (file)
index 0000000..9582bc5
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for CEPH kernel socket test.
+#
+
+obj-$(CONFIG_CEPHTESTS_FS) += ksocktest.o
+
+ksocktest-objs := kernclient.o messenger_mini.o ktcp.o
diff --git a/trunk/ceph/kernel/test/kernclient.c b/trunk/ceph/kernel/test/kernclient.c
new file mode 100644 (file)
index 0000000..b5acc0a
--- /dev/null
@@ -0,0 +1,114 @@
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <linux/string.h>
+#include <net/tcp.h>
+
+#include <linux/ceph_fs.h>
+#include "messenger.h"
+#include "ktcp.h"
+
+
+#define PORT 9009
+#define HOST cranium
+#define cranium 192.168.1.3
+
+MODULE_AUTHOR("Patience Warnick <patience@newdream.net>");
+MODULE_DESCRIPTION("kernel thread test for Linux");
+MODULE_LICENSE("GPL");
+
+int work_init(void);
+void shutdown_workqueues(void);
+int add_sock_callbacks(struct socket *, struct ceph_connection *);
+int inet_aton (const char *cp, struct in_addr *addr);
+struct task_struct *thread;
+
+
+/*
+ *  Wake up a thread when there is work to do
+ */
+/*  void thread_wake_up(void)
+{
+}
+*/
+/*
+ * Client socket thread
+ */
+static int sock_thread(void *unusedfornow)
+{
+       struct ceph_messenger *msgr = NULL;
+       struct ceph_connection *con;
+       struct sockaddr_in saddr;
+       int ret;
+
+       printk(KERN_INFO "starting kernel thread\n");
+
+       con = new_connection(msgr);
+
+       /* inet_aton("192.168.1.3", &saddr.sin_addr); */
+       /* con->peer_addr.ipaddr.sin_addr = saddr.sin_addr; */
+
+        saddr.sin_family = AF_INET;
+        saddr.sin_addr.s_addr = htonl(INADDR_ANY);
+        saddr.sin_port = htons(PORT);
+       printk(KERN_INFO "saddr info %p\n", &saddr);
+       con->peer_addr.ipaddr = saddr;
+
+
+       set_bit(WRITE_PEND, &con->state);
+
+       printk(KERN_INFO "about to connect to server\n");
+       /* connect to server */
+       if ((ret = do_connect(con))) {
+               printk(KERN_INFO "error connecting %d\n", ret);
+               goto done;
+       }
+       printk(KERN_INFO "connect succeeded\n");
+
+       set_current_state(TASK_INTERRUPTIBLE);
+        /* an endless loop in which we are doing our work */
+       while (!kthread_should_stop())
+        {
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule();
+               printk(KERN_INFO "sock thread has been interrupted\n");
+       }
+
+       set_current_state(TASK_RUNNING);
+        sock_release(con->sock);
+done:
+        kfree(con);
+       printk(KERN_INFO "kernel thread exiting\n");
+       return 0;
+}
+
+static int __init init_kst(void)
+{
+       int ret;
+
+       printk(KERN_INFO "kernel thread test init\n");
+       /* create new kernel threads */
+       ret = work_init();
+       thread = kthread_run(sock_thread, NULL, "sock-thread");
+               if (IS_ERR(thread))
+               {
+                       printk(KERN_INFO "failured to start kernel thread\n");
+                       return -ENOMEM;
+               }
+       return 0;
+}
+
+static void __exit exit_kst(void)
+{
+       printk(KERN_INFO "kernel thread test exit\n");
+       shutdown_workqueues();
+       kthread_stop(thread);
+       wake_up_process(thread);
+
+       return;
+}
+
+
+module_init(init_kst);
+module_exit(exit_kst);
diff --git a/trunk/ceph/kernel/test/ktcp.c b/trunk/ceph/kernel/test/ktcp.c
new file mode 100644 (file)
index 0000000..12decbe
--- /dev/null
@@ -0,0 +1,151 @@
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <net/tcp.h>
+#include <linux/string.h>
+#include "messenger.h"
+#include "ktcp.h"
+
+
+struct socket * _kconnect(struct sockaddr *saddr)
+{
+       int ret;
+       struct socket *sd = NULL;
+
+       ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sd);
+        if (ret < 0) {
+               printk(KERN_INFO "sock_create_kern error: %d\n", ret);
+               return NULL;
+       }
+
+       ret = sd->ops->connect(sd, (struct sockaddr *) saddr,
+                               sizeof (struct sockaddr_in),0);
+/*
+       ret = sd->ops->connect(sd, (struct sockaddr *) saddr,
+                               sizeof (struct sockaddr_in),O_NONBLOCK);
+
+       if (ret == -EINPROGRESS) {
+               printk(KERN_INFO "non-blocking connect in progress: %d\n", ret);
+               goto done;
+       }
+*/
+
+        if (ret < 0) {
+               printk(KERN_INFO "kernel_connect error: %d\n", ret);
+               sock_release(sd);
+       }
+done:
+       return(sd);
+}
+
+struct socket * _klisten(struct sockaddr *saddr)
+{
+       int ret;
+       struct socket *sd = NULL;
+       struct sockaddr_in *in_addr = (struct sockaddr_in *)saddr;
+
+
+       ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sd);
+        if (ret < 0) {
+               printk(KERN_INFO "sock_create_kern error: %d\n", ret);
+               return(NULL);
+       }
+
+       /* no user specified address given so create, will allow arg to mount */
+       if (!in_addr->sin_addr.s_addr) {
+               in_addr->sin_family = AF_INET;
+               in_addr->sin_addr.s_addr = htonl(INADDR_ANY);
+               in_addr->sin_port = htons(CEPH_PORT);  /* known port for now */
+               /* in_addr->sin_port = htons(0); */  /* any port */
+       }
+
+/* TBD: set sock options... */
+       /*  ret = kernel_setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
+                               (char *)optval, optlen); 
+       if (ret < 0) {
+               printk("Failed to set SO_REUSEADDR: %d\n", ret);
+       }  */
+       ret = sd->ops->bind(sd, saddr, sizeof(saddr));
+/* TBD: probaby want to tune the backlog queue .. */
+       ret = sd->ops->listen(sd, NUM_BACKUP);
+       if (ret < 0) {
+               printk(KERN_INFO "kernel_listen error: %d\n", ret);
+               sock_release(sd);
+               sd = NULL;
+       }
+       return(sd);
+}
+
+/*
+ * Note: Maybe don't need this, or make inline... keep for now for debugging..
+ * we may need to add more functionality
+ */
+struct socket *_kaccept(struct socket *sd)
+{
+       struct socket *new_sd = NULL;
+       int ret;
+
+       
+       ret = kernel_accept(sd, &new_sd, sd->file->f_flags);
+        if (ret < 0) {
+               printk(KERN_INFO "kernel_accept error: %d\n", ret);
+               return(new_sd);
+       }
+/* TBD:  shall we check name for validity?  */
+       return(new_sd);
+}
+
+/*
+ * receive a message this may return after partial send
+ */
+int _krecvmsg(struct socket *sd, void *buf, size_t len, unsigned msgflags)
+{
+       struct kvec iov = {buf, len};
+       struct msghdr msg = {.msg_flags = msgflags};
+       int rlen = 0;           /* length read */
+
+       printk(KERN_INFO "entered krevmsg\n");
+       msg.msg_flags |= MSG_DONTWAIT | MSG_NOSIGNAL;
+
+       /* receive one kvec for now...  */
+       rlen = kernel_recvmsg(sd, &msg, &iov, 1, len, msg.msg_flags);
+        if (rlen < 0) {
+               printk(KERN_INFO "kernel_recvmsg error: %d\n", rlen);
+        }
+       /* TBD: kernel_recvmsg doesn't fill in the name and namelen
+         */
+       return(rlen);
+
+}
+
+/*
+ * Send a message this may return after partial send
+ */
+int _ksendmsg(struct socket *sd, struct kvec *iov, 
+               size_t kvlen, size_t len, unsigned msgflags)
+{
+       struct msghdr msg = {.msg_flags = msgflags};
+       int rlen = 0;
+
+       printk(KERN_INFO "entered ksendmsg\n");
+       msg.msg_flags |=  MSG_DONTWAIT | MSG_NOSIGNAL;
+
+       rlen = kernel_sendmsg(sd, &msg, iov, kvlen, len);
+        if (rlen < 0) {
+               printk(KERN_INFO "kernel_sendmsg error: %d\n", rlen);
+        }
+       return(rlen);
+}
+
+struct sockaddr *_kgetname(struct socket *sd)
+{
+       struct sockaddr *saddr = NULL;
+       int len;
+       int ret;
+
+       if ((ret = sd->ops->getname(sd, (struct sockaddr *)saddr,
+                                       &len, 2) < 0)) {
+               printk(KERN_INFO "kernel getname error: %d\n", ret);
+       }
+       return(saddr);
+
+}
diff --git a/trunk/ceph/kernel/test/ktcp.h b/trunk/ceph/kernel/test/ktcp.h
new file mode 100644 (file)
index 0000000..a6f6d1f
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _FS_CEPH_TCP_H
+#define _FS_CEPH_TCP_H
+
+/* prototype definitions */
+struct socket * _kconnect(struct sockaddr *);
+struct socket * _klisten(struct sockaddr *);
+struct socket *_kaccept(struct socket *);
+int _krecvmsg(struct socket *, void *, size_t , unsigned);
+int _ksendmsg(struct socket *, struct kvec *, size_t, size_t, unsigned);
+
+/* Well known port for ceph client listener.. */
+#define CEPH_PORT 2002
+/* Max number of outstanding connections in listener queueu */
+#define NUM_BACKUP 10
+#endif
diff --git a/trunk/ceph/kernel/test/messenger.h b/trunk/ceph/kernel/test/messenger.h
new file mode 100644 (file)
index 0000000..b9cf355
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef __FS_CEPH_MESSENGER_H
+#define __FS_CEPH_MESSENGER_H
+
+#include <linux/uio.h>
+#include <linux/net.h>
+#include <linux/radix-tree.h>
+#include <linux/workqueue.h>
+#include <linux/ceph_fs.h>
+
+struct ceph_messenger {
+        struct socket *listen_sock;      /* listening socket */
+        struct work_struct awork;        /* accept work */
+        struct ceph_entity_inst inst;    /* my name+address */
+        spinlock_t con_lock;
+        struct list_head con_all;        /* all connections */
+};
+
+#define        NEW 1
+#define        CONNECTING 2
+#define        ACCEPTING 3
+#define        OPEN 4
+#define READ_PEND 5
+#define WRITE_PEND 6
+#define        REJECTING 7
+#define        CLOSED 8
+
+
+struct ceph_connection {
+       struct socket *sock;    /* connection socket */
+       __u32 state;
+       
+       atomic_t nref;
+       spinlock_t con_lock;    /* connection lock */
+
+       struct list_head list_all;   /* msgr->con_all */
+       struct ceph_entity_addr peer_addr; /* peer address */
+
+       char *buffer;
+
+       struct work_struct rwork;               /* received work */
+       struct work_struct swork;               /* send work */
+       int retries;
+       int error;                              /* error on connection */
+};
+
+
+struct ceph_connection *new_connection(struct ceph_messenger *);
+int do_connect(struct ceph_connection *con);
+#endif
diff --git a/trunk/ceph/kernel/test/messenger_mini.c b/trunk/ceph/kernel/test/messenger_mini.c
new file mode 100644 (file)
index 0000000..5d649d4
--- /dev/null
@@ -0,0 +1,326 @@
+#include <linux/kthread.h>
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <linux/string.h>
+#include <net/tcp.h>
+
+#include <linux/ceph_fs.h>
+#include "messenger.h"
+#include "ktcp.h"
+
+static struct workqueue_struct *recv_wq;        /* receive work queue */
+static struct workqueue_struct *send_wq;        /* send work queue */
+
+static void try_read(struct work_struct *);
+static void try_write(struct work_struct *);
+static void try_accept(struct work_struct *);
+
+int add_sock_callbacks(struct socket *, struct ceph_connection *);
+
+
+/*
+ * connections
+ */
+
+/* 
+ * create a new connection.  initial state is NEW.
+ */
+struct ceph_connection *new_connection(struct ceph_messenger *msgr)
+{
+       struct ceph_connection *con;
+       con = kmalloc(sizeof(struct ceph_connection), GFP_KERNEL);
+       if (con == NULL) 
+               return NULL;
+       memset(con, 0, sizeof(struct ceph_connection));
+
+       /* con->msgr = msgr; */
+
+       spin_lock_init(&con->con_lock);
+       INIT_WORK(&con->rwork, try_read);       /* setup work structure */
+       INIT_WORK(&con->swork, try_write);      /* setup work structure */
+
+       atomic_inc(&con->nref);
+       return con;
+}
+
+/*
+ * initiate connection to a remote socket.
+ *
+ */
+int do_connect(struct ceph_connection *con)
+{
+        struct sockaddr *paddr = (struct sockaddr *)&con->peer_addr.ipaddr;
+       int ret = 0;
+
+
+       set_bit(CONNECTING, &con->state);
+
+       ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &con->sock);
+       if (ret < 0) {
+                printk(KERN_INFO "sock_create_kern error: %d\n", ret);
+                goto done;
+        }
+
+        /* setup callbacks */
+        add_sock_callbacks(con->sock, con);
+
+
+        ret = con->sock->ops->connect(con->sock, paddr, 
+                                     sizeof(struct sockaddr_in),O_NONBLOCK);
+       if (ret == -EINPROGRESS) return 0;
+        if (ret < 0) {
+               /* TBD check for fatal errors, retry if not fatal.. */
+                printk(KERN_INFO "kernel_connect error: %d\n", ret);
+                sock_release(con->sock);
+               con->sock = NULL;
+        }
+done:
+        printk(KERN_INFO "do_connect state = %u\n", con->state);
+        return ret;
+}
+
+/*
+ * call when socket is writeable
+ */
+static void try_write(struct work_struct *work)
+{
+       struct ceph_connection *con;
+        struct kvec iov;
+       int ret;
+
+
+
+       con = container_of(work, struct ceph_connection, swork);
+
+        printk(KERN_INFO "Entered try_write state = %u\n", con->state);
+
+       clear_bit(WRITE_PEND, &con->state);
+       set_bit(READ_PEND, &con->state);
+
+
+        con->buffer = kzalloc(256, GFP_KERNEL);
+        if (con->buffer == NULL)
+                goto done;
+
+        strcpy(con->buffer, "hello world");
+        iov.iov_base = con->buffer;
+        iov.iov_len = 255;
+        printk(KERN_INFO "about to send message\n");
+        ret = _ksendmsg(con->sock,&iov,1,iov.iov_len,0);
+        if (ret < 0) goto done;
+        printk(KERN_INFO "wrote %d bytes to server\n", ret);
+
+       
+
+       kfree(con->buffer);
+done:
+       return;
+}
+
+
+/*
+ * call when data is available on the socket
+ */
+static void try_read(struct work_struct *work)
+{
+       struct ceph_connection *con;
+       int len;
+
+
+       con = container_of(work, struct ceph_connection, rwork);
+
+        printk(KERN_INFO "Entered try_read state = %u\n", con->state);
+
+        con->buffer = kzalloc(256, GFP_KERNEL);
+        if (con->buffer == NULL)
+                goto done;
+
+       len = _krecvmsg(con->sock,con->buffer,255,0);
+       if (len < 0){
+               printk(KERN_INFO "ERROR reading from socket\n");
+               goto done;
+       }
+        printk(KERN_INFO "received message: %s\n", con->buffer);
+        printk(KERN_INFO "message length: %d\n", len);
+
+       kfree(con->buffer);
+done:
+       return;
+}
+
+
+/*
+ * Accepter thread
+ */
+static void try_accept(struct work_struct *work)
+{
+       struct socket *sock, *new_sock;
+       struct sockaddr_in saddr;
+        struct ceph_connection *new_con = NULL;
+       struct ceph_messenger *msgr;
+       int len;
+
+       msgr = container_of(work, struct ceph_messenger, awork);
+       sock = msgr->listen_sock;
+
+
+        printk(KERN_INFO "Entered try_accept\n");
+
+
+        if (kernel_accept(sock, &new_sock, sock->file->f_flags) < 0) {
+               printk(KERN_INFO "error accepting connection \n");
+                goto done;
+        }
+        printk(KERN_INFO "accepted connection \n");
+
+        /* get the address at the other end */
+        memset(&saddr, 0, sizeof(saddr));
+        if (new_sock->ops->getname(new_sock, (struct sockaddr *)&saddr, &len, 2)) {
+                printk(KERN_INFO "getname error connection aborted\n");
+                sock_release(new_sock);
+                goto done;
+        }
+
+       /* initialize the msgr connection */
+       new_con = new_connection(msgr);
+       if (new_con == NULL) {
+                       printk(KERN_INFO "malloc failure\n");
+               sock_release(new_sock);
+               goto done;
+               }
+       new_con->sock = new_sock;
+       set_bit(ACCEPTING, &new_con->state);
+       /* new_con->in_tag = CEPH_MSGR_TAG_READY; */
+       /* fill in part of peers address */
+       new_con->peer_addr.ipaddr = saddr;
+
+       /* hand off to worker threads , send pending */
+       /*?? queue_work(send_wq, &new_con->swork);*/
+done:
+        return;
+}
+
+/*
+ * create a new messenger instance, saddr is address specified from mount arg.
+ * If null, will get created by _klisten()
+ */
+struct ceph_messenger *ceph_create_messenger(struct sockaddr *saddr)
+{
+        struct ceph_messenger *msgr;
+
+        msgr = kmalloc(sizeof(*msgr), GFP_KERNEL);
+        if (msgr == NULL)
+                return NULL;
+        memset(msgr, 0, sizeof(*msgr));
+
+        spin_lock_init(&msgr->con_lock);
+
+        /* create listening socket */
+        msgr->listen_sock = _klisten(saddr);
+        if (msgr->listen_sock == NULL) {
+                kfree(msgr);
+                return NULL;
+        }
+        /* TBD: setup callback for accept */
+        INIT_WORK(&msgr->awork, try_accept);       /* setup work structure */
+        return msgr;
+}
+
+/* Data available on socket or listen socket received a connect */
+static void ceph_data_ready(struct sock *sk, int count_unused)
+{
+        struct ceph_connection *con = (struct ceph_connection *)sk->sk_user_data;
+
+        printk(KERN_INFO "Entered ceph_data_ready state = %u\n", con->state);
+        if (test_bit(READ_PEND, &con->state)) {
+               printk(KERN_INFO "READ_PEND set in connection\n");
+                queue_work(recv_wq, &con->rwork);
+       }
+}
+
+static void ceph_write_space(struct sock *sk)
+{
+        struct ceph_connection *con = (struct ceph_connection *)sk->sk_user_data;
+
+        printk(KERN_INFO "Entered ceph_write_space state = %u\n",con->state);
+        if (test_bit(WRITE_PEND, &con->state)) {
+               printk(KERN_INFO "WRITE_PEND set in connection\n");
+                queue_work(send_wq, &con->swork);
+       }
+}
+
+static void ceph_state_change(struct sock *sk)
+{
+        struct ceph_connection *con = (struct ceph_connection *)sk->sk_user_data;
+       /* TBD: probably want to set our connection state to OPEN
+        * if state not set to READ or WRITE pending
+        */
+        printk(KERN_INFO "Entered ceph_state_change state = %u\n", con->state);
+        if (sk->sk_state == TCP_ESTABLISHED) {
+               if (test_and_clear_bit(CONNECTING, &con->state))
+                       set_bit(OPEN, &con->state);
+                ceph_write_space(sk);
+       }
+}
+
+/* Make a socket active */
+int add_sock_callbacks(struct socket *sock, struct ceph_connection *con)
+{
+       struct sock *sk = sock->sk;
+       sk->sk_user_data = con;
+        printk(KERN_INFO "Entered add_sock_callbacks\n");
+
+        /* Install callbacks */
+       sk->sk_data_ready = ceph_data_ready;
+       sk->sk_write_space = ceph_write_space;
+       sk->sk_state_change = ceph_state_change;
+
+        return 0;
+}
+
+/*
+ *  workqueue initialization
+ */
+
+int work_init(void)
+{
+        int ret = 0;
+
+       printk(KERN_INFO "entered work_init\n");
+        /*
+         * Create a num CPU threads to handle receive requests
+         * note: we can create more threads if needed to even out
+         * the scheduling of multiple requests..
+         */
+        recv_wq = create_workqueue("ceph-recv");
+        ret = IS_ERR(recv_wq);
+        if (ret) {
+                printk(KERN_INFO "receive worker failed to start: %d\n", ret);
+                destroy_workqueue(recv_wq);
+                return ret;
+        }
+
+        /*
+         * Create a single thread to handle send requests
+         * note: may use same thread pool as receive workers later...
+         */
+        send_wq = create_singlethread_workqueue("ceph-send");
+        ret = IS_ERR(send_wq);
+        if (ret) {
+                printk(KERN_INFO "send worker failed to start: %d\n", ret);
+                destroy_workqueue(send_wq);
+                return ret;
+        }
+       printk(KERN_INFO "successfully created wrkqueues\n");
+
+        return(ret);
+}
+
+/*
+ *  workqueue shutdown
+ */
+void shutdown_workqueues(void)
+{
+        destroy_workqueue(send_wq);
+        destroy_workqueue(recv_wq);
+}
diff --git a/trunk/ceph/kernel/test/threadtest.c b/trunk/ceph/kernel/test/threadtest.c
new file mode 100644 (file)
index 0000000..d594d4f
--- /dev/null
@@ -0,0 +1,68 @@
+#include <linux/module.h>
+#include <linux/kthread.h>
+
+MODULE_AUTHOR("Patience Warnick <patience@newdream.net>");
+MODULE_DESCRIPTION("kernel thread test for Linux");
+MODULE_LICENSE("GPL");
+
+#define NTHREADS 3
+struct task_struct *thread[3];
+/*  static DECLARE_WAIT_QUEUE_HEAD(dispatch_wait); */
+
+/*
+ *  Wake up a thread when there is work to do
+ */
+/*  void thread_wake_up(void)
+{
+}
+*/
+
+static int dispatch_thread(void *unusedfornow)
+{
+       printk(KERN_INFO "starting kernel thread\n");
+       set_current_state(TASK_INTERRUPTIBLE);
+        /* an endless loop in which we are doing our work */
+       while (!kthread_should_stop())
+        {
+               schedule();
+               printk(KERN_INFO "Dispatch thread has been interrupted\n");
+               set_current_state(TASK_INTERRUPTIBLE);
+       }
+       set_current_state(TASK_RUNNING);
+       printk(KERN_INFO "kernel thread exiting\n");
+       return 0;
+}
+
+static int __init init_kst(void)
+{
+       int i;
+
+       printk(KERN_INFO "kernel thread test init\n");
+       /* create new kernel threads */
+       for (i=0; i < NTHREADS; i++) {
+               thread[i] = kthread_run(dispatch_thread, NULL, "dispatcher thread");
+               if (IS_ERR(thread[i]))
+               {
+                       printk(KERN_INFO "failured to start kernel thread\n");
+                       return -ENOMEM;
+               }
+       }
+       return 0;
+}
+
+static void __exit exit_kst(void)
+{
+       int i;
+
+       printk(KERN_INFO "kernel thread test exit\n");
+       for (i=0; i <NTHREADS; i++) {
+               kthread_stop(thread[i]);
+               wake_up_process(thread[i]);
+       }
+
+       return;
+}
+
+
+module_init(init_kst);
+module_exit(exit_kst);
diff --git a/trunk/ceph/kernel/test/userclient.c b/trunk/ceph/kernel/test/userclient.c
new file mode 100644 (file)
index 0000000..ce173fc
--- /dev/null
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h> 
+
+int main(int argc, char *argv[])
+{
+       int sd, port,len;
+       struct sockaddr_in saddr;
+       struct hostent *server;
+       char buf[256];
+
+       if (argc < 3) {
+               fprintf(stderr,"usage %s hostname port\n", argv[0]);
+               exit(1);
+       }
+       port = atoi(argv[2]);
+       printf("port num = %d\n", port);
+       sd = socket(AF_INET, SOCK_STREAM, 0);
+       if (sd < 0) {
+               fprintf(stderr,"socket open error");
+               exit(1);
+       }
+       server = gethostbyname(argv[1]);
+       printf("server name  = %s\n", server->h_name);
+       printf("server ip  = %s\n", *(server->h_addr));
+       if (server == NULL) {
+               fprintf(stderr,"get host error\n");
+               exit(1);
+       }
+       bzero((char *) &saddr, sizeof(saddr));
+       saddr.sin_family = AF_INET;
+       bcopy((char *)server->h_addr, (char *)&saddr.sin_addr.s_addr, 
+                       server->h_length);
+       saddr.sin_port = htons(port);
+       if (connect(sd,(struct sockaddr *)&saddr,sizeof(saddr)) < 0) {
+               fprintf(stderr,"connection error\n");
+               exit(1);        
+       }
+       printf("Please enter the message: ");
+       bzero(buf,256);
+       fgets(buf,255,stdin);
+       len = write(sd,buf,strlen(buf));
+       if (len < 0) {
+               fprintf(stderr,"write error\n");
+               exit(1);        
+       }
+       bzero(buf,256);
+       len = read(sd,buf,255);
+       if (len < 0) {
+               fprintf(stderr,"write error\n");
+               exit(1);        
+       }
+       printf("received message %s\n",buf);
+       close(sd);
+       exit(0);
+}
diff --git a/trunk/ceph/kernel/test/userserver.c b/trunk/ceph/kernel/test/userserver.c
new file mode 100644 (file)
index 0000000..a27868c
--- /dev/null
@@ -0,0 +1,61 @@
+/* note:  port number is passed as an argument */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h> 
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+int main(int argc, char *argv[])
+{
+       struct sockaddr_in saddr, caddr;
+       int sd, new_sd, port, clen, numbytes;
+       char buf[256];
+
+       if (argc < 2) {
+               fprintf(stderr,"error must enter port \n");
+               exit(1);
+       }
+       printf("starting server\n");
+
+       sd = socket(AF_INET, SOCK_STREAM, 0);
+       if (sd < 0) {
+               fprintf(stderr,"error creating socket\n");
+               exit(1);
+       }
+       bzero((char *) &saddr, sizeof(struct sockaddr_in));
+       port = atoi(argv[1]);
+       saddr.sin_family = AF_INET;
+       saddr.sin_addr.s_addr = INADDR_ANY;
+       saddr.sin_port = htons(port);
+       if (bind(sd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
+               fprintf(stderr,"bind error\n");
+               exit(1);
+       }
+       listen(sd,5);
+       printf("started listening\n");
+       clen = sizeof(caddr);
+       new_sd = accept(sd, (struct sockaddr *) &caddr, &clen);
+       if (new_sd < 0) {
+               fprintf(stderr,"accept error\n");
+               exit(1);
+       }
+       printf("accepted connection\n");
+       bzero(buf,256);
+       numbytes = read(new_sd,buf,255);
+       if (numbytes < 0) {
+               fprintf(stderr,"read error\n");
+               exit(1);
+       }
+       printf("Message received: %s\n",buf);
+       strcpy(buf,"server received your message");
+       numbytes = write(new_sd, buf, 255);
+       if (numbytes < 0){
+               fprintf(stderr,"write error\n");
+               exit(1);
+       } 
+       close(new_sd);
+       close(sd);
+       exit(0); 
+}
+