Workaround Ubuntu guestfs bug

This commit is contained in:
Martin 2018-04-07 23:04:14 +02:00
parent 1b1abd0abd
commit a192dabe0b
2 changed files with 141 additions and 1 deletions

View File

@ -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<SFile> files = getFiles("/boot");
for(size_t i=0;i<files.size();++i)
{
if(!files[i].isdir
&& files[i].name.find("vmlinuz")==0)
{
if(chmod(("/boot/"+files[i].name).c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IROTH)!=0)
return false;
}
}
}
#endif //__linux__
return true;
}
#ifdef __linux__
bool mount_linux_loop(const std::string& imagepath)
{
@ -326,7 +347,9 @@ bool mount_linux_loop(const std::string& imagepath)
uid="uid="+convert(user_info->pw_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;

View File

@ -51,6 +51,121 @@ void getMousePos(int &x, int &y)
y=0;
}
std::vector<SFile> 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<SFile> 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