Skip to content

Commit fa4f990

Browse files
committed
de-prometheus the stats, add more metaclasses
1 parent fdd6a2c commit fa4f990

File tree

2 files changed

+82
-46
lines changed

2 files changed

+82
-46
lines changed

include/sys/spa.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ typedef struct spa_stats {
900900
spa_history_kstat_t state; /* pool state */
901901
spa_history_kstat_t guid; /* pool guid */
902902
spa_history_kstat_t iostats;
903-
spa_history_kstat_t fragmentation;
903+
spa_history_kstat_t fragmentation[5];
904904
} spa_stats_t;
905905

906906
typedef enum txg_state {

module/zfs/spa_stats.c

Lines changed: 81 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -303,67 +303,103 @@ spa_txg_history_init(spa_t *spa)
303303
offsetof(spa_txg_history_t, sth_node));
304304
}
305305

306+
typedef struct {
307+
spa_t *spa;
308+
int metaclass;
309+
} freespace_histogram_stat_t;
310+
306311
static void *
307312
spa_frag_addr(kstat_t *ksp, loff_t n)
308313
{
309-
if (n == 0)
310-
return ksp->ks_private;
311-
return NULL;
314+
if (n == 0) {
315+
freespace_histogram_stat_t *stat = ksp->ks_private;
316+
switch (stat->metaclass) {
317+
case 0:
318+
return (spa_normal_class(stat->spa));
319+
case 1:
320+
return (spa_log_class(stat->spa));
321+
case 2:
322+
return (spa_embedded_log_class(stat->spa));
323+
case 3:
324+
return (spa_special_class(stat->spa));
325+
case 4:
326+
return (spa_dedup_class(stat->spa));
327+
}
328+
}
329+
return (NULL);
312330
}
313331

314332
static int
315-
spa_frag_data(char *buf, size_t size, void *data) {
316-
spa_t *spa = (spa_t *)data;
317-
size_t offset = 0;
318-
const char *name = spa_name(spa);
319-
320-
metaslab_class_t *mc = spa_normal_class(spa);
321-
for (int i=0; i<RANGE_TREE_HISTOGRAM_SIZE; i++) {
322-
if (mc->mc_histogram[i] > 0) {
323-
int res = snprintf(buf + offset, size, "zfs_fragmentation_normal{power=\"%d\",pool=\"%s\"} %llu\n", i, name, (u_longlong_t)mc->mc_histogram[i]);
324-
offset += res;
325-
size -= res;
326-
}
327-
}
328-
329-
metaslab_class_t *smc = spa_special_class(spa);
330-
for (int i=0; i<RANGE_TREE_HISTOGRAM_SIZE; i++) {
331-
if (smc->mc_histogram[i] > 0) {
332-
int res = snprintf(buf + offset, size, "zfs_fragmentation_special{power=\"%d\",pool=\"%s\"} %llu\n", i, name, (u_longlong_t)smc->mc_histogram[i]);
333-
offset += res;
334-
size -= res;
335-
}
336-
}
337-
return 0;
333+
spa_frag_data(char *buf, size_t size, void *data)
334+
{
335+
metaslab_class_t *mc = data;
336+
size_t offset = 0;
337+
int res;
338+
// without this, it becomes a data-leak, and un-initialized strings
339+
// can be returned if all buckets are 0
340+
buf[0] = 0;
341+
342+
for (int i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i++) {
343+
if (mc->mc_histogram[i] > 0) {
344+
res = snprintf(buf + offset, size, "%d %llu\n", i,
345+
(u_longlong_t)mc->mc_histogram[i]);
346+
offset += res;
347+
size -= res;
348+
}
349+
}
350+
351+
return (0);
338352
}
339353

340354
static void
341355
spa_fragmentation_init(spa_t *spa)
342356
{
343-
char *name;
344-
spa_history_kstat_t *shk = &spa->spa_stats.fragmentation;
345-
kstat_t *ksp;
346-
347-
name = kmem_asprintf("zfs/%s", spa_name(spa));
348-
ksp = kstat_create(name, 0, "fragmentation", "misc", KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
349-
350-
shk->kstat = ksp;
351-
if (ksp) {
352-
ksp->ks_private = spa;
353-
ksp->ks_flags |= KSTAT_FLAG_NO_HEADERS;
354-
kstat_set_raw_ops(ksp, NULL, spa_frag_data, spa_frag_addr);
355-
kstat_install(ksp);
356-
}
357-
kmem_strfree(name);
357+
char *dirname;
358+
const char *statnames[] = {
359+
"fragmentation_normal",
360+
"fragmentation_log",
361+
"fragmentation_embedded_log",
362+
"fragmentation_special",
363+
"fragmentation_dedup"
364+
};
365+
for (int i = 0; i < 5; i++) {
366+
spa_history_kstat_t *shk = &spa->spa_stats.fragmentation[i];
367+
kstat_t *ksp;
368+
369+
dirname = kmem_asprintf("zfs/%s", spa_name(spa));
370+
ksp = kstat_create(dirname, 0, statnames[i], "misc",
371+
KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
372+
kmem_strfree(dirname);
373+
374+
shk->kstat = ksp;
375+
if (ksp) {
376+
freespace_histogram_stat_t *stat = kmem_zalloc(
377+
sizeof (freespace_histogram_stat_t), KM_SLEEP);
378+
stat->spa = spa;
379+
stat->metaclass = i;
380+
ksp->ks_private = stat;
381+
ksp->ks_flags |= KSTAT_FLAG_NO_HEADERS;
382+
kstat_set_raw_ops(ksp, NULL, spa_frag_data,
383+
spa_frag_addr);
384+
kstat_install(ksp);
385+
}
386+
}
358387
}
359388

360389
static void
361390
spa_fragmentation_destroy(spa_t *spa)
362391
{
363-
spa_history_kstat_t *shk = &spa->spa_stats.fragmentation;
364-
kstat_t *ksp = shk->kstat;
365-
if (ksp)
366-
kstat_delete(ksp);
392+
for (int i = 0; i < 5; i++) {
393+
spa_history_kstat_t *shk = &spa->spa_stats.fragmentation[i];
394+
kstat_t *ksp = shk->kstat;
395+
if (ksp) {
396+
if (ksp->ks_private) {
397+
kmem_free(ksp->ks_private,
398+
sizeof (freespace_histogram_stat_t));
399+
}
400+
kstat_delete(ksp);
401+
}
402+
}
367403
}
368404

369405
static void

0 commit comments

Comments
 (0)