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 ] device image-file\n"),
109 fprintf(stderr, _(" %s -I device image-file\n"), program_name);
110 fprintf(stderr, _(" %s -ra [ -cfnp ] [ -o src_offset ] "
111 "[ -O dest_offset ] src_fs [ dest_fs ]\n"),
116 static ext2_loff_t seek_relative(int fd, int offset)
118 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_CUR);
120 perror("seek_relative");
126 static ext2_loff_t seek_set(int fd, ext2_loff_t offset)
128 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_SET);
137 * Returns true if the block we are about to write is identical to
138 * what is already on the disk.
140 static int check_block(int fd, void *buf, void *cbuf, int blocksize)
143 int count = blocksize, ret;
149 ret = read(fd, cp, count);
151 perror("check_block");
157 ret = memcmp(buf, cbuf, blocksize);
158 seek_relative(fd, -blocksize);
159 return (ret == 0) ? 1 : 0;
162 static void generic_write(int fd, void *buf, int blocksize, blk64_t block)
164 int count, free_buf = 0;
172 err = ext2fs_get_arrayzero(1, blocksize, &buf);
174 com_err(program_name, err, "%s",
175 _("while allocating buffer"));
180 printf(_("Writing block %llu\n"), (unsigned long long) block);
182 seek_relative(fd, blocksize);
183 goto free_and_return;
185 count = write(fd, buf, blocksize);
186 if (count != blocksize) {
193 com_err(program_name, err,
194 _("error writing block %llu"), block);
196 com_err(program_name, err, "%s",
197 _("error in generic_write()"));
203 ext2fs_free_mem(&buf);
206 static void write_header(int fd, void *hdr, int hdr_size, int wrt_size)
212 if (hdr_size > wrt_size) {
213 fprintf(stderr, "%s",
214 _("Error: header size is bigger than wrt_size\n"));
217 ret = ext2fs_get_mem(wrt_size, &header_buf);
219 fputs(_("Couldn't allocate header buffer\n"), stderr);
224 memset(header_buf, 0, wrt_size);
227 memcpy(header_buf, hdr, hdr_size);
229 generic_write(fd, header_buf, wrt_size, NO_BLK);
231 ext2fs_free_mem(&header_buf);
234 static void write_image_file(ext2_filsys fs, int fd)
236 struct ext2_image_hdr hdr;
240 write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize);
241 memset(&hdr, 0, sizeof(struct ext2_image_hdr));
243 hdr.offset_super = ext2fs_cpu_to_le32(seek_relative(fd, 0));
244 retval = ext2fs_image_super_write(fs, fd, 0);
246 com_err(program_name, retval, "%s",
247 _("while writing superblock"));
251 hdr.offset_inode = ext2fs_cpu_to_le32(seek_relative(fd, 0));
252 retval = ext2fs_image_inode_write(fs, fd,
253 (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0);
255 com_err(program_name, retval, "%s",
256 _("while writing inode table"));
260 hdr.offset_blockmap = ext2fs_cpu_to_le32(seek_relative(fd, 0));
261 retval = ext2fs_image_bitmap_write(fs, fd, 0);
263 com_err(program_name, retval, "%s",
264 _("while writing block bitmap"));
268 hdr.offset_inodemap = ext2fs_cpu_to_le32(seek_relative(fd, 0));
269 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP);
271 com_err(program_name, retval, "%s",
272 _("while writing inode bitmap"));
276 hdr.magic_number = ext2fs_cpu_to_le32(EXT2_ET_MAGIC_E2IMAGE);
277 strcpy(hdr.magic_descriptor, "Ext2 Image 1.0");
278 gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname));
279 strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1);
280 hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0;
281 hdr.fs_blocksize = ext2fs_cpu_to_le32(fs->blocksize);
283 if (stat(device_name, &st) == 0)
284 hdr.fs_device = ext2fs_cpu_to_le32(st.st_rdev);
286 if (fstat(fd, &st) == 0) {
287 hdr.image_device = ext2fs_cpu_to_le32(st.st_dev);
288 hdr.image_inode = ext2fs_cpu_to_le32(st.st_ino);
290 memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid));
292 hdr.image_time = ext2fs_cpu_to_le32(time(0));
293 write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize);
297 * These set of functions are used to write a RAW image file.
299 static ext2fs_block_bitmap meta_block_map;
300 static ext2fs_block_bitmap scramble_block_map; /* Directory blocks to be scrambled */
301 static blk64_t meta_blocks_count;
303 struct process_block_struct {
309 * These subroutines short circuits ext2fs_get_blocks and
310 * ext2fs_check_directory; we use them since we already have the inode
311 * structure, so there's no point in letting the ext2fs library read
314 static ino_t stashed_ino = 0;
315 static struct ext2_inode *stashed_inode;
317 static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)),
323 if ((ino != stashed_ino) || !stashed_inode)
324 return EXT2_ET_CALLBACK_NOTHANDLED;
326 for (i=0; i < EXT2_N_BLOCKS; i++)
327 blocks[i] = stashed_inode->i_block[i];
331 static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)),
334 if ((ino != stashed_ino) || !stashed_inode)
335 return EXT2_ET_CALLBACK_NOTHANDLED;
337 if (!LINUX_S_ISDIR(stashed_inode->i_mode))
338 return EXT2_ET_NO_DIRECTORY;
342 static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
344 struct ext2_inode *inode)
346 if ((ino != stashed_ino) || !stashed_inode)
347 return EXT2_ET_CALLBACK_NOTHANDLED;
348 *inode = *stashed_inode;
352 static void use_inode_shortcuts(ext2_filsys fs, int use_shortcuts)
355 fs->get_blocks = meta_get_blocks;
356 fs->check_directory = meta_check_directory;
357 fs->read_inode = meta_read_inode;
361 fs->check_directory = 0;
366 static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
368 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
369 blk64_t ref_block EXT2FS_ATTR((unused)),
370 int ref_offset EXT2FS_ATTR((unused)),
371 void *priv_data EXT2FS_ATTR((unused)))
373 struct process_block_struct *p;
375 p = (struct process_block_struct *) priv_data;
377 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
379 if (scramble_block_map && p->is_dir && blockcnt >= 0)
380 ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr);
384 static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
386 e2_blkcnt_t blockcnt,
387 blk64_t ref_block EXT2FS_ATTR((unused)),
388 int ref_offset EXT2FS_ATTR((unused)),
389 void *priv_data EXT2FS_ATTR((unused)))
391 if (blockcnt < 0 || all_data) {
392 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
398 static void mark_table_blocks(ext2_filsys fs)
400 blk64_t first_block, b;
403 first_block = fs->super->s_first_data_block;
405 * Mark primary superblock
407 ext2fs_mark_block_bitmap2(meta_block_map, first_block);
411 * Mark the primary superblock descriptors
413 for (j = 0; j < fs->desc_blocks; j++) {
414 ext2fs_mark_block_bitmap2(meta_block_map,
415 ext2fs_descriptor_block_loc2(fs, first_block, j));
417 meta_blocks_count += fs->desc_blocks;
419 for (i = 0; i < fs->group_desc_count; i++) {
421 * Mark the blocks used for the inode table
423 if ((output_is_blk ||
424 !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) &&
425 ext2fs_inode_table_loc(fs, i)) {
426 unsigned int end = (unsigned) fs->inode_blocks_per_group;
427 /* skip unused blocks */
428 if (!output_is_blk && ext2fs_has_group_desc_csum(fs))
429 end -= (ext2fs_bg_itable_unused(fs, i) /
430 EXT2_INODES_PER_BLOCK(fs->super));
431 for (j = 0, b = ext2fs_inode_table_loc(fs, i);
434 ext2fs_mark_block_bitmap2(meta_block_map, b);
440 * Mark block used for the block bitmap
442 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
443 ext2fs_block_bitmap_loc(fs, i)) {
444 ext2fs_mark_block_bitmap2(meta_block_map,
445 ext2fs_block_bitmap_loc(fs, i));
450 * Mark block used for the inode bitmap
452 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
453 ext2fs_inode_bitmap_loc(fs, i)) {
454 ext2fs_mark_block_bitmap2(meta_block_map,
455 ext2fs_inode_bitmap_loc(fs, i));
462 * This function returns 1 if the specified block is all zeros
464 static int check_zero_block(char *buf, int blocksize)
467 int left = blocksize;
479 static int name_id[256];
481 #define EXT4_MAX_REC_LEN ((1<<16)-1)
483 static void scramble_dir_block(ext2_filsys fs, blk64_t blk, char *buf)
486 struct ext2_dir_entry_2 *dirent;
487 unsigned int rec_len;
490 end = buf + fs->blocksize;
491 for (p = buf; p < end-8; p += rec_len) {
492 dirent = (struct ext2_dir_entry_2 *) p;
493 rec_len = dirent->rec_len;
494 #ifdef WORDS_BIGENDIAN
495 rec_len = ext2fs_swab16(rec_len);
497 if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0)
498 rec_len = fs->blocksize;
500 rec_len = (rec_len & 65532) | ((rec_len & 3) << 16);
502 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len);
504 if (rec_len < 8 || (rec_len % 4) ||
506 printf(_("Corrupt directory block %llu: "
507 "bad rec_len (%d)\n"),
508 (unsigned long long) blk, rec_len);
510 (void) ext2fs_set_rec_len(fs, rec_len,
511 (struct ext2_dir_entry *) dirent);
512 #ifdef WORDS_BIGENDIAN
513 dirent->rec_len = ext2fs_swab16(dirent->rec_len);
517 if (dirent->name_len + 8U > rec_len) {
518 printf(_("Corrupt directory block %llu: "
519 "bad name_len (%d)\n"),
520 (unsigned long long) blk, dirent->name_len);
521 dirent->name_len = rec_len - 8;
525 len = rec_len - dirent->name_len - 8;
527 memset(cp+dirent->name_len, 0, len);
528 if (dirent->name_len==1 && cp[0] == '.')
530 if (dirent->name_len==2 && cp[0] == '.' && cp[1] == '.')
533 memset(cp, 'A', dirent->name_len);
534 len = dirent->name_len;
536 while ((len > 0) && (id > 0)) {
545 static char got_sigint;
547 static void sigint_handler(int unused EXT2FS_ATTR((unused)))
550 signal (SIGINT, SIG_DFL);
553 #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \
554 ((float) (b)))) + 0.5))
555 #define calc_rate(t, b, d) (((float)(t) / ((float)(1024 * 1024) / (b))) / (d))
557 static int print_progress(blk64_t num, blk64_t total)
559 return fprintf(stderr, _("%llu / %llu blocks (%d%%)"), num, total,
560 calc_percent(num, total));
563 static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags)
567 char *buf, *zero_buf;
570 blk64_t distance = 0;
571 blk64_t end = ext2fs_blocks_count(fs->super);
572 time_t last_update = 0;
573 time_t start_time = 0;
574 blk64_t total_written = 0;
577 retval = ext2fs_get_mem(fs->blocksize, &buf);
579 com_err(program_name, retval, "%s",
580 _("while allocating buffer"));
583 retval = ext2fs_get_memzero(fs->blocksize, &zero_buf);
585 com_err(program_name, retval, "%s",
586 _("while allocating buffer"));
590 fprintf(stderr, "%s", _("Copying "));
591 bscount = print_progress(total_written, meta_blocks_count);
593 last_update = time(NULL);
594 start_time = time(NULL);
596 /* when doing an in place move to the right, you can't start
597 at the beginning or you will overwrite data, so instead
598 divide the fs up into distance size chunks and write them
600 if (move_mode && dest_offset > source_offset) {
601 distance = (dest_offset - source_offset) / fs->blocksize;
602 if (distance < ext2fs_blocks_count(fs->super))
603 start = ext2fs_blocks_count(fs->super) - distance;
606 signal (SIGINT, sigint_handler);
609 seek_set(fd, (start * fs->blocksize) + dest_offset);
610 for (blk = start; blk < end; blk++) {
613 /* moving to the right */
614 if (distance >= ext2fs_blocks_count(fs->super)||
615 start == ext2fs_blocks_count(fs->super) -
617 kill(getpid(), SIGINT);
619 /* moving to the left */
620 if (blk < (source_offset - dest_offset) /
622 kill(getpid(), SIGINT);
626 fprintf(stderr, "%s",
627 _("Stopping now will destroy the filesystem, "
628 "interrupt again if you are sure\n"));
630 fprintf(stderr, "%s", _("Copying "));
631 bscount = print_progress(total_written,
638 if (show_progress && last_update != time(NULL)) {
640 last_update = time(NULL);
643 bscount = print_progress(total_written,
645 duration = time(NULL) - start_time;
646 if (duration > 5 && total_written) {
647 time_t est = (duration * meta_blocks_count /
648 total_written) - duration;
650 strftime(buff, 30, "%T", gmtime(&est));
653 _(" %s remaining at %.2f MB/s"),
654 buff, calc_rate(total_written,
660 if ((blk >= fs->super->s_first_data_block) &&
661 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
662 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
664 com_err(program_name, retval,
665 _("error reading block %llu"), blk);
668 if (scramble_block_map &&
669 ext2fs_test_block_bitmap2(scramble_block_map, blk))
670 scramble_dir_block(fs, blk, buf);
671 if ((flags & E2IMAGE_CHECK_ZERO_FLAG) &&
672 check_zero_block(buf, fs->blocksize))
675 seek_relative(fd, sparse);
677 if (check_block(fd, buf, check_buf, fs->blocksize)) {
678 seek_relative(fd, fs->blocksize);
681 generic_write(fd, buf, fs->blocksize, blk);
686 generic_write(fd, zero_buf,
690 sparse += fs->blocksize;
691 if (sparse > 1024*1024) {
692 seek_relative(fd, 1024*1024);
697 if (distance && start) {
698 if (start < distance) {
704 if (end < distance) {
705 /* past overlap, do rest in one go */
713 signal (SIGINT, SIG_DFL);
715 time_t duration = time(NULL) - start_time;
718 strftime(buff, 30, "%T", gmtime(&duration));
719 fprintf(stderr, _("Copied %llu / %llu blocks (%d%%) in %s "),
720 total_written, meta_blocks_count,
721 calc_percent(total_written, meta_blocks_count), buff);
723 fprintf(stderr, _("at %.2f MB/s"),
724 calc_rate(total_written, fs->blocksize, duration));
725 fputs(" \n", stderr);
727 #ifdef HAVE_FTRUNCATE64
731 offset = seek_set(fd,
732 fs->blocksize * ext2fs_blocks_count(fs->super) + dest_offset);
734 offset = seek_relative(fd, sparse);
736 if (ftruncate64(fd, offset) < 0) {
737 seek_relative(fd, -1);
738 generic_write(fd, zero_buf, 1, NO_BLK);
742 if (sparse && !distance) {
743 seek_relative(fd, sparse-1);
744 generic_write(fd, zero_buf, 1, NO_BLK);
747 ext2fs_free_mem(&zero_buf);
748 ext2fs_free_mem(&buf);
751 static void init_l1_table(struct ext2_qcow2_image *image)
756 ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table);
758 com_err(program_name, ret, "%s",
759 _("while allocating l1 table"));
763 image->l1_table = l1_table;
766 static void init_l2_cache(struct ext2_qcow2_image *image)
768 unsigned int count, i;
769 struct ext2_qcow2_l2_cache *cache;
770 struct ext2_qcow2_l2_table *table;
773 ret = ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache),
778 count = (image->l1_size > L2_CACHE_PREALLOC) ? L2_CACHE_PREALLOC :
781 cache->count = count;
783 cache->next_offset = image->l2_offset;
785 for (i = 0; i < count; i++) {
786 ret = ext2fs_get_arrayzero(1,
787 sizeof(struct ext2_qcow2_l2_table), &table);
791 ret = ext2fs_get_arrayzero(image->l2_size,
792 sizeof(__u64), &table->data);
796 table->next = cache->free_head;
797 cache->free_head = table;
800 image->l2_cache = cache;
804 com_err(program_name, ret, "%s", _("while allocating l2 cache"));
808 static void put_l2_cache(struct ext2_qcow2_image *image)
810 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
811 struct ext2_qcow2_l2_table *tmp, *table;
816 table = cache->free_head;
817 cache->free_head = NULL;
822 ext2fs_free_mem(&tmp->data);
823 ext2fs_free_mem(&tmp);
826 if (cache->free != cache->count) {
827 fprintf(stderr, "%s", _("Warning: There are still tables in "
828 "the cache while putting the cache, "
829 "data will be lost so the image may "
831 table = cache->used_head;
832 cache->used_head = NULL;
836 ext2fs_free_mem(&cache);
839 static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset)
841 struct ext2_qcow2_refcount *ref;
842 blk64_t table_clusters;
845 ref = &(img->refcount);
848 * One refcount block addresses 2048 clusters, one refcount table
849 * addresses cluster/sizeof(__u64) refcount blocks, and we need
850 * to address meta_blocks_count clusters + qcow2 metadata clusters
853 table_clusters = meta_blocks_count + (table_offset >>
855 table_clusters >>= (img->cluster_bits + 6 - 1);
856 table_clusters = (table_clusters == 0) ? 1 : table_clusters;
858 ref->refcount_table_offset = table_offset;
859 ref->refcount_table_clusters = table_clusters;
860 ref->refcount_table_index = 0;
861 ref->refcount_block_index = 0;
863 /* Allocate refcount table */
864 ret = ext2fs_get_arrayzero(ref->refcount_table_clusters,
865 img->cluster_size, &ref->refcount_table);
869 /* Allocate refcount block */
870 ret = ext2fs_get_arrayzero(1, img->cluster_size, &ref->refcount_block);
872 ext2fs_free_mem(&ref->refcount_table);
877 static errcode_t initialize_qcow2_image(int fd, ext2_filsys fs,
878 struct ext2_qcow2_image *image)
880 struct ext2_qcow2_hdr *header;
881 blk64_t total_size, offset;
882 int shift, l2_bits, header_size, l1_size, ret;
883 int cluster_bits = get_bits_from_size(fs->blocksize);
884 struct ext2_super_block *sb = fs->super;
886 if (fs->blocksize < 1024)
887 return EINVAL; /* Can never happen, but just in case... */
889 /* Allocate header */
890 ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header);
894 total_size = ext2fs_blocks_count(sb) << cluster_bits;
895 image->cluster_size = fs->blocksize;
896 image->l2_size = 1 << (cluster_bits - 3);
897 image->cluster_bits = cluster_bits;
900 header->magic = ext2fs_cpu_to_be32(QCOW_MAGIC);
901 header->version = ext2fs_cpu_to_be32(QCOW_VERSION);
902 header->size = ext2fs_cpu_to_be64(total_size);
903 header->cluster_bits = ext2fs_cpu_to_be32(cluster_bits);
905 header_size = (sizeof(struct ext2_qcow2_hdr) + 7) & ~7;
906 offset = align_offset(header_size, image->cluster_size);
908 header->l1_table_offset = ext2fs_cpu_to_be64(offset);
909 image->l1_offset = offset;
911 l2_bits = cluster_bits - 3;
912 shift = cluster_bits + l2_bits;
913 l1_size = ((total_size + (1LL << shift) - 1) >> shift);
914 header->l1_size = ext2fs_cpu_to_be32(l1_size);
915 image->l1_size = l1_size;
917 /* Make space for L1 table */
918 offset += align_offset(l1_size * sizeof(blk64_t), image->cluster_size);
920 /* Initialize refcounting */
921 ret = init_refcount(image, offset);
923 ext2fs_free_mem(&header);
926 header->refcount_table_offset = ext2fs_cpu_to_be64(offset);
927 header->refcount_table_clusters =
928 ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters);
929 offset += image->cluster_size;
930 offset += image->refcount.refcount_table_clusters <<
933 /* Make space for L2 tables */
934 image->l2_offset = offset;
935 offset += image->cluster_size;
937 /* Make space for first refcount block */
938 image->refcount.refcount_block_offset = offset;
941 /* Initialize l1 and l2 tables */
942 init_l1_table(image);
943 init_l2_cache(image);
948 static void free_qcow2_image(struct ext2_qcow2_image *img)
954 ext2fs_free_mem(&img->hdr);
957 ext2fs_free_mem(&img->l1_table);
959 if (img->refcount.refcount_table)
960 ext2fs_free_mem(&img->refcount.refcount_table);
961 if (img->refcount.refcount_block)
962 ext2fs_free_mem(&img->refcount.refcount_block);
966 ext2fs_free_mem(&img);
970 * Put table from used list (used_head) into free list (free_head).
971 * l2_table is used to return pointer to the next used table (used_head).
973 static void put_used_table(struct ext2_qcow2_image *img,
974 struct ext2_qcow2_l2_table **l2_table)
976 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
977 struct ext2_qcow2_l2_table *table;
979 table = cache->used_head;
980 cache->used_head = table->next;
984 cache->used_tail = NULL;
986 /* Clean the table for case we will need to use it again */
987 memset(table->data, 0, img->cluster_size);
988 table->next = cache->free_head;
989 cache->free_head = table;
993 *l2_table = cache->used_head;
996 static void flush_l2_cache(struct ext2_qcow2_image *image)
1000 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1001 struct ext2_qcow2_l2_table *table = cache->used_head;
1004 /* Store current position */
1005 offset = seek_relative(fd, 0);
1008 while (cache->free < cache->count) {
1009 if (seek != table->offset) {
1010 seek_set(fd, table->offset);
1011 seek = table->offset;
1014 generic_write(fd, (char *)table->data, image->cluster_size,
1016 put_used_table(image, &table);
1017 seek += image->cluster_size;
1020 /* Restore previous position */
1021 seek_set(fd, offset);
1025 * Get first free table (from free_head) and put it into tail of used list
1027 * l2_table is used to return pointer to moved table.
1028 * Returns 1 if the cache is full, 0 otherwise.
1030 static void get_free_table(struct ext2_qcow2_image *image,
1031 struct ext2_qcow2_l2_table **l2_table)
1033 struct ext2_qcow2_l2_table *table;
1034 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1036 if (0 == cache->free)
1037 flush_l2_cache(image);
1039 table = cache->free_head;
1041 cache->free_head = table->next;
1043 if (cache->used_tail)
1044 cache->used_tail->next = table;
1046 /* First item in the used list */
1047 cache->used_head = table;
1049 cache->used_tail = table;
1055 static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk,
1056 blk64_t data, blk64_t next)
1058 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
1059 struct ext2_qcow2_l2_table *table = cache->used_tail;
1060 blk64_t l1_index = blk / img->l2_size;
1061 blk64_t l2_index = blk & (img->l2_size - 1);
1065 * Need to create new table if it does not exist,
1068 if (!table || (table->l1_index != l1_index)) {
1069 get_free_table(img, &table);
1070 table->l1_index = l1_index;
1071 table->offset = cache->next_offset;
1072 cache->next_offset = next;
1073 img->l1_table[l1_index] =
1074 ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED);
1078 table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED);
1082 static int update_refcount(int fd, struct ext2_qcow2_image *img,
1083 blk64_t offset, blk64_t rfblk_pos)
1085 struct ext2_qcow2_refcount *ref;
1089 ref = &(img->refcount);
1090 table_index = offset >> (2 * img->cluster_bits - 1);
1093 * Need to create new refcount block when the offset addresses
1094 * another item in the refcount table
1096 if (table_index != ref->refcount_table_index) {
1098 seek_set(fd, ref->refcount_block_offset);
1100 generic_write(fd, (char *)ref->refcount_block,
1101 img->cluster_size, NO_BLK);
1102 memset(ref->refcount_block, 0, img->cluster_size);
1104 ref->refcount_table[ref->refcount_table_index] =
1105 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1106 ref->refcount_block_offset = rfblk_pos;
1107 ref->refcount_block_index = 0;
1108 ref->refcount_table_index = table_index;
1113 * We are relying on the fact that we are creating the qcow2
1114 * image sequentially, hence we will always allocate refcount
1115 * block items sequentially.
1117 ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1);
1118 ref->refcount_block_index++;
1122 static int sync_refcount(int fd, struct ext2_qcow2_image *img)
1124 struct ext2_qcow2_refcount *ref;
1126 ref = &(img->refcount);
1128 ref->refcount_table[ref->refcount_table_index] =
1129 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1130 seek_set(fd, ref->refcount_table_offset);
1131 generic_write(fd, (char *)ref->refcount_table,
1132 ref->refcount_table_clusters << img->cluster_bits, NO_BLK);
1134 seek_set(fd, ref->refcount_block_offset);
1135 generic_write(fd, (char *)ref->refcount_block, img->cluster_size,
1140 static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
1143 blk64_t blk, offset, size, end;
1145 struct ext2_qcow2_image *img;
1146 unsigned int header_size;
1148 /* allocate struct ext2_qcow2_image */
1149 retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img);
1151 com_err(program_name, retval, "%s",
1152 _("while allocating ext2_qcow2_image"));
1156 retval = initialize_qcow2_image(fd, fs, img);
1158 com_err(program_name, retval, "%s",
1159 _("while initializing ext2_qcow2_image"));
1162 header_size = align_offset(sizeof(struct ext2_qcow2_hdr),
1164 write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size);
1166 /* Refcount all qcow2 related metadata up to refcount_block_offset */
1167 end = img->refcount.refcount_block_offset;
1169 blk = end + img->cluster_size;
1170 for (offset = 0; offset <= end; offset += img->cluster_size) {
1171 if (update_refcount(fd, img, offset, blk)) {
1172 blk += img->cluster_size;
1174 * If we create new refcount block, we need to refcount
1177 end += img->cluster_size;
1180 seek_set(fd, offset);
1182 retval = ext2fs_get_mem(fs->blocksize, &buf);
1184 com_err(program_name, retval, "%s",
1185 _("while allocating buffer"));
1188 /* Write qcow2 data blocks */
1189 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) {
1190 if ((blk >= fs->super->s_first_data_block) &&
1191 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
1192 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
1194 com_err(program_name, retval,
1195 _("error reading block %llu"), blk);
1198 if (scramble_block_map &&
1199 ext2fs_test_block_bitmap2(scramble_block_map, blk))
1200 scramble_dir_block(fs, blk, buf);
1201 if (check_zero_block(buf, fs->blocksize))
1204 if (update_refcount(fd, img, offset, offset)) {
1205 /* Make space for another refcount block */
1206 offset += img->cluster_size;
1207 seek_set(fd, offset);
1209 * We have created the new refcount block, this
1210 * means that we need to refcount it as well.
1211 * So the previous update_refcount refcounted
1212 * the block itself and now we are going to
1213 * create refcount for data. New refcount
1214 * block should not be created!
1216 if (update_refcount(fd, img, offset, offset)) {
1217 fprintf(stderr, "%s",
1218 _("Programming error: multiple "
1219 "sequential refcount blocks "
1225 generic_write(fd, buf, fs->blocksize, blk);
1227 if (add_l2_item(img, blk, offset,
1228 offset + img->cluster_size)) {
1229 offset += img->cluster_size;
1230 if (update_refcount(fd, img, offset,
1231 offset + img->cluster_size)) {
1232 offset += img->cluster_size;
1233 if (update_refcount(fd, img, offset,
1235 fprintf(stderr, "%s",
1236 _("Programming error: multiple sequential refcount "
1237 "blocks created!\n"));
1241 offset += img->cluster_size;
1242 seek_set(fd, offset);
1246 offset += img->cluster_size;
1249 update_refcount(fd, img, offset, offset);
1250 flush_l2_cache(img);
1251 sync_refcount(fd, img);
1254 seek_set(fd, img->l1_offset);
1255 size = img->l1_size * sizeof(__u64);
1256 generic_write(fd, (char *)img->l1_table, size, NO_BLK);
1258 ext2fs_free_mem(&buf);
1259 free_qcow2_image(img);
1262 static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags)
1264 struct process_block_struct pb;
1265 struct ext2_inode inode;
1266 ext2_inode_scan scan;
1271 meta_blocks_count = 0;
1272 retval = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
1275 com_err(program_name, retval, "%s",
1276 _("while allocating block bitmap"));
1280 if (flags & E2IMAGE_SCRAMBLE_FLAG) {
1281 retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
1282 &scramble_block_map);
1284 com_err(program_name, retval, "%s",
1285 _("while allocating scramble block bitmap"));
1290 mark_table_blocks(fs);
1292 fprintf(stderr, "%s", _("Scanning inodes...\n"));
1294 retval = ext2fs_open_inode_scan(fs, 0, &scan);
1296 com_err(program_name, retval, "%s",
1297 _("while opening inode scan"));
1301 retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
1303 com_err(program_name, 0, "%s",
1304 _("Can't allocate block buffer"));
1308 use_inode_shortcuts(fs, 1);
1309 stashed_inode = &inode;
1311 retval = ext2fs_get_next_inode(scan, &ino, &inode);
1312 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
1315 com_err(program_name, retval, "%s",
1316 _("while getting next inode"));
1321 if (!inode.i_links_count)
1323 if (ext2fs_file_acl_block(fs, &inode)) {
1324 ext2fs_mark_block_bitmap2(meta_block_map,
1325 ext2fs_file_acl_block(fs, &inode));
1326 meta_blocks_count++;
1328 if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
1333 pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
1334 if (LINUX_S_ISDIR(inode.i_mode) ||
1335 (LINUX_S_ISLNK(inode.i_mode) &&
1336 ext2fs_inode_has_valid_blocks2(fs, &inode)) ||
1337 ino == fs->super->s_journal_inum) {
1338 retval = ext2fs_block_iterate3(fs, ino,
1339 BLOCK_FLAG_READ_ONLY, block_buf,
1340 process_dir_block, &pb);
1342 com_err(program_name, retval,
1343 _("while iterating over inode %u"),
1348 if ((inode.i_flags & EXT4_EXTENTS_FL) ||
1349 inode.i_block[EXT2_IND_BLOCK] ||
1350 inode.i_block[EXT2_DIND_BLOCK] ||
1351 inode.i_block[EXT2_TIND_BLOCK] || all_data) {
1352 retval = ext2fs_block_iterate3(fs,
1353 ino, BLOCK_FLAG_READ_ONLY, block_buf,
1354 process_file_block, &pb);
1356 com_err(program_name, retval,
1357 _("while iterating over inode %u"), ino);
1363 use_inode_shortcuts(fs, 0);
1365 if (type & E2IMAGE_QCOW2)
1366 output_qcow2_meta_data_blocks(fs, fd);
1368 output_meta_data_blocks(fs, fd, flags);
1370 ext2fs_free_mem(&block_buf);
1371 ext2fs_close_inode_scan(scan);
1372 ext2fs_free_block_bitmap(meta_block_map);
1373 if (type & E2IMAGE_SCRAMBLE_FLAG)
1374 ext2fs_free_block_bitmap(scramble_block_map);
1377 static void install_image(char *device, char *image_fn, int type)
1381 int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS |
1382 EXT2_FLAG_IGNORE_CSUM_ERRORS;
1388 com_err(program_name, 0, "%s",
1389 _("Raw and qcow2 images cannot be installed"));
1393 #ifdef CONFIG_TESTIO_DEBUG
1394 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1395 io_ptr = test_io_manager;
1396 test_io_backing_manager = unix_io_manager;
1399 io_ptr = unix_io_manager;
1401 retval = ext2fs_open (image_fn, open_flag, 0, 0,
1404 com_err(program_name, retval, _("while trying to open %s"),
1409 retval = ext2fs_read_bitmaps (fs);
1411 com_err(program_name, retval, "%s", _("error reading bitmaps"));
1415 fd = ext2fs_open_file(image_fn, O_RDONLY, 0);
1421 retval = io_ptr->open(device, IO_FLAG_RW, &io);
1423 com_err(device, 0, "%s", _("while opening device file"));
1427 ext2fs_rewrite_to_io(fs, io);
1429 seek_set(fd, ext2fs_le32_to_cpu(fs->image_header->offset_inode));
1431 retval = ext2fs_image_inode_read(fs, fd, 0);
1433 com_err(image_fn, 0, "%s",
1434 _("while restoring the image table"));
1439 ext2fs_close_free(&fs);
1442 static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name)
1445 *fd = ext2fs_open_file(name, O_RDONLY, 0600);
1449 return qcow2_read_header(*fd);
1452 int main (int argc, char ** argv)
1457 char *image_fn, offset_opt[64];
1458 struct ext2_qcow2_hdr *header = NULL;
1459 int open_flag = EXT2_FLAG_64BITS | EXT2_FLAG_IGNORE_CSUM_ERRORS;
1462 int mount_flags = 0;
1466 int ignore_rw_mount = 0;
1471 setlocale(LC_MESSAGES, "");
1472 setlocale(LC_CTYPE, "");
1473 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
1474 textdomain(NLS_CAT_NAME);
1475 set_com_err_gettext(gettext);
1477 fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION,
1480 program_name = *argv;
1481 add_error_table(&et_ext2_error_table);
1482 while ((c = getopt(argc, argv, "nrsIQafo:O:pc")) != EOF)
1485 flags |= E2IMAGE_INSTALL_FLAG;
1490 img_type |= E2IMAGE_QCOW2;
1495 img_type |= E2IMAGE_RAW;
1498 flags |= E2IMAGE_SCRAMBLE_FLAG;
1504 ignore_rw_mount = 1;
1510 source_offset = strtoull(optarg, NULL, 0);
1513 dest_offset = strtoull(optarg, NULL, 0);
1524 if (optind == argc - 1 &&
1525 (source_offset || dest_offset))
1527 else if (optind != argc - 2 )
1530 if (all_data && !img_type) {
1531 com_err(program_name, 0, "%s", _("-a option can only be used "
1532 "with raw or QCOW2 images."));
1535 if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) {
1536 com_err(program_name, 0, "%s",
1537 _("Offsets are only allowed with raw images."));
1540 if (move_mode && img_type != E2IMAGE_RAW) {
1541 com_err(program_name, 0, "%s",
1542 _("Move mode is only allowed with raw images."));
1545 if (move_mode && !all_data) {
1546 com_err(program_name, 0, "%s",
1547 _("Move mode requires all data mode."));
1550 device_name = argv[optind];
1552 image_fn = device_name;
1553 else image_fn = argv[optind+1];
1555 retval = ext2fs_check_if_mounted(device_name, &mount_flags);
1557 com_err(program_name, retval, "%s", _("checking if mounted"));
1561 if (img_type && !ignore_rw_mount &&
1562 (mount_flags & EXT2_MF_MOUNTED) &&
1563 !(mount_flags & EXT2_MF_READONLY)) {
1564 fprintf(stderr, "%s", _("\nRunning e2image on a R/W mounted "
1565 "filesystem can result in an\n"
1566 "inconsistent image which will not be useful "
1567 "for debugging purposes.\n"
1568 "Use -f option if you really want to do that.\n"));
1572 if (flags & E2IMAGE_INSTALL_FLAG) {
1573 install_image(device_name, image_fn, img_type);
1577 if (img_type & E2IMAGE_RAW) {
1578 header = check_qcow2_image(&qcow2_fd, device_name);
1580 flags |= E2IMAGE_IS_QCOW2_FLAG;
1584 sprintf(offset_opt, "offset=%llu", source_offset);
1585 retval = ext2fs_open2(device_name, offset_opt, open_flag, 0, 0,
1586 unix_io_manager, &fs);
1588 com_err (program_name, retval, _("while trying to open %s"),
1590 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout);
1591 if (retval == EXT2_ET_BAD_MAGIC)
1592 check_plausibility(device_name, CHECK_FS_EXIST, NULL);
1597 if (strcmp(image_fn, "-") == 0)
1600 int o_flags = O_CREAT|O_RDWR;
1602 if (img_type != E2IMAGE_RAW)
1604 if (access(image_fn, F_OK) != 0)
1605 flags |= E2IMAGE_CHECK_ZERO_FLAG;
1606 fd = ext2fs_open_file(image_fn, o_flags, 0600);
1608 com_err(program_name, errno,
1609 _("while trying to open %s"), image_fn);
1614 seek_set(fd, dest_offset);
1616 if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) {
1617 com_err(program_name, 0, "%s",
1618 _("QCOW2 image can not be written to the stdout!\n"));
1622 if (fstat(fd, &st)) {
1623 com_err(program_name, 0, "%s",
1624 _("Can not stat output\n"));
1627 if (ext2fsP_is_disk_device(st.st_mode))
1630 if (flags & E2IMAGE_IS_QCOW2_FLAG) {
1631 ret = qcow2_write_raw_image(qcow2_fd, fd, header);
1633 if (ret == -QCOW_COMPRESSED)
1634 fprintf(stderr, _("Image (%s) is compressed\n"),
1636 else if (ret == -QCOW_ENCRYPTED)
1637 fprintf(stderr, _("Image (%s) is encrypted\n"),
1639 else if (ret == -QCOW_CORRUPTED)
1640 fprintf(stderr, _("Image (%s) is corrupted\n"),
1643 com_err(program_name, ret,
1644 _("while trying to convert qcow2 image"
1645 " (%s) into raw image (%s)"),
1646 image_fn, device_name);
1653 if (img_type != E2IMAGE_RAW) {
1654 fprintf(stderr, "%s", _("The -c option only supported "
1659 fprintf(stderr, "%s", _("The -c option not supported "
1660 "when writing to stdout\n"));
1663 retval = ext2fs_get_mem(fs->blocksize, &check_buf);
1665 com_err(program_name, retval, "%s",
1666 _("while allocating check_buf"));
1670 if (show_progress && (img_type != E2IMAGE_RAW)) {
1671 fprintf(stderr, "%s",
1672 _("The -p option only supported in raw mode\n"));
1676 write_raw_image_file(fs, fd, img_type, flags);
1678 write_image_file(fs, fd);
1680 ext2fs_close_free(&fs);
1682 printf(_("%d blocks already contained the data to be copied\n"),
1690 remove_error_table(&et_ext2_error_table);