Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • D dbus
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 248
    • Issues 248
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 32
    • Merge requests 32
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • dbus
  • dbus
  • Issues
  • #313

Closed
Open
Created Oct 29, 2020 by John Baublitz@jbaublitz

dbus or libdbus appears to close the connection when stdin from a console (/dev/tty*) is sent as an argument

I bumped into an interesting issue where sending stdin from a process with a pseudoterminal as the controlling terminal works properly, but when run from a console, the following error is encountered: https://github.com/stratis-storage/project/issues/233.

The specific error of note here is org.freedesktop.DBus.Error.Disconnected. We have an alternate IPC mechanism that uses Unix sockets to transfer the file descriptor so I tried sending stdin from the console to the daemon process and that worked. This rules out that this is a limitation of Unix sockets. I also wondered if this had to do with the Python libraries that we use on top of python-dbus in our Python CLI. I wanted to rule that out so I wrote a D-Bus client in Rust to invoke just the problematic D-Bus method call:

use std::{error::Error, io::stdin, os::unix::io::AsRawFd, time::Duration};

use dbus::{arg::OwnedFd, blocking::Connection};

fn main() -> Result<(), Box<dyn Error>> {
    let key_desc = std::env::args()
        .nth(1)
        .ok_or_else(|| "Key description is a required argument")?;
    let connection = Connection::new_system()?;
    let proxy = connection.with_proxy(
        "org.storage.stratis2",
        "/org/storage/stratis2",
        Duration::from_secs(5),
    );
    println!("Enter key data:");
    let ((changed, _), rc, rs): ((bool, bool), u16, String) = proxy.method_call(
        "org.storage.stratis2.Manager.r2",
        "SetKey",
        (key_desc, unsafe { OwnedFd::new(stdin().as_raw_fd()) }, true),
    )?;
    if rc != 0 {
        Err(format!("Failed with error code {}: {}", rc, rs))?
    } else if !changed {
        Err("The requested action had no effect")?
    } else {
        Ok(())
    }
}

This also worked from a pseudoterminal-controlled shell, and failed with the same error when run from the console. This leads me to believe that this is a bug in either dbus itself or libdbus as both the Rust library (dbus-rs) and python-dbus bind to libdbus.

One additional piece of information that might be useful is that I monitored the D-Bus while this was occuring and no call to our SetKey method is ever registered in dbus-monitor indicating that it is never actually sent across the D-Bus before the connection is closed. strace also seems to indicate that the sendmsg call that is supposed to send the SetKey message succeeds according to the return value, but immediately after that, the recvmsg call appears to get a SIGHUP and returns 0 bytes read. The file descriptor for the D-Bus connection is then closed.

Let me know if you need any more information.

Assignee
Assign to
Time tracking