LCOV - code coverage report
Current view: top level - home/snorch/criu - log.c (source / functions) Hit Total Coverage
Test: coverage3.info Lines: 59 74 79.7 %
Date: 2014-04-22 Functions: 9 10 90.0 %
Branches: 24 36 66.7 %

           Branch data     Line data    Source code
       1                 :            : #include <stdlib.h>
       2                 :            : #include <stdio.h>
       3                 :            : #include <stdarg.h>
       4                 :            : #include <errno.h>
       5                 :            : #include <unistd.h>
       6                 :            : #include <stdbool.h>
       7                 :            : #include <limits.h>
       8                 :            : 
       9                 :            : #include <sys/types.h>
      10                 :            : #include <sys/time.h>
      11                 :            : #include <sys/resource.h>
      12                 :            : 
      13                 :            : #include <fcntl.h>
      14                 :            : 
      15                 :            : #include "compiler.h"
      16                 :            : #include "asm/types.h"
      17                 :            : #include "util.h"
      18                 :            : #include "cr_options.h"
      19                 :            : #include "servicefd.h"
      20                 :            : 
      21                 :            : #define DEFAULT_LOGFD           STDERR_FILENO
      22                 :            : /* Enable timestamps if verbosity is increased from default */
      23                 :            : #define LOG_TIMESTAMP           (DEFAULT_LOGLEVEL + 1)
      24                 :            : 
      25                 :            : static unsigned int current_loglevel = DEFAULT_LOGLEVEL;
      26                 :            : 
      27                 :            : static char buffer[PAGE_SIZE];
      28                 :            : static char buf_off = 0;
      29                 :            : 
      30                 :            : static struct timeval start;
      31                 :            : /*
      32                 :            :  * Manual buf len as sprintf will _always_ put '\0' at the end,
      33                 :            :  * but we want a "constant" pid to be there on restore
      34                 :            :  */
      35                 :            : #define TS_BUF_OFF      12
      36                 :            : 
      37                 :            : static void timediff(struct timeval *from, struct timeval *to)
      38                 :            : {
      39                 :    4325891 :         to->tv_sec -= from->tv_sec;
      40         [ +  + ]:    4325891 :         if (to->tv_usec >= from->tv_usec)
      41                 :    3462860 :                 to->tv_usec -= from->tv_usec;
      42                 :            :         else {
      43                 :     863031 :                 to->tv_sec--;
      44                 :     863031 :                 to->tv_usec += 1000000 - from->tv_usec;
      45                 :            :         }
      46                 :            : }
      47                 :            : 
      48                 :    4325891 : static void print_ts(void)
      49                 :            : {
      50                 :            :         struct timeval t;
      51                 :            : 
      52                 :    4325891 :         gettimeofday(&t, NULL);
      53                 :            :         timediff(&start, &t);
      54                 :    8651782 :         snprintf(buffer, TS_BUF_OFF,
      55                 :    8651782 :                         "(%02u.%06u)", (unsigned)t.tv_sec, (unsigned)t.tv_usec);
      56                 :    4325891 :         buffer[TS_BUF_OFF - 1] = ' '; /* kill the '\0' produced by snprintf */
      57                 :    4325891 : }
      58                 :            : 
      59                 :       6141 : int log_get_fd(void)
      60                 :            : {
      61                 :    4332034 :         int fd = get_service_fd(LOG_FD_OFF);
      62                 :            : 
      63 [ +  - ][ +  - ]:    4332034 :         return fd < 0 ? DEFAULT_LOGFD : fd;
      64                 :            : }
      65                 :            : 
      66                 :            : static void reset_buf_off(void)
      67                 :            : {
      68   [ +  -  +  + ]:       4390 :         if (current_loglevel >= LOG_TIMESTAMP)
      69                 :            :                 /* reserve space for a timestamp */
      70                 :       4388 :                 buf_off = TS_BUF_OFF;
      71                 :            :         else
      72                 :          2 :                 buf_off = 0;
      73                 :            : }
      74                 :            : 
      75                 :       3702 : int log_init(const char *output)
      76                 :            : {
      77                 :            :         int new_logfd, fd;
      78                 :            : 
      79                 :       3702 :         gettimeofday(&start, NULL);
      80                 :            :         reset_buf_off();
      81                 :            : 
      82         [ +  + ]:       3702 :         if (output) {
      83                 :            :                 new_logfd = open(output, O_CREAT|O_TRUNC|O_WRONLY|O_APPEND, 0600);
      84         [ -  + ]:       3700 :                 if (new_logfd < 0) {
      85                 :          0 :                         pr_perror("Can't create log file %s", output);
      86                 :          0 :                         return -1;
      87                 :            :                 }
      88                 :            :         } else {
      89                 :          2 :                 new_logfd = dup(DEFAULT_LOGFD);
      90         [ -  + ]:          2 :                 if (new_logfd < 0) {
      91                 :          0 :                         pr_perror("Can't dup log file");
      92                 :          0 :                         return -1;
      93                 :            :                 }
      94                 :            :         }
      95                 :            : 
      96                 :       3702 :         fd = install_service_fd(LOG_FD_OFF, new_logfd);
      97                 :       3702 :         close(new_logfd);
      98         [ -  + ]:       3702 :         if (fd < 0)
      99                 :            :                 goto err;
     100                 :            : 
     101                 :            :         return 0;
     102                 :            : 
     103                 :            : err:
     104                 :          0 :         pr_perror("Log engine failure, can't duplicate descriptor");
     105                 :          0 :         return -1;
     106                 :            : }
     107                 :            : 
     108                 :        688 : int log_init_by_pid(void)
     109                 :            : {
     110                 :            :         char path[PATH_MAX];
     111                 :            : 
     112                 :            :         /*
     113                 :            :          * reset buf_off as this fn is called on each fork while
     114                 :            :          * restoring process tree
     115                 :            :          */
     116                 :            :         reset_buf_off();
     117                 :            : 
     118         [ +  - ]:        688 :         if (!opts.log_file_per_pid) {
     119                 :        688 :                 buf_off += snprintf(buffer + buf_off, PAGE_SIZE - buf_off, "%6d: ", getpid());
     120                 :        688 :                 return 0;
     121                 :            :         }
     122                 :            : 
     123         [ #  # ]:          0 :         if (!opts.output)
     124                 :            :                 return 0;
     125                 :            : 
     126                 :          0 :         snprintf(path, PATH_MAX, "%s.%d", opts.output, getpid());
     127                 :            : 
     128                 :          0 :         return log_init(path);
     129                 :            : }
     130                 :            : 
     131                 :          0 : void log_fini(void)
     132                 :            : {
     133                 :          0 :         close_service_fd(LOG_FD_OFF);
     134                 :          0 : }
     135                 :            : 
     136                 :       3704 : void log_set_loglevel(unsigned int level)
     137                 :            : {
     138         [ +  + ]:       3704 :         if (level == LOG_UNSET)
     139                 :          2 :                 current_loglevel = DEFAULT_LOGLEVEL;
     140                 :            :         else
     141                 :       3702 :                 current_loglevel = level;
     142                 :       3704 : }
     143                 :            : 
     144                 :       7679 : unsigned int log_get_loglevel(void)
     145                 :            : {
     146                 :       7679 :         return current_loglevel;
     147                 :            : }
     148                 :            : 
     149                 :    4334283 : static void __print_on_level(unsigned int loglevel, const char *format, va_list params)
     150                 :            : {
     151                 :            :         int fd, size, ret, off = 0;
     152                 :            : 
     153         [ -  + ]:    4334283 :         if (unlikely(loglevel == LOG_MSG)) {
     154                 :            :                 fd = STDOUT_FILENO;
     155                 :          0 :                 off = buf_off; /* skip dangling timestamp */
     156                 :            :         } else {
     157         [ +  + ]:    4334283 :                 if (loglevel > current_loglevel)
     158                 :    4334283 :                         return;
     159                 :            :                 fd = log_get_fd();
     160         [ +  + ]:    4325893 :                 if (current_loglevel >= LOG_TIMESTAMP)
     161                 :    4325891 :                         print_ts();
     162                 :            :         }
     163                 :            : 
     164                 :    4325893 :         size  = vsnprintf(buffer + buf_off, PAGE_SIZE - buf_off, format, params);
     165                 :    4325893 :         size += buf_off;
     166                 :            : 
     167         [ +  + ]:    8651786 :         while (off < size) {
     168                 :    4325893 :                 ret = write(fd, buffer + off, size - off);
     169         [ +  - ]:    4325893 :                 if (ret <= 0)
     170                 :            :                         break;
     171                 :    4325893 :                 off += ret;
     172                 :            :         }
     173                 :            : }
     174                 :            : 
     175                 :    4334283 : void print_on_level(unsigned int loglevel, const char *format, ...)
     176                 :            : {
     177                 :            :         va_list params;
     178                 :            : 
     179                 :    4334283 :         va_start(params, format);
     180                 :    4334283 :         __print_on_level(loglevel, format, params);
     181                 :    4334283 :         va_end(params);
     182                 :    4334283 : }
     183                 :            : 
     184                 :        210 : int write_pidfile(int pid)
     185                 :            : {
     186                 :            :         int fd;
     187                 :            : 
     188                 :        210 :         fd = open(opts.pidfile, O_WRONLY | O_TRUNC | O_CREAT, 0600);
     189         [ -  + ]:        210 :         if (fd == -1) {
     190                 :          0 :                 pr_perror("Can't open %s", opts.pidfile);
     191                 :          0 :                 return -1;
     192                 :            :         }
     193                 :            : 
     194                 :            :         dprintf(fd, "%d", pid);
     195                 :        210 :         close(fd);
     196                 :        210 :         return 0;
     197                 :            : }

Generated by: LCOV version 1.9