.SH SYNOPSIS
.B e2image
[
-.B \-rI
+.B \-rsI
]
.I device
.I image-file
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!!!!
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.
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
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);
}
* 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;
};
/*
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;
}
}
}
+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)) {
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);
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;
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);
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)) ||
int open_flag = 0;
int raw_flag = 0;
int install_flag = 0;
+ int scramble_flag = 0;
int fd = 0;
#ifdef ENABLE_NLS
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;
}
if (raw_flag)
- write_raw_image_file(fs, fd);
+ write_raw_image_file(fs, fd, scramble_flag);
else
write_image_file(fs, fd);