This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: proposal: nsswitch refactoring
- From: DJ Delorie <dj at redhat dot com>
- To: Florian Weimer <fw at deneb dot enyo dot de>
- Cc: libc-alpha at sourceware dot org
- Date: Tue, 19 Mar 2019 12:50:00 -0400
- Subject: Re: proposal: nsswitch refactoring
Florian Weimer <fw@deneb.enyo.de> writes:
> We currently bind lookup functions lazily, so the module data is not
> entirely write-once, more like a collection of ivars (called SyncVar
> in Concurrent ML, basically futures without blocking).
But once we bind those and record their addresses, they won't change, so
I put them in the "write once" group. The rest of the data needs to be
write-flush-rewrite capable, in order to unload nsswitch.conf data and
reload it.
> One tricky aspect about the current framework is that the generic NSS
> code does not know which lookup functions exist.
I had noted that, and figured some sort of cache/hash/whatever would be
needed somewhere, but elided the problem for now :-)
> We already do this for the resolver configuration. We could probably
> reuse the same mechanism, and even the same data structure.
Thanks, I'll look at it.
> Which aspect are you referring to? The handling of struct pwd, struct
> hostend, etc., including parsing file data? Or forwarding a lookup
> operation from a function such as getpwnam to an NSS module function
> like _nss_files_getpwnam_r?
This doesn't include the shared objects like nss_files, nss_ldap, etc.
Just the core code that calls them all. I figure the arguments would
need to be stored in a struct, possibly with some other stateful
information. Like this pseudo-code:
static int
my_so_caller (nss_handler *shared_object, my_data *data)
{
/* call the shared_object's functions, passing my_data */
}
int
my_api_handler (arg1, arg2, arg3)
{
struct { ... } my_data;
my_data.arg1 = arg1;
...
nss_logic_handler (NSS_PWNAM, my_so_caller, &my_data);
return my_data.rv;
}
This means that none of the individual API functions need to have code
to do the logic of nsswitch.conf.
Alternately, the core logic could be a stateful machine:
int
my_api_handler (arg1, arg2, arg3)
{
nss_logic_state state;
nss_logic_initialize (NSS_PWNAM, &state);
while (nss_logic_handler (&state))
state->rv = state->shared_object->do_something (arg1, arg2, arg3);
return nss_logic_finalize (&state);
}