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