]> git.sur5r.net Git - bacula/bacula/commitdiff
First cut of relabel command
authorKern Sibbald <kern@sibbald.com>
Fri, 4 Apr 2003 12:31:18 +0000 (12:31 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 4 Apr 2003 12:31:18 +0000 (12:31 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@418 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/kernstodo
bacula/src/cats/drop_mysql_tables.in
bacula/src/dird/ua_cmds.c
bacula/src/stored/dircmd.c

index 4d6d5afe17d5548ffd5300873f1fb2d051a1efc9..1125308619fed2fb2ba6b0a7f32074fb03a9a987 100644 (file)
@@ -20,6 +20,8 @@ Testing to do: (painful)
 - multiple simultaneous Volumes
 
 For 1.30 release:
+- Pool requested twice in "relabel" command.
+  Must delete old volume from catalog.
 - Make non-zero status from RunJobBefore/After error the job.
 - Remove kern and kelvin from mysql_grant...
 - Install grant_mysql...
index 19b1c3fa45167f5ffa127af8d9b310fc56afed0c..e538d2ed1362646a4a19243e683be0d33dd39f8b 100644 (file)
@@ -4,7 +4,7 @@
 
 bindir=@SQL_BINDIR@
 
-if $bindir/mysql *$ <<END-OF-DATA
+if $bindir/mysql $* <<END-OF-DATA
 USE bacula;
 DROP TABLE IF EXISTS Filename;
 DROP TABLE IF EXISTS Path;
index 310b3a3d5de8e7c904770a86f2e7e8ef7a1f8ca0..0b81d81bd9afb4c124dabc401d6772c21fbea117 100644 (file)
@@ -66,12 +66,14 @@ static int helpcmd(UAContext *ua, char *cmd);
 static int deletecmd(UAContext *ua, char *cmd);
 static int usecmd(UAContext *ua, char *cmd),  unmountcmd(UAContext *ua, char *cmd);
 static int labelcmd(UAContext *ua, char *cmd), mountcmd(UAContext *ua, char *cmd), updatecmd(UAContext *ua, char *cmd);
+static int relabelcmd(UAContext *ua, char *cmd), mountcmd(UAContext *ua, char *cmd), updatecmd(UAContext *ua, char *cmd);
 static int versioncmd(UAContext *ua, char *cmd), automountcmd(UAContext *ua, char *cmd);
 static int timecmd(UAContext *ua, char *cmd);
 static int update_volume(UAContext *ua);
 static int update_pool(UAContext *ua);
 static int delete_volume(UAContext *ua);
 static int delete_pool(UAContext *ua);
+static int do_label(UAContext *ua, char *cmd, int relabel);
 
 int quitcmd(UAContext *ua, char *cmd);
 
@@ -86,6 +88,7 @@ static struct cmdstruct commands[] = {
  { N_("delete"),     deletecmd,    _("delete [pool=<pool-name> | media volume=<volume-name>]")},    
  { N_("help"),       helpcmd,      _("print this command")},
  { N_("label"),      labelcmd,     _("label a tape")},
+ { N_("relabel"),    relabelcmd,   _("relabel a tape")},
  { N_("list"),       listcmd,      _("list [pools | jobs | jobtotals | media <pool> | files job=<nn>]; from catalog")},
  { N_("llist"),      llistcmd,     _("full or long list like list command")},
  { N_("messages"),   messagescmd,  _("messages")},
@@ -1273,20 +1276,39 @@ static int delete_pool(UAContext *ua)
  *   label storage=xxx volume=vvv
  */
 static int labelcmd(UAContext *ua, char *cmd)
+{
+   return do_label(ua, cmd, 0);       /* standard label */
+}
+
+static int relabelcmd(UAContext *ua, char *cmd)
+{
+   return do_label(ua, cmd, 1);      /* relabel tape */
+}
+
+
+/*
+ * Common routine for both label and relabel
+ */
+static int do_label(UAContext *ua, char *cmd, int relabel)
 {
    STORE *store;
    BSOCK *sd;
    char dev_name[MAX_NAME_LENGTH];
-   MEDIA_DBR mr;
+   MEDIA_DBR mr, omr;
    POOL_DBR pr;
    int ok = FALSE;
    int mounted = FALSE;
    int i;
    int slot = 0;
-   static char *keyword[] = {
+   static char *name_keyword[] = {
+      "name",
+      NULL};
+
+   static char *vol_keyword[] = {
       "volume",
       NULL};
 
+
    if (!open_db(ua)) {
       return 1;
    }
@@ -1295,20 +1317,46 @@ static int labelcmd(UAContext *ua, char *cmd)
       return 1;
    }
 
-   i = find_arg_keyword(ua, keyword);
+   /* If relabel get name of Volume to relabel */
+   if (relabel) {
+      i = find_arg_keyword(ua, vol_keyword); 
+      if (i >= 0 && ua->argv[i]) {
+        memset(&omr, 0, sizeof(omr));
+        bstrncpy(omr.VolumeName, ua->argv[i], sizeof(omr.VolumeName));
+        if (!db_get_media_record(ua->jcr, ua->db, &omr)) {
+            bsendmsg(ua, "%s", db_strerror(ua->db));
+           goto getVol;
+        }
+        goto gotVol;
+      }
+getVol:
+      if (!select_pool_and_media_dbr(ua, &pr, &omr)) {
+        return 1;
+      }
+
+gotVol:
+      if (strcmp(omr.VolStatus, "Purged") != 0) {
+         bsendmsg(ua, _("Volume \"%s\" has VolStatus %s. It must be purged before relabeling.\n"),
+           omr.VolumeName, omr.VolStatus);
+        return 1;
+      }
+   }
+
+   i = find_arg_keyword(ua, name_keyword);
    if (i >=0 && ua->argv[i]) {
       strcpy(ua->cmd, ua->argv[i]);
-      goto gotVol;
+      goto gotName;
    }
 
-getVol:
+getName:
    if (!get_cmd(ua, _("Enter new Volume name: "))) {
       return 1;
    }
-gotVol:
-   if (strchr(ua->cmd, '|')) {
+gotName:
+   /* ****FIXME*** be much more restrictive in the name */
+   if (strpbrk(ua->cmd, "`~!@#$%^&*()[]{}|\\;'\"<>?,/")) {
       bsendmsg(ua, _("Illegal character | in a volume name.\n"));
-      goto getVol;
+      goto getName;
    }
    if (strlen(ua->cmd) >= MAX_NAME_LENGTH) {
       bsendmsg(ua, _("Volume name too long.\n"));
@@ -1316,16 +1364,15 @@ gotVol:
    }
    if (strlen(ua->cmd) == 0) {
       bsendmsg(ua, _("Volume name must be at least one character long.\n"));
-      goto getVol;
+      goto getName;
    }
 
-
    memset(&mr, 0, sizeof(mr));
    strcpy(mr.VolumeName, ua->cmd);
    if (db_get_media_record(ua->jcr, ua->db, &mr)) {
-       bsendmsg(ua, _("Media record for Volume %s already exists.\n"), 
+       bsendmsg(ua, _("Media record for new Volume \"%s\" already exists.\n"), 
          mr.VolumeName);
-       return 1;
+       goto getName;
    }
 
    /* Do some more checking on slot ****FIXME**** */
@@ -1356,9 +1403,16 @@ gotVol:
    bash_spaces(mr.VolumeName);
    bash_spaces(mr.MediaType);
    bash_spaces(pr.Name);
-   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 ...\n"));
+   if (relabel) {
+      bash_spaces(omr.VolumeName);
+      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 ...\n"));
+   } else {
+      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 ...\n"));
+   }
    while (bget_msg(sd, 0) >= 0) {
       bsendmsg(ua, "%s", sd->msg);
       if (strncmp(sd->msg, "3000 OK label.", 14) == 0) {
@@ -1376,7 +1430,7 @@ gotVol:
    if (ok) {
       set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
       if (db_create_media_record(ua->jcr, ua->db, &mr)) {
-         bsendmsg(ua, _("Media record for Volume=%s successfully created.\n"),
+         bsendmsg(ua, _("Media record for Volume \"%s\" successfully created.\n"),
            mr.VolumeName);
         if (ua->automount) {
             bsendmsg(ua, _("Requesting mount %s ...\n"), dev_name);
index de421646e7ab89946644eb7f8b08e55cb01cca11..016bd440aaab044ef212694dd9741b099c46112a 100644 (file)
@@ -62,13 +62,16 @@ extern int job_cmd(JCR *jcr);
 
 /* Forward referenced functions */
 static int label_cmd(JCR *jcr);
+static int relabel_cmd(JCR *jcr);
 static int setdebug_cmd(JCR *jcr);
 static int cancel_cmd(JCR *cjcr);
 static int mount_cmd(JCR *jcr);
 static int unmount_cmd(JCR *jcr);
 static int status_cmd(JCR *sjcr);
-static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolname, 
-                              int Slot);
+static int do_label(JCR *jcr, int relabel);
+static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
+                              char *newname, char *poolname, 
+                              int Slot, int relabel);
 static void send_blocked_status(JCR *jcr, DEVICE *dev);
 
 struct s_cmds {
@@ -84,6 +87,7 @@ static struct s_cmds cmds[] = {
    {"setdebug=", setdebug_cmd},       /* set debug level */
    {"cancel",    cancel_cmd},
    {"label",     label_cmd},          /* label a tape */
+   {"relabel",   relabel_cmd},        /* relabel a tape */
    {"mount",     mount_cmd},
    {"unmount",   unmount_cmd},
    {"status",    status_cmd},
@@ -239,21 +243,44 @@ static int cancel_cmd(JCR *cjcr)
  */
 static int label_cmd(JCR *jcr) 
 {
-   POOLMEM *dname, *volname, *poolname, *mtype;
+   return do_label(jcr, 0);
+}
+
+static int relabel_cmd(JCR *jcr) 
+{
+   return do_label(jcr, 1);
+}
+
+static int do_label(JCR *jcr, int relabel)  
+{
+   POOLMEM *dname, *newname, *oldname, *poolname, *mtype;
    BSOCK *dir = jcr->dir_bsock;
    DEVRES *device;
    DEVICE *dev;
-   int found = 0;
+   int found = 0, ok = 0;
    int slot;   
 
    dname = get_memory(dir->msglen+1);
-   volname = get_memory(dir->msglen+1);
+   newname = get_memory(dir->msglen+1);
+   oldname = get_memory(dir->msglen+1);
    poolname = get_memory(dir->msglen+1);
    mtype = get_memory(dir->msglen+1);
-   if (sscanf(dir->msg, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d",
-       dname, volname, poolname, mtype, &slot) == 5) {
+   if (relabel) {
+      if (sscanf(dir->msg, "relabel %s OldName=%s NewName=%s PoolName=%s MediaType=%s Slot=%d",
+         dname, oldname, newname, poolname, mtype, &slot) == 6) {
+        ok = 1;
+      }
+   } else {
+      *oldname = 0;
+      if (sscanf(dir->msg, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d",
+         dname, newname, poolname, mtype, &slot) == 5) {
+        ok = 1;
+      }
+   }
+   if (ok) {
       unbash_spaces(dname);
-      unbash_spaces(volname);
+      unbash_spaces(newname);
+      unbash_spaces(oldname);
       unbash_spaces(poolname);
       unbash_spaces(mtype);
       device = NULL;
@@ -274,10 +301,10 @@ static int label_cmd(JCR *jcr)
 
         P(dev->mutex);               /* Use P to avoid indefinite block */
         if (!(dev->state & ST_OPENED)) {
-           if (open_dev(dev, volname, READ_WRITE) < 0) {
+           if (open_dev(dev, newname, READ_WRITE) < 0) {
                bnet_fsend(dir, _("3994 Connot open device: %s\n"), strerror_dev(dev));
            } else {
-              label_volume_if_ok(jcr, dev, volname, poolname, slot);
+              label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
               force_close_dev(dev);
            }
          /* Under certain "safe" conditions, we can steal the lock */
@@ -285,7 +312,7 @@ static int label_cmd(JCR *jcr)
                    (dev->dev_blocked == BST_UNMOUNTED ||
                     dev->dev_blocked == BST_WAITING_FOR_SYSOP ||
                     dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP)) {
-           label_volume_if_ok(jcr, dev, volname, poolname, slot);
+           label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
         } else if (dev->state & ST_READ || dev->num_writers) {
            if (dev->state & ST_READ) {
                 bnet_fsend(dir, _("3901 Device %s is busy with 1 reader.\n"),
@@ -295,7 +322,7 @@ static int label_cmd(JCR *jcr)
                   dev_name(dev), dev->num_writers);
            }
         } else {                     /* device not being used */
-           label_volume_if_ok(jcr, dev, volname, poolname, slot);
+           label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
         }
         V(dev->mutex);
       } else {
@@ -307,7 +334,8 @@ static int label_cmd(JCR *jcr)
       bnet_fsend(dir, _("3903 Error scanning label command: %s\n"), dname);
    }
    free_memory(dname);
-   free_memory(volname);
+   free_memory(oldname);
+   free_memory(newname);
    free_memory(poolname);
    free_memory(mtype);
    bnet_sig(dir, BNET_EOD);
@@ -320,8 +348,9 @@ static int label_cmd(JCR *jcr)
  *
  *  Enter with the mutex set
  */
-static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolname,
-                              int slot) 
+static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname, 
+                              char *newname, char *poolname,
+                              int slot, int relabel)
 {
    BSOCK *dir = jcr->dir_bsock;
    DEV_BLOCK *block;
@@ -329,7 +358,7 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolnam
    
    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
    
-   strcpy(jcr->VolumeName, vname);
+   strcpy(jcr->VolumeName, newname);
    jcr->VolCatInfo.Slot = slot;
    autoload_device(jcr, dev, 0, dir);     /* autoload if possible */
    block = new_block(dev);
@@ -352,18 +381,27 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolnam
       case VOL_VERSION_ERROR:
       case VOL_LABEL_ERROR:
       case VOL_OK:
-         bnet_fsend(dir, _("3901 Cannot label Volume because it is \
-already labeled: %s\n"), dev->VolHdr.VolName);
-        break;
+        if (!relabel) {
+           bnet_fsend(dir, _(
+               "3901 Cannot label Volume because it is already labeled: %s\n"), 
+               dev->VolHdr.VolName);
+           break;
+        }
+        /* Relabel request. If oldname matches, continue */
+        if (strcmp(oldname, dev->VolHdr.VolName) != 0) {
+            bnet_fsend(dir, _("Wrong volume mounted.\n"));
+           break;
+        }
+        /* Fall through wanted! */
       case VOL_IO_ERROR:
       case VOL_NO_LABEL:
-        if (!write_volume_label_to_dev(jcr, jcr->device, vname, poolname)) {
+        if (!write_volume_label_to_dev(jcr, jcr->device, newname, poolname)) {
             bnet_fsend(dir, _("3903 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
            break;
         }
-        strcpy(jcr->VolumeName, vname);
+        strcpy(jcr->VolumeName, newname);
          bnet_fsend(dir, _("3000 OK label. Volume=%s Device=%s\n"), 
-           vname, dev->dev_name);
+           newname, dev->dev_name);
         break;
       default:
          bnet_fsend(dir, _("3902 Cannot label Volume. \