Skip to content

std::fs file not found code: 38, message: "Function not implemented" #41347

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

Closed
yoni386 opened this issue Apr 17, 2017 · 33 comments
Closed

std::fs file not found code: 38, message: "Function not implemented" #41347

yoni386 opened this issue Apr 17, 2017 · 33 comments
Labels
C-bug Category: This is a bug. P-low Low priority T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@yoni386
Copy link

yoni386 commented Apr 17, 2017

Rust Generated code worked on CentOS but but *fail on VMware Esxi hypervisor.

Some of the code portion does work on the same machine. explained in detail below.
c and rust libc works fine while rust std::fs panicked at 'Unable to open' "Function not implemented".

//rust libc

unsafe {
let fd = libc::open(filename.as_ptr(), libc::O_RDONLY);
let mut fp = libc::fopen(filename.as_ptr(), r.as_ptr());
libc::fgets(buff.as_mut_ptr(), 255, fp);


//println!("{}", str::from_utf8(buff).unwrap());


// println!("{:?}", &buff[..]); // this works


libc::printf(buff[..].as_ptr() as *const i8);
//let s = CString::new(buff.as_ptr()).expect("Invalid name");
//libc::printf(b"2: %s\n", buff.as_ptr() as *const i8 );
//libc::printf("%s\n", buff);
libc::close(fd);
}

// c code

#include <stdio.h>

main() {

   FILE *fp;
   char buff[255];

   fp = fopen("/var/log/vmkernel.log", "r");
   fscanf(fp, "%s", buff);
   printf("1 : %s\n", buff );

   fgets(buff, 255, (FILE*)fp);
   printf("2: %s\n", buff );

   fgets(buff, 1255, (FILE*)fp);
   printf("3: %s\n", buff );

    fgets(buff, 1255, (FILE*)fp);
   printf("4: %s\n", buff );

   fclose(fp);

} 

//the output

[root@v25:/tmp/b] RUST_BACKTRACE=1 ./4
Hello, world3!
Hello from a thread!
1          2          3          4          5          hello.txt  z
process exited with: exit code: 0
Child's id is 486267
"5"
"4"
"3"
"2"
"1"
"z"
"hello.txt"
thread 'main' panicked at 'Unable to open the file: Error { repr: Os { code: 38, message: "Function not implemented" } }', /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libcore/result.rs:868
stack backtrace:
   1:        0x37b79246c - <unknown>
   2:        0x37b796b0e - <unknown>
   3:        0x37b796714 - <unknown>
   4:        0x37b796f4b - <unknown>
   5:        0x37b796de4 - <unknown>
   6:        0x37b796d09 - <unknown>
   7:        0x37b796c97 - <unknown>
   8:        0x37b7bcd5d - <unknown>
   9:        0x37b789262 - <unknown>
  10:        0x37b78a79f - <unknown>
  11:        0x37b79eaca - <unknown>
  12:        0x37b797456 - <unknown>
  13:        0x3bc46b8cc - <unknown>
  14:        0x37b788e78 - <unknown>
1          2          3          4          5          hello.txt  z

// full example

extern crate libc;
use std::ffi::CString;
use std::fs::File;
use std::str;
use std::io::BufReader;
use std::io::prelude::*;


fn main() {

let filename = CString::new("/var/log/vmkernel.log").unwrap();
let r = CString::new("r").unwrap();
let mut buff = [0i8; 255];

// libc works


unsafe {


let fd = libc::open(filename.as_ptr(), libc::O_RDONLY);
let mut fp = libc::fopen(filename.as_ptr(), r.as_ptr());
libc::fgets(buff.as_mut_ptr(), 255, fp);


//println!("{}", str::from_utf8(buff).unwrap());


// println!("{:?}", &buff[..]); // this works


libc::printf(buff[..].as_ptr() as *const i8);
//let s = CString::new(buff.as_ptr()).expect("Invalid name");
//libc::printf(b"2: %s\n", buff.as_ptr() as *const i8 );
//libc::printf("%s\n", buff);
libc::close(fd);
}


// c also work

// #include <stdio.h>


// main() {


// FILE *fp;
// char buff[1255];


// fp = fopen("/var/log/vmkernel.log", "r");
// fscanf(fp, "%s", buff);
// printf("1 : %s\n", buff );


// fgets(buff, 1255, (FILE*)fp);
// printf("2: %s\n", buff );


// fgets(buff, 1255, (FILE*)fp);
// printf("3: %s\n", buff );


// fgets(buff, 1255, (FILE*)fp);
// printf("4: %s\n", buff );


// fclose(fp);


// }


// Using std::fs. problem; 
//this thread 'main' panicked at 'Unable to open the file: Error { repr: Os { code: 38, message: "Function not implemented" } }', /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libcore/result.rs:868 stack backtrace:
let file = File::open("/var/log/vmkernel.log");


let mut buf_reader = BufReader::new(file);
let mut contents = String::new();
buf_reader.read_to_string(&mut contents)?;
println!("{}", &contents);

}

If it's interesting, I found more issues in rust, also in those cases I compared it to c++ which successfully worked.
Please note - in centos OS the same rust and c are working only when taking it to Esxi OS there a valid problem.

For example:
c and c++ stdout, threads, system working. in rust only stdout (prints) worked "out of the box".

As said c and c++ and libs just work "out of the box", rust from the other hand forced me to do tweaks libc and compile it static and etc. The current status:

  1. Using stdout (println!) worked on 6.0 and 6.5 version without and effort from my side.
  2. using std::thread complained panicked missing glibc_2.14 and didn't work while c++ did. Now this works partiality - mainly on esx6.5.
  3. std::process now works on 6.5 with the tweaks below while c++ worked almost with 0% effort from my side.

Compiltion info:
VMware Esxi hypervisor version 6.5 with libc 2.12 (dev machine was centos 6 - compiled from cantos 6 as target x86_64-unknown-linux-musl and x86_64-unknown-linux-gnu.
target x86_64-unknown-linux-musl also from cantos7 which has libc2.17.

Let me know if more info can help. I will try more if there some kind of workaround and I will update.

@nagisa
Copy link
Member

nagisa commented Apr 18, 2017

Please run the code under strace.

@yoni386
Copy link
Author

yoni386 commented Apr 18, 2017

I will try to run strace. Yesterday I found out rust code returned file was not found.

@yoni386
Copy link
Author

yoni386 commented Apr 18, 2017

execve("/tmp/logs", ["/tmp/logs"], [/* 17 vars */]) = 0
mmap(NULL, 592, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x9d22d01000
arch_prctl(ARCH_SET_FS, 0x9d22d01100)   = 0
set_tid_address(0x9d22d01138)           = 542215
readlink("/etc/malloc.conf", 0x3d49bd45cb0, 4096) = -1 ENOENT (No such file or directory)
brk(0)                                  = 0x9ce2d01000
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x9d22d02000
munmap(0x9d22d02000, 2097152)           = 0
mmap(NULL, 4190208, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x9d22f02000
munmap(0x9d22f02000, 1040384)           = 0
munmap(0x9d23200000, 1052672)           = 0
sched_getaffinity(0, 128, {ffffffffffff, 0, 0, 0, 0, 0, 0, 0, 0}) = 72
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x9d23200000
rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER|SA_RESTART, 0x43cbb3}, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 8) = 0
rt_sigaction(SIGSEGV, {0x409c70, [], SA_RESTORER|SA_STACK|SA_SIGINFO, 0x43cbb3}, NULL, 8) = 0
rt_sigaction(SIGBUS, {0x409c70, [], SA_RESTORER|SA_STACK|SA_SIGINFO, 0x43cbb3}, NULL, 8) = 0
sigaltstack(NULL, {ss_sp=0, ss_flags=SS_DISABLE, ss_size=0}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x9d23400000
sigaltstack({ss_sp=0x9d23400000, ss_flags=0, ss_size=8192}, NULL) = 0
open("/var/log/vmkernel.log", O_RDONLY) = 3
open("/var/log/vmkernel.log", O_RDONLY) = 4
readv(4, [{"", 0}, {"2017-04-17T20:00:17.365Z cpu8:66"..., 1024}], 2) = 1024
ioctl(1, TIOCGWINSZ, {ws_row=62, ws_col=237, ws_xpixel=0, ws_ypixel=0}) = 0
writev(1, [{"", 0}, {"2017-04-17T20:00:17.365Z cpu8:66"..., 102}], 22017-04-17T20:00:17.365Z cpu8:66686)WARNING: DVFilter: 1199: Couldn't enable keepalive: Not supported
) = 102
close(3)                                = 0
open("./zzz", O_RDONLY|O_CLOEXEC)       = -1 ENOENT (No such file or directory)
write(2, "thread '", 8thread ')                 = 8
write(2, "main", 4main)                     = 4
write(2, "' panicked at '", 15' panicked at ')         = 15
write(2, "called `Result::unwrap()` on an "..., 113called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 2, message: "No such file or directory" } }) = 113
write(2, "', ", 3', )                      = 3
write(2, "/buildslave/rust-buildbot/slave/"..., 88/buildslave/rust-buildbot/slave/stable-dist-rustc-musl-linux/build/src/libcore/result.rs) = 88
write(2, ":", 1:)                        = 1
write(2, "868", 3868)                      = 3
write(2, "\n", 1
)                       = 1
write(2, "note: Run with `RUST_BACKTRACE=1"..., 51note: Run with `RUST_BACKTRACE=1` for a backtrace.
) = 51
sigaltstack({ss_sp=0, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x9d23400000, 8192)              = 0
lseek(4, -922, SEEK_CUR)                = 102
exit_group(101)                         = ?

@nagisa
Copy link
Member

nagisa commented Apr 18, 2017

The strace is for a different error than in the original report. Please run the same code as in the original report.

@yoni386
Copy link
Author

yoni386 commented Apr 18, 2017

rust code without c or libc

thread 'main' panicked at 'couldn't open /var/log/vmkernel.log: other os error None', src/main.rs:58
note: Run with `RUST_BACKTRACE=1` for a backtrace.
[root@clx-vcl-25:/tmp] strace ./logs_tmp
execve("./logs_tmp", ["./logs_tmp"], [/* 18 vars */]) = 0
mmap(NULL, 592, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x66bf50a000
arch_prctl(ARCH_SET_FS, 0x66bf50a100)   = 0
set_tid_address(0x66bf50a138)           = 542517
readlink("/etc/malloc.conf", 0x3165e4e1ca0, 4096) = -1 ENOENT (No such file or directory)
brk(0)                                  = 0x667f50a000
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x66bf50b000
munmap(0x66bf50b000, 2097152)           = 0
mmap(NULL, 4190208, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x66bf70b000
munmap(0x66bf70b000, 1003520)           = 0
munmap(0x66bfa00000, 1089536)           = 0
sched_getaffinity(0, 128, {ffffffffffff, 0, 0, 0, 0, 0, 0, 0, 0}) = 72
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x66bfa00000
rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER|SA_RESTART, 0x43b913}, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 8) = 0
rt_sigaction(SIGSEGV, {0x408d20, [], SA_RESTORER|SA_STACK|SA_SIGINFO, 0x43b913}, NULL, 8) = 0
rt_sigaction(SIGBUS, {0x408d20, [], SA_RESTORER|SA_STACK|SA_SIGINFO, 0x43b913}, NULL, 8) = 0
sigaltstack(NULL, {ss_sp=0, ss_flags=SS_DISABLE, ss_size=0}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x66bfc00000
sigaltstack({ss_sp=0x66bfc00000, ss_flags=0, ss_size=8192}, NULL) = 0
open("/var/log/vmkernel.log", O_RDONLY|O_CLOEXEC) = 3
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
ioctl(3, FIOCLEX)                       = -1 ENOSYS (Function not implemented)
close(3)                                = 0
write(2, "thread '", 8thread ')                 = 8
write(2, "main", 4main)                     = 4
write(2, "' panicked at '", 15' panicked at ')         = 15
write(2, "couldn't open /var/log/vmkernel."..., 56couldn't open /var/log/vmkernel.log: other os error None) = 56
write(2, "', ", 3', )                      = 3
write(2, "src/main.rs", 11src/main.rs)             = 11
write(2, ":", 1:)                        = 1
write(2, "58", 258)                       = 2
write(2, "\n", 1
)                       = 1
write(2, "note: Run with `RUST_BACKTRACE=1"..., 51note: Run with `RUST_BACKTRACE=1` for a backtrace.
) = 51
sigaltstack({ss_sp=0, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x66bfc00000, 8192)              = 0
exit_group(101)                         = ?

@yoni386
Copy link
Author

yoni386 commented Apr 18, 2017

Sorry over the last days I had many many attempts, I lost track. Bellow is src:

use std::fs::File;
use std::str;
use std::io::BufReader;
use std::io::prelude::*;


fn main() {

use std::error::Error;
use std::path::Path;

let path = Path::new("/var/log/vmkernel.log");
    let display = path.display();

    // Open the path in read-only mode, returns `io::Result<File>`i

    let mut file = match File::open(&path) {
        // The `description` method of `io::Error` returns a string that
        // describes the error
        Err(why) => panic!("couldn't open {}: {} {:?}", display,
                                                   why.description(),
                                                   why.cause(),),
        Ok(file) => file,
    };

    // Read the file contents into a string, returns `io::Result<usize>`
    let mut s = String::new();
    match file.read_to_string(&mut s) {
        Err(why) => panic!("couldn't read {}: {}", display,
                                                   why.description()),
        Ok(_) => print!("{} contains:\n{}", display, s),
    }

@yoni386 yoni386 changed the title std::fs code: 38, message: "Function not implemented" std::fs file not found code: 38, message: "Function not implemented" Apr 18, 2017
@nagisa
Copy link
Member

nagisa commented Apr 18, 2017

ioctl(3, FIOCLEX) = -1 ENOSYS (Function not implemented)

Here we go, that’s what your hypervisor does not implement.

@yoni386
Copy link
Author

yoni386 commented Apr 18, 2017

The reason why this fails only in rust is due to use of ioctl? Rust use ioctl and libc and c dosn't? is there a way to workaround it without libc or c?

@nagisa
Copy link
Member

nagisa commented Apr 18, 2017

The most correct solution would be to not run executables compiled for unknown-linux-* on something that is not really unknown-linux-*. The most correct "fix" would be to create/use an appropriate target.

@yoni386
Copy link
Author

yoni386 commented Apr 18, 2017

can you please point me to an example or a doc?

@nagisa
Copy link
Member

nagisa commented Apr 18, 2017

The targets are here. You’ll need to "fix" the libstd so incompatibilities like the one reported here are gone as well.

@eddyb
Copy link
Member

eddyb commented Apr 18, 2017

@yoni386 You can't use a single ` to wrap several lines of code, you need 3 (```) on a line before (with optionally the language just after it, like rust or c) and another 3 on a line after.
I've taken the liberty of editing your comments to make this issue navigable at all.

@yoni386
Copy link
Author

yoni386 commented Apr 18, 2017

  1. except android which target is not "unknown"? (full list on the bottom).
  2. any idea which target can best fit to esxi?
  3. As I know, not like in c there is no way to point to different libc, right?
    how static compile?
  4. by "fix" the libstd so incompatibilities like the one reported here are gone as well. you mean modify std src code?

aarch64-apple-ios
aarch64-linux-android
aarch64-unknown-linux-gnu
arm-linux-androideabi
arm-unknown-linux-gnueabi
arm-unknown-linux-gnueabihf
arm-unknown-linux-musleabi
arm-unknown-linux-musleabihf
armv7-apple-ios
armv7-linux-androideabi
armv7-unknown-linux-gnueabihf
armv7-unknown-linux-musleabihf
armv7s-apple-ios
asmjs-unknown-emscripten
i386-apple-ios
i586-pc-windows-msvc
i586-unknown-linux-gnu
i686-apple-darwin
i686-linux-android
i686-pc-windows-gnu
i686-pc-windows-msvc
i686-unknown-freebsd
i686-unknown-linux-gnu
i686-unknown-linux-musl
mips-unknown-linux-gnu
mips-unknown-linux-musl
mips64-unknown-linux-gnuabi64
mips64el-unknown-linux-gnuabi64
mipsel-unknown-linux-gnu
mipsel-unknown-linux-musl
powerpc-unknown-linux-gnu
powerpc64-unknown-linux-gnu
powerpc64le-unknown-linux-gnu
s390x-unknown-linux-gnu
wasm32-unknown-emscripten
x86_64-apple-darwin
x86_64-apple-ios
x86_64-pc-windows-gnu
x86_64-pc-windows-msvc
x86_64-rumprun-netbsd
x86_64-unknown-freebsd
x86_64-unknown-linux-gnu (default)
x86_64-unknown-linux-musl
x86_64-unknown-netbsd

@yoni386
Copy link
Author

yoni386 commented Apr 18, 2017

eddyb this is the return output of strace tool.

@nagisa
Copy link
Member

nagisa commented Apr 18, 2017

@yoni386

First let me answer your bullet points:

except android which target is not "unknown"? (full list on the bottom).

unknown here is irrelevant and can be mostly ignored.

any idea which target can best fit to esxi?

You’ll probably want to implement a custom target such as x86_64-esxi-linux-musl or some such.

As I know, not like in c there is no way to point to different libc, right? how static compile?

Pointing to a different runtime happens by selecting a suiting target: *-musl for MUSL libc, *-gnu for GNU libc, etc. The libc used is irrelevant to your problem however, because the functionality missing is not missing in libc, but in the kernel/platform/hypervisor itself.

by "fix" the libstd so incompatibilities like the one reported here are gone as well. you mean modify std src code?

Here I’ll describe what the fix is likely to end up looking like (bear in mind, this is a proper fix, and therefore is not easy):

  1. You copy the most-matching target (so, probably x86_64-unknown-linux-musl) and name it x86_64-esxi-linux-musl. Adjust the target as necessary to make it match the particularities of the platform;
  2. change the libstd, libcore, liblibc and other libraries to support your new target. That would indeed mean having to change the src code for these libraries. At this point you should have a compiler that can produce correct executables for your platform;
  3. (Optionally) submit a PR with all these changes against upstream. This may or may not get accepted.

Alternative approaches could be:

  1. Fix the hypervisor (probably much better solution overall);
  2. Stub the system call out, so it does not fail, but also does nothing;
  3. Submit a PR against libstd which makes libstd ignore the failures from the relevant ioctl call.

@yoni386
Copy link
Author

yoni386 commented Apr 19, 2017 via email

@eddyb
Copy link
Member

eddyb commented Apr 19, 2017

@yoni386 For what it's worth, this is what that flag does:

Set the close-on-exec flag (File IOctl CLose on EXec).
Setting this flag causes the file descriptor to be closed
when the calling process executes a new program.

This should be the default behavior but "worse is better". You can see cases in which this flag is set.
That would suggest x86_64-unknown-linux-newlib might work better but I'm not sure it's supported.

@yoni386
Copy link
Author

yoni386 commented Apr 19, 2017 via email

@eddyb
Copy link
Member

eddyb commented Apr 19, 2017

@yoni386 I'm really sorry, but there seems to be a language barrier making it hard for me to help you.

If you don't mind, could you tell us your native language, maybe there is someone in the Rust community who speaks it and can communicate more directly?

@whitequark
Copy link
Member

whitequark commented Apr 19, 2017

Per private discussion on IRC: we think that what happens here is that ESXi sort of embeds a Linux kernel, specifically Linux 2.4, which is probably just too old to have this syscall. Does Rust target Linux 2.4?

@nagisa
Copy link
Member

nagisa commented Apr 19, 2017 via email

@eddyb
Copy link
Member

eddyb commented Apr 19, 2017

// Currently the standard library supports Linux 2.6.18 so 2.4 would indeed need its own target.

@nagisa
Copy link
Member

nagisa commented Apr 19, 2017 via email

@whitequark
Copy link
Member

Ah, looks like it indeed doesn't: https://www.v-front.de/2013/08/a-myth-busted-and-faq-esxi-is-not-based.html. I'm guessing then they took the easy road to compatibility by implementing Linux syscalls and then compiling busybox, etc, with musl and a Linux triple.

Regardless of this the answer is the same, it needs its own target.

@yoni386
Copy link
Author

yoni386 commented Apr 19, 2017

Thanks everybody. I will continue to use c and c++ and maybe later I will use rust libc.
nagisa I you don't mind I will close this issue, this might be addressed as internal feedback "improve rust" by compile with different libc or making rust run everywhere as c and c++ does.

@yoni386
Copy link
Author

yoni386 commented Apr 22, 2017

how can I crate custom target with kernel 2.4? should I compile some how with no-std?

./rustup-init: /lib/tls/libc.so.6: version `GLIBC_2.3.4' not found (required by ./rustup-init)

@eddyb
Copy link
Member

eddyb commented Apr 22, 2017

@yoni386 So @tbu- went ahead and fixed this specific problem in #41462 - if that's accepted it will end up in the nightly at some point.

@yoni386
Copy link
Author

yoni386 commented Apr 22, 2017

by fixed you mean? fd will not be closed but it will also not panic? or it will fallback to a valid method on 2.4?

If I have more problems like that, is it possible "workaround" them? I mean in safe rust not libc or c.

@eddyb
Copy link
Member

eddyb commented Apr 22, 2017

@yoni386 That patch tries the existing method but if that errors (like it does for you) it will try the other one which might work (not sure though).

@yoni386
Copy link
Author

yoni386 commented Apr 22, 2017

How can I check this? clone the src from github and do a manual change and compile it?

@eddyb
Copy link
Member

eddyb commented Apr 22, 2017

@yoni386 You could, yeah. You can also do:

git clone https://github.com/tbu-/rust
cd rust
git checkout pr_cloexec_fallback_fcntl

@Mark-Simulacrum
Copy link
Member

We decided to hold off on the PR (#41462) at least until we could confirm that it fixes the problem here.

@Mark-Simulacrum Mark-Simulacrum added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Jun 23, 2017
@Mark-Simulacrum Mark-Simulacrum added C-bug Category: This is a bug. P-low Low priority labels Jul 27, 2017
@Mark-Simulacrum
Copy link
Member

Closing as we do not appear to have gotten confirmation that this fixes things and generally supporting things like this isn't really viable without help from people using those platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. P-low Low priority T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants