]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/tools/bbatch.c
Fix logic inversion.
[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 three of the GNU Affero 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 Affero 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 #include "cats/sql_glue.h"
60  
61 /* Forward referenced functions */
62 static void *do_batch(void *);
63
64
65 /* Local variables */
66 static B_DB *db;
67
68 static const char *db_name = "bacula";
69 static const char *db_user = "bacula";
70 static const char *db_password = "";
71 static const char *db_host = NULL;
72
73 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
74
75 static void usage()
76 {
77    fprintf(stderr, _(
78 PROG_COPYRIGHT
79 "\nVersion: %s (%s)\n"
80 "Example : bbatch -w /path/to/workdir -h localhost -f dat1 -f dat -f datx\n"
81 " will start 3 thread and load dat1, dat and datx in your catalog\n"
82 "See bbatch.c to generate datafile\n\n"
83 "Usage: bbatch [ options ] -w working/dir -f datafile\n"
84 "       -b                with batch mode\n"
85 "       -B                without batch mode\n"
86 "       -d <nn>           set debug level to <nn>\n"
87 "       -dt               print timestamp in debug output\n"
88 "       -n <name>         specify the database name (default bacula)\n"
89 "       -u <user>         specify database user name (default bacula)\n"
90 "       -P <password      specify database password (default none)\n"
91 "       -h <host>         specify database host (default NULL)\n"
92 "       -w <working>      specify working directory\n"
93 "       -r <jobids>       call restore code with given jobids\n"
94 "       -v                verbose\n"
95 "       -f <file>         specify data file\n"
96 "       -?                print this message\n\n"), 2001, VERSION, BDATE);
97    exit(1);
98 }
99
100 /* number of thread started */
101 int nb=0;
102
103 static int list_handler(void *ctx, int num_fields, char **row)
104 {
105    uint64_t *a = (uint64_t*) ctx;
106    (*a)++;
107    return 0;
108 }
109
110 int main (int argc, char *argv[])
111 {
112    int ch;
113    bool disable_batch = false;
114    char *restore_list=NULL;
115    setlocale(LC_ALL, "");
116    bindtextdomain("bacula", LOCALEDIR);
117    textdomain("bacula");
118    init_stack_dump();
119    lmgr_init_thread();
120    
121    char **files = (char **) malloc (10 * sizeof(char *));
122    int i;
123    my_name_is(argc, argv, "bbatch");
124    init_msg(NULL, NULL);
125
126    OSDependentInit();
127
128    while ((ch = getopt(argc, argv, "bBh:c:d:n:P:Su:vf:w:r:?")) != -1) {
129       switch (ch) {
130       case 'r':
131          restore_list=bstrdup(optarg);
132          break;
133       case 'B':
134          disable_batch = true;
135          break;
136       case 'b':
137          disable_batch = false;
138          break;
139       case 'd':                    /* debug level */
140          if (*optarg == 't') {
141             dbg_timestamp = true;
142          } else {
143             debug_level = atoi(optarg);
144             if (debug_level <= 0) {
145                debug_level = 1;
146             }
147          }
148          break;
149
150       case 'h':
151          db_host = optarg;
152          break;
153
154       case 'n':
155          db_name = optarg;
156          break;
157
158       case 'w':
159          working_directory = optarg;
160          break;
161
162       case 'u':
163          db_user = optarg;
164          break;
165
166       case 'P':
167          db_password = optarg;
168          break;
169
170       case 'v':
171          verbose++;
172          break;
173
174       case 'f':
175          if (nb < 10 ) {
176             files[nb++] = optarg;
177          }
178          break;
179
180       case '?':
181       default:
182          usage();
183
184       }
185    }
186    argc -= optind;
187    argv += optind;
188
189    if (argc != 0) {
190       Pmsg0(0, _("Wrong number of arguments: \n"));
191       usage();
192    }
193
194    if (restore_list) {
195       uint64_t nb_file=0;
196       btime_t start, end;
197       /* To use the -r option, the catalog should already contains records */
198       
199       if ((db = db_init_database(NULL, NULL, db_name, db_user, db_password,
200                                  db_host, 0, NULL, false, disable_batch)) == NULL) {
201          Emsg0(M_ERROR_TERM, 0, _("Could not init Bacula database\n"));
202       }
203       if (!db_open_database(NULL, db)) {
204          Emsg0(M_ERROR_TERM, 0, db_strerror(db));
205       }
206
207       start = get_current_btime();
208       db_get_file_list(NULL, db, restore_list, false, false, list_handler, &nb_file);
209       end = get_current_btime();
210
211       Pmsg3(0, _("Computing file list for jobid=%s files=%lld secs=%d\n"), 
212             restore_list, nb_file, (uint32_t)btime_to_unix(end-start));
213       
214       free(restore_list);
215       return 0;
216    }
217
218    if (disable_batch) {
219       printf("Without new Batch mode\n");
220    } else {
221       printf("With new Batch mode\n");
222    }
223
224    i = nb;
225    while (--i >= 0) {
226       pthread_t thid;
227       JCR *bjcr = new_jcr(sizeof(JCR), NULL);
228       bjcr->bsr = NULL;
229       bjcr->VolSessionId = 1;
230       bjcr->VolSessionTime = (uint32_t)time(NULL);
231       bjcr->NumReadVolumes = 0;
232       bjcr->NumWriteVolumes = 0;
233       bjcr->JobId = getpid();
234       bjcr->set_JobType(JT_CONSOLE);
235       bjcr->set_JobLevel(L_FULL);
236       bjcr->JobStatus = JS_Running;
237       bjcr->where = bstrdup(files[i]);
238       bjcr->job_name = get_pool_memory(PM_FNAME);
239       pm_strcpy(bjcr->job_name, "Dummy.Job.Name");
240       bjcr->client_name = get_pool_memory(PM_FNAME);
241       pm_strcpy(bjcr->client_name, "Dummy.Client.Name");
242       bstrncpy(bjcr->Job, "bbatch", sizeof(bjcr->Job));
243       bjcr->fileset_name = get_pool_memory(PM_FNAME);
244       pm_strcpy(bjcr->fileset_name, "Dummy.fileset.name");
245       bjcr->fileset_md5 = get_pool_memory(PM_FNAME);
246       pm_strcpy(bjcr->fileset_md5, "Dummy.fileset.md5");
247       
248       if ((db = db_init_database(NULL, NULL, db_name, db_user, db_password,
249                                  db_host, 0, NULL, false, false)) == NULL) {
250          Emsg0(M_ERROR_TERM, 0, _("Could not init Bacula database\n"));
251       }
252       if (!db_open_database(NULL, db)) {
253          Emsg0(M_ERROR_TERM, 0, db_strerror(db));
254       }
255       Dmsg0(200, "Database opened\n");
256       if (verbose) {
257          Pmsg2(000, _("Using Database: %s, User: %s\n"), db_name, db_user);
258       }
259       
260       bjcr->db = db;
261
262       pthread_create(&thid, NULL, do_batch, bjcr);
263    }
264
265    while (nb > 0) {
266       bmicrosleep(1,0);
267    }
268
269    return 0;
270 }
271
272 static void fill_attr(ATTR_DBR *ar, char *data)
273 {
274    char *p;
275    char *b;
276    int index=0;
277    ar->Stream = STREAM_UNIX_ATTRIBUTES;
278    ar->JobId = getpid();
279
280    for(p = b = data; *p; p++) {
281       if (*p == ';') {
282          *p = '\0';
283          switch (index) {
284          case 0:
285             ar->FileIndex = str_to_int64(b);
286             break;
287          case 1:
288             ar->fname = b;
289             break;
290          case 2:
291             ar->attr = b;
292             break;
293          case 3:
294             ar->Digest = b;
295             break;
296          }
297          index++;
298          b = ++p;
299       }
300    }
301 }
302
303 static void *do_batch(void *jcr)
304 {
305    JCR *bjcr = (JCR *)jcr;
306    char data[1024];
307    int lineno = 0;
308    struct ATTR_DBR ar;
309    memset(&ar, 0, sizeof(ar));
310    btime_t begin = get_current_btime();
311    char *datafile = bjcr->where;
312
313    FILE *fd = fopen(datafile, "r");
314    if (!fd) {
315       Emsg1(M_ERROR_TERM, 0, _("Error opening datafile %s\n"), datafile);
316    }
317    while (fgets(data, sizeof(data)-1, fd)) {
318       strip_trailing_newline(data);
319       lineno++;
320       if (verbose && ((lineno % 5000) == 1)) {
321          printf("\r%i", lineno);
322       }
323       fill_attr(&ar, data);
324       if (!db_create_attributes_record(bjcr, bjcr->db, &ar)) {
325          Emsg0(M_ERROR_TERM, 0, _("Error while inserting file\n"));
326       }
327    }
328    fclose(fd);
329    db_write_batch_file_records(bjcr);
330    btime_t end = get_current_btime();
331    
332    P(mutex);
333    char ed1[200], ed2[200];
334    printf("\rbegin = %s, end = %s\n", edit_int64(begin, ed1),edit_int64(end, ed2));
335    printf("Insert time = %sms\n", edit_int64((end - begin) / 10000, ed1));
336    printf("Create %u files at %.2f/s\n", lineno, 
337           (lineno / ((float)((end - begin) / 1000000))));
338    nb--;
339    V(mutex);
340    pthread_exit(NULL);
341    return NULL;
342 }