Monday, December 23, 2013

How to change path to backing file in qcow2

Standard utility cannot do this. Take C and qcow2 image format doc and write something like
#define ntohll(x) (((uint64_t)(ntohl((uint32_t)((x << 32) >> 32))) << 32) | ntohl(((uint32_t)(x >> 32))))


/* change filename in qcow2 */
int backing_file_patch(const char *in_file, const char *new_backing_file) {
    
    int f;
    uint64_t backing_file_offset;
    uint32_t backing_file_size;
        
    if ((f = open(in_file, O_RDWR)) == -1) {
        perror("open");
        goto error;
    }
    
    if (lseek(f, 8, SEEK_SET) == (off_t)-1) {
        perror("lseek");
        goto error;
    }

    if (read(f, &backing_file_offset, sizeof(backing_file_offset)) == -1) {
        perror("read");
        goto error;
    }
    backing_file_offset = ntohll(backing_file_offset);
    
    backing_file_size = strlen(new_backing_file);
    backing_file_size = htonl(backing_file_size);
    
    /* update backing_file_size */
    if (write(f, &backing_file_size, sizeof(backing_file_size)) == -1) {
        perror("write");
        goto error;
    }
    
    /* update path */
    if (lseek(f, backing_file_offset, SEEK_SET) == (off_t)-1) {
        perror("lseek");
        goto error;
    }
    if (write(f, new_backing_file, strlen(new_backing_file)) == -1) {
        perror("write");
        goto error;
    }
        
    close(f);
    return 0;
    
error:
    close(f);
    return 1;
}
To test this
/usr/sbin/xm block-attach 0 tap:qcow2:/home/test/vm_drive_C_snapshot.qcow2 /dev/xvda w 0
/bin/ntfs-3g -o dev_offset=7340032,rw,noatime,force,entry_timeout=60000,negative_timeout=60000,attr_timeout=60000,ac_attr_timeout=60000 /dev/xvda exposed
Cleanup
/bin/umount exposed
/usr/sbin/xm block-detach 0 51712

No comments:

Post a Comment