LCOV - code coverage report
Current view: top level - drivers - tapdisk-syslog.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 189 0.0 %
Date: 2025-01-09 17:56:42 Functions: 0 25 0.0 %
Branches: 0 82 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2016, Citrix Systems, Inc.
       3                 :            :  *
       4                 :            :  * All rights reserved.
       5                 :            :  *
       6                 :            :  * Redistribution and use in source and binary forms, with or without
       7                 :            :  * modification, are permitted provided that the following conditions are met:
       8                 :            :  * 
       9                 :            :  *  1. Redistributions of source code must retain the above copyright
      10                 :            :  *     notice, this list of conditions and the following disclaimer.
      11                 :            :  *  2. Redistributions in binary form must reproduce the above copyright
      12                 :            :  *     notice, this list of conditions and the following disclaimer in the
      13                 :            :  *     documentation and/or other materials provided with the distribution.
      14                 :            :  *  3. Neither the name of the copyright holder nor the names of its 
      15                 :            :  *     contributors may be used to endorse or promote products derived from 
      16                 :            :  *     this software without specific prior written permission.
      17                 :            :  *
      18                 :            :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      19                 :            :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      20                 :            :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      21                 :            :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
      22                 :            :  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      23                 :            :  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      24                 :            :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
      25                 :            :  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
      26                 :            :  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      27                 :            :  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      28                 :            :  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      29                 :            :  */
      30                 :            : 
      31                 :            : /*
      32                 :            :  * A non-blocking, buffered BSD syslog client.
      33                 :            :  *
      34                 :            :  * http://www.ietf.org/rfc/rfc3164.txt (FIXME: Read this.)
      35                 :            :  */
      36                 :            : 
      37                 :            : #ifdef HAVE_CONFIG_H
      38                 :            : #include "config.h"
      39                 :            : #endif
      40                 :            : 
      41                 :            : #define _ISOC99_SOURCE
      42                 :            : #include <stdlib.h>
      43                 :            : #include <stdio.h>
      44                 :            : #include <errno.h>
      45                 :            : #include <unistd.h>
      46                 :            : #include <time.h>
      47                 :            : #include <fcntl.h>
      48                 :            : #include <stdarg.h>
      49                 :            : #include <sys/mman.h>
      50                 :            : #include <sys/socket.h>
      51                 :            : #include <sys/un.h>
      52                 :            : 
      53                 :            : #include "tapdisk-server.h"
      54                 :            : #include "tapdisk-syslog.h"
      55                 :            : #include "tapdisk-utils.h"
      56                 :            : #include "timeout-math.h"
      57                 :            : 
      58                 :            : #define MIN(a,b) (((a) < (b)) ? (a) : (b))
      59                 :            : 
      60                 :            : static int tapdisk_syslog_sock_send(td_syslog_t *log,
      61                 :            :                                     const void *msg, size_t size);
      62                 :            : static int tapdisk_syslog_sock_connect(td_syslog_t *log);
      63                 :            : 
      64                 :            : static void tapdisk_syslog_sock_mask(td_syslog_t *log);
      65                 :            : static void tapdisk_syslog_sock_unmask(td_syslog_t *log);
      66                 :            : 
      67                 :            : static const struct sockaddr_un syslog_addr = {
      68                 :            :         .sun_family = AF_UNIX,
      69                 :            :         .sun_path   = "/dev/log"
      70                 :            : };
      71                 :            : 
      72                 :            : #define RING_PTR(_log, _idx)                                            \
      73                 :            :         (&(_log)->ring[(_idx) % (_log)->ringsz])
      74                 :            : 
      75                 :            : #define RING_FREE(_log)                                                 \
      76                 :            :         ((_log)->ringsz - ((_log)->prod - (_log)->cons))
      77                 :            : 
      78                 :            : /*
      79                 :            :  * NB. Ring buffer.
      80                 :            :  *
      81                 :            :  * We allocate a number of pages as indicated by @bufsz during
      82                 :            :  * initialization. From that, 1K is reserved for message staging, the
      83                 :            :  * rest is cyclic ring space.
      84                 :            :  *
      85                 :            :  * All producer/consumer offsets wrap on size_t range, not buffer
      86                 :            :  * size. Hence the RING() macros.
      87                 :            :  */
      88                 :            : 
      89                 :            : static void
      90                 :            : __tapdisk_syslog_ring_init(td_syslog_t *log)
      91                 :            : {
      92                 :          0 :         log->buf     = NULL;
      93                 :          0 :         log->bufsz   = 0;
      94                 :          0 :         log->msg     = NULL;
      95                 :          0 :         log->ring    = NULL;
      96                 :          0 :         log->ringsz  = 0;
      97                 :            : }
      98                 :            : 
      99                 :            : static inline size_t
     100                 :            : page_align(size_t size)
     101                 :            : {
     102                 :          0 :         size_t page_size = sysconf(_SC_PAGE_SIZE);
     103                 :          0 :         return (size + page_size - 1) & ~(page_size - 1);
     104                 :            : }
     105                 :            : 
     106                 :            : static void
     107                 :          0 : tapdisk_syslog_ring_uninit(td_syslog_t *log)
     108                 :            : {
     109         [ #  # ]:          0 :         if (log->buf)
     110                 :          0 :                 munmap(log->buf, log->bufsz);
     111                 :            : 
     112                 :            :         __tapdisk_syslog_ring_init(log);
     113                 :          0 : }
     114                 :            : 
     115                 :            : static int
     116                 :          0 : tapdisk_syslog_ring_init(td_syslog_t *log, size_t size)
     117                 :            : {
     118                 :            :         int prot, flags, err;
     119                 :            : 
     120                 :            :         __tapdisk_syslog_ring_init(log);
     121                 :            : 
     122                 :          0 :         log->bufsz = page_align(size);
     123                 :            : 
     124                 :          0 :         prot  = PROT_READ|PROT_WRITE;
     125                 :          0 :         flags = MAP_ANONYMOUS|MAP_PRIVATE;
     126                 :            : 
     127                 :          0 :         log->buf = mmap(NULL, log->bufsz, prot, flags, -1, 0);
     128         [ #  # ]:          0 :         if (log->buf == MAP_FAILED) {
     129                 :          0 :                 log->buf = NULL;
     130                 :          0 :                 err = -ENOMEM;
     131                 :          0 :                 goto fail;
     132                 :            :         }
     133                 :            : 
     134                 :          0 :         err = mlock(log->buf, size);
     135         [ #  # ]:          0 :         if (err) {
     136                 :          0 :                 err = -errno;
     137                 :          0 :                 goto fail;
     138                 :            :         }
     139                 :            : 
     140                 :          0 :         log->msg    = log->buf;
     141                 :          0 :         log->ring   = log->buf + TD_SYSLOG_PACKET_MAX;
     142                 :          0 :         log->ringsz = size     - TD_SYSLOG_PACKET_MAX;
     143                 :            : 
     144                 :          0 :         return 0;
     145                 :            : 
     146                 :            : fail:
     147                 :          0 :         tapdisk_syslog_ring_uninit(log);
     148                 :            : 
     149                 :          0 :         return err;
     150                 :            : }
     151                 :            : 
     152                 :            : static int
     153                 :          0 : tapdisk_syslog_ring_write_str(td_syslog_t *log, const char *msg, size_t len)
     154                 :            : {
     155                 :            :         size_t size, prod, i;
     156                 :            : 
     157                 :          0 :         len  = MIN(len, TD_SYSLOG_PACKET_MAX);
     158                 :          0 :         size = len + 1;
     159                 :            : 
     160         [ #  # ]:          0 :         if (size > RING_FREE(log))
     161                 :            :                 return -ENOBUFS;
     162                 :            : 
     163                 :            :         prod = log->prod;
     164                 :            : 
     165         [ #  # ]:          0 :         for (i = 0; i < len; ++i) {
     166                 :            :                 char c;
     167                 :            : 
     168                 :          0 :                 c = msg[i];
     169         [ #  # ]:          0 :                 if (c == 0)
     170                 :            :                         break;
     171                 :            : 
     172                 :          0 :                 *RING_PTR(log, prod) = c;
     173                 :          0 :                 prod++;
     174                 :            :         }
     175                 :            : 
     176                 :          0 :         *RING_PTR(log, prod) = 0;
     177                 :            : 
     178                 :          0 :         log->prod = prod + 1;
     179                 :            : 
     180                 :          0 :         return 0;
     181                 :            : }
     182                 :            : 
     183                 :            : static ssize_t
     184                 :          0 : tapdisk_syslog_ring_read_pkt(td_syslog_t *log, char *msg, size_t size)
     185                 :            : {
     186                 :            :         size_t cons;
     187                 :            :         ssize_t sz;
     188                 :            : 
     189                 :          0 :         size = MIN(size, TD_SYSLOG_PACKET_MAX);
     190                 :            : 
     191                 :          0 :         sz   = 0;
     192                 :          0 :         cons = log->cons;
     193                 :            : 
     194         [ #  # ]:          0 :         while (sz < size) {
     195                 :            :                 char c;
     196                 :            : 
     197         [ #  # ]:          0 :                 if (cons == log->prod)
     198                 :            :                         break;
     199                 :            : 
     200                 :          0 :                 c = *RING_PTR(log, cons);
     201                 :          0 :                 msg[sz++] = c;
     202                 :          0 :                 cons++;
     203                 :            : 
     204         [ #  # ]:          0 :                 if (c == 0)
     205                 :            :                         break;
     206                 :            :         }
     207                 :            : 
     208                 :          0 :         return sz - 1;
     209                 :            : }
     210                 :            : 
     211                 :            : static int
     212                 :          0 : tapdisk_syslog_ring_dispatch_one(td_syslog_t *log)
     213                 :            : {
     214                 :            :         size_t len;
     215                 :            :         int err;
     216                 :            : 
     217                 :          0 :         len = tapdisk_syslog_ring_read_pkt(log, log->msg,
     218                 :            :                                            TD_SYSLOG_PACKET_MAX);
     219         [ #  # ]:          0 :         if (len == -1)
     220                 :            :                 return -ENOMSG;
     221                 :            : 
     222                 :          0 :         err = tapdisk_syslog_sock_send(log, log->msg, len);
     223                 :            : 
     224         [ #  # ]:          0 :         if (err == -EAGAIN)
     225                 :            :                 return err;
     226                 :            : 
     227         [ #  # ]:          0 :         if (err)
     228                 :            :                 goto fail;
     229                 :            : 
     230                 :            : done:
     231                 :          0 :         log->cons += len + 1;
     232                 :          0 :         return 0;
     233                 :            : 
     234                 :            : fail:
     235                 :          0 :         log->stats.fails++;
     236                 :          0 :         goto done;
     237                 :            : }
     238                 :            : 
     239                 :            : static void
     240                 :          0 : tapdisk_syslog_ring_warning(td_syslog_t *log)
     241                 :            : {
     242                 :            :         int n, err;
     243                 :            : 
     244                 :          0 :         n        = log->oom;
     245                 :          0 :         log->oom = 0;
     246                 :            : 
     247                 :          0 :         err = tapdisk_syslog(log, TLOG_WARN,
     248                 :            :                              "tapdisk-syslog: %d messages dropped", n);
     249         [ #  # ]:          0 :         if (err)
     250                 :          0 :                 log->oom = n;
     251                 :          0 : }
     252                 :            : 
     253                 :            : static void
     254                 :          0 : tapdisk_syslog_ring_dispatch(td_syslog_t *log)
     255                 :            : {
     256                 :            :         int err;
     257                 :            : 
     258                 :            :         do {
     259                 :          0 :                 err = tapdisk_syslog_ring_dispatch_one(log);
     260         [ #  # ]:          0 :         } while (!err);
     261                 :            : 
     262         [ #  # ]:          0 :         if (log->oom)
     263                 :          0 :                 tapdisk_syslog_ring_warning(log);
     264                 :          0 : }
     265                 :            : 
     266                 :            : static int
     267                 :          0 : tapdisk_syslog_vsprintf(char *buf, size_t size,
     268                 :            :                         int prio, int facility, const struct timeval *tv,
     269                 :            :                         const char *ident, const char *fmt, va_list ap)
     270                 :            : {
     271                 :            :         char tsbuf[TD_SYSLOG_STRTIME_LEN+1];
     272                 :            :         size_t len;
     273                 :            : 
     274                 :            :         /*
     275                 :            :          * PKT       := PRI HEADER MSG
     276                 :            :          * PRI       := "<" {"0" .. "9"} ">"
     277                 :            :          * HEADER    := TIMESTAMP HOSTNAME
     278                 :            :          * MSG       := <TAG> <SEP> <CONTENT>
     279                 :            :          * SEP       := ":" | " " | "["
     280                 :            :          */
     281                 :            : 
     282                 :          0 :         tapdisk_syslog_strftime(tsbuf, sizeof(tsbuf), tv);
     283                 :            : 
     284                 :          0 :         len = 0;
     285                 :            : 
     286                 :            :         /* NB. meant to work with c99 null buffers */
     287                 :            : 
     288 [ #  # ][ #  # ]:          0 :         len += snprintf(buf ? buf + len : NULL, buf ? size - len : 0,
     289                 :            :                         "<%d>%s %s: ", prio | facility, tsbuf, ident);
     290                 :            : 
     291         [ #  # ]:          0 :         if (LOG_WARNING == prio)
     292 [ #  # ][ #  # ]:          0 :                 len += snprintf(buf ? buf + len : NULL, buf ? size - len : 0,
     293                 :            :                                 "tap-err:");
     294                 :            : 
     295 [ #  # ][ #  # ]:          0 :         len += vsnprintf(buf ? buf + len : NULL, buf ? size - len : 0,
     296                 :            :                          fmt, ap);
     297                 :            : 
     298                 :          0 :         return MIN(len, size);
     299                 :            : }
     300                 :            : 
     301                 :            : /*
     302                 :            :  * NB. Sockets.
     303                 :            :  *
     304                 :            :  * Syslog is based on a connectionless (DGRAM) unix transport.
     305                 :            :  *
     306                 :            :  * While it is reliable, we cannot block on syslogd because -- as with
     307                 :            :  * any IPC in tapdisk -- we could deadlock in page I/O writeback.
     308                 :            :  * Hence the syslog(3) avoidance on the datapath, which this code
     309                 :            :  * facilitates.
     310                 :            :  *
     311                 :            :  * This type of socket has a single (global) receive buffer on
     312                 :            :  * syslogd's end, but no send buffer at all. The does just that:
     313                 :            :  * headroom on the sender side.
     314                 :            :  *
     315                 :            :  * The transport is rather stateless, but we still need to connect()
     316                 :            :  * the socket, or select() will find no receive buffer to block
     317                 :            :  * on. While we never disconnect, connections are unreliable because
     318                 :            :  * syslog may shut down.
     319                 :            :  *
     320                 :            :  * Reconnection will be attempted with every user message submitted.
     321                 :            :  * Any send() or connect() failure other than EAGAIN discards the
     322                 :            :  * message. Also, the write event handler will go on to discard any
     323                 :            :  * remaining ring contents as well, once the socket is disconnected.
     324                 :            :  *
     325                 :            :  * In summary, no attempts to mask service blackouts in here.
     326                 :            :  */
     327                 :            : 
     328                 :            : int
     329                 :          0 : tapdisk_vsyslog(td_syslog_t *log, int prio, const char *fmt, va_list ap)
     330                 :            : {
     331                 :            :         struct timeval now;
     332                 :            :         size_t len;
     333                 :            :         int err;
     334                 :            : 
     335                 :          0 :         gettimeofday(&now, NULL);
     336                 :            : 
     337                 :          0 :         len = tapdisk_syslog_vsprintf(log->msg, TD_SYSLOG_PACKET_MAX,
     338                 :            :                                       prio, log->facility,
     339                 :          0 :                                       &now, log->ident, fmt, ap);
     340                 :            : 
     341                 :          0 :         log->stats.count += 1;
     342                 :          0 :         log->stats.bytes += len;
     343                 :            : 
     344         [ #  # ]:          0 :         if (log->cons != log->prod)
     345                 :            :                 goto busy;
     346                 :            : 
     347                 :            : send:
     348                 :          0 :         err = tapdisk_syslog_sock_send(log, log->msg, len);
     349         [ #  # ]:          0 :         if (!err)
     350                 :          0 :                 return 0;
     351                 :            : 
     352         [ #  # ]:          0 :         if (err == -ENOTCONN) {
     353                 :          0 :                 err = tapdisk_syslog_sock_connect(log);
     354         [ #  # ]:          0 :                 if (!err)
     355                 :            :                         goto send;
     356                 :            :         }
     357                 :            : 
     358         [ #  # ]:          0 :         if (err != -EAGAIN)
     359                 :            :                 goto fail;
     360                 :            : 
     361                 :          0 :         tapdisk_syslog_sock_unmask(log);
     362                 :            : 
     363                 :            : busy:
     364         [ #  # ]:          0 :         if (log->oom) {
     365                 :            :                 err = -ENOBUFS;
     366                 :            :                 goto oom;
     367                 :            :         }
     368                 :            : 
     369                 :          0 :         err = tapdisk_syslog_ring_write_str(log, log->msg, len);
     370         [ #  # ]:          0 :         if (!err)
     371                 :            :                 return 0;
     372                 :            : 
     373                 :          0 :         log->oom_tv = now;
     374                 :            : 
     375                 :            : oom:
     376                 :          0 :         log->oom++;
     377                 :          0 :         log->stats.drops++;
     378                 :          0 :         return err;
     379                 :            : 
     380                 :            : fail:
     381                 :          0 :         log->stats.fails++;
     382                 :          0 :         return err;
     383                 :            : }
     384                 :            : 
     385                 :            : int
     386                 :          0 : tapdisk_syslog(td_syslog_t *log, int prio, const char *fmt, ...)
     387                 :            : {
     388                 :            :         va_list ap;
     389                 :            :         int err;
     390                 :            : 
     391                 :          0 :         va_start(ap, fmt);
     392                 :          0 :         err = tapdisk_vsyslog(log, prio, fmt, ap);
     393                 :          0 :         va_end(ap);
     394                 :            : 
     395                 :          0 :         return err;
     396                 :            : }
     397                 :            : 
     398                 :            : static int
     399                 :          0 : tapdisk_syslog_sock_send(td_syslog_t *log, const void *msg, size_t size)
     400                 :            : {
     401                 :            :         ssize_t n;
     402                 :            : 
     403                 :          0 :         log->stats.xmits++;
     404                 :            : 
     405                 :          0 :         n = send(log->sock, msg, size, MSG_DONTWAIT);
     406         [ #  # ]:          0 :         if (n < 0)
     407                 :          0 :                 return -errno;
     408                 :            : 
     409                 :            :         return 0;
     410                 :            : }
     411                 :            : 
     412                 :            : static void
     413                 :          0 : tapdisk_syslog_sock_event(event_id_t id, char mode, void *private)
     414                 :            : {
     415                 :          0 :         td_syslog_t *log = private;
     416                 :            : 
     417                 :          0 :         tapdisk_syslog_ring_dispatch(log);
     418                 :            : 
     419         [ #  # ]:          0 :         if (log->cons == log->prod)
     420                 :          0 :                 tapdisk_syslog_sock_mask(log);
     421                 :          0 : }
     422                 :            : 
     423                 :            : static void
     424                 :          0 : __tapdisk_syslog_sock_init(td_syslog_t *log)
     425                 :            : {
     426                 :          0 :         log->sock     = -1;
     427                 :          0 :         log->event_id = -1;
     428                 :          0 : }
     429                 :            : 
     430                 :            : static void
     431                 :          0 : tapdisk_syslog_sock_close(td_syslog_t *log)
     432                 :            : {
     433         [ #  # ]:          0 :         if (log->sock >= 0)
     434                 :          0 :                 close(log->sock);
     435                 :            : 
     436         [ #  # ]:          0 :         if (log->event_id >= 0)
     437                 :          0 :                 tapdisk_server_unregister_event(log->event_id);
     438                 :            : 
     439                 :          0 :         __tapdisk_syslog_sock_init(log);
     440                 :          0 : }
     441                 :            : 
     442                 :            : static int
     443                 :          0 : tapdisk_syslog_sock_open(td_syslog_t *log)
     444                 :            : {
     445                 :            :         event_id_t id;
     446                 :            :         int s, err;
     447                 :            : 
     448                 :          0 :         __tapdisk_syslog_sock_init(log);
     449                 :            : 
     450                 :          0 :         s = socket(PF_UNIX, SOCK_DGRAM, 0);
     451         [ #  # ]:          0 :         if (s < 0) {
     452                 :          0 :                 err = -errno;
     453                 :          0 :                 goto fail;
     454                 :            :         }
     455                 :            : 
     456                 :          0 :         log->sock = s;
     457                 :            : 
     458                 :            : #if 0
     459                 :            :         err = fcntl(s, F_SETFL, O_NONBLOCK);
     460                 :            :         if (err < 0) {
     461                 :            :                 err = -errno;
     462                 :            :                 goto fail;
     463                 :            :         }
     464                 :            : #endif
     465                 :            : 
     466                 :          0 :         id = tapdisk_server_register_event(SCHEDULER_POLL_WRITE_FD,
     467                 :          0 :                                            s, TV_ZERO,
     468                 :            :                                            tapdisk_syslog_sock_event,
     469                 :            :                                            log);
     470         [ #  # ]:          0 :         if (id < 0) {
     471                 :            :                 err = id;
     472                 :            :                 goto fail;
     473                 :            :         }
     474                 :            : 
     475                 :          0 :         log->event_id = id;
     476                 :            : 
     477                 :          0 :         tapdisk_syslog_sock_mask(log);
     478                 :            : 
     479                 :          0 :         return 0;
     480                 :            : 
     481                 :            : fail:
     482                 :          0 :         tapdisk_syslog_sock_close(log);
     483                 :          0 :         return err;
     484                 :            : }
     485                 :            : 
     486                 :            : static int
     487                 :          0 : tapdisk_syslog_sock_connect(td_syslog_t *log)
     488                 :            : {
     489                 :            :         int err;
     490                 :            : 
     491                 :          0 :         err = connect(log->sock, &syslog_addr, sizeof(syslog_addr));
     492         [ #  # ]:          0 :         if (err < 0)
     493                 :          0 :                 err = -errno;
     494                 :            : 
     495                 :          0 :         return err;
     496                 :            : }
     497                 :            : 
     498                 :            : static void
     499                 :          0 : tapdisk_syslog_sock_mask(td_syslog_t *log)
     500                 :            : {
     501                 :          0 :         tapdisk_server_mask_event(log->event_id, 1);
     502                 :          0 : }
     503                 :            : 
     504                 :            : static void
     505                 :          0 : tapdisk_syslog_sock_unmask(td_syslog_t *log)
     506                 :            : {
     507                 :          0 :         tapdisk_server_mask_event(log->event_id, 0);
     508                 :          0 : }
     509                 :            : 
     510                 :            : void
     511                 :          0 : __tapdisk_syslog_init(td_syslog_t *log)
     512                 :            : {
     513                 :            :         memset(log, 0, sizeof(td_syslog_t));
     514                 :          0 :         __tapdisk_syslog_sock_init(log);
     515                 :            :         __tapdisk_syslog_ring_init(log);
     516                 :          0 : }
     517                 :            : 
     518                 :            : void
     519                 :          0 : tapdisk_syslog_close(td_syslog_t *log)
     520                 :            : {
     521                 :          0 :         tapdisk_syslog_ring_uninit(log);
     522                 :          0 :         tapdisk_syslog_sock_close(log);
     523                 :            : 
     524         [ #  # ]:          0 :         if (log->ident)
     525                 :          0 :                 free(log->ident);
     526                 :            : 
     527                 :          0 :         __tapdisk_syslog_init(log);
     528                 :          0 : }
     529                 :            : 
     530                 :            : int
     531                 :          0 : tapdisk_syslog_open(td_syslog_t *log, const char *ident, int facility, size_t bufsz)
     532                 :            : {
     533                 :            :         int err;
     534                 :            : 
     535                 :          0 :         __tapdisk_syslog_init(log);
     536                 :            : 
     537                 :          0 :         log->facility = facility;
     538         [ #  # ]:          0 :         log->ident = ident ? strndup(ident, TD_SYSLOG_IDENT_MAX) : NULL;
     539                 :            : 
     540                 :          0 :         err = tapdisk_syslog_sock_open(log);
     541         [ #  # ]:          0 :         if (err)
     542                 :            :                 goto fail;
     543                 :            : 
     544                 :          0 :         err = tapdisk_syslog_ring_init(log, bufsz);
     545         [ #  # ]:          0 :         if (err)
     546                 :            :                 goto fail;
     547                 :            : 
     548                 :            :         return 0;
     549                 :            : 
     550                 :            : fail:
     551                 :          0 :         tapdisk_syslog_close(log);
     552                 :            : 
     553                 :          0 :         return err;
     554                 :            : }
     555                 :            : 
     556                 :            : void
     557                 :          0 : tapdisk_syslog_stats(td_syslog_t *log, int prio)
     558                 :            : {
     559                 :          0 :         struct _td_syslog_stats *s = &log->stats;
     560                 :            : 
     561                 :          0 :         tapdisk_syslog(log, prio,
     562                 :            :                        "tapdisk-syslog: %llu messages, %llu bytes, "
     563                 :            :                        "xmits: %llu, failed: %llu, dropped: %llu",
     564                 :            :                        s->count, s->bytes,
     565                 :            :                        s->xmits, s->fails, s->drops);
     566                 :          0 : }
     567                 :            : 
     568                 :            : void
     569                 :          0 : tapdisk_syslog_flush(td_syslog_t *log)
     570                 :            : {
     571         [ #  # ]:          0 :         while (log->cons != log->prod)
     572                 :          0 :                 tapdisk_server_iterate();
     573                 :          0 : }

Generated by: LCOV version 1.13