Skip to content

Commit 6f58d70

Browse files
committed
lvm: Add support for running vgcfgbackup/restore
Fixes: #565
1 parent ae6e249 commit 6f58d70

File tree

7 files changed

+169
-0
lines changed

7 files changed

+169
-0
lines changed

docs/libblockdev-sections.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ bd_lvm_vgextend
327327
bd_lvm_vgreduce
328328
bd_lvm_vglock_start
329329
bd_lvm_vglock_stop
330+
bd_lvm_vgcfgbackup
331+
bd_lvm_vgcfgrestore
330332
bd_lvm_add_vg_tags
331333
bd_lvm_delete_vg_tags
332334
bd_lvm_vginfo

src/lib/plugin_apis/lvm.api

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ typedef enum {
738738
BD_LVM_TECH_DEVICES,
739739
BD_LVM_TECH_SHARED,
740740
BD_LVM_TECH_CONFIG,
741+
BD_LVM_TECH_VG_CFG_BACKUP_RESTORE,
741742
} BDLVMTech;
742743

743744
typedef enum {
@@ -2044,4 +2045,40 @@ gboolean bd_lvm_devices_delete (const gchar *device, const gchar *devices_file,
20442045
*/
20452046
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);
20462047

2048+
/**
2049+
* bd_lvm_vgcfgbackup:
2050+
* @vg_name: name of the VG to backup configuration
2051+
* @backup_file: (nullable): file to save the backup to or %NULL for using the default backup file
2052+
* in /etc/lvm/backup
2053+
* @extra: (nullable) (array zero-terminated=1): extra options for the vgcfgbackup command
2054+
* (just passed to LVM as is)
2055+
* @error: (out) (optional): place to store error (if any)
2056+
*
2057+
* Note: This function does not back up the data content of LVs. See `vgcfbackup(8)` man page
2058+
* for more information.
2059+
*
2060+
* Returns: Whether the backup was successfully created or not.
2061+
*
2062+
* Tech category: %BD_LVM_TECH_VG_CFG_BACKUP_RESTORE no mode (it is ignored)
2063+
*/
2064+
gboolean bd_lvm_vgcfgbackup (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error);
2065+
2066+
/**
2067+
* bd_lvm_vgcfgrestore:
2068+
* @vg_name: name of the VG to restore configuration
2069+
* @backup_file: (nullable): file to restore VG configuration from to or %NULL for using the
2070+
* latest backup in /etc/lvm/backup
2071+
* @extra: (nullable) (array zero-terminated=1): extra options for the vgcfgrestore command
2072+
* (just passed to LVM as is)
2073+
* @error: (out) (optional): place to store error (if any)
2074+
*
2075+
* Note: This function restores VG configuration created by %bd_lvm_vgcfgbackup from given
2076+
* @backup_file or from the latest backup in /etc/lvm/backup.
2077+
*
2078+
* Returns: Whether the configuration was successfully restored or not.
2079+
*
2080+
* Tech category: %BD_LVM_TECH_VG_CFG_BACKUP_RESTORE no mode (it is ignored)
2081+
*/
2082+
gboolean bd_lvm_vgcfgrestore (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error);
2083+
20472084
#endif /* BD_LVM_API */

src/plugins/lvm/lvm-common.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,3 +787,66 @@ gchar* bd_lvm_config_get (const gchar *section, const gchar *setting, const gcha
787787
return NULL;
788788
return g_strchomp (output);
789789
}
790+
791+
gboolean _vgcfgbackup_restore (const gchar *command, const gchar *vg_name, const gchar *file, const BDExtraArg **extra, GError **error) {
792+
const gchar *args[6] = {"lvm", NULL, NULL, NULL, NULL, NULL};
793+
guint next_arg = 1;
794+
gchar *output = NULL;
795+
g_autofree gchar *config_arg = NULL;
796+
797+
args[next_arg++] = command;
798+
if (file) {
799+
args[next_arg++] = "-f";
800+
args[next_arg++] = file;
801+
}
802+
args[next_arg++] = vg_name;
803+
804+
g_mutex_lock (&global_config_lock);
805+
if (global_config_str) {
806+
config_arg = g_strdup_printf ("--config=%s", global_config_str);
807+
args[next_arg++] = config_arg;
808+
}
809+
g_mutex_unlock (&global_config_lock);
810+
811+
return bd_utils_exec_and_capture_output (args, extra, &output, error);
812+
}
813+
814+
/**
815+
* bd_lvm_vgcfgbackup:
816+
* @vg_name: name of the VG to backup configuration
817+
* @backup_file: (nullable): file to save the backup to or %NULL for using the default backup file
818+
* in /etc/lvm/backup
819+
* @extra: (nullable) (array zero-terminated=1): extra options for the vgcfgbackup command
820+
* (just passed to LVM as is)
821+
* @error: (out) (optional): place to store error (if any)
822+
*
823+
* Note: This function does not back up the data content of LVs. See `vgcfbackup(8)` man page
824+
* for more information.
825+
*
826+
* Returns: Whether the backup was successfully created or not.
827+
*
828+
* Tech category: %BD_LVM_TECH_VG_CFG_BACKUP_RESTORE no mode (it is ignored)
829+
*/
830+
gboolean bd_lvm_vgcfgbackup (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error) {
831+
return _vgcfgbackup_restore ("vgcfgbackup", vg_name, backup_file, extra, error);
832+
}
833+
834+
/**
835+
* bd_lvm_vgcfgrestore:
836+
* @vg_name: name of the VG to restore configuration
837+
* @backup_file: (nullable): file to restore VG configuration from to or %NULL for using the
838+
* latest backup in /etc/lvm/backup
839+
* @extra: (nullable) (array zero-terminated=1): extra options for the vgcfgrestore command
840+
* (just passed to LVM as is)
841+
* @error: (out) (optional): place to store error (if any)
842+
*
843+
* Note: This function restores VG configuration created by %bd_lvm_vgcfgbackup from given
844+
* @backup_file or from the latest backup in /etc/lvm/backup.
845+
*
846+
* Returns: Whether the configuration was successfully restored or not.
847+
*
848+
* Tech category: %BD_LVM_TECH_VG_CFG_BACKUP_RESTORE no mode (it is ignored)
849+
*/
850+
gboolean bd_lvm_vgcfgrestore (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error) {
851+
return _vgcfgbackup_restore ("vgcfgrestore", vg_name, backup_file, extra, error);
852+
}

src/plugins/lvm/lvm-dbus.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ gboolean bd_lvm_is_tech_avail (BDLVMTech tech, guint64 mode, GError **error) {
382382
return check_deps (&avail_deps, DEPS_LVMDEVICES_MASK, deps, DEPS_LAST, &deps_check_lock, error);
383383
case BD_LVM_TECH_CONFIG:
384384
return check_deps (&avail_deps, DEPS_LVMCONFIG_MASK, deps, DEPS_LAST, &deps_check_lock, error);
385+
case BD_LVM_TECH_VG_CFG_BACKUP_RESTORE:
386+
return check_deps (&avail_deps, DEPS_LVM_MASK, deps, DEPS_LAST, &deps_check_lock, error);
385387
default:
386388
/* everything is supported by this implementation of the plugin */
387389
return check_dbus_deps (&avail_dbus_deps, DBUS_DEPS_LVMDBUSD_MASK, dbus_deps, DBUS_DEPS_LAST, &deps_check_lock, error);

src/plugins/lvm/lvm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ typedef enum {
202202
BD_LVM_TECH_DEVICES,
203203
BD_LVM_TECH_SHARED,
204204
BD_LVM_TECH_CONFIG,
205+
BD_LVM_TECH_VG_CFG_BACKUP_RESTORE,
205206
} BDLVMTech;
206207

207208
typedef enum {
@@ -256,6 +257,8 @@ gboolean bd_lvm_add_vg_tags (const gchar *vg_name, const gchar **tags, GError **
256257
gboolean bd_lvm_delete_vg_tags (const gchar *vg_name, const gchar **tags, GError **error);
257258
gboolean bd_lvm_vglock_start (const gchar *vg_name, const BDExtraArg **extra, GError **error);
258259
gboolean bd_lvm_vglock_stop (const gchar *vg_name, const BDExtraArg **extra, GError **error);
260+
gboolean bd_lvm_vgcfgbackup (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error);
261+
gboolean bd_lvm_vgcfgrestore (const gchar *vg_name, const gchar *backup_file, const BDExtraArg **extra, GError **error);
259262
BDLVMVGdata* bd_lvm_vginfo (const gchar *vg_name, GError **error);
260263
BDLVMVGdata** bd_lvm_vgs (GError **error);
261264

tests/lvm_dbus_tests.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import re
77
import shutil
88
import time
9+
import tempfile
910
from contextlib import contextmanager
1011
from packaging.version import Version
1112
from itertools import chain
@@ -2404,3 +2405,33 @@ def test_set_empty_config(self):
24042405
BlockDev.lvm_set_global_config("")
24052406
succ = BlockDev.lvm_pvremove(self.loop_dev)
24062407
self.assertTrue(succ)
2408+
2409+
2410+
class LvmTestBackupRestore(LvmPVVGTestCase):
2411+
def test_vgcfgbackup_restore(self):
2412+
"""Verify that it is possible to backup and restore VG configuration"""
2413+
2414+
succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None)
2415+
self.assertTrue(succ)
2416+
2417+
succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev], 0, None)
2418+
self.assertTrue(succ)
2419+
2420+
with tempfile.TemporaryDirectory() as d:
2421+
succ = BlockDev.lvm_vgcfgbackup("testVG", os.path.join(d, "testVGbackup"))
2422+
self.assertTrue(succ)
2423+
self.assertTrue(os.path.isfile(os.path.join(d, "testVGbackup")))
2424+
2425+
succ = BlockDev.lvm_vgcfgrestore("testVG", os.path.join(d, "testVGbackup"))
2426+
self.assertTrue(succ)
2427+
2428+
succ = BlockDev.lvm_vgcfgbackup("testVG", None)
2429+
self.assertTrue(succ)
2430+
2431+
# default location is /etc/lvm/backup/<vgname>
2432+
self.assertTrue(os.path.isfile("/etc/lvm/backup/testVG"))
2433+
2434+
succ = BlockDev.lvm_vgcfgrestore("testVG", None)
2435+
self.assertTrue(succ)
2436+
2437+
os.unlink("/etc/lvm/backup/testVG")

tests/lvm_test.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import overrides_hack
66
import re
77
import shutil
8+
import tempfile
89
import time
910
from contextlib import contextmanager
1011
from packaging.version import Version
@@ -2291,3 +2292,33 @@ def test_set_empty_config(self):
22912292
BlockDev.lvm_set_global_config("")
22922293
succ = BlockDev.lvm_pvremove(self.loop_dev)
22932294
self.assertTrue(succ)
2295+
2296+
2297+
class LvmTestBackupRestore(LvmPVVGTestCase):
2298+
def test_vgcfgbackup_restore(self):
2299+
"""Verify that it is possible to backup and restore VG configuration"""
2300+
2301+
succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None)
2302+
self.assertTrue(succ)
2303+
2304+
succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev], 0, None)
2305+
self.assertTrue(succ)
2306+
2307+
with tempfile.TemporaryDirectory() as d:
2308+
succ = BlockDev.lvm_vgcfgbackup("testVG", os.path.join(d, "testVGbackup"))
2309+
self.assertTrue(succ)
2310+
self.assertTrue(os.path.isfile(os.path.join(d, "testVGbackup")))
2311+
2312+
succ = BlockDev.lvm_vgcfgrestore("testVG", os.path.join(d, "testVGbackup"))
2313+
self.assertTrue(succ)
2314+
2315+
succ = BlockDev.lvm_vgcfgbackup("testVG", None)
2316+
self.assertTrue(succ)
2317+
2318+
# default location is /etc/lvm/backup/<vgname>
2319+
self.assertTrue(os.path.isfile("/etc/lvm/backup/testVG"))
2320+
2321+
succ = BlockDev.lvm_vgcfgrestore("testVG", None)
2322+
self.assertTrue(succ)
2323+
2324+
os.unlink("/etc/lvm/backup/testVG")

0 commit comments

Comments
 (0)