From: Need H. <snm...@ya...> - 2007-06-04 17:30:29
|
1) Lets say the first request made is to "snmpwalk" through Table2. Are you saying that Table1's container_load() procedure has never been called yet so none of the index values have been loaded and none of the rows have been allocated and placed into the Table1 container yet? If this is true, then how does an "snmpwalk" through Table2 work since no rows have been allocated to store the data yet? I am getting way confused. What actually happens when an "snmpwalk" of Table2 occurs first? Does the container_load() procedure of Table2 get called first? If so, then I am confused since I thought Table2's container_load() would not be reserving index values and not be performing any row allocation (basically not doing much of anything really) since I thought all of this would be handled in Table1 container_load() procedure only. What exactly should be placed into the container_load() procedure of Table2? If you indicate I should be reserving index values and/or allocating rows for the container then I am confused since I thought all of this would be done in in Table1 functionality. Actually, by now you understand I have a main Table1 (with 4 fields) and a Table2 (with 8 fields) which is an extension to Table1. Perhaps you can describe to me what functionality should be placed into the Table1_container_load(), Table1_row_prep(), Table2_container_load() and Table2_row_prep() routines? I think my problem is that I understand what the container_load and row_prep routines should do, but have no idea how to use them correctly when one of my tables is an extension of another table. 2) You state "Luckily, there is a failry easy way around that, which is sharing a single cache as well. See the function _ifXTable_container_init to see how it looks up the ifTable cache to share a container". I looked at this code and can see how another table's cache can be connected to the container of another table. Perhaps you can explain to me "why" I should be doing this as am I not clear as to why you are recommending this code to me in the first place. 3) You stated "Now, the problem is that when you are loading the container, you will have no idea which of the 6 tables triggered the load." Well this seems bad since I will not know what I am really loading? Are you indicating I should not be implementing it this way by adding all fields into the data_context of Table1? Is this your way of indicating to me that I will run into too many problems with combining all fields into the data_context of Table1 and that I should use sub-containers after all? 4) I wish you were local so I could stop by and have you simply draw some ideas on some paper as to what you are recommending. It is challenging for me to grasp how to do all of this as well as having no one here locally to bounce ideas around with. Again, thank you for your time and patience. Robert Story <rs...@fr...> wrote: On Fri, 1 Jun 2007 12:54:20 -0700 (PDT) Need wrote: NH> So Robert ..... instead of me implementing sub-containers, lets say I implement your other suggestion of adding all the fields defined in Table2,3,4,5,6 into the "data_context" structure for Table1. I believe I will be able to use a "union" to define these new fields within the structure to conserve space since each table is mutually exclusive to each other. Ok.. there is one issue with sharing a single container, but you may not care. The problem is that when walking the secondary tables, you will have to add code to each to make sure the current row index applies to the table in question, and then tell the agent to skip the row if it does not. So, if you have 1000 rows in Table1, and only 10 of which are in Table 2, there will be 990 wasted calls to Table2. Also note that there currently is not any generated code to handle skipping an inappropriate row, as currently the assumption is that the container only has appropriate rows. But it should be fairly trivial to fix that. NH> I assume the "container_load()" procedure of Table1 (main table) will be called first That is an invalid assumption. By default, the container_load function is called when a request comes in for a table. So it is possible that the first query the agent gets will be for table2, and not table1. Luckily, there is a failry easy way around that, which is sharing a single cache as well. See the function _ifXTable_container_init to see how it looks up the ifTable cache to share a container. Now, the problem is that when you are loading the container, you will have no idea which of the 6 tables triggered the load. NH> When the "container_load()" procedure for Table1 is called, I would like to populate all of Table1 fields at this time, however, must I populate all fields defined in Table2,3,4,5,6 at this time as well? NH> NH> If I do not populate the fields from Table2,3,4,5,6 at this time, then how will I be NH> able to populate the fields later? Will the "container_load()" procedure for Table2,3,4,5,6 be called eventually and should I populate those fields at this time instead? If so, how will I know what correct table index (ie: row index) from Table1 the data should be inserted into at this time? No, as I said before, you can use the row_prep function to delay the data lookup until it is needed. NH> Also, just curious .... when the cache expires, then I assume the "container_load()" procedure is called again to regenerate the complete table over again as it originally did ... is this correct? I assume new rows will be allocated again. Be default, the container is flushed, and must be reloaded from scratch. But you can set some cache attributes to prevent that, but then you must be careful to correctly add new entries and remove old entries. See the ifTable implementation for an example of one way to do this. --------------------------------- Bored stiff? Loosen up... Download and play hundreds of games for free on Yahoo! Games. |
From: Need H. <snm...@ya...> - 2007-06-05 15:29:28
|
OK, good stuff here ..... very helpful ... thanks. Here are a few more questions ... I have Table1 (main table) and Table2 ("1394 table" which is an extension of Table1). Lets say I have updated the Table2_container_init() routine to indicate that Table2 should use the same cache that Table1 uses. Now, when the first SNMP request is made and it is for Table2 (ex: "snmpwalk" request perhaps) then the Table1_container_load() routine will be called. Is this all correct so far? Inside the Table1_container_load() routine I will newly allocate all the required rows as well as assigning an index to each of these rows. If this is a subsequent call to Table1_container_load() then I will make sure to rebuild the Table1 from scratch by allocating all new rows, but making sure to use the same index values for each row as used before. Is this correct so far? Lets say that Table1 has the following 4 rows (and 2 columns) populated so far: index=1 type=1394 index=2 type=DVI index=3 type=1394 index=4 type=Tuner Now, since this SNMP request was for Table2, then the Table2_row_prep() routine will eventually be called. This procedure's interface provides a "row_context" data structure in which I can obtain the specific row index in which this request is related. I can then simply populate this specific row (from Table1) with the appropriate Table2 data .... is this correct? For a "snmpwalk" request will the Table2_row_prep() routine be called only twice and will the procedure interface supply row_conitext data for row 1 and 3 (since these are the indexes which relate to the 1394 Table2)? I am not sure how the agent would know which rows of Table1 are being used as extensions for Table2 data, so maybe you can clarify whether this works or not. If is does not work like this then perhaps you can tell me how I can determine which row from Table1 I need to populate with my Table2 data when the Table2_row_prep() routine is called. Robert Story <rs...@fr...> wrote: On Mon, 4 Jun 2007 10:30:25 -0700 (PDT) Need wrote: NH> 1) Lets say the first request made is to "snmpwalk" through Table2. Are you saying that Table1's container_load() procedure has never been called yet so none of the index values have been loaded and none of the rows have been allocated and placed into the Table1 container yet? If this is true, then how does an "snmpwalk" through Table2 work since no rows have been allocated to store the data yet? By default, yes. Remember, mib2c does not know about the relationship between the 2 tables, so the generated code treats each independently, with their own container and data. NH> I am getting way confused. What actually happens when an "snmpwalk" of Table2 occurs first? Does the container_load() procedure of Table2 get called first? Yes, by default it would. That is why I told you to use a shared cache in my last message. If each table uses the same cache, they when _any_ of them are accessed, the will call the table1 container_load function. NH> What exactly should be placed into the container_load() procedure of Table2? Nothing. You could actually delete it, if you also deleted the code that referenced it in the interface code. With a little work, the mib2c code could be updated to handle this automatically. Let me know if you want to sponsor a little work in this area. ;-) NH> Actually, by now you understand I have a main Table1 (with 4 fields) and a Table2 (with 8 fields) which is an extension to Table1. Perhaps you can describe to me what functionality should be placed into the Table1_container_load(), Table1_row_prep(), Table2_container_load() and Table2_row_prep() routines? I think my problem is that I understand what the container_load and row_prep routines should do, but have no idea how to use them correctly when one of my tables is an extension of another table. Table1_container_load(): load all the indexes. Optionally, load data context for tabels 1-N. Table1_row_prep(): load data context for table 1, if not done in container_load Table2_container_load(): nothing Table2_row_prep(): load data context for table 2, if not done in container_load NH> 2) You state "Luckily, there is a failry easy way around that, which is sharing a single cache as well. See the function _ifXTable_container_init to see how it looks up the ifTable cache to share a container". NH> NH> I looked at this code and can see how another table's cache can be connected to the container of another table. Perhaps you can explain to me "why" I should be doing this as am I not clear as to why you are recommending this code to me in the first place. The cache handler is the one that takes care of loading the container when a request comes in. NH> 3) You stated "Now, the problem is that when you are loading the container, you will have no idea which of the 6 tables triggered the load." NH> NH> Well this seems bad since I will not know what I am really loading? Are you indicating I should not be implementing it this way by adding all fields into the data_context of Table1? Is this your way of indicating to me that I will run into too many problems with combining all fields into the data_context of Table1 and that I should use sub-containers after all? No, I'm just saying that if you always load data for table1, you could be wasting time, since the query is actually for table4. So, if populating the container with all the data is expensive, you might want to just put in the indexes, and use row_prep for all the tables. On the other hand, if you have the data for tables 1 and 4 while getting the indexes, you could go ahead and save that data, since you've already got it. It might be a waste of time, but hey, you've already got the data. Remember, there is no ONE way to implement a table. It is highly dependent on where you get your data from. NH> 4) I wish you were local so I could stop by and have you simply draw some ideas on some paper as to what you are recommending. For the right price, I could be local for a few days. ;-) The problem is, you happened to have a non-trivial example to start with. You'll get there.... --------------------------------- Luggage? GPS? Comic books? Check out fitting gifts for grads at Yahoo! Search. |
From: Robert S. <rs...@fr...> - 2007-06-07 10:07:35
|
On Tue, 5 Jun 2007 08:29:17 -0700 (PDT) Need wrote: NH> I have Table1 (main table) and Table2 ("1394 table" which is an extension of Table1). Lets say I have updated the Table2_container_init() routine to indicate that Table2 should use the same cache that Table1 uses. Now, when the first SNMP request is made and it is for Table2 (ex: "snmpwalk" request perhaps) then the Table1_container_load() routine will be called. Is this all correct so far? Yep, _if_ the data isn't already loaded. It might be cached from a previous call (to any of the tables). NH> Inside the Table1_container_load() routine I will newly allocate all the required rows as well as assigning an index to each of these rows. If this is a subsequent call to Table1_container_load() then I will make sure to rebuild the Table1 from scratch by allocating all new rows, but making sure to use the same index values for each row as used before. Is this correct so far? Yes, that is one way to do it. YOu don't _have_ to start from scratch, but it's probably the easiest way. NH> Lets say that Table1 has the following 4 rows (and 2 columns) populated so far: NH> NH> index=1 type=1394 NH> index=2 type=DVI NH> index=3 type=1394 NH> index=4 type=Tuner NH> NH> Now, since this SNMP request was for Table2, then the Table2_row_prep() routine will eventually be called. This procedure's interface provides a "row_context" data structure in which I can obtain the specific row index in which this request is related. I can then simply populate this specific row (from Table1) with the appropriate Table2 data .... is this correct? Yes. NH> For a "snmpwalk" request will the Table2_row_prep() routine be called only twice and will the procedure interface supply row_conitext data for row 1 and 3 (since these are the indexes which relate to the 1394 Table2)? No. NH> I am not sure how the agent would know which rows of Table1 are being used as extensions for Table2 data, so maybe you can clarify whether this works or not. It doesn't know, and this is exactly the point I was trying to make earlier. NH> If is does not work like this then perhaps you can tell me how I can determine which row from Table1 I need to populate with my Table2 data when the Table2_row_prep() routine is called. The row_prep routine will be called for _each_ row. Not a big deal if we're talking a handful of rows, or you aren't too concerned about performance. This is the point at which you have to deviate from the default code created by mib2c. Normally row_prep is expected to return success or failure. What's needed here is a return of MFD_SKIP, indicating that the current row should be skipped if the type doesn't match the table. It's trivial to write the code for row_prep, but the table interface code for each of the secondary tables will have to be updated to handle this new return value. |
From: Need H. <snm...@ya...> - 2007-06-07 14:30:10
|
1) I updated my code a bit but for some reason the Table2_row_prep() routine is never called when I perform a "snmpwalk" of Table2. Any ideas why "Table2_row_prep()" is not being called at all (see the steps a-e below)? Here are the two tables I am dealing with for testing: Table1(ocStbHostAVInterfaceTable) Table2(ocStbHostAnalogVideoTable) a) I updated the Table1(ocStbHostAVInterfaceTable) data_context structure to include the fields from Table2(ocStbHostAnalogVideoTable). b) I updated Table2 "_ocStbHostAnalogVideoTable_container_init()" routine with the following code only, which I believe should tell Table2 to use the same cache as Table1(ocStbHostAVInterfaceTable): if_ctx->cache = netsnmp_cache_find_by_oid(ocStbHostAVInterfaceTable_oid, ocStbHostAVInterfaceTable_oid_size); if (NULL != if_ctx->cache) { if_ctx->container = (netsnmp_container *) if_ctx->cache->magic; return; } else { snmp_log(LOG_ERR, "error finding ocStbHostAVInterfaceTable cache\n"); } c) I added printf statements to the "init_data", "container_init", "container_load" and "row_prep" routines of Table1 and Table2 to verify the flow through the code was correct when an SNMP request was performed. d) When I start the SNMP agent the following flow is displayed. Does this seem correct so far? ENTER ocStbHostAnalogVideoTable_init_data() EXIT ocStbHostAnalogVideoTable_init_data() ENTER _ocStbHostAnalogVideoTable_container_init() EXIT _ocStbHostAnalogVideoTable_container_init() ENTER ocStbHostAVInterfaceTable_init_data() EXIT ocStbHostAVInterfaceTable_init_data() ENTER ocStbHostAVInterfaceTable_container_init() EXIT ocStbHostAVInterfaceTable_container_init() ENTER ocStbHostAVInterfaceTable_container_load() EXIT ocStbHostAVInterfaceTable_container_load() e) When I request a "snmpwalk" through Table1(ocStbHostAVInterfaceTable) then all of the fields of Table1 seem to displayed appropriately, however, doing a "snmpwalk" through Table2(ocStbHostAnalogVideoTable), returns nothing. I simply get the Linux cursor back, without any error or anything. Actually, none of my printf statements are displayed either, which means that the Table2_row_prep() routine is not being called at all. Note: I realize the "Table2_container_load()" routine is not being called (which is normal) since Table2 is using the same cache as Table1. I actually commented out all of the internal code in the "Table2_container_load()" routine, but I left the actual routine visible. Basically, the routine simply does nothing now, it is just empty. 2) In regards to "me" stating I will rebuild Table1 when the container_load() routine is called, "you" stated "You don't 'have' to start from scratch, but it's probably the easiest way". If I wanted to start from scratch and repopulate Table1, then I need to make sure to use the same index values for each row as I used before. In order to do this, I would assume I would need to store each index value by calling the "se_add_pair_to_slist" routine. Basically, I would need to link a unique text string to each of the index values being stored so when it comes time to repopulate the container (allocate new rows from scratch) then I can search for the unique text string (using the "se_find_value_in_slist" call) to find which index value was related previously then I can simply use that same index value for the regeneration of the container Table .... correct? Now, it would be nice if I did not have to regenerate the container used for Table1 everytime the container_load() routine was called, however, I am not sure how to do this? I thought Table1's container was freed(released) once the cache has expired and a new snmp request is received, so regenerating the container was necessary, but I guess I am wrong. How can a Table container be maintained and not be required to rebuild itself when the container_load() routine is called? If this will take a lot of effort to explain, then perhaps we should wait to have this discussion in the future, after my basic stuff is working. Although if this is an easy concept, then please explain. 3) You indicate that the "Table2_row_prep()" routine will be called for each row in Table1. This is fine, since I can check whether the current row actually relates to Table2 easily by checking the "type" value defined in "Table1". If the row is not related to Table2, then you indicate I should return MFD_SKIP. Yes, this seems straightforward, however (and you probably know I would be asking this), what changes must I make to the table interface code of each of the secondary tables in order for them to handle the new MFD_SKIP return value? Actually by "interface code" do you mean the "xxxxx_interface.c" files need to be updated, or are you referring to some other code file which would need to be updated? Based on the "ifTable" tutorial, I assumed MFD_SKIP was used in data "GET" routines in which the data was not existing in the table, however, I guess using this value can be used for other things as well. 4) One extra question for you: Once I have this SNMP agent stuff figured out, my next goal will be to implement a SNMP Client which will offer a set of APIs to be used by the row_prep() routines of the SNMP agent to populate the rows of the tables appropriately. Basically, these will be a set of procedures which can be called by the row_prep() routines to get the proper data which is associated with the current row being populated. It would be helpful if the SNMP client API procedure could return "extra" data (client-specific index values, etc..) to the agent (which can be stored) in which the agent could then pass back to the SNMP Client (as input to the API routines) when rebuilding the Table via the container_load() routine occurs. Basically, have the SNMP agent code store data for the sole purpose of passing it back to the SNMP Client which will make it easier for the client to obtain the requested data. Is storing "extra" data in the agent for the sole purpose of passing it back to the client a common practice? For example: Lets say the SNMP agent is populating row1 of the table. It will call an API routine that my company is providing to get the data it needs to populate the row. Now, inside this API routine, lets say it was necessary to access a few company-defined internal tables in order to get to the data which is being requested. It would be helpful that if the next time a request was made for the same data, then the index values to the comapny-defined internal tables couldbe provided in the interface to the API routine so lookup of the data can be performed much quicker. Robert Story <rs...@fr...> wrote: On Tue, 5 Jun 2007 08:29:17 -0700 (PDT) Need wrote: NH> I have Table1 (main table) and Table2 ("1394 table" which is an extension of Table1). Lets say I have updated the Table2_container_init() routine to indicate that Table2 should use the same cache that Table1 uses. Now, when the first SNMP request is made and it is for Table2 (ex: "snmpwalk" request perhaps) then the Table1_container_load() routine will be called. Is this all correct so far? Yep, _if_ the data isn't already loaded. It might be cached from a previous call (to any of the tables). NH> Inside the Table1_container_load() routine I will newly allocate all the required rows as well as assigning an index to each of these rows. If this is a subsequent call to Table1_container_load() then I will make sure to rebuild the Table1 from scratch by allocating all new rows, but making sure to use the same index values for each row as used before. Is this correct so far? Yes, that is one way to do it. YOu don't _have_ to start from scratch, but it's probably the easiest way. NH> Lets say that Table1 has the following 4 rows (and 2 columns) populated so far: NH> NH> index=1 type=1394 NH> index=2 type=DVI NH> index=3 type=1394 NH> index=4 type=Tuner NH> NH> Now, since this SNMP request was for Table2, then the Table2_row_prep() routine will eventually be called. This procedure's interface provides a "row_context" data structure in which I can obtain the specific row index in which this request is related. I can then simply populate this specific row (from Table1) with the appropriate Table2 data .... is this correct? Yes. NH> For a "snmpwalk" request will the Table2_row_prep() routine be called only twice and will the procedure interface supply row_conitext data for row 1 and 3 (since these are the indexes which relate to the 1394 Table2)? No. NH> I am not sure how the agent would know which rows of Table1 are being used as extensions for Table2 data, so maybe you can clarify whether this works or not. It doesn't know, and this is exactly the point I was trying to make earlier. NH> If is does not work like this then perhaps you can tell me how I can determine which row from Table1 I need to populate with my Table2 data when the Table2_row_prep() routine is called. The row_prep routine will be called for _each_ row. Not a big deal if we're talking a handful of rows, or you aren't too concerned about performance. This is the point at which you have to deviate from the default code created by mib2c. Normally row_prep is expected to return success or failure. What's needed here is a return of MFD_SKIP, indicating that the current row should be skipped if the type doesn't match the table. It's trivial to write the code for row_prep, but the table interface code for each of the secondary tables will have to be updated to handle this new return value. --------------------------------- You snooze, you lose. Get messages ASAP with AutoCheck in the all-new Yahoo! Mail Beta. |
From: Need H. <snm...@ya...> - 2007-06-07 15:59:40
|
Referring to my (3) question (shown below in attached email)..... I see the Table2 "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine calls the Table2 "ocStbHostAnalogVideoTable_row_prep()" routine. I attached this code below for reference: static int _mfd_ocStbHostAnalogVideoTable_object_lookup(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *agtreq_info, netsnmp_request_info *requests) { int rc = SNMP_ERR_NOERROR; ocStbHostAnalogVideoTable_rowreq_ctx *rowreq_ctx = netsnmp_container_table_row_extract(requests); DEBUGMSGTL(("internal:ocStbHostAnalogVideoTable:_mfd_ocStbHostAnalogVideoTable_object_lookup", "called\n")); /* * get our context from mfd * ocStbHostAnalogVideoTable_interface_ctx *if_ctx = * (ocStbHostAnalogVideoTable_interface_ctx *)reginfo->my_reg_void; */ if (NULL == rowreq_ctx) { rc = SNMP_ERR_NOCREATION; } if (MFD_SUCCESS != rc) netsnmp_request_set_error_all(requests, rc); else ocStbHostAnalogVideoTable_row_prep(rowreq_ctx); return SNMP_VALIDATE_ERR(rc); } /* _mfd_ocStbHostAnalogVideoTable_object_lookup */ I am assuming I should update the Table2 "ocStbHostAnalogVideoTable_row_prep()" routine to have an "int" return value and then update the Table2 "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine (shown above) to add the following "rc=" text to the "ocStbHostAnalogVideoTable_row_prep()" routine call (shown below): rc = ocStbHostAnalogVideoTable_row_prep(rowreq_ctx); Is this all which is required to process a MFD_SKIP value returned from the row_prep routine? Need Help <snm...@ya...> wrote: 3) You indicate that the "Table2_row_prep()" routine will be called for each row in Table1. This is fine, since I can check whether the current row actually relates to Table2 easily by checking the "type" value defined in "Table1". If the row is not related to Table2, then you indicate I should return MFD_SKIP. Yes, this seems straightforward, however (and you probably know I would be asking this), what changes must I make to the table interface code of each of the secondary tables in order for them to handle the new MFD_SKIP return value? Actually by "interface code" do you mean the "xxxxx_interface.c" files need to be updated, or are you referring to some other code file which would need to be updated? --------------------------------- Boardwalk for $500? In 2007? Ha! Play Monopoly Here and Now (it's updated for today's economy) at Yahoo! Games. |
From: Robert S. <rs...@fr...> - 2007-06-07 16:50:44
|
On Thu, 7 Jun 2007 08:59:37 -0700 (PDT) Need wrote: NH> if (MFD_SUCCESS != rc) NH> netsnmp_request_set_error_all(requests, rc); NH> else NH> ocStbHostAnalogVideoTable_row_prep(rowreq_ctx); NH> NH> return SNMP_VALIDATE_ERR(rc); NH> } /* _mfd_ocStbHostAnalogVideoTable_object_lookup */ NH> NH> NH> I am assuming I should update the Table2 "ocStbHostAnalogVideoTable_row_prep()" routine to have an "int" return value and then update the Table2 "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine (shown above) to add the following "rc=" text to the "ocStbHostAnalogVideoTable_row_prep()" routine call (shown below): NH> NH> rc = ocStbHostAnalogVideoTable_row_prep(rowreq_ctx); NH> NH> Is this all which is required to process a MFD_SKIP value returned from the row_prep routine? Yes. |
From: Need H. <snm...@ya...> - 2007-06-07 16:50:28
|
Referring to my oroblem outlined in (1) below ...... It seems the problem might be due to the fact that Table2(ocStbHostAnalogVideoTable) seems to be initialized before Table1(ocStbHostAVInterfaceTable), thus the cache from Table1 does not exist yet and can not be used for Table2. Is there a way to indicate which table should init first? I will keep looking around. Need Help <snm...@ya...> wrote: 1) I updated my code a bit but for some reason the Table2_row_prep() routine is never called when I perform a "snmpwalk" of Table2. Any ideas why "Table2_row_prep()" is not being called at all (see the steps a-e below)? Here are the two tables I am dealing with for testing: Table1(ocStbHostAVInterfaceTable) Table2(ocStbHostAnalogVideoTable) a) I updated the Table1(ocStbHostAVInterfaceTable) data_context structure to include the fields from Table2(ocStbHostAnalogVideoTable). b) I updated Table2 "_ocStbHostAnalogVideoTable_container_init()" routine with the following code only, which I believe should tell Table2 to use the same cache as Table1(ocStbHostAVInterfaceTable): if_ctx->cache = netsnmp_cache_find_by_oid(ocStbHostAVInterfaceTable_oid, ocStbHostAVInterfaceTable_oid_size); if (NULL != if_ctx->cache) { if_ctx->container = (netsnmp_container *) if_ctx->cache->magic; return; } else { snmp_log(LOG_ERR, "error finding ocStbHostAVInterfaceTable cache\n"); } c) I added printf statements to the "init_data", "container_init", "container_load" and "row_prep" routines of Table1 and Table2 to verify the flow through the code was correct when an SNMP request was performed. d) When I start the SNMP agent the following flow is displayed. Does this seem correct so far? ENTER ocStbHostAnalogVideoTable_init_data() EXIT ocStbHostAnalogVideoTable_init_data() ENTER _ocStbHostAnalogVideoTable_container_init() EXIT _ocStbHostAnalogVideoTable_container_init() ENTER ocStbHostAVInterfaceTable_init_data() EXIT ocStbHostAVInterfaceTable_init_data() ENTER ocStbHostAVInterfaceTable_container_init() EXIT ocStbHostAVInterfaceTable_container_init() ENTER ocStbHostAVInterfaceTable_container_load() EXIT ocStbHostAVInterfaceTable_container_load() e) When I request a "snmpwalk" through Table1(ocStbHostAVInterfaceTable) then all of the fields of Table1 seem to displayed appropriately, however, doing a "snmpwalk" through Table2(ocStbHostAnalogVideoTable), returns nothing. I simply get the Linux cursor back, without any error or anything. Actually, none of my printf statements are displayed either, which means that the Table2_row_prep() routine is not being called at all. Note: I realize the "Table2_container_load()" routine is not being called (which is normal) since Table2 is using the same cache as Table1. I actually commented out all of the internal code in the "Table2_container_load()" routine, but I left the actual routine visible. Basically, the routine simply does nothing now, it is just empty. --------------------------------- Sick sense of humor? Visit Yahoo! TV's Comedy with an Edge to see what's on, when. |
From: Robert S. <rs...@fr...> - 2007-06-07 17:00:38
|
On Thu, 7 Jun 2007 09:50:24 -0700 (PDT) Need wrote: NH> Referring to my oroblem outlined in (1) below ...... NH> NH> It seems the problem might be due to the fact that Table2(ocStbHostAnalogVideoTable) seems to be initialized before Table1(ocStbHostAVInterfaceTable), thus the cache from Table1 does not exist yet and can not be used for Table2. That's exactly what I just got through telling you. ;-) NH> Is there a way to indicate which table should init first? I will keep looking around. Nope. Check out the ifTable code. I think I just used a static var in table1 to indicate if it had initialized, and called table1 init from table2. |
From: Robert S. <rs...@fr...> - 2007-06-07 16:59:44
|
On Thu, 7 Jun 2007 07:30:03 -0700 (PDT) Need wrote: NH> 1) I updated my code a bit but for some reason the Table2_row_prep() routine is never called when I perform a "snmpwalk" of Table2. Any ideas why "Table2_row_prep()" is not being called at all (see the steps a-e below)? Nope. Try running the agent with -DocS,verbose:ocS,internal:ocS and then do a snmpgetnext ocStbHostAnalogVideoTable. NH> b) I updated Table2 "_ocStbHostAnalogVideoTable_container_init()" routine with the following code only, which I believe should tell Table2 to use the same cache as Table1(ocStbHostAVInterfaceTable): right. I assume you don't get an error message about finding the cache, right? NH> d) When I start the SNMP agent the following flow is displayed. Does this seem correct so far? NH> NH> ENTER ocStbHostAnalogVideoTable_init_data() NH> EXIT ocStbHostAnalogVideoTable_init_data() NH> ENTER _ocStbHostAnalogVideoTable_container_init() NH> EXIT _ocStbHostAnalogVideoTable_container_init() NH> ENTER ocStbHostAVInterfaceTable_init_data() NH> EXIT ocStbHostAVInterfaceTable_init_data() NH> ENTER ocStbHostAVInterfaceTable_container_init() NH> EXIT ocStbHostAVInterfaceTable_container_init() NH> ENTER ocStbHostAVInterfaceTable_container_load() NH> EXIT ocStbHostAVInterfaceTable_container_load() Actually, I think you need to muck around a bit to make sure that ocStbHostAVInterfaceTable is initialized first, or it would have created the cache for the analog video table. NH> 2) In regards to "me" stating I will rebuild Table1 when the container_load() routine is called, "you" stated "You don't 'have' to start from scratch, but it's probably the easiest way". NH> NH> If I wanted to start from scratch and repopulate Table1, then I need to make sure to use the same index values for each row as I used before. In order to do this, I would assume I would need to store each index value by calling the "se_add_pair_to_slist" routine. Basically, I would need to link a unique text string to each of the index values being stored so when it comes time to repopulate the container (allocate new rows from scratch) then I can search for the unique text string (using the "se_find_value_in_slist" call) to find which index value was related previously then I can simply use that same index value for the regeneration of the container Table .... correct? right, though you could use some other method besides slists if you wanted. NH> Now, it would be nice if I did not have to regenerate the container used for Table1 everytime the container_load() routine was called, however, I am not sure how to do this? I thought Table1's container was freed(released) once the cache has expired and a new snmp request is received, so regenerating the container was necessary, but I guess I am wrong. How can a Table container be maintained and not be required to rebuild itself when the container_load() routine is called? If this will take a lot of effort to explain, then perhaps we should wait to have this discussion in the future, after my basic stuff is working. Although if this is an easy concept, then please explain. Check out the container load function(s) for ifTable. NH> 3) You indicate that the "Table2_row_prep()" routine will be called for each row in Table1. This is fine, since I can check whether the current row actually relates to Table2 easily by checking the "type" value defined in "Table1". If the row is not related to Table2, then you indicate I should return MFD_SKIP. Yes, this seems straightforward, however (and you probably know I would be asking this), what changes must I make to the table interface code of each of the secondary tables in order for them to handle the new MFD_SKIP return value? Actually by "interface code" do you mean the "xxxxx_interface.c" files need to be updated, or NH> are you referring to some other code file which would need to be updated? xxx_interface.c is the place. NH> Based on the "ifTable" tutorial, I assumed MFD_SKIP was used in data "GET" routines in which the data was not existing in the table, however, I guess using this value can be used for other things as well. So far, that's what it has been used for. But this is a reasonable use of it as well, I think. NH> 4) One extra question for you: Let's get back to this one after things are working. Keep in mind, the more questions you ask in a single message, to more likely I am to take longer to respond. I only have so many hours in the day! |
From: Need H. <snm...@ya...> - 2007-06-07 17:10:52
|
Ok, I sent this email to you before I got your other reply. :>P Anyway, I did find a way to reverse the order of the init routines being called, but it just may be lucky I guess .... please confirm .... The file "agent/mibgroup/OC-STB-HOST-MIB.h" exists (which I needed to create manually based on our past discussions) so NetSNMP can determine which Tables to include during configure time. The file contents are as follows: config_require(OC-STB-HOST-MIB/ocStbHostAnalogVideoTable); config_require(OC-STB-HOST-MIB/ocStbHostAVInterfaceTable); Using the file described above resulted in Table2(ocStbHostAnalogVideoTable) being initialized before Table1(ocStbHostAVInterfaceTable). When I reversed the order of these tables (see below), then Table1 was initialized before Table2 (as desired) and I am now able to perform a "snmpwalk" through Table2 (oh yeah!). I see how the row_prep() routine is now being called for each row from Table1. I feel good right now .... <does a little dance>. config_require(OC-STB-HOST-MIB/ocStbHostAVInterfaceTable); config_require(OC-STB-HOST-MIB/ocStbHostAnalogVideoTable); Anyway, does switching these two lines around truely control the order in which the tables are initialized? If not, then I guess I will need to do what you are recommending in your response email instead. Robert Story <rs...@fr...> wrote: On Thu, 7 Jun 2007 09:50:24 -0700 (PDT) Need wrote: NH> Referring to my oroblem outlined in (1) below ...... NH> NH> It seems the problem might be due to the fact that Table2(ocStbHostAnalogVideoTable) seems to be initialized before Table1(ocStbHostAVInterfaceTable), thus the cache from Table1 does not exist yet and can not be used for Table2. That's exactly what I just got through telling you. ;-) NH> Is there a way to indicate which table should init first? I will keep looking around. Nope. Check out the ifTable code. I think I just used a static var in table1 to indicate if it had initialized, and called table1 init from table2. --------------------------------- Moody friends. Drama queens. Your life? Nope! - their life, your story. Play Sims Stories at Yahoo! Games. |
From: Robert S. <rs...@fr...> - 2007-06-07 20:38:51
|
On Thu, 7 Jun 2007 10:10:47 -0700 (PDT) Need wrote: NH> Anyway, does switching these two lines around truely control the order in which the tables are initialized? If not, then I guess I will need to do what you are recommending in your response email instead. It does, but assume that the way configure processes these statements doesn't change, and nobody starts snmpd with -I -ocStbHostAVInterfaceTable, which would disable the first table. The safest way is the way I mentioned. |
From: Need H. <snm...@ya...> - 2007-06-07 18:28:59
|
A) You stated there are other methods (instead of using "se_add_pair_to_slist" and "se_find_value_in_slist" routines) which can be used to remember index values. I assume "other methods" mean that I am free to implement any other way to remember index values if I want :>) ... or perhaps other methods already exist within NetSNMP? I asked this question, since it does seem silly to assign a "text string" to each index value like the "se_xxxx" routines mentioned above require in order to remember the index mappings. I might see if I can find another way without using text strings. Any advice? B) You state "Check out the container load function(s) for ifTable." . Well, this seems to complicated for me to understand just yet. I think I will simply regenerate Table1 during it's container_load() routine everytime since this would be easier for me right now. Perhaps in the future, updating this to not regenerate the full table everytime would be possible. C) Just wanted to confirm with you the following is true .... please confirm: The "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine calls the "ocStbHostAnalogVideoTable_row_prep()" routine and now it is possible for the "ocStbHostAnalogVideoTable_row_prep()" routine to return a MFD_SKIP value. This means the "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine can now return a MFD_SKIP value. I just wanted to confirm that this is ok and no additional code is required (somewhere else) to handle a MFD_SKIP value from being returned by the "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine. D) "the more questions you ask in a single message, to more likely I am to take longer to respond. I only have so many hours in the day!" I completely understand and immensely appreciate all the time and guidance you have provided me so far. Without this sort of assistance, I would not even come close to using SNMP for my company, especially after finding out I am dealing with tables which are related to other tables. I do apperciate your help immensely ...... thanks to you (as well as David of course) ! --------------------------------- Choose the right car based on your needs. Check out Yahoo! Autos new Car Finder tool. |
From: Need H. <snm...@ya...> - 2007-06-07 19:05:26
|
Ugh ... I just noticed something I think I am doing wrong: The Table2 data_context structure came configured with a "ProtectionStatus" field defined in it (since this is in my MIB). Knowing that Table2 is an extension of Table1 (and based on our past discussions on how to implement this type of table), I added the "ProtectionStatus" field defintion into Table1 data_context structure as well. Also, Table2 has been enhanced to use the same cache as defined by Table1. Now, when I "snmpwalk" through Table2, then the "Table2_row_prep()" routine is called and is providing a row_context structure as input. In this routine, I found that I am updating the "ProtectionStatus" field defined in the Table2 data_context structure instead of updating the one defined in the Table1 data_context structure. I think this is a mistake. I believe I want to update the "ProtectionStatus" field in Table1 data_context instead .... is this correct? If so, then how do I access the Table1 table so I can update the row data appropriately? I know the "rowreq_ctx->tbl_idx" value provided in the Table2_row_prep() routine tells me the row I am dealing with, but how do I get to Table1 to change the field data there? The other thing is that the "snmpwalk" of Table2 did display all rows showing the "ProtectionStatus" field value. Since the "ProtectionStatus" field was only populated in the Table2 data_context structure (ie: I never updated it in the Table1 data_context structure), then this means the "snmpwalk" is really walking through Table2 data and not really getting the data from Table1 like it should, so something still must be wrong with my set up. Actually, should the Table2 data_context structure include any fields at all? I would not think so, since all these fields have been added to Table1 data_context already. --------------------------------- Be a better Globetrotter. Get better travel answers from someone who knows. Yahoo! Answers - Check it out. |
From: Robert S. <rs...@fr...> - 2007-06-07 20:45:19
|
On Thu, 7 Jun 2007 12:05:15 -0700 (PDT) Need wrote: NH> Ugh ... I just noticed something I think I am doing wrong: NH> NH> The Table2 data_context structure came configured with a "ProtectionStatus" field defined in it (since this is in my MIB). Knowing that Table2 is an extension of Table1 (and based on our past discussions on how to implement this type of table), I added the "ProtectionStatus" field defintion into Table1 data_context structure as well. Also, Table2 has been enhanced to use the same cache as defined by Table1. NH> NH> Now, when I "snmpwalk" through Table2, then the "Table2_row_prep()" routine is called and is providing a row_context structure as input. In this routine, I found that I am updating the "ProtectionStatus" field defined in the Table2 data_context structure instead of updating the one defined in the Table1 data_context structure. I think this is a mistake. I believe I want to update the "ProtectionStatus" field in Table1 data_context instead .... is this correct? Yep. Check out the ifXTable headers.. you'll see that it is using ifTable structures. NH> If so, then how do I access the Table1 table so I can update the row data appropriately? I know the "rowreq_ctx->tbl_idx" value provided in the Table2_row_prep() routine tells me the row I am dealing with, but how do I get to Table1 to change the field data there? The data structure of the rowreq_ctx is the data structure from table1. NH> Actually, should the Table2 data_context structure include any fields at all? I would not think so, since all these fields have been added to Table1 data_context already. Nope. Try the sharing trick form ifXTable.... |
From: Need H. <snm...@ya...> - 2007-06-07 20:33:56
|
Returning MFD_SKIP from the Table2_row_prep() routine results in the following error: Error in packet. Reason: (genError) A general failure occured I generated the first two rows using snmpwalk and then decided to return MFD_SKIP for the third row request, thinking that the row data would be skipped and that Table2_row_prep() for the 4th row would occur, but I got the above error instead and the snmpwalk stopped. Any ideas? Need Help <snm...@ya...> wrote:C) Just wanted to confirm with you the following is true .... please confirm: The "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine calls the "ocStbHostAnalogVideoTable_row_prep()" routine and now it is possible for the "ocStbHostAnalogVideoTable_row_prep()" routine to return a MFD_SKIP value. This means the "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine can now return a MFD_SKIP value. I just wanted to confirm that this is ok and no additional code is required (somewhere else) to handle a MFD_SKIP value from being returned by the "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine. --------------------------------- Now that's room service! Choose from over 150,000 hotels in 45,000 destinations on Yahoo! Travel to find your fit. |
From: Robert S. <rs...@fr...> - 2007-06-07 20:46:46
|
On Thu, 7 Jun 2007 13:33:51 -0700 (PDT) Need wrote: NH> Returning MFD_SKIP from the Table2_row_prep() routine results in the following error: NH> NH> Error in packet. NH> Reason: (genError) A general failure occured NH> NH> NH> I generated the first two rows using snmpwalk and then decided to return MFD_SKIP for the third row request, thinking that the row data would be skipped and that Table2_row_prep() for the 4th row would occur, but I got the above error instead and the snmpwalk stopped. NH> NH> Any ideas? Yeah, you need some code for the interface file.. I'll try to take a look soon, but in the meantime you can poke around in the interface.c, look how skip is handled elsewhere, and try that. It might be that easy, but there might be some side effects to deal with as well. |
From: Robert S. <rs...@fr...> - 2007-06-07 20:42:42
|
On Thu, 7 Jun 2007 11:01:47 -0700 (PDT) Need wrote: NH> A) You stated there are other methods (instead of using "se_add_pair_to_slist" and "se_find_value_in_slist" routines) which can be used to remember index values. I assume "other methods" mean that I am free to implement any other way to remember index values if I want :>) ... or perhaps other methods already exist within NetSNMP? I asked this question, since it does seem silly to assign a "text string" to each index value like the "se_xxxx" routines mentioned above require in order to remember the index mappings. I might see if I can find another way without using text strings. Any advice? The slist stuff is just the easiest out of the box. If the devices have any sort of unique identifier, you could simply maintain a table of thosse identifiers and an unique id. NH> C) Just wanted to confirm with you the following is true .... please confirm: NH> NH> The "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine calls the "ocStbHostAnalogVideoTable_row_prep()" routine and now it is possible for the "ocStbHostAnalogVideoTable_row_prep()" routine to return a MFD_SKIP value. This means the "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine can now return a MFD_SKIP value. NH> NH> I just wanted to confirm that this is ok and no additional code is required (somewhere else) to handle a MFD_SKIP value from being returned by the "_mfd_ocStbHostAnalogVideoTable_object_lookup()" routine. The interface.c code for each table will have to be updated to handle the new return code. |
From: Need H. <snm...@ya...> - 2007-06-08 14:55:19
|
Here are the two tables I am dealing with again: Table1(ocStbHostAVInterfaceTable) Table2(ocStbHostAnalogVideoTable) I looked into the "ifXTable.h" file and saw how the "ifTable" data structures are being used. As a result I removed the following structure/definitions from Table2 .... ocStbHostAnalogVideoTable_registration ocStbHostAnalogVideoTable_data ocStbHostAnalogVideoTable_mib_index ocStbHostAnalogVideoTable_rowreq_ctx ocStbHostAnalogVideoTable_ref_rowreq_ctx ..... and added the following code to indicate to use Table1 structures: typedef ocStbHostAVInterfaceTable_registration ocStbHostAnalogVideoTable_registration; typedef ocStbHostAVInterfaceTable_data ocStbHostAnalogVideoTable_data; typedef ocStbHostAVInterfaceTable_mib_index ocStbHostAnalogVideoTable_mib_index; typedef ocStbHostAVInterfaceTable_rowreq_ctx ocStbHostAnalogVideoTable_rowreq_ctx; typedef ocStbHostAVInterfaceTable_ref_rowreq_ctx ocStbHostAnalogVideoTable_ref_rowreq_ctx; My problem now is that the code does not compile. I confirmed the compile errors are due to not being able to find the Table1 structure definitions (shown below). ocStbHostAVInterfaceTable_registration ocStbHostAVInterfaceTable_data ocStbHostAVInterfaceTable_mib_index ocStbHostAVInterfaceTable_rowreq_ctx ocStbHostAVInterfaceTable_ref_rowreq_ctx Of course, I made sure the Table1 header file (where these structures are defined) was included: #include "OC-STB-HOST-MIB/ocStbHostAVInterfaceTable/ocStbHostAVInterfaceTable.h" Anyway, I know this might be a long shot, but do you think I am missing some other thing? I have been looking at the "ifTable.h" and "ifXTable.h" code as a guide to see if I am missing anything, but I can determine what it could be causing my compile errors. Robert Story <rs...@fr...> wrote: On Thu, 7 Jun 2007 12:05:15 -0700 (PDT) Need wrote: NH> Ugh ... I just noticed something I think I am doing wrong: NH> Yep. Check out the ifXTable headers.. you'll see that it is using ifTable structures. --------------------------------- Got a little couch potato? Check out fun summer activities for kids. |
From: Need H. <snm...@ya...> - 2007-06-08 17:39:11
|
I might have figured this out ...... do not spend your time on this yet .... thanks Need Help <snm...@ya...> wrote: Here are the two tables I am dealing with again: Table1(ocStbHostAVInterfaceTable) Table2(ocStbHostAnalogVideoTable) I looked into the "ifXTable.h" file and saw how the "ifTable" data structures are being used. As a result I removed the following structure/definitions from Table2 .... ocStbHostAnalogVideoTable_registration ocStbHostAnalogVideoTable_data ocStbHostAnalogVideoTable_mib_index ocStbHostAnalogVideoTable_rowreq_ctx ocStbHostAnalogVideoTable_ref_rowreq_ctx ..... and added the following code to indicate to use Table1 structures: typedef ocStbHostAVInterfaceTable_registration ocStbHostAnalogVideoTable_registration; typedef ocStbHostAVInterfaceTable_data ocStbHostAnalogVideoTable_data; typedef ocStbHostAVInterfaceTable_mib_index ocStbHostAnalogVideoTable_mib_index; typedef ocStbHostAVInterfaceTable_rowreq_ctx ocStbHostAnalogVideoTable_rowreq_ctx; typedef ocStbHostAVInterfaceTable_ref_rowreq_ctx ocStbHostAnalogVideoTable_ref_rowreq_ctx; My problem now is that the code does not compile. I confirmed the compile errors are due to not being able to find the Table1 structure definitions (shown below). ocStbHostAVInterfaceTable_registration ocStbHostAVInterfaceTable_data ocStbHostAVInterfaceTable_mib_index ocStbHostAVInterfaceTable_rowreq_ctx ocStbHostAVInterfaceTable_ref_rowreq_ctx Of course, I made sure the Table1 header file (where these structures are defined) was included: #include "OC-STB-HOST-MIB/ocStbHostAVInterfaceTable/ocStbHostAVInterfaceTable.h" Anyway, I know this might be a long shot, but do you think I am missing some other thing? I have been looking at the "ifTable.h" and "ifXTable.h" code as a guide to see if I am missing anything, but I can determine what it could be causing my compile errors. Robert Story <rs...@fr...> wrote: On Thu, 7 Jun 2007 12:05:15 -0700 (PDT) Need wrote: NH> Ugh ... I just noticed something I think I am doing wrong: NH> Yep. Check out the ifXTable headers.. you'll see that it is using ifTable structures. --------------------------------- Got a little couch potato? Check out fun summer activities for kids.------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/_______________________________________________ Net-snmp-coders mailing list Net...@li... https://lists.sourceforge.net/lists/listinfo/net-snmp-coders --------------------------------- Don't get soaked. Take a quick peak at the forecast with theYahoo! Search weather shortcut. |
From: Need H. <snm...@ya...> - 2007-06-08 19:01:11
|
FOUND IT My problem was caused by having Table1 try to #include the header file from Table2 while Table2 had code to #include the header file from Table1. Things were getting screwy. I fixed this and it now compiles but I have a question. 1) Table2 included the Table1 header file so it could share the data structures defined in Table1. This is required based on how the ifTable/ifXTable share the data structures, so this seemed fine. Based on previous discussions, my goal was to update the data_context of Table1 to include a "union" of all the required "extended table" data structures since they are mutually exclusive to each other. Since Table2 already had all of it's data fields defined in one data_context structure, I thought I could simply have Table1 "#include" the header from Table2 and use this structure inside the Table1 data_context "union" definition. I then figured out I could not compile since both tables were trying to include each other's header files and this caused some problems. Anyway, I looked how ifTable/ifXTable handled this scenario and I saw that the ifTable did "not" include the header file from the ifXTable, but instead all of the fields in the ifXTable were copied into the ifTable data_context directly. I decided I could not simply copy all of the fields from my Table2 data_context into the Table1 data_context since I wanted to use a "union" of each table, so I needed to keep all the table data fields defined within their own structure. Using structures within the "union" definition allows me to keep each table mutually exclusive to each other easily. Anyway, what I ended up doing was simply moving the Table2 data_context structure definition into the header file of Table1 (I also renamed this data structure so the name did not conflict). Everything compiles now, but I have a question. Knowing that I have six tables which are extensions of Table1, then I would need to copy all of the data_context structures from these six extension tables into the Table1 header file to allow the "union" to work. Is there a better way to go about this? I mean, should Table1 header file include all data_context structure definitions from all extension tables? 2) Looking at how the ifTable/ifXTable code is implemented, I believe I do not need the following routines in my Table2 "interface.c" file. Would you please let me know if you agree that I can delete the following routines (also if you think there are more, then let me know): Table2_allocate_rowreq_ctx() Table2_release_rowreq_ctx() _cache_load() _cache_free() _container_item_free() _container_free() 3) I also decided I needed to update the _mfd_Table2_post_request() routine in Table2 to ... replace: Table2_release_rowreq_ctx(rowreq_ctx); with: Table1_release_rowreq_ctx(rowreq_ctx); Does this seem correct? Need Help <snm...@ya...> wrote: Here are the two tables I am dealing with again: Table1(ocStbHostAVInterfaceTable) Table2(ocStbHostAnalogVideoTable) I looked into the "ifXTable.h" file and saw how the "ifTable" data structures are being used. As a result I removed the following structure/definitions from Table2 .... ocStbHostAnalogVideoTable_registration ocStbHostAnalogVideoTable_data ocStbHostAnalogVideoTable_mib_index ocStbHostAnalogVideoTable_rowreq_ctx ocStbHostAnalogVideoTable_ref_rowreq_ctx ..... and added the following code to indicate to use Table1 structures: typedef ocStbHostAVInterfaceTable_registration ocStbHostAnalogVideoTable_registration; typedef ocStbHostAVInterfaceTable_data ocStbHostAnalogVideoTable_data; typedef ocStbHostAVInterfaceTable_mib_index ocStbHostAnalogVideoTable_mib_index; typedef ocStbHostAVInterfaceTable_rowreq_ctx ocStbHostAnalogVideoTable_rowreq_ctx; typedef ocStbHostAVInterfaceTable_ref_rowreq_ctx ocStbHostAnalogVideoTable_ref_rowreq_ctx; My problem now is that the code does not compile. I confirmed the compile errors are due to not being able to find the Table1 structure definitions (shown below). ocStbHostAVInterfaceTable_registration ocStbHostAVInterfaceTable_data ocStbHostAVInterfaceTable_mib_index ocStbHostAVInterfaceTable_rowreq_ctx ocStbHostAVInterfaceTable_ref_rowreq_ctx Of course, I made sure the Table1 header file (where these structures are defined) was included: #include "OC-STB-HOST-MIB/ocStbHostAVInterfaceTable/ocStbHostAVInterfaceTable.h" Anyway, I know this might be a long shot, but do you think I am missing some other thing? I have been looking at the "ifTable.h" and "ifXTable.h" code as a guide to see if I am missing anything, but I can determine what it could be causing my compile errors. Robert Story <rs...@fr...> wrote: On Thu, 7 Jun 2007 12:05:15 -0700 (PDT) Need wrote: NH> Ugh ... I just noticed something I think I am doing wrong: NH> Yep. Check out the ifXTable headers.. you'll see that it is using ifTable structures. --------------------------------- Got a little couch potato? Check out fun summer activities for kids.------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/_______________________________________________ Net-snmp-coders mailing list Net...@li... https://lists.sourceforge.net/lists/listinfo/net-snmp-coders --------------------------------- Get the free Yahoo! toolbar and rest assured with the added security of spyware protection. |
From: Robert S. <rs...@fr...> - 2007-06-10 23:08:09
|
On Fri, 8 Jun 2007 12:01:05 -0700 (PDT) Need wrote: NH> Everything compiles now, but I have a question. Knowing that I have six tables which are extensions of Table1, then I would need to copy all of the data_context structures from these six extension tables into the Table1 header file to allow the "union" to work. NH> NH> Is there a better way to go about this? I mean, should Table1 header file include all data_context structure definitions from all extension tables? Nope. Moving each data context structure into table1.h for a union is perfectly reasonable. NH> 2) Looking at how the ifTable/ifXTable code is implemented, I believe I do not need the following routines in my Table2 "interface.c" file. Would you please let me know if you agree that I can delete the following routines (also if you think there are more, then let me know): NH> NH> Table2_allocate_rowreq_ctx() NH> Table2_release_rowreq_ctx() NH> _cache_load() NH> _cache_free() NH> _container_item_free() NH> _container_free() Yeah, those can go. There a probably others, but I'd focus on getting some working code before I went around looking to optimize too much. NH> 3) I also decided I needed to update the _mfd_Table2_post_request() routine in Table2 to ... NH> NH> replace: NH> NH> Table2_release_rowreq_ctx(rowreq_ctx); NH> NH> with: NH> NH> Table1_release_rowreq_ctx(rowreq_ctx); NH> NH> NH> Does this seem correct? Yep. Or just update all the tableN headers to #define tableN_* to table1_* as needed. |
From: Need H. <snm...@ya...> - 2007-06-08 15:08:46
|
Here is the compile errors: In file included from mibgroup/OC-STB-HOST-MIB/ocStbHostAVInterfaceTable/ocStbHostAVInterfaceTable.h:44, from mibgroup/OC-STB-HOST-MIB/ocStbHostAVInterfaceTable/ocStbHostAVInterfaceTable_data_access.c:17: .../agent/mibgroup/OC-STB-HOST-MIB/ocStbHostAnalogVideoTable/ocStbHostAnalogVideoTable.h:72: error: syntax error before "ocStbHostAnalogVideoTable_registration" .../agent/mibgroup/OC-STB-HOST-MIB/ocStbHostAnalogVideoTable/ocStbHostAnalogVideoTable.h:72: warning: data definition has no type or storage class .../agent/mibgroup/OC-STB-HOST-MIB/ocStbHostAnalogVideoTable/ocStbHostAnalogVideoTable.h:73: error: syntax error before "ocStbHostAnalogVideoTable_data" .../agent/mibgroup/OC-STB-HOST-MIB/ocStbHostAnalogVideoTable/ocStbHostAnalogVideoTable.h:73: warning: data definition has no type or storage class .../agent/mibgroup/OC-STB-HOST-MIB/ocStbHostAnalogVideoTable/ocStbHostAnalogVideoTable.h:74: error: syntax error before "ocStbHostAnalogVideoTable_mib_index" .../agent/mibgroup/OC-STB-HOST-MIB/ocStbHostAnalogVideoTable/ocStbHostAnalogVideoTable.h:74: warning: data definition has no type or storage class .../agent/mibgroup/OC-STB-HOST-MIB/ocStbHostAnalogVideoTable/ocStbHostAnalogVideoTable.h:75: error: syntax error before "ocStbHostAnalogVideoTable_rowreq_ctx" .../agent/mibgroup/OC-STB-HOST-MIB/ocStbHostAnalogVideoTable/ocStbHostAnalogVideoTable.h:75: warning: data definition has no type or storage class .../agent/mibgroup/OC-STB-HOST-MIB/ocStbHostAnalogVideoTable/ocStbHostAnalogVideoTable.h:76: error: syntax error before "ocStbHostAnalogVideoTable_ref_rowreq_ctx" .../agent/mibgroup/OC-STB-HOST-MIB/ocStbHostAnalogVideoTable/ocStbHostAnalogVideoTable.h:76: warning: data definition has no type or storage class Robert Story <rs...@fr...> wrote: On Thu, 7 Jun 2007 13:33:51 -0700 (PDT) Need wrote: NH> Returning MFD_SKIP from the Table2_row_prep() routine results in the following error: NH> NH> Error in packet. NH> Reason: (genError) A general failure occured NH> NH> NH> I generated the first two rows using snmpwalk and then decided to return MFD_SKIP for the third row request, thinking that the row data would be skipped and that Table2_row_prep() for the 4th row would occur, but I got the above error instead and the snmpwalk stopped. NH> NH> Any ideas? Yeah, you need some code for the interface file.. I'll try to take a look soon, but in the meantime you can poke around in the interface.c, look how skip is handled elsewhere, and try that. It might be that easy, but there might be some side effects to deal with as well. --------------------------------- 8:00? 8:25? 8:40? Find a flick in no time with theYahoo! Search movie showtime shortcut. |
From: Robert S. <rs...@fr...> - 2007-06-05 11:05:28
|
On Mon, 4 Jun 2007 10:30:25 -0700 (PDT) Need wrote: NH> 1) Lets say the first request made is to "snmpwalk" through Table2. Are you saying that Table1's container_load() procedure has never been called yet so none of the index values have been loaded and none of the rows have been allocated and placed into the Table1 container yet? If this is true, then how does an "snmpwalk" through Table2 work since no rows have been allocated to store the data yet? By default, yes. Remember, mib2c does not know about the relationship between the 2 tables, so the generated code treats each independently, with their own container and data. NH> I am getting way confused. What actually happens when an "snmpwalk" of Table2 occurs first? Does the container_load() procedure of Table2 get called first? Yes, by default it would. That is why I told you to use a shared cache in my last message. If each table uses the same cache, they when _any_ of them are accessed, the will call the table1 container_load function. NH> What exactly should be placed into the container_load() procedure of Table2? Nothing. You could actually delete it, if you also deleted the code that referenced it in the interface code. With a little work, the mib2c code could be updated to handle this automatically. Let me know if you want to sponsor a little work in this area. ;-) NH> Actually, by now you understand I have a main Table1 (with 4 fields) and a Table2 (with 8 fields) which is an extension to Table1. Perhaps you can describe to me what functionality should be placed into the Table1_container_load(), Table1_row_prep(), Table2_container_load() and Table2_row_prep() routines? I think my problem is that I understand what the container_load and row_prep routines should do, but have no idea how to use them correctly when one of my tables is an extension of another table. Table1_container_load(): load all the indexes. Optionally, load data context for tabels 1-N. Table1_row_prep(): load data context for table 1, if not done in container_load Table2_container_load(): nothing Table2_row_prep(): load data context for table 2, if not done in container_load NH> 2) You state "Luckily, there is a failry easy way around that, which is sharing a single cache as well. See the function _ifXTable_container_init to see how it looks up the ifTable cache to share a container". NH> NH> I looked at this code and can see how another table's cache can be connected to the container of another table. Perhaps you can explain to me "why" I should be doing this as am I not clear as to why you are recommending this code to me in the first place. The cache handler is the one that takes care of loading the container when a request comes in. NH> 3) You stated "Now, the problem is that when you are loading the container, you will have no idea which of the 6 tables triggered the load." NH> NH> Well this seems bad since I will not know what I am really loading? Are you indicating I should not be implementing it this way by adding all fields into the data_context of Table1? Is this your way of indicating to me that I will run into too many problems with combining all fields into the data_context of Table1 and that I should use sub-containers after all? No, I'm just saying that if you always load data for table1, you could be wasting time, since the query is actually for table4. So, if populating the container with all the data is expensive, you might want to just put in the indexes, and use row_prep for all the tables. On the other hand, if you have the data for tables 1 and 4 while getting the indexes, you could go ahead and save that data, since you've already got it. It might be a waste of time, but hey, you've already got the data. Remember, there is no ONE way to implement a table. It is highly dependent on where you get your data from. NH> 4) I wish you were local so I could stop by and have you simply draw some ideas on some paper as to what you are recommending. For the right price, I could be local for a few days. ;-) The problem is, you happened to have a non-trivial example to start with. You'll get there.... |