diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2020-11-25 17:58:50 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2020-11-25 18:07:05 -0800 |
commit | 8ec1588722809a35a7d149bff10de56424e2658a (patch) | |
tree | dac9aca6321b92f84505293227c5151193dd8ee6 /src/report-tail-waste.c | |
parent | 7b15a68d12e2df7f45c4311d0281ff9a78693e81 (diff) |
src: initial commit of jio WIP source
This is a very quick and dirty experimental hack written in some
sort of bastard continuation-passing style in C w/io_uring using
journal-file introspection and manipulation duty as an excuse for
its existence.
Consider this unfinished prototype quality code.
Diffstat (limited to 'src/report-tail-waste.c')
-rw-r--r-- | src/report-tail-waste.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/report-tail-waste.c b/src/report-tail-waste.c new file mode 100644 index 0000000..fdd52cb --- /dev/null +++ b/src/report-tail-waste.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2020 - Vito Caputo - <vcaputo@pengaru.com> + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <inttypes.h> +#include <stdio.h> +#include <stdint.h> + +#include <iou.h> +#include <thunk.h> + +#include "bootid.h" +#include "humane.h" +#include "journals.h" +#include "machid.h" +#include "report-tail-waste.h" + +#include "upstream/journal-def.h" + + +typedef struct tail_waste_t { + unsigned per_state_counts[_STATE_MAX]; + uint64_t per_state_bytes[_STATE_MAX]; + uint64_t total, total_file_size; + unsigned n_journals; +} tail_waste_t; + + +THUNK_DEFINE_STATIC(print_tail_waste, journal_t **, journal, Header *, journal_header, ObjectHeader *, tail_object_header, tail_waste_t *, tail_waste) +{ + uint64_t sz, tail; + struct stat st; + int r; + humane_t h1, h2; + + assert(journal); + assert(journal_header); + assert(tail_object_header); + assert(tail_waste); + + r = fstat((*journal)->fd, &st); + if (r < 0) + return r; + + sz = st.st_size; + tail = journal_header->tail_object_offset + ALIGN64(tail_object_header->size); + + printf("\t%s: %s, size: %s, tail-waste: %s\n", + journal_state_str(journal_header->state), + (*journal)->name, + humane_bytes(&h1, sz), + humane_bytes(&h2, sz - tail)); + + tail_waste->per_state_bytes[journal_header->state] += sz - tail; + tail_waste->total += sz - tail; + tail_waste->total_file_size += sz; + tail_waste->per_state_counts[journal_header->state]++; + tail_waste->n_journals++; + + return 0; +} + + +THUNK_DEFINE_STATIC(per_journal_tail_waste, iou_t *, iou, journal_t **, journal_iter, tail_waste_t *, tail_waste) +{ + struct { + journal_t *journal; + Header header; + ObjectHeader tail_object_header; + } *foo; + + thunk_t *closure; + + assert(iou); + assert(journal_iter); + + closure = THUNK_ALLOC(print_tail_waste, (void **)&foo, sizeof(*foo)); + foo->journal = *journal_iter; + + return journal_get_header(iou, &foo->journal, &foo->header, THUNK( + journal_get_object_header(iou, &foo->journal, &foo->header.tail_object_offset, &foo->tail_object_header, THUNK_INIT( + print_tail_waste(closure, &foo->journal, &foo->header, &foo->tail_object_header, tail_waste))))); +} + + +/* print the size of wasted space between each journal's tail object and EOF, and a sum total. */ +int jio_report_tail_waste(iou_t *iou, int argc, char *argv[]) +{ + tail_waste_t tail_waste = {}; + char *machid; + journals_t *journals; + journal_t *journal_iter; + humane_t h1, h2; + int r; + + r = machid_get(iou, &machid, THUNK( + journals_open(iou, &machid, O_RDONLY, &journals, THUNK( + journals_for_each(&journals, &journal_iter, THUNK( + per_journal_tail_waste(iou, &journal_iter, &tail_waste))))))); + if (r < 0) + return r; + + printf("\nPer-journal:\n"); + r = iou_run(iou); + if (r < 0) + return r; + + printf("\nTotals:\n"); + printf("\tTail-waste by state:\n"); + for (int i = 0; i < _STATE_MAX; i++) { + printf("\t\t%10s [%u]: %s, %"PRIu64"%% of all tail-waste\n", + journal_state_str(i), + tail_waste.per_state_counts[i], + humane_bytes(&h1, tail_waste.per_state_bytes[i]), + tail_waste.total >= 100 ? tail_waste.per_state_bytes[i] / (tail_waste.total / 100) : 0); + } + + printf("\n\tAggregate tail-waste: %s, %"PRIu64"%% of %s spanning %u journal files\n", + humane_bytes(&h1, tail_waste.total), + tail_waste.total_file_size >= 100 ? tail_waste.total / (tail_waste.total_file_size / 100) : 0, + humane_bytes(&h2, tail_waste.total_file_size), + tail_waste.n_journals); + + return 0; +} |