3 * Bacula Director -- Tape labeling commands
5 * Kern Sibbald, April MMIII
10 Copyright (C) 2003-2005 Kern Sibbald
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 version 2 as amended with additional clauses defined in the
15 file LICENSE in the main source directory.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 the file LICENSE for additional details.
27 /* Slot list definition */
28 typedef struct s_vol_list {
29 struct s_vol_list *next;
35 /* Forward referenced functions */
36 static int do_label(UAContext *ua, const char *cmd, int relabel);
37 static void label_from_barcodes(UAContext *ua, int drive);
38 static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
39 POOL_DBR *pr, int relabel, bool media_record_exits, int drive);
40 static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan);
41 static void free_vol_list(vol_list_t *vol_list);
42 static bool is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr);
43 static BSOCK *open_sd_bsock(UAContext *ua);
44 static void close_sd_bsock(UAContext *ua);
45 static char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive);
46 static int get_num_slots_from_SD(UAContext *ua);
52 * label storage=xxx volume=vvv
54 int label_cmd(UAContext *ua, const char *cmd)
56 return do_label(ua, cmd, 0); /* standard label */
59 int relabel_cmd(UAContext *ua, const char *cmd)
61 return do_label(ua, cmd, 1); /* relabel tape */
64 static bool get_user_slot_list(UAContext *ua, char *slot_list, int num_slots)
69 for (int i=0; i <= num_slots; i++) {
72 i = find_arg_with_value(ua, "slots");
74 /* scan slot list in ua->argv[i] */
78 strip_trailing_junk(ua->argv[i]);
79 for (p=ua->argv[i]; p && *p; p=e) {
86 h = strchr(p, '-'); /* range? */
88 msg = _("Negative numbers not permitted\n");
93 if (!is_an_integer(h)) {
94 msg = _("Range end is not integer.\n");
98 if (!is_an_integer(p)) {
99 msg = _("Range start is not an integer.\n");
105 msg = _("Range end not bigger than start.\n");
110 if (!is_an_integer(p)) {
111 msg = _("Input value is not an integer.\n");
116 if (beg <= 0 || end <= 0) {
117 msg = _("Values must be be greater than zero.\n");
120 if (end >= num_slots) {
121 msg = _("Slot too large.\n");
124 for (i=beg; i<=end; i++) {
125 slot_list[i] = 1; /* Turn on specified range */
129 /* Turn everything on */
130 for (i=0; i <= num_slots; i++) {
134 Dmsg0(100, "Slots turned on:\n");
135 for (i=1; i <= num_slots; i++) {
137 Dmsg1(100, "%d\n", i);
147 * Update Slots corresponding to Volumes in autochanger
149 int update_slots(UAContext *ua)
152 vol_list_t *vl, *vol_list = NULL;
163 store = get_storage_resource(ua, 1);
167 drive = get_storage_drive(ua, store);
168 set_storage(ua->jcr, store);
170 scan = find_arg(ua, N_("scan")) >= 0;
172 max_slots = get_num_slots_from_SD(ua);
173 if (max_slots <= 0) {
174 bsendmsg(ua, _("No slots in changer to scan.\n"));
177 slot_list = (char *)malloc(max_slots+1);
178 if (!get_user_slot_list(ua, slot_list, max_slots)) {
183 vol_list = get_vol_list_from_SD(ua, scan);
186 bsendmsg(ua, _("No Volumes found to label, or no barcodes.\n"));
190 /* Walk through the list updating the media records */
191 for (vl=vol_list; vl; vl=vl->next) {
192 if (vl->Slot > max_slots) {
193 bsendmsg(ua, _("Slot %d larger than max %d ignored.\n"),
194 vl->Slot, max_slots);
197 /* Check if user wants us to look at this slot */
198 if (!slot_list[vl->Slot]) {
199 Dmsg1(100, "Skipping slot=%d\n", vl->Slot);
202 /* If scanning, we read the label rather than the barcode */
208 vl->VolName = get_volume_name_from_SD(ua, vl->Slot, drive);
209 Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot);
211 slot_list[vl->Slot] = 0; /* clear Slot */
213 Dmsg1(100, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot);
214 memset(&mr, 0, sizeof(mr));
217 mr.StorageId = store->StorageId;
218 /* Set InChanger to zero for this Slot */
220 db_make_inchanger_unique(ua->jcr, ua->db, &mr);
222 bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), vl->Slot);
225 memset(&mr, 0, sizeof(mr));
226 bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName));
228 if (db_get_media_record(ua->jcr, ua->db, &mr)) {
229 if (mr.Slot != vl->Slot || !mr.InChanger || mr.StorageId != store->StorageId) {
232 mr.StorageId = store->StorageId;
233 if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
234 bsendmsg(ua, "%s", db_strerror(ua->db));
237 "Catalog record for Volume \"%s\" updated to reference slot %d.\n"),
238 mr.VolumeName, mr.Slot);
241 bsendmsg(ua, _("Catalog record for Volume \"%s\" is up to date.\n"),
247 bsendmsg(ua, _("Record for Volume \"%s\" not found in catalog.\n"),
252 memset(&mr, 0, sizeof(mr));
254 mr.StorageId = store->StorageId;
256 for (int i=1; i <= max_slots; i++) {
259 /* Set InChanger to zero for this Slot */
260 db_make_inchanger_unique(ua->jcr, ua->db, &mr);
267 free_vol_list(vol_list);
276 * Common routine for both label and relabel
278 static int do_label(UAContext *ua, const char *cmd, int relabel)
282 char dev_name[MAX_NAME_LENGTH];
285 bool print_reminder = true;
286 bool label_barcodes = false;
290 bool media_record_exists = false;
291 static const char *barcode_keyword[] = {
297 memset(&pr, 0, sizeof(pr));
302 if (!relabel && (i=find_arg_keyword(ua, barcode_keyword)) >= 0) {
303 *ua->argk[i] = 0; /* zap barcode keyword */
304 label_barcodes = true;
307 store = get_storage_resource(ua, true/*use default*/);
311 drive = get_storage_drive(ua, store);
312 set_storage(ua->jcr, store);
314 if (label_barcodes) {
315 label_from_barcodes(ua, drive);
319 /* If relabel get name of Volume to relabel */
321 /* Check for oldvolume=name */
322 i = find_arg_with_value(ua, "oldvolume");
324 memset(&omr, 0, sizeof(omr));
325 bstrncpy(omr.VolumeName, ua->argv[i], sizeof(omr.VolumeName));
326 if (db_get_media_record(ua->jcr, ua->db, &omr)) {
329 bsendmsg(ua, "%s", db_strerror(ua->db));
331 /* No keyword or Vol not found, ask user to select */
332 if (!select_media_dbr(ua, &omr)) {
336 /* Require Volume to be Purged or Recycled */
338 if (strcmp(omr.VolStatus, "Purged") != 0 && strcmp(omr.VolStatus, "Recycle") != 0) {
339 bsendmsg(ua, _("Volume \"%s\" has VolStatus %s. It must be Purged or Recycled before relabeling.\n"),
340 omr.VolumeName, omr.VolStatus);
345 /* Check for volume=NewVolume */
346 i = find_arg_with_value(ua, "volume");
348 pm_strcpy(ua->cmd, ua->argv[i]);
352 /* Get a new Volume name */
354 media_record_exists = false;
355 if (!get_cmd(ua, _("Enter new Volume name: "))) {
359 if (!is_volume_name_legal(ua, ua->cmd)) {
363 memset(&mr, 0, sizeof(mr));
364 bstrncpy(mr.VolumeName, ua->cmd, sizeof(mr.VolumeName));
365 /* If VolBytes are zero the Volume is not labeled */
366 if (db_get_media_record(ua->jcr, ua->db, &mr)) {
367 if (mr.VolBytes != 0) {
368 bsendmsg(ua, _("Media record for new Volume \"%s\" already exists.\n"),
372 media_record_exists = true;
377 /* If autochanger, request slot */
378 i = find_arg_with_value(ua, "slot");
380 mr.Slot = atoi(ua->argv[i]);
381 mr.InChanger = 1; /* assumed if we are labeling it */
382 } else if (store->autochanger) {
383 if (!get_pint(ua, _("Enter slot (0 or Enter for none): "))) {
386 mr.Slot = ua->pint32_val;
387 mr.InChanger = 1; /* assumed if we are labeling it */
389 mr.StorageId = store->StorageId;
391 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
393 /* Must select Pool if not already done */
394 if (pr.PoolId == 0) {
395 memset(&pr, 0, sizeof(pr));
396 if (!select_pool_dbr(ua, &pr)) {
401 ok = send_label_request(ua, &mr, &omr, &pr, relabel, media_record_exists, drive);
404 sd = ua->jcr->store_bsock;
406 /* Delete the old media record */
407 if (!db_delete_media_record(ua->jcr, ua->db, &omr)) {
408 bsendmsg(ua, _("Delete of Volume \"%s\" failed. ERR=%s"),
409 omr.VolumeName, db_strerror(ua->db));
411 bsendmsg(ua, _("Old volume \"%s\" deleted from catalog.\n"),
413 /* Update the number of Volumes in the pool */
415 if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
416 bsendmsg(ua, "%s", db_strerror(ua->db));
421 bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
422 bsendmsg(ua, _("Requesting to mount %s ...\n"), dev_name);
423 bash_spaces(dev_name);
424 bnet_fsend(sd, "mount %s drive=%d", dev_name, drive);
425 unbash_spaces(dev_name);
426 while (bnet_recv(sd) >= 0) {
427 bsendmsg(ua, "%s", sd->msg);
429 * 3001 OK mount. Device=xxx or
430 * 3001 Mounted Volume vvvv
431 * 3002 Device "DVD-Writer" (/dev/hdc) is mounted.
432 * 3906 is cannot mount non-tape
433 * So for those, no need to print a reminder
435 if (strncmp(sd->msg, "3001 ", 5) == 0 ||
436 strncmp(sd->msg, "3002 ", 5) == 0 ||
437 strncmp(sd->msg, "3906 ", 5) == 0) {
438 print_reminder = false;
443 if (print_reminder) {
444 bsendmsg(ua, _("Do not forget to mount the drive!!!\n"));
452 * Request SD to send us the slot:barcodes, then wiffle
453 * through them all labeling them.
455 static void label_from_barcodes(UAContext *ua, int drive)
457 STORE *store = ua->jcr->store;
460 vol_list_t *vl, *vol_list = NULL;
461 bool media_record_exists;
466 max_slots = get_num_slots_from_SD(ua);
467 if (max_slots <= 0) {
468 bsendmsg(ua, _("No slots in changer to scan.\n"));
471 slot_list = (char *)malloc(max_slots+1);
472 if (!get_user_slot_list(ua, slot_list, max_slots)) {
476 vol_list = get_vol_list_from_SD(ua, false /*no scan*/);
479 bsendmsg(ua, _("No Volumes found to label, or no barcodes.\n"));
483 /* Display list of Volumes and ask if he really wants to proceed */
484 bsendmsg(ua, _("The following Volumes will be labeled:\n"
486 "==============\n"));
487 for (vl=vol_list; vl; vl=vl->next) {
488 if (!vl->VolName || !slot_list[vl->Slot]) {
491 bsendmsg(ua, "%4d %s\n", vl->Slot, vl->VolName);
493 if (!get_cmd(ua, _("Do you want to continue? (y/n): ")) ||
494 (ua->cmd[0] != 'y' && ua->cmd[0] != 'Y')) {
498 memset(&pr, 0, sizeof(pr));
499 if (!select_pool_dbr(ua, &pr)) {
502 memset(&omr, 0, sizeof(omr));
504 /* Fire off the label requests */
505 for (vl=vol_list; vl; vl=vl->next) {
506 if (!vl->VolName || !slot_list[vl->Slot]) {
509 memset(&mr, 0, sizeof(mr));
510 bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName));
511 media_record_exists = false;
512 if (db_get_media_record(ua->jcr, ua->db, &mr)) {
513 if (mr.VolBytes != 0) {
514 bsendmsg(ua, _("Media record for Slot %d Volume \"%s\" already exists.\n"),
515 vl->Slot, mr.VolumeName);
518 mr.StorageId = store->StorageId;
519 if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
520 bsendmsg(ua, _("Error setting InChanger: ERR=%s"), db_strerror(ua->db));
524 media_record_exists = true;
527 mr.StorageId = store->StorageId;
529 * Deal with creating cleaning tape here. Normal tapes created in
530 * send_label_request() below
532 if (is_cleaning_tape(ua, &mr, &pr)) {
533 if (media_record_exists) { /* we update it */
535 bstrncpy(mr.VolStatus, "Cleaning", sizeof(mr.VolStatus));
537 if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
538 bsendmsg(ua, "%s", db_strerror(ua->db));
540 } else { /* create the media record */
541 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
542 bstrncpy(mr.VolStatus, "Cleaning", sizeof(mr.VolStatus));
544 if (db_create_media_record(ua->jcr, ua->db, &mr)) {
545 bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"),
547 pr.NumVols++; /* this is a bit suspect */
548 if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
549 bsendmsg(ua, "%s", db_strerror(ua->db));
552 bsendmsg(ua, _("Catalog error on cleaning tape: %s"), db_strerror(ua->db));
555 continue; /* done, go handle next volume */
557 bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
560 send_label_request(ua, &mr, &omr, &pr, 0, media_record_exists, drive);
566 free_vol_list(vol_list);
573 * Check if the Volume name has legal characters
574 * If ua is non-NULL send the message
576 bool is_volume_name_legal(UAContext *ua, const char *name)
580 const char *accept = ":.-_";
582 /* Restrict the characters permitted in the Volume name */
583 for (p=name; *p; p++) {
584 if (B_ISALPHA(*p) || B_ISDIGIT(*p) || strchr(accept, (int)(*p))) {
588 bsendmsg(ua, _("Illegal character \"%c\" in a volume name.\n"), *p);
593 if (len >= MAX_NAME_LENGTH) {
595 bsendmsg(ua, _("Volume name too long.\n"));
601 bsendmsg(ua, _("Volume name must be at least one character long.\n"));
609 * NOTE! This routine opens the SD socket but leaves it open
611 static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
612 POOL_DBR *pr, int relabel, bool media_record_exists,
616 char dev_name[MAX_NAME_LENGTH];
619 if (!(sd=open_sd_bsock(ua))) {
622 bstrncpy(dev_name, ua->jcr->store->dev_name(), sizeof(dev_name));
623 bash_spaces(dev_name);
624 bash_spaces(mr->VolumeName);
625 bash_spaces(mr->MediaType);
626 bash_spaces(pr->Name);
628 bash_spaces(omr->VolumeName);
629 bnet_fsend(sd, "relabel %s OldName=%s NewName=%s PoolName=%s "
630 "MediaType=%s Slot=%d drive=%d",
631 dev_name, omr->VolumeName, mr->VolumeName, pr->Name,
632 mr->MediaType, mr->Slot, drive);
633 bsendmsg(ua, _("Sending relabel command from \"%s\" to \"%s\" ...\n"),
634 omr->VolumeName, mr->VolumeName);
636 bnet_fsend(sd, "label %s VolumeName=%s PoolName=%s MediaType=%s "
638 dev_name, mr->VolumeName, pr->Name, mr->MediaType,
640 bsendmsg(ua, _("Sending label command for Volume \"%s\" Slot %d ...\n"),
641 mr->VolumeName, mr->Slot);
642 Dmsg6(100, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d drive=%d\n",
643 dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot, drive);
646 while (bnet_recv(sd) >= 0) {
647 bsendmsg(ua, "%s", sd->msg);
648 if (strncmp(sd->msg, "3000 OK label.", 14) == 0) {
652 unbash_spaces(mr->VolumeName);
653 unbash_spaces(mr->MediaType);
654 unbash_spaces(pr->Name);
655 mr->LabelDate = time(NULL);
656 mr->set_label_date = true;
658 if (media_record_exists) { /* we update it */
661 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
662 bsendmsg(ua, "%s", db_strerror(ua->db));
665 } else { /* create the media record */
666 set_pool_dbr_defaults_in_media_dbr(mr, pr);
667 mr->VolBytes = 1; /* flag indicating Volume labeled */
669 if (db_create_media_record(ua->jcr, ua->db, mr)) {
670 bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d successfully created.\n"),
671 mr->VolumeName, mr->Slot);
672 /* Update number of volumes in pool */
674 if (!db_update_pool_record(ua->jcr, ua->db, pr)) {
675 bsendmsg(ua, "%s", db_strerror(ua->db));
678 bsendmsg(ua, "%s", db_strerror(ua->db));
683 bsendmsg(ua, _("Label command failed for Volume %s.\n"), mr->VolumeName);
688 static BSOCK *open_sd_bsock(UAContext *ua)
690 STORE *store = ua->jcr->store;
692 if (!ua->jcr->store_bsock) {
693 bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d ...\n"),
694 store->hdr.name, store->address, store->SDport);
695 if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
696 bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
700 return ua->jcr->store_bsock;
703 static void close_sd_bsock(UAContext *ua)
705 if (ua->jcr->store_bsock) {
706 bnet_sig(ua->jcr->store_bsock, BNET_TERMINATE);
707 bnet_close(ua->jcr->store_bsock);
708 ua->jcr->store_bsock = NULL;
712 static char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive)
714 STORE *store = ua->jcr->store;
716 char dev_name[MAX_NAME_LENGTH];
717 char *VolName = NULL;
720 if (!(sd=open_sd_bsock(ua))) {
721 bsendmsg(ua, _("Could not open SD socket.\n"));
724 bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
725 bash_spaces(dev_name);
726 /* Ask for autochanger list of volumes */
727 bnet_fsend(sd, _("readlabel %s Slot=%d drive=%d\n"), dev_name, Slot, drive);
728 Dmsg1(100, "Sent: %s", sd->msg);
730 /* Get Volume name in this Slot */
731 while (bnet_recv(sd) >= 0) {
732 bsendmsg(ua, "%s", sd->msg);
733 Dmsg1(100, "Got: %s", sd->msg);
734 if (strncmp(sd->msg, "3001 Volume=", 12) == 0) {
735 VolName = (char *)malloc(sd->msglen);
736 if (sscanf(sd->msg, "3001 Volume=%s Slot=%d", VolName, &rtn_slot) == 2) {
744 Dmsg1(100, "get_vol_name=%s\n", NPRT(VolName));
749 * We get the slot list from the Storage daemon.
750 * If scan is set, we return all slots found,
751 * otherwise, we return only slots with valid barcodes (Volume names)
753 static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan)
755 STORE *store = ua->jcr->store;
756 char dev_name[MAX_NAME_LENGTH];
759 vol_list_t *vol_list = NULL;
762 if (!(sd=open_sd_bsock(ua))) {
766 bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
767 bash_spaces(dev_name);
768 /* Ask for autochanger list of volumes */
769 bnet_fsend(sd, _("autochanger list %s \n"), dev_name);
771 /* Read and organize list of Volumes */
772 while (bnet_recv(sd) >= 0) {
775 strip_trailing_junk(sd->msg);
777 /* Check for returned SD messages */
778 if (sd->msg[0] == '3' && B_ISDIGIT(sd->msg[1]) &&
779 B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) &&
781 bsendmsg(ua, "%s\n", sd->msg); /* pass them on to user */
785 /* Validate Slot: if scanning, otherwise Slot:Barcode */
786 p = strchr(sd->msg, ':');
788 /* Scanning -- require only valid slot */
789 Slot = atoi(sd->msg);
793 bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg);
798 if (p && strlen(p) > 1) {
800 if (!is_an_integer(sd->msg) || (Slot=atoi(sd->msg)) <= 0) {
803 bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg);
809 if (!is_volume_name_legal(ua, p)) {
812 bsendmsg(ua, _("Invalid Volume name: %s\n"), sd->msg);
817 /* Add Slot and VolumeName to list */
818 vl = (vol_list_t *)malloc(sizeof(vol_list_t));
822 p++; /* skip separator */
824 vl->VolName = bstrdup(p);
828 Dmsg2(100, "Add slot=%d Vol=%s to SD list.\n", vl->Slot, NPRT(vl->VolName));
833 /* Add new entry to end of list */
834 for (vol_list_t *tvl=vol_list; tvl; tvl=tvl->next) {
847 static void free_vol_list(vol_list_t *vol_list)
852 for (vl=vol_list; vl; ) {
864 * We get the number of slots in the changer from the SD
866 static int get_num_slots_from_SD(UAContext *ua)
868 STORE *store = ua->jcr->store;
869 char dev_name[MAX_NAME_LENGTH];
874 if (!(sd=open_sd_bsock(ua))) {
878 bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
879 bash_spaces(dev_name);
880 /* Ask for autochanger list of volumes */
881 bnet_fsend(sd, _("autochanger slots %s \n"), dev_name);
883 while (bnet_recv(sd) >= 0) {
884 if (sscanf(sd->msg, "slots=%d\n", &slots) == 1) {
887 bsendmsg(ua, "%s", sd->msg);
891 bsendmsg(ua, _("Device \"%s\" has %d slots.\n"), store->dev_name(), slots);
898 * Check if this is a cleaning tape by comparing the Volume name
899 * with the Cleaning Prefix. If they match, this is a cleaning
902 static bool is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr)
904 /* Find Pool resource */
905 ua->jcr->pool = (POOL *)GetResWithName(R_POOL, pr->Name);
906 if (!ua->jcr->pool) {
907 bsendmsg(ua, _("Pool \"%s\" resource not found!\n"), pr->Name);
910 if (ua->jcr->pool->cleaning_prefix == NULL) {
913 Dmsg4(100, "CLNprefix=%s: Vol=%s: len=%d strncmp=%d\n",
914 ua->jcr->pool->cleaning_prefix, mr->VolumeName,
915 strlen(ua->jcr->pool->cleaning_prefix),
916 strncmp(mr->VolumeName, ua->jcr->pool->cleaning_prefix,
917 strlen(ua->jcr->pool->cleaning_prefix)));
918 return strncmp(mr->VolumeName, ua->jcr->pool->cleaning_prefix,
919 strlen(ua->jcr->pool->cleaning_prefix)) == 0;