freebsd/kstat: allow multi-level module names
This extends the existing special-case for zfs/poolname to split and create any number of intermediate sysctl names, so that multi-level module names are possible. Sponsored-by: Klara, Inc. Sponsored-by: Syneto Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
This commit is contained in:
parent
e31ed02433
commit
2c251e814c
|
@ -27,6 +27,10 @@
|
|||
* [1] https://illumos.org/man/1M/kstat
|
||||
* [2] https://illumos.org/man/9f/kstat_create
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2024, Klara, Inc.
|
||||
* Copyright (c) 2024, Syneto
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -287,7 +291,7 @@ __kstat_create(const char *module, int instance, const char *name,
|
|||
char buf[KSTAT_STRLEN];
|
||||
struct sysctl_oid *root;
|
||||
kstat_t *ksp;
|
||||
char *pool;
|
||||
char *p, *frag;
|
||||
|
||||
KASSERT(instance == 0, ("instance=%d", instance));
|
||||
if ((ks_type == KSTAT_TYPE_INTR) || (ks_type == KSTAT_TYPE_IO))
|
||||
|
@ -345,74 +349,54 @@ __kstat_create(const char *module, int instance, const char *name,
|
|||
else
|
||||
ksp->ks_data = kmem_zalloc(ksp->ks_data_size, KM_SLEEP);
|
||||
|
||||
/*
|
||||
* Some kstats use a module name like "zfs/poolname" to distinguish a
|
||||
* set of kstats belonging to a specific pool. Split on '/' to add an
|
||||
* extra node for the pool name if needed.
|
||||
*/
|
||||
sysctl_ctx_init(&ksp->ks_sysctl_ctx);
|
||||
|
||||
(void) strlcpy(buf, module, KSTAT_STRLEN);
|
||||
module = buf;
|
||||
pool = strchr(module, '/');
|
||||
if (pool != NULL)
|
||||
*pool++ = '\0';
|
||||
|
||||
/*
|
||||
* Create sysctl tree for those statistics:
|
||||
*
|
||||
* kstat.<module>[.<pool>].<class>.<name>
|
||||
* Walk over the module name, splitting on '/', and create the
|
||||
* intermediate nodes.
|
||||
*/
|
||||
sysctl_ctx_init(&ksp->ks_sysctl_ctx);
|
||||
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_STATIC_CHILDREN(_kstat), OID_AUTO, module, CTLFLAG_RW, 0,
|
||||
"");
|
||||
if (root == NULL) {
|
||||
printf("%s: Cannot create kstat.%s tree!\n", __func__, module);
|
||||
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
}
|
||||
if (pool != NULL) {
|
||||
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(root), OID_AUTO, pool, CTLFLAG_RW, 0, "");
|
||||
root = NULL;
|
||||
p = buf;
|
||||
while ((frag = strsep(&p, "/")) != NULL) {
|
||||
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx, root ?
|
||||
SYSCTL_CHILDREN(root) : SYSCTL_STATIC_CHILDREN(_kstat),
|
||||
OID_AUTO, frag, CTLFLAG_RW, 0, "");
|
||||
if (root == NULL) {
|
||||
printf("%s: Cannot create kstat.%s.%s tree!\n",
|
||||
__func__, module, pool);
|
||||
printf("%s: Cannot create kstat.%s tree!\n",
|
||||
__func__, buf);
|
||||
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
}
|
||||
if (p != NULL && p > frag)
|
||||
p[-1] = '.';
|
||||
}
|
||||
|
||||
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx, SYSCTL_CHILDREN(root),
|
||||
OID_AUTO, class, CTLFLAG_RW, 0, "");
|
||||
if (root == NULL) {
|
||||
if (pool != NULL)
|
||||
printf("%s: Cannot create kstat.%s.%s.%s tree!\n",
|
||||
__func__, module, pool, class);
|
||||
else
|
||||
printf("%s: Cannot create kstat.%s.%s tree!\n",
|
||||
__func__, module, class);
|
||||
printf("%s: Cannot create kstat.%s.%s tree!\n",
|
||||
__func__, buf, class);
|
||||
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (ksp->ks_type == KSTAT_TYPE_NAMED) {
|
||||
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(root),
|
||||
OID_AUTO, name, CTLFLAG_RW, 0, "");
|
||||
if (root == NULL) {
|
||||
if (pool != NULL)
|
||||
printf("%s: Cannot create kstat.%s.%s.%s.%s "
|
||||
"tree!\n", __func__, module, pool, class,
|
||||
name);
|
||||
else
|
||||
printf("%s: Cannot create kstat.%s.%s.%s "
|
||||
"tree!\n", __func__, module, class, name);
|
||||
printf("%s: Cannot create kstat.%s.%s.%s tree!\n",
|
||||
__func__, buf, class, name);
|
||||
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ksp->ks_sysctl_root = root;
|
||||
|
||||
return (ksp);
|
||||
|
|
Loading…
Reference in New Issue