1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 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 * This file handles accepting Director Commands
21 *
22 * Most Director commands are handled here, with the
23 * exception of the Job command command and subsequent
24 * subcommands that are handled
25 * in job.c.
26 *
27 * N.B. in this file, in general we must use P(dev->mutex) rather
28 * than dev->rLock() so that we can examine the blocked
29 * state rather than blocking ourselves because a Job
30 * thread has the device blocked. In some "safe" cases,
31 * we can do things to a blocked device. CAREFUL!!!!
32 *
33 * File daemon commands are handled in fdcmd.c
34 *
35 * Written by Kern Sibbald, May MMI
36 *
37 */
38
39 #include "bacula.h"
40 #include "stored.h"
41
42 /* Exported variables */
43
44 /* Imported variables */
45 extern BSOCK *filed_chan;
46 extern struct s_last_job last_job;
47 extern bool init_done;
48
49 /* Static variables */
50 static char derrmsg[] = "3900 Invalid command:";
51 static char OKsetdebug[] = "3000 OK setdebug=%ld trace=%ld options=%s tags=%s\n";
52 static char invalid_cmd[] = "3997 Invalid command for a Director with Monitor directive enabled.\n";
53 static char OK_bootstrap[] = "3000 OK bootstrap\n";
54 static char ERROR_bootstrap[] = "3904 Error bootstrap\n";
55 static char OKclient[] = "3000 OK client command\n";
56
57 /* Imported functions */
58 extern void terminate_child();
59 extern bool job_cmd(JCR *jcr);
60 extern bool use_cmd(JCR *jcr);
61 extern bool run_cmd(JCR *jcr);
62 extern bool status_cmd(JCR *sjcr);
63 extern bool qstatus_cmd(JCR *jcr);
64 extern bool collect_cmd(JCR *jcr);
65 //extern bool query_cmd(JCR *jcr);
66
67 /* Forward referenced functions */
68 static bool client_cmd(JCR *jcr);
69 static bool storage_cmd(JCR *jcr);
70 static bool label_cmd(JCR *jcr);
71 static bool die_cmd(JCR *jcr);
72 static bool relabel_cmd(JCR *jcr);
73 static bool truncate_cache_cmd(JCR *jcr);
74 static bool upload_cmd(JCR *jcr);
75 static bool readlabel_cmd(JCR *jcr);
76 static bool release_cmd(JCR *jcr);
77 static bool setdebug_cmd(JCR *jcr);
78 static bool cancel_cmd(JCR *cjcr);
79 static bool mount_cmd(JCR *jcr);
80 static bool unmount_cmd(JCR *jcr);
81 static bool enable_cmd(JCR *jcr);
82 static bool disable_cmd(JCR *jcr);
83 //static bool action_on_purge_cmd(JCR *jcr);
84 static bool bootstrap_cmd(JCR *jcr);
85 static bool cloud_list_cmd(JCR *jcr);
86 static bool cloud_prunecache_cmd(JCR *jcr);
87 static bool changer_cmd(JCR *sjcr);
88 static bool do_label(JCR *jcr, int relabel);
89 static DCR *find_device(JCR *jcr, POOL_MEM &dev_name,
90 POOLMEM *media_type, int drive);
91 static DCR *find_any_device(JCR *jcr, POOL_MEM &dev_name,
92 POOLMEM *media_type, int drive);
93 static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot);
94 static void label_volume_if_ok(DCR *dcr, char *oldname,
95 char *newname, char *poolname,
96 int Slot, int relabel);
97 static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName);
98 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev);
99
100 /* Responses send to Director for storage command */
101 static char BADcmd[] = "2902 Bad %s\n";
102 static char OKstore[] = "2000 OK storage\n";
103
104 /* Commands received from director that need scanning */
105 static char storaddr[] = "storage address=%s port=%d ssl=%d Job=%127s Authentication=%127s";
106
107 struct s_cmds {
108 const char *cmd;
109 bool (*func)(JCR *jcr);
110 bool monitoraccess; /* set if monitors can access this cmd */
111 };
112
113 /*
114 * The following are the recognized commands from the Director.
115 */
116 static struct s_cmds cmds[] = {
117 {"JobId=", job_cmd, 0}, /* start Job */
118 {"autochanger", changer_cmd, 0},
119 {"bootstrap", bootstrap_cmd, 0},
120 {"cancel", cancel_cmd, 0},
121 {"client", client_cmd, 0}, /* client address */
122 {".die", die_cmd, 0},
123 {"label", label_cmd, 0}, /* label a tape */
124 {"mount", mount_cmd, 0},
125 {"enable", enable_cmd, 0},
126 {"disable", disable_cmd, 0},
127 {"readlabel", readlabel_cmd, 0},
128 {"release", release_cmd, 0},
129 {"relabel", relabel_cmd, 0}, /* relabel a tape */
130 {"setdebug=", setdebug_cmd, 0}, /* set debug level */
131 {"status", status_cmd, 1},
132 {".status", qstatus_cmd, 1},
133 {"stop", cancel_cmd, 0},
134 {"storage", storage_cmd, 0}, /* get SD addr from Dir */
135 {"truncate", truncate_cache_cmd, 0},
136 {"upload", upload_cmd, 0},
137 {"prunecache", cloud_prunecache_cmd, 0},
138 {"cloudlist", cloud_list_cmd, 0}, /* List volumes/parts in the cloud */
139 {"unmount", unmount_cmd, 0},
140 {"use storage=", use_cmd, 0},
141 {"run", run_cmd, 0},
142 {"statistics", collect_cmd, 0},
143 // {"query", query_cmd, 0},
144 {NULL, NULL} /* list terminator */
145 };
146
147
148 /*
149 * Connection request. We accept connections either from the
150 * Director or a Client (File daemon).
151 *
152 * Note, we are running as a separate thread of the Storage daemon.
153 * and it is because a Director has made a connection with
154 * us on the "Message" channel.
155 *
156 * Basic tasks done here:
157 * - Create a JCR record
158 * - If it was from the FD, call handle_filed_connection()
159 * - Authenticate the Director
160 * - We wait for a command
161 * - We execute the command
162 * - We continue or exit depending on the return status
163 */
handle_connection_request(void * arg)164 void *handle_connection_request(void *arg)
165 {
166 BSOCK *bs = (BSOCK *)arg;
167 JCR *jcr;
168 int i;
169 bool found, quit;
170 int bnet_stat = 0;
171 char tbuf[100];
172
173 if (bs->recv() <= 0) {
174 Qmsg1(NULL, M_ERROR, 0, _("Connection request from %s failed.\n"), bs->who());
175 bmicrosleep(5, 0); /* make user wait 5 seconds */
176 bs->destroy();
177 return NULL;
178 }
179
180 /* Check for client connection */
181 if (is_client_connection(bs)) {
182 handle_client_connection(bs);
183 return NULL;
184 }
185
186 /*
187 * This is a connection from the Director, so setup a JCR
188 */
189 Dmsg1(050, "Got a DIR connection at %s\n", bstrftimes(tbuf, sizeof(tbuf),
190 (utime_t)time(NULL)));
191 jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */
192 jcr->dir_bsock = bs; /* save Director bsock */
193 jcr->dir_bsock->set_jcr(jcr);
194 jcr->dcrs = New(alist(10, not_owned_by_alist));
195 create_jobmedia_queue(jcr);
196 /* Initialize FD start condition variable */
197 int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
198 if (errstat != 0) {
199 berrno be;
200 Qmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
201 goto bail_out;
202 }
203
204 Dmsg0(1000, "stored in start_job\n");
205
206 /*
207 * Validate then authenticate the Director
208 */
209 if (!validate_dir_hello(jcr)) {
210 goto bail_out;
211 }
212 if (!authenticate_director(jcr)) {
213 Qmsg(jcr, M_FATAL, 0, _("[SF0100] Unable to authenticate Director\n"));
214 goto bail_out;
215 }
216 Dmsg0(90, "Message channel init completed.\n");
217
218 dequeue_messages(jcr); /* dequeue any daemon messages */
219
220 jcr->set_killable(true); /* allow dir to kill/cancel job */
221
222 for (quit=false; !quit;) {
223 /* Read command */
224 if ((bnet_stat = bs->recv()) <= 0) {
225 break; /* connection terminated */
226 }
227 Dmsg1(199, "<dird: %s\n", bs->msg);
228 /* Ensure that device initialization is complete */
229 while (!init_done) {
230 bmicrosleep(1, 0);
231 }
232 found = false;
233 for (i=0; cmds[i].cmd; i++) {
234 if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) {
235 if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
236 Dmsg1(100, "Command \"%s\" is invalid.\n", cmds[i].cmd);
237 bs->fsend(invalid_cmd);
238 bs->signal(BNET_EOD);
239 break;
240 }
241 Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
242 if (!cmds[i].func(jcr)) { /* do command */
243 quit = true; /* error, get out */
244 Dmsg1(190, "Command %s requests quit\n", cmds[i].cmd);
245 }
246 found = true; /* indicate command found */
247 break;
248 }
249 }
250 if (!found) { /* command not found */
251 POOL_MEM err_msg;
252 Mmsg(err_msg, "%s %s\n", derrmsg, bs->msg);
253 bs->fsend(err_msg.c_str());
254 break;
255 }
256 }
257 bail_out:
258 generate_daemon_event(jcr, "JobEnd");
259 generate_plugin_event(jcr, bsdEventJobEnd);
260 flush_jobmedia_queue(jcr);
261 dequeue_messages(jcr); /* send any queued messages */
262 dequeue_daemon_messages(jcr);
263 bs->signal(BNET_TERMINATE);
264 bs->destroy();
265 jcr->dir_bsock = NULL; /* just freed bsock */
266 free_plugins(jcr); /* release instantiated plugins */
267 free_jcr(jcr);
268 return NULL;
269 }
270
271
272 /*
273 * Force SD to die, and hopefully dump itself. Turned on only
274 * in development version.
275 */
die_cmd(JCR * jcr)276 static bool die_cmd(JCR *jcr)
277 {
278 #ifdef DEVELOPER
279 JCR *djcr = NULL;
280 int a;
281 BSOCK *dir = jcr->dir_bsock;
282 pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER;
283
284 if (strstr(dir->msg, "deadlock")) {
285 Pmsg0(000, "I have been requested to deadlock ...\n");
286 P(m);
287 P(m);
288 }
289
290 Pmsg1(000, "I have been requested to die ... (%s)\n", dir->msg);
291 a = djcr->JobId; /* ref NULL pointer */
292 djcr->JobId = a;
293 #endif
294 return 0;
295 }
296
297 /*
298 * Get address of client from Director
299 * This initiates SD Calls Client.
300 * We attempt to connect to the client (an FD or SD) and
301 * authenticate it.
302 */
client_cmd(JCR * jcr)303 static bool client_cmd(JCR *jcr)
304 {
305 int client_port; /* client port */
306 int enable_ssl; /* enable ssl */
307 BSOCK *dir = jcr->dir_bsock;
308 BSOCK *cl = new_bsock(); /* client bsock */
309
310 Dmsg1(100, "ClientCmd: %s", dir->msg);
311 jcr->sd_calls_client = true;
312 if (sscanf(dir->msg, "client address=%127s port=%d ssl=%d", jcr->client_addr, &client_port,
313 &enable_ssl) != 3) {
314 pm_strcpy(jcr->errmsg, dir->msg);
315 Jmsg(jcr, M_FATAL, 0, _("[SF0101] Bad client command: %s"), jcr->errmsg);
316 Dmsg1(050, "Bad client command: %s", jcr->errmsg);
317 goto bail_out;
318 }
319
320 Dmsg3(110, "Connect to client: %s:%d ssl=%d\n", jcr->client_addr, client_port,
321 enable_ssl);
322 /* Open command communications with Client */
323 /* Try to connect for 1 hour at 10 second intervals */
324 if (!cl->connect(jcr, 10, (int)me->ClientConnectTimeout, me->heartbeat_interval,
325 _("Client daemon"), jcr->client_addr, NULL, client_port, 1)) {
326 /* destroy() OK because cl is local */
327 cl->destroy();
328 Jmsg(jcr, M_FATAL, 0, _("[SF0102] Failed to connect to Client daemon: %s:%d\n"),
329 jcr->client_addr, client_port);
330 Dmsg2(100, "Failed to connect to Client daemon: %s:%d\n",
331 jcr->client_addr, client_port);
332 goto bail_out;
333 }
334 Dmsg0(110, "SD connection OK to Client.\n");
335
336 jcr->file_bsock = cl;
337 jcr->file_bsock->set_jcr(jcr);
338 if (!send_hello_client(jcr, jcr->Job)) {
339 goto bail_out;
340 }
341
342 /* Send OK to Director */
343 return dir->fsend(OKclient);
344
345 bail_out:
346 jcr->setJobStatus(JS_ErrorTerminated);
347 dir->fsend("3902 Bad %s cmd\n", "client");
348 return 0;
349 }
350
351 /*
352 * Get address of storage daemon from Director
353 */
storage_cmd(JCR * jcr)354 static bool storage_cmd(JCR *jcr)
355 {
356 int stored_port; /* storage daemon port */
357 int enable_ssl; /* enable ssl to sd */
358 char sd_auth_key[200];
359 BSOCK *dir = jcr->dir_bsock;
360 BSOCK *sd = new_bsock(); /* storage daemon bsock */
361 char Job[MAX_NAME_LENGTH];
362
363 Dmsg1(050, "StorageCmd: %s", dir->msg);
364 if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port,
365 &enable_ssl, Job, sd_auth_key) != 5) {
366 pm_strcpy(jcr->errmsg, dir->msg);
367 Jmsg(jcr, M_FATAL, 0, _("[SF0103] Bad storage command: %s"), jcr->errmsg);
368 Pmsg1(010, "Bad storage command: %s", jcr->errmsg);
369 goto bail_out;
370 }
371
372 unbash_spaces(Job);
373 if (jcr->sd_auth_key) {
374 bfree_and_null(jcr->sd_auth_key);
375 jcr->sd_auth_key = bstrdup(sd_auth_key);
376 }
377 if (stored_port != 0) {
378 Dmsg2(050, "sd_calls=%d sd_client=%d\n", jcr->sd_calls_client,
379 jcr->sd_client);
380 jcr->sd_calls_client = false; /* We are doing the connecting */
381 Dmsg3(050, "Connect to storage and wait: %s:%d ssl=%d\n", jcr->stored_addr, stored_port,
382 enable_ssl);
383 /* Open command communications with Storage daemon */
384 /* Try to connect for 1 hour at 10 second intervals */
385 if (!sd->connect(jcr, 10, (int)me->ClientConnectTimeout, me->heartbeat_interval,
386 _("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1)) {
387 /* destroy() OK because sd is local */
388 sd->destroy();
389 Jmsg(jcr, M_FATAL, 0, _("[SF0104] Failed to connect to Storage daemon: %s:%d\n"),
390 jcr->stored_addr, stored_port);
391 Dmsg2(010, "Failed to connect to Storage daemon: %s:%d\n",
392 jcr->stored_addr, stored_port);
393 goto bail_out;
394 }
395
396 Dmsg0(050, "Connection OK to SD.\n");
397
398 jcr->store_bsock = sd;
399 } else { /* The storage daemon called us */
400 jcr->sd_calls_client = true;
401 /* We should already have a storage connection! */
402 if (jcr->file_bsock && jcr->store_bsock == NULL) {
403 jcr->store_bsock = jcr->file_bsock;
404 }
405 if (jcr->store_bsock == NULL) {
406 Jmsg0(jcr, M_FATAL, 0, _("[SF0105] In storage_cmd port==0, no prior Storage connection.\n"));
407 Pmsg0(010, "In storage_cmd port==0, no prior Storage connection.\n");
408 goto bail_out;
409 }
410 }
411
412 if (!send_hello_sd(jcr, Job)) {
413 goto bail_out;
414 }
415
416 if (!authenticate_storagedaemon(jcr)) {
417 goto bail_out;
418 }
419 /*
420 * We are a client so we read from the socket we just
421 * opened as if we were a FD, so set file_bsock and
422 * clear the store_bsock.
423 */
424 jcr->file_bsock = jcr->store_bsock;
425 jcr->store_bsock = NULL;
426 jcr->authenticated = true; /* Dir authentication is sufficient */
427 Dmsg1(050, "=== Storage_cmd authenticated Job=%s with SD.\n", Job);
428
429 /* Send OK to Director */
430 return dir->fsend(OKstore);
431
432 bail_out:
433 Dmsg0(100, "Send storage command failed.\n");
434 dir->fsend(BADcmd, "storage");
435 return false;
436 }
437
438
439 /*
440 * Set debug level as requested by the Director
441 *
442 */
setdebug_cmd(JCR * jcr)443 static bool setdebug_cmd(JCR *jcr)
444 {
445 BSOCK *dir = jcr->dir_bsock;
446 int32_t trace_flag, lvl, hangup, blowup;
447 int64_t level, level_tags = 0;
448 char options[60];
449 char tags[512];
450 *tags = *options = 0;
451
452 Dmsg1(10, "setdebug_cmd: %s", dir->msg);
453
454 if (sscanf(dir->msg, "setdebug=%ld trace=%ld hangup=%ld blowup=%ld options=%55s tags=%511s",
455 &lvl, &trace_flag, &hangup, &blowup, options, tags) != 6)
456 {
457 if (sscanf(dir->msg, "setdebug=%ld trace=%ld", &lvl, &trace_flag) != 2 || lvl < 0) {
458 dir->fsend(_("3991 Bad setdebug command: %s\n"), dir->msg);
459 return 0;
460 }
461 }
462 level = lvl;
463 set_trace(trace_flag);
464 set_hangup(hangup);
465 set_blowup(blowup);
466 set_debug_flags(options);
467 if (!debug_parse_tags(tags, &level_tags)) {
468 *tags = 0;
469 }
470 if (level >= 0) {
471 debug_level = level;
472 }
473 debug_level_tags = level_tags;
474
475 /* TODO: Temp code to activate the new BSR optimisation code */
476 for (char *p = options; *p ; p++) {
477 switch(*p) {
478 case 'i': /* Use new match_bsr() code */
479 use_new_match_all = 1;
480 break;
481 case '0':
482 use_new_match_all = 0;
483 break;
484 }
485 }
486 /* **** */
487
488 return dir->fsend(OKsetdebug, lvl, trace_flag, options, tags);
489 }
490
491
492 /*
493 * Cancel a Job
494 * Be careful, we switch to using the job's JCR! So, using
495 * BSOCKs on that jcr can have two threads in the same code.
496 */
cancel_cmd(JCR * cjcr)497 static bool cancel_cmd(JCR *cjcr)
498 {
499 BSOCK *dir = cjcr->dir_bsock;
500 int oldStatus;
501 char Job[MAX_NAME_LENGTH];
502 JCR *jcr;
503 int status;
504 const char *reason;
505
506 if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
507 status = JS_Canceled;
508 reason = "canceled";
509 } else if (sscanf(dir->msg, "stop Job=%127s", Job) == 1) {
510 status = JS_Incomplete;
511 reason = "stopped";
512 } else {
513 dir->fsend(_("3903 Error scanning cancel command.\n"));
514 goto bail_out;
515 }
516 if (!(jcr=get_jcr_by_full_name(Job))) {
517 dir->fsend(_("3904 Job %s not found.\n"), Job);
518 } else {
519 oldStatus = jcr->JobStatus;
520 jcr->setJobStatus(status);
521 Dmsg2(800, "Cancel JobId=%d %p\n", jcr->JobId, jcr);
522 if (!jcr->authenticated && oldStatus == JS_WaitFD) {
523 pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
524 }
525 if (jcr->file_bsock) {
526 jcr->file_bsock->set_terminated();
527 jcr->file_bsock->set_timed_out();
528 Dmsg2(800, "Term bsock jid=%d %p\n", jcr->JobId, jcr);
529 } else {
530 /* Still waiting for FD to connect, release it */
531 pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
532 Dmsg2(800, "Signal FD connect jid=%d %p\n", jcr->JobId, jcr);
533 }
534 /* If thread waiting on mount, wake him */
535 if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
536 pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
537 Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
538 pthread_cond_broadcast(&wait_device_release);
539 }
540 if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->waiting_for_mount()) {
541 pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
542 Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
543 pthread_cond_broadcast(&wait_device_release);
544 }
545 jcr->my_thread_send_signal(TIMEOUT_SIGNAL);
546 dir->fsend(_("3000 JobId=%ld Job=\"%s\" marked to be %s.\n"),
547 jcr->JobId, jcr->Job, reason);
548 free_jcr(jcr);
549 }
550
551 bail_out:
552 dir->signal(BNET_EOD);
553 return 1;
554 }
555
556 /*
557 * Label a Volume
558 *
559 */
label_cmd(JCR * jcr)560 static bool label_cmd(JCR *jcr)
561 {
562 return do_label(jcr, 0);
563 }
564
relabel_cmd(JCR * jcr)565 static bool relabel_cmd(JCR *jcr)
566 {
567 return do_label(jcr, 1);
568 }
569
do_label(JCR * jcr,int relabel)570 static bool do_label(JCR *jcr, int relabel)
571 {
572 POOLMEM *newname, *oldname, *poolname, *mtype;
573 POOL_MEM dev_name;
574 BSOCK *dir = jcr->dir_bsock;
575 DCR *dcr = NULL;;
576 DEVICE *dev;
577 bool ok = false;
578 int32_t slot, drive;
579
580 newname = get_memory(dir->msglen+1);
581 oldname = get_memory(dir->msglen+1);
582 poolname = get_memory(dir->msglen+1);
583 mtype = get_memory(dir->msglen+1);
584 if (relabel) {
585 if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s "
586 "MediaType=%127s Slot=%d drive=%d",
587 dev_name.c_str(), oldname, newname, poolname, mtype,
588 &slot, &drive) == 7) {
589 ok = true;
590 }
591 } else {
592 *oldname = 0;
593 if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s "
594 "MediaType=%127s Slot=%d drive=%d",
595 dev_name.c_str(), newname, poolname, mtype, &slot, &drive) == 6) {
596 ok = true;
597 }
598 }
599 if (ok) {
600 unbash_spaces(newname);
601 unbash_spaces(oldname);
602 unbash_spaces(poolname);
603 unbash_spaces(mtype);
604 dcr = find_device(jcr, dev_name, mtype, drive);
605 if (dcr) {
606 uint32_t max_jobs;
607 dev = dcr->dev;
608 ok = true;
609 dev->Lock(); /* Use P to avoid indefinite block */
610 max_jobs = dev->max_concurrent_jobs;
611 dev->max_concurrent_jobs = 1;
612 bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
613 if (dcr->can_i_write_volume()) {
614 if (reserve_volume(dcr, newname) == NULL) {
615 ok = false;
616 }
617 Dmsg1(400, "Reserved Volume=\"%s\" for relabel/truncate.\n", newname);
618 } else {
619 ok = false;
620 }
621 if (!ok) {
622 dir->fsend(_("3908 Error reserving Volume=\"%s\": %s"), newname, jcr->errmsg);
623 dev->max_concurrent_jobs = max_jobs;
624 dev->Unlock();
625 goto bail_out;
626 }
627 /* ***FIXME*** truncate_option not implemented yet */
628
629 /* some command use recv and don't accept catalog update.
630 * it's not the case here, so we force dir_update_volume_info catalog update */
631 dcr->force_update_volume_info = true;
632
633 if (!dev->is_open() && !dev->is_busy()) {
634 Dmsg1(400, "Can %slabel. Device is not open\n", relabel?"re":"");
635 label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
636 dev->close(dcr);
637 /* Under certain "safe" conditions, we can steal the lock */
638 } else if (dev->can_obtain_block()) {
639 Dmsg0(400, "Can relabel. can_obtain_block\n");
640 label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
641 } else if (dev->is_busy() || dev->is_blocked()) {
642 send_dir_busy_message(dir, dev);
643 } else { /* device not being used */
644 Dmsg0(400, "Can relabel. device not used\n");
645 label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
646 }
647 dev->max_concurrent_jobs = max_jobs;
648 volume_unused(dcr);
649 dev->Unlock();
650 #ifdef DEVELOPER
651 if (chk_dbglvl(DT_VOLUME)) {
652 Dmsg0(0, "Waiting few seconds to force a bug...\n");
653 bmicrosleep(30, 0);
654 Dmsg0(0, "Doing free_volume()\n");
655 }
656 #endif
657 } else {
658 dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
659 }
660 } else {
661 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
662 pm_strcpy(jcr->errmsg, dir->msg);
663 dir->fsend(_("3903 Error scanning label command: %s\n"), jcr->errmsg);
664 }
665 bail_out:
666 if (dcr) {
667 free_dcr(dcr);
668 }
669 free_memory(oldname);
670 free_memory(newname);
671 free_memory(poolname);
672 free_memory(mtype);
673 dir->signal(BNET_EOD);
674 return true;
675 }
676
677 /*
678 * Handles truncate cache commands
679 */
truncate_cache_cmd(JCR * jcr)680 static bool truncate_cache_cmd(JCR *jcr)
681 {
682 POOLMEM *volname, *poolname, *mtype;
683 POOL_MEM dev_name;
684 BSOCK *dir = jcr->dir_bsock;
685 DCR *dcr = NULL;;
686 DEVICE *dev;
687 bool ok = false;
688 int32_t slot, drive;
689 int nbpart = 0;
690 int64_t size = 0;
691 char ed1[50];
692
693 volname = get_memory(dir->msglen+1);
694 poolname = get_memory(dir->msglen+1);
695 mtype = get_memory(dir->msglen+1);
696 if (sscanf(dir->msg, "truncate cache Storage=%127s Volume=%127s PoolName=%127s "
697 "MediaType=%127s Slot=%d drive=%d",
698 dev_name.c_str(), volname, poolname, mtype,
699 &slot, &drive) == 6) {
700 ok = true;
701 }
702 if (ok) {
703 unbash_spaces(volname);
704 unbash_spaces(poolname);
705 unbash_spaces(mtype);
706 dcr = find_device(jcr, dev_name, mtype, drive);
707 if (dcr) {
708 uint32_t max_jobs;
709 dev = dcr->dev;
710 ok = true;
711 dev->Lock(); /* Use P to avoid indefinite block */
712 max_jobs = dev->max_concurrent_jobs;
713 dev->max_concurrent_jobs = 1;
714 bstrncpy(dcr->VolumeName, volname, sizeof(dcr->VolumeName));
715 if (dcr->can_i_write_volume()) {
716 if (reserve_volume(dcr, volname) == NULL) {
717 ok = false;
718 }
719 Dmsg1(400, "Reserved volume \"%s\"\n", volname);
720 } else {
721 ok = false;
722 }
723 if (!ok) {
724 dir->fsend(_("3908 Error reserving Volume=\"%s\": %s"), volname, jcr->errmsg);
725 dev->max_concurrent_jobs = max_jobs;
726 dev->Unlock();
727 goto bail_out;
728 }
729 if ((!dev->is_open() && !dev->is_busy()) || dev->can_obtain_block()) {
730 Dmsg0(400, "Call truncate_cache\n");
731 nbpart = dev->truncate_cache(dcr, volname, &size);
732 if (nbpart >= 0) {
733 dir->fsend(_("3000 OK truncate cache for volume \"%s\" %d part(s) %sB\n"),
734 volname, nbpart, edit_uint64_with_suffix(size, ed1));
735 } else {
736 dir->fsend(_("3900 Truncate cache for volume \"%s\" failed. ERR=%s\n"), volname, dev->errmsg);
737 }
738 } else if (dev->is_busy() || dev->is_blocked()) {
739 send_dir_busy_message(dir, dev);
740 } else { /* device not being used */
741 Dmsg0(400, "Call truncate_cache\n");
742 nbpart = dev->truncate_cache(dcr, volname, &size);
743 if (nbpart >= 0) {
744 dir->fsend(_("3000 OK truncate cache for volume \"%s\" %d part(s) %sB\n"), volname,
745 nbpart, edit_uint64_with_suffix(size, ed1));
746 } else {
747 dir->fsend(_("3900 Truncate cache for volume \"%s\" failed. ERR=%s\n"), volname, dev->errmsg);
748 }
749 }
750 dev->max_concurrent_jobs = max_jobs;
751 volume_unused(dcr);
752 dev->Unlock();
753 #ifdef DEVELOPER
754 if (chk_dbglvl(DT_VOLUME)) {
755 Dmsg0(0, "Waiting few seconds to force a bug...\n");
756 bmicrosleep(30, 0);
757 Dmsg0(0, "Doing free_volume()\n");
758 }
759 #endif
760 } else {
761 dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
762 }
763 } else {
764 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
765 pm_strcpy(jcr->errmsg, dir->msg);
766 dir->fsend(_("3911 Error scanning truncate command: %s\n"), jcr->errmsg);
767 }
768 bail_out:
769 if (dcr) {
770 free_dcr(dcr);
771 }
772 free_memory(volname);
773 free_memory(poolname);
774 free_memory(mtype);
775 dir->signal(BNET_EOD);
776 return true;
777 }
778
cloud_prunecache_cmd(JCR * jcr)779 static bool cloud_prunecache_cmd(JCR *jcr)
780 {
781 /* TODO: Implement a function to prune the cache of a cloud device */
782 jcr->dir_bsock->fsend(_("3900 Not yet implemented\n"));
783 return true;
784 }
785
786 /* List volumes in the cloud */
cloud_list_cmd(JCR * jcr)787 static bool cloud_list_cmd(JCR *jcr)
788 {
789 BSOCK *dir = jcr->dir_bsock;
790 POOL_MEM dev_name;
791 POOLMEM *errmsg = get_pool_memory(PM_FNAME);
792 errmsg[0] = 0;
793 char volname[MAX_NAME_LENGTH];
794 char mtype[MAX_NAME_LENGTH];
795 int slot, drive;
796 DCR *dcr = NULL;
797
798 if (sscanf(dir->msg, "cloudlist Storage=%127s Volume=%127s MediaType=%127s Slot=%d drive=%d",
799 dev_name.c_str(), volname, mtype, &slot, &drive) != 5) {
800 dir->fsend(_("3912 Error scanning the command\n"));
801 goto bail_out;
802 }
803
804 /* In fact, we do not need to find and reserve a device for this operation,
805 * we just need to find one, idle or not
806 */
807 dcr = find_device(jcr, dev_name, mtype, drive);
808 if (!dcr) {
809 dir->fsend(_("3900 Error reserving device %s %s\n"), dev_name.c_str(), mtype);
810 goto bail_out;
811 }
812
813 if (volname[0] == 0) { /* List all volumes, TODO: Switch to a callback mode */
814 char *vol;
815 alist volumes(100, not_owned_by_alist);
816 if (!dcr->dev->get_cloud_volumes_list(dcr, &volumes, errmsg)) {
817 dir->fsend(_("3900 Error cannot get cloud Volume list. ERR=%s\n"), errmsg);
818 }
819 free_dcr(dcr);
820
821 foreach_alist(vol, &volumes) {
822 bash_spaces(vol);
823 dir->fsend("volume=%s\n", vol);
824 free(vol); /* Walk through the list only one time */
825 }
826
827 } else {
828 ilist parts(100, not_owned_by_alist);
829 if (!dcr->dev->get_cloud_volume_parts_list(dcr, volname, &parts, errmsg)) {
830 dir->fsend(_("3900 Error cannot get cloud Volume list. ERR=%s\n"), errmsg);
831 free_dcr(dcr);
832 goto bail_out;
833 }
834 free_dcr(dcr);
835
836 for (int i=1; i <= parts.last_index() ; i++) {
837 cloud_part *p = (cloud_part *)parts.get(i);
838 if (p) {
839 dir->fsend("part=%d size=%lld mtime=%lld\n", i, p->size, p->mtime);
840 free(p);
841 }
842 }
843 }
844
845 bail_out:
846 free_pool_memory(errmsg);
847 dir->signal(BNET_EOD);
848 return true;
849 }
850
851 /*
852 * Handles upload cache to Cloud command
853 */
upload_cmd(JCR * jcr)854 static bool upload_cmd(JCR *jcr)
855 {
856 POOLMEM *volname, *poolname, *mtype, *err;
857 POOL_MEM dev_name;
858 BSOCK *dir = jcr->dir_bsock;
859 DCR *dcr = NULL;
860 DEVICE *dev;
861 bool ok = false;
862 int32_t slot, drive;
863
864 volname = get_memory(dir->msglen+1);
865 poolname = get_memory(dir->msglen+1);
866 mtype = get_memory(dir->msglen+1);
867 err = get_pool_memory(PM_MESSAGE);
868 *volname = *poolname = *mtype = *err = 0;
869
870 if (sscanf(dir->msg, "upload Storage=%127s Volume=%127s PoolName=%127s "
871 "MediaType=%127s Slot=%d drive=%d",
872 dev_name.c_str(), volname, poolname, mtype,
873 &slot, &drive) == 6) {
874 ok = true;
875 }
876 if (ok) {
877 unbash_spaces(volname);
878 unbash_spaces(poolname);
879 unbash_spaces(mtype);
880 dcr = find_device(jcr, dev_name, mtype, drive);
881 if (dcr) {
882 uint32_t max_jobs;
883 dev = dcr->dev;
884 ok = true;
885 dev->Lock(); /* Use P to avoid indefinite block */
886 max_jobs = dev->max_concurrent_jobs;
887 dev->max_concurrent_jobs = 1;
888 bstrncpy(dcr->VolumeName, volname, sizeof(dcr->VolumeName));
889 if (dcr->can_i_write_volume()) {
890 if (reserve_volume(dcr, volname) == NULL) {
891 ok = false;
892 }
893 Dmsg1(400, "Reserved volume \"%s\"\n", volname);
894 } else {
895 ok = false;
896 }
897 if (!ok) {
898 dir->fsend(_("3908 Error reserving Volume=\"%s\": %s"), volname, jcr->errmsg);
899 dev->max_concurrent_jobs = max_jobs;
900 dev->Unlock();
901 goto bail_out;
902 }
903 if ((!dev->is_open() && !dev->is_busy()) || dev->can_obtain_block()) {
904 Dmsg0(400, "Can upload, because device is not open.\n");
905 dev->setVolCatName(volname);
906 dev->part = 0;
907 if (dev->open_device(dcr, OPEN_READ_WRITE)) {
908 ok = dev->upload_cache(dcr, volname, 0, err);
909 dev->part = 0;
910 dev->close(dcr);
911 dev->end_of_job(dcr, TRUNC_CONF_DEFAULT);
912 }
913 } else if (dev->is_busy() || dev->is_blocked()) {
914 send_dir_busy_message(dir, dev);
915 } else { /* device not being used */
916 Dmsg0(400, "Can upload, because device not used\n");
917 dev->setVolCatName(volname);
918 dev->part = 0;
919 if (dev->open_device(dcr, OPEN_READ_WRITE)) {
920 ok = dev->upload_cache(dcr, volname, 0, err);
921 dev->part = 0;
922 dev->close(dcr);
923 dev->end_of_job(dcr, TRUNC_CONF_DEFAULT);
924 }
925 }
926 dev->max_concurrent_jobs = max_jobs;
927 volume_unused(dcr);
928 dev->Unlock();
929 #ifdef DEVELOPER
930 if (chk_dbglvl(DT_VOLUME)) {
931 Dmsg0(0, "Waiting few seconds to force a bug...\n");
932 bmicrosleep(30, 0);
933 Dmsg0(0, "Doing free_volume()\n");
934 }
935 #endif
936 } else {
937 dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
938 }
939 } else {
940 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
941 pm_strcpy(jcr->errmsg, dir->msg);
942 dir->fsend(_("3912 Error scanning upload command: ERR=%s\n"), jcr->errmsg);
943 }
944 bail_out:
945 if (ok) {
946 dir->fsend(_("3000 OK upload.\n"));
947 } else {
948 dir->fsend(_("3999 Error with the upload: ERR=%s\n"), err);
949 }
950 if (dcr) {
951 free_dcr(dcr);
952 }
953 free_pool_memory(err);
954 free_memory(volname);
955 free_memory(poolname);
956 free_memory(mtype);
957 dir->signal(BNET_EOD);
958 return true;
959 }
960
961
962 /*
963 * Read the tape label and determine if we can safely
964 * label the tape (not a Bacula volume), then label it.
965 *
966 * Enter with the mutex set
967 */
label_volume_if_ok(DCR * dcr,char * oldname,char * newname,char * poolname,int slot,int relabel)968 static void label_volume_if_ok(DCR *dcr, char *oldname,
969 char *newname, char *poolname,
970 int slot, int relabel)
971 {
972 BSOCK *dir = dcr->jcr->dir_bsock;
973 bsteal_lock_t hold;
974 DEVICE *dev = dcr->dev;
975 int label_status;
976 int mode;
977 const char *volname = (relabel == 1) ? oldname : newname;
978 uint64_t volCatBytes;
979
980 if (!obtain_device_block(dev,
981 &hold,
982 1, /* one try */
983 BST_WRITING_LABEL)) {
984 send_dir_busy_message(dir, dev);
985 return;
986 }
987 dev->Unlock();
988
989 Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
990
991 Dmsg0(90, "try_autoload_device - looking for volume_info\n");
992 if (!try_autoload_device(dcr->jcr, dcr, slot, volname)) {
993 goto bail_out; /* error */
994 }
995
996
997 if (relabel) {
998 dev->truncating = true; /* let open_device() know we will truncate it */
999 }
1000 /* Set old volume name for open if relabeling */
1001 dcr->setVolCatName(volname);
1002
1003 /* Ensure that the device is open -- autoload_device() closes it */
1004 if (dev->is_tape()) {
1005 mode = OPEN_READ_WRITE;
1006 } else {
1007 mode = CREATE_READ_WRITE;
1008 }
1009 if (!dev->open_device(dcr, mode)) {
1010 dir->fsend(_("3929 Unable to open device \"%s\": ERR=%s\n"),
1011 dev->print_name(), dev->bstrerror());
1012 goto bail_out;
1013 }
1014
1015 /* See what we have for a Volume */
1016 label_status = dev->read_dev_volume_label(dcr);
1017
1018 /* Set new volume name */
1019 dcr->setVolCatName(newname);
1020 switch(label_status) {
1021 case VOL_NAME_ERROR:
1022 case VOL_VERSION_ERROR:
1023 case VOL_LABEL_ERROR:
1024 case VOL_OK:
1025 if (!relabel) {
1026 dir->fsend(_(
1027 "3920 Cannot label Volume because it is already labeled: \"%s\"\n"),
1028 dev->VolHdr.VolumeName);
1029 break;
1030 }
1031
1032 /* Relabel request. If oldname matches, continue */
1033 if (strcmp(oldname, dev->VolHdr.VolumeName) != 0) {
1034 dir->fsend(_("3921 Wrong volume mounted.\n"));
1035 break;
1036 }
1037 if (dev->label_type != B_BACULA_LABEL) {
1038 dir->fsend(_("3922 Cannot relabel an ANSI/IBM labeled Volume.\n"));
1039 break;
1040 }
1041 /* Fall through wanted! */
1042 case VOL_IO_ERROR:
1043 case VOL_NO_LABEL:
1044 if (!dev->write_volume_label(dcr, newname, poolname,
1045 relabel, true /* write label now */)) {
1046 dir->fsend(_("3912 Failed to label Volume %s: ERR=%s\n"),
1047 newname, dcr->jcr->errmsg);
1048 break;
1049 }
1050 volCatBytes = dev->VolCatInfo.VolCatBytes;
1051 /*
1052 * After writing label, create a new part
1053 */
1054 if (dev->is_cloud()) {
1055 dev->set_append();
1056 if (!dev->open_next_part(dcr)) {
1057 dir->fsend(_("3913 Failed to open next part: ERR=%s\n"), dcr->jcr->errmsg);
1058 break;
1059 }
1060 }
1061 bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
1062 /* The following 3000 OK label. string is scanned in ua_label.c */
1063 int type;
1064 if (dev->dev_type == B_FILE_DEV || dev->dev_type == B_ALIGNED_DEV ||
1065 dev->dev_type == B_CLOUD_DEV)
1066 {
1067 type = dev->dev_type;
1068 } else {
1069 type = 0;
1070 }
1071 dir->fsend("3000 OK label. VolBytes=%lld VolABytes=%lld VolType=%d Volume=\"%s\" Device=%s\n",
1072 volCatBytes, dev->VolCatInfo.VolCatAdataBytes,
1073 type, newname, dev->print_name());
1074 break;
1075 case VOL_TYPE_ERROR:
1076 dir->fsend(_("3917 Failed to label Volume: ERR=%s\n"), dcr->jcr->errmsg);
1077 break;
1078 case VOL_NO_MEDIA:
1079 dir->fsend(_("3918 Failed to label Volume (no media): ERR=%s\n"), dcr->jcr->errmsg);
1080 break;
1081 default:
1082 dir->fsend(_("3919 Cannot label Volume. "
1083 "Unknown status %d from read_volume_label()\n"), label_status);
1084 break;
1085 }
1086
1087 bail_out:
1088 if (dev->is_open() && !dev->has_cap(CAP_ALWAYSOPEN)) {
1089 dev->close(dcr);
1090 }
1091
1092 dev->end_of_job(dcr, TRUNC_CONF_DEFAULT);
1093
1094 if (!dev->is_open()) {
1095 dev->clear_volhdr();
1096 }
1097 volume_unused(dcr); /* no longer using volume */
1098 dev->Lock();
1099 give_back_device_block(dev, &hold);
1100 return;
1101 }
1102
1103
1104 /*
1105 * Read the tape label
1106 *
1107 * Enter with the mutex set
1108 */
read_label(DCR * dcr)1109 static bool read_label(DCR *dcr)
1110 {
1111 int ok;
1112 JCR *jcr = dcr->jcr;
1113 BSOCK *dir = jcr->dir_bsock;
1114 bsteal_lock_t hold;
1115 DEVICE *dev = dcr->dev;
1116
1117 if (!obtain_device_block(dev,
1118 &hold,
1119 1 /* one try */,
1120 BST_DOING_ACQUIRE)) {
1121 send_dir_busy_message(dir, dev);
1122 return false;
1123 }
1124 dev->Unlock();
1125 dcr->VolumeName[0] = 0;
1126 dev->clear_labeled(); /* force read of label */
1127 switch (dev->read_dev_volume_label(dcr)) {
1128 case VOL_OK:
1129 dir->fsend(_("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName);
1130 ok = true;
1131 break;
1132 default:
1133 dir->fsend(_("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"),
1134 dev->print_name(), jcr->errmsg);
1135 ok = false;
1136 break;
1137 }
1138 volume_unused(dcr);
1139 dev->Lock();
1140 give_back_device_block(dev, &hold);
1141 return ok;
1142 }
1143
1144 /*
1145 * Searches for device by name, and if found, creates a dcr and
1146 * returns it.
1147 */
find_device(JCR * jcr,POOL_MEM & devname,POOLMEM * media_type,int drive)1148 static DCR *find_device(JCR *jcr, POOL_MEM &devname,
1149 POOLMEM *media_type, int drive)
1150 {
1151 DEVRES *device;
1152 AUTOCHANGER *changer;
1153 bool found = false;
1154 DCR *dcr = NULL;
1155
1156 unbash_spaces(devname);
1157 foreach_res(device, R_DEVICE) {
1158 /* Find resource, and make sure we were able to open it */
1159 if (strcmp(device->hdr.name, devname.c_str()) == 0 &&
1160 (!media_type || strcmp(device->media_type, media_type) ==0)) {
1161 if (!device->dev) {
1162 device->dev = init_dev(jcr, device, false, statcollector);
1163 }
1164 if (!device->dev) {
1165 Jmsg(jcr, M_WARNING, 0, _("\n"
1166 "[SW0106] Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
1167 devname.c_str());
1168 continue;
1169 }
1170 Dmsg1(20, "Found device %s\n", device->hdr.name);
1171 found = true;
1172 break;
1173 }
1174 }
1175 if (!found) {
1176 foreach_res(changer, R_AUTOCHANGER) {
1177 /* Find resource, and make sure we were able to open it */
1178 if (strcmp(devname.c_str(), changer->hdr.name) == 0) {
1179 /* Try each device in this AutoChanger */
1180 foreach_alist(device, changer->device) {
1181 Dmsg1(100, "Try changer device %s\n", device->hdr.name);
1182 if (!device->dev) {
1183 device->dev = init_dev(jcr, device, false, statcollector);
1184 }
1185 if (!device->dev) {
1186 Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
1187 Jmsg(jcr, M_WARNING, 0, _("\n"
1188 "[SW0107] Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
1189 device->hdr.name, devname.c_str());
1190 continue;
1191 }
1192 if (!device->dev->autoselect) {
1193 Dmsg1(100, "Device %s not autoselect skipped.\n", devname.c_str());
1194 continue; /* device is not available */
1195 } else if (!device->dev->enabled) {
1196 Dmsg1(100, "Device %s disabled skipped.\n", devname.c_str());
1197 continue; /* device disabled */
1198 }
1199 if ((drive < 0 || drive == (int)device->dev->drive_index) &&
1200 (!media_type || strcmp(device->media_type, media_type) ==0)) {
1201 Dmsg1(20, "Found changer device %s\n", device->hdr.name);
1202 found = true;
1203 break;
1204 }
1205 Dmsg3(100, "Device %s drive wrong: want=%d got=%d skipping\n",
1206 devname.c_str(), drive, (int)device->dev->drive_index);
1207 }
1208 break; /* we found it but could not open a device */
1209 }
1210 }
1211 }
1212
1213 if (found) {
1214 Dmsg1(100, "Found device %s\n", device->hdr.name);
1215 dcr = new_dcr(jcr, NULL, device->dev);
1216 dcr->device = device;
1217 }
1218 return dcr;
1219 }
1220
1221 /*
1222 * Find even disabled devices so that we can enable them
1223 * ***FIXME*** This could probably be merged with find_device with another
1224 * argument, but this is easier for the moment.
1225 */
find_any_device(JCR * jcr,POOL_MEM & devname,POOLMEM * media_type,int drive)1226 static DCR *find_any_device(JCR *jcr, POOL_MEM &devname,
1227 POOLMEM *media_type, int drive)
1228 {
1229 DEVRES *device;
1230 AUTOCHANGER *changer;
1231 bool found = false;
1232 DCR *dcr = NULL;
1233
1234 unbash_spaces(devname);
1235 foreach_res(device, R_DEVICE) {
1236 /* Find resource, and make sure we were able to open it */
1237 if (strcmp(device->hdr.name, devname.c_str()) == 0 &&
1238 (!media_type || strcmp(device->media_type, media_type) ==0)) {
1239 if (!device->dev) {
1240 device->dev = init_dev(jcr, device, false, statcollector);
1241 }
1242 if (!device->dev) {
1243 Jmsg(jcr, M_WARNING, 0, _("\n"
1244 "[SW0108] Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
1245 devname.c_str());
1246 continue;
1247 }
1248 Dmsg1(20, "Found device %s\n", device->hdr.name);
1249 found = true;
1250 break;
1251 }
1252 }
1253 if (!found) {
1254 foreach_res(changer, R_AUTOCHANGER) {
1255 /* Find resource, and make sure we were able to open it */
1256 if (strcmp(devname.c_str(), changer->hdr.name) == 0) {
1257 /* Try each device in this AutoChanger */
1258 foreach_alist(device, changer->device) {
1259 Dmsg1(100, "Try changer device %s\n", device->hdr.name);
1260 if (!device->dev) {
1261 device->dev = init_dev(jcr, device, false, statcollector);
1262 }
1263 if (!device->dev) {
1264 Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
1265 Jmsg(jcr, M_WARNING, 0, _("\n"
1266 "[SW0109] Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
1267 device->hdr.name, devname.c_str());
1268 continue;
1269 }
1270 if ((drive < 0 || drive == (int)device->dev->drive_index) &&
1271 (!media_type || strcmp(device->media_type, media_type) ==0)) {
1272 Dmsg1(20, "Found changer device %s\n", device->hdr.name);
1273 found = true;
1274 break;
1275 }
1276 Dmsg3(100, "Device %s drive wrong: want=%d got=%d skipping\n",
1277 devname.c_str(), drive, (int)device->dev->drive_index);
1278 }
1279 break; /* we found it but could not open a device */
1280 }
1281 }
1282 }
1283
1284 if (found) {
1285 Dmsg1(100, "Found device %s\n", device->hdr.name);
1286 dcr = new_dcr(jcr, NULL, device->dev);
1287 dcr->device = device;
1288 }
1289 return dcr;
1290 }
1291
1292
1293 /*
1294 * Mount command from Director
1295 */
mount_cmd(JCR * jcr)1296 static bool mount_cmd(JCR *jcr)
1297 {
1298 POOL_MEM devname;
1299 BSOCK *dir = jcr->dir_bsock;
1300 DEVICE *dev;
1301 DCR *dcr;
1302 int32_t drive; /* device index */
1303 int32_t slot;
1304 bool ok;
1305
1306 Dmsg1(100, "%s\n", dir->msg);
1307 ok = sscanf(dir->msg, "mount %127s drive=%d slot=%d", devname.c_str(),
1308 &drive, &slot) == 3;
1309 Dmsg3(100, "ok=%d device_index=%d slot=%d\n", ok, drive, slot);
1310 if (ok) {
1311 dcr = find_device(jcr, devname, NULL, drive);
1312 if (dcr) {
1313 dev = dcr->dev;
1314 dev->Lock(); /* Use P to avoid indefinite block */
1315 Dmsg2(100, "mount cmd blocked=%d must_unload=%d\n", dev->blocked(),
1316 dev->must_unload());
1317 switch (dev->blocked()) { /* device blocked? */
1318 case BST_WAITING_FOR_SYSOP:
1319 /* Someone is waiting, wake him */
1320 Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
1321 dev->set_blocked(BST_MOUNT);
1322 dir->fsend("3001 OK mount requested. %sDevice=%s\n",
1323 slot>0?_("Specified slot ignored. "):"",
1324 dev->print_name());
1325 Dmsg1(100, "JobId=%u broadcast wait_next_vol\n", (uint32_t)dcr->jcr->JobId);
1326 pthread_cond_broadcast(&dev->wait_next_vol);
1327 Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId);
1328 pthread_cond_broadcast(&wait_device_release);
1329 break;
1330
1331 /* In both of these two cases, we (the user) unmounted the Volume */
1332 case BST_UNMOUNTED_WAITING_FOR_SYSOP:
1333 case BST_UNMOUNTED:
1334 Dmsg2(100, "Unmounted changer=%d slot=%d\n", dev->is_autochanger(), slot);
1335 if (dev->is_autochanger() && slot > 0) {
1336 try_autoload_device(jcr, dcr, slot, "");
1337 }
1338 /* We freed the device, so reopen it and wake any waiting threads */
1339 if (!dev->open_device(dcr, OPEN_READ_ONLY)) {
1340 dir->fsend(_("3901 Unable to open device \"%s\": ERR=%s\n"),
1341 dev->print_name(), dev->bstrerror());
1342 if (dev->blocked() == BST_UNMOUNTED) {
1343 /* We blocked the device, so unblock it */
1344 Dmsg0(100, "Unmounted. Unblocking device\n");
1345 unblock_device(dev);
1346 }
1347 break;
1348 }
1349 dev->read_dev_volume_label(dcr);
1350 if (dev->blocked() == BST_UNMOUNTED) {
1351 /* We blocked the device, so unblock it */
1352 Dmsg0(100, "Unmounted. Unblocking device\n");
1353 read_label(dcr); /* this should not be necessary */
1354 unblock_device(dev);
1355 } else {
1356 Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
1357 dev->set_blocked(BST_MOUNT);
1358 }
1359 if (dev->is_labeled()) {
1360 dir->fsend(_("3001 Device \"%s\" is mounted with Volume \"%s\"\n"),
1361 dev->print_name(), dev->VolHdr.VolumeName);
1362 } else {
1363 dir->fsend(_("3905 Device \"%s\" open but no Bacula volume is mounted.\n"
1364 "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
1365 dev->print_name());
1366 }
1367 pthread_cond_broadcast(&dev->wait_next_vol);
1368 Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId);
1369 pthread_cond_broadcast(&wait_device_release);
1370 break;
1371
1372 case BST_DOING_ACQUIRE:
1373 dir->fsend(_("3001 Device \"%s\" is doing acquire.\n"),
1374 dev->print_name());
1375 break;
1376
1377 case BST_WRITING_LABEL:
1378 dir->fsend(_("3903 Device \"%s\" is being labeled.\n"),
1379 dev->print_name());
1380 break;
1381
1382 case BST_NOT_BLOCKED:
1383 Dmsg2(100, "Not blocked changer=%d slot=%d\n", dev->is_autochanger(), slot);
1384 if (dev->is_autochanger() && slot > 0) {
1385 try_autoload_device(jcr, dcr, slot, "");
1386 }
1387 if (dev->is_open()) {
1388 if (dev->is_labeled()) {
1389 dir->fsend(_("3001 Device \"%s\" is mounted with Volume \"%s\"\n"),
1390 dev->print_name(), dev->VolHdr.VolumeName);
1391 } else {
1392 dir->fsend(_("3905 Device \"%s\" open but no Bacula volume is mounted.\n"
1393 "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
1394 dev->print_name());
1395 }
1396 } else if (dev->is_tape()) {
1397 if (!dev->open_device(dcr, OPEN_READ_ONLY)) {
1398 dir->fsend(_("3901 Unable to open device \"%s\": ERR=%s\n"),
1399 dev->print_name(), dev->bstrerror());
1400 break;
1401 }
1402 read_label(dcr);
1403 if (dev->is_labeled()) {
1404 dir->fsend(_("3001 Device \"%s\" is already mounted with Volume \"%s\"\n"),
1405 dev->print_name(), dev->VolHdr.VolumeName);
1406 } else {
1407 dir->fsend(_("3905 Device \"%s\" open but no Bacula volume is mounted.\n"
1408 "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
1409 dev->print_name());
1410 }
1411 if (dev->is_open() && !dev->has_cap(CAP_ALWAYSOPEN)) {
1412 dev->close(dcr);
1413 }
1414 } else if (dev->is_unmountable()) {
1415 if (dev->mount(1)) {
1416 dir->fsend(_("3002 Device \"%s\" is mounted.\n"), dev->print_name());
1417 } else {
1418 dir->fsend(_("3907 %s"), dev->bstrerror());
1419 }
1420 } else { /* must be file */
1421 dir->fsend(_("3906 File device \"%s\" is always mounted.\n"),
1422 dev->print_name());
1423 pthread_cond_broadcast(&dev->wait_next_vol);
1424 Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId);
1425 pthread_cond_broadcast(&wait_device_release);
1426 }
1427 break;
1428
1429 case BST_RELEASING:
1430 dir->fsend(_("3930 Device \"%s\" is being released.\n"), dev->print_name());
1431 break;
1432
1433 default:
1434 dir->fsend(_("3905 Unknown wait state %d\n"), dev->blocked());
1435 break;
1436 }
1437 dev->Unlock();
1438 free_dcr(dcr);
1439 } else {
1440 dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1441 }
1442 } else {
1443 pm_strcpy(jcr->errmsg, dir->msg);
1444 dir->fsend(_("3909 Error scanning mount command: %s\n"), jcr->errmsg);
1445 }
1446 dir->signal(BNET_EOD);
1447 return true;
1448 }
1449
1450 /* enable command from Director */
enable_cmd(JCR * jcr)1451 static bool enable_cmd(JCR *jcr)
1452 {
1453 POOL_MEM devname;
1454 BSOCK *dir = jcr->dir_bsock;
1455 DEVICE *dev;
1456 DCR *dcr;
1457 int32_t drive;
1458 bool ok;
1459 int deleted;
1460
1461 ok = sscanf(dir->msg, "enable %127s drive=%d", devname.c_str(),
1462 &drive) == 2;
1463 Dmsg3(100, "ok=%d device=%s device_index=%d\n", ok, devname.c_str(), drive);
1464 if (ok) {
1465 dcr = find_any_device(jcr, devname, NULL, drive);
1466 if (dcr) {
1467 dev = dcr->dev;
1468 dev->Lock(); /* Use P to avoid indefinite block */
1469 if (dev->enabled) {
1470 dir->fsend(_("3003 Device \"%s\" already enabled.\n"), dev->print_name());
1471 } else {
1472 dev->enabled = true;
1473 dev->devstatcollector->set_value_bool(dev->devstatmetrics.bacula_storage_device_status, true);
1474 dir->fsend(_("3002 Device \"%s\" enabled.\n"), dev->print_name());
1475 }
1476 deleted = dev->delete_alerts();
1477 if (deleted > 0) {
1478 dir->fsend(_("3004 Device \"%s\" deleted %d alert%s.\n"),
1479 dev->print_name(), deleted, deleted>1?"s":"");
1480 }
1481 dev->Unlock();
1482 free_dcr(dcr);
1483 }
1484 } else {
1485 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
1486 pm_strcpy(jcr->errmsg, dir->msg);
1487 dir->fsend(_("3907 Error scanning \"enable\" command: %s\n"), jcr->errmsg);
1488 }
1489 dir->signal(BNET_EOD);
1490 return true;
1491 }
1492
1493 /* enable command from Director */
disable_cmd(JCR * jcr)1494 static bool disable_cmd(JCR *jcr)
1495 {
1496 POOL_MEM devname;
1497 BSOCK *dir = jcr->dir_bsock;
1498 DEVICE *dev;
1499 DCR *dcr;
1500 int32_t drive;
1501 bool ok;
1502
1503 ok = sscanf(dir->msg, "disable %127s drive=%d", devname.c_str(),
1504 &drive) == 2;
1505 Dmsg3(100, "ok=%d device=%s device_index=%d\n", ok, devname.c_str(), drive);
1506 if (ok) {
1507 dcr = find_device(jcr, devname, NULL, drive);
1508 if (dcr) {
1509 dev = dcr->dev;
1510 dev->Lock();
1511 dev->enabled = false;
1512 dev->devstatcollector->set_value_bool(dev->devstatmetrics.bacula_storage_device_status, false);
1513 dir->fsend(_("3002 Device \"%s\" disabled.\n"), dev->print_name());
1514 dev->Unlock();
1515 free_dcr(dcr);
1516 }
1517 } else {
1518 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
1519 pm_strcpy(jcr->errmsg, dir->msg);
1520 dir->fsend(_("3907 Error scanning \"disable\" command: %s\n"), jcr->errmsg);
1521 }
1522 dir->signal(BNET_EOD);
1523 return true;
1524 }
1525
1526
1527 /*
1528 * unmount command from Director
1529 */
unmount_cmd(JCR * jcr)1530 static bool unmount_cmd(JCR *jcr)
1531 {
1532 POOL_MEM devname;
1533 BSOCK *dir = jcr->dir_bsock;
1534 DEVICE *dev;
1535 DCR *dcr;
1536 int32_t drive;
1537
1538 if (sscanf(dir->msg, "unmount %127s drive=%d", devname.c_str(), &drive) == 2) {
1539 dcr = find_device(jcr, devname, NULL, drive);
1540 if (dcr) {
1541 dev = dcr->dev;
1542 dev->Lock(); /* Use P to avoid indefinite block */
1543 if (!dev->is_open()) {
1544 if (!dev->is_busy()) {
1545 unload_autochanger(dcr, -1);
1546 }
1547 if (dev->is_unmountable()) {
1548 if (dev->unmount(0)) {
1549 dir->fsend(_("3002 Device \"%s\" unmounted.\n"),
1550 dev->print_name());
1551 } else {
1552 dir->fsend(_("3907 %s"), dev->bstrerror());
1553 }
1554 } else {
1555 Dmsg0(90, "Device already unmounted\n");
1556 dir->fsend(_("3901 Device \"%s\" is already unmounted.\n"),
1557 dev->print_name());
1558 }
1559 } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
1560 Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
1561 dev->blocked());
1562 if (!unload_autochanger(dcr, -1)) {
1563 /*
1564 * ***FIXME**** what is this ???? -- probably we had
1565 * the wrong volume so we must free it and try again. KES
1566 */
1567 dev->close(dcr);
1568 free_volume(dev);
1569 }
1570 if (dev->is_unmountable() && !dev->unmount(0)) {
1571 dir->fsend(_("3907 %s"), dev->bstrerror());
1572 } else {
1573 dev->set_blocked(BST_UNMOUNTED_WAITING_FOR_SYSOP);
1574 dir->fsend(_("3001 Device \"%s\" unmounted.\n"),
1575 dev->print_name());
1576 }
1577
1578 } else if (dev->blocked() == BST_DOING_ACQUIRE) {
1579 dir->fsend(_("3902 Device \"%s\" is busy in acquire.\n"),
1580 dev->print_name());
1581
1582 } else if (dev->blocked() == BST_WRITING_LABEL) {
1583 dir->fsend(_("3903 Device \"%s\" is being labeled.\n"),
1584 dev->print_name());
1585
1586 } else if (dev->is_busy()) {
1587 send_dir_busy_message(dir, dev);
1588 } else { /* device not being used */
1589 Dmsg0(90, "Device not in use, unmounting\n");
1590 /* On FreeBSD, I am having ASSERT() failures in block_device()
1591 * and I can only imagine that the thread id that we are
1592 * leaving in no_wait_id is being re-used. So here,
1593 * we simply do it by hand. Gross, but a solution.
1594 */
1595 /* block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
1596 dev->set_blocked(BST_UNMOUNTED);
1597 clear_thread_id(dev->no_wait_id);
1598 if (!unload_autochanger(dcr, -1)) {
1599 dev->close(dcr);
1600 free_volume(dev);
1601 }
1602 if (dev->is_unmountable() && !dev->unmount(0)) {
1603 dir->fsend(_("3907 %s"), dev->bstrerror());
1604 } else {
1605 dir->fsend(_("3002 Device \"%s\" unmounted.\n"),
1606 dev->print_name());
1607 }
1608 }
1609 dev->Unlock();
1610 free_dcr(dcr);
1611 } else {
1612 dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1613 }
1614 } else {
1615 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
1616 pm_strcpy(jcr->errmsg, dir->msg);
1617 dir->fsend(_("3907 Error scanning unmount command: %s\n"), jcr->errmsg);
1618 }
1619 dir->signal(BNET_EOD);
1620 return true;
1621 }
1622
1623 #if 0
1624 /*
1625 * The truncate command will recycle a volume. The director can call this
1626 * after purging a volume so that disk space will not be wasted. Only useful
1627 * for File Storage, of course.
1628 *
1629 *
1630 * It is currently disabled
1631 */
1632 static bool action_on_purge_cmd(JCR *jcr)
1633 {
1634 BSOCK *dir = jcr->dir_bsock;
1635
1636 char devname[MAX_NAME_LENGTH];
1637 char volumename[MAX_NAME_LENGTH];
1638 int32_t action;
1639
1640 /* TODO: Need to find a free device and ask for slot to the director */
1641 if (sscanf(dir->msg,
1642 "action_on_purge %127s vol=%127s action=%d",
1643 devname, volumename, &action)!= 5)
1644 {
1645 dir->fsend(_("3916 Error scanning action_on_purge command\n"));
1646 goto done;
1647 }
1648 unbash_spaces(volumename);
1649 unbash_spaces(devname);
1650
1651 /* Check if action is correct */
1652 if (action & AOP_TRUNCTATE) {
1653
1654 }
1655 /* ... */
1656
1657 done:
1658 dir->signal(BNET_EOD);
1659 return true;
1660 }
1661 #endif
1662
1663 /*
1664 * Release command from Director. This rewinds the device and if
1665 * configured does a offline and ensures that Bacula will
1666 * re-read the label of the tape before continuing. This gives
1667 * the operator the chance to change the tape anytime before the
1668 * next job starts.
1669 */
release_cmd(JCR * jcr)1670 static bool release_cmd(JCR *jcr)
1671 {
1672 POOL_MEM devname;
1673 BSOCK *dir = jcr->dir_bsock;
1674 DEVICE *dev;
1675 DCR *dcr;
1676 int32_t drive;
1677
1678 if (sscanf(dir->msg, "release %127s drive=%d", devname.c_str(), &drive) == 2) {
1679 dcr = find_device(jcr, devname, NULL, drive);
1680 if (dcr) {
1681 dev = dcr->dev;
1682 dev->Lock(); /* Use P to avoid indefinite block */
1683 if (!dev->is_open()) {
1684 if (!dev->is_busy()) {
1685 unload_autochanger(dcr, -1);
1686 }
1687 Dmsg0(90, "Device already released\n");
1688 dir->fsend(_("3921 Device \"%s\" already released.\n"),
1689 dev->print_name());
1690
1691 } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
1692 Dmsg2(90, "%d waiter dev_block=%d.\n", dev->num_waiting,
1693 dev->blocked());
1694 unload_autochanger(dcr, -1);
1695 dir->fsend(_("3922 Device \"%s\" waiting for sysop.\n"),
1696 dev->print_name());
1697
1698 } else if (dev->blocked() == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
1699 Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
1700 dev->blocked());
1701 dir->fsend(_("3922 Device \"%s\" waiting for mount.\n"),
1702 dev->print_name());
1703
1704 } else if (dev->blocked() == BST_DOING_ACQUIRE) {
1705 dir->fsend(_("3923 Device \"%s\" is busy in acquire.\n"),
1706 dev->print_name());
1707
1708 } else if (dev->blocked() == BST_WRITING_LABEL) {
1709 dir->fsend(_("3914 Device \"%s\" is being labeled.\n"),
1710 dev->print_name());
1711
1712 } else if (dev->is_busy()) {
1713 send_dir_busy_message(dir, dev);
1714 } else { /* device not being used */
1715 Dmsg0(90, "Device not in use, releasing\n");
1716 dcr->release_volume();
1717 dir->fsend(_("3022 Device \"%s\" released.\n"),
1718 dev->print_name());
1719 }
1720 dev->Unlock();
1721 free_dcr(dcr);
1722 } else {
1723 dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1724 }
1725 } else {
1726 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
1727 pm_strcpy(jcr->errmsg, dir->msg);
1728 dir->fsend(_("3927 Error scanning release command: %s\n"), jcr->errmsg);
1729 }
1730 dir->signal(BNET_EOD);
1731 return true;
1732 }
1733
1734 static pthread_mutex_t bsr_mutex = PTHREAD_MUTEX_INITIALIZER;
1735 static uint32_t bsr_uniq = 0;
1736
get_bootstrap_file(JCR * jcr,BSOCK * sock)1737 static bool get_bootstrap_file(JCR *jcr, BSOCK *sock)
1738 {
1739 POOLMEM *fname = get_pool_memory(PM_FNAME);
1740 FILE *bs;
1741 bool ok = false;
1742
1743 if (jcr->RestoreBootstrap) {
1744 unlink(jcr->RestoreBootstrap);
1745 free_pool_memory(jcr->RestoreBootstrap);
1746 }
1747 P(bsr_mutex);
1748 bsr_uniq++;
1749 Mmsg(fname, "%s/%s.%s.%d.bootstrap", me->working_directory, me->hdr.name,
1750 jcr->Job, bsr_uniq);
1751 V(bsr_mutex);
1752 Dmsg1(400, "bootstrap=%s\n", fname);
1753 jcr->RestoreBootstrap = fname;
1754 bs = bfopen(fname, "a+b"); /* create file */
1755 if (!bs) {
1756 berrno be;
1757 Jmsg(jcr, M_FATAL, 0, _("[SF0110] Could not create bootstrap file %s: ERR=%s\n"),
1758 jcr->RestoreBootstrap, be.bstrerror());
1759 goto bail_out;
1760 }
1761 Dmsg0(150, "=== Bootstrap file ===\n");
1762 while (sock->recv() >= 0) {
1763 Dmsg1(150, "%s", sock->msg);
1764 fputs(sock->msg, bs);
1765 }
1766 fclose(bs);
1767 Dmsg0(150, "=== end bootstrap file ===\n");
1768 jcr->bsr = parse_bsr(jcr, jcr->RestoreBootstrap);
1769 if (!jcr->bsr) {
1770 Jmsg(jcr, M_FATAL, 0, _("[SF0111] Error parsing bootstrap file.\n"));
1771 goto bail_out;
1772 }
1773 if (chk_dbglvl(150)) {
1774 dump_bsr(NULL, jcr->bsr, true);
1775 }
1776
1777 /* If we got a bootstrap, we are reading, so create read volume list */
1778 create_restore_volume_list(jcr, true /* store the volumes in the global vol_read list */);
1779 ok = true;
1780
1781 bail_out:
1782 unlink(jcr->RestoreBootstrap);
1783 free_pool_memory(jcr->RestoreBootstrap);
1784 jcr->RestoreBootstrap = NULL;
1785 if (!ok) {
1786 sock->fsend(ERROR_bootstrap);
1787 return false;
1788 }
1789 return sock->fsend(OK_bootstrap);
1790 }
1791
bootstrap_cmd(JCR * jcr)1792 static bool bootstrap_cmd(JCR *jcr)
1793 {
1794 return get_bootstrap_file(jcr, jcr->dir_bsock);
1795 }
1796
1797 /*
1798 * Autochanger command from Director
1799 */
changer_cmd(JCR * jcr)1800 static bool changer_cmd(JCR *jcr)
1801 {
1802 POOL_MEM devname;
1803 BSOCK *dir = jcr->dir_bsock;
1804 DEVICE *dev;
1805 DCR *dcr;
1806 const char *cmd = NULL;
1807 bool ok = false;
1808 /*
1809 * A safe_cmd may call autochanger script but does not load/unload
1810 * slots so it can be done at the same time that the drive is open.
1811 */
1812 bool safe_cmd = false;
1813
1814 if (sscanf(dir->msg, "autochanger listall %127s", devname.c_str()) == 1) {
1815 cmd = "listall";
1816 safe_cmd = ok = true;
1817 } else if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) {
1818 cmd = "list";
1819 safe_cmd = ok = true;
1820 } else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) {
1821 cmd = "slots";
1822 safe_cmd = ok = true;
1823 } else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) {
1824 cmd = "drives";
1825 safe_cmd = ok = true;
1826 }
1827 if (ok) {
1828 dcr = find_device(jcr, devname, NULL, -1);
1829 if (dcr) {
1830 dev = dcr->dev;
1831 dev->Lock(); /* Use P to avoid indefinite block */
1832 if (!dev->device->changer_res) {
1833 dir->fsend(_("3998 Device \"%s\" is not an autochanger.\n"),
1834 dev->print_name());
1835 /* Under certain "safe" conditions, we can steal the lock */
1836 } else if (safe_cmd || !dev->is_open() || dev->can_obtain_block()) {
1837 autochanger_cmd(dcr, dir, cmd);
1838 } else if (dev->is_busy() || dev->is_blocked()) {
1839 send_dir_busy_message(dir, dev);
1840 } else { /* device not being used */
1841 autochanger_cmd(dcr, dir, cmd);
1842 }
1843 dev->Unlock();
1844 free_dcr(dcr);
1845 } else {
1846 dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1847 }
1848 } else { /* error on scanf */
1849 pm_strcpy(jcr->errmsg, dir->msg);
1850 dir->fsend(_("3909 Error scanning autochanger drives/list/slots command: %s\n"),
1851 jcr->errmsg);
1852 }
1853 dir->signal(BNET_EOD);
1854 return true;
1855 }
1856
1857 /*
1858 * Read and return the Volume label
1859 */
readlabel_cmd(JCR * jcr)1860 static bool readlabel_cmd(JCR *jcr)
1861 {
1862 POOL_MEM devname;
1863 BSOCK *dir = jcr->dir_bsock;
1864 DEVICE *dev;
1865 DCR *dcr;
1866 int32_t Slot, drive;
1867
1868 if (sscanf(dir->msg, "readlabel %127s Slot=%d drive=%d", devname.c_str(),
1869 &Slot, &drive) == 3) {
1870 dcr = find_device(jcr, devname, NULL, drive);
1871 if (dcr) {
1872 dev = dcr->dev;
1873 dev->Lock(); /* Use P to avoid indefinite block */
1874 if (!dev->is_open()) {
1875 read_volume_label(jcr, dcr, dev, Slot);
1876 dev->close(dcr);
1877 /* Under certain "safe" conditions, we can steal the lock */
1878 } else if (dev->can_obtain_block()) {
1879 read_volume_label(jcr, dcr, dev, Slot);
1880 } else if (dev->is_busy() || dev->is_blocked()) {
1881 send_dir_busy_message(dir, dev);
1882 } else { /* device not being used */
1883 read_volume_label(jcr, dcr, dev, Slot);
1884 }
1885 dev->Unlock();
1886 free_dcr(dcr);
1887 } else {
1888 dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1889 }
1890 } else {
1891 pm_strcpy(jcr->errmsg, dir->msg);
1892 dir->fsend(_("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
1893 }
1894 dir->signal(BNET_EOD);
1895 return true;
1896 }
1897
1898
1899 /*
1900 * Read the tape label
1901 *
1902 * Enter with the mutex set
1903 */
read_volume_label(JCR * jcr,DCR * dcr,DEVICE * dev,int Slot)1904 static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot)
1905 {
1906 BSOCK *dir = jcr->dir_bsock;
1907 bsteal_lock_t hold;
1908
1909 dcr->set_dev(dev);
1910 if (!obtain_device_block(dev,
1911 &hold,
1912 1 /* one try */,
1913 BST_WRITING_LABEL)) {
1914 send_dir_busy_message(dir, dev);
1915 return;
1916 }
1917 dev->Unlock();
1918
1919 if (!try_autoload_device(jcr, dcr, Slot, "")) {
1920 goto bail_out; /* error */
1921 }
1922
1923 dev->clear_labeled(); /* force read of label */
1924 switch (dev->read_dev_volume_label(dcr)) {
1925 case VOL_OK:
1926 /* DO NOT add quotes around the Volume name. It is scanned in the DIR */
1927 dir->fsend(_("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
1928 Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
1929 break;
1930 default:
1931 dir->fsend(_("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"),
1932 dev->print_name(), jcr->errmsg);
1933 break;
1934 }
1935
1936 bail_out:
1937 dev->Lock();
1938 give_back_device_block(dev, &hold);
1939 return;
1940 }
1941
try_autoload_device(JCR * jcr,DCR * dcr,int slot,const char * VolName)1942 static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName)
1943 {
1944 BSOCK *dir = jcr->dir_bsock;
1945
1946 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
1947 dcr->VolCatInfo.Slot = slot;
1948 dcr->VolCatInfo.InChanger = slot > 0;
1949 if (autoload_device(dcr, 0, dir) < 0) { /* autoload if possible */
1950 return false;
1951 }
1952 return true;
1953 }
1954
send_dir_busy_message(BSOCK * dir,DEVICE * dev)1955 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
1956 {
1957 if (dev->is_blocked()) {
1958 switch (dev->blocked()) {
1959 case BST_UNMOUNTED:
1960 dir->fsend(_("3931 Device \"%s\" is BLOCKED. user unmounted.\n"),
1961 dev->print_name());
1962 break;
1963 case BST_UNMOUNTED_WAITING_FOR_SYSOP:
1964 dir->fsend(_("3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n"),
1965 dev->print_name());
1966 break;
1967 case BST_WAITING_FOR_SYSOP:
1968 dir->fsend(_("3933 Device \"%s\" is BLOCKED waiting for media.\n"),
1969 dev->print_name());
1970 break;
1971 case BST_DOING_ACQUIRE:
1972 dir->fsend(_("3934 Device \"%s\" is being initialized.\n"),
1973 dev->print_name());
1974 break;
1975 case BST_WRITING_LABEL:
1976 dir->fsend(_("3935 Device \"%s\" is blocked labeling a Volume.\n"),
1977 dev->print_name());
1978 break;
1979 default:
1980 dir->fsend(_("3935 Device \"%s\" is blocked for unknown reason.\n"),
1981 dev->print_name());
1982 break;
1983 }
1984 } else if (dev->can_read()) {
1985 dir->fsend(_("3936 Device \"%s\" is busy reading.\n"),
1986 dev->print_name());;
1987 } else {
1988 dir->fsend(_("3937 Device \"%s\" is busy with writers=%d reserved=%d.\n"),
1989 dev->print_name(), dev->num_writers, dev->num_reserved());
1990 }
1991 }
1992