[Ocfs2-tools-commits] smushran commits r503 - in trunk/debugfs.ocfs2: . include

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Mon Dec 20 16:38:41 CST 2004


Author: smushran
Date: 2004-12-20 16:38:39 -0600 (Mon, 20 Dec 2004)
New Revision: 503

Modified:
   trunk/debugfs.ocfs2/commands.c
   trunk/debugfs.ocfs2/include/utils.h
   trunk/debugfs.ocfs2/utils.c
Log:
commands rdump and lcd added in debugfs

Modified: trunk/debugfs.ocfs2/commands.c
===================================================================
--- trunk/debugfs.ocfs2/commands.c	2004-12-18 01:06:57 UTC (rev 502)
+++ trunk/debugfs.ocfs2/commands.c	2004-12-20 22:38:39 UTC (rev 503)
@@ -54,6 +54,7 @@
 static void do_quit (char **args);
 static void do_help (char **args);
 static void do_dump (char **args);
+static void do_rdump (char **args);
 static void do_cat (char **args);
 static void do_lcd (char **args);
 static void do_curdev (char **args);
@@ -64,7 +65,7 @@
 static void do_group (char **args);
 static void do_extent (char **args);
 static void do_chroot (char **args);
-static void do_slots (char **args);
+static void do_slotmap (char **args);
 
 extern gboolean allow_write;
 
@@ -94,6 +95,7 @@
   { "quit",   do_quit   },
   { "q",      do_quit   },
 
+  { "rdump",  do_rdump  },
   { "dump",   do_dump   },
   { "cat",    do_cat   },
 
@@ -112,7 +114,7 @@
   { "group", do_group },
   { "extent", do_extent },
 
-  { "slots", do_slots }
+  { "slotmap", do_slotmap }
 };
 
 /*
@@ -657,12 +659,15 @@
 //	printf ("pwd\t\t\t\tPrint working directory\n");
 	printf ("ls [-l] <filepath>\t\t\tList directory\n");
 	printf ("cd <filepath>\t\t\t\tChange directory\n");
+	printf ("lcd <filepath>\t\t\t\tChange directory on a mounted fs\n");
 	printf ("chroot <filepath>\t\t\tChange root\n");
 	printf ("cat <filepath>\t\t\t\tPrints file on stdout\n");
 	printf ("dump [-p] <filepath> <outfile>\t\tDumps file to outfile on a mounted fs\n");
+	printf ("rdump [-v] <filepath> <outdir>\t\tRecursively dumps from src to a dir on a mounted fs\n");
 	printf ("logdump <node#>\t\t\t\tPrints journal file for the node\n");
 	printf ("extent <inode#>\t\t\t\tShow extent block\n");
 	printf ("group <inode#>\t\t\t\tShow chain group\n");
+	printf ("slotmap\t\t\t\t\tShow slot map\n");
 	printf ("help, ?\t\t\t\t\tThis information\n");
 	printf ("quit, q\t\t\t\t\tExit the program\n");
 }
@@ -684,7 +689,22 @@
  */
 static void do_lcd (char **args)
 {
+	char *usage = "usage: lcd <dir on a mounted fs>";
 
+	if (check_device_open())
+		return ;
+
+	if (!args[1]) {
+		fprintf(stderr, "%s\n", usage);
+		return ;
+	}
+
+	if (chdir(args[1]) == -1) {
+		com_err(args[0], errno, "'%s'", args[1]);
+		return ;
+	}
+
+	return ;
 }
 
 /*
@@ -998,10 +1018,10 @@
 }
 
 /*
- * do_slots()
+ * do_slotmap()
  *
  */
-static void do_slots (char **args)
+static void do_slotmap (char **args)
 {
 	FILE *out;
 	errcode_t ret;
@@ -1028,3 +1048,93 @@
 
 	return ;
 }
+
+/*
+ * do_rdump()
+ *
+ */
+static void do_rdump(char **args)
+{
+	uint64_t blkno;
+	struct stat st;
+	char *p;
+	char *usage = "usage: rdump [-v] <srcdir> <dstdir>";
+	errcode_t ret;
+	int ind = 1;
+	int verbose = 0;
+	char tmp_str[40];
+
+	if (check_device_open())
+		return ;
+
+	if (!args[1]) {
+		fprintf(stderr, "%s\n", usage);
+		return ;
+	}
+
+	if (!strncmp(args[1], "-v", 2)) {
+		++ind;
+		++verbose;
+	}
+
+	if (!args[ind] || !args[ind+1]) {
+		fprintf(stderr, "%s\n", usage);
+		return ;
+	}
+
+	/* source */
+	ret = string_to_inode(gbls.fs, gbls.root_blkno, gbls.cwd_blkno,
+			      args[ind], &blkno);
+	if (ret) {
+		com_err(args[0], ret, " ");
+		return ;
+	}
+
+	/* destination... has to be a dir on a mounted fs */
+	if (stat(args[ind+1], &st) == -1) {
+		com_err(args[0], errno, "'%s'", args[ind+1]);
+		return ;
+	}
+
+	if (!S_ISDIR(st.st_mode)) {
+		com_err(args[0], OCFS2_ET_NO_DIRECTORY, "'%s'", args[ind+1]);
+		return ;
+	}
+
+	p = strrchr(args[ind], '/');
+	if (p)
+		p++;
+	else
+		p = args[ind];
+
+	/* I could traverse the dirs from the root and find the directory */
+	/* name... but this is debugfs, for crying out loud */
+	if (!strncmp(p, ".", 1) || !strncmp(p, "..", 2) || !strncmp(p, "/", 1)) {
+		time_t tt;
+		struct tm *tm;
+
+		time(&tt);
+		tm = localtime(&tt);
+		/* YYYY-MM-DD_HH:MI:SS */
+		snprintf(tmp_str, sizeof(tmp_str), "%4d-%2d-%2d_%02d:%02d:%02d",
+			 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
+			 tm->tm_hour, tm->tm_min, tm->tm_sec);
+		p = tmp_str;
+	}
+
+	/* drop the trailing '/' in destination */
+	if (1) {
+		char *q = args[ind+1];
+		q = q + strlen(args[ind+1]) - 1;
+		if (*q == '/')
+			*q = '\0';
+	}
+
+	fprintf(stdout, "Copying to %s/%s\n", args[ind+1], p);
+
+	ret = rdump_inode(gbls.fs, blkno, p, args[ind+1], verbose);
+	if (ret)
+		com_err(args[0], ret, " ");
+
+	return ;
+}

Modified: trunk/debugfs.ocfs2/include/utils.h
===================================================================
--- trunk/debugfs.ocfs2/include/utils.h	2004-12-18 01:06:57 UTC (rev 502)
+++ trunk/debugfs.ocfs2/include/utils.h	2004-12-20 22:38:39 UTC (rev 503)
@@ -26,6 +26,13 @@
 #ifndef __UTILS_H__
 #define __UTILS_H__
 
+typedef struct _rdump_opts {
+	ocfs2_filesys *fs;
+	char *fullname;
+	char *buf;
+	int verbose;
+} rdump_opts;
+
 void get_vote_flag (__u32 flag, GString *str);
 void get_publish_flag (__u32 flag, GString *str);
 void get_journal_blktyp (__u32 jtype, GString *str);
@@ -41,5 +48,6 @@
 			  uint32_t *buflen);
 void inode_perms_to_str(uint16_t mode, char *str, int len);
 void inode_time_to_str(uint64_t mtime, char *str, int len);
-
+errcode_t rdump_inode(ocfs2_filesys *fs, uint64_t blkno, const char *name,
+		      const char *dumproot, int verbose);
 #endif		/* __UTILS_H__ */

Modified: trunk/debugfs.ocfs2/utils.c
===================================================================
--- trunk/debugfs.ocfs2/utils.c	2004-12-18 01:06:57 UTC (rev 502)
+++ trunk/debugfs.ocfs2/utils.c	2004-12-20 22:38:39 UTC (rev 503)
@@ -284,34 +284,45 @@
 /*
  * fix_perms()
  *
+ * Code based on similar function in e2fsprogs-1.32/debugfs/dump.c
+ *
+ * Copyright (C) 1994 Theodore Ts'o.  This file may be redistributed
+ * under the terms of the GNU Public License.
  */
-static errcode_t fix_perms(const ocfs2_dinode *di, int *fd, char *out_file)
+static errcode_t fix_perms(const ocfs2_dinode *di, int *fd, char *name)
 {
 	struct utimbuf ut;
 	int i;
 	errcode_t ret = 0;
 
-	i = fchmod(*fd, di->i_mode);
+	if (*fd != -1)
+		i = fchmod(*fd, di->i_mode);
+	else
+		i = chmod(name, di->i_mode);
 	if (i == -1) {
 		ret = errno;
 		goto bail;
 	}
 
-	i = fchown(*fd, di->i_uid, di->i_gid);
+	if (*fd != -1)
+		i = fchown(*fd, di->i_uid, di->i_gid);
+	else
+		i = chown(name, di->i_uid, di->i_gid);
 	if (i == -1) {
 		ret = errno;
 		goto bail;
 	}
 
-	close(*fd);
-	*fd = -1;
+	if (*fd != -1) {
+		close(*fd);
+		*fd = -1;
+	}
 
 	ut.actime = di->i_atime;
 	ut.modtime = di->i_mtime;
-	if (utime(out_file, &ut) == -1) {
+	if (utime(name, &ut) == -1)
 		ret = errno;
-		goto bail;
-	}
+
 bail:
 	return ret;
 }
@@ -505,3 +516,158 @@
 
 	return ;
 }
+
+
+/*
+ * rdump_symlink()
+ *
+ * Code based on similar function in e2fsprogs-1.32/debugfs/dump.c
+ *
+ * Copyright (C) 1994 Theodore Ts'o.  This file may be redistributed
+ * under the terms of the GNU Public License.
+ */
+static errcode_t rdump_symlink(ocfs2_filesys *fs, uint64_t blkno, char *name)
+{
+	char *buf = NULL;
+	uint32_t len = 0;
+	errcode_t ret;
+
+	ret = read_whole_file(fs, blkno, &buf, &len);
+	if (ret)
+		goto bail;
+
+	if (symlink(buf, name) == -1)
+		ret = errno;
+
+bail:
+	if (buf)
+		ocfs2_free(&buf);
+
+	return ret;
+}
+
+/*
+ * rdump_dirent()
+ *
+ * Code based on similar function in e2fsprogs-1.32/debugfs/dump.c
+ *
+ * Copyright (C) 1994 Theodore Ts'o.  This file may be redistributed
+ * under the terms of the GNU Public License.
+ */
+static int rdump_dirent(struct ocfs2_dir_entry *rec, int offset, int blocksize,
+			char *buf, void *priv_data)
+{
+	rdump_opts *rd = (rdump_opts *)priv_data;
+	char tmp = rec->name[rec->name_len];
+	errcode_t ret = 0;
+
+	rec->name[rec->name_len] = '\0';
+
+	if (!strncmp(rec->name, ".", 1) || !strncmp(rec->name, "..", 2))
+		goto bail;
+
+	ret = rdump_inode(rd->fs, rec->inode, rec->name, rd->fullname,
+			  rd->verbose);
+
+bail:
+	rec->name[rec->name_len] = tmp;
+
+	return ret;
+}
+
+/*
+ * rdump_inode()
+ *
+ * Code based on similar function in e2fsprogs-1.32/debugfs/dump.c
+ *
+ * Copyright (C) 1994 Theodore Ts'o.  This file may be redistributed
+ * under the terms of the GNU Public License.
+ */
+errcode_t rdump_inode(ocfs2_filesys *fs, uint64_t blkno, const char *name,
+		      const char *dumproot, int verbose)
+{
+	char *fullname = NULL;
+	int len;
+	errcode_t ret;
+	char *buf = NULL;
+	char *dirbuf = NULL;
+	ocfs2_dinode *di;
+	int fd;
+	rdump_opts rd_opts = { NULL, NULL, NULL, 0 };
+
+	len = strlen(dumproot) + strlen(name) + 2;
+	ret = ocfs2_malloc(len, &fullname);
+	if (ret)
+		goto bail;
+
+	snprintf(fullname, len, "%s/%s", dumproot, name);
+
+	ret = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (ret)
+		goto bail;
+
+	ret = ocfs2_read_inode(fs, blkno, buf);
+	if (ret)
+		goto bail;
+	di = (ocfs2_dinode *)buf;
+
+	if (S_ISLNK(di->i_mode)) {
+		ret = rdump_symlink(fs, blkno, fullname);
+		if (ret)
+			goto bail;
+	} else if (S_ISREG(di->i_mode)) {
+		if (verbose)
+			fprintf(stdout, "%s\n", fullname);
+		fd = open(fullname, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
+		if (fd == -1) {
+			ret = errno;
+			goto bail;
+		}
+
+		ret = dump_file(fs, blkno, fd, fullname, 1);
+		if (ret)
+			goto bail;
+	} else if (S_ISDIR(di->i_mode) && strncmp(name, ".", 1) &&
+		   strncmp(name, "..", 2)) {
+
+		if (verbose)
+			fprintf(stdout, "%s\n", fullname);
+		/* Create the directory with 0700 permissions, because we
+		 * expect to have to create entries it.  Then fix its perms
+		 * once we've done the traversal. */
+		if (mkdir(fullname, S_IRWXU) == -1) {
+			ret = errno;
+			goto bail;
+		}
+
+		ret = ocfs2_malloc_block(fs->fs_io, &dirbuf);
+		if (ret)
+			goto bail;
+
+		rd_opts.fs = fs;
+		rd_opts.buf = dirbuf;
+		rd_opts.fullname = fullname;
+		rd_opts.verbose = verbose;
+
+		ret = ocfs2_dir_iterate(fs, blkno, 0, NULL,
+					rdump_dirent, (void *)&rd_opts);
+		if (ret)
+			goto bail;
+
+		fd = -1;
+		ret = fix_perms(di, &fd, fullname);
+		if (ret)
+			goto bail;
+	}
+	/* else do nothing (don't dump device files, sockets, fifos, etc.) */
+
+bail:
+	if (fullname)
+		ocfs2_free(&fullname);
+	if (buf)
+		ocfs2_free(&buf);
+	if (dirbuf)
+		ocfs2_free(&dirbuf);
+
+	return ret;
+}



More information about the Ocfs2-tools-commits mailing list