From a192dabe0b21ce4498d7cdf7ce70bcc17ea727aa Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 7 Apr 2018 23:04:14 +0200 Subject: [PATCH] Workaround Ubuntu guestfs bug --- mount_helper/main.cpp | 27 +++++- urbackupcommon/os_functions_lin_min.cpp | 115 ++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/mount_helper/main.cpp b/mount_helper/main.cpp index ec490f99..5003e6fa 100644 --- a/mount_helper/main.cpp +++ b/mount_helper/main.cpp @@ -184,6 +184,27 @@ bool chown_dir(const std::string& dir) return false; } +bool ubuntu_guestmount_fix() +{ +#ifdef __linux__ + //workaround for https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725 + if(getFile("/etc/os-release").find("NAME=\"Ubuntu\"")!=std::string::npos) + { + std::vector files = getFiles("/boot"); + for(size_t i=0;ipw_uid); gid="gid="+convert(user_info->pw_gid); } - + + ubuntu_guestmount_fix(); + std::cout << "Guestmount..." << std::endl; if(exec_wait("guestmount", true, "-r", "-n", "--format=raw", "-a", ("/dev/loop"+convert(devnum)).c_str(), "-o", "kernel_cache", @@ -462,6 +485,8 @@ bool mount_image(const std::string& imagepath) mount_options+="uid="+convert(user_info->pw_uid)+",gid="+convert(user_info->pw_gid)+",allow_root"; } + ubuntu_guestmount_fix(); + if(exec_wait(find_urbackupsrv_cmd(), true, "mount-vhd", "-f", imagepath.c_str(), "-m", mountpoint.c_str(), "-t", devpoint.c_str(), "-o", mount_options.c_str(), "--guestmount", NULL)) { std::cout << "UrBackup mount process returned non-zero return code" << std::endl; diff --git a/urbackupcommon/os_functions_lin_min.cpp b/urbackupcommon/os_functions_lin_min.cpp index 3d2b2989..0455044b 100644 --- a/urbackupcommon/os_functions_lin_min.cpp +++ b/urbackupcommon/os_functions_lin_min.cpp @@ -51,6 +51,121 @@ void getMousePos(int &x, int &y) y=0; } +std::vector getFiles(const std::string &path, bool *has_error, bool ignore_other_fs) +{ + if(has_error!=NULL) + { + *has_error=false; + } + std::string upath=(path); + std::vector tmp; + DIR *dp; + struct dirent64 *dirp; + if((dp = opendir(upath.c_str())) == NULL) + { + if(has_error!=NULL) + { + *has_error=true; + } + return tmp; + } + + dev_t parent_dev_id; + bool has_parent_dev_id=false; + if(ignore_other_fs) + { + struct stat64 f_info; + int rc=lstat64(upath.c_str(), &f_info); + if(rc==0) + { + has_parent_dev_id = true; + parent_dev_id = f_info.st_dev; + } + } + + upath+=os_file_sep(); + + errno=0; + while ((dirp = readdir64(dp)) != NULL) + { + SFile f; + f.name=(dirp->d_name); + if(f.name=="." || f.name==".." ) + continue; + + f.isdir=(dirp->d_type==DT_DIR); + + struct stat64 f_info; + int rc=lstat64((upath+dirp->d_name).c_str(), &f_info); + if(rc==0) + { + f.isdir = S_ISDIR(f_info.st_mode); + + if(ignore_other_fs && S_ISDIR(f_info.st_mode) + && has_parent_dev_id && parent_dev_id!=f_info.st_dev) + { + continue; + } + + if(S_ISLNK(f_info.st_mode)) + { + f.issym=true; + f.isspecialf=true; + struct stat64 l_info; + int rc2 = stat64((upath+dirp->d_name).c_str(), &l_info); + + if(rc2==0) + { + f.isdir=S_ISDIR(l_info.st_mode); + } + else + { + f.isdir=false; + } + } + + f.usn = (uint64)f_info.st_mtime | ((uint64)f_info.st_ctime<<32); + + if(!f.isdir) + { + if(!S_ISREG(f_info.st_mode) ) + { + f.isspecialf=true; + } + + f.size=f_info.st_size; + } + + f.last_modified=f_info.st_mtime; + f.created = f_info.st_ctime; + f.accessed = f_info.st_atime; + } + else + { + if(has_error!=NULL) + { + *has_error=true; + } + errno=0; + continue; + } + tmp.push_back(f); + errno=0; + } + + if(errno!=0) + { + if(has_error!=NULL) + *has_error=true; + } + + closedir(dp); + + std::sort(tmp.begin(), tmp.end()); + + return tmp; +} + bool os_create_reflink(const std::string &linkname, const std::string &fname) { #ifndef sun