## UDisksModule

UDisksModule — Daemon module

## Functions

gchar * | (*UDisksModuleIDFunc) ()
UDisksModule * | (*UDisksModuleNewFunc) ()
const gchar * | udisks_module_get_name ()
GDBusInterfaceSkeleton * | udisks_module_new_manager ()
GDBusObjectSkeleton ** | udisks_module_new_object ()
GType * | udisks_module_get_block_object_interface_types ()
GType * | udisks_module_get_drive_object_interface_types ()
GDBusInterfaceSkeleton * | udisks_module_new_block_object_interface ()
GDBusInterfaceSkeleton * | udisks_module_new_drive_object_interface ()
gchar * | udisks_module_track_parent ()
UDisksDaemon * | udisks_module_get_daemon ()
gboolean | udisks_module_object_process_uevent ()
gboolean | udisks_module_object_housekeeping ()

## Types and Values

struct | UDisksModule
struct | UDisksModuleClass
| UDisksModuleObject
struct | UDisksModuleObjectIface

## 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);
    };

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

### 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()`. |