diff options
author | Michael Biebl <biebl@debian.org> | 2012-03-15 13:34:07 +0100 |
---|---|---|
committer | Michael Biebl <biebl@debian.org> | 2012-03-15 13:34:07 +0100 |
commit | 83f29a271e7794e7bb88a27757c735ec36901bed (patch) | |
tree | 153d2180a6dde24c2165321bba9ea6f9fc197fe7 | |
parent | 188aed7ed2ac38db70141139bdcab2d10ee5bcaf (diff) | |
parent | c1860fd74db97b8311e5d8f018ded8145fb0b0f5 (diff) | |
download | rsyslog-83f29a271e7794e7bb88a27757c735ec36901bed.tar.gz |
Merge tag 'upstream/5.8.9'
Upstream version 5.8.9
-rw-r--r-- | ChangeLog | 9 | ||||
-rwxr-xr-x | configure | 20 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | doc/manual.html | 2 | ||||
-rw-r--r-- | plugins/imuxsock/imuxsock.c | 5 | ||||
-rw-r--r-- | runtime/queue.c | 10 | ||||
-rw-r--r-- | runtime/queue.h | 2 | ||||
-rw-r--r-- | runtime/statsobj.c | 36 | ||||
-rw-r--r-- | runtime/statsobj.h | 55 | ||||
-rw-r--r-- | runtime/wti.c | 2 | ||||
-rw-r--r-- | runtime/wtp.c | 2 | ||||
-rw-r--r-- | tools/Makefile.am | 3 | ||||
-rw-r--r-- | tools/Makefile.in | 4 | ||||
-rw-r--r-- | tools/recover_qi.pl | 207 |
14 files changed, 306 insertions, 53 deletions
@@ -1,4 +1,13 @@ --------------------------------------------------------------------------- +Version 5.8.9 [V5-stable] 2012-03-15 +- added tool to recover disk queue if .qi file is missing (recover_qi.pl) + Thanks to Kaiwang Chen for contributing this tool +- bugfix: stopped DA queue was never processed after a restart due to a + regression from statistics module +- added better doc for statsobj interface + Thanks to Kaiwang Chen for his suggestions and analysis in regard to the + stats subsystem. +--------------------------------------------------------------------------- Version 5.8.8 [V5-stable] 2012-03-05 - bugfix: omprog made rsyslog abort on startup if not binary to execute was configured @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.66 for rsyslog 5.8.8. +# Generated by GNU Autoconf 2.66 for rsyslog 5.8.9. # # Report bugs to <rsyslog@lists.adiscon.com>. # @@ -562,8 +562,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='rsyslog' PACKAGE_TARNAME='rsyslog' -PACKAGE_VERSION='5.8.8' -PACKAGE_STRING='rsyslog 5.8.8' +PACKAGE_VERSION='5.8.9' +PACKAGE_STRING='rsyslog 5.8.9' PACKAGE_BUGREPORT='rsyslog@lists.adiscon.com' PACKAGE_URL='' @@ -1475,7 +1475,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures rsyslog 5.8.8 to adapt to many kinds of systems. +\`configure' configures rsyslog 5.8.9 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1545,7 +1545,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of rsyslog 5.8.8:";; + short | recursive ) echo "Configuration of rsyslog 5.8.9:";; esac cat <<\_ACEOF @@ -1720,7 +1720,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -rsyslog configure 5.8.8 +rsyslog configure 5.8.9 generated by GNU Autoconf 2.66 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2299,7 +2299,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by rsyslog $as_me 5.8.8, which was +It was created by rsyslog $as_me 5.8.9, which was generated by GNU Autoconf 2.66. Invocation command line was $ $0 $@ @@ -3114,7 +3114,7 @@ fi # Define the identity of the package. PACKAGE='rsyslog' - VERSION='5.8.8' + VERSION='5.8.9' cat >>confdefs.h <<_ACEOF @@ -17336,7 +17336,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by rsyslog $as_me 5.8.8, which was +This file was extended by rsyslog $as_me 5.8.9, which was generated by GNU Autoconf 2.66. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17402,7 +17402,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -rsyslog config.status 5.8.8 +rsyslog config.status 5.8.9 configured by $0, generated by GNU Autoconf 2.66, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 3cb623d..1f72bcc 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.8.8],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.8.9],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff --git a/doc/manual.html b/doc/manual.html index 54a04f8..690143d 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -19,7 +19,7 @@ rsyslog support</a> available directly from the source!</p> <p><b>Please visit the <a href="http://www.rsyslog.com/sponsors">rsyslog sponsor's page</a> to honor the project sponsors or become one yourself!</b> We are very grateful for any help towards the project goals.</p> -<p><b>This documentation is for version 5.8.8 (v5-stable branch) of rsyslog.</b> +<p><b>This documentation is for version 5.8.9 (v5-stable branch) of rsyslog.</b> Visit the <i><a href="http://www.rsyslog.com/status">rsyslog status page</a></i></b> to obtain current version information and project status. </p><p><b>If you like rsyslog, you might diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index 4523798..5867f1c 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -784,7 +784,7 @@ CODESTARTwillRun else if(sd_booted()) { struct stat st; if(stat(SYSTEMD_JOURNAL, &st) != -1 && S_ISDIR(st.st_mode)) { - listeners[0].sockName = SYSTEMD_PATH_LOG; + listeners[0].sockName = (uchar*) SYSTEMD_PATH_LOG; } } if(ratelimitIntervalSysSock > 0) { @@ -1010,10 +1010,13 @@ CODEmodInit_QueryRegCFSLineHdlr /* support statistics gathering */ CHKiRet(statsobj.Construct(&modStats)); CHKiRet(statsobj.SetName(modStats, UCHAR_CONSTANT("imuxsock"))); + STATSCOUNTER_INIT(ctrSubmit, mutCtrSubmit); CHKiRet(statsobj.AddCounter(modStats, UCHAR_CONSTANT("submitted"), ctrType_IntCtr, &ctrSubmit)); + STATSCOUNTER_INIT(ctrLostRatelimit, mutCtrLostRatelimit); CHKiRet(statsobj.AddCounter(modStats, UCHAR_CONSTANT("ratelimit.discarded"), ctrType_IntCtr, &ctrLostRatelimit)); + STATSCOUNTER_INIT(ctrNumRatelimiters, mutCtrNumRatelimiters); CHKiRet(statsobj.AddCounter(modStats, UCHAR_CONSTANT("ratelimit.numratelimiters"), ctrType_IntCtr, &ctrNumRatelimiters)); CHKiRet(statsobj.ConstructFinalize(modStats)); diff --git a/runtime/queue.c b/runtime/queue.c index 9012abe..621a4ee 100644 --- a/runtime/queue.c +++ b/runtime/queue.c @@ -1787,7 +1787,8 @@ qqueueChkStopWrkrDA(qqueue_t *pThis) { DEFiRet; -//DBGPRINTF("XXXX: chkStopWrkrDA called, low watermark %d, phys Size %d\n", pThis->iLowWtrMrk, getPhysicalQueueSize(pThis)); + /*DBGPRINTF("XXXX: chkStopWrkrDA called, low watermark %d, log Size %d, phys Size %d, bEnqOnly %d\n", + pThis->iLowWtrMrk, getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis), pThis->bEnqOnly);*/ if(pThis->bEnqOnly) { iRet = RS_RET_TERMINATE_WHEN_IDLE; } @@ -1808,6 +1809,8 @@ static rsRetVal ChkStopWrkrReg(qqueue_t *pThis) { DEFiRet; + /*DBGPRINTF("XXXX: chkStopWrkrReg called, low watermark %d, log Size %d, phys Size %d, bEnqOnly %d\n", + pThis->iLowWtrMrk, getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis), pThis->bEnqOnly);*/ if(pThis->bEnqOnly) { iRet = RS_RET_TERMINATE_NOW; } else if(pThis->pqParent != NULL) { @@ -1844,6 +1847,7 @@ qqueueStart(qqueue_t *pThis) /* this is the ConstructionFinalizer */ int wrk; uchar *qName; size_t lenBuf; + int iQueueSizeSave; ASSERT(pThis != NULL); @@ -1925,6 +1929,8 @@ qqueueStart(qqueue_t *pThis) /* this is the ConstructionFinalizer */ qName = obj.GetName((obj_t*)pThis); CHKiRet(statsobj.Construct(&pThis->statsobj)); CHKiRet(statsobj.SetName(pThis->statsobj, qName)); + /* we need to save the queue size, as the stats module initializes it to 0! */ + /* iQueueSize is a dual-use counter: no init, no mutex! */ CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("size"), ctrType_Int, &pThis->iQueueSize)); @@ -1936,7 +1942,7 @@ qqueueStart(qqueue_t *pThis) /* this is the ConstructionFinalizer */ CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("full"), ctrType_IntCtr, &pThis->ctrFull)); - pThis->ctrMaxqsize = 0; + pThis->ctrMaxqsize = 0; /* no mutex needed, thus no init call */ CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("maxqsize"), ctrType_Int, &pThis->ctrMaxqsize)); diff --git a/runtime/queue.h b/runtime/queue.h index 9705718..7ef5673 100644 --- a/runtime/queue.h +++ b/runtime/queue.h @@ -169,7 +169,7 @@ struct queue_s { statsobj_t *statsobj; STATSCOUNTER_DEF(ctrEnqueued, mutCtrEnqueued); STATSCOUNTER_DEF(ctrFull, mutCtrFull); - int ctrMaxqsize; + int ctrMaxqsize; /* NOT guarded by a mutex */ }; diff --git a/runtime/statsobj.c b/runtime/statsobj.c index 131605e..367ddb1 100644 --- a/runtime/statsobj.c +++ b/runtime/statsobj.c @@ -3,25 +3,23 @@ * This object provides a statistics-gathering facility inside rsyslog. This * functionality will be pragmatically implemented and extended. * - * Copyright 2010 Rainer Gerhards and Adiscon GmbH. + * Copyright 2010-2012 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * - * The rsyslog runtime library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The rsyslog runtime library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the rsyslog runtime library. If not, see <http://www.gnu.org/licenses/>. - * - * A copy of the GPL can be found in the file "COPYING" in this distribution. - * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #include "config.h" @@ -139,6 +137,10 @@ finalize_it: /* add a counter to an object * ctrName is duplicated, caller must free it if requried + * NOTE: The counter is READ-ONLY and MUST NOT be modified (most + * importantly, it must not be initialized, so the caller must + * ensure the counter is properly initialized before AddCounter() + * is called. */ static rsRetVal addCounter(statsobj_t *pThis, uchar *ctrName, statsCtrType_t ctrType, void *pCtr) @@ -154,11 +156,9 @@ addCounter(statsobj_t *pThis, uchar *ctrName, statsCtrType_t ctrType, void *pCtr switch(ctrType) { case ctrType_IntCtr: ctr->val.pIntCtr = (intctr_t*) pCtr; - *(ctr->val.pIntCtr) = 0; break; case ctrType_Int: ctr->val.pInt = (int*) pCtr; - *(ctr->val.pInt) = 0; break; } addCtrToList(pThis, ctr); diff --git a/runtime/statsobj.h b/runtime/statsobj.h index 44c26be..9027988 100644 --- a/runtime/statsobj.h +++ b/runtime/statsobj.h @@ -1,24 +1,22 @@ /* The statsobj object. * - * Copyright 2010 Rainer Gerhards and Adiscon GmbH. + * Copyright 2010-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * - * The rsyslog runtime library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The rsyslog runtime library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the rsyslog runtime library. If not, see <http://www.gnu.org/licenses/>. - * - * A copy of the GPL can be found in the file "COPYING" in this distribution. - * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #ifndef INCLUDED_STATSOBJ_H #define INCLUDED_STATSOBJ_H @@ -96,6 +94,31 @@ PROTOTYPEObj(statsobj); * Unfortunately, this does not work if counter is e.g. "pThis->ctr". * So we decided, for clarity, to always insist on specifying the mutex * name (after all, it's just a few more keystrokes...). + * -------------------------------------------------------------------- + * NOTE WELL + * -------------------------------------------------------------------- + * There are actually two types of stats counters: "regular" counters, + * which are only used for stats purposes and "dual" counters, which + * are primarily used for other purposes but can be included in stats + * as well. ALL regular counters MUST be initialized with + * STATSCOUNTER_INIT and only be modified by STATSCOUNTER_* functions. + * They MUST NOT be used for any other purpose (if this seems to make + * sense, consider changing it to a dual counter). + * Dual counters are somewhat dangerous in that a single variable is + * used for two purposes: the actual application need and stats + * counting. However, this is supported for performance reasons, as it + * provides insight into the inner engine workings without need for + * additional counters (and their maintenance code). Dual counters + * MUST NOT be modified by STATSCOUNTER_* functions. Most importantly, + * it is expected that the actua application code provides proper + * (enough) synchronized access to these counters. Most importantly, + * this means they have NO stats-system mutex associated to them. + * + * The interface function AddCounter() is a read-only function. It + * only provides the stats subsystem with a reference to a counter. + * It is irrelevant if the counter is a regular or dual one. For that + * reason, AddCounter() must not modify the counter contents, as in + * the case of a dual counter application code may be broken. */ #define STATSCOUNTER_DEF(ctr, mut) \ intctr_t ctr; \ diff --git a/runtime/wti.c b/runtime/wti.c index 0b85c36..69da2e9 100644 --- a/runtime/wti.c +++ b/runtime/wti.c @@ -315,6 +315,8 @@ wtiWorker(wti_t *pThis) if(localRet == RS_RET_IDLE) { if(terminateRet == RS_RET_TERMINATE_WHEN_IDLE || bInactivityTOOccured) { d_pthread_mutex_unlock(pWtp->pmutUsr); + dbgoprint((obj_t*) pThis, "terminating worker terminateRet=%d, bInactivityTOOccured=%d\n", + terminateRet, bInactivityTOOccured); break; /* end of loop */ } doIdleProcessing(pThis, pWtp, &bInactivityTOOccured); diff --git a/runtime/wtp.c b/runtime/wtp.c index e615fb1..a53a988 100644 --- a/runtime/wtp.c +++ b/runtime/wtp.c @@ -309,7 +309,7 @@ wtpWrkrExecCleanup(wti_t *pWti) wtiSetState(pWti, WRKTHRD_STOPPED); ATOMIC_DEC(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd); - DBGPRINTF("%s: Worker thread %lx, terminated, um workers now %d\n", + DBGPRINTF("%s: Worker thread %lx, terminated, num workers now %d\n", wtpGetDbgHdr(pThis), (unsigned long) pWti, ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd)); diff --git a/tools/Makefile.am b/tools/Makefile.am index 96657ad..962ae50 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -47,4 +47,5 @@ zpipe_LDADD = -lz msggen_SOURCES = msggen.c endif -EXTRA_DIST = $(man_MANS) +EXTRA_DIST = $(man_MANS) \ + recover_qi.pl diff --git a/tools/Makefile.in b/tools/Makefile.in index b4532e4..5faadd4 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -336,7 +336,9 @@ rsyslogd_LDFLAGS = -export-dynamic @ENABLE_DIAGTOOLS_TRUE@zpipe_SOURCES = zpipe.c @ENABLE_DIAGTOOLS_TRUE@zpipe_LDADD = -lz @ENABLE_DIAGTOOLS_TRUE@msggen_SOURCES = msggen.c -EXTRA_DIST = $(man_MANS) +EXTRA_DIST = $(man_MANS) \ + recover_qi.pl + all: all-am .SUFFIXES: diff --git a/tools/recover_qi.pl b/tools/recover_qi.pl new file mode 100644 index 0000000..4e2cf9d --- /dev/null +++ b/tools/recover_qi.pl @@ -0,0 +1,207 @@ +#!/usr/bin/perl -w
+# recover rsyslog disk queue index (.qi) from queue files (.nnnnnnnn).
+#
+# See:
+# runtime/queue.c: qqueuePersist()
+# runtime/queue.c: qqueueTryLoadPersistedInfo()
+#
+# kaiwang.chen@gmail.com 2012-03-14
+#
+use strict;
+use Getopt::Long;
+
+my %opt = ();
+GetOptions(\%opt,"spool|w=s","basename|f=s","digits|d=i","help!");
+if ($opt{help}) {
+ print "Usage:
+\t$0 -w WorkDirectory -f QueueFileName -d 8 > QueueFileName.qi
+";
+ exit;
+}
+
+# runtime/queue.c: qConstructDisk()
+my $iMaxFiles = 10000000; # 0+"1".( "0"x($opt{digits} - 1));
+
+# get the list of queue files, spool directory excluded
+my $re = qr/^\Q$opt{basename}\E\.\d{$opt{digits}}$/;
+opendir(DIR, $opt{spool}) or die "can’t open spool: $!";
+my @qf = grep { /$re/ && -f "$opt{spool}/$_" } readdir(DIR);
+closedir DIR;
+
+# ensure order and continuity
+@qf = sort @qf;
+my ($head) = ($qf[0] =~ /(\d+)$/);
+my ($tail) = ($qf[-1] =~ /(\d+)$/);
+$head += 0;
+$tail += 0;
+if ($tail-$head+1 != @qf || $tail > $iMaxFiles) {
+ die "broken queue: missing file(s) or wrong tail\n";
+}
+
+# collect some counters about the queue, assuming all are unprocessed entries.
+my $sizeOnDisk = 0;
+my $iQueueSize = 0;
+chdir($opt{spool}) or die "can't chdir to spool: $!";
+print STDERR "traversing ". @qf ." files, please wait...\n";
+for (@qf) {
+ open FH, "<", $_ or die "can't read queue file $_\n";
+ $sizeOnDisk += (stat FH)[7];
+ while (<FH>) {
+ $iQueueSize++ if /^<Obj/; # runtime/msg.c: MsgSerialize()
+ }
+ close FH;
+}
+# happen to reuse last stat
+my $iCurrOffs_Write = (stat(_))[7];
+
+# runtime/queue.c: qqueuePersist()
+my $qqueue = Rsyslog::OPB->new("qqueue",1);
+$qqueue->property("iQueueSize", "INT", $iQueueSize);
+$qqueue->property("tVars.disk.sizeOnDisk", "INT64", $sizeOnDisk);
+$qqueue->property("tVars.disk.bytesRead", "INT64", 0);
+
+# runtime/stream.h: strmType_t
+my $STREAMTYPE_FILE_CIRCULAR = 1;
+# runtime/stream.h: strmMode_t
+my $STREAMMODE_READ = 1;
+my $STREAMMODE_WRITE_APPEND = 4;
+
+# runtime/stream.c: strmSerialize()
+# write to end
+my $strm_Write = Rsyslog::Obj->new("strm",1);
+$strm_Write->property( "iCurrFNum", "INT", $tail);
+$strm_Write->property( "pszFName", "PSZ", $opt{basename});
+$strm_Write->property( "iMaxFiles", "INT", $iMaxFiles);
+$strm_Write->property( "bDeleteOnClose", "INT", 0);
+$strm_Write->property( "sType", "INT", $STREAMTYPE_FILE_CIRCULAR);
+$strm_Write->property("tOperationsMode", "INT", $STREAMMODE_WRITE_APPEND);
+$strm_Write->property( "tOpenMode", "INT", 0600);
+$strm_Write->property( "iCurrOffs","INT64", $iCurrOffs_Write);
+# read from head
+my $strm_ReadDel = Rsyslog::Obj->new("strm",1);
+$strm_ReadDel->property( "iCurrFNum", "INT", $head);
+$strm_ReadDel->property( "pszFName", "PSZ", $opt{basename});
+$strm_ReadDel->property( "iMaxFiles", "INT", $iMaxFiles);
+$strm_ReadDel->property( "bDeleteOnClose", "INT", 1);
+$strm_ReadDel->property( "sType", "INT", $STREAMTYPE_FILE_CIRCULAR);
+$strm_ReadDel->property("tOperationsMode", "INT", $STREAMMODE_READ);
+$strm_ReadDel->property( "tOpenMode", "INT", 0600);
+$strm_ReadDel->property( "iCurrOffs","INT64", 0);
+
+# .qi
+print $qqueue->serialize();
+print $strm_Write->serialize();
+print $strm_ReadDel->serialize();
+
+exit;
+#-----------------------------------------------------------------------------
+
+package Rsyslog::Serializable;
+# runtime/obj.c
+sub COOKIE_OBJLINE { '<' }
+sub COOKIE_PROPLINE { '+' }
+sub COOKIE_ENDLINE { '>' }
+sub COOKIE_BLANKLINE { '.' }
+# VARTYPE(short_ptype)
+sub VARTYPE {
+ my ($t) = @_;
+ # runtime/obj-types.h: propType_t
+ my $ptype = "PROPTYPE_".$t;
+ # runtime/var.h: varType_t
+ my %vm = (
+ VARTYPE_NONE => 0,
+ VARTYPE_STR => 1,
+ VARTYPE_NUMBER => 2,
+ VARTYPE_SYSLOGTIME => 3,
+ );
+ # runtime/obj.c: SerializeProp()
+ my %p2v = (
+ #PROPTYPE_NONE => "",
+ PROPTYPE_PSZ => "VARTYPE_STR",
+ PROPTYPE_SHORT => "VARTYPE_NUMBER",
+ PROPTYPE_INT => "VARTYPE_NUMBER",
+ PROPTYPE_LONG => "VARTYPE_NUMBER",
+ PROPTYPE_INT64 => "VARTYPE_NUMBER",
+ PROPTYPE_CSTR => "VARTYPE_STR",
+ #PROPTYPE_SYSLOGTIME => "VARTYPE_SYSLOGTIME",
+ );
+ my $vtype = $p2v{$ptype};
+ unless ($vtype) {
+ die "property type $t is not supported!\n";
+ }
+ return $vm{$vtype};
+}
+sub serialize {
+ my $self = shift;
+ # runtime/obj.c: objSerializeHeader()
+ my $x = COOKIE_OBJLINE();
+ $x .= join(":", $self->type(), $self->cver(), $self->id(), $self->version());
+ $x .= ":\n";
+ for ( values %{$self->{props}} ) {
+ # runtime/obj.c: SerializeProp()
+ $x .= COOKIE_PROPLINE();
+ $x .= join(":",
+ $_->{name},
+ VARTYPE($_->{type}),
+ length($_->{value}),
+ $_->{value});
+ $x .= ":\n";
+ }
+ # runtime/obj.c: EndSerialize()
+ $x .= COOKIE_ENDLINE() . "End\n";
+ $x .= COOKIE_BLANKLINE() . "\n";
+}
+# constructor: new(id,version)
+sub new {
+ my ($class, $id, $version) = @_;
+ $class = ref $class if ref $class;
+ bless {
+ id => $id,
+ version => $version,
+ props => {},
+ }, $class;
+}
+sub id {
+ my $self = shift;
+ if (@_) {
+ my $x = $self->{id};
+ $self->{id} = shift;
+ return $x;
+ }
+ return $self->{id};
+}
+sub version {
+ my $self = shift;
+ if (@_) {
+ my $x = $self->{version};
+ $self->{version} = shift;
+ return $x;
+ }
+ return $self->{version};
+}
+# property(name, type, value)
+sub property {
+ my $self = shift;
+ my $name = shift;
+ if (@_) {
+ my $x = $self->{props}{$name};
+ $self->{props}{$name}{name} = $name;
+ $self->{props}{$name}{type} = shift;
+ $self->{props}{$name}{value} = shift;
+ return $x;
+ }
+ return $self->{props}{$name};
+}
+1;
+package Rsyslog::OPB;
+use base qw(Rsyslog::Serializable);
+sub type { 'OPB' }
+sub cver { 1 }
+sub new { shift->SUPER::new(@_) }
+1;
+package Rsyslog::Obj;
+use base qw(Rsyslog::Serializable);
+sub type { 'Obj' }
+sub cver { 1 }
+sub new { shift->SUPER::new(@_) }
+1;
|