diff options
author | LOLi <[email protected]> | 2017-07-24 19:52:53 +0200 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-07-24 10:52:53 -0700 |
commit | cd47801828c760efebbbb1fad7f7899369d8bce7 (patch) | |
tree | ce7a019516c51516d522730eaed289f508ed31f4 /module/spl | |
parent | 944117514d2aba081b15faad741e7d0c6b1465c8 (diff) |
Avoid WARN() from procfs on kstat collision
When we load a ZFS pool having spa_name equals to some existing kstat
we would have to create a duplicate entry, which procfs doesn't like.
For instance a ZFS pool named "zil" would have its kstat "txgs"
(module "zfs/zil") intalled under "/proc/spl/kstat/zfs/zil":
unfortunately we already have a kstat named "zil" (module "zfs")
installed in the same procfs location.
Avoid this issue by skipping the duplicate entry creation in procfs.
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: loli10K <[email protected]>
Closes #628
Diffstat (limited to 'module/spl')
-rw-r--r-- | module/spl/spl-kstat.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/module/spl/spl-kstat.c b/module/spl/spl-kstat.c index e8917a3ea..1b6a7df9b 100644 --- a/module/spl/spl-kstat.c +++ b/module/spl/spl-kstat.c @@ -27,6 +27,7 @@ #include <linux/seq_file.h> #include <sys/kstat.h> #include <sys/vmem.h> +#include <sys/cmn_err.h> #ifndef HAVE_PDE_DATA #define PDE_DATA(x) (PDE(x)->data) @@ -608,6 +609,29 @@ __kstat_create(const char *ks_module, int ks_instance, const char *ks_name, } EXPORT_SYMBOL(__kstat_create); +static int +kstat_detect_collision(kstat_t *ksp) +{ + kstat_module_t *module; + kstat_t *tmp; + char parent[KSTAT_STRLEN+1]; + char *cp; + + (void) strlcpy(parent, ksp->ks_module, sizeof(parent)); + + if ((cp = strrchr(parent, '/')) == NULL) + return (0); + + cp[0] = '\0'; + if ((module = kstat_find_module(parent)) != NULL) { + list_for_each_entry(tmp, &module->ksm_kstat_list, ks_list) + if (strncmp(tmp->ks_name, cp+1, KSTAT_STRLEN) == 0) + return (EEXIST); + } + + return (0); +} + void __kstat_install(kstat_t *ksp) { @@ -620,6 +644,11 @@ __kstat_install(kstat_t *ksp) module = kstat_find_module(ksp->ks_module); if (module == NULL) { + if (kstat_detect_collision(ksp) != 0) { + cmn_err(CE_WARN, "kstat_create('%s', '%s'): namespace" \ + " collision", ksp->ks_module, ksp->ks_name); + goto out; + } module = kstat_create_module(ksp->ks_module); if (module == NULL) goto out; |