When list element deleted MOP_DELETE called twice?

Hi All!

I have a list which has a list inside it and which further has a list inside it…

list A {
list B {
list C {
}
}
}

When I delete list A element and I do diff_iterate I am getting iterated twice for MOP_DELETE for A. Issue here is in the second iteration I am not having the element as its already deleted on first MOP_DELETE call. Please let me know if I am missing something ?.

rgds
Balaji

Does it really happen twice? Have you checked if you have two subscription points that’s triggered?

Quick demo:

$ cat test.yang
module test {
  namespace "http://tail-f.com/ns/example/test";
  prefix t;
  list A {
    key a;
    leaf a { type string; }
    leaf a2 { type string; }
    list B {
      key b;
      leaf b { type string; }
      leaf b2 { type string; }
      list C {
        key c;
        leaf c { type string; }
        leaf c2 { type string; }
      }
    }
  }

$ cat test.xml
<config xmlns="http://tail-f.com/ns/config/1.0">
  <A xmlns="http://tail-f.com/ns/example/root">
    <a>testA</a>
    <a2>testA2</a2>
    <B>
      <b>testB</b>
      <b2>testB2</b2>
      <C>
        <c>testC</c>
        <c2>testC2</c2>
      </C>
    </B>
  </A>
</config>

$ confd_load -d -d -m -l test.xml
TRACE Connected (maapi) to ConfD
starting user session ctxt=system user=system groups=[system]
TRACE MAAPI_START_USER_SESSION  --> CONFD_OK
TRACE MAAPI_START_TRANS  --> CONFD_OK
TRACE MAAPI_LOAD_CONFIG_FILE  --> CONFD_OK
TRACE MAAPI_APPLY_TRANS  --> CONFD_OK
TRACE MAAPI_END_USER_SESSION  --> CONFD_OK

$ confd_cmd -d -d -c "mdel /A" 
mdel "/A"
TRACE Connected (maapi) to ConfD
TRACE MAAPI_START_USER_SESSION  --> CONFD_OK
TRACE MAAPI_START_TRANS  --> CONFD_OK
TRACE MAAPI_DELETE /A --> CONFD_OK
TRACE MAAPI_APPLY_TRANS  --> CONFD_OK
TRACE MAAPI_STOP_TRANS  --> CONFD_OK
TRACE MAAPI_END_USER_SESSION  --> CONFD_OK

$ confd_cmd -d -d -c "subwait_iter / 1 2"
subwait_iter "/" "1" "2"
TRACE Connected (maapi) to ConfD
TRACE MAAPI_LOAD_ALL_NS
TRACE MAAPI_LOAD_HASH_DB
TRACE Connected (cdb) to ConfD
TRACE CDB_SUBSCRIBE / --> CONFD_OK
TRACE CDB_SUBSCRIBE_DONE  --> CONFD_OK
SUBSCRIBED TO /
TRACE CDB_SUBSCRIPTION_EVENT --> 7
COMMIT
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
TRACE CDB_SUB_ITERATE 7
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
/ /A{testA} created
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
/ /A{testA}/a set ( -> testA)
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
/ /A{testA}/a2 set ( -> testA2)
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
/ /A{testA}/B{testB} created
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
/ /A{testA}/B{testB}/b set ( -> testB)
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
/ /A{testA}/B{testB}/C{testC} created
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
/ /A{testA}/B{testB}/C{testC}/c set ( -> testC)
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
/ /A{testA}/B{testB}/C{testC}/c2 set ( -> testC2)
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
/ /A{testA}/B{testB}/b2 set ( -> testB2)
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
TRACE CDB_SYNC_SUB CDB_DONE_PRIORITY --> CONFD_OK
DONE

TRACE CDB_SUBSCRIPTION_EVENT --> 7
COMMIT
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
TRACE CDB_SUB_ITERATE 7
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
/ /A{testA} deleted
TRACE CDB_SUB_PROGRESS  --> CONFD_OK
TRACE CDB_SYNC_SUB CDB_DONE_PRIORITY --> CONFD_OK
DONE
1 Like

Thanks a lot , in code I could see we are registering twice. Removing the same worked fine…

On the same topic.

if we have subscription for /A and /A/B
— when a del on List A done, do we get MOP_DELETE notification for each element in list B ?

Terminal Window 1:
$ confd_load -d -d -m -l test.xml
$ confd_cmd -d -d -c “subwait_iter /A 1 100”

Terminal Window 2:
$ confd_cmd -d -d -c “subwait_iter /A/B 1 100”

Terminal Window 3:
$ confd_cmd -d -d -c “mdel /A”

Let us know the result when you tried the above :wink:

I passed the ITER_WANT_ANCESTOR_DELETE flag to the iter in list B subscription handler and I am able to get notificiations to the iter function.

1 Like

Thanks for sharing. For other readers from the confd_lib_cdb(3) man page under cdb_diff_iterate():

MOP_DELETED
The list entry, presence container, or optional leaf given by kp has been deleted.
If the subscription was triggered because an ancestor was deleted, the iter() function will not called at all if the delete was above the subscription point. However if the flag ITER_WANT_ANCESTOR_DELETE is passed to cdb_diff_iterate() then deletes that trigger a descendant subscription will also generate a call to iter(), and in this case kp will be the path that was actually deleted