DBUS API questions

David Zeuthen david at fubar.dk
Tue May 1 20:36:37 PDT 2007


Hi,

On Tue, 2007-05-01 at 14:09 -0500, Michael E Brown wrote:
> Not sure the best place to ask these questions. If there is a better
> email list to discuss this, please let me know.

Probably the hal list so I'm adding that as Cc...

>     I would like to start on a DBUS api for libsmbios.
> (http://linux.dell.com/libsmbios/main) I am afraid I dont have a lot of
> experience in dbus, though, so I wanted somebody else to help me a bit
> so I dont mess it up too badly.
> 
>     I thought it would be a good start to define my interfaces and
> object paths. Here is what I have come up with so far. This is all
> pseudocode. Final implementation will most likely be either glib or
> python (most likely). I wanted to get the interfaces/paths/etc right
> before I started coding this.
> 
>     I think I understand the difference between interfaces and object
> paths. I am still somewhat confused about how bus paths enter the
> picture. Some enlightenment would be appreciated.
> 
>     The motivation behind this is that almost all of the utilities in
> libsmbios require root access for various reasons. Right now, I have
> cmdline programs that must be run as root or using sudo. I'd like to
> write graphical interfaces for some of them, and think that splitting
> the graphical interface from the backend root stuff is the best way to
> go. Dbus seemed like a good choice so that users could write their own
> UI code for other desktop environments if they dont like mine (which
> will likely be gnome components written in glade/python)
> 
>     This is in addition to the work that other folks have already done
> to integrate some of my libsmbios stuff into HAL (which I *greatly*
> appreciate, btw.)

I'm obviously very biased :-) ... but I think what you're trying to
achieve is easiest done by just integrating with HAL since we already do
this kind of stuff for other user-space device libraries. HAL was also
sort of designed to do this thing. Let me start by explaining the three
basic extension points. It's mostly covered, or should be, in this
document btw

 http://people.freedesktop.org/~david/hal-spec/hal-spec.html

 - HAL Callouts
   Code that is run when a device object is added or removed. Basically
   this just allows you to run a program. You probably won't need this
   since libsmbios don't really deal with multiple devices in a Linux
   sense. One way you can use this, however, is to merge properties
   on device objects; e.g. for example if you have a Dell specific
   serial number you can add a callout to the root computer device
   object that runs a program and merges a property 

    dell.the_serial_number

   on the root computer device object.

 - Addons
   Code that runs for a specific device object; sort of like a
   system-wide daemon whose life cycle is tied to a device object.
   This is how we implement the Dell Backlight code btw; the addon
   simply claims the interface org.freedesktop.Hal.Device.LaptopPanel
   and, through a private connection to the main hal daemon, handles
   the methods on that interface and uses libsmbios to interface with
   the hardware. You want to use this if you expect the clients to
   call the methods a lot.

 - Method Calls
   A simply, yet effective way, of running a program in response to
   to a method call on a give device object. The way this works is
   a bit.. well.. it's not super nice but it's really useful for
   methods that are not called very often. The way it works is that
   you declare the interface using a HAL fdi file which is just XML.

For example, if a package drops a file 10-org-foo-bar.fdi

        <?xml version="1.0" encoding="UTF-8"?>
        
        <deviceinfo version="0.2">
          <device>
            <match key="info.udi" string="/org/freedesktop/Hal/devices/computer">
              <append key="info.interfaces" type="strlist">org.foo.Bar</append>
        
              <append key="org.foo.Bar.method_names" type="strlist">Frobnicate</append>
              <append key="org.foo.Bar.method_signatures" type="strlist">ssas</append>
              <append key="org.foo.Bar.method_argnames" type="strlist">frob_name frob_type frob_options</append>
              <append key="org.foo.Bar.method_execpaths" type="strlist">foobar-frobnicator --some-option</append>
                
              <append key="org.foo.Bar.method_names" type="strlist">Baz</append>
              <append key="org.foo.Bar.method_signatures" type="strlist">sb</append>
              <append key="org.foo.Bar.method_argnames" type="strlist">baz_name baz_should_bazify</append>
              <append key="org.foo.Bar.method_execpaths" type="strlist">foobar-bazinator</append>
        
            </match>
          </device>
        </deviceinfo>

in /usr/share/hal/fdi/policy/20thirdparty then this will have the effect
that the root computer device object simply gains a new D-Bus interface 
"org.foo.Bar" that you can call into via the system message bus. For
example

 $ dbus-send --system --print-reply --dest=org.freedesktop.Hal \
             /org/freedesktop/Hal/devices/computer \
             org.freedesktop.DBus.Introspectable.Introspect

  ...
  <interface name="org.foo.Bar">
    <method name="Frobnicate">
      <arg name="frob_name" direction="in" type="s"/>
      <arg name="frob_type" direction="in" type="s"/>
      <arg name="frob_options" direction="in" type="as"/>
      <arg name="return_code" direction="out" type="i"/>
    </method>
    <method name="Baz">
      <arg name="baz_name" direction="in" type="s"/>
      <arg name="baz_should_bazify" direction="in" type="b"/>
      <arg name="return_code" direction="out" type="i"/>
    </method>
  </interface>
  ...

And if you do e.g. 

 $ dbus-send --system --print-reply --dest=org.freedesktop.Hal \
             /org/freedesktop/Hal/devices/computer \
             org.foo.Bar.Baz

then foobar-bazinator will be run. This program will have to live in a
specific place - see the spec for details.

So that's pretty much it; the spec discusses how to throw exceptions
from your program. The only caveat is that method calls implemented this
way always return an integer; that's something we're going to fix for
HAL 0.5.10 (in a way so compat is preserved) so all types used by HAL
(which is int, uint64, string, strlist, bool, double) can be returned.

All these code paths are pretty stable since they are being used quite a
few places in HAL.. these feature also been available since.. I think
HAL 0.5.6 (or earlier) so it's supported by all the distros from last
year I think (I also think it's safe to assume that 95% or higher of all
Linux installations has HAL available).

Of course.. everything depends on what interface you want to export via
the IPC interface. I'm a big fan of exporting only high-level interfaces
that lets people do what they want in a single method call which I think
is what you're trying to say below with e.g. UpdateBIOS(). Exporting all
sorts of implementation details makes it a lot harder...

I'm also not sure it's worthwhile sending out signals for RadioChanged()
etc. - this is so standard behavior that eventually HAL should send out
D-Bus signals like these thus rendering the signals provided by a
hypothetical org.libsmbios service less than useful.

So I guess I'm saying, for the Dell specific things like UpdateBIOS()
I'd just merge an interface onto the root device object that exports
these. All this, as explained, can live in a libsmbios package; it's
just installing an XML file in the appropriate place...

Everything else should just be implemented in a vendor-agnostic way in
HAL just like HAL uses libsmbios for laptop backlight and RF kill
functionality. That has the benefit that if someone writes a kernel
driver or ports libsmbios to the kernel for some of this... we can just
use the kernel interface instead. 

Also, it means that other vendors can add the same functionality and
that the desktop / UI bits don't have to be specific to a given vendor
[1]. Which is what you guys benefit from now with the patch that was
integrated into HAL to use libsmbios for setting the backlight - e.g.
now things Just Work(tm) with KPowerSave, gnome-power-manager and other
applications that uses HAL (will rebuild HAL for Fedora 7 to use this
post-merge)

(In fact, much of that is happening for backlight drivers from other
vendors since the kernel gained the backlight class.)

And I'm more than happy to make HAL use libsmbios even more where it
makes sense / help out with how to integrate libsmbios with the HAL
extension points. I also know that Bastien is looking into the light
sensor stuff.

Whee, that was a long mail; hopefully it made some sense. How does my
proposal sound?

     David

[1] : It's a slippery slope that ends at the Windows world. Every time
(well almost) you buy a new piece of hardware [2] on Windows you get a
lot of "value added" software that you _need_ to use to make use of the
hardware. E.g. instead of just having a driver the vendor forces the
user to use his entire stack [3]. Not cool.

We actually have some of that in the Linux Desktop world already: hplip.

[2] : Uh, I know you work for a hardware vendor so please don't take
this the wrong way :-)

[3] : One blatant example of this is how many new USB sticks abuses a
flaw in Windows whereby programs on CD's are automatically run (without
user confirmation) in the default install. Thus, when you plug in a USB
stick it installs "value added" software without your consent. How do
they do it? They pretend to also be a USB optical drive! [4]

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=208521

[4] : OK, I'll stop the footnotes and anecdotes now.




More information about the hal mailing list