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 "support/quotaio.h"
56 #include "../version.h"
58 #define QCOW_OFLAG_COPIED (1ULL << 63)
59 #define NO_BLK ((blk64_t) -1)
63 #define E2IMAGE_QCOW2 2
66 #define E2IMAGE_INSTALL_FLAG 1
67 #define E2IMAGE_SCRAMBLE_FLAG 2
68 #define E2IMAGE_IS_QCOW2_FLAG 4
69 #define E2IMAGE_CHECK_ZERO_FLAG 8
71 static const char * program_name = "e2image";
72 static char * device_name = NULL;
74 static char output_is_blk;
76 /* writing to blk device: don't skip zeroed blocks */
77 static blk64_t source_offset, dest_offset;
78 static char move_mode;
79 static char show_progress;
80 static char *check_buf;
81 static int skipped_blocks;
83 static blk64_t align_offset(blk64_t offset, unsigned int n)
85 return (offset + n - 1) & ~((blk64_t) n - 1);
88 static int get_bits_from_size(size_t size)
96 /* Not a power of two */
106 static void usage(void)
108 fprintf(stderr, _("Usage: %s [ -r|-Q ] [ -f ] [ -b superblock ] [ -B blocksize ] "
109 "device image-file\n"),
111 fprintf(stderr, _(" %s -I device image-file\n"), program_name);
112 fprintf(stderr, _(" %s -ra [ -cfnp ] [ -o src_offset ] "
113 "[ -O dest_offset ] src_fs [ dest_fs ]\n"),
118 static ext2_loff_t seek_relative(int fd, int offset)
120 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_CUR);
122 perror("seek_relative");
128 static ext2_loff_t seek_set(int fd, ext2_loff_t offset)
130 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_SET);
139 * Returns true if the block we are about to write is identical to
140 * what is already on the disk.
142 static int check_block(int fd, void *buf, void *cbuf, int blocksize)
145 int count = blocksize, ret;
151 ret = read(fd, cp, count);
153 perror("check_block");
159 ret = memcmp(buf, cbuf, blocksize);
160 seek_relative(fd, -blocksize);
161 return (ret == 0) ? 1 : 0;
164 static void generic_write(int fd, void *buf, int blocksize, blk64_t block)
166 int count, free_buf = 0;
174 err = ext2fs_get_arrayzero(1, blocksize, &buf);
176 com_err(program_name, err, "%s",
177 _("while allocating buffer"));
182 printf(_("Writing block %llu\n"), (unsigned long long) block);
184 seek_relative(fd, blocksize);
185 goto free_and_return;
187 count = write(fd, buf, blocksize);
188 if (count != blocksize) {
195 com_err(program_name, err,
196 _("error writing block %llu"),
197 (unsigned long long) block);
199 com_err(program_name, err, "%s",
200 _("error in generic_write()"));
206 ext2fs_free_mem(&buf);
209 static void write_header(int fd, void *hdr, int hdr_size, int wrt_size)
215 if (hdr_size > wrt_size) {
216 fprintf(stderr, "%s",
217 _("Error: header size is bigger than wrt_size\n"));
220 ret = ext2fs_get_mem(wrt_size, &header_buf);
222 fputs(_("Couldn't allocate header buffer\n"), stderr);
227 memset(header_buf, 0, wrt_size);
230 memcpy(header_buf, hdr, hdr_size);
232 generic_write(fd, header_buf, wrt_size, NO_BLK);
234 ext2fs_free_mem(&header_buf);
237 static void write_image_file(ext2_filsys fs, int fd)
239 struct ext2_image_hdr hdr;
243 write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize);
244 memset(&hdr, 0, sizeof(struct ext2_image_hdr));
246 hdr.offset_super = ext2fs_cpu_to_le32(seek_relative(fd, 0));
247 retval = ext2fs_image_super_write(fs, fd, 0);
249 com_err(program_name, retval, "%s",
250 _("while writing superblock"));
254 hdr.offset_inode = ext2fs_cpu_to_le32(seek_relative(fd, 0));
255 retval = ext2fs_image_inode_write(fs, fd,
256 (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0);
258 com_err(program_name, retval, "%s",
259 _("while writing inode table"));
263 hdr.offset_blockmap = ext2fs_cpu_to_le32(seek_relative(fd, 0));
264 retval = ext2fs_image_bitmap_write(fs, fd, 0);
266 com_err(program_name, retval, "%s",
267 _("while writing block bitmap"));
271 hdr.offset_inodemap = ext2fs_cpu_to_le32(seek_relative(fd, 0));
272 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP);
274 com_err(program_name, retval, "%s",
275 _("while writing inode bitmap"));
279 hdr.magic_number = ext2fs_cpu_to_le32(EXT2_ET_MAGIC_E2IMAGE);
280 strcpy(hdr.magic_descriptor, "Ext2 Image 1.0");
281 gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname));
282 strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1);
283 hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0;
284 hdr.fs_blocksize = ext2fs_cpu_to_le32(fs->blocksize);
286 if (stat(device_name, &st) == 0)
287 hdr.fs_device = ext2fs_cpu_to_le32(st.st_rdev);
289 if (fstat(fd, &st) == 0) {
290 hdr.image_device = ext2fs_cpu_to_le32(st.st_dev);
291 hdr.image_inode = ext2fs_cpu_to_le32(st.st_ino);
293 memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid));
295 hdr.image_time = ext2fs_cpu_to_le32(time(0));
296 write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize);
300 * These set of functions are used to write a RAW image file.
302 static ext2fs_block_bitmap meta_block_map;
303 static ext2fs_block_bitmap scramble_block_map; /* Directory blocks to be scrambled */
304 static blk64_t meta_blocks_count;
306 struct process_block_struct {
312 * These subroutines short circuits ext2fs_get_blocks and
313 * ext2fs_check_directory; we use them since we already have the inode
314 * structure, so there's no point in letting the ext2fs library read
317 static ext2_ino_t stashed_ino = 0;
318 static struct ext2_inode *stashed_inode;
320 static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)),
326 if ((ino != stashed_ino) || !stashed_inode)
327 return EXT2_ET_CALLBACK_NOTHANDLED;
329 for (i=0; i < EXT2_N_BLOCKS; i++)
330 blocks[i] = stashed_inode->i_block[i];
334 static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)),
337 if ((ino != stashed_ino) || !stashed_inode)
338 return EXT2_ET_CALLBACK_NOTHANDLED;
340 if (!LINUX_S_ISDIR(stashed_inode->i_mode))
341 return EXT2_ET_NO_DIRECTORY;
345 static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
347 struct ext2_inode *inode)
349 if ((ino != stashed_ino) || !stashed_inode)
350 return EXT2_ET_CALLBACK_NOTHANDLED;
351 *inode = *stashed_inode;
355 static void use_inode_shortcuts(ext2_filsys fs, int use_shortcuts)
358 fs->get_blocks = meta_get_blocks;
359 fs->check_directory = meta_check_directory;
360 fs->read_inode = meta_read_inode;
364 fs->check_directory = 0;
369 static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
371 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
372 blk64_t ref_block EXT2FS_ATTR((unused)),
373 int ref_offset EXT2FS_ATTR((unused)),
374 void *priv_data EXT2FS_ATTR((unused)))
376 struct process_block_struct *p;
378 p = (struct process_block_struct *) priv_data;
380 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
382 if (scramble_block_map && p->is_dir && blockcnt >= 0)
383 ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr);
387 static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
389 e2_blkcnt_t blockcnt,
390 blk64_t ref_block EXT2FS_ATTR((unused)),
391 int ref_offset EXT2FS_ATTR((unused)),
392 void *priv_data EXT2FS_ATTR((unused)))
394 if (blockcnt < 0 || all_data) {
395 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
401 static void mark_table_blocks(ext2_filsys fs)
403 blk64_t first_block, b;
406 first_block = fs->super->s_first_data_block;
408 * Mark primary superblock
410 ext2fs_mark_block_bitmap2(meta_block_map, first_block);
414 * Mark the primary superblock descriptors
416 for (j = 0; j < fs->desc_blocks; j++) {
417 ext2fs_mark_block_bitmap2(meta_block_map,
418 ext2fs_descriptor_block_loc2(fs, first_block, j));
420 meta_blocks_count += fs->desc_blocks;
425 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) {
426 ext2fs_mark_block_bitmap2(meta_block_map, fs->super->s_mmp_block);
430 for (i = 0; i < fs->group_desc_count; i++) {
432 * Mark the blocks used for the inode table
434 if ((output_is_blk ||
435 !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) &&
436 ext2fs_inode_table_loc(fs, i)) {
437 unsigned int end = (unsigned) fs->inode_blocks_per_group;
438 /* skip unused blocks */
439 if (!output_is_blk && ext2fs_has_group_desc_csum(fs))
440 end -= (ext2fs_bg_itable_unused(fs, i) /
441 EXT2_INODES_PER_BLOCK(fs->super));
442 for (j = 0, b = ext2fs_inode_table_loc(fs, i);
445 ext2fs_mark_block_bitmap2(meta_block_map, b);
451 * Mark block used for the block bitmap
453 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
454 ext2fs_block_bitmap_loc(fs, i)) {
455 ext2fs_mark_block_bitmap2(meta_block_map,
456 ext2fs_block_bitmap_loc(fs, i));
461 * Mark block used for the inode bitmap
463 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
464 ext2fs_inode_bitmap_loc(fs, i)) {
465 ext2fs_mark_block_bitmap2(meta_block_map,
466 ext2fs_inode_bitmap_loc(fs, i));
473 * This function returns 1 if the specified block is all zeros
475 static int check_zero_block(char *buf, int blocksize)
478 int left = blocksize;
490 static int name_id[256];
492 #define EXT4_MAX_REC_LEN ((1<<16)-1)
494 static void scramble_dir_block(ext2_filsys fs, blk64_t blk, char *buf)
497 struct ext2_dir_entry_2 *dirent;
498 unsigned int rec_len;
501 end = buf + fs->blocksize;
502 for (p = buf; p < end-8; p += rec_len) {
503 dirent = (struct ext2_dir_entry_2 *) p;
504 rec_len = dirent->rec_len;
505 #ifdef WORDS_BIGENDIAN
506 rec_len = ext2fs_swab16(rec_len);
508 if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0)
509 rec_len = fs->blocksize;
511 rec_len = (rec_len & 65532) | ((rec_len & 3) << 16);
513 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len);
515 if (rec_len < 8 || (rec_len % 4) ||
517 printf(_("Corrupt directory block %llu: "
518 "bad rec_len (%d)\n"),
519 (unsigned long long) blk, rec_len);
521 (void) ext2fs_set_rec_len(fs, rec_len,
522 (struct ext2_dir_entry *) dirent);
523 #ifdef WORDS_BIGENDIAN
524 dirent->rec_len = ext2fs_swab16(dirent->rec_len);
528 if (dirent->name_len + 8U > rec_len) {
529 printf(_("Corrupt directory block %llu: "
530 "bad name_len (%d)\n"),
531 (unsigned long long) blk, dirent->name_len);
532 dirent->name_len = rec_len - 8;
536 len = rec_len - dirent->name_len - 8;
538 memset(cp+dirent->name_len, 0, len);
539 if (dirent->name_len==1 && cp[0] == '.')
541 if (dirent->name_len==2 && cp[0] == '.' && cp[1] == '.')
544 memset(cp, 'A', dirent->name_len);
545 len = dirent->name_len;
547 while ((len > 0) && (id > 0)) {
556 static char got_sigint;
558 static void sigint_handler(int unused EXT2FS_ATTR((unused)))
561 signal (SIGINT, SIG_DFL);
564 #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \
565 ((float) (b)))) + 0.5))
566 #define calc_rate(t, b, d) (((float)(t) / ((float)(1024 * 1024) / (b))) / (d))
568 static int print_progress(blk64_t num, blk64_t total)
570 return fprintf(stderr, _("%llu / %llu blocks (%d%%)"),
571 (unsigned long long) num,
572 (unsigned long long) total,
573 calc_percent(num, total));
576 static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags)
580 char *buf, *zero_buf;
583 blk64_t distance = 0;
584 blk64_t end = ext2fs_blocks_count(fs->super);
585 time_t last_update = 0;
586 time_t start_time = 0;
587 blk64_t total_written = 0;
590 retval = ext2fs_get_mem(fs->blocksize, &buf);
592 com_err(program_name, retval, "%s",
593 _("while allocating buffer"));
596 retval = ext2fs_get_memzero(fs->blocksize, &zero_buf);
598 com_err(program_name, retval, "%s",
599 _("while allocating buffer"));
603 fprintf(stderr, "%s", _("Copying "));
604 bscount = print_progress(total_written, meta_blocks_count);
606 last_update = time(NULL);
607 start_time = time(NULL);
609 /* when doing an in place move to the right, you can't start
610 at the beginning or you will overwrite data, so instead
611 divide the fs up into distance size chunks and write them
613 if (move_mode && dest_offset > source_offset) {
614 distance = (dest_offset - source_offset) / fs->blocksize;
615 if (distance < ext2fs_blocks_count(fs->super))
616 start = ext2fs_blocks_count(fs->super) - distance;
619 signal (SIGINT, sigint_handler);
622 seek_set(fd, (start * fs->blocksize) + dest_offset);
623 for (blk = start; blk < end; blk++) {
626 /* moving to the right */
627 if (distance >= ext2fs_blocks_count(fs->super)||
628 start == ext2fs_blocks_count(fs->super) -
630 kill(getpid(), SIGINT);
632 /* moving to the left */
633 if (blk < (source_offset - dest_offset) /
635 kill(getpid(), SIGINT);
639 fprintf(stderr, "%s",
640 _("Stopping now will destroy the filesystem, "
641 "interrupt again if you are sure\n"));
643 fprintf(stderr, "%s", _("Copying "));
644 bscount = print_progress(total_written,
651 if (show_progress && last_update != time(NULL)) {
653 last_update = time(NULL);
656 bscount = print_progress(total_written,
658 duration = time(NULL) - start_time;
659 if (duration > 5 && total_written) {
660 time_t est = (duration * meta_blocks_count /
661 total_written) - duration;
663 strftime(buff, 30, "%T", gmtime(&est));
666 _(" %s remaining at %.2f MB/s"),
667 buff, calc_rate(total_written,
673 if ((blk >= fs->super->s_first_data_block) &&
674 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
675 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
677 com_err(program_name, retval,
678 _("error reading block %llu"),
679 (unsigned long long) blk);
682 if (scramble_block_map &&
683 ext2fs_test_block_bitmap2(scramble_block_map, blk))
684 scramble_dir_block(fs, blk, buf);
685 if ((flags & E2IMAGE_CHECK_ZERO_FLAG) &&
686 check_zero_block(buf, fs->blocksize))
689 seek_relative(fd, sparse);
691 if (check_block(fd, buf, check_buf, fs->blocksize)) {
692 seek_relative(fd, fs->blocksize);
695 generic_write(fd, buf, fs->blocksize, blk);
700 generic_write(fd, zero_buf,
704 sparse += fs->blocksize;
705 if (sparse > 1024*1024) {
706 seek_relative(fd, 1024*1024);
711 if (distance && start) {
712 if (start < distance) {
718 if (end < distance) {
719 /* past overlap, do rest in one go */
727 signal (SIGINT, SIG_DFL);
729 time_t duration = time(NULL) - start_time;
732 strftime(buff, 30, "%T", gmtime(&duration));
733 fprintf(stderr, _("Copied %llu / %llu blocks (%d%%) in %s "),
734 (unsigned long long) total_written,
735 (unsigned long long) meta_blocks_count,
736 calc_percent(total_written, meta_blocks_count), buff);
738 fprintf(stderr, _("at %.2f MB/s"),
739 calc_rate(total_written, fs->blocksize, duration));
740 fputs(" \n", stderr);
742 #ifdef HAVE_FTRUNCATE64
746 offset = seek_set(fd,
747 fs->blocksize * ext2fs_blocks_count(fs->super) + dest_offset);
749 offset = seek_relative(fd, sparse);
751 if (ftruncate64(fd, offset) < 0) {
752 seek_relative(fd, -1);
753 generic_write(fd, zero_buf, 1, NO_BLK);
757 if (sparse && !distance) {
758 seek_relative(fd, sparse-1);
759 generic_write(fd, zero_buf, 1, NO_BLK);
762 ext2fs_free_mem(&zero_buf);
763 ext2fs_free_mem(&buf);
766 static void init_l1_table(struct ext2_qcow2_image *image)
771 ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table);
773 com_err(program_name, ret, "%s",
774 _("while allocating l1 table"));
778 image->l1_table = l1_table;
781 static void init_l2_cache(struct ext2_qcow2_image *image)
783 unsigned int count, i;
784 struct ext2_qcow2_l2_cache *cache;
785 struct ext2_qcow2_l2_table *table;
788 ret = ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache),
793 count = (image->l1_size > L2_CACHE_PREALLOC) ? L2_CACHE_PREALLOC :
796 cache->count = count;
798 cache->next_offset = image->l2_offset;
800 for (i = 0; i < count; i++) {
801 ret = ext2fs_get_arrayzero(1,
802 sizeof(struct ext2_qcow2_l2_table), &table);
806 ret = ext2fs_get_arrayzero(image->l2_size,
807 sizeof(__u64), &table->data);
811 table->next = cache->free_head;
812 cache->free_head = table;
815 image->l2_cache = cache;
819 com_err(program_name, ret, "%s", _("while allocating l2 cache"));
823 static void put_l2_cache(struct ext2_qcow2_image *image)
825 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
826 struct ext2_qcow2_l2_table *tmp, *table;
831 table = cache->free_head;
832 cache->free_head = NULL;
837 ext2fs_free_mem(&tmp->data);
838 ext2fs_free_mem(&tmp);
841 if (cache->free != cache->count) {
842 fprintf(stderr, "%s", _("Warning: There are still tables in "
843 "the cache while putting the cache, "
844 "data will be lost so the image may "
846 table = cache->used_head;
847 cache->used_head = NULL;
851 ext2fs_free_mem(&cache);
854 static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset)
856 struct ext2_qcow2_refcount *ref;
857 blk64_t table_clusters;
860 ref = &(img->refcount);
863 * One refcount block addresses 2048 clusters, one refcount table
864 * addresses cluster/sizeof(__u64) refcount blocks, and we need
865 * to address meta_blocks_count clusters + qcow2 metadata clusters
868 table_clusters = meta_blocks_count + (table_offset >>
870 table_clusters >>= (img->cluster_bits + 6 - 1);
871 table_clusters = (table_clusters == 0) ? 1 : table_clusters;
873 ref->refcount_table_offset = table_offset;
874 ref->refcount_table_clusters = table_clusters;
875 ref->refcount_table_index = 0;
876 ref->refcount_block_index = 0;
878 /* Allocate refcount table */
879 ret = ext2fs_get_arrayzero(ref->refcount_table_clusters,
880 img->cluster_size, &ref->refcount_table);
884 /* Allocate refcount block */
885 ret = ext2fs_get_arrayzero(1, img->cluster_size, &ref->refcount_block);
887 ext2fs_free_mem(&ref->refcount_table);
892 static errcode_t initialize_qcow2_image(int fd, ext2_filsys fs,
893 struct ext2_qcow2_image *image)
895 struct ext2_qcow2_hdr *header;
896 blk64_t total_size, offset;
897 int shift, l2_bits, header_size, l1_size, ret;
898 int cluster_bits = get_bits_from_size(fs->blocksize);
899 struct ext2_super_block *sb = fs->super;
901 /* Sbould never happen, but just in case... */
902 if (cluster_bits < 0)
903 return EXT2_FILSYS_CORRUPTED;
905 /* Allocate header */
906 ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header);
910 total_size = ext2fs_blocks_count(sb) << cluster_bits;
911 image->cluster_size = fs->blocksize;
912 image->l2_size = 1 << (cluster_bits - 3);
913 image->cluster_bits = cluster_bits;
916 header->magic = ext2fs_cpu_to_be32(QCOW_MAGIC);
917 header->version = ext2fs_cpu_to_be32(QCOW_VERSION);
918 header->size = ext2fs_cpu_to_be64(total_size);
919 header->cluster_bits = ext2fs_cpu_to_be32(cluster_bits);
921 header_size = (sizeof(struct ext2_qcow2_hdr) + 7) & ~7;
922 offset = align_offset(header_size, image->cluster_size);
924 header->l1_table_offset = ext2fs_cpu_to_be64(offset);
925 image->l1_offset = offset;
927 l2_bits = cluster_bits - 3;
928 shift = cluster_bits + l2_bits;
929 l1_size = ((total_size + (1LL << shift) - 1) >> shift);
930 header->l1_size = ext2fs_cpu_to_be32(l1_size);
931 image->l1_size = l1_size;
933 /* Make space for L1 table */
934 offset += align_offset(l1_size * sizeof(blk64_t), image->cluster_size);
936 /* Initialize refcounting */
937 ret = init_refcount(image, offset);
939 ext2fs_free_mem(&header);
942 header->refcount_table_offset = ext2fs_cpu_to_be64(offset);
943 header->refcount_table_clusters =
944 ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters);
945 offset += image->cluster_size;
946 offset += (blk64_t) image->refcount.refcount_table_clusters <<
949 /* Make space for L2 tables */
950 image->l2_offset = offset;
951 offset += image->cluster_size;
953 /* Make space for first refcount block */
954 image->refcount.refcount_block_offset = offset;
957 /* Initialize l1 and l2 tables */
958 init_l1_table(image);
959 init_l2_cache(image);
964 static void free_qcow2_image(struct ext2_qcow2_image *img)
970 ext2fs_free_mem(&img->hdr);
973 ext2fs_free_mem(&img->l1_table);
975 if (img->refcount.refcount_table)
976 ext2fs_free_mem(&img->refcount.refcount_table);
977 if (img->refcount.refcount_block)
978 ext2fs_free_mem(&img->refcount.refcount_block);
982 ext2fs_free_mem(&img);
986 * Put table from used list (used_head) into free list (free_head).
987 * l2_table is used to return pointer to the next used table (used_head).
989 static void put_used_table(struct ext2_qcow2_image *img,
990 struct ext2_qcow2_l2_table **l2_table)
992 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
993 struct ext2_qcow2_l2_table *table;
995 table = cache->used_head;
996 cache->used_head = table->next;
1000 cache->used_tail = NULL;
1002 /* Clean the table for case we will need to use it again */
1003 memset(table->data, 0, img->cluster_size);
1004 table->next = cache->free_head;
1005 cache->free_head = table;
1009 *l2_table = cache->used_head;
1012 static void flush_l2_cache(struct ext2_qcow2_image *image)
1016 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1017 struct ext2_qcow2_l2_table *table = cache->used_head;
1020 /* Store current position */
1021 offset = seek_relative(fd, 0);
1024 while (cache->free < cache->count) {
1025 if (seek != table->offset) {
1026 seek_set(fd, table->offset);
1027 seek = table->offset;
1030 generic_write(fd, (char *)table->data, image->cluster_size,
1032 put_used_table(image, &table);
1033 seek += image->cluster_size;
1036 /* Restore previous position */
1037 seek_set(fd, offset);
1041 * Get first free table (from free_head) and put it into tail of used list
1043 * l2_table is used to return pointer to moved table.
1044 * Returns 1 if the cache is full, 0 otherwise.
1046 static void get_free_table(struct ext2_qcow2_image *image,
1047 struct ext2_qcow2_l2_table **l2_table)
1049 struct ext2_qcow2_l2_table *table;
1050 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1052 if (0 == cache->free)
1053 flush_l2_cache(image);
1055 table = cache->free_head;
1057 cache->free_head = table->next;
1059 if (cache->used_tail)
1060 cache->used_tail->next = table;
1062 /* First item in the used list */
1063 cache->used_head = table;
1065 cache->used_tail = table;
1071 static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk,
1072 blk64_t data, blk64_t next)
1074 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
1075 struct ext2_qcow2_l2_table *table = cache->used_tail;
1076 blk64_t l1_index = blk / img->l2_size;
1077 blk64_t l2_index = blk & (img->l2_size - 1);
1081 * Need to create new table if it does not exist,
1084 if (!table || (table->l1_index != l1_index)) {
1085 get_free_table(img, &table);
1086 table->l1_index = l1_index;
1087 table->offset = cache->next_offset;
1088 cache->next_offset = next;
1089 img->l1_table[l1_index] =
1090 ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED);
1094 table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED);
1098 static int update_refcount(int fd, struct ext2_qcow2_image *img,
1099 blk64_t offset, blk64_t rfblk_pos)
1101 struct ext2_qcow2_refcount *ref;
1105 ref = &(img->refcount);
1106 table_index = offset >> (2 * img->cluster_bits - 1);
1109 * Need to create new refcount block when the offset addresses
1110 * another item in the refcount table
1112 if (table_index != ref->refcount_table_index) {
1114 seek_set(fd, ref->refcount_block_offset);
1116 generic_write(fd, (char *)ref->refcount_block,
1117 img->cluster_size, NO_BLK);
1118 memset(ref->refcount_block, 0, img->cluster_size);
1120 ref->refcount_table[ref->refcount_table_index] =
1121 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1122 ref->refcount_block_offset = rfblk_pos;
1123 ref->refcount_block_index = 0;
1124 ref->refcount_table_index = table_index;
1129 * We are relying on the fact that we are creating the qcow2
1130 * image sequentially, hence we will always allocate refcount
1131 * block items sequentially.
1133 ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1);
1134 ref->refcount_block_index++;
1138 static int sync_refcount(int fd, struct ext2_qcow2_image *img)
1140 struct ext2_qcow2_refcount *ref;
1142 ref = &(img->refcount);
1144 ref->refcount_table[ref->refcount_table_index] =
1145 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1146 seek_set(fd, ref->refcount_table_offset);
1147 generic_write(fd, (char *)ref->refcount_table,
1148 ref->refcount_table_clusters << img->cluster_bits, NO_BLK);
1150 seek_set(fd, ref->refcount_block_offset);
1151 generic_write(fd, (char *)ref->refcount_block, img->cluster_size,
1156 static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
1159 blk64_t blk, offset, size, end;
1161 struct ext2_qcow2_image *img;
1162 unsigned int header_size;
1164 /* allocate struct ext2_qcow2_image */
1165 retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img);
1167 com_err(program_name, retval, "%s",
1168 _("while allocating ext2_qcow2_image"));
1172 retval = initialize_qcow2_image(fd, fs, img);
1174 com_err(program_name, retval, "%s",
1175 _("while initializing ext2_qcow2_image"));
1178 header_size = align_offset(sizeof(struct ext2_qcow2_hdr),
1180 write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size);
1182 /* Refcount all qcow2 related metadata up to refcount_block_offset */
1183 end = img->refcount.refcount_block_offset;
1185 blk = end + img->cluster_size;
1186 for (offset = 0; offset <= end; offset += img->cluster_size) {
1187 if (update_refcount(fd, img, offset, blk)) {
1188 blk += img->cluster_size;
1190 * If we create new refcount block, we need to refcount
1193 end += img->cluster_size;
1196 seek_set(fd, offset);
1198 retval = ext2fs_get_mem(fs->blocksize, &buf);
1200 com_err(program_name, retval, "%s",
1201 _("while allocating buffer"));
1204 /* Write qcow2 data blocks */
1205 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) {
1206 if ((blk >= fs->super->s_first_data_block) &&
1207 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
1208 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
1210 com_err(program_name, retval,
1211 _("error reading block %llu"),
1212 (unsigned long long) blk);
1215 if (scramble_block_map &&
1216 ext2fs_test_block_bitmap2(scramble_block_map, blk))
1217 scramble_dir_block(fs, blk, buf);
1218 if (check_zero_block(buf, fs->blocksize))
1221 if (update_refcount(fd, img, offset, offset)) {
1222 /* Make space for another refcount block */
1223 offset += img->cluster_size;
1224 seek_set(fd, offset);
1226 * We have created the new refcount block, this
1227 * means that we need to refcount it as well.
1228 * So the previous update_refcount refcounted
1229 * the block itself and now we are going to
1230 * create refcount for data. New refcount
1231 * block should not be created!
1233 if (update_refcount(fd, img, offset, offset)) {
1234 fprintf(stderr, "%s",
1235 _("Programming error: multiple "
1236 "sequential refcount blocks "
1242 generic_write(fd, buf, fs->blocksize, blk);
1244 if (add_l2_item(img, blk, offset,
1245 offset + img->cluster_size)) {
1246 offset += img->cluster_size;
1247 if (update_refcount(fd, img, offset,
1248 offset + img->cluster_size)) {
1249 offset += img->cluster_size;
1250 if (update_refcount(fd, img, offset,
1252 fprintf(stderr, "%s",
1253 _("Programming error: multiple sequential refcount "
1254 "blocks created!\n"));
1258 offset += img->cluster_size;
1259 seek_set(fd, offset);
1263 offset += img->cluster_size;
1266 (void) update_refcount(fd, img, offset, offset);
1267 flush_l2_cache(img);
1268 sync_refcount(fd, img);
1271 seek_set(fd, img->l1_offset);
1272 size = img->l1_size * sizeof(__u64);
1273 generic_write(fd, (char *)img->l1_table, size, NO_BLK);
1275 ext2fs_free_mem(&buf);
1276 free_qcow2_image(img);
1279 static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags,
1282 struct process_block_struct pb;
1283 struct ext2_inode inode;
1284 ext2_inode_scan scan;
1289 meta_blocks_count = 0;
1290 retval = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
1293 com_err(program_name, retval, "%s",
1294 _("while allocating block bitmap"));
1298 if (flags & E2IMAGE_SCRAMBLE_FLAG) {
1299 retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
1300 &scramble_block_map);
1302 com_err(program_name, retval, "%s",
1303 _("while allocating scramble block bitmap"));
1311 ext2fs_mark_block_bitmap2(meta_block_map, superblock);
1312 meta_blocks_count++;
1315 * Mark the backup superblock descriptors
1317 for (j = 0; j < fs->desc_blocks; j++) {
1318 ext2fs_mark_block_bitmap2(meta_block_map,
1319 ext2fs_descriptor_block_loc2(fs, superblock, j));
1321 meta_blocks_count += fs->desc_blocks;
1324 mark_table_blocks(fs);
1326 fprintf(stderr, "%s", _("Scanning inodes...\n"));
1328 retval = ext2fs_open_inode_scan(fs, 0, &scan);
1330 com_err(program_name, retval, "%s",
1331 _("while opening inode scan"));
1335 retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
1337 com_err(program_name, 0, "%s",
1338 _("Can't allocate block buffer"));
1342 use_inode_shortcuts(fs, 1);
1343 stashed_inode = &inode;
1345 retval = ext2fs_get_next_inode(scan, &ino, &inode);
1346 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
1349 com_err(program_name, retval, "%s",
1350 _("while getting next inode"));
1355 if (!inode.i_links_count)
1357 if (ext2fs_file_acl_block(fs, &inode)) {
1358 ext2fs_mark_block_bitmap2(meta_block_map,
1359 ext2fs_file_acl_block(fs, &inode));
1360 meta_blocks_count++;
1362 if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
1367 pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
1368 if (LINUX_S_ISDIR(inode.i_mode) ||
1369 LINUX_S_ISLNK(inode.i_mode) ||
1370 ino == fs->super->s_journal_inum ||
1371 ino == quota_type2inum(USRQUOTA, fs->super) ||
1372 ino == quota_type2inum(GRPQUOTA, fs->super) ||
1373 ino == quota_type2inum(PRJQUOTA, fs->super) ||
1374 ino == fs->super->s_orphan_file_inum) {
1375 retval = ext2fs_block_iterate3(fs, ino,
1376 BLOCK_FLAG_READ_ONLY, block_buf,
1377 process_dir_block, &pb);
1379 com_err(program_name, retval,
1380 _("while iterating over inode %u"),
1385 if ((inode.i_flags & EXT4_EXTENTS_FL) ||
1386 inode.i_block[EXT2_IND_BLOCK] ||
1387 inode.i_block[EXT2_DIND_BLOCK] ||
1388 inode.i_block[EXT2_TIND_BLOCK] || all_data) {
1389 retval = ext2fs_block_iterate3(fs,
1390 ino, BLOCK_FLAG_READ_ONLY, block_buf,
1391 process_file_block, &pb);
1393 com_err(program_name, retval,
1394 _("while iterating over inode %u"), ino);
1400 use_inode_shortcuts(fs, 0);
1402 if (type & E2IMAGE_QCOW2)
1403 output_qcow2_meta_data_blocks(fs, fd);
1405 output_meta_data_blocks(fs, fd, flags);
1407 ext2fs_free_mem(&block_buf);
1408 ext2fs_close_inode_scan(scan);
1409 ext2fs_free_block_bitmap(meta_block_map);
1410 if (type & E2IMAGE_SCRAMBLE_FLAG)
1411 ext2fs_free_block_bitmap(scramble_block_map);
1414 static void install_image(char *device, char *image_fn, int type)
1418 int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS |
1419 EXT2_FLAG_IGNORE_CSUM_ERRORS;
1425 com_err(program_name, 0, "%s",
1426 _("Raw and qcow2 images cannot be installed"));
1430 #ifdef CONFIG_TESTIO_DEBUG
1431 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1432 io_ptr = test_io_manager;
1433 test_io_backing_manager = unix_io_manager;
1436 io_ptr = unix_io_manager;
1438 retval = ext2fs_open (image_fn, open_flag, 0, 0,
1441 com_err(program_name, retval, _("while trying to open %s"),
1446 retval = ext2fs_read_bitmaps (fs);
1448 com_err(program_name, retval, "%s", _("error reading bitmaps"));
1452 fd = ext2fs_open_file(image_fn, O_RDONLY, 0);
1458 retval = io_ptr->open(device, IO_FLAG_RW, &io);
1460 com_err(device, 0, "%s", _("while opening device file"));
1464 ext2fs_rewrite_to_io(fs, io);
1466 seek_set(fd, ext2fs_le32_to_cpu(fs->image_header->offset_inode));
1468 retval = ext2fs_image_inode_read(fs, fd, 0);
1470 com_err(image_fn, 0, "%s",
1471 _("while restoring the image table"));
1476 ext2fs_close_free(&fs);
1479 static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name)
1482 *fd = ext2fs_open_file(name, O_RDONLY, 0600);
1486 return qcow2_read_header(*fd);
1489 int main (int argc, char ** argv)
1494 char *image_fn, offset_opt[64];
1495 struct ext2_qcow2_hdr *header = NULL;
1496 int open_flag = EXT2_FLAG_64BITS | EXT2_FLAG_THREADS |
1497 EXT2_FLAG_IGNORE_CSUM_ERRORS;
1500 int mount_flags = 0;
1504 int ignore_rw_mount = 0;
1507 blk64_t superblock = 0;
1511 setlocale(LC_MESSAGES, "");
1512 setlocale(LC_CTYPE, "");
1513 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
1514 textdomain(NLS_CAT_NAME);
1515 set_com_err_gettext(gettext);
1517 fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION,
1520 program_name = *argv;
1523 add_error_table(&et_ext2_error_table);
1524 while ((c = getopt(argc, argv, "b:B:nrsIQafo:O:pc")) != EOF)
1527 superblock = strtoull(optarg, NULL, 0);
1530 blocksize = strtoul(optarg, NULL, 0);
1533 flags |= E2IMAGE_INSTALL_FLAG;
1538 img_type |= E2IMAGE_QCOW2;
1543 img_type |= E2IMAGE_RAW;
1546 flags |= E2IMAGE_SCRAMBLE_FLAG;
1552 ignore_rw_mount = 1;
1558 source_offset = strtoull(optarg, NULL, 0);
1561 dest_offset = strtoull(optarg, NULL, 0);
1572 if (optind == argc - 1 &&
1573 (source_offset || dest_offset))
1575 else if (optind != argc - 2 )
1578 if (all_data && !img_type) {
1579 com_err(program_name, 0, "%s", _("-a option can only be used "
1580 "with raw or QCOW2 images."));
1583 if (superblock && !img_type) {
1584 com_err(program_name, 0, "%s", _("-b option can only be used "
1585 "with raw or QCOW2 images."));
1588 if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) {
1589 com_err(program_name, 0, "%s",
1590 _("Offsets are only allowed with raw images."));
1593 if (move_mode && img_type != E2IMAGE_RAW) {
1594 com_err(program_name, 0, "%s",
1595 _("Move mode is only allowed with raw images."));
1598 if (move_mode && !all_data) {
1599 com_err(program_name, 0, "%s",
1600 _("Move mode requires all data mode."));
1603 device_name = argv[optind];
1605 image_fn = device_name;
1606 else image_fn = argv[optind+1];
1608 retval = ext2fs_check_if_mounted(device_name, &mount_flags);
1610 com_err(program_name, retval, "%s", _("checking if mounted"));
1614 if (img_type && !ignore_rw_mount &&
1615 (mount_flags & EXT2_MF_MOUNTED) &&
1616 !(mount_flags & EXT2_MF_READONLY)) {
1617 fprintf(stderr, "%s", _("\nRunning e2image on a R/W mounted "
1618 "filesystem can result in an\n"
1619 "inconsistent image which will not be useful "
1620 "for debugging purposes.\n"
1621 "Use -f option if you really want to do that.\n"));
1625 if (flags & E2IMAGE_INSTALL_FLAG) {
1626 install_image(device_name, image_fn, img_type);
1630 if (img_type & E2IMAGE_RAW) {
1631 header = check_qcow2_image(&qcow2_fd, device_name);
1633 flags |= E2IMAGE_IS_QCOW2_FLAG;
1637 sprintf(offset_opt, "offset=%llu", (unsigned long long) source_offset);
1638 retval = ext2fs_open2(device_name, offset_opt, open_flag,
1639 superblock, blocksize, unix_io_manager, &fs);
1641 com_err (program_name, retval, _("while trying to open %s"),
1643 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout);
1644 if (retval == EXT2_ET_BAD_MAGIC)
1645 check_plausibility(device_name, CHECK_FS_EXIST, NULL);
1650 if (strcmp(image_fn, "-") == 0)
1653 int o_flags = O_CREAT|O_RDWR;
1655 if (img_type != E2IMAGE_RAW)
1657 if (access(image_fn, F_OK) != 0)
1658 flags |= E2IMAGE_CHECK_ZERO_FLAG;
1659 fd = ext2fs_open_file(image_fn, o_flags, 0600);
1661 com_err(program_name, errno,
1662 _("while trying to open %s"), image_fn);
1667 seek_set(fd, dest_offset);
1669 if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) {
1670 com_err(program_name, 0, "%s",
1671 _("QCOW2 image can not be written to the stdout!\n"));
1675 if (fstat(fd, &st)) {
1676 com_err(program_name, 0, "%s",
1677 _("Can not stat output\n"));
1680 if (ext2fsP_is_disk_device(st.st_mode))
1683 if (flags & E2IMAGE_IS_QCOW2_FLAG) {
1684 ret = qcow2_write_raw_image(qcow2_fd, fd, header);
1686 if (ret == -QCOW_COMPRESSED)
1687 fprintf(stderr, _("Image (%s) is compressed\n"),
1689 else if (ret == -QCOW_ENCRYPTED)
1690 fprintf(stderr, _("Image (%s) is encrypted\n"),
1692 else if (ret == -QCOW_CORRUPTED)
1693 fprintf(stderr, _("Image (%s) is corrupted\n"),
1696 com_err(program_name, ret,
1697 _("while trying to convert qcow2 image"
1698 " (%s) into raw image (%s)"),
1699 image_fn, device_name);
1706 if (img_type != E2IMAGE_RAW) {
1707 fprintf(stderr, "%s", _("The -c option only supported "
1712 fprintf(stderr, "%s", _("The -c option not supported "
1713 "when writing to stdout\n"));
1716 retval = ext2fs_get_mem(fs->blocksize, &check_buf);
1718 com_err(program_name, retval, "%s",
1719 _("while allocating check_buf"));
1723 if (show_progress && (img_type != E2IMAGE_RAW)) {
1724 fprintf(stderr, "%s",
1725 _("The -p option only supported in raw mode\n"));
1729 write_raw_image_file(fs, fd, img_type, flags, superblock);
1731 write_image_file(fs, fd);
1733 ext2fs_close_free(&fs);
1735 printf(_("%d blocks already contained the data to be copied\n"),
1743 remove_error_table(&et_ext2_error_table);