From 74a6ef72be33ef8abb64462c33c6b1dd02e4b125 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:11:32 +0100 Subject: [PATCH 01/25] lvm: Fix buffer overrun in _vgcfgbackup_restore The args array had 6 elements but when both file and global_config_str are provided, all 6 slots are used leaving no room for the NULL terminator. Increase the array size to 7. Co-Authored-By: Claude Opus 4.6 --- src/plugins/lvm/lvm-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/lvm/lvm-common.c b/src/plugins/lvm/lvm-common.c index 9b0481be5..b3ee2721e 100644 --- a/src/plugins/lvm/lvm-common.c +++ b/src/plugins/lvm/lvm-common.c @@ -789,7 +789,7 @@ gchar* bd_lvm_config_get (const gchar *section, const gchar *setting, const gcha } gboolean _vgcfgbackup_restore (const gchar *command, const gchar *vg_name, const gchar *file, const BDExtraArg **extra, GError **error) { - const gchar *args[6] = {"lvm", NULL, NULL, NULL, NULL, NULL}; + const gchar *args[7] = {"lvm", NULL, NULL, NULL, NULL, NULL, NULL}; guint next_arg = 1; g_autofree gchar *config_arg = NULL; From a613b6b841e9057de26f12ae4a156941453abd6b Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:12:20 +0100 Subject: [PATCH 02/25] lvm-dbus: Fix duplicate feature index for VDO and writecache FEATURES_VDO and FEATURES_WRITECACHE were both defined as 0, so they shared the same bitmask. This caused writecache availability detection to be incorrect. Change FEATURES_WRITECACHE to 1 to match lvm.c. Co-Authored-By: Claude Opus 4.6 --- src/plugins/lvm/lvm-dbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/lvm/lvm-dbus.c b/src/plugins/lvm/lvm-dbus.c index 31f64676a..b5b5085e3 100644 --- a/src/plugins/lvm/lvm-dbus.c +++ b/src/plugins/lvm/lvm-dbus.c @@ -278,7 +278,7 @@ static const DBusDep dbus_deps[DBUS_DEPS_LAST] = { #define FEATURES_VDO 0 #define FEATURES_VDO_MASK (1 << FEATURES_VDO) -#define FEATURES_WRITECACHE 0 +#define FEATURES_WRITECACHE 1 #define FEATURES_WRITECACHE_MASK (1 << FEATURES_WRITECACHE) #define FEATURES_LAST 2 From cac5f0f5bcda83335049c5f31a6df677108b1ed0 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:17:14 +0100 Subject: [PATCH 03/25] lvm-dbus: Fix NULL dereferences on failed D-Bus calls In call_lvm_method_sync, get_object_property could return NULL but its result was passed directly to g_variant_get, causing a crash. Add a NULL check and proper error reporting. In get_lvm_object_properties, g_dbus_connection_call_sync could return NULL on failure but the result was used without checking. Return NULL early to let the already-set GError propagate to the caller. Co-Authored-By: Claude Opus 4.6 --- src/plugins/lvm/lvm-dbus.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/lvm/lvm-dbus.c b/src/plugins/lvm/lvm-dbus.c index b5b5085e3..9c29b601d 100644 --- a/src/plugins/lvm/lvm-dbus.c +++ b/src/plugins/lvm/lvm-dbus.c @@ -821,6 +821,15 @@ static gboolean call_lvm_method_sync (const gchar *obj, const gchar *intf, const g_free (log_msg); } else { ret = get_object_property (task_path, JOB_INTF, "GetError", &l_error); + if (!ret) { + if (!l_error) + g_set_error (&l_error, BD_LVM_ERROR, BD_LVM_ERROR_FAIL, + "Failed to get error from '%s' method of the '%s' object", + method, obj); + bd_utils_report_finished (prog_id, l_error->message); + g_propagate_error (error, l_error); + return FALSE; + } g_variant_get (ret, "(is)", &error_code, &error_msg); if (error_code != 0) { if (error_msg) { @@ -941,6 +950,8 @@ static GVariant* get_lvm_object_properties (const gchar *obj_id, const gchar *if ret = g_dbus_connection_call_sync (bus, LVM_BUS_NAME, MANAGER_OBJ, MANAGER_INTF, "LookUpByLvmId", args, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (!ret) + return NULL; g_variant_get (ret, "(o)", &obj_path); g_variant_unref (ret); From 4829a238d95117ebe887fe191a2778738113943b Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:21:58 +0100 Subject: [PATCH 04/25] lvm: Route pvmove through call_lvm_and_report_progress bd_lvm_pvmove was calling bd_utils_exec_and_report_progress directly, bypassing global_config_str and global_devices_str that are applied by the other call_lvm_* helpers. Add a new call_lvm_and_report_progress helper that prepends "lvm", applies global config/devices, and calls bd_utils_exec_and_report_progress. Co-Authored-By: Claude Opus 4.6 --- src/plugins/lvm/lvm.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/plugins/lvm/lvm.c b/src/plugins/lvm/lvm.c index 76c4cd7e7..c0937aa37 100644 --- a/src/plugins/lvm/lvm.c +++ b/src/plugins/lvm/lvm.c @@ -445,6 +445,43 @@ static gboolean call_lvm_and_capture_output (const gchar **args, const BDExtraAr return success; } +static gboolean call_lvm_and_report_progress (const gchar **args, const BDExtraArg **extra, BDUtilsProgExtract prog_extract, gint *proc_status, GError **error) { + gboolean success = FALSE; + guint i = 0; + guint args_length = g_strv_length ((gchar **) args); + g_autofree gchar *config_arg = NULL; + g_autofree gchar *devices_arg = NULL; + + if (!check_deps (&avail_deps, DEPS_LVM_MASK, deps, DEPS_LAST, &deps_check_lock, error)) + return FALSE; + + /* don't allow global config string changes during the run */ + g_mutex_lock (&global_config_lock); + + /* allocate enough space for the args plus "lvm", "--config", "--devices" and NULL */ + const gchar **argv = g_new0 (const gchar*, args_length + 4); + + /* construct argv from args with "lvm" prepended */ + argv[0] = "lvm"; + for (i=0; i < args_length; i++) + argv[i+1] = args[i]; + if (global_config_str) { + config_arg = g_strdup_printf ("--config=%s", global_config_str); + argv[++args_length] = config_arg; + } + if (global_devices_str) { + devices_arg = g_strdup_printf ("--devices=%s", global_devices_str); + argv[++args_length] = devices_arg; + } + argv[++args_length] = NULL; + + success = bd_utils_exec_and_report_progress (argv, extra, prog_extract, proc_status, error); + g_mutex_unlock (&global_config_lock); + g_free (argv); + + return success; +} + /** * parse_lvm_vars: * @str: string to parse @@ -1008,7 +1045,7 @@ gboolean bd_lvm_pvmove (const gchar *src, const gchar *dest, const BDExtraArg ** if (dest) args[4] = dest; - return bd_utils_exec_and_report_progress (args, extra, extract_pvmove_progress, &status, error); + return call_lvm_and_report_progress (args, extra, extract_pvmove_progress, &status, error); } /** From 776cc40dffe6fe5a9c635cc62fb4f50aa2deaa50 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:26:55 +0100 Subject: [PATCH 05/25] lvm-dbus: Free and copy data_lvs, metadata_lvs, and segs in LVdata bd_lvm_lvdata_free was missing g_strfreev calls for data_lvs and metadata_lvs, and free_segs for segs, leaking memory every time an LVdata struct was freed. bd_lvm_lvdata_copy was also not copying these fields. Add the missing calls to match the non-dbus lvm.c. Co-Authored-By: Claude Opus 4.6 --- src/plugins/lvm/lvm-dbus.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/lvm/lvm-dbus.c b/src/plugins/lvm/lvm-dbus.c index 9c29b601d..ee0bf92b1 100644 --- a/src/plugins/lvm/lvm-dbus.c +++ b/src/plugins/lvm/lvm-dbus.c @@ -166,6 +166,9 @@ BDLVMLVdata* bd_lvm_lvdata_copy (BDLVMLVdata *data) { new_data->metadata_percent = data->metadata_percent; new_data->copy_percent = data->copy_percent; new_data->lv_tags = g_strdupv (data->lv_tags); + new_data->data_lvs = g_strdupv (data->data_lvs); + new_data->metadata_lvs = g_strdupv (data->metadata_lvs); + new_data->segs = copy_segs (data->segs); return new_data; } @@ -185,6 +188,9 @@ void bd_lvm_lvdata_free (BDLVMLVdata *data) { g_free (data->roles); g_free (data->move_pv); g_strfreev (data->lv_tags); + g_strfreev (data->data_lvs); + g_strfreev (data->metadata_lvs); + free_segs (data->segs); g_free (data); } From d9be439bdfbe10ed4f98617d86a105064a51456f Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:30:47 +0100 Subject: [PATCH 06/25] crypto: Add BD_CRYPTO_TECH_MODE_MODIFY to LUKS supported modes Several LUKS functions (set_label, set_uuid, convert, set_persistent_flags) are documented as requiring BD_CRYPTO_TECH_MODE_MODIFY, but this mode was not included in the bd_crypto_is_tech_avail bitmask for BD_CRYPTO_TECH_LUKS. Callers checking tech availability before using these functions would get a false "not available" result. Co-Authored-By: Claude Opus 4.6 --- src/plugins/crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c index 0968d5090..b55d49e12 100644 --- a/src/plugins/crypto.c +++ b/src/plugins/crypto.c @@ -381,10 +381,10 @@ gboolean bd_crypto_is_tech_avail (BDCryptoTech tech, guint64 mode, GError **erro case BD_CRYPTO_TECH_LUKS: ret = mode & (BD_CRYPTO_TECH_MODE_CREATE|BD_CRYPTO_TECH_MODE_OPEN_CLOSE|BD_CRYPTO_TECH_MODE_QUERY| BD_CRYPTO_TECH_MODE_ADD_KEY|BD_CRYPTO_TECH_MODE_REMOVE_KEY|BD_CRYPTO_TECH_MODE_RESIZE| - BD_CRYPTO_TECH_MODE_SUSPEND_RESUME|BD_CRYPTO_TECH_MODE_BACKUP_RESTORE); + BD_CRYPTO_TECH_MODE_SUSPEND_RESUME|BD_CRYPTO_TECH_MODE_BACKUP_RESTORE|BD_CRYPTO_TECH_MODE_MODIFY); if (ret != mode) { g_set_error_literal (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_TECH_UNAVAIL, - "Only 'create', 'open', 'query', 'add-key', 'remove-key', 'resize', 'suspend-resume', 'backup-restore' supported for LUKS"); + "Only 'create', 'open', 'query', 'add-key', 'remove-key', 'resize', 'suspend-resume', 'backup-restore', 'modify' supported for LUKS"); return FALSE; } else return TRUE; From 55b0999aa036e630f5534a584936769feac05d8a Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:33:51 +0100 Subject: [PATCH 07/25] fs: Guard against division by zero in f2fs and xfs resize f2fs_resize_device divides by info->sector_size which can be 0 for older dump.f2fs versions. Add a check and return an error instead of crashing. Apply the same guard for xfs_resize_device with block_size, and also fix a memory leak of xfs_info when fs_mount fails. Co-Authored-By: Claude Opus 4.6 --- src/plugins/fs/generic.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/plugins/fs/generic.c b/src/plugins/fs/generic.c index 87ed8b0ec..104cae419 100644 --- a/src/plugins/fs/generic.c +++ b/src/plugins/fs/generic.c @@ -820,9 +820,18 @@ static gboolean xfs_resize_device (const gchar *device, guint64 new_size, const return FALSE; } + if (xfs_info->block_size == 0) { + g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_FAIL, + "Failed to get block size for device '%s'", device); + bd_fs_xfs_info_free (xfs_info); + return FALSE; + } + mountpoint = fs_mount (device, "xfs", FALSE, &unmount, error); - if (!mountpoint) + if (!mountpoint) { + bd_fs_xfs_info_free (xfs_info); return FALSE; + } new_size = (new_size + xfs_info->block_size - 1) / xfs_info->block_size; bd_fs_xfs_info_free (xfs_info); @@ -857,6 +866,13 @@ static gboolean f2fs_resize_device (const gchar *device, guint64 new_size, GErro return FALSE; } + if (info->sector_size == 0) { + g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_FAIL, + "Failed to get sector size for device '%s'", device); + bd_fs_f2fs_info_free (info); + return FALSE; + } + /* round to nearest sector_size multiple */ new_size = (new_size + info->sector_size - 1) / info->sector_size; From 5a32a9653f9977a9f421a4666c871d5cd3202ad5 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:43:03 +0100 Subject: [PATCH 08/25] dm: Move sys_path construction after NULL check in bd_dm_name_from_node The g_autofree initializer called g_strdup_printf with dm_node before the NULL check. Passing NULL to %s is undefined behavior per the C standard even though most implementations substitute "(null)". Move the path construction after the validation to avoid UB and ensure the correct error message is returned. Co-Authored-By: Claude Opus 4.6 --- src/plugins/dm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/dm.c b/src/plugins/dm.c index f829fbee1..58b390333 100644 --- a/src/plugins/dm.c +++ b/src/plugins/dm.c @@ -176,7 +176,7 @@ gboolean bd_dm_remove (const gchar *map_name, GError **error) { gchar* bd_dm_name_from_node (const gchar *dm_node, GError **error) { gchar *ret = NULL; gboolean success = FALSE; - g_autofree gchar *sys_path = g_strdup_printf ("/sys/class/block/%s/dm/name", dm_node); + g_autofree gchar *sys_path = NULL; if (!dm_node || strlen (dm_node) == 0) { g_set_error_literal (error, BD_DM_ERROR, BD_DM_ERROR_DEVICE_NOEXIST, @@ -184,6 +184,8 @@ gchar* bd_dm_name_from_node (const gchar *dm_node, GError **error) { return NULL; } + sys_path = g_strdup_printf ("/sys/class/block/%s/dm/name", dm_node); + if (access (sys_path, R_OK) != 0) { g_set_error_literal (error, BD_DM_ERROR, BD_DM_ERROR_SYS, "Failed to access dm node's parameters under /sys"); From 81997d52c1fa831f5e2c09bb5a836df2ef701a58 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:47:11 +0100 Subject: [PATCH 09/25] python: Fix exact exception type matching in ErrorProxy The exact type match in the exception transformation code compared the entire self._tr_excs list to e_type instead of comparing each entry's exception type (tr_t[0]). This always evaluated to False, making the exact match dead code and falling through to the isinstance check every time. Co-Authored-By: Claude Opus 4.6 --- src/python/gi/overrides/BlockDev.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/gi/overrides/BlockDev.py b/src/python/gi/overrides/BlockDev.py index b084dea48..a968a31ba 100644 --- a/src/python/gi/overrides/BlockDev.py +++ b/src/python/gi/overrides/BlockDev.py @@ -1279,7 +1279,7 @@ def wrapped(*args, **kwargs): raise xrule.new_exc(msg) # try to find exact type match - transform = next((tr_t for tr_t in self._tr_excs if self._tr_excs == e_type), None) + transform = next((tr_t for tr_t in self._tr_excs if tr_t[0] == e_type), None) if not transform: # no exact match, but we still caught the exception -> must be some child class transform = next(tr_t for tr_t in self._tr_excs if isinstance(e, tr_t[0])) From b78e96b665c1da68b9dd0eaf33a6bbd505d7492d Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:55:49 +0100 Subject: [PATCH 10/25] crypto: Check ioctl return value when getting entropy level The return value of ioctl(RNDGETENTCNT) was not checked. If the ioctl failed, current_entropy would stay at 0 causing the while loop to spin forever. Check the return value and log a warning on failure. Co-Authored-By: Claude Opus 4.6 --- src/plugins/crypto.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c index b55d49e12..8bd0a9244 100644 --- a/src/plugins/crypto.c +++ b/src/plugins/crypto.c @@ -1023,11 +1023,31 @@ gboolean _crypto_luks_format (const gchar *device, if (min_entropy > 0) { dev_random_fd = open ("/dev/random", O_RDONLY); if (dev_random_fd >= 0) { - ioctl (dev_random_fd, RNDGETENTCNT, ¤t_entropy); + if (ioctl (dev_random_fd, RNDGETENTCNT, ¤t_entropy) < 0) { + g_set_error (&l_error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_FORMAT_FAILED, + "Failed to get random data entropy level: %s", + strerror_l (errno, c_locale)); + close (dev_random_fd); + crypt_free (cd); + g_strfreev (cipher_specs); + bd_utils_report_finished (progress_id, l_error->message); + g_propagate_error (error, l_error); + return FALSE; + } while (current_entropy < min_entropy) { bd_utils_report_progress (progress_id, 0, "Waiting for enough random data entropy"); sleep (1); - ioctl (dev_random_fd, RNDGETENTCNT, ¤t_entropy); + if (ioctl (dev_random_fd, RNDGETENTCNT, ¤t_entropy) < 0) { + g_set_error (&l_error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_FORMAT_FAILED, + "Failed to get random data entropy level: %s", + strerror_l (errno, c_locale)); + close (dev_random_fd); + crypt_free (cd); + g_strfreev (cipher_specs); + bd_utils_report_finished (progress_id, l_error->message); + g_propagate_error (error, l_error); + return FALSE; + } } close (dev_random_fd); } else { From b3a6f7c86976e56ca2d3212fea04d4ea1f711b1b Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 12:57:54 +0100 Subject: [PATCH 11/25] utils: Fix memory leak of args in exec error paths In bd_utils_exec_and_capture_output_no_progress, the args array allocated by _append_extra_args was not freed on the g_spawn_sync failure and abnormal termination error paths. Co-Authored-By: Claude Opus 4.6 --- src/utils/exec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/utils/exec.c b/src/utils/exec.c index 08fc73564..048358950 100644 --- a/src/utils/exec.c +++ b/src/utils/exec.c @@ -231,6 +231,7 @@ gboolean bd_utils_exec_and_capture_output_no_progress (const gchar **argv, const /* error is already populated from the call */ g_free (stdout_data); g_free (stderr_data); + g_free (args); return FALSE; } @@ -247,6 +248,7 @@ gboolean bd_utils_exec_and_capture_output_no_progress (const gchar **argv, const /* process was terminated abnormally (e.g. using a signal) */ g_free (stdout_data); g_free (stderr_data); + g_free (args); g_propagate_error (error, l_error); return FALSE; } From 65ea3cd2705ad291981c995a734c5776bb970124 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 13:02:18 +0100 Subject: [PATCH 12/25] utils: Check WIFEXITED before calling WEXITSTATUS in exec WEXITSTATUS was called unconditionally after waitpid, but it is only defined when WIFEXITED is true. For signal-killed processes this is undefined behavior. Restructure the checks to test WIFSIGNALED first, and only call WEXITSTATUS when WIFEXITED is true. Co-Authored-By: Claude Opus 4.6 --- src/utils/exec.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/utils/exec.c b/src/utils/exec.c index 048358950..b3e65bfef 100644 --- a/src/utils/exec.c +++ b/src/utils/exec.c @@ -521,22 +521,25 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt close (err_fd); child_ret = waitpid (pid, &status, 0); - *proc_status = WEXITSTATUS (status); if (success) { if (child_ret > 0) { - if (*proc_status != 0) { - msg = stderr_data->len > 0 ? stderr_data->str : stdout_data->str; + if (WIFSIGNALED (status)) { + *proc_status = 128 + WTERMSIG (status); g_set_error (&l_error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, - "Process reported exit code %d: %s", *proc_status, msg); + "Process killed with a signal"); bd_utils_report_finished (progress_id, l_error->message); g_propagate_error (error, l_error); success = FALSE; - } else if (WIFSIGNALED (status)) { - g_set_error_literal (&l_error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, - "Process killed with a signal"); + } else if (WIFEXITED (status) && WEXITSTATUS (status) != 0) { + *proc_status = WEXITSTATUS (status); + msg = stderr_data->len > 0 ? stderr_data->str : stdout_data->str; + g_set_error (&l_error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, + "Process reported exit code %d: %s", *proc_status, msg); bd_utils_report_finished (progress_id, l_error->message); g_propagate_error (error, l_error); success = FALSE; + } else { + *proc_status = WIFEXITED (status) ? WEXITSTATUS (status) : 0; } } else if (child_ret == -1) { if (errno != ECHILD) { From a939b23fad5c2c5663202965f306152335e5e287 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 13:05:24 +0100 Subject: [PATCH 13/25] fs: Close pipe fds on fork failure in run_as_user When fork() fails, both ends of the pipe created just before need to be closed to avoid leaking file descriptors. Co-Authored-By: Claude Opus 4.6 --- src/plugins/fs/mount.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/fs/mount.c b/src/plugins/fs/mount.c index 2691be109..c5dba2506 100644 --- a/src/plugins/fs/mount.c +++ b/src/plugins/fs/mount.c @@ -510,6 +510,8 @@ static gboolean run_as_user (MountFunc func, MountArgs *args, uid_t run_as_uid, pid = fork (); if (pid == -1) { + close (pipefd[0]); + close (pipefd[1]); g_set_error_literal (error, BD_FS_ERROR, BD_FS_ERROR_FAIL, "Error forking."); return FALSE; From c4010b70a2238033389690db288db493bdc12ad0 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 13:10:58 +0100 Subject: [PATCH 14/25] utils: Close fds and reap child on stdin write failure When writing to the child's stdin fails in _utils_exec_and_report_progress, out_fd and err_fd were not closed and the child process was not reaped, leaking file descriptors and creating a zombie process. Co-Authored-By: Claude Opus 4.6 --- src/utils/exec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/utils/exec.c b/src/utils/exec.c index b3e65bfef..846fd8a72 100644 --- a/src/utils/exec.c +++ b/src/utils/exec.c @@ -467,6 +467,9 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt g_propagate_error (error, l_error); /* would overwrite errno, need to close as a last step */ close (in_fd); + close (out_fd); + close (err_fd); + waitpid (pid, NULL, 0); return FALSE; } close (in_fd); From 15fa75a1e16f0489d0449581e9d4d14f35bb70c6 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 13:30:26 +0100 Subject: [PATCH 15/25] lvm: Copy missing fields in pvdata and vgdata copy functions bd_lvm_vgdata_copy in both lvm.c and lvm-dbus.c was not copying the exported field, so copies always had exported=FALSE. Additionally, bd_lvm_pvdata_copy in lvm-dbus.c was not copying the missing field (lvm.c already copied it). Co-Authored-By: Claude Opus 4.6 --- src/plugins/lvm/lvm-dbus.c | 2 ++ src/plugins/lvm/lvm.c | 1 + 2 files changed, 3 insertions(+) diff --git a/src/plugins/lvm/lvm-dbus.c b/src/plugins/lvm/lvm-dbus.c index ee0bf92b1..a19f8cb00 100644 --- a/src/plugins/lvm/lvm-dbus.c +++ b/src/plugins/lvm/lvm-dbus.c @@ -100,6 +100,7 @@ BDLVMPVdata* bd_lvm_pvdata_copy (BDLVMPVdata *data) { new_data->vg_free_count = data->vg_free_count; new_data->vg_pv_count = data->vg_pv_count; new_data->pv_tags = g_strdupv (data->pv_tags); + new_data->missing = data->missing; return new_data; } @@ -131,6 +132,7 @@ BDLVMVGdata* bd_lvm_vgdata_copy (BDLVMVGdata *data) { new_data->free_count = data->free_count; new_data->pv_count = data->pv_count; new_data->vg_tags = g_strdupv (data->vg_tags); + new_data->exported = data->exported; return new_data; } diff --git a/src/plugins/lvm/lvm.c b/src/plugins/lvm/lvm.c index c0937aa37..5175fff06 100644 --- a/src/plugins/lvm/lvm.c +++ b/src/plugins/lvm/lvm.c @@ -100,6 +100,7 @@ BDLVMVGdata* bd_lvm_vgdata_copy (BDLVMVGdata *data) { new_data->free_count = data->free_count; new_data->pv_count = data->pv_count; new_data->vg_tags = g_strdupv (data->vg_tags); + new_data->exported = data->exported; return new_data; } From c8217f42dc4a719179f287a7a241cc141743826d Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 13:37:46 +0100 Subject: [PATCH 16/25] lvm-dbus: Fix multiple memory leaks - Free path returned by get_object_path in PV list loops in bd_lvm_vgcreate, bd_lvm_lvcreate, and bd_lvm_lvrepair. - Use g_autofree for obj_path in bd_lvm_lvsnapshotmerge. - Unref first prop GVariant before overwriting in bd_lvm_cache_pool_name. - Use g_autofree for data_lv_path and metadata_lv_path in bd_lvm_thpool_convert and bd_lvm_cache_pool_convert, also fixing a leak of data_lv_path when metadata_lv_path lookup fails. - Remove unreachable 'return FALSE' in bd_lvm_lvrepair. Co-Authored-By: Claude Opus 4.6 --- src/plugins/lvm/lvm-dbus.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/plugins/lvm/lvm-dbus.c b/src/plugins/lvm/lvm-dbus.c index a19f8cb00..be565b524 100644 --- a/src/plugins/lvm/lvm-dbus.c +++ b/src/plugins/lvm/lvm-dbus.c @@ -1991,6 +1991,7 @@ gboolean bd_lvm_vgcreate (const gchar *name, const gchar **pv_list, guint64 pe_s return FALSE; } g_variant_builder_add_value (&builder, g_variant_new ("o", path)); + g_free (path); } pvs = g_variant_builder_end (&builder); g_variant_builder_clear (&builder); @@ -2394,6 +2395,7 @@ gboolean bd_lvm_lvcreate (const gchar *vg_name, const gchar *lv_name, guint64 si return FALSE; } g_variant_builder_add_value (&builder, g_variant_new ("(ott)", path, (guint64) 0, (guint64) 0)); + g_free (path); } pvs = g_variant_builder_end (&builder); g_variant_builder_clear (&builder); @@ -2548,6 +2550,7 @@ gboolean bd_lvm_lvrepair (const gchar *vg_name, const gchar *lv_name, const gcha return FALSE; } g_variant_builder_add_value (&builder, g_variant_new ("o", path)); + g_free (path); } pvs = g_variant_builder_end (&builder); g_variant_builder_clear (&builder); @@ -2558,8 +2561,6 @@ gboolean bd_lvm_lvrepair (const gchar *vg_name, const gchar *lv_name, const gcha g_variant_builder_clear (&builder); return call_lv_method_sync (vg_name, lv_name, "RepairRaidLv", params, NULL, extra, TRUE, error); - - return FALSE; } /** @@ -2656,7 +2657,7 @@ gboolean bd_lvm_lvsnapshotcreate (const gchar *vg_name, const gchar *origin_name */ gboolean bd_lvm_lvsnapshotmerge (const gchar *vg_name, const gchar *snapshot_name, const BDExtraArg **extra, GError **error) { gchar *obj_id = NULL; - gchar *obj_path = NULL; + g_autofree gchar *obj_path = NULL; /* get object path for vg_name/snapshot_name and call SNAP_INTF, "Merge" */ obj_id = g_strdup_printf ("%s/%s", vg_name, snapshot_name); @@ -3712,6 +3713,7 @@ gchar* bd_lvm_cache_pool_name (const gchar *vg_name, const gchar *cached_lv, GEr if (!prop) return NULL; g_variant_get (prop, "o", &pool_obj_path); + g_variant_unref (prop); prop = get_object_property (pool_obj_path, LV_CMN_INTF, "Name", error); g_free (pool_obj_path); if (!prop) @@ -3764,8 +3766,8 @@ gboolean bd_lvm_thpool_convert (const gchar *vg_name, const gchar *data_lv, cons GVariantBuilder builder; GVariant *params = NULL; gchar *obj_id = NULL; - gchar *data_lv_path = NULL; - gchar *metadata_lv_path = NULL; + g_autofree gchar *data_lv_path = NULL; + g_autofree gchar *metadata_lv_path = NULL; gboolean ret = FALSE; obj_id = g_strdup_printf ("%s/%s", vg_name, data_lv); @@ -3814,8 +3816,8 @@ gboolean bd_lvm_cache_pool_convert (const gchar *vg_name, const gchar *data_lv, GVariantBuilder builder; GVariant *params = NULL; gchar *obj_id = NULL; - gchar *data_lv_path = NULL; - gchar *metadata_lv_path = NULL; + g_autofree gchar *data_lv_path = NULL; + g_autofree gchar *metadata_lv_path = NULL; gboolean ret = FALSE; obj_id = g_strdup_printf ("%s/%s", vg_name, data_lv); From 40e508ad5367e72c5b4764964b5a2963c36db34c Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 13:44:17 +0100 Subject: [PATCH 17/25] tests: Fix device path check in clean_scsi_debug os.path.exists was called with just the device basename (e.g. "sda") instead of the full path "/dev/sda", so the wait loop for the device to disappear never actually waited. Co-Authored-By: Claude Opus 4.6 --- tests/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils.py b/tests/utils.py index b2c9ef20b..3cdd0c6d5 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -261,7 +261,7 @@ def clean_scsi_debug(scsi_debug_dev): if os.path.exists('/sys/block/' + device): write_file('/sys/block/%s/device/delete' % device, '1') n_tries = 0 - while os.path.exists(device) and n_tries < 5: + while os.path.exists('/dev/' + device) and n_tries < 5: time.sleep(0.5) n_tries += 1 n_tries = 0 From fa68c6d97dd3d30c6819094fd7391c4f8ce728f8 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 13:46:09 +0100 Subject: [PATCH 18/25] s390: Close file descriptor on fputs failure in bd_s390_zfcp_offline When fputs failed writing the LUN to the sysfs file, the function returned without calling fclose, leaking the file descriptor. Co-Authored-By: Claude Opus 4.6 --- src/plugins/s390.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/s390.c b/src/plugins/s390.c index 0df102f7b..841dcc707 100644 --- a/src/plugins/s390.c +++ b/src/plugins/s390.c @@ -1003,6 +1003,7 @@ gboolean bd_s390_zfcp_offline (const gchar *devno, const gchar *wwpn, const gcha } rc = fputs (lun, fd); if (rc == EOF) { + fclose (fd); g_set_error (&l_error, BD_S390_ERROR, BD_S390_ERROR_DEVICE, "Could not remove LUN %s at WWPN %s on zFCP device %s", lun, wwpn, devno); g_free (unitrm); From 26354dcb5591dc2eb9a6c774ffa0ab06e77a0414 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 13:47:54 +0100 Subject: [PATCH 19/25] part: Add lower bound check in get_part_num backward scan The while loop walking backward through the string to find the partition number had no lower bound check. If the string consisted entirely of digits, the pointer would walk past the beginning of the buffer causing undefined behavior. Co-Authored-By: Claude Opus 4.6 --- src/plugins/part.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/part.c b/src/plugins/part.c index 4efff9b94..2878b99fa 100644 --- a/src/plugins/part.c +++ b/src/plugins/part.c @@ -135,6 +135,7 @@ static gint log2i (guint x) { static gint get_part_num (const gchar *part, GError **error) { const gchar *part_num_str = NULL; gint part_num = -1; + gsize i = 0; if (!part || *part == '\0') { g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL, @@ -142,11 +143,10 @@ static gint get_part_num (const gchar *part, GError **error) { return -1; } - part_num_str = part + (strlen (part) - 1); - while (isdigit (*part_num_str) || (*part_num_str == '-')) { - part_num_str--; - } - part_num_str++; + i = strlen (part); + while (i > 0 && (isdigit ((unsigned char) part[i - 1]) || part[i - 1] == '-')) + i--; + part_num_str = part + i; part_num = atoi (part_num_str); if (part_num == 0) { From e6cdbb3d57c8ce6688b5cb9b97ecee040839ff67 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 13:58:30 +0100 Subject: [PATCH 20/25] blockdev: Use zero-initializer for plugins_sonames array Replace explicit NULL initializer list with {0} to avoid mismatch between the number of initializer elements and BD_PLUGIN_UNDEF value if new plugins are added. Co-Authored-By: Claude Opus 4.6 --- src/lib/blockdev.c.in | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/blockdev.c.in b/src/lib/blockdev.c.in index 967dca065..6a46392b4 100644 --- a/src/lib/blockdev.c.in +++ b/src/lib/blockdev.c.in @@ -297,9 +297,7 @@ static gboolean load_plugins (BDPluginSpec **require_plugins, gboolean reload, g gboolean requested_loaded = TRUE; GError *error = NULL; GSequence *config_files = NULL; - GSList *plugins_sonames[BD_PLUGIN_UNDEF] = {NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, NULL}; + GSList *plugins_sonames[BD_PLUGIN_UNDEF] = {0}; BDPlugin plugin_name = BD_PLUGIN_UNDEF; guint64 required_plugins_mask = 0; From 5a7802cd3a8ef8d242a083f0853752d53b96b90c Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 14:44:31 +0100 Subject: [PATCH 21/25] crypto: Add missing crypt_free(cd) on error paths Add crypt_free(cd) calls on error paths where it was missing: - bd_crypto_luks_info, bd_crypto_integrity_info, bd_crypto_luks_token_info: when crypt_init_by_name fails after the initial crypt_init/crypt_load fallback sequence - _crypto_close, bd_crypto_luks_resize, bd_crypto_luks_suspend, bd_crypto_luks_resume: when crypt_init_by_name fails Co-Authored-By: Claude Opus 4.6 --- src/plugins/crypto.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c index 8bd0a9244..84ddd0de5 100644 --- a/src/plugins/crypto.c +++ b/src/plugins/crypto.c @@ -1442,6 +1442,7 @@ static gboolean _crypto_close (const gchar *device, const gchar *tech_name, GErr if (ret != 0) { g_set_error (&l_error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE, "Failed to initialize device: %s", strerror_l (-ret, c_locale)); + crypt_free (cd); bd_utils_report_finished (progress_id, l_error->message); g_propagate_error (error, l_error); return FALSE; @@ -1848,6 +1849,7 @@ gboolean bd_crypto_luks_resize (const gchar *luks_device, guint64 size, BDCrypto if (ret != 0) { g_set_error (&l_error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE, "Failed to initialize device: %s", strerror_l (-ret, c_locale)); + crypt_free (cd); bd_utils_report_finished (progress_id, l_error->message); g_propagate_error (error, l_error); return FALSE; @@ -1957,6 +1959,7 @@ gboolean bd_crypto_luks_suspend (const gchar *luks_device, GError **error) { if (ret != 0) { g_set_error (&l_error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE, "Failed to initialize device: %s", strerror_l (-ret, c_locale)); + crypt_free (cd); bd_utils_report_finished (progress_id, l_error->message); g_propagate_error (error, l_error); return FALSE; @@ -2006,6 +2009,7 @@ gboolean bd_crypto_luks_resume (const gchar *luks_device, BDCryptoKeyslotContext if (ret != 0) { g_set_error (&l_error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE, "Failed to initialize device: %s", strerror_l (-ret, c_locale)); + crypt_free (cd); bd_utils_report_finished (progress_id, l_error->message); g_propagate_error (error, l_error); return FALSE; @@ -2607,6 +2611,7 @@ BDCryptoLUKSInfo* bd_crypto_luks_info (const gchar *device, GError **error) { if (ret != 0) { g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE, "Failed to initialize device: %s", strerror_l (-ret, c_locale)); + crypt_free (cd); return NULL; } @@ -2762,6 +2767,7 @@ BDCryptoIntegrityInfo* bd_crypto_integrity_info (const gchar *device, GError **e if (ret != 0) { g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE, "Failed to initialize device: %s", strerror_l (-ret, c_locale)); + crypt_free (cd); return NULL; } @@ -2831,6 +2837,7 @@ BDCryptoLUKSTokenInfo** bd_crypto_luks_token_info (const gchar *device, GError * if (ret != 0) { g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE, "Failed to initialize device: %s", strerror_l (-ret, c_locale)); + crypt_free (cd); return NULL; } From 215491a50ef5a4e61fbb6715d28b89479758d332 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 14:48:09 +0100 Subject: [PATCH 22/25] lvm-dbus: Add NULL checks after get_object_property in get_lv_data_from_props get_object_property can return NULL if the D-Bus property lookup fails. The code in get_lv_data_from_props unconditionally called g_variant_get and g_variant_unref on the result without checking, which would cause a NULL pointer dereference crash. Co-Authored-By: Claude Opus 4.6 --- src/plugins/lvm/lvm-dbus.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/plugins/lvm/lvm-dbus.c b/src/plugins/lvm/lvm-dbus.c index be565b524..9182243f5 100644 --- a/src/plugins/lvm/lvm-dbus.c +++ b/src/plugins/lvm/lvm-dbus.c @@ -1385,14 +1385,18 @@ static BDLVMLVdata* get_lv_data_from_props (GVariant *props, GError **error G_GN g_variant_dict_lookup (&dict, "Vg", "o", &path); name = get_object_property (path, VG_INTF, "Name", NULL); g_free (path); - g_variant_get (name, "s", &(data->vg_name)); - g_variant_unref (name); + if (name) { + g_variant_get (name, "s", &(data->vg_name)); + g_variant_unref (name); + } g_variant_dict_lookup (&dict, "OriginLv", "o", &path); if (g_strcmp0 (path, "/") != 0) { name = get_object_property (path, LV_CMN_INTF, "Name", NULL); - g_variant_get (name, "s", &(data->origin)); - g_variant_unref (name); + if (name) { + g_variant_get (name, "s", &(data->origin)); + g_variant_unref (name); + } } g_free (path); path = NULL; @@ -1400,8 +1404,10 @@ static BDLVMLVdata* get_lv_data_from_props (GVariant *props, GError **error G_GN g_variant_dict_lookup (&dict, "PoolLv", "o", &path); if (g_strcmp0 (path, "/") != 0) { name = get_object_property (path, LV_CMN_INTF, "Name", NULL); - g_variant_get (name, "s", &(data->pool_lv)); - g_variant_unref (name); + if (name) { + g_variant_get (name, "s", &(data->pool_lv)); + g_variant_unref (name); + } } g_free (path); path = NULL; @@ -1409,8 +1415,10 @@ static BDLVMLVdata* get_lv_data_from_props (GVariant *props, GError **error G_GN g_variant_dict_lookup (&dict, "MovePv", "o", &path); if (path && g_strcmp0 (path, "/") != 0) { name = get_object_property (path, PV_INTF, "Name", NULL); - g_variant_get (name, "s", &(data->move_pv)); - g_variant_unref (name); + if (name) { + g_variant_get (name, "s", &(data->move_pv)); + g_variant_unref (name); + } } g_free (path); path = NULL; From c6c41c59b133e24a25c7e0e140a622b4e48260a9 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 14:48:25 +0100 Subject: [PATCH 23/25] nvdimm: Add missing ndctl_unref on error paths In bd_nvdimm_namespace_enable and bd_nvdimm_namespace_disable, when get_namespace_by_name returns NULL, the function returns without calling ndctl_unref(ctx), leaking the ndctl context. Co-Authored-By: Claude Opus 4.6 --- src/plugins/nvdimm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/nvdimm.c b/src/plugins/nvdimm.c index f6b2bea3f..c26b1f948 100644 --- a/src/plugins/nvdimm.c +++ b/src/plugins/nvdimm.c @@ -300,6 +300,7 @@ gboolean bd_nvdimm_namespace_enable (const gchar *namespace, const BDExtraArg ** if (!ndns) { g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_NOEXIST, "Failed to enable namespace: namespace '%s' not found.", namespace); + ndctl_unref (ctx); return FALSE; } @@ -343,6 +344,7 @@ gboolean bd_nvdimm_namespace_disable (const gchar *namespace, const BDExtraArg * if (!ndns) { g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_NOEXIST, "Failed to disable namespace: namespace '%s' not found.", namespace); + ndctl_unref (ctx); return FALSE; } From 17926581ee7701cc67c0bb22cf2e328dea0f0dab Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 14:50:25 +0100 Subject: [PATCH 24/25] fs: Remove unreachable code in bd_fs_unmount and bd_fs_mount Both branches of the if/else return, making the trailing 'return TRUE' unreachable dead code. Co-Authored-By: Claude Opus 4.6 --- src/plugins/fs/mount.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/plugins/fs/mount.c b/src/plugins/fs/mount.c index c5dba2506..05f272d58 100644 --- a/src/plugins/fs/mount.c +++ b/src/plugins/fs/mount.c @@ -696,8 +696,6 @@ gboolean bd_fs_unmount (const gchar *spec, gboolean lazy, gboolean force, const return ret; } else return do_unmount (&args, error); - - return TRUE; } /** @@ -779,8 +777,6 @@ gboolean bd_fs_mount (const gchar *device, const gchar *mountpoint, const gchar return ret; } else return do_mount (&args, error); - - return TRUE; } /** From a6673399e3810c4d4653fb58fdb5afacdadf8d96 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Tue, 10 Mar 2026 15:01:31 +0100 Subject: [PATCH 25/25] lvm: Move data copy and free functions to lvm-common.c The copy/free functions for BDLVMPVdata, BDLVMVGdata, BDLVMLVdata, BDLVMSEGdata, BDLVMVDOPooldata and BDLVMCacheStats were duplicated in both lvm.c and lvm-dbus.c. Move them to lvm-common.c which is compiled into both plugin libraries. This also fixes the build of lvm-dbus.c which used copy_segs/free_segs without defining them. Co-Authored-By: Claude Opus 4.6 --- src/plugins/lvm/lvm-common.c | 212 ++++++++++++++++++++++++++++++++++ src/plugins/lvm/lvm-dbus.c | 141 ----------------------- src/plugins/lvm/lvm.c | 213 ----------------------------------- 3 files changed, 212 insertions(+), 354 deletions(-) diff --git a/src/plugins/lvm/lvm-common.c b/src/plugins/lvm/lvm-common.c index b3ee2721e..499bc8fa9 100644 --- a/src/plugins/lvm/lvm-common.c +++ b/src/plugins/lvm/lvm-common.c @@ -61,6 +61,218 @@ GMutex global_config_lock; gchar *global_config_str = NULL; gchar *global_devices_str = NULL; +BDLVMPVdata* bd_lvm_pvdata_copy (BDLVMPVdata *data) { + if (data == NULL) + return NULL; + + BDLVMPVdata *new_data = g_new0 (BDLVMPVdata, 1); + + new_data->pv_name = g_strdup (data->pv_name); + new_data->pv_uuid = g_strdup (data->pv_uuid); + new_data->pv_free = data->pv_free; + new_data->pv_size = data->pv_size; + new_data->pe_start = data->pe_start; + new_data->vg_name = g_strdup (data->vg_name); + new_data->vg_uuid = g_strdup (data->vg_uuid); + new_data->vg_size = data->vg_size; + new_data->vg_free = data->vg_free; + new_data->vg_extent_size = data->vg_extent_size; + new_data->vg_extent_count = data->vg_extent_count; + new_data->vg_free_count = data->vg_free_count; + new_data->vg_pv_count = data->vg_pv_count; + new_data->pv_tags = g_strdupv (data->pv_tags); + new_data->missing = data->missing; + + return new_data; +} + +void bd_lvm_pvdata_free (BDLVMPVdata *data) { + if (data == NULL) + return; + + g_free (data->pv_name); + g_free (data->pv_uuid); + g_free (data->vg_name); + g_free (data->vg_uuid); + g_strfreev (data->pv_tags); + g_free (data); +} + +BDLVMVGdata* bd_lvm_vgdata_copy (BDLVMVGdata *data) { + if (data == NULL) + return NULL; + + BDLVMVGdata *new_data = g_new0 (BDLVMVGdata, 1); + + new_data->name = g_strdup (data->name); + new_data->uuid = g_strdup (data->uuid); + new_data->size = data->size; + new_data->free = data->free; + new_data->extent_size = data->extent_size; + new_data->extent_count = data->extent_count; + new_data->free_count = data->free_count; + new_data->pv_count = data->pv_count; + new_data->vg_tags = g_strdupv (data->vg_tags); + new_data->exported = data->exported; + return new_data; +} + +void bd_lvm_vgdata_free (BDLVMVGdata *data) { + if (data == NULL) + return; + + g_free (data->name); + g_free (data->uuid); + g_strfreev (data->vg_tags); + g_free (data); +} + +BDLVMSEGdata* bd_lvm_segdata_copy (BDLVMSEGdata *data) { + if (data == NULL) + return NULL; + + BDLVMSEGdata *new_data = g_new0 (BDLVMSEGdata, 1); + + new_data->size_pe = data->size_pe; + new_data->pv_start_pe = data->pv_start_pe; + new_data->pvdev = g_strdup (data->pvdev); + return new_data; +} + +void bd_lvm_segdata_free (BDLVMSEGdata *data) { + if (data == NULL) + return; + + g_free (data->pvdev); + g_free (data); +} + +static BDLVMSEGdata **copy_segs (BDLVMSEGdata **segs) { + int len; + BDLVMSEGdata **new_segs; + + if (segs == NULL) + return NULL; + + for (len = 0; segs[len]; len++) + ; + + new_segs = g_new0 (BDLVMSEGdata *, len+1); + for (int i = 0; i < len; i++) + new_segs[i] = bd_lvm_segdata_copy (segs[i]); + + return new_segs; +} + +static void free_segs (BDLVMSEGdata **segs) { + if (segs == NULL) + return; + + for (int i = 0; segs[i]; i++) + bd_lvm_segdata_free (segs[i]); + (g_free) (segs); +} + +BDLVMLVdata* bd_lvm_lvdata_copy (BDLVMLVdata *data) { + if (data == NULL) + return NULL; + + BDLVMLVdata *new_data = g_new0 (BDLVMLVdata, 1); + + new_data->lv_name = g_strdup (data->lv_name); + new_data->vg_name = g_strdup (data->vg_name); + new_data->uuid = g_strdup (data->uuid); + new_data->size = data->size; + new_data->attr = g_strdup (data->attr); + new_data->segtype = g_strdup (data->segtype); + new_data->origin = g_strdup (data->origin); + new_data->pool_lv = g_strdup (data->pool_lv); + new_data->data_lv = g_strdup (data->data_lv); + new_data->metadata_lv = g_strdup (data->metadata_lv); + new_data->roles = g_strdup (data->roles); + new_data->move_pv = g_strdup (data->move_pv); + new_data->data_percent = data->data_percent; + new_data->metadata_percent = data->metadata_percent; + new_data->copy_percent = data->copy_percent; + new_data->lv_tags = g_strdupv (data->lv_tags); + new_data->data_lvs = g_strdupv (data->data_lvs); + new_data->metadata_lvs = g_strdupv (data->metadata_lvs); + new_data->segs = copy_segs (data->segs); + return new_data; +} + +void bd_lvm_lvdata_free (BDLVMLVdata *data) { + if (data == NULL) + return; + + g_free (data->lv_name); + g_free (data->vg_name); + g_free (data->uuid); + g_free (data->attr); + g_free (data->segtype); + g_free (data->origin); + g_free (data->pool_lv); + g_free (data->data_lv); + g_free (data->metadata_lv); + g_free (data->roles); + g_free (data->move_pv); + g_strfreev (data->lv_tags); + g_strfreev (data->data_lvs); + g_strfreev (data->metadata_lvs); + free_segs (data->segs); + g_free (data); +} + +BDLVMVDOPooldata* bd_lvm_vdopooldata_copy (BDLVMVDOPooldata *data) { + if (data == NULL) + return NULL; + + BDLVMVDOPooldata *new_data = g_new0 (BDLVMVDOPooldata, 1); + + new_data->operating_mode = data->operating_mode; + new_data->compression_state = data->compression_state; + new_data->index_state = data->index_state; + new_data->write_policy = data->write_policy; + new_data->used_size = data->used_size; + new_data->saving_percent = data->saving_percent; + new_data->index_memory_size = data->index_memory_size; + new_data->deduplication = data->deduplication; + new_data->compression = data->compression; + return new_data; +} + +void bd_lvm_vdopooldata_free (BDLVMVDOPooldata *data) { + if (data == NULL) + return; + + g_free (data); +} + +BDLVMCacheStats* bd_lvm_cache_stats_copy (BDLVMCacheStats *data) { + if (data == NULL) + return NULL; + + BDLVMCacheStats *new = g_new0 (BDLVMCacheStats, 1); + + new->block_size = data->block_size; + new->cache_size = data->cache_size; + new->cache_used = data->cache_used; + new->md_block_size = data->md_block_size; + new->md_size = data->md_size; + new->md_used = data->md_used; + new->read_hits = data->read_hits; + new->read_misses = data->read_misses; + new->write_hits = data->write_hits; + new->write_misses = data->write_misses; + new->mode = data->mode; + + return new; +} + +void bd_lvm_cache_stats_free (BDLVMCacheStats *data) { + g_free (data); +} + /** * bd_lvm_is_supported_pe_size: * @size: size (in bytes) to test diff --git a/src/plugins/lvm/lvm-dbus.c b/src/plugins/lvm/lvm-dbus.c index 9182243f5..9a79f728c 100644 --- a/src/plugins/lvm/lvm-dbus.c +++ b/src/plugins/lvm/lvm-dbus.c @@ -80,147 +80,6 @@ GQuark bd_lvm_error_quark (void) return g_quark_from_static_string ("g-bd-lvm-error-quark"); } -BDLVMPVdata* bd_lvm_pvdata_copy (BDLVMPVdata *data) { - if (data == NULL) - return NULL; - - BDLVMPVdata *new_data = g_new0 (BDLVMPVdata, 1); - - new_data->pv_name = g_strdup (data->pv_name); - new_data->pv_uuid = g_strdup (data->pv_uuid); - new_data->pv_free = data->pv_free; - new_data->pv_size = data->pv_size; - new_data->pe_start = data->pe_start; - new_data->vg_name = g_strdup (data->vg_name); - new_data->vg_uuid = g_strdup (data->vg_uuid); - new_data->vg_size = data->vg_size; - new_data->vg_free = data->vg_free; - new_data->vg_extent_size = data->vg_extent_size; - new_data->vg_extent_count = data->vg_extent_count; - new_data->vg_free_count = data->vg_free_count; - new_data->vg_pv_count = data->vg_pv_count; - new_data->pv_tags = g_strdupv (data->pv_tags); - new_data->missing = data->missing; - - return new_data; -} - -void bd_lvm_pvdata_free (BDLVMPVdata *data) { - if (data == NULL) - return; - - g_free (data->pv_name); - g_free (data->pv_uuid); - g_free (data->vg_name); - g_free (data->vg_uuid); - g_strfreev (data->pv_tags); - g_free (data); -} - -BDLVMVGdata* bd_lvm_vgdata_copy (BDLVMVGdata *data) { - if (data == NULL) - return NULL; - - BDLVMVGdata *new_data = g_new0 (BDLVMVGdata, 1); - - new_data->name = g_strdup (data->name); - new_data->uuid = g_strdup (data->uuid); - new_data->size = data->size; - new_data->free = data->free; - new_data->extent_size = data->extent_size; - new_data->extent_count = data->extent_count; - new_data->free_count = data->free_count; - new_data->pv_count = data->pv_count; - new_data->vg_tags = g_strdupv (data->vg_tags); - new_data->exported = data->exported; - return new_data; -} - -void bd_lvm_vgdata_free (BDLVMVGdata *data) { - if (data == NULL) - return; - - g_free (data->name); - g_free (data->uuid); - g_strfreev (data->vg_tags); - g_free (data); -} - -BDLVMLVdata* bd_lvm_lvdata_copy (BDLVMLVdata *data) { - if (data == NULL) - return NULL; - - BDLVMLVdata *new_data = g_new0 (BDLVMLVdata, 1); - - new_data->lv_name = g_strdup (data->lv_name); - new_data->vg_name = g_strdup (data->vg_name); - new_data->uuid = g_strdup (data->uuid); - new_data->size = data->size; - new_data->attr = g_strdup (data->attr); - new_data->segtype = g_strdup (data->segtype); - new_data->origin = g_strdup (data->origin); - new_data->pool_lv = g_strdup (data->pool_lv); - new_data->data_lv = g_strdup (data->data_lv); - new_data->metadata_lv = g_strdup (data->metadata_lv); - new_data->roles = g_strdup (data->roles); - new_data->move_pv = g_strdup (data->move_pv); - new_data->data_percent = data->data_percent; - new_data->metadata_percent = data->metadata_percent; - new_data->copy_percent = data->copy_percent; - new_data->lv_tags = g_strdupv (data->lv_tags); - new_data->data_lvs = g_strdupv (data->data_lvs); - new_data->metadata_lvs = g_strdupv (data->metadata_lvs); - new_data->segs = copy_segs (data->segs); - return new_data; -} - -void bd_lvm_lvdata_free (BDLVMLVdata *data) { - if (data == NULL) - return; - - g_free (data->lv_name); - g_free (data->vg_name); - g_free (data->uuid); - g_free (data->attr); - g_free (data->segtype); - g_free (data->origin); - g_free (data->pool_lv); - g_free (data->data_lv); - g_free (data->metadata_lv); - g_free (data->roles); - g_free (data->move_pv); - g_strfreev (data->lv_tags); - g_strfreev (data->data_lvs); - g_strfreev (data->metadata_lvs); - free_segs (data->segs); - g_free (data); -} - -BDLVMCacheStats* bd_lvm_cache_stats_copy (BDLVMCacheStats *data) { - if (data == NULL) - return NULL; - - BDLVMCacheStats *new = g_new0 (BDLVMCacheStats, 1); - - new->block_size = data->block_size; - new->cache_size = data->cache_size; - new->cache_used = data->cache_used; - new->md_block_size = data->md_block_size; - new->md_size = data->md_size; - new->md_used = data->md_used; - new->read_hits = data->read_hits; - new->read_misses = data->read_misses; - new->write_hits = data->write_hits; - new->write_misses = data->write_misses; - new->mode = data->mode; - - return new; -} - -void bd_lvm_cache_stats_free (BDLVMCacheStats *data) { - g_free (data); -} - static gboolean setup_dbus_connection (GError **error) { gchar *addr = NULL; diff --git a/src/plugins/lvm/lvm.c b/src/plugins/lvm/lvm.c index 5175fff06..a049f9ef3 100644 --- a/src/plugins/lvm/lvm.c +++ b/src/plugins/lvm/lvm.c @@ -48,219 +48,6 @@ GQuark bd_lvm_error_quark (void) return g_quark_from_static_string ("g-bd-lvm-error-quark"); } -BDLVMPVdata* bd_lvm_pvdata_copy (BDLVMPVdata *data) { - if (data == NULL) - return NULL; - - BDLVMPVdata *new_data = g_new0 (BDLVMPVdata, 1); - - new_data->pv_name = g_strdup (data->pv_name); - new_data->pv_uuid = g_strdup (data->pv_uuid); - new_data->pv_free = data->pv_free; - new_data->pv_size = data->pv_size; - new_data->pe_start = data->pe_start; - new_data->vg_name = g_strdup (data->vg_name); - new_data->vg_uuid = g_strdup (data->vg_uuid); - new_data->vg_size = data->vg_size; - new_data->vg_free = data->vg_free; - new_data->vg_extent_size = data->vg_extent_size; - new_data->vg_extent_count = data->vg_extent_count; - new_data->vg_free_count = data->vg_free_count; - new_data->vg_pv_count = data->vg_pv_count; - new_data->pv_tags = g_strdupv (data->pv_tags); - new_data->missing = data->missing; - - return new_data; -} - -void bd_lvm_pvdata_free (BDLVMPVdata *data) { - if (data == NULL) - return; - - g_free (data->pv_name); - g_free (data->pv_uuid); - g_free (data->vg_name); - g_free (data->vg_uuid); - g_strfreev (data->pv_tags); - g_free (data); -} - -BDLVMVGdata* bd_lvm_vgdata_copy (BDLVMVGdata *data) { - if (data == NULL) - return NULL; - - BDLVMVGdata *new_data = g_new0 (BDLVMVGdata, 1); - - new_data->name = g_strdup (data->name); - new_data->uuid = g_strdup (data->uuid); - new_data->size = data->size; - new_data->free = data->free; - new_data->extent_size = data->extent_size; - new_data->extent_count = data->extent_count; - new_data->free_count = data->free_count; - new_data->pv_count = data->pv_count; - new_data->vg_tags = g_strdupv (data->vg_tags); - new_data->exported = data->exported; - return new_data; -} - -void bd_lvm_vgdata_free (BDLVMVGdata *data) { - if (data == NULL) - return; - - g_free (data->name); - g_free (data->uuid); - g_strfreev (data->vg_tags); - g_free (data); -} - -BDLVMSEGdata* bd_lvm_segdata_copy (BDLVMSEGdata *data) { - if (data == NULL) - return NULL; - - BDLVMSEGdata *new_data = g_new0 (BDLVMSEGdata, 1); - - new_data->size_pe = data->size_pe; - new_data->pv_start_pe = data->pv_start_pe; - new_data->pvdev = g_strdup (data->pvdev); - return new_data; -} - -void bd_lvm_segdata_free (BDLVMSEGdata *data) { - if (data == NULL) - return; - - g_free (data->pvdev); - g_free (data); -} - -static BDLVMSEGdata **copy_segs (BDLVMSEGdata **segs) { - int len; - BDLVMSEGdata **new_segs; - - if (segs == NULL) - return NULL; - - for (len = 0; segs[len]; len++) - ; - - new_segs = g_new0 (BDLVMSEGdata *, len+1); - for (int i = 0; i < len; i++) - new_segs[i] = bd_lvm_segdata_copy (segs[i]); - - return new_segs; -} - -static void free_segs (BDLVMSEGdata **segs) { - if (segs == NULL) - return; - - for (int i = 0; segs[i]; i++) - bd_lvm_segdata_free (segs[i]); - (g_free) (segs); -} - -BDLVMLVdata* bd_lvm_lvdata_copy (BDLVMLVdata *data) { - if (data == NULL) - return NULL; - - BDLVMLVdata *new_data = g_new0 (BDLVMLVdata, 1); - - new_data->lv_name = g_strdup (data->lv_name); - new_data->vg_name = g_strdup (data->vg_name); - new_data->uuid = g_strdup (data->uuid); - new_data->size = data->size; - new_data->attr = g_strdup (data->attr); - new_data->segtype = g_strdup (data->segtype); - new_data->origin = g_strdup (data->origin); - new_data->pool_lv = g_strdup (data->pool_lv); - new_data->data_lv = g_strdup (data->data_lv); - new_data->metadata_lv = g_strdup (data->metadata_lv); - new_data->roles = g_strdup (data->roles); - new_data->move_pv = g_strdup (data->move_pv); - new_data->data_percent = data->data_percent; - new_data->metadata_percent = data->metadata_percent; - new_data->copy_percent = data->copy_percent; - new_data->lv_tags = g_strdupv (data->lv_tags); - new_data->data_lvs = g_strdupv (data->data_lvs); - new_data->metadata_lvs = g_strdupv (data->metadata_lvs); - new_data->segs = copy_segs (data->segs); - return new_data; -} - -void bd_lvm_lvdata_free (BDLVMLVdata *data) { - if (data == NULL) - return; - - g_free (data->lv_name); - g_free (data->vg_name); - g_free (data->uuid); - g_free (data->attr); - g_free (data->segtype); - g_free (data->origin); - g_free (data->pool_lv); - g_free (data->data_lv); - g_free (data->metadata_lv); - g_free (data->roles); - g_free (data->move_pv); - g_strfreev (data->lv_tags); - g_strfreev (data->data_lvs); - g_strfreev (data->metadata_lvs); - free_segs (data->segs); - g_free (data); -} - -BDLVMVDOPooldata* bd_lvm_vdopooldata_copy (BDLVMVDOPooldata *data) { - if (data == NULL) - return NULL; - - BDLVMVDOPooldata *new_data = g_new0 (BDLVMVDOPooldata, 1); - - new_data->operating_mode = data->operating_mode; - new_data->compression_state = data->compression_state; - new_data->index_state = data->index_state; - new_data->write_policy = data->write_policy; - new_data->used_size = data->used_size; - new_data->saving_percent = data->saving_percent; - new_data->index_memory_size = data->index_memory_size; - new_data->deduplication = data->deduplication; - new_data->compression = data->compression; - return new_data; -} - -void bd_lvm_vdopooldata_free (BDLVMVDOPooldata *data) { - if (data == NULL) - return; - - g_free (data); -} - -BDLVMCacheStats* bd_lvm_cache_stats_copy (BDLVMCacheStats *data) { - if (data == NULL) - return NULL; - - BDLVMCacheStats *new = g_new0 (BDLVMCacheStats, 1); - - new->block_size = data->block_size; - new->cache_size = data->cache_size; - new->cache_used = data->cache_used; - new->md_block_size = data->md_block_size; - new->md_size = data->md_size; - new->md_used = data->md_used; - new->read_hits = data->read_hits; - new->read_misses = data->read_misses; - new->write_hits = data->write_hits; - new->write_misses = data->write_misses; - new->mode = data->mode; - - return new; -} - -void bd_lvm_cache_stats_free (BDLVMCacheStats *data) { - g_free (data); -} - - static volatile guint avail_deps = 0; static volatile guint avail_features = 0; static volatile guint avail_module_deps = 0;