[Ocfs2-tools-commits] manish commits r235 - in trunk: . ocfs2cdsl

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Sep 14 22:30:20 CDT 2004


Author: manish
Date: 2004-09-14 22:30:18 -0500 (Tue, 14 Sep 2004)
New Revision: 235

Added:
   trunk/ocfs2cdsl/
   trunk/ocfs2cdsl/Makefile
   trunk/ocfs2cdsl/ocfs2cdsl.c
Modified:
   trunk/Makefile
Log:
Add cdsl utility


Modified: trunk/Makefile
===================================================================
--- trunk/Makefile	2004-09-15 00:32:09 UTC (rev 234)
+++ trunk/Makefile	2004-09-15 03:30:18 UTC (rev 235)
@@ -22,7 +22,7 @@
 $(error could not detect architecture for tools)
 endif
 
-SUBDIRS = libocfs2 mkfs.ocfs2 mounted.ocfs2 extras load_ocfs ocfs_uid_gen
+SUBDIRS = libocfs2 mkfs.ocfs2 mounted.ocfs2 ocfs2cdsl extras load_ocfs ocfs_uid_gen
 
 ifdef BUILD_DEBUGOCFS2
 SUBDIRS += debugfs.ocfs2

Added: trunk/ocfs2cdsl/Makefile
===================================================================
--- trunk/ocfs2cdsl/Makefile	2004-09-15 00:32:09 UTC (rev 234)
+++ trunk/ocfs2cdsl/Makefile	2004-09-15 03:30:18 UTC (rev 235)
@@ -0,0 +1,35 @@
+TOPDIR = ..
+
+include $(TOPDIR)/Preamble.make
+
+WARNINGS = -Wall
+
+ifdef OCFS_DEBUG
+OPTS = -g
+endif
+
+CFLAGS = $(OPTS) $(WARNINGS) 
+
+SBIN_PROGRAMS = ocfs2cdsl
+
+DEFINES = -DG_DISABLE_DEPRECATED
+INCLUDES = $(GLIB_CFLAGS)
+
+OPTIMIZE = -g -O0
+
+CFLAGS += $(OPTIMIZE)
+
+VERSION_FILES = ocfs2cdsl.c
+VERSION_SRC = ocfs2cdsl.c
+VERSION_PREFIX = OCFS2
+
+DIST_RULES = dist-incdir
+
+#MANS = ocfs2cdsl.8
+
+DIST_FILES = $(VERSION_FILES) $(VERSION_SRC) ocfs2cdsl.c #ocfs2cdsl.8.in
+
+ocfs2cdsl: ocfs2cdsl.o
+	$(LINK) $(GLIB_LIBS)
+
+include $(TOPDIR)/Postamble.make

Added: trunk/ocfs2cdsl/ocfs2cdsl.c
===================================================================
--- trunk/ocfs2cdsl/ocfs2cdsl.c	2004-09-15 00:32:09 UTC (rev 234)
+++ trunk/ocfs2cdsl/ocfs2cdsl.c	2004-09-15 03:30:18 UTC (rev 235)
@@ -0,0 +1,487 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ocfs2cdsl.c
+ *
+ * OCFS2 CDSL utility
+ *
+ * Copyright (C) 2004 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Authors: Manish Singh
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mntent.h>
+#include <libgen.h>
+#include <getopt.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/statfs.h>
+#include <sys/utsname.h>
+
+#include <glib.h>
+
+
+#define OCFS_MAGIC 0xa156f7eb
+
+#define CDSL_BASE ".cluster"
+
+
+typedef enum {
+	CDSL_TYPE_HOSTNAME,
+	CDSL_TYPE_MACH,
+	CDSL_TYPE_OS,
+	CDSL_TYPE_NODENUM
+} CDSLType;
+
+
+typedef struct _State State;
+
+struct _State {
+	char *progname;
+
+	gboolean copy;
+	gboolean force;
+	gboolean dry_run;
+
+	gboolean verbose;
+	gboolean quiet;
+
+	CDSLType type;
+
+	char *filename;
+	char *dirname;
+	char *fullname;
+};
+
+
+static State *get_state (int argc, char **argv);
+static void usage(const char *progname);
+static void version(const char *progname);
+static char *get_ocfs2_root(const char *path);
+static char *cdsl_path_expand(State *s);
+static char *cdsl_target(State *s, const char *path);
+static void delete(State *s, const char *path);
+
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+
+int
+main(int argc, char **argv)
+{
+	State *s;
+	char *fsroot, *path;
+	char *cmd, *cmd_err;
+	int ret;
+	struct statfs sbuf;
+	gboolean exists;
+	char *cdsl_path, *cdsl_full;
+	char *target;
+	GError *error = NULL;
+
+	s = get_state(argc, argv);
+
+	if (statfs(s->dirname, &sbuf) != 0) {
+		fprintf(stderr, "%s: %s: %s\n", s->progname, s->filename,
+			g_strerror(errno));
+		exit(1);
+	}
+
+	if (sbuf.f_type != OCFS_MAGIC) {
+		fprintf(stderr, "%s: %s is not on an ocfs2 filesystem\n",
+			s->progname, s->filename);
+		exit(1);
+	}
+
+	fsroot = get_ocfs2_root(s->dirname);
+
+	if (fsroot == NULL) {
+		fprintf(stderr, "%s: %s is not on an ocfs2 filesystem\n",
+			s->progname, s->dirname);
+		exit(1);
+	}
+
+	exists = g_file_test(s->fullname, G_FILE_TEST_EXISTS);
+	if (exists) {
+		if (!g_file_test(s->fullname,
+				 G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_DIR)) {
+			fprintf(stderr, "%s: %s is not a file or directory\n",
+				s->progname, s->fullname);
+			exit(1);
+		}
+	}
+	else if (s->copy) {
+		fprintf(stderr, "%s: %s does not exist, but copy requested\n",
+			s->progname, s->fullname);
+		exit(1);
+	}
+
+	if (exists && !s->copy && !s->force) {
+		fprintf(stderr, "%s: %s already exists, but copy (-c) or "
+				"force (-f) not given\n",
+			s->progname, s->fullname);
+		exit(1);
+	}
+
+	path = s->dirname + strlen(fsroot) + 1;
+
+	if (exists) {
+		cdsl_path = g_build_filename(fsroot, cdsl_path_expand(s),
+					     path, NULL);
+
+		cmd = g_strdup_printf("mkdir -p %s", g_shell_quote(cdsl_path));
+
+		if (!g_spawn_command_line_sync(cmd, NULL, &cmd_err, &ret,
+					       &error)) {
+			fprintf(stderr, "%s: Couldn't mkdir: %s\n", s->progname,
+				error->message);
+			exit(1);
+		}
+
+		if (ret != 0) {
+			fprintf(stderr, "%s: mkdir error: %s\n", s->progname,
+				cmd_err);
+			exit(1);
+		}
+
+		g_free(cmd);
+
+		cdsl_full = g_build_filename(cdsl_path, s->filename, NULL);
+
+		if (g_file_test(cdsl_full, G_FILE_TEST_EXISTS)) {
+			if (s->force)
+				delete(s, cdsl_full);
+			else {
+				fprintf(stderr, "%s: CDSL already exists "
+						"To replace, use the force "
+						"(-f) option\n",
+					s->progname);
+				exit(1);
+			}
+		}
+
+		if (rename(s->fullname, cdsl_full) != 0) {
+			fprintf(stderr, "%s: could not rename %s: %s\n",
+				s->progname, s->filename, g_strerror(errno));
+			exit(1);
+		}
+
+		g_free (cdsl_full);
+		g_free (cdsl_path);
+	}
+
+	target = g_build_filename(cdsl_target(s, path), s->filename, NULL);
+
+	if (symlink(target, s->fullname) != 0) {
+		fprintf(stderr, "%s: could not symlink %s to %s: %s\n",
+			s->progname, target, s->fullname, g_strerror(errno));
+		exit(1);
+	}
+
+	g_free(target);
+
+	return 0;
+}
+
+static State *
+get_state(int argc, char **argv)
+{
+	char *progname;
+	gboolean copy = FALSE, force = FALSE, dry_run = FALSE;
+	gboolean quiet = FALSE, verbose = FALSE, show_version = FALSE;
+	CDSLType type = CDSL_TYPE_HOSTNAME;
+	char *filename, *dirname, *tmp;
+	State *s;
+	int c;
+
+	static struct option long_options[] = {
+		{ "type", 1, 0, 't' },
+		{ "copy", 0, 0, 'c' },
+		{ "force", 0, 0, 'f' },
+		{ "dry-run", 0, 0, 'n' },
+		{ "verbose", 0, 0, 'v' },
+		{ "quiet", 0, 0, 'q' },
+		{ "version", 0, 0, 'V' },
+		{ 0, 0, 0, 0 }
+	};
+
+	if (argc && *argv)
+		progname = g_path_get_basename(argv[0]);
+	else
+		progname = g_strdup("ocfs2cdsl");
+
+	while (1) {
+		c = getopt_long(argc, argv, "t:acfnvqV", long_options, NULL);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 't':
+			if (strcmp(optarg, "hostname") == 0)
+				type = CDSL_TYPE_HOSTNAME;
+			else if (strcmp(optarg, "mach") == 0)
+				type = CDSL_TYPE_MACH;
+			else if (strcmp(optarg, "os") == 0)
+				type = CDSL_TYPE_OS;
+			else if (strcmp(optarg, "nodenum") == 0)
+				type = CDSL_TYPE_NODENUM;
+			else {
+				fprintf(stderr, "%s: '%s' not a recognized "
+						"type",
+					progname, optarg);
+				exit(1);
+			}
+			break;
+		case 'c':
+			copy = TRUE;
+			break;
+		case 'f':
+			force = TRUE;
+			break;
+		case 'n':
+			dry_run = TRUE;
+			break;
+		case 'q':
+			quiet = TRUE;
+			break;
+		case 'v':
+			verbose = TRUE;
+			break;
+		case 'V':
+			show_version = TRUE;
+			break;
+		default:
+			usage(progname);
+			break;
+		}
+	}
+
+	if ((optind == argc) && !show_version)
+		usage(progname);
+
+	filename = argv[optind++];
+
+	tmp = g_path_get_dirname(filename);
+	dirname = canonicalize_file_name(tmp);
+	g_free(tmp);
+
+	if (dirname == NULL) {
+		fprintf(stderr, "%s: %s: %s\n", progname,
+			g_path_get_dirname(filename),
+			g_strerror(errno));
+		exit(1);
+	}
+
+	if (optind < argc)
+		usage(progname);
+
+	if (show_version) {
+		version(progname);
+		exit(0);
+	}
+
+	s = g_new0(State, 1);
+
+	s->progname = progname;
+
+	s->type     = type;
+
+	s->copy     = copy;
+	s->force    = force;
+	s->dry_run  = dry_run;
+
+	s->verbose  = verbose;
+	s->quiet    = quiet;
+
+	s->dirname  = g_strdup(dirname);
+	s->filename = g_path_get_basename(filename);
+
+	s->fullname = g_build_filename(s->dirname, s->filename, NULL);
+
+	free(dirname);
+
+	return s;
+}
+
+static void
+usage(const char *progname)
+{
+	fprintf(stderr, "Usage: %s [-cfnqvV] [-t hostname|mach|os|nodenum] "
+		"[filename]\n", progname);
+	exit(0);
+}
+
+static void
+version(const char *progname)
+{
+	fprintf(stderr, "%s %s %s (build %s)\n", progname,
+		OCFS2_BUILD_VERSION, OCFS2_BUILD_DATE, OCFS2_BUILD_MD5);
+}
+
+static char *
+get_ocfs2_root(const char *path)
+{
+	struct mntent *mnt;
+	FILE *fp;
+	int len, found_len;
+	char *found = NULL, *found_type = NULL;
+	char *ret = NULL;
+
+	fp = setmntent (_PATH_MOUNTED, "r");
+
+	if (fp == NULL)
+		return NULL;
+
+	while ((mnt = getmntent(fp))) {
+		len = strlen(mnt->mnt_dir);
+
+		if (strncmp(mnt->mnt_dir, path, len) == 0) {
+			if (path[len] == '/') {
+				found_len = len;
+
+				g_free(found);
+				found = g_strdup(mnt->mnt_dir);
+
+				g_free(found_type);
+				found_type = g_strdup(mnt->mnt_type);
+			}
+		}
+	}
+
+	endmntent(fp);
+
+	if (found_type && strcmp(found_type, "ocfs2") == 0)
+		ret = g_strdup(found);
+
+	g_free(found_type);
+	g_free(found);
+
+	ret = g_strdup("/tmp/ocfs2");
+	return ret;
+}
+
+static char *
+cdsl_path_expand(State *s)
+{
+	char *prefix, *val;
+	struct utsname buf;
+
+	uname(&buf);
+
+	switch(s->type) {
+	case CDSL_TYPE_HOSTNAME:
+		prefix = "hostname";
+		val = buf.nodename;
+		break;
+	case CDSL_TYPE_MACH:
+		prefix = "mach";
+		val = buf.machine;
+		break;
+	case CDSL_TYPE_OS:
+		prefix = "os";
+		val = buf.sysname;
+		break;
+	case CDSL_TYPE_NODENUM:
+		prefix = "nodenum";
+		val = "0";
+		break;
+	default:
+		g_assert_not_reached();
+		break;
+	}
+
+	return g_build_filename(CDSL_BASE, prefix, val, NULL);
+}
+
+static char *
+cdsl_target(State *s, const char *path)
+{
+	char *type, *val, *ret;
+	GString *prefix;
+	char **parts;
+	int i;
+
+	switch(s->type) {
+	case CDSL_TYPE_HOSTNAME:
+		type = "hostname";
+		break;
+	case CDSL_TYPE_MACH:
+		type = "mach";
+		break;
+	case CDSL_TYPE_OS:
+		type = "os";
+		break;
+	case CDSL_TYPE_NODENUM:
+		type = "nodenum";
+		break;
+	default:
+		g_assert_not_reached();
+		break;
+	}
+
+	val = g_strdup_printf("{%s}", type);
+
+	prefix = g_string_new("");
+
+	parts = g_strsplit(path, "/", -1);
+
+	for (i = 0; parts[i] != NULL; i++)
+		g_string_append(prefix, "../");
+
+	g_strfreev(parts);
+
+	ret = g_build_filename(prefix->str, CDSL_BASE, type, val, path, NULL);
+
+	g_string_free(prefix, TRUE);
+	g_free(val);
+
+	return ret;
+}
+
+static void
+delete(State *s, const char *path)
+{
+	char *cmd, *cmd_err, *quoted;
+	int ret;
+	GError *error = NULL;
+
+	quoted = g_shell_quote(path);
+	cmd = g_strdup_printf("rm -rf %s", quoted);
+	g_free(quoted);
+
+	if (!g_spawn_command_line_sync(cmd, NULL, &cmd_err, &ret, &error)) {
+		fprintf(stderr, "%s: Couldn't rm: %s\n", s->progname,
+			error->message);
+		exit(1);
+	}
+
+	if (ret != 0) {
+		fprintf(stderr, "%s: rm error: %s\n", s->progname, cmd_err);
+		exit(1);
+	}
+
+	g_free(cmd);
+}



More information about the Ocfs2-tools-commits mailing list