4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lnet/selftest/conctl.c
38 * Test client & Server
40 * Author: Liang Zhen <liangzhen@clusterfs.com>
45 #define LST_PING_TEST_MAGIC 0xbabeface
47 static int ping_srv_workitems
= SFW_TEST_WI_MAX
;
48 module_param(ping_srv_workitems
, int, 0644);
49 MODULE_PARM_DESC(ping_srv_workitems
, "# PING server workitems");
52 spinlock_t pnd_lock
; /* serialize */
53 int pnd_counter
; /* sequence counter */
56 static lst_ping_data_t lst_ping_data
;
59 ping_client_init(sfw_test_instance_t
*tsi
)
61 sfw_session_t
*sn
= tsi
->tsi_batch
->bat_session
;
63 LASSERT(tsi
->tsi_is_client
);
64 LASSERT(sn
&& (sn
->sn_features
& ~LST_FEATS_MASK
) == 0);
66 spin_lock_init(&lst_ping_data
.pnd_lock
);
67 lst_ping_data
.pnd_counter
= 0;
73 ping_client_fini(sfw_test_instance_t
*tsi
)
75 sfw_session_t
*sn
= tsi
->tsi_batch
->bat_session
;
79 LASSERT(tsi
->tsi_is_client
);
81 errors
= atomic_read(&sn
->sn_ping_errors
);
83 CWARN("%d pings have failed.\n", errors
);
85 CDEBUG(D_NET
, "Ping test finished OK.\n");
89 ping_client_prep_rpc(sfw_test_unit_t
*tsu
,
90 lnet_process_id_t dest
, srpc_client_rpc_t
**rpc
)
92 srpc_ping_reqst_t
*req
;
93 sfw_test_instance_t
*tsi
= tsu
->tsu_instance
;
94 sfw_session_t
*sn
= tsi
->tsi_batch
->bat_session
;
99 LASSERT((sn
->sn_features
& ~LST_FEATS_MASK
) == 0);
101 rc
= sfw_create_test_rpc(tsu
, dest
, sn
->sn_features
, 0, 0, rpc
);
105 req
= &(*rpc
)->crpc_reqstmsg
.msg_body
.ping_reqst
;
107 req
->pnr_magic
= LST_PING_TEST_MAGIC
;
109 spin_lock(&lst_ping_data
.pnd_lock
);
110 req
->pnr_seq
= lst_ping_data
.pnd_counter
++;
111 spin_unlock(&lst_ping_data
.pnd_lock
);
113 ktime_get_real_ts64(&ts
);
114 req
->pnr_time_sec
= ts
.tv_sec
;
115 req
->pnr_time_usec
= ts
.tv_nsec
/ NSEC_PER_USEC
;
121 ping_client_done_rpc(sfw_test_unit_t
*tsu
, srpc_client_rpc_t
*rpc
)
123 sfw_test_instance_t
*tsi
= tsu
->tsu_instance
;
124 sfw_session_t
*sn
= tsi
->tsi_batch
->bat_session
;
125 srpc_ping_reqst_t
*reqst
= &rpc
->crpc_reqstmsg
.msg_body
.ping_reqst
;
126 srpc_ping_reply_t
*reply
= &rpc
->crpc_replymsg
.msg_body
.ping_reply
;
127 struct timespec64 ts
;
131 if (rpc
->crpc_status
!= 0) {
132 if (!tsi
->tsi_stopping
) /* rpc could have been aborted */
133 atomic_inc(&sn
->sn_ping_errors
);
134 CERROR("Unable to ping %s (%d): %d\n",
135 libcfs_id2str(rpc
->crpc_dest
),
136 reqst
->pnr_seq
, rpc
->crpc_status
);
140 if (rpc
->crpc_replymsg
.msg_magic
!= SRPC_MSG_MAGIC
) {
141 __swab32s(&reply
->pnr_seq
);
142 __swab32s(&reply
->pnr_magic
);
143 __swab32s(&reply
->pnr_status
);
146 if (reply
->pnr_magic
!= LST_PING_TEST_MAGIC
) {
147 rpc
->crpc_status
= -EBADMSG
;
148 atomic_inc(&sn
->sn_ping_errors
);
149 CERROR("Bad magic %u from %s, %u expected.\n",
150 reply
->pnr_magic
, libcfs_id2str(rpc
->crpc_dest
),
151 LST_PING_TEST_MAGIC
);
155 if (reply
->pnr_seq
!= reqst
->pnr_seq
) {
156 rpc
->crpc_status
= -EBADMSG
;
157 atomic_inc(&sn
->sn_ping_errors
);
158 CERROR("Bad seq %u from %s, %u expected.\n",
159 reply
->pnr_seq
, libcfs_id2str(rpc
->crpc_dest
),
164 ktime_get_real_ts64(&ts
);
165 CDEBUG(D_NET
, "%d reply in %u usec\n", reply
->pnr_seq
,
166 (unsigned)((ts
.tv_sec
- reqst
->pnr_time_sec
) * 1000000 +
167 (ts
.tv_nsec
/ NSEC_PER_USEC
- reqst
->pnr_time_usec
)));
172 ping_server_handle(struct srpc_server_rpc
*rpc
)
174 struct srpc_service
*sv
= rpc
->srpc_scd
->scd_svc
;
175 srpc_msg_t
*reqstmsg
= &rpc
->srpc_reqstbuf
->buf_msg
;
176 srpc_msg_t
*replymsg
= &rpc
->srpc_replymsg
;
177 srpc_ping_reqst_t
*req
= &reqstmsg
->msg_body
.ping_reqst
;
178 srpc_ping_reply_t
*rep
= &rpc
->srpc_replymsg
.msg_body
.ping_reply
;
180 LASSERT(sv
->sv_id
== SRPC_SERVICE_PING
);
182 if (reqstmsg
->msg_magic
!= SRPC_MSG_MAGIC
) {
183 LASSERT(reqstmsg
->msg_magic
== __swab32(SRPC_MSG_MAGIC
));
185 __swab32s(&req
->pnr_seq
);
186 __swab32s(&req
->pnr_magic
);
187 __swab64s(&req
->pnr_time_sec
);
188 __swab64s(&req
->pnr_time_usec
);
190 LASSERT(reqstmsg
->msg_type
== srpc_service2request(sv
->sv_id
));
192 if (req
->pnr_magic
!= LST_PING_TEST_MAGIC
) {
193 CERROR("Unexpected magic %08x from %s\n",
194 req
->pnr_magic
, libcfs_id2str(rpc
->srpc_peer
));
198 rep
->pnr_seq
= req
->pnr_seq
;
199 rep
->pnr_magic
= LST_PING_TEST_MAGIC
;
201 if ((reqstmsg
->msg_ses_feats
& ~LST_FEATS_MASK
) != 0) {
202 replymsg
->msg_ses_feats
= LST_FEATS_MASK
;
203 rep
->pnr_status
= EPROTO
;
207 replymsg
->msg_ses_feats
= reqstmsg
->msg_ses_feats
;
209 CDEBUG(D_NET
, "Get ping %d from %s\n",
210 req
->pnr_seq
, libcfs_id2str(rpc
->srpc_peer
));
214 sfw_test_client_ops_t ping_test_client
;
215 void ping_init_test_client(void)
217 ping_test_client
.tso_init
= ping_client_init
;
218 ping_test_client
.tso_fini
= ping_client_fini
;
219 ping_test_client
.tso_prep_rpc
= ping_client_prep_rpc
;
220 ping_test_client
.tso_done_rpc
= ping_client_done_rpc
;
223 srpc_service_t ping_test_service
;
224 void ping_init_test_service(void)
226 ping_test_service
.sv_id
= SRPC_SERVICE_PING
;
227 ping_test_service
.sv_name
= "ping_test";
228 ping_test_service
.sv_handler
= ping_server_handle
;
229 ping_test_service
.sv_wi_total
= ping_srv_workitems
;