[Pvfs2-cvs] commit by vilayann in pvfs2/src/server: pvfs2-server.c pvfs2-server.h

CVS commit program cvs at parl.clemson.edu
Tue Aug 8 18:43:19 EDT 2006


Update of /anoncvs/pvfs2/src/server
In directory parlweb1:/tmp/cvs-serv5346/src/server

Modified Files:
	pvfs2-server.c pvfs2-server.h 
Log Message:
Drain the server pipeline before exiting. (i.e. finish the requests that were being
serviced before exiting)
Patch adds all server s_op structures into one of 2 lists (unexp list or exp list)
At the time of the signal, if the exp list is empty all requests have been serviced and
it is ok to exit, else we wait until those ops have been serviced or they time out.
This is necessary to prevent FS corruption (admittedly a rare occurrence ;))



Index: pvfs2-server.c
===================================================================
RCS file: /anoncvs/pvfs2/src/server/pvfs2-server.c,v
diff -p -u -r1.218 -r1.219
--- pvfs2-server.c	13 Jul 2006 05:11:42 -0000	1.218
+++ pvfs2-server.c	8 Aug 2006 22:43:19 -0000	1.219
@@ -92,6 +92,11 @@ static struct server_configuration_s ser
 static int signal_recvd_flag = 0;
 static pid_t server_controlling_pid = 0;
 
+/* A list of all serv_op's posted for unexpected message alone */
+static QLIST_HEAD(posted_sop_list);
+/* A list of all serv_op's posted for expected messages alone */
+static QLIST_HEAD(inprogress_sop_list);
+
 /* this is used externally by some server state machines */
 job_context_id server_job_context = -1;
 
@@ -143,6 +148,7 @@ static int server_initialize(
 static int server_initialize_subsystems(
     PINT_server_status_flag *server_status_flag);
 static int server_setup_signal_handlers(void);
+static int server_purge_unexpected_recv_machines(void);
 static int server_setup_process_environment(int background);
 static int server_shutdown(
     PINT_server_status_flag status,
@@ -570,11 +576,23 @@ int main(int argc, char **argv)
     {
         int i, comp_ct = PVFS_SERVER_TEST_COUNT;
 
+        /* IF a signal was received and we have drained all the state machines
+         * that were in progress, then we initiate shutdown of the server
+         */
         if (signal_recvd_flag != 0)
         {
-            ret = 0;
-            siglevel = signal_recvd_flag;
-            goto server_shutdown;
+            /*
+             * If we received a signal, then find out if we can exit now
+             * by checking if all s_ops (for expected messages) have either 
+             * finished or timed out,
+             */
+            if (qlist_empty(&inprogress_sop_list))
+            {
+                ret = 0;
+                siglevel = signal_recvd_flag;
+                goto server_shutdown;
+            }
+            /* not completed. continue... */
         }
 
         ret = job_testcontext(server_job_id_array,
@@ -1550,6 +1568,14 @@ static void server_sig_handler(int sig)
          * server to exit gracefully on the next work cycle
          */
         signal_recvd_flag = sig;
+        /*
+         * iterate through all the machines that we had posted for
+         * unexpected BMI messages and deallocate them.
+         * From now the server will only try and finish operations
+         * that are already in progress, wait for them to timeout
+         * or complete before initiating shutdown
+         */
+        server_purge_unexpected_recv_machines();
     }
 }
 
@@ -1681,6 +1707,8 @@ static int server_post_unexpected_recv(j
         }
         memset(s_op, 0, sizeof(PINT_server_op));
         s_op->op = BMI_UNEXPECTED_OP;
+        /* Add an unexpected s_ops to the list */
+        qlist_add_tail(&s_op->next, &posted_sop_list);
 
         /*
           TODO: Consider the optimization of enabling immediate
@@ -1703,6 +1731,34 @@ static int server_post_unexpected_recv(j
     return ret;
 }
 
+/* server_purge_unexpected_recv_machines()
+ *
+ * removes any s_ops that were posted to field unexpected BMI messages
+ *
+ * returns 0 on success and -PVFS_errno on failure.
+ */
+static int server_purge_unexpected_recv_machines(void)
+{
+    struct qlist_head *tmp = NULL, *tmp2 = NULL;
+
+    if (qlist_empty(&posted_sop_list))
+    {
+        gossip_err("WARNING: Found empty posted operation list!\n");
+        return -PVFS_EINVAL;
+    }
+    qlist_for_each_safe (tmp, tmp2, &posted_sop_list)
+    {
+        PINT_server_op *s_op = qlist_entry(tmp, PINT_server_op, next);
+
+        /* Remove s_op from the posted_sop_list */
+        qlist_del(&s_op->next);
+
+        /* free the operation structure itself */
+        free(s_op);
+    }
+    return 0;
+}
+
 /* server_state_machine_start()
  *
  * initializes fields in the s_op structure and begins execution of
@@ -1741,6 +1797,9 @@ static int server_state_machine_start(
         PVFS_perror_gossip("Error: PINT_decode failure", ret);
         return ret;
     }
+    /* Remove s_op from posted_sop_list and move it to the inprogress_sop_list */
+    qlist_del(&s_op->next);
+    qlist_add_tail(&s_op->next, &inprogress_sop_list);
 
     /* set timestamp on the beginning of this state machine */
     id_gen_fast_register(&tmp_id, s_op);
@@ -1786,6 +1845,8 @@ int server_state_machine_alloc_noreq(
         memset(*new_op, 0, sizeof(PINT_server_op));
         (*new_op)->op = op;
 
+        /* NOTE: We do not add these state machines to the in-progress or posted sop lists */
+
         /* find the state machine for this op type */
         (*new_op)->current_state = PINT_state_machine_locate(*new_op);
 
@@ -1873,6 +1934,9 @@ int server_state_machine_complete(PINT_s
     {
         free(s_op->unexp_bmi_buff.buffer);
     }
+
+    /* Remove s_op from the inprogress_sop_list */
+    qlist_del(&s_op->next);
 
     /* free the operation structure itself */
     free(s_op);

Index: pvfs2-server.h
===================================================================
RCS file: /anoncvs/pvfs2/src/server/pvfs2-server.h,v
diff -p -u -r1.135 -r1.136
--- pvfs2-server.h	13 Jul 2006 05:11:42 -0000	1.135
+++ pvfs2-server.h	8 Aug 2006 22:43:19 -0000	1.136
@@ -326,6 +326,7 @@ struct PINT_server_eattr_op
  */
 typedef struct PINT_server_op
 {
+    struct qlist_head   next; /* used to queue structures used for unexp style messages */
     enum PVFS_server_op op;  /* type of operation that we are servicing */
     /* the following fields are used in state machine processing to keep
      * track of the current state



More information about the Pvfs2-cvs mailing list