[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