Print this page
10703 smatch unreachable code checking needs reworking
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/scsi/libscsi/common/scsi_subr.c
+++ new/usr/src/lib/scsi/libscsi/common/scsi_subr.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 +/*
27 + * Copyright 2019 Joyent, Inc.
28 + */
29 +
26 30 #include <sys/types.h>
27 31 #include <sys/scsi/generic/commands.h>
28 32 #include <sys/scsi/impl/spc3_types.h>
29 33
30 34 #include <stddef.h>
31 35 #include <stdlib.h>
32 36 #include <string.h>
33 37 #include <strings.h>
34 38 #include <alloca.h>
35 39 #include <stdio.h>
36 40 #include <unistd.h>
37 41 #include <dlfcn.h>
38 42
39 43 #include <scsi/libscsi.h>
40 44 #include "libscsi_impl.h"
41 45
42 46 int
43 47 libscsi_assert(const char *expr, const char *file, int line)
44 48 {
45 49 char *msg;
46 50 size_t len;
47 51
48 52 len = snprintf(NULL, 0,
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
49 53 "ABORT: \"%s\", line %d: assertion failed: %s\n", file, line, expr);
50 54
51 55 msg = alloca(len + 1);
52 56
53 57 (void) snprintf(msg, len + 1,
54 58 "ABORT: \"%s\", line %d: assertion failed: %s\n", file, line, expr);
55 59
56 60 (void) write(STDERR_FILENO, msg, strlen(msg));
57 61
58 62 abort();
59 - _exit(1);
60 -
61 63 /*NOTREACHED*/
62 - return (0);
63 64 }
64 65
65 66 int
66 67 libscsi_set_errno(libscsi_hdl_t *hp, libscsi_errno_t err)
67 68 {
68 69 hp->lsh_errno = err;
69 70 hp->lsh_errmsg[0] = '\0';
70 71
71 72 return (-1);
72 73 }
73 74
74 75 /*
75 76 * Internal routine for setting both _ue_errno and _ue_errmsg. We save
76 77 * and restore the UNIX errno across this routing so the caller can use either
77 78 * libscsi_set_errno(), libscsi_error(), or libscsi_verror() without this value
78 79 * changing.
79 80 */
80 81 int
81 82 libscsi_verror(libscsi_hdl_t *hp, libscsi_errno_t err, const char *fmt,
82 83 va_list ap)
83 84 {
84 85 size_t n;
85 86 char *errmsg;
86 87
87 88 /*
88 89 * To allow the existing error message to itself be used in an error
89 90 * message, we put the new error message into a buffer on the stack,
90 91 * and then copy it into lsh_errmsg. We also need to set the errno,
91 92 * but because the call to libscsi_set_errno() is destructive to
92 93 * lsh_errmsg, we do this after we print into our temporary buffer
93 94 * (in case _libscsi_errmsg is part of the error message) and before we
94 95 * copy the temporary buffer on to _libscsi_errmsg (to prevent our new
95 96 * message from being nuked by the call to libscsi_set_errno()).
96 97 */
97 98 errmsg = alloca(sizeof (hp->lsh_errmsg));
98 99 (void) vsnprintf(errmsg, sizeof (hp->lsh_errmsg), fmt, ap);
99 100 (void) libscsi_set_errno(hp, err);
100 101
101 102 n = strlen(errmsg);
102 103
103 104 if (n != 0 && errmsg[n - 1] == '\n')
104 105 errmsg[n - 1] = '\0';
105 106
106 107 bcopy(errmsg, hp->lsh_errmsg, n + 1);
107 108
108 109 return (-1);
109 110 }
110 111
111 112 /*PRINTFLIKE3*/
112 113 int
113 114 libscsi_error(libscsi_hdl_t *hp, libscsi_errno_t err, const char *fmt, ...)
114 115 {
115 116 va_list ap;
116 117
117 118 if (fmt == NULL)
118 119 return (libscsi_set_errno(hp, err));
119 120
120 121 va_start(ap, fmt);
121 122 err = libscsi_verror(hp, err, fmt, ap);
122 123 va_end(ap);
123 124
124 125 return (err);
125 126 }
126 127
127 128 libscsi_errno_t
128 129 libscsi_errno(libscsi_hdl_t *hp)
129 130 {
130 131 return (hp->lsh_errno);
131 132 }
132 133
133 134 const char *
134 135 libscsi_errmsg(libscsi_hdl_t *hp)
135 136 {
136 137 if (hp->lsh_errmsg[0] == '\0')
137 138 (void) strlcpy(hp->lsh_errmsg, libscsi_strerror(hp->lsh_errno),
138 139 sizeof (hp->lsh_errmsg));
139 140
140 141 return (hp->lsh_errmsg);
141 142 }
142 143
143 144 void *
144 145 libscsi_alloc(libscsi_hdl_t *hp, size_t size)
145 146 {
146 147 void *mem;
147 148
148 149 if (size == 0) {
149 150 (void) libscsi_set_errno(hp, ESCSI_ZERO_LENGTH);
150 151 return (NULL);
151 152 }
152 153
153 154 if ((mem = malloc(size)) == NULL)
154 155 (void) libscsi_set_errno(hp, ESCSI_NOMEM);
155 156
156 157 return (mem);
157 158 }
158 159
159 160 void *
160 161 libscsi_zalloc(libscsi_hdl_t *hp, size_t size)
161 162 {
162 163 void *mem;
163 164
164 165 if ((mem = libscsi_alloc(hp, size)) == NULL)
165 166 return (NULL);
166 167
167 168 bzero(mem, size);
168 169
169 170 return (mem);
170 171 }
171 172
172 173 char *
173 174 libscsi_strdup(libscsi_hdl_t *hp, const char *str)
174 175 {
175 176 size_t len = strlen(str);
176 177 char *dup = libscsi_alloc(hp, len + 1);
177 178
178 179 if (dup == NULL)
179 180 return (NULL);
180 181
181 182 return (strcpy(dup, str));
182 183 }
183 184
184 185 /*ARGSUSED*/
185 186 void
186 187 libscsi_free(libscsi_hdl_t *hp, void *ptr)
187 188 {
188 189 free(ptr);
189 190 }
190 191
191 192 libscsi_hdl_t *
192 193 libscsi_init(uint_t version, libscsi_errno_t *errp)
193 194 {
194 195 libscsi_hdl_t *hp;
195 196
196 197 if ((hp = malloc(sizeof (libscsi_hdl_t))) == NULL) {
197 198 if (errp != NULL)
198 199 *errp = ESCSI_NOMEM;
199 200 return (NULL);
200 201 }
201 202
202 203 bzero(hp, sizeof (libscsi_hdl_t));
203 204 hp->lsh_version = version;
204 205
205 206 return (hp);
206 207 }
207 208
208 209 void
209 210 libscsi_fini(libscsi_hdl_t *hp)
210 211 {
211 212 libscsi_engine_impl_t *eip, *neip;
212 213
213 214 if (hp == NULL)
214 215 return;
215 216
216 217 ASSERT(hp->lsh_targets == 0);
217 218
218 219 for (eip = hp->lsh_engines; eip != NULL; eip = neip) {
219 220 neip = eip->lsei_next;
220 221 (void) dlclose(eip->lsei_dl_hdl);
221 222 libscsi_free(hp, eip);
222 223 }
223 224
224 225 free(hp);
225 226 }
226 227
227 228 size_t
228 229 libscsi_cmd_cdblen(libscsi_hdl_t *hp, uint8_t cmd)
229 230 {
230 231 size_t sz;
231 232
232 233 switch (CDB_GROUPID(cmd)) {
233 234 case CDB_GROUPID_0:
234 235 sz = CDB_GROUP0;
235 236 break;
236 237 case CDB_GROUPID_1:
237 238 sz = CDB_GROUP1;
238 239 break;
239 240 case CDB_GROUPID_2:
240 241 sz = CDB_GROUP2;
241 242 break;
242 243 case CDB_GROUPID_3:
243 244 sz = CDB_GROUP3;
244 245 break;
245 246 case CDB_GROUPID_4:
246 247 sz = CDB_GROUP4;
247 248 break;
248 249 case CDB_GROUPID_5:
249 250 sz = CDB_GROUP5;
250 251 break;
251 252 case CDB_GROUPID_6:
252 253 sz = CDB_GROUP6;
253 254 break;
254 255 case CDB_GROUPID_7:
255 256 sz = CDB_GROUP7;
256 257 break;
257 258 default:
258 259 sz = 0;
259 260 }
260 261
261 262 if (sz == 0)
262 263 (void) libscsi_error(hp, ESCSI_BADCMD,
263 264 "unknown or unsupported command %u", cmd);
264 265
265 266 return (sz);
266 267 }
267 268
268 269 static char *
269 270 libscsi_process_inquiry_string(libscsi_hdl_t *hp, const char *raw, size_t len)
270 271 {
271 272 char *buf;
272 273
273 274 buf = alloca(len + 1);
274 275 bcopy(raw, buf, len);
275 276
276 277 for (; len > 0; len--) {
277 278 if (buf[len - 1] != ' ')
278 279 break;
279 280 }
280 281
281 282 buf[len] = '\0';
282 283
283 284 return (libscsi_strdup(hp, buf));
284 285 }
285 286
286 287 /*
287 288 * As part of basic initialization, we always retrieve the INQUIRY information
288 289 * to have the vendor/product/revision information available for all consumers.
289 290 */
290 291 int
291 292 libscsi_get_inquiry(libscsi_hdl_t *hp, libscsi_target_t *tp)
292 293 {
293 294 libscsi_action_t *ap;
294 295 spc3_inquiry_cdb_t *cp;
295 296 spc3_inquiry_data_t data;
296 297 size_t len;
297 298
298 299 if ((ap = libscsi_action_alloc(hp, SPC3_CMD_INQUIRY,
299 300 LIBSCSI_AF_READ | LIBSCSI_AF_SILENT | LIBSCSI_AF_DIAGNOSE, &data,
300 301 offsetof(spc3_inquiry_data_t, id_vs_36[0]))) == NULL)
301 302 return (-1);
302 303
303 304 cp = (spc3_inquiry_cdb_t *)libscsi_action_get_cdb(ap);
304 305
305 306 SCSI_WRITE16(&cp->ic_allocation_length,
306 307 offsetof(spc3_inquiry_data_t, id_vs_36[0]));
307 308
308 309 if (libscsi_exec(ap, tp) != 0 ||
309 310 libscsi_action_get_status(ap) != 0) {
310 311 libscsi_action_free(ap);
311 312 return (libscsi_set_errno(hp, ESCSI_INQUIRY_FAILED));
312 313 }
313 314
314 315 (void) libscsi_action_get_buffer(ap, NULL, NULL, &len);
315 316 libscsi_action_free(ap);
316 317
317 318 if (len < offsetof(spc3_inquiry_data_t, id_vs_36))
318 319 return (libscsi_set_errno(hp, ESCSI_INQUIRY_FAILED));
319 320
320 321 if ((tp->lst_vendor = libscsi_process_inquiry_string(hp,
321 322 data.id_vendor_id, sizeof (data.id_vendor_id))) == NULL ||
322 323 (tp->lst_product = libscsi_process_inquiry_string(hp,
323 324 data.id_product_id, sizeof (data.id_product_id))) == NULL ||
324 325 (tp->lst_revision = libscsi_process_inquiry_string(hp,
325 326 data.id_product_revision,
326 327 sizeof (data.id_product_revision))) == NULL) {
327 328 return (-1);
328 329 }
329 330
330 331 return (0);
331 332 }
332 333
333 334 const char *
334 335 libscsi_vendor(libscsi_target_t *tp)
335 336 {
336 337 return (tp->lst_vendor);
337 338 }
338 339
339 340 const char *
340 341 libscsi_product(libscsi_target_t *tp)
341 342 {
342 343 return (tp->lst_product);
343 344 }
344 345
345 346 const char *
346 347 libscsi_revision(libscsi_target_t *tp)
347 348 {
348 349 return (tp->lst_revision);
349 350 }
↓ open down ↓ |
277 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX