Bug 257222 - Cannot use libzfs_core from user space programs due to missing libnvpair.h and other dependencies
Summary: Cannot use libzfs_core from user space programs due to missing libnvpair.h an...
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-07-16 19:08 UTC by WHR
Modified: 2023-07-15 06:20 UTC (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description WHR 2021-07-16 19:08:35 UTC
With FreeBSD's ZFS code base base switched to OpenZFS 2, a 'libzfs.h' finally provided with the base system, apparently resolving bug #193748; however this header is not useable by default, as many of its dependencies aren't provided with base system, such as 'libnvpair.h', the first missing header. As a result, to build anything that requires libzfs.h, a full FreeBSD source code must be installed, then configure the compiler to search headers from several different locations under the FreeBSD source tree.

Please make using libzfs in FreeBSD easier, by providing the ability of including libzfs.h just from base system, without need of installing full source code and manually adding many '-I' options to compiler.
Comment 1 Alan Somers freebsd_committer freebsd_triage 2021-09-09 04:38:14 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.
Comment 2 Michael Gmelin freebsd_committer freebsd_triage 2022-01-02 15:44:24 UTC
(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...
```
Comment 3 Michael Gmelin freebsd_committer freebsd_triage 2022-01-02 16:04:40 UTC
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
```
Comment 4 Alan Somers freebsd_committer freebsd_triage 2022-01-02 16:18:07 UTC
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.
Comment 5 Michael Gmelin freebsd_committer freebsd_triage 2022-01-02 16:35:48 UTC
(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
Comment 6 Alan Somers freebsd_committer freebsd_triage 2022-01-02 16:42:05 UTC
(In reply to Michael Gmelin from comment #5)
It pulls in those header files on which OS version?
Comment 7 Michael Gmelin freebsd_committer freebsd_triage 2022-01-02 17:12:08 UTC
(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).
Comment 8 Gleb Popov freebsd_committer freebsd_triage 2023-05-25 09:03:13 UTC
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);
                                                            ^
...
Comment 9 Gleb Popov freebsd_committer freebsd_triage 2023-05-25 09:09:38 UTC
(In reply to Michael Gmelin from comment #3)
Thanks for that, it compiles fine with your workaround!