Dobby  3.0
Dobby “Docker based Thingy” is a tool for managing and running OCI containers using crun
Classes | Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
DobbyIpcBus Class Reference

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::IAsyncReplyGetterinvokeMethod (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::IIpcServicemService
 
std::string mDbusAddress
 
std::string mDbusSocketPath
 
int mHandlerId
 
std::string mServiceSignal
 
std::map< int, ServiceHandlermServiceHandlers
 
std::map< int, SignalHandlermSignalHandlers
 
std::thread mServiceChangeThread
 
std::mutex mServiceChangeLock
 
std::condition_variable mServiceChangeCond
 
std::deque< ServiceChangeEventmServiceChangeQueue
 

Detailed Description

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.

Member Function Documentation

◆ address()

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.

◆ connect()

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.

Parameters
[in]dbusAddressThe dbus address to connect to.
Returns
true if managed to connect to the bus, otherwise false.

◆ disconnect()

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).

◆ disconnectNoLock()

void DobbyIpcBus::disconnectNoLock ( )
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.

◆ emitSignal()

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.

Parameters
[in]signalThe signal details.
[in]argsThe signal args.
Returns
true if successful, otherwise false.

◆ invokeMethod() [1/2]

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.

Parameters
[in]methodThe method to call.
[in]argsThe method args
[out]replyArgsThe reply.
Returns
true if successful, otherwise false.

◆ invokeMethod() [2/2]

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.

Parameters
[in]methodThe method to call.
[in]argsThe method args
[in]timeoutMsTimeout in milliseconds, -1 for default (5 seconds)
Returns
A result to wait on.

◆ registerServiceHandler()

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.

Parameters
[in]serviceNameThe name of the service to look out for.
[in]handlerFuncCallback function called when the service is added or removed. If added the argument supplied will be true, if removed it will be false.
Returns
if the notifier is successifully added then a positive handler id will be returned, otherwise -1

◆ registerServiceWatcher()

void DobbyIpcBus::registerServiceWatcher ( )
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.

◆ registerSignalHandler()

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.

Parameters
[in]signalThe signal details to watch for.
[in]handlerFuncCallback function called when the signal is received.
Returns
if the handler is successifully added then a positive handler id will be returned, otherwise -1

◆ serviceAvailable()

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.

Parameters
[in]serviceNameThe service to query.
Returns
true if the service is available, otherwise false.

◆ serviceChangeThread()

void DobbyIpcBus::serviceChangeThread ( )
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.

◆ serviceNameChanged()

void DobbyIpcBus::serviceNameChanged ( const AI_IPC::VariantList &  args)
private

Callback function called when dbus has informed us that a name on the bus has changed.

See also
https://dbus.freedesktop.org/doc/dbus-specification.html#bus-messages-name-owner-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.

Parameters
[in]argsThe args received

◆ socketPath()

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.

◆ socketPathFromAddress()

std::string DobbyIpcBus::socketPathFromAddress ( const std::string &  address)
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.

Parameters
[in]addressThe dbus address trying to parse
Returns
on success the path to the dbus socket, on failure an empty string.

◆ unregisterHandler()

void DobbyIpcBus::unregisterHandler ( int  handlerId)

Unregisters a signal or service handler.

Parameters
[in]handlerIdThe handler id returned by either the registerSignalHandler or registerServiceHandler methods.

The documentation for this class was generated from the following files: