Hi Cathy,
After the conversation we had on the phone today, I thought about the
idea I mentioned to you of having two API's, one for link ID management
and one for persisting configuration.
Here's how I fleshed it out. Any thoughts would be appreciated,
especially on what the names should be.
Link ID management:
get_new_linkid(name, class)
Create a link ID to name mapping for the given name.
delete_linkid(...)
Delete a link ID to name mapping. The argument could be either a link
ID or a name.
id2name(id)
Return the name associated with a given ID
name2id(name)
Return the ID associated with a given name
rename(name1, name2)
Change the link ID to name mapping such that the ID for name1 now refers
to name2. Note that the link's ID does not change, only the name
associated with it. The rationale behind the rename call is that the
persistent configuration API does not affect the link ID to name mapping
that's currently in memory.
We can add walkers if necessary.
All changes made with this API are temporary unless persisted. We could
implement these functions as wrappers around the door calls you've
already implemented, we'd just need to add one for the rename function.
Any configuration information that is temporary can be stored or
manipulated in any way the caller desires, except that the caller cannot
change the link ID to name mapping except through the above API. If the
caller desires to persist the information across reboots, then the
caller must use the following API:
Persistent link configuration API
get_new_conf()
Returns a link configuration structure. Does not affect persistent storage.
set_conf_field(conf, field_name, value)
Set the given field in the given structure to the given value. Does not
affect persist storage.
get_conf_field(conf, field_name, value, vallen)
Return the value for the given field in the given buffer.
get_conf(...)
Get the configuration structure for the given link. This is a copy of
what is in persistent storage. The argument could be either a link ID
or a link name. I lean towards a link ID.
commit_conf(conf)
Commit the given configuration structure to persistent storage.
delete_conf(link)
Delete the given link's configuration information from persistent storage
free_conf(conf)
Free the memory associated with a configuration structure returned by
either get_conf or get_new_conf. Does not affect persistent storage
walk_confs()
Return a configuration struct for each persistent link. I expect that
devfsadmd would use this on boot to determine what link ID to name
mappings have been persisted.
Judging by the work you've already done in devfsadmd, we might already
have the implementation or something that can be adapted to the
implementation for a few of these functions (such as [get|set]_conf_field).
A few examples of usage:
To configure a temporary link:
id = get_new_linkid(name, class)
/* configure new link here */
To persist a new link:
id = get_new_linkid(name, class);
conf = get_new_conf();
set_conf_field(conf, "class", class);
set_conf_field(conf, "name", name);
set_conf_field(conf, "id", id);
commit_conf(conf);
free_conf(conf);
Note that until commit_conf is called, the new link will not survive
across reboots.
To rename a temporary link:
rename("net0", "net1");
To rename a persistent link:
get_conf("net5", &conf);
/* NOTE: If get_conf were to take an ID, then replace the above line
with:
get_conf(name2id("net5"), &conf);
Note that get_conf("net6") AFTER calling rename should have the exact
same effect as what is shown in the example.
*/
rename("net5", "net6");
set_conf_field(conf, "name", "net6");
commit_conf(conf);
free_conf(conf);
Note that the rename operation is not persisted until the commit_conf
call returns.
To delete a link:
delete_linkid("net6");
delete_conf("net6"); /* If the link has been persisted */
I see this as a potential problem. Both steps have to be done if the
link has been persisted. If the API user only does the delete_linkid,
then the link ID to name mapping is removed, but it still exists in
persistent storage. For example:
delete_linkid("net6");
id = get_new_linkid("net10", class); /* Could return net6's link ID! */
If the user persisted this new link ID, we'd have a link ID collision on
the next reboot.
This also implies that there is no way to safely and temporarily delete
the link ID to name mapping for a persistent link. Since this is an
API, I think we could document this limitation.
If the API user just calls delete_conf without delete_linkid, that
situation is less harmful. On reboot, since there is no persistent
configuration for net6, net6's link ID to name mapping is not restored
and net6's ID is now available.
One thing I do not address here is locking. We should have a mutex lock
around the persistent configuration calls. I am not sure we need
special locking for the link ID management calls, I think the locking
you already have in place in devfsadmd would be sufficient. What do you
think?
Dan