David,

Thanks for your comments.  I'll work my way through and send you my
responses and a new webrev as soon as possible.

tom

David Bustos writes:
> Quoth Liane Praza on Fri, Aug 15, 2008 at 03:41:37PM -0700:
> > Tom, Antonello, and I would like to invite reviews of the code for 
> > extending the existing SMF templates to incorporate general service 
> > property metadata.
> > 
> > We previously published and discussed ARC materials on this alias, so 
> > the interfaces and goals of the project shouldn't be much of a surprise.
> > 
> > I'm re-posting our manpage diffs and interface information here for 
> > reference, though it is not under review:
> >    http://cr.opensolaris.org/~lianep/templates-0815/
> 
> While reading about the interfaces, I came across some text which
> I think many users will find unclear.  And during the review, I had some
> questions.  Since this documentation is not under review, however, feel
> free to ignore.
> 
>   smf_template(5)
>     "Templates may be defined for a service to describe metadata about
>     the service in general...": I think this would be more useful to
>       users if it were more concrete.  Specifically by describing when
>       users might want to produce or consume templates.  Perhaps saying
>       that service developers use templates to describe what
>       configuration values are valid, administrators can use templates
>       to validate configuration, and tool developers can use templates
>       to provide more helpful configuration user interfaces.
> 
>     "svcs -lv...": Perhaps you should specify that the output of svcs
>       -lv and svccfg describe are human-readable, and for programmatic
>       or stable access the libscf interfaces should be used.
> 
>     "A template is created...": This paragraph confuses me because the
>       first sentence says what creates a template, but the rest
>       describes, I think, how service developers should write templates
>       in their manifests.  Though maybe it's trying to describe which
>       templates should be used for which properties.  I suppose it turns
>       on the definition of "templated".
> 
>     "Templates defined globally...": I think you should clarify when
>       a template is considered to re-define another template.  Do they
>       have individual names?  Or is it based on their matching criteria?
>       It seems this information is most relevent to template authors,
>       except for when template consumers need to understand that
>       configuration validation can fail due to miscoordination between
>       different template authors.  So I'm not sure that the "Template
>       Composition" section is the best place for this.
> 
>     "Future work...": Is future work appropriate for a manpage?
> 
>     "Capital letters...": I suspect this should be qualified with "in
>       English locales".
> 
>     "If name or type is omitted, it acts like a wildcard.": I think you
>       mean that the template acts as though it has a wildcard for that
>       field.  Though saying that the template can act in such a way
>       might be considered bad diction.
> 
>     "This property lets us declare which.": First person doesn't seem
>       appropriate for a manpage.
> 
>     "internal_separators tells us...": Can this be deprecated now that
>       SMF Property Value Ordering has been integrated?
> 
>   svccfg(1M):
>     "... if invoked with the -s option...": -s is missing from the
>       synopsis.
> 
>   scf_tmpl_pg_name(3SCF):
>     "this funtion will return a string containing SCF_TMPL_WILDCARD":
>       SCF_TMPL_WILDCARD doesn't seem to be in the interface table of the
>       ARC case.  Is it appropriate to mention it here?
> 
>     "The caller is responsible for freeing the *out buffer on success.":
>       I presume you mean the caller should use free(3C).  Though in the
>       past, the library was required to provide its own freeing function
>       in case malloc() or free() were interposed, or the function used
>       an allocator in a library other than libc.  Is that no longer
>       necessary due to direct bindings?
> 
>     "The scf_tmpl_pg_target() function will retrieve the property
>     group's target as currently templated...": I don't understand what
>       you mean by a property group's target.  Do you mean the template's
>       target?
> 
>   scf_tmpl_prop_name(3SCF):
>     scf_tmpl_prop_internal_seps(): I don't understand how this function
>       will fill the scf_values_t.  Will there always be a single element
>       for the entire string of separators, or will there be a separate
>       element for each character of the separators string?
> 
>   scf_tmpl_validate_fmri(3SCF):
>     "The template validation functions offer a way to validate an
>     FMRI...": Really you're validating the configuration data associated
>       with an instance, eh?
> 
>     "By default, the validation functions look up composed data...": Is
>       this referring to the data to be validated, or the data to
>       validate against?
> 
> > The code review, parented to the onnv_95 snapshot is here:
> >    http://cr.opensolaris.org/~lianep/webrev-20080815/
> 
> So far I've reviewed svccfg's code.
> 
> cmd/svc/svccfg/Makefile: ok
> 
> cmd/svc/svccfg/svccfg.h
>   184: Please add a comment explaining that sc_pgroup_composed is
>     created & destroyed by compose_props() & composed_pg_destroy().
> 
> cmd/svc/svccfg/svccfg.l: ok
> 
> cmd/svc/svccfg/svccfg.y
>   133: This doesn't implement the -s option documented in
>     svccfg_1m.diff.  Which is correct?
> 
>   143: I'm not sure this should be flagged as a syntax error.  It seems
>     more like a semantic error to me (and therefore should use
>     semerr()), since the syntax of the command is correct, but the
>     command is wrong due to the context.
> 
>   420: cstyle calls for NULL instead of 0 for pointers.
> 
> cmd/svc/svccfg/svccfg_engine.c
>   584: lxml_get_bundle_file() seems to call semerr() before returning
>     any errors.  So it seems that this error is superfluous.  Am
>     I missing something?
> 
>   engine_import(): svccfg_1m.diff says -V is the default in interactive
>     mode, but I don't see where that is implemented.
> 
>   599: This error isn't very informative.  Are there cases where
>     tmpl_errors_print() doesn't print an informative error message?
> 
>   608: I believe lscf_bundle_import() prints an informative error
>     message before returning an error code.  So it seems that this error
>     is superfluous.  Am I missing something?
> 
> cmd/svc/svccfg/svccfg_help.c
>   33: Shouldn't this be updated?
> 
>   102-3: This is the only place "settings" is used.  Can we use
>     "properties" instead?
> 
> cmd/svc/svccfg/svccfg_internal.c
>   internal_pgroup_create_unique(): I think
>     internal_pgroup_create_strict() would be a more intuitive name for
>     this function, though I suspect internal_pgroup_create() with
>     a comment would be sufficient.
> 
>   load_instance():
>     - Please note in the comment that the property and property group
>       patterns of the composed instance are loaded also.
>     - Shouldn't inst be scf_instance_destroy()ed before returning?
>     - I think you should return ENOENT for a lot of the
>       SCF_ERROR_DELETED failures, since the caller shouldn't care
>       whether the instance didn't exist in the beginning, or was deleted
>       halfway through.
> 
>   1186: I think you should note that fmri will be referenced by
>     *inst_ptr (rather than being copied) in the function comment.
> 
>   1205: This should be "scf_pg_get_type", since that's the function that
>     returned the bad error.  And the following break is superfluous
>     since bad_error() never returns.
> 
>   1222: This should be bad_error("load_pg", rc).  And the following
>     break is superfluous since bad_error() never returns.
> 
> cmd/svc/svccfg/svccfg_libscf.c
>   66: I think it would help future modifiers of this code to add
>     a comment explaining when these macros are used.
> 
>   5810: Why are you changing this?  From what I can tell, imp_tsname is
>     allocated to be max_scf_name_len + 1 bytes long, at 6754.
> 
>   lscf_validate_fmri(): Please add a comment explaining what this
>     function is supposed to do.
> 
>   9428: Shouldn't inst_sz be of type size_t?
> 
>   9439: Is there a reason this isn't semerr(gettext("..."))?
> 
>   9444,59: I don't understand why these messages end with colons and
>     newlines before exiting.  But they doesn't seem helpful anyway.
>     I think it would be more helpful to inform the user that either
>     there is a defect in libscf, or memory was corrupted.
> 
>   9445: This should be superfluous since uu_die() should never return.
> 
>   9448-54: It doesn't seem wise to me to use lscf_select() in this way.
>     I suppose because lscf_select() is an entry point, so someone who
>     modifies it should be entitled to the assumption that it is not
>     being called from another entry point.  I think it would be better
>     to factor lscf_select() into an entry point and an
>     argument-accepting utility, which is invoked here.  I suppose it
>     doesn't need to be changed before you integrate, but at the very
>     least, a comment should be added before lscf_select() saying that
>     it's being used in this way.
> 
>   9460: This should be superfluous since uu_die() should never return.
> 
>   9478: By my reading of
>     
> http://cr.opensolaris.org/~lianep/templates-0815/scf_tmpl_validate_fmri.3SCF.new
>  ,
>     scf_tmpl_validate_fmri() doesn't accept SCF_PG_TMPL_FLAG_CURRENT.
>     Do you mean SCF_TMPL_VALIDATE_FLAG_CURRENT?
> 
>   9478: Since the only statement in this if statement tests ret, this
>     test seems redundant.  Couldn't we improve readability by
>     eliminating it?
> 
>       ret = scf_tmpl_validate_fmri(...);
>       if (ret == -1) {
>               ...
>       } else if (ret == 1 && errs != NULL) {
>               ...
>       }
> 
>       if (errs != NULL)
>       ...
> 
>   9486: len should be const.  And shouldn't it be size_t?  And there
>     should probably be a comment explaining its value, even if it's
>     arbitrary.
> 
>   lscf_validate_file(): Shouldn't this be static?
> 
>   9539: I believe this (char *) cast could be eliminated by making str
>     const char *.
> 
>   list_pg_tmpl(): I think it would help future modifiers of this code to
>     add a comment which explains what list_pg_tmpl() should do, and
>     particularly what how the templates argument affects behavior.
> 
>   10894: scf_value_get_astring() returns the length of the string,
>     rather than SCF_SUCCESS, on success.  I think you mean "== -1".
> 
>   10921,30,11162: Won't we print this if scf_tmpl_pg_name() fails?  Why
>     don't you print an error?  Do you mean to detect the wildcard?  If
>     so, the ARC materials say you should test for "*".
> 
>   10935,11180: Shouldn't "true" & "false" be in gettext()?  They are in
>     svccfg_tmpl.c.
> 
>   10995: I don't understand why you'd use quote_and_print() if the
>     string contains a space, tab, newline, or parentheses, since
>     quote_and_print() doesn't quote any of those characters.
> 
>   11018,64: Is there a reason not to use for (i = 0;
>     i < values.value_count; ++i) here?
> 
>   list_prop_tmpl(): Please add a comment explaining how prop and
>     templates arguments affect the behavior of this function.
> 
>   11198: What's the difference between this line and the other side of
>     the if?
> 
>   get_template_pg(): This function doesn't seem to be template-specific.
>     Can you change the name?  And move it to an area for utility
>     functions, either the top or the bottom of the file.
> 
>   11252: Why die on SCF_ERROR_DELETED?
> 
>   11270: This break should be superfluous because uu_die() shouldn't
>     return.
> 
>   11294: Why do we continue if the repository connection was broken?
> 
>   11304: Should there be a new macro for indentations twice as long as
>     TMPL_INDENT?
> 
>   11342: cstyle says labels must be on their own lines.
> 
>   11368,97: Why are these hardcoded for the "C" locale?
> 
>   11370: Why die if pg was deleted?  Why not act as though it never
>     existed?
> 
>   11383,410: Why goto done if scf_value_get_ustring() fails with
>     SCF_ERROR_NOT_FOUND?  It's not documented to do so, so I think you
>     should inform the user that libscf was defective, or memory was
>     corrupted, and maybe abort.
> 
>   11428: Why die if the current selection was deleted?  Why not issue an
>     error and return?
> 
>   11440: val & iter are never destroyed.
> 
>   11444: Is this legal?  I've only seen ARGSUSED before the function.
> 
>   11493: Won't prop_name always be NULL here?  Why not just use NULL?
> 
>   13662: Can you add a comment explaining that we have to set optind to
>     0 because the arguments start at argv[0] rather than argv[1]?
> 
>   13685: This line seems superfluous since argc isn't used again.
> 
> cmd/svc/svccfg/svccfg_main.c: ok
> 
> cmd/svc/svccfg/svccfg_tmpl.c
>   33: Could you mention the entry points and main data structures of
>     this file?  And maybe the main sections of code in the file?  E.g.,
>     the im_tmpl_error_print() code could be called out as a significant
>     block.
> 
>   75-294: There are a lot of types here.  Can you add a comment which
>     gives an overview of which types are used in what parts of the code?
>     This could go into the file comment.  Or maybe put in a few comments
>     that divide the types into sections.
> 
>   composed_pg_destroy(): If cpg_instance_pg->sc_pgroup_composed is
>     destroyed by composed_pg_destroy(), why isn't it in composed_pg_t?
>     Are there places were you have access to the instance pgroup_t but
>     not the composed_pg_t?
> 
>   431: Shouldn't you pass pg or cpg as the parent?
> 
>   511: Why not pass inst as the parent here?
> 
>   build_composed_property_groups(): This function is only called at the
>     end of build_composed_instance().  Does it make sense as a separate
>     function?
> 
>   620: Please add a comment explaining that we don't need to free the
>     strings because they should point to buffers owned by property_t's.
> 
>   626: "inialize and" should probably be "initialize an".
> 
>   778: Isn't this an error that we should catch with an assertion?
> 
>   809: Couldn't v be NULL?
> 
>   find_count_value(),find_tmpl_property(): I didn't think properties
>     can have values of different types.  In that case, it should suffice
>     to just use the first value on the list.
> 
>   find_tmpl_property(): Doesn't this do the same thing as
>     find_astring_value_in_pg()?
> 
>   find_restarter(): Why doesn't this function use sc_composed?
> 
>   get_ranges(): If count is a count of elements, it should be an
>     unsigned integer rather than a size_t.
> 
>   1005: This won't detect garbage after the number.  For that you should
>     test that *endptr2 == '\0'.
> 
>   scf_terrors_create(), scf_terrors_destroy(): Would you mind renaming
>     these functions so they don't begin with scf_?  Otherwise it's easy
>     to think they're defined in libscf rather than svccfg.
> 
>   1041: Shouldn't this say "Given a property group and ..."?
> 
>   1043: I find "template prop_pattern information" difficult to
>     understand.  Do you mean just "template information"?
> 
>   1067: I believe you should allocate a buffer of limit + 1 bytes, not
>     limit.
> 
>   1073: Couldn't the string be too long if prop_name is too long, which
>     is more of a problem with the manifest rather than the template?  Or
>     is it impossible to tell which is too long?
> 
>   im_tmpl_error_create(): This function is only called by
>     tmpl_errors_add_im().  Is it worth being on its own?
> 
>   im_tmpl_error_destroy(): This function is only called by
>     tmpl_errors_destroy().  Is it worth being on its own?
> 
>   1140: Would you mind describing the overall architecture here?
>     Specifically that im_tmpl_error_t's are printed by
>     im_tmpl_error_print(), which dispatches out to the im_perror_*()
>     functions, which use im_perror_item() as a utility.  And maybe the
>     general form of how the output will look.
> 
>   1215: Are you sure the strings won't have embedded quotes?  If so,
>     please add a comment.
> 
>   1390: I believe you're missing a space between "attribute" & "is".
> 
>   LLDIGITS: Isn't sizeof (uint64_t) always 8?  Do you mean
>     sizeof (long long)?  Can you add to the comment that this is based
>     on the idea that 10 digits are required to represent 32 bits?
>     Though if we're going to print numbers that large, I suspect we
>     should use thousands separators.  For the users.
> 
>   1464: The lltostr(3C) manpage I read says the function is undefined
>     for negative values.  Don't you have to pass the absolute value, and
>     prepend a negative yourself?  Maybe it would be easier to use
>     snprintf().
> 
>   add_scf_error(): This function is long enough to justify a block
>     comment explaining what it should do, I think.
> 
>   1548: Please break this assertion up into the two sub-conditions:
> 
>               assert(einfo != NULL);
>               assert(einfo->ei_type == EIT_CARDINALITY);
> 
>     This allows us to tell which condition failed from just the error
>     message.
> 
>   1682: All values of a property should have the same type, so searching
>     for one of type boolean is unnecessary.  You should just use the
>     first value on the list.
> 
>   load_general_templates(): Restarters are attributes of instances, not
>     services.  I suspect this means you need to move the sc_restarter
>     field of entity_t from sc_service to sc_instance.
> 
>   1727: You should not give up on the restarter because the the
>     service instance in question is a restarter -- restarters can be
>     delegated to restarters, too.
> 
>   1832: Why not use composition here?
> 
>   1980: Since this iterator is intended to iterate over multiple
>     instances, this comment should indicate such.
> 
>   pg_iter_next(): I think the name of this function is too generic.
>     I recommend something like next_possible_pattern_pg() or similar.
> 
>   2132: By scope, do you mean the entity which specifies the pattern?
>     If so, I suspect 'origin' or the like would be easier for future
>     coders to understand.  Particularly since "scope" doesn't appear in
>     the proposed smf_template(5).
> 
>   2133: Would it be counterintuitive to reverse the sense of this table?
>     That is, I suspect it would be clearer to list which scopes should
>     be applied for which targets, though it's possible that I just don't
>     understand how the function will be used very well yet.
> 
>   pg_target_check(): Would this function make sense to call if
>     pg_pattern was not just returned from iter?  I suspect that it would
>     be a cleaner interface to accept the tmpl_scope_t instead of the
>     pg_iter_t, to reduce the assumptions the function makes about the
>     caller.
> 
>   2362: Can't you just use strlen(pfx->pp_prefix) here?  It seems that
>     would obviate prop_prefix_t.
> 
>   tmpl_scan_general(): This seems a lot like gather_pattern().  Could
>     they be combined someday?
> 
>   2623: "server" -> "service".
> 
>   2770: What should a user do if he sees this message?
> 
>   2883: I presume you do this even if pg_patterns[i] isn't NULL because
>     you consider it an error for manifests to redefine patterns.  If so,
>     please add a comment explaining this.
> 
>   tmpl_required_pg_present(): Shouldn't this be static?
> 
> cmd/svc/svccfg/svccfg_xml.c
>   1321: Is this enough information for the user to know how to fix the
>     problem?
> 
>   lxml_get_common_name(): This function is only used in
>     lxml_get_tm_common_name().  Does it make sense to have both?
> 
>   1456: Too much indentation.
> 
>   lxml_get_description(): This function is only used in
>     lxml_get_tm_description().  Does it make sense to have both?
> 
>   1512,1555: It is not appropriate to die here because DTD validation
>     won't catch these problems.
> 
>   1706: Would DTD validation catch this?  If not, it's not appropiate to
>     die here.
> 
>   1825: I don't think it's good style to break an argument name from its
>     type.
> 
>   1913: It's not appropriate to die here because DTD won't catch this
>     problem.
> 
>   1921: "two elements" -> "two attributes"
> 
>   1925: I suspect this should be "name of prop_name".
> 
>   1955: Why is this max_scf_name_len and not max_scf_value_len + 1?
> 
>   1958: I think it would be better to assert that max_scf_name_len is
>     larger than the bytes required to represent two 64-bit numbers.  But
>     if you insist, at least change "to long" to "too long".
> 
>   2043,50,58: Is it possible for us to tell the user how many bytes too
>     long the name is?
> 
>   2289: It's not appropriate to die if prop_pattern_name is empty
>     because DTD validation won't catch it.
> 
>   2295: It's not appropriate to die here because DTD validation won't
>     catch the problem.
> 
>   2302: Can we tell the user how many bytes too long the name is?
> 
>   2313: How can this happen?  If the user includes a property_group by
>     that name?  If the user included duplicate prop_pattern's?
> 
>   2438: This can only happen if svccfg and the DTD are out-of-sync,
>     right?  In that case, I think you should die instead of warn.
> 
>   2444,49: How would these happen?
> 
>   2502: I think it would be more accurate to say that patterns with
>     target "all" are only allowed on the global service.
> 
>   2550: Can we tell the user how many bytes too long the type is?
> 
>   2559: It's not appropriate to die here because DTD validation won't
>     catch this problem.
> 
>   2575: Can we tell the user how many bytes too long the name is?
> 
>   2589-605: It's not appropriate to die here because DTD validation
>     won't catch this problem.
> 
>   2618: It's not appropriate to die here because DTD validation won't
>     catch this problem.  Plus, verify_pg_pattern_attributes() already
>     printed a more precise error message, so this one isn't useful.
> 
>   3016: It's not appropriate to die if sc_bundle_name is empty because
>     DTD validation won't catch that problem.
> 
> lib/libscf/inc/libscf.h
>   scf_values_t: These member names don't match the ARC materials.
> 
>   scf_tmpl_visibility_to_string(): The type of this argument doesn't
>     match the ARC materials.
> 
>   11214: Shouldn't this %d be %lld?
> 
> lib/libscf/inc/libscf_priv.h
>   _read_tmpl_prop_type_as_string(), _read_single_astring_from_pg():
>     Please include "scf" in the names of these functions so it's obvious
>     that they're defined in libscf.
> 
> 
> I'll continue reviewing the rest in the new webrev.
> 
> 
> David
> _______________________________________________
> smf-discuss mailing list
> smf-discuss at opensolaris.org

Reply via email to