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