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