mirror of
https://github.com/openSUSE/snapper.git
synced 2026-02-05 15:46:00 +01:00
- support sending compressed data in snbk
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024 SUSE LLC
|
||||
* Copyright (c) [2024-2025] SUSE LLC
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
@@ -70,6 +70,10 @@ namespace snapper
|
||||
get_child_value(json_file.get_root(), "ssh-identity", ssh_identity);
|
||||
}
|
||||
|
||||
get_child_value(json_file.get_root(), "send-compressed-data", send_compressed_data);
|
||||
get_child_nodes(json_file.get_root(), "send-options", send_options);
|
||||
get_child_nodes(json_file.get_root(), "receive-options", receive_options);
|
||||
|
||||
get_child_value(json_file.get_root(), "target-btrfs-bin", target_btrfs_bin);
|
||||
get_child_value(json_file.get_root(), "target-findmnt-bin", target_findmnt_bin);
|
||||
get_child_value(json_file.get_root(), "target-mkdir-bin", target_mkdir_bin);
|
||||
|
||||
@@ -70,6 +70,10 @@ namespace snapper
|
||||
Shell get_source_shell() const;
|
||||
Shell get_target_shell() const;
|
||||
|
||||
bool send_compressed_data = true;
|
||||
vector<string> send_options;
|
||||
vector<string> receive_options;
|
||||
|
||||
string target_btrfs_bin = BTRFS_BIN;
|
||||
string target_findmnt_bin = FINDMNT_BIN;
|
||||
string target_mkdir_bin = MKDIR_BIN;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) [2004-2015] Novell, Inc.
|
||||
* Copyright (c) [2017-2024] SUSE LLC
|
||||
* Copyright (c) [2017-2025] SUSE LLC
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/utsname.h>
|
||||
#include <cstring>
|
||||
#include <regex>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@@ -259,4 +260,88 @@ namespace snapper
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CmdBtrfsVersion::query_version()
|
||||
{
|
||||
if (did_set_version)
|
||||
return;
|
||||
|
||||
SystemCmd::Args cmd_args = { btrfs_bin, "--version" };
|
||||
SystemCmd cmd(shellify(shell, cmd_args));
|
||||
|
||||
if (cmd.retcode() != 0)
|
||||
{
|
||||
y2err("command '" << cmd.cmd() << "' failed: " << cmd.retcode());
|
||||
for (const string& tmp : cmd.get_stdout())
|
||||
y2err(tmp);
|
||||
for (const string& tmp : cmd.get_stderr())
|
||||
y2err(tmp);
|
||||
|
||||
SN_THROW(Exception("'btrfs --version' failed"));
|
||||
}
|
||||
|
||||
parse_version(cmd.get_stdout()[0]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CmdBtrfsVersion::parse_version(const string& version)
|
||||
{
|
||||
// example versions: "5.14 " (yes, with a trailing space), "6.0", "6.0.2"
|
||||
const regex version_rx("btrfs-progs v([0-9]+)\\.([0-9]+)(\\.([0-9]+))?( )*", regex::extended);
|
||||
|
||||
smatch match;
|
||||
|
||||
if (!regex_match(version, match, version_rx))
|
||||
SN_THROW(Exception("failed to parse btrfs version '" + version + "'"));
|
||||
|
||||
major = stoi(match[1]);
|
||||
minor = stoi(match[2]);
|
||||
patchlevel = match[4].length() == 0 ? 0 : stoi(match[4]);
|
||||
|
||||
y2mil("major:" << major << " minor:" << minor << " patchlevel:" << patchlevel);
|
||||
|
||||
did_set_version = true;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
CmdBtrfsVersion::supported_proto()
|
||||
{
|
||||
query_version();
|
||||
|
||||
if (major >= 6)
|
||||
return 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Uname::supported_proto()
|
||||
{
|
||||
const regex release_rx("^([0-9]+)\\.([0-9]+).*", regex::extended);
|
||||
|
||||
struct utsname buffer;
|
||||
|
||||
if (uname(&buffer) < 0)
|
||||
SN_THROW(Exception("syscall uname failed"));
|
||||
|
||||
cmatch match;
|
||||
|
||||
if (!regex_match(buffer.release, match, release_rx))
|
||||
SN_THROW(Exception("failed to parse uname release '" + string(buffer.release) + "'"));
|
||||
|
||||
int major = stoi(match[1]);
|
||||
int minor = stoi(match[2]);
|
||||
|
||||
y2mil("major:" << major << " minor:" << minor);
|
||||
|
||||
if (major >= 6)
|
||||
return 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) [2004-2015] Novell, Inc.
|
||||
* Copyright (c) [2017-2024] SUSE LLC
|
||||
* Copyright (c) [2017-2025] SUSE LLC
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
@@ -116,6 +116,45 @@ namespace snapper
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Lazy query of btrfs command version.
|
||||
*/
|
||||
class CmdBtrfsVersion
|
||||
{
|
||||
public:
|
||||
|
||||
CmdBtrfsVersion(const string& btrfs_bin, const Shell& shell)
|
||||
: btrfs_bin(btrfs_bin), shell(shell)
|
||||
{}
|
||||
|
||||
int supported_proto();
|
||||
|
||||
private:
|
||||
|
||||
void query_version();
|
||||
void parse_version(const string& version);
|
||||
|
||||
const string btrfs_bin;
|
||||
const Shell shell;
|
||||
|
||||
bool did_set_version = false;
|
||||
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
int patchlevel = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class Uname
|
||||
{
|
||||
public:
|
||||
|
||||
static int supported_proto();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
#include <sys/stat.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -187,6 +187,28 @@ namespace snapper
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
get_child_nodes(json_object* parent, const char* name, vector<string>& values)
|
||||
{
|
||||
vector<json_object*> children;
|
||||
|
||||
if (!get_child_nodes(parent, name, children))
|
||||
return false;
|
||||
|
||||
values.clear();
|
||||
|
||||
for (json_object* child : children)
|
||||
{
|
||||
if (!json_object_is_type(child, json_type_string))
|
||||
return false;
|
||||
|
||||
values.push_back(json_object_get_string(child));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
get_child_nodes(json_object* parent, const char* name, vector<json_object*>& children)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) [2017-2024] SUSE LLC
|
||||
* Copyright (c) [2017-2025] SUSE LLC
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
@@ -68,6 +68,9 @@ namespace snapper
|
||||
get_child_value(json_object* parent, const char* name, Type& value);
|
||||
|
||||
|
||||
bool
|
||||
get_child_nodes(json_object* parent, const char* name, vector<string>& values);
|
||||
|
||||
bool
|
||||
get_child_nodes(json_object* parent, const char* name, vector<json_object*>& children);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace snapper
|
||||
|
||||
|
||||
void
|
||||
TheBigThing::transfer(const BackupConfig& backup_config, const TheBigThings& the_big_things,
|
||||
TheBigThing::transfer(const BackupConfig& backup_config, TheBigThings& the_big_things,
|
||||
bool quiet)
|
||||
{
|
||||
if (!quiet)
|
||||
@@ -137,16 +137,29 @@ namespace snapper
|
||||
|
||||
// Copy snapshot to target.
|
||||
|
||||
const int proto = std::min({
|
||||
Uname::supported_proto(),
|
||||
the_big_things.source_btrfs_version.supported_proto(),
|
||||
the_big_things.target_btrfs_version.supported_proto()
|
||||
});
|
||||
|
||||
TheBigThings::const_iterator it1 = the_big_things.find_send_parent(*this);
|
||||
|
||||
SystemCmd::Args cmd3a_args = { BTRFS_BIN, "send" };
|
||||
if (proto >= 2)
|
||||
cmd3a_args << "--proto" << to_string(proto);
|
||||
if (backup_config.send_compressed_data && proto >= 2)
|
||||
cmd3a_args << "--compressed-data";
|
||||
cmd3a_args << backup_config.send_options;
|
||||
|
||||
if (it1 != the_big_things.end())
|
||||
cmd3a_args << "-p" << backup_config.source_path + "/" SNAPSHOTS_NAME "/" +
|
||||
to_string(it1->num) + "/" SNAPSHOT_NAME;
|
||||
cmd3a_args << "--" << backup_config.source_path + "/" SNAPSHOTS_NAME "/" + num_string + "/" SNAPSHOT_NAME;
|
||||
|
||||
SystemCmd::Args cmd3b_args = { backup_config.target_btrfs_bin, "receive", "--",
|
||||
backup_config.target_path + "/" + num_string };
|
||||
SystemCmd::Args cmd3b_args = { backup_config.target_btrfs_bin, "receive" };
|
||||
cmd3b_args << backup_config.receive_options;
|
||||
cmd3b_args << "--" << backup_config.target_path + "/" + num_string;
|
||||
|
||||
y2deb("source: " << cmd3a_args.get_values());
|
||||
y2deb("target: " << cmd3b_args.get_values());
|
||||
@@ -238,7 +251,9 @@ namespace snapper
|
||||
|
||||
|
||||
TheBigThings::TheBigThings(const BackupConfig& backup_config, ProxySnappers* snappers, bool verbose)
|
||||
: snapper(snappers->getSnapper(backup_config.config)), locker(snapper)
|
||||
: source_btrfs_version(BTRFS_BIN, backup_config.get_source_shell()),
|
||||
target_btrfs_version(backup_config.target_btrfs_bin, backup_config.get_target_shell()),
|
||||
snapper(snappers->getSnapper(backup_config.config)), locker(snapper)
|
||||
{
|
||||
if (backup_config.source_path != snapper->getConfig().getSubvolume())
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024 SUSE LLC
|
||||
* Copyright (c) [2024-2025] SUSE LLC
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "../proxy/proxy.h"
|
||||
#include "../proxy/locker.h"
|
||||
|
||||
#include "CmdBtrfs.h"
|
||||
|
||||
|
||||
namespace snapper
|
||||
{
|
||||
@@ -52,7 +54,7 @@ namespace snapper
|
||||
|
||||
TheBigThing(unsigned int num) : num(num) {}
|
||||
|
||||
void transfer(const BackupConfig& backup_config, const TheBigThings& the_big_things, bool quiet);
|
||||
void transfer(const BackupConfig& backup_config, TheBigThings& the_big_things, bool quiet);
|
||||
|
||||
void remove(const BackupConfig& backup_config, bool quiet);
|
||||
|
||||
@@ -110,6 +112,9 @@ namespace snapper
|
||||
*/
|
||||
const_iterator find_send_parent(const TheBigThing& the_big_thing) const;
|
||||
|
||||
CmdBtrfsVersion source_btrfs_version;
|
||||
CmdBtrfsVersion target_btrfs_version;
|
||||
|
||||
private:
|
||||
|
||||
const ProxySnapper* snapper;
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
<refentry id='snapper-backup-configs5'>
|
||||
|
||||
<refentryinfo>
|
||||
<date>2025-04-09</date>
|
||||
<date>2025-10-07</date>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>snapper-backup-configs</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
<refmiscinfo class='date'>2025-04-09</refmiscinfo>
|
||||
<refmiscinfo class='date'>2025-10-07</refmiscinfo>
|
||||
<refmiscinfo class='version'>@VERSION@</refmiscinfo>
|
||||
<refmiscinfo class='manual'>Filesystem Snapshot Management</refmiscinfo>
|
||||
</refmeta>
|
||||
@@ -102,6 +102,33 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>send-compressed-data</option></term>
|
||||
<listitem>
|
||||
<para>Per default snbk will add the option --compressed-data iff
|
||||
supported by the source and target system. This can be disable by
|
||||
setting this value to false.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>send-options</option></term>
|
||||
<listitem>
|
||||
<para>Extra options for the btrfs send command as an array
|
||||
of strings. Optional.</para>
|
||||
<para>Per default snbk automatically adds --proto and --compressed-data
|
||||
iff supported by both the source and target.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>receive-options</option></term>
|
||||
<listitem>
|
||||
<para>Extra options for the btrfs receive command as an
|
||||
array of strings. Optional.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>target-btrfs-bin</option></term>
|
||||
<listitem>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Oct 07 14:42:16 CEST 2025 - aschnell@suse.com
|
||||
|
||||
- support sending compressed data in snbk
|
||||
(gh#openSUSE/snapper#1059)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Sep 24 16:12:34 CEST 2025 - aschnell@suse.com
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$#" -eq 1 ] && [ "$1" == "--version" ]; then
|
||||
exec sudo /usr/sbin/btrfs --version
|
||||
fi
|
||||
|
||||
if [ "$#" -lt 3 ]; then
|
||||
echo "Usage: $0 <group> [subcommand] [options] -- /backup/..."
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user