// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Exported interface to basic qcow functionality to be used from C.

use libc::{EINVAL, EIO, ENOSYS};
use std::ffi::CStr;
use std::fs::OpenOptions;
use std::os::raw::{c_char, c_int};

use disk::{DiskFile, ImageType, QcowFile};
use sys_util::{flock, FlockOperation};

#[no_mangle]
pub unsafe extern "C" fn create_qcow_with_size(path: *const c_char, virtual_size: u64) -> c_int {
    // NULL pointers are checked, but this will access any other invalid pointer passed from C
    // code. It's the caller's responsibility to pass a valid pointer.
    if path.is_null() {
        return -EINVAL;
    }
    let c_str = CStr::from_ptr(path);
    let file_path = match c_str.to_str() {
        Ok(s) => s,
        Err(_) => return -EINVAL,
    };

    let file = match OpenOptions::new()
        .create(true)
        .read(true)
        .write(true)
        .open(file_path)
    {
        Ok(f) => f,
        Err(_) => return -1,
    };

    match QcowFile::new(file, virtual_size) {
        Ok(_) => 0,
        Err(_) => -1,
    }
}

#[no_mangle]
pub unsafe extern "C" fn expand_disk_image(path: *const c_char, virtual_size: u64) -> c_int {
    // NULL pointers are checked, but this will access any other invalid pointer passed from C
    // code. It's the caller's responsibility to pass a valid pointer.
    if path.is_null() {
        return -EINVAL;
    }
    let c_str = CStr::from_ptr(path);
    let file_path = match c_str.to_str() {
        Ok(s) => s,
        Err(_) => return -EINVAL,
    };

    let raw_image = match OpenOptions::new().read(true).write(true).open(file_path) {
        Ok(f) => f,
        Err(_) => return -EIO,
    };

    // Lock the disk image to prevent other processes from using it.
    if let Err(_) = flock(&raw_image, FlockOperation::LockExclusive, true) {
        return -EIO;
    }

    let image_type = match disk::detect_image_type(&raw_image) {
        Ok(t) => t,
        Err(_) => return -EINVAL,
    };

    let disk_image: Box<dyn DiskFile> = match image_type {
        ImageType::Raw => Box::new(raw_image),
        ImageType::Qcow2 => match QcowFile::from(raw_image) {
            Ok(f) => Box::new(f),
            Err(_) => return -EINVAL,
        },
        _ => return -EINVAL,
    };

    // For safety against accidentally shrinking the disk image due to a
    // programming error elsewhere, verify that the new size is larger than
    // the current size.  This is safe against races due to the exclusive
    // flock() taken above - this is only an advisory lock, but it is also
    // acquired by other instances of this function as well as crosvm
    // itself when running a VM, so this should be safe in all cases that
    // can access a disk image in normal operation.
    let current_size = match disk_image.get_len() {
        Ok(len) => len,
        Err(_) => return -EIO,
    };
    if current_size >= virtual_size {
        return 0;
    }

    match disk_image.set_len(virtual_size) {
        Ok(_) => 0,
        Err(_) => -ENOSYS,
    }
}
