Given the example of pool creation, what would you envision the arguments
to lza_pool_create() being?  Would it be able to return a detailed
description of the error, and if so how?  Take for example the errors
handled in check_replication().  Would you simply return the string that
vdev_error() prints to stderr today?  That would be straightforward to
implement, but it doesn't improve on the string-parsing requirement for
consumers (at least for errors).

--matt

On Tue, Mar 10, 2020 at 2:31 PM mikefcarlin via openzfs-developer <
developer@lists.open-zfs.org> wrote:

> What are the expected benefits over fork/exec'ing the zpool/zfs commands?
>
>
>   - Reduced overhead from calling library functions rather than spinning
> off subprocesses (although configuration in this case isn't a performance
> path by any means). This would be helpful for situations where you're
> constantly polling information/statistics from ZFS.
>   - Allows the user of the library to keep their implementation native
> (data structures, control flow, etc.) and avoid the need to parse CLI output
>   - Simplifies implementing native bindings in other languages.
>
> There are a lot of things happening in zfs_main.c and zpool_main.c.  How
> much of that are you suggesting move to the new library?  E.g. we could be
> talking about an API like `int run_zfs_command(char *argv[])` that
> essentially invokes main().  But having that library print to stdout, etc
> might not be what you're looking for.
>
>
> I'm suggesting that this new API layer contains all the same actions
> (probably some exceptions to this) that are present in zpool & zfs (read
> do_zpool_*() and do_zfs_*()). This could looks like the following:
>
> - lza_pool_create()
> - lza_pool_destroy()
> - etc.
>
> Any business logic that was present in those actions is pushed down into
> the libzfs_api library equivalent, leaving the CLI related functionality
> separated from the business logic that ZFS needs to execute a given action.
> If there isn't any real business logic that needs to be pushed down, the
> libzfs_api call would still acts as a proxy to the libzfs call that was
> previously made. This would allow libzfs_api to be an all encompassing API,
> preventing the client from needing to mix and match calls between the
> different ZFS libraries.
>
> How would you want errors to be expressed in the new API?
>
>
> I'd like to keep the API away from any sort of stdout/stderr output and
> leave that to the CLI layer. The API would return error codes (and possibly
> error text if that made sense) but wouldn't directly output anything and
> instead leave that up to the function caller (i.e. CLI would output to
> stdout/stderr, to Josh's example a REST API layer could respond to a
> request using the error code + text from the function call).
>
> Maybe you could give some examples of subcommands that do not have good
> equivalents in libzfs.  Here are a few that I looked at:
>
> zfs_do_set(): it seems to me that zfs_prop_set_list() is a good libzfs
> interface to use in its place.  But maybe you have something different in
> mind?
>
> zfs_do_send(): its CLI parsing is much more complicated but it looks like
> it boils down to one call to zfs_send_*().  Are you thinking that we should
> make a single API entry point that would cover all the zfs_send_*()
> variants?
>
> zfs_do_list(): the logic in print_dataset()  is a little involved, but
> unless you want the library to be generating the same string output that we
> have from the CLI, it seems like the existing libzfs functions for
> examining the zfs_handle_t seem decent.  Again, maybe an example of what
> you would like to see for a "true" API that's equivalent to zfs_do_list()
> would be helpful.
>
>
> The few functions you mentioned (set, send and list) are pretty barebones
> with regards to the business logic I'm interested in moving to the API
> layer. A couple examples of the functions that led me down this path were
> do_zpool_create() and do_zpool_add() with their usage of functions from
> zpool_vdev.c.
>
> do_zpool_create():
>
> ...
>
> /* pass off to make_root_vdev for bulk processing */
> nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun,
>     argc - 1, argv + 1);
> if (nvroot == NULL)
> goto errout;
>
> /* make_root_vdev() allows 0 toplevel children if there are spares */
> if (!zfs_allocatable_devs(nvroot)) {
> (void) fprintf(stderr, gettext("invalid vdev "
>     "specification: at least one toplevel vdev must be "
>     "specified\n"));
> goto errout;
> }
>
> ...
>
>
> This creation of the vdev spec and related functionality in zpool_vdev.c
> is decently involved and would likely be need to be duplicated by any
> client looking mimic zpool create or add.
>
> *openzfs <https://openzfs.topicbox.com/latest>* / openzfs-developer / see
> discussions <https://openzfs.topicbox.com/groups/developer> + participants
> <https://openzfs.topicbox.com/groups/developer/members> + delivery options
> <https://openzfs.topicbox.com/groups/developer/subscription> Permalink
> <https://openzfs.topicbox.com/groups/developer/Tdde1f0006baa1227-M6a3e8c4c47f5fd468da4b846>
>

------------------------------------------
openzfs: openzfs-developer
Permalink: 
https://openzfs.topicbox.com/groups/developer/Tdde1f0006baa1227-M1992df9620d8aaf81b3037fd
Delivery options: https://openzfs.topicbox.com/groups/developer/subscription

Reply via email to