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