]> git.proxmox.com Git - mirror_zfs.git/commitdiff
zinject: show more device fault fields
authorRob Norris <rob.norris@klarasystems.com>
Thu, 29 Feb 2024 23:38:41 +0000 (10:38 +1100)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 3 Apr 2024 23:06:19 +0000 (16:06 -0700)
Once there's a few different kinds injected, its pretty hard to see them
otherwise.

So, lets show IO type, error type and frequency fields in the table too.

Since we now have to convert from error code to pretty string, refactor
the error names into a table and add lookup functions.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Brian Atkinson <batkinson@lanl.gov>
Reviewed-by: Tino Reichardt <milky-zfs@mcmilk.de>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #15953

cmd/zinject/zinject.c

index a11b6d0b7fac8aa92cf963bc10b5ed580f21a9b5..8d0cf5d0a95750e9d4e21b05b03647abfdc9752b 100644 (file)
@@ -22,6 +22,7 @@
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
  * Copyright (c) 2017, Intel Corporation.
+ * Copyright (c) 2024, Klara Inc.
  */
 
 /*
@@ -208,6 +209,37 @@ type_to_name(uint64_t type)
        }
 }
 
+struct errstr {
+       int             err;
+       const char      *str;
+};
+static const struct errstr errstrtable[] = {
+       { EIO,          "io" },
+       { ECKSUM,       "checksum" },
+       { EINVAL,       "decompress" },
+       { EACCES,       "decrypt" },
+       { ENXIO,        "nxio" },
+       { ECHILD,       "dtl" },
+       { EILSEQ,       "corrupt" },
+       { 0, NULL },
+};
+
+static int
+str_to_err(const char *str)
+{
+       for (int i = 0; errstrtable[i].str != NULL; i++)
+               if (strcasecmp(errstrtable[i].str, str) == 0)
+                       return (errstrtable[i].err);
+       return (-1);
+}
+static const char *
+err_to_str(int err)
+{
+       for (int i = 0; errstrtable[i].str != NULL; i++)
+               if (errstrtable[i].err == err)
+                       return (errstrtable[i].str);
+       return ("[unknown]");
+}
 
 /*
  * Print usage message.
@@ -392,6 +424,10 @@ static int
 print_device_handler(int id, const char *pool, zinject_record_t *record,
     void *data)
 {
+       static const char *iotypestr[] = {
+           "null", "read", "write", "free", "claim", "ioctl", "trim", "all",
+       };
+
        int *count = data;
 
        if (record->zi_guid == 0 || record->zi_func[0] != '\0')
@@ -401,14 +437,21 @@ print_device_handler(int id, const char *pool, zinject_record_t *record,
                return (0);
 
        if (*count == 0) {
-               (void) printf("%3s  %-15s  %s\n", "ID", "POOL", "GUID");
-               (void) printf("---  ---------------  ----------------\n");
+               (void) printf("%3s  %-15s  %-16s  %-5s  %-10s  %-9s\n",
+                   "ID", "POOL", "GUID", "TYPE", "ERROR", "FREQ");
+               (void) printf(
+                   "---  ---------------  ----------------  "
+                   "-----  ----------  ---------\n");
        }
 
        *count += 1;
 
-       (void) printf("%3d  %-15s  %llx\n", id, pool,
-           (u_longlong_t)record->zi_guid);
+       double freq = record->zi_freq == 0 ? 100.0f :
+           (((double)record->zi_freq) / ZI_PERCENTAGE_MAX) * 100.0f;
+
+       (void) printf("%3d  %-15s  %llx  %-5s  %-10s  %8.4f%%\n", id, pool,
+           (u_longlong_t)record->zi_guid, iotypestr[record->zi_iotype],
+           err_to_str(record->zi_error), freq);
 
        return (0);
 }
@@ -842,24 +885,12 @@ main(int argc, char **argv)
                        }
                        break;
                case 'e':
-                       if (strcasecmp(optarg, "io") == 0) {
-                               error = EIO;
-                       } else if (strcasecmp(optarg, "checksum") == 0) {
-                               error = ECKSUM;
-                       } else if (strcasecmp(optarg, "decompress") == 0) {
-                               error = EINVAL;
-                       } else if (strcasecmp(optarg, "decrypt") == 0) {
-                               error = EACCES;
-                       } else if (strcasecmp(optarg, "nxio") == 0) {
-                               error = ENXIO;
-                       } else if (strcasecmp(optarg, "dtl") == 0) {
-                               error = ECHILD;
-                       } else if (strcasecmp(optarg, "corrupt") == 0) {
-                               error = EILSEQ;
-                       } else {
+                       error = str_to_err(optarg);
+                       if (error < 0) {
                                (void) fprintf(stderr, "invalid error type "
-                                   "'%s': must be 'io', 'checksum' or "
-                                   "'nxio'\n", optarg);
+                                   "'%s': must be one of: io decompress "
+                                   "decrypt nxio dtl corrupt\n",
+                                   optarg);
                                usage();
                                libzfs_fini(g_zfs);
                                return (1);