LCOV - code coverage report
Current view: top level - misc/kabi/lvm2.git/lib/log - log.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 70 182 38.5 %
Date: 2010-04-13 Functions: 11 16 68.8 %
Branches: 34 120 28.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
       3                 :            :  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
       4                 :            :  *
       5                 :            :  * This file is part of LVM2.
       6                 :            :  *
       7                 :            :  * This copyrighted material is made available to anyone wishing to use,
       8                 :            :  * modify, copy, or redistribute it subject to the terms and conditions
       9                 :            :  * of the GNU Lesser General Public License v.2.1.
      10                 :            :  *
      11                 :            :  * You should have received a copy of the GNU Lesser General Public License
      12                 :            :  * along with this program; if not, write to the Free Software Foundation,
      13                 :            :  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "lib.h"
      17                 :            : #include "device.h"
      18                 :            : #include "memlock.h"
      19                 :            : #include "lvm-string.h"
      20                 :            : #include "lvm-file.h"
      21                 :            : #include "defaults.h"
      22                 :            : #include "config.h"
      23                 :            : 
      24                 :            : #include <stdarg.h>
      25                 :            : #include <syslog.h>
      26                 :            : 
      27                 :            : static FILE *_log_file;
      28                 :            : static struct device _log_dev;
      29                 :            : static struct str_list _log_dev_alias;
      30                 :            : 
      31                 :            : static int _syslog = 0;
      32                 :            : static int _log_to_file = 0;
      33                 :            : static int _log_direct = 0;
      34                 :            : static int _log_while_suspended = 0;
      35                 :            : static int _indent = 1;
      36                 :            : static int _log_suppress = 0;
      37                 :            : static char _msg_prefix[30] = "  ";
      38                 :            : static int _already_logging = 0;
      39                 :            : static int _abort_on_internal_errors = 0;
      40                 :            : 
      41                 :            : static lvm2_log_fn_t _lvm2_log_fn = NULL;
      42                 :            : 
      43                 :            : static int _lvm_errno = 0;
      44                 :            : static int _store_errmsg = 0;
      45                 :            : static char *_lvm_errmsg = NULL;
      46                 :            : 
      47                 :          0 : void init_log_fn(lvm2_log_fn_t log_fn)
      48                 :            : {
      49         [ #  # ]:          0 :         if (log_fn)
      50                 :          0 :                 _lvm2_log_fn = log_fn;
      51                 :            :         else
      52                 :          0 :                 _lvm2_log_fn = NULL;
      53                 :          0 : }
      54                 :            : 
      55                 :          0 : void init_log_file(const char *log_file, int append)
      56                 :            : {
      57         [ #  # ]:          0 :         const char *open_mode = append ? "a" : "w";
      58                 :            : 
      59         [ #  # ]:          0 :         if (!(_log_file = fopen(log_file, open_mode))) {
      60                 :          0 :                 log_sys_error("fopen", log_file);
      61                 :          0 :                 return;
      62                 :            :         }
      63                 :            : 
      64                 :          0 :         _log_to_file = 1;
      65                 :            : }
      66                 :            : 
      67                 :          0 : void init_log_direct(const char *log_file, int append)
      68                 :            : {
      69         [ #  # ]:          0 :         int open_flags = append ? 0 : O_TRUNC;
      70                 :            : 
      71                 :          0 :         dev_create_file(log_file, &_log_dev, &_log_dev_alias, 1);
      72         [ #  # ]:          0 :         if (!dev_open_flags(&_log_dev, O_RDWR | O_CREAT | open_flags, 1, 0))
      73                 :          0 :                 return;
      74                 :            : 
      75                 :          0 :         _log_direct = 1;
      76                 :            : }
      77                 :            : 
      78                 :          3 : void init_log_while_suspended(int log_while_suspended)
      79                 :            : {
      80                 :          3 :         _log_while_suspended = log_while_suspended;
      81                 :          3 : }
      82                 :            : 
      83                 :          1 : void init_syslog(int facility)
      84                 :            : {
      85                 :          1 :         openlog("lvm", LOG_PID, facility);
      86                 :          1 :         _syslog = 1;
      87                 :          1 : }
      88                 :            : 
      89                 :          0 : int log_suppress(int suppress)
      90                 :            : {
      91                 :          0 :         int old_suppress = _log_suppress;
      92                 :            : 
      93                 :          0 :         _log_suppress = suppress;
      94                 :            : 
      95                 :          0 :         return old_suppress;
      96                 :            : }
      97                 :            : 
      98                 :          1 : void release_log_memory(void)
      99                 :            : {
     100         [ +  - ]:          1 :         if (!_log_direct)
     101                 :          1 :                 return;
     102                 :            : 
     103                 :          0 :         dm_free((char *) _log_dev_alias.str);
     104                 :          1 :         _log_dev_alias.str = "activate_log file";
     105                 :            : }
     106                 :            : 
     107                 :          1 : void fin_log(void)
     108                 :            : {
     109         [ -  + ]:          1 :         if (_log_direct) {
     110                 :          0 :                 dev_close(&_log_dev);
     111                 :          0 :                 _log_direct = 0;
     112                 :            :         }
     113                 :            : 
     114         [ -  + ]:          1 :         if (_log_to_file) {
     115         [ #  # ]:          0 :                 if (dm_fclose(_log_file)) {
     116         [ #  # ]:          0 :                         if (errno)
     117                 :          0 :                               fprintf(stderr, "failed to write log file: %s\n",
     118                 :            :                                       strerror(errno));
     119                 :            :                         else
     120                 :          0 :                               fprintf(stderr, "failed to write log file\n");
     121                 :            : 
     122                 :            :                 }
     123                 :          0 :                 _log_to_file = 0;
     124                 :            :         }
     125                 :          1 : }
     126                 :            : 
     127                 :          4 : void fin_syslog()
     128                 :            : {
     129         [ +  + ]:          4 :         if (_syslog)
     130                 :          1 :                 closelog();
     131                 :          4 :         _syslog = 0;
     132                 :          4 : }
     133                 :            : 
     134                 :          5 : void init_msg_prefix(const char *prefix)
     135                 :            : {
     136                 :          5 :         strncpy(_msg_prefix, prefix, sizeof(_msg_prefix));
     137                 :          5 :         _msg_prefix[sizeof(_msg_prefix) - 1] = '\0';
     138                 :          5 : }
     139                 :            : 
     140                 :          3 : void init_indent(int indent)
     141                 :            : {
     142                 :          3 :         _indent = indent;
     143                 :          3 : }
     144                 :            : 
     145                 :          3 : void init_abort_on_internal_errors(int fatal)
     146                 :            : {
     147                 :          3 :         _abort_on_internal_errors = fatal;
     148                 :          3 : }
     149                 :            : 
     150                 :          5 : void reset_lvm_errno(int store_errmsg)
     151                 :            : {
     152                 :          5 :         _lvm_errno = 0;
     153                 :            : 
     154         [ -  + ]:          5 :         if (_lvm_errmsg) {
     155                 :          0 :                 dm_free(_lvm_errmsg);
     156                 :          0 :                 _lvm_errmsg = NULL;
     157                 :            :         }
     158                 :            : 
     159                 :          5 :         _store_errmsg = store_errmsg;
     160                 :          5 : }
     161                 :            : 
     162                 :          1 : int stored_errno(void)
     163                 :            : {
     164                 :          1 :         return _lvm_errno;
     165                 :            : }
     166                 :            : 
     167                 :          0 : const char *stored_errmsg(void)
     168                 :            : {
     169         [ #  # ]:          0 :         return _lvm_errmsg ? : "";
     170                 :            : }
     171                 :            : 
     172                 :        600 : void print_log(int level, const char *file, int line, int dm_errno,
     173                 :            :                const char *format, ...)
     174                 :            : {
     175                 :            :         va_list ap;
     176                 :            :         char buf[1024], buf2[4096], locn[4096];
     177                 :            :         int bufused, n;
     178                 :            :         const char *message;
     179                 :            :         const char *trformat;           /* Translated format string */
     180                 :            :         char *newbuf;
     181                 :        600 :         int use_stderr = level & _LOG_STDERR;
     182                 :        600 :         int fatal_internal_error = 0;
     183                 :            : 
     184                 :        600 :         level &= ~_LOG_STDERR;
     185                 :            : 
     186 [ +  + ][ -  + ]:        600 :         if (_abort_on_internal_errors &&
     187                 :        592 :             !strncmp(format, INTERNAL_ERROR,
     188                 :            :                      strlen(INTERNAL_ERROR))) {
     189                 :          0 :                 fatal_internal_error = 1;
     190                 :            :                 /* Internal errors triggering abort cannot be suppressed. */
     191                 :          0 :                 _log_suppress = 0;
     192                 :          0 :                 level = _LOG_FATAL;
     193                 :            :         }
     194                 :            : 
     195         [ -  + ]:        600 :         if (_log_suppress == 2)
     196                 :          0 :                 return;
     197                 :            : 
     198         [ -  + ]:        600 :         if (level <= _LOG_ERR)
     199                 :          0 :                 init_error_message_produced(1);
     200                 :            : 
     201                 :        600 :         trformat = _(format);
     202                 :            : 
     203 [ -  + ][ #  # ]:        600 :         if (dm_errno && !_lvm_errno)
     204                 :          0 :                 _lvm_errno = dm_errno;
     205                 :            : 
     206 [ +  - ][ +  - ]:        600 :         if (_lvm2_log_fn || (_store_errmsg && (level <= _LOG_ERR))) {
                 [ -  + ]
     207                 :          0 :                 va_start(ap, format);
     208                 :          0 :                 n = vsnprintf(buf2, sizeof(buf2) - 1, trformat, ap);
     209                 :          0 :                 va_end(ap);
     210                 :            : 
     211         [ #  # ]:          0 :                 if (n < 0) {
     212                 :          0 :                         fprintf(stderr, _("vsnprintf failed: skipping external "
     213                 :            :                                         "logging function"));
     214                 :          0 :                         goto log_it;
     215                 :            :                 }
     216                 :            : 
     217                 :          0 :                 buf2[sizeof(buf2) - 1] = '\0';
     218                 :          0 :                 message = &buf2[0];
     219                 :            :         }
     220                 :            : 
     221 [ +  - ][ -  + ]:        600 :         if (_store_errmsg && (level <= _LOG_ERR)) {
     222         [ #  # ]:          0 :                 if (!_lvm_errmsg)
     223                 :          0 :                         _lvm_errmsg = dm_strdup(message);
     224         [ #  # ]:          0 :                 else if ((newbuf = dm_realloc(_lvm_errmsg,
     225                 :            :                                               strlen(_lvm_errmsg) +
     226                 :            :                                               strlen(message) + 2))) {
     227                 :          0 :                         _lvm_errmsg = strcat(newbuf, "\n");
     228                 :          0 :                         _lvm_errmsg = strcat(newbuf, message);
     229                 :            :                 }
     230                 :            :         }
     231                 :            : 
     232         [ -  + ]:        600 :         if (_lvm2_log_fn) {
     233                 :          0 :                 _lvm2_log_fn(level, file, line, 0, message);
     234         [ #  # ]:          0 :                 if (fatal_internal_error)
     235                 :          0 :                         abort();
     236                 :          0 :                 return;
     237                 :            :         }
     238                 :            : 
     239                 :            :       log_it:
     240         [ +  - ]:        600 :         if (!_log_suppress) {
     241         [ -  + ]:        600 :                 if (verbose_level() > _LOG_DEBUG)
     242                 :          0 :                         dm_snprintf(locn, sizeof(locn), "#%s:%d ",
     243                 :            :                                      file, line);
     244                 :            :                 else
     245                 :        600 :                         locn[0] = '\0';
     246                 :            : 
     247                 :        600 :                 va_start(ap, format);
     248 [ +  +  +  -  - :        600 :                 switch (level) {
                      - ]
     249                 :            :                 case _LOG_DEBUG:
     250   [ -  +  #  # ]:        451 :                         if (!strcmp("<backtrace>", format) &&
     251                 :          0 :                             verbose_level() <= _LOG_DEBUG)
     252                 :          0 :                                 break;
     253         [ -  + ]:        451 :                         if (verbose_level() >= _LOG_DEBUG) {
     254                 :          0 :                                 fprintf(stderr, "%s%s%s", locn, log_command_name(),
     255                 :            :                                         _msg_prefix);
     256         [ #  # ]:          0 :                                 if (_indent)
     257                 :          0 :                                         fprintf(stderr, "      ");
     258                 :          0 :                                 vfprintf(stderr, trformat, ap);
     259                 :          0 :                                 fputc('\n', stderr);
     260                 :            :                         }
     261                 :        451 :                         break;
     262                 :            : 
     263                 :            :                 case _LOG_INFO:
     264         [ -  + ]:        139 :                         if (verbose_level() >= _LOG_INFO) {
     265                 :          0 :                                 fprintf(stderr, "%s%s%s", locn, log_command_name(),
     266                 :            :                                         _msg_prefix);
     267         [ #  # ]:          0 :                                 if (_indent)
     268                 :          0 :                                         fprintf(stderr, "    ");
     269                 :          0 :                                 vfprintf(stderr, trformat, ap);
     270                 :          0 :                                 fputc('\n', stderr);
     271                 :            :                         }
     272                 :        139 :                         break;
     273                 :            :                 case _LOG_NOTICE:
     274         [ -  + ]:         10 :                         if (verbose_level() >= _LOG_NOTICE) {
     275                 :          0 :                                 fprintf(stderr, "%s%s%s", locn, log_command_name(),
     276                 :            :                                         _msg_prefix);
     277         [ #  # ]:          0 :                                 if (_indent)
     278                 :          0 :                                         fprintf(stderr, "  ");
     279                 :          0 :                                 vfprintf(stderr, trformat, ap);
     280                 :          0 :                                 fputc('\n', stderr);
     281                 :            :                         }
     282                 :         10 :                         break;
     283                 :            :                 case _LOG_WARN:
     284         [ #  # ]:          0 :                         if (verbose_level() >= _LOG_WARN) {
     285         [ #  # ]:          0 :                                 fprintf(use_stderr ? stderr : stdout, "%s%s",
     286                 :            :                                         log_command_name(), _msg_prefix);
     287         [ #  # ]:          0 :                                 vfprintf(use_stderr ? stderr : stdout, trformat, ap);
     288         [ #  # ]:          0 :                                 fputc('\n', use_stderr ? stderr : stdout);
     289                 :            :                         }
     290                 :          0 :                         break;
     291                 :            :                 case _LOG_ERR:
     292         [ #  # ]:          0 :                         if (verbose_level() >= _LOG_ERR) {
     293                 :          0 :                                 fprintf(stderr, "%s%s%s", locn, log_command_name(),
     294                 :            :                                         _msg_prefix);
     295                 :          0 :                                 vfprintf(stderr, trformat, ap);
     296                 :          0 :                                 fputc('\n', stderr);
     297                 :            :                         }
     298                 :          0 :                         break;
     299                 :            :                 case _LOG_FATAL:
     300                 :            :                 default:
     301         [ #  # ]:          0 :                         if (verbose_level() >= _LOG_FATAL) {
     302                 :          0 :                                 fprintf(stderr, "%s%s%s", locn, log_command_name(),
     303                 :            :                                         _msg_prefix);
     304                 :          0 :                                 vfprintf(stderr, trformat, ap);
     305                 :          0 :                                 fputc('\n', stderr);
     306                 :            :                         }
     307                 :            :                         break;
     308                 :            :                 }
     309                 :        600 :                 va_end(ap);
     310                 :            :         }
     311                 :            : 
     312         [ -  + ]:        600 :         if (fatal_internal_error)
     313                 :          0 :                 abort();
     314                 :            : 
     315         [ +  + ]:        600 :         if (level > debug_level())
     316                 :          5 :                 return;
     317                 :            : 
     318 [ -  + ][ #  # ]:        595 :         if (_log_to_file && (_log_while_suspended || !memlock())) {
                 [ #  # ]
     319                 :          0 :                 fprintf(_log_file, "%s:%d %s%s", file, line, log_command_name(),
     320                 :            :                         _msg_prefix);
     321                 :            : 
     322                 :          0 :                 va_start(ap, format);
     323                 :          0 :                 vfprintf(_log_file, trformat, ap);
     324                 :          0 :                 va_end(ap);
     325                 :            : 
     326                 :          0 :                 fprintf(_log_file, "\n");
     327                 :          0 :                 fflush(_log_file);
     328                 :            :         }
     329                 :            : 
     330 [ -  + ][ #  # ]:        595 :         if (_syslog && (_log_while_suspended || !memlock())) {
                 [ #  # ]
     331                 :          0 :                 va_start(ap, format);
     332                 :          0 :                 vsyslog(level, trformat, ap);
     333                 :          0 :                 va_end(ap);
     334                 :            :         }
     335                 :            : 
     336                 :            :         /* FIXME This code is unfinished - pre-extend & condense. */
     337 [ +  - ][ -  + ]:        595 :         if (!_already_logging && _log_direct && memlock()) {
                 [ #  # ]
     338                 :          0 :                 _already_logging = 1;
     339                 :          0 :                 memset(&buf, ' ', sizeof(buf));
     340                 :          0 :                 bufused = 0;
     341         [ #  # ]:          0 :                 if ((n = dm_snprintf(buf, sizeof(buf) - bufused - 1,
     342                 :            :                                       "%s:%d %s%s", file, line, log_command_name(),
     343                 :            :                                       _msg_prefix)) == -1)
     344                 :          0 :                         goto done;
     345                 :            : 
     346                 :          0 :                 bufused += n;
     347                 :            : 
     348                 :          0 :                 va_start(ap, format);
     349                 :          0 :                 n = vsnprintf(buf + bufused - 1, sizeof(buf) - bufused - 1,
     350                 :            :                               trformat, ap);
     351                 :          0 :                 va_end(ap);
     352                 :          0 :                 bufused += n;
     353                 :            : 
     354                 :            :               done:
     355                 :          0 :                 buf[bufused - 1] = '\n';
     356                 :          0 :                 buf[bufused] = '\n';
     357                 :          0 :                 buf[sizeof(buf) - 1] = '\n';
     358                 :            :                 /* FIXME real size bufused */
     359                 :          0 :                 dev_append(&_log_dev, sizeof(buf), buf);
     360                 :        600 :                 _already_logging = 0;
     361                 :            :         }
     362                 :            : }

Generated by: LCOV version 1.8