2 * e2image.c --- Program which writes an image file backing up
3 * critical metadata for the filesystem.
5 * Copyright 2000, 2001 by Theodore Ts'o.
8 * This file may be redistributed under the terms of the GNU Public
13 #ifndef _LARGEFILE_SOURCE
14 #define _LARGEFILE_SOURCE
16 #ifndef _LARGEFILE64_SOURCE
17 #define _LARGEFILE64_SOURCE
40 #include <sys/types.h>
44 #include "ext2fs/ext2_fs.h"
45 #include "ext2fs/ext2fs.h"
46 #include "ext2fs/ext2fsP.h"
47 #include "et/com_err.h"
48 #include "uuid/uuid.h"
50 #include "ext2fs/e2image.h"
51 #include "ext2fs/qcow2.h"
53 #include "support/nls-enable.h"
54 #include "support/plausible.h"
55 #include "../version.h"
57 #define QCOW_OFLAG_COPIED (1LL << 63)
58 #define NO_BLK ((blk64_t) -1)
62 #define E2IMAGE_QCOW2 2
65 #define E2IMAGE_INSTALL_FLAG 1
66 #define E2IMAGE_SCRAMBLE_FLAG 2
67 #define E2IMAGE_IS_QCOW2_FLAG 4
68 #define E2IMAGE_CHECK_ZERO_FLAG 8
70 static const char * program_name
= "e2image";
71 static char * device_name
= NULL
;
73 static char output_is_blk
;
75 /* writing to blk device: don't skip zeroed blocks */
76 static blk64_t source_offset
, dest_offset
;
77 static char move_mode
;
78 static char show_progress
;
79 static char *check_buf
;
80 static int skipped_blocks
;
82 static blk64_t
align_offset(blk64_t offset
, unsigned int n
)
84 return (offset
+ n
- 1) & ~((blk64_t
) n
- 1);
87 static int get_bits_from_size(size_t size
)
95 /* Not a power of two */
105 static void usage(void)
107 fprintf(stderr
, _("Usage: %s [ -r|Q ] [ -f ] device image-file\n"),
109 fprintf(stderr
, _(" %s -I device image-file\n"), program_name
);
110 fprintf(stderr
, _(" %s -ra [ -cfnp ] [ -o src_offset ] "
111 "[ -O dest_offset ] src_fs [ dest_fs ]\n"),
116 static ext2_loff_t
seek_relative(int fd
, int offset
)
118 ext2_loff_t ret
= ext2fs_llseek(fd
, offset
, SEEK_CUR
);
120 perror("seek_relative");
126 static ext2_loff_t
seek_set(int fd
, ext2_loff_t offset
)
128 ext2_loff_t ret
= ext2fs_llseek(fd
, offset
, SEEK_SET
);
137 * Returns true if the block we are about to write is identical to
138 * what is already on the disk.
140 static int check_block(int fd
, void *buf
, void *cbuf
, int blocksize
)
143 int count
= blocksize
, ret
;
149 ret
= read(fd
, cp
, count
);
151 perror("check_block");
157 ret
= memcmp(buf
, cbuf
, blocksize
);
158 seek_relative(fd
, -blocksize
);
159 return (ret
== 0) ? 1 : 0;
162 static void generic_write(int fd
, void *buf
, int blocksize
, blk64_t block
)
164 int count
, free_buf
= 0;
172 err
= ext2fs_get_arrayzero(1, blocksize
, &buf
);
174 com_err(program_name
, err
, "%s",
175 _("while allocating buffer"));
180 printf(_("Writing block %llu\n"), (unsigned long long) block
);
182 seek_relative(fd
, blocksize
);
183 goto free_and_return
;
185 count
= write(fd
, buf
, blocksize
);
186 if (count
!= blocksize
) {
193 com_err(program_name
, err
,
194 _("error writing block %llu"), block
);
196 com_err(program_name
, err
, "%s",
197 _("error in generic_write()"));
203 ext2fs_free_mem(&buf
);
206 static void write_header(int fd
, void *hdr
, int hdr_size
, int wrt_size
)
212 if (hdr_size
> wrt_size
) {
213 fprintf(stderr
, "%s",
214 _("Error: header size is bigger than wrt_size\n"));
217 ret
= ext2fs_get_mem(wrt_size
, &header_buf
);
219 fputs(_("Couldn't allocate header buffer\n"), stderr
);
224 memset(header_buf
, 0, wrt_size
);
227 memcpy(header_buf
, hdr
, hdr_size
);
229 generic_write(fd
, header_buf
, wrt_size
, NO_BLK
);
231 ext2fs_free_mem(&header_buf
);
234 static void write_image_file(ext2_filsys fs
, int fd
)
236 struct ext2_image_hdr hdr
;
240 write_header(fd
, NULL
, sizeof(struct ext2_image_hdr
), fs
->blocksize
);
241 memset(&hdr
, 0, sizeof(struct ext2_image_hdr
));
243 hdr
.offset_super
= ext2fs_cpu_to_le32(seek_relative(fd
, 0));
244 retval
= ext2fs_image_super_write(fs
, fd
, 0);
246 com_err(program_name
, retval
, "%s",
247 _("while writing superblock"));
251 hdr
.offset_inode
= ext2fs_cpu_to_le32(seek_relative(fd
, 0));
252 retval
= ext2fs_image_inode_write(fs
, fd
,
253 (fd
!= 1) ? IMAGER_FLAG_SPARSEWRITE
: 0);
255 com_err(program_name
, retval
, "%s",
256 _("while writing inode table"));
260 hdr
.offset_blockmap
= ext2fs_cpu_to_le32(seek_relative(fd
, 0));
261 retval
= ext2fs_image_bitmap_write(fs
, fd
, 0);
263 com_err(program_name
, retval
, "%s",
264 _("while writing block bitmap"));
268 hdr
.offset_inodemap
= ext2fs_cpu_to_le32(seek_relative(fd
, 0));
269 retval
= ext2fs_image_bitmap_write(fs
, fd
, IMAGER_FLAG_INODEMAP
);
271 com_err(program_name
, retval
, "%s",
272 _("while writing inode bitmap"));
276 hdr
.magic_number
= ext2fs_cpu_to_le32(EXT2_ET_MAGIC_E2IMAGE
);
277 strcpy(hdr
.magic_descriptor
, "Ext2 Image 1.0");
278 gethostname(hdr
.fs_hostname
, sizeof(hdr
.fs_hostname
));
279 strncpy(hdr
.fs_device_name
, device_name
, sizeof(hdr
.fs_device_name
)-1);
280 hdr
.fs_device_name
[sizeof(hdr
.fs_device_name
) - 1] = 0;
281 hdr
.fs_blocksize
= ext2fs_cpu_to_le32(fs
->blocksize
);
283 if (stat(device_name
, &st
) == 0)
284 hdr
.fs_device
= ext2fs_cpu_to_le32(st
.st_rdev
);
286 if (fstat(fd
, &st
) == 0) {
287 hdr
.image_device
= ext2fs_cpu_to_le32(st
.st_dev
);
288 hdr
.image_inode
= ext2fs_cpu_to_le32(st
.st_ino
);
290 memcpy(hdr
.fs_uuid
, fs
->super
->s_uuid
, sizeof(hdr
.fs_uuid
));
292 hdr
.image_time
= ext2fs_cpu_to_le32(time(0));
293 write_header(fd
, &hdr
, sizeof(struct ext2_image_hdr
), fs
->blocksize
);
297 * These set of functions are used to write a RAW image file.
299 static ext2fs_block_bitmap meta_block_map
;
300 static ext2fs_block_bitmap scramble_block_map
; /* Directory blocks to be scrambled */
301 static blk64_t meta_blocks_count
;
303 struct process_block_struct
{
309 * These subroutines short circuits ext2fs_get_blocks and
310 * ext2fs_check_directory; we use them since we already have the inode
311 * structure, so there's no point in letting the ext2fs library read
314 static ino_t stashed_ino
= 0;
315 static struct ext2_inode
*stashed_inode
;
317 static errcode_t
meta_get_blocks(ext2_filsys fs
EXT2FS_ATTR((unused
)),
323 if ((ino
!= stashed_ino
) || !stashed_inode
)
324 return EXT2_ET_CALLBACK_NOTHANDLED
;
326 for (i
=0; i
< EXT2_N_BLOCKS
; i
++)
327 blocks
[i
] = stashed_inode
->i_block
[i
];
331 static errcode_t
meta_check_directory(ext2_filsys fs
EXT2FS_ATTR((unused
)),
334 if ((ino
!= stashed_ino
) || !stashed_inode
)
335 return EXT2_ET_CALLBACK_NOTHANDLED
;
337 if (!LINUX_S_ISDIR(stashed_inode
->i_mode
))
338 return EXT2_ET_NO_DIRECTORY
;
342 static errcode_t
meta_read_inode(ext2_filsys fs
EXT2FS_ATTR((unused
)),
344 struct ext2_inode
*inode
)
346 if ((ino
!= stashed_ino
) || !stashed_inode
)
347 return EXT2_ET_CALLBACK_NOTHANDLED
;
348 *inode
= *stashed_inode
;
352 static void use_inode_shortcuts(ext2_filsys fs
, int use_shortcuts
)
355 fs
->get_blocks
= meta_get_blocks
;
356 fs
->check_directory
= meta_check_directory
;
357 fs
->read_inode
= meta_read_inode
;
361 fs
->check_directory
= 0;
366 static int process_dir_block(ext2_filsys fs
EXT2FS_ATTR((unused
)),
368 e2_blkcnt_t blockcnt
EXT2FS_ATTR((unused
)),
369 blk64_t ref_block
EXT2FS_ATTR((unused
)),
370 int ref_offset
EXT2FS_ATTR((unused
)),
371 void *priv_data
EXT2FS_ATTR((unused
)))
373 struct process_block_struct
*p
;
375 p
= (struct process_block_struct
*) priv_data
;
377 ext2fs_mark_block_bitmap2(meta_block_map
, *block_nr
);
379 if (scramble_block_map
&& p
->is_dir
&& blockcnt
>= 0)
380 ext2fs_mark_block_bitmap2(scramble_block_map
, *block_nr
);
384 static int process_file_block(ext2_filsys fs
EXT2FS_ATTR((unused
)),
386 e2_blkcnt_t blockcnt
,
387 blk64_t ref_block
EXT2FS_ATTR((unused
)),
388 int ref_offset
EXT2FS_ATTR((unused
)),
389 void *priv_data
EXT2FS_ATTR((unused
)))
391 if (blockcnt
< 0 || all_data
) {
392 ext2fs_mark_block_bitmap2(meta_block_map
, *block_nr
);
398 static void mark_table_blocks(ext2_filsys fs
)
400 blk64_t first_block
, b
;
403 first_block
= fs
->super
->s_first_data_block
;
405 * Mark primary superblock
407 ext2fs_mark_block_bitmap2(meta_block_map
, first_block
);
411 * Mark the primary superblock descriptors
413 for (j
= 0; j
< fs
->desc_blocks
; j
++) {
414 ext2fs_mark_block_bitmap2(meta_block_map
,
415 ext2fs_descriptor_block_loc2(fs
, first_block
, j
));
417 meta_blocks_count
+= fs
->desc_blocks
;
422 if (fs
->super
->s_feature_incompat
& EXT4_FEATURE_INCOMPAT_MMP
) {
423 ext2fs_mark_block_bitmap2(meta_block_map
, fs
->super
->s_mmp_block
);
427 for (i
= 0; i
< fs
->group_desc_count
; i
++) {
429 * Mark the blocks used for the inode table
431 if ((output_is_blk
||
432 !ext2fs_bg_flags_test(fs
, i
, EXT2_BG_INODE_UNINIT
)) &&
433 ext2fs_inode_table_loc(fs
, i
)) {
434 unsigned int end
= (unsigned) fs
->inode_blocks_per_group
;
435 /* skip unused blocks */
436 if (!output_is_blk
&& ext2fs_has_group_desc_csum(fs
))
437 end
-= (ext2fs_bg_itable_unused(fs
, i
) /
438 EXT2_INODES_PER_BLOCK(fs
->super
));
439 for (j
= 0, b
= ext2fs_inode_table_loc(fs
, i
);
442 ext2fs_mark_block_bitmap2(meta_block_map
, b
);
448 * Mark block used for the block bitmap
450 if (!ext2fs_bg_flags_test(fs
, i
, EXT2_BG_BLOCK_UNINIT
) &&
451 ext2fs_block_bitmap_loc(fs
, i
)) {
452 ext2fs_mark_block_bitmap2(meta_block_map
,
453 ext2fs_block_bitmap_loc(fs
, i
));
458 * Mark block used for the inode bitmap
460 if (!ext2fs_bg_flags_test(fs
, i
, EXT2_BG_INODE_UNINIT
) &&
461 ext2fs_inode_bitmap_loc(fs
, i
)) {
462 ext2fs_mark_block_bitmap2(meta_block_map
,
463 ext2fs_inode_bitmap_loc(fs
, i
));
470 * This function returns 1 if the specified block is all zeros
472 static int check_zero_block(char *buf
, int blocksize
)
475 int left
= blocksize
;
487 static int name_id
[256];
489 #define EXT4_MAX_REC_LEN ((1<<16)-1)
491 static void scramble_dir_block(ext2_filsys fs
, blk64_t blk
, char *buf
)
494 struct ext2_dir_entry_2
*dirent
;
495 unsigned int rec_len
;
498 end
= buf
+ fs
->blocksize
;
499 for (p
= buf
; p
< end
-8; p
+= rec_len
) {
500 dirent
= (struct ext2_dir_entry_2
*) p
;
501 rec_len
= dirent
->rec_len
;
502 #ifdef WORDS_BIGENDIAN
503 rec_len
= ext2fs_swab16(rec_len
);
505 if (rec_len
== EXT4_MAX_REC_LEN
|| rec_len
== 0)
506 rec_len
= fs
->blocksize
;
508 rec_len
= (rec_len
& 65532) | ((rec_len
& 3) << 16);
510 printf("rec_len = %d, name_len = %d\n", rec_len
, dirent
->name_len
);
512 if (rec_len
< 8 || (rec_len
% 4) ||
514 printf(_("Corrupt directory block %llu: "
515 "bad rec_len (%d)\n"),
516 (unsigned long long) blk
, rec_len
);
518 (void) ext2fs_set_rec_len(fs
, rec_len
,
519 (struct ext2_dir_entry
*) dirent
);
520 #ifdef WORDS_BIGENDIAN
521 dirent
->rec_len
= ext2fs_swab16(dirent
->rec_len
);
525 if (dirent
->name_len
+ 8U > rec_len
) {
526 printf(_("Corrupt directory block %llu: "
527 "bad name_len (%d)\n"),
528 (unsigned long long) blk
, dirent
->name_len
);
529 dirent
->name_len
= rec_len
- 8;
533 len
= rec_len
- dirent
->name_len
- 8;
535 memset(cp
+dirent
->name_len
, 0, len
);
536 if (dirent
->name_len
==1 && cp
[0] == '.')
538 if (dirent
->name_len
==2 && cp
[0] == '.' && cp
[1] == '.')
541 memset(cp
, 'A', dirent
->name_len
);
542 len
= dirent
->name_len
;
544 while ((len
> 0) && (id
> 0)) {
553 static char got_sigint
;
555 static void sigint_handler(int unused
EXT2FS_ATTR((unused
)))
558 signal (SIGINT
, SIG_DFL
);
561 #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \
562 ((float) (b)))) + 0.5))
563 #define calc_rate(t, b, d) (((float)(t) / ((float)(1024 * 1024) / (b))) / (d))
565 static int print_progress(blk64_t num
, blk64_t total
)
567 return fprintf(stderr
, _("%llu / %llu blocks (%d%%)"), num
, total
,
568 calc_percent(num
, total
));
571 static void output_meta_data_blocks(ext2_filsys fs
, int fd
, int flags
)
575 char *buf
, *zero_buf
;
578 blk64_t distance
= 0;
579 blk64_t end
= ext2fs_blocks_count(fs
->super
);
580 time_t last_update
= 0;
581 time_t start_time
= 0;
582 blk64_t total_written
= 0;
585 retval
= ext2fs_get_mem(fs
->blocksize
, &buf
);
587 com_err(program_name
, retval
, "%s",
588 _("while allocating buffer"));
591 retval
= ext2fs_get_memzero(fs
->blocksize
, &zero_buf
);
593 com_err(program_name
, retval
, "%s",
594 _("while allocating buffer"));
598 fprintf(stderr
, "%s", _("Copying "));
599 bscount
= print_progress(total_written
, meta_blocks_count
);
601 last_update
= time(NULL
);
602 start_time
= time(NULL
);
604 /* when doing an in place move to the right, you can't start
605 at the beginning or you will overwrite data, so instead
606 divide the fs up into distance size chunks and write them
608 if (move_mode
&& dest_offset
> source_offset
) {
609 distance
= (dest_offset
- source_offset
) / fs
->blocksize
;
610 if (distance
< ext2fs_blocks_count(fs
->super
))
611 start
= ext2fs_blocks_count(fs
->super
) - distance
;
614 signal (SIGINT
, sigint_handler
);
617 seek_set(fd
, (start
* fs
->blocksize
) + dest_offset
);
618 for (blk
= start
; blk
< end
; blk
++) {
621 /* moving to the right */
622 if (distance
>= ext2fs_blocks_count(fs
->super
)||
623 start
== ext2fs_blocks_count(fs
->super
) -
625 kill(getpid(), SIGINT
);
627 /* moving to the left */
628 if (blk
< (source_offset
- dest_offset
) /
630 kill(getpid(), SIGINT
);
634 fprintf(stderr
, "%s",
635 _("Stopping now will destroy the filesystem, "
636 "interrupt again if you are sure\n"));
638 fprintf(stderr
, "%s", _("Copying "));
639 bscount
= print_progress(total_written
,
646 if (show_progress
&& last_update
!= time(NULL
)) {
648 last_update
= time(NULL
);
651 bscount
= print_progress(total_written
,
653 duration
= time(NULL
) - start_time
;
654 if (duration
> 5 && total_written
) {
655 time_t est
= (duration
* meta_blocks_count
/
656 total_written
) - duration
;
658 strftime(buff
, 30, "%T", gmtime(&est
));
661 _(" %s remaining at %.2f MB/s"),
662 buff
, calc_rate(total_written
,
668 if ((blk
>= fs
->super
->s_first_data_block
) &&
669 ext2fs_test_block_bitmap2(meta_block_map
, blk
)) {
670 retval
= io_channel_read_blk64(fs
->io
, blk
, 1, buf
);
672 com_err(program_name
, retval
,
673 _("error reading block %llu"), blk
);
676 if (scramble_block_map
&&
677 ext2fs_test_block_bitmap2(scramble_block_map
, blk
))
678 scramble_dir_block(fs
, blk
, buf
);
679 if ((flags
& E2IMAGE_CHECK_ZERO_FLAG
) &&
680 check_zero_block(buf
, fs
->blocksize
))
683 seek_relative(fd
, sparse
);
685 if (check_block(fd
, buf
, check_buf
, fs
->blocksize
)) {
686 seek_relative(fd
, fs
->blocksize
);
689 generic_write(fd
, buf
, fs
->blocksize
, blk
);
694 generic_write(fd
, zero_buf
,
698 sparse
+= fs
->blocksize
;
699 if (sparse
> 1024*1024) {
700 seek_relative(fd
, 1024*1024);
705 if (distance
&& start
) {
706 if (start
< distance
) {
712 if (end
< distance
) {
713 /* past overlap, do rest in one go */
721 signal (SIGINT
, SIG_DFL
);
723 time_t duration
= time(NULL
) - start_time
;
726 strftime(buff
, 30, "%T", gmtime(&duration
));
727 fprintf(stderr
, _("Copied %llu / %llu blocks (%d%%) in %s "),
728 total_written
, meta_blocks_count
,
729 calc_percent(total_written
, meta_blocks_count
), buff
);
731 fprintf(stderr
, _("at %.2f MB/s"),
732 calc_rate(total_written
, fs
->blocksize
, duration
));
733 fputs(" \n", stderr
);
735 #ifdef HAVE_FTRUNCATE64
739 offset
= seek_set(fd
,
740 fs
->blocksize
* ext2fs_blocks_count(fs
->super
) + dest_offset
);
742 offset
= seek_relative(fd
, sparse
);
744 if (ftruncate64(fd
, offset
) < 0) {
745 seek_relative(fd
, -1);
746 generic_write(fd
, zero_buf
, 1, NO_BLK
);
750 if (sparse
&& !distance
) {
751 seek_relative(fd
, sparse
-1);
752 generic_write(fd
, zero_buf
, 1, NO_BLK
);
755 ext2fs_free_mem(&zero_buf
);
756 ext2fs_free_mem(&buf
);
759 static void init_l1_table(struct ext2_qcow2_image
*image
)
764 ret
= ext2fs_get_arrayzero(image
->l1_size
, sizeof(__u64
), &l1_table
);
766 com_err(program_name
, ret
, "%s",
767 _("while allocating l1 table"));
771 image
->l1_table
= l1_table
;
774 static void init_l2_cache(struct ext2_qcow2_image
*image
)
776 unsigned int count
, i
;
777 struct ext2_qcow2_l2_cache
*cache
;
778 struct ext2_qcow2_l2_table
*table
;
781 ret
= ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache
),
786 count
= (image
->l1_size
> L2_CACHE_PREALLOC
) ? L2_CACHE_PREALLOC
:
789 cache
->count
= count
;
791 cache
->next_offset
= image
->l2_offset
;
793 for (i
= 0; i
< count
; i
++) {
794 ret
= ext2fs_get_arrayzero(1,
795 sizeof(struct ext2_qcow2_l2_table
), &table
);
799 ret
= ext2fs_get_arrayzero(image
->l2_size
,
800 sizeof(__u64
), &table
->data
);
804 table
->next
= cache
->free_head
;
805 cache
->free_head
= table
;
808 image
->l2_cache
= cache
;
812 com_err(program_name
, ret
, "%s", _("while allocating l2 cache"));
816 static void put_l2_cache(struct ext2_qcow2_image
*image
)
818 struct ext2_qcow2_l2_cache
*cache
= image
->l2_cache
;
819 struct ext2_qcow2_l2_table
*tmp
, *table
;
824 table
= cache
->free_head
;
825 cache
->free_head
= NULL
;
830 ext2fs_free_mem(&tmp
->data
);
831 ext2fs_free_mem(&tmp
);
834 if (cache
->free
!= cache
->count
) {
835 fprintf(stderr
, "%s", _("Warning: There are still tables in "
836 "the cache while putting the cache, "
837 "data will be lost so the image may "
839 table
= cache
->used_head
;
840 cache
->used_head
= NULL
;
844 ext2fs_free_mem(&cache
);
847 static int init_refcount(struct ext2_qcow2_image
*img
, blk64_t table_offset
)
849 struct ext2_qcow2_refcount
*ref
;
850 blk64_t table_clusters
;
853 ref
= &(img
->refcount
);
856 * One refcount block addresses 2048 clusters, one refcount table
857 * addresses cluster/sizeof(__u64) refcount blocks, and we need
858 * to address meta_blocks_count clusters + qcow2 metadata clusters
861 table_clusters
= meta_blocks_count
+ (table_offset
>>
863 table_clusters
>>= (img
->cluster_bits
+ 6 - 1);
864 table_clusters
= (table_clusters
== 0) ? 1 : table_clusters
;
866 ref
->refcount_table_offset
= table_offset
;
867 ref
->refcount_table_clusters
= table_clusters
;
868 ref
->refcount_table_index
= 0;
869 ref
->refcount_block_index
= 0;
871 /* Allocate refcount table */
872 ret
= ext2fs_get_arrayzero(ref
->refcount_table_clusters
,
873 img
->cluster_size
, &ref
->refcount_table
);
877 /* Allocate refcount block */
878 ret
= ext2fs_get_arrayzero(1, img
->cluster_size
, &ref
->refcount_block
);
880 ext2fs_free_mem(&ref
->refcount_table
);
885 static errcode_t
initialize_qcow2_image(int fd
, ext2_filsys fs
,
886 struct ext2_qcow2_image
*image
)
888 struct ext2_qcow2_hdr
*header
;
889 blk64_t total_size
, offset
;
890 int shift
, l2_bits
, header_size
, l1_size
, ret
;
891 int cluster_bits
= get_bits_from_size(fs
->blocksize
);
892 struct ext2_super_block
*sb
= fs
->super
;
894 if (fs
->blocksize
< 1024)
895 return EINVAL
; /* Can never happen, but just in case... */
897 /* Allocate header */
898 ret
= ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr
), &header
);
902 total_size
= ext2fs_blocks_count(sb
) << cluster_bits
;
903 image
->cluster_size
= fs
->blocksize
;
904 image
->l2_size
= 1 << (cluster_bits
- 3);
905 image
->cluster_bits
= cluster_bits
;
908 header
->magic
= ext2fs_cpu_to_be32(QCOW_MAGIC
);
909 header
->version
= ext2fs_cpu_to_be32(QCOW_VERSION
);
910 header
->size
= ext2fs_cpu_to_be64(total_size
);
911 header
->cluster_bits
= ext2fs_cpu_to_be32(cluster_bits
);
913 header_size
= (sizeof(struct ext2_qcow2_hdr
) + 7) & ~7;
914 offset
= align_offset(header_size
, image
->cluster_size
);
916 header
->l1_table_offset
= ext2fs_cpu_to_be64(offset
);
917 image
->l1_offset
= offset
;
919 l2_bits
= cluster_bits
- 3;
920 shift
= cluster_bits
+ l2_bits
;
921 l1_size
= ((total_size
+ (1LL << shift
) - 1) >> shift
);
922 header
->l1_size
= ext2fs_cpu_to_be32(l1_size
);
923 image
->l1_size
= l1_size
;
925 /* Make space for L1 table */
926 offset
+= align_offset(l1_size
* sizeof(blk64_t
), image
->cluster_size
);
928 /* Initialize refcounting */
929 ret
= init_refcount(image
, offset
);
931 ext2fs_free_mem(&header
);
934 header
->refcount_table_offset
= ext2fs_cpu_to_be64(offset
);
935 header
->refcount_table_clusters
=
936 ext2fs_cpu_to_be32(image
->refcount
.refcount_table_clusters
);
937 offset
+= image
->cluster_size
;
938 offset
+= image
->refcount
.refcount_table_clusters
<<
941 /* Make space for L2 tables */
942 image
->l2_offset
= offset
;
943 offset
+= image
->cluster_size
;
945 /* Make space for first refcount block */
946 image
->refcount
.refcount_block_offset
= offset
;
949 /* Initialize l1 and l2 tables */
950 init_l1_table(image
);
951 init_l2_cache(image
);
956 static void free_qcow2_image(struct ext2_qcow2_image
*img
)
962 ext2fs_free_mem(&img
->hdr
);
965 ext2fs_free_mem(&img
->l1_table
);
967 if (img
->refcount
.refcount_table
)
968 ext2fs_free_mem(&img
->refcount
.refcount_table
);
969 if (img
->refcount
.refcount_block
)
970 ext2fs_free_mem(&img
->refcount
.refcount_block
);
974 ext2fs_free_mem(&img
);
978 * Put table from used list (used_head) into free list (free_head).
979 * l2_table is used to return pointer to the next used table (used_head).
981 static void put_used_table(struct ext2_qcow2_image
*img
,
982 struct ext2_qcow2_l2_table
**l2_table
)
984 struct ext2_qcow2_l2_cache
*cache
= img
->l2_cache
;
985 struct ext2_qcow2_l2_table
*table
;
987 table
= cache
->used_head
;
988 cache
->used_head
= table
->next
;
992 cache
->used_tail
= NULL
;
994 /* Clean the table for case we will need to use it again */
995 memset(table
->data
, 0, img
->cluster_size
);
996 table
->next
= cache
->free_head
;
997 cache
->free_head
= table
;
1001 *l2_table
= cache
->used_head
;
1004 static void flush_l2_cache(struct ext2_qcow2_image
*image
)
1008 struct ext2_qcow2_l2_cache
*cache
= image
->l2_cache
;
1009 struct ext2_qcow2_l2_table
*table
= cache
->used_head
;
1012 /* Store current position */
1013 offset
= seek_relative(fd
, 0);
1016 while (cache
->free
< cache
->count
) {
1017 if (seek
!= table
->offset
) {
1018 seek_set(fd
, table
->offset
);
1019 seek
= table
->offset
;
1022 generic_write(fd
, (char *)table
->data
, image
->cluster_size
,
1024 put_used_table(image
, &table
);
1025 seek
+= image
->cluster_size
;
1028 /* Restore previous position */
1029 seek_set(fd
, offset
);
1033 * Get first free table (from free_head) and put it into tail of used list
1035 * l2_table is used to return pointer to moved table.
1036 * Returns 1 if the cache is full, 0 otherwise.
1038 static void get_free_table(struct ext2_qcow2_image
*image
,
1039 struct ext2_qcow2_l2_table
**l2_table
)
1041 struct ext2_qcow2_l2_table
*table
;
1042 struct ext2_qcow2_l2_cache
*cache
= image
->l2_cache
;
1044 if (0 == cache
->free
)
1045 flush_l2_cache(image
);
1047 table
= cache
->free_head
;
1049 cache
->free_head
= table
->next
;
1051 if (cache
->used_tail
)
1052 cache
->used_tail
->next
= table
;
1054 /* First item in the used list */
1055 cache
->used_head
= table
;
1057 cache
->used_tail
= table
;
1063 static int add_l2_item(struct ext2_qcow2_image
*img
, blk64_t blk
,
1064 blk64_t data
, blk64_t next
)
1066 struct ext2_qcow2_l2_cache
*cache
= img
->l2_cache
;
1067 struct ext2_qcow2_l2_table
*table
= cache
->used_tail
;
1068 blk64_t l1_index
= blk
/ img
->l2_size
;
1069 blk64_t l2_index
= blk
& (img
->l2_size
- 1);
1073 * Need to create new table if it does not exist,
1076 if (!table
|| (table
->l1_index
!= l1_index
)) {
1077 get_free_table(img
, &table
);
1078 table
->l1_index
= l1_index
;
1079 table
->offset
= cache
->next_offset
;
1080 cache
->next_offset
= next
;
1081 img
->l1_table
[l1_index
] =
1082 ext2fs_cpu_to_be64(table
->offset
| QCOW_OFLAG_COPIED
);
1086 table
->data
[l2_index
] = ext2fs_cpu_to_be64(data
| QCOW_OFLAG_COPIED
);
1090 static int update_refcount(int fd
, struct ext2_qcow2_image
*img
,
1091 blk64_t offset
, blk64_t rfblk_pos
)
1093 struct ext2_qcow2_refcount
*ref
;
1097 ref
= &(img
->refcount
);
1098 table_index
= offset
>> (2 * img
->cluster_bits
- 1);
1101 * Need to create new refcount block when the offset addresses
1102 * another item in the refcount table
1104 if (table_index
!= ref
->refcount_table_index
) {
1106 seek_set(fd
, ref
->refcount_block_offset
);
1108 generic_write(fd
, (char *)ref
->refcount_block
,
1109 img
->cluster_size
, NO_BLK
);
1110 memset(ref
->refcount_block
, 0, img
->cluster_size
);
1112 ref
->refcount_table
[ref
->refcount_table_index
] =
1113 ext2fs_cpu_to_be64(ref
->refcount_block_offset
);
1114 ref
->refcount_block_offset
= rfblk_pos
;
1115 ref
->refcount_block_index
= 0;
1116 ref
->refcount_table_index
= table_index
;
1121 * We are relying on the fact that we are creating the qcow2
1122 * image sequentially, hence we will always allocate refcount
1123 * block items sequentially.
1125 ref
->refcount_block
[ref
->refcount_block_index
] = ext2fs_cpu_to_be16(1);
1126 ref
->refcount_block_index
++;
1130 static int sync_refcount(int fd
, struct ext2_qcow2_image
*img
)
1132 struct ext2_qcow2_refcount
*ref
;
1134 ref
= &(img
->refcount
);
1136 ref
->refcount_table
[ref
->refcount_table_index
] =
1137 ext2fs_cpu_to_be64(ref
->refcount_block_offset
);
1138 seek_set(fd
, ref
->refcount_table_offset
);
1139 generic_write(fd
, (char *)ref
->refcount_table
,
1140 ref
->refcount_table_clusters
<< img
->cluster_bits
, NO_BLK
);
1142 seek_set(fd
, ref
->refcount_block_offset
);
1143 generic_write(fd
, (char *)ref
->refcount_block
, img
->cluster_size
,
1148 static void output_qcow2_meta_data_blocks(ext2_filsys fs
, int fd
)
1151 blk64_t blk
, offset
, size
, end
;
1153 struct ext2_qcow2_image
*img
;
1154 unsigned int header_size
;
1156 /* allocate struct ext2_qcow2_image */
1157 retval
= ext2fs_get_mem(sizeof(struct ext2_qcow2_image
), &img
);
1159 com_err(program_name
, retval
, "%s",
1160 _("while allocating ext2_qcow2_image"));
1164 retval
= initialize_qcow2_image(fd
, fs
, img
);
1166 com_err(program_name
, retval
, "%s",
1167 _("while initializing ext2_qcow2_image"));
1170 header_size
= align_offset(sizeof(struct ext2_qcow2_hdr
),
1172 write_header(fd
, img
->hdr
, sizeof(struct ext2_qcow2_hdr
), header_size
);
1174 /* Refcount all qcow2 related metadata up to refcount_block_offset */
1175 end
= img
->refcount
.refcount_block_offset
;
1177 blk
= end
+ img
->cluster_size
;
1178 for (offset
= 0; offset
<= end
; offset
+= img
->cluster_size
) {
1179 if (update_refcount(fd
, img
, offset
, blk
)) {
1180 blk
+= img
->cluster_size
;
1182 * If we create new refcount block, we need to refcount
1185 end
+= img
->cluster_size
;
1188 seek_set(fd
, offset
);
1190 retval
= ext2fs_get_mem(fs
->blocksize
, &buf
);
1192 com_err(program_name
, retval
, "%s",
1193 _("while allocating buffer"));
1196 /* Write qcow2 data blocks */
1197 for (blk
= 0; blk
< ext2fs_blocks_count(fs
->super
); blk
++) {
1198 if ((blk
>= fs
->super
->s_first_data_block
) &&
1199 ext2fs_test_block_bitmap2(meta_block_map
, blk
)) {
1200 retval
= io_channel_read_blk64(fs
->io
, blk
, 1, buf
);
1202 com_err(program_name
, retval
,
1203 _("error reading block %llu"), blk
);
1206 if (scramble_block_map
&&
1207 ext2fs_test_block_bitmap2(scramble_block_map
, blk
))
1208 scramble_dir_block(fs
, blk
, buf
);
1209 if (check_zero_block(buf
, fs
->blocksize
))
1212 if (update_refcount(fd
, img
, offset
, offset
)) {
1213 /* Make space for another refcount block */
1214 offset
+= img
->cluster_size
;
1215 seek_set(fd
, offset
);
1217 * We have created the new refcount block, this
1218 * means that we need to refcount it as well.
1219 * So the previous update_refcount refcounted
1220 * the block itself and now we are going to
1221 * create refcount for data. New refcount
1222 * block should not be created!
1224 if (update_refcount(fd
, img
, offset
, offset
)) {
1225 fprintf(stderr
, "%s",
1226 _("Programming error: multiple "
1227 "sequential refcount blocks "
1233 generic_write(fd
, buf
, fs
->blocksize
, blk
);
1235 if (add_l2_item(img
, blk
, offset
,
1236 offset
+ img
->cluster_size
)) {
1237 offset
+= img
->cluster_size
;
1238 if (update_refcount(fd
, img
, offset
,
1239 offset
+ img
->cluster_size
)) {
1240 offset
+= img
->cluster_size
;
1241 if (update_refcount(fd
, img
, offset
,
1243 fprintf(stderr
, "%s",
1244 _("Programming error: multiple sequential refcount "
1245 "blocks created!\n"));
1249 offset
+= img
->cluster_size
;
1250 seek_set(fd
, offset
);
1254 offset
+= img
->cluster_size
;
1257 update_refcount(fd
, img
, offset
, offset
);
1258 flush_l2_cache(img
);
1259 sync_refcount(fd
, img
);
1262 seek_set(fd
, img
->l1_offset
);
1263 size
= img
->l1_size
* sizeof(__u64
);
1264 generic_write(fd
, (char *)img
->l1_table
, size
, NO_BLK
);
1266 ext2fs_free_mem(&buf
);
1267 free_qcow2_image(img
);
1270 static void write_raw_image_file(ext2_filsys fs
, int fd
, int type
, int flags
)
1272 struct process_block_struct pb
;
1273 struct ext2_inode inode
;
1274 ext2_inode_scan scan
;
1279 meta_blocks_count
= 0;
1280 retval
= ext2fs_allocate_block_bitmap(fs
, _("in-use block map"),
1283 com_err(program_name
, retval
, "%s",
1284 _("while allocating block bitmap"));
1288 if (flags
& E2IMAGE_SCRAMBLE_FLAG
) {
1289 retval
= ext2fs_allocate_block_bitmap(fs
, "scramble block map",
1290 &scramble_block_map
);
1292 com_err(program_name
, retval
, "%s",
1293 _("while allocating scramble block bitmap"));
1298 mark_table_blocks(fs
);
1300 fprintf(stderr
, "%s", _("Scanning inodes...\n"));
1302 retval
= ext2fs_open_inode_scan(fs
, 0, &scan
);
1304 com_err(program_name
, retval
, "%s",
1305 _("while opening inode scan"));
1309 retval
= ext2fs_get_mem(fs
->blocksize
* 3, &block_buf
);
1311 com_err(program_name
, 0, "%s",
1312 _("Can't allocate block buffer"));
1316 use_inode_shortcuts(fs
, 1);
1317 stashed_inode
= &inode
;
1319 retval
= ext2fs_get_next_inode(scan
, &ino
, &inode
);
1320 if (retval
== EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
)
1323 com_err(program_name
, retval
, "%s",
1324 _("while getting next inode"));
1329 if (!inode
.i_links_count
)
1331 if (ext2fs_file_acl_block(fs
, &inode
)) {
1332 ext2fs_mark_block_bitmap2(meta_block_map
,
1333 ext2fs_file_acl_block(fs
, &inode
));
1334 meta_blocks_count
++;
1336 if (!ext2fs_inode_has_valid_blocks2(fs
, &inode
))
1341 pb
.is_dir
= LINUX_S_ISDIR(inode
.i_mode
);
1342 if (LINUX_S_ISDIR(inode
.i_mode
) ||
1343 (LINUX_S_ISLNK(inode
.i_mode
) &&
1344 ext2fs_inode_has_valid_blocks2(fs
, &inode
)) ||
1345 ino
== fs
->super
->s_journal_inum
) {
1346 retval
= ext2fs_block_iterate3(fs
, ino
,
1347 BLOCK_FLAG_READ_ONLY
, block_buf
,
1348 process_dir_block
, &pb
);
1350 com_err(program_name
, retval
,
1351 _("while iterating over inode %u"),
1356 if ((inode
.i_flags
& EXT4_EXTENTS_FL
) ||
1357 inode
.i_block
[EXT2_IND_BLOCK
] ||
1358 inode
.i_block
[EXT2_DIND_BLOCK
] ||
1359 inode
.i_block
[EXT2_TIND_BLOCK
] || all_data
) {
1360 retval
= ext2fs_block_iterate3(fs
,
1361 ino
, BLOCK_FLAG_READ_ONLY
, block_buf
,
1362 process_file_block
, &pb
);
1364 com_err(program_name
, retval
,
1365 _("while iterating over inode %u"), ino
);
1371 use_inode_shortcuts(fs
, 0);
1373 if (type
& E2IMAGE_QCOW2
)
1374 output_qcow2_meta_data_blocks(fs
, fd
);
1376 output_meta_data_blocks(fs
, fd
, flags
);
1378 ext2fs_free_mem(&block_buf
);
1379 ext2fs_close_inode_scan(scan
);
1380 ext2fs_free_block_bitmap(meta_block_map
);
1381 if (type
& E2IMAGE_SCRAMBLE_FLAG
)
1382 ext2fs_free_block_bitmap(scramble_block_map
);
1385 static void install_image(char *device
, char *image_fn
, int type
)
1389 int open_flag
= EXT2_FLAG_IMAGE_FILE
| EXT2_FLAG_64BITS
|
1390 EXT2_FLAG_IGNORE_CSUM_ERRORS
;
1396 com_err(program_name
, 0, "%s",
1397 _("Raw and qcow2 images cannot be installed"));
1401 #ifdef CONFIG_TESTIO_DEBUG
1402 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
1403 io_ptr
= test_io_manager
;
1404 test_io_backing_manager
= unix_io_manager
;
1407 io_ptr
= unix_io_manager
;
1409 retval
= ext2fs_open (image_fn
, open_flag
, 0, 0,
1412 com_err(program_name
, retval
, _("while trying to open %s"),
1417 retval
= ext2fs_read_bitmaps (fs
);
1419 com_err(program_name
, retval
, "%s", _("error reading bitmaps"));
1423 fd
= ext2fs_open_file(image_fn
, O_RDONLY
, 0);
1429 retval
= io_ptr
->open(device
, IO_FLAG_RW
, &io
);
1431 com_err(device
, 0, "%s", _("while opening device file"));
1435 ext2fs_rewrite_to_io(fs
, io
);
1437 seek_set(fd
, ext2fs_le32_to_cpu(fs
->image_header
->offset_inode
));
1439 retval
= ext2fs_image_inode_read(fs
, fd
, 0);
1441 com_err(image_fn
, 0, "%s",
1442 _("while restoring the image table"));
1447 ext2fs_close_free(&fs
);
1450 static struct ext2_qcow2_hdr
*check_qcow2_image(int *fd
, char *name
)
1453 *fd
= ext2fs_open_file(name
, O_RDONLY
, 0600);
1457 return qcow2_read_header(*fd
);
1460 int main (int argc
, char ** argv
)
1465 char *image_fn
, offset_opt
[64];
1466 struct ext2_qcow2_hdr
*header
= NULL
;
1467 int open_flag
= EXT2_FLAG_64BITS
| EXT2_FLAG_IGNORE_CSUM_ERRORS
;
1470 int mount_flags
= 0;
1474 int ignore_rw_mount
= 0;
1479 setlocale(LC_MESSAGES
, "");
1480 setlocale(LC_CTYPE
, "");
1481 bindtextdomain(NLS_CAT_NAME
, LOCALEDIR
);
1482 textdomain(NLS_CAT_NAME
);
1483 set_com_err_gettext(gettext
);
1485 fprintf (stderr
, "e2image %s (%s)\n", E2FSPROGS_VERSION
,
1488 program_name
= *argv
;
1489 add_error_table(&et_ext2_error_table
);
1490 while ((c
= getopt(argc
, argv
, "nrsIQafo:O:pc")) != EOF
)
1493 flags
|= E2IMAGE_INSTALL_FLAG
;
1498 img_type
|= E2IMAGE_QCOW2
;
1503 img_type
|= E2IMAGE_RAW
;
1506 flags
|= E2IMAGE_SCRAMBLE_FLAG
;
1512 ignore_rw_mount
= 1;
1518 source_offset
= strtoull(optarg
, NULL
, 0);
1521 dest_offset
= strtoull(optarg
, NULL
, 0);
1532 if (optind
== argc
- 1 &&
1533 (source_offset
|| dest_offset
))
1535 else if (optind
!= argc
- 2 )
1538 if (all_data
&& !img_type
) {
1539 com_err(program_name
, 0, "%s", _("-a option can only be used "
1540 "with raw or QCOW2 images."));
1543 if ((source_offset
|| dest_offset
) && img_type
!= E2IMAGE_RAW
) {
1544 com_err(program_name
, 0, "%s",
1545 _("Offsets are only allowed with raw images."));
1548 if (move_mode
&& img_type
!= E2IMAGE_RAW
) {
1549 com_err(program_name
, 0, "%s",
1550 _("Move mode is only allowed with raw images."));
1553 if (move_mode
&& !all_data
) {
1554 com_err(program_name
, 0, "%s",
1555 _("Move mode requires all data mode."));
1558 device_name
= argv
[optind
];
1560 image_fn
= device_name
;
1561 else image_fn
= argv
[optind
+1];
1563 retval
= ext2fs_check_if_mounted(device_name
, &mount_flags
);
1565 com_err(program_name
, retval
, "%s", _("checking if mounted"));
1569 if (img_type
&& !ignore_rw_mount
&&
1570 (mount_flags
& EXT2_MF_MOUNTED
) &&
1571 !(mount_flags
& EXT2_MF_READONLY
)) {
1572 fprintf(stderr
, "%s", _("\nRunning e2image on a R/W mounted "
1573 "filesystem can result in an\n"
1574 "inconsistent image which will not be useful "
1575 "for debugging purposes.\n"
1576 "Use -f option if you really want to do that.\n"));
1580 if (flags
& E2IMAGE_INSTALL_FLAG
) {
1581 install_image(device_name
, image_fn
, img_type
);
1585 if (img_type
& E2IMAGE_RAW
) {
1586 header
= check_qcow2_image(&qcow2_fd
, device_name
);
1588 flags
|= E2IMAGE_IS_QCOW2_FLAG
;
1592 sprintf(offset_opt
, "offset=%llu", source_offset
);
1593 retval
= ext2fs_open2(device_name
, offset_opt
, open_flag
, 0, 0,
1594 unix_io_manager
, &fs
);
1596 com_err (program_name
, retval
, _("while trying to open %s"),
1598 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout
);
1599 if (retval
== EXT2_ET_BAD_MAGIC
)
1600 check_plausibility(device_name
, CHECK_FS_EXIST
, NULL
);
1605 if (strcmp(image_fn
, "-") == 0)
1608 int o_flags
= O_CREAT
|O_RDWR
;
1610 if (img_type
!= E2IMAGE_RAW
)
1612 if (access(image_fn
, F_OK
) != 0)
1613 flags
|= E2IMAGE_CHECK_ZERO_FLAG
;
1614 fd
= ext2fs_open_file(image_fn
, o_flags
, 0600);
1616 com_err(program_name
, errno
,
1617 _("while trying to open %s"), image_fn
);
1622 seek_set(fd
, dest_offset
);
1624 if ((img_type
& E2IMAGE_QCOW2
) && (fd
== 1)) {
1625 com_err(program_name
, 0, "%s",
1626 _("QCOW2 image can not be written to the stdout!\n"));
1630 if (fstat(fd
, &st
)) {
1631 com_err(program_name
, 0, "%s",
1632 _("Can not stat output\n"));
1635 if (ext2fsP_is_disk_device(st
.st_mode
))
1638 if (flags
& E2IMAGE_IS_QCOW2_FLAG
) {
1639 ret
= qcow2_write_raw_image(qcow2_fd
, fd
, header
);
1641 if (ret
== -QCOW_COMPRESSED
)
1642 fprintf(stderr
, _("Image (%s) is compressed\n"),
1644 else if (ret
== -QCOW_ENCRYPTED
)
1645 fprintf(stderr
, _("Image (%s) is encrypted\n"),
1647 else if (ret
== -QCOW_CORRUPTED
)
1648 fprintf(stderr
, _("Image (%s) is corrupted\n"),
1651 com_err(program_name
, ret
,
1652 _("while trying to convert qcow2 image"
1653 " (%s) into raw image (%s)"),
1654 image_fn
, device_name
);
1661 if (img_type
!= E2IMAGE_RAW
) {
1662 fprintf(stderr
, "%s", _("The -c option only supported "
1667 fprintf(stderr
, "%s", _("The -c option not supported "
1668 "when writing to stdout\n"));
1671 retval
= ext2fs_get_mem(fs
->blocksize
, &check_buf
);
1673 com_err(program_name
, retval
, "%s",
1674 _("while allocating check_buf"));
1678 if (show_progress
&& (img_type
!= E2IMAGE_RAW
)) {
1679 fprintf(stderr
, "%s",
1680 _("The -p option only supported in raw mode\n"));
1684 write_raw_image_file(fs
, fd
, img_type
, flags
);
1686 write_image_file(fs
, fd
);
1688 ext2fs_close_free(&fs
);
1690 printf(_("%d blocks already contained the data to be copied\n"),
1698 remove_error_table(&et_ext2_error_table
);