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