1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2021 Oxide Computer Company 14 */ 15 16 /* 17 * nvmeadm output formatting for ofmt based rendering 18 */ 19 20 #include <strings.h> 21 22 #include "nvmeadm.h" 23 24 typedef enum nvme_list_ofmt_field { 25 NVME_LIST_MODEL, 26 NVME_LIST_SERIAL, 27 NVME_LIST_FWREV, 28 NVME_LIST_VERSION, 29 NVME_LIST_SIZE, 30 NVME_LIST_CAPACITY, 31 NVME_LIST_USED, 32 NVME_LIST_INSTANCE, 33 NVME_LIST_NAMESPACE, 34 NVME_LIST_DISK 35 } nvme_list_ofmt_field_t; 36 37 static boolean_t 38 nvme_list_ofmt_cb(ofmt_arg_t *ofmt_arg, char *buf, uint_t buflen) 39 { 40 const nvme_process_arg_t *npa = ofmt_arg->ofmt_cbarg; 41 nvme_idns_lbaf_t *lbaf; 42 uint_t blksize; 43 uint64_t val; 44 int nvmelen; 45 size_t ret; 46 47 lbaf = &npa->npa_idns->id_lbaf[npa->npa_idns->id_flbas.lba_format]; 48 blksize = 1 << lbaf->lbaf_lbads; 49 50 switch (ofmt_arg->ofmt_id) { 51 case NVME_LIST_MODEL: 52 nvmelen = nvme_strlen(npa->npa_idctl->id_model, 53 sizeof (npa->npa_idctl->id_model)); 54 if (nvmelen <= 0 || nvmelen > buflen) { 55 return (B_FALSE); 56 } 57 (void) memcpy(buf, npa->npa_idctl->id_model, nvmelen); 58 buf[nvmelen] = '\0'; 59 ret = nvmelen; 60 break; 61 case NVME_LIST_SERIAL: 62 nvmelen = nvme_strlen(npa->npa_idctl->id_serial, 63 sizeof (npa->npa_idctl->id_serial)); 64 if (nvmelen <= 0 || nvmelen >= buflen) { 65 return (B_FALSE); 66 } 67 (void) memcpy(buf, npa->npa_idctl->id_serial, nvmelen); 68 buf[nvmelen] = '\0'; 69 ret = nvmelen; 70 break; 71 case NVME_LIST_FWREV: 72 nvmelen = nvme_strlen(npa->npa_idctl->id_fwrev, 73 sizeof (npa->npa_idctl->id_fwrev)); 74 if (nvmelen <= 0 || nvmelen >= buflen) { 75 return (B_FALSE); 76 } 77 (void) memcpy(buf, npa->npa_idctl->id_fwrev, nvmelen); 78 buf[nvmelen] = '\0'; 79 ret = nvmelen; 80 break; 81 case NVME_LIST_VERSION: 82 ret = snprintf(buf, buflen, "%u.%u", npa->npa_version->v_major, 83 npa->npa_version->v_minor); 84 break; 85 case NVME_LIST_INSTANCE: 86 ret = strlcat(buf, npa->npa_name, buflen); 87 break; 88 case NVME_LIST_NAMESPACE: 89 ret = strlcat(buf, di_minor_name(npa->npa_minor), buflen); 90 break; 91 case NVME_LIST_DISK: 92 if (npa->npa_dsk != NULL) { 93 ret = strlcat(buf, npa->npa_dsk, buflen); 94 } else { 95 ret = strlcat(buf, "--", buflen); 96 } 97 break; 98 case NVME_LIST_SIZE: 99 val = npa->npa_idns->id_nsize * blksize; 100 ret = snprintf(buf, buflen, "%" PRIu64, val); 101 break; 102 case NVME_LIST_CAPACITY: 103 val = npa->npa_idns->id_ncap * blksize; 104 ret = snprintf(buf, buflen, "%" PRIu64, val); 105 break; 106 case NVME_LIST_USED: 107 val = npa->npa_idns->id_nuse * blksize; 108 ret = snprintf(buf, buflen, "%" PRIu64, val); 109 break; 110 default: 111 abort(); 112 } 113 114 if (ret >= buflen) { 115 return (B_FALSE); 116 } 117 return (B_TRUE); 118 } 119 120 const ofmt_field_t nvme_list_ofmt[] = { 121 { "MODEL", 30, NVME_LIST_MODEL, nvme_list_ofmt_cb }, 122 { "SERIAL", 30, NVME_LIST_SERIAL, nvme_list_ofmt_cb }, 123 { "FWREV", 10, NVME_LIST_FWREV, nvme_list_ofmt_cb }, 124 { "VERSION", 10, NVME_LIST_VERSION, nvme_list_ofmt_cb }, 125 { "SIZE", 15, NVME_LIST_SIZE, nvme_list_ofmt_cb }, 126 { "CAPACITY", 15, NVME_LIST_CAPACITY, nvme_list_ofmt_cb }, 127 { "USED", 15, NVME_LIST_USED, nvme_list_ofmt_cb }, 128 { "INSTANCE", 10, NVME_LIST_INSTANCE, nvme_list_ofmt_cb }, 129 { "NAMESPACE", 10, NVME_LIST_NAMESPACE, nvme_list_ofmt_cb }, 130 { "DISK", 15, NVME_LIST_DISK, nvme_list_ofmt_cb }, 131 { NULL, 0, 0, NULL } 132 }; 133