int cmd_list(int argc, const char **argv) { const struct option options[] = { OPT_STRING('b', "bus", ¶m.bus, "bus-id", "filter by bus"), OPT_STRING('r', "region", ¶m.region, "region-id", "filter by region"), OPT_BOOLEAN('B', "buses", &list.buses, "include bus info"), OPT_BOOLEAN('D', "dimms", &list.dimms, "include dimm info"), OPT_BOOLEAN('R', "regions", &list.regions, "include region info"), OPT_BOOLEAN('N', "namespaces", &list.namespaces, "include namespace info (default)"), OPT_BOOLEAN('i', "idle", &list.idle, "include idle devices"), OPT_END(), }; const char * const u[] = { "ndctl list [<options>]", NULL }; struct json_object *jnamespaces = NULL; struct json_object *jregions = NULL; struct json_object *jdimms = NULL; struct json_object *jbuses = NULL; struct ndctl_ctx *ctx; struct ndctl_bus *bus; int i, rc; argc = parse_options(argc, argv, options, u, 0); for (i = 0; i < argc; i++) error("unknown parameter \"%s\"\n", argv[i]); if (argc) usage_with_options(u, options); rc = ndctl_new(&ctx); if (rc < 0) return rc; ndctl_bus_foreach(ctx, bus) { struct json_object *jbus = NULL; struct ndctl_region *region; struct ndctl_dimm *dimm; if (!util_bus_filter(bus, param.bus)) continue; if (list.buses) { if (!jbuses) { jbuses = json_object_new_array(); if (!jbuses) { fail("\n"); continue; } } jbus = util_bus_to_json(bus); if (!jbus) { fail("\n"); continue; } json_object_array_add(jbuses, jbus); } ndctl_dimm_foreach(bus, dimm) { struct json_object *jdimm; /* are we emitting dimms? */ if (!list.dimms) break; if (!list.idle && !ndctl_dimm_is_enabled(dimm)) continue; if (!jdimms) { jdimms = json_object_new_array(); if (!jdimms) { fail("\n"); continue; } if (jbus) json_object_object_add(jbus, "dimms", jdimms); } jdimm = util_dimm_to_json(dimm); if (!jdimm) { fail("\n"); continue; } /* * Without a bus we are collecting dimms anonymously * across the platform. */ json_object_array_add(jdimms, jdimm); } ndctl_region_foreach(bus, region) { struct json_object *jregion; if (!util_region_filter(region, param.region)) continue; if (!list.regions) { jnamespaces = list_namespaces(region, jbus, jnamespaces, true); continue; } if (!list.idle && !ndctl_region_is_enabled(region)) continue; if (!jregions) { jregions = json_object_new_array(); if (!jregions) { fail("\n"); continue; } if (jbus) json_object_object_add(jbus, "regions", jregions); } jregion = region_to_json(region); if (!jregion) { fail("\n"); continue; } /* * Without a bus we are collecting regions anonymously * across the platform. */ json_object_array_add(jregions, jregion); } if (jbuses) { jdimms = NULL; jregions = NULL; jnamespaces = NULL; } } if (jbuses) display_array(jbuses); else if ((!!jdimms + !!jregions + !!jnamespaces) > 1) { struct json_object *jplatform = json_object_new_object(); if (!jplatform) { fail("\n"); return -ENOMEM; } if (jdimms) json_object_object_add(jplatform, "dimms", jdimms); if (jregions) json_object_object_add(jplatform, "regions", jregions); if (jnamespaces) json_object_object_add(jplatform, "namespaces", jnamespaces); printf("%s\n", json_object_to_json_string_ext(jplatform, jflag)); json_object_put(jplatform); } else if (jdimms) display_array(jdimms); else if (jregions) display_array(jregions); else if (jnamespaces) display_array(jnamespaces); if (did_fail) return -ENOMEM; return 0; }
int cmd_list(int argc, const char **argv) { const struct option options[] = { OPT_STRING('b', "bus", ¶m.bus, "bus-id", "filter by bus"), OPT_STRING('r', "region", ¶m.region, "region-id", "filter by region"), OPT_STRING('d', "dimm", ¶m.dimm, "dimm-id", "filter by dimm"), OPT_STRING('t', "type", ¶m.type, "region-type", "filter by region-type"), OPT_BOOLEAN('B', "buses", &list.buses, "include bus info"), OPT_BOOLEAN('D', "dimms", &list.dimms, "include dimm info"), OPT_BOOLEAN('H', "health", &list.health, "include dimm health"), OPT_BOOLEAN('R', "regions", &list.regions, "include region info"), OPT_BOOLEAN('N', "namespaces", &list.namespaces, "include namespace info (default)"), OPT_BOOLEAN('i', "idle", &list.idle, "include idle devices"), OPT_END(), }; const char * const u[] = { "ndctl list [<options>]", NULL }; struct json_object *jnamespaces = NULL; struct json_object *jregions = NULL; struct json_object *jdimms = NULL; struct json_object *jbuses = NULL; struct ndctl_ctx *ctx; struct ndctl_bus *bus; unsigned int type = 0; int i, rc; argc = parse_options(argc, argv, options, u, 0); for (i = 0; i < argc; i++) error("unknown parameter \"%s\"\n", argv[i]); if (param.type && (strcmp(param.type, "pmem") != 0 && strcmp(param.type, "blk") != 0)) { error("unknown type \"%s\" must be \"pmem\" or \"blk\"\n", param.type); argc++; } if (argc) usage_with_options(u, options); if (num_list_flags() == 0) { list.buses = !!param.bus; list.regions = !!param.region; list.dimms = !!param.dimm; } if (num_list_flags() == 0) list.namespaces = true; if (param.type) { if (strcmp(param.type, "pmem") == 0) type = ND_DEVICE_REGION_PMEM; else type = ND_DEVICE_REGION_BLK; } rc = ndctl_new(&ctx); if (rc < 0) return rc; ndctl_bus_foreach(ctx, bus) { struct json_object *jbus = NULL; struct ndctl_region *region; struct ndctl_dimm *dimm; if (!util_bus_filter(bus, param.bus) || !util_bus_filter_by_dimm(bus, param.dimm)) continue; if (list.buses) { if (!jbuses) { jbuses = json_object_new_array(); if (!jbuses) { fail("\n"); continue; } } jbus = util_bus_to_json(bus); if (!jbus) { fail("\n"); continue; } json_object_array_add(jbuses, jbus); } ndctl_dimm_foreach(bus, dimm) { struct json_object *jdimm; /* are we emitting dimms? */ if (!list.dimms) break; if (!util_dimm_filter(dimm, param.dimm)) continue; if (!list.idle && !ndctl_dimm_is_enabled(dimm)) continue; if (!jdimms) { jdimms = json_object_new_array(); if (!jdimms) { fail("\n"); continue; } if (jbus) json_object_object_add(jbus, "dimms", jdimms); } jdimm = util_dimm_to_json(dimm); if (!jdimm) { fail("\n"); continue; } if (list.health) { struct json_object *jhealth; jhealth = util_dimm_health_to_json(dimm); if (jhealth) json_object_object_add(jdimm, "health", jhealth); else if (ndctl_dimm_is_cmd_supported(dimm, ND_CMD_SMART)) { /* * Failed to retrieve health data from * a dimm that otherwise supports smart * data retrieval commands. */ fail("\n"); continue; } } /* * Without a bus we are collecting dimms anonymously * across the platform. */ json_object_array_add(jdimms, jdimm); } ndctl_region_foreach(bus, region) { struct json_object *jregion; if (!util_region_filter(region, param.region) || !util_region_filter_by_dimm(region, param.dimm)) continue; if (type && ndctl_region_get_type(region) != type) continue; if (!list.regions) { jnamespaces = list_namespaces(region, jbus, jnamespaces, true); continue; } if (!list.idle && !ndctl_region_is_enabled(region)) continue; if (!jregions) { jregions = json_object_new_array(); if (!jregions) { fail("\n"); continue; } if (jbus) json_object_object_add(jbus, "regions", jregions); } jregion = region_to_json(region); if (!jregion) { fail("\n"); continue; } /* * Without a bus we are collecting regions anonymously * across the platform. */ json_object_array_add(jregions, jregion); } if (jbuses) { jdimms = NULL; jregions = NULL; jnamespaces = NULL; } } if (jbuses) util_display_json_array(stdout, jbuses, jflag); else if ((!!jdimms + !!jregions + !!jnamespaces) > 1) { struct json_object *jplatform = json_object_new_object(); if (!jplatform) { fail("\n"); return -ENOMEM; } if (jdimms) json_object_object_add(jplatform, "dimms", jdimms); if (jregions) json_object_object_add(jplatform, "regions", jregions); if (jnamespaces) json_object_object_add(jplatform, "namespaces", jnamespaces); printf("%s\n", json_object_to_json_string_ext(jplatform, jflag)); json_object_put(jplatform); } else if (jdimms) util_display_json_array(stdout, jdimms, jflag); else if (jregions) util_display_json_array(stdout, jregions, jflag); else if (jnamespaces) util_display_json_array(stdout, jnamespaces, jflag); if (did_fail) return -ENOMEM; return 0; }