]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/dircmd.c
Quote device name in SD and implement releasing message
[bacula/bacula] / bacula / src / stored / dircmd.c
index efc933e4bd9b9bd26e732e9199b7f61bb5bbc37a..e339602cf176613ffed70f5e62eea8e889363b32 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2001-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2001-2010 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
+   modify it under the terms of version three of the GNU Affero General Public
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
@@ -15,7 +15,7 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
+   You should have received a copy of the GNU Affero General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
@@ -43,8 +43,6 @@
  *
  *     Kern Sibbald, May MMI
  *
- *   Version $Id$
- *
  */
 
 #include "bacula.h"
@@ -58,7 +56,7 @@ extern struct s_last_job last_job;
 extern bool init_done;
 
 /* Static variables */
-static char derrmsg[]     = "3900 Invalid command\n";
+static char derrmsg[]     = "3900 Invalid command:";
 static char OKsetdebug[]  = "3000 OK setdebug=%d\n";
 static char invalid_cmd[] = "3997 Invalid command for a Director with Monitor directive enabled.\n";
 static char OK_bootstrap[]    = "3000 OK bootstrap\n";
@@ -83,6 +81,7 @@ static bool setdebug_cmd(JCR *jcr);
 static bool cancel_cmd(JCR *cjcr);
 static bool mount_cmd(JCR *jcr);
 static bool unmount_cmd(JCR *jcr);
+//static bool action_on_purge_cmd(JCR *jcr);
 static bool bootstrap_cmd(JCR *jcr);
 static bool changer_cmd(JCR *sjcr);
 static bool do_label(JCR *jcr, int relabel);
@@ -118,6 +117,7 @@ static struct s_cmds cmds[] = {
    {"status",      status_cmd,      1},
    {".status",     qstatus_cmd,     1},
    {"unmount",     unmount_cmd,     0},
+//   {"action_on_purge",  action_on_purge_cmd,    0},
    {"use storage=", use_cmd,        0},
    {"run",         run_cmd,         0},
 // {"query",       query_cmd,       0},
@@ -232,14 +232,16 @@ void *handle_connection_request(void *arg)
            Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
            if (!cmds[i].func(jcr)) { /* do command */
               quit = true; /* error, get out */
-              Dmsg1(190, "Command %s reqeusts quit\n", cmds[i].cmd);
+              Dmsg1(190, "Command %s requests quit\n", cmds[i].cmd);
            }
            found = true;             /* indicate command found */
            break;
         }
       }
       if (!found) {                   /* command not found */
-        bs->fsend(derrmsg);
+        POOL_MEM err_msg;
+        Mmsg(err_msg, "%s %s\n", derrmsg, bs->msg);
+        bs->fsend(err_msg.c_str());
         break;
       }
    }
@@ -305,14 +307,18 @@ static bool cancel_cmd(JCR *cjcr)
       } else {
          oldStatus = jcr->JobStatus;
          set_jcr_job_status(jcr, JS_Canceled);
+         Dmsg2(800, "Cancel JobId=%d %p\n", jcr->JobId, jcr);
          if (!jcr->authenticated && oldStatus == JS_WaitFD) {
             pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
          }
          if (jcr->file_bsock) {
-            bnet_sig(jcr->file_bsock, BNET_TERMINATE);
+            jcr->file_bsock->signal(BNET_TERMINATE);
+            jcr->file_bsock->set_terminated();
+            Dmsg2(800, "Term bsock jid=%d %p\n", jcr->JobId, jcr);
          } else {
             /* Still waiting for FD to connect, release it */
             pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
+            Dmsg2(800, "Signal FD connect jid=%d %p\n", jcr->JobId, jcr);
          }
          /* If thread waiting on mount, wake him */
          if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
@@ -325,7 +331,8 @@ static bool cancel_cmd(JCR *cjcr)
             Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
             pthread_cond_broadcast(&wait_device_release);
          }
-         Jmsg(jcr, M_INFO, 0, _("Job %s marked to be canceled.\n"), jcr->Job);
+         Jmsg(jcr, M_INFO, 0, _("JobId=%d Job=\"%s\" marked to be canceled.\n"), 
+            (int)jcr->JobId, jcr->Job);
          dir->fsend(_("3000 Job %s marked to be canceled.\n"), jcr->Job);
          free_jcr(jcr);
       }
@@ -459,9 +466,9 @@ static void label_volume_if_ok(DCR *dcr, char *oldname,
       dev->truncating = true;         /* let open() know we will truncate it */
    }
    /* Set old volume name for open if relabeling */
-   bstrncpy(dcr->VolCatInfo.VolCatName, volname, sizeof(dcr->VolCatInfo.VolCatName));
+   dcr->setVolCatName(volname);
    if (dev->open(dcr, mode) < 0) {
-      dir->fsend(_("3910 Unable to open device %s: ERR=%s\n"),
+      dir->fsend(_("3910 Unable to open device \"%s\": ERR=%s\n"),
          dev->print_name(), dev->bstrerror());
       goto bail_out;      
    }
@@ -470,7 +477,7 @@ static void label_volume_if_ok(DCR *dcr, char *oldname,
    label_status = read_dev_volume_label(dcr);
    
    /* Set new volume name */
-   bstrncpy(dcr->VolCatInfo.VolCatName, newname, sizeof(dcr->VolCatInfo.VolCatName));
+   dcr->setVolCatName(newname);
    switch(label_status) {
    case VOL_NAME_ERROR:
    case VOL_VERSION_ERROR:
@@ -548,7 +555,7 @@ static bool read_label(DCR *dcr)
       ok = true;
       break;
    default:
-      dir->fsend(_("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
+      dir->fsend(_("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"),
          dev->print_name(), jcr->errmsg);
       ok = false;
       break;
@@ -676,7 +683,7 @@ static bool mount_cmd(JCR *jcr)
             }
             /* We freed the device, so reopen it and wake any waiting threads */
             if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
-               dir->fsend(_("3901 Unable to open device %s: ERR=%s\n"),
+               dir->fsend(_("3901 Unable to open device \"%s\": ERR=%s\n"),
                   dev->print_name(), dev->bstrerror());
                if (dev->blocked() == BST_UNMOUNTED) {
                   /* We blocked the device, so unblock it */
@@ -696,10 +703,10 @@ static bool mount_cmd(JCR *jcr)
                dev->set_blocked(BST_MOUNT);
             }
             if (dev->is_labeled()) {
-               dir->fsend(_("3001 Device %s is mounted with Volume \"%s\"\n"),
+               dir->fsend(_("3001 Device \"%s\" is mounted with Volume \"%s\"\n"),
                   dev->print_name(), dev->VolHdr.VolumeName);
             } else {
-               dir->fsend(_("3905 Device %s open but no Bacula volume is mounted.\n"
+               dir->fsend(_("3905 Device \"%s\" open but no Bacula volume is mounted.\n"
                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
                           dev->print_name());
             }
@@ -709,12 +716,12 @@ static bool mount_cmd(JCR *jcr)
             break;
 
          case BST_DOING_ACQUIRE:
-            dir->fsend(_("3001 Device %s is doing acquire.\n"),
+            dir->fsend(_("3001 Device \"%s\" is doing acquire.\n"),
                        dev->print_name());
             break;
 
          case BST_WRITING_LABEL:
-            dir->fsend(_("3903 Device %s is being labeled.\n"), 
+            dir->fsend(_("3903 Device \"%s\" is being labeled.\n"), 
                dev->print_name());
             break;
 
@@ -724,43 +731,49 @@ static bool mount_cmd(JCR *jcr)
             }
             if (dev->is_open()) {
                if (dev->is_labeled()) {
-                  dir->fsend(_("3001 Device %s is mounted with Volume \"%s\"\n"),
+                  dir->fsend(_("3001 Device \"%s\" is mounted with Volume \"%s\"\n"),
                      dev->print_name(), dev->VolHdr.VolumeName);
                } else {
-                  dir->fsend(_("3905 Device %s open but no Bacula volume is mounted.\n"
+                  dir->fsend(_("3905 Device \"%s\" open but no Bacula volume is mounted.\n"
                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
                              dev->print_name());
                }
             } else if (dev->is_tape()) {
                if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
-                  dir->fsend(_("3901 Unable to open device %s: ERR=%s\n"),
+                  dir->fsend(_("3901 Unable to open device \"%s\": ERR=%s\n"),
                      dev->print_name(), dev->bstrerror());
                   break;
                }
                read_label(dcr);
                if (dev->is_labeled()) {
-                  dir->fsend(_("3001 Device %s is already mounted with Volume \"%s\"\n"),
+                  dir->fsend(_("3001 Device \"%s\" is already mounted with Volume \"%s\"\n"),
                      dev->print_name(), dev->VolHdr.VolumeName);
                } else {
-                  dir->fsend(_("3905 Device %s open but no Bacula volume is mounted.\n"
+                  dir->fsend(_("3905 Device \"%s\" open but no Bacula volume is mounted.\n"
                                     "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
                              dev->print_name());
                }
             } else if (dev->is_unmountable()) {
                if (dev->mount(1)) {
-                  dir->fsend(_("3002 Device %s is mounted.\n"), 
-                     dev->print_name());
+                  dir->fsend(_("3002 Device \"%s\" is mounted.\n"), dev->print_name());
                } else {
                   dir->fsend(_("3907 %s"), dev->bstrerror());
                } 
             } else { /* must be file */
-               dir->fsend(_("3906 File device %s is always mounted.\n"),
+               dir->fsend(_("3906 File device \"%s\" is always mounted.\n"),
                   dev->print_name());
+               pthread_cond_broadcast(&dev->wait_next_vol);
+               Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId);
+               pthread_cond_broadcast(&wait_device_release);
             }
             break;
 
+         case BST_RELEASING:
+            dir->fsend(_("3930 Device \"%s\" is being released.\n"), dev->print_name());
+            break;
+
          default:
-            dir->fsend(_("3905 Bizarre wait state %d\n"), dev->blocked());
+            dir->fsend(_("3905 Unknown wait state %d\n"), dev->blocked());
             break;
          }
          dev->dunlock();
@@ -798,14 +811,14 @@ static bool unmount_cmd(JCR *jcr)
             }
             if (dev->is_unmountable()) {
                if (dev->unmount(0)) {
-                  dir->fsend(_("3002 Device %s unmounted.\n"), 
+                  dir->fsend(_("3002 Device \"%s\" unmounted.\n"), 
                      dev->print_name());
                } else {
                   dir->fsend(_("3907 %s"), dev->bstrerror());
                } 
             } else {
                Dmsg0(90, "Device already unmounted\n");
-               dir->fsend(_("3901 Device %s is already unmounted.\n"), 
+               dir->fsend(_("3901 Device \"%s\" is already unmounted.\n"), 
                   dev->print_name());
             }
          } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
@@ -820,16 +833,16 @@ static bool unmount_cmd(JCR *jcr)
                dir->fsend(_("3907 %s"), dev->bstrerror());
             } else {
                dev->set_blocked(BST_UNMOUNTED_WAITING_FOR_SYSOP);
-               dir->fsend(_("3001 Device %s unmounted.\n"), 
+               dir->fsend(_("3001 Device \"%s\" unmounted.\n"), 
                   dev->print_name());
             }
 
          } else if (dev->blocked() == BST_DOING_ACQUIRE) {
-            dir->fsend(_("3902 Device %s is busy in acquire.\n"), 
+            dir->fsend(_("3902 Device \"%s\" is busy in acquire.\n"), 
                dev->print_name());
 
          } else if (dev->blocked() == BST_WRITING_LABEL) {
-            dir->fsend(_("3903 Device %s is being labeled.\n"), 
+            dir->fsend(_("3903 Device \"%s\" is being labeled.\n"), 
                dev->print_name());
 
          } else if (dev->is_busy()) {
@@ -851,7 +864,7 @@ static bool unmount_cmd(JCR *jcr)
             if (dev->is_unmountable() && !dev->unmount(0)) {
                dir->fsend(_("3907 %s"), dev->bstrerror());
             } else {
-               dir->fsend(_("3002 Device %s unmounted.\n"), 
+               dir->fsend(_("3002 Device \"%s\" unmounted.\n"), 
                   dev->print_name());
             }
          }
@@ -869,6 +882,46 @@ static bool unmount_cmd(JCR *jcr)
    return true;
 }
 
+#if 0
+/*
+ * The truncate command will recycle a volume. The director can call this
+ * after purging a volume so that disk space will not be wasted. Only useful
+ * for File Storage, of course.
+ *
+ *
+ * It is currently disabled
+ */
+static bool action_on_purge_cmd(JCR *jcr)
+{
+   BSOCK *dir = jcr->dir_bsock;
+
+   char devname[MAX_NAME_LENGTH];
+   char volumename[MAX_NAME_LENGTH];
+   int action;
+
+   /* TODO: Need to find a free device and ask for slot to the director */
+   if (sscanf(dir->msg, 
+              "action_on_purge %127s vol=%127s action=%d",
+              devname, volumename, &action)!= 5) 
+   {
+      dir->fsend(_("3916 Error scanning action_on_purge command\n"));
+      goto done;
+   }
+   unbash_spaces(volumename);
+   unbash_spaces(devname);
+
+   /* Check if action is correct */
+   if (action & AOP_TRUNCTATE) {
+
+   } 
+   /* ... */
+
+done:
+   dir->signal(BNET_EOD);
+   return true;
+}
+#endif
+
 /*
  * Release command from Director. This rewinds the device and if
  *   configured does a offline and ensures that Bacula will
@@ -894,28 +947,28 @@ static bool release_cmd(JCR *jcr)
                unload_autochanger(dcr, -1);
             }
             Dmsg0(90, "Device already released\n");
-            dir->fsend(_("3921 Device %s already released.\n"), 
+            dir->fsend(_("3921 Device \"%s\" already released.\n"), 
                dev->print_name());
 
          } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
             Dmsg2(90, "%d waiter dev_block=%d.\n", dev->num_waiting,
                dev->blocked());
             unload_autochanger(dcr, -1);
-            dir->fsend(_("3922 Device %s waiting for sysop.\n"), 
+            dir->fsend(_("3922 Device \"%s\" waiting for sysop.\n"), 
                dev->print_name());
 
          } else if (dev->blocked() == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
                dev->blocked());
-            dir->fsend(_("3922 Device %s waiting for mount.\n"), 
+            dir->fsend(_("3922 Device \"%s\" waiting for mount.\n"), 
                dev->print_name());
 
          } else if (dev->blocked() == BST_DOING_ACQUIRE) {
-            dir->fsend(_("3923 Device %s is busy in acquire.\n"), 
+            dir->fsend(_("3923 Device \"%s\" is busy in acquire.\n"), 
                dev->print_name());
 
          } else if (dev->blocked() == BST_WRITING_LABEL) {
-            dir->fsend(_("3914 Device %s is being labeled.\n"), 
+            dir->fsend(_("3914 Device \"%s\" is being labeled.\n"), 
                dev->print_name());
 
          } else if (dev->is_busy()) {
@@ -923,7 +976,7 @@ static bool release_cmd(JCR *jcr)
          } else {                     /* device not being used */
             Dmsg0(90, "Device not in use, releasing\n");
             dcr->release_volume();
-            dir->fsend(_("3022 Device %s released.\n"), 
+            dir->fsend(_("3022 Device \"%s\" released.\n"), 
                dev->print_name());
          }
          dev->dunlock();
@@ -1038,7 +1091,7 @@ static bool changer_cmd(JCR *jcr)
          dev = dcr->dev;
          dev->dlock();                 /* Use P to avoid indefinite block */
          if (!dev->device->changer_res) {
-            dir->fsend(_("3995 Device %s is not an autochanger.\n"), 
+            dir->fsend(_("3995 Device \"%s\" is not an autochanger.\n"), 
                dev->print_name());
          /* Under certain "safe" conditions, we can steal the lock */
          } else if (safe_cmd || !dev->is_open() || dev->can_steal_lock()) {
@@ -1130,7 +1183,7 @@ static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot)
       Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
       break;
    default:
-      dir->fsend(_("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
+      dir->fsend(_("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"),
                  dev->print_name(), jcr->errmsg);
       break;
    }
@@ -1158,35 +1211,35 @@ static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
    if (dev->is_blocked()) {
       switch (dev->blocked()) {
       case BST_UNMOUNTED:
-         dir->fsend(_("3931 Device %s is BLOCKED. user unmounted.\n"),
+         dir->fsend(_("3931 Device \"%s\" is BLOCKED. user unmounted.\n"),
             dev->print_name());
          break;
       case BST_UNMOUNTED_WAITING_FOR_SYSOP:
-         dir->fsend(_("3932 Device %s is BLOCKED. user unmounted during wait for media/mount.\n"),
+         dir->fsend(_("3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n"),
              dev->print_name());
          break;
       case BST_WAITING_FOR_SYSOP:
-         dir->fsend(_("3933 Device %s is BLOCKED waiting for media.\n"),
+         dir->fsend(_("3933 Device \"%s\" is BLOCKED waiting for media.\n"),
             dev->print_name());
          break;
       case BST_DOING_ACQUIRE:
-         dir->fsend(_("3934 Device %s is being initialized.\n"),
+         dir->fsend(_("3934 Device \"%s\" is being initialized.\n"),
             dev->print_name());
          break;
       case BST_WRITING_LABEL:
-         dir->fsend(_("3935 Device %s is blocked labeling a Volume.\n"),
+         dir->fsend(_("3935 Device \"%s\" is blocked labeling a Volume.\n"),
             dev->print_name());
          break;
       default:
-         dir->fsend(_("3935 Device %s is blocked for unknown reason.\n"),
+         dir->fsend(_("3935 Device \"%s\" is blocked for unknown reason.\n"),
             dev->print_name());
          break;
       }
    } else if (dev->can_read()) {
-       dir->fsend(_("3936 Device %s is busy reading.\n"),
+       dir->fsend(_("3936 Device \"%s\" is busy reading.\n"),
                    dev->print_name());;
    } else {
-       dir->fsend(_("3937 Device %s is busy with %d writer(s).\n"),
+       dir->fsend(_("3937 Device \"%s\" is busy with %d writer(s).\n"),
           dev->print_name(), dev->num_writers);
    }
 }