Must statement fails on powerpc but works on i686

The edit-config (shown) gets a “must-violation” error on confd 6.3 - i686 (which is correct since 0.1 is less than 0.2 ) but the same edit-config is accepted on confd 6.3 - powerpc version and the record is successfully created in cdb. The YANG fragment is shown below.

Question: What is being used by confd for xpath evaluation? Is this some /usr/lib/libxml2.so version issue on the target linux box ? Thanks

<edit-config>
    <target>
      <running/>
    </target>
    <config>
      <ggios xmlns="http://www.glimmerglass.com/ios/gg-ios-yang"
             xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
      <iosThresholds>
        <threshold nc:operation="create">
          <name>powerThreshold</name>
          <hysteresis>0.1</hysteresis> 
        </threshold>
      </iosThresholds>
     </ggios>
    </config>
  </edit-config>

===================================================

container iosThresholds {
    description "";

  list threshold {
  key name;
  description "";
  tailf:callpoint iosThresholdsHook { tailf:transaction-hook object; }
  must "(number(maxPower) - number(minPower)) <= number(/ggios/iosConfiguration/iosMaxSignalRange)"
        { error-message "Specified values exceed the maximum allowed power range"; }

  leaf name {
    type string { length "1..20"; }
    mandatory true;
    description "";
  }

  leaf descr {
    type string { length "0..64"; }
    default "An IOS power threshold value to monitor";
    description "";
  }

  leaf minPower {
    type string;
    default "-20.0";
    must "number(.) >= number(/ggios/iosConfiguration/iosMinSignalPower) and number(.) <= number(/ggios/iosConfiguration/iosMaxSignalPower)";
    description
     "Identifies the minimum power (dBm) value for monitoring threshold
      crossings on the assigned port.";
  }

  leaf maxPower {
    type string;
    default "5.0";
    must "number(.) <= number(/ggios/iosConfiguration/iosMaxSignalPower) and number(.) >= number(/ggios/iosConfiguration/iosMinSignalPower)";
    description
     "Identifies the maximum power (dBm) value for monitoring threshold
      crossings on the assigned port.";
  }

  leaf hysteresis {
    type string;
    default "1.0";
    must "number(.) >= number('0.2')" { tailf:dependency '.'; }
    description
     "Identifies the hysteresis gap (dB) value for monitoring threshold
      crossings on the assigned port. This value helps avoid
      spurious events caused by power whipsaw from signal noise.";
  }
}

}`

FYI: If its related to my bug, I see following line in the CHANGES file:

ConfD-6.0 [June 22, 2015]
=========================
(Issue tracker: #17038, #17929)

  • confd: The internal regexp library has been updated to libxml2 version
    2.9.2.

Question: Is confd 6.3 using same version of libxml2 on both platforms - 686 and ppc.

Thanks

Works on the PPC target I have.
From ConfD 6.3 and later releases you have some some useful XPath dev tools in the C-style CLI that you can try on your target:

$ confd_cli -C -u admin
admin connected from 127.0.0.1
# devtools true
# config       
Entering configuration mode terminal
# xpath must "number('0.1') >= number('0.2')"
false
# xpath must "number('0.3') >= number('0.2')"
true

Is your PPC a “no floating point” target? Are you using “MATH_EMULATION”, i.e. does your Linux variant emulate a floating-point unit?

Thanks I tried the CLI and sure my target failed the xpath must! But why ?

My PPC linux has a native floating point unit on it. Is there a compile option I could have missed, when I recompiled libconfd for to use 0.9.8 version of openssl ?

  LN0001# devtools true
    LN0001# config
    Entering configuration mode terminal
    LN0001(config)# xpath must "number('0.1') >= number('0.2')"
    true
    LN0001(config)# xpath must "number('0.3') >= number('0.2')"
    true
    LN0001(config)# xpath must "number('1') >= number('2')"    
    false
    LN0001(config)#

I ran the following script on my PPC linux to make sure it can do float comparison and its working.

----------------------------------test.sh------------
    #!/bin/sh
    minimum=$(echo 10.55 10.35 | awk '{if ($1 < $2) print $1; else print $2}')
    echo $minimum
    ----------------------------------------------

# ./test.sh
10.35

Interestingly the xpath eval shows following on my ppc box in confd_cli:

Also the return values are more ridiculous when running confd as “confd -smp 4”. The return value is 25 million 25000000 for xpath eval “number(‘0.5’)” and actually for any float value!

The following output is when using confd without -smp flag:

LN0001(config)# xpath eval "number('0.5')"
0
LN0001(config)# xpath eval number('0.1') 
0
LN0001(config)# xpath eval "number('0.1')"
0
LN0001(config)# xpath eval number('0.5')
0
LN0001(config)# xpath eval number(0.5)  
0
LN0001(config)# xpath must "number('0.5') > number('0.7')"
false
LN0001(config)# xpath must "number('0.5') > number('0.7')"
false
LN0001(config)# xpath must "number('0.8') > number('0.7')"
false
LN0001(config)# xpath must "number('0.9') > number('0.7')"
false
LN0001(config)# xpath eval "number('0.5') > number('0.7')"

LN0001(config)# xpath eval "number('0.5') > number('0.7')"

LN0001(config)# xpath eval "number('0.5')"                
0
LN0001(config)# xpath eval "1 + 2"      
3
LN0001(config)# xpath eval "1 + 1.0"
1
LN0001(config)# xpath eval "1 + 2.0"
2
LN0001(config)# xpath eval "1 + 2"  
3
LN0001(config)# xpath eval "2.0"  
2
LN0001(config)# xpath eval 2.0
2
LN0001(config)# xpath eval 2.5
2

I don’t see how the rebuilt crypto modules or libconfd would be involved here.

Perhaps you can test your PPC based system running something like:

$ cat test.xml
<test/>
$ xmllint --xpath "number('0.3') > number('0.2')" test.xml; echo ""
true
$ xmllint --xpath "number('0.1') > number('0.2')" test.xml; echo ""
false
$ xmllint --xpath "number('0.1')" test.xml; echo ""
0.1

Also, have you considered using the YANG decimal64 built-in type instead of strings?
For example:

  leaf hysteresis {
    type decimal64 {
      fraction-digits 1;
    }
    default 1.0;
    must ". >= 0.2" { tailf:dependency '.'; }
    description
     "Identifies the hysteresis gap (dB) value for monitoring threshold
      crossings on the assigned port. This value helps avoid
      spurious events caused by power whipsaw from signal noise.";
  }

I believe the weird results here could be due to your kernel and/or OS libraries not matching your HW. The ConfD ppc build assumes HW floating-point support, and you say that your CPU has a FPU - but if your kernel/libraries are not aware of that, the FPU will not be properly initiated and managed, causing random results for floating-point operations (as opposed to the case where you don’t have a FPU, where they will cause a kernel trap).

So check your kernel configuration, in particular CONFIG_MATH_EMULATION, and whether your glibc is built with -msoft-float.

Thanks all, I’ll look into our kernel build flags later but that certainly would be a great find for us for many other reasons.

My ppc platform is hostage to busybox patches and I do not have “xmllint” binary on the platform at this time.

In meantime, I’ll try the decimal64 suggestion or use tailf:validate to get me going.

Thanks

So I tried the suggestion to use decimal64 instead of string and it didn’t work either. The problem is still the same - xpath must statement fails due to floating point value comparisons on ppc platform. This xpath works just fine on i686.

So, short of looking further into glibc build issues on my ppc platform - i’ll just use tail:validate callback to do the same validation of data values.

Yes, the XPath definition of “number” is floating point. With decimal64, you could use the Tailf-proprietary compare() XPath function in your must expression - see the section XPATH FUNCTIONS in the tailf_yang_extensions(5) manual page.

However looking back at your original must statement, I’m afraid I can’t see how to express it using compare() - there’s no support for arithmetic on the internal values.

Using decimal64 could still be useful - you get syntax check and parsing done by ConfD.