Skip to content
This repository has been archived by the owner on Oct 16, 2022. It is now read-only.

Commit

Permalink
Fix #865, #839, #680: Do not create or remove Qgroups when snapshots …
Browse files Browse the repository at this point in the history
…are created or removed

This fixes multiple issues related to quota groups but also removes the ability to display columns for 'Size' and 'Unshared Size' for BTRFS snapshots.
  • Loading branch information
teejee2008 committed May 28, 2022
1 parent d7ba851 commit 4b1af6d
Show file tree
Hide file tree
Showing 4 changed files with 2 additions and 267 deletions.
225 changes: 1 addition & 224 deletions src/Core/Main.vala
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ public class Main : GLib.Object{
public int count_hourly = 6;
public int count_boot = 5;

public bool btrfs_use_qgroup = true;

public string app_mode = "";

public bool dry_run = false;
Expand Down Expand Up @@ -2881,8 +2879,6 @@ public class Main : GLib.Object{

log_msg(string.nfill(78, '-'));

query_subvolume_quotas();

thread_restore_running = false;
return thr_success;
}
Expand Down Expand Up @@ -3054,7 +3050,6 @@ public class Main : GLib.Object{
config.set_string_member("include_btrfs_home_for_backup", include_btrfs_home_for_backup.to_string());
config.set_string_member("include_btrfs_home_for_restore", include_btrfs_home_for_restore.to_string());
config.set_string_member("stop_cron_emails", stop_cron_emails.to_string());
config.set_string_member("btrfs_use_qgroup", btrfs_use_qgroup.to_string());

config.set_string_member("schedule_monthly", schedule_monthly.to_string());
config.set_string_member("schedule_weekly", schedule_weekly.to_string());
Expand Down Expand Up @@ -3151,8 +3146,7 @@ public class Main : GLib.Object{

include_btrfs_home_for_restore = json_get_bool(config, "include_btrfs_home_for_restore", include_btrfs_home_for_restore);
stop_cron_emails = json_get_bool(config, "stop_cron_emails", stop_cron_emails);
btrfs_use_qgroup = json_get_bool(config, "btrfs_use_qgroup", btrfs_use_qgroup);


if (cmd_btrfs_mode != null){
btrfs_mode = cmd_btrfs_mode; //override
}
Expand Down Expand Up @@ -3843,31 +3837,6 @@ public class Main : GLib.Object{
return;
}

//query quota
ok = query_subvolume_quotas();

if (!ok){

if (btrfs_use_qgroup){

//try enabling quota
ok = enable_subvolume_quotas();
if (!ok){
thread_subvol_info_success = false;
thread_subvol_info_running = false;
return;
}

//query quota again
ok = query_subvolume_quotas();
if (!ok){
thread_subvol_info_success = false;
thread_subvol_info_running = false;
return;
}
}
}

thread_subvol_info_success = true;
thread_subvol_info_running = false;
return;
Expand Down Expand Up @@ -3942,198 +3911,6 @@ public class Main : GLib.Object{
return true;
}

public bool query_subvolume_quotas(){

bool ok = query_subvolume_quota("@");
if (repo.device.uuid != repo.device_home.uuid){
ok = ok && query_subvolume_quota("@home");
}
return ok;
}

public bool query_subvolume_quota(string subvol_name){

log_debug("query_subvolume_quota():%s".printf(subvol_name));

string cmd = "";
string std_out;
string std_err;
int ret_val;

string options = use_option_raw ? "--raw" : "";

cmd = "btrfs qgroup show %s '%s'".printf(options, repo.mount_paths[subvol_name]);
log_debug(cmd);
ret_val = exec_sync(cmd, out std_out, out std_err);

if (ret_val != 0){

if (use_option_raw){
use_option_raw = false;

// try again without --raw option
cmd = "btrfs qgroup show '%s'".printf(repo.mount_paths[subvol_name]);
log_debug(cmd);
ret_val = exec_sync(cmd, out std_out, out std_err);
}

if (ret_val != 0){
log_error (std_err);
log_error(_("btrfs returned an error") + ": %d".printf(ret_val));
log_error(_("Failed to query subvolume quota"));
return false;
}
}

/* Sample Output:
*
qgroupid rfer excl
-------- ---- ----
0/5 106496 106496
0/257 3825262592 557056
0/258 12689408 49152
* */

foreach(string line in std_out.split("\n")){
if (line == null) { continue; }

string[] parts = line.split(" ");
if (parts.length < 3) { continue; }
if (parts[0].split("/").length < 2) { continue; }

int subvol_id = int.parse(parts[0].split("/")[1]);

Subvolume subvol = null;

if ((sys_subvolumes.size > 0) && (sys_subvolumes["@"].id == subvol_id)){

subvol = sys_subvolumes["@"];
}
else if ((sys_subvolumes.size > 0)
&& sys_subvolumes.has_key("@home")
&& (sys_subvolumes["@home"].id == subvol_id)){

subvol = sys_subvolumes["@home"];
}
else {
foreach(var bak in repo.snapshots){
foreach(var sub in bak.subvolumes.values){
if (sub.id == subvol_id){
subvol = sub;
}
}
}
}

if (subvol != null){
int part_num = -1;
foreach(string part in parts){
if (part.strip().length > 0){
part_num ++;
switch (part_num){
case 1:
subvol.total_bytes = int64.parse(part);
break;
case 2:
subvol.unshared_bytes = int64.parse(part);
break;
default:
//ignore
break;
}
}
}
}
}

foreach(var bak in repo.snapshots){
bak.update_control_file();
}

return true;
}

public bool enable_subvolume_quotas(){

if (!btrfs_use_qgroup){ return false; }

bool ok = enable_subvolume_quota("@");

if (repo.device.uuid != repo.device_home.uuid){
ok = ok && enable_subvolume_quota("@home");
}
if (ok){
log_msg(_("Enabled subvolume quota support"));
}

return ok;
}

public bool enable_subvolume_quota(string subvol_name){

if (!btrfs_use_qgroup){ return false; }

log_debug("enable_subvolume_quota():%s".printf(subvol_name));

string cmd = "";
string std_out;
string std_err;
int ret_val;

cmd = "btrfs quota enable '%s'".printf(repo.mount_paths[subvol_name]);
log_debug(cmd);

ret_val = exec_sync(cmd, out std_out, out std_err);

if (ret_val != 0){
log_error (std_err);
log_error(_("btrfs returned an error") + ": %d".printf(ret_val));
log_error(_("Failed to enable subvolume quota"));
return false;
}

return true;
}

public bool rescan_subvolume_quotas(){

bool ok = rescan_subvolume_quota("@");

if (repo.device.uuid != repo.device_home.uuid){
ok = ok && rescan_subvolume_quota("@home");
}
if (ok){
log_msg(_("Enabled subvolume quota support"));
}

return ok;
}

public bool rescan_subvolume_quota(string subvol_name){

log_debug("rescan_subvolume_quota():%s".printf(subvol_name));

string cmd = "";
string std_out;
string std_err;
int ret_val;

cmd = "btrfs quota rescan '%s'".printf(repo.mount_paths[subvol_name]);
log_debug(cmd);

ret_val = exec_sync(cmd, out std_out, out std_err);

if (ret_val != 0){

log_error (std_err);
log_error(_("btrfs returned an error") + ": %d".printf(ret_val));
log_error(_("Failed to rescan subvolume quota"));
return false;
}

return true;
}

// cron jobs

public void cron_job_update(){
Expand Down
15 changes: 0 additions & 15 deletions src/Core/Subvolume.vala
Original file line number Diff line number Diff line change
Expand Up @@ -165,21 +165,6 @@ public class Subvolume : GLib.Object{
}

log_msg("%s: %s (Id:%ld)\n".printf(_("Deleted subvolume"), name, id));

if ((id > 0) && (repo != null)){

log_msg("%s: 0/%ld".printf(_("Destroying qgroup"), id));

cmd = "btrfs qgroup destroy 0/%ld '%s'".printf(id, repo.mount_paths[name]);
log_debug(cmd);
ret_val = exec_sync(cmd, out std_out, out std_err);
if (ret_val != 0){
log_error(_("Failed to destroy qgroup") + ": '0/%ld'".printf(id));
return false;
}

log_msg("%s: 0/%ld\n".printf(_("Destroyed qgroup"), id));
}

return true;
}
Expand Down
6 changes: 1 addition & 5 deletions src/Gtk/MiscBox.vala
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@ class MiscBox : Gtk.Box{

private Gtk.Window parent_window;
private bool restore_mode = false;

//private Gtk.CheckButton chk_include_btrfs_home;
//private Gtk.CheckButton chk_enable_qgroups;



public MiscBox (Gtk.Window _parent_window, bool _restore_mode) {

log_debug("MiscBox: MiscBox()");
Expand Down
23 changes: 0 additions & 23 deletions src/Gtk/UsersBox.vala
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ class UsersBox : Gtk.Box{
private Gtk.Box box_btrfs;
private Gtk.Label lbl_message;
private Gtk.CheckButton chk_include_btrfs_home;
private Gtk.CheckButton chk_enable_qgroups;
private bool restore_mode = false;

public UsersBox (Gtk.Window _parent_window, ExcludeBox _exclude_box, bool _restore_mode) {
Expand Down Expand Up @@ -73,8 +72,6 @@ class UsersBox : Gtk.Box{
add(box_btrfs);

init_btrfs_home_option(box_btrfs);

init_btrfs_qgroup_option(box_btrfs);

refresh();

Expand Down Expand Up @@ -347,26 +344,6 @@ class UsersBox : Gtk.Box{
}
}

private void init_btrfs_qgroup_option(Gtk.Box box){

if (!restore_mode){

var label = add_label_header(box, _("Miscellaneous"), true);
label.margin_top = 12;

chk_enable_qgroups = new Gtk.CheckButton.with_label(_("Enable BTRFS qgroups (recommended)"));
box.add(chk_enable_qgroups);

chk_enable_qgroups.set_tooltip_text(_("Required for displaying shared and unshared size for snapshots in the main window"));

chk_enable_qgroups.active = App.btrfs_use_qgroup;

chk_enable_qgroups.toggled.connect(()=>{
App.btrfs_use_qgroup = chk_enable_qgroups.active;
});
}
}

// helpers

public void refresh(){
Expand Down

0 comments on commit 4b1af6d

Please sign in to comment.