Whamcloud - gitweb
LU-16509 lnet: quash memcpy WARN_ONCE false positive
[fs/lustre-release.git] / lnet / utils / wirecheck.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.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2014, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  */
31
32 #ifndef _GNU_SOURCE
33 #define _GNU_SOURCE
34 #endif
35
36 #include <stddef.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <sys/types.h>
42 #include <sys/wait.h>
43 #include <linux/lnet/lnet-types.h>
44
45 #ifndef HAVE_STRNLEN
46 #define strnlen(s, i) strlen(s)
47 #endif
48
49 #define BLANK_LINE()                            \
50 do {                                            \
51         printf ("\n");                          \
52 } while (0)
53
54 #define COMMENT(c)                              \
55 do {                                            \
56         printf ("        /* "c" */\n");         \
57 } while (0)
58
59 #define STRINGIFY(a) #a
60
61 #define CHECK_BUILD_TEST(a)                                     \
62         printf("        BUILD_BUG_ON("#a");\n")
63
64 #define CHECK_DEFINE(a)                                                 \
65 do {                                                                    \
66         printf ("        BUILD_BUG_ON("#a" != "STRINGIFY(a)");\n");     \
67 } while (0)
68
69 #define CHECK_VALUE(a)                                     \
70 do {                                                       \
71         printf ("        BUILD_BUG_ON("#a" != %d);\n", a); \
72 } while (0)
73
74 #define CHECK_MEMBER_OFFSET(s,m)                \
75 do {                                            \
76         CHECK_VALUE((int)offsetof(s, m));       \
77 } while (0)
78
79 #define CHECK_MEMBER_SIZEOF(s,m)                \
80 do {                                            \
81         CHECK_VALUE((int)sizeof(((s *)0)->m));  \
82 } while (0)
83
84 #define CHECK_MEMBER_IS_FLEXIBLE(s, m)                  \
85 do {                                                                    \
86         CHECK_MEMBER_OFFSET(s, m);                                      \
87         CHECK_BUILD_TEST(offsetof(struct s, m) != sizeof(struct s));    \
88 } while (0)
89
90 #define CHECK_MEMBER(s,m)                       \
91 do {                                            \
92         CHECK_MEMBER_OFFSET(s, m);              \
93         CHECK_MEMBER_SIZEOF(s, m);              \
94 } while (0)
95
96 #define CHECK_STRUCT(s)                         \
97 do {                                            \
98         BLANK_LINE ();                          \
99         COMMENT ("Checks for struct "#s);       \
100         CHECK_VALUE((int)sizeof(s));            \
101 } while (0)
102
103 void
104 check_lnet_handle_wire(void)
105 {
106         CHECK_STRUCT(struct lnet_handle_wire);
107         CHECK_MEMBER(struct lnet_handle_wire, wh_interface_cookie);
108         CHECK_MEMBER(struct lnet_handle_wire, wh_object_cookie);
109 }
110
111 void
112 check_lnet_magicversion (void)
113 {
114         CHECK_STRUCT(struct lnet_magicversion);
115         CHECK_MEMBER(struct lnet_magicversion, magic);
116         CHECK_MEMBER(struct lnet_magicversion, version_major);
117         CHECK_MEMBER(struct lnet_magicversion, version_minor);
118 }
119
120 void
121 check_lnet_hdr_nid4(void)
122 {
123         CHECK_STRUCT(struct _lnet_hdr_nid4);
124         CHECK_MEMBER(struct _lnet_hdr_nid4, dest_nid);
125         CHECK_MEMBER(struct _lnet_hdr_nid4, src_nid);
126         CHECK_MEMBER(struct _lnet_hdr_nid4, dest_pid);
127         CHECK_MEMBER(struct _lnet_hdr_nid4, src_pid);
128         CHECK_MEMBER(struct _lnet_hdr_nid4, type);
129         CHECK_MEMBER(struct _lnet_hdr_nid4, payload_length);
130         CHECK_MEMBER(struct _lnet_hdr_nid4, msg);
131
132         BLANK_LINE ();
133         COMMENT ("Ack");
134         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.ack.dst_wmd);
135         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.ack.match_bits);
136         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.ack.mlength);
137
138         BLANK_LINE ();
139         COMMENT ("Put");
140         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.put.ack_wmd);
141         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.put.match_bits);
142         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.put.hdr_data);
143         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.put.ptl_index);
144         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.put.offset);
145
146         BLANK_LINE ();
147         COMMENT ("Get");
148         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.get.return_wmd);
149         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.get.match_bits);
150         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.get.ptl_index);
151         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.get.src_offset);
152         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.get.sink_length);
153
154         BLANK_LINE ();
155         COMMENT ("Reply");
156         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.reply.dst_wmd);
157
158         BLANK_LINE ();
159         COMMENT ("Hello");
160         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.hello.incarnation);
161         CHECK_MEMBER(struct _lnet_hdr_nid4, msg.hello.type);
162 }
163
164 void
165 check_lnet_ni_status(void)
166 {
167         BLANK_LINE();
168         COMMENT("Checks for struct lnet_ni_status and related constants");
169
170         CHECK_DEFINE(LNET_NI_STATUS_INVALID);
171         CHECK_DEFINE(LNET_NI_STATUS_UP);
172         CHECK_DEFINE(LNET_NI_STATUS_DOWN);
173
174         CHECK_STRUCT(struct lnet_ni_status);
175         CHECK_MEMBER(struct lnet_ni_status, ns_nid);
176         CHECK_MEMBER(struct lnet_ni_status, ns_status);
177         CHECK_MEMBER(struct lnet_ni_status, ns_msg_size);
178
179         CHECK_STRUCT(struct lnet_ni_large_status);
180         CHECK_MEMBER(struct lnet_ni_large_status, ns_status);
181         CHECK_MEMBER(struct lnet_ni_large_status, ns_nid);
182 }
183
184 void
185 check_lnet_ping_info(void)
186 {
187         BLANK_LINE();
188         COMMENT("Checks for struct lnet_ping_info and related constants");
189
190         CHECK_DEFINE(LNET_PROTO_PING_MAGIC);
191         CHECK_VALUE(LNET_PING_FEAT_INVAL);
192         CHECK_VALUE(LNET_PING_FEAT_BASE);
193         CHECK_VALUE(LNET_PING_FEAT_NI_STATUS);
194         CHECK_VALUE(LNET_PING_FEAT_RTE_DISABLED);
195         CHECK_VALUE(LNET_PING_FEAT_MULTI_RAIL);
196         CHECK_VALUE(LNET_PING_FEAT_DISCOVERY);
197         CHECK_VALUE(LNET_PING_FEAT_LARGE_ADDR);
198         CHECK_VALUE(LNET_PING_FEAT_PRIMARY_LARGE);
199         CHECK_VALUE(LNET_PING_FEAT_BITS);
200
201         CHECK_STRUCT(struct lnet_ping_info);
202         CHECK_MEMBER(struct lnet_ping_info, pi_magic);
203         CHECK_MEMBER(struct lnet_ping_info, pi_features);
204         CHECK_MEMBER(struct lnet_ping_info, pi_pid);
205         CHECK_MEMBER(struct lnet_ping_info, pi_nnis);
206         CHECK_MEMBER_IS_FLEXIBLE(struct lnet_ping_info, pi_ni);
207 }
208
209 void
210 system_string(char *cmdline, char *str, int len)
211 {
212         int   fds[2];
213         int   rc;
214         pid_t pid;
215
216         rc = pipe (fds);
217         if (rc != 0)
218                 abort ();
219
220         pid = fork ();
221         if (pid == 0) {
222                 /* child */
223                 int   fd = fileno(stdout);
224
225                 rc = dup2(fds[1], fd);
226                 if (rc != fd)
227                         abort();
228
229                 exit(system(cmdline));
230                 /* notreached */
231         } else if ((int)pid < 0) {
232                 abort();
233         } else {
234                 FILE *f = fdopen (fds[0], "r");
235
236                 if (f == NULL)
237                         abort();
238
239                 close(fds[1]);
240
241                 if (fgets(str, len, f) == NULL)
242                         abort();
243
244                 if (waitpid(pid, &rc, 0) != pid)
245                         abort();
246
247                 if (!WIFEXITED(rc) ||
248                     WEXITSTATUS(rc) != 0)
249                         abort();
250
251                 if (strnlen(str, len) == len)
252                         str[len - 1] = 0;
253
254                 if (str[strlen(str) - 1] == '\n')
255                         str[strlen(str) - 1] = 0;
256
257                 fclose(f);
258         }
259 }
260
261 int
262 main (int argc, char **argv)
263 {
264         char unameinfo[256];
265         char gccinfo[256];
266
267         system_string("uname -a", unameinfo, sizeof(unameinfo));
268         system_string("gcc -v 2>&1 | tail -1", gccinfo, sizeof(gccinfo));
269
270         printf ("void lnet_assert_wire_constants (void)\n"
271                 "{\n"
272                 "        /* Wire protocol assertions generated by 'wirecheck'\n"
273                 "         * running on %s\n"
274                 "         * with %s */\n"
275                 "\n", unameinfo, gccinfo);
276
277         BLANK_LINE ();
278
279         COMMENT ("Constants...");
280
281         CHECK_DEFINE (LNET_PROTO_RA_MAGIC);
282
283         CHECK_DEFINE (LNET_PROTO_TCP_MAGIC);
284         CHECK_DEFINE (LNET_PROTO_TCP_VERSION_MAJOR);
285         CHECK_DEFINE (LNET_PROTO_TCP_VERSION_MINOR);
286
287         CHECK_VALUE (LNET_MSG_ACK);
288         CHECK_VALUE (LNET_MSG_PUT);
289         CHECK_VALUE (LNET_MSG_GET);
290         CHECK_VALUE (LNET_MSG_REPLY);
291         CHECK_VALUE (LNET_MSG_HELLO);
292
293         check_lnet_handle_wire();
294         check_lnet_magicversion();
295         check_lnet_hdr_nid4();
296         check_lnet_ni_status();
297         check_lnet_ping_info();
298
299         printf ("}\n\n");
300
301         return (0);
302 }