Whamcloud - gitweb
LU-4629 libcfs: fix buffer overflow of string buffer
[fs/lustre-release.git] / lnet / utils / lstclient.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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
19  *
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
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lnet/selftest/conctl.c
37  *
38  * Author: Liang Zhen <liangzhen@clusterfs.com>
39  */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <getopt.h>
44 #include <errno.h>
45 #include <pwd.h>
46 #include <lnet/lnetctl.h>
47 #include <lnet/lnetst.h>
48 #include "../selftest/rpc.h"
49 #include "../selftest/selftest.h"
50
51 static int lstjn_stopping = 0;
52 static int lstjn_intialized = 0;
53
54
55 static struct option lstjn_options[] =
56 {
57         {"sesid",       required_argument,  0, 's' },
58         {"group",       required_argument,  0, 'g' },
59         {"features",    required_argument,  0, 'f' },
60         {"server_mode", no_argument,        0, 'm' },
61         {0,             0,                  0,  0  }
62 };
63
64 void
65 lstjn_stop (int sig)
66 {
67         lstjn_stopping = 1;
68 }
69
70 void
71 lstjn_rpc_done(srpc_client_rpc_t *rpc)
72 {
73         if (!lstjn_intialized)
74                 lstjn_intialized = 1;
75 }
76
77 int
78 lstjn_join_session(char *ses, char *grp, unsigned feats)
79 {
80         lnet_process_id_t  sesid;
81         srpc_client_rpc_t *rpc;
82         srpc_join_reqst_t *req;
83         srpc_join_reply_t *rep;
84         srpc_mksn_reqst_t *sreq;
85         srpc_mksn_reply_t *srep;
86         int                rc;
87
88         sesid.pid = LUSTRE_LNET_PID;
89         sesid.nid = libcfs_str2nid(ses);
90         if (sesid.nid == LNET_NID_ANY) {
91                 fprintf(stderr, "Invalid session NID: %s\n", ses);
92                 return -1;
93         }
94
95         rpc = sfw_create_rpc(sesid, SRPC_SERVICE_JOIN, feats,
96                              0, 0, lstjn_rpc_done, NULL);
97         if (rpc == NULL) {
98                 fprintf(stderr, "Out of memory\n");
99                 return -1;
100         }
101
102         req = &rpc->crpc_reqstmsg.msg_body.join_reqst;
103
104         req->join_sid = LST_INVALID_SID;
105         strncpy(req->join_group, grp, sizeof(req->join_group));
106         req->join_group[sizeof(req->join_group) - 1] = '\0';
107
108         sfw_post_rpc(rpc);
109
110         for (;;) {
111                 rc = selftest_wait_events();
112
113                 if (lstjn_intialized)
114                         break;
115         }
116
117         if (rpc->crpc_status != 0) {
118                 fprintf(stderr, "Failed to send RPC to console: %s\n",
119                         strerror(rpc->crpc_status));
120                 srpc_client_rpc_decref(rpc);
121                 return -1;
122         }
123
124         sfw_unpack_message(&rpc->crpc_replymsg);
125
126         rep = &rpc->crpc_replymsg.msg_body.join_reply;
127         if (rep->join_status != 0) {
128                 fprintf(stderr, "Can't join session %s group %s: %s\n",
129                         ses, grp, strerror(rep->join_status));
130                 srpc_client_rpc_decref(rpc);
131                 return -1;
132         }
133
134         if (rpc->crpc_replymsg.msg_ses_feats != feats) {
135                 /* this can only happen when connecting to old console
136                  * which will ignore features */
137                 fprintf(stderr, "Can't join session %s group %s because "
138                         "feature bits can't match: %x/%x, please set "
139                         "feature bits by -f FEATURES and retry\n",
140                         ses, grp, feats, rpc->crpc_replymsg.msg_ses_feats);
141                 srpc_client_rpc_decref(rpc);
142                 return -1;
143         }
144
145         sreq = &rpc->crpc_reqstmsg.msg_body.mksn_reqst;
146         sreq->mksn_sid     = rep->join_sid;
147         sreq->mksn_force   = 0;
148         strcpy(sreq->mksn_name, rep->join_session);
149
150         srep = &rpc->crpc_replymsg.msg_body.mksn_reply;
151
152         rc = sfw_make_session(sreq, srep);
153         if (rc != 0 || srep->mksn_status != 0) {
154                 fprintf(stderr, "Can't create session: %d, %s\n",
155                         rc, strerror(srep->mksn_status));
156                 srpc_client_rpc_decref(rpc);
157                 return -1;
158         }
159
160         fprintf(stdout, "Session %s, ID: %s, "LPU64"\n",
161                 ses, libcfs_nid2str(rep->join_sid.ses_nid),
162                 rep->join_sid.ses_stamp);
163
164         srpc_client_rpc_decref(rpc);
165
166         return 0;
167 }
168
169 int
170 main(int argc, char **argv)
171 {
172         char    *ses = NULL;
173         char    *grp = NULL;
174         unsigned feats = LST_FEATS_MASK;
175         int      server_mode_flag = 0;
176         int      optidx;
177         int      c;
178         int      rc;
179
180         const char *usage_string =
181                    "Usage: lstclient --sesid ID --group GROUP "
182                    "--features FEATURES [--server_mode]\n";
183
184         while (1) {
185                 c = getopt_long(argc, argv, "s:g:f:m",
186                                 lstjn_options, &optidx);
187
188                 if (c == -1)
189                         break;
190
191                 switch (c) {
192                 case 's':
193                         ses = optarg;
194                         break;
195                 case 'g':
196                         grp = optarg;
197                         break;
198                 case 'f':
199                         feats = strtol(optarg, NULL, 16);
200                         break;
201
202                 case 'm':
203                         server_mode_flag = 1;
204                         break;
205                 default:
206                         fprintf(stderr, "%s", usage_string);
207                         return -1;
208                 }
209         }
210
211         if (optind != argc || grp == NULL || ses == NULL) {
212                 fprintf(stderr, "%s", usage_string);
213                 return -1;
214         }
215
216         if ((feats & ~LST_FEATS_MASK) != 0) {
217                 fprintf(stderr,
218                         "lstclient can't understand these feature bits: %x\n",
219                         (feats & ~LST_FEATS_MASK));
220                 return -1;
221         }
222
223         rc = libcfs_debug_init(5 * 1024 * 1024);
224         if (rc != 0) {
225                 fprintf(stderr, "libcfs_debug_init() failed: %d\n", rc);
226                 return -1;
227         }
228
229         rc = cfs_wi_startup();
230         if (rc != 0) {
231                 fprintf(stderr, "cfs_wi_startup() failed: %d\n", rc);
232                 libcfs_debug_cleanup();
233                 return -1;
234         }
235
236         rc = LNetInit();
237         if (rc != 0) {
238                 fprintf(stderr, "LNetInit() failed: %d\n", rc);
239                 cfs_wi_shutdown();
240                 libcfs_debug_cleanup();
241                 return -1;
242         }
243
244         if (server_mode_flag)
245                 lnet_server_mode();
246
247         rc = lnet_selftest_init();
248         if (rc != 0) {
249                 fprintf(stderr, "Can't startup selftest\n");
250                 LNetFini();
251                 cfs_wi_shutdown();
252                 libcfs_debug_cleanup();
253                 return -1;
254         }
255
256         rc = lstjn_join_session(ses, grp, feats);
257         if (rc != 0)
258                 goto out;
259
260         signal(SIGINT, lstjn_stop);
261
262         fprintf(stdout, "Start handling selftest requests, Ctl-C to stop\n");
263
264         while (!lstjn_stopping) {
265                 selftest_wait_events();
266
267                 if (!sfw_session_removed())
268                         continue;
269
270                 fprintf(stdout, "Session ended\n");
271                 break;
272         }
273
274 out:
275         lnet_selftest_fini();
276
277         LNetFini();
278
279         cfs_wi_shutdown();
280
281         libcfs_debug_cleanup();
282
283         return rc;
284 }