Software Development Kit (SDK) and API Discussions

"not well-formed (invalid token)" error with SDK Perl API




I'm facing this nasty bug when invoking nfs-exportfs-list-rules-2 with perl API (latest SDK 3.5.1).

Obviously, perl XLM parser does not like the API answer.

I know why this occurs. One of the /etc/exports entry has non-ascii byte.

This path has ntfs security and is shared thru CIFS and NFS.

This non-ascii (special french char) seems to not cause any other trouble, neither on the filer itself (regarding exportfs rules), nor on the unix NFS clients.

The filer is running DOT


Any help appreciated.

Fighting with users about the path name (back to pure ascii) will not be a piece of cake !






SDK is limited to support UTF-8 character encoding. Any data that is sent by the ONTAP that is not UTF-8 will

result in xml parsing errors. What is the volume language set for the volume which has non-ascii characters?

There is no workaround from SDK, but you can try NaServer::set_debug_style("NA_PRINT_DONT_PARSE") core API which will just prints (not parse)

the raw xml data of the API response. You need to apply some logic to extract the required values from the raw xml.

This this is something hard to do.



Thanks a lot for the clarification.

Actually the language for this volume is "fr (french)".

So you must be right. I'll simply do some test to confirm.

Now being able to identify the "bad boys", at least this provides me some alternatives:

- run with debug activated and parse by myself. I'll give it a try.

- failback to really old SNMP or RSH method, which I really hate, to say the least...



If someone cares, here is the workaround I've implemented.

Read /etc/exports on root volume thru file-read-file API.

     Remove entries starting with #.

     I assume the file match the currently load rules. In the worst case some path might not exist anymore. Armless for me.

Analyse each path to check if it's UTF-8 encoded or not (obviously, UTF-8 volumes need UTF-8 encoded export path to work, and non-UTF-8 volumes need non-UTF-8 export path).

Keep the information in an array or hash.

If no such non-UTF-8 path has been found, don't do anything specia. You can call nfs-exportfs-rules-list-2.

Sure, if someone has manually exported a non-UTF-8 path, You've lost !

If there is some non-UTF-8 path.

Activate the "NA_PRINT_DONT_PARSE" debug option.

Duplicate STDOUT to some other file descriptor (to avoid debug output).

Call nfs-exportfs-rules-list-2 but don't care about the exit code because of course it will not be OK !

Restore standard STDOUT (if you need it later).

Get the XML raw output from $session->{xml}

DON'T blindly convert the whole XML data to UTF-8 with encode perl function. Because if you do that and have some path with true UTF-8 chars (for other volumes), as they use prefix bytes they will be converted again. So you'll fix a problem but create another one.

For each non-UTF-8 path detected previously, do a search/replace work in the XML data to replace those path with their UTF-8 version.

Now the XML data is really UTF-8 compliant, we can do manually what invoke should have done at the very end:

$inv = $session->parse_xml($XML, '<nfs-exportfs-list-rules-2></nfs-exportfs-list-rules-2>');

This solution applies for calling nfs-exportfs-list-rules-2 with no option to get all the information in one shot.

It's also possible to call it for each exported path as an arg, and then determine easily if the workaround is needed or not for each path.

But I see no benefit for it if you need all the information.

It works for me. but I don't expect it to be bulletproof...



Recently I also faced this kind of issue in which volume language set as french. After closing analyzing the module I resolved the problem by adding following code in parse_xml method:

#$p->parse($xml);  #commented by Pallav Gupta, as earlier it was not supporting accent character parsing.

$p->parse($xml, ProtocolEncoding => 'ISO-8859-1');


Pallav Gupta