[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