Skip to content

Commit e5da0be

Browse files
hoshinolinaslp
authored andcommitted
x11: Introduce the -x command line option to enable X11 forwarding
Instead of enabling X11 forwarding unconditionally but hiding it behind the HOST_DISPLAY variable, enable it if the --direct-x11 flag is used. In that case, directly set it as the DISPLAY environment variable. This makes it easier for users to enable the feature and use it correctly. Eventually, we can flip the logic of the flag to make direct X11 the default. Keep the server at :1 to keep churn down, and because it seems like a generally helpful distinction, since the server is usually :0 on the host. Signed-off-by: Asahi Lina <[email protected]>
1 parent e15a496 commit e5da0be

5 files changed

Lines changed: 31 additions & 25 deletions

File tree

crates/muvm/src/bin/muvm.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,18 @@ fn main() -> Result<()> {
375375
options.server_port.to_string(),
376376
);
377377

378+
if options.direct_x11 {
379+
let display =
380+
env::var("DISPLAY").context("X11 forwarding requested but DISPLAY is unset")?;
381+
env.insert("HOST_DISPLAY".to_string(), display);
382+
383+
// And forward XAUTHORITY. This will be modified to fix the
384+
// display name in muvm-guest.
385+
if let Ok(xauthority) = env::var("XAUTHORITY") {
386+
env.insert("XAUTHORITY".to_string(), xauthority);
387+
}
388+
}
389+
378390
let mut krun_config = KrunConfig {
379391
args: Vec::new(),
380392
envs: Vec::new(),

crates/muvm/src/cli_options.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub struct Options {
1515
pub passt_socket: Option<PathBuf>,
1616
pub server_port: u32,
1717
pub fex_images: Vec<String>,
18+
pub direct_x11: bool,
1819
pub command: PathBuf,
1920
pub command_args: Vec<String>,
2021
}
@@ -98,6 +99,11 @@ pub fn options() -> OptionParser<Options> {
9899
.argument("SERVER_PORT")
99100
.fallback(3334)
100101
.display_fallback();
102+
let direct_x11 = long("direct-x11")
103+
.short('x')
104+
.help("Use direct X11 forwarding instead of sommelier + XWayland")
105+
.switch();
106+
101107
let command = positional("COMMAND").help("the command you want to execute in the vm");
102108
let command_args = any::<String, _, _>("COMMAND_ARGS", |arg| {
103109
(!["--help", "-h"].contains(&&*arg)).then_some(arg)
@@ -113,6 +119,7 @@ pub fn options() -> OptionParser<Options> {
113119
passt_socket,
114120
server_port,
115121
fex_images,
122+
direct_x11,
116123
// positionals
117124
command,
118125
command_args,

crates/muvm/src/env.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,6 @@ pub fn prepare_env_vars(env: Vec<(String, Option<String>)>) -> Result<HashMap<St
6464
env_map.insert(key, value);
6565
}
6666

67-
// If we have an X11 display in the host, set HOST_DISPLAY in the guest.
68-
// muvm-guest will then use this to set up xauth and replace it with :1
69-
// (which is forwarded to the host display).
70-
if let Ok(display) = env::var("DISPLAY") {
71-
env_map.insert("HOST_DISPLAY".to_string(), display);
72-
73-
// And forward XAUTHORITY. This will be modified to fix the
74-
// display name in muvm-guest.
75-
if let Ok(xauthority) = env::var("XAUTHORITY") {
76-
env_map.insert("XAUTHORITY".to_string(), xauthority);
77-
}
78-
}
79-
8067
debug!(env:? = env_map; "env vars");
8168

8269
Ok(env_map)

crates/muvm/src/guest/bin/muvm-guest.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,13 @@ fn main() -> Result<()> {
7373
let pulse_path = pulse_path.join("native");
7474
setup_socket_proxy(pulse_path, 3333)?;
7575

76-
setup_x11_forwarding(run_path)?;
77-
78-
// Will not return if successful.
79-
exec_sommelier(&options.command, &options.command_args)
80-
.context("Failed to execute sommelier")?;
76+
if !setup_x11_forwarding(run_path)? {
77+
// Will not return if successful.
78+
exec_sommelier(&options.command, &options.command_args)
79+
.context("Failed to execute sommelier")?;
80+
}
8181

82-
// Fallback option if sommelier is not present.
82+
// Fallback option if sommelier is not present or for direct X11 mode.
8383
debug!(command:? = options.command, command_args:? = options.command_args; "exec");
8484
let err = Command::new(&options.command)
8585
.args(options.command_args)

crates/muvm/src/guest/x11.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ use super::socket::setup_socket_proxy;
1111

1212
use crate::utils::env::find_in_path;
1313

14-
pub fn setup_x11_forwarding<P>(run_path: P) -> Result<()>
14+
pub fn setup_x11_forwarding<P>(run_path: P) -> Result<bool>
1515
where
1616
P: AsRef<Path>,
1717
{
1818
// Set by muvm if DISPLAY was provided from the host.
1919
let host_display = match env::var("HOST_DISPLAY") {
2020
Ok(d) => d,
21-
Err(_) => return Ok(()),
21+
Err(_) => return Ok(false),
2222
};
2323

2424
if !host_display.starts_with(':') {
@@ -35,14 +35,14 @@ where
3535

3636
cmd.spawn().context("Failed to spawn `x112virtgpu`")?;
3737
} else {
38+
log::error!("x112virtgpu not available, X11 forwarding will operate in socket forwarding mode. This is probably not what you want.");
3839
setup_socket_proxy(Path::new("/tmp/.X11-unix/X1"), 6000)?;
3940
}
4041

41-
// Set HOST_DISPLAY to :1, which is the display number within the guest
42-
// at which the actual host display is accessible.
4342
// SAFETY: Safe if and only if `muvm-guest` program is not multithreaded.
4443
// See https://doc.rust-lang.org/std/env/fn.set_var.html#safety
45-
env::set_var("HOST_DISPLAY", ":1");
44+
env::set_var("DISPLAY", ":1");
45+
env::set_var("XSHMFENCE_NO_MEMFD", "1");
4646

4747
if let Ok(xauthority) = std::env::var("XAUTHORITY") {
4848
let src_path = format!("/run/muvm-host/{}", xauthority);
@@ -100,5 +100,5 @@ where
100100
env::set_var("XAUTHORITY", dst_path);
101101
}
102102

103-
Ok(())
103+
Ok(true)
104104
}

0 commit comments

Comments
 (0)