systemdからの新しいsd-busAPI

新ではsystemdにv221のリリースで、我々は導入されているSD-バスAPIをの安定版リリースに付属ことにsystemdSD-バスは、私たちの最小限のD-バスであるIPCのCライブラリ古典的なソケットベースのD-バスとの両方のサポート、kdbusとしてバックエンドをライブラリはしばらくの間systemdの一部でしたが、外部ユーザーに影響を与えずにAPIを自由に変更したかったため、内部でのみ使用されていました。ただし、v221以降、安定したAPIを作成できたと確信しています。





この投稿では、sd-busライブラリの概要、D-Busの基本とその概念の簡単な要約、およびそれを使用してD-Busクライアントとサービスを作成する方法の簡単な例を示します。





D-Busとは何ですか?

D-Busが実際に何であるかを簡単に思い出させることから始めましょう。これは、Linuxおよびその他のオペレーティングシステム用の強力な汎用IPCシステムです。バス、オブジェクト、インターフェイス、メソッド、シグナル、プロパティなどの概念を定義します。きめ細かいアクセス制御、リッチタイプのシステム、簡単な検出、自己診断、監視、信頼性の高いマルチキャスト、サービスの起動、ファイル記述子の転送などを提供します。Linuxで使用されているプログラミング言語の多くにはバインディングがあります。





D-Busは、10年以上にわたってLinuxシステムのコアコンポーネントです。これは、Linuxで最も広く使用されている高レベルのローカルIPCシステムです。 systemdは、その開始以来、インターフェイスを公開するIPCシステムです。そしてsystemdの前でさえ、Upstartがそのインターフェースに使用したのはIPCシステムでした。 GNOME、KDE、および多くのシステムコンポーネントで使用されます。





D-Busは、仕様リファレンス実装の両方を指します。リファレンス実装は、バスサーバーコンポーネントとクライアントライブラリの両方を提供します。クライアントライブラリには、C言語と他のプログラミング言語の両方で人気のある後続の実装が他にもたくさんありますが、広く使用されているサーバー側は、リファレンス実装で指定されているものだけです。 (ただし、kdbusプロジェクトは、カーネルコンポーネントとしてこのサーバー実装の代替手段を提供するように取り組んでいます。)





D-Bus IPC AF_UNIX. TCP/IP. , D-Bus TCP . D-Bus , ssh, . systemd , API .





D-Bus: , , AF_UNIX FIFO UNIX . , D-Bus -: AF_UNIX/FIFO D-Bus , TCP HTTP/REST. , AF_UNIX/FIFO , D-Bus , , , , .





10- D-Bus , , , - ( , kdbus, sd-bus), , , . IPC, , D-Bus, , , D-Bus.





: D-Bus . Linux IPC, . , D-Bus , , , .





sd-bus?

, sd-bus, D-Bus .





D-Bus: libdbus, D-Bus, GDBus, GLib, GNOME.





libdbus , . , . , API , API , . , , . , (, OOM , ) , Windows UNIX.





GDBus - . GLib/GObject libdbus. GDBus , libdbus. libdbus, , GObject D-Bus GObject. D-Bus GVariant, GLib. GLib, , D-Bus , libdbus.





sd-bus , libdbus, GDBus. libdbus GDBus: , , , , , , , GDBus/GLib/GObject/GVariant. systemd, OOM. , , kdbus D-Bus («dbus1»). , kdbus, dbus1, - , . libdbus GDBus, sd-bus, Linux Linux , . , ( ): libdbus, GDBus . ( ), . , : , kdbus , , , libdbus GDBus.





, , API :





  • GLib/GObject, GDBus .





  • , Linux, Windows, Mac OS UNIX, GDBus ( GLib/GObject), libdbus ( ).





  • sd-bus.





( C++, . : Qt, QtDBus API D-Bus, libdbus.)





D-Bus

D-Bus . , . . :





  • - , IPC. : , , ; , , , . ( , , , , , , , .)





  • - , IPC API . . , org.freedesktop.NetworkManager



    - , API- NetworkManager, org.freedesktop.login1



    - , API- systemd-logind



    .





  • - , IPC API . , , , . , . .





  • - . , , - . - , , . , D-Bus , , . : /org/freedesktop/login1



    - «» org.freedesktop.login1



    (, , systemd-logind). , . , , systemd-logind



    /org/freedesktop/login1/session



    , : /org/freedesktop/login1/session/_7



    , /org/freedesktop/login1/session./_55



    . , .





  • , , . - , ( ), . D-Bus , , Java, . , . , . (, , , , .) , , , . , org.freedesktop.DBus.Introspectable



    , org.freedesktop.DBus.Peer



    org.freedesktop.DBus.Properties



    .





  • . «» «», - , Java. D-Bus , . D-Bus . , , . ( ) CamelCase. , systemd-logind



    ActivateSession



    org.freedesktop.login1.Manager



    , /org/freedesktop/login1



    org.freedesktop.login1



    .





  • , ( , , . ). , . . , , s



    u



    32- , , as



    a(sb)



    , . . D-Bus, . ActivateSession



    ( , , s



    ) ( , , ). , , . .





  • - , D-Bus. , . . , , . , , - . , . / --, -- ( , , --). : systemd-logind



    SessionNew



    - , , SessionRemoved



    , .





  • - , D-Bus. , , C#. . , , . : systemd-logind



    Docked



    b



    ( ). , systemd-logind



    , - ( ).





D-Bus . , . . , -, HTTP REST. HTTP- D-Bus:





  • HTTP-, . , VPN. , , . «» D-Bus.





  • HTTP- . .





  • HTTP- URL-. URL-, ( , «/») D-Bus.





  • «» URL- ( , , , ), , . D-Bus .





  • , HTTP- «?», D-Bus.





, HTTP- D-Bus . , , , .





. , , .





systemd busctl, D-Bus. , . ( --user, ):





$ busctl
NAME                                       PID PROCESS         USER             CONNECTION    UNIT                      SESSION    DESCRIPTION
:1.1                                         1 systemd         root             :1.1          -                         -          -
:1.11                                      705 NetworkManager  root             :1.11         NetworkManager.service    -          -
:1.14                                      744 gdm             root             :1.14         gdm.service               -          -
:1.4                                       708 systemd-logind  root             :1.4          systemd-logind.service    -          -
:1.7200                                  17563 busctl          lennart          :1.7200       session-1.scope           1          -
[…]
org.freedesktop.NetworkManager             705 NetworkManager  root             :1.11         NetworkManager.service    -          -
org.freedesktop.login1                     708 systemd-logind  root             :1.4          systemd-logind.service    -          -
org.freedesktop.systemd1                     1 systemd         root             :1.1          -                         -          -
org.gnome.DisplayManager                   744 gdm             root             :1.14         gdm.service               -          -
[…]
      
      



( , ).





, . , ":1.11". D-Bus . , , , . , IP-. , , busctl, . , ( ; , ). DNS, , IP- , , . , , IP-, , . ( , , , IP- , ).





, . , (, , systemd).





. , org.freedesktop.login1:





$ busctl tree org.freedesktop.login1
└─/org/freedesktop/login1
  ├─/org/freedesktop/login1/seat
  │ ├─/org/freedesktop/login1/seat/seat0
  │ └─/org/freedesktop/login1/seat/self
  ├─/org/freedesktop/login1/session
  │ ├─/org/freedesktop/login1/session/_31
  │ └─/org/freedesktop/login1/session/self
  └─/org/freedesktop/login1/user
    ├─/org/freedesktop/login1/user/_1000
    └─/org/freedesktop/login1/user/self
      
      



, ? , , : TAB, . D-Bus!





, . . , , , :





$ busctl introspect org.freedesktop.login1 /org/freedesktop/login1/session/_31
NAME                                TYPE      SIGNATURE RESULT/VALUE                             FLAGS
org.freedesktop.DBus.Introspectable interface -         -                                        -
.Introspect                         method    -         s                                        -
org.freedesktop.DBus.Peer           interface -         -                                        -
.GetMachineId                       method    -         s                                        -
.Ping                               method    -         -                                        -
org.freedesktop.DBus.Properties     interface -         -                                        -
.Get                                method    ss        v                                        -
.GetAll                             method    s         a{sv}                                    -
.Set                                method    ssv       -                                        -
.PropertiesChanged                  signal    sa{sv}as  -                                        -
org.freedesktop.login1.Session      interface -         -                                        -
.Activate                           method    -         -                                        -
.Kill                               method    si        -                                        -
.Lock                               method    -         -                                        -
.PauseDeviceComplete                method    uu        -                                        -
.ReleaseControl                     method    -         -                                        -
.ReleaseDevice                      method    uu        -                                        -
.SetIdleHint                        method    b         -                                        -
.TakeControl                        method    b         -                                        -
.TakeDevice                         method    uu        hb                                       -
.Terminate                          method    -         -                                        -
.Unlock                             method    -         -                                        -
.Active                             property  b         true                                     emits-change
.Audit                              property  u         1                                        const
.Class                              property  s         "user"                                   const
.Desktop                            property  s         ""                                       const
.Display                            property  s         ""                                       const
.Id                                 property  s         "1"                                      const
.IdleHint                           property  b         true                                     emits-change
.IdleSinceHint                      property  t         1434494624206001                         emits-change
.IdleSinceHintMonotonic             property  t         0                                        emits-change
.Leader                             property  u         762                                      const
.Name                               property  s         "lennart"                                const
.Remote                             property  b         false                                    const
.RemoteHost                         property  s         ""                                       const
.RemoteUser                         property  s         ""                                       const
.Scope                              property  s         "session-1.scope"                        const
.Seat                               property  (so)      "seat0" "/org/freedesktop/login1/seat... const
.Service                            property  s         "gdm-autologin"                          const
.State                              property  s         "active"                                 -
.TTY                                property  s         "/dev/tty1"                              const
.Timestamp                          property  t         1434494630344367                         const
.TimestampMonotonic                 property  t         34814579                                 const
.Type                               property  s         "x11"                                    const
.User                               property  (uo)      1000 "/org/freedesktop/login1/user/_1... const
.VTNr                               property  u         1                                        const
.Lock                               signal    -         -                                        -
.PauseDevice                        signal    uus       -                                        -
.ResumeDevice                       signal    uuh       -                                        -
.Unlock                             signal    -         -                                        -
      
      



, busctl , , TAB. , , , systemd-logind



. , . . . , . . .





. : - :





# busctl call org.freedesktop.login1 /org/freedesktop/login1/session/_31 org.freedesktop.login1.Session Lock
      
      



, , : . - , - , TAB. Lock



, . , , Enter , ( , systemd-logind. GNOME , KDE ).





Lock



, . , . , systemd :





# busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager StartUnit ss "cups.service" "replace"
o "/org/freedesktop/systemd1/job/42684"
      
      



, , ( , , ). - . , , . StartUnit systemd , , . . , : ( o ), .





, , busctl



. . .





busctl



. , D-Bus ( .cap



Wireshark!) . , sd-bus, busctl



, , .





busctl



( ) API sd-bus. , sd-bus. , . kdbus, D-Bus, !





sd-bus

! , sd-bus.





API sd-bus sd-bus.h.





, .





  • kdbus, dbus1 .





  • ssh .





  • . 34 , PID .





  • , , , .





  • , , .





  • D-Bus UNIX ( ), D-Bus Linux.





  • , . .





API , . , sd_bus_



.





sd-bus

. :





#include <stdio.h>
#include <stdlib.h>
#include <systemd/sd-bus.h>

int main(int argc, char *argv[]) {
  sd_bus_error error = SD_BUS_ERROR_NULL;
  sd_bus_message *m = NULL;
  sd_bus *bus = NULL;
  const char *path;
  int r;

  /* Connect to the system bus */
  r = sd_bus_open_system(&bus);
  if (r < 0) {
    fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
    goto finish;
  }

  /* Issue the method call and store the respons message in m */
  r = sd_bus_call_method(bus,
                         "org.freedesktop.systemd1",           /* service to contact */
                         "/org/freedesktop/systemd1",          /* object path */
                         "org.freedesktop.systemd1.Manager",   /* interface name */
                         "StartUnit",                          /* method name */
                         &error,                               /* object to return error in */
                         &m,                                   /* return message on success */
                         "ss",                                 /* input signature */
                         "cups.service",                       /* first argument */
                         "replace");                           /* second argument */
  if (r < 0) {
    fprintf(stderr, "Failed to issue method call: %s\n", error.message);
    goto finish;
  }

  /* Parse the response message */
  r = sd_bus_message_read(m, "o", &path);
  if (r < 0) {
    fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
    goto finish;
  }

  printf("Queued service job as %s.\n", path);

finish:
  sd_bus_error_free(&error);
  sd_bus_message_unref(m);
  sd_bus_unref(bus);

  return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
      
      



bus-client.c



, :





$ gcc bus-client.c -o bus-client `pkg-config --cflags --libs libsystemd`
      
      



bus-client



, . root, StartUnit



:





# ./bus-client
Queued service job as /org/freedesktop/systemd1/job/3586.
      
      



. , . busctl



, . , . , D-Bus sd-bus. , , , sd-bus.





sd-bus

, - . , . . , : 64- , 64- .





#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <systemd/sd-bus.h>

static int method_multiply(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
  int64_t x, y;
  int r;

  /* Read the parameters */
  r = sd_bus_message_read(m, "xx", &x, &y);
  if (r < 0) {
    fprintf(stderr, "Failed to parse parameters: %s\n", strerror(-r));
    return r;
  }

  /* Reply with the response */
  return sd_bus_reply_method_return(m, "x", x * y);
}

static int method_divide(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
  int64_t x, y;
  int r;

  /* Read the parameters */
  r = sd_bus_message_read(m, "xx", &x, &y);
  if (r < 0) {
    fprintf(stderr, "Failed to parse parameters: %s\n", strerror(-r));
    return r;
  }

  /* Return an error on division by zero */
  if (y == 0) {
    sd_bus_error_set_const(ret_error, "net.poettering.DivisionByZero", "Sorry, can't allow division by zero.");
    return -EINVAL;
  }

  return sd_bus_reply_method_return(m, "x", x / y);
}

/* The vtable of our little object, implements the net.poettering.Calculator interface */
static const sd_bus_vtable calculator_vtable[] = {
  SD_BUS_VTABLE_START(0),
  SD_BUS_METHOD("Multiply", "xx", "x", method_multiply, SD_BUS_VTABLE_UNPRIVILEGED),
  SD_BUS_METHOD("Divide",   "xx", "x", method_divide,   SD_BUS_VTABLE_UNPRIVILEGED),
  SD_BUS_VTABLE_END
};

int main(int argc, char *argv[]) {
  sd_bus_slot *slot = NULL;
  sd_bus *bus = NULL;
  int r;

  /* Connect to the user bus this time */
  r = sd_bus_open_user(&bus);
  if (r < 0) {
    fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
    goto finish;
  }

  /* Install the object */
  r = sd_bus_add_object_vtable(bus,
                               &slot,
                               "/net/poettering/Calculator",  /* object path */
                               "net.poettering.Calculator",   /* interface name */
                               calculator_vtable,
                               NULL);
  if (r < 0) {
    fprintf(stderr, "Failed to issue method call: %s\n", strerror(-r));
    goto finish;
  }

  /* Take a well-known service name so that clients can find us */
  r = sd_bus_request_name(bus, "net.poettering.Calculator", 0);
  if (r < 0) {
    fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-r));
    goto finish;
  }

  for (;;) {
    /* Process requests */
    r = sd_bus_process(bus, NULL);
    if (r < 0) {
      fprintf(stderr, "Failed to process bus: %s\n", strerror(-r));
      goto finish;
    }
    if (r > 0) /* we processed a request, try to process another one, right-away */
      continue;

    /* Wait for the next request to process */
    r = sd_bus_wait(bus, (uint64_t) -1);
    if (r < 0) {
      fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r));
      goto finish;
    }
  }

finish:
  sd_bus_slot_unref(slot);
  sd_bus_unref(bus);

  return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
      
      



bus-service.c



, :





$ gcc bus-service.c -o bus-service `pkg-config --cflags --libs libsystemd`
      
      



:





$ ./bus-service
      
      



. , , , . : , . : , , , . , --user busctl. .





$ busctl --user tree net.poettering.Calculator
└─/net/poettering/Calculator
      
      



, , , , . , :





$ busctl --user introspect net.poettering.Calculator /net/poettering/Calculator
NAME                                TYPE      SIGNATURE RESULT/VALUE FLAGS
net.poettering.Calculator           interface -         -            -
.Divide                             method    xx        x            -
.Multiply                           method    xx        x            -
org.freedesktop.DBus.Introspectable interface -         -            -
.Introspect                         method    -         s            -
org.freedesktop.DBus.Peer           interface -         -            -
.GetMachineId                       method    -         s            -
.Ping                               method    -         -            -
org.freedesktop.DBus.Properties     interface -         -            -
.Get                                method    ss        v            -
.GetAll                             method    s         a{sv}        -
.Set                                method    ssv       -            -
.PropertiesChanged                  signal    sa{sv}as  -            -
      
      



, sd-bus . , , , ! , «xx» ( 64- ) «x». ! ?





$ busctl --user call net.poettering.Calculator /net/poettering/Calculator net.poettering.Calculator Multiply xx 5 7
x 35
      
      



! 5 7, 35! :





$ busctl --user call net.poettering.Calculator /net/poettering/Calculator net.poettering.Calculator Divide xx 99 17
x 5
      
      



! ! ! :





$ busctl --user call net.poettering.Calculator /net/poettering/Calculator net.poettering.Calculator Divide xx 43 0
Sorry, can't allow division by zero.
      
      



! . , , .





, . , , , , , . D-Bus sd-bus, ...





この投稿がお役に立てば幸いです。自分のプログラムにsd-busを使用することに興味がある場合は、それがお役に立てば幸いです。さらに質問がある場合は、(不完全な)manページを見て、IRCまたはsystemdメーリングリストで質問してください。さらに例が必要な場合は、systemdのソースツリーを見てください。systemdの多くのバスサービスはすべて、sd-busを広範囲に使用しています。








All Articles