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