summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2005-01-19 00:26:43 -0500
committerTheodore Ts'o <tytso@mit.edu>2005-01-19 00:26:43 -0500
commitd851ed3983ed4b25d1db58bfbd23dcb6712c0c3b (patch)
treed7483c44c240e471e0184ea69996665b36238948
parent8800c738350800a66d38aa22f5ec916f97c29622 (diff)
downloade2fsprogs-d851ed3983ed4b25d1db58bfbd23dcb6712c0c3b.tar.gz
e2image.c, e2image.8.in: Add support for the -s option which
scrambles directory entries for raw image files.
-rw-r--r--misc/ChangeLog5
-rw-r--r--misc/e2image.8.in78
-rw-r--r--misc/e2image.c111
3 files changed, 159 insertions, 35 deletions
diff --git a/misc/ChangeLog b/misc/ChangeLog
index c8356f8d..5812a981 100644
--- a/misc/ChangeLog
+++ b/misc/ChangeLog
@@ -1,3 +1,8 @@
+2005-01-18 Theodore Ts'o <tytso@mit.edu>
+
+ * e2image.c, e2image.8.in: Add support for the -s option which
+ scrambles directory entries for raw image files.
+
2005-01-17 Theodore Ts'o <tytso@mit.edu>
* tune2fs.c: On Solaris, defining _XOPEN_SOURCE inexplicably
diff --git a/misc/e2image.8.in b/misc/e2image.8.in
index 45ee272d..4b75e6df 100644
--- a/misc/e2image.8.in
+++ b/misc/e2image.8.in
@@ -8,7 +8,7 @@ e2image \- Save critical ext2/ext3 filesystem data to a file
.SH SYNOPSIS
.B e2image
[
-.B \-rI
+.B \-rsI
]
.I device
.I image-file
@@ -45,10 +45,41 @@ requires random-access access to the file, which can not be done using a
pipe. This restriction will hopefully be lifted in a future version of
.BR e2image .)
.PP
+It is a very good idea to periodically (at boot time and
+every week or so) to create image files for all of
+filesystems on a system, as well as saving the partition
+layout (which can be generated using the using
+.B fdisk \-l
+command). Ideally the image file should be stored on some filesystem
+other that
+the filesystem whose data it contains, to ensure that its data is
+accessible in the case where the filesystem has been badly damaged.
+.PP
+To save disk space,
+.B e2image
+creates the image file as a sparse file.
+Hence, if the image file
+needs to be copied to another location, it should
+either be compressed first or copied using the
+.B \-\-sparse=always
+option to GNU version of
+.BR cp .
+.PP
+The size of an ext2 image file depends primarily on the size of the
+filesystems and how many inodes are in use. For a typical 10 gigabyte
+filesystem, with 200,000 inodes in use out of 1.2 million inodes, the
+image file be approximately 35 megabytes; a 4 gigabyte filesystem with
+15,000 inodes in use out of 550,000 inodes will result in a 3 megabyte
+image file. Image files tend to be quite
+compressible; an image file taking up 32 megabytes of space on
+disk will generally compress down to 3 or 4 megabytes.
+.PP
+.SH RESTORING FILESYSTEM METADATA USING AN IMAGE FILE
+.PP
The
.B \-I
option will cause e2image to install the metadata stored in the image
-file to the device. It can be used to restore the filesystem metadata
+file back to the device. It can be used to restore the filesystem metadata
back to the device in emergency situations.
.PP
.B WARNING!!!!
@@ -62,6 +93,7 @@ be lost. In general, you should make a full image
backup of the filesystem first, in case you wish to try other recovery
strategies afterwards.
.PP
+.SH RAW IMAGE FILES
The
.B \-r
option will create a raw image file instead of a normal image file.
@@ -74,37 +106,25 @@ created as a sparse file. (Beware of copying or
compressing/decompressing this file with utilities that don't understand
how to create sparse files; the file will become as large as the
filesystem itself!) Secondly, the raw image file also includes indirect
-blocks and data blocks, which the current image file does not have,
+blocks and directory blocks, which the standard image file does not have,
although this may change in the future.
.PP
-It is a very good idea to periodically (at boot time and
-every week or so) to create image files for all of
-filesystems on a system, as well as saving the partition
-layout (which can be generated using the using
-.B fdisk \-l
-command). Ideally the image file should be stored on some filesystem
-other that
-the filesystem whose data it contains, to ensure that its data is
-accessible in the case where the filesystem has been badly damaged.
+Raw image files are sometimes used when sending filesystems to as part
+of bug reports to e2fsprogs. When used in this capacity, the
+recommended command is (replace hda1 with appropriate device):
.PP
-To save disk space,
-.B e2image
-creates the image file as a sparse file.
-Hence, if the image file
-needs to be copied to another location, it should
-either be compressed first or copied using the
-.B \-\-sparse=always
-option to GNU version of
-.BR cp .
+.br
+\ \fBe2image -r /dev/hda1 - | bzip2 > hda1.e2i.bz2\fR
.PP
-The size of an ext2 image file depends primarily on the size of the
-filesystems and how many inodes are in use. For a typical 10 gigabyte
-filesystem, with 200,000 inodes in use out of 1.2 million inodes, the
-image file be approximately 35 megabytes; a 4 gigabyte filesystem with
-15,000 inodes in use out of 550,000 inodes will result in a 3 megabyte
-image file. Image files tend to be quite
-compressible; an image file taking up 32 megabytes of space on
-disk will generally compress down to 3 or 4 megabytes.
+This will only send the metadata information, without any data blocks.
+However, the filenames in the directory blocks can still reveal
+information about the contents of the filesystem that the bug reporter
+may wish to keep confidential. To address this concern, the
+.B \-s
+option can be specified. This will cause
+.B e2image
+to scramble directory entries and zero out any unused portions
+of the directory blocks before writing them to the image file.
.PP
.SH AUTHOR
.B e2image
diff --git a/misc/e2image.c b/misc/e2image.c
index 9ff35108..cd71431b 100644
--- a/misc/e2image.c
+++ b/misc/e2image.c
@@ -47,7 +47,8 @@ char * device_name = NULL;
static void usage(void)
{
- fprintf(stderr, _("Usage: %s [-r] device image_file\n"), program_name);
+ fprintf(stderr, _("Usage: %s [-rsI] device image_file\n"),
+ program_name);
exit (1);
}
@@ -146,9 +147,11 @@ static void write_image_file(ext2_filsys fs, int fd)
* These set of functions are used to write a RAW image file.
*/
ext2fs_block_bitmap meta_block_map;
+ext2fs_block_bitmap scramble_block_map; /* Directory blocks to be scrambled */
struct process_block_struct {
ext2_ino_t ino;
+ int is_dir;
};
/*
@@ -216,7 +219,15 @@ static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
int ref_offset EXT2FS_ATTR((unused)),
void *priv_data EXT2FS_ATTR((unused)))
{
+ struct process_block_struct *p;
+
+ p = (struct process_block_struct *) priv_data;
+
+ printf("block %d, ino %d, is_dir=%d\n", *block_nr, p->ino, p->is_dir);
+
ext2fs_mark_block_bitmap(meta_block_map, *block_nr);
+ if (scramble_block_map && p->is_dir && blockcnt >= 0)
+ ext2fs_mark_block_bitmap(scramble_block_map, *block_nr);
return 0;
}
@@ -326,14 +337,83 @@ static void write_block(int fd, char *buf, int sparse_offset,
}
}
+int name_id[256];
+
+static void scramble_dir_block(ext2_filsys fs, blk_t blk, char *buf)
+{
+ char *p, *end, *cp;
+ struct ext2_dir_entry_2 *dirent;
+ int rec_len, id, len;
+
+ printf("Scrambling directory block %d\n", blk);
+
+ end = buf + fs->blocksize;
+ for (p = buf; p < end-8; p += rec_len) {
+ dirent = (struct ext2_dir_entry_2 *) p;
+ rec_len = dirent->rec_len;
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES)
+ rec_len = ext2fs_swab16(rec_len);
+#endif
+#if 0
+ printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len);
+#endif
+ if (rec_len < 8 || (rec_len % 4) ||
+ (p+rec_len > end)) {
+ printf("Corrupt directory block %lu: "
+ "bad rec_len (%d)\n", blk, rec_len);
+ rec_len = end - p;
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES)
+ dirent->rec_len = ext2fs_swab16(rec_len);
+#endif
+ continue;
+ }
+ if (dirent->name_len + 8 > rec_len) {
+ printf("Corrupt directory block %lu: "
+ "bad name_len (%d)\n", blk, dirent->name_len);
+ dirent->name_len = rec_len - 8;
+ continue;
+ }
+ if (dirent->name_len==1 && p[8] == '.')
+ continue;
+ if (dirent->name_len==2 && p[8] == '.' && p[9] == '.')
+ continue;
+
+ cp = p+8;
+ memset(cp, 'A', dirent->name_len);
+ len = rec_len - dirent->name_len - 8;
+ if (len > 0)
+ memset(cp+dirent->name_len, 0, len);
+ len = dirent->name_len;
+ id = name_id[len]++;
+ while ((len > 0) && (id > 0)) {
+ *cp += id % 26;
+ id = id / 26;
+ cp++;
+ len--;
+ }
+ }
+}
+
static void output_meta_data_blocks(ext2_filsys fs, int fd)
{
errcode_t retval;
blk_t blk;
- char buf[8192], zero_buf[8192];
+ char *buf, *zero_buf;
int sparse = 0;
- memset(zero_buf, 0, sizeof(zero_buf));
+ buf = malloc(fs->blocksize);
+ if (!buf) {
+ com_err(program_name, ENOMEM, "while allocating buffer");
+ exit(1);
+ }
+ zero_buf = malloc(fs->blocksize);
+ if (!zero_buf) {
+ com_err(program_name, ENOMEM, "while allocating buffer");
+ exit(1);
+ }
+ memset(zero_buf, 0, fs->blocksize);
for (blk = 0; blk < fs->super->s_blocks_count; blk++) {
if ((blk >= fs->super->s_first_data_block) &&
ext2fs_test_block_bitmap(meta_block_map, blk)) {
@@ -342,6 +422,9 @@ static void output_meta_data_blocks(ext2_filsys fs, int fd)
com_err(program_name, retval,
"error reading block %d", blk);
}
+ if (scramble_block_map &&
+ ext2fs_test_block_bitmap(scramble_block_map, blk))
+ scramble_dir_block(fs, blk, buf);
if ((fd != 1) && check_zero_block(buf, fs->blocksize))
goto sparse_write;
write_block(fd, buf, sparse, fs->blocksize, blk);
@@ -363,7 +446,7 @@ static void output_meta_data_blocks(ext2_filsys fs, int fd)
write_block(fd, zero_buf, sparse, 1, -1);
}
-static void write_raw_image_file(ext2_filsys fs, int fd)
+static void write_raw_image_file(ext2_filsys fs, int fd, int scramble_flag)
{
struct process_block_struct pb;
struct ext2_inode inode;
@@ -378,6 +461,16 @@ static void write_raw_image_file(ext2_filsys fs, int fd)
com_err(program_name, retval, "while allocating block bitmap");
exit(1);
}
+
+ if (scramble_flag) {
+ retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
+ &scramble_block_map);
+ if (retval) {
+ com_err(program_name, retval,
+ "while allocating scramble block bitmap");
+ exit(1);
+ }
+ }
mark_table_blocks(fs);
@@ -416,6 +509,8 @@ static void write_raw_image_file(ext2_filsys fs, int fd)
continue;
stashed_ino = ino;
+ pb.ino = ino;
+ pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
if (LINUX_S_ISDIR(inode.i_mode) ||
(LINUX_S_ISLNK(inode.i_mode) &&
ext2fs_inode_has_valid_blocks(&inode)) ||
@@ -523,6 +618,7 @@ int main (int argc, char ** argv)
int open_flag = 0;
int raw_flag = 0;
int install_flag = 0;
+ int scramble_flag = 0;
int fd = 0;
#ifdef ENABLE_NLS
@@ -536,11 +632,14 @@ int main (int argc, char ** argv)
if (argc && *argv)
program_name = *argv;
initialize_ext2_error_table();
- while ((c = getopt (argc, argv, "rI")) != EOF)
+ while ((c = getopt (argc, argv, "rsI")) != EOF)
switch (c) {
case 'r':
raw_flag++;
break;
+ case 's':
+ scramble_flag++;
+ break;
case 'I':
install_flag++;
break;
@@ -582,7 +681,7 @@ int main (int argc, char ** argv)
}
if (raw_flag)
- write_raw_image_file(fs, fd);
+ write_raw_image_file(fs, fd, scramble_flag);
else
write_image_file(fs, fd);