Skip to content
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

Create unnamed O_TMPFILE fails in VirtFS (error 22(EINVAL): Invalid argument) #2051

Open
aleasims opened this issue Aug 15, 2024 · 4 comments

Comments

@aleasims
Copy link

Description

When I'm trying to create unnamed temporary file O_TMPFILE in directory mounted with VirtFS, it fails with error 22: invalid argument.

Reproduce

Consider following C code :

main.c:

#define _GNU_SOURCE

#include <fcntl.h>
#include <stdio.h>

int main()
{
    int fd = open("/tmp", O_TMPFILE | O_RDWR);
    printf("fd = %d\n", fd);
    return 0;
}

Compile code and run with ops, mounting directory through VirtFS:

gcc -o main main.c && ops run --mounts /tmp:/tmp ./main

Expected result

Program works successfully, just like on native Linux platform: unnamed tmp file is created and removed at the end of execution. Printed fd is positive:

running local instance
booting /home/alea/.ops/images/main ...
FS: filesystem_read_entire: t 0x7fc601c4, bufheap 0x00017054, buffer_handler 0x7fbdd000, status_handler 0x7fc609b4
FS: read_entire_complete: status [invalid format %v], addr 0x00000000
en1: assigned 10.0.2.15
fd = 3

Actual result

Returned fd is -1:

running local instance
booting /home/alea/.ops/images/main ...
FS: filesystem_read_entire: t 0x7fc601c4, bufheap 0x00017054, buffer_handler 0x7fbdd000, status_handler 0x7fc609b4
FS: read_entire_complete: status [invalid format %v], addr 0x00000000
en1: assigned 10.0.2.15
fd = -1

Setup

$ ops profile
Ops version: 0.1.41
Nanos version: 0.1.51
Qemu version: 6.2.0
OS: linux
Arch: amd64
Virtualized: false

I tested the same with --nightly and with local build of master branch and the same error occurs.

What I found

It looks like to me that open() syscall results in calling filesystem_creat_unnamed function, and 9pfs implementation fails immediately if asked to create unnamed file.

But I'm not sure, if 9pfs supports unnamed files at all. In that case this behavior is different from Unix-like, where creating such unnamed tmp files is a normal thing.

@francescolavra
Copy link
Member

francescolavra commented Aug 15, 2024

Creation of unnamed temporary files in a 9P filesystem is indeed not supported.
As far as I'm aware, this is not supported on Linux either, and when looking at the 9P protocol I couldn't see a way for a 9P client to send commands to the server to create temporary files, so I doubt O_TMPFILE will ever be supported on VirtFS-mounted directories.

@aleasims
Copy link
Author

aleasims commented Aug 16, 2024

@francescolavra thanks for the answer!

As far as I see from Linux man, O_TMPFILE in Linux is unnamed by default and can be linked with linkat() if needed.

In that case, probably it is possible to change the error code? From that man page (ERRORS section) I can see these three codes which are treated as "O_TMPFILE files are not supported on the filesystem":

  • EISDIR
  • ENOENT
  • EOPNOTSUPP

Some libraries which work with temp files check for these error codes to decide if they need to fallback to normal named files. So it would be very helpful, if nanos open() could return one of these error codes.

@francescolavra
Copy link
Member

To be clear, when I said that creation of unnamed temporary files is not supported on Linux, I meant that it's not supported in a 9P filesystem, i.e. a filesystem mounted with the -t 9p option.
As for the error code, EINVAL is indeed not appropriate, I will change it to EOPNOTSUPP.

francescolavra added a commit that referenced this issue Aug 21, 2024
Having filesystem-specific error codes requires conversion between
filesystem codes and POSIX standard codes every time a filesystem-
related error is reported to userspace. For the 9P filesystem, in
some cases a double conversion (from a standard code to a
filesystem code and then back to a standard code) may need to be
done.
This change removes the fs_status enum that declares the filesystem
error codes, and uses standard POSIX codes to report filesystem
errors; this allows eliminating the above conversions. Standard
error codes are defined in the new kernel/errno.h header file; in
order to prevent this file from being included from userspace code,
the kernel directory is being removed from the include paths in
the relevant Makefiles; this required some adjustments to other
header files so that they can be included by both kernel and non-
kernel code.
For the 9P filesystem, the p9_create() callback function is being
modified so that EOPNOTSUPP is returned instead or EINVAL if the
user program tries to open a file with the O_TMPFILE flag (#2051).
francescolavra added a commit that referenced this issue Aug 21, 2024
Having filesystem-specific error codes requires conversion between
filesystem codes and POSIX standard codes every time a filesystem-
related error is reported to userspace. For the 9P filesystem, in
some cases a double conversion (from a standard code to a
filesystem code and then back to a standard code) may need to be
done.
This change removes the fs_status enum that declares the filesystem
error codes, and uses standard POSIX codes to report filesystem
errors; this allows eliminating the above conversions. Standard
error codes are defined in the new kernel/errno.h header file; in
order to prevent this file from being included from userspace code,
the kernel directory is being removed from the include paths in
the relevant Makefiles; this required some adjustments to other
header files so that they can be included by both kernel and non-
kernel code.
For the 9P filesystem, the p9_create() callback function is being
modified so that EOPNOTSUPP is returned instead or EINVAL if the
user program tries to open a file with the O_TMPFILE flag (#2051).
francescolavra added a commit that referenced this issue Aug 21, 2024
Having filesystem-specific error codes requires conversion between
filesystem codes and POSIX standard codes every time a filesystem-
related error is reported to userspace. For the 9P filesystem, in
some cases a double conversion (from a standard code to a
filesystem code and then back to a standard code) may need to be
done.
This change removes the fs_status enum that declares the filesystem
error codes, and uses standard POSIX codes to report filesystem
errors; this allows eliminating the above conversions. Standard
error codes are defined in the new kernel/errno.h header file; in
order to prevent this file from being included from userspace code,
the kernel directory is being removed from the include paths in
the relevant Makefiles; this required some adjustments to other
header files so that they can be included by both kernel and non-
kernel code.
For the 9P filesystem, the p9_create() callback function is being
modified so that EOPNOTSUPP is returned instead or EINVAL if the
user program tries to open a file with the O_TMPFILE flag (#2051).
@francescolavra
Copy link
Member

As part of a larger refactoring, #2054 changes the error code returned by open(O_TMPFILE) from EINVAL to EOPNOTSUPP.

francescolavra added a commit that referenced this issue Aug 26, 2024
Having filesystem-specific error codes requires conversion between
filesystem codes and POSIX standard codes every time a filesystem-
related error is reported to userspace. For the 9P filesystem, in
some cases a double conversion (from a standard code to a
filesystem code and then back to a standard code) may need to be
done.
This change removes the fs_status enum that declares the filesystem
error codes, and uses standard POSIX codes to report filesystem
errors; this allows eliminating the above conversions. Standard
error codes are defined in the new kernel/errno.h header file; in
order to prevent this file from being included from userspace code,
the kernel directory is being removed from the include paths in
the relevant Makefiles; this required some adjustments to other
header files so that they can be included by both kernel and non-
kernel code.
For the 9P filesystem, the p9_create() callback function is being
modified so that EOPNOTSUPP is returned instead or EINVAL if the
user program tries to open a file with the O_TMPFILE flag (#2051).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants