Skip to content

Commit

Permalink
freebsd/kstat: replace existing kstat if name is reused
Browse files Browse the repository at this point in the history
Normally, when trying to add a sysctl name that already exists, the
kernel rejects it with a warning. This changes the code to search for a
sysctl with the wanted name in same root. If it exists, it is destroyed,
allowing the new one to go in.

Arguably, a collision like this shouldn't ever happen, but during
import multiple vdev_t (and so vdev_queue_t, and so vdev_queue stats)
can exist at the same time for the same guid. There's no real way to
tell which is which without substantial refactoring in the import and
vdev init codepaths, whch is probably worthwhile but not for today.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
  • Loading branch information
robn committed May 16, 2024
1 parent 13266a2 commit ff729e1
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions module/os/freebsd/spl/spl_kstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,26 @@ kstat_install_named(kstat_t *ksp)
if (ksent->data_type != 0) {
typelast = ksent->data_type;
namelast = ksent->name;

/*
* If a sysctl with this name already exists on this on
* this root, first remove it by deleting it from its
* old context, and then destroying it.
*/
struct sysctl_oid *oid = NULL;
SYSCTL_FOREACH(oid,
SYSCTL_CHILDREN(ksp->ks_sysctl_root)) {
if (strcmp(oid->oid_name, namelast) == 0) {
kstat_t *oldksp =
(kstat_t *)oid->oid_arg1;
sysctl_ctx_entry_del(
&oldksp->ks_sysctl_ctx, oid);
sysctl_remove_oid(oid, 1, 0);
break;
}
}
}

switch (typelast) {
case KSTAT_DATA_CHAR:
/* Not Implemented */
Expand Down

0 comments on commit ff729e1

Please sign in to comment.