blob: ff498623d4072946dfdd6d1042fa51d4a0145741 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
#define _FILE_OFFSET_BITS 64
#define __USE_FILE_OFFSET64
#define _XOPEN_SOURCE 600
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <locale.h>
#include <limits.h>
#include <assert.h>
#include <blkid/blkid.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <uuid/uuid.h>
#include "bcache.h"
#include "lib.h"
#include "bitwise.h"
#include "zoned.h"
#include "features.h"
#include "list.h"
int show_bdevs_detail(void)
{
struct list_head head;
struct dev *devs, *n;
INIT_LIST_HEAD(&head);
int ret;
ret = list_bdevs(&head);
if (ret != 0) {
fprintf(stderr, "Failed to list devices\n");
return ret;
}
printf("Name\t\tUuid\t\t\t\t\tCset_Uuid\t\t\t\tType\t\t\tState");
printf("\t\t\tBname\t\tAttachToDev\tAttachToCset\n");
list_for_each_entry_safe(devs, n, &head, dev_list) {
printf("%s\t%s\t%s\t%lu", devs->name, devs->uuid,
devs->cset, devs->version);
switch (devs->version) {
// These are handled the same by the kernel
case BCACHE_SB_VERSION_CDEV:
case BCACHE_SB_VERSION_CDEV_WITH_UUID:
case BCACHE_SB_VERSION_CDEV_WITH_FEATURES:
printf(" (cache)");
break;
// The second adds data offset supporet
case BCACHE_SB_VERSION_BDEV:
case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
case BCACHE_SB_VERSION_BDEV_WITH_FEATURES:
printf(" (data)");
break;
default:
printf(" (unknown)");
break;
}
printf("\t\t%-16s", devs->state);
printf("\t%-16s", devs->bname);
char attachdev[30];
if (strlen(devs->attachuuid) == 36) {
cset_to_devname(&head, devs->cset, attachdev);
} else if (devs->version == BCACHE_SB_VERSION_CDEV
|| devs->version ==
BCACHE_SB_VERSION_CDEV_WITH_UUID) {
strcpy(attachdev, BCACHE_NO_SUPPORT);
} else {
strcpy(attachdev, BCACHE_ATTACH_ALONE);
}
printf("%-16s", attachdev);
printf("%s", devs->attachuuid);
putchar('\n');
}
free_dev(&head);
return 0;
}
int show_bdevs(void)
{
struct list_head head;
struct dev *devs, *n;
INIT_LIST_HEAD(&head);
int ret;
ret = list_bdevs(&head);
if (ret != 0) {
fprintf(stderr, "Failed to list devices\n");
return ret;
}
printf("Name\t\tType\t\tState\t\t\tBname\t\tAttachToDev\n");
list_for_each_entry_safe(devs, n, &head, dev_list) {
printf("%s\t%lu", devs->name, devs->version);
switch (devs->version) {
// These are handled the same by the kernel
case BCACHE_SB_VERSION_CDEV:
case BCACHE_SB_VERSION_CDEV_WITH_UUID:
case BCACHE_SB_VERSION_CDEV_WITH_FEATURES:
printf(" (cache)");
break;
// The second adds data offset supporet
case BCACHE_SB_VERSION_BDEV:
case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
case BCACHE_SB_VERSION_BDEV_WITH_FEATURES:
printf(" (data)");
break;
default:
printf(" (unknown)");
break;
}
printf("\t%-16s", devs->state);
printf("\t%-16s", devs->bname);
char attachdev[30];
if (strlen(devs->attachuuid) == 36) {
cset_to_devname(&head, devs->cset, attachdev);
} else if (devs->version == BCACHE_SB_VERSION_CDEV
|| devs->version ==
BCACHE_SB_VERSION_CDEV_WITH_UUID) {
strcpy(attachdev, BCACHE_NO_SUPPORT);
} else {
strcpy(attachdev, BCACHE_ATTACH_ALONE);
}
printf("%s", attachdev);
putchar('\n');
}
free_dev(&head);
return 0;
}
int detail_single(char *devname)
{
struct bdev bd;
struct cdev cd;
int type = 1;
int ret;
ret = detail_dev(devname, &bd, &cd, &type);
if (ret != 0) {
fprintf(stderr, "Failed to detail device\n");
return ret;
}
if (type == BCACHE_SB_VERSION_BDEV ||
type == BCACHE_SB_VERSION_BDEV_WITH_OFFSET ||
type == BCACHE_SB_VERSION_BDEV_WITH_FEATURES) {
printf("sb.magic\t\t%s\n", bd.base.magic);
printf("sb.first_sector\t\t%" PRIu64 "\n",
bd.base.first_sector);
printf("sb.csum\t\t\t%" PRIX64 "\n", bd.base.csum);
printf("sb.version\t\t%" PRIu64, bd.base.version);
printf(" [backing device]\n");
putchar('\n');
printf("dev.label\t\t");
if (*bd.base.label)
print_encode(bd.base.label);
else
printf("(empty)");
putchar('\n');
printf("dev.uuid\t\t%s\n", bd.base.uuid);
printf("dev.sectors_per_block\t%u\n"
"dev.sectors_per_bucket\t%u\n",
bd.base.sectors_per_block,
bd.base.sectors_per_bucket);
printf("dev.data.first_sector\t%u\n"
"dev.data.cache_mode\t%d",
bd.first_sector, bd.cache_mode);
switch (bd.cache_mode) {
case CACHE_MODE_WRITETHROUGH:
printf(" [writethrough]\n");
break;
case CACHE_MODE_WRITEBACK:
printf(" [writeback]\n");
break;
case CACHE_MODE_WRITEAROUND:
printf(" [writearound]\n");
break;
case CACHE_MODE_NONE:
printf(" [no caching]\n");
break;
default:
putchar('\n');
}
printf("dev.data.cache_state\t%u", bd.cache_state);
switch (bd.cache_state) {
case BDEV_STATE_NONE:
printf(" [detached]\n");
break;
case BDEV_STATE_CLEAN:
printf(" [clean]\n");
break;
case BDEV_STATE_DIRTY:
printf(" [dirty]\n");
break;
case BDEV_STATE_STALE:
printf(" [inconsistent]\n");
break;
default:
putchar('\n');
}
putchar('\n');
printf("cset.uuid\t\t%s\n", bd.base.cset);
} else if (type == BCACHE_SB_VERSION_CDEV ||
type == BCACHE_SB_VERSION_CDEV_WITH_UUID ||
type == BCACHE_SB_VERSION_CDEV_WITH_FEATURES) {
printf("sb.magic\t\t%s\n", cd.base.magic);
printf("sb.first_sector\t\t%" PRIu64 "\n",
cd.base.first_sector);
printf("sb.csum\t\t\t%" PRIX64 "\n", cd.base.csum);
printf("sb.version\t\t%" PRIu64, cd.base.version);
printf(" [cache device]\n");
print_cache_set_supported_feature_sets(&cd.base.sb);
putchar('\n');
printf("dev.label\t\t");
if (*cd.base.label)
print_encode(cd.base.label);
else
printf("(empty)");
putchar('\n');
printf("dev.uuid\t\t%s\n", cd.base.uuid);
printf("dev.sectors_per_block\t%u\n"
"dev.sectors_per_bucket\t%u\n",
cd.base.sectors_per_block,
cd.base.sectors_per_bucket);
printf("dev.cache.first_sector\t%u\n"
"dev.cache.cache_sectors\t%ju\n"
"dev.cache.total_sectors\t%ju\n"
"dev.cache.ordered\t%s\n"
"dev.cache.discard\t%s\n"
"dev.cache.pos\t\t%u\n"
"dev.cache.replacement\t%d",
cd.first_sector,
cd.cache_sectors,
cd.total_sectors,
cd.ordered ? "yes" : "no",
cd.discard ? "yes" : "no", cd.pos, cd.replacement);
switch (cd.replacement) {
case CACHE_REPLACEMENT_LRU:
printf(" [lru]\n");
break;
case CACHE_REPLACEMENT_FIFO:
printf(" [fifo]\n");
break;
case CACHE_REPLACEMENT_RANDOM:
printf(" [random]\n");
break;
default:
putchar('\n');
}
putchar('\n');
printf("cset.uuid\t\t%s\n", cd.base.cset);
} else {
return 1;
}
return 0;
}