]> git.sur5r.net Git - bacula/bacula/commitdiff
More backport from Branch-5.1 to Branch-5.0
authorKern Sibbald <kern@sibbald.com>
Sat, 31 Jul 2010 16:54:35 +0000 (18:54 +0200)
committerKern Sibbald <kern@sibbald.com>
Sat, 31 Jul 2010 16:54:35 +0000 (18:54 +0200)
16 files changed:
bacula/scripts/Makefile.in
bacula/scripts/mtx-changer.in
bacula/src/lib/bpipe.c
bacula/src/lib/bsock.c
bacula/src/lib/mntent_cache.c [new file with mode: 0644]
bacula/src/lib/mntent_cache.h [new file with mode: 0644]
bacula/src/lib/util.c
bacula/src/qt-console/mainwin.cpp
bacula/src/qt-console/pages.cpp
bacula/src/qt-console/pages.h
bacula/src/qt-console/run/run.cpp
bacula/src/qt-console/util/fmtwidgetitem.cpp
bacula/src/stored/autochanger.c
bacula/src/stored/btape.c
bacula/src/stored/mac.c
bacula/src/tools/bbatch.c

index 374043256fb5cb82f6325a2fd8d860a7c7c6f657..32950148816691d91351a060daa611edd513b92d 100755 (executable)
@@ -65,8 +65,10 @@ install: installdirs
        $(INSTALL_SCRIPT) dvd-handler $(DESTDIR)$(scriptdir)/dvd-handler
        $(INSTALL_DATA)   btraceback.gdb $(DESTDIR)$(scriptdir)/btraceback.gdb
        $(INSTALL_DATA)   btraceback.dbx $(DESTDIR)$(scriptdir)/btraceback.dbx
+       $(INSTALL_DATA)   btraceback.mdb $(DESTDIR)$(scriptdir)/btraceback.mdb
        chmod 0644 $(DESTDIR)$(scriptdir)/btraceback.gdb \
-                  $(DESTDIR)$(scriptdir)/btraceback.dbx
+                  $(DESTDIR)$(scriptdir)/btraceback.dbx \
+                  $(DESTDIR)$(scriptdir)/btraceback.mdb
        $(INSTALL_SCRIPT) btraceback $(DESTDIR)$(sbindir)/btraceback
 
 
@@ -86,6 +88,7 @@ uninstall:
        (cd $(DESTDIR)$(scriptdir); $(RMF) dvd-handler)  
        (cd $(DESTDIR)$(scriptdir); $(RMF) btraceback.gdb)
        (cd $(DESTDIR)$(scriptdir); $(RMF) btraceback.dbx)
+       (cd $(DESTDIR)$(scriptdir); $(RMF) btraceback.mdb)
        (cd $(DESTDIR)$(sbindir);   $(RMF) btraceback)
 
 Makefile: Makefile.in
index 5aa992674792aad4328f4240ebd0be62c3ac6a53..ca5c5481ff1c71504e869c2e49e58a1587459a07 100644 (file)
@@ -215,7 +215,7 @@ case $cmd in
       fi
       ${MTX} -f $ctl status >${TMPFILE}
       rtn=$?
-      # can be converted to awk+sed+cut, contributions are welcome
+      # can be converted to awk+sed+cut, see below
       perl -ne '
 /Data Transfer Element (\d+):Empty/ && print "D:$1:E\n";
 /Data Transfer Element (\d+):Full \(Storage Element (\d+) Loaded\)(:VolumeTag =\s*(.+))?/ && print "D:$1:F:$2:$4\n";
@@ -223,6 +223,11 @@ case $cmd in
 /Storage Element (\d+):Full( :VolumeTag=(.+))?/ && print "S:$1:F:$3\n";
 /Storage Element (\d+) IMPORT.EXPORT:Empty/ && print "I:$1:E\n";
 /Storage Element (\d+) IMPORT.EXPORT:Full( :VolumeTag=(.+))?/ && print "I:$1:F:$3\n";' ${TMPFILE}
+      # If perl isn't installed, you can use by those commands
+#cat ${TMPFILE} | grep "Data Transfer Element" | awk "{print \"D:\"\$4 \$7 \$9 \$10}" | sed "s/=/:/" | sed "s/Full/F:/" | sed "s/Empty/E/"
+#cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep -v "IMPORT/EXPORT" | awk "{print \"S:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/"
+#cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep "IMPORT/EXPORT" | awk "{print \"I:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/" 
+
       rm -f ${TMPFILE} >/dev/null 2>&1
       exit $rtn
       ;;
index cd0aaedf3b199d73ef61c20870577d4c4ba72b22..79a6c0cbceb5de4cb86389cc04217ff177e1129c 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-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.
@@ -30,7 +30,6 @@
  *
  *    Kern Sibbald, November MMII
  *
- *   Version $Id$
  */
 
 
index 80fabde618aa59eb394250a654f48d8953724f93..94efd6bfe407d5cbe88a4b789fc93343b78840f9 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2007-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.
@@ -30,7 +30,6 @@
  *
  *  by Kern Sibbald
  *
- *   Version $Id: $
  */
 
 
@@ -334,9 +333,29 @@ bool BSOCK::send()
    int32_t *hdr;
    bool ok = true;
 
-   if (errors || is_terminated() || msglen > 1000000) {
+   if (errors) {
+      if (!m_suppress_error_msgs) {
+         Qmsg4(m_jcr, M_ERROR, 0,  _("Socket has errors=%d on call to %s:%s:%d\n"),
+             errors, m_who, m_host, m_port);
+      }
+      return false;
+   }
+   if (is_terminated()) {
+      if (!m_suppress_error_msgs) {
+         Qmsg4(m_jcr, M_ERROR, 0,  _("Socket is terminated=%d on call to %s:%s:%d\n"),
+             is_terminated(), m_who, m_host, m_port);
+      }
+      return false;
+   }
+   if (msglen > 4000000) {
+      if (!m_suppress_error_msgs) {
+         Qmsg4(m_jcr, M_ERROR, 0,
+            _("Socket has insane msglen=%d on call to %s:%s:%d\n"),
+             msglen, m_who, m_host, m_port);
+      }
       return false;
    }
+
    if (m_use_locking) P(m_mutex);
    /* Compute total packet length */
    if (msglen <= 0) {
@@ -649,6 +668,7 @@ int BSOCK::get_peer(char *buf, socklen_t buflen)
 bool BSOCK::set_buffer_size(uint32_t size, int rw)
 {
    uint32_t dbuf_size, start_size;
+
 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
    int opt;
    opt = IPTOS_THROUGHPUT;
@@ -665,6 +685,17 @@ bool BSOCK::set_buffer_size(uint32_t size, int rw)
       Qmsg0(get_jcr(), M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
       return false;
    }
+
+   /*
+    * If user has not set the size, use the OS default -- i.e. do not
+    *   try to set it.  This allows sys admins to set the size they
+    *   want in the OS, and Bacula will comply. See bug #1493
+    */
+   if (size == 0) {
+      msglen = dbuf_size;
+      return true;
+   }
+
    if (rw & BNET_SETBUF_READ) {
       while ((dbuf_size > TAPE_BSIZE) && (setsockopt(m_fd, SOL_SOCKET,
               SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
@@ -1021,7 +1052,7 @@ bail_out:
    bsnprintf(msg, msglen, _("Authorization problem with Director at \"%s:%d\"\n"
              "Most likely the passwords do not agree.\n"
              "If you are using TLS, there may have been a certificate validation error during the TLS handshake.\n"
-             "Please see http://www.bacula.org/5.0.x-manuals/Auth-Error for help.\n"), 
+             "Please see http://www.bacula.org/en/rel-manual/Bacula_Freque_Asked_Questi.html#SECTION003760000000000000000 for help.\n"), 
              dir->host(), dir->port());
    return false;
 }
diff --git a/bacula/src/lib/mntent_cache.c b/bacula/src/lib/mntent_cache.c
new file mode 100644 (file)
index 0000000..def077c
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2009-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 three of the GNU Affero General Public
+   License as published by the Free Software Foundation and included
+   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 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.
+
+   Bacula® is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+
+/**
+ * This code implements a cache with the current mounted filesystems for which
+ * its uses the mostly in kernel mount information and export the different OS
+ * specific interfaces using a generic interface. We use a hashed cache which is
+ * accessed using a hash on the device id and we keep the previous cache hit as
+ * most of the time we get called quite a lot with most of the time the same
+ * device so keeping the previous cache hit we have a very optimized code path.
+ *
+ * This interface is implemented for the following OS-es:
+ *
+ * - Linux
+ * - HPUX
+ * - DARWIN (OSX)
+ * - IRIX
+ * - AIX
+ * - OSF1 (True64)
+ * - Solaris
+ *
+ * Currently we only use this code for Linux and OSF1 based fstype determination.
+ * For the other OS-es we can use the fstype present in stat structure on those OS-es.
+ *
+ * This code replaces the big switch we used before based on SUPER_MAGIC present in
+ * the statfs(2) structure but which need extra code for each new filesystem added to
+ * the OS and for Linux that tends to be often as it has quite some different filesystems.
+ * This new implementation should eliminate this as we use the Linux /proc/mounts in kernel
+ * data which automatically adds any new filesystem when added to the kernel.
+ */
+
+/*
+ *  Marco van Wieringen, August 2009
+ */
+
+#include "bacula.h"
+#include "mntent_cache.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(HAVE_GETMNTENT)
+#if defined(HAVE_LINUX_OS) || defined(HAVE_HPUX_OS)
+#include <mntent.h>
+#elif defined(HAVE_SUN_OS)
+#include <sys/mnttab.h>
+#endif /* HAVE_GETMNTENT */
+#elif defined(HAVE_GETMNTINFO)
+#if defined(HAVE_DARWIN_OS)
+#include <sys/param.h>
+#include <sys/ucred.h> 
+#include <sys/mount.h> 
+#else
+#include <sys/types.h>
+#include <sys/statvfs.h>
+#endif
+#elif defined(HAVE_AIX_OS)
+#include <fshelp.h>
+#include <sys/vfs.h>
+#elif defined(HAVE_OSF1_OS)
+#include <sys/mount.h>
+#endif
+
+static char cache_initialized = 0;
+
+/**
+ * Protected data by mutex lock.
+ */
+static pthread_mutex_t mntent_cache_lock = PTHREAD_MUTEX_INITIALIZER;
+static mntent_cache_entry_t *mntent_cache_entry_hashtable[NR_MNTENT_CACHE_ENTRIES];
+static mntent_cache_entry_t *previous_cache_hit = NULL;
+
+/**
+ * Simple hash function.
+ */
+static uint32_t mntent_hash_function(uint32_t dev)
+{
+   return (dev % NR_MNTENT_CACHE_ENTRIES);
+}
+
+/**
+ * Add a new entry to the cache.
+ * This function should be called with a write lock on the mntent_cache.
+ */
+static void add_mntent_mapping(uint32_t dev, const char *special, const char *mountpoint,
+                               const char *fstype, const char *mntopts)
+{
+   uint32_t hash;
+   mntent_cache_entry_t *mce;
+
+   /**
+    * Select the correct hash bucket.
+    */
+   hash = mntent_hash_function(dev);
+
+   /**
+    * See if this is the first being put into the hash bucket.
+    */
+   if (mntent_cache_entry_hashtable[hash] == (mntent_cache_entry_t *)NULL) {
+      mce = (mntent_cache_entry_t *)malloc(sizeof(mntent_cache_entry_t));
+      memset((caddr_t)mce, 0, sizeof(mntent_cache_entry_t));
+      mntent_cache_entry_hashtable[hash] = mce;
+   } else {
+      /**
+       * Walk the linked list in the hash bucket.
+       */
+      for (mce = mntent_cache_entry_hashtable[hash]; mce->next != NULL; mce = mce->next) ;
+      mce->next = (mntent_cache_entry_t *)malloc(sizeof(mntent_cache_entry_t));
+      mce = mce->next;
+      memset((caddr_t)mce, 0, sizeof(mntent_cache_entry_t));
+   }
+
+   mce->dev = dev;
+   mce->special = bstrdup(special);
+   mce->mountpoint = bstrdup(mountpoint);
+   mce->fstype = bstrdup(fstype);
+   if (mntopts) {
+      mce->mntopts = bstrdup(mntopts);
+   }
+}
+
+/**
+ * OS specific function to load the different mntents into the cache.
+ * This function should be called with a write lock on the mntent_cache.
+ */
+static void refresh_mount_cache(void)
+{
+#if defined(HAVE_GETMNTENT)
+   FILE *fp;
+   struct stat st;
+#if defined(HAVE_LINUX_OS) || defined(HAVE_HPUX_OS) || defined(HAVE_IRIX_OS)
+   struct mntent *mnt;
+
+#if defined(HAVE_LINUX_OS)
+   if ((fp = setmntent("/proc/mounts", "r")) == (FILE *)NULL) {
+      if ((fp = setmntent(_PATH_MOUNTED, "r")) == (FILE *)NULL) {
+         return;
+      }
+   }
+#elif defined(HAVE_HPUX_OS)
+   if ((fp = fopen(MNT_MNTTAB, "r")) == (FILE *)NULL) {
+      return;
+   }
+#elif defined(HAVE_IRIX_OS)
+   if ((fp = setmntent(MOUNTED, "r")) == (FILE *)NULL) {
+      return;
+   }
+#endif
+
+   while ((mnt = getmntent(fp)) != (struct mntent *)NULL) {
+      if (stat(mnt->mnt_dir, &st) < 0) {
+         continue;
+      }
+
+      add_mntent_mapping(st.st_dev, mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts);
+   }
+
+   endmntent(fp);
+#elif defined(HAVE_SUN_OS)
+   struct mnttab mnt;
+
+   if ((fp = fopen(MNTTAB, "r")) == (FILE *)NULL)
+      return;
+
+   while (getmntent(fp, &mnt) == 0) {
+      if (stat(mnt.mnt_mountp, &st) < 0) {
+         continue;
+      }
+
+      add_mntent_mapping(st.st_dev, mnt.mnt_special, mnt.mnt_mountp, mnt.mnt_fstype, mnt.mnt_mntopts);
+   }
+
+   fclose(fp);
+#endif /* HAVE_SUN_OS */
+#elif defined(HAVE_GETMNTINFO)
+   int cnt;
+   struct stat st;
+#if defined(HAVE_DARWIN_OS)
+   struct statfs *mntinfo;
+#else
+   struct statvfs *mntinfo;
+#endif
+
+   if ((cnt = getmntinfo(&mntinfo, MNT_NOWAIT)) > 0) {
+      while (cnt > 0) {
+         if (stat(mntinfo->f_mntonname, &st) == 0) {
+            add_mntent_mapping(st.st_dev,
+                               mntinfo->f_mntfromname,
+                               mntinfo->f_mntonname,
+                               mntinfo->f_fstypename,
+                               NULL);
+         }
+         mntinfo++;
+         cnt--;
+      }
+   }
+#elif defined(HAVE_AIX_OS)
+   int bufsize;
+   char *entries, *current;
+   struct vmount *vmp;
+   struct stat st;
+   struct vfs_ent *ve;
+   int n_entries, cnt;
+
+   if (mntctl(MCTL_QUERY, sizeof(bufsize), (struct vmount *)&bufsize) != 0) {
+      return;
+   }
+
+   entries = malloc(bufsize);
+   if ((n_entries = mntctl(MCTL_QUERY, bufsize, (struct vmount *) entries)) < 0) {
+      free(entries);
+      return;
+   }
+
+   cnt = 0;
+   current = entries;
+   while (cnt < n_entries) {
+      vmp = (struct vmount *)current;
+
+      if (stat(current + vmp->vmt_data[VMT_STUB].vmt_off, &st) < 0) {
+         continue;
+      }
+
+      ve = getvfsbytype(vmp->vmt_gfstype);
+      if (ve && ve->vfsent_name) {
+         add_mntent_mapping(st.st_dev,
+                            current + vmp->vmt_data[VMT_OBJECT].vmt_off,
+                            current + vmp->vmt_data[VMT_STUB].vmt_off,
+                            ve->vfsent_name,
+                            current + vmp->vmt_data[VMT_ARGS].vmt_off);
+      }
+      current = current + vmp->vmt_length;
+      cnt++;
+   }
+   free(entries);
+#elif defined(HAVE_OSF1_OS)
+   struct statfs *entries, *current;
+   struct stat st;
+   int n_entries, cnt;
+   int size;
+
+   if ((n_entries = getfsstat((struct statfs *)0, 0L, MNT_NOWAIT)) < 0) {
+      return;
+   }
+
+   size = (n_entries + 1) * sizeof(struct statfs);
+   entries = malloc(size);
+
+   if ((n_entries = getfsstat(entries, size, MNT_NOWAIT)) < 0) {
+      free(entries);
+      return;
+   }
+
+   cnt = 0;
+   current = entries;
+   while (cnt < n_entries) {
+      if (stat(current->f_mntonname, &st) < 0) {
+         continue;
+      }
+      add_mntent_mapping(st.st_dev,
+                         current->f_mntfromname,
+                         current->f_mntonname,
+                         current->f_fstypename,
+                         NULL);
+      current++;
+      cnt++;
+   }
+   free(stats);
+#endif
+}
+
+/**
+ * Clear the cache (either by flushing it or by initializing it.)
+ * This function should be called with a write lock on the mntent_cache.
+ */
+static void clear_mount_cache()
+{
+   uint32_t hash;
+   mntent_cache_entry_t *mce, *mce_next;
+
+   if (cache_initialized == 0) {
+      /**
+       * Initialize the hash table.
+       */
+      memset((caddr_t)mntent_cache_entry_hashtable, 0, NR_MNTENT_CACHE_ENTRIES * sizeof(mntent_cache_entry_t *));
+      cache_initialized = 1;
+   } else {
+      /**
+       * Clear the previous_cache_hit.
+       */
+      previous_cache_hit = NULL;
+
+      /**
+       * Walk all hash buckets.
+       */
+      for (hash = 0; hash < NR_MNTENT_CACHE_ENTRIES; hash++) {
+         /**
+          * Walk the content of this hash bucket.
+          */
+         mce = mntent_cache_entry_hashtable[hash];
+         mntent_cache_entry_hashtable[hash] = NULL;
+         while (mce != NULL) {
+            /**
+             * Save the pointer to the next entry.
+             */
+            mce_next = mce->next;
+
+            /**
+             * Free the structure.
+             */
+            if (mce->mntopts)
+               free(mce->mntopts);
+            free(mce->fstype);
+            free(mce->mountpoint);
+            free(mce->special);
+            free(mce);
+
+            mce = mce_next;
+         }
+      }
+   }
+}
+
+/**
+ * Initialize the cache for use.
+ */
+static void initialize_mntent_cache(void)
+{
+   /**
+    * Lock the cache while we update it.
+    */
+   P(mntent_cache_lock);
+
+   /**
+    * Make sure the cache is empty (either by flushing it or by initializing it.)
+    */
+   clear_mount_cache();
+
+   /**
+    * Refresh the cache.
+    */
+   refresh_mount_cache();
+
+   /**
+    * We are done updating the cache.
+    */
+   V(mntent_cache_lock);
+}
+
+void preload_mntent_cache(void)
+{
+   initialize_mntent_cache();
+}
+
+void flush_mntent_cache(void)
+{
+   /**
+    * Lock the cache while we update it.
+    */
+   P(mntent_cache_lock);
+
+   /**
+    * Make sure the cache is empty (either by flushing it or by initializing it.)
+    */
+   clear_mount_cache();
+
+   /**
+    * We are done updating the cache.
+    */
+   V(mntent_cache_lock);
+}
+
+/**
+ * Find a mapping in the cache.
+ */
+mntent_cache_entry_t *find_mntent_mapping(uint32_t dev)
+{
+   uint32_t hash;
+   mntent_cache_entry_t *mce;
+
+   /**
+    * Initialize the cache if that was not done before.
+    */
+   if (cache_initialized == 0) {
+      initialize_mntent_cache();
+   }
+
+   /**
+    * Shortcut when we get a request for the same device again.
+    */
+   if (previous_cache_hit && previous_cache_hit->dev == dev) {
+      return previous_cache_hit;
+   }
+
+   /**
+    * Lock the cache while we walk it.
+    */
+   P(mntent_cache_lock);
+
+   /**
+    * Select the correct hash bucket.
+    */
+   hash = mntent_hash_function(dev);
+
+   /**
+    * Walk the hash bucket.
+    */
+   for (mce = mntent_cache_entry_hashtable[hash]; mce != NULL; mce = mce->next) {
+      if (mce->dev == dev) {
+         previous_cache_hit = mce;
+         V(mntent_cache_lock);
+         return mce;
+      }
+   }
+
+   /**
+    * We are done walking the cache.
+    */
+   V(mntent_cache_lock);
+   return NULL;
+}
diff --git a/bacula/src/lib/mntent_cache.h b/bacula/src/lib/mntent_cache.h
new file mode 100644 (file)
index 0000000..39b7e2f
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2009-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 three of the GNU Affero General Public
+   License as published by the Free Software Foundation and included
+   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 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.
+
+   Bacula® is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+
+/*
+ *  Marco van Wieringen, August 2009
+ */
+
+#ifndef _MNTENT_CACHE_H
+#define _MNTENT_CACHE_H 1
+
+#define NR_MNTENT_CACHE_ENTRIES 32
+
+struct mntent_cache_entry_t {
+   uint32_t dev;
+   char *special;
+   char *mountpoint;
+   char *fstype;
+   char *mntopts;
+   struct mntent_cache_entry_t *next;
+};
+
+mntent_cache_entry_t *find_mntent_mapping(uint32_t dev);
+
+void preload_mntent_cache(void);
+void flush_mntent_cache(void);
+
+#endif /* _MNTENT_CACHE_H */
index 8f1fb4b21e9ad19af5bbb99fd3089e98a8266fcb..c3a5142b8f581c056c10e022a27ca59d4e42939f 100644 (file)
@@ -399,7 +399,7 @@ const char *job_type_to_str(int type)
  */
 char *aop_to_str(int aop, POOL_MEM &ret)
 {
-   if (aop & AOP_TRUNCATE) {
+   if (aop & ON_PURGE_TRUNCATE) {
       pm_strcpy(ret, _("Truncate"));
    }
    if (!aop) {
@@ -718,6 +718,8 @@ void decode_session_key(char *decode, char *session, char *key, int maxlen)
  *  %t = Job type (Backup, ...)
  *  %r = Recipients
  *  %v = Volume name
+ *  %b = Job Bytes
+ *  %f = Job Files
  *
  *  omsg = edited output message
  *  imsg = input string containing edit codes (%x)
@@ -728,7 +730,7 @@ POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to, job_co
 {
    char *p, *q;
    const char *str;
-   char add[20];
+   char add[50];
    char name[MAX_NAME_LENGTH];
    int i;
 
@@ -803,6 +805,12 @@ POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to, job_co
                str = _("*none*");
             }
             break;
+         case 'f':                    /* Job Files */
+            str = edit_uint64(jcr->JobFiles, add);
+            break;
+         case 'b':                    /* Job Bytes */
+            str = edit_uint64(jcr->JobBytes, add);
+            break;
          case 't':
             if (jcr) {
                str = job_type_to_str(jcr->getJobType());
index 676ee898cb6c27df6c4223a32b647e2548e336c3..eca18bd28d4c407fdf5a755c8785fdccb39ebbd5 100644 (file)
@@ -515,9 +515,7 @@ void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *pre
       }
       /* set the value for the currently active console */
       int stackindex = tabWidget->indexOf(nextPage);
-      if (!nextPage->isOnceDocked()) {
-         nextPage->dockPage();
-      }
+      nextPage->firstUseDock();
    
       /* Is this page currently on the stack or is it undocked */
       if (stackindex >= 0) {
index a1700672b266c51c7875ca17f524a324be4205a1..8537604b029a31d0f9ffa4c0870a571867bb49e0 100644 (file)
@@ -57,6 +57,15 @@ Pages::Pages()
    m_docked = false;
    m_onceDocked = false;
    m_closeable = true;
+   m_dockOnFirstUse = true;
+}
+
+/* first Use Dock */
+void Pages::firstUseDock()
+{
+   if (!m_onceDocked && m_dockOnFirstUse) {
+      dockPage();
+   }
 }
 
 /*
index 654712240661c04700fafa6cd1cf845e5342b393..a31443d1038efd9fcdf362fe03cf5c0d1aa7313a 100644 (file)
@@ -78,6 +78,7 @@ public:
    QString &name() { return m_name; };
    void getVolumeList(QStringList &);
    void getStatusList(QStringList &);
+   void firstUseDock();
 
 public slots:
    /* closeEvent is a virtual function inherited from QWidget */
@@ -94,6 +95,7 @@ protected:
    bool m_closeable;
    bool m_docked;
    bool m_onceDocked;
+   bool m_dockOnFirstUse;
    Console *m_console;
    QString m_name;
 };
index cf3c67cb98b623be50ae15431aebcf2f00682191..60c59b3972249f81e9df6fa286c3ae77c737af04 100644 (file)
@@ -46,6 +46,7 @@ runPage::runPage()
 
 runPage::runPage(const QString &defJob)
 {
+   m_dockOnFirstUse = false;
    init();
    if (defJob != "")
       jobCombo->setCurrentIndex(jobCombo->findText(defJob, Qt::MatchExactly));
@@ -57,6 +58,7 @@ runPage::runPage(const QString &defJob, const QString &level,
                  const QString &pool, const QString &storage,
                  const QString &client, const QString &fileset)
 {
+   m_dockOnFirstUse = false;
    init();
    jobCombo->setCurrentIndex(jobCombo->findText(defJob, Qt::MatchExactly));
    job_name_change(0);
index 817800f6ee2722c22fb07da8a5a63c3a422434ad..348d2b2ef7e7f57428734709ccf581beed30dbfe 100644 (file)
@@ -221,7 +221,7 @@ void ItemFormatterBase::setPercent(int index, float value)
  * the tooltip stuff
  */
 void ItemFormatterBase::setPixmap(int index, const QPixmap &pix, 
-                                  const QString &tip)
+                                  const QString & /* tip */)
 {
    setPixmap(index, pix);
 }
index cb009f1581bfb6ac3aa5f028c754af83f5fdce60..40189d6ae1d92ef236b82ee65ba923266fe99b8e 100644 (file)
@@ -653,7 +653,15 @@ char *edit_device_codes(DCR *dcr, char *omsg, const char *imsg, const char *cmd)
             str = dcr->jcr->Job;
             break;
          case 'v':
-            str = NPRT(dcr->VolumeName);
+            if (dcr->VolCatInfo.VolCatName[0]) {
+               str = dcr->VolCatInfo.VolCatName;
+            } else if (dcr->VolumeName[0]) {
+               str = dcr->VolumeName;
+            } else if (dcr->dev->vol && dcr->dev->vol->vol_name) {
+               str = dcr->dev->vol->vol_name;
+            } else {
+               str = dcr->dev->VolHdr.VolumeName;
+            }
             break;
          case 'f':
             str = NPRT(dcr->jcr->client_name);
index d19fbcc7d4c4490ae948899a6e30c0b8c2789d9c..b4fbf4f23924c1dfe3fc090378f7ec9c2d7c567b 100644 (file)
@@ -2552,6 +2552,7 @@ static bool do_unfill()
    if (compare_blocks(last_block, block)) {
       if (simple) {
          Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
+         rc = true;
       } else {
          Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
       }
index 1354682784c65c731d2841477f773fa44bc667a9..5641e7e8539ee0d4fefa0018ecc8d46d48404c4f 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2006-2009 Free Software Foundation Europe e.V.
+   Copyright (C) 2006-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.
@@ -31,7 +31,6 @@
  *
  *     Kern Sibbald, January MMVI
  *
- *   Version $Id$
  */
 
 #include "bacula.h"
@@ -187,7 +186,6 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
    JCR *jcr = dcr->jcr;
    DEVICE *dev = jcr->dcr->dev;
    char buf1[100], buf2[100];
-   int32_t stream;   
    
 #ifdef xxx
    Dmsg5(000, "on entry     JobId=%d FI=%s SessId=%d Strm=%s len=%d\n",
@@ -263,25 +261,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
       FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
       stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
 
-   /* Send attributes and digest to Director for Catalog */
-   stream = rec->Stream;
-   if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX ||
-       crypto_digest_stream_type(stream) != CRYPTO_DIGEST_NONE) {
-      if (!jcr->no_attributes) {
-         BSOCK *dir = jcr->dir_bsock;
-         if (are_attributes_spooled(jcr)) {
-            dir->set_spooling();
-         }
-         Dmsg0(850, "Send attributes to dir.\n");
-         if (!dir_update_file_attributes(jcr->dcr, rec)) {
-            dir->clear_spooling();
-            Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"),
-               dir->bstrerror());
-            return false;
-         }
-         dir->clear_spooling();
-      }
-   }
+   send_attrs_to_dir(jcr, rec);
 
    return true;
 }
index 5d2d144b05493ed923bf514f2defab10cfd902c9..c7d5cab5576a3dd15ee47113866f3bed8c92cb46 100644 (file)
@@ -87,6 +87,7 @@ PROG_COPYRIGHT
 "       -P <password      specify database password (default none)\n"
 "       -h <host>         specify database host (default NULL)\n"
 "       -w <working>      specify working directory\n"
+"       -r <jobids>       call restore code with given jobids\n"
 "       -v                verbose\n"
 "       -f <file>         specify data file\n"
 "       -?                print this message\n\n"), 2001, VERSION, BDATE);
@@ -96,9 +97,17 @@ PROG_COPYRIGHT
 /* number of thread started */
 int nb=0;
 
+static int list_handler(void *ctx, int num_fields, char **row)
+{
+   uint64_t *a = (uint64_t*) ctx;
+   (*a)++;
+   return 0;
+}
+
 int main (int argc, char *argv[])
 {
    int ch;
+   char *restore_list=NULL;
    setlocale(LC_ALL, "");
    bindtextdomain("bacula", LOCALEDIR);
    textdomain("bacula");
@@ -112,8 +121,12 @@ int main (int argc, char *argv[])
 
    OSDependentInit();
 
-   while ((ch = getopt(argc, argv, "h:c:d:n:P:Su:vf:w:?")) != -1) {
+   while ((ch = getopt(argc, argv, "h:c:d:n:P:Su:vf:w:r:?")) != -1) {
       switch (ch) {
+      case 'r':
+         restore_list=bstrdup(optarg);
+         break;
+
       case 'd':                    /* debug level */
          if (*optarg == 't') {
             dbg_timestamp = true;
@@ -169,6 +182,30 @@ int main (int argc, char *argv[])
       usage();
    }
 
+   if (restore_list) {
+      uint64_t nb_file=0;
+      btime_t start, end;
+      /* To use the -r option, the catalog should already contains records */
+      
+      if ((db=db_init(NULL, NULL, db_name, db_user, db_password,
+                      db_host, 0, NULL, 0)) == NULL) {
+         Emsg0(M_ERROR_TERM, 0, _("Could not init Bacula database\n"));
+      }
+      if (!db_open_database(NULL, db)) {
+         Emsg0(M_ERROR_TERM, 0, db_strerror(db));
+      }
+
+      start = get_current_btime();
+      db_get_file_list(NULL, db, restore_list, list_handler, &nb_file);
+      end = get_current_btime();
+
+      Pmsg3(0, _("Computing file list for jobid=%s files=%lld secs=%d\n"), 
+            restore_list, nb_file, (uint32_t)btime_to_unix(end-start));
+      
+      free(restore_list);
+      return 0;
+   }
+
 #ifdef HAVE_BATCH_FILE_INSERT
    printf("With new Batch mode\n");
 #else
@@ -198,8 +235,8 @@ int main (int argc, char *argv[])
       bjcr->fileset_md5 = get_pool_memory(PM_FNAME);
       pm_strcpy(bjcr->fileset_md5, "Dummy.fileset.md5");
       
-      if ((db=db_init_database(NULL, db_name, db_user, db_password,
-                               db_host, 0, NULL, 0)) == NULL) {
+      if ((db=db_init(NULL, NULL, db_name, db_user, db_password,
+                      db_host, 0, NULL, 0)) == NULL) {
          Emsg0(M_ERROR_TERM, 0, _("Could not init Bacula database\n"));
       }
       if (!db_open_database(NULL, db)) {