1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45use thiserror::Error;
6use zx_status::Status;
78#[cfg(target_os = "fuchsia")]
9use {fidl_fuchsia_io as fio, fidl_fuchsia_mem as fmem};
1011/// An error encountered while opening an image.
12#[derive(Debug, Error)]
13#[allow(missing_docs)]
14pub enum OpenImageError {
15#[error("while opening the file path {path:?}")]
16OpenPath {
17 path: String,
18#[source]
19err: fuchsia_fs::node::OpenError,
20 },
2122#[error("while calling get_backing_memory for {path:?}")]
23FidlGetBackingMemory {
24 path: String,
25#[source]
26err: fidl::Error,
27 },
2829#[error("while obtaining vmo of file for {path:?}: {status}")]
30GetBackingMemory { path: String, status: Status },
3132#[error("while converting vmo to a resizable vmo for {path:?}: {status}")]
33CloneBuffer { path: String, status: Status },
34}
3536#[cfg(target_os = "fuchsia")]
37/// Opens the given `path` as a resizable VMO buffer and returns the buffer on success.
38pub(crate) async fn open_from_path(
39 proxy: &fio::DirectoryProxy,
40 path: &str,
41) -> Result<fmem::Buffer, OpenImageError> {
42let file = fuchsia_fs::directory::open_file(proxy, path, fio::PERM_READABLE)
43 .await
44.map_err(|err| OpenImageError::OpenPath { path: path.to_string(), err })?;
4546let vmo = file
47 .get_backing_memory(fio::VmoFlags::READ)
48 .await
49.map_err(|err| OpenImageError::FidlGetBackingMemory { path: path.to_string(), err })?
50.map_err(Status::from_raw)
51 .map_err(|status| OpenImageError::GetBackingMemory { path: path.to_string(), status })?;
5253let size = vmo
54 .get_content_size()
55 .map_err(|status| OpenImageError::GetBackingMemory { path: path.to_string(), status })?;
5657// The paver service requires VMOs that are resizable, and blobfs does not give out resizable
58 // VMOs. Fortunately, a copy-on-write child clone of the vmo can be made resizable.
59let vmo = vmo
60 .create_child(
61 zx::VmoChildOptions::SNAPSHOT_AT_LEAST_ON_WRITE | zx::VmoChildOptions::RESIZABLE,
620,
63 size,
64 )
65 .map_err(|status| OpenImageError::CloneBuffer { path: path.to_string(), status })?;
6667Ok(fmem::Buffer { vmo, size })
68}