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 (1ULL << 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 "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"),
196 (unsigned long long) block);
198 com_err(program_name, err, "%s",
199 _("error in generic_write()"));
205 ext2fs_free_mem(&buf);
208 static void write_header(int fd, void *hdr, int hdr_size, int wrt_size)
214 if (hdr_size > wrt_size) {
215 fprintf(stderr, "%s",
216 _("Error: header size is bigger than wrt_size\n"));
219 ret = ext2fs_get_mem(wrt_size, &header_buf);
221 fputs(_("Couldn't allocate header buffer\n"), stderr);
226 memset(header_buf, 0, wrt_size);
229 memcpy(header_buf, hdr, hdr_size);
231 generic_write(fd, header_buf, wrt_size, NO_BLK);
233 ext2fs_free_mem(&header_buf);
236 static void write_image_file(ext2_filsys fs, int fd)
238 struct ext2_image_hdr hdr;
242 write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize);
243 memset(&hdr, 0, sizeof(struct ext2_image_hdr));
245 hdr.offset_super = ext2fs_cpu_to_le32(seek_relative(fd, 0));
246 retval = ext2fs_image_super_write(fs, fd, 0);
248 com_err(program_name, retval, "%s",
249 _("while writing superblock"));
253 hdr.offset_inode = ext2fs_cpu_to_le32(seek_relative(fd, 0));
254 retval = ext2fs_image_inode_write(fs, fd,
255 (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0);
257 com_err(program_name, retval, "%s",
258 _("while writing inode table"));
262 hdr.offset_blockmap = ext2fs_cpu_to_le32(seek_relative(fd, 0));
263 retval = ext2fs_image_bitmap_write(fs, fd, 0);
265 com_err(program_name, retval, "%s",
266 _("while writing block bitmap"));
270 hdr.offset_inodemap = ext2fs_cpu_to_le32(seek_relative(fd, 0));
271 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP);
273 com_err(program_name, retval, "%s",
274 _("while writing inode bitmap"));
278 hdr.magic_number = ext2fs_cpu_to_le32(EXT2_ET_MAGIC_E2IMAGE);
279 strcpy(hdr.magic_descriptor, "Ext2 Image 1.0");
280 gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname));
281 strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1);
282 hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0;
283 hdr.fs_blocksize = ext2fs_cpu_to_le32(fs->blocksize);
285 if (stat(device_name, &st) == 0)
286 hdr.fs_device = ext2fs_cpu_to_le32(st.st_rdev);
288 if (fstat(fd, &st) == 0) {
289 hdr.image_device = ext2fs_cpu_to_le32(st.st_dev);
290 hdr.image_inode = ext2fs_cpu_to_le32(st.st_ino);
292 memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid));
294 hdr.image_time = ext2fs_cpu_to_le32(time(0));
295 write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize);
299 * These set of functions are used to write a RAW image file.
301 static ext2fs_block_bitmap meta_block_map;
302 static ext2fs_block_bitmap scramble_block_map; /* Directory blocks to be scrambled */
303 static blk64_t meta_blocks_count;
305 struct process_block_struct {
311 * These subroutines short circuits ext2fs_get_blocks and
312 * ext2fs_check_directory; we use them since we already have the inode
313 * structure, so there's no point in letting the ext2fs library read
316 static ext2_ino_t stashed_ino = 0;
317 static struct ext2_inode *stashed_inode;
319 static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)),
325 if ((ino != stashed_ino) || !stashed_inode)
326 return EXT2_ET_CALLBACK_NOTHANDLED;
328 for (i=0; i < EXT2_N_BLOCKS; i++)
329 blocks[i] = stashed_inode->i_block[i];
333 static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)),
336 if ((ino != stashed_ino) || !stashed_inode)
337 return EXT2_ET_CALLBACK_NOTHANDLED;
339 if (!LINUX_S_ISDIR(stashed_inode->i_mode))
340 return EXT2_ET_NO_DIRECTORY;
344 static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
346 struct ext2_inode *inode)
348 if ((ino != stashed_ino) || !stashed_inode)
349 return EXT2_ET_CALLBACK_NOTHANDLED;
350 *inode = *stashed_inode;
354 static void use_inode_shortcuts(ext2_filsys fs, int use_shortcuts)
357 fs->get_blocks = meta_get_blocks;
358 fs->check_directory = meta_check_directory;
359 fs->read_inode = meta_read_inode;
363 fs->check_directory = 0;
368 static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
370 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
371 blk64_t ref_block EXT2FS_ATTR((unused)),
372 int ref_offset EXT2FS_ATTR((unused)),
373 void *priv_data EXT2FS_ATTR((unused)))
375 struct process_block_struct *p;
377 p = (struct process_block_struct *) priv_data;
379 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
381 if (scramble_block_map && p->is_dir && blockcnt >= 0)
382 ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr);
386 static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
388 e2_blkcnt_t blockcnt,
389 blk64_t ref_block EXT2FS_ATTR((unused)),
390 int ref_offset EXT2FS_ATTR((unused)),
391 void *priv_data EXT2FS_ATTR((unused)))
393 if (blockcnt < 0 || all_data) {
394 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
400 static void mark_table_blocks(ext2_filsys fs)
402 blk64_t first_block, b;
405 first_block = fs->super->s_first_data_block;
407 * Mark primary superblock
409 ext2fs_mark_block_bitmap2(meta_block_map, first_block);
413 * Mark the primary superblock descriptors
415 for (j = 0; j < fs->desc_blocks; j++) {
416 ext2fs_mark_block_bitmap2(meta_block_map,
417 ext2fs_descriptor_block_loc2(fs, first_block, j));
419 meta_blocks_count += fs->desc_blocks;
424 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) {
425 ext2fs_mark_block_bitmap2(meta_block_map, fs->super->s_mmp_block);
429 for (i = 0; i < fs->group_desc_count; i++) {
431 * Mark the blocks used for the inode table
433 if ((output_is_blk ||
434 !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) &&
435 ext2fs_inode_table_loc(fs, i)) {
436 unsigned int end = (unsigned) fs->inode_blocks_per_group;
437 /* skip unused blocks */
438 if (!output_is_blk && ext2fs_has_group_desc_csum(fs))
439 end -= (ext2fs_bg_itable_unused(fs, i) /
440 EXT2_INODES_PER_BLOCK(fs->super));
441 for (j = 0, b = ext2fs_inode_table_loc(fs, i);
444 ext2fs_mark_block_bitmap2(meta_block_map, b);
450 * Mark block used for the block bitmap
452 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
453 ext2fs_block_bitmap_loc(fs, i)) {
454 ext2fs_mark_block_bitmap2(meta_block_map,
455 ext2fs_block_bitmap_loc(fs, i));
460 * Mark block used for the inode bitmap
462 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
463 ext2fs_inode_bitmap_loc(fs, i)) {
464 ext2fs_mark_block_bitmap2(meta_block_map,
465 ext2fs_inode_bitmap_loc(fs, i));
472 * This function returns 1 if the specified block is all zeros
474 static int check_zero_block(char *buf, int blocksize)
477 int left = blocksize;
489 static int name_id[256];
491 #define EXT4_MAX_REC_LEN ((1<<16)-1)
493 static void scramble_dir_block(ext2_filsys fs, blk64_t blk, char *buf)
496 struct ext2_dir_entry_2 *dirent;
497 unsigned int rec_len;
500 end = buf + fs->blocksize;
501 for (p = buf; p < end-8; p += rec_len) {
502 dirent = (struct ext2_dir_entry_2 *) p;
503 rec_len = dirent->rec_len;
504 #ifdef WORDS_BIGENDIAN
505 rec_len = ext2fs_swab16(rec_len);
507 if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0)
508 rec_len = fs->blocksize;
510 rec_len = (rec_len & 65532) | ((rec_len & 3) << 16);
512 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len);
514 if (rec_len < 8 || (rec_len % 4) ||
516 printf(_("Corrupt directory block %llu: "
517 "bad rec_len (%d)\n"),
518 (unsigned long long) blk, rec_len);
520 (void) ext2fs_set_rec_len(fs, rec_len,
521 (struct ext2_dir_entry *) dirent);
522 #ifdef WORDS_BIGENDIAN
523 dirent->rec_len = ext2fs_swab16(dirent->rec_len);
527 if (dirent->name_len + 8U > rec_len) {
528 printf(_("Corrupt directory block %llu: "
529 "bad name_len (%d)\n"),
530 (unsigned long long) blk, dirent->name_len);
531 dirent->name_len = rec_len - 8;
535 len = rec_len - dirent->name_len - 8;
537 memset(cp+dirent->name_len, 0, len);
538 if (dirent->name_len==1 && cp[0] == '.')
540 if (dirent->name_len==2 && cp[0] == '.' && cp[1] == '.')
543 memset(cp, 'A', dirent->name_len);
544 len = dirent->name_len;
546 while ((len > 0) && (id > 0)) {
555 static char got_sigint;
557 static void sigint_handler(int unused EXT2FS_ATTR((unused)))
560 signal (SIGINT, SIG_DFL);
563 #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \
564 ((float) (b)))) + 0.5))
565 #define calc_rate(t, b, d) (((float)(t) / ((float)(1024 * 1024) / (b))) / (d))
567 static int print_progress(blk64_t num, blk64_t total)
569 return fprintf(stderr, _("%llu / %llu blocks (%d%%)"),
570 (unsigned long long) num,
571 (unsigned long long) total,
572 calc_percent(num, total));
575 static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags)
579 char *buf, *zero_buf;
582 blk64_t distance = 0;
583 blk64_t end = ext2fs_blocks_count(fs->super);
584 time_t last_update = 0;
585 time_t start_time = 0;
586 blk64_t total_written = 0;
589 retval = ext2fs_get_mem(fs->blocksize, &buf);
591 com_err(program_name, retval, "%s",
592 _("while allocating buffer"));
595 retval = ext2fs_get_memzero(fs->blocksize, &zero_buf);
597 com_err(program_name, retval, "%s",
598 _("while allocating buffer"));
602 fprintf(stderr, "%s", _("Copying "));
603 bscount = print_progress(total_written, meta_blocks_count);
605 last_update = time(NULL);
606 start_time = time(NULL);
608 /* when doing an in place move to the right, you can't start
609 at the beginning or you will overwrite data, so instead
610 divide the fs up into distance size chunks and write them
612 if (move_mode && dest_offset > source_offset) {
613 distance = (dest_offset - source_offset) / fs->blocksize;
614 if (distance < ext2fs_blocks_count(fs->super))
615 start = ext2fs_blocks_count(fs->super) - distance;
618 signal (SIGINT, sigint_handler);
621 seek_set(fd, (start * fs->blocksize) + dest_offset);
622 for (blk = start; blk < end; blk++) {
625 /* moving to the right */
626 if (distance >= ext2fs_blocks_count(fs->super)||
627 start == ext2fs_blocks_count(fs->super) -
629 kill(getpid(), SIGINT);
631 /* moving to the left */
632 if (blk < (source_offset - dest_offset) /
634 kill(getpid(), SIGINT);
638 fprintf(stderr, "%s",
639 _("Stopping now will destroy the filesystem, "
640 "interrupt again if you are sure\n"));
642 fprintf(stderr, "%s", _("Copying "));
643 bscount = print_progress(total_written,
650 if (show_progress && last_update != time(NULL)) {
652 last_update = time(NULL);
655 bscount = print_progress(total_written,
657 duration = time(NULL) - start_time;
658 if (duration > 5 && total_written) {
659 time_t est = (duration * meta_blocks_count /
660 total_written) - duration;
662 strftime(buff, 30, "%T", gmtime(&est));
665 _(" %s remaining at %.2f MB/s"),
666 buff, calc_rate(total_written,
672 if ((blk >= fs->super->s_first_data_block) &&
673 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
674 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
676 com_err(program_name, retval,
677 _("error reading block %llu"),
678 (unsigned long long) blk);
681 if (scramble_block_map &&
682 ext2fs_test_block_bitmap2(scramble_block_map, blk))
683 scramble_dir_block(fs, blk, buf);
684 if ((flags & E2IMAGE_CHECK_ZERO_FLAG) &&
685 check_zero_block(buf, fs->blocksize))
688 seek_relative(fd, sparse);
690 if (check_block(fd, buf, check_buf, fs->blocksize)) {
691 seek_relative(fd, fs->blocksize);
694 generic_write(fd, buf, fs->blocksize, blk);
699 generic_write(fd, zero_buf,
703 sparse += fs->blocksize;
704 if (sparse > 1024*1024) {
705 seek_relative(fd, 1024*1024);
710 if (distance && start) {
711 if (start < distance) {
717 if (end < distance) {
718 /* past overlap, do rest in one go */
726 signal (SIGINT, SIG_DFL);
728 time_t duration = time(NULL) - start_time;
731 strftime(buff, 30, "%T", gmtime(&duration));
732 fprintf(stderr, _("Copied %llu / %llu blocks (%d%%) in %s "),
733 (unsigned long long) total_written,
734 (unsigned long long) meta_blocks_count,
735 calc_percent(total_written, meta_blocks_count), buff);
737 fprintf(stderr, _("at %.2f MB/s"),
738 calc_rate(total_written, fs->blocksize, duration));
739 fputs(" \n", stderr);
741 #ifdef HAVE_FTRUNCATE64
745 offset = seek_set(fd,
746 fs->blocksize * ext2fs_blocks_count(fs->super) + dest_offset);
748 offset = seek_relative(fd, sparse);
750 if (ftruncate64(fd, offset) < 0) {
751 seek_relative(fd, -1);
752 generic_write(fd, zero_buf, 1, NO_BLK);
756 if (sparse && !distance) {
757 seek_relative(fd, sparse-1);
758 generic_write(fd, zero_buf, 1, NO_BLK);
761 ext2fs_free_mem(&zero_buf);
762 ext2fs_free_mem(&buf);
765 static void init_l1_table(struct ext2_qcow2_image *image)
770 ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table);
772 com_err(program_name, ret, "%s",
773 _("while allocating l1 table"));
777 image->l1_table = l1_table;
780 static void init_l2_cache(struct ext2_qcow2_image *image)
782 unsigned int count, i;
783 struct ext2_qcow2_l2_cache *cache;
784 struct ext2_qcow2_l2_table *table;
787 ret = ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache),
792 count = (image->l1_size > L2_CACHE_PREALLOC) ? L2_CACHE_PREALLOC :
795 cache->count = count;
797 cache->next_offset = image->l2_offset;
799 for (i = 0; i < count; i++) {
800 ret = ext2fs_get_arrayzero(1,
801 sizeof(struct ext2_qcow2_l2_table), &table);
805 ret = ext2fs_get_arrayzero(image->l2_size,
806 sizeof(__u64), &table->data);
810 table->next = cache->free_head;
811 cache->free_head = table;
814 image->l2_cache = cache;
818 com_err(program_name, ret, "%s", _("while allocating l2 cache"));
822 static void put_l2_cache(struct ext2_qcow2_image *image)
824 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
825 struct ext2_qcow2_l2_table *tmp, *table;
830 table = cache->free_head;
831 cache->free_head = NULL;
836 ext2fs_free_mem(&tmp->data);
837 ext2fs_free_mem(&tmp);
840 if (cache->free != cache->count) {
841 fprintf(stderr, "%s", _("Warning: There are still tables in "
842 "the cache while putting the cache, "
843 "data will be lost so the image may "
845 table = cache->used_head;
846 cache->used_head = NULL;
850 ext2fs_free_mem(&cache);
853 static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset)
855 struct ext2_qcow2_refcount *ref;
856 blk64_t table_clusters;
859 ref = &(img->refcount);
862 * One refcount block addresses 2048 clusters, one refcount table
863 * addresses cluster/sizeof(__u64) refcount blocks, and we need
864 * to address meta_blocks_count clusters + qcow2 metadata clusters
867 table_clusters = meta_blocks_count + (table_offset >>
869 table_clusters >>= (img->cluster_bits + 6 - 1);
870 table_clusters = (table_clusters == 0) ? 1 : table_clusters;
872 ref->refcount_table_offset = table_offset;
873 ref->refcount_table_clusters = table_clusters;
874 ref->refcount_table_index = 0;
875 ref->refcount_block_index = 0;
877 /* Allocate refcount table */
878 ret = ext2fs_get_arrayzero(ref->refcount_table_clusters,
879 img->cluster_size, &ref->refcount_table);
883 /* Allocate refcount block */
884 ret = ext2fs_get_arrayzero(1, img->cluster_size, &ref->refcount_block);
886 ext2fs_free_mem(&ref->refcount_table);
891 static errcode_t initialize_qcow2_image(int fd, ext2_filsys fs,
892 struct ext2_qcow2_image *image)
894 struct ext2_qcow2_hdr *header;
895 blk64_t total_size, offset;
896 int shift, l2_bits, header_size, l1_size, ret;
897 int cluster_bits = get_bits_from_size(fs->blocksize);
898 struct ext2_super_block *sb = fs->super;
900 /* Sbould never happen, but just in case... */
901 if (cluster_bits < 0)
902 return EXT2_FILSYS_CORRUPTED;
904 /* Allocate header */
905 ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header);
909 total_size = ext2fs_blocks_count(sb) << cluster_bits;
910 image->cluster_size = fs->blocksize;
911 image->l2_size = 1 << (cluster_bits - 3);
912 image->cluster_bits = cluster_bits;
915 header->magic = ext2fs_cpu_to_be32(QCOW_MAGIC);
916 header->version = ext2fs_cpu_to_be32(QCOW_VERSION);
917 header->size = ext2fs_cpu_to_be64(total_size);
918 header->cluster_bits = ext2fs_cpu_to_be32(cluster_bits);
920 header_size = (sizeof(struct ext2_qcow2_hdr) + 7) & ~7;
921 offset = align_offset(header_size, image->cluster_size);
923 header->l1_table_offset = ext2fs_cpu_to_be64(offset);
924 image->l1_offset = offset;
926 l2_bits = cluster_bits - 3;
927 shift = cluster_bits + l2_bits;
928 l1_size = ((total_size + (1LL << shift) - 1) >> shift);
929 header->l1_size = ext2fs_cpu_to_be32(l1_size);
930 image->l1_size = l1_size;
932 /* Make space for L1 table */
933 offset += align_offset(l1_size * sizeof(blk64_t), image->cluster_size);
935 /* Initialize refcounting */
936 ret = init_refcount(image, offset);
938 ext2fs_free_mem(&header);
941 header->refcount_table_offset = ext2fs_cpu_to_be64(offset);
942 header->refcount_table_clusters =
943 ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters);
944 offset += image->cluster_size;
945 offset += image->refcount.refcount_table_clusters <<
948 /* Make space for L2 tables */
949 image->l2_offset = offset;
950 offset += image->cluster_size;
952 /* Make space for first refcount block */
953 image->refcount.refcount_block_offset = offset;
956 /* Initialize l1 and l2 tables */
957 init_l1_table(image);
958 init_l2_cache(image);
963 static void free_qcow2_image(struct ext2_qcow2_image *img)
969 ext2fs_free_mem(&img->hdr);
972 ext2fs_free_mem(&img->l1_table);
974 if (img->refcount.refcount_table)
975 ext2fs_free_mem(&img->refcount.refcount_table);
976 if (img->refcount.refcount_block)
977 ext2fs_free_mem(&img->refcount.refcount_block);
981 ext2fs_free_mem(&img);
985 * Put table from used list (used_head) into free list (free_head).
986 * l2_table is used to return pointer to the next used table (used_head).
988 static void put_used_table(struct ext2_qcow2_image *img,
989 struct ext2_qcow2_l2_table **l2_table)
991 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
992 struct ext2_qcow2_l2_table *table;
994 table = cache->used_head;
995 cache->used_head = table->next;
999 cache->used_tail = NULL;
1001 /* Clean the table for case we will need to use it again */
1002 memset(table->data, 0, img->cluster_size);
1003 table->next = cache->free_head;
1004 cache->free_head = table;
1008 *l2_table = cache->used_head;
1011 static void flush_l2_cache(struct ext2_qcow2_image *image)
1015 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1016 struct ext2_qcow2_l2_table *table = cache->used_head;
1019 /* Store current position */
1020 offset = seek_relative(fd, 0);
1023 while (cache->free < cache->count) {
1024 if (seek != table->offset) {
1025 seek_set(fd, table->offset);
1026 seek = table->offset;
1029 generic_write(fd, (char *)table->data, image->cluster_size,
1031 put_used_table(image, &table);
1032 seek += image->cluster_size;
1035 /* Restore previous position */
1036 seek_set(fd, offset);
1040 * Get first free table (from free_head) and put it into tail of used list
1042 * l2_table is used to return pointer to moved table.
1043 * Returns 1 if the cache is full, 0 otherwise.
1045 static void get_free_table(struct ext2_qcow2_image *image,
1046 struct ext2_qcow2_l2_table **l2_table)
1048 struct ext2_qcow2_l2_table *table;
1049 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1051 if (0 == cache->free)
1052 flush_l2_cache(image);
1054 table = cache->free_head;
1056 cache->free_head = table->next;
1058 if (cache->used_tail)
1059 cache->used_tail->next = table;
1061 /* First item in the used list */
1062 cache->used_head = table;
1064 cache->used_tail = table;
1070 static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk,
1071 blk64_t data, blk64_t next)
1073 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
1074 struct ext2_qcow2_l2_table *table = cache->used_tail;
1075 blk64_t l1_index = blk / img->l2_size;
1076 blk64_t l2_index = blk & (img->l2_size - 1);
1080 * Need to create new table if it does not exist,
1083 if (!table || (table->l1_index != l1_index)) {
1084 get_free_table(img, &table);
1085 table->l1_index = l1_index;
1086 table->offset = cache->next_offset;
1087 cache->next_offset = next;
1088 img->l1_table[l1_index] =
1089 ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED);
1093 table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED);
1097 static int update_refcount(int fd, struct ext2_qcow2_image *img,
1098 blk64_t offset, blk64_t rfblk_pos)
1100 struct ext2_qcow2_refcount *ref;
1104 ref = &(img->refcount);
1105 table_index = offset >> (2 * img->cluster_bits - 1);
1108 * Need to create new refcount block when the offset addresses
1109 * another item in the refcount table
1111 if (table_index != ref->refcount_table_index) {
1113 seek_set(fd, ref->refcount_block_offset);
1115 generic_write(fd, (char *)ref->refcount_block,
1116 img->cluster_size, NO_BLK);
1117 memset(ref->refcount_block, 0, img->cluster_size);
1119 ref->refcount_table[ref->refcount_table_index] =
1120 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1121 ref->refcount_block_offset = rfblk_pos;
1122 ref->refcount_block_index = 0;
1123 ref->refcount_table_index = table_index;
1128 * We are relying on the fact that we are creating the qcow2
1129 * image sequentially, hence we will always allocate refcount
1130 * block items sequentially.
1132 ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1);
1133 ref->refcount_block_index++;
1137 static int sync_refcount(int fd, struct ext2_qcow2_image *img)
1139 struct ext2_qcow2_refcount *ref;
1141 ref = &(img->refcount);
1143 ref->refcount_table[ref->refcount_table_index] =
1144 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1145 seek_set(fd, ref->refcount_table_offset);
1146 generic_write(fd, (char *)ref->refcount_table,
1147 ref->refcount_table_clusters << img->cluster_bits, NO_BLK);
1149 seek_set(fd, ref->refcount_block_offset);
1150 generic_write(fd, (char *)ref->refcount_block, img->cluster_size,
1155 static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
1158 blk64_t blk, offset, size, end;
1160 struct ext2_qcow2_image *img;
1161 unsigned int header_size;
1163 /* allocate struct ext2_qcow2_image */
1164 retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img);
1166 com_err(program_name, retval, "%s",
1167 _("while allocating ext2_qcow2_image"));
1171 retval = initialize_qcow2_image(fd, fs, img);
1173 com_err(program_name, retval, "%s",
1174 _("while initializing ext2_qcow2_image"));
1177 header_size = align_offset(sizeof(struct ext2_qcow2_hdr),
1179 write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size);
1181 /* Refcount all qcow2 related metadata up to refcount_block_offset */
1182 end = img->refcount.refcount_block_offset;
1184 blk = end + img->cluster_size;
1185 for (offset = 0; offset <= end; offset += img->cluster_size) {
1186 if (update_refcount(fd, img, offset, blk)) {
1187 blk += img->cluster_size;
1189 * If we create new refcount block, we need to refcount
1192 end += img->cluster_size;
1195 seek_set(fd, offset);
1197 retval = ext2fs_get_mem(fs->blocksize, &buf);
1199 com_err(program_name, retval, "%s",
1200 _("while allocating buffer"));
1203 /* Write qcow2 data blocks */
1204 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) {
1205 if ((blk >= fs->super->s_first_data_block) &&
1206 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
1207 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
1209 com_err(program_name, retval,
1210 _("error reading block %llu"),
1211 (unsigned long long) blk);
1214 if (scramble_block_map &&
1215 ext2fs_test_block_bitmap2(scramble_block_map, blk))
1216 scramble_dir_block(fs, blk, buf);
1217 if (check_zero_block(buf, fs->blocksize))
1220 if (update_refcount(fd, img, offset, offset)) {
1221 /* Make space for another refcount block */
1222 offset += img->cluster_size;
1223 seek_set(fd, offset);
1225 * We have created the new refcount block, this
1226 * means that we need to refcount it as well.
1227 * So the previous update_refcount refcounted
1228 * the block itself and now we are going to
1229 * create refcount for data. New refcount
1230 * block should not be created!
1232 if (update_refcount(fd, img, offset, offset)) {
1233 fprintf(stderr, "%s",
1234 _("Programming error: multiple "
1235 "sequential refcount blocks "
1241 generic_write(fd, buf, fs->blocksize, blk);
1243 if (add_l2_item(img, blk, offset,
1244 offset + img->cluster_size)) {
1245 offset += img->cluster_size;
1246 if (update_refcount(fd, img, offset,
1247 offset + img->cluster_size)) {
1248 offset += img->cluster_size;
1249 if (update_refcount(fd, img, offset,
1251 fprintf(stderr, "%s",
1252 _("Programming error: multiple sequential refcount "
1253 "blocks created!\n"));
1257 offset += img->cluster_size;
1258 seek_set(fd, offset);
1262 offset += img->cluster_size;
1265 update_refcount(fd, img, offset, offset);
1266 flush_l2_cache(img);
1267 sync_refcount(fd, img);
1270 seek_set(fd, img->l1_offset);
1271 size = img->l1_size * sizeof(__u64);
1272 generic_write(fd, (char *)img->l1_table, size, NO_BLK);
1274 ext2fs_free_mem(&buf);
1275 free_qcow2_image(img);
1278 static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags,
1281 struct process_block_struct pb;
1282 struct ext2_inode inode;
1283 ext2_inode_scan scan;
1288 meta_blocks_count = 0;
1289 retval = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
1292 com_err(program_name, retval, "%s",
1293 _("while allocating block bitmap"));
1297 if (flags & E2IMAGE_SCRAMBLE_FLAG) {
1298 retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
1299 &scramble_block_map);
1301 com_err(program_name, retval, "%s",
1302 _("while allocating scramble block bitmap"));
1310 ext2fs_mark_block_bitmap2(meta_block_map, superblock);
1311 meta_blocks_count++;
1314 * Mark the backup superblock descriptors
1316 for (j = 0; j < fs->desc_blocks; j++) {
1317 ext2fs_mark_block_bitmap2(meta_block_map,
1318 ext2fs_descriptor_block_loc2(fs, superblock, j));
1320 meta_blocks_count += fs->desc_blocks;
1323 mark_table_blocks(fs);
1325 fprintf(stderr, "%s", _("Scanning inodes...\n"));
1327 retval = ext2fs_open_inode_scan(fs, 0, &scan);
1329 com_err(program_name, retval, "%s",
1330 _("while opening inode scan"));
1334 retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
1336 com_err(program_name, 0, "%s",
1337 _("Can't allocate block buffer"));
1341 use_inode_shortcuts(fs, 1);
1342 stashed_inode = &inode;
1344 retval = ext2fs_get_next_inode(scan, &ino, &inode);
1345 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
1348 com_err(program_name, retval, "%s",
1349 _("while getting next inode"));
1354 if (!inode.i_links_count)
1356 if (ext2fs_file_acl_block(fs, &inode)) {
1357 ext2fs_mark_block_bitmap2(meta_block_map,
1358 ext2fs_file_acl_block(fs, &inode));
1359 meta_blocks_count++;
1361 if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
1366 pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
1367 if (LINUX_S_ISDIR(inode.i_mode) ||
1368 (LINUX_S_ISLNK(inode.i_mode) &&
1369 ext2fs_inode_has_valid_blocks2(fs, &inode)) ||
1370 ino == fs->super->s_journal_inum) {
1371 retval = ext2fs_block_iterate3(fs, ino,
1372 BLOCK_FLAG_READ_ONLY, block_buf,
1373 process_dir_block, &pb);
1375 com_err(program_name, retval,
1376 _("while iterating over inode %u"),
1381 if ((inode.i_flags & EXT4_EXTENTS_FL) ||
1382 inode.i_block[EXT2_IND_BLOCK] ||
1383 inode.i_block[EXT2_DIND_BLOCK] ||
1384 inode.i_block[EXT2_TIND_BLOCK] || all_data) {
1385 retval = ext2fs_block_iterate3(fs,
1386 ino, BLOCK_FLAG_READ_ONLY, block_buf,
1387 process_file_block, &pb);
1389 com_err(program_name, retval,
1390 _("while iterating over inode %u"), ino);
1396 use_inode_shortcuts(fs, 0);
1398 if (type & E2IMAGE_QCOW2)
1399 output_qcow2_meta_data_blocks(fs, fd);
1401 output_meta_data_blocks(fs, fd, flags);
1403 ext2fs_free_mem(&block_buf);
1404 ext2fs_close_inode_scan(scan);
1405 ext2fs_free_block_bitmap(meta_block_map);
1406 if (type & E2IMAGE_SCRAMBLE_FLAG)
1407 ext2fs_free_block_bitmap(scramble_block_map);
1410 static void install_image(char *device, char *image_fn, int type)
1414 int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS |
1415 EXT2_FLAG_IGNORE_CSUM_ERRORS;
1421 com_err(program_name, 0, "%s",
1422 _("Raw and qcow2 images cannot be installed"));
1426 #ifdef CONFIG_TESTIO_DEBUG
1427 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1428 io_ptr = test_io_manager;
1429 test_io_backing_manager = unix_io_manager;
1432 io_ptr = unix_io_manager;
1434 retval = ext2fs_open (image_fn, open_flag, 0, 0,
1437 com_err(program_name, retval, _("while trying to open %s"),
1442 retval = ext2fs_read_bitmaps (fs);
1444 com_err(program_name, retval, "%s", _("error reading bitmaps"));
1448 fd = ext2fs_open_file(image_fn, O_RDONLY, 0);
1454 retval = io_ptr->open(device, IO_FLAG_RW, &io);
1456 com_err(device, 0, "%s", _("while opening device file"));
1460 ext2fs_rewrite_to_io(fs, io);
1462 seek_set(fd, ext2fs_le32_to_cpu(fs->image_header->offset_inode));
1464 retval = ext2fs_image_inode_read(fs, fd, 0);
1466 com_err(image_fn, 0, "%s",
1467 _("while restoring the image table"));
1472 ext2fs_close_free(&fs);
1475 static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name)
1478 *fd = ext2fs_open_file(name, O_RDONLY, 0600);
1482 return qcow2_read_header(*fd);
1485 int main (int argc, char ** argv)
1490 char *image_fn, offset_opt[64];
1491 struct ext2_qcow2_hdr *header = NULL;
1492 int open_flag = EXT2_FLAG_64BITS | EXT2_FLAG_THREADS |
1493 EXT2_FLAG_IGNORE_CSUM_ERRORS;
1496 int mount_flags = 0;
1500 int ignore_rw_mount = 0;
1503 blk64_t superblock = 0;
1507 setlocale(LC_MESSAGES, "");
1508 setlocale(LC_CTYPE, "");
1509 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
1510 textdomain(NLS_CAT_NAME);
1511 set_com_err_gettext(gettext);
1513 fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION,
1516 program_name = *argv;
1517 add_error_table(&et_ext2_error_table);
1518 while ((c = getopt(argc, argv, "b:B:nrsIQafo:O:pc")) != EOF)
1521 superblock = strtoull(optarg, NULL, 0);
1524 blocksize = strtoul(optarg, NULL, 0);
1527 flags |= E2IMAGE_INSTALL_FLAG;
1532 img_type |= E2IMAGE_QCOW2;
1537 img_type |= E2IMAGE_RAW;
1540 flags |= E2IMAGE_SCRAMBLE_FLAG;
1546 ignore_rw_mount = 1;
1552 source_offset = strtoull(optarg, NULL, 0);
1555 dest_offset = strtoull(optarg, NULL, 0);
1566 if (optind == argc - 1 &&
1567 (source_offset || dest_offset))
1569 else if (optind != argc - 2 )
1572 if (all_data && !img_type) {
1573 com_err(program_name, 0, "%s", _("-a option can only be used "
1574 "with raw or QCOW2 images."));
1577 if (superblock && !img_type) {
1578 com_err(program_name, 0, "%s", _("-b option can only be used "
1579 "with raw or QCOW2 images."));
1582 if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) {
1583 com_err(program_name, 0, "%s",
1584 _("Offsets are only allowed with raw images."));
1587 if (move_mode && img_type != E2IMAGE_RAW) {
1588 com_err(program_name, 0, "%s",
1589 _("Move mode is only allowed with raw images."));
1592 if (move_mode && !all_data) {
1593 com_err(program_name, 0, "%s",
1594 _("Move mode requires all data mode."));
1597 device_name = argv[optind];
1599 image_fn = device_name;
1600 else image_fn = argv[optind+1];
1602 retval = ext2fs_check_if_mounted(device_name, &mount_flags);
1604 com_err(program_name, retval, "%s", _("checking if mounted"));
1608 if (img_type && !ignore_rw_mount &&
1609 (mount_flags & EXT2_MF_MOUNTED) &&
1610 !(mount_flags & EXT2_MF_READONLY)) {
1611 fprintf(stderr, "%s", _("\nRunning e2image on a R/W mounted "
1612 "filesystem can result in an\n"
1613 "inconsistent image which will not be useful "
1614 "for debugging purposes.\n"
1615 "Use -f option if you really want to do that.\n"));
1619 if (flags & E2IMAGE_INSTALL_FLAG) {
1620 install_image(device_name, image_fn, img_type);
1624 if (img_type & E2IMAGE_RAW) {
1625 header = check_qcow2_image(&qcow2_fd, device_name);
1627 flags |= E2IMAGE_IS_QCOW2_FLAG;
1631 sprintf(offset_opt, "offset=%llu", (unsigned long long) source_offset);
1632 retval = ext2fs_open2(device_name, offset_opt, open_flag,
1633 superblock, blocksize, unix_io_manager, &fs);
1635 com_err (program_name, retval, _("while trying to open %s"),
1637 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout);
1638 if (retval == EXT2_ET_BAD_MAGIC)
1639 check_plausibility(device_name, CHECK_FS_EXIST, NULL);
1644 if (strcmp(image_fn, "-") == 0)
1647 int o_flags = O_CREAT|O_RDWR;
1649 if (img_type != E2IMAGE_RAW)
1651 if (access(image_fn, F_OK) != 0)
1652 flags |= E2IMAGE_CHECK_ZERO_FLAG;
1653 fd = ext2fs_open_file(image_fn, o_flags, 0600);
1655 com_err(program_name, errno,
1656 _("while trying to open %s"), image_fn);
1661 seek_set(fd, dest_offset);
1663 if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) {
1664 com_err(program_name, 0, "%s",
1665 _("QCOW2 image can not be written to the stdout!\n"));
1669 if (fstat(fd, &st)) {
1670 com_err(program_name, 0, "%s",
1671 _("Can not stat output\n"));
1674 if (ext2fsP_is_disk_device(st.st_mode))
1677 if (flags & E2IMAGE_IS_QCOW2_FLAG) {
1678 ret = qcow2_write_raw_image(qcow2_fd, fd, header);
1680 if (ret == -QCOW_COMPRESSED)
1681 fprintf(stderr, _("Image (%s) is compressed\n"),
1683 else if (ret == -QCOW_ENCRYPTED)
1684 fprintf(stderr, _("Image (%s) is encrypted\n"),
1686 else if (ret == -QCOW_CORRUPTED)
1687 fprintf(stderr, _("Image (%s) is corrupted\n"),
1690 com_err(program_name, ret,
1691 _("while trying to convert qcow2 image"
1692 " (%s) into raw image (%s)"),
1693 image_fn, device_name);
1700 if (img_type != E2IMAGE_RAW) {
1701 fprintf(stderr, "%s", _("The -c option only supported "
1706 fprintf(stderr, "%s", _("The -c option not supported "
1707 "when writing to stdout\n"));
1710 retval = ext2fs_get_mem(fs->blocksize, &check_buf);
1712 com_err(program_name, retval, "%s",
1713 _("while allocating check_buf"));
1717 if (show_progress && (img_type != E2IMAGE_RAW)) {
1718 fprintf(stderr, "%s",
1719 _("The -p option only supported in raw mode\n"));
1723 write_raw_image_file(fs, fd, img_type, flags, superblock);
1725 write_image_file(fs, fd);
1727 ext2fs_close_free(&fs);
1729 printf(_("%d blocks already contained the data to be copied\n"),
1737 remove_error_table(&et_ext2_error_table);