[AGENT++] Why is it possible to destroy an non existing row?
Claus Klein
claus.klein at arcormail.de
Wed Jun 19 23:36:16 CEST 2013
Hi Frank,
Ok, RFC2579 requires no error, that is right and is good.
I request to delete a row and with response, the row should not exist, too if it does not exists before.
But with agent++ code, the row is created in state destroyed. That is wrong!
I tried to fix the cleanup() code, which does not work for me.
At my subagent, notready_rows are always empty,
and the destroyed rows are ignored too?
When and where should the notready_rows filled?
I found an additional problem: after a set request with timeout, the
master agent may close the connection before cleanup and some tables or mibs are locked.
So the cleanup() run into a deadlock!
//Regards
Claus
/**
* Periodically remove all rows that are notReady for more
* than a given timeout (default is 5 minutes)
*
* Note: a row cannot be set from notInService or active to notReady
*/
void MibTable::remove_unused_rows() {
start_synch();
if ((row_status) && (!(row_timeout.in_time()))) {
OidListCursor<MibTableRow> cur(&content);
std::cerr << __FUNCTION__ << " MibTable=" << oid.get_printable()
<< std::endl; //TODO remove TRACE
//FIXME OrderedListCursor<MibTableRow> cur;
//FIXME for (cur.init(¬ready_rows ); cur.get(); )
for (/**/; cur.get(); /***/) {
snmpRowStatus* status = cur.get()->get_row_status();
std::cerr << __FUNCTION__ << " index="
<< cur.get()->index.get_printable() << " status="
<< status->get() << std::endl; //TODO remove TRACE
if ((status->get() == rowNotReady) ||
(status->get() == rowDestroy)) {
std::cerr << __FUNCTION__ << " remove row "
<< cur.get()->index.get_printable() << std::endl; //TODO remove TRACE
LOG_BEGIN(EVENT_LOG | 2);
LOG("MibTable: removing row due to timeout");
LOG(cur.get()->index.get_printable());
LOG_END;
fire_row_changed(rowDestroy, cur.get(), cur.get()->get_index());
//FIXME ListItem<MibTableRow>* victim = cur.get_cursor();
MibTableRow* del = cur.get();
cur.next();
content.remove(del);
//FIXME delete notready_rows.remove(victim);
continue;
}
cur.next();
}
notready_rows.clear();
OidListCursor<MibTableRow> c;
for (c.init(&content); c.get(); c.next()) {
if (c.get()->get_row_status()->get() == rowNotReady)
notready_rows.add(c.get());
}
row_timeout.set_timestamp();
}
// ...
end_synch();
}
On 19.06.2013, at 00:04, Frank Fock wrote:
> Hi Claus,
>
> The SNMP RFCs require that a request setting the status of a non-existing
> row to destroy(6) should return no error. It is left to the implementation
> how this goal is achieved.
>
> I improved the behavior for this use case with AGENT++ 4.0 and AgentX++ 2.0.
> May be that helps?
>
> Best regards,
> Frank
>
> Am 18.06.2013 23:10, schrieb Claus Klein:
>> Hi,
>>
>> I can't understand why it should possible to delete a non existing row?
>>
>> I have added this code to prevent this strange behavior:
>>
>> int netSnmpHostsEntry::is_transition_ok(MibTable* table, MibTableRow* row, const Oidx& index,
>> int currentStatus, int requestedStatus) {
>> // The row 'row' with 'index' from 'table' (which will be 0 for local table)
>> // is requested to change status. Accept or deny this state change here.
>> //--AgentGen BEGIN=netSnmpHostsEntry::is_transition_ok
>>
>> if ((currentStatus == rowEmpty) && (requestedStatus == rowDestroy)) {
>> std::cerr << BOOST_CURRENT_FUNCTION << "(" << currentStatus << " -> "
>> << requestedStatus << ") This is not allowed!" << std::endl;
>> return SNMP_ERROR_INCONSIST_VAL;
>> }
>> ...
>> }
>>
>>
>> Without this check the following happens:
>>
>> Claus-Kleins-MacBook-Pro:agentproI12 clausklein$ snmptable -Cib -r0 -t10 localhost hoststable
>> SNMP table: NET-SNMP-EXAMPLES-MIB::netSnmpHostsTable
>>
>> index AddressType Address Storage RowStatus
>> \"loopback\" ipv6 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 " nonVolatile active
>> \"localhost\" ipv4 "7F 00 00 01 " nonVolatile active
>> \"broadcasthost\" ipv4 "FF FF FF FF " nonVolatile active
>>
>> Claus-Kleins-MacBook-Pro:agentproI12 clausklein$ snmpset localhost netSnmpHostRowStatus.\"test\" = destroy
>> NET-SNMP-EXAMPLES-MIB::netSnmpHostRowStatus.\"test\" = INTEGER: destroy(6)
>>
>> Claus-Kleins-MacBook-Pro:agentproI12 clausklein$ snmptable -Cib -r0 -t10 localhost hoststable
>> SNMP table: NET-SNMP-EXAMPLES-MIB::netSnmpHostsTable
>>
>> index AddressType Address Storage RowStatus
>> \"loopback\" ipv6 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 " nonVolatile active
>> \"localhost\" ipv4 "7F 00 00 01 " nonVolatile active
>> \"broadcasthost\" ipv4 "FF FF FF FF " nonVolatile active
>> \"test\" ? ? nonVolatile destroy
>>
>> Claus-Kleins-MacBook-Pro:agentproI12 clausklein$ snmpset localhost netSnmpHostRowStatus.\"test\" = destroy
>> Error in packet.
>> Reason: inconsistentValue (The set value is illegal or unsupported in some way)
>> Failed object: NET-SNMP-EXAMPLES-MIB::netSnmpHostRowStatus.\"test\"
>>
>> Claus-Kleins-MacBook-Pro:agentproI12 clausklein$
>>
>>
>> ... and the index is blocked with RowStatus "destroy" forever.
>>
>> Tested with shared and non shared Tables; current net-snmp as agentX master and
>>
>> agent++v3.5.31
>> agentX++v1.4.18a
>> libdes-l-4.01a
>> snmp++v3.2.25
>>
>> as agentX subagent.
>>
>>
>> //Regards
>> Claus
>>
>>
>>
>>
>>
>> _______________________________________________
>> AGENTPP mailing list
>> AGENTPP at agentpp.org
>> http://lists.agentpp.org/mailman/listinfo/agentpp
>
> --
> ---
> AGENT++
> Maximilian-Kolbe-Str. 10
> 73257 Koengen, Germany
> https://agentpp.com
> Phone: +49 7024 8688230
> Fax: +49 7024 8688231
>
> _______________________________________________
> AGENTPP mailing list
> AGENTPP at agentpp.org
> http://lists.agentpp.org/mailman/listinfo/agentpp
More information about the AGENTPP
mailing list