summaryrefslogtreecommitdiffstats
path: root/module/spl
diff options
context:
space:
mode:
authorLOLi <[email protected]>2017-07-24 19:52:53 +0200
committerBrian Behlendorf <[email protected]>2017-07-24 10:52:53 -0700
commitcd47801828c760efebbbb1fad7f7899369d8bce7 (patch)
treece7a019516c51516d522730eaed289f508ed31f4 /module/spl
parent944117514d2aba081b15faad741e7d0c6b1465c8 (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.c29
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;