pub fn new(file_path: &str, file_len: u64) -> Result<FileBackend> {
        let path = std::path::Path::new(&file_path);
        let file = if path.is_dir() {
            let fs_path = format!("{}{}", file_path, "/stratovirt_backmem_XXXXXX");
            let fs_cstr = std::ffi::CString::new(fs_path.clone()).unwrap().into_raw();

            let raw_fd = unsafe { libc::mkstemp(fs_cstr) };
            if raw_fd < 0 {
                return Err(std::io::Error::last_os_error())
                    .chain_err(|| format!("Failed to create file in directory: {} ", file_path));
            }

            if unsafe { libc::unlink(fs_cstr) } != 0 {
                error!(
                    "Failed to unlink file \"{}\", error: {}",
                    fs_path,
                    std::io::Error::last_os_error()
                );
            }
            unsafe { File::from_raw_fd(raw_fd) }
        } else {
            let is_created = !path.exists();
            // Open the file, if not exist, create it.
            let file_ret = std::fs::OpenOptions::new()
                .read(true)
                .write(true)
                .create(true)
                .open(path)
                .chain_err(|| format!("Failed to Open file: {}", file_path))?;

            if is_created
                && unsafe { libc::unlink(std::ffi::CString::new(file_path).unwrap().into_raw()) }
                    != 0
            {
                error!(
                    "Failed to unlink file \"{}\", error: {}",
                    file_path,
                    std::io::Error::last_os_error()
                );
            }

            file_ret
        };

        // Safe because struct `statfs` only contains plain-data-type field,
        // and set to all-zero will not cause any undefined behavior.
        let mut fstat: libc::statfs = unsafe { std::mem::zeroed() };
        unsafe { libc::fstatfs(file.as_raw_fd(), &mut fstat) };
        info!(
            "Using memory backing file, the page size is {}",
            fstat.f_bsize
        );

        let old_file_len = file.metadata().unwrap().len();
        if old_file_len == 0 {
            file.set_len(file_len)
                .chain_err(|| format!("Failed to set length of file: {}", file_path))?;
        } else if old_file_len < file_len {
            bail!("Backing file {} does not has sufficient resource for allocating RAM (size is 0x{:X})", file_path, file_len);
        }

        Ok(FileBackend {
            file: Arc::new(file),
            offset: 0_u64,
            page_size: fstat.f_bsize as u64,
        })
    }
/// Construct a new FileBackend according to path and length.
/// If the file is already created, this function does not change its length.
///
/// # Arguments
///
/// * `file_path` - The path of file.
/// * `file_len` - The size of file.
///
/// # Errors
///
/// Return Error if
/// * fail to create the file.
/// * fail to open the file.
/// * fail to set file length.
Construct a new FileBackend according to path and length.
If the file is already created, this function does not change its length.
Construct a new FileBackend according to path and length . If the file is already created this function does not change its length .
pub fn new(file_path: &str, file_len: u64) -> Result<FileBackend> {
        let path = std::path::Path::new(&file_path);
        let file = if path.is_dir() {
            let fs_path = format!("{}{}", file_path, "/stratovirt_backmem_XXXXXX");
            let fs_cstr = std::ffi::CString::new(fs_path.clone()).unwrap().into_raw();
            let raw_fd = unsafe { libc::mkstemp(fs_cstr) };
            if raw_fd < 0 {
                return Err(std::io::Error::last_os_error())
                    .chain_err(|| format!("Failed to create file in directory: {} ", file_path));
            }
            if unsafe { libc::unlink(fs_cstr) } != 0 {
                error!(
                    "Failed to unlink file \"{}\", error: {}",
                    fs_path,
                    std::io::Error::last_os_error()
                );
            }
            unsafe { File::from_raw_fd(raw_fd) }
        } else {
            let is_created = !path.exists();
            // Open the file, if not exist, create it.
            let file_ret = std::fs::OpenOptions::new()
                .read(true)
                .write(true)
                .create(true)
                .open(path)
                .chain_err(|| format!("Failed to Open file: {}", file_path))?;
            if is_created
                && unsafe { libc::unlink(std::ffi::CString::new(file_path).unwrap().into_raw()) }
                    != 0
            {
                error!(
                    "Failed to unlink file \"{}\", error: {}",
                    file_path,
                    std::io::Error::last_os_error()
                );
            }
            file_ret
        };
        // Safe because struct `statfs` only contains plain-data-type field,
        // and set to all-zero will not cause any undefined behavior.
        let mut fstat: libc::statfs = unsafe { std::mem::zeroed() };
        unsafe { libc::fstatfs(file.as_raw_fd(), &mut fstat) };
        info!(
            "Using memory backing file, the page size is {}",
            fstat.f_bsize
        );
        let old_file_len = file.metadata().unwrap().len();
        if old_file_len == 0 {
            file.set_len(file_len)
                .chain_err(|| format!("Failed to set length of file: {}", file_path))?;
        } else if old_file_len < file_len {
            bail!("Backing file {} does not has sufficient resource for allocating RAM (size is 0x{:X})", file_path, file_len);
        }
        Ok(FileBackend {
            file: Arc::new(file),
            offset: 0_u64,
            page_size: fstat.f_bsize as u64,
        })
    }
pub fn new ( file_path : & str , file_len : u64 ) -> Result < FileBackend > { let path = std :: path :: Path :: new ( & file_path ) ; let file = if path . is_dir ( ) { let fs_path = format ! ( " " file_path " " ) ; let fs_cstr = std :: ffi :: CString :: new ( fs_path . clone ( ) ) . unwrap ( ) . into_raw ( ) ; let raw_fd = unsafe { libc :: mkstemp ( fs_cstr ) } ; if raw_fd < 0 { return Err ( std :: io :: Error :: last_os_error ( ) ) . chain_err ( | | format ! ( " " file_path ) ) ; } if unsafe { libc :: unlink ( fs_cstr ) } != 0 { error ! ( " \" \" " fs_path std io Error last_os_error ( ) ) ; } unsafe { File :: from_raw_fd ( raw_fd ) } } else { let is_created = ! path . exists ( ) ; // Open the file, if not exist, create it. let file_ret = std :: fs :: OpenOptions :: new ( ) . read ( true ) . write ( true ) . create ( true ) . open ( path ) . chain_err ( | | format ! ( " " file_path ) ) ? ; if is_created && unsafe { libc :: unlink ( std :: ffi :: CString :: new ( file_path ) . unwrap ( ) . into_raw ( ) ) } != 0 { error ! ( " \" \" " file_path std io Error last_os_error ( ) ) ; } file_ret } ; // Safe because struct `statfs` only contains plain-data-type field, // and set to all-zero will not cause any undefined behavior. let mut fstat : libc :: statfs = unsafe { std :: mem :: zeroed ( ) } ; unsafe { libc :: fstatfs ( file . as_raw_fd ( ) , & mut fstat ) } ; info ! ( " " fstat f_bsize ) ; let old_file_len = file . metadata ( ) . unwrap ( ) . len ( ) ; if old_file_len == 0 { file . set_len ( file_len ) . chain_err ( | | format ! ( " " file_path ) ) ? ; } else if old_file_len < file_len { bail ! ( " " file_path file_len ) ; } Ok ( FileBackend { file : Arc :: new ( file ) , offset : 0_u64 , page_size : fstat . f_bsize as u64 , } ) }
Construct a new FileBackend according to path and length.
Construct a new FileBackend according to path and length .
file_path
&str
file_len
u64
file_path
&str
file_len
u64
errors
Return Error if
fail to create the file.
fail to open the file.
fail to set file length.
Return Error if fail to create the file . fail to open the file . fail to set file length .