]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/ua_label.c
Fix: clock diff, Dan's patch, Nic's patch, segfault
[bacula/bacula] / bacula / src / dird / ua_label.c
index be0746b3239ce59e3acc3980181855fe44e3fa10..b6e1c55c239e255bcd2af9de157ff43e5d24c454 100644 (file)
@@ -42,7 +42,7 @@ typedef struct s_vol_list {
 static int do_label(UAContext *ua, char *cmd, int relabel);
 static void label_from_barcodes(UAContext *ua);
 static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, 
-              POOL_DBR *pr, int relabel);
+              POOL_DBR *pr, int relabel, bool media_record_exits);
 static vol_list_t *get_slot_list_from_SD(UAContext *ua);
 static int is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr);
 
@@ -52,12 +52,12 @@ static int is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr);
  *  
  *   label storage=xxx volume=vvv
  */
-int labelcmd(UAContext *ua, char *cmd)
+int label_cmd(UAContext *ua, char *cmd)
 {
    return do_label(ua, cmd, 0);       /* standard label */
 }
 
-int relabelcmd(UAContext *ua, char *cmd)
+int relabel_cmd(UAContext *ua, char *cmd)
 {
    return do_label(ua, cmd, 1);      /* relabel tape */
 }
@@ -94,6 +94,7 @@ int update_slots(UAContext *ua)
 
       memset(&mr, 0, sizeof(mr));
       bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName));
+      db_lock(ua->db);
       if (db_get_media_record(ua->jcr, ua->db, &mr)) {
          if (mr.Slot != vl->Slot) {
             mr.Slot = vl->Slot;
@@ -108,11 +109,13 @@ int update_slots(UAContext *ua)
              bsendmsg(ua, _("Catalog record for Volume \"%s\" is up to date.\n"),
                mr.VolumeName);
          }   
+         db_unlock(ua->db);
          continue;
       } else {
           bsendmsg(ua, _("Record for Volume \"%s\" not found in catalog.\n"), 
             mr.VolumeName);
       }
+      db_unlock(ua->db);
    }
 
 
@@ -145,9 +148,10 @@ static int do_label(UAContext *ua, char *cmd, int relabel)
    char dev_name[MAX_NAME_LENGTH];
    MEDIA_DBR mr, omr;
    POOL_DBR pr;
+   bool print_reminder = true;
    int ok = FALSE;
-   int mounted = FALSE;
    int i;
+   bool media_record_exists = false;
    static char *barcode_keyword[] = {
       "barcode",
       "barcodes",
@@ -171,8 +175,8 @@ static int do_label(UAContext *ua, char *cmd, int relabel)
 
    /* If relabel get name of Volume to relabel */
    if (relabel) {
-      /* Check for volume=OldVolume */
-      i = find_arg_with_value(ua, "volume"); 
+      /* Check for oldvolume=name */
+      i = find_arg_with_value(ua, "oldvolume"); 
       if (i >= 0) {
         memset(&omr, 0, sizeof(omr));
         bstrncpy(omr.VolumeName, ua->argv[i], sizeof(omr.VolumeName));
@@ -195,8 +199,8 @@ checkVol:
       }
    }
 
-   /* Check for name=NewVolume */
-   i = find_arg_with_value(ua, "name");
+   /* Check for volume=NewVolume */
+   i = find_arg_with_value(ua, "volume");
    if (i >= 0) {
       pm_strcpy(&ua->cmd, ua->argv[i]);
       goto checkName;
@@ -204,6 +208,7 @@ checkVol:
 
    /* Get a new Volume name */
    for ( ;; ) {
+      media_record_exists = false;
       if (!get_cmd(ua, _("Enter new Volume name: "))) {
         return 1;
       }
@@ -214,10 +219,14 @@ checkName:
 
       memset(&mr, 0, sizeof(mr));
       bstrncpy(mr.VolumeName, ua->cmd, sizeof(mr.VolumeName));
+      /* If VolBytes are zero the Volume is not labeled */
       if (db_get_media_record(ua->jcr, ua->db, &mr)) {
-          bsendmsg(ua, _("Media record for new Volume \"%s\" already exists.\n"), 
-            mr.VolumeName);
-         continue;
+        if (mr.VolBytes != 0) {
+             bsendmsg(ua, _("Media record for new Volume \"%s\" already exists.\n"), 
+               mr.VolumeName);
+            continue;
+         }
+         media_record_exists = true;
       }
       break;                         /* Got it */
    }
@@ -252,7 +261,7 @@ checkName:
    }
    sd = ua->jcr->store_bsock;
 
-   ok = send_label_request(ua, &mr, &omr, &pr, relabel);
+   ok = send_label_request(ua, &mr, &omr, &pr, relabel, media_record_exists);
 
    if (ok) {
       if (relabel) {
@@ -265,8 +274,8 @@ checkName:
         }
       }
       if (ua->automount) {
-        strcpy(dev_name, store->dev_name);
-         bsendmsg(ua, _("Requesting mount %s ...\n"), dev_name);
+        bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
+         bsendmsg(ua, _("Requesting to mount %s ...\n"), dev_name);
         bash_spaces(dev_name);
          bnet_fsend(sd, "mount %s", dev_name);
         unbash_spaces(dev_name);
@@ -275,12 +284,17 @@ checkName:
            /* Here we can get
             *  3001 OK mount. Device=xxx      or
             *  3001 Mounted Volume vvvv
+            *  3906 is cannot mount non-tape
+            * So for those, no need to print a reminder
             */
-            mounted = strncmp(sd->msg, "3001 ", 5) == 0;
+            if (strncmp(sd->msg, "3001 ", 5) == 0 ||
+                strncmp(sd->msg, "3906 ", 5) == 0) {
+              print_reminder = false;
+           }
         }
       }
    }
-   if (!mounted) {
+   if (print_reminder) {
       bsendmsg(ua, _("Do not forget to mount the drive!!!\n"));
    }
    bnet_sig(sd, BNET_TERMINATE);
@@ -300,6 +314,7 @@ static void label_from_barcodes(UAContext *ua)
    POOL_DBR pr;
    MEDIA_DBR mr, omr;
    vol_list_t *vl, *vol_list = NULL;
+   bool media_record_exists;
 
    vol_list = get_slot_list_from_SD(ua);
 
@@ -331,24 +346,35 @@ static void label_from_barcodes(UAContext *ua)
 
       memset(&mr, 0, sizeof(mr));
       bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName));
+      media_record_exists = false;
       if (db_get_media_record(ua->jcr, ua->db, &mr)) {
-          bsendmsg(ua, _("Media record for Slot %d Volume \"%s\" already exists.\n"), 
-            vl->Slot, mr.VolumeName);
-         continue;
+         if (mr.VolBytes != 0) {
+             bsendmsg(ua, _("Media record for Slot %d Volume \"%s\" already exists.\n"), 
+               vl->Slot, mr.VolumeName);
+            continue;
+         } 
+         media_record_exists = true;
       }
       /*
        * Deal with creating cleaning tape here. Normal tapes created in
        *  send_label_request() below
        */
       if (is_cleaning_tape(ua, &mr, &pr)) {
-        set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
-        if (db_create_media_record(ua->jcr, ua->db, &mr)) {
-            bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"),
-              mr.VolumeName);
-        } else {
-            bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db));
+        if (media_record_exists) {      /* we update it */
+           mr.VolBytes = 1;
+           if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
+                bsendmsg(ua, "%s", db_strerror(ua->db));
+           }
+        } else {                        /* create the media record */
+           set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
+           if (db_create_media_record(ua->jcr, ua->db, &mr)) {
+               bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"),
+                 mr.VolumeName);
+           } else {
+               bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db));
+           }
         }
-        continue;
+        continue;                    /* done, go handle next volume */
       }
       bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
       if (ua->jcr->store_bsock) {
@@ -364,7 +390,7 @@ static void label_from_barcodes(UAContext *ua)
       }
 
       mr.Slot = vl->Slot;
-      send_label_request(ua, &mr, &omr, &pr, 0);
+      send_label_request(ua, &mr, &omr, &pr, 0, media_record_exists);
    }
 
 
@@ -424,7 +450,7 @@ int is_volume_name_legal(UAContext *ua, char *name)
 }
 
 static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, 
-                             POOL_DBR *pr, int relabel)
+                             POOL_DBR *pr, int relabel, bool media_record_exists)
 {
    BSOCK *sd;
    char dev_name[MAX_NAME_LENGTH];
@@ -438,12 +464,12 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    bash_spaces(pr->Name);
    if (relabel) {
       bash_spaces(omr->VolumeName);
-      bnet_fsend(sd, _("relabel %s OldName=%s NewName=%s PoolName=%s MediaType=%s Slot=%d")
+      bnet_fsend(sd, "relabel %s OldName=%s NewName=%s PoolName=%s MediaType=%s Slot=%d"
         dev_name, omr->VolumeName, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot);
       bsendmsg(ua, _("Sending relabel command from \"%s\" to \"%s\" ...\n"),
         omr->VolumeName, mr->VolumeName);
    } else {
-      bnet_fsend(sd, _("label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d")
+      bnet_fsend(sd, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d"
         dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot);
       bsendmsg(ua, _("Sending label command for Volume \"%s\" Slot %d ...\n"), 
         mr->VolumeName, mr->Slot);
@@ -462,13 +488,22 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    unbash_spaces(pr->Name);
    mr->LabelDate = time(NULL);
    if (ok) {
-      set_pool_dbr_defaults_in_media_dbr(mr, pr);
-      if (db_create_media_record(ua->jcr, ua->db, mr)) {
-         bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d  successfully created.\n"),
+      if (media_record_exists) {      /* we update it */
+        mr->VolBytes = 1;
+        if (!db_update_media_record(ua->jcr, ua->db, mr)) {
+             bsendmsg(ua, "%s", db_strerror(ua->db));
+            ok = FALSE;
+        }
+      } else {                       /* create the media record */
+        set_pool_dbr_defaults_in_media_dbr(mr, pr);
+        mr->VolBytes = 1;               /* flag indicating Volume labeled */
+        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);
-      } else {
-         bsendmsg(ua, "%s", db_strerror(ua->db));
-        ok = FALSE;
+        } else {
+            bsendmsg(ua, "%s", db_strerror(ua->db));
+           ok = FALSE;
+        }
       }
    } else {
       bsendmsg(ua, _("Label command failed.\n"));
@@ -566,6 +601,11 @@ static int is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr)
    if (ua->jcr->pool->cleaning_prefix == NULL) {
       return 0;
    }
+   Dmsg4(200, "CLNprefix=%s: Vol=%s: len=%d strncmp=%d\n",
+      ua->jcr->pool->cleaning_prefix, mr->VolumeName,
+      strlen(ua->jcr->pool->cleaning_prefix), 
+      strncmp(mr->VolumeName, ua->jcr->pool->cleaning_prefix,
+                 strlen(ua->jcr->pool->cleaning_prefix)));
    return strncmp(mr->VolumeName, ua->jcr->pool->cleaning_prefix,
                  strlen(ua->jcr->pool->cleaning_prefix)) == 0;
 }