[YANGTOOLS-512] Deleted Flow in config "magically" shows up after node restart. Created: 25/Sep/15  Updated: 10/Apr/22  Resolved: 13/Oct/15

Status: Resolved
Project: yangtools
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug
Reporter: Luis Gomez Assignee: Robert Varga
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


External issue ID: 4359

 Description   

A flow that is deleted in config ds, appears after node restart.

Steps to reproduce:

1) start controller with bin/karaf

2) install odl-openflowplugin-flow-services-ui or odl-openflowplugin-flow-services-ui-li

3) enter the "magic" sequence:

3.1) add a flow, like example below or anything you like:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<flow xmlns="urn:opendaylight:flow:inventory">
<hard-timeout>0</hard-timeout>
<idle-timeout>0</idle-timeout>
<priority>2</priority>
<flow-name>flow1</flow-name>
<match>
<ethernet-match>
<ethernet-type>
<type>2048</type>
</ethernet-type>
</ethernet-match>
<ipv4-destination>10.0.10.0/24</ipv4-destination>
</match>
<id>1</id>
<table_id>0</table_id>
<instructions>
<instruction>
<order>0</order>
<apply-actions>
<action>
<output-action>
<output-node-connector>1</output-node-connector>
</output-action>
<order>0</order>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>

3.2) Remove the flow

3.3) Add again the same flow

3.4) Remove again the flow

4) Stop controller (i.e. logout)

5) Start controller bin/karaf

Deleted flow is there in config!



 Comments   
Comment by Moiz Raja [ 25/Sep/15 ]

After deleting the flow and before restarting the controller are you able to see the flow in the datastore?

Comment by Luis Gomez [ 25/Sep/15 ]

No, the flow adds/removes with no issues before the restart.

Comment by Moiz Raja [ 25/Sep/15 ]

On which version did you encounter this problem? Is it reproducible on stable/lithium?

Comment by Luis Gomez [ 25/Sep/15 ]

both stable/lithium and master.

Comment by Luis Gomez [ 25/Sep/15 ]

I have just reproduced with latest stable/lithium distro from Nexus.

https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/org/opendaylight/integration/distribution-karaf/0.3.2-SNAPSHOT/distribution-karaf-0.3.2-20150925.203437-84.zip

BR/Luis

Comment by Moiz Raja [ 26/Sep/15 ]

See CONTROLLER-1297 - It was fixed in helium by changing the journal-recovery batch size to 1.

https://git.opendaylight.org/gerrit/#/c/20736/

The workaround on stable/lithium for this particular bug right now is to set shard-journal-recovery-log-batch-size to 1 in etc/org.opendaylight.controller.cluster.datastore.cfg. The bug however appears to be in the underlying DataTree code I presume because when we do the operations described in this bug in separate transactions it produces a different output than when we do the same set of operations in a single transaction on recovery.

Comment by Anil Vishnoi [ 26/Sep/15 ]

we do similar bug in ovsdb plugin as well, when bridge related config data pops up again in the data store, after restart. I will try this workaround and see if it works.

Comment by Luis Gomez [ 27/Sep/15 ]

Workaround suggested by Moiz works, at least for the issue reported.

Comment by Robert Varga [ 30/Sep/15 ]

Not an MD-SAL issue, but rather CDS.

Comment by Moiz Raja [ 30/Sep/15 ]

Robert were you able to test out DataTree in this scenario (add, delete, add, delete of the same node) to confirm that this is not a DataTree issue?

Note that the issue is when we take four operations that were done in separate transactions and put it on a single transaction then this problem happens - and not when they are replayed on a single transaction.

Comment by Robert Varga [ 30/Sep/15 ]

Well, no, as there is no description of what the operations on DataTree are. Given that CDS data tree recovery is not a single write, but rather a series of operations from the journal, it is not clear what the before-state, DataTreeModification and after-state looks like.

Comment by Moiz Raja [ 30/Sep/15 ]

The test case is simple,

Tx1 -> Add Flow 1 -> DTC 1
Tx2 -> Remove Flow 1 -> DTC 2
Tx3 -> Add Flow 1 -> DTC 3
Tx3 -> Remove Flow 1 -> DTC 4

Each transaction yields a DataTreeCandidate which we store in the journal.

On recovery,

Tx1 -> Apply (DTC1, DTC2, DTC3, DTC4) -> This triggers the bug

If instead we do the following,

Tx1 -> Apply DTC1
Tx2 -> Apply DTC2
Tx3 -> Apply DTC3
Tx4 -> Apply DTC4

This works just fine.

I am trying to reproduce the bug in a test case - so stay tuned.

Comment by Moiz Raja [ 30/Sep/15 ]

I've reproduced this problem using a unit test

https://git.opendaylight.org/gerrit/#/c/27678/

I believe this shows the issue with the DataTree.

Comment by Robert Varga [ 05/Oct/15 ]

As the data tree candididates are applied, the modification to be applied looks like this:

MutableDataTree [modification=NodeModification [identifier=(urn:ietf:params:xml:ns:netconf:base:1.0)data, modificationType=TOUCH, childModification={(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)cars=NodeModification [identifier=(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)cars, modificationType=WRITE, childModification={}]}]]

MutableDataTree [modification=NodeModification [identifier=(urn:ietf:params:xml:ns:netconf:base:1.0)data, modificationType=TOUCH, childModification={(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)cars=NodeModification [identifier=(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)cars, modificationType=WRITE, childModification={(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car=NodeModification [identifier=(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car, modificationType=TOUCH, childModification={(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car[

{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)name=altima}

]=NodeModification [identifier=(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car[

{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)name=altima}

], modificationType=DELETE, childModification={}]}]}]}]]

MutableDataTree [modification=NodeModification [identifier=(urn:ietf:params:xml:ns:netconf:base:1.0)data, modificationType=TOUCH, childModification={(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)cars=NodeModification [identifier=(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)cars, modificationType=WRITE, childModification={(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car=NodeModification [identifier=(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car, modificationType=TOUCH, childModification={(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car[

{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)name=altima}

]=NodeModification [identifier=(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car[

{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)name=altima}

], modificationType=WRITE, childModification={}]}]}]}]]

MutableDataTree [modification=NodeModification [identifier=(urn:ietf:params:xml:ns:netconf:base:1.0)data, modificationType=TOUCH, childModification={(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)cars=NodeModification [identifier=(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)cars, modificationType=WRITE, childModification={(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car=NodeModification [identifier=(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car, modificationType=TOUCH, childModification={(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car[

{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)name=altima}

]=NodeModification [identifier=(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)car[

{(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:cars?revision=2014-03-13)name=altima}

], modificationType=NONE, childModification={}]}]}]}]]

The important thing to note is that the top-level write after the first transaction already contains the 'altima' node in its data. Note that for second operation we carry a DELETE operation, for third we have an explicit WRITE.

So when the second DELETE operation comes along, it sees a WRITE operation on non-preexisting data and turns it into a NONE operation. When we then apply this modification, WRITE is processed as usual and the other operations turn out to be no-ops – hence altima looks like it's been resurrected.

The problem is that the original node is resolved from the underlying snapshot, not the WRITE operation into which the modification is nested. In theory we should be able to set the before-state to the data from that write operation, which should have the effect of the fourth operation seeing this as a DELETE on data we wrote, but which has pre-existing data – thus resolving to a DELETE node (not NONE), hence achieving the same state we see after two operations.

Comment by Robert Varga [ 05/Oct/15 ]

Be: https://git.opendaylight.org/gerrit/27924

Comment by Tony Tkacik [ 13/Oct/15 ]

Merged in Beryllium and stable/lithium (Lithium SR-3)

Generated at Wed Feb 07 20:53:28 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.