Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions docs/libblockdev-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,8 @@ bd_lvm_vgextend
bd_lvm_vgreduce
bd_lvm_vglock_start
bd_lvm_vglock_stop
bd_lvm_vgcfgbackup
bd_lvm_vgcfgrestore
bd_lvm_add_vg_tags
bd_lvm_delete_vg_tags
bd_lvm_vginfo
Expand Down
37 changes: 37 additions & 0 deletions src/lib/plugin_apis/lvm.api
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ typedef enum {
BD_LVM_TECH_DEVICES,
BD_LVM_TECH_SHARED,
BD_LVM_TECH_CONFIG,
BD_LVM_TECH_VG_CFG_BACKUP_RESTORE,
} BDLVMTech;

typedef enum {
Expand Down Expand Up @@ -2044,4 +2045,40 @@ gboolean bd_lvm_devices_delete (const gchar *device, const gchar *devices_file,
*/
gchar* bd_lvm_config_get (const gchar *section, const gchar *setting, const gchar *type, gboolean values_only, gboolean global_config, const BDExtraArg **extra, GError **error);

/**
* bd_lvm_vgcfgbackup:
* @vg_name: name of the VG to backup configuration
* @backup_file: (nullable): file to save the backup to or %NULL for using the default backup file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still get an impression that this is about backing up the whole VG data. I think it should be noted this is about configuration of the VG.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I've changed both the docstrings to emphasize the backup/restore is for configuration only. I've also added note from the vgcfgbackup which mentions this doesn't back up the LV data.

* in /etc/lvm/backup
* @extra: (nullable) (array zero-terminated=1): extra options for the vgcfgbackup command
* (just passed to LVM as is)
* @error: (out) (optional): place to store error (if any)
*
* Note: This function does not back up the data content of LVs. See `vgcfbackup(8)` man page
* for more information.
*
* Returns: Whether the backup was successfully created or not.
*
* Tech category: %BD_LVM_TECH_VG_CFG_BACKUP_RESTORE no mode (it is ignored)
*/
gboolean bd_lvm_vgcfgbackup (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error);

/**
* bd_lvm_vgcfgrestore:
* @vg_name: name of the VG to restore configuration
* @backup_file: (nullable): file to restore VG configuration from to or %NULL for using the
* latest backup in /etc/lvm/backup
* @extra: (nullable) (array zero-terminated=1): extra options for the vgcfgrestore command
* (just passed to LVM as is)
* @error: (out) (optional): place to store error (if any)
*
* Note: This function restores VG configuration created by %bd_lvm_vgcfgbackup from given
* @backup_file or from the latest backup in /etc/lvm/backup.
*
* Returns: Whether the configuration was successfully restored or not.
*
* Tech category: %BD_LVM_TECH_VG_CFG_BACKUP_RESTORE no mode (it is ignored)
*/
gboolean bd_lvm_vgcfgrestore (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error);

#endif /* BD_LVM_API */
63 changes: 63 additions & 0 deletions src/plugins/lvm/lvm-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,3 +787,66 @@ gchar* bd_lvm_config_get (const gchar *section, const gchar *setting, const gcha
return NULL;
return g_strchomp (output);
}

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};
guint next_arg = 1;
gchar *output = NULL;
g_autofree gchar *config_arg = NULL;

args[next_arg++] = command;
if (file) {
args[next_arg++] = "-f";
args[next_arg++] = file;
}
args[next_arg++] = vg_name;

g_mutex_lock (&global_config_lock);
if (global_config_str) {
config_arg = g_strdup_printf ("--config=%s", global_config_str);
args[next_arg++] = config_arg;
}
g_mutex_unlock (&global_config_lock);

return bd_utils_exec_and_capture_output (args, extra, &output, error);
}

/**
* bd_lvm_vgcfgbackup:
* @vg_name: name of the VG to backup configuration
* @backup_file: (nullable): file to save the backup to or %NULL for using the default backup file
* in /etc/lvm/backup
* @extra: (nullable) (array zero-terminated=1): extra options for the vgcfgbackup command
* (just passed to LVM as is)
* @error: (out) (optional): place to store error (if any)
*
* Note: This function does not back up the data content of LVs. See `vgcfbackup(8)` man page
* for more information.
*
* Returns: Whether the backup was successfully created or not.
*
* Tech category: %BD_LVM_TECH_VG_CFG_BACKUP_RESTORE no mode (it is ignored)
*/
gboolean bd_lvm_vgcfgbackup (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error) {
return _vgcfgbackup_restore ("vgcfgbackup", vg_name, backup_file, extra, error);
}

/**
* bd_lvm_vgcfgrestore:
* @vg_name: name of the VG to restore configuration
* @backup_file: (nullable): file to restore VG configuration from to or %NULL for using the
* latest backup in /etc/lvm/backup
* @extra: (nullable) (array zero-terminated=1): extra options for the vgcfgrestore command
* (just passed to LVM as is)
* @error: (out) (optional): place to store error (if any)
*
* Note: This function restores VG configuration created by %bd_lvm_vgcfgbackup from given
* @backup_file or from the latest backup in /etc/lvm/backup.
*
* Returns: Whether the configuration was successfully restored or not.
*
* Tech category: %BD_LVM_TECH_VG_CFG_BACKUP_RESTORE no mode (it is ignored)
*/
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);
}
2 changes: 2 additions & 0 deletions src/plugins/lvm/lvm-dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ gboolean bd_lvm_is_tech_avail (BDLVMTech tech, guint64 mode, GError **error) {
return check_deps (&avail_deps, DEPS_LVMDEVICES_MASK, deps, DEPS_LAST, &deps_check_lock, error);
case BD_LVM_TECH_CONFIG:
return check_deps (&avail_deps, DEPS_LVMCONFIG_MASK, deps, DEPS_LAST, &deps_check_lock, error);
case BD_LVM_TECH_VG_CFG_BACKUP_RESTORE:
return check_deps (&avail_deps, DEPS_LVM_MASK, deps, DEPS_LAST, &deps_check_lock, error);
default:
/* everything is supported by this implementation of the plugin */
return check_dbus_deps (&avail_dbus_deps, DBUS_DEPS_LVMDBUSD_MASK, dbus_deps, DBUS_DEPS_LAST, &deps_check_lock, error);
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/lvm/lvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ typedef enum {
BD_LVM_TECH_DEVICES,
BD_LVM_TECH_SHARED,
BD_LVM_TECH_CONFIG,
BD_LVM_TECH_VG_CFG_BACKUP_RESTORE,
} BDLVMTech;

typedef enum {
Expand Down Expand Up @@ -256,6 +257,8 @@ gboolean bd_lvm_add_vg_tags (const gchar *vg_name, const gchar **tags, GError **
gboolean bd_lvm_delete_vg_tags (const gchar *vg_name, const gchar **tags, GError **error);
gboolean bd_lvm_vglock_start (const gchar *vg_name, const BDExtraArg **extra, GError **error);
gboolean bd_lvm_vglock_stop (const gchar *vg_name, const BDExtraArg **extra, GError **error);
gboolean bd_lvm_vgcfgbackup (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error);
gboolean bd_lvm_vgcfgrestore (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error);
BDLVMVGdata* bd_lvm_vginfo (const gchar *vg_name, GError **error);
BDLVMVGdata** bd_lvm_vgs (GError **error);

Expand Down
31 changes: 31 additions & 0 deletions tests/lvm_dbus_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import re
import shutil
import time
import tempfile
from contextlib import contextmanager
from packaging.version import Version
from itertools import chain
Expand Down Expand Up @@ -2404,3 +2405,33 @@ def test_set_empty_config(self):
BlockDev.lvm_set_global_config("")
succ = BlockDev.lvm_pvremove(self.loop_dev)
self.assertTrue(succ)


class LvmTestBackupRestore(LvmPVVGTestCase):
def test_vgcfgbackup_restore(self):
"""Verify that it is possible to backup and restore VG configuration"""

succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None)
self.assertTrue(succ)

succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev], 0, None)
self.assertTrue(succ)

with tempfile.TemporaryDirectory() as d:
succ = BlockDev.lvm_vgcfgbackup("testVG", os.path.join(d, "testVGbackup"))
self.assertTrue(succ)
self.assertTrue(os.path.isfile(os.path.join(d, "testVGbackup")))

succ = BlockDev.lvm_vgcfgrestore("testVG", os.path.join(d, "testVGbackup"))
self.assertTrue(succ)

succ = BlockDev.lvm_vgcfgbackup("testVG", None)
self.assertTrue(succ)

# default location is /etc/lvm/backup/<vgname>
self.assertTrue(os.path.isfile("/etc/lvm/backup/testVG"))

succ = BlockDev.lvm_vgcfgrestore("testVG", None)
self.assertTrue(succ)

os.unlink("/etc/lvm/backup/testVG")
31 changes: 31 additions & 0 deletions tests/lvm_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import overrides_hack
import re
import shutil
import tempfile
import time
from contextlib import contextmanager
from packaging.version import Version
Expand Down Expand Up @@ -2291,3 +2292,33 @@ def test_set_empty_config(self):
BlockDev.lvm_set_global_config("")
succ = BlockDev.lvm_pvremove(self.loop_dev)
self.assertTrue(succ)


class LvmTestBackupRestore(LvmPVVGTestCase):
def test_vgcfgbackup_restore(self):
"""Verify that it is possible to backup and restore VG configuration"""

succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None)
self.assertTrue(succ)

succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev], 0, None)
self.assertTrue(succ)

with tempfile.TemporaryDirectory() as d:
succ = BlockDev.lvm_vgcfgbackup("testVG", os.path.join(d, "testVGbackup"))
self.assertTrue(succ)
self.assertTrue(os.path.isfile(os.path.join(d, "testVGbackup")))

succ = BlockDev.lvm_vgcfgrestore("testVG", os.path.join(d, "testVGbackup"))
self.assertTrue(succ)

succ = BlockDev.lvm_vgcfgbackup("testVG", None)
self.assertTrue(succ)

# default location is /etc/lvm/backup/<vgname>
self.assertTrue(os.path.isfile("/etc/lvm/backup/testVG"))

succ = BlockDev.lvm_vgcfgrestore("testVG", None)
self.assertTrue(succ)

os.unlink("/etc/lvm/backup/testVG")