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
&& ext2fs_has_group_desc_csum(fs
))
423 end
-= (ext2fs_bg_itable_unused(fs
, i
) /
424 EXT2_INODES_PER_BLOCK(fs
->super
));
425 for (j
= 0, b
= ext2fs_inode_table_loc(fs
, i
);
428 ext2fs_mark_block_bitmap2(meta_block_map
, b
);
434 * Mark block used for the block bitmap
436 if (!ext2fs_bg_flags_test(fs
, i
, EXT2_BG_BLOCK_UNINIT
) &&
437 ext2fs_block_bitmap_loc(fs
, i
)) {
438 ext2fs_mark_block_bitmap2(meta_block_map
,
439 ext2fs_block_bitmap_loc(fs
, i
));
444 * Mark block used for the inode bitmap
446 if (!ext2fs_bg_flags_test(fs
, i
, EXT2_BG_INODE_UNINIT
) &&
447 ext2fs_inode_bitmap_loc(fs
, i
)) {
448 ext2fs_mark_block_bitmap2(meta_block_map
,
449 ext2fs_inode_bitmap_loc(fs
, i
));
456 * This function returns 1 if the specified block is all zeros
458 static int check_zero_block(char *buf
, int blocksize
)
461 int left
= blocksize
;
473 static int name_id
[256];
475 #define EXT4_MAX_REC_LEN ((1<<16)-1)
477 static void scramble_dir_block(ext2_filsys fs
, blk64_t blk
, char *buf
)
480 struct ext2_dir_entry_2
*dirent
;
481 unsigned int rec_len
;
484 end
= buf
+ fs
->blocksize
;
485 for (p
= buf
; p
< end
-8; p
+= rec_len
) {
486 dirent
= (struct ext2_dir_entry_2
*) p
;
487 rec_len
= dirent
->rec_len
;
488 #ifdef WORDS_BIGENDIAN
489 rec_len
= ext2fs_swab16(rec_len
);
491 if (rec_len
== EXT4_MAX_REC_LEN
|| rec_len
== 0)
492 rec_len
= fs
->blocksize
;
494 rec_len
= (rec_len
& 65532) | ((rec_len
& 3) << 16);
496 printf("rec_len = %d, name_len = %d\n", rec_len
, dirent
->name_len
);
498 if (rec_len
< 8 || (rec_len
% 4) ||
500 printf(_("Corrupt directory block %llu: "
501 "bad rec_len (%d)\n"),
502 (unsigned long long) blk
, rec_len
);
504 (void) ext2fs_set_rec_len(fs
, rec_len
,
505 (struct ext2_dir_entry
*) dirent
);
506 #ifdef WORDS_BIGENDIAN
507 dirent
->rec_len
= ext2fs_swab16(dirent
->rec_len
);
511 if (dirent
->name_len
+ 8U > rec_len
) {
512 printf(_("Corrupt directory block %llu: "
513 "bad name_len (%d)\n"),
514 (unsigned long long) blk
, dirent
->name_len
);
515 dirent
->name_len
= rec_len
- 8;
519 len
= rec_len
- dirent
->name_len
- 8;
521 memset(cp
+dirent
->name_len
, 0, len
);
522 if (dirent
->name_len
==1 && cp
[0] == '.')
524 if (dirent
->name_len
==2 && cp
[0] == '.' && cp
[1] == '.')
527 memset(cp
, 'A', dirent
->name_len
);
528 len
= dirent
->name_len
;
530 while ((len
> 0) && (id
> 0)) {
539 static char got_sigint
;
541 static void sigint_handler(int unused
EXT2FS_ATTR((unused
)))
544 signal (SIGINT
, SIG_DFL
);
547 #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \
548 ((float) (b)))) + 0.5))
549 #define calc_rate(t, b, d) (((float)(t) / ((1024 * 1024) / (b))) / (d))
551 static int print_progress(blk64_t num
, blk64_t total
)
553 return fprintf(stderr
, _("%llu / %llu blocks (%d%%)"), num
, total
,
554 calc_percent(num
, total
));
557 static void output_meta_data_blocks(ext2_filsys fs
, int fd
, int flags
)
561 char *buf
, *zero_buf
;
564 blk64_t distance
= 0;
565 blk64_t end
= ext2fs_blocks_count(fs
->super
);
566 time_t last_update
= 0;
567 time_t start_time
= 0;
568 blk64_t total_written
= 0;
571 retval
= ext2fs_get_mem(fs
->blocksize
, &buf
);
573 com_err(program_name
, retval
, "%s",
574 _("while allocating buffer"));
577 retval
= ext2fs_get_memzero(fs
->blocksize
, &zero_buf
);
579 com_err(program_name
, retval
, "%s",
580 _("while allocating buffer"));
584 fprintf(stderr
, "%s", _("Copying "));
585 bscount
= print_progress(total_written
, meta_blocks_count
);
587 last_update
= time(NULL
);
588 start_time
= time(NULL
);
590 /* when doing an in place move to the right, you can't start
591 at the beginning or you will overwrite data, so instead
592 divide the fs up into distance size chunks and write them
594 if (move_mode
&& dest_offset
> source_offset
) {
595 distance
= (dest_offset
- source_offset
) / fs
->blocksize
;
596 if (distance
< ext2fs_blocks_count(fs
->super
))
597 start
= ext2fs_blocks_count(fs
->super
) - distance
;
600 signal (SIGINT
, sigint_handler
);
603 seek_set(fd
, (start
* fs
->blocksize
) + dest_offset
);
604 for (blk
= start
; blk
< end
; blk
++) {
607 /* moving to the right */
608 if (distance
>= ext2fs_blocks_count(fs
->super
)||
609 start
== ext2fs_blocks_count(fs
->super
) -
611 kill(getpid(), SIGINT
);
613 /* moving to the left */
614 if (blk
< (source_offset
- dest_offset
) /
616 kill(getpid(), SIGINT
);
620 fprintf(stderr
, "%s",
621 _("Stopping now will destroy the filesystem, "
622 "interrupt again if you are sure\n"));
624 fprintf(stderr
, "%s", _("Copying "));
625 bscount
= print_progress(total_written
,
632 if (show_progress
&& last_update
!= time(NULL
)) {
634 last_update
= time(NULL
);
637 bscount
= print_progress(total_written
,
639 duration
= time(NULL
) - start_time
;
640 if (duration
> 5 && total_written
) {
641 time_t est
= (duration
* meta_blocks_count
/
642 total_written
) - duration
;
644 strftime(buff
, 30, "%T", gmtime(&est
));
647 _(" %s remaining at %.2f MB/s"),
648 buff
, calc_rate(total_written
,
654 if ((blk
>= fs
->super
->s_first_data_block
) &&
655 ext2fs_test_block_bitmap2(meta_block_map
, blk
)) {
656 retval
= io_channel_read_blk64(fs
->io
, blk
, 1, buf
);
658 com_err(program_name
, retval
,
659 _("error reading block %llu"), blk
);
662 if (scramble_block_map
&&
663 ext2fs_test_block_bitmap2(scramble_block_map
, blk
))
664 scramble_dir_block(fs
, blk
, buf
);
665 if ((flags
& E2IMAGE_CHECK_ZERO_FLAG
) &&
666 check_zero_block(buf
, fs
->blocksize
))
669 seek_relative(fd
, sparse
);
671 if (check_block(fd
, buf
, check_buf
, fs
->blocksize
)) {
672 seek_relative(fd
, fs
->blocksize
);
675 generic_write(fd
, buf
, fs
->blocksize
, blk
);
680 generic_write(fd
, zero_buf
,
684 sparse
+= fs
->blocksize
;
685 if (sparse
> 1024*1024) {
686 seek_relative(fd
, 1024*1024);
691 if (distance
&& start
) {
692 if (start
< distance
) {
698 if (end
< distance
) {
699 /* past overlap, do rest in one go */
707 signal (SIGINT
, SIG_DFL
);
709 time_t duration
= time(NULL
) - start_time
;
712 strftime(buff
, 30, "%T", gmtime(&duration
));
713 fprintf(stderr
, _("Copied %llu / %llu blocks (%d%%) in %s "),
714 total_written
, meta_blocks_count
,
715 calc_percent(total_written
, meta_blocks_count
), buff
);
717 fprintf(stderr
, _("at %.2f MB/s"),
718 calc_rate(total_written
, fs
->blocksize
, duration
));
719 fputs(" \n", stderr
);
721 #ifdef HAVE_FTRUNCATE64
725 offset
= seek_set(fd
,
726 fs
->blocksize
* ext2fs_blocks_count(fs
->super
) + dest_offset
);
728 offset
= seek_relative(fd
, sparse
);
730 if (ftruncate64(fd
, offset
) < 0) {
731 seek_relative(fd
, -1);
732 generic_write(fd
, zero_buf
, 1, NO_BLK
);
736 if (sparse
&& !distance
) {
737 seek_relative(fd
, sparse
-1);
738 generic_write(fd
, zero_buf
, 1, NO_BLK
);
741 ext2fs_free_mem(&zero_buf
);
742 ext2fs_free_mem(&buf
);
745 static void init_l1_table(struct ext2_qcow2_image
*image
)
750 ret
= ext2fs_get_arrayzero(image
->l1_size
, sizeof(__u64
), &l1_table
);
752 com_err(program_name
, ret
, "%s",
753 _("while allocating l1 table"));
757 image
->l1_table
= l1_table
;
760 static void init_l2_cache(struct ext2_qcow2_image
*image
)
762 unsigned int count
, i
;
763 struct ext2_qcow2_l2_cache
*cache
;
764 struct ext2_qcow2_l2_table
*table
;
767 ret
= ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache
),
772 count
= (image
->l1_size
> L2_CACHE_PREALLOC
) ? L2_CACHE_PREALLOC
:
775 cache
->count
= count
;
777 cache
->next_offset
= image
->l2_offset
;
779 for (i
= 0; i
< count
; i
++) {
780 ret
= ext2fs_get_arrayzero(1,
781 sizeof(struct ext2_qcow2_l2_table
), &table
);
785 ret
= ext2fs_get_arrayzero(image
->l2_size
,
786 sizeof(__u64
), &table
->data
);
790 table
->next
= cache
->free_head
;
791 cache
->free_head
= table
;
794 image
->l2_cache
= cache
;
798 com_err(program_name
, ret
, "%s", _("while allocating l2 cache"));
802 static void put_l2_cache(struct ext2_qcow2_image
*image
)
804 struct ext2_qcow2_l2_cache
*cache
= image
->l2_cache
;
805 struct ext2_qcow2_l2_table
*tmp
, *table
;
810 table
= cache
->free_head
;
811 cache
->free_head
= NULL
;
816 ext2fs_free_mem(&tmp
->data
);
817 ext2fs_free_mem(&tmp
);
820 if (cache
->free
!= cache
->count
) {
821 fprintf(stderr
, "%s", _("Warning: There are still tables in "
822 "the cache while putting the cache, "
823 "data will be lost so the image may "
825 table
= cache
->used_head
;
826 cache
->used_head
= NULL
;
830 ext2fs_free_mem(&cache
);
833 static int init_refcount(struct ext2_qcow2_image
*img
, blk64_t table_offset
)
835 struct ext2_qcow2_refcount
*ref
;
836 blk64_t table_clusters
;
839 ref
= &(img
->refcount
);
842 * One refcount block addresses 2048 clusters, one refcount table
843 * addresses cluster/sizeof(__u64) refcount blocks, and we need
844 * to address meta_blocks_count clusters + qcow2 metadata clusters
847 table_clusters
= meta_blocks_count
+ (table_offset
>>
849 table_clusters
>>= (img
->cluster_bits
+ 6 - 1);
850 table_clusters
= (table_clusters
== 0) ? 1 : table_clusters
;
852 ref
->refcount_table_offset
= table_offset
;
853 ref
->refcount_table_clusters
= table_clusters
;
854 ref
->refcount_table_index
= 0;
855 ref
->refcount_block_index
= 0;
857 /* Allocate refcount table */
858 ret
= ext2fs_get_arrayzero(ref
->refcount_table_clusters
,
859 img
->cluster_size
, &ref
->refcount_table
);
863 /* Allocate refcount block */
864 ret
= ext2fs_get_arrayzero(1, img
->cluster_size
, &ref
->refcount_block
);
866 ext2fs_free_mem(&ref
->refcount_table
);
871 static int initialize_qcow2_image(int fd
, ext2_filsys fs
,
872 struct ext2_qcow2_image
*image
)
874 struct ext2_qcow2_hdr
*header
;
875 blk64_t total_size
, offset
;
876 int shift
, l2_bits
, header_size
, l1_size
, ret
;
877 int cluster_bits
= get_bits_from_size(fs
->blocksize
);
878 struct ext2_super_block
*sb
= fs
->super
;
880 /* Allocate header */
881 ret
= ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr
), &header
);
885 total_size
= ext2fs_blocks_count(sb
) << cluster_bits
;
886 image
->cluster_size
= fs
->blocksize
;
887 image
->l2_size
= 1 << (cluster_bits
- 3);
888 image
->cluster_bits
= cluster_bits
;
891 header
->magic
= ext2fs_cpu_to_be32(QCOW_MAGIC
);
892 header
->version
= ext2fs_cpu_to_be32(QCOW_VERSION
);
893 header
->size
= ext2fs_cpu_to_be64(total_size
);
894 header
->cluster_bits
= ext2fs_cpu_to_be32(cluster_bits
);
896 header_size
= (sizeof(struct ext2_qcow2_hdr
) + 7) & ~7;
897 offset
= align_offset(header_size
, image
->cluster_size
);
899 header
->l1_table_offset
= ext2fs_cpu_to_be64(offset
);
900 image
->l1_offset
= offset
;
902 l2_bits
= cluster_bits
- 3;
903 shift
= cluster_bits
+ l2_bits
;
904 l1_size
= ((total_size
+ (1LL << shift
) - 1) >> shift
);
905 header
->l1_size
= ext2fs_cpu_to_be32(l1_size
);
906 image
->l1_size
= l1_size
;
908 /* Make space for L1 table */
909 offset
+= align_offset(l1_size
* sizeof(blk64_t
), image
->cluster_size
);
911 /* Initialize refcounting */
912 ret
= init_refcount(image
, offset
);
914 ext2fs_free_mem(&header
);
917 header
->refcount_table_offset
= ext2fs_cpu_to_be64(offset
);
918 header
->refcount_table_clusters
=
919 ext2fs_cpu_to_be32(image
->refcount
.refcount_table_clusters
);
920 offset
+= image
->cluster_size
;
921 offset
+= image
->refcount
.refcount_table_clusters
<<
924 /* Make space for L2 tables */
925 image
->l2_offset
= offset
;
926 offset
+= image
->cluster_size
;
928 /* Make space for first refcount block */
929 image
->refcount
.refcount_block_offset
= offset
;
932 /* Initialize l1 and l2 tables */
933 init_l1_table(image
);
934 init_l2_cache(image
);
939 static void free_qcow2_image(struct ext2_qcow2_image
*img
)
945 ext2fs_free_mem(&img
->hdr
);
948 ext2fs_free_mem(&img
->l1_table
);
950 if (img
->refcount
.refcount_table
)
951 ext2fs_free_mem(&img
->refcount
.refcount_table
);
952 if (img
->refcount
.refcount_block
)
953 ext2fs_free_mem(&img
->refcount
.refcount_block
);
957 ext2fs_free_mem(&img
);
961 * Put table from used list (used_head) into free list (free_head).
962 * l2_table is used to return pointer to the next used table (used_head).
964 static void put_used_table(struct ext2_qcow2_image
*img
,
965 struct ext2_qcow2_l2_table
**l2_table
)
967 struct ext2_qcow2_l2_cache
*cache
= img
->l2_cache
;
968 struct ext2_qcow2_l2_table
*table
;
970 table
= cache
->used_head
;
971 cache
->used_head
= table
->next
;
975 cache
->used_tail
= NULL
;
977 /* Clean the table for case we will need to use it again */
978 memset(table
->data
, 0, img
->cluster_size
);
979 table
->next
= cache
->free_head
;
980 cache
->free_head
= table
;
984 *l2_table
= cache
->used_head
;
987 static void flush_l2_cache(struct ext2_qcow2_image
*image
)
991 struct ext2_qcow2_l2_cache
*cache
= image
->l2_cache
;
992 struct ext2_qcow2_l2_table
*table
= cache
->used_head
;
995 /* Store current position */
996 offset
= seek_relative(fd
, 0);
999 while (cache
->free
< cache
->count
) {
1000 if (seek
!= table
->offset
) {
1001 seek_set(fd
, table
->offset
);
1002 seek
= table
->offset
;
1005 generic_write(fd
, (char *)table
->data
, image
->cluster_size
,
1007 put_used_table(image
, &table
);
1008 seek
+= image
->cluster_size
;
1011 /* Restore previous position */
1012 seek_set(fd
, offset
);
1016 * Get first free table (from free_head) and put it into tail of used list
1018 * l2_table is used to return pointer to moved table.
1019 * Returns 1 if the cache is full, 0 otherwise.
1021 static void get_free_table(struct ext2_qcow2_image
*image
,
1022 struct ext2_qcow2_l2_table
**l2_table
)
1024 struct ext2_qcow2_l2_table
*table
;
1025 struct ext2_qcow2_l2_cache
*cache
= image
->l2_cache
;
1027 if (0 == cache
->free
)
1028 flush_l2_cache(image
);
1030 table
= cache
->free_head
;
1032 cache
->free_head
= table
->next
;
1034 if (cache
->used_tail
)
1035 cache
->used_tail
->next
= table
;
1037 /* First item in the used list */
1038 cache
->used_head
= table
;
1040 cache
->used_tail
= table
;
1046 static int add_l2_item(struct ext2_qcow2_image
*img
, blk64_t blk
,
1047 blk64_t data
, blk64_t next
)
1049 struct ext2_qcow2_l2_cache
*cache
= img
->l2_cache
;
1050 struct ext2_qcow2_l2_table
*table
= cache
->used_tail
;
1051 blk64_t l1_index
= blk
/ img
->l2_size
;
1052 blk64_t l2_index
= blk
& (img
->l2_size
- 1);
1056 * Need to create new table if it does not exist,
1059 if (!table
|| (table
->l1_index
!= l1_index
)) {
1060 get_free_table(img
, &table
);
1061 table
->l1_index
= l1_index
;
1062 table
->offset
= cache
->next_offset
;
1063 cache
->next_offset
= next
;
1064 img
->l1_table
[l1_index
] =
1065 ext2fs_cpu_to_be64(table
->offset
| QCOW_OFLAG_COPIED
);
1069 table
->data
[l2_index
] = ext2fs_cpu_to_be64(data
| QCOW_OFLAG_COPIED
);
1073 static int update_refcount(int fd
, struct ext2_qcow2_image
*img
,
1074 blk64_t offset
, blk64_t rfblk_pos
)
1076 struct ext2_qcow2_refcount
*ref
;
1080 ref
= &(img
->refcount
);
1081 table_index
= offset
>> (2 * img
->cluster_bits
- 1);
1084 * Need to create new refcount block when the offset addresses
1085 * another item in the refcount table
1087 if (table_index
!= ref
->refcount_table_index
) {
1089 seek_set(fd
, ref
->refcount_block_offset
);
1091 generic_write(fd
, (char *)ref
->refcount_block
,
1092 img
->cluster_size
, NO_BLK
);
1093 memset(ref
->refcount_block
, 0, img
->cluster_size
);
1095 ref
->refcount_table
[ref
->refcount_table_index
] =
1096 ext2fs_cpu_to_be64(ref
->refcount_block_offset
);
1097 ref
->refcount_block_offset
= rfblk_pos
;
1098 ref
->refcount_block_index
= 0;
1099 ref
->refcount_table_index
= table_index
;
1104 * We are relying on the fact that we are creating the qcow2
1105 * image sequentially, hence we will always allocate refcount
1106 * block items sequentialy.
1108 ref
->refcount_block
[ref
->refcount_block_index
] = ext2fs_cpu_to_be16(1);
1109 ref
->refcount_block_index
++;
1113 static int sync_refcount(int fd
, struct ext2_qcow2_image
*img
)
1115 struct ext2_qcow2_refcount
*ref
;
1117 ref
= &(img
->refcount
);
1119 ref
->refcount_table
[ref
->refcount_table_index
] =
1120 ext2fs_cpu_to_be64(ref
->refcount_block_offset
);
1121 seek_set(fd
, ref
->refcount_table_offset
);
1122 generic_write(fd
, (char *)ref
->refcount_table
,
1123 ref
->refcount_table_clusters
<< img
->cluster_bits
, NO_BLK
);
1125 seek_set(fd
, ref
->refcount_block_offset
);
1126 generic_write(fd
, (char *)ref
->refcount_block
, img
->cluster_size
,
1131 static void output_qcow2_meta_data_blocks(ext2_filsys fs
, int fd
)
1134 blk64_t blk
, offset
, size
, end
;
1136 struct ext2_qcow2_image
*img
;
1137 unsigned int header_size
;
1139 /* allocate struct ext2_qcow2_image */
1140 retval
= ext2fs_get_mem(sizeof(struct ext2_qcow2_image
), &img
);
1142 com_err(program_name
, retval
, "%s",
1143 _("while allocating ext2_qcow2_image"));
1147 retval
= initialize_qcow2_image(fd
, fs
, img
);
1149 com_err(program_name
, retval
, "%s",
1150 _("while initializing ext2_qcow2_image"));
1153 header_size
= align_offset(sizeof(struct ext2_qcow2_hdr
),
1155 write_header(fd
, img
->hdr
, sizeof(struct ext2_qcow2_hdr
), header_size
);
1157 /* Refcount all qcow2 related metadata up to refcount_block_offset */
1158 end
= img
->refcount
.refcount_block_offset
;
1160 blk
= end
+ img
->cluster_size
;
1161 for (offset
= 0; offset
<= end
; offset
+= img
->cluster_size
) {
1162 if (update_refcount(fd
, img
, offset
, blk
)) {
1163 blk
+= img
->cluster_size
;
1165 * If we create new refcount block, we need to refcount
1168 end
+= img
->cluster_size
;
1171 seek_set(fd
, offset
);
1173 retval
= ext2fs_get_mem(fs
->blocksize
, &buf
);
1175 com_err(program_name
, retval
, "%s",
1176 _("while allocating buffer"));
1179 /* Write qcow2 data blocks */
1180 for (blk
= 0; blk
< ext2fs_blocks_count(fs
->super
); blk
++) {
1181 if ((blk
>= fs
->super
->s_first_data_block
) &&
1182 ext2fs_test_block_bitmap2(meta_block_map
, blk
)) {
1183 retval
= io_channel_read_blk64(fs
->io
, blk
, 1, buf
);
1185 com_err(program_name
, retval
,
1186 _("error reading block %llu"), blk
);
1189 if (scramble_block_map
&&
1190 ext2fs_test_block_bitmap2(scramble_block_map
, blk
))
1191 scramble_dir_block(fs
, blk
, buf
);
1192 if (check_zero_block(buf
, fs
->blocksize
))
1195 if (update_refcount(fd
, img
, offset
, offset
)) {
1196 /* Make space for another refcount block */
1197 offset
+= img
->cluster_size
;
1198 seek_set(fd
, offset
);
1200 * We have created the new refcount block, this
1201 * means that we need to refcount it as well.
1202 * So the previous update_refcount refcounted
1203 * the block itself and now we are going to
1204 * create refcount for data. New refcount
1205 * block should not be created!
1207 if (update_refcount(fd
, img
, offset
, offset
)) {
1208 fprintf(stderr
, "%s",
1209 _("Programming error: multiple "
1210 "sequential refcount blocks "
1216 generic_write(fd
, buf
, fs
->blocksize
, blk
);
1218 if (add_l2_item(img
, blk
, offset
,
1219 offset
+ img
->cluster_size
)) {
1220 offset
+= img
->cluster_size
;
1221 if (update_refcount(fd
, img
, offset
,
1222 offset
+ img
->cluster_size
)) {
1223 offset
+= img
->cluster_size
;
1224 if (update_refcount(fd
, img
, offset
,
1226 fprintf(stderr
, "%s",
1227 _("Programming error: multiple sequential refcount "
1228 "blocks created!\n"));
1232 offset
+= img
->cluster_size
;
1233 seek_set(fd
, offset
);
1237 offset
+= img
->cluster_size
;
1240 update_refcount(fd
, img
, offset
, offset
);
1241 flush_l2_cache(img
);
1242 sync_refcount(fd
, img
);
1245 seek_set(fd
, img
->l1_offset
);
1246 size
= img
->l1_size
* sizeof(__u64
);
1247 generic_write(fd
, (char *)img
->l1_table
, size
, NO_BLK
);
1249 ext2fs_free_mem(&buf
);
1250 free_qcow2_image(img
);
1253 static void write_raw_image_file(ext2_filsys fs
, int fd
, int type
, int flags
)
1255 struct process_block_struct pb
;
1256 struct ext2_inode inode
;
1257 ext2_inode_scan scan
;
1262 meta_blocks_count
= 0;
1263 retval
= ext2fs_allocate_block_bitmap(fs
, _("in-use block map"),
1266 com_err(program_name
, retval
, "%s",
1267 _("while allocating block bitmap"));
1271 if (flags
& E2IMAGE_SCRAMBLE_FLAG
) {
1272 retval
= ext2fs_allocate_block_bitmap(fs
, "scramble block map",
1273 &scramble_block_map
);
1275 com_err(program_name
, retval
, "%s",
1276 _("while allocating scramble block bitmap"));
1281 mark_table_blocks(fs
);
1283 printf("%s", _("Scanning inodes...\n"));
1285 retval
= ext2fs_open_inode_scan(fs
, 0, &scan
);
1287 com_err(program_name
, retval
, "%s",
1288 _("while opening inode scan"));
1292 retval
= ext2fs_get_mem(fs
->blocksize
* 3, &block_buf
);
1294 com_err(program_name
, 0, "%s",
1295 _("Can't allocate block buffer"));
1299 use_inode_shortcuts(fs
, 1);
1300 stashed_inode
= &inode
;
1302 retval
= ext2fs_get_next_inode(scan
, &ino
, &inode
);
1303 if (retval
== EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
)
1306 com_err(program_name
, retval
, "%s",
1307 _("while getting next inode"));
1312 if (!inode
.i_links_count
)
1314 if (ext2fs_file_acl_block(fs
, &inode
)) {
1315 ext2fs_mark_block_bitmap2(meta_block_map
,
1316 ext2fs_file_acl_block(fs
, &inode
));
1317 meta_blocks_count
++;
1319 if (!ext2fs_inode_has_valid_blocks2(fs
, &inode
))
1324 pb
.is_dir
= LINUX_S_ISDIR(inode
.i_mode
);
1325 if (LINUX_S_ISDIR(inode
.i_mode
) ||
1326 (LINUX_S_ISLNK(inode
.i_mode
) &&
1327 ext2fs_inode_has_valid_blocks2(fs
, &inode
)) ||
1328 ino
== fs
->super
->s_journal_inum
) {
1329 retval
= ext2fs_block_iterate3(fs
, ino
,
1330 BLOCK_FLAG_READ_ONLY
, block_buf
,
1331 process_dir_block
, &pb
);
1333 com_err(program_name
, retval
,
1334 _("while iterating over inode %u"),
1339 if ((inode
.i_flags
& EXT4_EXTENTS_FL
) ||
1340 inode
.i_block
[EXT2_IND_BLOCK
] ||
1341 inode
.i_block
[EXT2_DIND_BLOCK
] ||
1342 inode
.i_block
[EXT2_TIND_BLOCK
] || all_data
) {
1343 retval
= ext2fs_block_iterate3(fs
,
1344 ino
, BLOCK_FLAG_READ_ONLY
, block_buf
,
1345 process_file_block
, &pb
);
1347 com_err(program_name
, retval
,
1348 _("while iterating over inode %u"), ino
);
1354 use_inode_shortcuts(fs
, 0);
1356 if (type
& E2IMAGE_QCOW2
)
1357 output_qcow2_meta_data_blocks(fs
, fd
);
1359 output_meta_data_blocks(fs
, fd
, flags
);
1361 ext2fs_free_mem(&block_buf
);
1362 ext2fs_close_inode_scan(scan
);
1363 ext2fs_free_block_bitmap(meta_block_map
);
1364 if (type
& E2IMAGE_SCRAMBLE_FLAG
)
1365 ext2fs_free_block_bitmap(scramble_block_map
);
1368 static void install_image(char *device
, char *image_fn
, int type
)
1372 int open_flag
= EXT2_FLAG_IMAGE_FILE
| EXT2_FLAG_64BITS
;
1378 com_err(program_name
, 0, "%s",
1379 _("Raw and qcow2 images cannot be installed"));
1383 #ifdef CONFIG_TESTIO_DEBUG
1384 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1385 io_ptr
= test_io_manager
;
1386 test_io_backing_manager
= unix_io_manager
;
1389 io_ptr
= unix_io_manager
;
1391 retval
= ext2fs_open (image_fn
, open_flag
, 0, 0,
1394 com_err(program_name
, retval
, _("while trying to open %s"),
1399 retval
= ext2fs_read_bitmaps (fs
);
1401 com_err(program_name
, retval
, "%s", _("error reading bitmaps"));
1405 fd
= ext2fs_open_file(image_fn
, O_RDONLY
, 0);
1411 retval
= io_ptr
->open(device
, IO_FLAG_RW
, &io
);
1413 com_err(device
, 0, "%s", _("while opening device file"));
1417 ext2fs_rewrite_to_io(fs
, io
);
1419 seek_set(fd
, fs
->image_header
->offset_inode
);
1421 retval
= ext2fs_image_inode_read(fs
, fd
, 0);
1423 com_err(image_fn
, 0, "%s",
1424 _("while restoring the image table"));
1432 static struct ext2_qcow2_hdr
*check_qcow2_image(int *fd
, char *name
)
1435 *fd
= ext2fs_open_file(name
, O_RDONLY
, 0600);
1439 return qcow2_read_header(*fd
);
1442 int main (int argc
, char ** argv
)
1447 char *image_fn
, offset_opt
[64];
1448 struct ext2_qcow2_hdr
*header
= NULL
;
1449 int open_flag
= EXT2_FLAG_64BITS
;
1452 int mount_flags
= 0;
1456 int ignore_rw_mount
= 0;
1461 setlocale(LC_MESSAGES
, "");
1462 setlocale(LC_CTYPE
, "");
1463 bindtextdomain(NLS_CAT_NAME
, LOCALEDIR
);
1464 textdomain(NLS_CAT_NAME
);
1465 set_com_err_gettext(gettext
);
1467 fprintf (stderr
, "e2image %s (%s)\n", E2FSPROGS_VERSION
,
1470 program_name
= *argv
;
1471 add_error_table(&et_ext2_error_table
);
1472 while ((c
= getopt(argc
, argv
, "nrsIQafo:O:pc")) != EOF
)
1475 flags
|= E2IMAGE_INSTALL_FLAG
;
1480 img_type
|= E2IMAGE_QCOW2
;
1485 img_type
|= E2IMAGE_RAW
;
1488 flags
|= E2IMAGE_SCRAMBLE_FLAG
;
1494 ignore_rw_mount
= 1;
1500 source_offset
= strtoull(optarg
, NULL
, 0);
1503 dest_offset
= strtoull(optarg
, NULL
, 0);
1514 if (optind
== argc
- 1 &&
1515 (source_offset
|| dest_offset
))
1517 else if (optind
!= argc
- 2 )
1520 if (all_data
&& !img_type
) {
1521 com_err(program_name
, 0, "%s", _("-a option can only be used "
1522 "with raw or QCOW2 images."));
1525 if ((source_offset
|| dest_offset
) && img_type
!= E2IMAGE_RAW
) {
1526 com_err(program_name
, 0, "%s",
1527 _("Offsets are only allowed with raw images."));
1530 if (move_mode
&& img_type
!= E2IMAGE_RAW
) {
1531 com_err(program_name
, 0, "%s",
1532 _("Move mode is only allowed with raw images."));
1535 if (move_mode
&& !all_data
) {
1536 com_err(program_name
, 0, "%s",
1537 _("Move mode requires all data mode."));
1540 device_name
= argv
[optind
];
1542 image_fn
= device_name
;
1543 else image_fn
= argv
[optind
+1];
1545 retval
= ext2fs_check_if_mounted(device_name
, &mount_flags
);
1547 com_err(program_name
, retval
, "%s", _("checking if mounted"));
1551 if (img_type
&& !ignore_rw_mount
&&
1552 (mount_flags
& EXT2_MF_MOUNTED
) &&
1553 !(mount_flags
& EXT2_MF_READONLY
)) {
1554 fprintf(stderr
, "%s", _("\nRunning e2image on a R/W mounted "
1555 "filesystem can result in an\n"
1556 "inconsistent image which will not be useful "
1557 "for debugging purposes.\n"
1558 "Use -f option if you really want to do that.\n"));
1562 if (flags
& E2IMAGE_INSTALL_FLAG
) {
1563 install_image(device_name
, image_fn
, img_type
);
1567 if (img_type
& E2IMAGE_RAW
) {
1568 header
= check_qcow2_image(&qcow2_fd
, device_name
);
1570 flags
|= E2IMAGE_IS_QCOW2_FLAG
;
1574 sprintf(offset_opt
, "offset=%llu", source_offset
);
1575 retval
= ext2fs_open2(device_name
, offset_opt
, open_flag
, 0, 0,
1576 unix_io_manager
, &fs
);
1578 com_err (program_name
, retval
, _("while trying to open %s"),
1580 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout
);
1585 if (strcmp(image_fn
, "-") == 0)
1588 int o_flags
= O_CREAT
|O_RDWR
;
1590 if (img_type
!= E2IMAGE_RAW
)
1592 if (access(image_fn
, F_OK
) != 0)
1593 flags
|= E2IMAGE_CHECK_ZERO_FLAG
;
1594 fd
= ext2fs_open_file(image_fn
, o_flags
, 0600);
1596 com_err(program_name
, errno
,
1597 _("while trying to open %s"), image_fn
);
1602 seek_set(fd
, dest_offset
);
1604 if ((img_type
& E2IMAGE_QCOW2
) && (fd
== 1)) {
1605 com_err(program_name
, 0, "%s",
1606 _("QCOW2 image can not be written to the stdout!\n"));
1610 if (fstat(fd
, &st
)) {
1611 com_err(program_name
, 0, "%s",
1612 _("Can not stat output\n"));
1615 if (S_ISBLK(st
.st_mode
))
1618 if (flags
& E2IMAGE_IS_QCOW2_FLAG
) {
1619 ret
= qcow2_write_raw_image(qcow2_fd
, fd
, header
);
1621 if (ret
== -QCOW_COMPRESSED
)
1622 fprintf(stderr
, _("Image (%s) is compressed\n"),
1624 if (ret
== -QCOW_ENCRYPTED
)
1625 fprintf(stderr
, _("Image (%s) is encrypted\n"),
1627 com_err(program_name
, ret
,
1628 _("while trying to convert qcow2 image"
1629 " (%s) into raw image (%s)"),
1630 device_name
, image_fn
);
1636 if (img_type
!= E2IMAGE_RAW
) {
1637 fprintf(stderr
, "%s", _("The -c option only supported "
1642 fprintf(stderr
, "%s", _("The -c option not supported "
1643 "when writing to stdout\n"));
1646 retval
= ext2fs_get_mem(fs
->blocksize
, &check_buf
);
1648 com_err(program_name
, retval
, "%s",
1649 _("while allocating check_buf"));
1653 if (show_progress
&& (img_type
!= E2IMAGE_RAW
)) {
1654 fprintf(stderr
, "%s",
1655 _("The -p option only supported in raw mode\n"));
1659 write_raw_image_file(fs
, fd
, img_type
, flags
);
1661 write_image_file(fs
, fd
);
1665 printf(_("%d blocks already contained the data to be copied\n"),
1673 remove_error_table(&et_ext2_error_table
);