Summary: | Cannot use libzfs_core from user space programs due to missing libnvpair.h and other dependencies | ||
---|---|---|---|
Product: | Base System | Reporter: | WHR <msl0000023508> |
Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> |
Status: | Open --- | ||
Severity: | Affects Some People | CC: | arrowd, asomers, freebsdbugs, freqlabs, grembo, shawn.webb |
Priority: | --- | ||
Version: | CURRENT | ||
Hardware: | Any | ||
OS: | Any |
Description
WHR
2021-07-16 19:08:35 UTC
The thing about libzfs is that it is not a stable interface. It was never intended to be one, and never has been. It changes frequently, and in non-backwards compatible ways. That's why its use is highly discouraged by programs outside of the base system. The few that do use it (sysutils/py-iocage for example) typically break during an OS upgrade. libzfs_core, OTOH, _is_ a stable interface. It has a simple API, very similar to what the zfs command line tools provide. And it's guaranteed to preserve backwards compatibility. I suggest you convert your program to use libzfs_core instead of libzfs. If you don't, you'll continue to need the kernel headers. (In reply to Alan Somers from comment #1) Re-opening, as even if using libzfs_core.h kernel sources are required, so all the problems described by the bug author still exist. This is how /usr/include/libzfs_core.h begins: ``` #ifndef _LIBZFS_CORE_H #define _LIBZFS_CORE_H #include <libnvpair.h> ``` Minimal example: ``` $ cat >test.c <<EOF #include <libzfs_core.h> int main() { } EOF $ cc test.c /usr/include/libzfs_core.h:32:10: fatal error: 'libnvpair.h' file not found #include <libnvpair.h> ^~~~~~~~~~~~~ 1 error generated. $ find / -name libnvpair.h /usr/src/sys/contrib/openzfs/include/libnvpair.h Try adding it to the search path: $ cc -I/usr/src/sys/contrib/openzfs/include test.c tons of errors, many more include paths required... ``` Simple working example: ``` $ cat >test.c <<EOF #include <sys/stdtypes.h> #include <libzfs_core.h> int main(int argc, char** argv) { if (argc != 2) { fprintf(stderr, "Invalid arguments\n"); return 101; } if (libzfs_core_init() != 0) { fprintf(stderr, "Can't init libzfs\n"); return 101; } int exists = lzc_exists(argv[1]); printf("%s %s\n", argv[1], exists ? "exists" : "doesn't exist"); libzfs_core_fini(); return exists ? 0 : 1; } EOF $ cc \ -I/usr/src/sys/contrib/openzfs/include \ -I/usr/src/sys/contrib/openzfs/lib/libspl/include \ -lzfs_core -lzfs -o test test.c $ ./test zroot zroot exists ``` Adding libnvpair.h to /usr/include sounds reasonable. Note however that even if you do that I don't think libzfs_core would work on 13.0-RELEASE; I found some libzfs_core -> libzfs dependencies :(. But it might work on 14.0-CURRENT. (In reply to Alan Somers from comment #4) For completeness sake: My example from above pulls in these headers from /usr/src: . /usr/src/sys/contrib/openzfs/lib/libspl/include/sys/stdtypes.h . /usr/src/sys/contrib/openzfs/include/libzfs_core.h .. /usr/src/sys/contrib/openzfs/include/libnvpair.h ... /usr/src/sys/contrib/openzfs/include/sys/nvpair.h .... /usr/src/sys/contrib/openzfs/lib/libspl/include/sys/types.h ..... /usr/src/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h ..... /usr/src/sys/contrib/openzfs/lib/libspl/include/sys/feature_tests.h ..... /usr/src/sys/contrib/openzfs/lib/libspl/include/sys/types32.h ...... /usr/src/sys/contrib/openzfs/lib/libspl/include/sys/inttypes.h ..... /usr/src/sys/contrib/openzfs/lib/libspl/include/sys/va_list.h ...... /usr/src/sys/contrib/openzfs/lib/libspl/include/sys/types.h .... /usr/src/sys/contrib/openzfs/lib/libspl/include/sys/time.h ... /usr/src/sys/contrib/openzfs/lib/libspl/include/stdlib.h ... /usr/src/sys/contrib/openzfs/lib/libspl/include/stdio.h .. /usr/src/sys/contrib/openzfs/include/sys/fs/zfs.h ... /usr/src/sys/contrib/openzfs/include/sys/zio_priority.h (In reply to Michael Gmelin from comment #5) It pulls in those header files on which OS version? (In reply to Alan Somers from comment #6) Sorry, forget to qualify (as the bug is about CURRENT). My tests/examples were on 13.0-RELEASE-p5 (releng/13.0, commit 2646dd66). This problem is still there in 14-CURRENT. Simply including <libzfs_core.h> results in In file included from /usr/include/libzfs_core.h:32: In file included from /usr/include/libnvpair.h:29: /usr/include/sys/nvpair.h:152:45: error: unknown type name 'uint_t' _SYS_NVPAIR_H int nvlist_alloc(nvlist_t **, uint_t, int); ^ ... /usr/include/sys/nvpair.h:171:70: error: unknown type name 'boolean_t' _SYS_NVPAIR_H int nvlist_add_boolean_value(nvlist_t *, const char *, boolean_t); ^ /usr/include/sys/nvpair.h:172:61: error: unknown type name 'uchar_t'; did you mean 'wchar_t'? _SYS_NVPAIR_H int nvlist_add_byte(nvlist_t *, const char *, uchar_t); ^ ... (In reply to Michael Gmelin from comment #3) Thanks for that, it compiles fine with your workaround! |