/* 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);
}
예제 #2
0
파일: path.c 프로젝트: Dazdin9o/DECAF
static char*
substring_dup( const char*  start, const char*  end )
{
    int    len    = end - start;
    char*  result = android_alloc(len+1);
    memcpy(result, start, len);
    result[len] = 0;
    return result;
}
/* Loads a single boot property from a snapshot file
 */
static int
boot_property_load_property( QEMUFile  *f )
{
    int ret;

    /* load key */
    uint32_t key_buf_len = qemu_get_be32(f);
    char* key = android_alloc(key_buf_len);
    if ((ret = qemu_get_buffer(f, (uint8_t*)key, key_buf_len) != (int)key_buf_len)) {
        D("%s: key load failed: expected %d bytes, got %d\n",
          __FUNCTION__, key_buf_len, ret);
        goto fail_key;
    }

    /* load value */
    uint32_t value_buf_len = qemu_get_be32(f);
    char* value = android_alloc(value_buf_len);
    if ((ret = qemu_get_buffer(f, (uint8_t*)value, value_buf_len) != (int)value_buf_len)) {
        D("%s: value load failed: expected %d bytes, got %d\n",
          __FUNCTION__, value_buf_len, ret);
        goto fail_value;
    }

    /* add the property */
    ret = boot_property_add2(key, key_buf_len - 1, value, value_buf_len - 1);
    if (ret < 0) {
        D("%s: load failed: cannot add boot property (details follow)\n",
          __FUNCTION__);
        boot_property_raise_warning(ret, key, key_buf_len - 1, value, value_buf_len - 1);
        goto fail_value;
    }

    return 0;

    /* in case of errors, clean up before return */
    fail_value:
        AFREE(value);
    fail_key:
        AFREE(key);
        return -EIO;
}
예제 #4
0
void*
_android_array_alloc( size_t  itemSize, size_t  count )
{
#if ACONFIG_USE_ASSERT
    size_t  maxSize;

    if (itemSize == 0)
        AASSERT_FAIL("item size is 0\n");

    maxSize = (~(size_t)0) / itemSize;
    if (count > maxSize)
        AASSERT_FAIL("allocation too large (%d > %d)\n", count, maxSize);
#endif
    return android_alloc(itemSize * count);
}
static BootProperty*
boot_property_alloc( const char*  name,  int  namelen,
                     const char*  value, int  valuelen )
{
    int            length = namelen + 1 + valuelen;
    BootProperty*  prop = android_alloc( sizeof(*prop) + length + 1 );
    char*          p;

    prop->next     = NULL;
    prop->property = p = (char*)(prop + 1);
    prop->length   = length;

    memcpy( p, name, namelen );
    p += namelen;
    *p++ = '=';
    memcpy( p, value, valuelen );
    p += valuelen;
    *p = '\0';

    return prop;
}
static SnapshotInfo*
snapshot_info_alloc()
{
    return android_alloc(sizeof(SnapshotInfo));
}