|
|
e0018b |
From e31fc778998b4d02ffec68e61869aaeccfd99be8 Mon Sep 17 00:00:00 2001
|
|
|
e0018b |
From: Dan Williams <dan.j.williams@intel.com>
|
|
|
e0018b |
Date: Sun, 23 Jan 2022 16:54:17 -0800
|
|
|
e0018b |
Subject: [PATCH 114/217] util: Implement common bind/unbind helpers
|
|
|
e0018b |
|
|
|
e0018b |
Refactor ndctl_{bind,unbind}() into util_{bind,unbind}() for libcxl to
|
|
|
e0018b |
reuse.
|
|
|
e0018b |
|
|
|
e0018b |
daxctl can not join the party for now as it needs to play games with
|
|
|
e0018b |
'new_id'.
|
|
|
e0018b |
|
|
|
e0018b |
Link: https://lore.kernel.org/r/164298565707.3021641.7763459936156744907.stgit@dwillia2-desk3.amr.corp.intel.com
|
|
|
e0018b |
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
|
|
|
e0018b |
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
|
|
|
e0018b |
---
|
|
|
e0018b |
ndctl/lib/libndctl.c | 103 +++++--------------------------------------
|
|
|
e0018b |
util/sysfs.c | 76 +++++++++++++++++++++++++++++++
|
|
|
e0018b |
util/sysfs.h | 8 ++++
|
|
|
e0018b |
3 files changed, 96 insertions(+), 91 deletions(-)
|
|
|
e0018b |
|
|
|
e0018b |
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
|
|
|
e0018b |
index 1374ad9..98d184b 100644
|
|
|
e0018b |
--- a/ndctl/lib/libndctl.c
|
|
|
e0018b |
+++ b/ndctl/lib/libndctl.c
|
|
|
e0018b |
@@ -1665,10 +1665,6 @@ static enum ndctl_fwa_result fwa_result_to_result(const char *result)
|
|
|
e0018b |
return NDCTL_FWA_RESULT_INVALID;
|
|
|
e0018b |
}
|
|
|
e0018b |
|
|
|
e0018b |
-static int ndctl_bind(struct ndctl_ctx *ctx, struct kmod_module *module,
|
|
|
e0018b |
- const char *devname);
|
|
|
e0018b |
-static int ndctl_unbind(struct ndctl_ctx *ctx, const char *devpath);
|
|
|
e0018b |
-
|
|
|
e0018b |
static int populate_dimm_attributes(struct ndctl_dimm *dimm,
|
|
|
e0018b |
const char *dimm_base,
|
|
|
e0018b |
const char *bus_prefix)
|
|
|
e0018b |
@@ -2305,7 +2301,7 @@ NDCTL_EXPORT int ndctl_dimm_disable(struct ndctl_dimm *dimm)
|
|
|
e0018b |
if (!ndctl_dimm_is_enabled(dimm))
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_unbind(ctx, dimm->dimm_path);
|
|
|
e0018b |
+ util_unbind(dimm->dimm_path, ctx);
|
|
|
e0018b |
|
|
|
e0018b |
if (ndctl_dimm_is_enabled(dimm)) {
|
|
|
e0018b |
err(ctx, "%s: failed to disable\n", devname);
|
|
|
e0018b |
@@ -2324,7 +2320,7 @@ NDCTL_EXPORT int ndctl_dimm_enable(struct ndctl_dimm *dimm)
|
|
|
e0018b |
if (ndctl_dimm_is_enabled(dimm))
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_bind(ctx, dimm->module, devname);
|
|
|
e0018b |
+ util_bind(devname, dimm->module, "nd", ctx);
|
|
|
e0018b |
|
|
|
e0018b |
if (!ndctl_dimm_is_enabled(dimm)) {
|
|
|
e0018b |
err(ctx, "%s: failed to enable\n", devname);
|
|
|
e0018b |
@@ -3573,7 +3569,7 @@ NDCTL_EXPORT int ndctl_region_enable(struct ndctl_region *region)
|
|
|
e0018b |
if (ndctl_region_is_enabled(region))
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_bind(ctx, region->module, devname);
|
|
|
e0018b |
+ util_bind(devname, region->module, "nd", ctx);
|
|
|
e0018b |
|
|
|
e0018b |
if (!ndctl_region_is_enabled(region)) {
|
|
|
e0018b |
err(ctx, "%s: failed to enable\n", devname);
|
|
|
e0018b |
@@ -3610,7 +3606,7 @@ static int ndctl_region_disable(struct ndctl_region *region, int cleanup)
|
|
|
e0018b |
if (!ndctl_region_is_enabled(region))
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_unbind(ctx, region->region_path);
|
|
|
e0018b |
+ util_unbind(region->region_path, ctx);
|
|
|
e0018b |
|
|
|
e0018b |
if (ndctl_region_is_enabled(region)) {
|
|
|
e0018b |
err(ctx, "%s: failed to disable\n", devname);
|
|
|
e0018b |
@@ -4373,81 +4369,6 @@ NDCTL_EXPORT struct badblock *ndctl_namespace_get_first_badblock(
|
|
|
e0018b |
return badblocks_iter_first(&ndns->bb_iter, ctx, path);
|
|
|
e0018b |
}
|
|
|
e0018b |
|
|
|
e0018b |
-static int ndctl_bind(struct ndctl_ctx *ctx, struct kmod_module *module,
|
|
|
e0018b |
- const char *devname)
|
|
|
e0018b |
-{
|
|
|
e0018b |
- DIR *dir;
|
|
|
e0018b |
- int rc = 0;
|
|
|
e0018b |
- char path[200];
|
|
|
e0018b |
- struct dirent *de;
|
|
|
e0018b |
- const int len = sizeof(path);
|
|
|
e0018b |
-
|
|
|
e0018b |
- if (!devname) {
|
|
|
e0018b |
- err(ctx, "missing devname\n");
|
|
|
e0018b |
- return -EINVAL;
|
|
|
e0018b |
- }
|
|
|
e0018b |
-
|
|
|
e0018b |
- if (module) {
|
|
|
e0018b |
- rc = kmod_module_probe_insert_module(module,
|
|
|
e0018b |
- KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL,
|
|
|
e0018b |
- NULL);
|
|
|
e0018b |
- if (rc < 0) {
|
|
|
e0018b |
- err(ctx, "%s: insert failure: %d\n", __func__, rc);
|
|
|
e0018b |
- return rc;
|
|
|
e0018b |
- }
|
|
|
e0018b |
- }
|
|
|
e0018b |
-
|
|
|
e0018b |
- if (snprintf(path, len, "/sys/bus/nd/drivers") >= len) {
|
|
|
e0018b |
- err(ctx, "%s: buffer too small!\n", devname);
|
|
|
e0018b |
- return -ENXIO;
|
|
|
e0018b |
- }
|
|
|
e0018b |
-
|
|
|
e0018b |
- dir = opendir(path);
|
|
|
e0018b |
- if (!dir) {
|
|
|
e0018b |
- err(ctx, "%s: opendir(\"%s\") failed\n", devname, path);
|
|
|
e0018b |
- return -ENXIO;
|
|
|
e0018b |
- }
|
|
|
e0018b |
-
|
|
|
e0018b |
- while ((de = readdir(dir)) != NULL) {
|
|
|
e0018b |
- char *drv_path;
|
|
|
e0018b |
-
|
|
|
e0018b |
- if (de->d_ino == 0)
|
|
|
e0018b |
- continue;
|
|
|
e0018b |
- if (de->d_name[0] == '.')
|
|
|
e0018b |
- continue;
|
|
|
e0018b |
- if (asprintf(&drv_path, "%s/%s/bind", path, de->d_name) < 0) {
|
|
|
e0018b |
- err(ctx, "%s: path allocation failure\n", devname);
|
|
|
e0018b |
- continue;
|
|
|
e0018b |
- }
|
|
|
e0018b |
-
|
|
|
e0018b |
- rc = sysfs_write_attr_quiet(ctx, drv_path, devname);
|
|
|
e0018b |
- free(drv_path);
|
|
|
e0018b |
- if (rc == 0)
|
|
|
e0018b |
- break;
|
|
|
e0018b |
- }
|
|
|
e0018b |
- closedir(dir);
|
|
|
e0018b |
-
|
|
|
e0018b |
- if (rc) {
|
|
|
e0018b |
- dbg(ctx, "%s: bind failed\n", devname);
|
|
|
e0018b |
- return -ENXIO;
|
|
|
e0018b |
- }
|
|
|
e0018b |
- return 0;
|
|
|
e0018b |
-}
|
|
|
e0018b |
-
|
|
|
e0018b |
-static int ndctl_unbind(struct ndctl_ctx *ctx, const char *devpath)
|
|
|
e0018b |
-{
|
|
|
e0018b |
- const char *devname = devpath_to_devname(devpath);
|
|
|
e0018b |
- char path[200];
|
|
|
e0018b |
- const int len = sizeof(path);
|
|
|
e0018b |
-
|
|
|
e0018b |
- if (snprintf(path, len, "%s/driver/unbind", devpath) >= len) {
|
|
|
e0018b |
- err(ctx, "%s: buffer too small!\n", devname);
|
|
|
e0018b |
- return -ENXIO;
|
|
|
e0018b |
- }
|
|
|
e0018b |
-
|
|
|
e0018b |
- return sysfs_write_attr(ctx, path, devname);
|
|
|
e0018b |
-}
|
|
|
e0018b |
-
|
|
|
e0018b |
static void *add_btt(void *parent, int id, const char *btt_base);
|
|
|
e0018b |
static void *add_pfn(void *parent, int id, const char *pfn_base);
|
|
|
e0018b |
static void *add_dax(void *parent, int id, const char *dax_base);
|
|
|
e0018b |
@@ -4533,7 +4454,7 @@ NDCTL_EXPORT int ndctl_namespace_enable(struct ndctl_namespace *ndns)
|
|
|
e0018b |
if (ndctl_namespace_is_enabled(ndns))
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
|
|
|
e0018b |
- rc = ndctl_bind(ctx, ndns->module, devname);
|
|
|
e0018b |
+ rc = util_bind(devname, ndns->module, "nd", ctx);
|
|
|
e0018b |
|
|
|
e0018b |
/*
|
|
|
e0018b |
* Rescan now as successfully enabling a namespace device leads
|
|
|
e0018b |
@@ -4581,7 +4502,7 @@ NDCTL_EXPORT int ndctl_namespace_disable(struct ndctl_namespace *ndns)
|
|
|
e0018b |
if (!ndctl_namespace_is_enabled(ndns))
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_unbind(ctx, ndns->ndns_path);
|
|
|
e0018b |
+ util_unbind(ndns->ndns_path, ctx);
|
|
|
e0018b |
|
|
|
e0018b |
if (ndctl_namespace_is_enabled(ndns)) {
|
|
|
e0018b |
err(ctx, "%s: failed to disable\n", devname);
|
|
|
e0018b |
@@ -5420,7 +5341,7 @@ NDCTL_EXPORT int ndctl_btt_enable(struct ndctl_btt *btt)
|
|
|
e0018b |
if (ndctl_btt_is_enabled(btt))
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_bind(ctx, btt->module, devname);
|
|
|
e0018b |
+ util_bind(devname, btt->module, "nd", ctx);
|
|
|
e0018b |
|
|
|
e0018b |
if (!ndctl_btt_is_enabled(btt)) {
|
|
|
e0018b |
err(ctx, "%s: failed to enable\n", devname);
|
|
|
e0018b |
@@ -5457,7 +5378,7 @@ NDCTL_EXPORT int ndctl_btt_delete(struct ndctl_btt *btt)
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
}
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_unbind(ctx, btt->btt_path);
|
|
|
e0018b |
+ util_unbind(btt->btt_path, ctx);
|
|
|
e0018b |
|
|
|
e0018b |
rc = ndctl_btt_set_namespace(btt, NULL);
|
|
|
e0018b |
if (rc) {
|
|
|
e0018b |
@@ -5908,7 +5829,7 @@ NDCTL_EXPORT int ndctl_pfn_enable(struct ndctl_pfn *pfn)
|
|
|
e0018b |
if (ndctl_pfn_is_enabled(pfn))
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_bind(ctx, pfn->module, devname);
|
|
|
e0018b |
+ util_bind(devname, pfn->module, "nd", ctx);
|
|
|
e0018b |
|
|
|
e0018b |
if (!ndctl_pfn_is_enabled(pfn)) {
|
|
|
e0018b |
err(ctx, "%s: failed to enable\n", devname);
|
|
|
e0018b |
@@ -5945,7 +5866,7 @@ NDCTL_EXPORT int ndctl_pfn_delete(struct ndctl_pfn *pfn)
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
}
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_unbind(ctx, pfn->pfn_path);
|
|
|
e0018b |
+ util_unbind(pfn->pfn_path, ctx);
|
|
|
e0018b |
|
|
|
e0018b |
rc = ndctl_pfn_set_namespace(pfn, NULL);
|
|
|
e0018b |
if (rc) {
|
|
|
e0018b |
@@ -6101,7 +6022,7 @@ NDCTL_EXPORT int ndctl_dax_enable(struct ndctl_dax *dax)
|
|
|
e0018b |
if (ndctl_dax_is_enabled(dax))
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_bind(ctx, pfn->module, devname);
|
|
|
e0018b |
+ util_bind(devname, pfn->module, "nd", ctx);
|
|
|
e0018b |
|
|
|
e0018b |
if (!ndctl_dax_is_enabled(dax)) {
|
|
|
e0018b |
err(ctx, "%s: failed to enable\n", devname);
|
|
|
e0018b |
@@ -6132,7 +6053,7 @@ NDCTL_EXPORT int ndctl_dax_delete(struct ndctl_dax *dax)
|
|
|
e0018b |
return 0;
|
|
|
e0018b |
}
|
|
|
e0018b |
|
|
|
e0018b |
- ndctl_unbind(ctx, pfn->pfn_path);
|
|
|
e0018b |
+ util_unbind(pfn->pfn_path, ctx);
|
|
|
e0018b |
|
|
|
e0018b |
rc = ndctl_dax_set_namespace(dax, NULL);
|
|
|
e0018b |
if (rc) {
|
|
|
e0018b |
diff --git a/util/sysfs.c b/util/sysfs.c
|
|
|
e0018b |
index 23330cb..968683b 100644
|
|
|
e0018b |
--- a/util/sysfs.c
|
|
|
e0018b |
+++ b/util/sysfs.c
|
|
|
e0018b |
@@ -145,3 +145,79 @@ struct kmod_module *__util_modalias_to_module(struct kmod_ctx *kmod_ctx,
|
|
|
e0018b |
|
|
|
e0018b |
return mod;
|
|
|
e0018b |
}
|
|
|
e0018b |
+
|
|
|
e0018b |
+int __util_bind(const char *devname, struct kmod_module *module,
|
|
|
e0018b |
+ const char *bus, struct log_ctx *ctx)
|
|
|
e0018b |
+{
|
|
|
e0018b |
+ DIR *dir;
|
|
|
e0018b |
+ int rc = 0;
|
|
|
e0018b |
+ char path[200];
|
|
|
e0018b |
+ struct dirent *de;
|
|
|
e0018b |
+ const int len = sizeof(path);
|
|
|
e0018b |
+
|
|
|
e0018b |
+ if (!devname) {
|
|
|
e0018b |
+ log_err(ctx, "missing devname\n");
|
|
|
e0018b |
+ return -EINVAL;
|
|
|
e0018b |
+ }
|
|
|
e0018b |
+
|
|
|
e0018b |
+ if (module) {
|
|
|
e0018b |
+ rc = kmod_module_probe_insert_module(module,
|
|
|
e0018b |
+ KMOD_PROBE_APPLY_BLACKLIST,
|
|
|
e0018b |
+ NULL, NULL, NULL, NULL);
|
|
|
e0018b |
+ if (rc < 0) {
|
|
|
e0018b |
+ log_err(ctx, "%s: insert failure: %d\n", __func__, rc);
|
|
|
e0018b |
+ return rc;
|
|
|
e0018b |
+ }
|
|
|
e0018b |
+ }
|
|
|
e0018b |
+
|
|
|
e0018b |
+ if (snprintf(path, len, "/sys/bus/%s/drivers", bus) >= len) {
|
|
|
e0018b |
+ log_err(ctx, "%s: buffer too small!\n", devname);
|
|
|
e0018b |
+ return -ENXIO;
|
|
|
e0018b |
+ }
|
|
|
e0018b |
+
|
|
|
e0018b |
+ dir = opendir(path);
|
|
|
e0018b |
+ if (!dir) {
|
|
|
e0018b |
+ log_err(ctx, "%s: opendir(\"%s\") failed\n", devname, path);
|
|
|
e0018b |
+ return -ENXIO;
|
|
|
e0018b |
+ }
|
|
|
e0018b |
+
|
|
|
e0018b |
+ while ((de = readdir(dir)) != NULL) {
|
|
|
e0018b |
+ char *drv_path;
|
|
|
e0018b |
+
|
|
|
e0018b |
+ if (de->d_ino == 0)
|
|
|
e0018b |
+ continue;
|
|
|
e0018b |
+ if (de->d_name[0] == '.')
|
|
|
e0018b |
+ continue;
|
|
|
e0018b |
+
|
|
|
e0018b |
+ if (asprintf(&drv_path, "%s/%s/bind", path, de->d_name) < 0) {
|
|
|
e0018b |
+ log_err(ctx, "%s: path allocation failure\n", devname);
|
|
|
e0018b |
+ continue;
|
|
|
e0018b |
+ }
|
|
|
e0018b |
+
|
|
|
e0018b |
+ rc = __sysfs_write_attr_quiet(ctx, drv_path, devname);
|
|
|
e0018b |
+ free(drv_path);
|
|
|
e0018b |
+ if (rc == 0)
|
|
|
e0018b |
+ break;
|
|
|
e0018b |
+ }
|
|
|
e0018b |
+ closedir(dir);
|
|
|
e0018b |
+
|
|
|
e0018b |
+ if (rc) {
|
|
|
e0018b |
+ log_dbg(ctx, "%s: bind failed\n", devname);
|
|
|
e0018b |
+ return -ENXIO;
|
|
|
e0018b |
+ }
|
|
|
e0018b |
+ return 0;
|
|
|
e0018b |
+}
|
|
|
e0018b |
+
|
|
|
e0018b |
+int __util_unbind(const char *devpath, struct log_ctx *ctx)
|
|
|
e0018b |
+{
|
|
|
e0018b |
+ const char *devname = devpath_to_devname(devpath);
|
|
|
e0018b |
+ char path[200];
|
|
|
e0018b |
+ const int len = sizeof(path);
|
|
|
e0018b |
+
|
|
|
e0018b |
+ if (snprintf(path, len, "%s/driver/unbind", devpath) >= len) {
|
|
|
e0018b |
+ log_err(ctx, "%s: buffer too small!\n", devname);
|
|
|
e0018b |
+ return -ENXIO;
|
|
|
e0018b |
+ }
|
|
|
e0018b |
+
|
|
|
e0018b |
+ return __sysfs_write_attr(ctx, path, devname);
|
|
|
e0018b |
+}
|
|
|
e0018b |
diff --git a/util/sysfs.h b/util/sysfs.h
|
|
|
e0018b |
index bdee4f5..4c95c70 100644
|
|
|
e0018b |
--- a/util/sysfs.h
|
|
|
e0018b |
+++ b/util/sysfs.h
|
|
|
e0018b |
@@ -35,4 +35,12 @@ struct kmod_module *__util_modalias_to_module(struct kmod_ctx *kmod_ctx,
|
|
|
e0018b |
struct log_ctx *log);
|
|
|
e0018b |
#define util_modalias_to_module(ctx, buf) \
|
|
|
e0018b |
__util_modalias_to_module((ctx)->kmod_ctx, buf, &(ctx)->ctx)
|
|
|
e0018b |
+
|
|
|
e0018b |
+int __util_bind(const char *devname, struct kmod_module *module, const char *bus,
|
|
|
e0018b |
+ struct log_ctx *ctx);
|
|
|
e0018b |
+#define util_bind(n, m, b, c) __util_bind(n, m, b, &(c)->ctx)
|
|
|
e0018b |
+
|
|
|
e0018b |
+int __util_unbind(const char *devpath, struct log_ctx *ctx);
|
|
|
e0018b |
+#define util_unbind(p, c) __util_unbind(p, &(c)->ctx)
|
|
|
e0018b |
+
|
|
|
e0018b |
#endif /* __UTIL_SYSFS_H__ */
|
|
|
e0018b |
--
|
|
|
e0018b |
2.27.0
|
|
|
e0018b |
|