[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(&notready_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