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