> This is a request for people to review the NWAM Phase 1 code.
>
> The code can be found at http://cr.opensolaris.org/~mph/nwam1_cr/
>
> For those inside sun there is a cscope database
> in /net/coupe.eng/builds/mph/nwam1_cr/usr/src (sorry to those external
> to SWAN).
>
> Documentation can both be found in the source tree and on the project
> web page at http://opensolaris.org/os/project/nwam/
Michael,
Here are my comments on nwamadm, netcfgd and the DLPI logic in nwamd.
General:
* A number of functions are named without appropriate prefixes
(e.g. nwam_) in ways that encroach upon actively evolved public
namespaces. For instance, door_switch() and and dlpi_notify().
* A number of functions use chumminess with lint to make arguments
appear to be used (e.g., `foo = foo'). This is not a robust or
clear way to handle unused arguments; please use ARGSUSED or
the NOTE() facility to mark unused arguments.
* A number of places seem to check for pthread_mutex_lock()
failure. This is needless: there are no cases short of
programmer error that will lead to pthread_mutex_lock() failing
(for a normal pthread lock).
nwamadm/Makefile:
* Given the way gettext() is used in nwamadm, you need something
like XGETFLAGS += -a -x $(PROG).xcl and an nwamadm.xcl file.
* 34: Why is LFLAGS set in here?
* 36: -I. is wrong; local header files should be included with
`#include "local.h"'.
* 30: Needless; source is only built from one file.
* 42-44: Needless rules.
* 55: Why not use lint_PROG?
nwamadm.c:
* Throughout: the ofmt API needs to be used to print stuff out
rather than rolling your own printing logic. This will also
provide parsable mode and user-selectable fields for free
(which currently seem to be missing).
* Throughout: what's up with the name zerr()? Am I to assume it's
because this code started life as zoneadm.c? Seems like it
should be called die(), and seems like you could also use a
die_nwamerr() function that takes a nwamerr and does the
nwam_strerror() a la die_dlerr() in dladm.
* Throughout: seems a shame that the libnwam walker APIs require
a non-NULL cb_ret argument, as nothing here seems to want to
consult it. Why not allow it to be NULL?
* 50: Needless blank line.
* 58, 64-72: The use of both command numbers *and* an array of
command entries seems muddled. Seems like all the functionality
tied to command numbers could be folded into state tracked in
the command entries -- e.g., a cmd_help pointer-to-function (or
just a simple const char *), and a flags field that indicates
whether e.g. "-x" can be used or whether the type needs to be
determined.
* 60: Should be cmd_handler for consistency.
* 60: Should define a typedef for this -- e.g.:
typedef int (cmd_handle_func_t)(int, char **);
... then declare cmd_handler as a pointer to this, and the
declarations on 79-84 as instances of this type.
* 77: Seems like this FMRI should be in a library header.
* 151: Unclear why this is a global; seems like it should be
declared in interact_func() and passed to eventhandler().
* 167-277: I'd expect these helper routines to be in libnwam
rather than nwamadm. Some of them already appear to be there,
such as nwam_ncu_type_to_flag(). Why are they here?
* 179, 193, 215, 230, 246, 262, 275, 297: The default cases here
seem unhelpful. I'd expect strings of "?" and enumerations
along the lines of NWAM_OBJECT_TYPE_UNKNOWN.
* 209: Presumably this should be "ncu"?
* 323: Presumably this should be ""%s: <subcommand>".
* 368, 371: This seems like abuse of return values, as
NWAM_WALK_HALTED and NWAM_SUCCESS do not appear to be intended
for this use. Instead, it seems that the walker should return
0 or 1.
* 378: Why is it safe to ignore the return value from this
function? Is it that we assume `state' will only be modified
by this function call upon success? Seems a needless
assumption.
* 451: Would seem more natural to return `type' and remove the
`num' parameter in place of an NWAM_OBJECT_TYPE_UNKNOWN value.
* 514: This seems unnecessarily obscure; don't we know
cmd_to_str(CMD_LIST) == "list"?
* 549-558: Seems like this would just be:
if (cmd_num != CMD_LIST && type == NWAM_OBJECT_TYPE_NONE)
* 560: Needless cast.
* 653-684: This should be factored out into a funciton that takes
the type and then is merely called here for NWAM_NCU_TYPE_LINK
and NWAM_NCU_TYPE_INTERFACE. For bonus points, could take a
function pointer which would be either &nwam_ncu_enable or
&nwam_ncu_disable.
* 651, 690, 693: Should be a switch statement with NWAM_SUCCESS,
NWAM_ENTITY_MULTIPLE_VALUES and default.
* 705-715: Can factor this out to a function and reuse this code with
disable_func(). For I18N to work, you need to restructure the
messages -- e.g.: "cannot enable: <blah>" -- then you'll end up
parameterizing the subcommand name (which won't be translated).
* 719: By the time we get here isn't the enable complete? That
is, seems like this should be "Enabled", not "Enabling".
* 724: `if' block should be replaced with assert(ret !=
NWAM_SUCCESS)' and the code should be unindented.
* 785-868: See previous comments regarding enable_func() code.
* 871: Would seem preferable to return a error code indicating
whether the function succeeded rather than overloading
*_UNINITALIZED for the job.
* 872, 934: Everything that uses determine_object_state() immediately
then calls add_to_profile_entry(). Seems like it would be
simpler to have add_to_profile_entry() get the state itself
rather than taking `state' and `auxstate' arguments.
* 928: How do we get here? Seems like we should assert(0).
* 932: p_entries is a linked list, not an array.
* 956: p_last_entry is gross. Does the order of the list matter?
If not, why not prepend to the list? If so, would prefer to
make the list circular and use p_prev.
* 979, 1020, 1058, 1090: Needless cast.
* 986, 988: `name' appears to be leaked.
* 988: `val' appears to be leaked.
* 1108-1156: See previous comments about using ofmt. As an aside,
the field names are generally considered part of the command
itself and are not something we translate -- and this is
important when -o <field> is supported.
* 1165-1166: Needless "optimization".
* 1196-1199: No voodoo code, please.
* 1207, 1219, 1227, 1234: Needless cast.
* 1250, 1251: Useless comments.
* 1260-1475: This function is really hard to read -- and again,
ofmt should be used to print output.
* 1260-1475: Is this intended as a debugging aid or something that
end-users would actually use? If the latter, seems like some
I18N handling is missing in the various prompts. Also, how is
the end-user supposed to make sense of the stuff output from
this? Further, it seems odd to me that the interactive support
and event monitor have been glommed together into one facility.
* 1266: `action' should be declared properly as a `const char *'
and the bogus casts on line 1278, 1422, and 1449 should be
removed.
* 1338, 1346, 1388: This works without fflush(stdout)?
* 1338, 1346, 1388: Can the user ^C out? If so, how does that
work? If not, seems a usability problem.
* 1366, 1402: Why are errors going to stdout?
* 1378, 1388: Would expect a space after the ":".
* 1432: How do you know this is a sockaddr_in? Sure looks like
this code can be reached with a sockeddr_in6.
* 1474: Remove blank line.
* 1511: See previous comment about I18N with field names.
* 1515-1528: Odd code here seems to stem from mixing interaction
and event monitoring.
* 1543: strdup() can fail. This is the problem with using
basename(3C) rather than just doing the typical:
if ((execname = strrchr(argv[0], '/')) == NULL)
execname = argv[0];
else
execname++;
You can also remove the <libgen.h> #include and -lgen link.
* 1551-1554: This means one cannot observe the events at NWAM
startup with "interact" which seems unfortunate.
* 1531: So using the "interact" subcommand always exits with a
non-zero status?
* 1547, 1554, 1565: Would be clearer as EXIT_FAILURE.
* 1556: I suppose it doesn't matter much, but `state' is leaked.
netcfgd:
* Unclear why this consists of multiple source files; it seems
like everything could be consolidated into a single source file
without sacrificing maintainability.
netcfgd/Makefile:
* 29-30: Pulling in Makefile.lib seems wrong since that's for
building libraries. Just use $(ROOT)/lib.
* 35: Remove needless HEADERS definition.
* 61: What does this $(ROOTCMD) dependency do?
netcfgd/util.h:
* Given that this only has logging functions, seems odd it's named
util.h. (But then again, I can't figure out why this exists.)
* 33: Need a /* PRINTFLIKE2 */ here.
* 39: No externs, please.
netcfgd/logging.c:
* 28-29: Unclear what this comment has to do with anything; no
debug.c here.
* 42: s/The idea for having this function is so that you can
/This function allows you to/
* 43: s/Its/It's/
* 59: Why 256? Why not vasprintf()?
* 81-90: Could be replaced with (in util.h)
#define dprintf(...) nlog(LOG_DEBUG, __VA_ARGS__)
netcfgd/main.c:
* General: I can't figure out what the zonename code is for;
we never seem to use the `zonename' variable. My nits below
assume that somehow it's supposed to do something.
* 28: Comment should provide an overview of what this daemon does
on a technical level.
* 32, 34, 38, 39, 40, et al: Superfluous #includes
* 51, 52: No excuse for these being globals.
* 57-59: Unclear what this comment has to do with anything.
* 68: Where does this code lookup SMF properties?
* 70: Where does this code manage privileges?
* 76: Is there a reason this uses LOG_NDELAY?
* 79-113: Someone *really* needs to put this in a library :-(
Looks like this is cut line-for-line from Nevada nwamd/main.c
which in turn took it from pppoe/pppoed.c.
* 124: Prefer const.
* 126: No need to define `zoneid'; just inline the call to
getzoneid() int the getzonenamebyid() call.
* 132: Why is it correct to charge on with GLOBAL_ZONENAME in
this case?
* 141-142: Just curious: what exactly are we localizing? All of
the messages here go to syslog which is not localized.
* 145: Why is this LOG_INFO? Seems like LOG_DEBUG. Also, LOG_PID
was specified to openlog() so I'm not sure why this includes the
pid as well. Finally, the message should be generated in
start_logging(), not here.
* 149-155: Indenting here is one level off.
* 162: Comment states the obvious.
* 166-168: Unclear why we want to ignore USR1/USR2/INT.
* 170: Need to resolve this XXX for SIGTHAW.
dlpi_events.c:
* Throughout: libdlpi does not use `errno' for errors. All of the
dlpi-related log messages in this file are busted.
* 34: Unclear what net/route.h has to do with this file.
* 65: This `if' clause is needless: nwamd has requested to only
receive events of these two types.
* 67: Use of 'IFF_UP' to have some relationship to the link state
seems wrong. Seems like it would be simpler to change
link_state.link_state to link_state.link_up and just have it be
a boolean.
* 71: Shouldn't this message explain the administrative impact?
* 88-102: Unclear why this function is allocating a buffer to
receive into since it does nothing with this buffer -- and even
more unclear why this buffer is sized to DLPI_PHYSADDR_MAX.
Seems like this whole function should just be:
static void *
nwamd_dlpi_thread(void *arg)
{
int rc;
dlpi_handle_t *dh = arg;
for (;;) {
rc = dlpi_recv(*dh, NULL, NULL, NULL, NULL, -1, NULL);
if (rc != DLPI_SUCCESS) {
nlog(LOG_ERR, "nwam_dlpi_thread: dlpi_recv "
"failed: %s", dlpi_strerror(rc));
break;
}
}
return (NULL);
}
* 94: Bogus cast.
* 99: Unclear where the magic notion of three failures comes from;
one would think any unexpected failure would be worth stopping
for.
* 100: resumably *dh was meant?
* 105: This function would be much easier to read if a local
variable was declared for ncu->ncu_node.u_link.
* 123: Can this happen? If so, what prevents a situation where two
thread simultaneously pass this check and race to both call
pthread_create()?
* 135, 182: Comments only tell me what is clear already from the
code.
* 136-146: dlpi_bind() is no longer needed to use dlpi_enabnotify().
* 150: Sure seems like `strdup(name)' ends up getting leaked here.
Shouldn't this be NULL?
* 160: Presumably the intent is to record the error value returned
from pthread_create() in the nlog() message?
--
meem
_______________________________________________
networking-discuss mailing list
[email protected]