2 * e2image.c --- Program which writes an image file backing up
3 * critical metadata for the filesystem.
5 * Copyright 2000, 2001 by Theodore Ts'o.
8 * This file may be redistributed under the terms of the GNU Public
13 #define _LARGEFILE_SOURCE
14 #define _LARGEFILE64_SOURCE
36 #include <sys/types.h>
40 #include "ext2fs/ext2_fs.h"
41 #include "ext2fs/ext2fs.h"
42 #include "et/com_err.h"
43 #include "uuid/uuid.h"
45 #include "ext2fs/e2image.h"
46 #include "ext2fs/qcow2.h"
48 #include "../version.h"
49 #include "nls-enable.h"
51 #define QCOW_OFLAG_COPIED (1LL << 63)
52 #define NO_BLK ((blk64_t) -1)
56 #define E2IMAGE_QCOW2 2
59 #define E2IMAGE_INSTALL_FLAG 1
60 #define E2IMAGE_SCRAMBLE_FLAG 2
61 #define E2IMAGE_IS_QCOW2_FLAG 4
62 #define E2IMAGE_CHECK_ZERO_FLAG 8
64 static const char * program_name
= "e2image";
65 static char * device_name
= NULL
;
67 static char output_is_blk
;
69 /* writing to blk device: don't skip zeroed blocks */
70 static blk64_t source_offset
, dest_offset
;
71 static char move_mode
;
72 static char show_progress
;
73 static char *check_buf
;
74 static int skipped_blocks
;
76 static blk64_t
align_offset(blk64_t offset
, unsigned int n
)
78 return (offset
+ n
- 1) & ~((blk64_t
) n
- 1);
81 static int get_bits_from_size(size_t size
)
89 /* Not a power of two */
99 static void usage(void)
101 fprintf(stderr
, _("Usage: %s [ -r|Q ] [ -fr ] device image-file\n"),
103 fprintf(stderr
, _(" %s -I device image-file\n"), program_name
);
104 fprintf(stderr
, _(" %s -ra [ -cfnp ] [ -o src_offset ] "
105 "[ -O dest_offset ] src_fs [ dest_fs ]\n"),
110 static ext2_loff_t
seek_relative(int fd
, int offset
)
112 ext2_loff_t ret
= ext2fs_llseek(fd
, offset
, SEEK_CUR
);
114 perror("seek_relative");
120 static ext2_loff_t
seek_set(int fd
, ext2_loff_t offset
)
122 ext2_loff_t ret
= ext2fs_llseek(fd
, offset
, SEEK_SET
);
131 * Returns true if the block we are about to write is identical to
132 * what is already on the disk.
134 static int check_block(int fd
, void *buf
, void *cbuf
, int blocksize
)
137 int count
= blocksize
, ret
;
143 ret
= read(fd
, cp
, count
);
145 perror("check_block");
151 ret
= memcmp(buf
, cbuf
, blocksize
);
152 seek_relative(fd
, -blocksize
);
153 return (ret
== 0) ? 1 : 0;
156 static void generic_write(int fd
, void *buf
, int blocksize
, blk64_t block
)
158 int count
, free_buf
= 0;
166 err
= ext2fs_get_arrayzero(1, blocksize
, &buf
);
168 com_err(program_name
, err
, "%s",
169 _("while allocating buffer"));
174 printf(_("Writing block %llu\n"), (unsigned long long) block
);
176 seek_relative(fd
, blocksize
);
177 goto free_and_return
;
179 count
= write(fd
, buf
, blocksize
);
180 if (count
!= blocksize
) {
187 com_err(program_name
, err
,
188 _("error writing block %llu"), block
);
190 com_err(program_name
, err
, "%s",
191 _("error in generic_write()"));
197 ext2fs_free_mem(&buf
);
200 static void write_header(int fd
, void *hdr
, int hdr_size
, int wrt_size
)
206 if (hdr_size
> wrt_size
) {
207 fprintf(stderr
, "%s",
208 _("Error: header size is bigger than wrt_size\n"));
211 ret
= ext2fs_get_mem(wrt_size
, &header_buf
);
213 fputs(_("Couldn't allocate header buffer\n"), stderr
);
218 memset(header_buf
, 0, wrt_size
);
221 memcpy(header_buf
, hdr
, hdr_size
);
223 generic_write(fd
, header_buf
, wrt_size
, NO_BLK
);
225 ext2fs_free_mem(&header_buf
);
228 static void write_image_file(ext2_filsys fs
, int fd
)
230 struct ext2_image_hdr hdr
;
234 write_header(fd
, NULL
, sizeof(struct ext2_image_hdr
), fs
->blocksize
);
235 memset(&hdr
, 0, sizeof(struct ext2_image_hdr
));
237 hdr
.offset_super
= seek_relative(fd
, 0);
238 retval
= ext2fs_image_super_write(fs
, fd
, 0);
240 com_err(program_name
, retval
, "%s",
241 _("while writing superblock"));
245 hdr
.offset_inode
= seek_relative(fd
, 0);
246 retval
= ext2fs_image_inode_write(fs
, fd
,
247 (fd
!= 1) ? IMAGER_FLAG_SPARSEWRITE
: 0);
249 com_err(program_name
, retval
, "%s",
250 _("while writing inode table"));
254 hdr
.offset_blockmap
= seek_relative(fd
, 0);
255 retval
= ext2fs_image_bitmap_write(fs
, fd
, 0);
257 com_err(program_name
, retval
, "%s",
258 _("while writing block bitmap"));
262 hdr
.offset_inodemap
= seek_relative(fd
, 0);
263 retval
= ext2fs_image_bitmap_write(fs
, fd
, IMAGER_FLAG_INODEMAP
);
265 com_err(program_name
, retval
, "%s",
266 _("while writing inode bitmap"));
270 hdr
.magic_number
= EXT2_ET_MAGIC_E2IMAGE
;
271 strcpy(hdr
.magic_descriptor
, "Ext2 Image 1.0");
272 gethostname(hdr
.fs_hostname
, sizeof(hdr
.fs_hostname
));
273 strncpy(hdr
.fs_device_name
, device_name
, sizeof(hdr
.fs_device_name
)-1);
274 hdr
.fs_device_name
[sizeof(hdr
.fs_device_name
) - 1] = 0;
275 hdr
.fs_blocksize
= fs
->blocksize
;
277 if (stat(device_name
, &st
) == 0)
278 hdr
.fs_device
= st
.st_rdev
;
280 if (fstat(fd
, &st
) == 0) {
281 hdr
.image_device
= st
.st_dev
;
282 hdr
.image_inode
= st
.st_ino
;
284 memcpy(hdr
.fs_uuid
, fs
->super
->s_uuid
, sizeof(hdr
.fs_uuid
));
286 hdr
.image_time
= time(0);
287 write_header(fd
, &hdr
, sizeof(struct ext2_image_hdr
), fs
->blocksize
);
291 * These set of functions are used to write a RAW image file.
293 static ext2fs_block_bitmap meta_block_map
;
294 static ext2fs_block_bitmap scramble_block_map
; /* Directory blocks to be scrambled */
295 static blk64_t meta_blocks_count
;
297 struct process_block_struct
{
303 * These subroutines short circuits ext2fs_get_blocks and
304 * ext2fs_check_directory; we use them since we already have the inode
305 * structure, so there's no point in letting the ext2fs library read
308 static ino_t stashed_ino
= 0;
309 static struct ext2_inode
*stashed_inode
;
311 static errcode_t
meta_get_blocks(ext2_filsys fs
EXT2FS_ATTR((unused
)),
317 if ((ino
!= stashed_ino
) || !stashed_inode
)
318 return EXT2_ET_CALLBACK_NOTHANDLED
;
320 for (i
=0; i
< EXT2_N_BLOCKS
; i
++)
321 blocks
[i
] = stashed_inode
->i_block
[i
];
325 static errcode_t
meta_check_directory(ext2_filsys fs
EXT2FS_ATTR((unused
)),
328 if ((ino
!= stashed_ino
) || !stashed_inode
)
329 return EXT2_ET_CALLBACK_NOTHANDLED
;
331 if (!LINUX_S_ISDIR(stashed_inode
->i_mode
))
332 return EXT2_ET_NO_DIRECTORY
;
336 static errcode_t
meta_read_inode(ext2_filsys fs
EXT2FS_ATTR((unused
)),
338 struct ext2_inode
*inode
)
340 if ((ino
!= stashed_ino
) || !stashed_inode
)
341 return EXT2_ET_CALLBACK_NOTHANDLED
;
342 *inode
= *stashed_inode
;
346 static void use_inode_shortcuts(ext2_filsys fs
, int use_shortcuts
)
349 fs
->get_blocks
= meta_get_blocks
;
350 fs
->check_directory
= meta_check_directory
;
351 fs
->read_inode
= meta_read_inode
;
355 fs
->check_directory
= 0;
360 static int process_dir_block(ext2_filsys fs
EXT2FS_ATTR((unused
)),
362 e2_blkcnt_t blockcnt
EXT2FS_ATTR((unused
)),
363 blk64_t ref_block
EXT2FS_ATTR((unused
)),
364 int ref_offset
EXT2FS_ATTR((unused
)),
365 void *priv_data
EXT2FS_ATTR((unused
)))
367 struct process_block_struct
*p
;
369 p
= (struct process_block_struct
*) priv_data
;
371 ext2fs_mark_block_bitmap2(meta_block_map
, *block_nr
);
373 if (scramble_block_map
&& p
->is_dir
&& blockcnt
>= 0)
374 ext2fs_mark_block_bitmap2(scramble_block_map
, *block_nr
);
378 static int process_file_block(ext2_filsys fs
EXT2FS_ATTR((unused
)),
380 e2_blkcnt_t blockcnt
,
381 blk64_t ref_block
EXT2FS_ATTR((unused
)),
382 int ref_offset
EXT2FS_ATTR((unused
)),
383 void *priv_data
EXT2FS_ATTR((unused
)))
385 if (blockcnt
< 0 || all_data
) {
386 ext2fs_mark_block_bitmap2(meta_block_map
, *block_nr
);
392 static void mark_table_blocks(ext2_filsys fs
)
394 blk64_t first_block
, b
;
397 first_block
= fs
->super
->s_first_data_block
;
399 * Mark primary superblock
401 ext2fs_mark_block_bitmap2(meta_block_map
, first_block
);
405 * Mark the primary superblock descriptors
407 for (j
= 0; j
< fs
->desc_blocks
; j
++) {
408 ext2fs_mark_block_bitmap2(meta_block_map
,
409 ext2fs_descriptor_block_loc2(fs
, first_block
, j
));
411 meta_blocks_count
+= fs
->desc_blocks
;
413 for (i
= 0; i
< fs
->group_desc_count
; i
++) {
415 * Mark the blocks used for the inode table
417 if ((output_is_blk
||
418 !ext2fs_bg_flags_test(fs
, i
, EXT2_BG_INODE_UNINIT
)) &&
419 ext2fs_inode_table_loc(fs
, i
)) {
420 unsigned int end
= (unsigned) fs
->inode_blocks_per_group
;
421 /* skip unused blocks */
422 if (!output_is_blk
&&
423 EXT2_HAS_RO_COMPAT_FEATURE(fs
->super
,
424 EXT4_FEATURE_RO_COMPAT_GDT_CSUM
))
425 end
-= (ext2fs_bg_itable_unused(fs
, i
) /
426 EXT2_INODES_PER_BLOCK(fs
->super
));
427 for (j
= 0, b
= ext2fs_inode_table_loc(fs
, i
);
430 ext2fs_mark_block_bitmap2(meta_block_map
, b
);
436 * Mark block used for the block bitmap
438 if (!ext2fs_bg_flags_test(fs
, i
, EXT2_BG_BLOCK_UNINIT
) &&
439 ext2fs_block_bitmap_loc(fs
, i
)) {
440 ext2fs_mark_block_bitmap2(meta_block_map
,
441 ext2fs_block_bitmap_loc(fs
, i
));
446 * Mark block used for the inode bitmap
448 if (!ext2fs_bg_flags_test(fs
, i
, EXT2_BG_INODE_UNINIT
) &&
449 ext2fs_inode_bitmap_loc(fs
, i
)) {
450 ext2fs_mark_block_bitmap2(meta_block_map
,
451 ext2fs_inode_bitmap_loc(fs
, i
));
458 * This function returns 1 if the specified block is all zeros
460 static int check_zero_block(char *buf
, int blocksize
)
463 int left
= blocksize
;
475 static int name_id
[256];
477 #define EXT4_MAX_REC_LEN ((1<<16)-1)
479 static void scramble_dir_block(ext2_filsys fs
, blk64_t blk
, char *buf
)
482 struct ext2_dir_entry_2
*dirent
;
483 unsigned int rec_len
;
486 end
= buf
+ fs
->blocksize
;
487 for (p
= buf
; p
< end
-8; p
+= rec_len
) {
488 dirent
= (struct ext2_dir_entry_2
*) p
;
489 rec_len
= dirent
->rec_len
;
490 #ifdef WORDS_BIGENDIAN
491 rec_len
= ext2fs_swab16(rec_len
);
493 if (rec_len
== EXT4_MAX_REC_LEN
|| rec_len
== 0)
494 rec_len
= fs
->blocksize
;
496 rec_len
= (rec_len
& 65532) | ((rec_len
& 3) << 16);
498 printf("rec_len = %d, name_len = %d\n", rec_len
, dirent
->name_len
);
500 if (rec_len
< 8 || (rec_len
% 4) ||
502 printf(_("Corrupt directory block %llu: "
503 "bad rec_len (%d)\n"),
504 (unsigned long long) blk
, rec_len
);
506 (void) ext2fs_set_rec_len(fs
, rec_len
,
507 (struct ext2_dir_entry
*) dirent
);
508 #ifdef WORDS_BIGENDIAN
509 dirent
->rec_len
= ext2fs_swab16(dirent
->rec_len
);
513 if (dirent
->name_len
+ 8U > rec_len
) {
514 printf(_("Corrupt directory block %llu: "
515 "bad name_len (%d)\n"),
516 (unsigned long long) blk
, dirent
->name_len
);
517 dirent
->name_len
= rec_len
- 8;
521 len
= rec_len
- dirent
->name_len
- 8;
523 memset(cp
+dirent
->name_len
, 0, len
);
524 if (dirent
->name_len
==1 && cp
[0] == '.')
526 if (dirent
->name_len
==2 && cp
[0] == '.' && cp
[1] == '.')
529 memset(cp
, 'A', dirent
->name_len
);
530 len
= dirent
->name_len
;
532 while ((len
> 0) && (id
> 0)) {
541 static char got_sigint
;
543 static void sigint_handler(int unused
EXT2FS_ATTR((unused
)))
546 signal (SIGINT
, SIG_DFL
);
549 #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \
550 ((float) (b)))) + 0.5))
551 #define calc_rate(t, b, d) (((float)(t) / ((1024 * 1024) / (b))) / (d))
553 static int print_progress(blk64_t num
, blk64_t total
)
555 return fprintf(stderr
, _("%llu / %llu blocks (%d%%)"), num
, total
,
556 calc_percent(num
, total
));
559 static void output_meta_data_blocks(ext2_filsys fs
, int fd
, int flags
)
563 char *buf
, *zero_buf
;
566 blk64_t distance
= 0;
567 blk64_t end
= ext2fs_blocks_count(fs
->super
);
568 time_t last_update
= 0;
569 time_t start_time
= 0;
570 blk64_t total_written
= 0;
573 retval
= ext2fs_get_mem(fs
->blocksize
, &buf
);
575 com_err(program_name
, retval
, "%s",
576 _("while allocating buffer"));
579 retval
= ext2fs_get_memzero(fs
->blocksize
, &zero_buf
);
581 com_err(program_name
, retval
, "%s",
582 _("while allocating buffer"));
586 fprintf(stderr
, "%s", _("Copying "));
587 bscount
= print_progress(total_written
, meta_blocks_count
);
589 last_update
= time(NULL
);
590 start_time
= time(NULL
);
592 /* when doing an in place move to the right, you can't start
593 at the beginning or you will overwrite data, so instead
594 divide the fs up into distance size chunks and write them
596 if (move_mode
&& dest_offset
> source_offset
) {
597 distance
= (dest_offset
- source_offset
) / fs
->blocksize
;
598 if (distance
< ext2fs_blocks_count(fs
->super
))
599 start
= ext2fs_blocks_count(fs
->super
) - distance
;
602 signal (SIGINT
, sigint_handler
);
605 seek_set(fd
, (start
* fs
->blocksize
) + dest_offset
);
606 for (blk
= start
; blk
< end
; blk
++) {
609 /* moving to the right */
610 if (distance
>= ext2fs_blocks_count(fs
->super
)||
611 start
== ext2fs_blocks_count(fs
->super
) -
613 kill(getpid(), SIGINT
);
615 /* moving to the left */
616 if (blk
< (source_offset
- dest_offset
) /
618 kill(getpid(), SIGINT
);
622 fprintf(stderr
, "%s",
623 _("Stopping now will destroy the filesystem, "
624 "interrupt again if you are sure\n"));
626 fprintf(stderr
, "%s", _("Copying "));
627 bscount
= print_progress(total_written
,
634 if (show_progress
&& last_update
!= time(NULL
)) {
636 last_update
= time(NULL
);
639 bscount
= print_progress(total_written
,
641 duration
= time(NULL
) - start_time
;
642 if (duration
> 5 && total_written
) {
643 time_t est
= (duration
* meta_blocks_count
/
644 total_written
) - duration
;
646 strftime(buff
, 30, "%T", gmtime(&est
));
649 _(" %s remaining at %.2f MB/s"),
650 buff
, calc_rate(total_written
,
656 if ((blk
>= fs
->super
->s_first_data_block
) &&
657 ext2fs_test_block_bitmap2(meta_block_map
, blk
)) {
658 retval
= io_channel_read_blk64(fs
->io
, blk
, 1, buf
);
660 com_err(program_name
, retval
,
661 _("error reading block %llu"), blk
);
664 if (scramble_block_map
&&
665 ext2fs_test_block_bitmap2(scramble_block_map
, blk
))
666 scramble_dir_block(fs
, blk
, buf
);
667 if ((flags
& E2IMAGE_CHECK_ZERO_FLAG
) &&
668 check_zero_block(buf
, fs
->blocksize
))
671 seek_relative(fd
, sparse
);
673 if (check_block(fd
, buf
, check_buf
, fs
->blocksize
)) {
674 seek_relative(fd
, fs
->blocksize
);
677 generic_write(fd
, buf
, fs
->blocksize
, blk
);
682 generic_write(fd
, zero_buf
,
686 sparse
+= fs
->blocksize
;
687 if (sparse
> 1024*1024) {
688 seek_relative(fd
, 1024*1024);
693 if (distance
&& start
) {
694 if (start
< distance
) {
700 if (end
< distance
) {
701 /* past overlap, do rest in one go */
709 signal (SIGINT
, SIG_DFL
);
711 time_t duration
= time(NULL
) - start_time
;
714 strftime(buff
, 30, "%T", gmtime(&duration
));
715 fprintf(stderr
, _("Copied %llu / %llu blocks (%d%%) in %s "),
716 total_written
, meta_blocks_count
,
717 calc_percent(total_written
, meta_blocks_count
), buff
);
719 fprintf(stderr
, _("at %.2f MB/s"),
720 calc_rate(total_written
, fs
->blocksize
, duration
));
721 fputs(" \n", stderr
);
723 #ifdef HAVE_FTRUNCATE64
727 offset
= seek_set(fd
,
728 fs
->blocksize
* ext2fs_blocks_count(fs
->super
) + dest_offset
);
730 offset
= seek_relative(fd
, sparse
);
732 if (ftruncate64(fd
, offset
) < 0) {
733 seek_relative(fd
, -1);
734 generic_write(fd
, zero_buf
, 1, NO_BLK
);
738 if (sparse
&& !distance
) {
739 seek_relative(fd
, sparse
-1);
740 generic_write(fd
, zero_buf
, 1, NO_BLK
);
743 ext2fs_free_mem(&zero_buf
);
744 ext2fs_free_mem(&buf
);
747 static void init_l1_table(struct ext2_qcow2_image
*image
)
752 ret
= ext2fs_get_arrayzero(image
->l1_size
, sizeof(__u64
), &l1_table
);
754 com_err(program_name
, ret
, "%s",
755 _("while allocating l1 table"));
759 image
->l1_table
= l1_table
;
762 static void init_l2_cache(struct ext2_qcow2_image
*image
)
764 unsigned int count
, i
;
765 struct ext2_qcow2_l2_cache
*cache
;
766 struct ext2_qcow2_l2_table
*table
;
769 ret
= ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache
),
774 count
= (image
->l1_size
> L2_CACHE_PREALLOC
) ? L2_CACHE_PREALLOC
:
777 cache
->count
= count
;
779 cache
->next_offset
= image
->l2_offset
;
781 for (i
= 0; i
< count
; i
++) {
782 ret
= ext2fs_get_arrayzero(1,
783 sizeof(struct ext2_qcow2_l2_table
), &table
);
787 ret
= ext2fs_get_arrayzero(image
->l2_size
,
788 sizeof(__u64
), &table
->data
);
792 table
->next
= cache
->free_head
;
793 cache
->free_head
= table
;
796 image
->l2_cache
= cache
;
800 com_err(program_name
, ret
, "%s", _("while allocating l2 cache"));
804 static void put_l2_cache(struct ext2_qcow2_image
*image
)
806 struct ext2_qcow2_l2_cache
*cache
= image
->l2_cache
;
807 struct ext2_qcow2_l2_table
*tmp
, *table
;
812 table
= cache
->free_head
;
813 cache
->free_head
= NULL
;
818 ext2fs_free_mem(&tmp
->data
);
819 ext2fs_free_mem(&tmp
);
822 if (cache
->free
!= cache
->count
) {
823 fprintf(stderr
, "%s", _("Warning: There are still tables in "
824 "the cache while putting the cache, "
825 "data will be lost so the image may "
827 table
= cache
->used_head
;
828 cache
->used_head
= NULL
;
832 ext2fs_free_mem(&cache
);
835 static int init_refcount(struct ext2_qcow2_image
*img
, blk64_t table_offset
)
837 struct ext2_qcow2_refcount
*ref
;
838 blk64_t table_clusters
;
841 ref
= &(img
->refcount
);
844 * One refcount block addresses 2048 clusters, one refcount table
845 * addresses cluster/sizeof(__u64) refcount blocks, and we need
846 * to address meta_blocks_count clusters + qcow2 metadata clusters
849 table_clusters
= meta_blocks_count
+ (table_offset
>>
851 table_clusters
>>= (img
->cluster_bits
+ 6 - 1);
852 table_clusters
= (table_clusters
== 0) ? 1 : table_clusters
;
854 ref
->refcount_table_offset
= table_offset
;
855 ref
->refcount_table_clusters
= table_clusters
;
856 ref
->refcount_table_index
= 0;
857 ref
->refcount_block_index
= 0;
859 /* Allocate refcount table */
860 ret
= ext2fs_get_arrayzero(ref
->refcount_table_clusters
,
861 img
->cluster_size
, &ref
->refcount_table
);
865 /* Allocate refcount block */
866 ret
= ext2fs_get_arrayzero(1, img
->cluster_size
, &ref
->refcount_block
);
868 ext2fs_free_mem(&ref
->refcount_table
);
873 static int initialize_qcow2_image(int fd
, ext2_filsys fs
,
874 struct ext2_qcow2_image
*image
)
876 struct ext2_qcow2_hdr
*header
;
877 blk64_t total_size
, offset
;
878 int shift
, l2_bits
, header_size
, l1_size
, ret
;
879 int cluster_bits
= get_bits_from_size(fs
->blocksize
);
880 struct ext2_super_block
*sb
= fs
->super
;
882 /* Allocate header */
883 ret
= ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr
), &header
);
887 total_size
= ext2fs_blocks_count(sb
) << cluster_bits
;
888 image
->cluster_size
= fs
->blocksize
;
889 image
->l2_size
= 1 << (cluster_bits
- 3);
890 image
->cluster_bits
= cluster_bits
;
893 header
->magic
= ext2fs_cpu_to_be32(QCOW_MAGIC
);
894 header
->version
= ext2fs_cpu_to_be32(QCOW_VERSION
);
895 header
->size
= ext2fs_cpu_to_be64(total_size
);
896 header
->cluster_bits
= ext2fs_cpu_to_be32(cluster_bits
);
898 header_size
= (sizeof(struct ext2_qcow2_hdr
) + 7) & ~7;
899 offset
= align_offset(header_size
, image
->cluster_size
);
901 header
->l1_table_offset
= ext2fs_cpu_to_be64(offset
);
902 image
->l1_offset
= offset
;
904 l2_bits
= cluster_bits
- 3;
905 shift
= cluster_bits
+ l2_bits
;
906 l1_size
= ((total_size
+ (1LL << shift
) - 1) >> shift
);
907 header
->l1_size
= ext2fs_cpu_to_be32(l1_size
);
908 image
->l1_size
= l1_size
;
910 /* Make space for L1 table */
911 offset
+= align_offset(l1_size
* sizeof(blk64_t
), image
->cluster_size
);
913 /* Initialize refcounting */
914 ret
= init_refcount(image
, offset
);
916 ext2fs_free_mem(&header
);
919 header
->refcount_table_offset
= ext2fs_cpu_to_be64(offset
);
920 header
->refcount_table_clusters
=
921 ext2fs_cpu_to_be32(image
->refcount
.refcount_table_clusters
);
922 offset
+= image
->cluster_size
;
923 offset
+= image
->refcount
.refcount_table_clusters
<<
926 /* Make space for L2 tables */
927 image
->l2_offset
= offset
;
928 offset
+= image
->cluster_size
;
930 /* Make space for first refcount block */
931 image
->refcount
.refcount_block_offset
= offset
;
934 /* Initialize l1 and l2 tables */
935 init_l1_table(image
);
936 init_l2_cache(image
);
941 static void free_qcow2_image(struct ext2_qcow2_image
*img
)
947 ext2fs_free_mem(&img
->hdr
);
950 ext2fs_free_mem(&img
->l1_table
);
952 if (img
->refcount
.refcount_table
)
953 ext2fs_free_mem(&img
->refcount
.refcount_table
);
954 if (img
->refcount
.refcount_block
)
955 ext2fs_free_mem(&img
->refcount
.refcount_block
);
959 ext2fs_free_mem(&img
);
963 * Put table from used list (used_head) into free list (free_head).
964 * l2_table is used to return pointer to the next used table (used_head).
966 static void put_used_table(struct ext2_qcow2_image
*img
,
967 struct ext2_qcow2_l2_table
**l2_table
)
969 struct ext2_qcow2_l2_cache
*cache
= img
->l2_cache
;
970 struct ext2_qcow2_l2_table
*table
;
972 table
= cache
->used_head
;
973 cache
->used_head
= table
->next
;
977 cache
->used_tail
= NULL
;
979 /* Clean the table for case we will need to use it again */
980 memset(table
->data
, 0, img
->cluster_size
);
981 table
->next
= cache
->free_head
;
982 cache
->free_head
= table
;
986 *l2_table
= cache
->used_head
;
989 static void flush_l2_cache(struct ext2_qcow2_image
*image
)
993 struct ext2_qcow2_l2_cache
*cache
= image
->l2_cache
;
994 struct ext2_qcow2_l2_table
*table
= cache
->used_head
;
997 /* Store current position */
998 offset
= seek_relative(fd
, 0);
1001 while (cache
->free
< cache
->count
) {
1002 if (seek
!= table
->offset
) {
1003 seek_set(fd
, table
->offset
);
1004 seek
= table
->offset
;
1007 generic_write(fd
, (char *)table
->data
, image
->cluster_size
,
1009 put_used_table(image
, &table
);
1010 seek
+= image
->cluster_size
;
1013 /* Restore previous position */
1014 seek_set(fd
, offset
);
1018 * Get first free table (from free_head) and put it into tail of used list
1020 * l2_table is used to return pointer to moved table.
1021 * Returns 1 if the cache is full, 0 otherwise.
1023 static void get_free_table(struct ext2_qcow2_image
*image
,
1024 struct ext2_qcow2_l2_table
**l2_table
)
1026 struct ext2_qcow2_l2_table
*table
;
1027 struct ext2_qcow2_l2_cache
*cache
= image
->l2_cache
;
1029 if (0 == cache
->free
)
1030 flush_l2_cache(image
);
1032 table
= cache
->free_head
;
1034 cache
->free_head
= table
->next
;
1036 if (cache
->used_tail
)
1037 cache
->used_tail
->next
= table
;
1039 /* First item in the used list */
1040 cache
->used_head
= table
;
1042 cache
->used_tail
= table
;
1048 static int add_l2_item(struct ext2_qcow2_image
*img
, blk64_t blk
,
1049 blk64_t data
, blk64_t next
)
1051 struct ext2_qcow2_l2_cache
*cache
= img
->l2_cache
;
1052 struct ext2_qcow2_l2_table
*table
= cache
->used_tail
;
1053 blk64_t l1_index
= blk
/ img
->l2_size
;
1054 blk64_t l2_index
= blk
& (img
->l2_size
- 1);
1058 * Need to create new table if it does not exist,
1061 if (!table
|| (table
->l1_index
!= l1_index
)) {
1062 get_free_table(img
, &table
);
1063 table
->l1_index
= l1_index
;
1064 table
->offset
= cache
->next_offset
;
1065 cache
->next_offset
= next
;
1066 img
->l1_table
[l1_index
] =
1067 ext2fs_cpu_to_be64(table
->offset
| QCOW_OFLAG_COPIED
);
1071 table
->data
[l2_index
] = ext2fs_cpu_to_be64(data
| QCOW_OFLAG_COPIED
);
1075 static int update_refcount(int fd
, struct ext2_qcow2_image
*img
,
1076 blk64_t offset
, blk64_t rfblk_pos
)
1078 struct ext2_qcow2_refcount
*ref
;
1082 ref
= &(img
->refcount
);
1083 table_index
= offset
>> (2 * img
->cluster_bits
- 1);
1086 * Need to create new refcount block when the offset addresses
1087 * another item in the refcount table
1089 if (table_index
!= ref
->refcount_table_index
) {
1091 seek_set(fd
, ref
->refcount_block_offset
);
1093 generic_write(fd
, (char *)ref
->refcount_block
,
1094 img
->cluster_size
, NO_BLK
);
1095 memset(ref
->refcount_block
, 0, img
->cluster_size
);
1097 ref
->refcount_table
[ref
->refcount_table_index
] =
1098 ext2fs_cpu_to_be64(ref
->refcount_block_offset
);
1099 ref
->refcount_block_offset
= rfblk_pos
;
1100 ref
->refcount_block_index
= 0;
1101 ref
->refcount_table_index
= table_index
;
1106 * We are relying on the fact that we are creating the qcow2
1107 * image sequentially, hence we will always allocate refcount
1108 * block items sequentialy.
1110 ref
->refcount_block
[ref
->refcount_block_index
] = ext2fs_cpu_to_be16(1);
1111 ref
->refcount_block_index
++;
1115 static int sync_refcount(int fd
, struct ext2_qcow2_image
*img
)
1117 struct ext2_qcow2_refcount
*ref
;
1119 ref
= &(img
->refcount
);
1121 ref
->refcount_table
[ref
->refcount_table_index
] =
1122 ext2fs_cpu_to_be64(ref
->refcount_block_offset
);
1123 seek_set(fd
, ref
->refcount_table_offset
);
1124 generic_write(fd
, (char *)ref
->refcount_table
,
1125 ref
->refcount_table_clusters
<< img
->cluster_bits
, NO_BLK
);
1127 seek_set(fd
, ref
->refcount_block_offset
);
1128 generic_write(fd
, (char *)ref
->refcount_block
, img
->cluster_size
,
1133 static void output_qcow2_meta_data_blocks(ext2_filsys fs
, int fd
)
1136 blk64_t blk
, offset
, size
, end
;
1138 struct ext2_qcow2_image
*img
;
1139 unsigned int header_size
;
1141 /* allocate struct ext2_qcow2_image */
1142 retval
= ext2fs_get_mem(sizeof(struct ext2_qcow2_image
), &img
);
1144 com_err(program_name
, retval
, "%s",
1145 _("while allocating ext2_qcow2_image"));
1149 retval
= initialize_qcow2_image(fd
, fs
, img
);
1151 com_err(program_name
, retval
, "%s",
1152 _("while initializing ext2_qcow2_image"));
1155 header_size
= align_offset(sizeof(struct ext2_qcow2_hdr
),
1157 write_header(fd
, img
->hdr
, sizeof(struct ext2_qcow2_hdr
), header_size
);
1159 /* Refcount all qcow2 related metadata up to refcount_block_offset */
1160 end
= img
->refcount
.refcount_block_offset
;
1162 blk
= end
+ img
->cluster_size
;
1163 for (offset
= 0; offset
<= end
; offset
+= img
->cluster_size
) {
1164 if (update_refcount(fd
, img
, offset
, blk
)) {
1165 blk
+= img
->cluster_size
;
1167 * If we create new refcount block, we need to refcount
1170 end
+= img
->cluster_size
;
1173 seek_set(fd
, offset
);
1175 retval
= ext2fs_get_mem(fs
->blocksize
, &buf
);
1177 com_err(program_name
, retval
, "%s",
1178 _("while allocating buffer"));
1181 /* Write qcow2 data blocks */
1182 for (blk
= 0; blk
< ext2fs_blocks_count(fs
->super
); blk
++) {
1183 if ((blk
>= fs
->super
->s_first_data_block
) &&
1184 ext2fs_test_block_bitmap2(meta_block_map
, blk
)) {
1185 retval
= io_channel_read_blk64(fs
->io
, blk
, 1, buf
);
1187 com_err(program_name
, retval
,
1188 _("error reading block %llu"), blk
);
1191 if (scramble_block_map
&&
1192 ext2fs_test_block_bitmap2(scramble_block_map
, blk
))
1193 scramble_dir_block(fs
, blk
, buf
);
1194 if (check_zero_block(buf
, fs
->blocksize
))
1197 if (update_refcount(fd
, img
, offset
, offset
)) {
1198 /* Make space for another refcount block */
1199 offset
+= img
->cluster_size
;
1200 seek_set(fd
, offset
);
1202 * We have created the new refcount block, this
1203 * means that we need to refcount it as well.
1204 * So the previous update_refcount refcounted
1205 * the block itself and now we are going to
1206 * create refcount for data. New refcount
1207 * block should not be created!
1209 if (update_refcount(fd
, img
, offset
, offset
)) {
1210 fprintf(stderr
, "%s",
1211 _("Programming error: multiple "
1212 "sequential refcount blocks "
1218 generic_write(fd
, buf
, fs
->blocksize
, blk
);
1220 if (add_l2_item(img
, blk
, offset
,
1221 offset
+ img
->cluster_size
)) {
1222 offset
+= img
->cluster_size
;
1223 if (update_refcount(fd
, img
, offset
,
1224 offset
+ img
->cluster_size
)) {
1225 offset
+= img
->cluster_size
;
1226 if (update_refcount(fd
, img
, offset
,
1228 fprintf(stderr
, "%s",
1229 _("Programming error: multiple sequential refcount "
1230 "blocks created!\n"));
1234 offset
+= img
->cluster_size
;
1235 seek_set(fd
, offset
);
1239 offset
+= img
->cluster_size
;
1242 update_refcount(fd
, img
, offset
, offset
);
1243 flush_l2_cache(img
);
1244 sync_refcount(fd
, img
);
1247 seek_set(fd
, img
->l1_offset
);
1248 size
= img
->l1_size
* sizeof(__u64
);
1249 generic_write(fd
, (char *)img
->l1_table
, size
, NO_BLK
);
1251 ext2fs_free_mem(&buf
);
1252 free_qcow2_image(img
);
1255 static void write_raw_image_file(ext2_filsys fs
, int fd
, int type
, int flags
)
1257 struct process_block_struct pb
;
1258 struct ext2_inode inode
;
1259 ext2_inode_scan scan
;
1264 meta_blocks_count
= 0;
1265 retval
= ext2fs_allocate_block_bitmap(fs
, _("in-use block map"),
1268 com_err(program_name
, retval
, "%s",
1269 _("while allocating block bitmap"));
1273 if (flags
& E2IMAGE_SCRAMBLE_FLAG
) {
1274 retval
= ext2fs_allocate_block_bitmap(fs
, "scramble block map",
1275 &scramble_block_map
);
1277 com_err(program_name
, retval
, "%s",
1278 _("while allocating scramble block bitmap"));
1283 mark_table_blocks(fs
);
1285 printf("%s", _("Scanning inodes...\n"));
1287 retval
= ext2fs_open_inode_scan(fs
, 0, &scan
);
1289 com_err(program_name
, retval
, "%s",
1290 _("while opening inode scan"));
1294 retval
= ext2fs_get_mem(fs
->blocksize
* 3, &block_buf
);
1296 com_err(program_name
, 0, "%s",
1297 _("Can't allocate block buffer"));
1301 use_inode_shortcuts(fs
, 1);
1302 stashed_inode
= &inode
;
1304 retval
= ext2fs_get_next_inode(scan
, &ino
, &inode
);
1305 if (retval
== EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
)
1308 com_err(program_name
, retval
, "%s",
1309 _("while getting next inode"));
1314 if (!inode
.i_links_count
)
1316 if (ext2fs_file_acl_block(fs
, &inode
)) {
1317 ext2fs_mark_block_bitmap2(meta_block_map
,
1318 ext2fs_file_acl_block(fs
, &inode
));
1319 meta_blocks_count
++;
1321 if (!ext2fs_inode_has_valid_blocks2(fs
, &inode
))
1326 pb
.is_dir
= LINUX_S_ISDIR(inode
.i_mode
);
1327 if (LINUX_S_ISDIR(inode
.i_mode
) ||
1328 (LINUX_S_ISLNK(inode
.i_mode
) &&
1329 ext2fs_inode_has_valid_blocks2(fs
, &inode
)) ||
1330 ino
== fs
->super
->s_journal_inum
) {
1331 retval
= ext2fs_block_iterate3(fs
, ino
,
1332 BLOCK_FLAG_READ_ONLY
, block_buf
,
1333 process_dir_block
, &pb
);
1335 com_err(program_name
, retval
,
1336 _("while iterating over inode %u"),
1341 if ((inode
.i_flags
& EXT4_EXTENTS_FL
) ||
1342 inode
.i_block
[EXT2_IND_BLOCK
] ||
1343 inode
.i_block
[EXT2_DIND_BLOCK
] ||
1344 inode
.i_block
[EXT2_TIND_BLOCK
] || all_data
) {
1345 retval
= ext2fs_block_iterate3(fs
,
1346 ino
, BLOCK_FLAG_READ_ONLY
, block_buf
,
1347 process_file_block
, &pb
);
1349 com_err(program_name
, retval
,
1350 _("while iterating over inode %u"), ino
);
1356 use_inode_shortcuts(fs
, 0);
1358 if (type
& E2IMAGE_QCOW2
)
1359 output_qcow2_meta_data_blocks(fs
, fd
);
1361 output_meta_data_blocks(fs
, fd
, flags
);
1363 ext2fs_free_mem(&block_buf
);
1364 ext2fs_close_inode_scan(scan
);
1365 ext2fs_free_block_bitmap(meta_block_map
);
1366 if (type
& E2IMAGE_SCRAMBLE_FLAG
)
1367 ext2fs_free_block_bitmap(scramble_block_map
);
1370 static void install_image(char *device
, char *image_fn
, int type
)
1374 int open_flag
= EXT2_FLAG_IMAGE_FILE
| EXT2_FLAG_64BITS
;
1380 com_err(program_name
, 0, "%s",
1381 _("Raw and qcow2 images cannot be installed"));
1385 #ifdef CONFIG_TESTIO_DEBUG
1386 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1387 io_ptr
= test_io_manager
;
1388 test_io_backing_manager
= unix_io_manager
;
1391 io_ptr
= unix_io_manager
;
1393 retval
= ext2fs_open (image_fn
, open_flag
, 0, 0,
1396 com_err(program_name
, retval
, _("while trying to open %s"),
1401 retval
= ext2fs_read_bitmaps (fs
);
1403 com_err(program_name
, retval
, "%s", _("error reading bitmaps"));
1407 fd
= ext2fs_open_file(image_fn
, O_RDONLY
, 0);
1413 retval
= io_ptr
->open(device
, IO_FLAG_RW
, &io
);
1415 com_err(device
, 0, "%s", _("while opening device file"));
1419 ext2fs_rewrite_to_io(fs
, io
);
1421 seek_set(fd
, fs
->image_header
->offset_inode
);
1423 retval
= ext2fs_image_inode_read(fs
, fd
, 0);
1425 com_err(image_fn
, 0, "%s",
1426 _("while restoring the image table"));
1431 ext2fs_close_free(&fs
);
1434 static struct ext2_qcow2_hdr
*check_qcow2_image(int *fd
, char *name
)
1437 *fd
= ext2fs_open_file(name
, O_RDONLY
, 0600);
1441 return qcow2_read_header(*fd
);
1444 int main (int argc
, char ** argv
)
1449 char *image_fn
, offset_opt
[64];
1450 struct ext2_qcow2_hdr
*header
= NULL
;
1451 int open_flag
= EXT2_FLAG_64BITS
;
1454 int mount_flags
= 0;
1458 int ignore_rw_mount
= 0;
1463 setlocale(LC_MESSAGES
, "");
1464 setlocale(LC_CTYPE
, "");
1465 bindtextdomain(NLS_CAT_NAME
, LOCALEDIR
);
1466 textdomain(NLS_CAT_NAME
);
1467 set_com_err_gettext(gettext
);
1469 fprintf (stderr
, "e2image %s (%s)\n", E2FSPROGS_VERSION
,
1472 program_name
= *argv
;
1473 add_error_table(&et_ext2_error_table
);
1474 while ((c
= getopt(argc
, argv
, "nrsIQafo:O:pc")) != EOF
)
1477 flags
|= E2IMAGE_INSTALL_FLAG
;
1482 img_type
|= E2IMAGE_QCOW2
;
1487 img_type
|= E2IMAGE_RAW
;
1490 flags
|= E2IMAGE_SCRAMBLE_FLAG
;
1496 ignore_rw_mount
= 1;
1502 source_offset
= strtoull(optarg
, NULL
, 0);
1505 dest_offset
= strtoull(optarg
, NULL
, 0);
1516 if (optind
== argc
- 1 &&
1517 (source_offset
|| dest_offset
))
1519 else if (optind
!= argc
- 2 )
1522 if (all_data
&& !img_type
) {
1523 com_err(program_name
, 0, "%s", _("-a option can only be used "
1524 "with raw or QCOW2 images."));
1527 if ((source_offset
|| dest_offset
) && img_type
!= E2IMAGE_RAW
) {
1528 com_err(program_name
, 0, "%s",
1529 _("Offsets are only allowed with raw images."));
1532 if (move_mode
&& img_type
!= E2IMAGE_RAW
) {
1533 com_err(program_name
, 0, "%s",
1534 _("Move mode is only allowed with raw images."));
1537 if (move_mode
&& !all_data
) {
1538 com_err(program_name
, 0, "%s",
1539 _("Move mode requires all data mode."));
1542 device_name
= argv
[optind
];
1544 image_fn
= device_name
;
1545 else image_fn
= argv
[optind
+1];
1547 retval
= ext2fs_check_if_mounted(device_name
, &mount_flags
);
1549 com_err(program_name
, retval
, "%s", _("checking if mounted"));
1553 if (img_type
&& !ignore_rw_mount
&&
1554 (mount_flags
& EXT2_MF_MOUNTED
) &&
1555 !(mount_flags
& EXT2_MF_READONLY
)) {
1556 fprintf(stderr
, "%s", _("\nRunning e2image on a R/W mounted "
1557 "filesystem can result in an\n"
1558 "inconsistent image which will not be useful "
1559 "for debugging purposes.\n"
1560 "Use -f option if you really want to do that.\n"));
1564 if (flags
& E2IMAGE_INSTALL_FLAG
) {
1565 install_image(device_name
, image_fn
, img_type
);
1569 if (img_type
& E2IMAGE_RAW
) {
1570 header
= check_qcow2_image(&qcow2_fd
, device_name
);
1572 flags
|= E2IMAGE_IS_QCOW2_FLAG
;
1576 sprintf(offset_opt
, "offset=%llu", source_offset
);
1577 retval
= ext2fs_open2(device_name
, offset_opt
, open_flag
, 0, 0,
1578 unix_io_manager
, &fs
);
1580 com_err (program_name
, retval
, _("while trying to open %s"),
1582 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout
);
1587 if (strcmp(image_fn
, "-") == 0)
1590 int o_flags
= O_CREAT
|O_RDWR
;
1592 if (img_type
!= E2IMAGE_RAW
)
1594 if (access(image_fn
, F_OK
) != 0)
1595 flags
|= E2IMAGE_CHECK_ZERO_FLAG
;
1596 fd
= ext2fs_open_file(image_fn
, o_flags
, 0600);
1598 com_err(program_name
, errno
,
1599 _("while trying to open %s"), image_fn
);
1604 seek_set(fd
, dest_offset
);
1606 if ((img_type
& E2IMAGE_QCOW2
) && (fd
== 1)) {
1607 com_err(program_name
, 0, "%s",
1608 _("QCOW2 image can not be written to the stdout!\n"));
1612 if (fstat(fd
, &st
)) {
1613 com_err(program_name
, 0, "%s",
1614 _("Can not stat output\n"));
1617 if (S_ISBLK(st
.st_mode
))
1620 if (flags
& E2IMAGE_IS_QCOW2_FLAG
) {
1621 ret
= qcow2_write_raw_image(qcow2_fd
, fd
, header
);
1623 if (ret
== -QCOW_COMPRESSED
)
1624 fprintf(stderr
, _("Image (%s) is compressed\n"),
1626 if (ret
== -QCOW_ENCRYPTED
)
1627 fprintf(stderr
, _("Image (%s) is encrypted\n"),
1629 com_err(program_name
, ret
,
1630 _("while trying to convert qcow2 image"
1631 " (%s) into raw image (%s)"),
1632 device_name
, image_fn
);
1638 if (img_type
!= E2IMAGE_RAW
) {
1639 fprintf(stderr
, "%s", _("The -c option only supported "
1644 fprintf(stderr
, "%s", _("The -c option not supported "
1645 "when writing to stdout\n"));
1648 retval
= ext2fs_get_mem(fs
->blocksize
, &check_buf
);
1650 com_err(program_name
, retval
, "%s",
1651 _("while allocating check_buf"));
1655 if (show_progress
&& (img_type
!= E2IMAGE_RAW
)) {
1656 fprintf(stderr
, "%s",
1657 _("The -p option only supported in raw mode\n"));
1661 write_raw_image_file(fs
, fd
, img_type
, flags
);
1663 write_image_file(fs
, fd
);
1665 ext2fs_close_free(&fs
);
1667 printf(_("%d blocks already contained the data to be copied\n"),
1675 remove_error_table(&et_ext2_error_table
);