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