Skip to content

Commit

Permalink
lvm: Enhancements for LVM2 RAID support
Browse files Browse the repository at this point in the history
  • Loading branch information
mvollmer committed May 13, 2022
1 parent b4a260a commit 39a00f3
Show file tree
Hide file tree
Showing 15 changed files with 446 additions and 16 deletions.
77 changes: 76 additions & 1 deletion modules/lvm2/data/org.freedesktop.UDisks2.lvm2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@
-->
<property name="NeedsPolling" type="b" access="read"/>

<!-- MissingPhysicalVolumes:
A list of the UUIDs of missing physical volumes.
-->
<property name="MissingPhysicalVolumes" type="as" access="read"/>

<!-- Poll:
Make sure that all properties of this volume group and of all
Expand Down Expand Up @@ -251,13 +257,26 @@
<arg name="options" direction="in" type="a{sv}"/>
</method>

<!-- RemoveMissingPhysicalVolumes:
Forget about all physical volumes that went missing.
No additional options are currently defined.
-->
<method name="RemoveMissingPhysicalVolumes">
<arg name="options" direction="in" type="a{sv}"/>
</method>

<!-- CreatePlainVolume:
@name: The name of the new logical volume.
@size: The size.
@options: Additional options.
@result: The object path of the new logical volume.
Create a 'normal' new logical volume.
Create a 'normal' new logical volume. Calling this method is
equivalent to calling CreatePlainVolumeWithLayout with
"linear" as the layout type and an empty array of physical
volumes.
No additional options are currently defined.
-->
Expand All @@ -268,6 +287,29 @@
<arg name="result" type="o" direction="out"/>
</method>

<!-- CreatePlainVolumeWithLayout:
@name: The name of the new logical volume.
@size: The size.
@layout: The layout type, like "linear", "raid5"
@pvs: The physical volumes to use
@options: Additional options.
@result: The object path of the new logical volume.
Create a 'normal' new logical volume with the given layout
type on the given physical volumes. It is okay to leave
"pvs" empty; LVM2 will then choose suitable ones on its own.
No additional options are currently defined.
-->
<method name="CreatePlainVolumeWithLayout">
<arg name="name" type="s" direction="in"/>
<arg name="size" type="t" direction="in"/>
<arg name="layout" type="s" direction="in"/>
<arg name="pvs" type="ao" direction="in"/>
<arg name="options" type="a{sv}" direction="in"/>
<arg name="result" type="o" direction="out"/>
</method>

<!-- CreateThinPoolVolume:
@name: The name of the new logical volume.
@size: The total size.
Expand Down Expand Up @@ -436,6 +478,23 @@
-->
<property name="Type" type="s" access="read"/>

<!-- Layout:
The layout of this logical volume, such as "linear", "raid5",
etc.
-->
<property name="Layout" type="s" access="read"/>

<!-- SyncRatio:
How far along the logical volume is with resynchronizing. A
value of 1.0 corresponds to fully synchronized and indicates
that no operation is in progress. This is only relevant for
logical volumes with some redundancy, like "raid1" or
"raid5".
-->
<property name="SyncRatio" type="d" access="read"/>

<!-- ThinPool:
For a thin volume, the object path of its pool.
Expand Down Expand Up @@ -557,6 +616,22 @@
<arg name="options" type="a{sv}" direction="in"/>
</method>

<!-- Repair:
@pvs: A list of physical volumes to use for the repair.
@options: Additional options.
Attempt a repair of this logical volume after it has lost
some physical volumes. Space is allocated from the given
physical volumes as needed. A empty list means to allocate
from all physical volumes.
No additional options are currently defined.
-->
<method name="Repair">
<arg name="pvs" type="ao" direction="in"/>
<arg name="options" direction="in" type="a{sv}"/>
</method>

<!-- CreateSnapshot:
@name: The name of the snapshot.
@size: The size of the backing store for the snapshot, in bytes.
Expand Down
11 changes: 10 additions & 1 deletion modules/lvm2/jobhelpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ gboolean lvcreate_job_func (UDisksThreadedJob *job,
GError **error)
{
LVJobData *data = user_data;
return bd_lvm_lvcreate (data->vg_name, data->new_lv_name, data->new_lv_size, NULL /* type */, NULL /* pvs */, NULL /* extra_args */, error);
return bd_lvm_lvcreate (data->vg_name, data->new_lv_name, data->new_lv_size, data->new_lv_layout, data->new_lv_pvs, NULL /* extra_args */, error);
}

gboolean lvcreate_thin_pool_job_func (UDisksThreadedJob *job,
Expand Down Expand Up @@ -207,6 +207,15 @@ gboolean lv_vdo_deduplication_job_func (UDisksThreadedJob *job,
return bd_lvm_vdo_disable_deduplication (data->vg_name, data->lv_name, NULL /* extra_args */, error);
}

gboolean lvrepair_job_func (UDisksThreadedJob *job,
GCancellable *cancellable,
gpointer user_data,
GError **error)
{
LVJobData *data = user_data;
return bd_lvm_lvrepair (data->vg_name, data->lv_name, data->new_lv_pvs, NULL /* extra_args */, error);
}

gboolean vgcreate_job_func (UDisksThreadedJob *job,
GCancellable *cancellable,
gpointer user_data,
Expand Down
7 changes: 7 additions & 0 deletions modules/lvm2/jobhelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ typedef struct {
const gchar *vg_name;
const gchar *lv_name;
const gchar *new_lv_name;
const gchar *new_lv_layout;
const gchar **new_lv_pvs;
const gchar *pool_name;
guint64 new_lv_size;
guint64 virtual_size;
Expand Down Expand Up @@ -98,6 +100,11 @@ gboolean lvresize_job_func (UDisksThreadedJob *job,
gpointer user_data,
GError **error);

gboolean lvrepair_job_func (UDisksThreadedJob *job,
GCancellable *cancellable,
gpointer user_data,
GError **error);

gboolean lvactivate_job_func (UDisksThreadedJob *job,
GCancellable *cancellable,
gpointer user_data,
Expand Down
71 changes: 71 additions & 0 deletions modules/lvm2/udiskslinuxlogicalvolume.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ udisks_linux_logical_volume_update (UDisksLinuxLogicalVolume *logical_volume
UDisksLinuxVolumeGroupObject *group_object,
BDLVMLVdata *lv_info,
BDLVMLVdata *meta_lv_info,
BDLVMLVdata **all_lv_infos,
gboolean *needs_polling_ret)
{
UDisksLogicalVolume *iface;
Expand Down Expand Up @@ -182,6 +183,16 @@ udisks_linux_logical_volume_update (UDisksLinuxLogicalVolume *logical_volume
active = TRUE;
}
udisks_logical_volume_set_type_ (iface, type);
udisks_logical_volume_set_layout (iface, lv_info->segtype);
if (g_str_has_prefix (lv_info->segtype, "raid") || g_strcmp0 (lv_info->segtype, "mirror"))
{
udisks_logical_volume_set_sync_ratio (iface, lv_info->copy_percent / 100.0);
if (lv_info->copy_percent != 100)
*needs_polling_ret = TRUE;
}
else
udisks_logical_volume_set_sync_ratio (iface, 1.0);

udisks_logical_volume_set_active (iface, active);
udisks_logical_volume_set_size (iface, size);

Expand Down Expand Up @@ -508,6 +519,65 @@ handle_delete (UDisksLogicalVolume *_volume,

/* ---------------------------------------------------------------------------------------------------- */

static gboolean
handle_repair (UDisksLogicalVolume *_volume,
GDBusMethodInvocation *invocation,
const gchar *const *arg_pvs,
GVariant *options)
{
GError *error = NULL;
UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (_volume);
UDisksLinuxLogicalVolumeObject *object = NULL;
UDisksDaemon *daemon = NULL;
uid_t caller_uid;
UDisksLinuxVolumeGroupObject *group_object;
LVJobData data = {0};
g_auto(GStrv) pvs = NULL;

if (!common_setup (volume, invocation, options,
N_("Authentication is required to delete a logical volume"),
&object, &daemon, &caller_uid))
goto out;

group_object = udisks_linux_logical_volume_object_get_volume_group (object);
data.vg_name = udisks_linux_volume_group_object_get_name (group_object);
data.lv_name = udisks_linux_logical_volume_object_get_name (object);
pvs = udisks_daemon_util_lvm2_gather_pvs (daemon, group_object, arg_pvs, &error);
if (pvs == NULL)
{
g_dbus_method_invocation_return_gerror (invocation, error);
goto out;
}
data.new_lv_pvs = (const gchar **)pvs;

if (!udisks_daemon_launch_threaded_job_sync (daemon,
UDISKS_OBJECT (object),
"lvm-lvol-repair",
caller_uid,
lvrepair_job_func,
&data,
NULL, /* user_data_free_func */
NULL, /* GCancellable */
&error))
{
g_dbus_method_invocation_return_error (invocation,
UDISKS_ERROR,
UDISKS_ERROR_FAILED,
"Error repairing logical volume: %s",
error->message);
g_clear_error (&error);
goto out;
}

udisks_logical_volume_complete_repair (_volume, invocation);

out:
g_clear_object (&object);
return TRUE;
}

/* ---------------------------------------------------------------------------------------------------- */

static UDisksObject *
wait_for_logical_volume_object (UDisksDaemon *daemon,
gpointer user_data)
Expand Down Expand Up @@ -1054,6 +1124,7 @@ logical_volume_iface_init (UDisksLogicalVolumeIface *iface)
iface->handle_delete = handle_delete;
iface->handle_rename = handle_rename;
iface->handle_resize = handle_resize;
iface->handle_repair = handle_repair;
iface->handle_activate = handle_activate;
iface->handle_deactivate = handle_deactivate;
iface->handle_create_snapshot = handle_create_snapshot;
Expand Down
1 change: 1 addition & 0 deletions modules/lvm2/udiskslinuxlogicalvolume.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ void udisks_linux_logical_volume_update (UDisksLinuxLogicalVol
UDisksLinuxVolumeGroupObject *group_object,
BDLVMLVdata *lv_info,
BDLVMLVdata *meta_lv_info,
BDLVMLVdata **all_lv_infos,
gboolean *needs_polling_ret);
void udisks_linux_logical_volume_update_etctabs (UDisksLinuxLogicalVolume *logical_volume,
UDisksLinuxVolumeGroupObject *group_object);
Expand Down
3 changes: 2 additions & 1 deletion modules/lvm2/udiskslinuxlogicalvolumeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,14 +300,15 @@ void
udisks_linux_logical_volume_object_update (UDisksLinuxLogicalVolumeObject *object,
BDLVMLVdata *lv_info,
BDLVMLVdata *meta_lv_info,
BDLVMLVdata **all_lv_infos,
BDLVMVDOPooldata *vdo_info,
gboolean *needs_polling_ret)
{
g_return_if_fail (UDISKS_IS_LINUX_LOGICAL_VOLUME_OBJECT (object));

udisks_linux_logical_volume_update (UDISKS_LINUX_LOGICAL_VOLUME (object->iface_logical_volume),
object->volume_group,
lv_info, meta_lv_info,
lv_info, meta_lv_info, all_lv_infos,
needs_polling_ret);

if (vdo_info)
Expand Down
1 change: 1 addition & 0 deletions modules/lvm2/udiskslinuxlogicalvolumeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const gchar *udisks_linux_logical_volume_object_get_name
void udisks_linux_logical_volume_object_update (UDisksLinuxLogicalVolumeObject *object,
BDLVMLVdata *lv_info,
BDLVMLVdata *meta_lv_info,
BDLVMLVdata **all_lv_infos,
BDLVMVDOPooldata *vdo_info,
gboolean *needs_polling_ret);
void udisks_linux_logical_volume_object_update_etctabs (UDisksLinuxLogicalVolumeObject *object);
Expand Down
4 changes: 3 additions & 1 deletion modules/lvm2/udiskslinuxmodulelvm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,10 @@ lvm_update_vgs (GObject *source_obj,
}

for (pvs_p = pvs; *pvs_p; pvs_p++)
if (g_strcmp0 ((*pvs_p)->vg_name, vg_name) == 0)
{
if (g_strcmp0 ((*pvs_p)->vg_name, vg_name) == 0)
vg_pvs = g_slist_prepend (vg_pvs, bd_lvm_pvdata_copy (*pvs_p));
}

udisks_linux_volume_group_object_update (group, *vgs_p, vg_pvs);
}
Expand Down
Loading

0 comments on commit 39a00f3

Please sign in to comment.