]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/tools/bbatch.c
ebl fix segfault with debug mode
[bacula/bacula] / bacula / src / tools / bbatch.c
1 /*
2  *
3  *  Program to test batch mode
4  *
5  *   Eric Bollengier, March 2007
6  *
7  *
8  *   Version $Id$
9  */
10 /*
11    Bacula® - The Network Backup Solution
12
13    Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
14
15    The main author of Bacula is Kern Sibbald, with contributions from
16    many others, a complete list can be found in the file AUTHORS.
17    This program is Free Software; you can redistribute it and/or
18    modify it under the terms of version two of the GNU General Public
19    License as published by the Free Software Foundation and included
20    in the file LICENSE.
21
22    This program is distributed in the hope that it will be useful, but
23    WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25    General Public License for more details.
26
27    You should have received a copy of the GNU General Public License
28    along with this program; if not, write to the Free Software
29    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30    02110-1301, USA.
31
32    Bacula® is a registered trademark of Kern Sibbald.
33    The licensor of Bacula is the Free Software Foundation Europe
34    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
35    Switzerland, email:ftf@fsfeurope.org.
36 */
37
38 /*
39   to create datafile
40  
41   for i in $(seq 10000 99999) ; do
42      j=$((($i % 1000) + 555))
43      echo "$i;/tmp/totabofds$j/fiddddle${j}$i;xxxLSTATxxxx;xxxxxxxMD5xxxxxx"
44   done  > dat1
45  
46   or
47
48   j=0
49   find / | while read a; do
50    j=$(($j+1))
51    echo "$j;$a;xxxLSTATxxxx;xxxxxxxMD5xxxxxx"
52   done > dat1
53  */
54
55 #include "bacula.h"
56 #include "stored/stored.h"
57 #include "findlib/find.h"
58 #include "cats/cats.h"
59  
60 /* Forward referenced functions */
61 static void *do_batch(void *);
62
63
64 /* Local variables */
65 static B_DB *db;
66
67 static const char *db_name = "bacula";
68 static const char *db_user = "bacula";
69 static const char *db_password = "";
70 static const char *db_host = NULL;
71
72 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
73
74 static void usage()
75 {
76    fprintf(stderr, _(
77 PROG_COPYRIGHT
78 "\nVersion: %s (%s)\n"
79 "Example : bbatch -w /path/to/workdir -h localhost -f dat1 -f dat -f datx\n"
80 " will start 3 thread and load dat1, dat and datx in your catalog\n"
81 "See bbatch.c to generate datafile\n\n"
82 "Usage: bbatch [ options ] -w working/dir -f datafile\n"
83 "       -d <nn>           set debug level to <nn>\n"
84 "       -dt               print timestamp in debug output\n"
85 "       -n <name>         specify the database name (default bacula)\n"
86 "       -u <user>         specify database user name (default bacula)\n"
87 "       -P <password      specify database password (default none)\n"
88 "       -h <host>         specify database host (default NULL)\n"
89 "       -w <working>      specify working directory\n"
90 "       -v                verbose\n"
91 "       -f <file>         specify data file\n"
92 "       -?                print this message\n\n"), 2001, VERSION, BDATE);
93    exit(1);
94 }
95
96 /* number of thread started */
97 int nb=0;
98
99 int main (int argc, char *argv[])
100 {
101    int ch;
102    setlocale(LC_ALL, "");
103    bindtextdomain("bacula", LOCALEDIR);
104    textdomain("bacula");
105    init_stack_dump();
106    
107    char **files = (char **) malloc (10 * sizeof(char *));
108    int i;
109    my_name_is(argc, argv, "bbatch");
110    init_msg(NULL, NULL);
111
112    OSDependentInit();
113
114    while ((ch = getopt(argc, argv, "h:c:d:n:P:Su:vf:w:?")) != -1) {
115       switch (ch) {
116       case 'd':                    /* debug level */
117          if (*optarg == 't') {
118             dbg_timestamp = true;
119          } else {
120             debug_level = atoi(optarg);
121             if (debug_level <= 0) {
122                debug_level = 1;
123             }
124          }
125          break;
126
127       case 'h':
128          db_host = optarg;
129          break;
130
131       case 'n':
132          db_name = optarg;
133          break;
134
135       case 'w':
136          working_directory = optarg;
137          break;
138
139       case 'u':
140          db_user = optarg;
141          break;
142
143       case 'P':
144          db_password = optarg;
145          break;
146
147       case 'v':
148          verbose++;
149          break;
150
151       case 'f':
152          if (nb < 10 ) {
153             files[nb++] = optarg;
154          }
155          break;
156
157       case '?':
158       default:
159          usage();
160
161       }
162    }
163    argc -= optind;
164    argv += optind;
165
166    if (argc != 0) {
167       Pmsg0(0, _("Wrong number of arguments: \n"));
168       usage();
169    }
170
171 #ifdef HAVE_BATCH_FILE_INSERT
172    printf("With new Batch mode\n");
173 #else
174    printf("Without new Batch mode\n");
175 #endif
176    i = nb;
177    while (--i >= 0) {
178       pthread_t thid;
179       JCR *bjcr = new_jcr(sizeof(JCR), NULL);
180       bjcr->bsr = NULL;
181       bjcr->VolSessionId = 1;
182       bjcr->VolSessionTime = (uint32_t)time(NULL);
183       bjcr->NumReadVolumes = 0;
184       bjcr->NumWriteVolumes = 0;
185       bjcr->JobId = getpid();
186       bjcr->set_JobType(JT_CONSOLE);
187       bjcr->set_JobLevel(L_FULL);
188       bjcr->JobStatus = JS_Running;
189       bjcr->where = bstrdup(files[i]);
190       bjcr->job_name = get_pool_memory(PM_FNAME);
191       pm_strcpy(bjcr->job_name, "Dummy.Job.Name");
192       bjcr->client_name = get_pool_memory(PM_FNAME);
193       pm_strcpy(bjcr->client_name, "Dummy.Client.Name");
194       bstrncpy(bjcr->Job, "bbatch", sizeof(bjcr->Job));
195       bjcr->fileset_name = get_pool_memory(PM_FNAME);
196       pm_strcpy(bjcr->fileset_name, "Dummy.fileset.name");
197       bjcr->fileset_md5 = get_pool_memory(PM_FNAME);
198       pm_strcpy(bjcr->fileset_md5, "Dummy.fileset.md5");
199       
200       if ((db=db_init_database(NULL, db_name, db_user, db_password,
201                                db_host, 0, NULL, 0)) == NULL) {
202          Emsg0(M_ERROR_TERM, 0, _("Could not init Bacula database\n"));
203       }
204       if (!db_open_database(NULL, db)) {
205          Emsg0(M_ERROR_TERM, 0, db_strerror(db));
206       }
207       Dmsg0(200, "Database opened\n");
208       if (verbose) {
209          Pmsg2(000, _("Using Database: %s, User: %s\n"), db_name, db_user);
210       }
211       
212       bjcr->db = db;
213
214       pthread_create(&thid, NULL, do_batch, bjcr);
215    }
216
217    while (nb > 0) {
218       bmicrosleep(1,0);
219    }
220
221    return 0;
222 }
223
224 static void fill_attr(ATTR_DBR *ar, char *data)
225 {
226    char *p;
227    char *b;
228    int index=0;
229    ar->Stream = STREAM_UNIX_ATTRIBUTES;
230    ar->JobId = getpid();
231
232    for(p = b = data; *p; p++) {
233       if (*p == ';') {
234          *p = '\0';
235          switch (index) {
236          case 0:
237             ar->FileIndex = str_to_int64(b);
238             break;
239          case 1:
240             ar->fname = b;
241             break;
242          case 2:
243             ar->attr = b;
244             break;
245          case 3:
246             ar->Digest = b;
247             break;
248          }
249          index++;
250          b = ++p;
251       }
252    }
253 }
254
255 static void *do_batch(void *jcr)
256 {
257    JCR *bjcr = (JCR *)jcr;
258    char data[1024];
259    int lineno = 0;
260    struct ATTR_DBR ar;
261    memset(&ar, 0, sizeof(ar));
262    btime_t begin = get_current_btime();
263    char *datafile = bjcr->where;
264
265    FILE *fd = fopen(datafile, "r");
266    if (!fd) {
267       Emsg1(M_ERROR_TERM, 0, _("Error opening datafile %s\n"), datafile);
268    }
269    while (fgets(data, sizeof(data)-1, fd)) {
270       strip_trailing_newline(data);
271       lineno++;
272       if (verbose && ((lineno % 5000) == 1)) {
273          printf("\r%i", lineno);
274       }
275       fill_attr(&ar, data);
276       if (!db_create_file_attributes_record(bjcr, bjcr->db, &ar)) {
277          Emsg0(M_ERROR_TERM, 0, _("Error while inserting file\n"));
278       }
279    }
280    fclose(fd);
281    db_write_batch_file_records(bjcr);
282    btime_t end = get_current_btime();
283    
284    P(mutex);
285    char ed1[200], ed2[200];
286    printf("\rbegin = %s, end = %s\n", edit_int64(begin, ed1),edit_int64(end, ed2));
287    printf("Insert time = %sms\n", edit_int64((end - begin) / 10000, ed1));
288    printf("Create %u files at %.2f/s\n", lineno, 
289           (lineno / ((float)((end - begin) / 1000000))));
290    nb--;
291    V(mutex);
292    pthread_exit(NULL);
293    return NULL;
294 }