Whamcloud - gitweb
LU-1961 build: fix 'dereference before null check' errors
[fs/lustre-release.git] / lnet / selftest / console.c
index 4eaf731..04c1a38 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -28,6 +26,8 @@
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -408,9 +408,9 @@ lstcon_sesrpc_readent(int transop, srpc_msg_t *msg,
 }
 
 static int
-lstcon_group_nodes_add(lstcon_group_t *grp, int count,
-                       lnet_process_id_t *ids_up,
-                       cfs_list_t *result_up)
+lstcon_group_nodes_add(lstcon_group_t *grp,
+                      int count, lnet_process_id_t *ids_up,
+                      unsigned *featp, cfs_list_t *result_up)
 {
         lstcon_rpc_trans_t      *trans;
         lstcon_ndlink_t         *ndl;
@@ -463,6 +463,8 @@ lstcon_group_nodes_add(lstcon_group_t *grp, int count,
 
         rc = lstcon_rpc_trans_interpreter(trans, result_up,
                                           lstcon_sesrpc_readent);
+       *featp = trans->tas_features;
+
         /* destroy all RPGs */
         lstcon_rpc_trans_destroy(trans);
 
@@ -552,8 +554,8 @@ lstcon_group_add(char *name)
 }
 
 int
-lstcon_nodes_add(char *name, int count,
-                 lnet_process_id_t *ids_up, cfs_list_t *result_up)
+lstcon_nodes_add(char *name, int count, lnet_process_id_t *ids_up,
+                unsigned *featp, cfs_list_t *result_up)
 {
         lstcon_group_t         *grp;
         int                     rc;
@@ -575,7 +577,7 @@ lstcon_nodes_add(char *name, int count,
                 return -EBUSY;
         }
 
-        rc = lstcon_group_nodes_add(grp, count, ids_up, result_up);
+       rc = lstcon_group_nodes_add(grp, count, ids_up, featp, result_up);
 
         lstcon_group_put(grp);
 
@@ -1267,7 +1269,7 @@ lstcon_test_add(char *name, int type, int loop, int concur,
                 CDEBUG(D_NET, "Can't change running batch %s\n", name);
                 return rc;
         }
-        
+
         rc = lstcon_group_find(src_name, &src_grp);
         if (rc != 0) {
                 CDEBUG(D_NET, "Can't find group %s\n", src_name);
@@ -1682,8 +1684,8 @@ lstcon_new_session_id(lst_sid_t *sid)
 extern srpc_service_t lstcon_acceptor_service;
 
 int
-lstcon_session_new(char *name, int key,
-                   int timeout,int force, lst_sid_t *sid_up)
+lstcon_session_new(char *name, int key, unsigned feats,
+                  int timeout, int force, lst_sid_t *sid_up)
 {
         int     rc = 0;
         int     i;
@@ -1691,8 +1693,8 @@ lstcon_session_new(char *name, int key,
         if (console_session.ses_state != LST_SESSION_NONE) {
                 /* session exists */
                 if (!force) {
-                        CERROR("Session %s already exists\n",
-                               console_session.ses_name);
+                       CNETERR("Session %s already exists\n",
+                               console_session.ses_name);
                         return -EEXIST;
                 }
 
@@ -1703,9 +1705,25 @@ lstcon_session_new(char *name, int key,
                         return rc;
         }
 
-        for (i = 0; i < LST_GLOBAL_HASHSIZE; i++) {
-                LASSERT (cfs_list_empty(&console_session.ses_ndl_hash[i]));
-        }
+       if ((feats & ~LST_FEATS_MASK) != 0) {
+               CNETERR("Unknown session features %x\n",
+                       (feats & ~LST_FEATS_MASK));
+               return -EINVAL;
+       }
+
+       for (i = 0; i < LST_GLOBAL_HASHSIZE; i++)
+               LASSERT(cfs_list_empty(&console_session.ses_ndl_hash[i]));
+
+       lstcon_new_session_id(&console_session.ses_id);
+
+       console_session.ses_key     = key;
+       console_session.ses_state   = LST_SESSION_ACTIVE;
+       console_session.ses_force   = !!force;
+       console_session.ses_features = feats;
+       console_session.ses_feats_updated = 0;
+       console_session.ses_timeout = (timeout <= 0) ?
+                                     LST_CONSOLE_TIMEOUT : timeout;
+       strcpy(console_session.ses_name, name);
 
         rc = lstcon_batch_add(LST_DEFAULT_BATCH);
         if (rc != 0)
@@ -1721,15 +1739,6 @@ lstcon_session_new(char *name, int key,
                 return rc;
         }
 
-        lstcon_new_session_id(&console_session.ses_id);
-
-        console_session.ses_key     = key;
-        console_session.ses_state   = LST_SESSION_ACTIVE;
-        console_session.ses_force   = !!force;
-        console_session.ses_timeout = (timeout <= 0)? LST_CONSOLE_TIMEOUT:
-                                                      timeout;
-        strcpy(console_session.ses_name, name);
-
         if (cfs_copy_to_user(sid_up, &console_session.ses_id,
                              sizeof(lst_sid_t)) == 0)
                 return rc;
@@ -1740,7 +1749,7 @@ lstcon_session_new(char *name, int key,
 }
 
 int
-lstcon_session_info(lst_sid_t *sid_up, int *key_up,
+lstcon_session_info(lst_sid_t *sid_up, int *key_up, unsigned *featp,
                     lstcon_ndlist_ent_t *ndinfo_up, char *name_up, int len)
 {
         lstcon_ndlist_ent_t *entp;
@@ -1762,7 +1771,10 @@ lstcon_session_info(lst_sid_t *sid_up, int *key_up,
 
         if (cfs_copy_to_user(sid_up, &console_session.ses_id,
                              sizeof(lst_sid_t)) ||
-            cfs_copy_to_user(key_up, &console_session.ses_key, sizeof(int)) ||
+           cfs_copy_to_user(key_up, &console_session.ses_key,
+                            sizeof(*key_up)) ||
+           cfs_copy_to_user(featp, &console_session.ses_features,
+                            sizeof(*featp)) ||
             cfs_copy_to_user(ndinfo_up, entp, sizeof(*entp)) ||
             cfs_copy_to_user(name_up, console_session.ses_name, len))
                 rc = -EFAULT;
@@ -1806,6 +1818,7 @@ lstcon_session_end()
         console_session.ses_state = LST_SESSION_NONE;
         console_session.ses_key   = 0;
         console_session.ses_force = 0;
+       console_session.ses_feats_updated = 0;
 
         /* destroy all batches */
         while (!cfs_list_empty(&console_session.ses_bat_list)) {
@@ -1833,6 +1846,38 @@ lstcon_session_end()
         return rc;
 }
 
+int
+lstcon_session_feats_check(unsigned feats)
+{
+       int rc = 0;
+
+       if ((feats & ~LST_FEATS_MASK) != 0) {
+               CERROR("Can't support these features: %x\n",
+                      (feats & ~LST_FEATS_MASK));
+               return -EPROTO;
+       }
+
+       spin_lock(&console_session.ses_rpc_lock);
+
+       if (!console_session.ses_feats_updated) {
+               console_session.ses_feats_updated = 1;
+               console_session.ses_features = feats;
+       }
+
+       if (console_session.ses_features != feats)
+               rc = -EPROTO;
+
+       spin_unlock(&console_session.ses_rpc_lock);
+
+       if (rc != 0) {
+               CERROR("remote features %x do not match with "
+                      "session features %x of console\n",
+                      feats, console_session.ses_features);
+       }
+
+       return rc;
+}
+
 static int
 lstcon_acceptor_handle (srpc_server_rpc_t *rpc)
 {
@@ -1846,7 +1891,7 @@ lstcon_acceptor_handle (srpc_server_rpc_t *rpc)
 
         sfw_unpack_message(req);
 
-        cfs_mutex_down(&console_session.ses_mutex);
+       mutex_lock(&console_session.ses_mutex);
 
         jrep->join_sid = console_session.ses_id;
 
@@ -1855,6 +1900,11 @@ lstcon_acceptor_handle (srpc_server_rpc_t *rpc)
                 goto out;
         }
 
+       if (lstcon_session_feats_check(req->msg_ses_feats) != 0) {
+               jrep->join_status = EPROTO;
+               goto out;
+       }
+
         if (jreq->join_sid.ses_nid != LNET_NID_ANY &&
              !lstcon_session_match(jreq->join_sid)) {
                 jrep->join_status = EBUSY;
@@ -1902,10 +1952,11 @@ lstcon_acceptor_handle (srpc_server_rpc_t *rpc)
         jrep->join_status  = 0;
 
 out:
+       rep->msg_ses_feats = console_session.ses_features;
         if (grp != NULL)
                 lstcon_group_put(grp);
 
-        cfs_mutex_up(&console_session.ses_mutex);
+       mutex_unlock(&console_session.ses_mutex);
 
         return rc;
 }
@@ -1917,7 +1968,7 @@ void lstcon_init_acceptor_service(void)
         lstcon_acceptor_service.sv_name    = "join session";
         lstcon_acceptor_service.sv_handler = lstcon_acceptor_handle;
         lstcon_acceptor_service.sv_id      = SRPC_SERVICE_JOIN;
-        lstcon_acceptor_service.sv_concur  = SFW_SERVICE_CONCURRENCY;
+       lstcon_acceptor_service.sv_wi_total = SFW_FRWK_WI_MAX;
 }
 
 extern int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_data *data);
@@ -1929,19 +1980,20 @@ int
 lstcon_console_init(void)
 {
         int     i;
-        int     n;
         int     rc;
 
         memset(&console_session, 0, sizeof(lstcon_session_t));
 
-        console_session.ses_id      = LST_INVALID_SID;
-        console_session.ses_state   = LST_SESSION_NONE;
-        console_session.ses_timeout = 0;
-        console_session.ses_force   = 0;
-        console_session.ses_expired = 0;
-        console_session.ses_laststamp = cfs_time_current_sec();   
+       console_session.ses_id              = LST_INVALID_SID;
+       console_session.ses_state           = LST_SESSION_NONE;
+       console_session.ses_timeout         = 0;
+       console_session.ses_force           = 0;
+       console_session.ses_expired         = 0;
+       console_session.ses_feats_updated   = 0;
+       console_session.ses_features        = LST_FEATS_MASK;
+       console_session.ses_laststamp       = cfs_time_current_sec();
 
-        cfs_init_mutex(&console_session.ses_mutex);
+       mutex_init(&console_session.ses_mutex);
 
         CFS_INIT_LIST_HEAD(&console_session.ses_ndl_list);
         CFS_INIT_LIST_HEAD(&console_session.ses_grp_list);
@@ -1968,8 +2020,9 @@ lstcon_console_init(void)
                 return rc;
         }
 
-        n = srpc_service_add_buffers(&lstcon_acceptor_service, SFW_POST_BUFFERS);
-        if (n != SFW_POST_BUFFERS) {
+       rc = srpc_service_add_buffers(&lstcon_acceptor_service,
+                                     lstcon_acceptor_service.sv_wi_total);
+       if (rc != 0) {
                 rc = -ENOMEM;
                 goto out;
         }
@@ -2000,7 +2053,7 @@ lstcon_console_fini(void)
 
         libcfs_deregister_ioctl(&lstcon_ioctl_handler);
 
-        cfs_mutex_down(&console_session.ses_mutex);
+       mutex_lock(&console_session.ses_mutex);
 
         srpc_shutdown_service(&lstcon_acceptor_service);
         srpc_remove_service(&lstcon_acceptor_service);
@@ -2010,7 +2063,7 @@ lstcon_console_fini(void)
 
         lstcon_rpc_module_fini();
 
-        cfs_mutex_up(&console_session.ses_mutex);
+       mutex_unlock(&console_session.ses_mutex);
 
         LASSERT (cfs_list_empty(&console_session.ses_ndl_list));
         LASSERT (cfs_list_empty(&console_session.ses_grp_list));