Skip to content
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 29 additions & 28 deletions src/usbg_9pfs.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only

use std::fs::read_dir;
use std::os::unix::ffi::OsStrExt;
use std::os::unix::fs::symlink;
use std::{thread, time};
use std::thread;
use std::time::Duration;

use log::debug;

Expand All @@ -12,15 +12,24 @@ use crate::mount::mount_apivfs;
use crate::util::{mkdir, write_file};
use crate::Result;

fn setup_9pfs_gadget(device: &String) -> Result<()> {
fn setup_9pfs_gadget(options: &mut CmdlineOptions) -> Result<()> {
debug!("Initializing USB 9pfs gadget ...");

let udc = read_dir("/sys/class/udc")
.map_err(|e| format!("Failed to list /sys/class/udc: {e}"))?
.next()
.ok_or("No UDC found to attach the 9pfs gadget".to_string())?
.map_err(|e| format!("Failed to inspect the first entry in /sys/class/udc: {e}"))?
.file_name();
let udc = if let Some(device) = &options.root {
device.to_owned()
} else {
read_dir("/sys/class/udc")
.map_err(|e| format!("Failed to list /sys/class/udc: {e}"))?
.next()
.ok_or("No UDC found to attach the 9pfs gadget".to_string())?
.map_err(|e| format!("Failed to inspect the first entry in /sys/class/udc: {e}"))?
.file_name()
.into_string()
.map_err(|e| format!("invalid utf-8 in file name: {e:?}"))?
}
.as_bytes()
.escape_ascii()
.to_string();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong. In the else case, the string is converted multiple times.


mount_apivfs("/sys/kernel/config", "configfs")?;

Expand All @@ -46,38 +55,30 @@ fn setup_9pfs_gadget(device: &String) -> Result<()> {
mkdir("/sys/kernel/config/usb_gadget/9pfs/configs/c.1")?;
mkdir("/sys/kernel/config/usb_gadget/9pfs/configs/c.1/strings/0x409")?;

let function = format!("/sys/kernel/config/usb_gadget/9pfs/functions/usb9pfs.{device}");
let link = format!("/sys/kernel/config/usb_gadget/9pfs/configs/c.1/usb9pfs.{device}");
let function = format!("/sys/kernel/config/usb_gadget/9pfs/functions/usb9pfs.{udc}");
let link = format!("/sys/kernel/config/usb_gadget/9pfs/configs/c.1/usb9pfs.{udc}");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @a3f said, that this name does not really matter, so maybe just use a fixed name.
@a3f, what do you think?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was mistaken. If I change this to something different from the first argument of the mount call, mounting fails.

mkdir(&function)?;
symlink(&function, &link)?;

debug!(
"Attaching 9pfs gatget to UDC {}",
udc.as_bytes().escape_ascii()
);
write_file(
"/sys/kernel/config/usb_gadget/9pfs/UDC",
udc.as_encoded_bytes(),
)?;
debug!("Attaching 9pfs gatget to UDC {udc}",);
write_file("/sys/kernel/config/usb_gadget/9pfs/UDC", &udc)?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, the file name read above is not necessarily UTF-8, so converting it into a String is technically not correct.


thread::sleep(Duration::from_secs(1));

options.root = Some(udc);

let d = time::Duration::new(1, 0);
thread::sleep(d);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated, this should be a separate commit.

Ok(())
}

pub fn prepare_9pfs_gadget(options: &CmdlineOptions) -> Result<bool> {
pub fn prepare_9pfs_gadget(options: &mut CmdlineOptions) -> Result<bool> {
if options.rootfstype.as_deref() == Some("9p")
&& options
.rootflags
.as_deref()
.is_some_and(|flags| flags.contains("trans=usbg"))
{
if let Some(root) = &options.root {
setup_9pfs_gadget(root)?;
Ok(true)
} else {
Err("Missing root= for 9p!".into())
}
setup_9pfs_gadget(options)?;
Ok(true)
} else {
Ok(false)
}
Expand Down