sysrepo / sysrepo

YANG-based configuration and operational state data store for Unix/Linux applications

Home Page:http://www.sysrepo.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

regression: pushing multiple `leaf-list` data inside an operational `list` doesn't preserve all values

jktjkt opened this issue · comments

While upgrading from CESNET/libyang@fc4dbd9 to CESNET/libyang@03d6d6c and sysrepo from 337a675 to cbddb02, it seems that there was a change in how nested lists are handled. This is shown in this CI failure (here's our commit).

Basically, the code is pushing operational data to ietf-alarms' alarm-inventory through a sequence of sr_set_item_str calls. The module looks like this:

  +--rw alarms
     +--...
     +--ro alarm-inventory
     |  +--ro alarm-type* [alarm-type-id alarm-type-qualifier]
     |     +--ro alarm-type-id           alarm-type-id
     |     +--ro alarm-type-qualifier    alarm-type-qualifier
     |     +--ro resource*               resource-match
     |     +--ro will-clear              boolean
     |     +--ro severity-level*         severity
     |     +--ro description             string
     ...

...and the code is supposed to be pushing a Cartesian product of four alarm-type-ids (which are part of the list keys here) and some resources (which are a leafref in our case). That means that there will be four list instances of the /ietf-alarms:alarm-inventory/alarm-type, and each of these instances is expected to have a three-member leaf-list called resources. Here's how the resulting edit looks like if I print it right before sr_apply_changes:

{
  "ietf-alarms:alarms": {
    "@": {
      "ietf-netconf:operation": "merge",
      "ietf-origin:origin": "ietf-origin:intended"
    },
    "alarm-inventory": {
      "@": {
        "ietf-origin:origin": "ietf-origin:unknown"
      },
      "alarm-type": [
        {
          "@": {
            "ietf-origin:origin": "ietf-origin:unknown"
          },
          "alarm-type-id": "velia-alarms:sensor-high-value-alarm",
          "alarm-type-qualifier": "",
          "resource": [
            "/ietf-hardware:hardware/component[name='ne:power']",
            "/ietf-hardware:hardware/component[name='ne:psu:child']",
            "/ietf-hardware:hardware/component[name='ne:temperature-cpu']"
          ],
          "@resource": [
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            },
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            },
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            }
          ]
        },
        {
          "alarm-type-id": "velia-alarms:sensor-low-value-alarm",
          "alarm-type-qualifier": "",
          "resource": [
            "/ietf-hardware:hardware/component[name='ne:power']",
            "/ietf-hardware:hardware/component[name='ne:psu:child']",
            "/ietf-hardware:hardware/component[name='ne:temperature-cpu']"
          ],
          "@resource": [
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            },
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            },
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            }
          ]
        },
        {
          "alarm-type-id": "velia-alarms:sensor-missing-alarm",
          "alarm-type-qualifier": "",
          "resource": [
            "/ietf-hardware:hardware/component[name='ne:power']",
            "/ietf-hardware:hardware/component[name='ne:psu:child']",
            "/ietf-hardware:hardware/component[name='ne:temperature-cpu']"
          ],
          "@resource": [
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            },
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            },
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            }
          ]
        },
        {
          "alarm-type-id": "velia-alarms:sensor-nonoperational",
          "alarm-type-qualifier": "",
          "resource": [
            "/ietf-hardware:hardware/component[name='ne:power']",
            "/ietf-hardware:hardware/component[name='ne:psu:child']",
            "/ietf-hardware:hardware/component[name='ne:temperature-cpu']"
          ],
          "@resource": [
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            },
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            },
            {
              "sysrepo:dup-inst-list-position": [null],
              "ietf-netconf:operation": "merge"
            }
          ]
        }
      ]
    }
  }
}

This looks sane; for each of the alarm-type-id identities, there's a list of three resources. However, at the receiving end, the callback only gets the following values:

[file/line unavailable]:0: FATAL ERROR: No match for call of change with signature void(const ValueChanges&) with.
  param  _1 == {
  "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[1]":
    "/ietf-hardware:hardware/component[name='ne:power']",
  "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[2]":
    "/ietf-hardware:hardware/component[name='ne:psu:child']",
  "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[3]":
    "/ietf-hardware:hardware/component[name='ne:temperature-cpu']",
  "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1]":
    "/ietf-hardware:hardware/component[name='ne:power']",
  "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1]":
    "/ietf-hardware:hardware/component[name='ne:power']",
  "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1]":
    "/ietf-hardware:hardware/component[name='ne:power']",
}

...in short, only the first list instance gets all three resources, whereas the remaining three list insatnces only get a single-item leaf-list.

Could you please take a look? This can be reproduced through velia's test case (ctest -R test-sysrepo_ietf-hardware --output-on-failure).

I tried to bisect this. I kept libyang at the newest version (CESNET/libyang@03d6d6c1b), and I started my bisection run just on sysrepo. The first commit which started failing is 7ae1ce9, which sounds rather fishy.

Please help me reproduce it by modifying the new test, based on this information only it worked and I really do not have time to bisect your C++ tests. But the commit you found could break things because multiple calls of libyang functions were joined into a unified one, sometimes with minor changes in case all the tests were passing. An opportunity to add new ones now.

OK, I can identify the bug now. When an edit like the one above is pushed, all the individual leaf-list nodes that are below the second and third list instances have their XPath indexes set to [1]. Here's the reproducer:

#include <iostream>
#include <thread>
#include <sysrepo-cpp/Connection.hpp>

using namespace std::literals;

int main() {
    auto client = sysrepo::Connection{}.sessionStart();
    client.switchDatastore(sysrepo::Datastore::Operational);

    for (const auto id : {"velia-alarms:sensor-high-value-alarm", "velia-alarms:sensor-low-value-alarm", "velia-alarms:sensor-missing-alarm", "velia-alarms:sensor-nonoperational"}) {
        const auto prefix = "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='"s + id + "'][alarm-type-qualifier='']";
        for (const auto& resource : {"/ietf-hardware:hardware/component[name='ne:power']", "/ietf-hardware:hardware/component[name='ne:psu:child']", "/ietf-hardware:hardware/component[name='ne:temperature-cpu']"}) {
            client.setItem(prefix + "/resource", resource);
        }
    }
    std::cerr << "edit: " << *client.getPendingChanges()->printStr(libyang::DataFormat::JSON, libyang::PrintFlags::WithSiblings) << "\n";
    client.applyChanges();
    std::this_thread::sleep_for(1s);
    return 0;
}
  • install these two YANG models:
  • run sysrepo's sysrepo/examples/application_changes_example
  • in another shell, build and run the reproducer:
    • g++ -std=c++20 -Wall -O2 $(pkg-config --cflags --libs sysrepo-cpp libyang-cpp) bug3244.cpp -o bug3244
    • ./bug3244

Here's how the output is different between commits 73b3cfd (good) and 7ae1ce9 (bad):

--- good        2024-02-14 22:04:27.252958734 +0100
+++ bad 2024-02-14 22:04:51.004997235 +0100
@@ -1,121 +1,121 @@
 Application will watch for "ietf-alarms" changes in "operational" datastore.
 
  ========== READING RUNNING CONFIG: ==========
 
 /ietf-alarms:alarms (container)
 /ietf-alarms:alarms/control (container)
 /ietf-alarms:alarms/alarm-inventory (container)
 /ietf-alarms:alarms/alarm-list (container)
 
 
  ========== LISTENING FOR CHANGES ==========
 
 
 
  ========== EVENT change CHANGES: ====================================
 
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 
  ========== END OF CHANGES =======================================
 
  ========== EVENT done CHANGES: ====================================
 
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+CREATED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 
  ========== END OF CHANGES =======================================
 
  ========== CONFIG HAS CHANGED, CURRENT RUNNING CONFIG: ==========
 
 /ietf-alarms:alarms (container)
 /ietf-alarms:alarms/control (container)
 /ietf-alarms:alarms/alarm-inventory (container)
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier=''] (list instance)
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/alarm-type-id = velia-alarms:sensor-high-value-alarm
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/alarm-type-qualifier = 
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier=''] (list instance)
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/alarm-type-id = velia-alarms:sensor-low-value-alarm
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/alarm-type-qualifier = 
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier=''] (list instance)
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/alarm-type-id = velia-alarms:sensor-missing-alarm
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/alarm-type-qualifier = 
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier=''] (list instance)
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/alarm-type-id = velia-alarms:sensor-nonoperational
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/alarm-type-qualifier = 
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
 /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 /ietf-alarms:alarms/alarm-list (container)
 
 
  ========== EVENT change CHANGES: ====================================
 
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 
  ========== END OF CHANGES =======================================
 
  ========== EVENT done CHANGES: ====================================
 
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-high-value-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-low-value-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-missing-alarm'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:power']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[2] = /ietf-hardware:hardware/component[name='ne:psu:child']
-DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[3] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:psu:child']
+DELETED: /ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='velia-alarms:sensor-nonoperational'][alarm-type-qualifier='']/resource[1] = /ietf-hardware:hardware/component[name='ne:temperature-cpu']
 
  ========== END OF CHANGES =======================================
 
  ========== CONFIG HAS CHANGED, CURRENT RUNNING CONFIG: ==========
 
 /ietf-alarms:alarms (container)
 /ietf-alarms:alarms/control (container)
 /ietf-alarms:alarms/alarm-inventory (container)
 /ietf-alarms:alarms/alarm-list (container)
 Application exit requested, exiting.

So I believe I have fixed this or at least vastly improved the situation because there are a few suspicious things. I have not managed to reproduce your output, only the deletion problem, creation log was fine (but I was using the latest devel so maybe that is why, but still strange). Also, in the callback for the deletion the positions are actually not reported (in prev_value) but since the diff is correct now, they can be learnt from the diff tree. I think they could be added without much trouble but it now probably behaves the same way it did before so I have not changed it. Let me know if it now works as expected.

thanks