[Ocfs2-tools-devel] [PATCH 4/6] O2info: Add running codes for '--fs-features'.
Tristan Ye
tristan.ye at oracle.com
Thu Apr 22 01:01:25 PDT 2010
Task of dumping fs features will also be capable of two approaches,
including libocfs2 and ioctl methods.
Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
o2info/o2info.c | 16 +++++
o2info/operations.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++
o2info/utils.c | 66 ++++++++++++++++++++
o2info/utils.h | 4 +
4 files changed, 252 insertions(+), 0 deletions(-)
diff --git a/o2info/o2info.c b/o2info/o2info.c
index 28601dd..1e281d9 100644
--- a/o2info/o2info.c
+++ b/o2info/o2info.c
@@ -34,6 +34,8 @@
#include "utils.h"
+extern struct o2info_operation fs_features_op;
+
static LIST_HEAD(o2info_op_task_list);
static int o2info_op_task_count;
int cluster_coherent;
@@ -98,10 +100,24 @@ static struct o2info_option coherency_option = {
.opt_private = NULL,
};
+static struct o2info_option fs_features_option = {
+ .opt_option = {
+ .name = "fs-features",
+ .val = CHAR_MAX,
+ .has_arg = 0,
+ .flag = NULL,
+ },
+ .opt_help = " --fs-features",
+ .opt_handler = NULL,
+ .opt_op = &fs_features_op,
+ .opt_private = NULL,
+};
+
static struct o2info_option *options[] = {
&help_option,
&version_option,
&coherency_option,
+ &fs_features_option,
NULL,
};
diff --git a/o2info/operations.c b/o2info/operations.c
index ad719a4..d2a190c 100644
--- a/o2info/operations.c
+++ b/o2info/operations.c
@@ -59,3 +59,169 @@ static void o2i_error(struct o2info_operation *op, const char *fmt, ...)
return;
}
+
+struct o2info_fs_features {
+ uint32_t compat;
+ uint32_t incompat;
+ uint32_t rocompat;
+};
+
+static int get_fs_features_ioctl(struct o2info_operation *op,
+ int fd,
+ struct o2info_fs_features *ofs)
+{
+ int rc = 0, flags = 0;
+ struct ocfs2_info_fs_features oif;
+
+ memset(ofs, 0, sizeof(*ofs));
+ flags |= cluster_coherent;
+
+ o2info_fill_request((struct ocfs2_info_request *)&oif, sizeof(oif),
+ OCFS2_INFO_FS_FEATURES, flags);
+
+ uint64_t reqs[1] = {(unsigned long)&oif};
+
+ struct ocfs2_info info = {
+ .oi_requests = (uint64_t)reqs,
+ .oi_count = 1,
+ };
+
+ rc = ioctl(fd, OCFS2_IOC_INFO, &info);
+ if (rc) {
+ rc = errno;
+ o2i_error(op, "ioctl failed: %s\n", strerror(rc));
+ goto out;
+ }
+
+ if (oif.if_req.ir_flags & OCFS2_INFO_FL_FILLED) {
+ ofs->compat = oif.if_compat_features;
+ ofs->incompat = oif.if_incompat_features;
+ ofs->rocompat = oif.if_ro_compat_features;
+ }
+
+out:
+ return rc;
+}
+
+static int get_fs_features_libocfs2(struct o2info_operation *op,
+ ocfs2_filesys *fs,
+ struct o2info_fs_features *ofs)
+{
+ int rc = 0;
+ struct ocfs2_super_block *sb = NULL;
+
+ memset(ofs, 0, sizeof(*ofs));
+
+ sb = OCFS2_RAW_SB(fs->fs_super);
+ ofs->compat = sb->s_feature_compat;
+ ofs->incompat = sb->s_feature_incompat;
+ ofs->rocompat = sb->s_feature_ro_compat;
+
+ return rc;
+}
+
+static void o2info_print_line(char const *title, char *content, char splitter)
+{
+ char *ptr = NULL, *token = NULL, *tmp = NULL;
+ uint32_t max_len = 80, len = 0;
+
+ tmp = malloc(max_len);
+ ptr = content;
+
+ snprintf(tmp, max_len, "%s", title);
+ fprintf(stdout, "%s", tmp);
+ len += strlen(tmp);
+
+ while (ptr) {
+
+ token = ptr;
+ ptr = strchr(ptr, splitter);
+
+ if (ptr)
+ *ptr = 0;
+
+ if (strcmp(token, "") != 0) {
+ snprintf(tmp, max_len, " %s", token);
+ len += strlen(tmp);
+ if (len > max_len) {
+ fprintf(stdout, "\n");
+ len = 0;
+ snprintf(tmp, max_len, "%s", title);
+ fprintf(stdout, "%s", tmp);
+ len += strlen(tmp);
+ snprintf(tmp, max_len, " %s", token);
+ fprintf(stdout, "%s", tmp);
+ len += strlen(tmp);
+ } else
+ fprintf(stdout, "%s", tmp);
+ }
+
+ if (!ptr)
+ break;
+
+ ptr++;
+ }
+
+ fprintf(stdout, "\n");
+
+ if (tmp)
+ ocfs2_free(&tmp);
+}
+
+static int fs_features_run(struct o2info_operation *op,
+ struct o2info_method *om,
+ void *arg)
+{
+ int rc = 0;
+ static struct o2info_fs_features ofs;
+
+ char *compat = NULL;
+ char *incompat = NULL;
+ char *rocompat = NULL;
+ char *features = NULL;
+
+ if (om->om_method == O2INFO_USE_IOCTL)
+ rc = get_fs_features_ioctl(op, om->om_fd, &ofs);
+ else
+ rc = get_fs_features_libocfs2(op, om->om_fs, &ofs);
+ if (rc)
+ goto out;
+
+ rc = o2info_get_compat_flag(ofs.compat, &compat);
+ if (rc)
+ goto out;
+
+ rc = o2info_get_incompat_flag(ofs.incompat, &incompat);
+ if (rc)
+ goto out;
+
+ rc = o2info_get_rocompat_flag(ofs.rocompat, &rocompat);
+ if (rc)
+ goto out;
+
+ features = malloc(strlen(compat) + strlen(incompat) +
+ strlen(rocompat) + 3);
+
+ sprintf(features, "%s %s %s", compat, incompat, rocompat);
+
+ o2info_print_line("Features:", features, ' ');
+
+out:
+ if (compat)
+ ocfs2_free(&compat);
+
+ if (incompat)
+ ocfs2_free(&incompat);
+
+ if (rocompat)
+ ocfs2_free(&rocompat);
+
+ if (features)
+ ocfs2_free(&features);
+
+ return rc;
+}
+
+DEFINE_O2INFO_OP(fs_features,
+ fs_features_run,
+ NULL);
diff --git a/o2info/utils.c b/o2info/utils.c
index 0911c50..85b2fdf 100644
--- a/o2info/utils.c
+++ b/o2info/utils.c
@@ -31,6 +31,72 @@
#include "utils.h"
+int o2info_get_compat_flag(uint32_t flag, char **compat)
+{
+ errcode_t err;
+ char buf[PATH_MAX];
+ ocfs2_fs_options flags = {
+ .opt_compat = flag,
+ };
+
+ *buf = '\0';
+ err = ocfs2_snprint_feature_flags(buf, PATH_MAX, &flags);
+ if (!err) {
+ *compat = strdup(buf);
+ if (!*compat) {
+ errorf("No memory for allocation\n");
+ err = -1;
+ }
+ } else
+ tcom_err(err, "while processing feature flags");
+
+ return err;
+}
+
+int o2info_get_incompat_flag(uint32_t flag, char **incompat)
+{
+ errcode_t err;
+ char buf[PATH_MAX];
+ ocfs2_fs_options flags = {
+ .opt_incompat = flag,
+ };
+
+ *buf = '\0';
+ err = ocfs2_snprint_feature_flags(buf, PATH_MAX, &flags);
+ if (!err) {
+ *incompat = strdup(buf);
+ if (!*incompat) {
+ errorf("No memory for allocation\n");
+ err = -1;
+ }
+ } else
+ tcom_err(err, "while processing feature flags");
+
+ return err;
+}
+
+int o2info_get_rocompat_flag(uint32_t flag, char **rocompat)
+{
+ errcode_t err;
+ char buf[PATH_MAX];
+ ocfs2_fs_options flags = {
+ .opt_ro_compat = flag,
+ };
+
+ *buf = '\0';
+ err = ocfs2_snprint_feature_flags(buf, PATH_MAX, &flags);
+ if (!err) {
+ *rocompat = strdup(buf);
+ if (!*rocompat) {
+ errorf("No memory for allocation\n");
+ err = -1;
+ }
+ } else
+ tcom_err(err, "while processing feature flags");
+
+ return err;
+}
+
errcode_t o2info_open(struct o2info_method *om, int flags)
{
errcode_t err = 0;
diff --git a/o2info/utils.h b/o2info/utils.h
index 6d55d39..69446c2 100644
--- a/o2info/utils.h
+++ b/o2info/utils.h
@@ -22,6 +22,10 @@
#include "o2info.h"
+int o2info_get_compat_flag(uint32_t flag, char **compat);
+int o2info_get_incompat_flag(uint32_t flag, char **incompat);
+int o2info_get_rocompat_flag(uint32_t flag, char **rocompat);
+
int o2info_method(const char *path);
errcode_t o2info_open(struct o2info_method *om, int flags);
--
1.5.5
More information about the Ocfs2-tools-devel
mailing list