]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
added module level debugging, some error handling
authorpatiencew <patiencew@29311d96-e01e-0410-9327-a35deaab8ce9>
Fri, 7 Dec 2007 23:19:20 +0000 (23:19 +0000)
committerpatiencew <patiencew@29311d96-e01e-0410-9327-a35deaab8ce9>
Fri, 7 Dec 2007 23:19:20 +0000 (23:19 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2201 29311d96-e01e-0410-9327-a35deaab8ce9

12 files changed:
trunk/ceph/kernel/client.c
trunk/ceph/kernel/dir.c
trunk/ceph/kernel/inode.c
trunk/ceph/kernel/ktcp.c
trunk/ceph/kernel/mds_client.c
trunk/ceph/kernel/mdsmap.c
trunk/ceph/kernel/messenger.c
trunk/ceph/kernel/messenger.h
trunk/ceph/kernel/mon_client.c
trunk/ceph/kernel/osd_client.c
trunk/ceph/kernel/super.c
trunk/ceph/kernel/super.h

index 010cf24cec240e93378f0129977785a1fcff0d8a..e92a2023c3bf19fc336119fc993d462441ef23a1 100644 (file)
@@ -4,12 +4,15 @@
 #include <linux/sched.h>
 #include <linux/random.h>
 #include "client.h"
+extern int ceph_client_debug = 50;
+#define DOUT_VAR ceph_client_debug
+#define DOUT_PREFIX "client: "
 #include "super.h"
 #include "ktcp.h"
 
 
 /* debug level; defined in include/ceph_fs.h */
-int ceph_debug = 200;
+int ceph_debug = 0;
 
 /*
  * directory of filesystems mounted by this host
@@ -111,7 +114,7 @@ trymount:
        mount_msg->hdr.dst.name.num = which;
        mount_msg->hdr.dst.addr = args->mon_addr[which];
 
-       ceph_msg_send(client->msgr, mount_msg);
+       ceph_msg_send(client->msgr, mount_msg, 0);
        dout(10, "mount from mon%d, %d attempts left\n", which, attempts);
 
        /* wait */
index e8332e33ebd2901686e38c8e8afd229cd0fa8567..009744ca715ac3913b3f409d1e52bca4ffe522b9 100644 (file)
@@ -1,4 +1,6 @@
-
+extern int ceph_dir_debug = 50;
+#define DOUT_VAR ceph_dir_debug
+#define DOUT_PREFIX "dir: "
 #include "super.h"
 
 const struct inode_operations ceph_dir_iops;
index b973ca6603e7a6917b76079bc559f1510e67f6ed..f49da4a0c0c01515cff23f0240abdaf94ca85528 100644 (file)
@@ -5,6 +5,9 @@
 
 #include <linux/ceph_fs.h>
 
+extern int ceph_inode_debug = 50;
+#define DOUT_VAR ceph_inode_debug
+#define DOUT_PREFIX "inode: "
 #include "super.h"
 
 const struct inode_operations ceph_symlink_iops;
index 4732c4027650d8896d4c39b5539798a5508c63ba..dee3306ded4a7161f9a6527235b85bb5d1ca3bff 100644 (file)
@@ -4,6 +4,11 @@
 #include <linux/string.h>
 #include "messenger.h"
 #include "ktcp.h"
+#include "ktcp.h"
+extern int ceph_tcp_debug = 50;
+#define DOUT_VAR ceph_tcp_debug
+#define DOUT_PREFIX "tcp: "
+#include "super.h"
 
 struct workqueue_struct *recv_wq = NULL;       /* receive work queue */
 struct workqueue_struct *send_wq = NULL;       /* send work queue */
@@ -42,12 +47,10 @@ static void ceph_write_space(struct sock *sk)
         struct ceph_connection *con = (struct ceph_connection *)sk->sk_user_data;
 
         dout(30, "ceph_write_space %p state = %u\n", con, con->state);
-       /* only queue to workqueue if not already queued */
-        if (con && !work_pending(&con->swork) &&
-           test_bit(WRITE_PENDING, &con->state)) {
+       /* only queue to workqueue if a WRITE is pending */
+        if (con && test_bit(WRITE_PENDING, &con->state)) {
                 dout(30, "ceph_write_space %p queuing write work\n", con);
-               set_bit(WRITEABLE, &con->state);
-                queue_work(send_wq, &con->swork);
+                queue_work(send_wq, &con->swork.work);
         }
        /* Since we have our own write_space, Clear the SOCK_NOSPACE flag */
        clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
index 1e0a68b2df96fdb0a1eee14ae6737d4b3b754516..3edb79e88623fc5a8c9b4e4384d57fc39da949eb 100644 (file)
@@ -4,6 +4,9 @@
 #include <linux/sched.h>
 #include "mds_client.h"
 #include "mon_client.h"
+extern int ceph_mds_debug = 50;
+#define DOUT_VAR ceph_mds_debug
+#define DOUT_PREFIX "mds: "
 #include "super.h"
 #include "messenger.h"
 
@@ -13,7 +16,7 @@ static void send_msg_mds(struct ceph_mds_client *mdsc, struct ceph_msg *msg, int
        msg->hdr.dst.addr = *ceph_mdsmap_get_addr(mdsc->mdsmap, mds);
        msg->hdr.dst.name.type = CEPH_ENTITY_TYPE_MDS;
        msg->hdr.dst.name.num = mds;
-       ceph_msg_send(mdsc->client->msgr, msg);
+       ceph_msg_send(mdsc->client->msgr, msg, BASE_RETRY_INTERVAL);
 }
 
 
index 68dea0c6188f46e53df7ee21afa72d08847fb48c..8da17533e43546157faf9d83b0ad46bed8caf9f3 100644 (file)
@@ -7,6 +7,11 @@
 #include "mdsmap.h"
 #include "messenger.h"
 
+extern int ceph_mdsmap_debug = 50;
+#define DOUT_VAR ceph_mdsmap_debug
+#define DOUT_PREFIX "mdsmap: "
+#include "super.h"
+
 int ceph_mdsmap_get_state(struct ceph_mdsmap *m, int w)
 {
        BUG_ON(w < 0);
index 32a98dcf45b04e0bb2605ec4ec2b0059296d99ce..6700d20c29cebc62fd0d72cf34ca9c2b3fa024ca 100644 (file)
@@ -7,6 +7,10 @@
 #include <net/tcp.h>
 #include "messenger.h"
 #include "ktcp.h"
+extern int ceph_msgr_debug = 50;
+#define DOUT_VAR ceph_msgr_debug
+#define DOUT_PREFIX "msgr: " 
+#include "super.h"
 
 /* static tag bytes */
 static char tag_ready = CEPH_MSGR_TAG_READY;
@@ -19,6 +23,72 @@ static void try_read(struct work_struct *);
 static void try_write(struct work_struct *);
 static void try_accept(struct work_struct *);
 
+/*
+ * failure case
+ * A retry mechanism is used with exponential backoff
+ */
+static void ceph_send_fault(struct ceph_connection *con, int error)
+{
+       derr(1, "connection error %d to peer %x:%d\n", error,
+            ntohl(con->peer_addr.ipaddr.sin_addr.s_addr),
+            ntohs(con->peer_addr.ipaddr.sin_port));
+
+       if (!con->delay) {
+               derr(1, "timeout not set\n");
+               return;
+       }
+
+       switch (error) {
+               /* no space in socket buffer, ceph_write_space will handle 
+                * requeueing */
+               case -EAGAIN:
+                       break;
+               case -ETIMEDOUT:
+                       derr(1, "timed out to peer %x:%d\n",
+                            ntohl(con->peer_addr.ipaddr.sin_addr.s_addr),
+                            ntohs(con->peer_addr.ipaddr.sin_port));
+               /* peer unreachable */
+               case -EHOSTDOWN:
+               case -EHOSTUNREACH:
+               case -ENETUNREACH:
+                       derr(1, "ENETUNREACH set\n");
+                       spin_lock(&con->out_queue_lock);
+                       list_splice_init(&con->out_sent, &con->out_queue);
+                       spin_unlock(&con->out_queue_lock);
+                       /* retry with delay */
+                       queue_delayed_work(send_wq, &con->swork, 
+                                          BASE_RETRY_INTERVAL);
+                       break;
+               case -EPIPE:
+               case -ECONNREFUSED:
+               case -ECONNRESET:
+               /* never connected socket. SOCK_DONE flag not set */
+               case -ENOTCONN:
+                       derr(1, "ENOTCONN set\n");
+                       /* TBD: setup timeout here */
+                       if (!test_and_clear_bit(CONNECTING, &con->state)){
+                               derr(1, "CONNECTING bit not set\n");
+                               /* reset buffer */
+                               spin_lock(&con->out_queue_lock);
+                               list_splice_init(&con->out_sent, 
+                                                &con->out_queue);
+                               spin_unlock(&con->out_queue_lock);
+                               clear_bit(OPEN, &con->state);
+                       }
+                       set_bit(NEW, &con->state);
+                       /* retry with delay */
+                       queue_delayed_work(send_wq, &con->swork, 
+                                          BASE_RETRY_INTERVAL);
+                       break;
+               case -EIO:
+                       derr(1, "EIO set\n");
+                       /* shutdown or soft timeout */
+
+               default:
+                       /* if we ever hit here ... */
+                       derr(1, "unrecognized error %d\n", error);
+       }
+}
 
 /*
  * calculate the number of pages a given length and offset map onto,
@@ -69,7 +139,7 @@ static struct ceph_connection *new_connection(struct ceph_messenger *msgr)
        INIT_LIST_HEAD(&con->out_sent);
 
        INIT_WORK(&con->rwork, try_read);
-       INIT_WORK(&con->swork, try_write);
+       INIT_DELAYED_WORK(&con->swork, try_write);
 
        return con;
 }
@@ -393,17 +463,9 @@ static void try_write(struct work_struct *work)
        struct ceph_messenger *msgr;
        int ret = 1;
 
-       con = container_of(work, struct ceph_connection, swork);
+       con = container_of(work, struct ceph_connection, swork.work);
        msgr = con->msgr;
        dout(30, "try_write start %p state %d\n", con, con->state);
-
-retry:
-       if (test_and_set_bit(WRITING, &con->state) != 0) {
-               dout(30, "try_write connection already writing\n");
-               return;
-       }
-       clear_bit(WRITEABLE, &con->state);
-
 more:
        dout(30, "try_write out_kvec_bytes %d\n", con->out_kvec_bytes);
 
@@ -416,15 +478,11 @@ more:
                dout(5, "try_write initiated connect\n");
                if (ret < 0) {
                        /* fault */
-                       derr(1, "connect error, FIXME\n");
+                       derr(1, "connect error\n");
+                       ceph_send_fault(con, ret);
                        goto done;
                }
        }
-       /*if (test_bit(CONNECTING, &con->state)) {
-               dout(30, "try_write still connecting, doing nothing for now\n");
-               goto done;
-       }
-       */
 
        /* kvec data queued? */
        if (con->out_kvec_left) {
@@ -439,8 +497,7 @@ more:
                        put_connection(con);
                }
                if (ret < 0) {
-                       /* TBD: handle error; return for now */
-                       con->error = ret;
+                       ceph_send_fault(con, ret);
                        goto done; /* error */
                }
        }
@@ -450,6 +507,10 @@ more:
                ret = write_partial_msg_pages(con, con->out_msg);
                if (ret == 0) 
                        goto done;
+               if (ret < 0) {
+                       ceph_send_fault(con, ret);
+                       goto done;
+               }
        }
        
        /* anything else pending? */
@@ -459,34 +520,17 @@ more:
        } else if (!list_empty(&con->out_queue)) {
                prepare_write_message(con);
        } else {
+               clear_bit(WRITE_PENDING, &con->state);
                /* hmm, nothing to do! No more writes pending? */
                dout(30, "try_write nothing else to write.\n");
-               clear_bit(WRITING, &con->state);         /* clear this first */
-               clear_bit(WRITE_PENDING, &con->state);   /* and this second, to avoid a race. */
                spin_unlock(&con->out_queue_lock);
-               return;
+               goto done;
        }
        spin_unlock(&con->out_queue_lock);
        goto more;
 
 done:
        dout(30, "try_write done\n");
-       clear_bit(WRITING, &con->state);
-
-       /*
-        * See if we became WRITEABLE again to avoid race against socket.  
-        * Otherwise, this would be bad:
-        *  A B
-        *  -   enter try_write, do some work
-        *  -   socket fills, we get -EAGAIN or whatever
-        *    - socket becomes writeable again, work is queued
-        *    - new try_write sees WRITING bit, exits
-        *  -   original try_write clears WRITING bit
-        */
-       if (test_bit(WRITEABLE, &con->state)) {
-               dout(30, "try_write writeable flag got set again, looping just in case\n");
-               goto retry;
-       }
        return;
 }
 
@@ -881,7 +925,7 @@ static void try_accept(struct work_struct *work)
         * hand off to worker threads ,should be able to write, we want to 
         * try to write right away, we may have missed socket state change
         */
-       queue_work(send_wq, &new_con->swork);
+       queue_work(send_wq, &new_con->swork.work);
 done:
         return;
 }
@@ -944,7 +988,8 @@ void ceph_messenger_destroy(struct ceph_messenger *msgr)
  *
  * will take+drop msgr, then connection locks.
  */
-int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg)
+int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg, 
+                 unsigned long timeout)
 {
        struct ceph_connection *con;
        int ret = 0;
@@ -968,7 +1013,7 @@ int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg)
                     ntohl(msg->hdr.dst.addr.ipaddr.sin_addr.s_addr),
                     ntohs(msg->hdr.dst.addr.ipaddr.sin_port));
        }                    
-
+       con->delay = timeout;
        /* queue */
        spin_lock(&con->out_queue_lock);
        msg->hdr.seq = ++con->out_seq;
@@ -980,7 +1025,7 @@ int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg)
                
        if (test_and_set_bit(WRITE_PENDING, &con->state) == 0) {
                dout(30, "ceph_msg_send queuing new swork on %p\n", con);
-               queue_work(send_wq, &con->swork);
+               queue_work(send_wq, &con->swork.work);
                dout(30, "ceph_msg_send queued\n");
        }
 
index b8c81a3b3d9c0bdc60c8b2510ceaadb94de36592..7396fb1d797cab727f7401429eccc72935c06771 100644 (file)
@@ -49,6 +49,9 @@ struct ceph_msg_pos {
        int data_pos;
 };
 
+/* ceph connection fault delay defaults */
+#define BASE_RETRY_INTERVAL    (3U * HZ)
+#define MAX_RETRY_INTERVAL     (5U * 60 * HZ)
 
 /* ceph_connection state bit flags */
 #define NEW            0
@@ -105,9 +108,9 @@ struct ceph_connection {
        struct ceph_msg_pos in_msg_pos;
 
        struct work_struct rwork;               /* received work */
-       struct work_struct swork;               /* send work */
-       int retries;
-       int error;                              /* error on connection */
+       struct delayed_work swork;              /* send work */
+        unsigned long           delay;          /* delay interval */
+        unsigned int            retries;        /* temp track of retries */
 };
 
 
@@ -119,7 +122,8 @@ static __inline__ void ceph_msg_get(struct ceph_msg *msg) {
        atomic_inc(&msg->nref);
 }
 extern void ceph_msg_put(struct ceph_msg *msg);
-extern int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg);
+extern int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg, 
+                        unsigned long timeout);
 
 
 /* encoding/decoding helpers */
index 35984ac636a979e249a6d5de69e7d20832665007..7ae08b27ba19ec9be26ace1b7e1f7a5f4d5ac13b 100644 (file)
@@ -2,6 +2,10 @@
 #include <linux/types.h>
 #include <linux/random.h>
 #include "mon_client.h"
+extern int ceph_mon_debug = 50;
+#define DOUT_VAR ceph_mon_debug
+#define DOUT_PREFIX "mon: "
+#include "super.h"
 
 
 int ceph_monmap_decode(struct ceph_monmap *m, void *p, void *end)
index 3d8fe452205deaa0d35fcc7db103fbf3d89254bd..4dc43607d93b792c7b2bbd2ced43b6b468e339b0 100644 (file)
@@ -1,10 +1,13 @@
-
 #include <linux/slab.h>
 #include <linux/err.h>
 
 #include "crush/crush.h"
 #include "osd_client.h"
 #include "messenger.h"
+extern int ceph_osd_debug = 50;
+#define DOUT_VAR ceph_osd_debug
+#define DOUT_PREFIX "osd: "
+#include "super.h"
 
 /* maps */
 
index a02ac5b61a9ae6aec78d19462f41a51a7a5226a2..bffeb14f4038ef6c9e3f6ecb9fd05c3cd8fabf37 100644 (file)
@@ -1,10 +1,12 @@
-
 #include <linux/module.h>
 #include <linux/parser.h>
 #include <linux/fs.h>
 #include <linux/mount.h>
 #include <linux/seq_file.h>
 #include <linux/string.h>
+extern int ceph_super_debug = 50;
+#define DOUT_VAR ceph_super_debug
+#define DOUT_PREFIX "super: "
 #include "super.h"
 #include "ktcp.h"
 
index b7bf215a0231aac3ad31f06a8ef67cfea3b69c71..eb2bcb9d01d2c8cdd8f6d1a59f524d27d521bc1e 100644 (file)
@@ -6,6 +6,10 @@
 
 #include "client.h"
 
+extern int ceph_debug;
+# define dout(x, args...) do { if (x <= (ceph_debug ? ceph_debug : DOUT_VAR)) printk(KERN_INFO "ceph_" DOUT_PREFIX args); } while (0);
+# define derr(x, args...) do { if (x <= (ceph_debug ? ceph_debug : DOUT_VAR)) printk(KERN_ERR "ceph_" DOUT_PREFIX args); } while (0);
+
 /*
  * mount options
  */