Message forwarded from Christian Seiler:
On 10/30/2015 10:47 AM, Peter Hatina wrote:
in several projects, we identified the need to have a client-side library
for the
iSCSI communication.
Just out of curiosity: could you provide one or two examples?
This library has been living in Fedora for a while;
but
we would like to change this situation and upstream several patches from
Fedora.
If this is upstreamed, I think there should be a commitment about ABI
compatibility: that ABI breaks are very rare, and if they happen, the
SONAME of the library is consistently updated, so that no third-party
software breaks there. (Also, we should make sure that the built
libraries across distributions actually share the same ABI.)
Looking at the code, it seems to me that there are already a lot of
things in there that make a ton of sense and will ensure that it won't
be a burden to keep ABI compatibility (i.e.: I like):
- central library context + functions to create / destroy that
- proper namespacing of functions with libiscsi_
- a lot of getter/setter functions for different things
What I think could be improved:
- trivial: add $(LDFLAGS) to the linker rules in the Makefile. In
Debian we compile packages with hardening options by default (e.g.
-Wl,-z,relro), and we pass these to the build system. I sent a
couple of patches upstream earlier (that have now been committed)
that make sure that passing env variables is possible for the rest
of open-iscsi. Also, you should filter -fPIE and -fpie from the
flags building libraries, because they conflict with -fPIC, i.e.
use something like:
CFLAGS_LIB = $(filter-out -fPIE -fpie -pie,$(CFLAGS))
LDFLAGS_LIB = $(filter-out -fPIE -fpie -pie,$(LDFLAGS))
and use those flags in the rules. (If you want to overwrite the
original variables instead of creating new ones with a suffix,
make sure you use override.)
- enum libiscsi_auth_t: I'd prefer if explicit values were specified
in the enum, then it'd be harder to accidentally break binary
compatibility
- libiscsi_session_timeout: mention that all values are in seconds,
document semantics of special values (if any)
- the big one: fixed sized arrays in data structures: I really
dislike this, just because this
* the current use of just doing strlcpy() hides potential
truncation errors
* if the maximum length is changed at some point, this
immediately breaks ABI
The advantage of these data structures is that they simplify
memory management inside the library a bit, because without
fixed lengths, there's need for explicit destructor functions.
This also applies to simple values in some getters. So,
instead of doing something like
PUBLIC int libiscsi_node_get_parameter(
struct libiscsi_context *context,
const struct libiscsi_node *node,
const char *parameter,
char *value);
it would be better to simply have
PUBLIC int libiscsi_node_get_parameter(
struct libiscsi_context *context,
const struct libiscsi_node *node,
const char *parameter,
char **value);
where value is allocated inside the function and only if no error
occurred the pointer will be changed by the function. (Also,
tasking the user with making sure that the buffer they pass to
the function is large enough is a recipe for potential buffer
overflow exploits in client software.)
- next big one: some of the data structures. I think that the
following data structures should not be user-visible but rather have
initializers/destructors + getters/setters to manipulate them:
libiscsi_node
libiscsi_session_info
libiscsi_network_config
The reasoning as to why I think they shouldn't be user-visible is
the following: if at some point the structures are to be modified
(even if it's just adding a simple field), having them user-visible
will mean that any change will be ABI-incompatible. But I could
easily imagine that any of the mentioned structures might change in
the future due to improvements (e.g. information about whether the
connection is done in software or whether it's offloaded could later
be added to the node data structure).
libiscsi_session_timeout is fine as long as you are sure that no
other timeout will come - but OTOH, since it's only used in the
session_info structure, having a couple of getters for the different
timeouts might be a better idea.
The auth_info stuff I would keep as-is (with the only change being
that the CHAP version has char *username instead of
char username[MAXLEN] - see above). The semantics there should be as
follows: when the program passes information _into_ the library, the
library should only assume the structure passed is big enough for
the auth type specified, and for all information passed _from_ the
library libiscsi has to allocate the storage itself, to make sure
that the structure is always large enough.
- libiscsi is not entirely thread-safe (see the comments you wrote in
the code) and libiscsi can definitely not be used with multiple
contexts at the same time (due to the limitations of the underlying
code in open-iscsi it reuses).
This is not something that should prevent the addition of libiscsi,
but it should be clearly documented that that is the case - it
doesn't affect the ABI whatsoever, so it is perfectly reasonable to
say that initially it's not safe to use it more than once at the
same time in a program and then in a long-term effort try to improve
that situation by making more of the underlying code (that was
written with standalone binaries in mind) context-aware.
Nitpicks:
- do you really want to guard __attribute__((visibility("default")))
by __GNUC__ >= 4? GCC 4 was released a decade ago.
- you should document better that with "client library" you mean a
library that communicates with iscsid on Linux systems (and may
require some privileges), not an actual initiator implementation.
With that in mind: is libiscsi not a bit generic a name for
something that specific? A short search lead me to
<https://github.com/sahlberg/libiscsi>
<https://github.com/sahlberg/libiscsi>, so there's apparently
already at least one libiscsi out there that actually implements
the iSCSI protocol directly. Maybe use libopen-iscsi? Or
libiscsid-client?
- installing a pkg-config file would be really nice, especially if you
have sofware that uses this.
- it should be well-documented that the library should always match
the the installed iscsid version, because it internally uses the
communication protocol via the socket and that might be bound to
change between releases. This also means that there should be a big
fat warning against building the library statically and linking
against it, because that wouldn't be upgrade-safe.
I would be very pleased, if some of you, upstream developers, look at my
github
repository [1] with several changes regarding open-iscsi.
As I said, not an upstream developer, but hopefully you'll find my
feedback useful regardless.
There are some changes in that repository not related to libiscsi and I
would suggest treating them separately. (If they are intended for
upstream at all.)
Regards,
Christian
--
You received this message because you are subscribed to the Google Groups
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/open-iscsi.
For more options, visit https://groups.google.com/d/optout.