1209
1209
string time_stamp = dt_created.format("%Y-%m-%d_%H-%M-%S");
1210
string snapshot_dir = repo.snapshots_path;
1211
1210
string snapshot_name = time_stamp;
1212
string snapshot_path = path_combine(snapshot_dir, snapshot_name);
1213
dir_create(snapshot_path);
1211
string sys_uuid = (sys_root == null) ? "" : sys_root.uuid;
1212
string snapshot_path = "";
1215
string sys_uuid = (sys_root == null) ? "" : sys_root.uuid;
1216
Snapshot snapshot_to_link = null;
1218
1214
// create subvolume snapshots
1220
1216
foreach(var subvol in sys_subvolumes.values){
1222
string mount_path = repo.mount_path;
1224
if ((subvol.name == "@home") && (subvol.dev_uuid != repo.device.uuid)){
1226
Device.automount_udisks(subvol.dev_uuid, parent_window);
1228
var mps = Device.get_device_mount_points(subvol.dev_uuid);
1230
mount_path = mps[0].mount_point;
1237
string cmd = "btrfs subvolume snapshot '%s/%s' '%s/%s' \n".printf(mount_path, subvol.name, snapshot_path, subvol.name);
1218
snapshot_path = path_combine(repo.mount_paths[subvol.name], "timeshift-btrfs/snapshots/%s".printf(snapshot_name));
1219
dir_create(snapshot_path, true);
1221
string src_path = path_combine(repo.mount_paths[subvol.name], subvol.name);
1222
string dst_path = path_combine(snapshot_path, subvol.name);
1224
string cmd = "btrfs subvolume snapshot '%s' '%s' \n".printf(src_path, dst_path);
1238
1225
if (LOG_COMMANDS) { log_debug(cmd); }
1240
1227
string std_out, std_err;
1245
1232
log_error(_("Failed to create subvolume snapshot") + ": %s".printf(subvol.name));
1236
log_msg(_("Created subvolume snapshot") + ": %s".printf(dst_path));
1250
log_msg(_("Writing control file..."));
1240
//log_msg(_("Writing control file..."));
1242
snapshot_path = path_combine(repo.mount_paths["@"], "timeshift-btrfs/snapshots/%s".printf(snapshot_name));
1252
1244
// write control file
1253
1245
var snapshot = Snapshot.write_control_file(
1254
1246
snapshot_path, dt_created, sys_uuid, current_distro.full_name(),
1255
tag, cmd_comments, 0, true, false);
1247
tag, cmd_comments, 0, true, false, App.repo);
1257
1249
// write subvolume info
1258
1250
foreach(var subvol in sys_subvolumes.values){
2441
2457
int ret_val = exec_script_sync(sh_fsck, null, null, false, false, false, true);
2461
public bool restore_execute_btrfs(Gtk.Window? parent_win){
2463
log_debug("Main: restore_execute_btrfs()");
2465
string cmd, std_out, std_err;
2467
//query_subvolume_info();
2469
bool ok = create_pre_restore_snapshot_btrfs();
2474
// restore snapshot subvolumes by creating new subvolume snapshots
2476
foreach(string subvol_name in new string[] { "@","@home" }){
2478
string subvol_path = path_combine(snapshot_to_restore.path, subvol_name);
2480
if (dir_exists(subvol_path)){
2481
string src_path = path_combine(snapshot_to_restore.path, subvol_name);
2482
string dst_path = path_combine(App.repo.mount_paths[subvol_name], subvol_name);
2483
cmd = "btrfs subvolume snapshot '%s' '%s'".printf(src_path, dst_path);
2485
int status = exec_sync(cmd, out std_out, out std_err);
2487
log_error (std_err);
2488
log_error(_("btrfs returned an error") + ": %d".printf(status));
2489
log_error(_("Failed to restore system subvolume") + ": %s".printf(subvol_name));
2493
log_msg(_("Restored system subvolume") + ": %s".printf(subvol_name));
2498
log_msg(_("Restore completed without errors"));
2499
if (restore_current_system){
2500
log_msg(_("Snapshot will become active after system is rebooted."));
2506
public bool create_pre_restore_snapshot_btrfs(){
2508
log_debug("Main: create_pre_restore_snapshot_btrfs()");
2510
string cmd, std_out, std_err;
2511
DateTime dt_created = new DateTime.now_local();
2512
string time_stamp = dt_created.format("%Y-%m-%d_%H-%M-%S");
2513
string snapshot_name = time_stamp;
2514
string snapshot_path = path_combine(App.repo.snapshots_path, snapshot_name);
2517
* The @ and @home subvolumes need to be backed-up only if they are in use by the system.
2518
* If user restores a snapshot and then tries to restore another snapshot before the next reboot
2519
* then the @ and @home subvolumes are the ones that were previously restored and need to be deleted.
2522
bool create_pre_restore_backup = false;
2524
if (restore_current_system){
2526
// check for an existing pre-restore backup
2528
Snapshot snap_prev = null;
2530
foreach(var bak in repo.snapshots){
2534
log_msg(_("Found existing pre-restore snapshot") + ": %s".printf(bak.name));
2540
//delete system subvolumes
2541
sys_subvolumes["@"].remove();
2542
sys_subvolumes["@home"].remove();
2543
log_msg(_("Deleted system subvolumes: @, @home"));
2545
//update description for pre-restore backup
2546
snap_prev.description = "Before restoring '%s'".printf(snapshot_to_restore.date_formatted);
2547
snap_prev.update_control_file();
2550
create_pre_restore_backup = true;
2554
create_pre_restore_backup = true;
2557
if (create_pre_restore_backup){
2559
log_msg(_("Creating pre-restore snapshot from system subvolumes..."));
2561
dir_create(snapshot_path);
2563
// move subvolumes ----------------
2565
bool no_subvolumes_found = true;
2567
foreach(string subvol_name in new string[] { "@", "@home" }){
2569
string src_path = path_combine(repo.mount_paths[subvol_name], subvol_name);
2570
if (!dir_exists(src_path)){
2571
log_error(_("Could not find system subvolume") + ": %s".printf(subvol_name));
2575
no_subvolumes_found = false;
2577
string dst_path = path_combine(snapshot_path, subvol_name);
2578
cmd = "mv '%s' '%s'".printf(src_path, dst_path);
2580
int status = exec_sync(cmd, out std_out, out std_err);
2582
log_error (std_err);
2583
log_error(_("Failed to move system subvolume to snapshot directory") + ": %s".printf(subvol_name));
2587
log_msg(_("Moved system subvolume to snapshot directory") + ": %s".printf(subvol_name));
2591
if (no_subvolumes_found){
2592
//could not find system subvolumes for backing up(!)
2593
file_delete(snapshot_path); //cleanup and ignore
2594
log_error(_("Could not find system subvolumes for creating pre-restore snapshot"));
2597
// write control file -----------
2599
var snap = Snapshot.write_control_file(
2600
snapshot_path, dt_created, sys_root.uuid, current_distro.full_name(),
2601
"ondemand", "", 0, true, false, App.repo);
2603
snap.description = "Before restoring '%s'".printf(snapshot_to_restore.date_formatted);
2606
// write subvolume info
2607
foreach(var subvol in sys_subvolumes.values){
2608
snap.subvolumes.set(subvol.name, subvol);
2611
snap.update_control_file(); // save subvolume info
2613
log_msg(_("Created pre-restore snapshot") + ": %s".printf(snap.name));
2615
repo.load_snapshots();