]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/ua_label.c
Pool + label cleanups from bug reports
[bacula/bacula] / bacula / src / dird / ua_label.c
index 8c3cd474ff817a12ea019b94e4ccfca61d730f45..2b3c95cdd521f8658077a2381d851e702f2739e5 100644 (file)
@@ -39,9 +39,9 @@ typedef struct s_vol_list {
 
 
 /* Forward referenced functions */
-static int do_label(UAContext *ua, char *cmd, int relabel);
+static int do_label(UAContext *ua, const char *cmd, int relabel);
 static void label_from_barcodes(UAContext *ua);
-static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, 
+static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, 
               POOL_DBR *pr, int relabel, bool media_record_exits);
 static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan);
 static void free_vol_list(vol_list_t *vol_list);
@@ -56,12 +56,12 @@ static char *get_volume_name_from_SD(UAContext *ua, int Slot);
  *  
  *   label storage=xxx volume=vvv
  */
-int label_cmd(UAContext *ua, char *cmd)
+int label_cmd(UAContext *ua, const char *cmd)
 {
    return do_label(ua, cmd, 0);       /* standard label */
 }
 
-int relabel_cmd(UAContext *ua, char *cmd)
+int relabel_cmd(UAContext *ua, const char *cmd)
 {
    return do_label(ua, cmd, 1);      /* relabel tape */
 }
@@ -71,7 +71,7 @@ static int const max_slots = 5000;
 static bool get_user_slot_list(UAContext *ua, char *slot_list, int num_slots)
 {
    int i;
-   char *msg;
+   const char *msg;
 
    for (int i=0; i<num_slots; i++) {
       slot_list[i] = 0;
@@ -189,6 +189,10 @@ int update_slots(UAContext *ua)
 
    /* Walk through the list updating the media records */
    for (vl=vol_list; vl; vl=vl->next) {
+      if (vl->Slot >= max_slots) {
+         bsendmsg(ua, _("Slot %d larger than max %d ignored.\n"));
+        continue;
+      }
       /* Check if user wants us to look at this slot */
       if (!slot_list[vl->Slot]) {
          Dmsg1(100, "Skipping slot=%d\n", vl->Slot);
@@ -203,8 +207,17 @@ int update_slots(UAContext *ua)
         vl->VolName = get_volume_name_from_SD(ua, vl->Slot);
          Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot);
       }
+      slot_list[vl->Slot] = 0;       /* clear Slot */
       if (!vl->VolName) {
-         Dmsg1(100, "No VolName for Slot=%d skipping.\n", vl->Slot);
+         Dmsg1(100, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot);
+        memset(&mr, 0, sizeof(mr));
+        mr.Slot = vl->Slot;
+        mr.InChanger = 1;
+        /* Set InChanger to zero for this Slot */
+        db_lock(ua->db);
+        db_make_inchanger_unique(ua->jcr, ua->db, &mr);
+        db_unlock(ua->db);
+         bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), vl->Slot);
         continue;
       }
       memset(&mr, 0, sizeof(mr));
@@ -215,7 +228,7 @@ int update_slots(UAContext *ua)
             mr.Slot = vl->Slot;
             mr.InChanger = 1;
             if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
-                bsendmsg(ua, _("%s\n"), db_strerror(ua->db));
+                bsendmsg(ua, "%s", db_strerror(ua->db));
             } else {
                bsendmsg(ua, _(
                   "Catalog record for Volume \"%s\" updated to reference slot %d.\n"),
@@ -233,8 +246,19 @@ int update_slots(UAContext *ua)
       }
       db_unlock(ua->db);
    }
-
-
+   memset(&mr, 0, sizeof(mr));
+   mr.InChanger = 1;
+   for (int i=1; i<max_slots; i++) {
+      if (slot_list[i]) {
+        mr.Slot = i;
+        /* Set InChanger to zero for this Slot */
+        db_lock(ua->db);
+        db_make_inchanger_unique(ua->jcr, ua->db, &mr);
+        db_unlock(ua->db);
+         bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), i);
+      }
+   }
+      
 bail_out:
 
    free_vol_list(vol_list);
@@ -248,7 +272,7 @@ bail_out:
 /*
  * Common routine for both label and relabel
  */
-static int do_label(UAContext *ua, char *cmd, int relabel)
+static int do_label(UAContext *ua, const char *cmd, int relabel)
 {
    STORE *store;
    BSOCK *sd;
@@ -259,7 +283,7 @@ static int do_label(UAContext *ua, char *cmd, int relabel)
    int ok = FALSE;
    int i;
    bool media_record_exists = false;
-   static char *barcode_keyword[] = {
+   static const char *barcode_keyword[] = {
       "barcode",
       "barcodes",
       NULL};
@@ -367,12 +391,18 @@ checkName:
    if (ok) {
       sd = ua->jcr->store_bsock;
       if (relabel) {
+        /* Delete the old media record */
         if (!db_delete_media_record(ua->jcr, ua->db, &omr)) {
             bsendmsg(ua, _("Delete of Volume \"%s\" failed. ERR=%s"),
               omr.VolumeName, db_strerror(ua->db));
         } else {
             bsendmsg(ua, _("Old volume \"%s\" deleted from catalog.\n"), 
               omr.VolumeName);
+           /* Update the number of Volumes in the pool */
+           pr.NumVols--;
+           if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
+               bsendmsg(ua, "%s", db_strerror(ua->db));
+           }
         }
       }
       if (ua->automount) {
@@ -419,8 +449,7 @@ static void label_from_barcodes(UAContext *ua)
 
    slot_list = (char *)malloc(max_slots);
    if (!get_user_slot_list(ua, slot_list, max_slots)) {
-      free(slot_list);
-      return;
+      goto bail_out;
    }
 
    vol_list = get_vol_list_from_SD(ua, false /*no scan*/);
@@ -489,6 +518,10 @@ static void label_from_barcodes(UAContext *ua)
            if (db_create_media_record(ua->jcr, ua->db, &mr)) {
                bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"),
                  mr.VolumeName);
+              pr.NumVols++;          /* this is a bit suspect */
+              if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
+                  bsendmsg(ua, "%s", db_strerror(ua->db));
+              }
            } else {
                bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db));
            }
@@ -498,13 +531,12 @@ static void label_from_barcodes(UAContext *ua)
       bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
 
       mr.Slot = vl->Slot;
-      if (!send_label_request(ua, &mr, &omr, &pr, 0, media_record_exists)) {
-        goto bail_out;
-      }
+      send_label_request(ua, &mr, &omr, &pr, 0, media_record_exists);
    }
 
 
 bail_out:
+   free(slot_list);
    free_vol_list(vol_list);
    close_sd_bsock(ua);
 
@@ -515,11 +547,11 @@ bail_out:
  * Check if the Volume name has legal characters
  * If ua is non-NULL send the message
  */
-bool is_volume_name_legal(UAContext *ua, char *name)
+bool is_volume_name_legal(UAContext *ua, const char *name)
 {
    int len;
-   char *p;
-   char *accept = ":.-_";
+   const char *p;
+   const char *accept = ":.-_";
 
    /* Restrict the characters permitted in the Volume name */
    for (p=name; *p; p++) {
@@ -547,15 +579,18 @@ bool is_volume_name_legal(UAContext *ua, char *name)
    return 1;
 }
 
-static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, 
-                             POOL_DBR *pr, int relabel, bool media_record_exists)
+/*
+ * NOTE! This routine opens the SD socket but leaves it open
+ */
+static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, 
+                              POOL_DBR *pr, int relabel, bool media_record_exists)
 {
    BSOCK *sd;
    char dev_name[MAX_NAME_LENGTH];
-   int ok = FALSE;
+   bool ok = false;
 
    if (!(sd=open_sd_bsock(ua))) {
-      return 0;
+      return false;
    }
    bstrncpy(dev_name, ua->jcr->store->dev_name, sizeof(dev_name));
    bash_spaces(dev_name);
@@ -580,10 +615,9 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    while (bnet_recv(sd) >= 0) {
       bsendmsg(ua, "%s", sd->msg);
       if (strncmp(sd->msg, "3000 OK label.", 14) == 0) {
-        ok = TRUE;
+        ok = true;
       } 
    }
-   close_sd_bsock(ua);
    unbash_spaces(mr->VolumeName);
    unbash_spaces(mr->MediaType);
    unbash_spaces(pr->Name);
@@ -594,7 +628,7 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
         mr->InChanger = 1;
         if (!db_update_media_record(ua->jcr, ua->db, mr)) {
              bsendmsg(ua, "%s", db_strerror(ua->db));
-            ok = FALSE;
+            ok = false;
         }
       } else {                       /* create the media record */
         set_pool_dbr_defaults_in_media_dbr(mr, pr);
@@ -603,13 +637,18 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
         if (db_create_media_record(ua->jcr, ua->db, mr)) {
             bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d  successfully created.\n"),
            mr->VolumeName, mr->Slot);
+           /* Update number of volumes in pool */
+           pr->NumVols++;
+           if (!db_update_pool_record(ua->jcr, ua->db, pr)) {
+               bsendmsg(ua, "%s", db_strerror(ua->db));
+           }
         } else {
             bsendmsg(ua, "%s", db_strerror(ua->db));
-           ok = FALSE;
+           ok = false;
         }
       }
    } else {
-      bsendmsg(ua, _("Label command failed.\n"));
+      bsendmsg(ua, _("Label command failed for Volume %s.\n"), mr->VolumeName);
    }
    return ok;
 }
@@ -754,7 +793,7 @@ static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan)
       } else {
         vl->VolName = NULL;
       }
-      Dmsg2(100, "Add slot=%d Vol=%s to list.\n", vl->Slot, NPRT(vl->VolName));
+      Dmsg2(100, "Add slot=%d Vol=%s to SD list.\n", vl->Slot, NPRT(vl->VolName));
       if (!vol_list) {
         vl->next = vol_list;
         vol_list = vl;
@@ -776,6 +815,7 @@ static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan)
 static void free_vol_list(vol_list_t *vol_list)
 {
    vol_list_t *vl;
+
    /* Free list */
    for (vl=vol_list; vl; ) {
       vol_list_t *ovl;