e2image.c revision 6b5535f40974d522e827c83d02d005ac5c8b5056
1/* 2 * e2image.c --- Program which writes an image file backing up 3 * critical metadata for the filesystem. 4 * 5 * Copyright 2000, 2001 by Theodore Ts'o. 6 * 7 * %Begin-Header% 8 * This file may be redistributed under the terms of the GNU Public 9 * License. 10 * %End-Header% 11 */ 12 13#define _LARGEFILE_SOURCE 14#define _LARGEFILE64_SOURCE 15 16#include "config.h" 17#include <fcntl.h> 18#include <grp.h> 19#ifdef HAVE_GETOPT_H 20#include <getopt.h> 21#else 22extern char *optarg; 23extern int optind; 24#endif 25#include <pwd.h> 26#include <stdio.h> 27#ifdef HAVE_STDLIB_H 28#include <stdlib.h> 29#endif 30#include <string.h> 31#include <time.h> 32#include <unistd.h> 33#include <fcntl.h> 34#include <errno.h> 35#include <sys/stat.h> 36#include <sys/types.h> 37#include <assert.h> 38 39#include "ext2fs/ext2_fs.h" 40#include "ext2fs/ext2fs.h" 41#include "et/com_err.h" 42#include "uuid/uuid.h" 43#include "e2p/e2p.h" 44#include "ext2fs/e2image.h" 45#include "ext2fs/qcow2.h" 46 47#include "../version.h" 48#include "nls-enable.h" 49 50#define QCOW_OFLAG_COPIED (1LL << 63) 51 52 53static const char * program_name = "e2image"; 54static char * device_name = NULL; 55static char all_data; 56static char output_is_blk; 57/* writing to blk device: don't skip zeroed blocks */ 58blk64_t source_offset, dest_offset; 59 60static void lseek_error_and_exit(int errnum) 61{ 62 fprintf(stderr, "seek: %s\n", error_message(errnum)); 63 exit(1); 64} 65 66static blk64_t align_offset(blk64_t offset, int n) 67{ 68 return (offset + n - 1) & ~(n - 1); 69} 70 71static int get_bits_from_size(size_t size) 72{ 73 int res = 0; 74 75 if (size == 0) 76 return -1; 77 78 while (size != 1) { 79 /* Not a power of two */ 80 if (size & 1) 81 return -1; 82 83 size >>= 1; 84 res++; 85 } 86 return res; 87} 88 89static void usage(void) 90{ 91 fprintf(stderr, _("Usage: %s [-rsIQaf] [-o source_offset] [-O dest_offset] device image_file\n"), 92 program_name); 93 exit (1); 94} 95 96static void generic_write(int fd, void *buf, int blocksize, blk64_t block) 97{ 98 int count, free_buf = 0; 99 errcode_t err; 100 101 if (!blocksize) 102 return; 103 104 if (!buf) { 105 free_buf = 1; 106 err = ext2fs_get_arrayzero(1, blocksize, &buf); 107 if (err) { 108 com_err(program_name, err, "while allocating buffer"); 109 exit(1); 110 } 111 } 112 113 count = write(fd, buf, blocksize); 114 if (count != blocksize) { 115 if (count == -1) 116 err = errno; 117 else 118 err = 0; 119 120 if (block) 121 com_err(program_name, err, "error writing block %llu", 122 block); 123 else 124 com_err(program_name, err, "error in write()"); 125 126 exit(1); 127 } 128 if (free_buf) 129 ext2fs_free_mem(&buf); 130} 131 132static void write_header(int fd, void *hdr, int hdr_size, int wrt_size) 133{ 134 char *header_buf; 135 int ret; 136 137 /* Sanity check */ 138 if (hdr_size > wrt_size) { 139 fprintf(stderr, "%s", 140 _("Error: header size is bigger than wrt_size\n")); 141 } 142 143 ret = ext2fs_get_mem(wrt_size, &header_buf); 144 if (ret) { 145 fputs(_("Couldn't allocate header buffer\n"), stderr); 146 exit(1); 147 } 148 149 if (ext2fs_llseek(fd, 0, SEEK_SET) < 0) { 150 perror("ext2fs_llseek while writing header"); 151 exit(1); 152 } 153 memset(header_buf, 0, wrt_size); 154 155 if (hdr) 156 memcpy(header_buf, hdr, hdr_size); 157 158 generic_write(fd, header_buf, wrt_size, 0); 159 160 ext2fs_free_mem(&header_buf); 161} 162 163static void write_image_file(ext2_filsys fs, int fd) 164{ 165 struct ext2_image_hdr hdr; 166 struct stat st; 167 errcode_t retval; 168 169 write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize); 170 memset(&hdr, 0, sizeof(struct ext2_image_hdr)); 171 172 hdr.offset_super = ext2fs_llseek(fd, 0, SEEK_CUR); 173 retval = ext2fs_image_super_write(fs, fd, 0); 174 if (retval) { 175 com_err(program_name, retval, "%s", 176 _("while writing superblock")); 177 exit(1); 178 } 179 180 hdr.offset_inode = ext2fs_llseek(fd, 0, SEEK_CUR); 181 retval = ext2fs_image_inode_write(fs, fd, 182 (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0); 183 if (retval) { 184 com_err(program_name, retval, "%s", 185 _("while writing inode table")); 186 exit(1); 187 } 188 189 hdr.offset_blockmap = ext2fs_llseek(fd, 0, SEEK_CUR); 190 retval = ext2fs_image_bitmap_write(fs, fd, 0); 191 if (retval) { 192 com_err(program_name, retval, "%s", 193 _("while writing block bitmap")); 194 exit(1); 195 } 196 197 hdr.offset_inodemap = ext2fs_llseek(fd, 0, SEEK_CUR); 198 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP); 199 if (retval) { 200 com_err(program_name, retval, "%s", 201 _("while writing inode bitmap")); 202 exit(1); 203 } 204 205 hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE; 206 strcpy(hdr.magic_descriptor, "Ext2 Image 1.0"); 207 gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname)); 208 strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1); 209 hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0; 210 hdr.fs_blocksize = fs->blocksize; 211 212 if (stat(device_name, &st) == 0) 213 hdr.fs_device = st.st_rdev; 214 215 if (fstat(fd, &st) == 0) { 216 hdr.image_device = st.st_dev; 217 hdr.image_inode = st.st_ino; 218 } 219 memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid)); 220 221 hdr.image_time = time(0); 222 write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize); 223} 224 225/* 226 * These set of functions are used to write a RAW image file. 227 */ 228static ext2fs_block_bitmap meta_block_map; 229static ext2fs_block_bitmap scramble_block_map; /* Directory blocks to be scrambled */ 230static blk64_t meta_blocks_count; 231 232struct process_block_struct { 233 ext2_ino_t ino; 234 int is_dir; 235}; 236 237/* 238 * These subroutines short circuits ext2fs_get_blocks and 239 * ext2fs_check_directory; we use them since we already have the inode 240 * structure, so there's no point in letting the ext2fs library read 241 * the inode again. 242 */ 243static ino_t stashed_ino = 0; 244static struct ext2_inode *stashed_inode; 245 246static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)), 247 ext2_ino_t ino, 248 blk_t *blocks) 249{ 250 int i; 251 252 if ((ino != stashed_ino) || !stashed_inode) 253 return EXT2_ET_CALLBACK_NOTHANDLED; 254 255 for (i=0; i < EXT2_N_BLOCKS; i++) 256 blocks[i] = stashed_inode->i_block[i]; 257 return 0; 258} 259 260static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)), 261 ext2_ino_t ino) 262{ 263 if ((ino != stashed_ino) || !stashed_inode) 264 return EXT2_ET_CALLBACK_NOTHANDLED; 265 266 if (!LINUX_S_ISDIR(stashed_inode->i_mode)) 267 return EXT2_ET_NO_DIRECTORY; 268 return 0; 269} 270 271static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)), 272 ext2_ino_t ino, 273 struct ext2_inode *inode) 274{ 275 if ((ino != stashed_ino) || !stashed_inode) 276 return EXT2_ET_CALLBACK_NOTHANDLED; 277 *inode = *stashed_inode; 278 return 0; 279} 280 281static void use_inode_shortcuts(ext2_filsys fs, int use_shortcuts) 282{ 283 if (use_shortcuts) { 284 fs->get_blocks = meta_get_blocks; 285 fs->check_directory = meta_check_directory; 286 fs->read_inode = meta_read_inode; 287 stashed_ino = 0; 288 } else { 289 fs->get_blocks = 0; 290 fs->check_directory = 0; 291 fs->read_inode = 0; 292 } 293} 294 295static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)), 296 blk64_t *block_nr, 297 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), 298 blk64_t ref_block EXT2FS_ATTR((unused)), 299 int ref_offset EXT2FS_ATTR((unused)), 300 void *priv_data EXT2FS_ATTR((unused))) 301{ 302 struct process_block_struct *p; 303 304 p = (struct process_block_struct *) priv_data; 305 306 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr); 307 meta_blocks_count++; 308 if (scramble_block_map && p->is_dir && blockcnt >= 0) 309 ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr); 310 return 0; 311} 312 313static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)), 314 blk64_t *block_nr, 315 e2_blkcnt_t blockcnt, 316 blk64_t ref_block EXT2FS_ATTR((unused)), 317 int ref_offset EXT2FS_ATTR((unused)), 318 void *priv_data EXT2FS_ATTR((unused))) 319{ 320 if (blockcnt < 0 || all_data) { 321 ext2fs_mark_block_bitmap2(meta_block_map, *block_nr); 322 meta_blocks_count++; 323 } 324 return 0; 325} 326 327static void mark_table_blocks(ext2_filsys fs) 328{ 329 blk64_t first_block, b; 330 unsigned int i,j; 331 332 first_block = fs->super->s_first_data_block; 333 /* 334 * Mark primary superblock 335 */ 336 ext2fs_mark_block_bitmap2(meta_block_map, first_block); 337 meta_blocks_count++; 338 339 /* 340 * Mark the primary superblock descriptors 341 */ 342 for (j = 0; j < fs->desc_blocks; j++) { 343 ext2fs_mark_block_bitmap2(meta_block_map, 344 ext2fs_descriptor_block_loc2(fs, first_block, j)); 345 } 346 meta_blocks_count += fs->desc_blocks; 347 348 for (i = 0; i < fs->group_desc_count; i++) { 349 /* 350 * Mark the blocks used for the inode table 351 */ 352 if ((output_is_blk || 353 !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) && 354 ext2fs_inode_table_loc(fs, i)) { 355 unsigned int end = (unsigned) fs->inode_blocks_per_group; 356 /* skip unused blocks */ 357 if (!output_is_blk && 358 EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 359 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) 360 end -= (ext2fs_bg_itable_unused(fs, i) / 361 EXT2_INODES_PER_BLOCK(fs->super)); 362 for (j = 0, b = ext2fs_inode_table_loc(fs, i); 363 j < end; 364 j++, b++) { 365 ext2fs_mark_block_bitmap2(meta_block_map, b); 366 meta_blocks_count++; 367 } 368 } 369 370 /* 371 * Mark block used for the block bitmap 372 */ 373 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) && 374 ext2fs_block_bitmap_loc(fs, i)) { 375 ext2fs_mark_block_bitmap2(meta_block_map, 376 ext2fs_block_bitmap_loc(fs, i)); 377 meta_blocks_count++; 378 } 379 380 /* 381 * Mark block used for the inode bitmap 382 */ 383 if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) && 384 ext2fs_inode_bitmap_loc(fs, i)) { 385 ext2fs_mark_block_bitmap2(meta_block_map, 386 ext2fs_inode_bitmap_loc(fs, i)); 387 meta_blocks_count++; 388 } 389 } 390} 391 392/* 393 * This function returns 1 if the specified block is all zeros 394 */ 395static int check_zero_block(char *buf, int blocksize) 396{ 397 char *cp = buf; 398 int left = blocksize; 399 400 if (output_is_blk) 401 return 0; 402 while (left > 0) { 403 if (*cp++) 404 return 0; 405 left--; 406 } 407 return 1; 408} 409 410static void write_block(int fd, char *buf, int sparse_offset, 411 int blocksize, blk64_t block) 412{ 413 ext2_loff_t ret = 0; 414 415 if (sparse_offset) 416 ret = ext2fs_llseek(fd, sparse_offset, SEEK_CUR); 417 418 if (ret < 0) 419 lseek_error_and_exit(errno); 420 generic_write(fd, buf, blocksize, block); 421} 422 423static int name_id[256]; 424 425#define EXT4_MAX_REC_LEN ((1<<16)-1) 426 427static void scramble_dir_block(ext2_filsys fs, blk64_t blk, char *buf) 428{ 429 char *p, *end, *cp; 430 struct ext2_dir_entry_2 *dirent; 431 unsigned int rec_len; 432 int id, len; 433 434 end = buf + fs->blocksize; 435 for (p = buf; p < end-8; p += rec_len) { 436 dirent = (struct ext2_dir_entry_2 *) p; 437 rec_len = dirent->rec_len; 438#ifdef WORDS_BIGENDIAN 439 rec_len = ext2fs_swab16(rec_len); 440#endif 441 if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0) 442 rec_len = fs->blocksize; 443 else 444 rec_len = (rec_len & 65532) | ((rec_len & 3) << 16); 445#if 0 446 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len); 447#endif 448 if (rec_len < 8 || (rec_len % 4) || 449 (p+rec_len > end)) { 450 printf("Corrupt directory block %lu: " 451 "bad rec_len (%d)\n", (unsigned long) blk, 452 rec_len); 453 rec_len = end - p; 454 (void) ext2fs_set_rec_len(fs, rec_len, 455 (struct ext2_dir_entry *) dirent); 456#ifdef WORDS_BIGENDIAN 457 dirent->rec_len = ext2fs_swab16(dirent->rec_len); 458#endif 459 continue; 460 } 461 if (dirent->name_len + 8U > rec_len) { 462 printf("Corrupt directory block %lu: " 463 "bad name_len (%d)\n", (unsigned long) blk, 464 dirent->name_len); 465 dirent->name_len = rec_len - 8; 466 continue; 467 } 468 cp = p+8; 469 len = rec_len - dirent->name_len - 8; 470 if (len > 0) 471 memset(cp+dirent->name_len, 0, len); 472 if (dirent->name_len==1 && cp[0] == '.') 473 continue; 474 if (dirent->name_len==2 && cp[0] == '.' && cp[1] == '.') 475 continue; 476 477 memset(cp, 'A', dirent->name_len); 478 len = dirent->name_len; 479 id = name_id[len]++; 480 while ((len > 0) && (id > 0)) { 481 *cp += id % 26; 482 id = id / 26; 483 cp++; 484 len--; 485 } 486 } 487} 488 489static void output_meta_data_blocks(ext2_filsys fs, int fd) 490{ 491 errcode_t retval; 492 blk64_t blk; 493 char *buf, *zero_buf; 494 int sparse = 0; 495 496 retval = ext2fs_get_mem(fs->blocksize, &buf); 497 if (retval) { 498 com_err(program_name, retval, "while allocating buffer"); 499 exit(1); 500 } 501 retval = ext2fs_get_memzero(fs->blocksize, &zero_buf); 502 if (retval) { 503 com_err(program_name, retval, "while allocating buffer"); 504 exit(1); 505 } 506 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) { 507 if ((blk >= fs->super->s_first_data_block) && 508 ext2fs_test_block_bitmap2(meta_block_map, blk)) { 509 retval = io_channel_read_blk64(fs->io, blk, 1, buf); 510 if (retval) { 511 com_err(program_name, retval, 512 "error reading block %llu", blk); 513 } 514 if (scramble_block_map && 515 ext2fs_test_block_bitmap2(scramble_block_map, blk)) 516 scramble_dir_block(fs, blk, buf); 517 if ((fd != 1) && check_zero_block(buf, fs->blocksize)) 518 goto sparse_write; 519 write_block(fd, buf, sparse, fs->blocksize, blk); 520 sparse = 0; 521 } else { 522 sparse_write: 523 if (fd == 1) { 524 write_block(fd, zero_buf, 0, 525 fs->blocksize, blk); 526 continue; 527 } 528 sparse += fs->blocksize; 529 if (sparse > 1024*1024) { 530 write_block(fd, 0, 1024*1024, 0, 0); 531 sparse -= 1024*1024; 532 } 533 } 534 } 535#ifdef HAVE_FTRUNCATE64 536 if (sparse) { 537 ext2_loff_t offset = ext2fs_llseek(fd, sparse, SEEK_CUR); 538 539 if (offset < 0) 540 lseek_error_and_exit(errno); 541 if (ftruncate64(fd, offset) < 0) 542 write_block(fd, zero_buf, -1, 1, -1); 543 } 544#else 545 if (sparse) 546 write_block(fd, zero_buf, sparse-1, 1, -1); 547#endif 548 ext2fs_free_mem(&zero_buf); 549 ext2fs_free_mem(&buf); 550} 551 552static void init_l1_table(struct ext2_qcow2_image *image) 553{ 554 __u64 *l1_table; 555 errcode_t ret; 556 557 ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table); 558 if (ret) { 559 com_err(program_name, ret, "while allocating l1 table"); 560 exit(1); 561 } 562 563 image->l1_table = l1_table; 564} 565 566static void init_l2_cache(struct ext2_qcow2_image *image) 567{ 568 unsigned int count, i; 569 struct ext2_qcow2_l2_cache *cache; 570 struct ext2_qcow2_l2_table *table; 571 errcode_t ret; 572 573 ret = ext2fs_get_arrayzero(1, sizeof(struct ext2_qcow2_l2_cache), 574 &cache); 575 if (ret) 576 goto alloc_err; 577 578 count = (image->l1_size > L2_CACHE_PREALLOC) ? L2_CACHE_PREALLOC : 579 image->l1_size; 580 581 cache->count = count; 582 cache->free = count; 583 cache->next_offset = image->l2_offset; 584 585 for (i = 0; i < count; i++) { 586 ret = ext2fs_get_arrayzero(1, 587 sizeof(struct ext2_qcow2_l2_table), &table); 588 if (ret) 589 goto alloc_err; 590 591 ret = ext2fs_get_arrayzero(image->l2_size, 592 sizeof(__u64), &table->data); 593 if (ret) 594 goto alloc_err; 595 596 table->next = cache->free_head; 597 cache->free_head = table; 598 } 599 600 image->l2_cache = cache; 601 return; 602 603alloc_err: 604 com_err(program_name, ret, "while allocating l2 cache"); 605 exit(1); 606} 607 608static void put_l2_cache(struct ext2_qcow2_image *image) 609{ 610 struct ext2_qcow2_l2_cache *cache = image->l2_cache; 611 struct ext2_qcow2_l2_table *tmp, *table; 612 613 if (!cache) 614 return; 615 616 table = cache->free_head; 617 cache->free_head = NULL; 618again: 619 while (table) { 620 tmp = table; 621 table = table->next; 622 ext2fs_free_mem(&tmp->data); 623 ext2fs_free_mem(&tmp); 624 } 625 626 if (cache->free != cache->count) { 627 fprintf(stderr, "Warning: There are still tables in the " 628 "cache while putting the cache, data will " 629 "be lost so the image may not be valid.\n"); 630 table = cache->used_head; 631 cache->used_head = NULL; 632 goto again; 633 } 634 635 ext2fs_free_mem(&cache); 636} 637 638static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset) 639{ 640 struct ext2_qcow2_refcount *ref; 641 blk64_t table_clusters; 642 errcode_t ret; 643 644 ref = &(img->refcount); 645 646 /* 647 * One refcount block addresses 2048 clusters, one refcount table 648 * addresses cluster/sizeof(__u64) refcount blocks, and we need 649 * to address meta_blocks_count clusters + qcow2 metadata clusters 650 * in the worst case. 651 */ 652 table_clusters = meta_blocks_count + (table_offset >> 653 img->cluster_bits); 654 table_clusters >>= (img->cluster_bits + 6 - 1); 655 table_clusters = (table_clusters == 0) ? 1 : table_clusters; 656 657 ref->refcount_table_offset = table_offset; 658 ref->refcount_table_clusters = table_clusters; 659 ref->refcount_table_index = 0; 660 ref->refcount_block_index = 0; 661 662 /* Allocate refcount table */ 663 ret = ext2fs_get_arrayzero(ref->refcount_table_clusters, 664 img->cluster_size, &ref->refcount_table); 665 if (ret) 666 return ret; 667 668 /* Allocate refcount block */ 669 ret = ext2fs_get_arrayzero(1, img->cluster_size, &ref->refcount_block); 670 if (ret) 671 ext2fs_free_mem(&ref->refcount_table); 672 673 return ret; 674} 675 676static int initialize_qcow2_image(int fd, ext2_filsys fs, 677 struct ext2_qcow2_image *image) 678{ 679 struct ext2_qcow2_hdr *header; 680 blk64_t total_size, offset; 681 int shift, l2_bits, header_size, l1_size, ret; 682 int cluster_bits = get_bits_from_size(fs->blocksize); 683 struct ext2_super_block *sb = fs->super; 684 685 /* Allocate header */ 686 ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header); 687 if (ret) 688 return ret; 689 690 total_size = ext2fs_blocks_count(sb) << cluster_bits; 691 image->cluster_size = fs->blocksize; 692 image->l2_size = 1 << (cluster_bits - 3); 693 image->cluster_bits = cluster_bits; 694 image->fd = fd; 695 696 header->magic = ext2fs_cpu_to_be32(QCOW_MAGIC); 697 header->version = ext2fs_cpu_to_be32(QCOW_VERSION); 698 header->size = ext2fs_cpu_to_be64(total_size); 699 header->cluster_bits = ext2fs_cpu_to_be32(cluster_bits); 700 701 header_size = (sizeof(struct ext2_qcow2_hdr) + 7) & ~7; 702 offset = align_offset(header_size, image->cluster_size); 703 704 header->l1_table_offset = ext2fs_cpu_to_be64(offset); 705 image->l1_offset = offset; 706 707 l2_bits = cluster_bits - 3; 708 shift = cluster_bits + l2_bits; 709 l1_size = ((total_size + (1LL << shift) - 1) >> shift); 710 header->l1_size = ext2fs_cpu_to_be32(l1_size); 711 image->l1_size = l1_size; 712 713 /* Make space for L1 table */ 714 offset += align_offset(l1_size * sizeof(blk64_t), image->cluster_size); 715 716 /* Initialize refcounting */ 717 ret = init_refcount(image, offset); 718 if (ret) { 719 ext2fs_free_mem(&header); 720 return ret; 721 } 722 header->refcount_table_offset = ext2fs_cpu_to_be64(offset); 723 header->refcount_table_clusters = 724 ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters); 725 offset += image->cluster_size; 726 offset += image->refcount.refcount_table_clusters << 727 image->cluster_bits; 728 729 /* Make space for L2 tables */ 730 image->l2_offset = offset; 731 offset += image->cluster_size; 732 733 /* Make space for first refcount block */ 734 image->refcount.refcount_block_offset = offset; 735 736 image->hdr = header; 737 /* Initialize l1 and l2 tables */ 738 init_l1_table(image); 739 init_l2_cache(image); 740 741 return 0; 742} 743 744static void free_qcow2_image(struct ext2_qcow2_image *img) 745{ 746 if (!img) 747 return; 748 749 if (img->hdr) 750 ext2fs_free_mem(&img->hdr); 751 752 if (img->l1_table) 753 ext2fs_free_mem(&img->l1_table); 754 755 if (img->refcount.refcount_table) 756 ext2fs_free_mem(&img->refcount.refcount_table); 757 if (img->refcount.refcount_block) 758 ext2fs_free_mem(&img->refcount.refcount_block); 759 760 put_l2_cache(img); 761 762 ext2fs_free_mem(&img); 763} 764 765/** 766 * Put table from used list (used_head) into free list (free_head). 767 * l2_table is used to return pointer to the next used table (used_head). 768 */ 769static void put_used_table(struct ext2_qcow2_image *img, 770 struct ext2_qcow2_l2_table **l2_table) 771{ 772 struct ext2_qcow2_l2_cache *cache = img->l2_cache; 773 struct ext2_qcow2_l2_table *table; 774 775 table = cache->used_head; 776 cache->used_head = table->next; 777 778 assert(table); 779 if (!table->next) 780 cache->used_tail = NULL; 781 782 /* Clean the table for case we will need to use it again */ 783 memset(table->data, 0, img->cluster_size); 784 table->next = cache->free_head; 785 cache->free_head = table; 786 787 cache->free++; 788 789 *l2_table = cache->used_head; 790} 791 792static void flush_l2_cache(struct ext2_qcow2_image *image) 793{ 794 blk64_t seek = 0; 795 ext2_loff_t offset; 796 struct ext2_qcow2_l2_cache *cache = image->l2_cache; 797 struct ext2_qcow2_l2_table *table = cache->used_head; 798 int fd = image->fd; 799 800 /* Store current position */ 801 if ((offset = ext2fs_llseek(fd, 0, SEEK_CUR)) < 0) 802 lseek_error_and_exit(errno); 803 804 assert(table); 805 while (cache->free < cache->count) { 806 if (seek != table->offset) { 807 if (ext2fs_llseek(fd, table->offset, SEEK_SET) < 0) 808 lseek_error_and_exit(errno); 809 seek = table->offset; 810 } 811 812 generic_write(fd, (char *)table->data, image->cluster_size , 0); 813 put_used_table(image, &table); 814 seek += image->cluster_size; 815 } 816 817 /* Restore previous position */ 818 if (ext2fs_llseek(fd, offset, SEEK_SET) < 0) 819 lseek_error_and_exit(errno); 820} 821 822/** 823 * Get first free table (from free_head) and put it into tail of used list 824 * (to used_tail). 825 * l2_table is used to return pointer to moved table. 826 * Returns 1 if the cache is full, 0 otherwise. 827 */ 828static void get_free_table(struct ext2_qcow2_image *image, 829 struct ext2_qcow2_l2_table **l2_table) 830{ 831 struct ext2_qcow2_l2_table *table; 832 struct ext2_qcow2_l2_cache *cache = image->l2_cache; 833 834 if (0 == cache->free) 835 flush_l2_cache(image); 836 837 table = cache->free_head; 838 assert(table); 839 cache->free_head = table->next; 840 841 if (cache->used_tail) 842 cache->used_tail->next = table; 843 else 844 /* First item in the used list */ 845 cache->used_head = table; 846 847 cache->used_tail = table; 848 cache->free--; 849 850 *l2_table = table; 851} 852 853static int add_l2_item(struct ext2_qcow2_image *img, blk64_t blk, 854 blk64_t data, blk64_t next) 855{ 856 struct ext2_qcow2_l2_cache *cache = img->l2_cache; 857 struct ext2_qcow2_l2_table *table = cache->used_tail; 858 blk64_t l1_index = blk / img->l2_size; 859 blk64_t l2_index = blk & (img->l2_size - 1); 860 int ret = 0; 861 862 /* 863 * Need to create new table if it does not exist, 864 * or if it is full 865 */ 866 if (!table || (table->l1_index != l1_index)) { 867 get_free_table(img, &table); 868 table->l1_index = l1_index; 869 table->offset = cache->next_offset; 870 cache->next_offset = next; 871 img->l1_table[l1_index] = 872 ext2fs_cpu_to_be64(table->offset | QCOW_OFLAG_COPIED); 873 ret++; 874 } 875 876 table->data[l2_index] = ext2fs_cpu_to_be64(data | QCOW_OFLAG_COPIED); 877 return ret; 878} 879 880static int update_refcount(int fd, struct ext2_qcow2_image *img, 881 blk64_t offset, blk64_t rfblk_pos) 882{ 883 struct ext2_qcow2_refcount *ref; 884 __u32 table_index; 885 int ret = 0; 886 887 ref = &(img->refcount); 888 table_index = offset >> (2 * img->cluster_bits - 1); 889 890 /* 891 * Need to create new refcount block when the offset addresses 892 * another item in the refcount table 893 */ 894 if (table_index != ref->refcount_table_index) { 895 896 if (ext2fs_llseek(fd, ref->refcount_block_offset, SEEK_SET) < 0) 897 lseek_error_and_exit(errno); 898 899 generic_write(fd, (char *)ref->refcount_block, 900 img->cluster_size, 0); 901 memset(ref->refcount_block, 0, img->cluster_size); 902 903 ref->refcount_table[ref->refcount_table_index] = 904 ext2fs_cpu_to_be64(ref->refcount_block_offset); 905 ref->refcount_block_offset = rfblk_pos; 906 ref->refcount_block_index = 0; 907 ref->refcount_table_index = table_index; 908 ret++; 909 } 910 911 /* 912 * We are relying on the fact that we are creating the qcow2 913 * image sequentially, hence we will always allocate refcount 914 * block items sequentialy. 915 */ 916 ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1); 917 ref->refcount_block_index++; 918 return ret; 919} 920 921static int sync_refcount(int fd, struct ext2_qcow2_image *img) 922{ 923 struct ext2_qcow2_refcount *ref; 924 925 ref = &(img->refcount); 926 927 ref->refcount_table[ref->refcount_table_index] = 928 ext2fs_cpu_to_be64(ref->refcount_block_offset); 929 if (ext2fs_llseek(fd, ref->refcount_table_offset, SEEK_SET) < 0) 930 lseek_error_and_exit(errno); 931 generic_write(fd, (char *)ref->refcount_table, 932 ref->refcount_table_clusters << img->cluster_bits, 0); 933 934 if (ext2fs_llseek(fd, ref->refcount_block_offset, SEEK_SET) < 0) 935 lseek_error_and_exit(errno); 936 generic_write(fd, (char *)ref->refcount_block, img->cluster_size, 0); 937 return 0; 938} 939 940static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd) 941{ 942 errcode_t retval; 943 blk64_t blk, offset, size, end; 944 char *buf; 945 struct ext2_qcow2_image *img; 946 unsigned int header_size; 947 948 /* allocate struct ext2_qcow2_image */ 949 retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img); 950 if (retval) { 951 com_err(program_name, retval, 952 "while allocating ext2_qcow2_image"); 953 exit(1); 954 } 955 956 retval = initialize_qcow2_image(fd, fs, img); 957 if (retval) { 958 com_err(program_name, retval, 959 "while initializing ext2_qcow2_image"); 960 exit(1); 961 } 962 header_size = align_offset(sizeof(struct ext2_qcow2_hdr), 963 img->cluster_size); 964 write_header(fd, img->hdr, sizeof(struct ext2_qcow2_hdr), header_size); 965 966 /* Refcount all qcow2 related metadata up to refcount_block_offset */ 967 end = img->refcount.refcount_block_offset; 968 if (ext2fs_llseek(fd, end, SEEK_SET) < 0) 969 lseek_error_and_exit(errno); 970 blk = end + img->cluster_size; 971 for (offset = 0; offset <= end; offset += img->cluster_size) { 972 if (update_refcount(fd, img, offset, blk)) { 973 blk += img->cluster_size; 974 /* 975 * If we create new refcount block, we need to refcount 976 * it as well. 977 */ 978 end += img->cluster_size; 979 } 980 } 981 if (ext2fs_llseek(fd, offset, SEEK_SET) < 0) 982 lseek_error_and_exit(errno); 983 984 retval = ext2fs_get_mem(fs->blocksize, &buf); 985 if (retval) { 986 com_err(program_name, retval, "while allocating buffer"); 987 exit(1); 988 } 989 /* Write qcow2 data blocks */ 990 for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) { 991 if ((blk >= fs->super->s_first_data_block) && 992 ext2fs_test_block_bitmap2(meta_block_map, blk)) { 993 retval = io_channel_read_blk64(fs->io, blk, 1, buf); 994 if (retval) { 995 com_err(program_name, retval, 996 "error reading block %llu", blk); 997 continue; 998 } 999 if (scramble_block_map && 1000 ext2fs_test_block_bitmap2(scramble_block_map, blk)) 1001 scramble_dir_block(fs, blk, buf); 1002 if (check_zero_block(buf, fs->blocksize)) 1003 continue; 1004 1005 if (update_refcount(fd, img, offset, offset)) { 1006 /* Make space for another refcount block */ 1007 offset += img->cluster_size; 1008 if (ext2fs_llseek(fd, offset, SEEK_SET) < 0) 1009 lseek_error_and_exit(errno); 1010 /* 1011 * We have created the new refcount block, this 1012 * means that we need to refcount it as well. 1013 * So the previous update_refcount refcounted 1014 * the block itself and now we are going to 1015 * create refcount for data. New refcount 1016 * block should not be created! 1017 */ 1018 if (update_refcount(fd, img, offset, offset)) { 1019 fprintf(stderr, "Programming error: " 1020 "multiple sequential refcount " 1021 "blocks created!\n"); 1022 exit(1); 1023 } 1024 } 1025 1026 generic_write(fd, buf, fs->blocksize, 0); 1027 1028 if (add_l2_item(img, blk, offset, 1029 offset + img->cluster_size)) { 1030 offset += img->cluster_size; 1031 if (update_refcount(fd, img, offset, 1032 offset + img->cluster_size)) { 1033 offset += img->cluster_size; 1034 if (update_refcount(fd, img, offset, 1035 offset)) { 1036 fprintf(stderr, 1037 "Programming error: multiple sequential refcount " 1038 "blocks created!\n"); 1039 exit(1); 1040 } 1041 } 1042 offset += img->cluster_size; 1043 if (ext2fs_llseek(fd, offset, SEEK_SET) < 0) 1044 lseek_error_and_exit(errno); 1045 continue; 1046 } 1047 1048 offset += img->cluster_size; 1049 } 1050 } 1051 update_refcount(fd, img, offset, offset); 1052 flush_l2_cache(img); 1053 sync_refcount(fd, img); 1054 1055 /* Write l1_table*/ 1056 if (ext2fs_llseek(fd, img->l1_offset, SEEK_SET) < 0) 1057 lseek_error_and_exit(errno); 1058 size = img->l1_size * sizeof(__u64); 1059 generic_write(fd, (char *)img->l1_table, size, 0); 1060 1061 ext2fs_free_mem(&buf); 1062 free_qcow2_image(img); 1063} 1064 1065static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) 1066{ 1067 struct process_block_struct pb; 1068 struct ext2_inode inode; 1069 ext2_inode_scan scan; 1070 ext2_ino_t ino; 1071 errcode_t retval; 1072 char * block_buf; 1073 1074 meta_blocks_count = 0; 1075 retval = ext2fs_allocate_block_bitmap(fs, "in-use block map", 1076 &meta_block_map); 1077 if (retval) { 1078 com_err(program_name, retval, "while allocating block bitmap"); 1079 exit(1); 1080 } 1081 1082 if (flags & E2IMAGE_SCRAMBLE_FLAG) { 1083 retval = ext2fs_allocate_block_bitmap(fs, "scramble block map", 1084 &scramble_block_map); 1085 if (retval) { 1086 com_err(program_name, retval, 1087 "while allocating scramble block bitmap"); 1088 exit(1); 1089 } 1090 } 1091 1092 mark_table_blocks(fs); 1093 1094 retval = ext2fs_open_inode_scan(fs, 0, &scan); 1095 if (retval) { 1096 com_err(program_name, retval,"%s", 1097 _("while opening inode scan")); 1098 exit(1); 1099 } 1100 1101 retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf); 1102 if (retval) { 1103 com_err(program_name, 0, "%s", 1104 _("Can't allocate block buffer")); 1105 exit(1); 1106 } 1107 1108 use_inode_shortcuts(fs, 1); 1109 stashed_inode = &inode; 1110 while (1) { 1111 retval = ext2fs_get_next_inode(scan, &ino, &inode); 1112 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) 1113 continue; 1114 if (retval) { 1115 com_err(program_name, retval, "%s", 1116 _("while getting next inode")); 1117 exit(1); 1118 } 1119 if (ino == 0) 1120 break; 1121 if (!inode.i_links_count) 1122 continue; 1123 if (ext2fs_file_acl_block(fs, &inode)) { 1124 ext2fs_mark_block_bitmap2(meta_block_map, 1125 ext2fs_file_acl_block(fs, &inode)); 1126 meta_blocks_count++; 1127 } 1128 if (!ext2fs_inode_has_valid_blocks2(fs, &inode)) 1129 continue; 1130 1131 stashed_ino = ino; 1132 pb.ino = ino; 1133 pb.is_dir = LINUX_S_ISDIR(inode.i_mode); 1134 if (LINUX_S_ISDIR(inode.i_mode) || 1135 (LINUX_S_ISLNK(inode.i_mode) && 1136 ext2fs_inode_has_valid_blocks2(fs, &inode)) || 1137 ino == fs->super->s_journal_inum) { 1138 retval = ext2fs_block_iterate3(fs, ino, 1139 BLOCK_FLAG_READ_ONLY, block_buf, 1140 process_dir_block, &pb); 1141 if (retval) { 1142 com_err(program_name, retval, 1143 "while iterating over inode %u", 1144 ino); 1145 exit(1); 1146 } 1147 } else { 1148 if ((inode.i_flags & EXT4_EXTENTS_FL) || 1149 inode.i_block[EXT2_IND_BLOCK] || 1150 inode.i_block[EXT2_DIND_BLOCK] || 1151 inode.i_block[EXT2_TIND_BLOCK] || all_data) { 1152 retval = ext2fs_block_iterate3(fs, 1153 ino, BLOCK_FLAG_READ_ONLY, block_buf, 1154 process_file_block, &pb); 1155 if (retval) { 1156 com_err(program_name, retval, 1157 "while iterating over inode %u", ino); 1158 exit(1); 1159 } 1160 } 1161 } 1162 } 1163 use_inode_shortcuts(fs, 0); 1164 1165 if (type & E2IMAGE_QCOW2) 1166 output_qcow2_meta_data_blocks(fs, fd); 1167 else 1168 output_meta_data_blocks(fs, fd); 1169 1170 ext2fs_free_mem(&block_buf); 1171 ext2fs_close_inode_scan(scan); 1172 ext2fs_free_block_bitmap(meta_block_map); 1173 if (type & E2IMAGE_SCRAMBLE_FLAG) 1174 ext2fs_free_block_bitmap(scramble_block_map); 1175} 1176 1177static void install_image(char *device, char *image_fn, int type) 1178{ 1179 errcode_t retval; 1180 ext2_filsys fs; 1181 int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS; 1182 int fd = 0; 1183 io_manager io_ptr; 1184 io_channel io; 1185 1186 if (type) { 1187 com_err(program_name, 0, "Raw and qcow2 images cannot" 1188 "be installed"); 1189 exit(1); 1190 } 1191 1192#ifdef CONFIG_TESTIO_DEBUG 1193 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) { 1194 io_ptr = test_io_manager; 1195 test_io_backing_manager = unix_io_manager; 1196 } else 1197#endif 1198 io_ptr = unix_io_manager; 1199 1200 retval = ext2fs_open (image_fn, open_flag, 0, 0, 1201 io_ptr, &fs); 1202 if (retval) { 1203 com_err (program_name, retval, _("while trying to open %s"), 1204 image_fn); 1205 exit(1); 1206 } 1207 1208 retval = ext2fs_read_bitmaps (fs); 1209 if (retval) { 1210 com_err(program_name, retval, "error reading bitmaps"); 1211 exit(1); 1212 } 1213 1214 fd = ext2fs_open_file(image_fn, O_RDONLY, 0); 1215 if (fd < 0) { 1216 perror(image_fn); 1217 exit(1); 1218 } 1219 1220 retval = io_ptr->open(device, IO_FLAG_RW, &io); 1221 if (retval) { 1222 com_err(device, 0, "while opening device file"); 1223 exit(1); 1224 } 1225 1226 ext2fs_rewrite_to_io(fs, io); 1227 1228 if (ext2fs_llseek(fd, fs->image_header->offset_inode, SEEK_SET) < 0) { 1229 perror("ext2fs_llseek"); 1230 exit(1); 1231 } 1232 1233 retval = ext2fs_image_inode_read(fs, fd, 0); 1234 if (retval) { 1235 com_err(image_fn, 0, "while restoring the image table"); 1236 exit(1); 1237 } 1238 1239 close(fd); 1240 ext2fs_close (fs); 1241} 1242 1243static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name) 1244{ 1245 1246 *fd = ext2fs_open_file(name, O_RDONLY, 0600); 1247 if (*fd < 0) 1248 return NULL; 1249 1250 return qcow2_read_header(*fd); 1251} 1252 1253int main (int argc, char ** argv) 1254{ 1255 int c; 1256 errcode_t retval; 1257 ext2_filsys fs; 1258 char *image_fn; 1259 struct ext2_qcow2_hdr *header = NULL; 1260 int open_flag = EXT2_FLAG_64BITS; 1261 int img_type = 0; 1262 int flags = 0; 1263 int mount_flags = 0; 1264 int qcow2_fd = 0; 1265 int fd = 0; 1266 int ret = 0; 1267 int ignore_rw_mount = 0; 1268 struct stat st; 1269 1270#ifdef ENABLE_NLS 1271 setlocale(LC_MESSAGES, ""); 1272 setlocale(LC_CTYPE, ""); 1273 bindtextdomain(NLS_CAT_NAME, LOCALEDIR); 1274 textdomain(NLS_CAT_NAME); 1275 set_com_err_gettext(gettext); 1276#endif 1277 fprintf (stderr, "e2image %s (%s)\n", E2FSPROGS_VERSION, 1278 E2FSPROGS_DATE); 1279 if (argc && *argv) 1280 program_name = *argv; 1281 add_error_table(&et_ext2_error_table); 1282 while ((c = getopt(argc, argv, "rsIQafo:O:")) != EOF) 1283 switch (c) { 1284 case 'I': 1285 flags |= E2IMAGE_INSTALL_FLAG; 1286 break; 1287 case 'Q': 1288 if (img_type) 1289 usage(); 1290 img_type |= E2IMAGE_QCOW2; 1291 break; 1292 case 'r': 1293 if (img_type) 1294 usage(); 1295 img_type |= E2IMAGE_RAW; 1296 break; 1297 case 's': 1298 flags |= E2IMAGE_SCRAMBLE_FLAG; 1299 break; 1300 case 'a': 1301 all_data = 1; 1302 break; 1303 case 'f': 1304 ignore_rw_mount = 1; 1305 break; 1306 case 'o': 1307 source_offset = strtoull(optarg, NULL, 0); 1308 break; 1309 case 'O': 1310 dest_offset = strtoull(optarg, NULL, 0); 1311 break; 1312 default: 1313 usage(); 1314 } 1315 if (optind != argc - 2 ) 1316 usage(); 1317 1318 if (all_data && !img_type) { 1319 com_err(program_name, 0, "-a option can only be used " 1320 "with raw or QCOW2 images."); 1321 exit(1); 1322 } 1323 if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) { 1324 com_err(program_name, 0, 1325 "Offsets are only allowed with raw images."); 1326 exit(1); 1327 } 1328 device_name = argv[optind]; 1329 image_fn = argv[optind+1]; 1330 1331 retval = ext2fs_check_if_mounted(device_name, &mount_flags); 1332 if (retval) { 1333 com_err(program_name, retval, "checking if mounted"); 1334 exit(1); 1335 } 1336 1337 if (img_type && !ignore_rw_mount && 1338 (mount_flags & EXT2_MF_MOUNTED) && 1339 !(mount_flags & EXT2_MF_READONLY)) { 1340 fprintf(stderr, "\nRunning e2image on a R/W mounted " 1341 "filesystem can result in an\n" 1342 "inconsistent image which will not be useful " 1343 "for debugging purposes.\n" 1344 "Use -f option if you really want to do that.\n"); 1345 exit(1); 1346 } 1347 1348 if (flags & E2IMAGE_INSTALL_FLAG) { 1349 install_image(device_name, image_fn, img_type); 1350 exit (0); 1351 } 1352 1353 if (img_type & E2IMAGE_RAW) { 1354 header = check_qcow2_image(&qcow2_fd, device_name); 1355 if (header) { 1356 flags |= E2IMAGE_IS_QCOW2_FLAG; 1357 goto skip_device; 1358 } 1359 } 1360 char *options; 1361 asprintf (&options, "offset=%llu", source_offset); 1362 retval = ext2fs_open2 (device_name, options, open_flag, 0, 0, 1363 unix_io_manager, &fs); 1364 free (options); 1365 if (retval) { 1366 com_err (program_name, retval, _("while trying to open %s"), 1367 device_name); 1368 fputs(_("Couldn't find valid filesystem superblock.\n"), stdout); 1369 exit(1); 1370 } 1371 1372skip_device: 1373 if (strcmp(image_fn, "-") == 0) 1374 fd = 1; 1375 else { 1376 fd = ext2fs_open_file(image_fn, O_CREAT|O_TRUNC|O_WRONLY, 0600); 1377 if (fd < 0) { 1378 com_err(program_name, errno, 1379 _("while trying to open %s"), argv[optind+1]); 1380 exit(1); 1381 } 1382 } 1383 if (dest_offset) 1384 if (ext2fs_llseek (fd, dest_offset, SEEK_SET) < 0) { 1385 perror("ext2fs_llseek"); 1386 exit(1); 1387 } 1388 1389 if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) { 1390 com_err(program_name, 0, "QCOW2 image can not be written to " 1391 "the stdout!\n"); 1392 exit(1); 1393 } 1394 if (fd != 1) { 1395 if (fstat(fd, &st)) { 1396 com_err(program_name, 0, "Can not stat output\n"); 1397 exit(1); 1398 } 1399 if (S_ISBLK(st.st_mode)) 1400 output_is_blk = 1; 1401 } 1402 if (flags & E2IMAGE_IS_QCOW2_FLAG) { 1403 ret = qcow2_write_raw_image(qcow2_fd, fd, header); 1404 if (ret) { 1405 if (ret == -QCOW_COMPRESSED) 1406 fprintf(stderr, "Image (%s) is compressed\n", 1407 image_fn); 1408 if (ret == -QCOW_ENCRYPTED) 1409 fprintf(stderr, "Image (%s) is encrypted\n", 1410 image_fn); 1411 com_err(program_name, ret, 1412 _("while trying to convert qcow2 image" 1413 " (%s) into raw image (%s)"), 1414 device_name, image_fn); 1415 } 1416 goto out; 1417 } 1418 1419 1420 if (img_type) 1421 write_raw_image_file(fs, fd, img_type, flags); 1422 else 1423 write_image_file(fs, fd); 1424 1425 ext2fs_close (fs); 1426out: 1427 if (header) 1428 free(header); 1429 if (qcow2_fd) 1430 close(qcow2_fd); 1431 remove_error_table(&et_ext2_error_table); 1432 return ret; 1433} 1434