Bug Summary

File:.build-ci/../plugins/huawei/huawei-nvme.c
Warning:line 90, column 2
Value stored to 'err' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name huawei-nvme.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/__w/nvme-cli/nvme-cli/.build-ci -fcoverage-compilation-dir=/__w/nvme-cli/nvme-cli/.build-ci -resource-dir /usr/lib/llvm-19/lib/clang/19 -include /__w/nvme-cli/nvme-cli/.build-ci/nvme-config.h -I nvme.p -I . -I .. -I ccan -I ../ccan -I libnvme/src -I ../libnvme/src -I /usr/include/json-c -D _FILE_OFFSET_BITS=64 -D _GNU_SOURCE -U NDEBUG -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -std=gnu99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-opt-analyze-headers -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /__w/nvme-cli/nvme-cli/.build-ci/scan-results/2026-06-24-175442-590-1 -x c ../plugins/huawei/huawei-nvme.c
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2017-2019 Huawei Corporation or its affiliates.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * Author: Zou Ming<zouming.zouming@huawei.com>,
16 * Yang Feng <philip.yang@huawei.com>
17 */
18#include <stdio.h>
19#include <string.h>
20#include <stdlib.h>
21#include <inttypes.h>
22#include <errno(*__errno_location ()).h>
23#include <limits.h>
24#include <fcntl.h>
25#include <unistd.h>
26#include <dirent.h>
27
28#include <sys/stat.h>
29
30#include <libnvme.h>
31
32#include "common.h"
33#include "nvme-cmds.h"
34#include "nvme.h"
35#include "plugin.h"
36
37#include "util/suffix.h"
38
39#define CREATE_CMD
40#include "huawei-nvme.h"
41
42#define HW_SSD_PCI_VENDOR_ID0x19E5 0x19E5
43#define ARRAY_NAME_LEN80 80
44#define NS_NAME_LEN40 40
45
46#define MIN_ARRAY_NAME_LEN16 16
47#define MIN_NS_NAME_LEN16 16
48
49struct huawei_list_item {
50 char node[1024];
51 struct nvme_id_ctrl ctrl;
52 unsigned int nsid;
53 struct nvme_id_ns ns;
54 unsigned int block;
55 char ns_name[NS_NAME_LEN40];
56 char array_name[ARRAY_NAME_LEN80];
57 bool_Bool huawei_device;
58};
59
60struct huawei_list_element_len {
61 unsigned int node;
62 unsigned int ns_name;
63 unsigned int nguid;
64 unsigned int ns_id;
65 unsigned int usage;
66 unsigned int array_name;
67};
68
69static int huawei_get_nvme_info(struct libnvme_transport_handle *hdl,
70 struct huawei_list_item *item, const char *node)
71{
72 struct stat nvme_stat_info;
73 int err;
74 int len;
75
76 memset(item, 0, sizeof(*item));
77
78 err = nvme_identify_ctrl(hdl, &item->ctrl);
79 if (err)
80 return err;
81
82 /*identify huawei device*/
83 if (strstr(item->ctrl.mn, "Huawei") == NULL((void*)0) &&
84 le16_to_cpu(item->ctrl.vid) != HW_SSD_PCI_VENDOR_ID0x19E5) {
85 item->huawei_device = false0;
86 return 0;
87 }
88
89 item->huawei_device = true1;
90 err = libnvme_get_nsid(hdl, &item->nsid);
Value stored to 'err' is never read
91 err = nvme_identify_ns(hdl, item->nsid, &item->ns);
92 if (err)
93 return err;
94
95 err = fstat(libnvme_transport_handle_get_fd(hdl), &nvme_stat_info);
96 if (err < 0)
97 return err;
98
99 strncpy(item->node, node, sizeof(item->node));
100 item->node[sizeof(item->node) - 1] = '\0';
101 item->block = S_ISBLK(nvme_stat_info.st_mode)((((nvme_stat_info.st_mode)) & 0170000) == (0060000));
102
103 if (item->ns.vs[0] == 0) {
104 len = snprintf(item->ns_name, NS_NAME_LEN40, "%s", "----");
105 if (len < 0)
106 return -EINVAL22;
107 } else {
108 memcpy(item->ns_name, item->ns.vs, NS_NAME_LEN40);
109 item->ns_name[NS_NAME_LEN40 - 1] = '\0';
110 }
111
112 if (item->ctrl.vs[0] == 0) {
113 len = snprintf(item->array_name, ARRAY_NAME_LEN80, "%s", "----");
114 if (len < 0)
115 return -EINVAL22;
116 } else {
117 memcpy(item->array_name, item->ctrl.vs, ARRAY_NAME_LEN80);
118 item->array_name[ARRAY_NAME_LEN80 - 1] = '\0';
119 }
120 return 0;
121}
122
123#ifdef CONFIG_JSONC
124static void format(char *formatter, size_t fmt_sz, char *tofmt, size_t tofmtsz)
125{
126 fmt_sz = snprintf(formatter, fmt_sz, "%-*.*s", (int)tofmtsz, (int)tofmtsz, tofmt);
127
128 /* trim() the obnoxious trailing white lines */
129 while (fmt_sz) {
130 if (formatter[fmt_sz - 1] != ' ' && formatter[fmt_sz - 1] != '\0') {
131 formatter[fmt_sz] = '\0';
132 break;
133 }
134 fmt_sz--;
135 }
136}
137
138static void huawei_json_print_list_items(struct huawei_list_item *list_items,
139 unsigned int len)
140{
141 struct json_object *root;
142 struct json_object *devices;
143 struct json_object *device_attrs;
144 char formatter[128] = { 0 };
145 int index, i = 0;
146
147 root = json_create_object()json_object_new_object();
148 devices = json_create_array()json_object_new_array();
149 for (i = 0; i < len; i++) {
150 device_attrs = json_create_object()json_object_new_object();
151
152 json_object_add_value_string(device_attrs,
153 "DevicePath",
154 list_items[i].node);
155
156 if (sscanf(list_items[i].node, "/dev/nvme%d", &index) == 1)
157 json_object_add_value_int(device_attrs,json_object_object_add(device_attrs, "Index", json_object_new_int
(index))
158 "Index",json_object_object_add(device_attrs, "Index", json_object_new_int
(index))
159 index)json_object_object_add(device_attrs, "Index", json_object_new_int
(index))
;
160
161 format(formatter, sizeof(formatter),
162 list_items[i].ns_name,
163 sizeof(list_items[i].ns_name));
164
165 json_object_add_value_string(device_attrs,
166 "NS Name",
167 formatter);
168
169 format(formatter, sizeof(formatter),
170 list_items[i].array_name,
171 sizeof(list_items[i].array_name));
172
173 json_object_add_value_string(device_attrs,
174 "Array Name",
175 formatter);
176
177 json_array_add_value_object(devices, device_attrs)json_object_array_add(devices, device_attrs);
178 }
179 json_object_add_value_array(root, "Devices", devices)json_object_object_add(root, "Devices", devices);
180 json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 <<
1) | (1 << 4)))
;
181 printf("\n");
182 json_free_object(root)json_object_put(root);
183}
184#endif /* CONFIG_JSONC */
185
186static void huawei_print_list_head(struct huawei_list_element_len element_len)
187{
188 char dash[128];
189 int i;
190
191 for (i = 0; i < 128; i++)
192 dash[i] = '-';
193 dash[127] = '\0';
194
195 printf("%-*.*s %-*.*s %-*.*s %-*.*s %-*.*s %-*.*s\n",
196 element_len.node, element_len.node, "Node",
197 element_len.ns_name, element_len.ns_name, "NS Name",
198 element_len.nguid, element_len.nguid, "Nguid",
199 element_len.ns_id, element_len.ns_id, "NS ID",
200 element_len.usage, element_len.usage, "Usage",
201 element_len.array_name, element_len.array_name, "Array Name");
202
203 printf("%-.*s %-.*s %-.*s %-.*s %-.*s %-.*s\n",
204 element_len.node, dash, element_len.ns_name, dash,
205 element_len.nguid, dash, element_len.ns_id, dash,
206 element_len.usage, dash, element_len.array_name, dash);
207}
208
209static void huawei_print_list_item(struct huawei_list_item *list_item,
210 struct huawei_list_element_len element_len)
211{
212 __u8 lba_index;
213
214 nvme_id_ns_flbas_to_lbaf_inuse(list_item->ns.flbas, &lba_index);
215 unsigned long long lba = 1ULL << list_item->ns.lbaf[lba_index].ds;
216 double nsze = le64_to_cpu(list_item->ns.nsze) * lba;
217 double nuse = le64_to_cpu(list_item->ns.nuse) * lba;
218
219 const char *s_suffix = suffix_si_get(&nsze);
220 const char *u_suffix = suffix_si_get(&nuse);
221
222 char usage[128];
223 char nguid_buf[2 * sizeof(list_item->ns.nguid) + 1];
224 char *nguid = nguid_buf;
225 int i;
226
227 sprintf(usage, "%6.2f %2sB / %6.2f %2sB", nuse, u_suffix, nsze, s_suffix);
228
229 memset(nguid, 0, sizeof(nguid_buf));
230 for (i = 0; i < sizeof(list_item->ns.nguid); i++)
231 nguid += sprintf(nguid, "%02x", list_item->ns.nguid[i]);
232
233 printf("%-*.*s %-*.*s %-*.*s %-*d %-*.*s %-*.*s\n",
234 element_len.node, element_len.node, list_item->node,
235 element_len.ns_name, element_len.ns_name, list_item->ns_name,
236 element_len.nguid, element_len.nguid, nguid_buf,
237 element_len.ns_id, list_item->nsid,
238 element_len.usage, element_len.usage, usage,
239 element_len.array_name, element_len.array_name,
240 list_item->array_name);
241
242}
243
244static unsigned int choose_len(unsigned int old_len, unsigned int cur_len, unsigned int default_len)
245{
246 unsigned int temp_len;
247
248 temp_len = (cur_len > default_len) ? cur_len : default_len;
249 if (temp_len > old_len)
250 return temp_len;
251 return old_len;
252}
253
254static unsigned int huawei_get_ns_len(struct huawei_list_item *list_items, unsigned int len,
255 unsigned int default_len)
256{
257 int i;
258 unsigned int min_len = default_len;
259
260 for (i = 0 ; i < len ; i++)
261 min_len = choose_len(min_len, strlen(list_items->ns_name), default_len);
262
263 return min_len;
264}
265
266static int huawei_get_array_len(struct huawei_list_item *list_items, unsigned int len,
267 unsigned int default_len)
268{
269 int i;
270 int min_len = default_len;
271
272 for (i = 0 ; i < len ; i++)
273 min_len = choose_len(min_len, strlen(list_items->array_name), default_len);
274
275 return min_len;
276}
277
278static void huawei_print_list_items(struct huawei_list_item *list_items, unsigned int len)
279{
280 unsigned int i;
281 struct huawei_list_element_len element_len;
282
283 element_len.node = 16;
284 element_len.nguid = 2 * sizeof(list_items->ns.nguid) + 1;
285 element_len.ns_id = 9;
286 element_len.usage = 26;
287 element_len.ns_name = huawei_get_ns_len(list_items, len, MIN_NS_NAME_LEN16);
288 element_len.array_name = huawei_get_array_len(list_items, len, MIN_ARRAY_NAME_LEN16);
289
290 huawei_print_list_head(element_len);
291
292 for (i = 0 ; i < len ; i++)
293 huawei_print_list_item(&list_items[i], element_len);
294}
295
296static int huawei_list(int argc, char **argv, struct command *acmd,
297 struct plugin *plugin)
298{
299 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx =
300 libnvme_create_global_ctx(stdoutstdout, LIBNVME_DEFAULT_LOGLEVELLIBNVME_LOG_WARN);
301 char path[264];
302 struct dirent **devices;
303 struct huawei_list_item *list_items;
304 unsigned int i, n, ret;
305 unsigned int huawei_num = 0;
306 nvme_print_flags_t fmt;
307 const char *desc = "Retrieve basic information for the given huawei device";
308
309 NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
310
311 if (!ctx)
312 return -ENOMEM12;
313
314 ret = argconfig_parse(argc, argv, desc, opts);
315 if (ret)
316 return ret;
317
318 ret = validate_output_format(nvme_args.output_format, &fmt);
319 if (ret < 0 || (fmt != JSON && fmt != NORMAL))
320 return ret;
321
322 n = scandir("/dev", &devices, libnvme_filter_namespace, alphasort);
323 if (n <= 0)
324 return n;
325
326 list_items = calloc(n, sizeof(*list_items));
327 if (!list_items) {
328 fprintf(stderrstderr, "can not allocate controller list payload\n");
329 ret = ENOMEM12;
330 goto out_free_devices;
331 }
332
333 for (i = 0; i < n; i++) {
334 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
335
336 snprintf(path, sizeof(path), "/dev/%s", devices[i]->d_name);
337 ret = libnvme_open(ctx, path, &hdl);
338 if (ret) {
339 fprintf(stderrstderr, "Cannot open device %s: %s\n",
340 path, libnvme_strerror(-ret));
341 continue;
342 }
343 ret = huawei_get_nvme_info(hdl, &list_items[huawei_num], path);
344 if (ret)
345 goto out_free_list_items;
346
347 if (list_items[huawei_num].huawei_device == true1)
348 huawei_num++;
349 }
350
351 if (huawei_num > 0) {
352#ifdef CONFIG_JSONC
353 if (fmt == JSON)
354 huawei_json_print_list_items(list_items, huawei_num);
355 else
356#endif /* CONFIG_JSONC */
357 huawei_print_list_items(list_items, huawei_num);
358 }
359out_free_list_items:
360 free(list_items);
361out_free_devices:
362 for (i = 0; i < n; i++)
363 free(devices[i]);
364 free(devices);
365
366 return ret;
367}
368
369static void huawei_do_id_ctrl(__u8 *vs, struct json_object *root)
370{
371 char array_name[ARRAY_NAME_LEN80 + 1] = {0};
372
373 memcpy(array_name, vs, ARRAY_NAME_LEN80);
374 if (root)
375 json_object_add_value_string(root, "array name", strlen(array_name) > 1 ? array_name : "NULL");
376 else
377 printf("array name : %s\n", strlen(array_name) > 1 ? array_name : "NULL");
378}
379
380static int huawei_id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin)
381{
382 return __id_ctrl(argc, argv, acmd, plugin, huawei_do_id_ctrl);
383}