-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider exposing FUSE-specific errors from libfuse{2,3}
#693
Comments
My motivating example leads me to want to try mounting twice: once with |
This is a great idea, thanks for taking the time to suggest it! Do you think you could work on this (or do you know someone who could)? libfuse is fully volunteer driven. This means new features and bugfixes are implemented only when someone has a personal interest in them and therefore also does the necessary work. So if someone (that probably means you) is interested in working on this, then I'd be happy to give guidance and review patches. |
Sure, I'd be happy to give this a go (in my own spare time). Lack of knowledge of the internals is definitely my weakness here (I've only ever used FUSE at a relatively high level), so guidance would be greatly appreciated. Here's my current understanding of the APIs I'm interacting with:
If we want to go in the direction of uniformly reporting FUSE-specific errors, then we'd likely want to do so from other APIs as well. So the first step is probably to just walk the codebase and figure out what all the possible error conditions are (unless there is somewhere that already documents them). Then we can figure out the kinds of FUSE-specific errors we need to handle, and whether simply assigning them error codes is sufficient, or whether we just return e.g. -2 and define a separate |
Hmm, I have a concern regarding changing the return value from -1 to values below that - existing users might not expect that and check for == -1 instead of < 0. I guess it would be saver to set errno. An alternative might be to set the fuse error into errno values > XYZ (1000?) and then to add a new function const char *fuse_strerror(), which handles these values as well. |
Yep, that's the same main issue I raised in the OP. It's always fine to take the |
You can assign errno yourself, but it might get overwritten by other calls - this is one of the issues in fuse_session_mount(). One way to solve that is to
Introducing your own TLS error value also works, but users that missed fuse_strerror() would get surprising results as you noticed. On setting errno they would get correct results for standard error code and "unknown error" (I actually don't know what strerror(1000) exactly returns) for fuse error codes. |
Yep. That's why my original suggestion was to use other return values, so it was a transparent upgrade that could be easily leveraged. It would be nice if we could just do that instead of relying on out-of-band signaling. How tricky would it be to survey the userbase of the mounting APIs (which is likely smaller than the userbase of the filesystem APIs) to see how they currently interpret return values?
If we can do so safely, I think we should set |
I won't switch my branch just for that, libfuse2 is deprecated anyway. master branch has include/fuse_lowlevel.h and that clearly states -1. Changing it would break API and ABI - you would need to handle that - I don't think that will be easy here, unless you want to introduce a function like fuse_session_mount2(). If you look at libfabric, its API functions take the expected version - there it is easier to do changes like those you are proposing, but libfuse does not have this at the moment and passing the API version can be rather confusing for the caller as well,
|
It would break the documented API, yes, but it would not break ABI (the method would still return My suggestion amounts to: /**
* Mount a FUSE file system.
*
* @param mountpoint the mount point path
* @param se session object
*
* @return 0 on success, -1 on system failure (in which case errno should be
* checked for details), other negative values for FUSE-specific errors.
**/
int fuse_session_mount(struct fuse_session *se, const char *mountpoint); essentially replacing And in fact we can reason that this is a potentially safe (depending on how system APIs handle -1 as a file descriptor) change for the same reason it would be for |
It would break any existing binary that expects 0 or -1 as value. It is easy enough to change something like that in a small project, but in libfuse that has many users (nobody knows how many) - might introduce issues for a number of users. Which is why I'm suggesting to go the errno way, which would not break anything. At least I don't easily see what might get broken. |
i.e. there is no guarantee that different platforms will agree on what So if altering the return values is not an option that the wider FUSE community would accept, then the only viable option is door number 3: add a FUSE-specific TLS error variable, and a new method to query its current value. |
Did some digging into the code, and learned some more about how the architecture is set up. For my motivating example:
The core point this workflow raises is that in order to correctly report all errors (or at least the error that is motivating me to work on this issue), we need to be able to pass not only a file descriptor out of Is it safe to treat this protocol as internal, and make arbitrary changes to it? At a glance, I cannot see any evidence that the protocol is versioned in any way. The code that invokes If versioning is needed, and I'm correct that there is no current versioning, then we'd need to use two methods to establish bidirectional versioning:
|
You can assume that libfuse3 and fusermount3 are always in sync. |
I'm closing this issue for now. Please note that this isn't meant to imply that you haven't found a real bug or worthwhile potential improvement - you most likely have and I'm grateful that you took the time to report it. Unfortunately, this project does not currently have any active, regular contributors. As the maintainer, I try to review pull requests and make regular releases, but unfortunately I have no capacity to do significant development beyond that. I understand that this is frustrating for users, but I hope you can also understand that any development work that I do on this project has to compete with spending time with my family, doing work that I get paid for, doing something recreational without a computer, or working on features/bugs that affect me personally. Most bugs and ideas - unfortunately including this one - loose out in this competition. In other words, unless you plan to work on this yourself or can recruit someone who will, it's unlikely that anyone is going to do anything about it anytime soon. Still, you may wonder why I am closing the issue rather than keeping it open. In short, I want the issue tracker to show the most important issues that users should be aware of and where prospective contributors could make the biggest difference. I do not think there is much value in using it as an exhaustive database of every idea or glitch that someone has ever encountered - especially if no one is intending to address/implement it. For this reason, I am closing most issues when it becomes clear that they're unlikely to see any activity in the near future - and this seems to be the case here. I understand that you have invested time and effort in reporting this, and I am very sorry that currently there is no way to build upon this. I wish the situation was different. |
fuse_mount_compat25 / fuse_session_mount
currently return -1 on error, but provide no other information about what went wrong. If the cause is a system error, the caller can useerrno
to guess what went wrong, but otherwise the caller just has to abort.My motivating example: if the mount options
auto_unmount,allow_{root,other}
are set but the user does not haveuser_allow_other
set in theirfuse.conf
, thefusermount / fusermount3
binaries will print an error message to stderr but not set errno. This means thatfuse_mount_compat25 / fuse_session_mount
(which callfusermount / fusermount3
under the hood) will return -1, but if the caller tries to figure out what error occurred usingerrno
, they will get0
indicating success. Thefuser
Rust crate was doing precisely this, and reporting the error asError: Success
which is a very confusing error message. It was addressed by explicitly mappingerrno = 0
to an unknown error type (cberner/fuser#178, cberner/fuser#218).Perhaps instead the return value itself could be altered, based on whether the error is due to a FUSE-specific config issue or not?
fuse_mount_compat25 / fuse_session_mount
could be documented as returning -1 on an error from a system call (in which case the caller checkserrno
for more information), andvalue < -1
for FUSE-specific errors. The main issue would be how downstream users of libfuse would behave on receiving an error that is not -1 (i.e. if they consider success to beret >= 0
, orret != -1
).The text was updated successfully, but these errors were encountered: