Esempio n. 1
0
static int extend(int input)
{
	struct pstore_header *header;
	unsigned long ndx;
	off_t f_end;

	header = pstore_header_read(input);

	seek_or_die(input, 0, SEEK_END);

	for (ndx = 0; ndx < header->nr_tables; ndx++) {
		struct pstore_table *table = header->tables[ndx];

		if (pstore_table_matches(table, table_ref)) {
			if (extend_table(table, input) < 0)
				return -1;
		}
	}

	f_end = seek_or_die(input, 0, SEEK_CUR);

	/*
	 * Write out the header again because offsets to last extents changed.
	 */
	seek_or_die(input, 0, SEEK_SET);
	if (pstore_header_write(header, input) < 0)
		die("pstore_header_write");

	pstore_header_delete(header);

	seek_or_die(input, f_end, SEEK_SET);

	return 0;
}
/* Reads a snapshot record from a qcow2-formatted file.
 *
 * The function assumes the file position of 'fd' points to the beginning of a
 * QcowSnapshotHeader record. When the call returns, the file position of fd is
 * at the place where the next QcowSnapshotHeader should start, if there is one.
 *
 * C.f. QCowSnapshotHeader in block/qcow2-snapshot.c for the complete layout of
 * the header.
 */
static void
snapshot_info_read( int fd, SnapshotInfo* info )
{
    uint64_t start_offset = seek_or_die(fd, 0, SEEK_CUR);

    uint32_t extra_data_size;
    uint16_t id_str_size, name_size;

    /* read fixed-length fields */
    seek_or_die(fd, 12, SEEK_CUR);  /* skip l1 info */
    read_or_die(fd, &id_str_size,         sizeof(id_str_size));
    read_or_die(fd, &name_size,           sizeof(name_size));
    read_or_die(fd, &info->date_sec,      sizeof(info->date_sec));
    read_or_die(fd, &info->date_nsec,     sizeof(info->date_nsec));
    read_or_die(fd, &info->vm_clock_nsec, sizeof(info->vm_clock_nsec));
    read_or_die(fd, &info->vm_state_size, sizeof(info->vm_state_size));
    read_or_die(fd, &extra_data_size,     sizeof(extra_data_size));

    /* convert to host endianness */
    be16_to_cpus(&id_str_size);
    be16_to_cpus(&name_size);
    be32_to_cpus(&info->date_sec);
    be32_to_cpus(&info->date_nsec);
    be64_to_cpus(&info->vm_clock_nsec);
    be32_to_cpus(&info->vm_state_size);
    be32_to_cpus(&extra_data_size);
    be32_to_cpus(&extra_data_size);

    /* read variable-length buffers*/
    info->id_str = android_alloc(id_str_size + 1); // +1: manual null-termination
    info->name   = android_alloc(name_size + 1);
    seek_or_die(fd, extra_data_size, SEEK_CUR);  /* skip extra data */
    read_or_die(fd, info->id_str, id_str_size);
    read_or_die(fd, info->name, name_size);

    info->id_str[id_str_size] = '\0';
    info->name[name_size] = '\0';

    /* headers are 8 byte aligned, ceil to nearest multiple of 8 */
    uint64_t end_offset   = seek_or_die(fd, 0, SEEK_CUR);
    uint32_t total_size   = end_offset - start_offset;
    uint32_t aligned_size = ((total_size - 1) / 8 + 1) * 8;

    /* skip to start of next record */
    seek_or_die(fd, start_offset + aligned_size, SEEK_SET);
}
Esempio n. 3
0
static int extend_column(struct pstore_column *column, int input)
{
	struct pstore_extent *extent;
	off_t offset;

	offset = seek_or_die(input, 0, SEEK_CUR);

	extent = pstore_extent_read(column, column->last_extent, input);

	column->prev_extent = extent;
	column->extent = pstore_extent_new(column, PSTORE_COMP_NONE);

	seek_or_die(input, offset, SEEK_SET);

	if (pstore_column_preallocate(column, input, extent_len) < 0)
		return -1;

	if (pstore_extent_write_metadata(column->extent, PSTORE_LAST_EXTENT, input) < 0)
		return -1;

	return 0;
}
Esempio n. 4
0
int cmd_extend(int argc, char *argv[])
{
	int input;
	off_t f_size;

	if (argc < 3)
		usage();

	parse_args(argc - 1, argv + 1);

	input = open(input_file, O_RDWR);
	if (input < 0)
		die("Failed to open input file '%s': %s", input_file, strerror(errno));

	f_size = seek_or_die(input, 0, SEEK_END);

	if (posix_fallocate(input, f_size, extent_len) != 0)
		die("posix_fallocate");

	seek_or_die(input, 0, SEEK_SET);

	if (extend(input) < 0)
		die("extend failed");

	f_size = seek_or_die(input, 0, SEEK_CUR);

	if (ftruncate(input, f_size) != 0)
		die("ftruncate");

	if (fsync(input) < 0)
		die("fsync");

	if (close(input) < 0)
		die("close");

	return 0;
}