Open loukamb opened 3 months ago
The source of the error is into Mega SDK (https://github.com/meganz/sdk). Maybe the issue should be reported there instead.
Taking a look at the code now I'm getting a better understanding of the situation.
The Mega SDK has two fingerprint systems. One is UUID that is reliable and persistent and the other is an uint64_t that, by their own admission in the comment, is very unreliable and unlikely to persist across reboot.
When checking the path the SDK try to identify which device the path is on. If it can find the device it will use the reliable UUID. If it can't figure out which device the path is on then it will fall back to the unreliable uint64_t. In the log you can see the message "Falling back to legacy filesystem fingerprint" indicating that it failed to find the device and is falling back to the unreliable uint64_t.
The SDK try to identify the device from the path by checking both /proc/mounts and /etc/mtab. The log message "Couldn't resolve device symlink: /dev/nvme0n1p2" indicates that it failed for some yet unknown reason. If I can figure out why this happen then I can fix the problem.
@loukamb could you please try 'realpath /dev/nvme0n1p2' in a shell?
@ChiwTheNeko
louka@desktop ~ $ realpath /dev/nvme0n1p2
/dev/nvme0n1p2
@ChiwTheNeko
louka@desktop ~ $ realpath /dev/nvme0n1p2 /dev/nvme0n1p2
That's weird. It seems the cause of the error is not the same for you than for me even though it's in the same part of the code. I'm starting to wonder if there could be more than one bug in there.
If you are able, could you please compile and run that code on your machine? This is the function that the Mega SDK uses to identify the device your sync is on, with my proposed fix included. If it doesn't work for you that means there is another bug.
#include <mntent.h>
#include <string>
#include <functional>
#include <memory>
#include <cstring>
#include <cassert>
#include <iostream>
#include <linux/limits.h>
static std::string deviceOf(const std::string& database,
const std::string& path)
{
// Convenience.
using FileDeleter = std::function<int(FILE*)>;
using FilePtr = std::unique_ptr<FILE, FileDeleter>;
std::cout << "Opening mount database: "
<< database
<< std::endl;
// Try and open mount database.
FilePtr mounts(setmntent(database.c_str(), "r"), endmntent);
// Couldn't open mount database.
if (!mounts)
{
// Latch error.
auto error = errno;
std::cout << "Couldn't open mount database: "
<< database
<< ". Error was: "
<< strerror(error)
<< std::endl;
return std::string();
}
// What device contains path?
std::string device;
// Determines which device is the strongest match.
//
// As an example consider:
// /dev/sda1 -> /mnt/usb
// /dev/sda2 -> /mnt/usb/a/b/c
//
// /dev/sda2 is a better match for /mnt/usb/a/b/c/d.
std::size_t score = 0;
// Temporary storage space for mount entries.
std::string storage(3 * PATH_MAX, '\x0');
// Try and determine which device contains path.
for (errno = 0; ; )
{
struct mntent entry;
// Couldn't retrieve mount entry.
if (!getmntent_r(mounts.get(),
&entry,
storage.data(),
static_cast<int>(storage.size())))
break;
// Where is this device mounted?
std::string target = entry.mnt_dir;
// Path's too short to be contained by target.
if (path.size() < target.size())
continue;
// Target doesn't contain path.
if (path.compare(0, target.size(), target))
continue;
// Existing device is a better match.
if (score >= target.size())
continue;
// This device is a better match.
device = entry.mnt_fsname;
score = target.size();
}
// Couldn't retrieve mount entry.
if (errno)
{
// Latch error.
auto error = errno;
std::cout << "Couldn't enumerate mount database: "
<< database
<< ". Error was: "
<< std::strerror(error)
<< std::endl;
return std::string();
}
// No device seems to contain path.
if (device.empty())
{
std::cout << "No device seems to contain path: "
<< path
<< std::endl;
return std::string();
}
// Device isn't actually a device.
if (device.front() != '/')
{
std::cout << "A virtual device "
<< device
<< " seems to contain path: "
<< path
<< std::endl;
return std::string();
}
std::cout << "Path "
<< path
<< " is on device "
<< device
<< std::endl;
// Couldn't resolve symlinks in device.
//
// This is necessary to correctly handle nodes managed by device-mapper.
// Say, the user is using LUKS or LVM.
if (!realpath(device.c_str(), storage.data()))
{
// Latch error.
auto error = errno;
std::cout << "Couldn't resolve device symlink: "
<< device
<< ". Error was: "
<< std::strerror(error)
<< std::endl;
return std::string();
}
// Truncate storage down to size.
auto it = std::find(storage.begin(), storage.end(), '\x0');
int index = std::distance(storage.begin(), it);
std::cout << "index " << index << std::endl;
storage.erase(std::find(storage.begin(), storage.end(), '\x0'), storage.end());
// Sanity.
assert(!storage.empty());
// For debugging purposes.
std::cout << "Path "
<< path
<< " is on storage "
<< storage
<< std::endl;
// Return device to caller.
return storage;
}
int main()
{
deviceOf("/proc/mounts", "/home/louka/MEGA");
deviceOf("/etc/mtab", "/home/louka/MEGA");
return 0;
}
Hello. We apologize for the lack of comms on this. Our developers are aware of the issue and are working to resolve it.
According to our developers there are 2 fixes that need to be implemented to resolve the issue. The first fix will be deployed in ver 5.4.0 of the desktop application and the second fix will be deployed in a future release as we are still currently testing it.
Hello. We apologize for the lack of comms on this. Our developers are aware of the issue and are working to resolve it.
According to our developers there are 2 fixes that need to be implemented to resolve the issue. The first fix will be deployed in ver 5.4.0 of the desktop application and the second fix will be deployed in a future release as we are still currently testing it.
Hi. Any idea when this will be fixed as megasync is currently unusable for me until this is resolved.
i installed v5.4.0 but that still did not fix the issue. my local folder is still stopping the backup. it give me the error "Problem syncing or backing up this folder" if i recreate the local folder it works but it does not make sense to do that all the time
I found the problem for me. I was using an external SSD with exFAT file system. Reformatted to Ext4 and everything seems to be working now.
I am using unraid and all my disks are btrs
As retrieved from MEGAsync's logs:
For some reason, MEGAsync is hallucinating that the filesystem hosting
/home/louka/MEGA
is somehow no longer the same filesystem. I can guarantee that it is the exact same filesystem on the exact same disk. The only thing that changed is that I rebooted my computer to fix a monitor issue, with literally no other change to my computer whatsoever. Additionally, I have absolutely no idea what the "filesystem id" is or why it changes, shouldn't the application use the IDs returned bylsblk -o name,uuid
if it really doesn't want to use paths? As to why MEGAsync is trying to parse my disk from its handle in/dev
(why would you even do this?) and failing, I have no idea why because my main partition (/dev/nvme0n1p2
) is properly mounted, aslsblk
shows:I have attempted the following:
/home/louka/MEGA
./home/louka/MEGA
.Judging from what the logs say is happening, I suggest that you use literally any other way of retrieving the sync folder. I see no reason why you want to even care about the device files - theoretically, someone should be allowed to move the sync folder to another SSD and have MEGA just read from it for further sync. If not, then you either need to massively improve your filesystem identification mechanism/fingerprinting, because rebooting your computer is apparently enough to break it. And if you don't want to change it, then at least give us the option to bypass it! That should be an obvious feature to add.