📄 mfd-access-unsorted-external-defines.m2i
字号:
## unsorted-external summary ------------------------- The unsorted-external data access code is for cases when you data is kept UNSORTED and EXTERNAL to the agent/sub-agent. This code was generated based on the following assumptions or settings: 1) The raw data for this table is UNSORTED. @if $mfd_readme_verbose != 0@ UNSORTED data is data that is not kept in the same order as the way SNMP expects the index(es) for the table to be kept. [It could very well be sorted in some other order, but for the purpose of SNMP, the order is incorrect.] If you're not sure if your data is sorted in an SNMP compliant way, its likely not. Because the raw data is unsorted, to satisfy a particular request, the entire data set must be examined to find the apropriate index. This is done via a simple loop. The MFD handler will call your get_first function and the call the get_next function repeatedly, until it returns SNMPERR_NO_VARS. @end@ 2) The raw data for this table is EXTERNAL. @if $mfd_readme_verbose != 0@ EXTERNAL data is data that is owned by some other process, device, file or mechanism. The agent must use some interface to read or modify the data. An external process may modify the data without the agent's knowledge. For example, the Net-SNMP agent implements the interface table (ifTable), which reports on network interfaces. The host operating system owns this data, and Net-SNMP must use system calls to report or manipulate the data. Examples of external data include data stored in kernel space, in files, in another non-memory shared process, and data stored in devices. @end@ 3) The raw data for this table is TRANSIENT. @if $mfd_readme_verbose != 0@ TRANSIENT data is data that may be overwritten by another funtion or process. For example, many OS functions return data in a static buffer that will be reused the next time the function is called. Because of this, we will assume that you will copy the raw data retrieved from these other sources to a generated structure for use within the Net-SNMP agent. (Don't worry, we'll help you) @end@#### this should be syncronized with master version of comments in## mfd-access-unsorted-external-body.m2i You should be able to copy## the comments here and replace " * " with " ".## The unsorted external data access code works by calling a few simple functions to get the index value for each row. Once the agent determines which row is needed to process an incoming request, another function is called to retrieve the data for that row. A simplified version of the pseudo-code looks like this: ${context}_loop_init_context(loop) ${context}_loop_get_first(loop,data) while( no_error ) { if( best_match(data, key) ${context}_loop_save_position(loop,pos); ${context}_loop_get_next(loop,data) } ${context}_loop_get_data(pos,data) ${context}_loop_cleanup_context(loop)#### end sync## We will talk about each individual step below.######################################################################## Defining context for the loop ----------------------------- TODO : typedef ${context}_loop_context WHERE: ${table}_data_access.h @if $mfd_readme_verbose != 0@#### this should be syncronized with master version of comments in## mfd-access-unsorted-external-body.m2i You should be able to copy## the comments here and replace " * " with " ".## Since the actual loop is in the MFD handler, a loop contex parameter is provided to help you keep track of where you are in between calls to functions that you wrote and the master MFD handler calls. The structure of this context is user defineable, and is defined in the file ${table}_data_access.h. E.G., if your data is stored in a linked list, the obvious thing you want to know from one function call to the next is your current position in the linked list. Thus the easiest context to use is a pointer within the linked list. For an array, the current index to that array would be easiest. The funtion calls are actually passed a reference to the loop context, to allow the loop context to be allocated memory. Here are some simple examples definitions for various data formats. These definitions are used in examples later on.#### end sync## Linked list ----------- typedef list_node ${context}_loop_context; Array ----- typedef integer ${context}_loop_context; File ---- typedef struct ${context}_loop_context_s { char * file_name; FILE * f; char line[128]; } ${context}_loop_context; @end@######################################################################## Initialization -------------- TODO : Initialization FUNC : ${context}_loop_init_data WHERE: ${table}_data_access.c @if $mfd_readme_verbose != 0@ The ${context}_loop_init_data function will be called during startup to allow for any initialization needed for the data access routines. @end@######################################################################## Preparing for the loop ---------------------- TODO : initialize loop context FUNC : ${context}_loop_init_context WHERE: ${table}_data_access.c @if $mfd_readme_verbose != 0@#### this should be syncronized with master version of comments in## mfd-access-unsorted-external-body.m2i You should be able to copy## the comments here and replace " * " with " ".## This function will be called before the start of a new itertion over the data. The loop context that is initialized here will be passed to ${context}_loop_get_first and ${context}_loop_get_next. Set the loop context variable ref->loop_ctx so that the iteration functions (get_first and get_next) can locate the apropriate data context.#### end sync## The primary purpose of the loop_init_context call is to initialize the loop context data (ref). Here are some simple examples, based on the earlier example loop contexts. Linked list ----------- ref->loop_ctx = my_table_head_ptr; Array ----- /* instead of actually allocating memory, just use the pointer */ /* as an integer */ (integer)(ref->loop_ctx) = 0; File ---- ref->loop_ctx = SNMP_MALLOC_TYPEDEF(${context}_loop_context); /* error checking here */ ref->loop_ctx->file_name = (char*) reg->mfd_user_ctx; ref->loop_ctx->f = fopen( ref->loop_ctx->file_name, "r+" ); @end@######################################################################## The Loop -------- TODO : return raw data FUNC : ${context}_loop_get_first WHERE: ${table}_data_access.c @if $mfd_readme_verbose != 0@#### this should be syncronized with master version of comments in## mfd-access-unsorted-external-body.m2i You should be able to copy## the comments here and replace " * " with " ".## This function is called to return set the index(es) for the first ${context}_data in the data set. Note that during the loop, the only important thing is the indexes. If access to your data is cheap/fast (e.g. you have a pointer to a structure in memory), it would make sense to update the data here. If, however, the accessing the data invovles more work (e.g. parsing some other existing data, or peforming calculations to derive the data), then you should limit yourslef to setting the indexes. Extracting the can be put off until the desired row is found See the notes on ${context}_loop_get_data(). Note that this function does not correspond to a SNMP GET pdu, and you should return data items in whatever order they are already in. (In fact, if your data is already ordered in the same order as the SNMP indexes, you shouldn't be using the unsorted-access code). This function should update the table index (rowreq_ctx_ref->rowreq_ctx->tbl_idx) values for the raw data (rowreq_ctx_ref->rowreq_ctx->data).#### end sync## Linked list ----------- rowreq_ctx_ref->rowreq_ctx->data = loop_ctx_ref->loop_ctx; Array ----- /* assuming registration has array of pointers */ rowreq_ctx_ref->rowreq_ctx->data = reg->mfd_user_ctx[(integer)(ref->loop_ctx)]; File ---- fgets(loop_ctx_ref->loop_ctx->line, sizeof(loop_ctx_ref->loop_ctx->line), loop_ctx_ref->loop_ctx->f); rowreq_ctx_ref->rowreq_ctx->data = loop_ctx_ref->loop_ctx->line; @end@ TODO : return raw data FUNC : ${context}_loop_get_next WHERE: ${table}_data_access.c @if $mfd_readme_verbose != 0@#### this should be syncronized with master version of comments in## mfd-access-unsorted-external-body.m2i You should be able to copy## the comments here and replace " * " with " ".## This function returns the next data item in the data set. The same caveat applies here as did above. The indexes are the important parts during loop processing. Note that this function does not correspond to a SNMP GET-NEXT pdu, and you should return data items in whatever order they are already in. (In fact, if your data is already ordered in the same order as the SNMP indexes, you shouldn't be using the unsorted-access code).#### end sync## Linked list ----------- loop_ctx_ref->loop_ctx = loop_ctx_ref->loop_ctx->next; rowreq_ctx_ref->rowreq_ctx->data = loop_ctx_ref->loop_ctx; Array ----- ++((integer)(ref->loop_ctx)); /* assuming registration has array of pointers */ rowreq_ctx_ref->rowreq_ctx->data = reg->mfd_user_ctx[(integer)(ref->loop_ctx)]; File ---- fgets(loop_ctx_ref->loop_ctx->line, sizeof(loop_ctx_ref->loop_ctx->line), loop_ctx_ref->loop_ctx->f); rowreq_ctx_ref->rowreq_ctx->data = loop_ctx_ref->loop_ctx->line; @end@######################################################################## Updating the Index ------------------ TODO : update index for the raw data FUNC : ${context}_indexes_set WHERE: ${table}_data_access.c This is a convenience function for setting the index context from the native C data. Where necessary, value mapping should be done. @if $mfd_readme_verbose == 1@ This function should update the table index values (found in tbl_idx) for the given raw data. @end@######################################################################## Saving a position in the loop ----------------------------- TODO : Saving a position in the loop FUNC : ${context}_loop_save_position WHERE: ${table}_data_access.c @if $mfd_readme_verbose != 0@#### this should be syncronized with master version of comments in## mfd-access-unsorted-external-body.m2i You should be able to copy## the comments here and replace " * " with " ".## During loop iteration, the iterator keeps track of the row that is the current best match. This function is called when the current row is a better match than any previous row. You should save any information you need to be able to locate this row again from the current loop context to a new loop context. At the end of the loop, when the best match has been found, the saved loop context will be used to get the data for the row by calling ${context}_loop_get_data().@if $m2c_data_transient != 0@ # persistent Since your data is transient, you need to make a copy of it before the iterator moves on to the next row.@end@#### end sync## @end@######################################################################## Returning Data For an Index --------------------------- TODO : copy transient raw data to generated structure FUNC : ${context}_loop_get_data WHERE: ${table}_data_access.c @if $mfd_readme_verbose != 0@#### this should be syncronized with master version of comments in## mfd-access-unsorted-external-body.m2i You should be able to copy## the comments here and replace " * " with " ".## At the end of the loop, when the best match has been found, the saved loop context will be used to get the data for the row by calling ${context}_loop_get_data().#### end sync## @end@######################################################################## Cleaning up after the loop -------------------------- TODO : release any allocated memory FUNC : ${context}_loop_cleanup_context WHERE: ${table}_data_access.c @if $mfd_readme_verbose != 0@#### this should be syncronized with master version of comments in## mfd-access-unsorted-external-body.m2i You should be able to copy## the comments here and replace " * " with " ".## This function will be called once the loop iteration has completed to release any memory allocated for loop reference.#### end sync## The purpose of the loop_cleanup_context call is to release any memory allocated for the loop context data. Here are some simple examples, based on the earlier example loop contexts. Linked list ----------- /* nothing to do */ Array ----- /* nothing to do */ File ---- free(ref->loop_ctx); @end@##@end@ // m2c_processing_type eq 'r########################################################################@if $m2c_mark_boundary == 1@/** END code generated by $RCSfile: mfd-access-unsorted-external-defines.m2i,v $ $Revision: 1.12 $ */@end@
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -