root/examples/perfcounter/perf_writer_util.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fatal
  2. add_key_raw
  3. add_key
  4. make_key
  5. usage
  6. parse_flags
  7. setup_file_paths
  8. sigterm_handler
  9. daemonize
  10. get_counter_id
  11. init_perf_counter

   1 /* 
   2  *  Unix SMB/CIFS implementation.
   3  *  Performance Counter Daemon
   4  *
   5  *  Copyright (C) Marcin Krzysztof Porwit    2005
   6  *  
   7  *  This program is free software; you can redistribute it and/or modify
   8  *  it under the terms of the GNU General Public License as published by
   9  *  the Free Software Foundation; either version 3 of the License, or
  10  *  (at your option) any later version.
  11  *  
  12  *  This program is distributed in the hope that it will be useful,
  13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  *  GNU General Public License for more details.
  16  *  
  17  *  You should have received a copy of the GNU General Public License
  18  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  19  */
  20 
  21 #include "perf.h"
  22 
  23 extern sig_atomic_t keep_running;
  24 
  25 void fatal(char *msg)
     /* [<][>][^][v][top][bottom][index][help] */
  26 {
  27   perror(msg);
  28   exit(1);
  29 }
  30 
  31 void add_key_raw(TDB_CONTEXT *db, char *keystring, void *databuf, size_t datasize, int flags)
     /* [<][>][^][v][top][bottom][index][help] */
  32 {
  33   TDB_DATA key, data;
  34 
  35   key.dptr = keystring;
  36   key.dsize = strlen(keystring);
  37   data.dptr = databuf;
  38   data.dsize = datasize;
  39 
  40   tdb_store(db, key, data, flags);
  41 }
  42 
  43 void add_key(TDB_CONTEXT *db, char *keystring, char *datastring, int flags)
     /* [<][>][^][v][top][bottom][index][help] */
  44 {
  45   TDB_DATA key, data;
  46 
  47   key.dptr = keystring;
  48   key.dsize = strlen(keystring);
  49   data.dptr = datastring;
  50   data.dsize = strlen(datastring);
  51 
  52   tdb_store(db, key, data, flags);
  53 }
  54 
  55 void make_key(char *buf, int buflen, int key_part1, char *key_part2)
     /* [<][>][^][v][top][bottom][index][help] */
  56 {
  57     memset(buf, 0, buflen);
  58     if(key_part2 != NULL)
  59         sprintf(buf, "%d%s", key_part1, key_part2);
  60     else
  61         sprintf(buf, "%d", key_part1);
  62 
  63     return;
  64 }
  65 
  66 void usage(char *progname)
     /* [<][>][^][v][top][bottom][index][help] */
  67 {
  68     fprintf(stderr, "Usage: %s [-d] [-f <file_path>].\n", progname);
  69     fprintf(stderr, "\t-d: run as a daemon.\n");
  70     fprintf(stderr, "\t-f <file_path>: path where the TDB files reside.\n");
  71     fprintf(stderr, "\t\tDEFAULT is /var/lib/samba/perfmon\n");
  72     exit(1);
  73 }
  74 
  75 void parse_flags(RuntimeSettings *rt, int argc, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
  76 {
  77     int flag;
  78     
  79     while((flag = getopt(argc, argv, "df:")) != -1)
  80     {
  81         switch(flag)
  82         {
  83             case 'd':
  84             {
  85                 rt->dflag = TRUE;
  86                 break;
  87             }
  88             case 'f':
  89             {
  90                 memcpy(rt->dbDir, optarg, strlen(optarg));
  91                 break;
  92             }
  93             default:
  94             {
  95                 usage(argv[0]);
  96             }
  97         }
  98     }
  99 
 100     return;
 101 }
 102 
 103 void setup_file_paths(RuntimeSettings *rt)
     /* [<][>][^][v][top][bottom][index][help] */
 104 {
 105     int status;
 106 
 107     if(strlen(rt->dbDir) == 0)
 108     {
 109         /* No file path was passed in, use default */
 110         sprintf(rt->dbDir, "/var/lib/samba/perfmon");
 111     }
 112 
 113     sprintf(rt->nameFile, "%s/names.tdb", rt->dbDir);
 114     sprintf(rt->counterFile, "%s/data.tdb", rt->dbDir);
 115 
 116     mkdir(rt->dbDir, 0755);
 117     rt->cnames = tdb_open(rt->nameFile, 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644);
 118     rt->cdata = tdb_open(rt->counterFile, 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644);
 119 
 120     if(rt->cnames == NULL || rt->cdata == NULL)
 121     {
 122         perror("setup_file_paths");
 123         exit(1);
 124     }
 125 
 126     return;
 127 }
 128 
 129 void sigterm_handler()
     /* [<][>][^][v][top][bottom][index][help] */
 130 {
 131     keep_running = FALSE;
 132     return;
 133 }
 134 
 135 void daemonize(RuntimeSettings *rt)
     /* [<][>][^][v][top][bottom][index][help] */
 136 {
 137     pid_t pid;
 138     int i;
 139     int fd;
 140 
 141     /* Check if we're already a daemon */
 142     if(getppid() == 1)
 143         return;
 144     pid = fork();
 145     if(pid < 0)
 146         /* can't fork */
 147         exit(1);
 148     else if(pid > 0)
 149     {
 150         /* we're the parent */
 151         tdb_close(rt->cnames);
 152         tdb_close(rt->cdata);
 153         exit(0);
 154     }
 155 
 156     /* get a new session */
 157     if(setsid() == -1)
 158         exit(2);
 159 
 160     /* Change CWD */
 161     chdir("/");
 162 
 163     /* close file descriptors */
 164     close(STDIN_FILENO);
 165     close(STDOUT_FILENO);
 166     close(STDERR_FILENO);
 167 
 168     /* And reopen them as safe defaults */
 169     fd = open("/dev/null", O_RDONLY);
 170     if(fd != 0)
 171     {
 172         dup2(fd, 0);
 173         close(fd);
 174     }
 175     fd = open("/dev/null", O_WRONLY);
 176     if(fd != 1)
 177     {
 178         dup2(fd, 1);
 179         close(fd);
 180     }
 181     fd = open("/dev/null", O_WRONLY);
 182     if(fd != 2)
 183     {
 184         dup2(fd, 2);
 185         close(fd);
 186     }
 187 
 188     /* handle signals */
 189     signal(SIGINT, SIG_IGN);
 190     signal(SIGHUP, SIG_IGN);
 191     signal(SIGTERM, sigterm_handler);
 192 
 193     return;
 194 }
 195 
 196 int get_counter_id(PERF_DATA_BLOCK *data)
     /* [<][>][^][v][top][bottom][index][help] */
 197 {
 198     data->counter_id += 2;
 199     data->num_counters++;
 200 
 201     return data->counter_id;
 202 }
 203 
 204 void init_perf_counter(PerfCounter *counter,
     /* [<][>][^][v][top][bottom][index][help] */
 205                        PerfCounter *parent,
 206                        unsigned int index,
 207                        char *name,
 208                        char *help,
 209                        int counter_type,
 210                        int record_type)
 211 {
 212     counter->index = index;
 213     memcpy(counter->name, name, strlen(name));
 214     memcpy(counter->help, help, strlen(help));
 215     counter->counter_type = counter_type;
 216     counter->record_type = record_type;
 217 
 218     switch(record_type)
 219     {
 220         case PERF_OBJECT:
 221             sprintf(counter->relationships, "p");
 222             break;
 223         case PERF_COUNTER:
 224             sprintf(counter->relationships, "c[%d]", parent->index);
 225             break;
 226         case PERF_INSTANCE:
 227             sprintf(counter->relationships, "i[%d]", parent->index);
 228             break;
 229         default:
 230             perror("init_perf_counter: unknown record type");
 231             exit(1);
 232     }
 233 
 234     return;
 235 }

/* [<][>][^][v][top][bottom][index][help] */