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 "et/com_err.h"
47 #include "uuid/uuid.h"
49 #include "ext2fs/e2image.h"
50 #include "ext2fs/qcow2.h"
52 #include "support/nls-enable.h"
53 #include "support/plausible.h"
54 #include "../version.h"
56 #define QCOW_OFLAG_COPIED (1LL << 63)
57 #define NO_BLK ((blk64_t) -1)
61 #define E2IMAGE_QCOW2 2
64 #define E2IMAGE_INSTALL_FLAG 1
65 #define E2IMAGE_SCRAMBLE_FLAG 2
66 #define E2IMAGE_IS_QCOW2_FLAG 4
67 #define E2IMAGE_CHECK_ZERO_FLAG 8
69 static const char * program_name = "e2image";
70 static char * device_name = NULL;
72 static char output_is_blk;
74 /* writing to blk device: don't skip zeroed blocks */
75 static blk64_t source_offset, dest_offset;
76 static char move_mode;
77 static char show_progress;
78 static char *check_buf;
79 static int skipped_blocks;
81 static blk64_t align_offset(blk64_t offset, unsigned int n)
83 return (offset + n - 1) & ~((blk64_t) n - 1);
86 static int get_bits_from_size(size_t size)
94 /* Not a power of two */
104 static void usage(void)
106 fprintf(stderr, _("Usage: %s [ -r|Q ] [ -fr ] device image-file\n"),
108 fprintf(stderr, _(" %s -I device image-file\n"), program_name);
109 fprintf(stderr, _(" %s -ra [ -cfnp ] [ -o src_offset ] "
110 "[ -O dest_offset ] src_fs [ dest_fs ]\n"),
115 static ext2_loff_t seek_relative(int fd, int offset)
117 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_CUR);
119 perror("seek_relative");
125 static ext2_loff_t seek_set(int fd, ext2_loff_t offset)
127 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_SET);
136 * Returns true if the block we are about to write is identical to
137 * what is already on the disk.
139 static int check_block(int fd, void *buf, void *cbuf, int blocksize)
142 int count = blocksize, ret;
148 ret = read(fd, cp, count);
150 perror("check_block");
156 ret = memcmp(buf, cbuf, blocksize);
157 seek_relative(fd, -blocksize);
158 return (ret == 0) ? 1 : 0;
161 static void generic_write(int fd, void *buf, int blocksize, blk64_t block)
163 int count, free_buf = 0;
171 err = ext2fs_get_arrayzero(1, blocksize, &buf);
173 com_err(program_name, err, "%s",
174 _("while allocating buffer"));
179 printf(_("Writing block %llu\n"), (unsigned long long) block);
181 seek_relative(fd, blocksize);
182 goto free_and_return;
184 count = write(fd, buf, blocksize);
185 if (count != blocksize) {
192 com_err(program_name, err,
193 _("error writing block %llu"), block);
195 com_err(program_name, err, "%s",
196 _("error in generic_write()"));
202 ext2fs_free_mem(&buf);
205 static void write_header(int fd, void *hdr, int hdr_size, int wrt_size)
211 if (hdr_size > wrt_size) {
212 fprintf(stderr, "%s",
213 _("Error: header size is bigger than wrt_size\n"));
216 ret = ext2fs_get_mem(wrt_size, &header_buf);
218 fputs(_("Couldn't allocate header buffer\n"), stderr);
223 memset(header_buf, 0, wrt_size);
226 memcpy(header_buf, hdr, hdr_size);
228 generic_write(fd, header_buf, wrt_size, NO_BLK);
230 ext2fs_free_mem(&header_buf);
233 static void write_image_file(ext2_filsys fs, int fd)
235 struct ext2_image_hdr hdr;
239 write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize);
240 memset(&hdr, 0, sizeof(struct ext2_image_hdr));
242 hdr.offset_super = seek_relative(fd, 0);
243 retval = ext2fs_image_super_write(fs, fd, 0);
245 com_err(program_name, retval, "%s",
246 _("while writing superblock"));
250 hdr.offset_inode = seek_relative(fd, 0);
251 retval = ext2fs_image_inode_write(fs, fd,
252 (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0);
254 com_err(program_name, retval, "%s",
255 _("while writing inode table"));
259 hdr.offset_blockmap = seek_relative(fd, 0);
260 retval = ext2fs_image_bitmap_write(fs, fd, 0);
262 com_err(program_name, retval, "%s",
263 _("while writing block bitmap"));
267 hdr.offset_inodemap = seek_relative(fd, 0);
268 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP);
270 com_err(program_name, retval, "%s",
271 _("while writing inode bitmap"));
275 hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE;
276 strcpy(hdr.magic_descriptor, "Ext2 Image 1.0");
277 gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname));
278 strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1);
279 hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0;
280 hdr.fs_blocksize = fs->blocksize;
282 if (stat(device_name, &st) == 0)
283 hdr.fs_device = st.st_rdev;
285 if (fstat(fd, &st) == 0) {
286 hdr.image_device = st.st_dev;
287 hdr.image_inode = st.st_ino;
289 memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid));
291 hdr.image_time = time(0);
292 write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize);
296 * These set of functions are used to write a RAW image file.
298 static ext2fs_block_bitmap meta_block_map;
299 static ext2fs_block_bitmap scramble_block_map; /* Directory blocks to be scrambled */
300 static blk64_t meta_blocks_count;
302 struct process_block_struct {
308 * These subroutines short circuits ext2fs_get_blocks and
309 * ext2fs_check_directory; we use them since we already have the inode
310 * structure, so there's no point in letting the ext2fs library read
313 static ino_t stashed_ino = 0;
314 static struct ext2_inode *stashed_inode;
316 static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)),
322 if ((ino != stashed_ino) || !stashed_inode)
323 return EXT2_ET_CALLBACK_NOTHANDLED;
325 for (i=0; i < EXT2_N_BLOCKS; i++)
326 blocks[i] = stashed_inode->i_block[i];
330 static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)),
333 if ((ino != stashed_ino) || !stashed_inode)
334 return EXT2_ET_CALLBACK_NOTHANDLED;
336 if (!LINUX_S_ISDIR(stashed_inode->i_mode))
337 return EXT2_ET_NO_DIRECTORY;
341 static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
343 struct ext2_inode *inode)
345 if ((ino != stashed_ino) || !stashed_inode)
346 return EXT2_ET_CALLBACK_NOTHANDLED;
347 *inode = *stashed_inode;
351 static void use_inode_shortcuts(ext2_filsys fs, int use_shortcuts)
354 fs->get_blocks = meta_get_blocks;
355 fs->check_directory = meta_check_directory;
356 fs->read_inode = meta_read_inode;
360 fs->check_directory = 0;
365 static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
367 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
368 blk64_t ref_block EXT2FS_ATTR((unused)),
369 int ref_offset EXT2FS_ATTR((unused)),
370 void *priv_data EXT2FS_ATTR((unused)))
372 struct process_block_struct *p;
374 p = (struct process_block_struct *) priv_data;
376 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
378 if (scramble_block_map && p->is_dir && blockcnt >= 0)
379 ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr);
383 static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
385 e2_blkcnt_t blockcnt,
386 blk64_t ref_block EXT2FS_ATTR((unused)),
387 int ref_offset EXT2FS_ATTR((unused)),
388 void *priv_data EXT2FS_ATTR((unused)))
390 if (blockcnt < 0 || all_data) {
391 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
397 static void mark_table_blocks(ext2_filsys fs)
399 blk64_t first_block, b;
402 first_block = fs->super->s_first_data_block;
404 * Mark primary superblock
406 ext2fs_mark_block_bitmap2(meta_block_map, first_block);
410 * Mark the primary superblock descriptors
412 for (j = 0; j < fs->desc_blocks; j++) {
413 ext2fs_mark_block_bitmap2(meta_block_map,
414 ext2fs_descriptor_block_loc2(fs, first_block, j));
416 meta_blocks_count += fs->desc_blocks;
418 for (i = 0; i < fs->group_desc_count; i++) {
420 * Mark the blocks used for the inode table
422 if ((output_is_blk ||
423 !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) &&
424 ext2fs_inode_table_loc(fs, i)) {
425 unsigned int end = (unsigned) fs->inode_blocks_per_group;
426 /* skip unused blocks */
427 if (!output_is_blk && ext2fs_has_group_desc_csum(fs))
428 end -= (ext2fs_bg_itable_unused(fs, i) /
429 EXT2_INODES_PER_BLOCK(fs->super));
430 for (j = 0, b = ext2fs_inode_table_loc(fs, i);
433 ext2fs_mark_block_bitmap2(meta_block_map, b);
439 * Mark block used for the block bitmap
441 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
442 ext2fs_block_bitmap_loc(fs, i)) {
443 ext2fs_mark_block_bitmap2(meta_block_map,
444 ext2fs_block_bitmap_loc(fs, i));
449 * Mark block used for the inode bitmap
451 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
452 ext2fs_inode_bitmap_loc(fs, i)) {
453 ext2fs_mark_block_bitmap2(meta_block_map,
454 ext2fs_inode_bitmap_loc(fs, i));
461 * This function returns 1 if the specified block is all zeros
463 static int check_zero_block(char *buf, int blocksize)
466 int left = blocksize;
478 static int name_id[256];
480 #define EXT4_MAX_REC_LEN ((1<<16)-1)
482 static void scramble_dir_block(ext2_filsys fs, blk64_t blk, char *buf)
485 struct ext2_dir_entry_2 *dirent;
486 unsigned int rec_len;
489 end = buf + fs->blocksize;
490 for (p = buf; p < end-8; p += rec_len) {
491 dirent = (struct ext2_dir_entry_2 *) p;
492 rec_len = dirent->rec_len;
493 #ifdef WORDS_BIGENDIAN
494 rec_len = ext2fs_swab16(rec_len);
496 if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0)
497 rec_len = fs->blocksize;
499 rec_len = (rec_len & 65532) | ((rec_len & 3) << 16);
501 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len);
503 if (rec_len < 8 || (rec_len % 4) ||
505 printf(_("Corrupt directory block %llu: "
506 "bad rec_len (%d)\n"),
507 (unsigned long long) blk, rec_len);
509 (void) ext2fs_set_rec_len(fs, rec_len,
510 (struct ext2_dir_entry *) dirent);
511 #ifdef WORDS_BIGENDIAN
512 dirent->rec_len = ext2fs_swab16(dirent->rec_len);
516 if (dirent->name_len + 8U > rec_len) {
517 printf(_("Corrupt directory block %llu: "
518 "bad name_len (%d)\n"),
519 (unsigned long long) blk, dirent->name_len);
520 dirent->name_len = rec_len - 8;
524 len = rec_len - dirent->name_len - 8;
526 memset(cp+dirent->name_len, 0, len);
527 if (dirent->name_len==1 && cp[0] == '.')
529 if (dirent->name_len==2 && cp[0] == '.' && cp[1] == '.')
532 memset(cp, 'A', dirent->name_len);
533 len = dirent->name_len;
535 while ((len > 0) && (id > 0)) {
544 static char got_sigint;
546 static void sigint_handler(int unused EXT2FS_ATTR((unused)))
549 signal (SIGINT, SIG_DFL);
552 #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \
553 ((float) (b)))) + 0.5))
554 #define calc_rate(t, b, d) (((float)(t) / ((1024 * 1024) / (b))) / (d))
556 static int print_progress(blk64_t num, blk64_t total)
558 return fprintf(stderr, _("%llu / %llu blocks (%d%%)"), num, total,
559 calc_percent(num, total));
562 static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags)
566 char *buf, *zero_buf;
569 blk64_t distance = 0;
570 blk64_t end = ext2fs_blocks_count(fs->super);
571 time_t last_update = 0;
572 time_t start_time = 0;
573 blk64_t total_written = 0;
576 retval = ext2fs_get_mem(fs->blocksize, &buf);
578 com_err(program_name, retval, "%s",
579 _("while allocating buffer"));
582 retval = ext2fs_get_memzero(fs->blocksize, &zero_buf);
584 com_err(program_name, retval, "%s",
585 _("while allocating buffer"));
589 fprintf(stderr, "%s", _("Copying "));
590 bscount = print_progress(total_written, meta_blocks_count);
592 last_update = time(NULL);
593 start_time = time(NULL);
595 /* when doing an in place move to the right, you can't start
596 at the beginning or you will overwrite data, so instead
597 divide the fs up into distance size chunks and write them
599 if (move_mode && dest_offset > source_offset) {
600 distance = (dest_offset - source_offset) / fs->blocksize;
601 if (distance < ext2fs_blocks_count(fs->super))
602 start = ext2fs_blocks_count(fs->super) - distance;
605 signal (SIGINT, sigint_handler);
608 seek_set(fd, (start * fs->blocksize) + dest_offset);
609 for (blk = start; blk < end; blk++) {
612 /* moving to the right */
613 if (distance >= ext2fs_blocks_count(fs->super)||
614 start == ext2fs_blocks_count(fs->super) -
616 kill(getpid(), SIGINT);
618 /* moving to the left */
619 if (blk < (source_offset - dest_offset) /
621 kill(getpid(), SIGINT);
625 fprintf(stderr, "%s",
626 _("Stopping now will destroy the filesystem, "
627 "interrupt again if you are sure\n"));
629 fprintf(stderr, "%s", _("Copying "));
630 bscount = print_progress(total_written,
637 if (show_progress && last_update != time(NULL)) {
639 last_update = time(NULL);
642 bscount = print_progress(total_written,
644 duration = time(NULL) - start_time;
645 if (duration > 5 && total_written) {
646 time_t est = (duration * meta_blocks_count /
647 total_written) - duration;
649 strftime(buff, 30, "%T", gmtime(&est));
652 _(" %s remaining at %.2f MB/s"),
653 buff, calc_rate(total_written,
659 if ((blk >= fs->super->s_first_data_block) &&
660 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
661 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
663 com_err(program_name, retval,
664 _("error reading block %llu"), blk);
667 if (scramble_block_map &&
668 ext2fs_test_block_bitmap2(scramble_block_map, blk))
669 scramble_dir_block(fs, blk, buf);
670 if ((flags & E2IMAGE_CHECK_ZERO_FLAG) &&
671 check_zero_block(buf, fs->blocksize))
674 seek_relative(fd, sparse);
676 if (check_block(fd, buf, check_buf, fs->blocksize)) {
677 seek_relative(fd, fs->blocksize);
680 generic_write(fd, buf, fs->blocksize, blk);
685 generic_write(fd, zero_buf,
689 sparse += fs->blocksize;
690 if (sparse > 1024*1024) {
691 seek_relative(fd, 1024*1024);
696 if (distance && start) {
697 if (start < distance) {
703 if (end < distance) {
704 /* past overlap, do rest in one go */
712 signal (SIGINT, SIG_DFL);
714 time_t duration = time(NULL) - start_time;
717 strftime(buff, 30, "%T", gmtime(&duration));
718 fprintf(stderr, _("Copied %llu / %llu blocks (%d%%) in %s "),
719 total_written, meta_blocks_count,
720 calc_percent(total_written, meta_blocks_count), buff);
722 fprintf(stderr, _("at %.2f MB/s"),
723 calc_rate(total_written, fs->blocksize, duration));
724 fputs(" \n", stderr);
726 #ifdef HAVE_FTRUNCATE64
730 offset = seek_set(fd,
731 fs->blocksize * ext2fs_blocks_count(fs->super) + dest_offset);
733 offset = seek_relative(fd, sparse);
735 if (ftruncate64(fd, offset) < 0) {
736 seek_relative(fd, -1);
737 generic_write(fd, zero_buf, 1, NO_BLK);
741 if (sparse && !distance) {
742 seek_relative(fd, sparse-1);
743 generic_write(fd, zero_buf, 1, NO_BLK);
746 ext2fs_free_mem(&zero_buf);
747 ext2fs_free_mem(&buf);
750 static void init_l1_table(struct ext2_qcow2_image *image)
755 ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table);
757 com_err(program_name, ret, "%s",
758 _("while allocating l1 table"));
762 image->l1_table = l1_table;
765 static void init_l2_cache(struct ext2_qcow2_image *image)
767 unsigned int count, i;
768 struct ext2_qcow2_l2_cache *cache;
769 struct ext2_qcow2_l2_table *table;
772 ret = ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache),
777 count = (image->l1_size > L2_CACHE_PREALLOC) ? L2_CACHE_PREALLOC :
780 cache->count = count;
782 cache->next_offset = image->l2_offset;
784 for (i = 0; i < count; i++) {
785 ret = ext2fs_get_arrayzero(1,
786 sizeof(struct ext2_qcow2_l2_table), &table);
790 ret = ext2fs_get_arrayzero(image->l2_size,
791 sizeof(__u64), &table->data);
795 table->next = cache->free_head;
796 cache->free_head = table;
799 image->l2_cache = cache;
803 com_err(program_name, ret, "%s", _("while allocating l2 cache"));
807 static void put_l2_cache(struct ext2_qcow2_image *image)
809 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
810 struct ext2_qcow2_l2_table *tmp, *table;
815 table = cache->free_head;
816 cache->free_head = NULL;
821 ext2fs_free_mem(&tmp->data);
822 ext2fs_free_mem(&tmp);
825 if (cache->free != cache->count) {
826 fprintf(stderr, "%s", _("Warning: There are still tables in "
827 "the cache while putting the cache, "
828 "data will be lost so the image may "
830 table = cache->used_head;
831 cache->used_head = NULL;
835 ext2fs_free_mem(&cache);
838 static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset)
840 struct ext2_qcow2_refcount *ref;
841 blk64_t table_clusters;
844 ref = &(img->refcount);
847 * One refcount block addresses 2048 clusters, one refcount table
848 * addresses cluster/sizeof(__u64) refcount blocks, and we need
849 * to address meta_blocks_count clusters + qcow2 metadata clusters
852 table_clusters = meta_blocks_count + (table_offset >>
854 table_clusters >>= (img->cluster_bits + 6 - 1);
855 table_clusters = (table_clusters == 0) ? 1 : table_clusters;
857 ref->refcount_table_offset = table_offset;
858 ref->refcount_table_clusters = table_clusters;
859 ref->refcount_table_index = 0;
860 ref->refcount_block_index = 0;
862 /* Allocate refcount table */
863 ret = ext2fs_get_arrayzero(ref->refcount_table_clusters,
864 img->cluster_size, &ref->refcount_table);
868 /* Allocate refcount block */
869 ret = ext2fs_get_arrayzero(1, img->cluster_size, &ref->refcount_block);
871 ext2fs_free_mem(&ref->refcount_table);
876 static int initialize_qcow2_image(int fd, ext2_filsys fs,
877 struct ext2_qcow2_image *image)
879 struct ext2_qcow2_hdr *header;
880 blk64_t total_size, offset;
881 int shift, l2_bits, header_size, l1_size, ret;
882 int cluster_bits = get_bits_from_size(fs->blocksize);
883 struct ext2_super_block *sb = fs->super;
885 /* Allocate header */
886 ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header);
890 total_size = ext2fs_blocks_count(sb) << cluster_bits;
891 image->cluster_size = fs->blocksize;
892 image->l2_size = 1 << (cluster_bits - 3);
893 image->cluster_bits = cluster_bits;
896 header->magic = ext2fs_cpu_to_be32(QCOW_MAGIC);
897 header->version = ext2fs_cpu_to_be32(QCOW_VERSION);
898 header->size = ext2fs_cpu_to_be64(total_size);
899 header->cluster_bits = ext2fs_cpu_to_be32(cluster_bits);
901 header_size = (sizeof(struct ext2_qcow2_hdr) + 7) & ~7;
902 offset = align_offset(header_size, image->cluster_size);
904 header->l1_table_offset = ext2fs_cpu_to_be64(offset);
905 image->l1_offset = offset;
907 l2_bits = cluster_bits - 3;
908 shift = cluster_bits + l2_bits;
909 l1_size = ((total_size + (1LL << shift) - 1) >> shift);
910 header->l1_size = ext2fs_cpu_to_be32(l1_size);
911 image->l1_size = l1_size;
913 /* Make space for L1 table */
914 offset += align_offset(l1_size * sizeof(blk64_t), image->cluster_size);
916 /* Initialize refcounting */
917 ret = init_refcount(image, offset);
919 ext2fs_free_mem(&header);
922 header->refcount_table_offset = ext2fs_cpu_to_be64(offset);
923 header->refcount_table_clusters =
924 ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters);
925 offset += image->cluster_size;
926 offset += image->refcount.refcount_table_clusters <<
929 /* Make space for L2 tables */
930 image->l2_offset = offset;
931 offset += image->cluster_size;
933 /* Make space for first refcount block */
934 image->refcount.refcount_block_offset = offset;
937 /* Initialize l1 and l2 tables */
938 init_l1_table(image);
939 init_l2_cache(image);
944 static void free_qcow2_image(struct ext2_qcow2_image *img)
950 ext2fs_free_mem(&img->hdr);
953 ext2fs_free_mem(&img->l1_table);
955 if (img->refcount.refcount_table)
956 ext2fs_free_mem(&img->refcount.refcount_table);
957 if (img->refcount.refcount_block)
958 ext2fs_free_mem(&img->refcount.refcount_block);
962 ext2fs_free_mem(&img);
966 * Put table from used list (used_head) into free list (free_head).
967 * l2_table is used to return pointer to the next used table (used_head).
969 static void put_used_table(struct ext2_qcow2_image *img,
970 struct ext2_qcow2_l2_table **l2_table)
972 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
973 struct ext2_qcow2_l2_table *table;
975 table = cache->used_head;
976 cache->used_head = table->next;
980 cache->used_tail = NULL;
982 /* Clean the table for case we will need to use it again */
983 memset(table->data, 0, img->cluster_size);
984 table->next = cache->free_head;
985 cache->free_head = table;
989 *l2_table = cache->used_head;
992 static void flush_l2_cache(struct ext2_qcow2_image *image)
996 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
997 struct ext2_qcow2_l2_table *table = cache->used_head;
1000 /* Store current position */
1001 offset = seek_relative(fd, 0);
1004 while (cache->free < cache->count) {
1005 if (seek != table->offset) {
1006 seek_set(fd, table->offset);
1007 seek = table->offset;
1010 generic_write(fd, (char *)table->data, image->cluster_size,
1012 put_used_table(image, &table);
1013 seek += image->cluster_size;
1016 /* Restore previous position */
1017 seek_set(fd, offset);
1021 * Get first free table (from free_head) and put it into tail of used list
1023 * l2_table is used to return pointer to moved table.
1024 * Returns 1 if the cache is full, 0 otherwise.
1026 static void get_free_table(struct ext2_qcow2_image *image,
1027 struct ext2_qcow2_l2_table **l2_table)
1029 struct ext2_qcow2_l2_table *table;
1030 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1032 if (0 == cache->free)
1033 flush_l2_cache(image);
1035 table = cache->free_head;
1037 cache->free_head = table->next;
1039 if (cache->used_tail)
1040 cache->used_tail->next = table;
1042 /* First item in the used list */
1043 cache->used_head = table;
1045 cache->used_tail = table;
1051 static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk,
1052 blk64_t data, blk64_t next)
1054 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
1055 struct ext2_qcow2_l2_table *table = cache->used_tail;
1056 blk64_t l1_index = blk / img->l2_size;
1057 blk64_t l2_index = blk & (img->l2_size - 1);
1061 * Need to create new table if it does not exist,
1064 if (!table || (table->l1_index != l1_index)) {
1065 get_free_table(img, &table);
1066 table->l1_index = l1_index;
1067 table->offset = cache->next_offset;
1068 cache->next_offset = next;
1069 img->l1_table[l1_index] =
1070 ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED);
1074 table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED);
1078 static int update_refcount(int fd, struct ext2_qcow2_image *img,
1079 blk64_t offset, blk64_t rfblk_pos)
1081 struct ext2_qcow2_refcount *ref;
1085 ref = &(img->refcount);
1086 table_index = offset >> (2 * img->cluster_bits - 1);
1089 * Need to create new refcount block when the offset addresses
1090 * another item in the refcount table
1092 if (table_index != ref->refcount_table_index) {
1094 seek_set(fd, ref->refcount_block_offset);
1096 generic_write(fd, (char *)ref->refcount_block,
1097 img->cluster_size, NO_BLK);
1098 memset(ref->refcount_block, 0, img->cluster_size);
1100 ref->refcount_table[ref->refcount_table_index] =
1101 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1102 ref->refcount_block_offset = rfblk_pos;
1103 ref->refcount_block_index = 0;
1104 ref->refcount_table_index = table_index;
1109 * We are relying on the fact that we are creating the qcow2
1110 * image sequentially, hence we will always allocate refcount
1111 * block items sequentialy.
1113 ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1);
1114 ref->refcount_block_index++;
1118 static int sync_refcount(int fd, struct ext2_qcow2_image *img)
1120 struct ext2_qcow2_refcount *ref;
1122 ref = &(img->refcount);
1124 ref->refcount_table[ref->refcount_table_index] =
1125 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1126 seek_set(fd, ref->refcount_table_offset);
1127 generic_write(fd, (char *)ref->refcount_table,
1128 ref->refcount_table_clusters << img->cluster_bits, NO_BLK);
1130 seek_set(fd, ref->refcount_block_offset);
1131 generic_write(fd, (char *)ref->refcount_block, img->cluster_size,
1136 static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
1139 blk64_t blk, offset, size, end;
1141 struct ext2_qcow2_image *img;
1142 unsigned int header_size;
1144 /* allocate struct ext2_qcow2_image */
1145 retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img);
1147 com_err(program_name, retval, "%s",
1148 _("while allocating ext2_qcow2_image"));
1152 retval = initialize_qcow2_image(fd, fs, img);
1154 com_err(program_name, retval, "%s",
1155 _("while initializing ext2_qcow2_image"));
1158 header_size = align_offset(sizeof(struct ext2_qcow2_hdr),
1160 write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size);
1162 /* Refcount all qcow2 related metadata up to refcount_block_offset */
1163 end = img->refcount.refcount_block_offset;
1165 blk = end + img->cluster_size;
1166 for (offset = 0; offset <= end; offset += img->cluster_size) {
1167 if (update_refcount(fd, img, offset, blk)) {
1168 blk += img->cluster_size;
1170 * If we create new refcount block, we need to refcount
1173 end += img->cluster_size;
1176 seek_set(fd, offset);
1178 retval = ext2fs_get_mem(fs->blocksize, &buf);
1180 com_err(program_name, retval, "%s",
1181 _("while allocating buffer"));
1184 /* Write qcow2 data blocks */
1185 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) {
1186 if ((blk >= fs->super->s_first_data_block) &&
1187 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
1188 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
1190 com_err(program_name, retval,
1191 _("error reading block %llu"), blk);
1194 if (scramble_block_map &&
1195 ext2fs_test_block_bitmap2(scramble_block_map, blk))
1196 scramble_dir_block(fs, blk, buf);
1197 if (check_zero_block(buf, fs->blocksize))
1200 if (update_refcount(fd, img, offset, offset)) {
1201 /* Make space for another refcount block */
1202 offset += img->cluster_size;
1203 seek_set(fd, offset);
1205 * We have created the new refcount block, this
1206 * means that we need to refcount it as well.
1207 * So the previous update_refcount refcounted
1208 * the block itself and now we are going to
1209 * create refcount for data. New refcount
1210 * block should not be created!
1212 if (update_refcount(fd, img, offset, offset)) {
1213 fprintf(stderr, "%s",
1214 _("Programming error: multiple "
1215 "sequential refcount blocks "
1221 generic_write(fd, buf, fs->blocksize, blk);
1223 if (add_l2_item(img, blk, offset,
1224 offset + img->cluster_size)) {
1225 offset += img->cluster_size;
1226 if (update_refcount(fd, img, offset,
1227 offset + img->cluster_size)) {
1228 offset += img->cluster_size;
1229 if (update_refcount(fd, img, offset,
1231 fprintf(stderr, "%s",
1232 _("Programming error: multiple sequential refcount "
1233 "blocks created!\n"));
1237 offset += img->cluster_size;
1238 seek_set(fd, offset);
1242 offset += img->cluster_size;
1245 update_refcount(fd, img, offset, offset);
1246 flush_l2_cache(img);
1247 sync_refcount(fd, img);
1250 seek_set(fd, img->l1_offset);
1251 size = img->l1_size * sizeof(__u64);
1252 generic_write(fd, (char *)img->l1_table, size, NO_BLK);
1254 ext2fs_free_mem(&buf);
1255 free_qcow2_image(img);
1258 static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags)
1260 struct process_block_struct pb;
1261 struct ext2_inode inode;
1262 ext2_inode_scan scan;
1267 meta_blocks_count = 0;
1268 retval = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
1271 com_err(program_name, retval, "%s",
1272 _("while allocating block bitmap"));
1276 if (flags & E2IMAGE_SCRAMBLE_FLAG) {
1277 retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
1278 &scramble_block_map);
1280 com_err(program_name, retval, "%s",
1281 _("while allocating scramble block bitmap"));
1286 mark_table_blocks(fs);
1288 fprintf(stderr, "%s", _("Scanning inodes...\n"));
1290 retval = ext2fs_open_inode_scan(fs, 0, &scan);
1292 com_err(program_name, retval, "%s",
1293 _("while opening inode scan"));
1297 retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
1299 com_err(program_name, 0, "%s",
1300 _("Can't allocate block buffer"));
1304 use_inode_shortcuts(fs, 1);
1305 stashed_inode = &inode;
1307 retval = ext2fs_get_next_inode(scan, &ino, &inode);
1308 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
1311 com_err(program_name, retval, "%s",
1312 _("while getting next inode"));
1317 if (!inode.i_links_count)
1319 if (ext2fs_file_acl_block(fs, &inode)) {
1320 ext2fs_mark_block_bitmap2(meta_block_map,
1321 ext2fs_file_acl_block(fs, &inode));
1322 meta_blocks_count++;
1324 if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
1329 pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
1330 if (LINUX_S_ISDIR(inode.i_mode) ||
1331 (LINUX_S_ISLNK(inode.i_mode) &&
1332 ext2fs_inode_has_valid_blocks2(fs, &inode)) ||
1333 ino == fs->super->s_journal_inum) {
1334 retval = ext2fs_block_iterate3(fs, ino,
1335 BLOCK_FLAG_READ_ONLY, block_buf,
1336 process_dir_block, &pb);
1338 com_err(program_name, retval,
1339 _("while iterating over inode %u"),
1344 if ((inode.i_flags & EXT4_EXTENTS_FL) ||
1345 inode.i_block[EXT2_IND_BLOCK] ||
1346 inode.i_block[EXT2_DIND_BLOCK] ||
1347 inode.i_block[EXT2_TIND_BLOCK] || all_data) {
1348 retval = ext2fs_block_iterate3(fs,
1349 ino, BLOCK_FLAG_READ_ONLY, block_buf,
1350 process_file_block, &pb);
1352 com_err(program_name, retval,
1353 _("while iterating over inode %u"), ino);
1359 use_inode_shortcuts(fs, 0);
1361 if (type & E2IMAGE_QCOW2)
1362 output_qcow2_meta_data_blocks(fs, fd);
1364 output_meta_data_blocks(fs, fd, flags);
1366 ext2fs_free_mem(&block_buf);
1367 ext2fs_close_inode_scan(scan);
1368 ext2fs_free_block_bitmap(meta_block_map);
1369 if (type & E2IMAGE_SCRAMBLE_FLAG)
1370 ext2fs_free_block_bitmap(scramble_block_map);
1373 static void install_image(char *device, char *image_fn, int type)
1377 int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS;
1383 com_err(program_name, 0, "%s",
1384 _("Raw and qcow2 images cannot be installed"));
1388 #ifdef CONFIG_TESTIO_DEBUG
1389 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1390 io_ptr = test_io_manager;
1391 test_io_backing_manager = unix_io_manager;
1394 io_ptr = unix_io_manager;
1396 retval = ext2fs_open (image_fn, open_flag, 0, 0,
1399 com_err(program_name, retval, _("while trying to open %s"),
1404 retval = ext2fs_read_bitmaps (fs);
1406 com_err(program_name, retval, "%s", _("error reading bitmaps"));
1410 fd = ext2fs_open_file(image_fn, O_RDONLY, 0);
1416 retval = io_ptr->open(device, IO_FLAG_RW, &io);
1418 com_err(device, 0, "%s", _("while opening device file"));
1422 ext2fs_rewrite_to_io(fs, io);
1424 seek_set(fd, fs->image_header->offset_inode);
1426 retval = ext2fs_image_inode_read(fs, fd, 0);
1428 com_err(image_fn, 0, "%s",
1429 _("while restoring the image table"));
1434 ext2fs_close_free(&fs);
1437 static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name)
1440 *fd = ext2fs_open_file(name, O_RDONLY, 0600);
1444 return qcow2_read_header(*fd);
1447 int main (int argc, char ** argv)
1452 char *image_fn, offset_opt[64];
1453 struct ext2_qcow2_hdr *header = NULL;
1454 int open_flag = EXT2_FLAG_64BITS;
1457 int mount_flags = 0;
1461 int ignore_rw_mount = 0;
1466 setlocale(LC_MESSAGES, "");
1467 setlocale(LC_CTYPE, "");
1468 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
1469 textdomain(NLS_CAT_NAME);
1470 set_com_err_gettext(gettext);
1472 fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION,
1475 program_name = *argv;
1476 add_error_table(&et_ext2_error_table);
1477 while ((c = getopt(argc, argv, "nrsIQafo:O:pc")) != EOF)
1480 flags |= E2IMAGE_INSTALL_FLAG;
1485 img_type |= E2IMAGE_QCOW2;
1490 img_type |= E2IMAGE_RAW;
1493 flags |= E2IMAGE_SCRAMBLE_FLAG;
1499 ignore_rw_mount = 1;
1505 source_offset = strtoull(optarg, NULL, 0);
1508 dest_offset = strtoull(optarg, NULL, 0);
1519 if (optind == argc - 1 &&
1520 (source_offset || dest_offset))
1522 else if (optind != argc - 2 )
1525 if (all_data && !img_type) {
1526 com_err(program_name, 0, "%s", _("-a option can only be used "
1527 "with raw or QCOW2 images."));
1530 if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) {
1531 com_err(program_name, 0, "%s",
1532 _("Offsets are only allowed with raw images."));
1535 if (move_mode && img_type != E2IMAGE_RAW) {
1536 com_err(program_name, 0, "%s",
1537 _("Move mode is only allowed with raw images."));
1540 if (move_mode && !all_data) {
1541 com_err(program_name, 0, "%s",
1542 _("Move mode requires all data mode."));
1545 device_name = argv[optind];
1547 image_fn = device_name;
1548 else image_fn = argv[optind+1];
1550 retval = ext2fs_check_if_mounted(device_name, &mount_flags);
1552 com_err(program_name, retval, "%s", _("checking if mounted"));
1556 if (img_type && !ignore_rw_mount &&
1557 (mount_flags & EXT2_MF_MOUNTED) &&
1558 !(mount_flags & EXT2_MF_READONLY)) {
1559 fprintf(stderr, "%s", _("\nRunning e2image on a R/W mounted "
1560 "filesystem can result in an\n"
1561 "inconsistent image which will not be useful "
1562 "for debugging purposes.\n"
1563 "Use -f option if you really want to do that.\n"));
1567 if (flags & E2IMAGE_INSTALL_FLAG) {
1568 install_image(device_name, image_fn, img_type);
1572 if (img_type & E2IMAGE_RAW) {
1573 header = check_qcow2_image(&qcow2_fd, device_name);
1575 flags |= E2IMAGE_IS_QCOW2_FLAG;
1579 sprintf(offset_opt, "offset=%llu", source_offset);
1580 retval = ext2fs_open2(device_name, offset_opt, open_flag, 0, 0,
1581 unix_io_manager, &fs);
1583 com_err (program_name, retval, _("while trying to open %s"),
1585 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout);
1586 if (retval == EXT2_ET_BAD_MAGIC)
1587 check_plausibility(device_name, CHECK_FS_EXIST, NULL);
1592 if (strcmp(image_fn, "-") == 0)
1595 int o_flags = O_CREAT|O_RDWR;
1597 if (img_type != E2IMAGE_RAW)
1599 if (access(image_fn, F_OK) != 0)
1600 flags |= E2IMAGE_CHECK_ZERO_FLAG;
1601 fd = ext2fs_open_file(image_fn, o_flags, 0600);
1603 com_err(program_name, errno,
1604 _("while trying to open %s"), image_fn);
1609 seek_set(fd, dest_offset);
1611 if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) {
1612 com_err(program_name, 0, "%s",
1613 _("QCOW2 image can not be written to the stdout!\n"));
1617 if (fstat(fd, &st)) {
1618 com_err(program_name, 0, "%s",
1619 _("Can not stat output\n"));
1622 if (S_ISBLK(st.st_mode))
1625 if (flags & E2IMAGE_IS_QCOW2_FLAG) {
1626 ret = qcow2_write_raw_image(qcow2_fd, fd, header);
1628 if (ret == -QCOW_COMPRESSED)
1629 fprintf(stderr, _("Image (%s) is compressed\n"),
1631 if (ret == -QCOW_ENCRYPTED)
1632 fprintf(stderr, _("Image (%s) is encrypted\n"),
1634 com_err(program_name, ret,
1635 _("while trying to convert qcow2 image"
1636 " (%s) into raw image (%s)"),
1637 device_name, image_fn);
1643 if (img_type != E2IMAGE_RAW) {
1644 fprintf(stderr, "%s", _("The -c option only supported "
1649 fprintf(stderr, "%s", _("The -c option not supported "
1650 "when writing to stdout\n"));
1653 retval = ext2fs_get_mem(fs->blocksize, &check_buf);
1655 com_err(program_name, retval, "%s",
1656 _("while allocating check_buf"));
1660 if (show_progress && (img_type != E2IMAGE_RAW)) {
1661 fprintf(stderr, "%s",
1662 _("The -p option only supported in raw mode\n"));
1666 write_raw_image_file(fs, fd, img_type, flags);
1668 write_image_file(fs, fd);
1670 ext2fs_close_free(&fs);
1672 printf(_("%d blocks already contained the data to be copied\n"),
1680 remove_error_table(&et_ext2_error_table);