}
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;
rc = lstcon_rpc_trans_interpreter(trans, result_up,
lstcon_sesrpc_readent);
+ *featp = trans->tas_features;
+
/* destroy all RPGs */
lstcon_rpc_trans_destroy(trans);
}
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;
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);
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);
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;
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;
}
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)
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;
}
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;
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;
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)) {
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;
+ }
+
+ cfs_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;
+
+ cfs_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)
{
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;
jrep->join_status = 0;
out:
+ rep->msg_ses_feats = console_session.ses_features;
if (grp != NULL)
lstcon_group_put(grp);
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_mutex_init(&console_session.ses_mutex);