2293
2293
// skip mounting for non-system devices
2295
if (mnt.mount_point.has_prefix("/mnt") || mnt.mount_point.has_prefix("/mount")
2296
|| mnt.mount_point.has_prefix("/sdcard") || mnt.mount_point.has_prefix("/cdrom")
2297
|| mnt.mount_point.has_prefix("/media") || (mnt.mount_point == "none")
2298
|| !mnt.mount_point.has_prefix("/")
2299
|| (!mnt.device.has_prefix("/dev/") && !mnt.device.down().has_prefix("uuid="))){
2295
if (!mnt.is_for_system_directory()){
2304
2299
// find device by name or uuid
2306
2301
Device mnt_dev = null;
2307
if (mnt.get_uuid().length > 0){
2308
mnt_dev = Device.get_device_by_uuid(mnt.get_uuid());
2302
if (mnt.device_uuid.length > 0){
2303
mnt_dev = Device.get_device_by_uuid(mnt.device_uuid);
2311
2306
mnt_dev = Device.get_device_by_name(mnt.device);
2993
2991
//update /etc/fstab when restoring to another device --------------------
2995
2993
if (!restore_current_system){
2996
string fstab_path = target_path + "etc/fstab";
2997
var fstab_list = FsTabEntry.read_file(fstab_path);
2999
foreach(var mount_entry in mount_list){
3001
foreach(var fstab_entry in fstab_list){
3002
if (fstab_entry.mount_point == mount_entry.mount_point){
3005
//update fstab entry
3006
fstab_entry.device = "UUID=%s".printf(mount_entry.device.uuid);
3007
fstab_entry.type = mount_entry.device.fstype;
3009
//fix mount options for / and /home
3010
if (restore_target.fstype != "btrfs"){
3012
if ((fstab_entry.mount_point == "/")
3013
&& fstab_entry.options.contains("subvol=@")){
3015
fstab_entry.options = fstab_entry.options.replace("subvol=@","").strip();
3017
if (fstab_entry.options.has_suffix(",")){
3018
fstab_entry.options = fstab_entry.options[0:fstab_entry.options.length - 1];
3021
else if ((fstab_entry.mount_point == "/home")
3022
&& fstab_entry.options.contains("subvol=@home")){
3024
fstab_entry.options = fstab_entry.options.replace("subvol=@home","").strip();
3026
if (fstab_entry.options.has_suffix(",")){
3027
fstab_entry.options = fstab_entry.options[0:fstab_entry.options.length - 1];
3035
//add new fstab entry
3036
FsTabEntry fstab_entry = new FsTabEntry();
3037
fstab_entry.device = "UUID=%s".printf(mount_entry.device.uuid);
3038
fstab_entry.mount_point = mount_entry.mount_point;
3039
fstab_entry.type = mount_entry.device.fstype;
3040
fstab_list.add(fstab_entry);
3045
* If user has not mounted /home, and /home is mounted on another device (according to the fstab file)
3046
* then remove the /home mount entry from the fstab.
3047
* This is required - otherwise when the user boots the restored system they will continue to see
3048
* the existing device as /home and instead of seeing the files restored to /home on the *root* device.
3049
* We will do this fix only for /home and leave all other mount points untouched.
3052
bool found_home_in_fstab = false;
3053
FsTabEntry fstab_home_entry = null;
3054
foreach(var fstab_entry in fstab_list){
3055
if (fstab_entry.mount_point == "/home"){
3056
found_home_in_fstab = true;
3057
fstab_home_entry = fstab_entry;
3062
bool found_home_in_mount_list = false;
3063
foreach(MountEntry mount_entry in mount_list){
3064
if (mount_entry.mount_point == "/home"){
3065
found_home_in_mount_list = true;
3070
if (found_home_in_fstab && !found_home_in_mount_list){
3071
//remove fstab entry for /home
3072
fstab_list.remove(fstab_home_entry);
3075
// sort the entries based on mount path
3076
// this is critical to ensure that base paths are mounted before child paths
3078
fstab_list.sort((a, b)=>{
3079
return strcmp(a.mount_point, b.mount_point);
3082
//write the updated file --------------
3084
string text = "# <file system> <mount point> <type> <options> <dump> <pass>\n\n";
3085
text += FsTabEntry.create_file_text(fstab_list.to_array(), false);
3086
if (file_exists(fstab_path)){
3087
file_delete(fstab_path);
3089
file_write(fstab_path, text);
3091
log_msg(_("Updated /etc/fstab on target device") + ": %s".printf(fstab_path));
3093
//create folders for mount points in /etc/fstab to prevent mount errors during boot ---------
3095
foreach(var fstab_entry in fstab_list){
3096
if (fstab_entry.mount_point.length == 0){ continue; }
3097
if (!fstab_entry.mount_point.has_prefix("/")){ continue; }
3099
string mount_path = target_path +
3100
fstab_entry.mount_point[1:fstab_entry.mount_point.length];
3102
if (fstab_entry.is_comment || fstab_entry.is_empty_line
3103
|| (mount_path.length == 0)){
3108
if (!dir_exists(mount_path)){
3110
log_msg("Created mount point on target device: %s".printf(
3111
fstab_entry.mount_point));
3113
dir_create(mount_path);
2995
fix_fstab_file(target_path);
2997
fix_crypttab_file(target_path);
3118
3000
unmount_target_device(false);
3126
3008
thread_restore_running = false;
3011
public void fix_fstab_file(string target_path){
3013
string fstab_path = target_path + "etc/fstab";
3014
var fstab_list = FsTabEntry.read_file(fstab_path);
3016
foreach(var mnt in mount_list){
3018
var entry = FsTabEntry.find_entry_by_mount_point(fstab_list, mnt.mount_point);
3022
entry = new FsTabEntry();
3023
entry.mount_point = mnt.mount_point;
3024
fstab_list.add(entry);
3027
//update fstab entry
3028
entry.device = "UUID=%s".printf(mnt.device.uuid);
3029
entry.type = mnt.device.fstype;
3031
// fix mount options for non-btrfs device
3032
if (mnt.device.fstype != "btrfs"){
3033
// remove subvol option
3034
entry.remove_option("subvol=%s".printf(entry.subvolume_name()));
3039
* Remove fstab entries for any system directories that
3040
* the user has not explicitly mapped before restore/clone
3041
* This ensures that the cloned/restored system does not mount
3042
* any devices to system paths that the user has not explicitly specified
3045
for(int i = fstab_list.size - 1; i >= 0; i--){
3046
var entry = fstab_list[i];
3048
if (!entry.is_for_system_directory()){ continue; }
3050
var mnt = MountEntry.find_entry_by_mount_point(mount_list, entry.mount_point);
3052
fstab_list.remove(entry);
3056
// write the updated file
3058
FsTabEntry.write_file(fstab_list, fstab_path, false);
3060
log_msg(_("Updated /etc/fstab on target device") + ": %s".printf(fstab_path));
3062
// create directories on disk for mount points in /etc/fstab
3064
foreach(var entry in fstab_list){
3065
if (entry.mount_point.length == 0){ continue; }
3066
if (!entry.mount_point.has_prefix("/")){ continue; }
3068
string mount_path = path_combine(
3069
target_path, entry.mount_point);
3071
if (entry.is_comment
3072
|| entry.is_empty_line
3073
|| (mount_path.length == 0)){
3078
if (!dir_exists(mount_path)){
3080
log_msg("Created mount point on target device: %s".printf(
3081
entry.mount_point));
3083
dir_create(mount_path);
3088
public void fix_crypttab_file(string target_path){
3089
string file_path = target_path + "etc/crypttab";
3090
var crypttab_list = CryptTabEntry.read_file(file_path);
3092
// add option "nofail" to existing entries
3094
foreach(var entry in crypttab_list){
3095
entry.append_option("nofail");
3098
// check and add entries for mapped devices which are encrypted
3100
foreach(var mnt in mount_list){
3101
if ((mnt.device != null) && (mnt.device.is_on_encrypted_partition())){
3104
var entry = CryptTabEntry.find_entry_by_uuid(
3105
crypttab_list, mnt.device.parent.uuid);
3109
entry = new CryptTabEntry();
3110
crypttab_list.add(entry);
3113
// set custom values
3114
entry.device_uuid = mnt.device.parent.uuid;
3115
entry.mapped_name = "luks-%s".printf(mnt.device.parent.uuid);
3116
entry.keyfile = "none";
3117
entry.options = "luks,nofail";
3121
CryptTabEntry.write_file(crypttab_list, file_path, false);
3129
3124
public void save_exclude_list_for_restore(string file_path){