]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/dircmd.c
Move bnet_despool() into class in bsock.c
[bacula/bacula] / bacula / src / stored / dircmd.c
index 134b784b492856c4f2a0af19dbb6f0dee2722731..d78f723143aca0f7597b6a4c76a1942a1d91d0f3 100644 (file)
  *
  */
 /*
-   Copyright (C) 2001-2006 Kern Sibbald
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   version 2 as amended with additional clauses defined in the
-   file LICENSE in the main source directory.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
-   the file LICENSE for additional details.
-
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2001-2007 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
+   License as published by the Free Software Foundation plus additions
+   that are listed in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   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
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of John Walker.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ *  This file handles accepting Director Commands
+ *
+ *    Most Director commands are handled here, with the
+ *    exception of the Job command command and subsequent
+ *    subcommands that are handled
+ *    in job.c.
+ *
+ *    N.B. in this file, in general we must use P(dev->mutex) rather
+ *      than lock_device(dev) so that we can examine the blocked
+ *      state rather than blocking ourselves because a Job
+ *      thread has the device blocked. In some "safe" cases,
+ *      we can do things to a blocked device. CAREFUL!!!!
+ *
+ *    File daemon commands are handled in fdcmd.c
+ *
+ *     Kern Sibbald, May MMI
+ *
+ *   Version $Id$
+ *
  */
 
 #include "bacula.h"
@@ -49,7 +83,7 @@ extern bool init_done;
 /* Static variables */
 static char derrmsg[]     = "3900 Invalid command\n";
 static char OKsetdebug[]  = "3000 OK setdebug=%d\n";
-static char illegal_cmd[] = "3997 Illegal command for a Director with Monitor directive enabled\n";
+static char invalid_cmd[] = "3997 Invalid command for a Director with Monitor directive enabled.\n";
 
 /* Imported functions */
 extern void terminate_child();
@@ -135,7 +169,7 @@ void *handle_connection_request(void *arg)
    int bnet_stat = 0;
    char name[MAX_NAME_LENGTH];
 
-   if (bnet_recv(bs) <= 0) {
+   if (bs->recv() <= 0) {
       Emsg0(M_ERROR, 0, _("Connection request failed.\n"));
       bnet_close(bs);
       return NULL;
@@ -165,7 +199,7 @@ void *handle_connection_request(void *arg)
    Dmsg0(110, "Start Dir Job\n");
    jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */
    jcr->dir_bsock = bs;               /* save Director bsock */
-   jcr->dir_bsock->jcr = jcr;
+   jcr->dir_bsock->set_jcr(jcr);
    jcr->dcrs = New(alist(10, not_owned_by_alist));
    /* Initialize FD start condition variable */
    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
@@ -187,7 +221,7 @@ void *handle_connection_request(void *arg)
 
    for (quit=false; !quit;) {
       /* Read command */
-      if ((bnet_stat = bnet_recv(bs)) <= 0) {
+      if ((bnet_stat = bs->recv()) <= 0) {
          break;               /* connection terminated */
       }
       Dmsg1(199, "<dird: %s\n", bs->msg);
@@ -199,9 +233,9 @@ void *handle_connection_request(void *arg)
       for (i=0; cmds[i].cmd; i++) {
         if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) {
            if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
-              Dmsg1(100, "Command %s illegal.\n", cmds[i].cmd);
-              bnet_fsend(bs, illegal_cmd);
-              bnet_sig(bs, BNET_EOD);
+              Dmsg1(100, "Command \"%s\" is invalid.\n", cmds[i].cmd);
+              bnet_fsend(bs, invalid_cmd);
+              bs->signal(BNET_EOD);
               break;
            }
            Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
@@ -279,7 +313,7 @@ static bool cancel_cmd(JCR *cjcr)
             pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
             pthread_cond_broadcast(&wait_device_release);
          }
-         Jmsg(jcr, M_INFO, 0, _("Job marked to be canceled.\n"));
+         Jmsg(jcr, M_INFO, 0, _("Job %s marked to be canceled.\n"), jcr->Job);
          bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job);
          free_jcr(jcr);
       }
@@ -342,7 +376,7 @@ static bool do_label(JCR *jcr, int relabel)
       dcr = find_device(jcr, dev_name, drive);
       if (dcr) {
          dev = dcr->dev;
-         P(dev->mutex);               /* Use P to avoid indefinite block */
+         dev->lock();                 /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
             Dmsg1(400, "Can %slabel. Device is not open\n", relabel?"re":"");
             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
@@ -357,7 +391,7 @@ static bool do_label(JCR *jcr, int relabel)
             Dmsg0(400, "Can relabel. device not used\n");
             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
          }
-         V(dev->mutex);
+         dev->unlock();
          free_dcr(dcr);
          jcr->dcr = NULL;
       } else {
@@ -462,7 +496,7 @@ static void label_volume_if_ok(DCR *dcr, char *oldname,
                  dev->is_dvd()?1:0, newname, dev->print_name());
       break;
    case VOL_NO_MEDIA:
-      bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
+      bnet_fsend(dir, _("3914 Failed to label Volume (no media): ERR=%s\n"), dev->bstrerror());
       break;
    default:
       bnet_fsend(dir, _("3913 Cannot label Volume. "
@@ -606,13 +640,13 @@ static bool mount_cmd(JCR *jcr)
       dcr = find_device(jcr, devname, drive);
       if (dcr) {
          dev = dcr->dev;
-         P(dev->mutex);               /* Use P to avoid indefinite block */
-         Dmsg1(100, "mount cmd blocked=%d\n", dev->dev_blocked);
-         switch (dev->dev_blocked) {         /* device blocked? */
+         dev->lock();                 /* Use P to avoid indefinite block */
+         Dmsg1(100, "mount cmd blocked=%d\n", dev->blocked());
+         switch (dev->blocked()) {         /* device blocked? */
          case BST_WAITING_FOR_SYSOP:
             /* Someone is waiting, wake him */
             Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
-            dev->dev_blocked = BST_MOUNT;
+            dev->set_blocked(BST_MOUNT);
             bnet_fsend(dir, "3001 OK mount. Device=%s\n", 
                dev->print_name());
             pthread_cond_broadcast(&dev->wait_next_vol);
@@ -629,7 +663,7 @@ static bool mount_cmd(JCR *jcr)
             if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
                bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
                   dev->bstrerror());
-               if (dev->dev_blocked == BST_UNMOUNTED) {
+               if (dev->blocked() == BST_UNMOUNTED) {
                   /* We blocked the device, so unblock it */
                   Dmsg0(100, "Unmounted. Unblocking device\n");
                   unblock_device(dev);
@@ -637,14 +671,14 @@ static bool mount_cmd(JCR *jcr)
                break;
             }
             read_dev_volume_label(dcr);
-            if (dev->dev_blocked == BST_UNMOUNTED) {
+            if (dev->blocked() == BST_UNMOUNTED) {
                /* We blocked the device, so unblock it */
                Dmsg0(100, "Unmounted. Unblocking device\n");
                read_label(dcr);       /* this should not be necessary */
                unblock_device(dev);
             } else {
                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
-               dev->dev_blocked = BST_MOUNT;
+               dev->set_blocked(BST_MOUNT);
             }
             if (dev->is_labeled()) {
                bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
@@ -710,10 +744,10 @@ static bool mount_cmd(JCR *jcr)
             break;
 
          default:
-            bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
+            bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->blocked());
             break;
          }
-         V(dev->mutex);
+         dev->unlock();
          free_dcr(dcr);
          jcr->dcr = NULL;
       } else {
@@ -742,7 +776,7 @@ static bool unmount_cmd(JCR *jcr)
       dcr = find_device(jcr, devname, drive);
       if (dcr) {
          dev = dcr->dev;
-         P(dev->mutex);               /* Use P to avoid indefinite block */
+         dev->lock();                 /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
             if (!dev->is_busy()) {
                unload_autochanger(dcr, -1);          
@@ -759,25 +793,26 @@ static bool unmount_cmd(JCR *jcr)
                bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), 
                   dev->print_name());
             }
-         } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
+         } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
-               dev->dev_blocked);
+               dev->blocked());
             if (!unload_autochanger(dcr, -1)) {
+               /* ***FIXME**** what is this ????  */
                dev->close();
             }
             if (dev->is_dvd() && !dev->unmount(0)) {
                bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
             } else {
-               dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
+               dev->set_blocked(BST_UNMOUNTED_WAITING_FOR_SYSOP);
                bnet_fsend(dir, _("3001 Device %s unmounted.\n"), 
                   dev->print_name());
             }
 
-         } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
+         } else if (dev->blocked() == BST_DOING_ACQUIRE) {
             bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"), 
                dev->print_name());
 
-         } else if (dev->dev_blocked == BST_WRITING_LABEL) {
+         } else if (dev->blocked() == BST_WRITING_LABEL) {
             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
                dev->print_name());
 
@@ -791,7 +826,7 @@ static bool unmount_cmd(JCR *jcr)
              * we simply do it by hand.  Gross, but a solution.
              */
             /*  block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
-            dev->dev_blocked = BST_UNMOUNTED;
+            dev->set_blocked(BST_UNMOUNTED);
             dev->no_wait_id = 0;
             if (!unload_autochanger(dcr, -1)) {
                dev->close();
@@ -803,7 +838,7 @@ static bool unmount_cmd(JCR *jcr)
                   dev->print_name());
             }
          }
-         V(dev->mutex);
+         dev->unlock();
          free_dcr(dcr);
          jcr->dcr = NULL;
       } else {
@@ -837,7 +872,7 @@ static bool release_cmd(JCR *jcr)
       dcr = find_device(jcr, devname, drive);
       if (dcr) {
          dev = dcr->dev;
-         P(dev->mutex);               /* Use P to avoid indefinite block */
+         dev->lock();                 /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
             if (!dev->is_busy()) {
                unload_autochanger(dcr, -1);
@@ -846,24 +881,24 @@ static bool release_cmd(JCR *jcr)
             bnet_fsend(dir, _("3921 Device %s already released.\n"), 
                dev->print_name());
 
-         } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
+         } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
             Dmsg2(90, "%d waiter dev_block=%d.\n", dev->num_waiting,
-               dev->dev_blocked);
+               dev->blocked());
             unload_autochanger(dcr, -1);
             bnet_fsend(dir, _("3922 Device %s waiting for sysop.\n"), 
                dev->print_name());
 
-         } else if (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
+         } else if (dev->blocked() == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
-               dev->dev_blocked);
+               dev->blocked());
             bnet_fsend(dir, _("3922 Device %s waiting for mount.\n"), 
                dev->print_name());
 
-         } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
+         } else if (dev->blocked() == BST_DOING_ACQUIRE) {
             bnet_fsend(dir, _("3923 Device %s is busy in acquire.\n"), 
                dev->print_name());
 
-         } else if (dev->dev_blocked == BST_WRITING_LABEL) {
+         } else if (dev->blocked() == BST_WRITING_LABEL) {
             bnet_fsend(dir, _("3914 Device %s is being labeled.\n"), 
                dev->print_name());
 
@@ -876,7 +911,7 @@ static bool release_cmd(JCR *jcr)
             bnet_fsend(dir, _("3022 Device %s released.\n"), 
                dev->print_name());
          }
-         V(dev->mutex);
+         dev->unlock();
          free_dcr(dcr);
          jcr->dcr = NULL;
       } else {
@@ -928,7 +963,7 @@ static bool changer_cmd(JCR *jcr)
       dcr = find_device(jcr, devname, -1);
       if (dcr) {
          dev = dcr->dev;
-         P(dev->mutex);               /* Use P to avoid indefinite block */
+         dev->lock();                 /* Use P to avoid indefinite block */
          if (!dev->device->changer_res) {
             bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), 
                dev->print_name());
@@ -940,7 +975,7 @@ static bool changer_cmd(JCR *jcr)
          } else {                     /* device not being used */
             autochanger_cmd(dcr, dir, cmd);
          }
-         V(dev->mutex);
+         dev->unlock();
          free_dcr(dcr);
          jcr->dcr = NULL;
       } else {
@@ -951,7 +986,7 @@ static bool changer_cmd(JCR *jcr)
       bnet_fsend(dir, _("3908 Error scanning autocharger drives/list/slots command: %s\n"),
          jcr->errmsg);
    }
-   bnet_sig(dir, BNET_EOD);
+   dir->signal(BNET_EOD);
    return true;
 }
 
@@ -972,7 +1007,7 @@ static bool readlabel_cmd(JCR *jcr)
       dcr = find_device(jcr, devname, drive);
       if (dcr) {
          dev = dcr->dev;
-         P(dev->mutex);               /* Use P to avoid indefinite block */
+         dev->lock();                 /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
             read_volume_label(jcr, dev, Slot);
             dev->close();
@@ -984,7 +1019,7 @@ static bool readlabel_cmd(JCR *jcr)
          } else {                     /* device not being used */
             read_volume_label(jcr, dev, Slot);
          }
-         V(dev->mutex);
+         dev->unlock();
          free_dcr(dcr);
          jcr->dcr = NULL;
       } else {
@@ -994,7 +1029,7 @@ static bool readlabel_cmd(JCR *jcr)
       pm_strcpy(jcr->errmsg, dir->msg);
       bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
    }
-   bnet_sig(dir, BNET_EOD);
+   dir->signal(BNET_EOD);
    return true;
 }
 
@@ -1052,7 +1087,7 @@ static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
 {
    if (dev->is_blocked()) {
-      switch (dev->dev_blocked) {
+      switch (dev->blocked()) {
       case BST_UNMOUNTED:
          bnet_fsend(dir, _("3931 Device %s is BLOCKED. user unmounted.\n"),
             dev->print_name());