273 lines
12 KiB
Plaintext
273 lines
12 KiB
Plaintext
FreeIPMI Coding
|
|
|
|
by
|
|
|
|
Albert Chu
|
|
chu11@llnl.gov
|
|
Last Updated: February 8, 2012
|
|
|
|
These are some short descriptions on coding style, API style, other
|
|
thoughts for those interested in developing for FreeIPMI.
|
|
|
|
1) Code Style
|
|
-------------
|
|
|
|
The GNU coding style was selected for FreeIPMI. Please try to follow
|
|
the coding style used in the rest of FreeIPMI. Here's a short example
|
|
that covers the generics of the GNU coding style.
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int a = 0;
|
|
int b = 1;
|
|
|
|
if (a == 1)
|
|
printf("yoda\n");
|
|
|
|
if (a == 5
|
|
|| b == 1)
|
|
{
|
|
printf("foobar\n");
|
|
printf("xyzzy\n");
|
|
}
|
|
|
|
while (a++ < 5)
|
|
printf("lala\n");
|
|
|
|
while (b++ < 7)
|
|
{
|
|
printf("blah\n");
|
|
printf("garble\n");
|
|
}
|
|
}
|
|
|
|
2) Parameter Checking
|
|
---------------------
|
|
|
|
Please carefully check the input parameters on the inputs your
|
|
program and/or functions take. Minor parsing issues can lead to
|
|
catastrophic mistakes in IPMI.
|
|
|
|
For example, suppose you have a --power-control option that takes a
|
|
number to represent a type of operation (on, off, etc.). Suppose a
|
|
user inputs "--power-control=foobar". The "foobar" will be read as a
|
|
'0' by strtoul(). If not properly checked, the '0' can be passed to
|
|
the IPMI Chassis Control command, which uses the '0' to power off a
|
|
node.
|
|
|
|
In programs, when appropriate, output error messages to the user
|
|
indicating that how and why the inputted parameters were incorrect.
|
|
|
|
3) Code Consistency
|
|
-------------------
|
|
|
|
Please keep your code as consistent as possible to other code in
|
|
FreeIPMI. That includes code indenting style, brace style, API style,
|
|
and naming convention (which is discussed in more detail below).
|
|
|
|
Although there may be situations that a particular API style or naming
|
|
convention will make things easier for you and your code (such as
|
|
shortening the name of a function, decreasing the number of parameters
|
|
you need to pass to a function via a struct, etc.), we ask that your
|
|
code be consistent so that it does not confuse other developers.
|
|
|
|
If there is a distinct technical reason that you must use a different
|
|
API style, please bring it up with the FreeIPMI authors.
|
|
|
|
For example, pretty much all of the "fill" functions in libfreeipmi
|
|
take the exact parameters they need to fill the fiid object which is
|
|
passed along as a parameter. All parameters are passed by value, not
|
|
by a pointer or other method (e.g. object, struct, etc.).
|
|
|
|
Exceptions do exist. For example, fill_cmd_chassis_identify() takes
|
|
parameters passed by pointer instead of passed by value. The reason
|
|
is that both fields are optional and need not be filled according to
|
|
the IPMI specification. The pointer gives the caller the ability to
|
|
set values (by passing a valid pointer) or not (by passing NULL).
|
|
|
|
4) Libfreeipmi naming/function parameter conventions
|
|
----------------------------------------------------
|
|
|
|
The naming style in libfreeipmi was developed primarily for the
|
|
purpose of readability when code is being compared to the IPMI
|
|
specification.
|
|
|
|
Due to the size of the IPMI spec, there will be a lot of code. In
|
|
earlier versions of FreeIPMI, there was confusion on where code was
|
|
located, what parameters were called, how parameters should be input,
|
|
etc. due to different people using different abbreviations styles,
|
|
putting functions out of order with the spec, in different files,
|
|
using/not-using different bitmasks, etc. The code has been auditted
|
|
and cleaned up since then.
|
|
|
|
So when adding new functions/templates/parameters/files/etc. to
|
|
libfreeipmi, please name them consistently to the rest of the
|
|
libfreeipmi library and the IPMI specification.
|
|
|
|
This includes:
|
|
- naming functions/templates/parameters/files based on the spec
|
|
- in most cases, not abbreviating any words (or using consistent
|
|
abbreviations in the rest of the library, check first!)
|
|
- matching parameter lists to the templates and in the same order
|
|
- ordering functions/templates/parameters/files/etc. consistently with the spec.
|
|
|
|
For example:
|
|
|
|
ipmi-messaging-support-cmds.c
|
|
|
|
is the file for messaging support commands, chapter 22 of the IPMI 2.0 spec.
|
|
|
|
tmpl_cmd_get_channel_authentication_capabilities_rq
|
|
tmpl_cmd_get_channel_authentication_capabilities_rs
|
|
|
|
are the templates for the Get Channel Authentication Capapilities
|
|
command.
|
|
|
|
fiid_template_t tmpl_cmd_get_channel_authentication_capabilities_rq =
|
|
{
|
|
{ 8, "cmd", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 4, "channel_number", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 3, "reserved1", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "get_ipmi_v2.0_extended_data", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 4, "maximum_privilege_level", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 4, "reserved2", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 0, "", 0}
|
|
};
|
|
|
|
fiid_template_t tmpl_cmd_get_channel_authentication_capabilities_rs =
|
|
{
|
|
{ 8, "cmd", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED | FIID_FIELD_MAKES_PACKET_SUFFICIENT},
|
|
{ 8, "comp_code", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED | FIID_FIELD_MAKES_PACKET_SUFFICIENT},
|
|
{ 8, "channel_number", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_type.none", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_type.md2", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_type.md5", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_type.reserved1", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_type.straight_password_key", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_type.oem_prop", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_type.reserved2", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_type.ipmi_v2.0_extended_capabilities_available", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_status.anonymous_login", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_status.null_username", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_status.non_null_username", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_status.user_level_authentication", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_status.per_message_authentication", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "authentication_status.k_g", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 2, "authentication_status.reserved", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "channel_supports_ipmi_v1.5_connections", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 1, "channel_supports_ipmi_v2.0_connections", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 6, "reserved", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 24, "oem_id", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 8, "oem_auxiliary_data", FIID_FIELD_REQUIRED | FIID_FIELD_LENGTH_FIXED},
|
|
{ 0, "", 0}
|
|
};
|
|
|
|
The fields listed in the templates above directly match table 22-15,
|
|
the Get Channel Authentication Capabilities request and response
|
|
commands.
|
|
|
|
int fill_cmd_get_channel_authentication_capabilities (uint8_t channel_number,
|
|
uint8_t maximum_privilege_level,
|
|
fiid_obj_t obj_cmd_rq);
|
|
|
|
The function above matches the naming and takes exactly the parameters
|
|
needed by the Get Channel Authentication Capabilities request
|
|
template.
|
|
|
|
The coding conditions specified above may lead to function names or
|
|
function parameters names that exceed the 80 column mark or having
|
|
very long parameter lists. We accept this annoyance (or poor coding
|
|
style, we admit it), as we consider matching the specification as a
|
|
more important need in libfreeipmi.
|
|
|
|
For example:
|
|
|
|
int
|
|
fill_cmd_set_lan_configuration_parameters_authentication_type_enables (uint8_t channel_number,
|
|
uint8_t callback_level_none,
|
|
uint8_t callback_level_md2,
|
|
uint8_t callback_level_md5,
|
|
uint8_t callback_level_straight_password,
|
|
uint8_t callback_level_oem_proprietary,
|
|
uint8_t user_level_none,
|
|
uint8_t user_level_md2,
|
|
uint8_t user_level_md5,
|
|
uint8_t user_level_straight_password,
|
|
uint8_t user_level_oem_proprietary,
|
|
uint8_t operator_level_none,
|
|
uint8_t operator_level_md2,
|
|
uint8_t operator_level_md5,
|
|
uint8_t operator_level_straight_password,
|
|
uint8_t operator_level_oem_proprietary,
|
|
uint8_t admin_level_none,
|
|
uint8_t admin_level_md2,
|
|
uint8_t admin_level_md5,
|
|
uint8_t admin_level_straight_password,
|
|
uint8_t admin_level_oem_proprietary,
|
|
uint8_t oem_level_none,
|
|
uint8_t oem_level_md2,
|
|
uint8_t oem_level_md5,
|
|
uint8_t oem_level_straight_password,
|
|
uint8_t oem_level_oem_proprietary,
|
|
fiid_obj_t obj_cmd_rq);
|
|
|
|
The function name and parameters look pretty long and terrible. But
|
|
the names and fields exactly match the get authentication type enables
|
|
fields listed in Table 23-4. There should be very little difficulty
|
|
understanding what this funciton does, how it should be called, and
|
|
what the parameters are if you are reading along with the spec.
|
|
|
|
Because we want the code to match the IPMI spec as closely as
|
|
possible, we currently accept the code inefficiencies (due to large
|
|
stacks of parameters) that come with having long parameters lists and
|
|
the atrocities of having gigantic 25+ parameter function calls in
|
|
code.
|
|
|
|
5) Compilation and Development Notes
|
|
------------------------------------
|
|
|
|
Normally, to build and develop from the source tree you need to run:
|
|
|
|
./autogen.sh
|
|
./configure
|
|
make
|
|
|
|
out of the directory you are in.
|
|
|
|
The following configure options can help you with many development
|
|
issues:
|
|
|
|
--enable-debug
|
|
|
|
This option will turn on compilation of debugging symbols. More
|
|
warnings may also be enabled when compiling.
|
|
|
|
In addition, this option may enable a few "workarounds" to allow for
|
|
easier development of code. Most notably, inband drivers may look in
|
|
additional locations for an ipckey, so that inband development can be
|
|
done in a local directory without a full installation.
|
|
|
|
Generally speaking, if developing out of a local tree, you'll almost
|
|
always want to enable this flag.
|
|
|
|
--enable-profile
|
|
|
|
If --enable-debug is enabled, this option will turn on compilation
|
|
with profiling data.
|
|
|
|
--enable-trace
|
|
|
|
Compile tracing information into a significant portion of FreeIPMI
|
|
code. This will result in significant amounts of extra information to
|
|
be output.
|
|
|
|
--enable-rawdumps
|
|
|
|
Some users may be more familiar with raw IPMI packet dumps instead of
|
|
the detailed field identified dumps that normally occur when running
|
|
tools with --debug. In this case, --enable-rawdumps, will inform
|
|
FreeIPMI to also output packets in raw form.
|
|
|
|
|