2 * e2image.c --- Program which writes an image file backing up
3 * critical metadata for the filesystem.
5 * Copyright 2000, 2001 by Theodore Ts'o.
8 * This file may be redistributed under the terms of the GNU Public
13 #ifndef _LARGEFILE_SOURCE
14 #define _LARGEFILE_SOURCE
16 #ifndef _LARGEFILE64_SOURCE
17 #define _LARGEFILE64_SOURCE
40 #include <sys/types.h>
44 #include "ext2fs/ext2_fs.h"
45 #include "ext2fs/ext2fs.h"
46 #include "ext2fs/ext2fsP.h"
47 #include "et/com_err.h"
48 #include "uuid/uuid.h"
50 #include "ext2fs/e2image.h"
51 #include "ext2fs/qcow2.h"
53 #include "support/nls-enable.h"
54 #include "support/plausible.h"
55 #include "../version.h"
57 #define QCOW_OFLAG_COPIED (1LL << 63)
58 #define NO_BLK ((blk64_t) -1)
62 #define E2IMAGE_QCOW2 2
65 #define E2IMAGE_INSTALL_FLAG 1
66 #define E2IMAGE_SCRAMBLE_FLAG 2
67 #define E2IMAGE_IS_QCOW2_FLAG 4
68 #define E2IMAGE_CHECK_ZERO_FLAG 8
70 static const char * program_name = "e2image";
71 static char * device_name = NULL;
73 static char output_is_blk;
75 /* writing to blk device: don't skip zeroed blocks */
76 static blk64_t source_offset, dest_offset;
77 static char move_mode;
78 static char show_progress;
79 static char *check_buf;
80 static int skipped_blocks;
82 static blk64_t align_offset(blk64_t offset, unsigned int n)
84 return (offset + n - 1) & ~((blk64_t) n - 1);
87 static int get_bits_from_size(size_t size)
95 /* Not a power of two */
105 static void usage(void)
107 fprintf(stderr, _("Usage: %s [ -r|Q ] [ -f ] [ -b superblock ] [ -B blocksize]"
108 "[ -fr ] device image-file\n"),
110 fprintf(stderr, _(" %s -I device image-file\n"), program_name);
111 fprintf(stderr, _(" %s -ra [ -cfnp ] [ -o src_offset ] "
112 "[ -O dest_offset ] src_fs [ dest_fs ]\n"),
117 static ext2_loff_t seek_relative(int fd, int offset)
119 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_CUR);
121 perror("seek_relative");
127 static ext2_loff_t seek_set(int fd, ext2_loff_t offset)
129 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_SET);
138 * Returns true if the block we are about to write is identical to
139 * what is already on the disk.
141 static int check_block(int fd, void *buf, void *cbuf, int blocksize)
144 int count = blocksize, ret;
150 ret = read(fd, cp, count);
152 perror("check_block");
158 ret = memcmp(buf, cbuf, blocksize);
159 seek_relative(fd, -blocksize);
160 return (ret == 0) ? 1 : 0;
163 static void generic_write(int fd, void *buf, int blocksize, blk64_t block)
165 int count, free_buf = 0;
173 err = ext2fs_get_arrayzero(1, blocksize, &buf);
175 com_err(program_name, err, "%s",
176 _("while allocating buffer"));
181 printf(_("Writing block %llu\n"), (unsigned long long) block);
183 seek_relative(fd, blocksize);
184 goto free_and_return;
186 count = write(fd, buf, blocksize);
187 if (count != blocksize) {
194 com_err(program_name, err,
195 _("error writing block %llu"), block);
197 com_err(program_name, err, "%s",
198 _("error in generic_write()"));
204 ext2fs_free_mem(&buf);
207 static void write_header(int fd, void *hdr, int hdr_size, int wrt_size)
213 if (hdr_size > wrt_size) {
214 fprintf(stderr, "%s",
215 _("Error: header size is bigger than wrt_size\n"));
218 ret = ext2fs_get_mem(wrt_size, &header_buf);
220 fputs(_("Couldn't allocate header buffer\n"), stderr);
225 memset(header_buf, 0, wrt_size);
228 memcpy(header_buf, hdr, hdr_size);
230 generic_write(fd, header_buf, wrt_size, NO_BLK);
232 ext2fs_free_mem(&header_buf);
235 static void write_image_file(ext2_filsys fs, int fd)
237 struct ext2_image_hdr hdr;
241 write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize);
242 memset(&hdr, 0, sizeof(struct ext2_image_hdr));
244 hdr.offset_super = ext2fs_cpu_to_le32(seek_relative(fd, 0));
245 retval = ext2fs_image_super_write(fs, fd, 0);
247 com_err(program_name, retval, "%s",
248 _("while writing superblock"));
252 hdr.offset_inode = ext2fs_cpu_to_le32(seek_relative(fd, 0));
253 retval = ext2fs_image_inode_write(fs, fd,
254 (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0);
256 com_err(program_name, retval, "%s",
257 _("while writing inode table"));
261 hdr.offset_blockmap = ext2fs_cpu_to_le32(seek_relative(fd, 0));
262 retval = ext2fs_image_bitmap_write(fs, fd, 0);
264 com_err(program_name, retval, "%s",
265 _("while writing block bitmap"));
269 hdr.offset_inodemap = ext2fs_cpu_to_le32(seek_relative(fd, 0));
270 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP);
272 com_err(program_name, retval, "%s",
273 _("while writing inode bitmap"));
277 hdr.magic_number = ext2fs_cpu_to_le32(EXT2_ET_MAGIC_E2IMAGE);
278 strcpy(hdr.magic_descriptor, "Ext2 Image 1.0");
279 gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname));
280 strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1);
281 hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0;
282 hdr.fs_blocksize = ext2fs_cpu_to_le32(fs->blocksize);
284 if (stat(device_name, &st) == 0)
285 hdr.fs_device = ext2fs_cpu_to_le32(st.st_rdev);
287 if (fstat(fd, &st) == 0) {
288 hdr.image_device = ext2fs_cpu_to_le32(st.st_dev);
289 hdr.image_inode = ext2fs_cpu_to_le32(st.st_ino);
291 memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid));
293 hdr.image_time = ext2fs_cpu_to_le32(time(0));
294 write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize);
298 * These set of functions are used to write a RAW image file.
300 static ext2fs_block_bitmap meta_block_map;
301 static ext2fs_block_bitmap scramble_block_map; /* Directory blocks to be scrambled */
302 static blk64_t meta_blocks_count;
304 struct process_block_struct {
310 * These subroutines short circuits ext2fs_get_blocks and
311 * ext2fs_check_directory; we use them since we already have the inode
312 * structure, so there's no point in letting the ext2fs library read
315 static ino_t stashed_ino = 0;
316 static struct ext2_inode *stashed_inode;
318 static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)),
324 if ((ino != stashed_ino) || !stashed_inode)
325 return EXT2_ET_CALLBACK_NOTHANDLED;
327 for (i=0; i < EXT2_N_BLOCKS; i++)
328 blocks[i] = stashed_inode->i_block[i];
332 static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)),
335 if ((ino != stashed_ino) || !stashed_inode)
336 return EXT2_ET_CALLBACK_NOTHANDLED;
338 if (!LINUX_S_ISDIR(stashed_inode->i_mode))
339 return EXT2_ET_NO_DIRECTORY;
343 static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
345 struct ext2_inode *inode)
347 if ((ino != stashed_ino) || !stashed_inode)
348 return EXT2_ET_CALLBACK_NOTHANDLED;
349 *inode = *stashed_inode;
353 static void use_inode_shortcuts(ext2_filsys fs, int use_shortcuts)
356 fs->get_blocks = meta_get_blocks;
357 fs->check_directory = meta_check_directory;
358 fs->read_inode = meta_read_inode;
362 fs->check_directory = 0;
367 static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
369 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
370 blk64_t ref_block EXT2FS_ATTR((unused)),
371 int ref_offset EXT2FS_ATTR((unused)),
372 void *priv_data EXT2FS_ATTR((unused)))
374 struct process_block_struct *p;
376 p = (struct process_block_struct *) priv_data;
378 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
380 if (scramble_block_map && p->is_dir && blockcnt >= 0)
381 ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr);
385 static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
387 e2_blkcnt_t blockcnt,
388 blk64_t ref_block EXT2FS_ATTR((unused)),
389 int ref_offset EXT2FS_ATTR((unused)),
390 void *priv_data EXT2FS_ATTR((unused)))
392 if (blockcnt < 0 || all_data) {
393 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
399 static void mark_table_blocks(ext2_filsys fs)
401 blk64_t first_block, b;
404 first_block = fs->super->s_first_data_block;
406 * Mark primary superblock
408 ext2fs_mark_block_bitmap2(meta_block_map, first_block);
412 * Mark the primary superblock descriptors
414 for (j = 0; j < fs->desc_blocks; j++) {
415 ext2fs_mark_block_bitmap2(meta_block_map,
416 ext2fs_descriptor_block_loc2(fs, first_block, j));
418 meta_blocks_count += fs->desc_blocks;
423 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) {
424 ext2fs_mark_block_bitmap2(meta_block_map, fs->super->s_mmp_block);
428 for (i = 0; i < fs->group_desc_count; i++) {
430 * Mark the blocks used for the inode table
432 if ((output_is_blk ||
433 !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) &&
434 ext2fs_inode_table_loc(fs, i)) {
435 unsigned int end = (unsigned) fs->inode_blocks_per_group;
436 /* skip unused blocks */
437 if (!output_is_blk && ext2fs_has_group_desc_csum(fs))
438 end -= (ext2fs_bg_itable_unused(fs, i) /
439 EXT2_INODES_PER_BLOCK(fs->super));
440 for (j = 0, b = ext2fs_inode_table_loc(fs, i);
443 ext2fs_mark_block_bitmap2(meta_block_map, b);
449 * Mark block used for the block bitmap
451 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
452 ext2fs_block_bitmap_loc(fs, i)) {
453 ext2fs_mark_block_bitmap2(meta_block_map,
454 ext2fs_block_bitmap_loc(fs, i));
459 * Mark block used for the inode bitmap
461 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
462 ext2fs_inode_bitmap_loc(fs, i)) {
463 ext2fs_mark_block_bitmap2(meta_block_map,
464 ext2fs_inode_bitmap_loc(fs, i));
471 * This function returns 1 if the specified block is all zeros
473 static int check_zero_block(char *buf, int blocksize)
476 int left = blocksize;
488 static int name_id[256];
490 #define EXT4_MAX_REC_LEN ((1<<16)-1)
492 static void scramble_dir_block(ext2_filsys fs, blk64_t blk, char *buf)
495 struct ext2_dir_entry_2 *dirent;
496 unsigned int rec_len;
499 end = buf + fs->blocksize;
500 for (p = buf; p < end-8; p += rec_len) {
501 dirent = (struct ext2_dir_entry_2 *) p;
502 rec_len = dirent->rec_len;
503 #ifdef WORDS_BIGENDIAN
504 rec_len = ext2fs_swab16(rec_len);
506 if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0)
507 rec_len = fs->blocksize;
509 rec_len = (rec_len & 65532) | ((rec_len & 3) << 16);
511 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len);
513 if (rec_len < 8 || (rec_len % 4) ||
515 printf(_("Corrupt directory block %llu: "
516 "bad rec_len (%d)\n"),
517 (unsigned long long) blk, rec_len);
519 (void) ext2fs_set_rec_len(fs, rec_len,
520 (struct ext2_dir_entry *) dirent);
521 #ifdef WORDS_BIGENDIAN
522 dirent->rec_len = ext2fs_swab16(dirent->rec_len);
526 if (dirent->name_len + 8U > rec_len) {
527 printf(_("Corrupt directory block %llu: "
528 "bad name_len (%d)\n"),
529 (unsigned long long) blk, dirent->name_len);
530 dirent->name_len = rec_len - 8;
534 len = rec_len - dirent->name_len - 8;
536 memset(cp+dirent->name_len, 0, len);
537 if (dirent->name_len==1 && cp[0] == '.')
539 if (dirent->name_len==2 && cp[0] == '.' && cp[1] == '.')
542 memset(cp, 'A', dirent->name_len);
543 len = dirent->name_len;
545 while ((len > 0) && (id > 0)) {
554 static char got_sigint;
556 static void sigint_handler(int unused EXT2FS_ATTR((unused)))
559 signal (SIGINT, SIG_DFL);
562 #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \
563 ((float) (b)))) + 0.5))
564 #define calc_rate(t, b, d) (((float)(t) / ((float)(1024 * 1024) / (b))) / (d))
566 static int print_progress(blk64_t num, blk64_t total)
568 return fprintf(stderr, _("%llu / %llu blocks (%d%%)"), num, total,
569 calc_percent(num, total));
572 static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags)
576 char *buf, *zero_buf;
579 blk64_t distance = 0;
580 blk64_t end = ext2fs_blocks_count(fs->super);
581 time_t last_update = 0;
582 time_t start_time = 0;
583 blk64_t total_written = 0;
586 retval = ext2fs_get_mem(fs->blocksize, &buf);
588 com_err(program_name, retval, "%s",
589 _("while allocating buffer"));
592 retval = ext2fs_get_memzero(fs->blocksize, &zero_buf);
594 com_err(program_name, retval, "%s",
595 _("while allocating buffer"));
599 fprintf(stderr, "%s", _("Copying "));
600 bscount = print_progress(total_written, meta_blocks_count);
602 last_update = time(NULL);
603 start_time = time(NULL);
605 /* when doing an in place move to the right, you can't start
606 at the beginning or you will overwrite data, so instead
607 divide the fs up into distance size chunks and write them
609 if (move_mode && dest_offset > source_offset) {
610 distance = (dest_offset - source_offset) / fs->blocksize;
611 if (distance < ext2fs_blocks_count(fs->super))
612 start = ext2fs_blocks_count(fs->super) - distance;
615 signal (SIGINT, sigint_handler);
618 seek_set(fd, (start * fs->blocksize) + dest_offset);
619 for (blk = start; blk < end; blk++) {
622 /* moving to the right */
623 if (distance >= ext2fs_blocks_count(fs->super)||
624 start == ext2fs_blocks_count(fs->super) -
626 kill(getpid(), SIGINT);
628 /* moving to the left */
629 if (blk < (source_offset - dest_offset) /
631 kill(getpid(), SIGINT);
635 fprintf(stderr, "%s",
636 _("Stopping now will destroy the filesystem, "
637 "interrupt again if you are sure\n"));
639 fprintf(stderr, "%s", _("Copying "));
640 bscount = print_progress(total_written,
647 if (show_progress && last_update != time(NULL)) {
649 last_update = time(NULL);
652 bscount = print_progress(total_written,
654 duration = time(NULL) - start_time;
655 if (duration > 5 && total_written) {
656 time_t est = (duration * meta_blocks_count /
657 total_written) - duration;
659 strftime(buff, 30, "%T", gmtime(&est));
662 _(" %s remaining at %.2f MB/s"),
663 buff, calc_rate(total_written,
669 if ((blk >= fs->super->s_first_data_block) &&
670 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
671 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
673 com_err(program_name, retval,
674 _("error reading block %llu"), blk);
677 if (scramble_block_map &&
678 ext2fs_test_block_bitmap2(scramble_block_map, blk))
679 scramble_dir_block(fs, blk, buf);
680 if ((flags & E2IMAGE_CHECK_ZERO_FLAG) &&
681 check_zero_block(buf, fs->blocksize))
684 seek_relative(fd, sparse);
686 if (check_block(fd, buf, check_buf, fs->blocksize)) {
687 seek_relative(fd, fs->blocksize);
690 generic_write(fd, buf, fs->blocksize, blk);
695 generic_write(fd, zero_buf,
699 sparse += fs->blocksize;
700 if (sparse > 1024*1024) {
701 seek_relative(fd, 1024*1024);
706 if (distance && start) {
707 if (start < distance) {
713 if (end < distance) {
714 /* past overlap, do rest in one go */
722 signal (SIGINT, SIG_DFL);
724 time_t duration = time(NULL) - start_time;
727 strftime(buff, 30, "%T", gmtime(&duration));
728 fprintf(stderr, _("Copied %llu / %llu blocks (%d%%) in %s "),
729 total_written, meta_blocks_count,
730 calc_percent(total_written, meta_blocks_count), buff);
732 fprintf(stderr, _("at %.2f MB/s"),
733 calc_rate(total_written, fs->blocksize, duration));
734 fputs(" \n", stderr);
736 #ifdef HAVE_FTRUNCATE64
740 offset = seek_set(fd,
741 fs->blocksize * ext2fs_blocks_count(fs->super) + dest_offset);
743 offset = seek_relative(fd, sparse);
745 if (ftruncate64(fd, offset) < 0) {
746 seek_relative(fd, -1);
747 generic_write(fd, zero_buf, 1, NO_BLK);
751 if (sparse && !distance) {
752 seek_relative(fd, sparse-1);
753 generic_write(fd, zero_buf, 1, NO_BLK);
756 ext2fs_free_mem(&zero_buf);
757 ext2fs_free_mem(&buf);
760 static void init_l1_table(struct ext2_qcow2_image *image)
765 ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table);
767 com_err(program_name, ret, "%s",
768 _("while allocating l1 table"));
772 image->l1_table = l1_table;
775 static void init_l2_cache(struct ext2_qcow2_image *image)
777 unsigned int count, i;
778 struct ext2_qcow2_l2_cache *cache;
779 struct ext2_qcow2_l2_table *table;
782 ret = ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache),
787 count = (image->l1_size > L2_CACHE_PREALLOC) ? L2_CACHE_PREALLOC :
790 cache->count = count;
792 cache->next_offset = image->l2_offset;
794 for (i = 0; i < count; i++) {
795 ret = ext2fs_get_arrayzero(1,
796 sizeof(struct ext2_qcow2_l2_table), &table);
800 ret = ext2fs_get_arrayzero(image->l2_size,
801 sizeof(__u64), &table->data);
805 table->next = cache->free_head;
806 cache->free_head = table;
809 image->l2_cache = cache;
813 com_err(program_name, ret, "%s", _("while allocating l2 cache"));
817 static void put_l2_cache(struct ext2_qcow2_image *image)
819 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
820 struct ext2_qcow2_l2_table *tmp, *table;
825 table = cache->free_head;
826 cache->free_head = NULL;
831 ext2fs_free_mem(&tmp->data);
832 ext2fs_free_mem(&tmp);
835 if (cache->free != cache->count) {
836 fprintf(stderr, "%s", _("Warning: There are still tables in "
837 "the cache while putting the cache, "
838 "data will be lost so the image may "
840 table = cache->used_head;
841 cache->used_head = NULL;
845 ext2fs_free_mem(&cache);
848 static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset)
850 struct ext2_qcow2_refcount *ref;
851 blk64_t table_clusters;
854 ref = &(img->refcount);
857 * One refcount block addresses 2048 clusters, one refcount table
858 * addresses cluster/sizeof(__u64) refcount blocks, and we need
859 * to address meta_blocks_count clusters + qcow2 metadata clusters
862 table_clusters = meta_blocks_count + (table_offset >>
864 table_clusters >>= (img->cluster_bits + 6 - 1);
865 table_clusters = (table_clusters == 0) ? 1 : table_clusters;
867 ref->refcount_table_offset = table_offset;
868 ref->refcount_table_clusters = table_clusters;
869 ref->refcount_table_index = 0;
870 ref->refcount_block_index = 0;
872 /* Allocate refcount table */
873 ret = ext2fs_get_arrayzero(ref->refcount_table_clusters,
874 img->cluster_size, &ref->refcount_table);
878 /* Allocate refcount block */
879 ret = ext2fs_get_arrayzero(1, img->cluster_size, &ref->refcount_block);
881 ext2fs_free_mem(&ref->refcount_table);
886 static errcode_t initialize_qcow2_image(int fd, ext2_filsys fs,
887 struct ext2_qcow2_image *image)
889 struct ext2_qcow2_hdr *header;
890 blk64_t total_size, offset;
891 int shift, l2_bits, header_size, l1_size, ret;
892 int cluster_bits = get_bits_from_size(fs->blocksize);
893 struct ext2_super_block *sb = fs->super;
895 if (fs->blocksize < 1024)
896 return EINVAL; /* Can never happen, but just in case... */
898 /* Allocate header */
899 ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header);
903 total_size = ext2fs_blocks_count(sb) << cluster_bits;
904 image->cluster_size = fs->blocksize;
905 image->l2_size = 1 << (cluster_bits - 3);
906 image->cluster_bits = cluster_bits;
909 header->magic = ext2fs_cpu_to_be32(QCOW_MAGIC);
910 header->version = ext2fs_cpu_to_be32(QCOW_VERSION);
911 header->size = ext2fs_cpu_to_be64(total_size);
912 header->cluster_bits = ext2fs_cpu_to_be32(cluster_bits);
914 header_size = (sizeof(struct ext2_qcow2_hdr) + 7) & ~7;
915 offset = align_offset(header_size, image->cluster_size);
917 header->l1_table_offset = ext2fs_cpu_to_be64(offset);
918 image->l1_offset = offset;
920 l2_bits = cluster_bits - 3;
921 shift = cluster_bits + l2_bits;
922 l1_size = ((total_size + (1LL << shift) - 1) >> shift);
923 header->l1_size = ext2fs_cpu_to_be32(l1_size);
924 image->l1_size = l1_size;
926 /* Make space for L1 table */
927 offset += align_offset(l1_size * sizeof(blk64_t), image->cluster_size);
929 /* Initialize refcounting */
930 ret = init_refcount(image, offset);
932 ext2fs_free_mem(&header);
935 header->refcount_table_offset = ext2fs_cpu_to_be64(offset);
936 header->refcount_table_clusters =
937 ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters);
938 offset += image->cluster_size;
939 offset += image->refcount.refcount_table_clusters <<
942 /* Make space for L2 tables */
943 image->l2_offset = offset;
944 offset += image->cluster_size;
946 /* Make space for first refcount block */
947 image->refcount.refcount_block_offset = offset;
950 /* Initialize l1 and l2 tables */
951 init_l1_table(image);
952 init_l2_cache(image);
957 static void free_qcow2_image(struct ext2_qcow2_image *img)
963 ext2fs_free_mem(&img->hdr);
966 ext2fs_free_mem(&img->l1_table);
968 if (img->refcount.refcount_table)
969 ext2fs_free_mem(&img->refcount.refcount_table);
970 if (img->refcount.refcount_block)
971 ext2fs_free_mem(&img->refcount.refcount_block);
975 ext2fs_free_mem(&img);
979 * Put table from used list (used_head) into free list (free_head).
980 * l2_table is used to return pointer to the next used table (used_head).
982 static void put_used_table(struct ext2_qcow2_image *img,
983 struct ext2_qcow2_l2_table **l2_table)
985 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
986 struct ext2_qcow2_l2_table *table;
988 table = cache->used_head;
989 cache->used_head = table->next;
993 cache->used_tail = NULL;
995 /* Clean the table for case we will need to use it again */
996 memset(table->data, 0, img->cluster_size);
997 table->next = cache->free_head;
998 cache->free_head = table;
1002 *l2_table = cache->used_head;
1005 static void flush_l2_cache(struct ext2_qcow2_image *image)
1009 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1010 struct ext2_qcow2_l2_table *table = cache->used_head;
1013 /* Store current position */
1014 offset = seek_relative(fd, 0);
1017 while (cache->free < cache->count) {
1018 if (seek != table->offset) {
1019 seek_set(fd, table->offset);
1020 seek = table->offset;
1023 generic_write(fd, (char *)table->data, image->cluster_size,
1025 put_used_table(image, &table);
1026 seek += image->cluster_size;
1029 /* Restore previous position */
1030 seek_set(fd, offset);
1034 * Get first free table (from free_head) and put it into tail of used list
1036 * l2_table is used to return pointer to moved table.
1037 * Returns 1 if the cache is full, 0 otherwise.
1039 static void get_free_table(struct ext2_qcow2_image *image,
1040 struct ext2_qcow2_l2_table **l2_table)
1042 struct ext2_qcow2_l2_table *table;
1043 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1045 if (0 == cache->free)
1046 flush_l2_cache(image);
1048 table = cache->free_head;
1050 cache->free_head = table->next;
1052 if (cache->used_tail)
1053 cache->used_tail->next = table;
1055 /* First item in the used list */
1056 cache->used_head = table;
1058 cache->used_tail = table;
1064 static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk,
1065 blk64_t data, blk64_t next)
1067 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
1068 struct ext2_qcow2_l2_table *table = cache->used_tail;
1069 blk64_t l1_index = blk / img->l2_size;
1070 blk64_t l2_index = blk & (img->l2_size - 1);
1074 * Need to create new table if it does not exist,
1077 if (!table || (table->l1_index != l1_index)) {
1078 get_free_table(img, &table);
1079 table->l1_index = l1_index;
1080 table->offset = cache->next_offset;
1081 cache->next_offset = next;
1082 img->l1_table[l1_index] =
1083 ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED);
1087 table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED);
1091 static int update_refcount(int fd, struct ext2_qcow2_image *img,
1092 blk64_t offset, blk64_t rfblk_pos)
1094 struct ext2_qcow2_refcount *ref;
1098 ref = &(img->refcount);
1099 table_index = offset >> (2 * img->cluster_bits - 1);
1102 * Need to create new refcount block when the offset addresses
1103 * another item in the refcount table
1105 if (table_index != ref->refcount_table_index) {
1107 seek_set(fd, ref->refcount_block_offset);
1109 generic_write(fd, (char *)ref->refcount_block,
1110 img->cluster_size, NO_BLK);
1111 memset(ref->refcount_block, 0, img->cluster_size);
1113 ref->refcount_table[ref->refcount_table_index] =
1114 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1115 ref->refcount_block_offset = rfblk_pos;
1116 ref->refcount_block_index = 0;
1117 ref->refcount_table_index = table_index;
1122 * We are relying on the fact that we are creating the qcow2
1123 * image sequentially, hence we will always allocate refcount
1124 * block items sequentially.
1126 ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1);
1127 ref->refcount_block_index++;
1131 static int sync_refcount(int fd, struct ext2_qcow2_image *img)
1133 struct ext2_qcow2_refcount *ref;
1135 ref = &(img->refcount);
1137 ref->refcount_table[ref->refcount_table_index] =
1138 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1139 seek_set(fd, ref->refcount_table_offset);
1140 generic_write(fd, (char *)ref->refcount_table,
1141 ref->refcount_table_clusters << img->cluster_bits, NO_BLK);
1143 seek_set(fd, ref->refcount_block_offset);
1144 generic_write(fd, (char *)ref->refcount_block, img->cluster_size,
1149 static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
1152 blk64_t blk, offset, size, end;
1154 struct ext2_qcow2_image *img;
1155 unsigned int header_size;
1157 /* allocate struct ext2_qcow2_image */
1158 retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img);
1160 com_err(program_name, retval, "%s",
1161 _("while allocating ext2_qcow2_image"));
1165 retval = initialize_qcow2_image(fd, fs, img);
1167 com_err(program_name, retval, "%s",
1168 _("while initializing ext2_qcow2_image"));
1171 header_size = align_offset(sizeof(struct ext2_qcow2_hdr),
1173 write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size);
1175 /* Refcount all qcow2 related metadata up to refcount_block_offset */
1176 end = img->refcount.refcount_block_offset;
1178 blk = end + img->cluster_size;
1179 for (offset = 0; offset <= end; offset += img->cluster_size) {
1180 if (update_refcount(fd, img, offset, blk)) {
1181 blk += img->cluster_size;
1183 * If we create new refcount block, we need to refcount
1186 end += img->cluster_size;
1189 seek_set(fd, offset);
1191 retval = ext2fs_get_mem(fs->blocksize, &buf);
1193 com_err(program_name, retval, "%s",
1194 _("while allocating buffer"));
1197 /* Write qcow2 data blocks */
1198 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) {
1199 if ((blk >= fs->super->s_first_data_block) &&
1200 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
1201 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
1203 com_err(program_name, retval,
1204 _("error reading block %llu"), blk);
1207 if (scramble_block_map &&
1208 ext2fs_test_block_bitmap2(scramble_block_map, blk))
1209 scramble_dir_block(fs, blk, buf);
1210 if (check_zero_block(buf, fs->blocksize))
1213 if (update_refcount(fd, img, offset, offset)) {
1214 /* Make space for another refcount block */
1215 offset += img->cluster_size;
1216 seek_set(fd, offset);
1218 * We have created the new refcount block, this
1219 * means that we need to refcount it as well.
1220 * So the previous update_refcount refcounted
1221 * the block itself and now we are going to
1222 * create refcount for data. New refcount
1223 * block should not be created!
1225 if (update_refcount(fd, img, offset, offset)) {
1226 fprintf(stderr, "%s",
1227 _("Programming error: multiple "
1228 "sequential refcount blocks "
1234 generic_write(fd, buf, fs->blocksize, blk);
1236 if (add_l2_item(img, blk, offset,
1237 offset + img->cluster_size)) {
1238 offset += img->cluster_size;
1239 if (update_refcount(fd, img, offset,
1240 offset + img->cluster_size)) {
1241 offset += img->cluster_size;
1242 if (update_refcount(fd, img, offset,
1244 fprintf(stderr, "%s",
1245 _("Programming error: multiple sequential refcount "
1246 "blocks created!\n"));
1250 offset += img->cluster_size;
1251 seek_set(fd, offset);
1255 offset += img->cluster_size;
1258 update_refcount(fd, img, offset, offset);
1259 flush_l2_cache(img);
1260 sync_refcount(fd, img);
1263 seek_set(fd, img->l1_offset);
1264 size = img->l1_size * sizeof(__u64);
1265 generic_write(fd, (char *)img->l1_table, size, NO_BLK);
1267 ext2fs_free_mem(&buf);
1268 free_qcow2_image(img);
1271 static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags,
1274 struct process_block_struct pb;
1275 struct ext2_inode inode;
1276 ext2_inode_scan scan;
1281 meta_blocks_count = 0;
1282 retval = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
1285 com_err(program_name, retval, "%s",
1286 _("while allocating block bitmap"));
1290 if (flags & E2IMAGE_SCRAMBLE_FLAG) {
1291 retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
1292 &scramble_block_map);
1294 com_err(program_name, retval, "%s",
1295 _("while allocating scramble block bitmap"));
1303 ext2fs_mark_block_bitmap2(meta_block_map, superblock);
1304 meta_blocks_count++;
1307 * Mark the backup superblock descriptors
1309 for (j = 0; j < fs->desc_blocks; j++) {
1310 ext2fs_mark_block_bitmap2(meta_block_map,
1311 ext2fs_descriptor_block_loc2(fs, superblock, j));
1313 meta_blocks_count += fs->desc_blocks;
1316 mark_table_blocks(fs);
1318 fprintf(stderr, "%s", _("Scanning inodes...\n"));
1320 retval = ext2fs_open_inode_scan(fs, 0, &scan);
1322 com_err(program_name, retval, "%s",
1323 _("while opening inode scan"));
1327 retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
1329 com_err(program_name, 0, "%s",
1330 _("Can't allocate block buffer"));
1334 use_inode_shortcuts(fs, 1);
1335 stashed_inode = &inode;
1337 retval = ext2fs_get_next_inode(scan, &ino, &inode);
1338 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
1341 com_err(program_name, retval, "%s",
1342 _("while getting next inode"));
1347 if (!inode.i_links_count)
1349 if (ext2fs_file_acl_block(fs, &inode)) {
1350 ext2fs_mark_block_bitmap2(meta_block_map,
1351 ext2fs_file_acl_block(fs, &inode));
1352 meta_blocks_count++;
1354 if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
1359 pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
1360 if (LINUX_S_ISDIR(inode.i_mode) ||
1361 (LINUX_S_ISLNK(inode.i_mode) &&
1362 ext2fs_inode_has_valid_blocks2(fs, &inode)) ||
1363 ino == fs->super->s_journal_inum) {
1364 retval = ext2fs_block_iterate3(fs, ino,
1365 BLOCK_FLAG_READ_ONLY, block_buf,
1366 process_dir_block, &pb);
1368 com_err(program_name, retval,
1369 _("while iterating over inode %u"),
1374 if ((inode.i_flags & EXT4_EXTENTS_FL) ||
1375 inode.i_block[EXT2_IND_BLOCK] ||
1376 inode.i_block[EXT2_DIND_BLOCK] ||
1377 inode.i_block[EXT2_TIND_BLOCK] || all_data) {
1378 retval = ext2fs_block_iterate3(fs,
1379 ino, BLOCK_FLAG_READ_ONLY, block_buf,
1380 process_file_block, &pb);
1382 com_err(program_name, retval,
1383 _("while iterating over inode %u"), ino);
1389 use_inode_shortcuts(fs, 0);
1391 if (type & E2IMAGE_QCOW2)
1392 output_qcow2_meta_data_blocks(fs, fd);
1394 output_meta_data_blocks(fs, fd, flags);
1396 ext2fs_free_mem(&block_buf);
1397 ext2fs_close_inode_scan(scan);
1398 ext2fs_free_block_bitmap(meta_block_map);
1399 if (type & E2IMAGE_SCRAMBLE_FLAG)
1400 ext2fs_free_block_bitmap(scramble_block_map);
1403 static void install_image(char *device, char *image_fn, int type)
1407 int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS |
1408 EXT2_FLAG_IGNORE_CSUM_ERRORS;
1414 com_err(program_name, 0, "%s",
1415 _("Raw and qcow2 images cannot be installed"));
1419 #ifdef CONFIG_TESTIO_DEBUG
1420 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1421 io_ptr = test_io_manager;
1422 test_io_backing_manager = unix_io_manager;
1425 io_ptr = unix_io_manager;
1427 retval = ext2fs_open (image_fn, open_flag, 0, 0,
1430 com_err(program_name, retval, _("while trying to open %s"),
1435 retval = ext2fs_read_bitmaps (fs);
1437 com_err(program_name, retval, "%s", _("error reading bitmaps"));
1441 fd = ext2fs_open_file(image_fn, O_RDONLY, 0);
1447 retval = io_ptr->open(device, IO_FLAG_RW, &io);
1449 com_err(device, 0, "%s", _("while opening device file"));
1453 ext2fs_rewrite_to_io(fs, io);
1455 seek_set(fd, ext2fs_le32_to_cpu(fs->image_header->offset_inode));
1457 retval = ext2fs_image_inode_read(fs, fd, 0);
1459 com_err(image_fn, 0, "%s",
1460 _("while restoring the image table"));
1465 ext2fs_close_free(&fs);
1468 static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name)
1471 *fd = ext2fs_open_file(name, O_RDONLY, 0600);
1475 return qcow2_read_header(*fd);
1478 int main (int argc, char ** argv)
1483 char *image_fn, offset_opt[64];
1484 struct ext2_qcow2_hdr *header = NULL;
1485 int open_flag = EXT2_FLAG_64BITS | EXT2_FLAG_IGNORE_CSUM_ERRORS;
1488 int mount_flags = 0;
1492 int ignore_rw_mount = 0;
1495 blk64_t superblock = 0;
1499 setlocale(LC_MESSAGES, "");
1500 setlocale(LC_CTYPE, "");
1501 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
1502 textdomain(NLS_CAT_NAME);
1503 set_com_err_gettext(gettext);
1505 fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION,
1508 program_name = *argv;
1509 add_error_table(&et_ext2_error_table);
1510 while ((c = getopt(argc, argv, "b:B:nrsIQafo:O:pc")) != EOF)
1513 superblock = strtoull(optarg, NULL, 0);
1516 blocksize = strtoul(optarg, NULL, 0);
1519 flags |= E2IMAGE_INSTALL_FLAG;
1524 img_type |= E2IMAGE_QCOW2;
1529 img_type |= E2IMAGE_RAW;
1532 flags |= E2IMAGE_SCRAMBLE_FLAG;
1538 ignore_rw_mount = 1;
1544 source_offset = strtoull(optarg, NULL, 0);
1547 dest_offset = strtoull(optarg, NULL, 0);
1558 if (optind == argc - 1 &&
1559 (source_offset || dest_offset))
1561 else if (optind != argc - 2 )
1564 if (all_data && !img_type) {
1565 com_err(program_name, 0, "%s", _("-a option can only be used "
1566 "with raw or QCOW2 images."));
1569 if (superblock && !img_type) {
1570 com_err(program_name, 0, "%s", _("-b option can only be used "
1571 "with raw or QCOW2 images."));
1574 if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) {
1575 com_err(program_name, 0, "%s",
1576 _("Offsets are only allowed with raw images."));
1579 if (move_mode && img_type != E2IMAGE_RAW) {
1580 com_err(program_name, 0, "%s",
1581 _("Move mode is only allowed with raw images."));
1584 if (move_mode && !all_data) {
1585 com_err(program_name, 0, "%s",
1586 _("Move mode requires all data mode."));
1589 device_name = argv[optind];
1591 image_fn = device_name;
1592 else image_fn = argv[optind+1];
1594 retval = ext2fs_check_if_mounted(device_name, &mount_flags);
1596 com_err(program_name, retval, "%s", _("checking if mounted"));
1600 if (img_type && !ignore_rw_mount &&
1601 (mount_flags & EXT2_MF_MOUNTED) &&
1602 !(mount_flags & EXT2_MF_READONLY)) {
1603 fprintf(stderr, "%s", _("\nRunning e2image on a R/W mounted "
1604 "filesystem can result in an\n"
1605 "inconsistent image which will not be useful "
1606 "for debugging purposes.\n"
1607 "Use -f option if you really want to do that.\n"));
1611 if (flags & E2IMAGE_INSTALL_FLAG) {
1612 install_image(device_name, image_fn, img_type);
1616 if (img_type & E2IMAGE_RAW) {
1617 header = check_qcow2_image(&qcow2_fd, device_name);
1619 flags |= E2IMAGE_IS_QCOW2_FLAG;
1623 sprintf(offset_opt, "offset=%llu", source_offset);
1624 retval = ext2fs_open2(device_name, offset_opt, open_flag,
1625 superblock, blocksize, unix_io_manager, &fs);
1627 com_err (program_name, retval, _("while trying to open %s"),
1629 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout);
1630 if (retval == EXT2_ET_BAD_MAGIC)
1631 check_plausibility(device_name, CHECK_FS_EXIST, NULL);
1636 if (strcmp(image_fn, "-") == 0)
1639 int o_flags = O_CREAT|O_RDWR;
1641 if (img_type != E2IMAGE_RAW)
1643 if (access(image_fn, F_OK) != 0)
1644 flags |= E2IMAGE_CHECK_ZERO_FLAG;
1645 fd = ext2fs_open_file(image_fn, o_flags, 0600);
1647 com_err(program_name, errno,
1648 _("while trying to open %s"), image_fn);
1653 seek_set(fd, dest_offset);
1655 if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) {
1656 com_err(program_name, 0, "%s",
1657 _("QCOW2 image can not be written to the stdout!\n"));
1661 if (fstat(fd, &st)) {
1662 com_err(program_name, 0, "%s",
1663 _("Can not stat output\n"));
1666 if (ext2fsP_is_disk_device(st.st_mode))
1669 if (flags & E2IMAGE_IS_QCOW2_FLAG) {
1670 ret = qcow2_write_raw_image(qcow2_fd, fd, header);
1672 if (ret == -QCOW_COMPRESSED)
1673 fprintf(stderr, _("Image (%s) is compressed\n"),
1675 else if (ret == -QCOW_ENCRYPTED)
1676 fprintf(stderr, _("Image (%s) is encrypted\n"),
1678 else if (ret == -QCOW_CORRUPTED)
1679 fprintf(stderr, _("Image (%s) is corrupted\n"),
1682 com_err(program_name, ret,
1683 _("while trying to convert qcow2 image"
1684 " (%s) into raw image (%s)"),
1685 image_fn, device_name);
1692 if (img_type != E2IMAGE_RAW) {
1693 fprintf(stderr, "%s", _("The -c option only supported "
1698 fprintf(stderr, "%s", _("The -c option not supported "
1699 "when writing to stdout\n"));
1702 retval = ext2fs_get_mem(fs->blocksize, &check_buf);
1704 com_err(program_name, retval, "%s",
1705 _("while allocating check_buf"));
1709 if (show_progress && (img_type != E2IMAGE_RAW)) {
1710 fprintf(stderr, "%s",
1711 _("The -p option only supported in raw mode\n"));
1715 write_raw_image_file(fs, fd, img_type, flags, superblock);
1717 write_image_file(fs, fd);
1719 ext2fs_close_free(&fs);
1721 printf(_("%d blocks already contained the data to be copied\n"),
1729 remove_error_table(&et_ext2_error_table);