UDisksModule

UDisksModule — Daemon module

Functions

Types and Values

Description

UDisks module design

UDisksModule is a stateful object that represents a daemon module. It is supposed to hold arbitrary runtime data and perform proper initialization and cleanup within its constructor and destructor. Once initialized by UDisksModuleManager the instance is usually kept around until the daemon exits. Although proper module unloading is not currently implemented the object destructor may be actually called in some cases.

Derived UDisksModule object is supposed to implement failable initialization and return proper error that the UDisksModuleManager would propagate further up the stack. Modules are free to use failable initialization for checking runtime dependencies such as additional config files and fail if misconfigured.

UDisks module naming conventions

Every module must implement and export two symbols that are used as entry points: udisks_module_id() and udisks_module_ID_new() where ID is a string returned by udisks_module_id(). This identification string is subsequently used at several places - primarily serves as an unique and user readable module identifier (e.g. lvm2) passed in as an argument to the org.freedesktop.UDisks2.Manager.EnableModule() method call.

Physically modules are essentially regular shared objects (.so) that are loaded from $(libdir)/udisks2/modules directory (typically /usr/lib/udisks2/modules). No extra service or config files are needed, however a specific file naming of libudisks2_ID.so is required.

Module API

Other than the two entry points described in last paragraph the rest of the daemon to module interaction is done via UDisksModule class methods over an instance created by the udisks_module_ID_new() constructor. Please see particular UDisksModule methods for detailed description of each way of extending the daemon functionality. Most methods are pretty straightforward with the exception of extra drive and block object interfaces.

It's important to provide udisks_module_get_block_object_interface_types() and udisks_module_new_block_object_interface() methods (or drive respectively) always in pairs as the UDisksLinuxBlockObject and UDisksLinuxDriveObject machinery needs to register available interface skeleton types first and subsequently create target interfaces for each specified type and route uevents onto. There can be only one extra interface of a given type on a single UDisksLinuxBlockObject or UDisksLinuxDriveObject object.

In case of an existing interface for a particular type uevents are routed through the udisks_module_object_process_uevent() method of a UDisksModuleObject interface that the newly created GDBusInterfaceSkeleton interface has to implement. This call is supposed to process updated information and indicate via the return keep argument whether the particular interface is valid or should be removed from the object.

In case no GDBusInterfaceSkeleton interface of a given type is attached on the particular object, udisks_module_new_block_object_interface() or udisks_module_new_drive_object_interface() methods respectively are called in attempt to create new one. These methods are supposed to check whether the interface type is applicable for the current object and return NULL if not.

Exposing independent module objects on the master UDisks object manager as another way of daemon extensibility works in a similar way - please see udisks_module_new_object() for detailed description.

Functions

UDisksModuleIDFunc ()

gchar *
(*UDisksModuleIDFunc) (void);

Function prototype that is called by UDisksModuleManager to get unique module identifier. No initialization is supposed to be done at this point.

Returns

The module ID string. Free with g_free().

[transfer full]

Since: 2.0


UDisksModuleNewFunc ()

UDisksModule *
(*UDisksModuleNewFunc) (UDisksDaemon *daemon,
                        GCancellable *cancellable,
                        GError **error);

Function prototype that creates a new UDisksModule instance. Module initialization is done at this point. This is a failable method call that properly reports module initialization failure.

Parameters

daemon

A UDisksDaemon instance.

 

cancellable

A GCancellable or NULL.

[nullable]

error

Return location for error or NULL.

 

Returns

A UDisksModule object or NULL if error is set. Free with g_object_unref().

[transfer full]

Since: 2.9


udisks_module_get_name ()

const gchar *
udisks_module_get_name (UDisksModule *module);

Gets the name of the module .

Parameters

module

A UDisksModule.

 

Returns

A module name string. Do not free, the string is owned by module .

[transfer none]

Since: 2.9.0


udisks_module_new_manager ()

GDBusInterfaceSkeleton *
udisks_module_new_manager (UDisksModule *module);

Creates a new GDBusInterfaceSkeleton instance carrying an additional D-Bus interface to be exported on the UDisksManager object (at the /org/freedesktop/UDisks2/Manager path). It is a fairly simple stateless object not related to any device and serves the purpose of performing general tasks or creating new resources. Only a single manager interface can be provided by each module.

Parameters

module

A UDisksModule.

 

Returns

A new GDBusInterfaceSkeleton. Free with g_object_unref().

[transfer full][nullable]

Since: 2.9.0


udisks_module_new_object ()

GDBusObjectSkeleton **
udisks_module_new_object (UDisksModule *module,
                          UDisksLinuxDevice *device);

Creates one or more GDBusObjectSkeleton objects that implement the UDisksModuleObject interface. Multiple objects may be returned by this method call, e.g. in case more than one object type is needed in order to represent a particular feature.

Objects are exported by UDisksLinuxProvider on the master object manager under the /org/freedesktop/UDisks2 path just like regular block and drive objects. This allows to create brand new object types fully handled by modules and providing custom interfaces. Objects in this scope are meant to be of virtual kind and are pretty flexible in this regard - not necessarily bound to any specific block device or drive. Perhaps even representing a group of resources. For illustration this kind of object may represent a RAID array comprised of several block devices, devices of the same kind such as loop devices or any higher level representation of something else.

Note that it's not currently possible to share module objects across multiple modules with the intention to attach extra interfaces on a foreign module object. In such case each module needs to export its own unique object, no matter if they share or represent similar kind of resource.

This method may be called quite often, for nearly any uevent received. It's done this way for broad flexibility and to give module objects a chance to claim any device needed.

Module objects are supposed to maintain internal list of claimed devices and track their validity, i.e. indicate removal only after all tracked devices are gone. Every module object may claim one or more devices. UDisksLinuxProvider essentially provides uevent routing and guarantees that existing objects are asked first to consider a claim of the device before new object is attempted to be created. This works always in the scope of a particular module, i.e. existing module objects and their claims are always considered separately for each module.

The uevent routing works as follows:

  1. Existing module objects are asked first to process the uevent for a particular device via the udisks_module_object_process_uevent() method on the UDisksModuleObject interface. The method return value and the keep argument control the claim:

    • method return value of FALSE means the object doesn't currently hold the claim of the device and is not interested of making new one. The return value of keep is ignored in this case.

    • method return value of TRUE and the keep return value of FALSE indicates the object is not valid anymore and should be unexported from the object manager.

    • method return value of TRUE and the keep return value of TRUE indicates the object has processed the updated information and remains valid.

  2. In case the device has not been claimed by any existing module object, meaning all the udisks_module_object_process_uevent() method calls from previous step returned FALSE, only then a new object is attempted to be created via this udisks_module_new_object() method call. If there was a claim release in the previous step, no attempt to create new object is made to prevent creating bogus objects for recently released devices.

Parameters

module

A UDisksModule.

 

device

A UDisksLinuxDevice device object.

 

Returns

NULL-terminated array of new GDBusObjectSkeleton objects or NULL when the module is not interested in the device .

[element-type GDBusObjectSkeleton][array zero-terminated=1][nullable][transfer full]

Since: 2.9.0


udisks_module_get_block_object_interface_types ()

GType *
udisks_module_get_block_object_interface_types
                               (UDisksModule *module);

Gets an array of interface skeleton GType types the module provides as additional interfaces for the UDisksLinuxBlockObject. This list is subsequently used by UDisksLinuxBlockObject to track available interfaces and to create new ones via udisks_module_new_block_object_interface().

Parameters

module

A UDisksModule.

 

Returns

A NULL-terminated array of GType types or NULL when the module doesn't handle block object interfaces. Do not free, the data belongs to the module.

[element-type GType][array zero-terminated=1][nullable][transfer none]

Since: 2.9.0


udisks_module_get_drive_object_interface_types ()

GType *
udisks_module_get_drive_object_interface_types
                               (UDisksModule *module);

Gets an array of interface skeleton GType types the module provides as additional interfaces for the UDisksLinuxDriveObject. This list is subsequently used by UDisksLinuxDriveObject to track available interfaces and to create new ones via udisks_module_new_drive_object_interface().

Parameters

module

A UDisksModule.

 

Returns

A NULL-terminated array of GType types or NULL when the module doesn't handle drive object interfaces. Do not free, the data belongs to the module.

[element-type GType][array zero-terminated=1][nullable][transfer none]

Since: 2.9.0


udisks_module_new_block_object_interface ()

GDBusInterfaceSkeleton *
udisks_module_new_block_object_interface
                               (UDisksModule *module,
                                UDisksLinuxBlockObject *object,
                                GType interface_type);

Tries to create a new GDBusInterfaceSkeleton instance of type interface_type that is supposed to be attached on the block object . This method call is also supposed to check whether the desired interface_type is applicable for the current object and return NULL if it's not. The returned instance must implement the UDisksModuleObject interface with the udisks_module_object_process_uevent() method that is used to process uevents and controls whether the interface should be removed or not.

Note that it is important not to take reference to object to avoid circular references. The returned GDBusInterfaceSkeleton will be exported on the object and unexported when no longer valid (typically as a result of a remove uevent). The returned object is responsible to perform cleanup in its destructor as it's not generally guaranteed the remove uevent will be sent prior to that.

Parameters

module

A UDisksModule.

 

object

A UDisksLinuxBlockObject.

 

interface_type

A GType of the desired new interface skeleton.

 

Returns

A new GDBusInterfaceSkeleton instance or NULL when not applicable for the object . Free with g_object_unref().

[transfer full][nullable]

Since: 2.9.0


udisks_module_new_drive_object_interface ()

GDBusInterfaceSkeleton *
udisks_module_new_drive_object_interface
                               (UDisksModule *module,
                                UDisksLinuxDriveObject *object,
                                GType interface_type);

Tries to create a new GDBusInterfaceSkeleton instance of type interface_type that is supposed to be attached on the drive object . This method call is also supposed to check whether the desired interface_type is applicable for the current object and return NULL if it's not. The returned instance must implement the UDisksModuleObject interface with the udisks_module_object_process_uevent() method that is used to process uevents and controls whether the interface should be removed or not.

Note that it is important not to take reference to object to avoid circular references. The returned GDBusInterfaceSkeleton will be exported on the object and unexported when no longer valid (typically as a result of a remove uevent). The returned object is responsible to perform cleanup in its destructor as it's not generally guaranteed the remove uevent will be sent prior to that.

Parameters

module

A UDisksModule.

 

object

A UDisksLinuxDriveObject.

 

interface_type

A GType of the desired new interface skeleton.

 

Returns

A new GDBusInterfaceSkeleton instance or NULL when not applicable for the object . Free with g_object_unref().

[transfer full][nullable]

Since: 2.9.0


udisks_module_track_parent ()

gchar *
udisks_module_track_parent (UDisksModule *module,
                            const gchar *path,
                            gchar **uuid);

Finds a parent block device and returns its object path and UUID. If the return value is NULL, the value of uuid has not been changed. Related to udisks_daemon_get_parent_for_tracking().

Parameters

module

A UDisksModule.

 

path

object path of a child to find parent of

 

uuid

a pointer to return parent UUID string

 

Returns

object path of the parent device. Free with g_free().

[transfer full][nullable]

Since: 2.9.0


udisks_module_get_daemon ()

UDisksDaemon *
udisks_module_get_daemon (UDisksModule *module);

Gets the daemon used by module .

Parameters

module

A UDisksModule.

 

Returns

A UDisksDaemon. Do not free, the object is owned by module .

[transfer none]

Since: 2.9.0


udisks_module_object_process_uevent ()

gboolean
udisks_module_object_process_uevent (UDisksModuleObject *object,
                                     const gchar *action,
                                     UDisksLinuxDevice *device,
                                     gboolean *keep);

A UDisksModuleObject method that is called by UDisksLinuxBlockObject, UDisksLinuxDriveObject and UDisksLinuxProvider to process a uevent on exported module objects and interfaces and control their validity.

Upon receiving a uevent the object implementing the UDisksModuleObject interface is responsible for processing updated information and indicate whether the object is still valid or not.

This function may be called quite often and since uevent processing is currently serialized by UDisksLinuxProvider this method call should minimize its processing time as much as possible.

See related udisks_module_new_object(), udisks_module_new_block_object_interface() and udisks_module_new_drive_object_interface() methods for information how uevent routing is done and what effect the return values have.

Set keep to FALSE if the object or interface should be unexported and removed, TRUE if the object or interface should be kept around. The return value of keep is ignored when the return value from this method is FALSE. These return values should align with the uevent action , i.e. a keep return value of FALSE is expected for a remove action . Note that the remove uevent is not always sent to block objects and the daemon may opt for direct object destruction (for which the object should be prepared to perform proper cleanup within its destructor).

Parameters

object

A UDisksModuleObject.

 

action

uevent action, common values are add, change and remove or NULL

 

device

A UDisksLinuxDevice device object or NULL if the device hasn't changed.

 

keep

A return value whether to keep the object around or not.

 

Returns

TRUE in case the uevent was processed, FALSE when the device is not applicable for the object or interface.

Since: 2.0


udisks_module_object_housekeeping ()

gboolean
udisks_module_object_housekeeping (UDisksModuleObject *object,
                                   guint secs_since_last,
                                   GCancellable *cancellable,
                                   GError **error);

A UDisksModuleObject method that is called periodically (every ten minutes or so) by UDisksLinuxProvider to perform module housekeeping tasks such as refreshing ATA SMART data.

The method runs in a dedicated thread and is allowed to perform blocking I/O.

Long-running tasks should periodically check cancellable to see if they have been cancelled.

Parameters

object

A UDisksModuleObject.

 

secs_since_last

Number of seconds since the last housekeeping or 0 if the first housekeeping ever.

 

cancellable

A GCancellable or NULL.

 

error

Return location for error or NULL.

 

Returns

TRUE if the operation succeeded, FALSE if error is set.

Since: 2.0

Types and Values

struct UDisksModule

struct UDisksModule {
};

The UDisksModule structure contains only private data and should only be accessed using the provided API.


struct UDisksModuleClass

struct UDisksModuleClass {
  GObjectClass parent_class;

  GDBusInterfaceSkeleton  * (*new_manager)                      (UDisksModule           *module);
  GDBusObjectSkeleton    ** (*new_object)                       (UDisksModule           *module,
                                                                 UDisksLinuxDevice      *device);
  gchar                   * (*track_parent)                     (UDisksModule           *module,
                                                                 const gchar            *path,
                                                                 gchar                 **uuid);
  GType                   * (*get_block_object_interface_types) (UDisksModule           *module);
  GType                   * (*get_drive_object_interface_types) (UDisksModule           *module);
  GDBusInterfaceSkeleton  * (*new_block_object_interface)       (UDisksModule           *module,
                                                                 UDisksLinuxBlockObject *object,
                                                                 GType                   interface_type);
  GDBusInterfaceSkeleton  * (*new_drive_object_interface)       (UDisksModule           *module,
                                                                 UDisksLinuxDriveObject *object,
                                                                 GType                   interface_type);
  void                      (*handle_uevent)                    (UDisksModule           *module,
                                                                 UDisksLinuxDevice      *device);
};

Class structure for UDisksModule.

Members

new_manager ()

Virtual function for udisks_module_new_manager(). The default implementation returns NULL.

 

new_object ()

Virtual function for udisks_module_new_object(). The default implementation returns NULL.

 

track_parent ()

Virtual function for udisks_module_track_parent(). The default implementation returns NULL.

 

get_block_object_interface_types ()

Virtual function for udisks_module_get_block_object_interface_types(). The default implementation returns NULL.

 

get_drive_object_interface_types ()

Virtual function for udisks_module_get_drive_object_interface_types(). The default implementation returns NULL.

 

new_block_object_interface ()

Virtual function for udisks_module_new_block_object_interface(). The default implementation returns NULL.

 

new_drive_object_interface ()

Virtual function for udisks_module_new_drive_object_interface(). The default implementation returns NULL.

 

handle_uevent ()

Virtual function for udisks_module_handle_uevent(). The default implementation returns NULL.

 

UDisksModuleObject

typedef struct _UDisksModuleObject UDisksModuleObject;

The UDisksModuleObject structure contains only private data and should only be accessed using the provided API.


struct UDisksModuleObjectIface

struct UDisksModuleObjectIface {
  GTypeInterface parent_iface;

  gboolean (*process_uevent) (UDisksModuleObject  *object,
                              const gchar         *action,
                              UDisksLinuxDevice   *device,
                              gboolean            *keep);

  gboolean (*housekeeping) (UDisksModuleObject  *object,
                            guint                secs_since_last,
                            GCancellable        *cancellable,
                            GError             **error);
};

Object interface structure for UDisksModuleObject.

Members

GTypeInterface parent_iface;

The parent interface.

 

process_uevent ()

Virtual function for udisks_module_object_process_uevent().

 

housekeeping ()

Virtual function for udisks_module_object_housekeeping().