scoutfs-utils: add fd which uses alloc_detail

Add the df command which uses the new alloc_detail ioctl to show df for
the metadata and data devices separately.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2020-10-26 15:19:41 -07:00
committed by Zach Brown
parent 36c426d555
commit a19e151277
3 changed files with 149 additions and 8 deletions
+126
View File
@@ -0,0 +1,126 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <assert.h>
#include "sparse.h"
#include "util.h"
#include "format.h"
#include "ioctl.h"
#include "cmd.h"
#define COLS 8
static int df_cmd(int argc, char **argv)
{
struct scoutfs_ioctl_alloc_detail ad;
struct scoutfs_ioctl_alloc_detail_entry *ade = NULL;
struct scoutfs_ioctl_statfs_more sfm;
char *title[COLS];
u64 fields[COLS];
int wid[COLS];
u64 nr = 4096 / sizeof(*ade);
u64 meta_free = 0;
u64 data_free = 0;
int ret;
int fd;
int i;
if (argc != 2) {
fprintf(stderr, "must specify path\n");
return -EINVAL;
}
fd = open(argv[1], O_RDONLY);
if (fd < 0) {
ret = -errno;
fprintf(stderr, "failed to open '%s': %s (%d)\n",
argv[1], strerror(errno), errno);
return ret;
}
sfm.valid_bytes = sizeof(struct scoutfs_ioctl_statfs_more);
ret = ioctl(fd, SCOUTFS_IOC_STATFS_MORE, &sfm);
if (ret < 0) {
fprintf(stderr, "statfs_more returned %d: error %s (%d)\n",
ret, strerror(errno), errno);
ret = -EIO;
goto out;
}
do {
free(ade);
ade = calloc(nr, sizeof(*ade));
if (!ade) {
ret = -ENOMEM;
goto out;
}
ad.entries_ptr = (intptr_t)ade;
ad.entries_nr = nr;
ret = ioctl(fd, SCOUTFS_IOC_ALLOC_DETAIL, &ad);
if (ret < 0 && errno == EOVERFLOW)
nr = nr + (nr >> 2);
} while (ret < 0 && errno == EOVERFLOW);
if (ret < 0) {
fprintf(stderr, "alloc_detail returned %d: error %s (%d)\n",
ret, strerror(errno), errno);
ret = -EIO;
goto out;
}
for (i = 0; i < ret; i++) {
if (ade[i].meta)
meta_free += ade[i].blocks;
else
data_free += ade[i].blocks;
}
title[0] = "64K-Meta";
title[1] = "Used";
title[2] = "Avail";
title[3] = "Use%";
title[4] = "4K-Data";
title[5] = "Used";
title[6] = "Avail";
title[7] = "Use%";
fields[0] = sfm.total_meta_blocks;
fields[1] = sfm.total_meta_blocks - meta_free;
fields[2] = meta_free;
fields[3] = fields[1] * 100 / fields[0];
fields[4] = sfm.total_data_blocks;
fields[5] = sfm.total_data_blocks - data_free;
fields[6] = data_free;
fields[7] = fields[5] * 100 / fields[4];
for (i = 0; i < array_size(fields); i++)
wid[i] = max(snprintf(NULL, 0, "%s", title[i]),
snprintf(NULL, 0, "%llu", fields[i]));
for (i = 0; i < array_size(fields); i++)
printf("%*s ", wid[i], title[i]);
printf("\n");
for (i = 0; i < array_size(fields); i++)
wid[i] = printf("%*llu ", wid[i], fields[i]);
printf("\n");
ret = 0;
out:
free(ade);
return ret;
}
static void __attribute__((constructor)) df_ctor(void)
{
cmd_register("df", "<path>",
"show metadata and data block usage", df_cmd);
}
+6 -8
View File
@@ -297,6 +297,12 @@ struct scoutfs_alloc_root {
struct scoutfs_btree_root root;
}__packed;
/* types of allocators, exposed to alloc_detail ioctl */
#define SCOUTFS_ALLOC_OWNER_NONE 0
#define SCOUTFS_ALLOC_OWNER_SERVER 1
#define SCOUTFS_ALLOC_OWNER_MOUNT 2
#define SCOUTFS_ALLOC_OWNER_SRCH 3
struct scoutfs_mounted_client_btree_val {
__u8 flags;
} __packed;
@@ -816,7 +822,6 @@ enum {
SCOUTFS_NET_CMD_GET_ROOTS,
SCOUTFS_NET_CMD_ADVANCE_SEQ,
SCOUTFS_NET_CMD_GET_LAST_SEQ,
SCOUTFS_NET_CMD_STATFS,
SCOUTFS_NET_CMD_LOCK,
SCOUTFS_NET_CMD_LOCK_RECOVER,
SCOUTFS_NET_CMD_SRCH_GET_COMPACT,
@@ -857,13 +862,6 @@ struct scoutfs_net_inode_alloc {
__le64 nr;
} __packed;
struct scoutfs_net_statfs {
__le64 total_blocks; /* total blocks in device */
__le64 next_ino; /* next unused inode number */
__le64 bfree; /* free blocks */
__u8 uuid[SCOUTFS_UUID_BYTES]; /* logical volume uuid */
} __packed;
struct scoutfs_net_roots {
struct scoutfs_btree_root fs_root;
struct scoutfs_btree_root logs_root;
+17
View File
@@ -394,4 +394,21 @@ struct scoutfs_ioctl_data_wait_err {
#define SCOUTFS_IOC_DATA_WAIT_ERR _IOR(SCOUTFS_IOCTL_MAGIC, 11, \
struct scoutfs_ioctl_data_wait_err)
#define SCOUTFS_IOC_ALLOC_DETAIL _IOR(SCOUTFS_IOCTL_MAGIC, 12, \
struct scoutfs_ioctl_alloc_detail)
struct scoutfs_ioctl_alloc_detail {
__u64 entries_ptr;
__u64 entries_nr;
};
struct scoutfs_ioctl_alloc_detail_entry {
__u64 id;
__u64 blocks;
__u8 type;
__u8 meta:1,
avail:1;
};
#endif