Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
0562935
tests: Fix typo in test_list_subvolumes_different_mount
vojtechtrefny Jan 14, 2026
83dc609
tests: Add a test case for lvm_pvmove
vojtechtrefny Jan 14, 2026
a9edf54
tests: Add a test case for bd_fs_can_set_uuid
vojtechtrefny Jan 14, 2026
67cc2f8
tests: Fix test case for fs_can_get_info
vojtechtrefny Jan 14, 2026
bd19f89
tests: Add tests for BlockDev.get_plugin_name and try_reinit
vojtechtrefny Jan 22, 2026
37efd4e
tests: Cover more corner cases in LVM plugins tests
vojtechtrefny Jan 22, 2026
1899a66
lvm: Move bd_lvm_cache_stats to the lvm-common file
vojtechtrefny Jan 22, 2026
804f120
lvm: Remove EUID check from bd_lvm_cache_stats
vojtechtrefny Jan 22, 2026
5657286
tests: Test XFS resize with both mounted and unmounted devices
vojtechtrefny Jan 22, 2026
c1130b7
tests: Add missing test cases for generic FS set/check label/UUID
vojtechtrefny Jan 22, 2026
40226ce
smart: Fix API for bd_smart_is_tech_avail
vojtechtrefny Jan 22, 2026
31ae532
tests: Add more tests for the utils module
vojtechtrefny Jan 23, 2026
3070388
tests: Add more tests for the loop plugin
vojtechtrefny Jan 23, 2026
24c0bcf
tests: Add more tests for the part plugin
vojtechtrefny Jan 23, 2026
479fe9b
mpath: Remove EUID check from the mpath plugin functions
vojtechtrefny Jan 23, 2026
1998112
tests: Add a simple test case for bd_mpath_flush_mpaths
vojtechtrefny Jan 23, 2026
f0cf319
smart: Mark bd_smart_check_deps as deprecated
vojtechtrefny Jan 26, 2026
d7cb5c9
docs: Add steps to run coverage with LCOV
vojtechtrefny Jan 26, 2026
13bb88f
tests: Add more tests for the crypto plugin
vojtechtrefny Jan 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/libblockdev-docs.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,31 @@ cat dist/libblockdev.spec.in | grep BuildRequires: | cut -f2 -d: | cut -f2 -d' '

is equivalent to `make test-all'.
</para>

<para>
To get full coverage report for the C code the LCOV tool can be used:

<screen><userinput>./autogen.sh</userinput></screen>
<screen><userinput>./configure CFLAGS="-O0 -g --coverage" LDFLAGS="--coverage" --prefix=/usr</userinput></screen>
<screen><userinput>make -j</userinput></screen>

to configure and build the project with coverage enabled, run

<screen><userinput>lcov --directory . --zerocounters</userinput></screen>
<screen><userinput>lcov --directory . --capture --initial --output-file coverage-base.info</userinput></screen>

to configure lcov, run tests as usual with

<screen><userinput>sudo python3 tests/run_tests.py --include-tags all</userinput></screen>

and produce the HTML report using

<screen><userinput>lcov --directory . --capture --output-file coverage-test.info</userinput></screen>
<screen><userinput>lcov --remove coverage-test.info '/usr/*' --output-file coverage-filtered.info</userinput></screen>
<screen><userinput>genhtml coverage-filtered.info --output-directory coverage-report --title "libblockdev Coverage Report" --show-details --legend</userinput></screen>

</para>

</chapter>

<xi:include href="3.0-api-changes.xml"><xi:fallback /></xi:include>
Expand Down
2 changes: 1 addition & 1 deletion src/lib/plugin_apis/smart.api
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ typedef enum {
* Returns: whether the @tech-@mode combination is available -- supported by the
* plugin implementation and having all the runtime dependencies available
*/
gboolean bd_smart_is_tech_avail (BDSmartTechMode tech, G_GNUC_UNUSED guint64 mode, GError **error);
gboolean bd_smart_is_tech_avail (BDSmartTech tech, G_GNUC_UNUSED guint64 mode, GError **error);

/* BpG-skip */
/**
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/fs/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1305,7 +1305,7 @@ gboolean bd_fs_check (const gchar *device, const gchar *fstype, GError **error)
* Tech category: always available
*/
gboolean bd_fs_check_label (const gchar *fstype, const gchar *label, GError **error) {
if (!fstype) {
if (!fstype || strlen (fstype) == 0) {
g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_NOFS,
"Filesystem type must be specified to check label format");
return FALSE;
Expand Down Expand Up @@ -1352,7 +1352,7 @@ gboolean bd_fs_set_label (const gchar *device, const gchar *label, const gchar *
* Tech category: always available
*/
gboolean bd_fs_check_uuid (const gchar *fstype, const gchar *uuid, GError **error) {
if (!fstype) {
if (!fstype || strlen (fstype) == 0) {
g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_NOFS,
"Filesystem type must be specified to check UUID format");
return FALSE;
Expand Down
121 changes: 121 additions & 0 deletions src/plugins/lvm/lvm-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,3 +850,124 @@ gboolean bd_lvm_vgcfgbackup (const gchar *vg_name, const gchar *backup_file, con
gboolean bd_lvm_vgcfgrestore (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error) {
return _vgcfgbackup_restore ("vgcfgrestore", vg_name, backup_file, extra, error);
}

/**
* bd_lvm_cache_stats:
* @vg_name: name of the VG containing the @cached_lv
* @cached_lv: cached LV to get stats for
* @error: (out) (optional): place to store error (if any)
*
* Returns: stats for the @cached_lv or %NULL in case of error
*
* Tech category: %BD_LVM_TECH_CACHE-%BD_LVM_TECH_MODE_QUERY
*/
BDLVMCacheStats* bd_lvm_cache_stats (const gchar *vg_name, const gchar *cached_lv, GError **error) {
struct dm_pool *pool = NULL;
struct dm_task *task = NULL;
struct dm_info info;
struct dm_status_cache *status = NULL;
gchar *map_name = NULL;
guint64 start = 0;
guint64 length = 0;
gchar *type = NULL;
gchar *params = NULL;
BDLVMCacheStats *ret = NULL;
BDLVMLVdata *lvdata = NULL;

lvdata = bd_lvm_lvinfo (vg_name, cached_lv, error);
if (!lvdata)
return NULL;

pool = dm_pool_create ("bd-pool", 20);

if (g_strcmp0 (lvdata->segtype, "thin-pool") == 0)
map_name = dm_build_dm_name (pool, vg_name, lvdata->data_lv, NULL);
else
/* translate the VG+LV name into the DM map name */
map_name = dm_build_dm_name (pool, vg_name, cached_lv, NULL);

bd_lvm_lvdata_free (lvdata);

task = dm_task_create (DM_DEVICE_STATUS);
if (!task) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR,
"Failed to create DM task for the cache map '%s': ", map_name);
dm_pool_destroy (pool);
return NULL;
}

if (dm_task_set_name (task, map_name) == 0) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR,
"Failed to create DM task for the cache map '%s': ", map_name);
dm_task_destroy (task);
dm_pool_destroy (pool);
return NULL;
}

if (dm_task_run (task) == 0) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR,
"Failed to run the DM task for the cache map '%s': ", map_name);
dm_task_destroy (task);
dm_pool_destroy (pool);
return NULL;
}

if (dm_task_get_info (task, &info) == 0) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR,
"Failed to get task info for the cache map '%s': ", map_name);
dm_task_destroy (task);
dm_pool_destroy (pool);
return NULL;
}

if (!info.exists) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_CACHE_NOCACHE,
"The cache map '%s' doesn't exist: ", map_name);
dm_task_destroy (task);
dm_pool_destroy (pool);
return NULL;
}

dm_get_next_target (task, NULL, &start, &length, &type, &params);

if (dm_get_status_cache (pool, params, &status) == 0) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_CACHE_INVAL,
"Failed to get status of the cache map '%s': ", map_name);
dm_task_destroy (task);
dm_pool_destroy (pool);
return NULL;
}

ret = g_new0 (BDLVMCacheStats, 1);
ret->block_size = status->block_size * SECTOR_SIZE;
ret->cache_size = status->total_blocks * ret->block_size;
ret->cache_used = status->used_blocks * ret->block_size;

ret->md_block_size = status->metadata_block_size * SECTOR_SIZE;
ret->md_size = status->metadata_total_blocks * ret->md_block_size;
ret->md_used = status->metadata_used_blocks * ret->md_block_size;

ret->read_hits = status->read_hits;
ret->read_misses = status->read_misses;
ret->write_hits = status->write_hits;
ret->write_misses = status->write_misses;

if (status->feature_flags & DM_CACHE_FEATURE_WRITETHROUGH)
ret->mode = BD_LVM_CACHE_MODE_WRITETHROUGH;
else if (status->feature_flags & DM_CACHE_FEATURE_WRITEBACK)
ret->mode = BD_LVM_CACHE_MODE_WRITEBACK;
else {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_CACHE_INVAL,
"Failed to determine status of the cache from '%"G_GUINT64_FORMAT"': ",
status->feature_flags);
dm_task_destroy (task);
dm_pool_destroy (pool);
bd_lvm_cache_stats_free (ret);
return NULL;
}

dm_task_destroy (task);
dm_pool_destroy (pool);

return ret;
}
127 changes: 0 additions & 127 deletions src/plugins/lvm/lvm-dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -3697,133 +3697,6 @@ gchar* bd_lvm_cache_pool_name (const gchar *vg_name, const gchar *cached_lv, GEr
return pool_name;
}

/**
* bd_lvm_cache_stats:
* @vg_name: name of the VG containing the @cached_lv
* @cached_lv: cached LV to get stats for
* @error: (out) (optional): place to store error (if any)
*
* Returns: stats for the @cached_lv or %NULL in case of error
*
* Tech category: %BD_LVM_TECH_CACHE-%BD_LVM_TECH_MODE_QUERY
*/
BDLVMCacheStats* bd_lvm_cache_stats (const gchar *vg_name, const gchar *cached_lv, GError **error) {
struct dm_pool *pool = NULL;
struct dm_task *task = NULL;
struct dm_info info;
struct dm_status_cache *status = NULL;
gchar *map_name = NULL;
guint64 start = 0;
guint64 length = 0;
gchar *type = NULL;
gchar *params = NULL;
BDLVMCacheStats *ret = NULL;
BDLVMLVdata *lvdata = NULL;

if (geteuid () != 0) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_NOT_ROOT,
"Not running as root, cannot query DM maps");
return NULL;
}

lvdata = bd_lvm_lvinfo (vg_name, cached_lv, error);
if (!lvdata)
return NULL;

pool = dm_pool_create ("bd-pool", 20);

if (g_strcmp0 (lvdata->segtype, "thin-pool") == 0)
map_name = dm_build_dm_name (pool, vg_name, lvdata->data_lv, NULL);
else
/* translate the VG+LV name into the DM map name */
map_name = dm_build_dm_name (pool, vg_name, cached_lv, NULL);

bd_lvm_lvdata_free (lvdata);

task = dm_task_create (DM_DEVICE_STATUS);
if (!task) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR,
"Failed to create DM task for the cache map '%s': ", map_name);
dm_pool_destroy (pool);
return NULL;
}

if (dm_task_set_name (task, map_name) == 0) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR,
"Failed to create DM task for the cache map '%s': ", map_name);
dm_task_destroy (task);
dm_pool_destroy (pool);
return NULL;
}

if (dm_task_run (task) == 0) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR,
"Failed to run the DM task for the cache map '%s': ", map_name);
dm_task_destroy (task);
dm_pool_destroy (pool);
return NULL;
}

if (dm_task_get_info (task, &info) == 0) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR,
"Failed to get task info for the cache map '%s': ", map_name);
dm_task_destroy (task);
dm_pool_destroy (pool);
return NULL;
}

if (!info.exists) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_CACHE_NOCACHE,
"The cache map '%s' doesn't exist: ", map_name);
dm_task_destroy (task);
dm_pool_destroy (pool);
return NULL;
}

dm_get_next_target (task, NULL, &start, &length, &type, &params);

if (dm_get_status_cache (pool, params, &status) == 0) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_CACHE_INVAL,
"Failed to get status of the cache map '%s': ", map_name);
dm_task_destroy (task);
dm_pool_destroy (pool);
return NULL;
}

ret = g_new0 (BDLVMCacheStats, 1);
ret->block_size = status->block_size * SECTOR_SIZE;
ret->cache_size = status->total_blocks * ret->block_size;
ret->cache_used = status->used_blocks * ret->block_size;

ret->md_block_size = status->metadata_block_size * SECTOR_SIZE;
ret->md_size = status->metadata_total_blocks * ret->md_block_size;
ret->md_used = status->metadata_used_blocks * ret->md_block_size;

ret->read_hits = status->read_hits;
ret->read_misses = status->read_misses;
ret->write_hits = status->write_hits;
ret->write_misses = status->write_misses;

if (status->feature_flags & DM_CACHE_FEATURE_WRITETHROUGH)
ret->mode = BD_LVM_CACHE_MODE_WRITETHROUGH;
else if (status->feature_flags & DM_CACHE_FEATURE_WRITEBACK)
ret->mode = BD_LVM_CACHE_MODE_WRITEBACK;
else {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_CACHE_INVAL,
"Failed to determine status of the cache from '%"G_GUINT64_FORMAT"': ",
status->feature_flags);
dm_task_destroy (task);
dm_pool_destroy (pool);
bd_lvm_cache_stats_free (ret);
return NULL;
}

dm_task_destroy (task);
dm_pool_destroy (pool);

return ret;
}

/**
* bd_lvm_thpool_convert:
* @vg_name: name of the VG to create the new thin pool in
Expand Down
Loading