nondestructive.c (2c449a4c5a338d2dd39a1949524e57c06ce7eff6) nondestructive.c (b37d1deb045d7bc7877fb1d9afdb39d43130dcc4)
1/*-
2 * Copyright (C) 2021 Axcient, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 28 unchanged lines hidden (view full) ---

37#include <stdint.h>
38#include <stdio.h>
39#include <stdlib.h>
40
41#include <cam/scsi/scsi_enc.h>
42
43#include "common.h"
44
1/*-
2 * Copyright (C) 2021 Axcient, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 28 unchanged lines hidden (view full) ---

37#include <stdint.h>
38#include <stdio.h>
39#include <stdlib.h>
40
41#include <cam/scsi/scsi_enc.h>
42
43#include "common.h"
44
45static bool do_getelmdesc(const char *devname, int fd) {
45static bool
46do_getelmdesc(const char *devname, int fd)
47{
46 regex_t re;
47 FILE *pipe;
48 char cmd[256];
49 char line[256];
50 char *actual;
51 unsigned nobj;
52 unsigned elm_idx = 0;
53 int r;

--- 66 unchanged lines hidden (view full) ---

120}
121ATF_TC_BODY(getelmdesc, tc)
122{
123 if (!has_ses())
124 atf_tc_skip("No ses devices found");
125 for_each_ses_dev(do_getelmdesc, O_RDONLY);
126}
127
48 regex_t re;
49 FILE *pipe;
50 char cmd[256];
51 char line[256];
52 char *actual;
53 unsigned nobj;
54 unsigned elm_idx = 0;
55 int r;

--- 66 unchanged lines hidden (view full) ---

122}
123ATF_TC_BODY(getelmdesc, tc)
124{
125 if (!has_ses())
126 atf_tc_skip("No ses devices found");
127 for_each_ses_dev(do_getelmdesc, O_RDONLY);
128}
129
128static bool do_getelmdevnames(const char *devname __unused, int fd) {
130static bool
131do_getelmdevnames(const char *devname __unused, int fd)
132{
129 encioc_element_t *map;
130 unsigned nobj;
131 const size_t namesize = 128;
133 encioc_element_t *map;
134 unsigned nobj;
135 const size_t namesize = 128;
132 int r;
136 int r, status;
133 char *namebuf;
134 unsigned elm_idx;
135
136 r = ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj);
137 ATF_REQUIRE_EQ(r, 0);
138
139 namebuf = calloc(namesize, sizeof(char));
140 ATF_REQUIRE(namebuf != NULL);

--- 18 unchanged lines hidden (view full) ---

159 ATF_REQUIRE_EQ(r, 0);
160
161 memset(&elmdn, 0, sizeof(elmdn));
162 elmdn.elm_idx = elm_idx;
163 elmdn.elm_names_size = namesize;
164 elmdn.elm_devnames = namebuf;
165 namebuf[0] = '\0';
166 r = ioctl(fd, ENCIOC_GETELMDEVNAMES, (caddr_t) &elmdn);
137 char *namebuf;
138 unsigned elm_idx;
139
140 r = ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj);
141 ATF_REQUIRE_EQ(r, 0);
142
143 namebuf = calloc(namesize, sizeof(char));
144 ATF_REQUIRE(namebuf != NULL);

--- 18 unchanged lines hidden (view full) ---

163 ATF_REQUIRE_EQ(r, 0);
164
165 memset(&elmdn, 0, sizeof(elmdn));
166 elmdn.elm_idx = elm_idx;
167 elmdn.elm_names_size = namesize;
168 elmdn.elm_devnames = namebuf;
169 namebuf[0] = '\0';
170 r = ioctl(fd, ENCIOC_GETELMDEVNAMES, (caddr_t) &elmdn);
167 if (e_status.cstat[0] != SES_OBJSTAT_UNSUPPORTED &&
168 e_status.cstat[0] != SES_OBJSTAT_NOTINSTALLED &&
171 status = ses_status_common_get_element_status_code(
172 (struct ses_status_common*)&e_status.cstat[0]);
173 if (status != SES_OBJSTAT_UNSUPPORTED &&
174 status != SES_OBJSTAT_NOTINSTALLED &&
169 (map[elm_idx].elm_type == ELMTYP_DEVICE ||
170 map[elm_idx].elm_type == ELMTYP_ARRAY_DEV))
171 {
172 ATF_CHECK_EQ_MSG(r, 0, "devnames not found. This could be due to a buggy ses driver, buggy ses controller, dead HDD, or an ATA HDD in a SAS slot");
173 } else {
174 ATF_CHECK(r != 0);
175 }
176
177 if (r == 0) {
178 size_t z = 0;
175 (map[elm_idx].elm_type == ELMTYP_DEVICE ||
176 map[elm_idx].elm_type == ELMTYP_ARRAY_DEV))
177 {
178 ATF_CHECK_EQ_MSG(r, 0, "devnames not found. This could be due to a buggy ses driver, buggy ses controller, dead HDD, or an ATA HDD in a SAS slot");
179 } else {
180 ATF_CHECK(r != 0);
181 }
182
183 if (r == 0) {
184 size_t z = 0;
179 int da = 0, ada = 0, pass = 0, nvd = 0;
180 int nvme = 0, unknown = 0;
185 int da = 0, ada = 0, pass = 0, nda = 0, unknown = 0;
181
182 while(elmdn.elm_devnames[z] != '\0') {
183 size_t e;
184 char *s;
185
186 if (elmdn.elm_devnames[z] == ',')
187 z++; /* Skip the comma */
188 s = elmdn.elm_devnames + z;
189 e = strcspn(s, "0123456789");
190 if (0 == strncmp("da", s, e))
191 da++;
192 else if (0 == strncmp("ada", s, e))
193 ada++;
194 else if (0 == strncmp("pass", s, e))
195 pass++;
186
187 while(elmdn.elm_devnames[z] != '\0') {
188 size_t e;
189 char *s;
190
191 if (elmdn.elm_devnames[z] == ',')
192 z++; /* Skip the comma */
193 s = elmdn.elm_devnames + z;
194 e = strcspn(s, "0123456789");
195 if (0 == strncmp("da", s, e))
196 da++;
197 else if (0 == strncmp("ada", s, e))
198 ada++;
199 else if (0 == strncmp("pass", s, e))
200 pass++;
196 else if (0 == strncmp("nvd", s, e))
197 nvd++;
198 else if (0 == strncmp("nvme", s, e))
199 nvme++;
201 else if (0 == strncmp("nda", s, e))
202 nda++;
200 else
201 unknown++;
202 z += strcspn(elmdn.elm_devnames + z, ",");
203 }
204 /* There should be one pass dev for each non-pass dev */
203 else
204 unknown++;
205 z += strcspn(elmdn.elm_devnames + z, ",");
206 }
207 /* There should be one pass dev for each non-pass dev */
205 ATF_CHECK_EQ(pass, da + ada + nvd + nvme);
208 ATF_CHECK_EQ(pass, da + ada + nda);
206 ATF_CHECK_EQ_MSG(0, unknown,
207 "Unknown device names %s", elmdn.elm_devnames);
208 }
209 }
210 free(map);
211 free(namebuf);
212
213 return (true);

--- 10 unchanged lines hidden (view full) ---

224ATF_TC_BODY(getelmdevnames, tc)
225{
226 if (!has_ses())
227 atf_tc_skip("No ses devices found");
228 for_each_ses_dev(do_getelmdevnames, O_RDONLY);
229}
230
231static int
209 ATF_CHECK_EQ_MSG(0, unknown,
210 "Unknown device names %s", elmdn.elm_devnames);
211 }
212 }
213 free(map);
214 free(namebuf);
215
216 return (true);

--- 10 unchanged lines hidden (view full) ---

227ATF_TC_BODY(getelmdevnames, tc)
228{
229 if (!has_ses())
230 atf_tc_skip("No ses devices found");
231 for_each_ses_dev(do_getelmdevnames, O_RDONLY);
232}
233
234static int
232elm_type_name2int(const char *name) {
235elm_type_name2int(const char *name)
236{
233 const char *elm_type_names[] = ELM_TYPE_NAMES;
234 int i;
235
236 for (i = 0; i <= ELMTYP_LAST; i++) {
237 /* sg_ses uses different case than ses(4) */
238 if (0 == strcasecmp(name, elm_type_names[i]))
239 return i;
240 }
241 return (-1);
242}
243
237 const char *elm_type_names[] = ELM_TYPE_NAMES;
238 int i;
239
240 for (i = 0; i <= ELMTYP_LAST; i++) {
241 /* sg_ses uses different case than ses(4) */
242 if (0 == strcasecmp(name, elm_type_names[i]))
243 return i;
244 }
245 return (-1);
246}
247
244static bool do_getelmmap(const char *devname, int fd) {
248static bool
249do_getelmmap(const char *devname, int fd)
250{
245 encioc_element_t *map;
246 FILE *pipe;
247 char cmd[256];
248 char line[256];
249 unsigned elm_idx = 0;
250 unsigned nobj, subenc_id;
251 int r, elm_type;
252

--- 62 unchanged lines hidden (view full) ---

315}
316ATF_TC_BODY(getelmmap, tc)
317{
318 if (!has_ses())
319 atf_tc_skip("No ses devices found");
320 for_each_ses_dev(do_getelmmap, O_RDONLY);
321}
322
251 encioc_element_t *map;
252 FILE *pipe;
253 char cmd[256];
254 char line[256];
255 unsigned elm_idx = 0;
256 unsigned nobj, subenc_id;
257 int r, elm_type;
258

--- 62 unchanged lines hidden (view full) ---

321}
322ATF_TC_BODY(getelmmap, tc)
323{
324 if (!has_ses())
325 atf_tc_skip("No ses devices found");
326 for_each_ses_dev(do_getelmmap, O_RDONLY);
327}
328
323static bool do_getelmstat(const char *devname, int fd) {
329static bool
330do_getelmstat(const char *devname, int fd)
331{
324 encioc_element_t *map;
325 unsigned elm_idx;
326 unsigned nobj;
327 int r, elm_subidx;
328 elm_type_t last_elm_type = -1;
329
330 r = ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj);
331 ATF_REQUIRE_EQ(r, 0);

--- 54 unchanged lines hidden (view full) ---

386}
387ATF_TC_BODY(getelmstat, tc)
388{
389 if (!has_ses())
390 atf_tc_skip("No ses devices found");
391 for_each_ses_dev(do_getelmstat, O_RDONLY);
392}
393
332 encioc_element_t *map;
333 unsigned elm_idx;
334 unsigned nobj;
335 int r, elm_subidx;
336 elm_type_t last_elm_type = -1;
337
338 r = ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj);
339 ATF_REQUIRE_EQ(r, 0);

--- 54 unchanged lines hidden (view full) ---

394}
395ATF_TC_BODY(getelmstat, tc)
396{
397 if (!has_ses())
398 atf_tc_skip("No ses devices found");
399 for_each_ses_dev(do_getelmstat, O_RDONLY);
400}
401
394static bool do_getencid(const char *devname, int fd) {
402static bool
403do_getencid(const char *devname, int fd)
404{
395 encioc_string_t stri;
396 FILE *pipe;
397 char cmd[256];
398 char encid[32];
399 char line[256];
400 char sg_encid[32];
401 int r, sg_ses_r;
402

--- 33 unchanged lines hidden (view full) ---

436}
437ATF_TC_BODY(getencid, tc)
438{
439 if (!has_ses())
440 atf_tc_skip("No ses devices found");
441 for_each_ses_dev(do_getencid, O_RDONLY);
442}
443
405 encioc_string_t stri;
406 FILE *pipe;
407 char cmd[256];
408 char encid[32];
409 char line[256];
410 char sg_encid[32];
411 int r, sg_ses_r;
412

--- 33 unchanged lines hidden (view full) ---

446}
447ATF_TC_BODY(getencid, tc)
448{
449 if (!has_ses())
450 atf_tc_skip("No ses devices found");
451 for_each_ses_dev(do_getencid, O_RDONLY);
452}
453
444static bool do_getencname(const char *devname, int fd) {
454static bool
455do_getencname(const char *devname, int fd)
456{
445 encioc_string_t stri;
446 FILE *pipe;
447 char cmd[256];
448 char encname[32];
449 char line[256];
450 int r;
451
452 snprintf(cmd, sizeof(cmd), "sg_inq -o %s | awk '"

--- 29 unchanged lines hidden (view full) ---

482}
483ATF_TC_BODY(getencname, tc)
484{
485 if (!has_ses())
486 atf_tc_skip("No ses devices found");
487 for_each_ses_dev(do_getencname, O_RDONLY);
488}
489
457 encioc_string_t stri;
458 FILE *pipe;
459 char cmd[256];
460 char encname[32];
461 char line[256];
462 int r;
463
464 snprintf(cmd, sizeof(cmd), "sg_inq -o %s | awk '"

--- 29 unchanged lines hidden (view full) ---

494}
495ATF_TC_BODY(getencname, tc)
496{
497 if (!has_ses())
498 atf_tc_skip("No ses devices found");
499 for_each_ses_dev(do_getencname, O_RDONLY);
500}
501
490static bool do_getencstat(const char *devname, int fd) {
502static bool
503do_getencstat(const char *devname, int fd)
504{
491 FILE *pipe;
492 char cmd[256];
493 unsigned char e, estat, invop, info, noncrit, crit, unrecov;
494 int r;
495
496 snprintf(cmd, sizeof(cmd), "sg_ses -p2 %s "
497 "| grep 'INVOP='",
498 devname);

--- 26 unchanged lines hidden (view full) ---

525}
526ATF_TC_BODY(getencstat, tc)
527{
528 if (!has_ses())
529 atf_tc_skip("No ses devices found");
530 for_each_ses_dev(do_getencstat, O_RDONLY);
531}
532
505 FILE *pipe;
506 char cmd[256];
507 unsigned char e, estat, invop, info, noncrit, crit, unrecov;
508 int r;
509
510 snprintf(cmd, sizeof(cmd), "sg_ses -p2 %s "
511 "| grep 'INVOP='",
512 devname);

--- 26 unchanged lines hidden (view full) ---

539}
540ATF_TC_BODY(getencstat, tc)
541{
542 if (!has_ses())
543 atf_tc_skip("No ses devices found");
544 for_each_ses_dev(do_getencstat, O_RDONLY);
545}
546
533static bool do_getnelm(const char *devname, int fd) {
547static bool
548do_getnelm(const char *devname, int fd)
549{
534 FILE *pipe;
535 char cmd[256];
536 char line[256];
537 unsigned nobj, expected = 0;
538 int r, sg_ses_r;
539
540 snprintf(cmd, sizeof(cmd), "sg_ses -p1 %s", devname);
541 pipe = popen(cmd, "r");

--- 31 unchanged lines hidden (view full) ---

573}
574ATF_TC_BODY(getnelm, tc)
575{
576 if (!has_ses())
577 atf_tc_skip("No ses devices found");
578 for_each_ses_dev(do_getnelm, O_RDONLY);
579}
580
550 FILE *pipe;
551 char cmd[256];
552 char line[256];
553 unsigned nobj, expected = 0;
554 int r, sg_ses_r;
555
556 snprintf(cmd, sizeof(cmd), "sg_ses -p1 %s", devname);
557 pipe = popen(cmd, "r");

--- 31 unchanged lines hidden (view full) ---

589}
590ATF_TC_BODY(getnelm, tc)
591{
592 if (!has_ses())
593 atf_tc_skip("No ses devices found");
594 for_each_ses_dev(do_getnelm, O_RDONLY);
595}
596
581static bool do_getstring(const char *devname, int fd) {
597static bool
598do_getstring(const char *devname, int fd)
599{
582 FILE *pipe;
583 char cmd[256];
584 char *sg_ses_buf, *ses_buf;
585 ssize_t sg_ses_count;
586 encioc_string_t str_in;
587 int r;
588
589 sg_ses_buf = malloc(65535);

--- 65 unchanged lines hidden ---
600 FILE *pipe;
601 char cmd[256];
602 char *sg_ses_buf, *ses_buf;
603 ssize_t sg_ses_count;
604 encioc_string_t str_in;
605 int r;
606
607 sg_ses_buf = malloc(65535);

--- 65 unchanged lines hidden ---