authfs: Support write config/operation in fuse
Bug: 171279640
Test: atest
Test: tools/device-test.sh
Change-Id: Ic611f72d51a5522d9ec6e6fdc82c115b5782c4ac
diff --git a/authfs/src/main.rs b/authfs/src/main.rs
index 39482e3..a4b0d40 100644
--- a/authfs/src/main.rs
+++ b/authfs/src/main.rs
@@ -43,8 +43,8 @@
mod fusefs;
use auth::FakeAuthenticator;
-use file::{LocalFileReader, RemoteFileReader, RemoteMerkleTreeReader};
-use fsverity::VerifiedFileReader;
+use file::{LocalFileReader, RemoteFileEditor, RemoteFileReader, RemoteMerkleTreeReader};
+use fsverity::{VerifiedFileEditor, VerifiedFileReader};
use fusefs::{FileConfig, Inode};
#[derive(StructOpt)]
@@ -68,6 +68,13 @@
#[structopt(long, parse(try_from_str = parse_remote_ro_file_unverified_option))]
remote_ro_file_unverified: Vec<OptionRemoteRoFileUnverified>,
+ /// A new read-writable remote file with integrity check. Can be multiple.
+ ///
+ /// For example, `--remote-new-verified-file 12:34` tells the filesystem to associate entry 12
+ /// with a remote file 34.
+ #[structopt(long, parse(try_from_str = parse_remote_new_rw_file_option))]
+ remote_new_rw_file: Vec<OptionRemoteRwFile>,
+
/// Debug only. A read-only local file with integrity check. Can be multiple.
#[structopt(long, parse(try_from_str = parse_local_file_ro_option))]
local_ro_file: Vec<OptionLocalFileRo>,
@@ -102,6 +109,13 @@
file_size: u64,
}
+struct OptionRemoteRwFile {
+ ino: Inode,
+
+ /// ID to refer to the remote file.
+ remote_id: i32,
+}
+
struct OptionLocalFileRo {
ino: Inode,
@@ -151,6 +165,17 @@
})
}
+fn parse_remote_new_rw_file_option(option: &str) -> Result<OptionRemoteRwFile> {
+ let strs: Vec<&str> = option.split(':').collect();
+ if strs.len() != 2 {
+ bail!("Invalid option: {}", option);
+ }
+ Ok(OptionRemoteRwFile {
+ ino: strs[0].parse::<Inode>().unwrap(),
+ remote_id: strs[1].parse::<i32>().unwrap(),
+ })
+}
+
fn parse_local_file_ro_option(option: &str) -> Result<OptionLocalFileRo> {
let strs: Vec<&str> = option.split(':').collect();
if strs.len() != 5 {
@@ -223,6 +248,12 @@
Ok(FileConfig::LocalUnverifiedReadonlyFile(file_reader, file_size))
}
+fn new_config_remote_new_verified_file(remote_id: i32) -> Result<FileConfig> {
+ let remote_file =
+ RemoteFileEditor::new(Arc::new(Mutex::new(file::get_local_binder())), remote_id);
+ Ok(FileConfig::RemoteVerifiedNewFile(VerifiedFileEditor::new(remote_file)))
+}
+
fn prepare_file_pool(args: &Args) -> Result<BTreeMap<Inode, FileConfig>> {
let mut file_pool = BTreeMap::new();
@@ -240,6 +271,10 @@
);
}
+ for config in &args.remote_new_rw_file {
+ file_pool.insert(config.ino, new_config_remote_new_verified_file(config.remote_id)?);
+ }
+
for config in &args.local_ro_file {
file_pool.insert(
config.ino,