Skip to content

Commit

Permalink
Avoid WARN() from procfs on kstat collision
Browse files Browse the repository at this point in the history
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 openzfs#628
  • Loading branch information
loli10K authored and behlendorf committed Jul 24, 2017
1 parent 9441175 commit cd47801
Showing 1 changed file with 29 additions and 0 deletions.
29 changes: 29 additions & 0 deletions module/spl/spl-kstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down

0 comments on commit cd47801

Please sign in to comment.