[Ocfs2-tools-devel] [PATCH 5/7] Ocfs2-tools: Add implementation of operations to o2info.
Tristan Ye
tristan.ye at oracle.com
Fri Nov 27 00:53:30 PST 2009
All of o2info's operations will be linked to a task list,
and executed one by one later, the real running code of
a new item for o2info is expected to be added there.
Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
o2info/o2info_operations.c | 330 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 330 insertions(+), 0 deletions(-)
create mode 100644 o2info/o2info_operations.c
diff --git a/o2info/o2info_operations.c b/o2info/o2info_operations.c
new file mode 100644
index 0000000..7470503
--- /dev/null
+++ b/o2info/o2info_operations.c
@@ -0,0 +1,330 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * o2info_operations.c
+ *
+ * Operation helpers for o2info utility
+ *
+ * Copyright (C) 2009 Oracle. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License version 2 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.
+ */
+
+#include "o2info_utils.h"
+
+typedef struct ocfs2_info_request OIR, *POIR;
+typedef struct ocfs2_info_request_clustersize OIRC, *POIRC;
+typedef struct ocfs2_info_request_blocksize OIRB, *POIRB;
+typedef struct ocfs2_info_request_slotnum OIRS, *POIRS;
+typedef struct ocfs2_info_request_label OIRL, *POIRL;
+typedef struct ocfs2_info_request_uuid OIRU, *POIRU;
+typedef struct ocfs2_info_request_fs_features OIRF, *POIRF;
+
+static int freefrag_run(struct o2info_operation *op,
+ struct o2info_method *om,
+ void *arg)
+{
+ return 0;
+}
+
+DEFINE_O2INFO_OP(freefrag,
+ freefrag_run,
+ NULL);
+
+static int freeinode_run(struct o2info_operation *op,
+ struct o2info_method *om,
+ void *arg)
+{
+ return 0;
+}
+
+DEFINE_O2INFO_OP(freeinode,
+ freeinode_run,
+ NULL);
+
+static int filestat_run(struct o2info_operation *op,
+ struct o2info_method *om,
+ void *arg)
+{
+ return 0;
+}
+
+DEFINE_O2INFO_OP(filestat,
+ filestat_run,
+ NULL);
+
+static int usage_run(struct o2info_operation *op,
+ struct o2info_method *om,
+ void *arg)
+{
+ return 0;
+}
+
+DEFINE_O2INFO_OP(usage,
+ usage_run,
+ NULL);
+
+struct o2info_volinfo {
+ uint32_t blocksize;
+ uint32_t clustersize;
+ uint16_t slotnum;
+ uint8_t label[OCFS2_MAX_VOL_LABEL_LEN];
+ uint8_t uuid[OCFS2_VOL_UUID_LEN];
+};
+
+static int get_volinfo(struct o2info_operation *op, struct o2info_method *om,
+ struct o2info_volinfo *vf)
+{
+ int rc = 0;
+ struct ocfs2_super_block *sb = NULL;
+
+ if (om->method & USE_LIBOCFS2) {
+ sb = OCFS2_RAW_SB(om->fs->fs_super);
+ vf->blocksize = 1 << sb->s_blocksize_bits;
+ vf->clustersize = 1 << sb->s_clustersize_bits;
+ vf->slotnum = sb->s_max_slots;
+ memmove(vf->label, sb->s_label, OCFS2_MAX_VOL_LABEL_LEN);
+ memmove(vf->uuid, sb->s_uuid, OCFS2_VOL_UUID_LEN);
+ goto out;
+ }
+
+ if (om->method & USE_IOCTL) {
+ struct ocfs2_info_request_blocksize brq = {
+ { OCFS2_INFO_BLOCKSIZE,
+ OCFS2_INFO_FL_NON_COHERENT},
+ 0
+ };
+
+ struct ocfs2_info_request_clustersize crq = {
+ { OCFS2_INFO_CLUSTERSIZE,
+ OCFS2_INFO_FL_NON_COHERENT},
+ 0
+ };
+
+ struct ocfs2_info_request_slotnum srq = {
+ { OCFS2_INFO_SLOTNUM,
+ OCFS2_INFO_FL_NON_COHERENT},
+ 0
+ };
+
+ struct ocfs2_info_request_label lrq = {
+ { OCFS2_INFO_LABEL,
+ OCFS2_INFO_FL_NON_COHERENT},
+ };
+ memset(lrq.ir_label, 0, OCFS2_MAX_VOL_LABEL_LEN);
+
+ struct ocfs2_info_request_uuid urq = {
+ { OCFS2_INFO_UUID,
+ OCFS2_INFO_FL_NON_COHERENT},
+ };
+ memset(urq.ir_uuid, 0, OCFS2_VOL_UUID_LEN);
+
+ /*
+ * Note: the requests in array need to be NULL-terminated
+ * to let kernel understand.
+ */
+ struct ocfs2_info_request *info[6] = {(POIR)&brq,
+ (POIR)&crq,
+ (POIR)&srq,
+ (POIR)&lrq,
+ (POIR)&urq,
+ NULL};
+
+ rc = ioctl(om->fd, OCFS2_IOC_INFO, info);
+ if (rc) {
+ rc = errno;
+ fprintf(stderr, "ioctl failed:%d %s\n", rc,
+ strerror(rc));
+ goto out;
+ }
+
+ if (info[0]->ir_flags & OCFS2_INFO_FL_FILLED)
+ vf->blocksize = ((POIRB)info[0])->ir_blocksize;
+ else
+ vf->blocksize = 0;
+
+ if (info[1]->ir_flags & OCFS2_INFO_FL_FILLED)
+ vf->clustersize = ((POIRC)info[1])->ir_clustersize;
+ else
+ vf->clustersize = 0;
+
+ if (info[2]->ir_flags & OCFS2_INFO_FL_FILLED)
+ vf->slotnum = ((POIRS)info[2])->ir_slotnum;
+ else
+ vf->slotnum = 0;
+
+ if (info[3]->ir_flags & OCFS2_INFO_FL_FILLED)
+ memmove(vf->label, ((POIRL)info[3])->ir_label,
+ OCFS2_MAX_VOL_LABEL_LEN);
+ else
+ memset(vf->label, 0, OCFS2_MAX_VOL_LABEL_LEN);
+
+ if (info[4]->ir_flags & OCFS2_INFO_FL_FILLED)
+ memmove(vf->uuid, ((POIRU)info[4])->ir_uuid,
+ OCFS2_VOL_UUID_LEN);
+ else
+ memset(vf->uuid, 0, OCFS2_VOL_UUID_LEN);
+
+ goto out;
+ }
+out:
+ return rc;
+}
+
+static int volinfo_run(struct o2info_operation *op,
+ struct o2info_method *om,
+ void *arg)
+{
+ int i, count, max, rc = 0;
+ struct o2info_volinfo vf;
+
+ const char *items[] = {
+ "Block Size:",
+ "Cluster Size:",
+ "Node Slots:",
+ "Label:",
+ "UUID:"
+ };
+
+ rc = get_volinfo(op, om, &vf);
+ if (rc)
+ goto out;
+
+ count = sizeof(items) / sizeof(char *);
+ max = max_str_len(items, count);
+
+ fprintf_aligned_space(stdout, max, items[0]);
+ fprintf(stdout, "%s %u\n", items[0], vf.blocksize);
+ fprintf_aligned_space(stdout, max, items[1]);
+ fprintf(stdout, "%s %u\n", items[1], vf.clustersize);
+ fprintf_aligned_space(stdout, max, items[2]);
+ fprintf(stdout, "%s %u\n", items[2], vf.slotnum);
+ fprintf_aligned_space(stdout, max, items[3]);
+ fprintf(stdout, "%s %.*s\n", items[3], OCFS2_MAX_VOL_LABEL_LEN,
+ vf.label);
+ fprintf_aligned_space(stdout, max, items[4]);
+ fprintf(stdout, "%s ", items[4]);
+ for (i = 0; i < OCFS2_VOL_UUID_LEN; i++)
+ fprintf(stdout, "%02X", vf.uuid[i]);
+ fprintf(stdout, "\n");
+
+out:
+ return rc;
+}
+
+DEFINE_O2INFO_OP(volinfo,
+ volinfo_run,
+ NULL);
+
+struct o2info_fs_features {
+ uint32_t compat;
+ uint32_t incompat;
+ uint32_t rocompat;
+};
+
+static int get_fs_features(struct o2info_operation *op,
+ struct o2info_method *om,
+ struct o2info_fs_features *ofs)
+{
+ int rc = 0;
+ struct ocfs2_super_block *sb = NULL;
+
+ if (om->method & USE_LIBOCFS2) {
+ sb = OCFS2_RAW_SB(om->fs->fs_super);
+ ofs->compat = sb->s_feature_compat;
+ ofs->incompat = sb->s_feature_incompat;
+ ofs->rocompat = sb->s_feature_ro_compat;
+ goto out;
+ }
+
+ if (om->method & USE_IOCTL) {
+ struct ocfs2_info_request_fs_features frq = {
+ { OCFS2_INFO_FS_FEATURES,
+ OCFS2_INFO_FL_NON_COHERENT},
+ 0,
+ 0,
+ 0
+ };
+
+ struct ocfs2_info_request *info[2] = {(POIR)&frq, NULL};
+
+ rc = ioctl(om->fd, OCFS2_IOC_INFO, info);
+ if (rc) {
+ rc = errno;
+ fprintf(stderr, "ioctl failed:%d %s\n", rc,
+ strerror(rc));
+ goto out;
+ }
+
+ if (info[0]->ir_flags & OCFS2_INFO_FL_FILLED) {
+ ofs->compat = ((POIRF)info[0])->ir_compat_features;
+ ofs->incompat = ((POIRF)info[0])->ir_incompat_features;
+ ofs->rocompat = ((POIRF)info[0])->ir_ro_compat_features;
+ } else {
+ ofs->compat = 0;
+ ofs->incompat = 0;
+ ofs->rocompat = 0;
+ }
+ }
+
+out:
+ return rc;
+}
+
+static int fs_features_run(struct o2info_operation *op,
+ struct o2info_method *om,
+ void *arg)
+{
+ int count, max, rc = 0;
+ struct o2info_fs_features ofs;
+
+ GString *compat = NULL;
+ GString *incompat = NULL;
+ GString *rocompat = NULL;
+
+ const char *items[] = {
+ "Feature Compat:",
+ "Feature Incompat:",
+ "Feature RO compat:"
+ };
+
+ compat = g_string_new(NULL);
+ incompat = g_string_new(NULL);
+ rocompat = g_string_new(NULL);
+
+ rc = get_fs_features(op, om, &ofs);
+
+ get_compat_flag(ofs.compat, compat);
+ get_incompat_flag(ofs.incompat, incompat);
+ get_rocompat_flag(ofs.rocompat, rocompat);
+
+ count = sizeof(items) / sizeof(char *);
+ max = max_str_len(items, count);
+
+ fprintf_aligned_space(stdout, max, items[0]);
+ fprintf(stdout, "%s %u %s\n", items[0], ofs.compat,
+ compat->str);
+ fprintf_aligned_space(stdout, max, items[1]);
+ fprintf(stdout, "%s %u %s\n", items[1], ofs.incompat,
+ incompat->str);
+ fprintf_aligned_space(stdout, max, items[2]);
+ fprintf(stdout, "%s %u %s\n", items[2], ofs.rocompat,
+ rocompat->str);
+
+ g_string_free(compat, 1);
+ g_string_free(incompat, 1);
+ g_string_free(rocompat, 1);
+
+ return rc;
+}
+
+DEFINE_O2INFO_OP(fs_features,
+ fs_features_run,
+ NULL);
--
1.5.5
More information about the Ocfs2-tools-devel
mailing list