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 #define _LARGEFILE_SOURCE
14 #define _LARGEFILE64_SOURCE
36 #include <sys/types.h>
40 #include "ext2fs/ext2_fs.h"
41 #include "ext2fs/ext2fs.h"
42 #include "et/com_err.h"
43 #include "uuid/uuid.h"
45 #include "ext2fs/e2image.h"
46 #include "ext2fs/qcow2.h"
48 #include "../version.h"
49 #include "nls-enable.h"
51 #define QCOW_OFLAG_COPIED (1LL << 63)
52 #define NO_BLK ((blk64_t) -1)
56 #define E2IMAGE_QCOW2 2
59 #define E2IMAGE_INSTALL_FLAG 1
60 #define E2IMAGE_SCRAMBLE_FLAG 2
61 #define E2IMAGE_IS_QCOW2_FLAG 4
62 #define E2IMAGE_CHECK_ZERO_FLAG 8
64 static const char * program_name = "e2image";
65 static char * device_name = NULL;
67 static char output_is_blk;
69 /* writing to blk device: don't skip zeroed blocks */
70 static blk64_t source_offset, dest_offset;
71 static char move_mode;
72 static char show_progress;
73 static char *check_buf;
74 static int skipped_blocks;
76 static blk64_t align_offset(blk64_t offset, unsigned int n)
78 return (offset + n - 1) & ~((blk64_t) n - 1);
81 static int get_bits_from_size(size_t size)
89 /* Not a power of two */
99 static void usage(void)
101 fprintf(stderr, _("Usage: %s [ -r|Q ] [ -fr ] device image-file\n"),
103 fprintf(stderr, _(" %s -I device image-file\n"), program_name);
104 fprintf(stderr, _(" %s -ra [ -cfnp ] [ -o src_offset ] "
105 "[ -O dest_offset ] src_fs [ dest_fs ]\n"),
110 static ext2_loff_t seek_relative(int fd, int offset)
112 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_CUR);
114 perror("seek_relative");
120 static ext2_loff_t seek_set(int fd, ext2_loff_t offset)
122 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_SET);
131 * Returns true if the block we are about to write is identical to
132 * what is already on the disk.
134 static int check_block(int fd, void *buf, void *cbuf, int blocksize)
137 int count = blocksize, ret;
143 ret = read(fd, cp, count);
145 perror("check_block");
151 ret = memcmp(buf, cbuf, blocksize);
152 seek_relative(fd, -blocksize);
153 return (ret == 0) ? 1 : 0;
156 static void generic_write(int fd, void *buf, int blocksize, blk64_t block)
158 int count, free_buf = 0;
166 err = ext2fs_get_arrayzero(1, blocksize, &buf);
168 com_err(program_name, err,
169 _("while allocating buffer"));
174 printf(_("Writing block %llu\n"), (unsigned long long) block);
176 seek_relative(fd, blocksize);
177 goto free_and_return;
179 count = write(fd, buf, blocksize);
180 if (count != blocksize) {
187 com_err(program_name, err,
188 _("error writing block %llu"), block);
190 com_err(program_name, err, _("error in write()"));
196 ext2fs_free_mem(&buf);
199 static void write_header(int fd, void *hdr, int hdr_size, int wrt_size)
205 if (hdr_size > wrt_size) {
206 fprintf(stderr, "%s",
207 _("Error: header size is bigger than wrt_size\n"));
210 ret = ext2fs_get_mem(wrt_size, &header_buf);
212 fputs(_("Couldn't allocate header buffer\n"), stderr);
217 memset(header_buf, 0, wrt_size);
220 memcpy(header_buf, hdr, hdr_size);
222 generic_write(fd, header_buf, wrt_size, NO_BLK);
224 ext2fs_free_mem(&header_buf);
227 static void write_image_file(ext2_filsys fs, int fd)
229 struct ext2_image_hdr hdr;
233 write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize);
234 memset(&hdr, 0, sizeof(struct ext2_image_hdr));
236 hdr.offset_super = seek_relative(fd, 0);
237 retval = ext2fs_image_super_write(fs, fd, 0);
239 com_err(program_name, retval, "%s",
240 _("while writing superblock"));
244 hdr.offset_inode = seek_relative(fd, 0);
245 retval = ext2fs_image_inode_write(fs, fd,
246 (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0);
248 com_err(program_name, retval, "%s",
249 _("while writing inode table"));
253 hdr.offset_blockmap = seek_relative(fd, 0);
254 retval = ext2fs_image_bitmap_write(fs, fd, 0);
256 com_err(program_name, retval, "%s",
257 _("while writing block bitmap"));
261 hdr.offset_inodemap = seek_relative(fd, 0);
262 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP);
264 com_err(program_name, retval, "%s",
265 _("while writing inode bitmap"));
269 hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE;
270 strcpy(hdr.magic_descriptor, "Ext2 Image 1.0");
271 gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname));
272 strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1);
273 hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0;
274 hdr.fs_blocksize = fs->blocksize;
276 if (stat(device_name, &st) == 0)
277 hdr.fs_device = st.st_rdev;
279 if (fstat(fd, &st) == 0) {
280 hdr.image_device = st.st_dev;
281 hdr.image_inode = st.st_ino;
283 memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid));
285 hdr.image_time = time(0);
286 write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize);
290 * These set of functions are used to write a RAW image file.
292 static ext2fs_block_bitmap meta_block_map;
293 static ext2fs_block_bitmap scramble_block_map; /* Directory blocks to be scrambled */
294 static blk64_t meta_blocks_count;
296 struct process_block_struct {
302 * These subroutines short circuits ext2fs_get_blocks and
303 * ext2fs_check_directory; we use them since we already have the inode
304 * structure, so there's no point in letting the ext2fs library read
307 static ino_t stashed_ino = 0;
308 static struct ext2_inode *stashed_inode;
310 static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)),
316 if ((ino != stashed_ino) || !stashed_inode)
317 return EXT2_ET_CALLBACK_NOTHANDLED;
319 for (i=0; i < EXT2_N_BLOCKS; i++)
320 blocks[i] = stashed_inode->i_block[i];
324 static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)),
327 if ((ino != stashed_ino) || !stashed_inode)
328 return EXT2_ET_CALLBACK_NOTHANDLED;
330 if (!LINUX_S_ISDIR(stashed_inode->i_mode))
331 return EXT2_ET_NO_DIRECTORY;
335 static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
337 struct ext2_inode *inode)
339 if ((ino != stashed_ino) || !stashed_inode)
340 return EXT2_ET_CALLBACK_NOTHANDLED;
341 *inode = *stashed_inode;
345 static void use_inode_shortcuts(ext2_filsys fs, int use_shortcuts)
348 fs->get_blocks = meta_get_blocks;
349 fs->check_directory = meta_check_directory;
350 fs->read_inode = meta_read_inode;
354 fs->check_directory = 0;
359 static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
361 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
362 blk64_t ref_block EXT2FS_ATTR((unused)),
363 int ref_offset EXT2FS_ATTR((unused)),
364 void *priv_data EXT2FS_ATTR((unused)))
366 struct process_block_struct *p;
368 p = (struct process_block_struct *) priv_data;
370 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
372 if (scramble_block_map && p->is_dir && blockcnt >= 0)
373 ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr);
377 static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
379 e2_blkcnt_t blockcnt,
380 blk64_t ref_block EXT2FS_ATTR((unused)),
381 int ref_offset EXT2FS_ATTR((unused)),
382 void *priv_data EXT2FS_ATTR((unused)))
384 if (blockcnt < 0 || all_data) {
385 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
391 static void mark_table_blocks(ext2_filsys fs)
393 blk64_t first_block, b;
396 first_block = fs->super->s_first_data_block;
398 * Mark primary superblock
400 ext2fs_mark_block_bitmap2(meta_block_map, first_block);
404 * Mark the primary superblock descriptors
406 for (j = 0; j < fs->desc_blocks; j++) {
407 ext2fs_mark_block_bitmap2(meta_block_map,
408 ext2fs_descriptor_block_loc2(fs, first_block, j));
410 meta_blocks_count += fs->desc_blocks;
412 for (i = 0; i < fs->group_desc_count; i++) {
414 * Mark the blocks used for the inode table
416 if ((output_is_blk ||
417 !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) &&
418 ext2fs_inode_table_loc(fs, i)) {
419 unsigned int end = (unsigned) fs->inode_blocks_per_group;
420 /* skip unused blocks */
421 if (!output_is_blk &&
422 EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
423 EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
424 end -= (ext2fs_bg_itable_unused(fs, i) /
425 EXT2_INODES_PER_BLOCK(fs->super));
426 for (j = 0, b = ext2fs_inode_table_loc(fs, i);
429 ext2fs_mark_block_bitmap2(meta_block_map, b);
435 * Mark block used for the block bitmap
437 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
438 ext2fs_block_bitmap_loc(fs, i)) {
439 ext2fs_mark_block_bitmap2(meta_block_map,
440 ext2fs_block_bitmap_loc(fs, i));
445 * Mark block used for the inode bitmap
447 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
448 ext2fs_inode_bitmap_loc(fs, i)) {
449 ext2fs_mark_block_bitmap2(meta_block_map,
450 ext2fs_inode_bitmap_loc(fs, i));
457 * This function returns 1 if the specified block is all zeros
459 static int check_zero_block(char *buf, int blocksize)
462 int left = blocksize;
474 static int name_id[256];
476 #define EXT4_MAX_REC_LEN ((1<<16)-1)
478 static void scramble_dir_block(ext2_filsys fs, blk64_t blk, char *buf)
481 struct ext2_dir_entry_2 *dirent;
482 unsigned int rec_len;
485 end = buf + fs->blocksize;
486 for (p = buf; p < end-8; p += rec_len) {
487 dirent = (struct ext2_dir_entry_2 *) p;
488 rec_len = dirent->rec_len;
489 #ifdef WORDS_BIGENDIAN
490 rec_len = ext2fs_swab16(rec_len);
492 if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0)
493 rec_len = fs->blocksize;
495 rec_len = (rec_len & 65532) | ((rec_len & 3) << 16);
497 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len);
499 if (rec_len < 8 || (rec_len % 4) ||
501 printf(_("Corrupt directory block %llu: "
502 "bad rec_len (%d)\n"),
503 (unsigned long long) blk, rec_len);
505 (void) ext2fs_set_rec_len(fs, rec_len,
506 (struct ext2_dir_entry *) dirent);
507 #ifdef WORDS_BIGENDIAN
508 dirent->rec_len = ext2fs_swab16(dirent->rec_len);
512 if (dirent->name_len + 8U > rec_len) {
513 printf(_("Corrupt directory block %llu: "
514 "bad name_len (%d)\n"),
515 (unsigned long long) blk, dirent->name_len);
516 dirent->name_len = rec_len - 8;
520 len = rec_len - dirent->name_len - 8;
522 memset(cp+dirent->name_len, 0, len);
523 if (dirent->name_len==1 && cp[0] == '.')
525 if (dirent->name_len==2 && cp[0] == '.' && cp[1] == '.')
528 memset(cp, 'A', dirent->name_len);
529 len = dirent->name_len;
531 while ((len > 0) && (id > 0)) {
540 static char got_sigint;
542 static void sigint_handler(int unused EXT2FS_ATTR((unused)))
545 signal (SIGINT, SIG_DFL);
548 #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \
549 ((float) (b)))) + 0.5))
550 #define calc_rate(t, b, d) (((float)(t) / ((1024 * 1024) / (b))) / (d))
552 static int print_progress(blk64_t num, blk64_t total)
554 return fprintf(stderr, _("%llu / %llu blocks (%d%%)"), num, total,
555 calc_percent(num, total));
558 static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags)
562 char *buf, *zero_buf;
565 blk64_t distance = 0;
566 blk64_t end = ext2fs_blocks_count(fs->super);
567 time_t last_update = 0;
568 time_t start_time = 0;
569 blk64_t total_written = 0;
572 retval = ext2fs_get_mem(fs->blocksize, &buf);
574 com_err(program_name, retval, _("while allocating buffer"));
577 retval = ext2fs_get_memzero(fs->blocksize, &zero_buf);
579 com_err(program_name, retval, _("while allocating buffer"));
583 fprintf(stderr, _("Copying "));
584 bscount = print_progress(total_written, meta_blocks_count);
586 last_update = time(NULL);
587 start_time = time(NULL);
589 /* when doing an in place move to the right, you can't start
590 at the beginning or you will overwrite data, so instead
591 divide the fs up into distance size chunks and write them
593 if (move_mode && dest_offset > source_offset) {
594 distance = (dest_offset - source_offset) / fs->blocksize;
595 if (distance < ext2fs_blocks_count(fs->super))
596 start = ext2fs_blocks_count(fs->super) - distance;
599 signal (SIGINT, sigint_handler);
602 seek_set(fd, (start * fs->blocksize) + dest_offset);
603 for (blk = start; blk < end; blk++) {
606 /* moving to the right */
607 if (distance >= ext2fs_blocks_count(fs->super) ||
608 start == ext2fs_blocks_count(fs->super) - distance)
609 kill (getpid(), SIGINT);
611 /* moving to the left */
612 if (blk < (source_offset - dest_offset) / fs->blocksize)
613 kill (getpid(), SIGINT);
618 _("Stopping now will destroy the filesystem, "
619 "interrupt again if you are sure\n"));
621 fprintf(stderr, _("Copying "));
622 bscount = print_progress(total_written,
629 if (show_progress && last_update != time(NULL)) {
631 last_update = time(NULL);
634 bscount = print_progress(total_written,
636 duration = time(NULL) - start_time;
638 time_t est = (duration * meta_blocks_count /
639 total_written) - duration;
641 strftime(buff, 30, "%T", gmtime(&est));
642 bscount += fprintf(stderr,
643 _(" %s remaining at %.2f MB/s"),
644 buff, calc_rate(total_written,
650 if ((blk >= fs->super->s_first_data_block) &&
651 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
652 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
654 com_err(program_name, retval,
655 _("error reading block %llu"), blk);
658 if (scramble_block_map &&
659 ext2fs_test_block_bitmap2(scramble_block_map, blk))
660 scramble_dir_block(fs, blk, buf);
661 if ((flags & E2IMAGE_CHECK_ZERO_FLAG) &&
662 check_zero_block(buf, fs->blocksize))
665 seek_relative(fd, sparse);
667 if (check_block(fd, buf, check_buf, fs->blocksize)) {
668 seek_relative(fd, fs->blocksize);
671 generic_write(fd, buf, fs->blocksize, blk);
676 generic_write(fd, zero_buf,
680 sparse += fs->blocksize;
681 if (sparse > 1024*1024) {
682 seek_relative(fd, 1024*1024);
687 if (distance && start) {
688 if (start < distance) {
694 if (end < distance) {
695 /* past overlap, do rest in one go */
703 signal (SIGINT, SIG_DFL);
705 time_t duration = time(NULL) - start_time;
709 strftime(buff, 30, "%T", gmtime(&duration));
710 fprintf(stderr, _("\b\b\b\b\b\b\b\bCopied %llu / %llu "
711 "blocks (%d%%) in %s at %.2f MB/s \n"),
712 total_written, meta_blocks_count,
713 calc_percent(total_written, meta_blocks_count), buff,
714 calc_rate(total_written, fs->blocksize, duration));
716 #ifdef HAVE_FTRUNCATE64
720 offset = seek_set(fd,
721 fs->blocksize * ext2fs_blocks_count(fs->super) + dest_offset);
723 offset = seek_relative(fd, sparse);
725 if (ftruncate64(fd, offset) < 0) {
726 seek_relative(fd, -1);
727 generic_write(fd, zero_buf, 1, NO_BLK);
731 if (sparse && !distance) {
732 seek_relative(fd, sparse-1);
733 generic_write(fd, zero_buf, 1, NO_BLK);
736 ext2fs_free_mem(&zero_buf);
737 ext2fs_free_mem(&buf);
740 static void init_l1_table(struct ext2_qcow2_image *image)
745 ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table);
747 com_err(program_name, ret, _("while allocating l1 table"));
751 image->l1_table = l1_table;
754 static void init_l2_cache(struct ext2_qcow2_image *image)
756 unsigned int count, i;
757 struct ext2_qcow2_l2_cache *cache;
758 struct ext2_qcow2_l2_table *table;
761 ret = ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache),
766 count = (image->l1_size > L2_CACHE_PREALLOC) ? L2_CACHE_PREALLOC :
769 cache->count = count;
771 cache->next_offset = image->l2_offset;
773 for (i = 0; i < count; i++) {
774 ret = ext2fs_get_arrayzero(1,
775 sizeof(struct ext2_qcow2_l2_table), &table);
779 ret = ext2fs_get_arrayzero(image->l2_size,
780 sizeof(__u64), &table->data);
784 table->next = cache->free_head;
785 cache->free_head = table;
788 image->l2_cache = cache;
792 com_err(program_name, ret, _("while allocating l2 cache"));
796 static void put_l2_cache(struct ext2_qcow2_image *image)
798 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
799 struct ext2_qcow2_l2_table *tmp, *table;
804 table = cache->free_head;
805 cache->free_head = NULL;
810 ext2fs_free_mem(&tmp->data);
811 ext2fs_free_mem(&tmp);
814 if (cache->free != cache->count) {
815 fprintf(stderr, _("Warning: There are still tables in the "
816 "cache while putting the cache, data will "
817 "be lost so the image may not be valid.\n"));
818 table = cache->used_head;
819 cache->used_head = NULL;
823 ext2fs_free_mem(&cache);
826 static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset)
828 struct ext2_qcow2_refcount *ref;
829 blk64_t table_clusters;
832 ref = &(img->refcount);
835 * One refcount block addresses 2048 clusters, one refcount table
836 * addresses cluster/sizeof(__u64) refcount blocks, and we need
837 * to address meta_blocks_count clusters + qcow2 metadata clusters
840 table_clusters = meta_blocks_count + (table_offset >>
842 table_clusters >>= (img->cluster_bits + 6 - 1);
843 table_clusters = (table_clusters == 0) ? 1 : table_clusters;
845 ref->refcount_table_offset = table_offset;
846 ref->refcount_table_clusters = table_clusters;
847 ref->refcount_table_index = 0;
848 ref->refcount_block_index = 0;
850 /* Allocate refcount table */
851 ret = ext2fs_get_arrayzero(ref->refcount_table_clusters,
852 img->cluster_size, &ref->refcount_table);
856 /* Allocate refcount block */
857 ret = ext2fs_get_arrayzero(1, img->cluster_size, &ref->refcount_block);
859 ext2fs_free_mem(&ref->refcount_table);
864 static int initialize_qcow2_image(int fd, ext2_filsys fs,
865 struct ext2_qcow2_image *image)
867 struct ext2_qcow2_hdr *header;
868 blk64_t total_size, offset;
869 int shift, l2_bits, header_size, l1_size, ret;
870 int cluster_bits = get_bits_from_size(fs->blocksize);
871 struct ext2_super_block *sb = fs->super;
873 /* Allocate header */
874 ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header);
878 total_size = ext2fs_blocks_count(sb) << cluster_bits;
879 image->cluster_size = fs->blocksize;
880 image->l2_size = 1 << (cluster_bits - 3);
881 image->cluster_bits = cluster_bits;
884 header->magic = ext2fs_cpu_to_be32(QCOW_MAGIC);
885 header->version = ext2fs_cpu_to_be32(QCOW_VERSION);
886 header->size = ext2fs_cpu_to_be64(total_size);
887 header->cluster_bits = ext2fs_cpu_to_be32(cluster_bits);
889 header_size = (sizeof(struct ext2_qcow2_hdr) + 7) & ~7;
890 offset = align_offset(header_size, image->cluster_size);
892 header->l1_table_offset = ext2fs_cpu_to_be64(offset);
893 image->l1_offset = offset;
895 l2_bits = cluster_bits - 3;
896 shift = cluster_bits + l2_bits;
897 l1_size = ((total_size + (1LL << shift) - 1) >> shift);
898 header->l1_size = ext2fs_cpu_to_be32(l1_size);
899 image->l1_size = l1_size;
901 /* Make space for L1 table */
902 offset += align_offset(l1_size * sizeof(blk64_t), image->cluster_size);
904 /* Initialize refcounting */
905 ret = init_refcount(image, offset);
907 ext2fs_free_mem(&header);
910 header->refcount_table_offset = ext2fs_cpu_to_be64(offset);
911 header->refcount_table_clusters =
912 ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters);
913 offset += image->cluster_size;
914 offset += image->refcount.refcount_table_clusters <<
917 /* Make space for L2 tables */
918 image->l2_offset = offset;
919 offset += image->cluster_size;
921 /* Make space for first refcount block */
922 image->refcount.refcount_block_offset = offset;
925 /* Initialize l1 and l2 tables */
926 init_l1_table(image);
927 init_l2_cache(image);
932 static void free_qcow2_image(struct ext2_qcow2_image *img)
938 ext2fs_free_mem(&img->hdr);
941 ext2fs_free_mem(&img->l1_table);
943 if (img->refcount.refcount_table)
944 ext2fs_free_mem(&img->refcount.refcount_table);
945 if (img->refcount.refcount_block)
946 ext2fs_free_mem(&img->refcount.refcount_block);
950 ext2fs_free_mem(&img);
954 * Put table from used list (used_head) into free list (free_head).
955 * l2_table is used to return pointer to the next used table (used_head).
957 static void put_used_table(struct ext2_qcow2_image *img,
958 struct ext2_qcow2_l2_table **l2_table)
960 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
961 struct ext2_qcow2_l2_table *table;
963 table = cache->used_head;
964 cache->used_head = table->next;
968 cache->used_tail = NULL;
970 /* Clean the table for case we will need to use it again */
971 memset(table->data, 0, img->cluster_size);
972 table->next = cache->free_head;
973 cache->free_head = table;
977 *l2_table = cache->used_head;
980 static void flush_l2_cache(struct ext2_qcow2_image *image)
984 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
985 struct ext2_qcow2_l2_table *table = cache->used_head;
988 /* Store current position */
989 offset = seek_relative(fd, 0);
992 while (cache->free < cache->count) {
993 if (seek != table->offset) {
994 seek_set(fd, table->offset);
995 seek = table->offset;
998 generic_write(fd, (char *)table->data, image->cluster_size,
1000 put_used_table(image, &table);
1001 seek += image->cluster_size;
1004 /* Restore previous position */
1005 seek_set(fd, offset);
1009 * Get first free table (from free_head) and put it into tail of used list
1011 * l2_table is used to return pointer to moved table.
1012 * Returns 1 if the cache is full, 0 otherwise.
1014 static void get_free_table(struct ext2_qcow2_image *image,
1015 struct ext2_qcow2_l2_table **l2_table)
1017 struct ext2_qcow2_l2_table *table;
1018 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1020 if (0 == cache->free)
1021 flush_l2_cache(image);
1023 table = cache->free_head;
1025 cache->free_head = table->next;
1027 if (cache->used_tail)
1028 cache->used_tail->next = table;
1030 /* First item in the used list */
1031 cache->used_head = table;
1033 cache->used_tail = table;
1039 static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk,
1040 blk64_t data, blk64_t next)
1042 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
1043 struct ext2_qcow2_l2_table *table = cache->used_tail;
1044 blk64_t l1_index = blk / img->l2_size;
1045 blk64_t l2_index = blk & (img->l2_size - 1);
1049 * Need to create new table if it does not exist,
1052 if (!table || (table->l1_index != l1_index)) {
1053 get_free_table(img, &table);
1054 table->l1_index = l1_index;
1055 table->offset = cache->next_offset;
1056 cache->next_offset = next;
1057 img->l1_table[l1_index] =
1058 ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED);
1062 table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED);
1066 static int update_refcount(int fd, struct ext2_qcow2_image *img,
1067 blk64_t offset, blk64_t rfblk_pos)
1069 struct ext2_qcow2_refcount *ref;
1073 ref = &(img->refcount);
1074 table_index = offset >> (2 * img->cluster_bits - 1);
1077 * Need to create new refcount block when the offset addresses
1078 * another item in the refcount table
1080 if (table_index != ref->refcount_table_index) {
1082 seek_set(fd, ref->refcount_block_offset);
1084 generic_write(fd, (char *)ref->refcount_block,
1085 img->cluster_size, NO_BLK);
1086 memset(ref->refcount_block, 0, img->cluster_size);
1088 ref->refcount_table[ref->refcount_table_index] =
1089 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1090 ref->refcount_block_offset = rfblk_pos;
1091 ref->refcount_block_index = 0;
1092 ref->refcount_table_index = table_index;
1097 * We are relying on the fact that we are creating the qcow2
1098 * image sequentially, hence we will always allocate refcount
1099 * block items sequentialy.
1101 ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1);
1102 ref->refcount_block_index++;
1106 static int sync_refcount(int fd, struct ext2_qcow2_image *img)
1108 struct ext2_qcow2_refcount *ref;
1110 ref = &(img->refcount);
1112 ref->refcount_table[ref->refcount_table_index] =
1113 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1114 seek_set(fd, ref->refcount_table_offset);
1115 generic_write(fd, (char *)ref->refcount_table,
1116 ref->refcount_table_clusters << img->cluster_bits, NO_BLK);
1118 seek_set(fd, ref->refcount_block_offset);
1119 generic_write(fd, (char *)ref->refcount_block, img->cluster_size,
1124 static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
1127 blk64_t blk, offset, size, end;
1129 struct ext2_qcow2_image *img;
1130 unsigned int header_size;
1132 /* allocate struct ext2_qcow2_image */
1133 retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img);
1135 com_err(program_name, retval,
1136 _("while allocating ext2_qcow2_image"));
1140 retval = initialize_qcow2_image(fd, fs, img);
1142 com_err(program_name, retval,
1143 _("while initializing ext2_qcow2_image"));
1146 header_size = align_offset(sizeof(struct ext2_qcow2_hdr),
1148 write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size);
1150 /* Refcount all qcow2 related metadata up to refcount_block_offset */
1151 end = img->refcount.refcount_block_offset;
1153 blk = end + img->cluster_size;
1154 for (offset = 0; offset <= end; offset += img->cluster_size) {
1155 if (update_refcount(fd, img, offset, blk)) {
1156 blk += img->cluster_size;
1158 * If we create new refcount block, we need to refcount
1161 end += img->cluster_size;
1164 seek_set(fd, offset);
1166 retval = ext2fs_get_mem(fs->blocksize, &buf);
1168 com_err(program_name, retval, _("while allocating buffer"));
1171 /* Write qcow2 data blocks */
1172 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) {
1173 if ((blk >= fs->super->s_first_data_block) &&
1174 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
1175 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
1177 com_err(program_name, retval,
1178 _("error reading block %llu"), blk);
1181 if (scramble_block_map &&
1182 ext2fs_test_block_bitmap2(scramble_block_map, blk))
1183 scramble_dir_block(fs, blk, buf);
1184 if (check_zero_block(buf, fs->blocksize))
1187 if (update_refcount(fd, img, offset, offset)) {
1188 /* Make space for another refcount block */
1189 offset += img->cluster_size;
1190 seek_set(fd, offset);
1192 * We have created the new refcount block, this
1193 * means that we need to refcount it as well.
1194 * So the previous update_refcount refcounted
1195 * the block itself and now we are going to
1196 * create refcount for data. New refcount
1197 * block should not be created!
1199 if (update_refcount(fd, img, offset, offset)) {
1200 fprintf(stderr, _("Programming error: "
1201 "multiple sequential refcount "
1202 "blocks created!\n"));
1207 generic_write(fd, buf, fs->blocksize, blk);
1209 if (add_l2_item(img, blk, offset,
1210 offset + img->cluster_size)) {
1211 offset += img->cluster_size;
1212 if (update_refcount(fd, img, offset,
1213 offset + img->cluster_size)) {
1214 offset += img->cluster_size;
1215 if (update_refcount(fd, img, offset,
1218 _("Programming error: multiple sequential refcount "
1219 "blocks created!\n"));
1223 offset += img->cluster_size;
1224 seek_set(fd, offset);
1228 offset += img->cluster_size;
1231 update_refcount(fd, img, offset, offset);
1232 flush_l2_cache(img);
1233 sync_refcount(fd, img);
1236 seek_set(fd, img->l1_offset);
1237 size = img->l1_size * sizeof(__u64);
1238 generic_write(fd, (char *)img->l1_table, size, NO_BLK);
1240 ext2fs_free_mem(&buf);
1241 free_qcow2_image(img);
1244 static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags)
1246 struct process_block_struct pb;
1247 struct ext2_inode inode;
1248 ext2_inode_scan scan;
1253 meta_blocks_count = 0;
1254 retval = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
1257 com_err(program_name, retval,
1258 _("while allocating block bitmap"));
1262 if (flags & E2IMAGE_SCRAMBLE_FLAG) {
1263 retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
1264 &scramble_block_map);
1266 com_err(program_name, retval,
1267 _("while allocating scramble block bitmap"));
1272 mark_table_blocks(fs);
1274 printf(_("Scanning inodes...\n"));
1276 retval = ext2fs_open_inode_scan(fs, 0, &scan);
1278 com_err(program_name, retval,"%s",
1279 _("while opening inode scan"));
1283 retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
1285 com_err(program_name, 0, "%s",
1286 _("Can't allocate block buffer"));
1290 use_inode_shortcuts(fs, 1);
1291 stashed_inode = &inode;
1293 retval = ext2fs_get_next_inode(scan, &ino, &inode);
1294 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
1297 com_err(program_name, retval, "%s",
1298 _("while getting next inode"));
1303 if (!inode.i_links_count)
1305 if (ext2fs_file_acl_block(fs, &inode)) {
1306 ext2fs_mark_block_bitmap2(meta_block_map,
1307 ext2fs_file_acl_block(fs, &inode));
1308 meta_blocks_count++;
1310 if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
1315 pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
1316 if (LINUX_S_ISDIR(inode.i_mode) ||
1317 (LINUX_S_ISLNK(inode.i_mode) &&
1318 ext2fs_inode_has_valid_blocks2(fs, &inode)) ||
1319 ino == fs->super->s_journal_inum) {
1320 retval = ext2fs_block_iterate3(fs, ino,
1321 BLOCK_FLAG_READ_ONLY, block_buf,
1322 process_dir_block, &pb);
1324 com_err(program_name, retval,
1325 _("while iterating over inode %u"),
1330 if ((inode.i_flags & EXT4_EXTENTS_FL) ||
1331 inode.i_block[EXT2_IND_BLOCK] ||
1332 inode.i_block[EXT2_DIND_BLOCK] ||
1333 inode.i_block[EXT2_TIND_BLOCK] || all_data) {
1334 retval = ext2fs_block_iterate3(fs,
1335 ino, BLOCK_FLAG_READ_ONLY, block_buf,
1336 process_file_block, &pb);
1338 com_err(program_name, retval,
1339 _("while iterating over inode %u"), ino);
1345 use_inode_shortcuts(fs, 0);
1347 if (type & E2IMAGE_QCOW2)
1348 output_qcow2_meta_data_blocks(fs, fd);
1350 output_meta_data_blocks(fs, fd, flags);
1352 ext2fs_free_mem(&block_buf);
1353 ext2fs_close_inode_scan(scan);
1354 ext2fs_free_block_bitmap(meta_block_map);
1355 if (type & E2IMAGE_SCRAMBLE_FLAG)
1356 ext2fs_free_block_bitmap(scramble_block_map);
1359 static void install_image(char *device, char *image_fn, int type)
1363 int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS;
1369 com_err(program_name, 0, _("Raw and qcow2 images cannot"
1374 #ifdef CONFIG_TESTIO_DEBUG
1375 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1376 io_ptr = test_io_manager;
1377 test_io_backing_manager = unix_io_manager;
1380 io_ptr = unix_io_manager;
1382 retval = ext2fs_open (image_fn, open_flag, 0, 0,
1385 com_err (program_name, retval, _("while trying to open %s"),
1390 retval = ext2fs_read_bitmaps (fs);
1392 com_err(program_name, retval, _("error reading bitmaps"));
1396 fd = ext2fs_open_file(image_fn, O_RDONLY, 0);
1402 retval = io_ptr->open(device, IO_FLAG_RW, &io);
1404 com_err(device, 0, _("while opening device file"));
1408 ext2fs_rewrite_to_io(fs, io);
1410 seek_set(fd, fs->image_header->offset_inode);
1412 retval = ext2fs_image_inode_read(fs, fd, 0);
1414 com_err(image_fn, 0, _("while restoring the image table"));
1422 static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name)
1425 *fd = ext2fs_open_file(name, O_RDONLY, 0600);
1429 return qcow2_read_header(*fd);
1432 int main (int argc, char ** argv)
1437 char *image_fn, offset_opt[64];
1438 struct ext2_qcow2_hdr *header = NULL;
1439 int open_flag = EXT2_FLAG_64BITS;
1442 int mount_flags = 0;
1446 int ignore_rw_mount = 0;
1451 setlocale(LC_MESSAGES, "");
1452 setlocale(LC_CTYPE, "");
1453 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
1454 textdomain(NLS_CAT_NAME);
1455 set_com_err_gettext(gettext);
1457 fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION,
1460 program_name = *argv;
1461 add_error_table(&et_ext2_error_table);
1462 while ((c = getopt(argc, argv, "nrsIQafo:O:pc")) != EOF)
1465 flags |= E2IMAGE_INSTALL_FLAG;
1470 img_type |= E2IMAGE_QCOW2;
1475 img_type |= E2IMAGE_RAW;
1478 flags |= E2IMAGE_SCRAMBLE_FLAG;
1484 ignore_rw_mount = 1;
1490 source_offset = strtoull(optarg, NULL, 0);
1493 dest_offset = strtoull(optarg, NULL, 0);
1504 if (optind == argc - 1 &&
1505 (source_offset || dest_offset))
1507 else if (optind != argc - 2 )
1510 if (all_data && !img_type) {
1511 com_err(program_name, 0, _("-a option can only be used "
1512 "with raw or QCOW2 images."));
1515 if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) {
1516 com_err(program_name, 0,
1517 _("Offsets are only allowed with raw images."));
1520 if (move_mode && img_type != E2IMAGE_RAW) {
1521 com_err(program_name, 0,
1522 _("Move mode is only allowed with raw images."));
1525 if (move_mode && !all_data) {
1526 com_err(program_name, 0,
1527 _("Move mode requires all data mode."));
1530 device_name = argv[optind];
1532 image_fn = device_name;
1533 else image_fn = argv[optind+1];
1535 retval = ext2fs_check_if_mounted(device_name, &mount_flags);
1537 com_err(program_name, retval, _("checking if mounted"));
1541 if (img_type && !ignore_rw_mount &&
1542 (mount_flags & EXT2_MF_MOUNTED) &&
1543 !(mount_flags & EXT2_MF_READONLY)) {
1544 fprintf(stderr, _("\nRunning e2image on a R/W mounted "
1545 "filesystem can result in an\n"
1546 "inconsistent image which will not be useful "
1547 "for debugging purposes.\n"
1548 "Use -f option if you really want to do that.\n"));
1552 if (flags & E2IMAGE_INSTALL_FLAG) {
1553 install_image(device_name, image_fn, img_type);
1557 if (img_type & E2IMAGE_RAW) {
1558 header = check_qcow2_image(&qcow2_fd, device_name);
1560 flags |= E2IMAGE_IS_QCOW2_FLAG;
1564 sprintf(offset_opt, "offset=%llu", source_offset);
1565 retval = ext2fs_open2(device_name, offset_opt, open_flag, 0, 0,
1566 unix_io_manager, &fs);
1568 com_err (program_name, retval, _("while trying to open %s"),
1570 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout);
1575 if (strcmp(image_fn, "-") == 0)
1578 int o_flags = O_CREAT|O_RDWR;
1580 if (img_type != E2IMAGE_RAW)
1582 if (access(image_fn, F_OK) != 0)
1583 flags |= E2IMAGE_CHECK_ZERO_FLAG;
1584 fd = ext2fs_open_file(image_fn, o_flags, 0600);
1586 com_err(program_name, errno,
1587 _("while trying to open %s"), image_fn);
1592 seek_set(fd, dest_offset);
1594 if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) {
1595 com_err(program_name, 0, _("QCOW2 image can not be written to "
1600 if (fstat(fd, &st)) {
1601 com_err(program_name, 0, _("Can not stat output\n"));
1604 if (S_ISBLK(st.st_mode))
1607 if (flags & E2IMAGE_IS_QCOW2_FLAG) {
1608 ret = qcow2_write_raw_image(qcow2_fd, fd, header);
1610 if (ret == -QCOW_COMPRESSED)
1611 fprintf(stderr, _("Image (%s) is compressed\n"),
1613 if (ret == -QCOW_ENCRYPTED)
1614 fprintf(stderr, _("Image (%s) is encrypted\n"),
1616 com_err(program_name, ret,
1617 _("while trying to convert qcow2 image"
1618 " (%s) into raw image (%s)"),
1619 device_name, image_fn);
1625 if (img_type != E2IMAGE_RAW) {
1626 fprintf(stderr, _("The -c option only supported "
1631 fprintf(stderr, _("The -c option is not supported "
1632 "when writing to stdout\n"));
1635 retval = ext2fs_get_mem(fs->blocksize, &check_buf);
1637 com_err(program_name, retval,
1638 _("while allocating check_buf"));
1642 if (show_progress && (img_type != E2IMAGE_RAW)) {
1643 fprintf(stderr, _("The -p option only supported "
1648 write_raw_image_file(fs, fd, img_type, flags);
1650 write_image_file(fs, fd);
1654 printf(_("%d blocks already contained the data to be copied.\n"),
1662 remove_error_table(&et_ext2_error_table);