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 [-acfnprsIQ] [-o src_offset] "
102 "[-O dest_offset] \\\n\tdevice image_file\n"),
107 static ext2_loff_t seek_relative(int fd, int offset)
109 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_CUR);
111 perror("seek_relative");
117 static ext2_loff_t seek_set(int fd, ext2_loff_t offset)
119 ext2_loff_t ret = ext2fs_llseek(fd, offset, SEEK_SET);
128 * Returns true if the block we are about to write is identical to
129 * what is already on the disk.
131 static int check_block(int fd, void *buf, void *cbuf, int blocksize)
134 int count = blocksize, ret;
140 ret = read(fd, cp, count);
142 perror("check_block");
148 ret = memcmp(buf, cbuf, blocksize);
149 seek_relative(fd, -blocksize);
150 return (ret == 0) ? 1 : 0;
153 static void generic_write(int fd, void *buf, int blocksize, blk64_t block)
155 int count, free_buf = 0;
163 err = ext2fs_get_arrayzero(1, blocksize, &buf);
165 com_err(program_name, err,
166 _("while allocating buffer"));
171 printf(_("Writing block %llu\n"), (unsigned long long) block);
172 seek_relative(fd, blocksize);
175 count = write(fd, buf, blocksize);
176 if (count != blocksize) {
183 com_err(program_name, err,
184 _("error writing block %llu"), block);
186 com_err(program_name, err, _("error in write()"));
191 ext2fs_free_mem(&buf);
194 static void write_header(int fd, void *hdr, int hdr_size, int wrt_size)
200 if (hdr_size > wrt_size) {
201 fprintf(stderr, "%s",
202 _("Error: header size is bigger than wrt_size\n"));
205 ret = ext2fs_get_mem(wrt_size, &header_buf);
207 fputs(_("Couldn't allocate header buffer\n"), stderr);
212 memset(header_buf, 0, wrt_size);
215 memcpy(header_buf, hdr, hdr_size);
217 generic_write(fd, header_buf, wrt_size, NO_BLK);
219 ext2fs_free_mem(&header_buf);
222 static void write_image_file(ext2_filsys fs, int fd)
224 struct ext2_image_hdr hdr;
228 write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize);
229 memset(&hdr, 0, sizeof(struct ext2_image_hdr));
231 hdr.offset_super = seek_relative(fd, 0);
232 retval = ext2fs_image_super_write(fs, fd, 0);
234 com_err(program_name, retval, "%s",
235 _("while writing superblock"));
239 hdr.offset_inode = seek_relative(fd, 0);
240 retval = ext2fs_image_inode_write(fs, fd,
241 (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0);
243 com_err(program_name, retval, "%s",
244 _("while writing inode table"));
248 hdr.offset_blockmap = seek_relative(fd, 0);
249 retval = ext2fs_image_bitmap_write(fs, fd, 0);
251 com_err(program_name, retval, "%s",
252 _("while writing block bitmap"));
256 hdr.offset_inodemap = seek_relative(fd, 0);
257 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP);
259 com_err(program_name, retval, "%s",
260 _("while writing inode bitmap"));
264 hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE;
265 strcpy(hdr.magic_descriptor, "Ext2 Image 1.0");
266 gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname));
267 strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1);
268 hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0;
269 hdr.fs_blocksize = fs->blocksize;
271 if (stat(device_name, &st) == 0)
272 hdr.fs_device = st.st_rdev;
274 if (fstat(fd, &st) == 0) {
275 hdr.image_device = st.st_dev;
276 hdr.image_inode = st.st_ino;
278 memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid));
280 hdr.image_time = time(0);
281 write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize);
285 * These set of functions are used to write a RAW image file.
287 static ext2fs_block_bitmap meta_block_map;
288 static ext2fs_block_bitmap scramble_block_map; /* Directory blocks to be scrambled */
289 static blk64_t meta_blocks_count;
291 struct process_block_struct {
297 * These subroutines short circuits ext2fs_get_blocks and
298 * ext2fs_check_directory; we use them since we already have the inode
299 * structure, so there's no point in letting the ext2fs library read
302 static ino_t stashed_ino = 0;
303 static struct ext2_inode *stashed_inode;
305 static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)),
311 if ((ino != stashed_ino) || !stashed_inode)
312 return EXT2_ET_CALLBACK_NOTHANDLED;
314 for (i=0; i < EXT2_N_BLOCKS; i++)
315 blocks[i] = stashed_inode->i_block[i];
319 static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)),
322 if ((ino != stashed_ino) || !stashed_inode)
323 return EXT2_ET_CALLBACK_NOTHANDLED;
325 if (!LINUX_S_ISDIR(stashed_inode->i_mode))
326 return EXT2_ET_NO_DIRECTORY;
330 static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
332 struct ext2_inode *inode)
334 if ((ino != stashed_ino) || !stashed_inode)
335 return EXT2_ET_CALLBACK_NOTHANDLED;
336 *inode = *stashed_inode;
340 static void use_inode_shortcuts(ext2_filsys fs, int use_shortcuts)
343 fs->get_blocks = meta_get_blocks;
344 fs->check_directory = meta_check_directory;
345 fs->read_inode = meta_read_inode;
349 fs->check_directory = 0;
354 static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
356 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
357 blk64_t ref_block EXT2FS_ATTR((unused)),
358 int ref_offset EXT2FS_ATTR((unused)),
359 void *priv_data EXT2FS_ATTR((unused)))
361 struct process_block_struct *p;
363 p = (struct process_block_struct *) priv_data;
365 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
367 if (scramble_block_map && p->is_dir && blockcnt >= 0)
368 ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr);
372 static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
374 e2_blkcnt_t blockcnt,
375 blk64_t ref_block EXT2FS_ATTR((unused)),
376 int ref_offset EXT2FS_ATTR((unused)),
377 void *priv_data EXT2FS_ATTR((unused)))
379 if (blockcnt < 0 || all_data) {
380 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
386 static void mark_table_blocks(ext2_filsys fs)
388 blk64_t first_block, b;
391 first_block = fs->super->s_first_data_block;
393 * Mark primary superblock
395 ext2fs_mark_block_bitmap2(meta_block_map, first_block);
399 * Mark the primary superblock descriptors
401 for (j = 0; j < fs->desc_blocks; j++) {
402 ext2fs_mark_block_bitmap2(meta_block_map,
403 ext2fs_descriptor_block_loc2(fs, first_block, j));
405 meta_blocks_count += fs->desc_blocks;
407 for (i = 0; i < fs->group_desc_count; i++) {
409 * Mark the blocks used for the inode table
411 if ((output_is_blk ||
412 !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) &&
413 ext2fs_inode_table_loc(fs, i)) {
414 unsigned int end = (unsigned) fs->inode_blocks_per_group;
415 /* skip unused blocks */
416 if (!output_is_blk && ext2fs_has_group_desc_csum(fs))
417 end -= (ext2fs_bg_itable_unused(fs, i) /
418 EXT2_INODES_PER_BLOCK(fs->super));
419 for (j = 0, b = ext2fs_inode_table_loc(fs, i);
422 ext2fs_mark_block_bitmap2(meta_block_map, b);
428 * Mark block used for the block bitmap
430 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
431 ext2fs_block_bitmap_loc(fs, i)) {
432 ext2fs_mark_block_bitmap2(meta_block_map,
433 ext2fs_block_bitmap_loc(fs, i));
438 * Mark block used for the inode bitmap
440 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
441 ext2fs_inode_bitmap_loc(fs, i)) {
442 ext2fs_mark_block_bitmap2(meta_block_map,
443 ext2fs_inode_bitmap_loc(fs, i));
450 * This function returns 1 if the specified block is all zeros
452 static int check_zero_block(char *buf, int blocksize)
455 int left = blocksize;
467 static int name_id[256];
469 #define EXT4_MAX_REC_LEN ((1<<16)-1)
471 static void scramble_dir_block(ext2_filsys fs, blk64_t blk, char *buf)
474 struct ext2_dir_entry_2 *dirent;
475 unsigned int rec_len;
478 end = buf + fs->blocksize;
479 for (p = buf; p < end-8; p += rec_len) {
480 dirent = (struct ext2_dir_entry_2 *) p;
481 rec_len = dirent->rec_len;
482 #ifdef WORDS_BIGENDIAN
483 rec_len = ext2fs_swab16(rec_len);
485 if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0)
486 rec_len = fs->blocksize;
488 rec_len = (rec_len & 65532) | ((rec_len & 3) << 16);
490 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len);
492 if (rec_len < 8 || (rec_len % 4) ||
494 printf(_("Corrupt directory block %llu: "
495 "bad rec_len (%d)\n"),
496 (unsigned long long) blk, rec_len);
498 (void) ext2fs_set_rec_len(fs, rec_len,
499 (struct ext2_dir_entry *) dirent);
500 #ifdef WORDS_BIGENDIAN
501 dirent->rec_len = ext2fs_swab16(dirent->rec_len);
505 if (dirent->name_len + 8U > rec_len) {
506 printf(_("Corrupt directory block %llu: "
507 "bad name_len (%d)\n"),
508 (unsigned long long) blk, dirent->name_len);
509 dirent->name_len = rec_len - 8;
513 len = rec_len - dirent->name_len - 8;
515 memset(cp+dirent->name_len, 0, len);
516 if (dirent->name_len==1 && cp[0] == '.')
518 if (dirent->name_len==2 && cp[0] == '.' && cp[1] == '.')
521 memset(cp, 'A', dirent->name_len);
522 len = dirent->name_len;
524 while ((len > 0) && (id > 0)) {
533 static char got_sigint;
535 static void sigint_handler(int unused EXT2FS_ATTR((unused)))
538 signal (SIGINT, SIG_DFL);
541 static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags)
545 char *buf, *zero_buf;
548 blk64_t distance = 0;
549 blk64_t end = ext2fs_blocks_count(fs->super);
550 time_t last_update = 0;
551 time_t start_time = 0;
552 blk64_t total_written = 0;
555 retval = ext2fs_get_mem(fs->blocksize, &buf);
557 com_err(program_name, retval, _("while allocating buffer"));
560 retval = ext2fs_get_memzero(fs->blocksize, &zero_buf);
562 com_err(program_name, retval, _("while allocating buffer"));
566 printf(_("Copying "));
567 bscount = printf(_("%llu / %llu blocks (%llu%%)"),
570 (total_written + 50) / ((meta_blocks_count + 50) / 100));
572 last_update = time(NULL);
573 start_time = time(NULL);
575 /* when doing an in place move to the right, you can't start
576 at the beginning or you will overwrite data, so instead
577 divide the fs up into distance size chunks and write them
579 if (move_mode && dest_offset > source_offset) {
580 distance = (dest_offset - source_offset) / fs->blocksize;
581 if (distance < ext2fs_blocks_count(fs->super))
582 start = ext2fs_blocks_count(fs->super) - distance;
585 signal (SIGINT, sigint_handler);
588 seek_set(fd, (start * fs->blocksize) + dest_offset);
589 for (blk = start; blk < end; blk++) {
592 /* moving to the right */
593 if (distance >= ext2fs_blocks_count(fs->super) ||
594 start == ext2fs_blocks_count(fs->super) - distance)
595 kill (getpid(), SIGINT);
597 /* moving to the left */
598 if (blk < (source_offset - dest_offset) / fs->blocksize)
599 kill (getpid(), SIGINT);
603 printf(_("Stopping now will destroy the filesystem, "
604 "interrupt again if you are sure\n"));
606 printf(_("Copying "));
607 bscount = printf(_("%llu / %llu blocks (%llu%%)"),
610 (total_written + 50) / ((meta_blocks_count + 50)
617 if (show_progress && last_update != time(NULL)) {
619 last_update = time(NULL);
622 bscount = printf(_("%llu / %llu blocks (%llu%%)"),
625 (total_written + 50) /
626 ((meta_blocks_count + 50) / 100));
627 duration = time(NULL) - start_time;
629 time_t est = (duration *
630 meta_blocks_count / total_written) -
633 strftime(buff, 30, "%T", gmtime(&est));
634 bscount += printf(_(" %s remaining at %.2f MB/s"),
636 ((float)total_written /
637 ((1024 * 1024) / fs->blocksize)) /
642 if ((blk >= fs->super->s_first_data_block) &&
643 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
644 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
646 com_err(program_name, retval,
647 _("error reading block %llu"), blk);
650 if (scramble_block_map &&
651 ext2fs_test_block_bitmap2(scramble_block_map, blk))
652 scramble_dir_block(fs, blk, buf);
653 if ((flags & E2IMAGE_CHECK_ZERO_FLAG) &&
654 check_zero_block(buf, fs->blocksize))
657 seek_relative(fd, sparse);
659 if (check_block(fd, buf, check_buf, fs->blocksize)) {
660 seek_relative(fd, fs->blocksize);
663 generic_write(fd, buf, fs->blocksize, blk);
667 generic_write(fd, zero_buf, fs->blocksize, blk);
670 sparse += fs->blocksize;
671 if (sparse > 1024*1024) {
672 seek_relative(fd, 1024*1024);
677 if (distance && start) {
678 if (start < distance) {
684 if (end < distance) {
685 /* past overlap, do rest in one go */
693 signal (SIGINT, SIG_DFL);
695 time_t duration = time(NULL) - start_time;
699 strftime(buff, 30, "%T", gmtime(&duration));
700 printf(_("\b\b\b\b\b\b\b\bCopied %llu / %llu blocks (%llu%%) "
701 "in %s at %.2f MB/s \n"),
704 (total_written + 50) / ((meta_blocks_count + 50) / 100),
706 ((float)total_written /
707 ((1024 * 1024) / fs->blocksize)) /
711 #ifdef HAVE_FTRUNCATE64
715 offset = seek_set(fd,
716 fs->blocksize * ext2fs_blocks_count(fs->super) + dest_offset);
718 offset = seek_relative(fd, sparse);
720 if (ftruncate64(fd, offset) < 0) {
721 seek_relative(fd, -1);
722 generic_write(fd, zero_buf, 1, NO_BLK);
726 if (sparse && !distance) {
727 seek_relative(fd, sparse-1);
728 generic_write(fd, zero_buf, 1, NO_BLK);
731 ext2fs_free_mem(&zero_buf);
732 ext2fs_free_mem(&buf);
735 static void init_l1_table(struct ext2_qcow2_image *image)
740 ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table);
742 com_err(program_name, ret, _("while allocating l1 table"));
746 image->l1_table = l1_table;
749 static void init_l2_cache(struct ext2_qcow2_image *image)
751 unsigned int count, i;
752 struct ext2_qcow2_l2_cache *cache;
753 struct ext2_qcow2_l2_table *table;
756 ret = ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache),
761 count = (image->l1_size > L2_CACHE_PREALLOC) ? L2_CACHE_PREALLOC :
764 cache->count = count;
766 cache->next_offset = image->l2_offset;
768 for (i = 0; i < count; i++) {
769 ret = ext2fs_get_arrayzero(1,
770 sizeof(struct ext2_qcow2_l2_table), &table);
774 ret = ext2fs_get_arrayzero(image->l2_size,
775 sizeof(__u64), &table->data);
779 table->next = cache->free_head;
780 cache->free_head = table;
783 image->l2_cache = cache;
787 com_err(program_name, ret, _("while allocating l2 cache"));
791 static void put_l2_cache(struct ext2_qcow2_image *image)
793 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
794 struct ext2_qcow2_l2_table *tmp, *table;
799 table = cache->free_head;
800 cache->free_head = NULL;
805 ext2fs_free_mem(&tmp->data);
806 ext2fs_free_mem(&tmp);
809 if (cache->free != cache->count) {
810 fprintf(stderr, _("Warning: There are still tables in the "
811 "cache while putting the cache, data will "
812 "be lost so the image may not be valid.\n"));
813 table = cache->used_head;
814 cache->used_head = NULL;
818 ext2fs_free_mem(&cache);
821 static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset)
823 struct ext2_qcow2_refcount *ref;
824 blk64_t table_clusters;
827 ref = &(img->refcount);
830 * One refcount block addresses 2048 clusters, one refcount table
831 * addresses cluster/sizeof(__u64) refcount blocks, and we need
832 * to address meta_blocks_count clusters + qcow2 metadata clusters
835 table_clusters = meta_blocks_count + (table_offset >>
837 table_clusters >>= (img->cluster_bits + 6 - 1);
838 table_clusters = (table_clusters == 0) ? 1 : table_clusters;
840 ref->refcount_table_offset = table_offset;
841 ref->refcount_table_clusters = table_clusters;
842 ref->refcount_table_index = 0;
843 ref->refcount_block_index = 0;
845 /* Allocate refcount table */
846 ret = ext2fs_get_arrayzero(ref->refcount_table_clusters,
847 img->cluster_size, &ref->refcount_table);
851 /* Allocate refcount block */
852 ret = ext2fs_get_arrayzero(1, img->cluster_size, &ref->refcount_block);
854 ext2fs_free_mem(&ref->refcount_table);
859 static int initialize_qcow2_image(int fd, ext2_filsys fs,
860 struct ext2_qcow2_image *image)
862 struct ext2_qcow2_hdr *header;
863 blk64_t total_size, offset;
864 int shift, l2_bits, header_size, l1_size, ret;
865 int cluster_bits = get_bits_from_size(fs->blocksize);
866 struct ext2_super_block *sb = fs->super;
868 /* Allocate header */
869 ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header);
873 total_size = ext2fs_blocks_count(sb) << cluster_bits;
874 image->cluster_size = fs->blocksize;
875 image->l2_size = 1 << (cluster_bits - 3);
876 image->cluster_bits = cluster_bits;
879 header->magic = ext2fs_cpu_to_be32(QCOW_MAGIC);
880 header->version = ext2fs_cpu_to_be32(QCOW_VERSION);
881 header->size = ext2fs_cpu_to_be64(total_size);
882 header->cluster_bits = ext2fs_cpu_to_be32(cluster_bits);
884 header_size = (sizeof(struct ext2_qcow2_hdr) + 7) & ~7;
885 offset = align_offset(header_size, image->cluster_size);
887 header->l1_table_offset = ext2fs_cpu_to_be64(offset);
888 image->l1_offset = offset;
890 l2_bits = cluster_bits - 3;
891 shift = cluster_bits + l2_bits;
892 l1_size = ((total_size + (1LL << shift) - 1) >> shift);
893 header->l1_size = ext2fs_cpu_to_be32(l1_size);
894 image->l1_size = l1_size;
896 /* Make space for L1 table */
897 offset += align_offset(l1_size * sizeof(blk64_t), image->cluster_size);
899 /* Initialize refcounting */
900 ret = init_refcount(image, offset);
902 ext2fs_free_mem(&header);
905 header->refcount_table_offset = ext2fs_cpu_to_be64(offset);
906 header->refcount_table_clusters =
907 ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters);
908 offset += image->cluster_size;
909 offset += image->refcount.refcount_table_clusters <<
912 /* Make space for L2 tables */
913 image->l2_offset = offset;
914 offset += image->cluster_size;
916 /* Make space for first refcount block */
917 image->refcount.refcount_block_offset = offset;
920 /* Initialize l1 and l2 tables */
921 init_l1_table(image);
922 init_l2_cache(image);
927 static void free_qcow2_image(struct ext2_qcow2_image *img)
933 ext2fs_free_mem(&img->hdr);
936 ext2fs_free_mem(&img->l1_table);
938 if (img->refcount.refcount_table)
939 ext2fs_free_mem(&img->refcount.refcount_table);
940 if (img->refcount.refcount_block)
941 ext2fs_free_mem(&img->refcount.refcount_block);
945 ext2fs_free_mem(&img);
949 * Put table from used list (used_head) into free list (free_head).
950 * l2_table is used to return pointer to the next used table (used_head).
952 static void put_used_table(struct ext2_qcow2_image *img,
953 struct ext2_qcow2_l2_table **l2_table)
955 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
956 struct ext2_qcow2_l2_table *table;
958 table = cache->used_head;
959 cache->used_head = table->next;
963 cache->used_tail = NULL;
965 /* Clean the table for case we will need to use it again */
966 memset(table->data, 0, img->cluster_size);
967 table->next = cache->free_head;
968 cache->free_head = table;
972 *l2_table = cache->used_head;
975 static void flush_l2_cache(struct ext2_qcow2_image *image)
979 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
980 struct ext2_qcow2_l2_table *table = cache->used_head;
983 /* Store current position */
984 offset = seek_relative(fd, 0);
987 while (cache->free < cache->count) {
988 if (seek != table->offset) {
989 seek_set(fd, table->offset);
990 seek = table->offset;
993 generic_write(fd, (char *)table->data, image->cluster_size,
995 put_used_table(image, &table);
996 seek += image->cluster_size;
999 /* Restore previous position */
1000 seek_set(fd, offset);
1004 * Get first free table (from free_head) and put it into tail of used list
1006 * l2_table is used to return pointer to moved table.
1007 * Returns 1 if the cache is full, 0 otherwise.
1009 static void get_free_table(struct ext2_qcow2_image *image,
1010 struct ext2_qcow2_l2_table **l2_table)
1012 struct ext2_qcow2_l2_table *table;
1013 struct ext2_qcow2_l2_cache *cache = image->l2_cache;
1015 if (0 == cache->free)
1016 flush_l2_cache(image);
1018 table = cache->free_head;
1020 cache->free_head = table->next;
1022 if (cache->used_tail)
1023 cache->used_tail->next = table;
1025 /* First item in the used list */
1026 cache->used_head = table;
1028 cache->used_tail = table;
1034 static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk,
1035 blk64_t data, blk64_t next)
1037 struct ext2_qcow2_l2_cache *cache = img->l2_cache;
1038 struct ext2_qcow2_l2_table *table = cache->used_tail;
1039 blk64_t l1_index = blk / img->l2_size;
1040 blk64_t l2_index = blk & (img->l2_size - 1);
1044 * Need to create new table if it does not exist,
1047 if (!table || (table->l1_index != l1_index)) {
1048 get_free_table(img, &table);
1049 table->l1_index = l1_index;
1050 table->offset = cache->next_offset;
1051 cache->next_offset = next;
1052 img->l1_table[l1_index] =
1053 ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED);
1057 table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED);
1061 static int update_refcount(int fd, struct ext2_qcow2_image *img,
1062 blk64_t offset, blk64_t rfblk_pos)
1064 struct ext2_qcow2_refcount *ref;
1068 ref = &(img->refcount);
1069 table_index = offset >> (2 * img->cluster_bits - 1);
1072 * Need to create new refcount block when the offset addresses
1073 * another item in the refcount table
1075 if (table_index != ref->refcount_table_index) {
1077 seek_set(fd, ref->refcount_block_offset);
1079 generic_write(fd, (char *)ref->refcount_block,
1080 img->cluster_size, NO_BLK);
1081 memset(ref->refcount_block, 0, img->cluster_size);
1083 ref->refcount_table[ref->refcount_table_index] =
1084 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1085 ref->refcount_block_offset = rfblk_pos;
1086 ref->refcount_block_index = 0;
1087 ref->refcount_table_index = table_index;
1092 * We are relying on the fact that we are creating the qcow2
1093 * image sequentially, hence we will always allocate refcount
1094 * block items sequentialy.
1096 ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1);
1097 ref->refcount_block_index++;
1101 static int sync_refcount(int fd, struct ext2_qcow2_image *img)
1103 struct ext2_qcow2_refcount *ref;
1105 ref = &(img->refcount);
1107 ref->refcount_table[ref->refcount_table_index] =
1108 ext2fs_cpu_to_be64(ref->refcount_block_offset);
1109 seek_set(fd, ref->refcount_table_offset);
1110 generic_write(fd, (char *)ref->refcount_table,
1111 ref->refcount_table_clusters << img->cluster_bits, NO_BLK);
1113 seek_set(fd, ref->refcount_block_offset);
1114 generic_write(fd, (char *)ref->refcount_block, img->cluster_size,
1119 static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
1122 blk64_t blk, offset, size, end;
1124 struct ext2_qcow2_image *img;
1125 unsigned int header_size;
1127 /* allocate struct ext2_qcow2_image */
1128 retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img);
1130 com_err(program_name, retval,
1131 _("while allocating ext2_qcow2_image"));
1135 retval = initialize_qcow2_image(fd, fs, img);
1137 com_err(program_name, retval,
1138 _("while initializing ext2_qcow2_image"));
1141 header_size = align_offset(sizeof(struct ext2_qcow2_hdr),
1143 write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size);
1145 /* Refcount all qcow2 related metadata up to refcount_block_offset */
1146 end = img->refcount.refcount_block_offset;
1148 blk = end + img->cluster_size;
1149 for (offset = 0; offset <= end; offset += img->cluster_size) {
1150 if (update_refcount(fd, img, offset, blk)) {
1151 blk += img->cluster_size;
1153 * If we create new refcount block, we need to refcount
1156 end += img->cluster_size;
1159 seek_set(fd, offset);
1161 retval = ext2fs_get_mem(fs->blocksize, &buf);
1163 com_err(program_name, retval, _("while allocating buffer"));
1166 /* Write qcow2 data blocks */
1167 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) {
1168 if ((blk >= fs->super->s_first_data_block) &&
1169 ext2fs_test_block_bitmap2(meta_block_map, blk)) {
1170 retval = io_channel_read_blk64(fs->io, blk, 1, buf);
1172 com_err(program_name, retval,
1173 _("error reading block %llu"), blk);
1176 if (scramble_block_map &&
1177 ext2fs_test_block_bitmap2(scramble_block_map, blk))
1178 scramble_dir_block(fs, blk, buf);
1179 if (check_zero_block(buf, fs->blocksize))
1182 if (update_refcount(fd, img, offset, offset)) {
1183 /* Make space for another refcount block */
1184 offset += img->cluster_size;
1185 seek_set(fd, offset);
1187 * We have created the new refcount block, this
1188 * means that we need to refcount it as well.
1189 * So the previous update_refcount refcounted
1190 * the block itself and now we are going to
1191 * create refcount for data. New refcount
1192 * block should not be created!
1194 if (update_refcount(fd, img, offset, offset)) {
1195 fprintf(stderr, _("Programming error: "
1196 "multiple sequential refcount "
1197 "blocks created!\n"));
1202 generic_write(fd, buf, fs->blocksize, blk);
1204 if (add_l2_item(img, blk, offset,
1205 offset + img->cluster_size)) {
1206 offset += img->cluster_size;
1207 if (update_refcount(fd, img, offset,
1208 offset + img->cluster_size)) {
1209 offset += img->cluster_size;
1210 if (update_refcount(fd, img, offset,
1213 _("Programming error: multiple sequential refcount "
1214 "blocks created!\n"));
1218 offset += img->cluster_size;
1219 seek_set(fd, offset);
1223 offset += img->cluster_size;
1226 update_refcount(fd, img, offset, offset);
1227 flush_l2_cache(img);
1228 sync_refcount(fd, img);
1231 seek_set(fd, img->l1_offset);
1232 size = img->l1_size * sizeof(__u64);
1233 generic_write(fd, (char *)img->l1_table, size, NO_BLK);
1235 ext2fs_free_mem(&buf);
1236 free_qcow2_image(img);
1239 static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags)
1241 struct process_block_struct pb;
1242 struct ext2_inode inode;
1243 ext2_inode_scan scan;
1248 meta_blocks_count = 0;
1249 retval = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
1252 com_err(program_name, retval,
1253 _("while allocating block bitmap"));
1257 if (flags & E2IMAGE_SCRAMBLE_FLAG) {
1258 retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
1259 &scramble_block_map);
1261 com_err(program_name, retval,
1262 _("while allocating scramble block bitmap"));
1267 mark_table_blocks(fs);
1269 printf(_("Scanning inodes...\n"));
1271 retval = ext2fs_open_inode_scan(fs, 0, &scan);
1273 com_err(program_name, retval,"%s",
1274 _("while opening inode scan"));
1278 retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
1280 com_err(program_name, 0, "%s",
1281 _("Can't allocate block buffer"));
1285 use_inode_shortcuts(fs, 1);
1286 stashed_inode = &inode;
1288 retval = ext2fs_get_next_inode(scan, &ino, &inode);
1289 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
1292 com_err(program_name, retval, "%s",
1293 _("while getting next inode"));
1298 if (!inode.i_links_count)
1300 if (ext2fs_file_acl_block(fs, &inode)) {
1301 ext2fs_mark_block_bitmap2(meta_block_map,
1302 ext2fs_file_acl_block(fs, &inode));
1303 meta_blocks_count++;
1305 if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
1310 pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
1311 if (LINUX_S_ISDIR(inode.i_mode) ||
1312 (LINUX_S_ISLNK(inode.i_mode) &&
1313 ext2fs_inode_has_valid_blocks2(fs, &inode)) ||
1314 ino == fs->super->s_journal_inum) {
1315 retval = ext2fs_block_iterate3(fs, ino,
1316 BLOCK_FLAG_READ_ONLY, block_buf,
1317 process_dir_block, &pb);
1319 com_err(program_name, retval,
1320 _("while iterating over inode %u"),
1325 if ((inode.i_flags & EXT4_EXTENTS_FL) ||
1326 inode.i_block[EXT2_IND_BLOCK] ||
1327 inode.i_block[EXT2_DIND_BLOCK] ||
1328 inode.i_block[EXT2_TIND_BLOCK] || all_data) {
1329 retval = ext2fs_block_iterate3(fs,
1330 ino, BLOCK_FLAG_READ_ONLY, block_buf,
1331 process_file_block, &pb);
1333 com_err(program_name, retval,
1334 _("while iterating over inode %u"), ino);
1340 use_inode_shortcuts(fs, 0);
1342 if (type & E2IMAGE_QCOW2)
1343 output_qcow2_meta_data_blocks(fs, fd);
1345 output_meta_data_blocks(fs, fd, flags);
1347 ext2fs_free_mem(&block_buf);
1348 ext2fs_close_inode_scan(scan);
1349 ext2fs_free_block_bitmap(meta_block_map);
1350 if (type & E2IMAGE_SCRAMBLE_FLAG)
1351 ext2fs_free_block_bitmap(scramble_block_map);
1354 static void install_image(char *device, char *image_fn, int type)
1358 int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS;
1364 com_err(program_name, 0, _("Raw and qcow2 images cannot"
1369 #ifdef CONFIG_TESTIO_DEBUG
1370 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1371 io_ptr = test_io_manager;
1372 test_io_backing_manager = unix_io_manager;
1375 io_ptr = unix_io_manager;
1377 retval = ext2fs_open (image_fn, open_flag, 0, 0,
1380 com_err (program_name, retval, _("while trying to open %s"),
1385 retval = ext2fs_read_bitmaps (fs);
1387 com_err(program_name, retval, _("error reading bitmaps"));
1391 fd = ext2fs_open_file(image_fn, O_RDONLY, 0);
1397 retval = io_ptr->open(device, IO_FLAG_RW, &io);
1399 com_err(device, 0, _("while opening device file"));
1403 ext2fs_rewrite_to_io(fs, io);
1405 seek_set(fd, fs->image_header->offset_inode);
1407 retval = ext2fs_image_inode_read(fs, fd, 0);
1409 com_err(image_fn, 0, "while restoring the image table");
1417 static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name)
1420 *fd = ext2fs_open_file(name, O_RDONLY, 0600);
1424 return qcow2_read_header(*fd);
1427 int main (int argc, char ** argv)
1432 char *image_fn, offset_opt[64];
1433 struct ext2_qcow2_hdr *header = NULL;
1434 int open_flag = EXT2_FLAG_64BITS;
1437 int mount_flags = 0;
1441 int ignore_rw_mount = 0;
1446 setlocale(LC_MESSAGES, "");
1447 setlocale(LC_CTYPE, "");
1448 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
1449 textdomain(NLS_CAT_NAME);
1450 set_com_err_gettext(gettext);
1452 fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION,
1455 program_name = *argv;
1456 add_error_table(&et_ext2_error_table);
1457 while ((c = getopt(argc, argv, "nrsIQafo:O:pc")) != EOF)
1460 flags |= E2IMAGE_INSTALL_FLAG;
1465 img_type |= E2IMAGE_QCOW2;
1470 img_type |= E2IMAGE_RAW;
1473 flags |= E2IMAGE_SCRAMBLE_FLAG;
1479 ignore_rw_mount = 1;
1485 source_offset = strtoull(optarg, NULL, 0);
1488 dest_offset = strtoull(optarg, NULL, 0);
1499 if (optind == argc - 1 &&
1500 (source_offset || dest_offset))
1502 else if (optind != argc - 2 )
1505 if (all_data && !img_type) {
1506 com_err(program_name, 0, _("-a option can only be used "
1507 "with raw or QCOW2 images."));
1510 if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) {
1511 com_err(program_name, 0,
1512 _("Offsets are only allowed with raw images."));
1515 if (move_mode && img_type != E2IMAGE_RAW) {
1516 com_err(program_name, 0,
1517 _("Move mode is only allowed with raw images."));
1520 if (move_mode && !all_data) {
1521 com_err(program_name, 0,
1522 _("Move mode requires all data mode."));
1525 device_name = argv[optind];
1527 image_fn = device_name;
1528 else image_fn = argv[optind+1];
1530 retval = ext2fs_check_if_mounted(device_name, &mount_flags);
1532 com_err(program_name, retval, _("checking if mounted"));
1536 if (img_type && !ignore_rw_mount &&
1537 (mount_flags & EXT2_MF_MOUNTED) &&
1538 !(mount_flags & EXT2_MF_READONLY)) {
1539 fprintf(stderr, _("\nRunning e2image on a R/W mounted "
1540 "filesystem can result in an\n"
1541 "inconsistent image which will not be useful "
1542 "for debugging purposes.\n"
1543 "Use -f option if you really want to do that.\n"));
1547 if (flags & E2IMAGE_INSTALL_FLAG) {
1548 install_image(device_name, image_fn, img_type);
1552 if (img_type & E2IMAGE_RAW) {
1553 header = check_qcow2_image(&qcow2_fd, device_name);
1555 flags |= E2IMAGE_IS_QCOW2_FLAG;
1559 sprintf(offset_opt, "offset=%llu", source_offset);
1560 retval = ext2fs_open2(device_name, offset_opt, open_flag, 0, 0,
1561 unix_io_manager, &fs);
1563 com_err (program_name, retval, _("while trying to open %s"),
1565 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout);
1570 if (strcmp(image_fn, "-") == 0)
1573 int o_flags = O_CREAT|O_RDWR;
1575 if (img_type != E2IMAGE_RAW)
1577 if (access(image_fn, F_OK) != 0)
1578 flags |= E2IMAGE_CHECK_ZERO_FLAG;
1579 fd = ext2fs_open_file(image_fn, o_flags, 0600);
1581 com_err(program_name, errno,
1582 _("while trying to open %s"), image_fn);
1587 seek_set(fd, dest_offset);
1589 if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) {
1590 com_err(program_name, 0, _("QCOW2 image can not be written to "
1595 if (fstat(fd, &st)) {
1596 com_err(program_name, 0, "Can not stat output\n");
1599 if (S_ISBLK(st.st_mode))
1602 if (flags & E2IMAGE_IS_QCOW2_FLAG) {
1603 ret = qcow2_write_raw_image(qcow2_fd, fd, header);
1605 if (ret == -QCOW_COMPRESSED)
1606 fprintf(stderr, _("Image (%s) is compressed\n"),
1608 if (ret == -QCOW_ENCRYPTED)
1609 fprintf(stderr, _("Image (%s) is encrypted\n"),
1611 com_err(program_name, ret,
1612 _("while trying to convert qcow2 image"
1613 " (%s) into raw image (%s)"),
1614 device_name, image_fn);
1620 if (img_type != E2IMAGE_RAW) {
1621 fprintf(stderr, _("The -c option only supported "
1626 fprintf(stderr, _("The -c option is not supported "
1627 "when writing to stdout\n"));
1630 retval = ext2fs_get_mem(fs->blocksize, &check_buf);
1632 com_err(program_name, retval,
1633 _("while allocating check_buf"));
1639 write_raw_image_file(fs, fd, img_type, flags);
1641 write_image_file(fs, fd);
1645 printf(_("%d blocks already contained the data to be copied.\n"),
1653 remove_error_table(&et_ext2_error_table);