We already support filtering region and bus listings by dimm, lets extend that to the other object types. I.e. permit buses to be filtered by regions, dimms, and namespaces; allow regions to be filtered by dimms, and namespaces etc...
For example, to list all the DIMMs that comprise a given namespace: # ndctl list --dimms --namespace=7.0 [ { "dev":"nmem1", "id":"cdab-0a-07e0-ffffffff", "handle":0, "phys_id":0 }, { "dev":"nmem3", "id":"cdab-0a-07e0-fffeffff", "handle":256, "phys_id":2 }, { "dev":"nmem2", "id":"cdab-0a-07e0-feffffff", "handle":1, "phys_id":1 }, { "dev":"nmem4", "id":"cdab-0a-07e0-fefeffff", "handle":257, "phys_id":3 } ] Reported-by: Keith Hazelet <keith.haze...@intel.com> Signed-off-by: Dan Williams <dan.j.willi...@intel.com> --- ndctl/list.c | 14 +++++++-- util/filter.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ util/filter.h | 10 ++++++ 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/ndctl/list.c b/ndctl/list.c index c910c776c61d..1960e9f8d7b5 100644 --- a/ndctl/list.c +++ b/ndctl/list.c @@ -344,7 +344,9 @@ int cmd_list(int argc, const char **argv, void *ctx) struct ndctl_dimm *dimm; if (!util_bus_filter(bus, param.bus) - || !util_bus_filter_by_dimm(bus, param.dimm)) + || !util_bus_filter_by_dimm(bus, param.dimm) + || !util_bus_filter_by_region(bus, param.region) + || !util_bus_filter_by_namespace(bus, param.namespace)) continue; if (list.buses) { @@ -371,7 +373,11 @@ int cmd_list(int argc, const char **argv, void *ctx) if (!list.dimms) break; - if (!util_dimm_filter(dimm, param.dimm)) + if (!util_dimm_filter(dimm, param.dimm) + || !util_dimm_filter_by_region(dimm, + param.region) + || !util_dimm_filter_by_namespace(dimm, + param.namespace)) continue; if (!list.idle && !ndctl_dimm_is_enabled(dimm)) @@ -425,7 +431,9 @@ int cmd_list(int argc, const char **argv, void *ctx) if (!util_region_filter(region, param.region) || !util_region_filter_by_dimm(region, - param.dimm)) + param.dimm) + || !util_region_filter_by_namespace(region, + param.namespace)) continue; if (type && ndctl_region_get_type(region) != type) diff --git a/util/filter.c b/util/filter.c index 400c11a3a80a..acc006cd1d41 100644 --- a/util/filter.c +++ b/util/filter.c @@ -130,6 +130,37 @@ struct ndctl_bus *util_bus_filter_by_dimm(struct ndctl_bus *bus, return NULL; } +struct ndctl_bus *util_bus_filter_by_region(struct ndctl_bus *bus, + const char *ident) +{ + struct ndctl_region *region; + + if (!ident || strcmp(ident, "all") == 0) + return bus; + + ndctl_region_foreach(bus, region) + if (util_region_filter(region, ident)) + return bus; + return NULL; +} + + +struct ndctl_bus *util_bus_filter_by_namespace(struct ndctl_bus *bus, + const char *ident) +{ + struct ndctl_region *region; + struct ndctl_namespace *ndns; + + if (!ident || strcmp(ident, "all") == 0) + return bus; + + ndctl_region_foreach(bus, region) + ndctl_namespace_foreach(region, ndns) + if (util_namespace_filter(ndns, ident)) + return bus; + return NULL; +} + struct ndctl_region *util_region_filter_by_dimm(struct ndctl_region *region, const char *ident) { @@ -145,6 +176,65 @@ struct ndctl_region *util_region_filter_by_dimm(struct ndctl_region *region, return NULL; } +struct ndctl_dimm *util_dimm_filter_by_region(struct ndctl_dimm *dimm, + const char *ident) +{ + struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm); + struct ndctl_region *region; + struct ndctl_dimm *check; + + if (!ident || strcmp(ident, "all") == 0) + return dimm; + + ndctl_region_foreach(bus, region) { + if (!util_region_filter(region, ident)) + continue; + ndctl_dimm_foreach_in_region(region, check) + if (check == dimm) + return dimm; + } + + return NULL; +} + +struct ndctl_dimm *util_dimm_filter_by_namespace(struct ndctl_dimm *dimm, + const char *ident) +{ + struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm); + struct ndctl_namespace *ndns; + struct ndctl_region *region; + struct ndctl_dimm *check; + + if (!ident || strcmp(ident, "all") == 0) + return dimm; + + ndctl_region_foreach(bus, region) { + ndctl_namespace_foreach(region, ndns) { + if (!util_namespace_filter(ndns, ident)) + continue; + ndctl_dimm_foreach_in_region(region, check) + if (check == dimm) + return dimm; + } + } + + return NULL; +} + +struct ndctl_region *util_region_filter_by_namespace(struct ndctl_region *region, + const char *ident) +{ + struct ndctl_namespace *ndns; + + if (!ident || strcmp(ident, "all") == 0) + return region; + + ndctl_namespace_foreach(region, ndns) + if (util_namespace_filter(ndns, ident)) + return region; + return NULL; +} + struct daxctl_dev *util_daxctl_dev_filter(struct daxctl_dev *dev, const char *ident) { diff --git a/util/filter.h b/util/filter.h index dcc537caaaf9..aa0098d2c099 100644 --- a/util/filter.h +++ b/util/filter.h @@ -20,8 +20,18 @@ struct ndctl_namespace *util_namespace_filter(struct ndctl_namespace *ndns, struct ndctl_dimm *util_dimm_filter(struct ndctl_dimm *dimm, const char *ident); struct ndctl_bus *util_bus_filter_by_dimm(struct ndctl_bus *bus, const char *ident); +struct ndctl_bus *util_bus_filter_by_region(struct ndctl_bus *bus, + const char *ident); +struct ndctl_bus *util_bus_filter_by_namespace(struct ndctl_bus *bus, + const char *ident); struct ndctl_region *util_region_filter_by_dimm(struct ndctl_region *region, const char *ident); +struct ndctl_dimm *util_dimm_filter_by_region(struct ndctl_dimm *dimm, + const char *ident); +struct ndctl_dimm *util_dimm_filter_by_namespace(struct ndctl_dimm *dimm, + const char *ident); +struct ndctl_region *util_region_filter_by_namespace(struct ndctl_region *region, + const char *ident); struct daxctl_dev *util_daxctl_dev_filter(struct daxctl_dev *dev, const char *ident); #endif _______________________________________________ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm