Browse Source

Merge branch 'candidate-6.2.2' into candidate-6.4.0

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 8 năm trước cách đây
mục cha
commit
cf79df169e

+ 3 - 1
cmake_modules/FindICU.cmake

@@ -63,7 +63,9 @@ IF (NOT ICU_FOUND)
     ELSE()
     ELSE()
       STRING(REPLACE "icuuc" "icuin" ICU_EXTRA1 "${ICU_LIBRARIES}")
       STRING(REPLACE "icuuc" "icuin" ICU_EXTRA1 "${ICU_LIBRARIES}")
     ENDIF()
     ENDIF()
-    set (ICU_LIBRARIES ${ICU_LIBRARIES} ${ICU_EXTRA1} ${ICU_EXTRA2} )
+    # The order is important for lib2 processing:
+    # depender, such as icuil8n, should be placed before the dependee
+    set (ICU_LIBRARIES ${ICU_EXTRA1} ${ICU_LIBRARIES} ${ICU_EXTRA2} )
   ENDIF()
   ENDIF()
 
 
 
 

+ 9 - 1
common/thorhelper/roxiehelper.cpp

@@ -527,7 +527,10 @@ public:
     {
     {
         sorter->reset();
         sorter->reset();
     }
     }
-
+    ~SortedInputReader()
+    {
+        sorter->reset();
+    }
     virtual const void *nextRow()
     virtual const void *nextRow()
     {
     {
         if (!firstRead)
         if (!firstRead)
@@ -613,6 +616,11 @@ class CSortAlgorithm : implements CInterfaceOf<ISortAlgorithm>
 public:
 public:
     CSortAlgorithm() { elapsedCycles = 0; }
     CSortAlgorithm() { elapsedCycles = 0; }
 
 
+    virtual void beforeDispose() override
+    {
+        reset();
+    }
+
     virtual void getSortedGroup(ConstPointerArray & result)
     virtual void getSortedGroup(ConstPointerArray & result)
     {
     {
         loop
         loop

+ 12 - 4
common/workunit/referencedfilelist.cpp

@@ -337,7 +337,10 @@ void ReferencedFile::resolveLocal(const char *dstCluster, const char *srcCluster
     if(df)
     if(df)
         processLocalFileInfo(df, dstCluster, srcCluster, subfiles);
         processLocalFileInfo(df, dstCluster, srcCluster, subfiles);
     else
     else
+    {
         flags |= RefFileNotFound;
         flags |= RefFileNotFound;
+        DBGLOG("ReferencedFile not found (local) %s", logicalName.str());
+    }
 }
 }
 
 
 IPropertyTree *ReferencedFile::getRemoteFileTree(IUserDescriptor *user, INode *remote, const char *remotePrefix)
 IPropertyTree *ReferencedFile::getRemoteFileTree(IUserDescriptor *user, INode *remote, const char *remotePrefix)
@@ -404,6 +407,9 @@ void ReferencedFile::resolveRemote(IUserDescriptor *user, INode *remote, const c
     }
     }
 
 
     flags |= RefFileNotFound;
     flags |= RefFileNotFound;
+
+    StringBuffer dest;
+    DBGLOG("ReferencedFile not found %s [dali=%s, remote=%s, prefix=%s]", logicalName.str(), daliip.get(), remote ? remote->endpoint().getUrlStr(dest).str() : nullptr, remotePrefix);
 }
 }
 
 
 void ReferencedFile::resolve(const char *dstCluster, const char *srcCluster, IUserDescriptor *user, INode *remote, const char *remotePrefix, bool checkLocalFirst, StringArray *subfiles, bool _trackSubFiles, bool resolveForeign)
 void ReferencedFile::resolve(const char *dstCluster, const char *srcCluster, IUserDescriptor *user, INode *remote, const char *remotePrefix, bool checkLocalFirst, StringArray *subfiles, bool _trackSubFiles, bool resolveForeign)
@@ -438,13 +444,13 @@ void ReferencedFile::cloneInfo(unsigned updateFlags, IDFUhelper *helper, IUserDe
     catch (IException *e)
     catch (IException *e)
     {
     {
         flags |= RefFileCopyInfoFailed;
         flags |= RefFileCopyInfoFailed;
-        DBGLOG(e);
+        DBGLOG(e, "ReferencedFile ");
         e->Release();
         e->Release();
     }
     }
     catch (...)
     catch (...)
     {
     {
         flags |= RefFileCopyInfoFailed;
         flags |= RefFileCopyInfoFailed;
-        DBGLOG("Unknown error copying file info for [%s::] %s, from %s on dfs-dali %s", filePrefix.str(), logicalName.str(), fileSrcCluster.length() ? fileSrcCluster.get() : "*", daliip.str());
+        DBGLOG("ReferencedFile Unknown error copying file info for [%s::] %s, from %s on dfs-dali %s", filePrefix.str(), logicalName.str(), fileSrcCluster.length() ? fileSrcCluster.get() : "*", daliip.str());
     }
     }
 }
 }
 
 
@@ -489,13 +495,13 @@ void ReferencedFile::cloneSuperInfo(unsigned updateFlags, ReferencedFileList *li
     catch (IException *e)
     catch (IException *e)
     {
     {
         flags |= RefFileCopyInfoFailed;
         flags |= RefFileCopyInfoFailed;
-        DBGLOG(e);
+        DBGLOG(e, "ReferencedFile ");
         e->Release();
         e->Release();
     }
     }
     catch (...)
     catch (...)
     {
     {
         flags |= RefFileCopyInfoFailed;
         flags |= RefFileCopyInfoFailed;
-        DBGLOG("Unknown error copying superfile info for %s", logicalName.str());
+        DBGLOG("ReferencedFile Unknown error copying superfile info for %s", logicalName.str());
     }
     }
 }
 }
 
 
@@ -625,6 +631,8 @@ bool ReferencedFileList::addFilesFromQuery(IConstWorkUnit *cw, const IHpccPackag
             bool isOpt = false;
             bool isOpt = false;
             const char *logicalName = node.queryProp("att[@name='_fileName']/@value");
             const char *logicalName = node.queryProp("att[@name='_fileName']/@value");
             if (!logicalName)
             if (!logicalName)
+                logicalName = node.queryProp("att[@name='_indexFileName']/@value");
+            if (!logicalName)
                 continue;
                 continue;
 
 
             isOpt = node.getPropBool("att[@name='_isIndexOpt']/@value");
             isOpt = node.getPropBool("att[@name='_isIndexOpt']/@value");

+ 8 - 5
docs/ECLLanguageReference/ECLR-includer.xml

@@ -41,7 +41,7 @@
     <xi:include href="common/Version.xml" xpointer="DateVer"
     <xi:include href="common/Version.xml" xpointer="DateVer"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
 
 
-    <releaseinfo>© 2015 HPCC Systems<superscript>®</superscript>. All rights
+    <releaseinfo>© 2017 HPCC Systems<superscript>®</superscript>. All rights
     reserved. Except where otherwise noted, ECL Language Reference content
     reserved. Except where otherwise noted, ECL Language Reference content
     licensed under Creative Commons public license.</releaseinfo>
     licensed under Creative Commons public license.</releaseinfo>
 
 
@@ -549,8 +549,9 @@
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-FETCH.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-FETCH.xml"
                 xpointer="element(/1)"
                 xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
+
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-FROMJSON.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-FROMJSON.xml"
-		xpointer="element(/1)"
+                xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
 
 
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-FROMUNICODE.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-FROMUNICODE.xml"
@@ -724,6 +725,7 @@
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-ORDERED.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-ORDERED.xml"
                 xpointer="element(/1)"
                 xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
+
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-OUTPUT.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-OUTPUT.xml"
                 xpointer="element(/1)"
                 xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
@@ -887,8 +889,9 @@
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-THISNODE.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-THISNODE.xml"
                 xpointer="element(/1)"
                 xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
+
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-TOJSON.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-TOJSON.xml"
-		xpointer="element(/1)"
+                xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
 
 
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-TOPN.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-TOPN.xml"
@@ -922,6 +925,7 @@
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-UNICODEORDER.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-UNICODEORDER.xml"
                 xpointer="element(/1)"
                 xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
+
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-UNORDERED.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/BltInFunc-UNORDERED.xml"
                 xpointer="element(/1)"
                 xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
@@ -1101,12 +1105,11 @@
     <xi:include href="ECLLanguageReference/ECLR_mods/Templ-WARNING.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/Templ-WARNING.xml"
                 xpointer="element(/1)"
                 xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
- 
 
 
     <xi:include href="ECLLanguageReference/ECLR_mods/Templ-WEBSERVICE.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/Templ-WEBSERVICE.xml"
                 xpointer="element(/1)"
                 xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
- 
+
     <xi:include href="ECLLanguageReference/ECLR_mods/Templ-WORKUNIT.xml"
     <xi:include href="ECLLanguageReference/ECLR_mods/Templ-WORKUNIT.xml"
                 xpointer="element(/1)"
                 xpointer="element(/1)"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />
                 xmlns:xi="http://www.w3.org/2001/XInclude" />

+ 4 - 4
docs/common/Version.xml

@@ -5,11 +5,11 @@
   <chapterinfo>
   <chapterinfo>
     <date id="DateVer">DEVELOPER NON-GENERATED VERSION</date>
     <date id="DateVer">DEVELOPER NON-GENERATED VERSION</date>
 
 
-    <releaseinfo id="FooterInfo">© 2016 HPCC
+    <releaseinfo id="FooterInfo">© 2017 HPCC
     Systems<superscript>®</superscript>. All rights reserved</releaseinfo>
     Systems<superscript>®</superscript>. All rights reserved</releaseinfo>
 
 
     <copyright id="Copyright">
     <copyright id="Copyright">
-      <year>2016 HPCC Systems<superscript>®</superscript>. All rights
+      <year>2017 HPCC Systems<superscript>®</superscript>. All rights
       reserved</year>
       reserved</year>
     </copyright>
     </copyright>
   </chapterinfo>
   </chapterinfo>
@@ -24,7 +24,7 @@
     and that is to store the chapterinfo the above sections that are being
     and that is to store the chapterinfo the above sections that are being
     used by several other documents.</para>
     used by several other documents.</para>
 
 
-    <para id="CHMVer">2016 Version X.X</para>
+    <para id="CHMVer">2017 Version X.X</para>
 
 
     <para>The following line is the code to be put into the document you wish
     <para>The following line is the code to be put into the document you wish
     to include the above version info in:</para>
     to include the above version info in:</para>
@@ -40,6 +40,6 @@
     structure that we can use bookinfo/date and other elements for other
     structure that we can use bookinfo/date and other elements for other
     purposes.</para>
     purposes.</para>
 
 
-    <para>☺</para>
+    <para>☺ © Γ∏</para>
   </section>
   </section>
 </chapter>
 </chapter>

+ 4 - 4
docs/common/Version.xml.in

@@ -3,13 +3,13 @@
 "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 <chapter>
 <chapter>
   <chapterinfo>
   <chapterinfo>
-    <date id="DateVer">2016 Version ${DOC_VERSION}</date>
+    <date id="DateVer">2017 Version ${DOC_VERSION}</date>
 
 
-    <releaseinfo id="FooterInfo">© 2016 HPCC
+    <releaseinfo id="FooterInfo">© 2017 HPCC
     Systems<superscript>®</superscript>. All rights reserved</releaseinfo>
     Systems<superscript>®</superscript>. All rights reserved</releaseinfo>
 
 
     <copyright id="Copyright">
     <copyright id="Copyright">
-      <year>2016 HPCC Systems<superscript>®</superscript>. All rights
+      <year>2017 HPCC Systems<superscript>®</superscript>. All rights
       reserved</year>
       reserved</year>
     </copyright>
     </copyright>
   </chapterinfo>
   </chapterinfo>
@@ -24,7 +24,7 @@
     serve one purpose and that is to store the chapterinfo the above sections
     serve one purpose and that is to store the chapterinfo the above sections
     that are being used by several other documents.</para>
     that are being used by several other documents.</para>
 
 
-    <para id="CHMVer">2016 Version ${DOC_VERSION}</para>
+    <para id="CHMVer">2017 Version ${DOC_VERSION}</para>
 
 
     <para>The following line is the code to be put into the document you wish
     <para>The following line is the code to be put into the document you wish
     to include the above version info in:</para>
     to include the above version info in:</para>

+ 1 - 1
esp/logging/logginglib/logthread.hpp

@@ -47,7 +47,7 @@ class CLogThread : public Thread , implements IUpdateLogThread
 
 
     Owned<IEspLogAgent> logAgent;
     Owned<IEspLogAgent> logAgent;
     LOGServiceType services[MAXLOGSERVICES];
     LOGServiceType services[MAXLOGSERVICES];
-    SafeQueueOf<IInterface, false> logQueue;
+    QueueOf<IInterface, false> logQueue;
     CriticalSection logQueueCrit;
     CriticalSection logQueueCrit;
     Semaphore       m_sem;
     Semaphore       m_sem;
 
 

+ 10 - 1
initfiles/sbin/hpcc_setenv.in

@@ -102,7 +102,16 @@ IFS="${OIFS}"
 umask ${OUMASK}
 umask ${OUMASK}
 
 
 # use less heap when threaded
 # use less heap when threaded
-export MALLOC_ARENA_MAX=8
+# but if set too low it can affect performance significantly
+num_arenas=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
+if [ -z "$num_arenas" ] ; then
+    num_arenas = 8
+elif [ $num_arenas -lt 8 ] ; then
+    num_arenas = 8
+elif [ $num_arenas -gt 32 ] ; then
+    num_arenas = 32
+fi
+export MALLOC_ARENA_MAX=$num_arenas
 
 
 PATH_PREFIX=`cat ${HPCC_CONFIG} | sed -n "/\[${SECTION}\]/,/\[/p" | grep "^path *= *" | sed -e 's/^path *= *//'`
 PATH_PREFIX=`cat ${HPCC_CONFIG} | sed -n "/\[${SECTION}\]/,/\[/p" | grep "^path *= *" | sed -e 's/^path *= *//'`
 
 

+ 14 - 3
roxie/ccd/ccdprotocol.cpp

@@ -1372,7 +1372,7 @@ public:
         if (name.isEmpty())
         if (name.isEmpty())
         {
         {
             const char *fmt = mlFmt==MarkupFmt_XML ? "XML" : "JSON";
             const char *fmt = mlFmt==MarkupFmt_XML ? "XML" : "JSON";
-            IException *E = MakeStringException(-1, "ERROR: Invalid %s received from %s:%d - %s queryName not found", fmt, peer, port, msg);
+            IException *E = MakeStringException(-1, "ERROR: Invalid %s queryName not found - received from %s:%d - %s", fmt, peer, port, msg);
             logctx.logOperatorException(E, __FILE__, __LINE__, "Invalid query %s", fmt);
             logctx.logOperatorException(E, __FILE__, __LINE__, "Invalid query %s", fmt);
             throw E;
             throw E;
         }
         }
@@ -1435,8 +1435,16 @@ public:
     {
     {
         if (!name.isEmpty())
         if (!name.isEmpty())
             more = false;
             more = false;
-        else if (headerDepth && streq(tag, "Header"))
-            headerDepth--;
+        else if (headerDepth) //will never be true if !isSoap
+        {
+            const char *local = strchr(tag, ':');
+            if (local)
+                local++;
+            else
+                local = tag;
+            if (streq(local, "Header"))
+                headerDepth--;
+        }
     }
     }
 
 
 };
 };
@@ -1848,11 +1856,14 @@ readAnother:
                                 if (stricmp(format, "raw") == 0)
                                 if (stricmp(format, "raw") == 0)
                                 {
                                 {
                                     protocolFlags |= HPCC_PROTOCOL_NATIVE_RAW;
                                     protocolFlags |= HPCC_PROTOCOL_NATIVE_RAW;
+                                    if (client) //not stand alone roxie exe
+                                        protocolFlags |= HPCC_PROTOCOL_BLOCKED;
                                     mlResponseFmt = MarkupFmt_Unknown;
                                     mlResponseFmt = MarkupFmt_Unknown;
                                 }
                                 }
                                 else if (stricmp(format, "bxml") == 0)
                                 else if (stricmp(format, "bxml") == 0)
                                 {
                                 {
                                     protocolFlags |= HPCC_PROTOCOL_BLOCKED;
                                     protocolFlags |= HPCC_PROTOCOL_BLOCKED;
+                                    mlResponseFmt = MarkupFmt_XML;
                                 }
                                 }
                                 else if (stricmp(format, "ascii") == 0)
                                 else if (stricmp(format, "ascii") == 0)
                                 {
                                 {

+ 3 - 3
roxie/ccd/ccdserver.cpp

@@ -15986,7 +15986,7 @@ public:
                 if (inputUsed[i1])
                 if (inputUsed[i1])
                     inputAdaptors[i1]->setParentExtract(parentExtractSize, parentExtract);
                     inputAdaptors[i1]->setParentExtract(parentExtractSize, parentExtract);
                 else
                 else
-                    inputAdaptors[i1]->stop();
+                    inputAdaptors[i1]->queryInput()->stopall();
             }
             }
 
 
             for (unsigned i2 = 0; i2 < numOutputs; i2++)
             for (unsigned i2 = 0; i2 < numOutputs; i2++)
@@ -15998,7 +15998,7 @@ public:
             ForEachItemIn(i3, extra.unusedOutputs)
             ForEachItemIn(i3, extra.unusedOutputs)
             {
             {
                 Owned<IFinalRoxieInput> output = graph->selectOutput(numInputs+extra.unusedOutputs.item(i3));
                 Owned<IFinalRoxieInput> output = graph->selectOutput(numInputs+extra.unusedOutputs.item(i3));
-                // output->queryStream().stop(); Is this needed??
+                output->stopall();
             }
             }
         }
         }
     }
     }
@@ -16014,7 +16014,7 @@ public:
             ForEachItemIn(i3, extra.unusedOutputs)
             ForEachItemIn(i3, extra.unusedOutputs)
             {
             {
                 Owned<IFinalRoxieInput> output = graph->selectOutput(numInputs+extra.unusedOutputs.item(i3));
                 Owned<IFinalRoxieInput> output = graph->selectOutput(numInputs+extra.unusedOutputs.item(i3));
-                // Is this needed ?? output->queryStream().stop();
+                output->stopall();
             }
             }
             CRoxieServerActivity::stop();
             CRoxieServerActivity::stop();
         }
         }

+ 6 - 0
roxie/ccd/ccdserver.hpp

@@ -108,6 +108,12 @@ interface IFinalRoxieInput : extends IInputBase
     virtual IIndexReadActivityInfo *queryIndexReadActivity() = 0;
     virtual IIndexReadActivityInfo *queryIndexReadActivity() = 0;
 
 
     virtual IStrandJunction *getOutputStreams(IRoxieSlaveContext *ctx, unsigned idx, PointerArrayOf<IEngineRowStream> &streams, const StrandOptions * consumerOptions, bool consumerOrdered, IOrderedCallbackCollection * orderedCallbacks) = 0;  // Use StrandFlags values for flags
     virtual IStrandJunction *getOutputStreams(IRoxieSlaveContext *ctx, unsigned idx, PointerArrayOf<IEngineRowStream> &streams, const StrandOptions * consumerOptions, bool consumerOrdered, IOrderedCallbackCollection * orderedCallbacks) = 0;  // Use StrandFlags values for flags
+
+    inline void stopall()
+    {
+        for (int i = 0; i < numConcreteOutputs(); i++)
+            queryConcreteOutputStream(i)->stop();
+    }
 };
 };
 
 
 extern IEngineRowStream *connectSingleStream(IRoxieSlaveContext *ctx, IFinalRoxieInput *input, unsigned idx, Owned<IStrandJunction> &junction, bool consumerOrdered);
 extern IEngineRowStream *connectSingleStream(IRoxieSlaveContext *ctx, IFinalRoxieInput *input, unsigned idx, Owned<IStrandJunction> &junction, bool consumerOrdered);

+ 89 - 70
system/jlib/jdebug.cpp

@@ -1668,8 +1668,8 @@ class CExtendedStats  // Disk network and cpu stats
     unsigned ncpu;
     unsigned ncpu;
     bool first;
     bool first;
     char *kbuf;
     char *kbuf;
-    size32_t kbufsz;
     size32_t kbufmax;
     size32_t kbufmax;
+    int kbadcnt;
     unsigned short kbufcrc;
     unsigned short kbufcrc;
     __uint64 totalcpu;
     __uint64 totalcpu;
 
 
@@ -1858,70 +1858,80 @@ class CExtendedStats  // Disk network and cpu stats
         return true;
         return true;
     }
     }
 
 
-    size32_t  getKLog(const char *&data)
+    size32_t getKLog(const char *&data)
     {
     {
 #ifdef __linux__
 #ifdef __linux__
-        if (kbufmax) {
-            loop {
-                char *newkbuf = (char *)malloc(kbufmax);
-                if (!newkbuf)
-                    break;  // OOM - abort logging
-                size32_t newkbufsz = klogctl(3,newkbuf,kbufmax);
-                if ((int)newkbufsz<0) {
-                    ERRLOG("klogctl error %d",errno);
-                    free(newkbuf);
-                    data = NULL;
-                    return 0;
+        if (kbufmax)
+        {
+            data = nullptr;
+            size32_t ksz = 0;
+            unsigned short lastCRC = 0;
+            // NOTE: allocated 2*kbufmax to work around kernel bug
+            // where klogctl() could sometimes return more than requested
+            size32_t sz = klogctl(3, kbuf, kbufmax);
+            if ((int)sz < 0)
+            {
+                if (kbadcnt < 5)
+                {
+                    ERRLOG("klogctl SYSLOG_ACTION_READ_ALL error %d", errno);
+                    kbadcnt++;
                 }
                 }
-                if (newkbufsz<kbufmax) {
-                    unsigned short crc = chksum16(newkbuf,newkbufsz);
-                    if (kbuf) {
-                        if (crc!=kbufcrc) {
-                            unsigned ofs = 0;
-                            if ((newkbufsz>=kbufsz)) {
-                                for (unsigned i=0;i+3<kbufsz;i++) { // not very quick!
-                                    if (memcmp(kbuf+i,newkbuf,kbufsz-i)==0) {
-                                        ofs = kbufsz-i;
-                                        break;
-                                    }
-                                }
-                            }
-                            size32_t ret = newkbufsz-ofs;
-                            if (ret>3) {
-                                kbufcrc = crc;
-                                free(kbuf);
-                                kbuf = newkbuf;
-                                kbufsz = newkbufsz;
-                                data = kbuf+ofs;
-                                return ret;
-                            }
-                        }
+                else
+                    kbufmax = 0;
+                return 0;
+            }
+#if 0
+            kbuf[sz] = '\0';
+#endif
+            if (kbufcrc)
+            {
+                data = kbuf;
+                ksz = sz;
+            }
+            // determine where new info starts ...
+            StringBuffer ln;
+            const char *p = kbuf;
+            const char *e = p+sz;
+            while (p && p!=e)
+            {
+                if (*p=='<')
+                {
+                    ln.clear();
+                    while ((p && p!=e)&&(*p!='\n'))
+                    {
+                        ln.append(*p);
+                        p++;
+                        sz--;
                     }
                     }
-                    else  { // first time {
-                        kbuf = newkbuf;
-                        newkbuf = NULL;
-                        kbufsz = newkbufsz;
+                    lastCRC = chksum16(ln.str(), ln.length());
+                    if (kbufcrc && kbufcrc == lastCRC)
+                    {
+                        ksz = sz - 1;
+                        if (ksz && sz)
+                            data = p + 1;
+                        else
+                            data = nullptr;
                     }
                     }
-                    free(newkbuf);
-                    data = NULL;
-                    return 0;
                 }
                 }
-                if (kbufmax>0x100000) {
-                    // don't believe!
-                    ERRLOG("klogctl buffer too big!");
-                    free(newkbuf);
-                    break;
+                while ((p && p!=e)&&(*p!='\n'))
+                {
+                    p++;
+                    sz--;
+                }
+                if (p && p!=e)
+                {
+                    p++;
+                    sz--;
                 }
                 }
-                kbufmax += 0x1000;
-                free(newkbuf);
             }
             }
-            kbufmax = 0;
-            kbufsz = 0;
-            free(kbuf);
-            kbuf = NULL;
+            if (lastCRC)
+                kbufcrc = lastCRC;
+            if (!ksz)
+                data = nullptr;
+            return ksz;
         }
         }
 #endif
 #endif
-        data = NULL;
+        data = nullptr;
         return 0;
         return 0;
     }
     }
 
 
@@ -1956,8 +1966,7 @@ public:
         oldblkio = NULL;
         oldblkio = NULL;
         first = true;
         first = true;
         ncpu = 0;
         ncpu = 0;
-        kbuf = NULL;
-        kbufsz = 0;
+        kbuf = nullptr;
         kbufcrc = 0;
         kbufcrc = 0;
         memset(&oldcpu, 0, sizeof(oldcpu));
         memset(&oldcpu, 0, sizeof(oldcpu));
         memset(&newcpu, 0, sizeof(newcpu));
         memset(&newcpu, 0, sizeof(newcpu));
@@ -1967,8 +1976,14 @@ public:
         memset(&oldnet, 0, sizeof(oldnet));
         memset(&oldnet, 0, sizeof(oldnet));
         memset(&newnet, 0, sizeof(newnet));
         memset(&newnet, 0, sizeof(newnet));
         ndisks = 0;
         ndisks = 0;
+        kbadcnt = 0;
         if (printklog)
         if (printklog)
+        {
             kbufmax = 0x1000;
             kbufmax = 0x1000;
+            kbuf = (char *)malloc(kbufmax*2);
+            if (!kbuf)
+                kbufmax = 0;
+        }
         else
         else
             kbufmax = 0;
             kbufmax = 0;
     }
     }
@@ -1976,9 +1991,10 @@ public:
     ~CExtendedStats()
     ~CExtendedStats()
     {
     {
         free(partition);
         free(partition);
-        free(kbuf);
         free(newblkio);
         free(newblkio);
         free(oldblkio);
         free(oldblkio);
+        if (kbuf != nullptr)
+            free(kbuf);
     }
     }
 
 
     bool getLine(StringBuffer &out)
     bool getLine(StringBuffer &out)
@@ -2042,23 +2058,26 @@ public:
         return true;
         return true;
     }
     }
 
 
-#define KERN_EMERG  "<0>"   // system is unusable
-#define KERN_ALERT  "<1>"   // action must be taken immediately
-#define KERN_CRIT   "<2>"   // critical conditions
-#define KERN_ERR    "<3>"   // error conditions
+#define KERN_EMERG   "<0>"   // system is unusable
+#define KERN_ALERT   "<1>"   // action must be taken immediately
+#define KERN_CRIT    "<2>"   // critical conditions
+#define KERN_ERR     "<3>"   // error conditions
 #define KERN_WARNING "<4>"  // warning conditions
 #define KERN_WARNING "<4>"  // warning conditions
-#define KERN_NOTICE "<5>"   // normal but significant condition
-#define KERN_INFO   "<6>"   // informational
-#define KERN_DEBUG  "<7>"   // debug-level messages
+#define KERN_NOTICE  "<5>"   // normal but significant condition
+#define KERN_INFO    "<6>"   // informational
+#define KERN_DEBUG   "<7>"   // debug-level messages
 #define KMSGTEST(S) if (memcmp(p,S,3)==0) { ln.append(#S); level = p[1]-'0'; }
 #define KMSGTEST(S) if (memcmp(p,S,3)==0) { ln.append(#S); level = p[1]-'0'; }
 
 
     void printKLog(IPerfMonHook *hook)
     void printKLog(IPerfMonHook *hook)
     {
     {
-        const char *p;
+        const char *p = nullptr;
         size32_t sz = getKLog(p);
         size32_t sz = getKLog(p);
+#if 0
+        DBGLOG("getKLog() returns: %u <%s>", sz, p);
+#endif
         StringBuffer ln;
         StringBuffer ln;
         const char *e = p+sz;
         const char *e = p+sz;
-        while (p!=e) {
+        while (p && (p!=e)) {
             if (*p=='<') {
             if (*p=='<') {
                 ln.clear();
                 ln.clear();
                 int level = -1;
                 int level = -1;
@@ -2076,16 +2095,16 @@ public:
                 }
                 }
                 p += 3;
                 p += 3;
                 ln.append(": ");
                 ln.append(": ");
-                while ((p!=e)&&(*p!='\n'))
+                while ((p && p!=e)&&(*p!='\n'))
                     ln.append(*(p++));
                     ln.append(*(p++));
                 if (hook)
                 if (hook)
                     hook->log(level, ln.str());
                     hook->log(level, ln.str());
                 else
                 else
                     PROGLOG("%s",ln.str());
                     PROGLOG("%s",ln.str());
             }
             }
-            while ((p!=e)&&(*p!='\n'))
+            while ((p && p!=e)&&(*p!='\n'))
                 p++;
                 p++;
-            if (p!=e)
+            if (p && p!=e)
                 p++;
                 p++;
         }
         }
     }
     }

+ 2 - 1
system/security/shared/caching.cpp

@@ -367,8 +367,9 @@ bool CPermissionsCache::lookup(ISecUser& sec_user)
                     DBGLOG("CACHE: CPermissionsCache Found validated user %s", username);
                     DBGLOG("CACHE: CPermissionsCache Found validated user %s", username);
 #endif
 #endif
                     // Copy cached user to the sec_user structure, but still keep the original clear text password.
                     // Copy cached user to the sec_user structure, but still keep the original clear text password.
+                    StringAttr originalPW(pw);
                     user->queryUser()->copyTo(sec_user);
                     user->queryUser()->copyTo(sec_user);
-                    sec_user.credentials().setPassword(pw);
+                    sec_user.credentials().setPassword(originalPW.get());
                     return true;
                     return true;
                 }
                 }
                 else
                 else

+ 2 - 2
testing/regress/ecl/aaalibrary2.ecl

@@ -30,13 +30,13 @@ string10        forename;
 integer2        age := 25;
 integer2        age := 25;
             END;
             END;
 
 
-FilterDatasetInterface(dataset(namesRecord) ds, string search, boolean onlyOldies) := interface
+FilterDatasetInterface(dataset(namesRecord) ds, dataset(namesRecord) unused, string search, boolean onlyOldies) := interface
     export dataset(namesRecord) matches;
     export dataset(namesRecord) matches;
     export dataset(namesRecord) others;
     export dataset(namesRecord) others;
 end;
 end;
 
 
 
 
-filterDatasetLibrary(dataset(namesRecord) ds, string search, boolean onlyOldies) := module,library(FilterDatasetInterface)
+filterDatasetLibrary(dataset(namesRecord) ds, dataset(namesRecord) unused, string search, boolean onlyOldies) := module,library(FilterDatasetInterface)
     f := ds;
     f := ds;
     shared g := if (onlyOldies, f(age >= 65), f);
     shared g := if (onlyOldies, f(age >= 65), f);
     export matches := g(surname = search);
     export matches := g(surname = search);

+ 3 - 0
testing/regress/ecl/key/library1.xml

@@ -10,3 +10,6 @@
 <Dataset name='OldNotHalliday'>
 <Dataset name='OldNotHalliday'>
  <Row><surname>Smith               </surname><forename>George    </forename><age>75</age></Row>
  <Row><surname>Smith               </surname><forename>George    </forename><age>75</age></Row>
 </Dataset>
 </Dataset>
+<Dataset name='Result 4'>
+ <Row><surname>a                   </surname><forename>a         </forename><age>2</age></Row>
+</Dataset>

+ 6 - 3
testing/regress/ecl/library1.ecl

@@ -26,21 +26,22 @@ integer2        age := 25;
             END;
             END;
 
 
 
 
-FilterDatasetInterface(dataset(namesRecord) ds, string search, boolean onlyOldies) := interface
+FilterDatasetInterface(dataset(namesRecord) ds, dataset(namesRecord) unused, string search, boolean onlyOldies) := interface
     export dataset(namesRecord) matches;
     export dataset(namesRecord) matches;
     export dataset(namesRecord) others;
     export dataset(namesRecord) others;
 end;
 end;
 
 
 
 
-FilterDatasetLibrary(dataset(namesRecord) ds, string search, boolean onlyOldies) := module,library(FilterDatasetInterface)
+FilterDatasetLibrary(dataset(namesRecord) ds, dataset(namesRecord) unused, string search, boolean onlyOldies) := module,library(FilterDatasetInterface)
     f := ds;
     f := ds;
     shared g := if (onlyOldies, f(age >= 65), f);
     shared g := if (onlyOldies, f(age >= 65), f);
     export matches := g(surname = search);
     export matches := g(surname = search);
     export others := g(surname != search);
     export others := g(surname != search);
 end;
 end;
 
 
+empty := nofold(DATASET([{'a','a',2}], namesRecord));
 
 
-filterDataset(dataset(namesRecord) ds, string search, boolean onlyOldies) := library(internal(FilterDatasetLibrary), FilterDatasetInterface(ds, search, onlyOldies));
+filterDataset(dataset(namesRecord) ds, string search, boolean onlyOldies) := library(internal(FilterDatasetLibrary), FilterDatasetInterface(ds, empty, search, onlyOldies));
 
 
 
 
 namesTable := dataset([
 namesTable := dataset([
@@ -58,3 +59,5 @@ output(filtered2.others,,named('NotHalliday'));
 
 
 filtered3 := filterDataset(namesTable, 'Halliday', true);
 filtered3 := filterDataset(namesTable, 'Halliday', true);
 output(filtered3.others,,named('OldNotHalliday'));
 output(filtered3.others,,named('OldNotHalliday'));
+
+output(empty);

+ 3 - 2
testing/regress/ecl/library2.ecl

@@ -27,13 +27,14 @@ string10        forename;
 integer2        age := 25;
 integer2        age := 25;
             END;
             END;
 
 
-FilterDatasetInterface(dataset(namesRecord) ds, string search, boolean onlyOldies) := interface
+FilterDatasetInterface(dataset(namesRecord) ds, dataset(namesRecord) unused, string search, boolean onlyOldies) := interface
     export dataset(namesRecord) matches;
     export dataset(namesRecord) matches;
     export dataset(namesRecord) others;
     export dataset(namesRecord) others;
 end;
 end;
 
 
+empty := DATASET([], namesRecord);
 
 
-filterDataset(dataset(namesRecord) ds, string search, boolean onlyOldies) := library('aaaLibrary2',FilterDatasetInterface(ds,search,onlyOldies));
+filterDataset(dataset(namesRecord) ds, string search, boolean onlyOldies) := library('aaaLibrary2',FilterDatasetInterface(ds,empty,search,onlyOldies));
 
 
 namesTable := dataset([
 namesTable := dataset([
         {'Halliday','Gavin',31},
         {'Halliday','Gavin',31},

+ 4 - 2
testing/regress/ecl/library2a.ecl

@@ -27,7 +27,7 @@ string10        forename;
 integer2        age := 25;
 integer2        age := 25;
             END;
             END;
 
 
-FilterDatasetInterface(dataset(namesRecord) ds, string search, boolean onlyOldies) := interface
+FilterDatasetInterface(dataset(namesRecord) ds, dataset(namesRecord) unused, string search, boolean onlyOldies) := interface
     export dataset(namesRecord) matches;
     export dataset(namesRecord) matches;
     export dataset(namesRecord) others;
     export dataset(namesRecord) others;
 end;
 end;
@@ -35,7 +35,9 @@ end;
 
 
 boolean falseval := false: stored('yeahright');
 boolean falseval := false: stored('yeahright');
 
 
-filterDataset(dataset(namesRecord) ds, string search, boolean onlyOldies) := library('aaaLibrary2',FilterDatasetInterface(ds,search,onlyOldies));
+empty := DATASET([], namesRecord);
+
+filterDataset(dataset(namesRecord) ds, string search, boolean onlyOldies) := library('aaaLibrary2',FilterDatasetInterface(ds,empty,search,onlyOldies));
 
 
 namesTable := dataset([
 namesTable := dataset([
         {'Halliday','Gavin',31},
         {'Halliday','Gavin',31},