Dobby
3.0
Dobby “Docker based Thingy” is a tool for managing and running OCI containers using crun
|
Wraps an IPC service object on a given bus. More...
#include <DobbyIpcBus.h>
Classes | |
struct | tagServiceChangeEvent |
struct | tagServiceHandler |
struct | tagSignalHandler |
Public Member Functions | |
DobbyIpcBus (const std::string &dbusAddress, const std::shared_ptr< AI_IPC::IIpcService > &ipcService) | |
bool | connect (const std::string &address) |
Tries to connect to the bus at the given address. More... | |
void | disconnect () |
Simply disconnects from the bus. More... | |
const std::string & | address () const |
Simply returns the dbus address if we have one. More... | |
const std::string & | socketPath () const |
Returns just the socket path of the dbus address. More... | |
std::shared_ptr< AI_IPC::IAsyncReplyGetter > | invokeMethod (const AI_IPC::Method &method, const AI_IPC::VariantList &args, int timeoutMs) const |
Invokes the ipc method. More... | |
bool | invokeMethod (const AI_IPC::Method &method, const AI_IPC::VariantList &args, AI_IPC::VariantList &replyArgs) const |
Invokes the ipc method. More... | |
bool | emitSignal (const AI_IPC::Signal &signal, const AI_IPC::VariantList &args) const |
Sends out a signal over dbus. More... | |
bool | serviceAvailable (const std::string &serviceName) const |
Queries if the given service is available on the bus. More... | |
int | registerServiceHandler (const std::string &serviceName, const ServiceHandlerFn &handlerFunc) |
Registers a callback function that will be called when the given service is added or removed from the bus. More... | |
int | registerSignalHandler (const AI_IPC::Signal &signal, const AI_IPC::SignalHandler &handlerFunc) |
Registers a callback function that will be called when the given signal is received on the bus. More... | |
void | unregisterHandler (int handlerId) |
Unregisters a signal or service handler. More... | |
Private Types | |
typedef struct DobbyIpcBus::tagServiceHandler | ServiceHandler |
typedef struct DobbyIpcBus::tagSignalHandler | SignalHandler |
typedef struct DobbyIpcBus::tagServiceChangeEvent | ServiceChangeEvent |
Private Member Functions | |
void | disconnectNoLock () |
Disconnects the service from the bus. More... | |
void | registerServiceWatcher () |
Install a signal handler to detect services arriving / leaving the bus. More... | |
void | serviceNameChanged (const AI_IPC::VariantList &args) |
Callback function called when dbus has informed us that a name on the bus has changed. More... | |
void | serviceChangeThread () |
Thread function that receives notifications on service changes and then calls the install handler. More... | |
Static Private Member Functions | |
static std::string | socketPathFromAddress (const std::string &address) |
Utility function to extract the socket path from the dbus address string. More... | |
Private Attributes | |
std::mutex | mLock |
std::shared_ptr< AI_IPC::IIpcService > | mService |
std::string | mDbusAddress |
std::string | mDbusSocketPath |
int | mHandlerId |
std::string | mServiceSignal |
std::map< int, ServiceHandler > | mServiceHandlers |
std::map< int, SignalHandler > | mSignalHandlers |
std::thread | mServiceChangeThread |
std::mutex | mServiceChangeLock |
std::condition_variable | mServiceChangeCond |
std::deque< ServiceChangeEvent > | mServiceChangeQueue |
Wraps an IPC service object on a given bus.
This class is a helper for the DobbyUtils. It is used to manage a connection to a dbus so that plugins don't need to do the heavy lifting.
For example these objects allow for the bus coming and going, and for managing multiple clients of the bus. It is possible for the bus address to be changed and the clients won't notice or have to re-register their handlers.
This class is not intended to replace the IpcService class, in fact it relies on it quite heavily, rather it is intended to manage that class for multiple clients.
const std::string & DobbyIpcBus::address | ( | ) | const |
Simply returns the dbus address if we have one.
If not currently connected to a service this will return an empty string.
bool DobbyIpcBus::connect | ( | const std::string & | dbusAddress | ) |
Tries to connect to the bus at the given address.
This method will close any existing connection first before trying to to connect to the new address. If the method fails to connect to the new bus the old connection is not restored, the bus will be left in the disconnected state.
[in] | dbusAddress | The dbus address to connect to. |
void DobbyIpcBus::disconnect | ( | ) |
Simply disconnects from the bus.
If there were any service notifiers installed they will each get a 'service left' callback (provided the bus was actually connected).
|
private |
Disconnects the service from the bus.
This will call any service notifiers to tell them that their interested service(s) has left the bus. Obviously this may not actually be true, but since we're closing our connection to the bus it might as well be because there is no way to now talk to those services.
It then flushes out all messages and removes the signal notifier.
bool DobbyIpcBus::emitSignal | ( | const AI_IPC::Signal & | signal, |
const AI_IPC::VariantList & | args | ||
) | const |
Sends out a signal over dbus.
This is a pure wrapper around the IpcService::emitSignal function.
[in] | signal | The signal details. |
[in] | args | The signal args. |
bool DobbyIpcBus::invokeMethod | ( | const AI_IPC::Method & | method, |
const AI_IPC::VariantList & | args, | ||
AI_IPC::VariantList & | replyArgs | ||
) | const |
Invokes the ipc method.
This is a pure wrapper around the IpcService::invokeMethod function.
[in] | method | The method to call. |
[in] | args | The method args |
[out] | replyArgs | The reply. |
std::shared_ptr< AI_IPC::IAsyncReplyGetter > DobbyIpcBus::invokeMethod | ( | const AI_IPC::Method & | method, |
const AI_IPC::VariantList & | args, | ||
int | timeoutMs | ||
) | const |
Invokes the ipc method.
This is a pure wrapper around the IpcService::invokeMethod function.
[in] | method | The method to call. |
[in] | args | The method args |
[in] | timeoutMs | Timeout in milliseconds, -1 for default (5 seconds) |
int DobbyIpcBus::registerServiceHandler | ( | const std::string & | serviceName, |
const ServiceHandlerFn & | handlerFunc | ||
) |
Registers a callback function that will be called when the given service is added or removed from the bus.
This in turn is useful for hooks to manage situations where the daemon they are talking to has crashed / restarted.
Case in point is the Jumper hook, it wants to know if the daemon has crashed so it doesn't block container startup by trying to talk to a nonexisting daemon. And likewise it wants to know when it's arrived back so it can re-create any state stored in the daemon.
To remove the handler call ipcUnregisterHandler with the handler id returned by this function.
[in] | serviceName | The name of the service to look out for. |
[in] | handlerFunc | Callback function called when the service is added or removed. If added the argument supplied will be true, if removed it will be false. |
|
private |
Install a signal handler to detect services arriving / leaving the bus.
Installs a signal listener for the 'org.freedesktop.DBus.NameOwnerChanged' signal which is used to tell when services arrive and leave the bus, we use it to implement the DobbyUtils::ipcServiceNotify() method
The method updates the mNotifierSignal internal string to hold the the registered handler. It is assumed that the handler is not already installed.
int DobbyIpcBus::registerSignalHandler | ( | const AI_IPC::Signal & | signal, |
const AI_IPC::SignalHandler & | handlerFunc | ||
) |
Registers a callback function that will be called when the given signal is received on the bus.
This is a pure wrapper around the IpcService.registerSignalHandler function.
[in] | signal | The signal details to watch for. |
[in] | handlerFunc | Callback function called when the signal is received. |
bool DobbyIpcBus::serviceAvailable | ( | const std::string & | serviceName | ) | const |
Queries if the given service is available on the bus.
This is a pure wrapper around the IpcService::serviceAvailable function.
[in] | serviceName | The service to query. |
|
private |
Thread function that receives notifications on service changes and then calls the install handler.
We use a separate thread to notify of signal changes because we don't want to block the IpcService thread for long periods of time while plugins setup / teardown their IPC code.
|
private |
Callback function called when dbus has informed us that a name on the bus has changed.
We use this signal to notify any listeners (typically hooks) that a service has arrived or left the bus. This in turn is useful for hooks to manage situations where the daemon they are talking to has crashed / restarted.
Case in point is the Jumper hook, it wants to know if the daemon has crashed so it doesn't block container startup trying to talk to non-existing daemon. And likewise it wants to know when it's arrived back so it can re-create any state stored in the daemon.
[in] | args | The args received |
const std::string & DobbyIpcBus::socketPath | ( | ) | const |
Returns just the socket path of the dbus address.
If not currently connected to a service this will return an empty string.
|
staticprivate |
Utility function to extract the socket path from the dbus address string.
This uses the low level dbus library API to parse the address and extract the fields. If the address supplied is not a unix socket then an empty string is returned.
[in] | address | The dbus address trying to parse |
void DobbyIpcBus::unregisterHandler | ( | int | handlerId | ) |
Unregisters a signal or service handler.
[in] | handlerId | The handler id returned by either the registerSignalHandler or registerServiceHandler methods. |