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