The kernel is implementing a '/sys/bus/dax' ABI to allow for alternate device-DAX drivers to be bound to device instances. In support of this conversion, teach the libdaxctl subsystem-layout-specific code to parse the new layout.
For backwards compatibility the implementation transparently and optionally supports either '/sys/bus/dax' or '/sys/class/dax'. Signed-off-by: Dan Williams <dan.j.willi...@intel.com> --- daxctl/lib/libdaxctl-private.h | 11 ++++++ daxctl/lib/libdaxctl.c | 70 +++++++++++++++++++++++++++++----------- util/sysfs.c | 2 + 3 files changed, 62 insertions(+), 21 deletions(-) diff --git a/daxctl/lib/libdaxctl-private.h b/daxctl/lib/libdaxctl-private.h index f7667324026f..4a462e7245d2 100644 --- a/daxctl/lib/libdaxctl-private.h +++ b/daxctl/lib/libdaxctl-private.h @@ -15,6 +15,17 @@ #define DAXCTL_EXPORT __attribute__ ((visibility("default"))) +enum dax_subsystem { + DAX_UNKNOWN, + DAX_CLASS, + DAX_BUS, +}; + +static const char *dax_subsystems[] = { + [DAX_CLASS] = "/sys/class/dax", + [DAX_BUS] = "/sys/bus/dax/devices", +}; + /** * struct daxctl_region - container for dax_devices */ diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c index 22f4210a7ea0..c2e3a52d6c7c 100644 --- a/daxctl/lib/libdaxctl.c +++ b/daxctl/lib/libdaxctl.c @@ -444,26 +444,38 @@ static void dax_devices_init(struct daxctl_region *region) { struct daxctl_ctx *ctx = daxctl_region_get_ctx(region); char daxdev_fmt[50]; - char *region_path; + size_t i; if (region->devices_init) return; region->devices_init = 1; sprintf(daxdev_fmt, "dax%d.", region->id); - if (asprintf(®ion_path, "%s/dax", region->region_path) < 0) { - dbg(ctx, "region path alloc fail\n"); - return; + for (i = 0; i < ARRAY_SIZE(dax_subsystems); i++) { + char *region_path; + + if (i == DAX_BUS) + region_path = region->region_path; + else if (i == DAX_CLASS) { + if (asprintf(®ion_path, "%s/dax", + region->region_path) < 0) { + dbg(ctx, "region path alloc fail\n"); + continue; + } + } else + continue; + sysfs_device_parse(ctx, region_path, daxdev_fmt, region, + add_dax_dev); + if (i == DAX_CLASS) + free(region_path); } - sysfs_device_parse(ctx, region_path, daxdev_fmt, region, add_dax_dev); - free(region_path); } -static char *dax_region_path(const char *base, const char *device) +static char *dax_region_path(const char *device, enum dax_subsystem subsys) { char *path, *region_path, *c; - if (asprintf(&path, "%s/%s", base, device) < 0) + if (asprintf(&path, "%s/%s", dax_subsystems[subsys], device) < 0) return NULL; /* dax_region must be the instance's direct parent */ @@ -472,7 +484,11 @@ static char *dax_region_path(const char *base, const char *device) if (!region_path) return NULL; - /* 'region_path' is now regionX/dax/daxX.Y', trim back to regionX */ + /* + * 'region_path' is now regionX/dax/daxX.Y' (DAX_CLASS), or + * regionX/daxX.Y (DAX_BUS), trim it back to the regionX + * component + */ c = strrchr(region_path, '/'); if (!c) { free(region_path); @@ -480,6 +496,9 @@ static char *dax_region_path(const char *base, const char *device) } *c = '\0'; + if (subsys == DAX_BUS) + return region_path; + c = strrchr(region_path, '/'); if (!c) { free(region_path); @@ -490,20 +509,15 @@ static char *dax_region_path(const char *base, const char *device) return region_path; } -static void dax_regions_init(struct daxctl_ctx *ctx) +static void __dax_regions_init(struct daxctl_ctx *ctx, enum dax_subsystem subsys) { - const char *base = "/sys/class/dax"; struct dirent *de; - DIR *dir; + DIR *dir = NULL; - if (ctx->regions_init) - return; - - ctx->regions_init = 1; - - dir = opendir(base); + dir = opendir(dax_subsystems[subsys]); if (!dir) { - dbg(ctx, "no dax regions found\n"); + dbg(ctx, "no dax regions found via: %s\n", + dax_subsystems[subsys]); return; } @@ -516,7 +530,7 @@ static void dax_regions_init(struct daxctl_ctx *ctx) continue; if (sscanf(de->d_name, "dax%d.%d", ®ion_id, &id) != 2) continue; - dev_path = dax_region_path(base, de->d_name); + dev_path = dax_region_path(de->d_name, subsys); if (!dev_path) { err(ctx, "dax region path allocation failure\n"); continue; @@ -529,6 +543,22 @@ static void dax_regions_init(struct daxctl_ctx *ctx) closedir(dir); } +static void dax_regions_init(struct daxctl_ctx *ctx) +{ + size_t i; + + if (ctx->regions_init) + return; + + ctx->regions_init = 1; + + for (i = 0; i < ARRAY_SIZE(dax_subsystems); i++) { + if (i == DAX_UNKNOWN) + continue; + __dax_regions_init(ctx, i); + } +} + DAXCTL_EXPORT struct daxctl_dev *daxctl_dev_get_first(struct daxctl_region *region) { dax_devices_init(region); diff --git a/util/sysfs.c b/util/sysfs.c index 0440fd0f49a3..9f7bc1f4930f 100644 --- a/util/sysfs.c +++ b/util/sysfs.c @@ -91,7 +91,7 @@ int __sysfs_device_parse(struct log_ctx *ctx, const char *base_path, struct dirent *de; DIR *dir; - log_dbg(ctx, "base: %s dev: %s\n", base_path, dev_name); + log_dbg(ctx, "base: '%s' dev: '%s'\n", base_path, dev_name); dir = opendir(base_path); if (!dir) { log_dbg(ctx, "no \"%s\" devices found\n", dev_name); _______________________________________________ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm