Activation in Rust doesn't appear to work
When using the Connection::with_activate it appears to hang forever during preexec. Notably, invoking varlink bridge (from varlink-cli) over Connection::with_bridge also complains about an owned file descriptor already being closed.
Strace for running ping example using --client and relying on activation:
sched_getaffinity(121347, 32, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]) = 8
rt_sigaction(SIGSEGV, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
sigaltstack(NULL, {ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fe7ef3fd000
mprotect(0x7fe7ef3fd000, 4096, PROT_NONE) = 0
sigaltstack({ss_sp=0x7fe7ef3fe000, ss_flags=0, ss_size=8192}, NULL) = 0
rt_sigaction(SIGSEGV, {sa_handler=0x564fbb5d18e0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7fe7ef040140}, NULL, 8) = 0
rt_sigaction(SIGBUS, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGBUS, {sa_handler=0x564fbb5d18e0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7fe7ef040140}, NULL, 8) = 0
mkdir("/tmp/.tmpZVE3bV", 0777) = 0
socket(AF_UNIX, SOCK_STREAM, 0) = 3
bind(3, {sa_family=AF_UNIX, sun_path="/tmp/.tmpZVE3bV/varlink-socket"}, 33) = 0
listen(3, 128) = 0
socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, [4, 5]) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fe7ef400a90) = 121348
close(5) = 0
recvfrom(4,
If I alter client.rs I can get the connection to work but it'll hang further into the reply from the activated client:
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/tmp/.tmpJfVLUt/varlink-socket"}, 33) = 0
fcntl(3, F_DUPFD_CLOEXEC, 3) = 4
fcntl(3, F_DUPFD_CLOEXEC, 3) = 5
write(5, "{\"method\":\"org.example.ping.Ping"..., 64) = 64
recvfrom(4,
diff --git a/varlink/Cargo.toml b/varlink/Cargo.toml
index 097dca0..6bde2ff 100644
--- a/varlink/Cargo.toml
+++ b/varlink/Cargo.toml
@@ -2,7 +2,7 @@
name = "varlink"
version = "11.0.1"
authors = ["Harald Hoyer <[email protected]>"]
-edition = "2018"
+edition = "2021"
rust-version = "1.70.0"
license = "MIT OR Apache-2.0"
diff --git a/varlink/src/client.rs b/varlink/src/client.rs
index 026acf5..e83dbd5 100644
--- a/varlink/src/client.rs
+++ b/varlink/src/client.rs
@@ -96,6 +96,9 @@ pub fn varlink_exec<S: ?Sized + AsRef<str>>(
let child = unsafe {
Command::new("sh")
.arg("-c")
+ .env("VARLINK_ADDRESS", format!("unix:{}", file_path.display()))
+ .env("LISTEN_FDS", "1")
+ .env("LISTEN_FDNAMES", "varlink")
.arg(executable)
.pre_exec({
let file_path = file_path.clone();
@@ -105,10 +108,11 @@ pub fn varlink_exec<S: ?Sized + AsRef<str>>(
dup2(fd, 3);
close(fd);
}
- env::set_var("VARLINK_ADDRESS", format!("unix:{}", file_path.display()));
- env::set_var("LISTEN_FDS", "1");
- env::set_var("LISTEN_FDNAMES", "varlink");
- env::set_var("LISTEN_PID", format!("{}", getpid()));
+
+ let pid_str = std::ffi::CString::new(format!("{}", getpid())).unwrap();
+ let key = c"LISTEN_PID";
+ libc::setenv(key.as_ptr(), pid_str.as_ptr(), 1);
+
Ok(())
}
})
(Effectively I'm seeing a hang in env::set_var usage in pre_exec, after this I'm not quite sure where the hang is) - I do wonder if its perhaps a clone3()/stack related issue.
OK, another issue is the issue of unix_socket crate (basically busted).
So..
- use unix_socket::UnixListener;
+ use std::os::unix::net::UnixListener;
- use unix_socket::UnixStream as AbstractStream;
+ use std::os::unix::net::UnixStream as AbstractStream;
Will then resolve most other issues.Unfortunately at this point the tempdir crate comes into play, and...
thread 'main' panicked at examples/ping/src/main.rs:63:22:
called `Result::unwrap()` on an `Err` value: varlink/src/client.rs:39: Io(ConnectionRefused)
Caused by:
Os { code: 111, kind: ConnectionRefused, message: "Connection refused" }
stack backtrace:
error: running server with address unix:/tmp/.tmpvE7Wxu/varlink-socket
Caused by:
0: IO error
1: No such file or directory (os error 2) 0: rust_begin_unwind
It appears the socket is being deleted early.. 🫠