|
Packit |
2ba279 |
#include <stdlib.h>
|
|
Packit |
2ba279 |
#include <stdio.h>
|
|
Packit |
2ba279 |
#include <unistd.h>
|
|
Packit |
2ba279 |
#include <string.h>
|
|
Packit |
2ba279 |
#include <glib.h>
|
|
Packit |
2ba279 |
#include <blockdev/blockdev.h>
|
|
Packit |
2ba279 |
#include <blockdev/lvm.h>
|
|
Packit |
2ba279 |
#include <bytesize/bs_size.h>
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
void print_usage (const char *cmd) {
|
|
Packit |
2ba279 |
fprintf (stderr, "Usage: %s CACHED_LV [CACHED_LV2...]\n", cmd);
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
void print_size (guint64 bytes, gboolean newline) {
|
|
Packit |
2ba279 |
BSSize size = bs_size_new_from_bytes (bytes, 1);
|
|
Packit |
2ba279 |
char *size_str = bs_size_human_readable (size, BS_BUNIT_MiB, 2, true);
|
|
Packit |
2ba279 |
printf ("%10s%s", size_str, newline ? "\n" : "");
|
|
Packit |
2ba279 |
free (size_str);
|
|
Packit |
2ba279 |
bs_size_free (size);
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
void print_ratio (guint64 part, guint64 total, gboolean space, gboolean newline) {
|
|
Packit |
2ba279 |
float percent = ((float) part / total) * 100;
|
|
Packit |
2ba279 |
printf ("%s[%6.2f%%]%s", space ? " " : "", percent, newline ? "\n" : "");
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
gboolean print_lv_stats (const char *vg_name, const char *lv_name, GError **error) {
|
|
Packit |
2ba279 |
BDLVMLVdata *lv_data = bd_lvm_lvinfo (vg_name, lv_name, error);
|
|
Packit |
2ba279 |
if (!lv_data)
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
BDLVMCacheStats *stats = bd_lvm_cache_stats (vg_name, lv_name, error);
|
|
Packit |
2ba279 |
if (!stats)
|
|
Packit |
2ba279 |
return FALSE;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
printf ("%s/%s:\n", vg_name, lv_name);
|
|
Packit |
2ba279 |
printf (" mode: %13s\n", bd_lvm_cache_get_mode_str (stats->mode, error)); /* ignoring 'error', must be a valid mode */
|
|
Packit |
2ba279 |
printf (" LV size: "); print_size (lv_data->size, TRUE);
|
|
Packit |
2ba279 |
printf (" cache size: "); print_size (stats->cache_size, TRUE);
|
|
Packit |
2ba279 |
printf (" cache used: "); print_size (stats->cache_used, FALSE); print_ratio (stats->cache_used, stats->cache_size, TRUE, TRUE);
|
|
Packit |
2ba279 |
printf (" read misses: %10"G_GUINT64_FORMAT"\n", stats->read_misses);
|
|
Packit |
2ba279 |
printf (" read hits: %10"G_GUINT64_FORMAT, stats->read_hits); print_ratio (stats->read_hits, stats->read_hits + stats->read_misses, TRUE, TRUE);
|
|
Packit |
2ba279 |
printf (" write misses: %10"G_GUINT64_FORMAT"\n", stats->write_misses);
|
|
Packit |
2ba279 |
printf (" write hits: %10"G_GUINT64_FORMAT, stats->write_hits); print_ratio (stats->write_hits, stats->write_hits + stats->write_misses, TRUE, TRUE);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
bd_lvm_lvdata_free (lv_data);
|
|
Packit |
2ba279 |
bd_lvm_cache_stats_free (stats);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
return TRUE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
int main (int argc, char *argv[]) {
|
|
Packit |
2ba279 |
gboolean ret = FALSE;
|
|
Packit |
2ba279 |
GError *error = NULL;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (argc < 2) {
|
|
Packit |
2ba279 |
fprintf (stderr, "No cached LV to get the stats for specified!\n");
|
|
Packit |
2ba279 |
print_usage (argv[0]);
|
|
Packit |
2ba279 |
return 1;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if ((g_strcmp0(argv[1], "-h") == 0) || g_strcmp0(argv[1], "--help") == 0) {
|
|
Packit |
2ba279 |
print_usage (argv[0]);
|
|
Packit |
2ba279 |
return 1;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/* check that we are runnig as root */
|
|
Packit |
2ba279 |
if ((getuid() != 0) || (geteuid() != 0)) {
|
|
Packit |
2ba279 |
fprintf (stderr, "This utility must be run as root.\n");
|
|
Packit |
2ba279 |
return 1;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
/* initialize the library -- we only need the LVM plugin */
|
|
Packit |
2ba279 |
BDPluginSpec lvm_plugin = {BD_PLUGIN_LVM, NULL};
|
|
Packit |
2ba279 |
BDPluginSpec *plugins[] = {&lvm_plugin, NULL};
|
|
Packit |
2ba279 |
ret = bd_init (plugins, NULL, &error);
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
if (!ret) {
|
|
Packit |
2ba279 |
fprintf (stderr, "Failed to initialize the libblockdev library: %s\n",
|
|
Packit |
2ba279 |
error->message);
|
|
Packit |
2ba279 |
return 2;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
gboolean ok = TRUE;
|
|
Packit |
2ba279 |
for (int i = 1; i < argc; i++) {
|
|
Packit |
2ba279 |
char *slash = strchr (argv[i], '/');
|
|
Packit |
2ba279 |
if (!slash) {
|
|
Packit |
2ba279 |
fprintf (stderr, "Invalid LV specified: '%s'. Has to be in the VG/LV format.\n", argv[i]);
|
|
Packit |
2ba279 |
ok = FALSE;
|
|
Packit |
2ba279 |
continue;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
*slash = '\0';
|
|
Packit |
2ba279 |
const char *vg_name = argv[i];
|
|
Packit |
2ba279 |
const char *lv_name = slash + 1;
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
ret = print_lv_stats (vg_name, lv_name, &error);
|
|
Packit |
2ba279 |
if (!ret) {
|
|
Packit |
2ba279 |
fprintf (stderr, "Failed to get stats for '%s/%s': %s\n",
|
|
Packit |
2ba279 |
vg_name, lv_name, error->message);
|
|
Packit |
2ba279 |
ok = FALSE;
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
}
|
|
Packit |
2ba279 |
|
|
Packit |
2ba279 |
return ok ? 0 : 3;
|
|
Packit |
2ba279 |
}
|