]> git.sur5r.net Git - bacula/bacula/commitdiff
Merge branch 'master' into basejobv3
authorEric Bollengier <eric@eb.homelinux.org>
Mon, 24 Aug 2009 13:30:36 +0000 (15:30 +0200)
committerEric Bollengier <eric@eb.homelinux.org>
Mon, 24 Aug 2009 13:30:36 +0000 (15:30 +0200)
58 files changed:
bacula/AUTHORS
bacula/autoconf/bacula-macros/os.m4
bacula/autoconf/configure.in
bacula/configure
bacula/platforms/Makefile.in
bacula/platforms/osx/Makefile.in [new file with mode: 0644]
bacula/platforms/osx/files/org.bacula.bacula-fd.plist.in [new file with mode: 0644]
bacula/platforms/osx/files/uninstall.command.in [new file with mode: 0644]
bacula/platforms/osx/resources/Description.plist.in [new file with mode: 0644]
bacula/platforms/osx/resources/Info.plist.in [new file with mode: 0644]
bacula/platforms/osx/resources/ReadMe.html.in [new file with mode: 0644]
bacula/platforms/osx/resources/postflight.in [new file with mode: 0644]
bacula/platforms/osx/resources/preupgrade.in [new file with mode: 0644]
bacula/platforms/redhat/bacula.spec
bacula/src/dird/ua_label.c
bacula/src/filed/acl.c
bacula/src/filed/acl.h
bacula/src/filed/backup.c
bacula/src/filed/filed.h
bacula/src/filed/job.c
bacula/src/filed/restore.c
bacula/src/filed/xattr.c
bacula/src/filed/xattr.h
bacula/src/findlib/find.c
bacula/src/jcr.h
bacula/src/lib/bsock.h
bacula/src/lib/lockmgr.h
bacula/src/lib/message.c
bacula/src/qt-console/console/console.cpp
bacula/src/qt-console/joblist/joblist.cpp
bacula/src/qt-console/main.cpp
bacula/src/qt-console/mediainfo/mediainfo.cpp
bacula/src/qt-console/pages.cpp
bacula/src/qt-console/pages.h
bacula/src/qt-console/status/dirstat.cpp
bacula/src/stored/acquire.c
bacula/src/stored/append.c
bacula/src/stored/autochanger.c
bacula/src/stored/btape.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/dircmd.c
bacula/src/stored/label.c
bacula/src/stored/lock.c
bacula/src/stored/mount.c
bacula/src/stored/spool.c
bacula/src/stored/vol_mgr.c
bacula/src/stored/wait.c
bacula/src/version.h
bacula/technotes
regress/.gitignore
regress/all-dev-tests [new file with mode: 0755]
regress/do_dev [new file with mode: 0755]
regress/scripts/bacula-sd-2disk-drive.conf.in
regress/scripts/config_dart
regress/tests/acl-xattr-test
regress/tests/big-virtual-changer-test
regress/tests/virtual-changer-test

index e6e181f2782cba448f243a8a3aaa51a0cb63c78f..1d0fce27ef9b35b87dbf99e3eb9dfd759d072b60 100644 (file)
@@ -62,6 +62,7 @@ Karl Cunningham
 Kern Sibbald
 Kjetil Torgrim Homme
 Landon Fuller   
+Lorenz Schori
 Luca Berra
 Lucas B. Cohen
 Lucas Di Pentima
index 7fe1a6bf6da3e644a47cc38215bbf482910f03c3..7a3ce55d5a67c58d78b28b79e3d699cc9808e4b0 100644 (file)
@@ -207,6 +207,9 @@ then
 elif test -f /etc/slackware-version
 then
         DISTNAME=slackware
+elif test x$host_vendor = xapple
+then
+    DISTNAME=osx
 elif test $HAVE_UNAME=yes -a x`uname -s` = xDarwin
 then
     DISTNAME=darwin
index 149f9e7c3eb4ef17ce59979a7082735e0546ad4d..fb074230d8e93fc12b07f0464c4bc1cbff7522f1 100644 (file)
@@ -2617,6 +2617,14 @@ darwin)
    PFILES="${PFILES} \
       platforms/darwin/Makefile"
   ;;
+osx)
+   DISTVER=`uname -r`
+   TAPEDRIVE="/dev/nst0"
+   PSCMD="ps -e -o pid,command"
+   MACOSX=macosx
+   PFILES="${PFILES} \
+      platforms/osx/Makefile"
+  ;;
 debian)
    if `test -f /etc/apt/sources.list && grep -q ubuntu /etc/apt/sources.list`; then
       DISTNAME="ubuntu"
index 25a0a85cc8b348d570f7a51e27cee085ec58db23..b711d9fc9682bb22a82bc7efd7bc4128d798b507 100755 (executable)
@@ -16408,6 +16408,9 @@ then
 elif test -f /etc/slackware-version
 then
         DISTNAME=slackware
+elif test x$host_vendor = xapple
+then
+    DISTNAME=osx
 elif test $HAVE_UNAME=yes -a x`uname -s` = xDarwin
 then
     DISTNAME=darwin
@@ -42624,6 +42627,14 @@ darwin)
    PFILES="${PFILES} \
       platforms/darwin/Makefile"
   ;;
+osx)
+   DISTVER=`uname -r`
+   TAPEDRIVE="/dev/nst0"
+   PSCMD="ps -e -o pid,command"
+   MACOSX=macosx
+   PFILES="${PFILES} \
+      platforms/osx/Makefile"
+  ;;
 debian)
    if `test -f /etc/apt/sources.list && grep -q ubuntu /etc/apt/sources.list`; then
       DISTNAME="ubuntu"
index 1a7b89408bd0e92d4e01ec1036cf28b3a583c93d..79101b07fd9b31bf25e53ab48335bcf81d5953c9 100644 (file)
@@ -11,7 +11,7 @@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL = @INSTALL@
 
-SUBDIRS = freebsd redhat solaris unknown openbsd irix gentoo \
+SUBDIRS = freebsd redhat solaris unknown openbsd osx irix gentoo \
          debian darwin aix bsdi mandrake slackware alpha ubuntu
 
 MAKE = make
diff --git a/bacula/platforms/osx/Makefile.in b/bacula/platforms/osx/Makefile.in
new file mode 100644 (file)
index 0000000..cd483d7
--- /dev/null
@@ -0,0 +1,149 @@
+#
+# This is the makefile template for the platform directory
+# which contains general platform installation.
+#
+#  17 August 2009 -- Lorenz Schori
+# 
+#   for Bacula release @VERSION@ (@DATE@) -- @DISTNAME@
+#
+
+
+# bacula version and download site
+BACULA_VERSION:=@VERSION@
+BACULA_DL_URL:=http://downloads.sourceforge.net/project/bacula/bacula/${BACULA_VERSION}/bacula-${BACULA_VERSION}.tar.gz
+
+# fakeroot version and download site
+FAKEROOT_VERSION:=1.13
+FAKEROOT_DL_URL:=http://ftp.de.debian.org/debian/pool/main/f/fakeroot/fakeroot_${FAKEROOT_VERSION}.tar.gz
+
+# Build universal binary. Comment out when building versions of bacula < 3.0.0
+ARCHFLAGS:=-arch i386 -arch ppc
+MACOSX_SDK_SYSROOT:=/Developer/SDKs/MacOSX10.4u.sdk
+MACOSX_VERSION_FLAGS:=-mmacosx-version-min=10.4
+
+# Tools
+PM:=/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
+MAKE:=/usr/bin/make
+CURL:=/usr/bin/curl
+TAR:=/usr/bin/tar
+
+########### you should not have to edit anything beyond this line ###########
+
+# Build paths
+DL_DIR:=dl
+BUILD_DIR:=build
+PRODUCTS_DIR:=products
+TOOLS_DIR:=tools
+
+WORKING_DIR:=${BUILD_DIR}/${BACULA_VERSION}
+BACULA_TAR:=${DL_DIR}/bacula-${BACULA_VERSION}.tar.gz
+BACULA_SOURCE:=${WORKING_DIR}/bacula-${BACULA_VERSION}
+BACULA_DESTDIR:=${WORKING_DIR}/destdir
+BACULA_PREFIX:=/usr/local/bacula-${BACULA_VERSION}
+
+# Detect whether we sit inside the bacula source tree. In this case we won't
+# download the tar from sourceforge but instead work with what its there
+# already
+CURSUB:=$(CURDIR:%/platforms/osx=%)
+ifneq ($(CURDIR),$(CURSUB))
+       BACULA_TAR:=
+       BACULA_SOURCE:=../../
+#      BACULA_VERSION:=$(shell sed -n 's,^VERSION=,,p' $(CURSUB)/autoconf/Make.common)
+endif
+
+PACKAGE_TITLE:=Bacula File Daemon ${BACULA_VERSION}
+PACKAGE_DIR:=${PRODUCTS_DIR}/${PACKAGE_TITLE}
+PACKAGE_BUNDLE:=${PACKAGE_DIR}/${PACKAGE_TITLE}.pkg
+PACKAGE_DMG:=${PRODUCTS_DIR}/${PACKAGE_TITLE}.dmg
+PACKAGE_RESOURCES:=Description.plist Info.plist ReadMe.html postflight preupgrade
+PACKAGE_XRESOURCES:=postflight preupgrade
+
+FAKEROOT_TAR:=${DL_DIR}/fakeroot-${FAKEROOT_VERSION}.tar.gz
+FAKEROOT_SOURCE:=${TOOLS_DIR}/fakeroot-${FAKEROOT_VERSION}
+FAKEROOT_DESTDIR:=${FAKEROOT_SOURCE}/destdir
+FAKEROOT:=${FAKEROOT_DESTDIR}/bin/fakeroot
+
+# Flags for the toolchain
+CONFIGFLAGS:=--enable-client-only --prefix=${BACULA_PREFIX} \
+    --with-dir-password=@DIR_PW@ --with-fd-password=@FD_PW@ \
+    --with-sd-password=@SD_PW@ --with-mon-dir-password=@MON_DIR_PW@ \
+    --with-mon-fd-password=@MON_FD_PW@ --with-mon-sd-password=@MON_SD_PW@ \
+    --with-basename=@BASENAME@ --with-hostname=@HOSTNAME@
+CPPFLAGS:=-isysroot ${MACOSX_SDK_SYSROOT} ${MACOSX_VERSION_FLAGS}
+CFLAGS:=-O -g ${ARCHFLAGS}
+CXXFLAGS:=${CFLAGS}
+LDFLAGS:=${MACOSX_VERSION_FLAGS} ${ARCHFLAGS}
+
+dmg: pkg
+       hdiutil create -srcfolder "${PACKAGE_DIR}" "${PACKAGE_DMG}"
+
+pkg: ${BACULA_DESTDIR} ${WORKING_DIR}/resources ${FAKEROOT_DESTDIR}
+       mkdir -p "${PACKAGE_DIR}"
+
+       ${FAKEROOT} ${PM} -build -ds -v -f "\"${BACULA_DESTDIR}\"" -p "\"${PACKAGE_BUNDLE}\"" \
+               -r "\"${WORKING_DIR}/resources\"" -i "\"${WORKING_DIR}/resources/Info.plist\""
+
+       cp ${WORKING_DIR}/resources/ReadMe.html "${PACKAGE_DIR}/ReadMe.html"
+
+       sed -e "s,@PREFIX@,${BACULA_PREFIX},g" -e "s,@BACULA_VERSION@,${BACULA_VERSION},g" \
+               files/uninstall.command.in > "${PACKAGE_DIR}/uninstall.command";
+       chmod 0775 "${PACKAGE_DIR}/uninstall.command"
+
+${WORKING_DIR}/resources: ${BACULA_DESTDIR}
+       mkdir -p "${WORKING_DIR}/resources"
+
+       for res in ${PACKAGE_RESOURCES}; do \
+               sed -e "s,@PREFIX@,${BACULA_PREFIX},g" -e "s,@BACULA_VERSION@,${BACULA_VERSION},g" \
+                       resources/$$res.in > "${WORKING_DIR}/resources/$$res"; \
+       done
+
+       for xres in ${PACKAGE_XRESOURCES}; do \
+               chmod +x "${WORKING_DIR}/resources/$$xres"; \
+       done
+
+       cp "${BACULA_SOURCE}/LICENSE" "${WORKING_DIR}/resources/License.txt"
+
+${BACULA_DESTDIR}: ${BACULA_SOURCE}
+       (cd ${BACULA_SOURCE} && ./configure ${CONFIGFLAGS} CPPFLAGS="${CPPFLAGS}" CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" LDFLAGS="${LDFLAGS}")
+       ${MAKE} -C ${BACULA_SOURCE} LDFLAGS="-Wl,-syslibroot,${MACOSX_SDK_SYSROOT} ${LDFLAGS}"
+       ${MAKE} -C ${BACULA_SOURCE} install DESTDIR="${CURDIR}/${BACULA_DESTDIR}"
+
+       rm -rf "${BACULA_DESTDIR}/tmp"
+
+       for conffile in ${BACULA_DESTDIR}${BACULA_PREFIX}/etc/*.conf; do \
+               mv $$conffile $$conffile.example; \
+       done
+
+       mkdir -p "${BACULA_DESTDIR}${BACULA_PREFIX}/Library/LaunchDaemons"
+       sed "s,@PREFIX@,${BACULA_PREFIX},g" files/org.bacula.bacula-fd.plist.in \
+               > "${BACULA_DESTDIR}${BACULA_PREFIX}/Library/LaunchDaemons/org.bacula.bacula-fd.plist"
+
+${BACULA_SOURCE}: ${BACULA_TAR}
+       mkdir -p "${WORKING_DIR}"
+       ${TAR} -xzf "${BACULA_TAR}" -C "${WORKING_DIR}"
+
+${BACULA_TAR}:
+       mkdir -p "${DL_DIR}"
+       ${CURL} -L -o "${BACULA_TAR}" "${BACULA_DL_URL}"
+
+${FAKEROOT_DESTDIR}: ${FAKEROOT_SOURCE}
+       (cd ${FAKEROOT_SOURCE} && ./configure --prefix=${CURDIR}/${FAKEROOT_DESTDIR})
+       ${MAKE} -C ${FAKEROOT_SOURCE}
+       ${MAKE} -C ${FAKEROOT_SOURCE} install
+
+${FAKEROOT_SOURCE}: ${FAKEROOT_TAR}
+       mkdir -p "${TOOLS_DIR}"
+       ${TAR} -xzf "${FAKEROOT_TAR}" -C "${TOOLS_DIR}"
+
+${FAKEROOT_TAR}:
+       mkdir -p "${DL_DIR}"
+       ${CURL} -L -o "${FAKEROOT_TAR}" "${FAKEROOT_DL_URL}"
+
+.PHONY: distclean
+distclean: clean
+       rm -rf "${DL_DIR}" "${PRODUCTS_DIR}" "${TOOLS_DIR}"
+
+.PHONY: clean
+clean:
+       rm -rf "${BUILD_DIR}" "${PACKAGE_DIR}" "${PACKAGE_DMG}"
+
diff --git a/bacula/platforms/osx/files/org.bacula.bacula-fd.plist.in b/bacula/platforms/osx/files/org.bacula.bacula-fd.plist.in
new file mode 100644 (file)
index 0000000..9952c40
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>Label</key>
+       <string>org.bacula.bacula-fd</string>
+       <key>ProgramArguments</key>
+       <array>
+               <string>@PREFIX@/sbin/bacula-fd</string>
+               <string>-f</string>
+               <string>-c</string>
+               <string>@PREFIX@/etc/bacula-fd.conf</string>
+       </array>
+       <key>Sockets</key>
+       <dict>
+               <key>Listeners</key>
+               <array>
+                       <dict>
+                               <key>SockServiceName</key>
+                               <string>bacula-fd</string>
+                       </dict>
+               </array>
+       </dict>
+</dict>
+</plist>
diff --git a/bacula/platforms/osx/files/uninstall.command.in b/bacula/platforms/osx/files/uninstall.command.in
new file mode 100644 (file)
index 0000000..90b1efa
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+echo "Bacula file daemon @BACULA_VERSION@ uninstaller"
+
+# Remove startup item
+echo "* Bacula startup item... "
+if [ -f /Library/LaunchDaemons/org.bacula.bacula-fd.plist ]; then
+       sudo launchctl unload /Library/LaunchDaemons/org.bacula.bacula-fd.plist
+       sudo rm /Library/LaunchDaemons/org.bacula.bacula-fd.plist
+       echo "  + removed successfully"
+else
+  echo "  - not found, nothing to remove"
+fi
+
+echo "* Bacula file daemon... "
+if [ -d "/usr/local/bacula-@BACULA_VERSION@" ]; then
+  sudo rm -r "/usr/local/bacula-@BACULA_VERSION@"
+       echo "  + removed successfully"
+else
+  echo "  - not found, nothing to remove"  
+fi
+
+echo "* Installer receipt... "
+if [ -d "/Library/Receipts/Bacula File Daemon @BACULA_VERSION@.pkg" ]; then
+  sudo rm -r "/Library/Receipts/Bacula File Daemon @BACULA_VERSION@.pkg"
+       echo "  + removed successfully"
+else
+  echo "  - not found, nothing to remove"  
+fi
diff --git a/bacula/platforms/osx/resources/Description.plist.in b/bacula/platforms/osx/resources/Description.plist.in
new file mode 100644 (file)
index 0000000..976546e
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>IFPkgDescriptionDescription</key>
+       <string></string>
+       <key>IFPkgDescriptionTitle</key>
+       <string>Bacula File Daemon @BACULA_VERSION@</string>
+</dict>
+</plist>
diff --git a/bacula/platforms/osx/resources/Info.plist.in b/bacula/platforms/osx/resources/Info.plist.in
new file mode 100644 (file)
index 0000000..9d1cd1c
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleIdentifier</key>
+       <string>org.bacula.bacula-fd</string>
+       <key>CFBundleShortVersionString</key>
+       <string>@BACULA_VERSION@</string>
+</dict>
+</plist>
diff --git a/bacula/platforms/osx/resources/ReadMe.html.in b/bacula/platforms/osx/resources/ReadMe.html.in
new file mode 100644 (file)
index 0000000..22914c8
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+
+<html lang="en">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <title>Bacula File Daemon @BACULA_VERSION@</title>
+  <meta name="author" content="Lorenz Schori">
+  <style type="text/css" media="screen">
+    body {font-family: Helvetica, sans-serif}
+  </style>
+  <!-- Date: 2009-08-12 -->
+</head>
+<body>
+  <h1>Bacula File Daemon @BACULA_VERSION@</h1>
+  <p>
+    Bacula is on Open Source, enterprise ready, network based backup program.
+    This installer package contains the bacula file daemon for Mac OS X 10.4
+    or later built as an universal binary for PPC and Intel processors.
+  </p>
+  <h2>Requirements</h2>
+  <p>
+    The bacula file daemon is only the client component of the backup system.
+    For proper operation the file daemon needs to have access to a bacula
+    director and storage daemon, typically installed on a server machine in
+    the local network.
+  </p>
+  <h2>Installation</h2>
+  <p>
+    Open the Bacula File Daemon @BACULA_VERSION@ installer package and follow the
+    directions given to you.
+  </p>
+  <h2>Configuration</h2>
+  <p>
+    After the installation is complete you have to adapt the configuration
+    file to your needs. Use your favorite command line editor and don't forget
+    to become root before you try to open the file. E.g:
+    <pre>sudo vim /usr/local/bacula-@BACULA_VERSION@/etc/bacula-fd.conf</pre>
+  </p>
+  <h2>Operating the File Daemon</h2>
+  <p>
+    Use launchctl to enable and disable the bacula file daemon.
+    <pre>sudo launchctl load -w /Library/LaunchDaemons/org.bacula.bacula-fd.plist</pre></br>
+    <pre>sudo launchctl unload -w /Library/LaunchDaemons/org.bacula.bacula-fd.plist</pre></br>
+  </p>
+  <h2>Uninstalling the File Daemon</h2>
+  <p>
+    Doubleclick the script uninstaller.command to remove the bacula file
+    daemon completely from your system.
+  </p>
+  <h2>Resources</h2>
+  <p>
+    Refer to the bacula website for more information.
+  </p>
+  <a href="http://bacula.org/">http://bacula.org</a>
+</body>
+</html>
diff --git a/bacula/platforms/osx/resources/postflight.in b/bacula/platforms/osx/resources/postflight.in
new file mode 100644 (file)
index 0000000..d0e4bee
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+function genpw() {
+  openssl rand -base64 33
+}
+
+# copy example config files and fix permissions
+if [ ! -f $3@PREFIX@/etc/bacula-fd.conf ]; then
+  DIR_PW=$(genpw)
+  FD_PW=$(genpw)
+  SD_PW=$(genpw)
+  MON_DIR_PW=$(genpw)
+  MON_FD_PW=$(genpw)
+  MON_SD_PW=$(genpw)
+  HOSTNAME=$(hostname -s)
+  sed \
+    -e "s,@DIR_PW@,$DIR_PW,g" \
+    -e "s,@FD_PW@,$FD_PW,g" \
+    -e "s,@SD_PW@,$SD_PW,g" \
+    -e "s,@MON_DIR_PW@,$MON_DIR_PW,g" \
+    -e "s,@MON_FD_PW@,$MON_FD_PW,g" \
+    -e "s,@MON_SD_PW@,$MON_SD_PW,g" \
+    -e "s,@BASENAME@,$HOSTNAME,g" \
+    -e "s,@HOSTNAME@,$HOSTNAME,g" \
+    "$3@PREFIX@/etc/bacula-fd.conf.example" > "$3@PREFIX@/etc/bacula-fd.conf"
+fi
+chmod 0640 "$3@PREFIX@/etc/bacula-fd.conf"
+
+# install startup item
+mkdir -p -m 0755 "$3/Library/LaunchDaemons"
+chmod 0644 "$3@PREFIX@/Library/LaunchDaemons/org.bacula.bacula-fd.plist"
+ln -fs "$3@PREFIX@/Library/LaunchDaemons/org.bacula.bacula-fd.plist" "$3/Library/LaunchDaemons/org.bacula.bacula-fd.plist"
+
+# Load startup item
+/bin/launchctl load "$3/Library/LaunchDaemons/org.bacula.bacula-fd.plist"
diff --git a/bacula/platforms/osx/resources/preupgrade.in b/bacula/platforms/osx/resources/preupgrade.in
new file mode 100644 (file)
index 0000000..99f8d30
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+# unload bacula file daemon before upgrading
+
+if [ -f "$3/Library/LaunchDaemons/org.bacula.bacula-fd.plist" ]; then
+  /bin/launchctl unload "$3/Library/LaunchDaemons/org.bacula.bacula-fd.plist"
+fi
+
index 1a6363a198f6433d04d530bbc9fa64117207010a..0f3754906038c88f904f2248e149c4b495ed2515 100644 (file)
@@ -1441,6 +1441,8 @@ echo "The database update scripts were installed to %{script_dir}/updatedb"
 %endif
 
 %changelog
+* Mon Aug 10 2009 Philipp Storz <philipp.storz@dass-it.de>
+- changes to work with opensuse build service
 * Sat Jun 20 2009 D. Scott Barninger <barninger@fairfieldcomputers.com>
 - Fix bat install which is now handled by make and uses shared libs
 * Sat May 16 2009 D. Scott Barninger <barninger@fairfieldcomputers.com>
index 6d7e9fe90e86289738d947ae51ae592b0dfcc909..83a1e7563f0ba3c981547f86feb5cebc3d92f798 100644 (file)
@@ -1123,6 +1123,7 @@ void status_slots(UAContext *ua, STORE *store_r)
          if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
             strcpy(pr.Name, "?");
          }
+         db_unlock(ua->db);
 
          if (ua->api) {
             ua->send_msg(slot_api_full_format,
@@ -1138,7 +1139,6 @@ void status_slots(UAContext *ua, STORE *store_r)
                          mr.VolumeName, mr.VolStatus, mr.MediaType, pr.Name);
          }
 
-         db_unlock(ua->db);
          continue;
       } else {                  /* TODO: get information from catalog  */
          if (ua->api) {
index ca8313a2e3b3ae12aaa6b01a5557a38c50f26a54..b6f83f5b72518f939328f868509f8ba8374e3565 100644 (file)
@@ -53,7 +53,6 @@
   
 #include "bacula.h"
 #include "filed.h"
-#include "acl.h"
   
 #if !defined(HAVE_ACL)
 /*
@@ -83,8 +82,9 @@ static bacl_exit_code send_acl_stream(JCR *jcr, int stream)
    /*
     * Sanity check
     */
-   if (jcr->acl_data_len <= 0)
+   if (jcr->acl_data->content_length <= 0) {
       return bacl_exit_ok;
+   }
 
    /*
     * Send header
@@ -98,10 +98,10 @@ static bacl_exit_code send_acl_stream(JCR *jcr, int stream)
    /*
     * Send the buffer to the storage deamon
     */
-   Dmsg1(400, "Backing up ACL <%s>\n", jcr->acl_data);
+   Dmsg1(400, "Backing up ACL <%s>\n", jcr->acl_data->content);
    msgsave = sd->msg;
-   sd->msg = jcr->acl_data;
-   sd->msglen = jcr->acl_data_len + 1;
+   sd->msg = jcr->acl_data->content;
+   sd->msglen = jcr->acl_data->content_length + 1;
    if (!sd->send()) {
       sd->msg = msgsave;
       sd->msglen = 0;
@@ -137,7 +137,7 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
    char *acl_text;
 
    if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
-      jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
+      jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text);
       actuallyfree(acl_text);
       return send_acl_stream(jcr, STREAM_ACL_AIX_TEXT);
    }
@@ -146,7 +146,7 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 
 static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream)
 {
-   if (acl_put(jcr->last_fname, jcr->acl_data, 0) != 0) {
+   if (acl_put(jcr->last_fname, jcr->acl_data->content, 0) != 0) {
       return bacl_exit_error;
    }
    return bacl_exit_ok;
@@ -343,8 +343,8 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
        * to acl_to_text() besides.
        */
       if (acl->acl_cnt <= 0) {
-         pm_strcpy(jcr->acl_data, "");
-         jcr->acl_data_len = 0;
+         pm_strcpy(jcr->acl_data->content, "");
+         jcr->acl_data->content_length = 0;
          acl_free(acl);
          return bacl_exit_ok;
       }
@@ -359,15 +359,15 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
           * The ACLs simply reflect the (already known) standard permissions
           * So we don't send an ACL stream to the SD.
           */
-         pm_strcpy(jcr->acl_data, "");
-         jcr->acl_data_len = 0;
+         pm_strcpy(jcr->acl_data->content, "");
+         jcr->acl_data->content_length = 0;
          acl_free(acl);
          return bacl_exit_ok;
       }
 #endif
 
       if ((acl_text = acl_to_text(acl, NULL)) != NULL) {
-         jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
+         jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text);
          acl_free(acl);
          acl_free(acl_text);
          return bacl_exit_ok;
@@ -378,8 +378,8 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
       Dmsg2(100, "acl_to_text error file=%s ERR=%s\n",  
             jcr->last_fname, be.bstrerror());
 
-      pm_strcpy(jcr->acl_data, "");
-      jcr->acl_data_len = 0;
+      pm_strcpy(jcr->acl_data->content, "");
+      jcr->acl_data->content_length = 0;
       acl_free(acl);
       return bacl_exit_error;
    }
@@ -394,8 +394,8 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
          break;                       /* not supported */
 #endif
       case ENOENT:
-         pm_strcpy(jcr->acl_data, "");
-         jcr->acl_data_len = 0;
+         pm_strcpy(jcr->acl_data->content, "");
+         jcr->acl_data->content_length = 0;
          return bacl_exit_ok;
       default:
          /* Some real error */
@@ -404,16 +404,16 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
          Dmsg2(100, "acl_get_file error file=%s ERR=%s\n",  
                jcr->last_fname, be.bstrerror());
 
-         pm_strcpy(jcr->acl_data, "");
-         jcr->acl_data_len = 0;
+         pm_strcpy(jcr->acl_data->content, "");
+         jcr->acl_data->content_length = 0;
          return bacl_exit_error;
       }
    }
    /*
     * Not supported, just pretend there is nothing to see
     */
-   pm_strcpy(jcr->acl_data, "");
-   jcr->acl_data_len = 0;
+   pm_strcpy(jcr->acl_data->content, "");
+   jcr->acl_data->content_length = 0;
    return bacl_exit_ok;
 }
 
@@ -430,7 +430,7 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
     * If we get empty default ACLs, clear ACLs now
     */
    ostype = bac_to_os_acltype(acltype);
-   if (ostype == ACL_TYPE_DEFAULT && strlen(jcr->acl_data) == 0) {
+   if (ostype == ACL_TYPE_DEFAULT && strlen(jcr->acl_data->content) == 0) {
       if (acl_delete_def_file(jcr->last_fname) == 0) {
          return bacl_exit_ok;
       }
@@ -444,12 +444,12 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
       }
    }
 
-   acl = acl_from_text(jcr->acl_data);
+   acl = acl_from_text(jcr->acl_data->content);
    if (acl == NULL) {
       Mmsg2(jcr->errmsg, _("acl_from_text error on file \"%s\": ERR=%s\n"),
             jcr->last_fname, be.bstrerror());
       Dmsg3(100, "acl_from_text error acl=%s file=%s ERR=%s\n",  
-         jcr->acl_data, jcr->last_fname, be.bstrerror());
+         jcr->acl_data->content, jcr->last_fname, be.bstrerror());
       return bacl_exit_error;
    }
 
@@ -462,7 +462,7 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
       Mmsg2(jcr->errmsg, _("acl_valid error on file \"%s\": ERR=%s\n"),
             jcr->last_fname, be.bstrerror());
       Dmsg3(100, "acl_valid error acl=%s file=%s ERR=%s\n",  
-         jcr->acl_data, jcr->last_fname, be.bstrerror());
+         jcr->acl_data->content, jcr->last_fname, be.bstrerror());
       acl_free(acl);
       return bacl_exit_error;
    }
@@ -483,7 +483,7 @@ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
          Mmsg2(jcr->errmsg, _("acl_set_file error on file \"%s\": ERR=%s\n"),
                jcr->last_fname, be.bstrerror());
          Dmsg3(100, "acl_set_file error acl=%s file=%s ERR=%s\n",
-               jcr->acl_data, jcr->last_fname, be.bstrerror());
+               jcr->acl_data->content, jcr->last_fname, be.bstrerror());
          acl_free(acl);
          return bacl_exit_error;
       }
@@ -524,7 +524,7 @@ static bacl_exit_code darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
       return bacl_exit_fatal;
 #endif
 
-   if (jcr->acl_data_len > 0) {
+   if (jcr->acl_data->content_length > 0) {
       return send_acl_stream(jcr, STREAM_ACL_DARWIN_ACCESS_ACL);
    }
    return bacl_exit_ok;
@@ -571,7 +571,7 @@ static bacl_exit_code generic_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
    if (generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS) == bacl_exit_fatal)
       return bacl_exit_fatal;
 
-   if (jcr->acl_data_len > 0) {
+   if (jcr->acl_data->content_length > 0) {
       if (send_acl_stream(jcr, os_access_acl_streams[0]) == bacl_exit_fatal)
          return bacl_exit_fatal;
    }
@@ -582,7 +582,7 @@ static bacl_exit_code generic_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
    if (ff_pkt->type == FT_DIREND) {
       if (generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT) == bacl_exit_fatal)
          return bacl_exit_fatal;
-      if (jcr->acl_data_len > 0) {
+      if (jcr->acl_data->content_length > 0) {
          if (send_acl_stream(jcr, os_default_acl_streams[0]) == bacl_exit_fatal)
             return bacl_exit_fatal;
       }
@@ -637,9 +637,9 @@ static bacl_exit_code tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
    /*
     * Read access ACLs for files, dirs and links
     */
-   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
+   if ((jcr->acl_data->content_length = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
       return bacl_exit_error;
-   if (jcr->acl_data_len > 0) {
+   if (jcr->acl_data->content_length > 0) {
       if (!send_acl_stream(jcr, STREAM_ACL_TRU64_ACCESS_ACL))
          return bacl_exit_error;
    }
@@ -647,9 +647,9 @@ static bacl_exit_code tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
     * Directories can have default ACLs too
     */
    if (ff_pkt->type == FT_DIREND) {
-      if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
+      if ((jcr->acl_data->content_length = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
          return bacl_exit_error;
-      if (jcr->acl_data_len > 0) {
+      if (jcr->acl_data->content_length > 0) {
          if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_ACL))
             return bacl_exit_error;
       }
@@ -659,9 +659,9 @@ static bacl_exit_code tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
        * See http://www.helsinki.fi/atk/unix/dec_manuals/DOC_40D/AQ0R2DTE/DOCU_018.HTM
        * Section 21.5 Default ACLs 
        */
-      if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT_DIR)) < 0)
+      if ((jcr->acl_data->content_length = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT_DIR)) < 0)
          return bacl_exit_error;
-      if (jcr->acl_data_len > 0) {
+      if (jcr->acl_data->content_length > 0) {
          if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_DIR_ACL))
             return bacl_exit_error;
       }
@@ -744,13 +744,13 @@ static bacl_exit_code hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
          /*
           * Not supported, just pretend there is nothing to see
           */
-         pm_strcpy(jcr->acl_data, "");
-         jcr->acl_data_len = 0;
+         pm_strcpy(jcr->acl_data->content, "");
+         jcr->acl_data->content_length = 0;
          return bacl_exit_ok;
 #endif
       case ENOENT:
-         pm_strcpy(jcr->acl_data, "");
-         jcr->acl_data_len = 0;
+         pm_strcpy(jcr->acl_data->content, "");
+         jcr->acl_data->content_length = 0;
          return bacl_exit_ok;
       default:
          Mmsg2(jcr->errmsg, _("getacl error on file \"%s\": ERR=%s\n"),
@@ -758,14 +758,14 @@ static bacl_exit_code hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
          Dmsg2(100, "getacl error file=%s ERR=%s\n",  
                jcr->last_fname, be.bstrerror());
 
-         pm_strcpy(jcr->acl_data, "");
-         jcr->acl_data_len = 0;
+         pm_strcpy(jcr->acl_data->content, "");
+         jcr->acl_data->content_length = 0;
          return bacl_exit_error;
       }
    }
    if (n == 0) {
-      pm_strcpy(jcr->acl_data, "");
-      jcr->acl_data_len = 0;
+      pm_strcpy(jcr->acl_data->content, "");
+      jcr->acl_data->content_length = 0;
       return bacl_exit_ok;
    }
    if ((n = getacl(jcr->last_fname, n, acls)) > 0) {
@@ -774,12 +774,12 @@ static bacl_exit_code hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
           * The ACLs simply reflect the (already known) standard permissions
           * So we don't send an ACL stream to the SD.
           */
-         pm_strcpy(jcr->acl_data, "");
-         jcr->acl_data_len = 0;
+         pm_strcpy(jcr->acl_data->content, "");
+         jcr->acl_data->content_length = 0;
          return bacl_exit_ok;
       }
       if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
-         jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
+         jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text);
          actuallyfree(acl_text);
 
          return send_acl_stream(jcr, STREAM_ACL_HPUX_ACL_ENTRY);
@@ -787,7 +787,7 @@ static bacl_exit_code hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
       Mmsg2(jcr->errmsg, _("acltostr error on file \"%s\": ERR=%s\n"),
             jcr->last_fname, be.bstrerror());
       Dmsg3(100, "acltostr error acl=%s file=%s ERR=%s\n",  
-            jcr->acl_data, jcr->last_fname, be.bstrerror());
+            jcr->acl_data->content, jcr->last_fname, be.bstrerror());
       return bacl_exit_error;
    }
    return bacl_exit_error;
@@ -799,19 +799,19 @@ static bacl_exit_code hpux_parse_acl_streams(JCR *jcr, int stream)
    struct acl_entry acls[NACLENTRIES];
    berrno be;
 
-   n = strtoacl(jcr->acl_data, 0, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP);
+   n = strtoacl(jcr->acl_data->content, 0, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP);
    if (n <= 0) {
       Mmsg2(jcr->errmsg, _("strtoacl error on file \"%s\": ERR=%s\n"),
             jcr->last_fname, be.bstrerror());
       Dmsg3(100, "strtoacl error acl=%s file=%s ERR=%s\n",  
-            jcr->acl_data, jcr->last_fname, be.bstrerror());
+            jcr->acl_data->content, jcr->last_fname, be.bstrerror());
       return bacl_exit_error;
    }
-   if (strtoacl(jcr->acl_data, n, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP) != n) {
+   if (strtoacl(jcr->acl_data->content, n, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP) != n) {
       Mmsg2(jcr->errmsg, _("strtoacl error on file \"%s\": ERR=%s\n"),
             jcr->last_fname, be.bstrerror());
       Dmsg3(100, "strtoacl error acl=%s file=%s ERR=%s\n",  
-            jcr->acl_data, jcr->last_fname, be.bstrerror());
+            jcr->acl_data->content, jcr->last_fname, be.bstrerror());
 
       return bacl_exit_error;
    }
@@ -829,7 +829,7 @@ static bacl_exit_code hpux_parse_acl_streams(JCR *jcr, int stream)
          Mmsg2(jcr->errmsg, _("setacl error on file \"%s\": ERR=%s\n"),
                jcr->last_fname, be.bstrerror());
          Dmsg3(100, "setacl error acl=%s file=%s ERR=%s\n",
-               jcr->acl_data, jcr->last_fname, be.bstrerror());
+               jcr->acl_data->content, jcr->last_fname, be.bstrerror());
          return bacl_exit_error;
       }
    }
@@ -903,8 +903,8 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
    acl_enabled = pathconf(jcr->last_fname, _PC_ACL_ENABLED);
    switch (acl_enabled) {
    case 0:
-      pm_strcpy(jcr->acl_data, "");
-      jcr->acl_data_len = 0;
+      pm_strcpy(jcr->acl_data->content, "");
+      jcr->acl_data->content_length = 0;
       return bacl_exit_ok;
    case -1:
       switch (errno) {
@@ -942,8 +942,8 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
        * The ACLs simply reflect the (already known) standard permissions
        * So we don't send an ACL stream to the SD.
        */
-      pm_strcpy(jcr->acl_data, "");
-      jcr->acl_data_len = 0;
+      pm_strcpy(jcr->acl_data->content, "");
+      jcr->acl_data->content_length = 0;
       return bacl_exit_ok;
    }
 
@@ -957,7 +957,7 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 #endif /* ACL_SID_FMT */
 
    if ((acl_text = acl_totext(aclp, flags)) != NULL) {
-      jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
+      jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text);
       actuallyfree(acl_text);
 
       switch (acl_type(aclp)) {
@@ -1003,7 +1003,7 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream)
             Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"),
                   jcr->last_fname, be.bstrerror());
             Dmsg3(100, "pathconf error acl=%s file=%s ERR=%s\n",  
-                  jcr->acl_data, jcr->last_fname, be.bstrerror());
+                  jcr->acl_data->content, jcr->last_fname, be.bstrerror());
             return bacl_exit_error;
          }
       default:
@@ -1040,11 +1040,11 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream)
          break;
       }
 
-      if ((error = acl_fromtext(jcr->acl_data, &aclp)) != 0) {
+      if ((error = acl_fromtext(jcr->acl_data->content, &aclp)) != 0) {
          Mmsg2(jcr->errmsg, _("acl_fromtext error on file \"%s\": ERR=%s\n"),
                jcr->last_fname, acl_strerror(error));
          Dmsg3(100, "acl_fromtext error acl=%s file=%s ERR=%s\n",  
-               jcr->acl_data, jcr->last_fname, acl_strerror(error));
+               jcr->acl_data->content, jcr->last_fname, acl_strerror(error));
          return bacl_exit_error;
       }
 
@@ -1088,7 +1088,7 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream)
             Mmsg2(jcr->errmsg, _("acl_set error on file \"%s\": ERR=%s\n"),
                   jcr->last_fname, acl_strerror(error));
             Dmsg3(100, "acl_set error acl=%s file=%s ERR=%s\n",  
-                  jcr->acl_data, jcr->last_fname, acl_strerror(error));
+                  jcr->acl_data->content, jcr->last_fname, acl_strerror(error));
             acl_free(aclp);
             return bacl_exit_error;
          }
@@ -1152,13 +1152,13 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
           * So we don't send an ACL stream to the SD.
           */
          free(acls);
-         pm_strcpy(jcr->acl_data, "");
-         jcr->acl_data_len = 0;
+         pm_strcpy(jcr->acl_data->content, "");
+         jcr->acl_data->content_length = 0;
          return bacl_exit_ok;
       }
 
       if ((acl_text = acltotext(acls, n)) != NULL) {
-         jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
+         jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text);
          actuallyfree(acl_text);
          free(acls);
          return send_acl_stream(jcr, STREAM_ACL_SOLARIS_ACLENT);
@@ -1167,7 +1167,7 @@ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
       Mmsg2(jcr->errmsg, _("acltotext error on file \"%s\": ERR=%s\n"),
             jcr->last_fname, be.bstrerror());
       Dmsg3(100, "acltotext error acl=%s file=%s ERR=%s\n",  
-            jcr->acl_data, jcr->last_fname, be.bstrerror());
+            jcr->acl_data->content, jcr->last_fname, be.bstrerror());
    }
 
    free(acls);
@@ -1180,12 +1180,12 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream)
    aclent_t *acls;
    berrno be;
 
-   acls = aclfromtext(jcr->acl_data, &n);
+   acls = aclfromtext(jcr->acl_data->content, &n);
    if (!acls) {
       Mmsg2(jcr->errmsg, _("aclfromtext error on file \"%s\": ERR=%s\n"),
             jcr->last_fname, be.bstrerror());
       Dmsg3(100, "aclfromtext error acl=%s file=%s ERR=%s\n",  
-            jcr->acl_data, jcr->last_fname, be.bstrerror());
+            jcr->acl_data->content, jcr->last_fname, be.bstrerror());
       return bacl_exit_error;
    }
 
@@ -1202,7 +1202,7 @@ static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, int stream)
          Mmsg2(jcr->errmsg, _("acl(SETACL) error on file \"%s\": ERR=%s\n"),
                jcr->last_fname, be.bstrerror());
          Dmsg3(100, "acl(SETACL) error acl=%s file=%s ERR=%s\n",
-               jcr->acl_data, jcr->last_fname, be.bstrerror());
+               jcr->acl_data->content, jcr->last_fname, be.bstrerror());
          actuallyfree(acls);
          return bacl_exit_error;
       }
index 06d4194248c11a40bb68f85ba016e10e0a02f18c..dc60ce41ec239f9146faf54ac99d382f6955e796 100644 (file)
@@ -69,4 +69,13 @@ typedef enum {
 #define BACL_ENOTSUP          ENOTSUP
 #endif
 
+/*
+ * Internal tracking data.
+ */
+struct acl_data_t {
+   POOLMEM *content;
+   uint32_t content_length;
+   uint32_t nr_errors;
+};
+
 #endif
index e92f880b4f7d7102f47ffd6629c70fbcfc3a51b6..83b60508618e89b57c5f2c1d58d19a9f649a7176 100644 (file)
@@ -141,12 +141,15 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
    start_heartbeat_monitor(jcr);
 
    if (have_acl) {
-      jcr->acl_data = get_pool_memory(PM_MESSAGE);
-      jcr->total_acl_errors = 0;
+      jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t));
+      memset((caddr_t)jcr->acl_data, 0, sizeof(acl_data_t));
+      jcr->acl_data->content = get_pool_memory(PM_MESSAGE);
    }
+
    if (have_xattr) {
-      jcr->xattr_data = get_pool_memory(PM_MESSAGE);
-      jcr->total_xattr_errors = 0;
+      jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t));
+      memset((caddr_t)jcr->xattr_data, 0, sizeof(xattr_data_t));
+      jcr->xattr_data->content = get_pool_memory(PM_MESSAGE);
    }
 
    /* Subroutine save_file() is called for each file */
@@ -155,13 +158,13 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
       set_jcr_job_status(jcr, JS_ErrorTerminated);
    }
 
-   if (jcr->total_acl_errors > 0) {
+   if (have_acl && jcr->acl_data->nr_errors > 0) {
       Jmsg(jcr, M_ERROR, 0, _("Encountered %ld acl errors while doing backup\n"),
-           jcr->total_acl_errors);
+           jcr->acl_data->nr_errors);
    }
-   if (jcr->total_xattr_errors > 0) {
+   if (have_xattr && jcr->xattr_data->nr_errors > 0) {
       Jmsg(jcr, M_ERROR, 0, _("Encountered %ld xattr errors while doing backup\n"),
-           jcr->total_xattr_errors);
+           jcr->xattr_data->nr_errors);
    }
 
    accurate_finish(jcr);              /* send deleted or base file list to SD */
@@ -171,11 +174,13 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
    sd->signal(BNET_EOD);            /* end of sending data */
 
    if (have_acl && jcr->acl_data) {
-      free_pool_memory(jcr->acl_data);
+      free_pool_memory(jcr->acl_data->content);
+      free(jcr->acl_data);
       jcr->acl_data = NULL;
    }
    if (have_xattr && jcr->xattr_data) {
-      free_pool_memory(jcr->xattr_data);
+      free_pool_memory(jcr->xattr_data->content);
+      free(jcr->xattr_data);
       jcr->xattr_data = NULL;
    }
    if (jcr->big_buf) {
@@ -619,10 +624,10 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
              * Non-fatal errors, count them and when the number is under ACL_REPORT_ERR_MAX_PER_JOB
              * print the error message set by the lower level routine in jcr->errmsg.
              */
-            if (jcr->total_acl_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
+            if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
                Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
             }
-            jcr->total_acl_errors++;
+            jcr->acl_data->nr_errors++;
             break;
          case bacl_exit_ok:
             break;
@@ -643,10 +648,10 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
              * Non-fatal errors, count them and when the number is under XATTR_REPORT_ERR_MAX_PER_JOB
              * print the error message set by the lower level routine in jcr->errmsg.
              */
-            if (jcr->total_xattr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
+            if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
                Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
             }
-            jcr->total_xattr_errors++;
+            jcr->xattr_data->nr_errors++;
             break;
          case bxattr_exit_ok:
             break;
index b82aef08600ac2b9ab23d29fab8ddde554b34c56..54905cbf445466600514e0be258dde13b5bed316 100644 (file)
@@ -66,6 +66,8 @@ typedef enum {
 #include "filed_conf.h"
 #include "fd_plugins.h"
 #include "findlib/find.h"
+#include "acl.h"
+#include "xattr.h"
 #include "jcr.h"
 #include "protos.h"                   /* file daemon prototypes */
 #include "lib/runscript.h"
index e41d7f270b73ce730874edf309d56cd11807c99c..502d11439bbfa4720bec558a4904a7401948e6b6 100644 (file)
@@ -148,7 +148,7 @@ static char errmsg[]      = "2999 Invalid command\n";
 static char no_auth[]     = "2998 No Authorization\n";
 static char invalid_cmd[] = "2997 Invalid command for a Director with Monitor directive enabled.\n";
 static char OKinc[]       = "2000 OK include\n";
-static char OKest[]       = "2000 OK estimate files=%u bytes=%s\n";
+static char OKest[]       = "2000 OK estimate files=%s bytes=%s\n";
 static char OKlevel[]     = "2000 OK level\n";
 static char OKbackup[]    = "2000 OK backup\n";
 static char OKbootstrap[] = "2000 OK bootstrap\n";
@@ -456,7 +456,7 @@ static int setdebug_cmd(JCR *jcr)
 static int estimate_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
-   char ed2[50];
+   char ed1[50], ed2[50];
 
    if (sscanf(dir->msg, estimatecmd, &jcr->listing) != 1) {
       pm_strcpy(jcr->errmsg, dir->msg);
@@ -465,7 +465,7 @@ static int estimate_cmd(JCR *jcr)
       return 0;
    }
    make_estimate(jcr);
-   dir->fsend(OKest, jcr->num_files_examined,
+   dir->fsend(OKest, edit_uint64_with_commas(jcr->num_files_examined, ed1),
       edit_uint64_with_commas(jcr->JobBytes, ed2));
    dir->signal(BNET_EOD);
    return 1;
index c1dc3b735264a6baf83297535803989a5008f326..808daec84b14a4f5b3867cf85888134df2d57b68 100644 (file)
@@ -251,12 +251,14 @@ void do_restore(JCR *jcr)
    binit(&rctx.forkbfd);
    attr = rctx.attr = new_attr(jcr);
    if (have_acl) {
-      jcr->acl_data = get_pool_memory(PM_MESSAGE);
-      jcr->total_acl_errors = 0;
+      jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t));
+      memset((caddr_t)jcr->acl_data, 0, sizeof(acl_data_t));
+      jcr->acl_data->content = get_pool_memory(PM_MESSAGE);
    }
    if (have_xattr) {
-      jcr->xattr_data = get_pool_memory(PM_MESSAGE);
-      jcr->total_xattr_errors = 0;
+      jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t));
+      memset((caddr_t)jcr->xattr_data, 0, sizeof(xattr_data_t));
+      jcr->xattr_data->content = get_pool_memory(PM_MESSAGE);
    }
 
    while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
@@ -610,8 +612,8 @@ void do_restore(JCR *jcr)
             break;
          }
          if (have_acl) {
-            pm_memcpy(jcr->acl_data, sd->msg, sd->msglen);
-            jcr->acl_data_len = sd->msglen;
+            pm_memcpy(jcr->acl_data->content, sd->msg, sd->msglen);
+            jcr->acl_data->content_length = sd->msglen;
             switch (parse_acl_streams(jcr, rctx.stream)) {
             case bacl_exit_fatal:
                goto bail_out;
@@ -620,10 +622,10 @@ void do_restore(JCR *jcr)
                 * Non-fatal errors, count them and when the number is under ACL_REPORT_ERR_MAX_PER_JOB
                 * print the error message set by the lower level routine in jcr->errmsg.
                 */
-               if (jcr->total_acl_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
+               if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
                   Qmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
                }
-               jcr->total_acl_errors++;
+               jcr->acl_data->nr_errors++;
                break;
             case bacl_exit_ok:
                break;
@@ -649,8 +651,8 @@ void do_restore(JCR *jcr)
             break;
          }
          if (have_xattr) {
-            pm_memcpy(jcr->xattr_data, sd->msg, sd->msglen);
-            jcr->xattr_data_len = sd->msglen;
+            pm_memcpy(jcr->xattr_data->content, sd->msg, sd->msglen);
+            jcr->xattr_data->content_length = sd->msglen;
             switch (parse_xattr_streams(jcr, rctx.stream)) {
             case bxattr_exit_fatal:
                goto bail_out;
@@ -659,10 +661,10 @@ void do_restore(JCR *jcr)
                 * Non-fatal errors, count them and when the number is under XATTR_REPORT_ERR_MAX_PER_JOB
                 * print the error message set by the lower level routine in jcr->errmsg.
                 */
-               if (jcr->total_xattr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
+               if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
                   Qmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
                }
-               jcr->total_xattr_errors++;
+               jcr->xattr_data->nr_errors++;
                break;
             case bxattr_exit_ok:
                break;
@@ -731,7 +733,42 @@ bail_out:
    set_jcr_job_status(jcr, JS_ErrorTerminated);
 
 ok_out:
-   /* Free Signature & Crypto Data */
+   /*
+    * First output the statistics.
+    */
+   Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
+      edit_uint64(jcr->JobBytes, ec1));
+   if (have_acl && jcr->acl_data->nr_errors > 0) {
+      Jmsg(jcr, M_ERROR, 0, _("Encountered %ld acl errors while doing restore\n"),
+           jcr->acl_data->nr_errors);
+   }
+   if (have_xattr && jcr->xattr_data->nr_errors > 0) {
+      Jmsg(jcr, M_ERROR, 0, _("Encountered %ld xattr errors while doing restore\n"),
+           jcr->xattr_data->nr_errors);
+   }
+   if (non_support_data > 1 || non_support_attr > 1) {
+      Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
+         non_support_data, non_support_attr);
+   }
+   if (non_support_rsrc) {
+      Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
+   }
+   if (non_support_finfo) {
+      Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
+   }
+   if (non_support_acl) {
+      Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
+   }
+   if (non_support_crypto) {
+      Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
+   }
+   if (non_support_xattr) {
+      Jmsg(jcr, M_INFO, 0, _("%d non-supported xattr streams ignored.\n"), non_support_xattr);
+   }
+
+   /*
+    * Free Signature & Crypto Data
+    */
    free_signature(rctx);
    free_session(rctx);
    if (jcr->crypto.digest) {
@@ -739,17 +776,22 @@ ok_out:
       jcr->crypto.digest = NULL;
    }
 
-   /* Free file cipher restore context */
+   /*
+    * Free file cipher restore context
+    */
    if (rctx.cipher_ctx.cipher) {
       crypto_cipher_free(rctx.cipher_ctx.cipher);
       rctx.cipher_ctx.cipher = NULL;
    }
+
    if (rctx.cipher_ctx.buf) {
       free_pool_memory(rctx.cipher_ctx.buf);
       rctx.cipher_ctx.buf = NULL;
    }
 
-   /* Free alternate stream cipher restore context */
+   /*
+    * Free alternate stream cipher restore context
+    */
    if (rctx.fork_cipher_ctx.cipher) {
       crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
       rctx.fork_cipher_ctx.cipher = NULL;
@@ -765,48 +807,21 @@ ok_out:
       jcr->compress_buf_size = 0;
    }
 
-   if (have_xattr && jcr->xattr_data) {
-      free_pool_memory(jcr->xattr_data);
-      jcr->xattr_data = NULL;
-   }
    if (have_acl && jcr->acl_data) {
-      free_pool_memory(jcr->acl_data);
+      free_pool_memory(jcr->acl_data->content);
+      free(jcr->acl_data);
       jcr->acl_data = NULL;
    }
 
+   if (have_xattr && jcr->xattr_data) {
+      free_pool_memory(jcr->xattr_data->content);
+      free(jcr->xattr_data);
+      jcr->xattr_data = NULL;
+   }
+
    bclose(&rctx.forkbfd);
    bclose(&rctx.bfd);
    free_attr(rctx.attr);
-   Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
-      edit_uint64(jcr->JobBytes, ec1));
-   if (jcr->total_acl_errors > 0) {
-      Jmsg(jcr, M_ERROR, 0, _("Encountered %ld acl errors while doing restore\n"),
-           jcr->total_acl_errors);
-   }
-   if (jcr->total_xattr_errors > 0) {
-      Jmsg(jcr, M_ERROR, 0, _("Encountered %ld xattr errors while doing restore\n"),
-           jcr->total_xattr_errors);
-   }
-   if (non_support_data > 1 || non_support_attr > 1) {
-      Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
-         non_support_data, non_support_attr);
-   }
-   if (non_support_rsrc) {
-      Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
-   }
-   if (non_support_finfo) {
-      Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
-   }
-   if (non_support_acl) {
-      Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
-   }
-   if (non_support_crypto) {
-      Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
-   }
-   if (non_support_xattr) {
-      Jmsg(jcr, M_INFO, 0, _("%d non-supported xattr streams ignored.\n"), non_support_xattr);
-   }
-
 }
 
 #ifdef HAVE_LIBZ
index c444d62093acbc9348067dcfbbd2b55aa0a22f21..b814183ae444b95b3aa8e0368842f0e11d3626fa 100644 (file)
@@ -45,7 +45,6 @@
 
 #include "bacula.h"
 #include "filed.h"
-#include "xattr.h"
 
 #if !defined(HAVE_XATTR)
 /*
@@ -75,8 +74,9 @@ static bxattr_exit_code send_xattr_stream(JCR *jcr, int stream)
    /*
     * Sanity check
     */
-   if (jcr->xattr_data_len <= 0)
+   if (jcr->xattr_data->content_length <= 0) {
       return bxattr_exit_ok;
+   }
 
    /*
     * Send header
@@ -90,10 +90,10 @@ static bxattr_exit_code send_xattr_stream(JCR *jcr, int stream)
    /*
     * Send the buffer to the storage deamon
     */
-   Dmsg1(400, "Backing up XATTR <%s>\n", jcr->xattr_data);
+   Dmsg1(400, "Backing up XATTR <%s>\n", jcr->xattr_data->content);
    msgsave = sd->msg;
-   sd->msg = jcr->xattr_data;
-   sd->msglen = jcr->xattr_data_len;
+   sd->msg = jcr->xattr_data->content;
+   sd->msglen = jcr->xattr_data->content_length;
    if (!sd->send()) {
       sd->msg = msgsave;
       sd->msglen = 0;
@@ -215,8 +215,8 @@ static uint32_t serialize_xattr_stream(JCR *jcr, uint32_t expected_serialize_len
     * Make sure the serialized stream fits in the poolmem buffer.
     * We allocate some more to be sure the stream is gonna fit.
     */
-   jcr->xattr_data = check_pool_memory_size(jcr->xattr_data, expected_serialize_len + 10);
-   ser_begin(jcr->xattr_data, expected_serialize_len + 10);
+   jcr->xattr_data->content = check_pool_memory_size(jcr->xattr_data->content, expected_serialize_len + 10);
+   ser_begin(jcr->xattr_data->content, expected_serialize_len + 10);
 
    /*
     * Walk the list of xattrs and serialize the data.
@@ -236,9 +236,9 @@ static uint32_t serialize_xattr_stream(JCR *jcr, uint32_t expected_serialize_len
       ser_bytes(current_xattr->value, current_xattr->value_length);
    }
 
-   ser_end(jcr->xattr_data, expected_serialize_len + 10);
-   jcr->xattr_data_len = ser_length(jcr->xattr_data);
-   return jcr->xattr_data_len;
+   ser_end(jcr->xattr_data->content, expected_serialize_len + 10);
+   jcr->xattr_data->content_length = ser_length(jcr->xattr_data->content);
+   return jcr->xattr_data->content_length;
 }
 
 static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt)
@@ -463,8 +463,8 @@ static bxattr_exit_code generic_xattr_parse_streams(JCR *jcr, int stream)
     * Start unserializing the data. We keep on looping while we have not
     * unserialized all bytes in the stream.
     */
-   unser_begin(jcr->xattr_data, jcr->xattr_data_len);
-   while (unser_length(jcr->xattr_data) < jcr->xattr_data_len) {
+   unser_begin(jcr->xattr_data->content, jcr->xattr_data->content_length);
+   while (unser_length(jcr->xattr_data->content) < jcr->xattr_data->content_length) {
       /*
        * First make sure the magic is present. This way we can easily catch corruption.
        * Any missing MAGIC is fatal we do NOT try to continue.
@@ -532,7 +532,7 @@ static bxattr_exit_code generic_xattr_parse_streams(JCR *jcr, int stream)
       free(current_xattr.value);
    }
 
-   unser_end(jcr->xattr_data, jcr->xattr_data_len);
+   unser_end(jcr->xattr_data->content, jcr->xattr_data->content_length);
    return retval;
 }
 
@@ -647,27 +647,15 @@ static int os_default_xattr_streams[2] = { STREAM_XATTR_SOLARIS, STREAM_XATTR_SO
 static int os_default_xattr_streams[1] = { STREAM_XATTR_SOLARIS };
 #endif /* defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) */
 
-/*
- * This is the count of xattrs saved on a certain file, it gets reset
- * on each new file processed and is used to see if we need to send
- * the hidden xattr dir data. We only send that data when we encounter
- * an other xattr on the file.
- */
-static int nr_xattr_saved = 0;
-static char toplevel_hidden_dir_xattr_data[MAXSTRING];
-static int toplevel_hidden_dir_xattr_data_len;
-
 /*
  * This code creates a temporary cache with entries for each xattr which has
  * a link count > 1 (which indicates it has one or more hard linked counterpart(s))
  */
-static alist *xattr_link_cache = NULL;
-
-static xattr_link_cache_entry_t *find_xattr_link_cache_entry(ino_t inum)
+static xattr_link_cache_entry_t *find_xattr_link_cache_entry(JCR *jcr, ino_t inum)
 {
    xattr_link_cache_entry_t *ptr;
 
-   foreach_alist(ptr, xattr_link_cache) {
+   foreach_alist(ptr, jcr->xattr_data->link_cache) {
       if (ptr && ptr->inum == inum) {
          return ptr;
       }
@@ -675,7 +663,7 @@ static xattr_link_cache_entry_t *find_xattr_link_cache_entry(ino_t inum)
    return NULL;
 }
 
-static void add_xattr_link_cache_entry(ino_t inum, char *target)
+static void add_xattr_link_cache_entry(JCR *jcr, ino_t inum, char *target)
 {
    xattr_link_cache_entry_t *ptr;
 
@@ -683,7 +671,7 @@ static void add_xattr_link_cache_entry(ino_t inum, char *target)
    memset((caddr_t)ptr, 0, sizeof(xattr_link_cache_entry_t));
    ptr->inum = inum;
    bstrncpy(ptr->target, target, sizeof(ptr->target));
-   xattr_link_cache->append(ptr);
+   jcr->xattr_data->link_cache->append(ptr);
 }
 
 #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED)
@@ -911,7 +899,7 @@ static bxattr_exit_code solaris_save_xattrs(JCR *jcr, const char *xattr_namespac
  * actual_xattr_data is the content of the xattr file.
  */
 static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
-                                         const char *attrname, bool toplevel_hidden_dir, int stream)
+                                           const char *attrname, bool toplevel_hidden_dir, int stream)
 {
    int cnt;
    int attrfd = -1;
@@ -967,7 +955,6 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
       cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c",
                      target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0);
       break;
-
    case S_IFDIR:
       /*
        * Get any acl on the xattr.
@@ -980,15 +967,17 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
        */
       if (toplevel_hidden_dir) {
          /*
-          * Save the data for later storage when we encounter a real xattr.
-          * Encode the stat struct into an ASCII representation and jump out of the function.
+          * Save the data for later storage when we encounter a real xattr. We store the data
+          * in the jcr->xattr_data->content buffer and flush that just before sending out the
+          * first real xattr. Encode the stat struct into an ASCII representation and jump
+          * out of the function.
           */
          encode_stat(attribs, &st, 0, stream);
-         toplevel_hidden_dir_xattr_data_len = bsnprintf(toplevel_hidden_dir_xattr_data,
-                                                        sizeof(toplevel_hidden_dir_xattr_data),
-                                                        "%s%c%s%c%s%c",
-                                                        target_attrname, 0, attribs, 0,
-                                                        (acl_text) ? acl_text : "", 0);
+         cnt = bsnprintf(buffer, sizeof(buffer),
+                         "%s%c%s%c%s%c",
+                         target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0);
+         pm_memcpy(jcr->xattr_data->content, buffer, cnt);
+         jcr->xattr_data->content_length = cnt;
          goto bail_out;
       } else {
          /*
@@ -1009,7 +998,7 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
          /*
           * See if the cache already knows this inode number.
           */
-         if ((xlce = find_xattr_link_cache_entry(st.st_ino)) != NULL) {
+         if ((xlce = find_xattr_link_cache_entry(jcr, st.st_ino)) != NULL) {
             /*
              * Generate a xattr encoding with the reference to the target in there.
              */
@@ -1017,8 +1006,8 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
             cnt = bsnprintf(buffer, sizeof(buffer),
                             "%s%c%s%c%s%c",
                             target_attrname, 0, attribs, 0, xlce->target, 0);
-            pm_memcpy(jcr->xattr_data, buffer, cnt);
-            jcr->xattr_data_len = cnt;
+            pm_memcpy(jcr->xattr_data->content, buffer, cnt);
+            jcr->xattr_data->content_length = cnt;
             retval = send_xattr_stream(jcr, stream);
 
             /*
@@ -1031,7 +1020,7 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
           * Store this hard linked file in the cache.
           * Store the name relative to the top level xattr space.
           */
-         add_xattr_link_cache_entry(st.st_ino, target_attrname + 1);
+         add_xattr_link_cache_entry(jcr, st.st_ino, target_attrname + 1);
       }
 
       /*
@@ -1066,7 +1055,6 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
          }
       }
       break;
-
    case S_IFLNK:
       /*
        * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
@@ -1093,30 +1081,37 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
       cnt = bsnprintf(buffer, sizeof(buffer),
                       "%s%c%s%c%s%c",
                       target_attrname, 0, attribs, 0, link_source, 0);
-      pm_memcpy(jcr->xattr_data, buffer, cnt);
-      jcr->xattr_data_len = cnt;
+      pm_memcpy(jcr->xattr_data->content, buffer, cnt);
+      jcr->xattr_data->content_length = cnt;
       retval = send_xattr_stream(jcr, stream);
 
+      if (retval == bxattr_exit_ok) {
+         jcr->xattr_data->nr_saved++;
+      }
+
       /*
        * For a soft linked file we are ready now, no need to recursively save the attributes.
        */
       goto bail_out;
-
    default:
       goto bail_out;
    }
 
    /*
-    * See if this is the first real xattr being saved. If it is save the toplevel_hidden_dir attributes first.
+    * See if this is the first real xattr being saved.
+    * If it is save the toplevel_hidden_dir attributes first.
+    * This is easy as its stored already in the jcr->xattr_data->content buffer.
     */
-   if (nr_xattr_saved == 0) {
-      pm_memcpy(jcr->xattr_data, toplevel_hidden_dir_xattr_data, toplevel_hidden_dir_xattr_data_len);
-      jcr->xattr_data_len = toplevel_hidden_dir_xattr_data_len;
+   if (jcr->xattr_data->nr_saved == 0) {
       retval = send_xattr_stream(jcr, STREAM_XATTR_SOLARIS);
+      if (retval != bxattr_exit_ok) {
+         goto bail_out;
+      }
+      jcr->xattr_data->nr_saved++;
    }
 
-   pm_memcpy(jcr->xattr_data, buffer, cnt);
-   jcr->xattr_data_len = cnt;
+   pm_memcpy(jcr->xattr_data->content, buffer, cnt);
+   jcr->xattr_data->content_length = cnt;
 
    /*
     * Only dump the content of regular files.
@@ -1134,9 +1129,9 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
          }
 
          while ((cnt = read(attrfd, buffer, sizeof(buffer))) > 0) {
-            jcr->xattr_data = check_pool_memory_size(jcr->xattr_data, jcr->xattr_data_len + cnt);
-            memcpy(jcr->xattr_data + jcr->xattr_data_len, buffer, cnt);
-            jcr->xattr_data_len += cnt;
+            jcr->xattr_data->content = check_pool_memory_size(jcr->xattr_data->content, jcr->xattr_data->content_length + cnt);
+            memcpy(jcr->xattr_data->content + jcr->xattr_data->content_length, buffer, cnt);
+            jcr->xattr_data->content_length += cnt;
          }
 
          if (cnt < 0) {
@@ -1155,7 +1150,9 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
 
    if (retval) {
       retval = send_xattr_stream(jcr, stream);
-      nr_xattr_saved++;
+      if (retval == bxattr_exit_ok) {
+         jcr->xattr_data->nr_saved++;
+      }
    }
 
    /*
@@ -1439,16 +1436,16 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible)
     * Parse the xattr stream. First the part that is the same for all xattrs.
     */
    used_bytes = 0;
-   total_bytes = jcr->xattr_data_len;
+   total_bytes = jcr->xattr_data->content_length;
 
    /*
     * The name of the target xattr has a leading / we are not interested
     * in that so skip it when decoding the string. We always start a the /
     * of the xattr space anyway.
     */
-   target_attrname = jcr->xattr_data + 1;
+   target_attrname = jcr->xattr_data->content + 1;
    if ((bp = strchr(target_attrname, '\0')) == (char *)NULL ||
-       (used_bytes = (bp - jcr->xattr_data)) >= (total_bytes - 1)) {
+       (used_bytes = (bp - jcr->xattr_data->content)) >= (total_bytes - 1)) {
       goto parse_error;
    }
    attribs = ++bp;
@@ -1539,7 +1536,7 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible)
     * Decode the next field (acl_text).
     */
    if ((bp = strchr(attribs, '\0')) == (char *)NULL ||
-       (used_bytes = (bp - jcr->xattr_data)) >= (total_bytes - 1)) {
+       (used_bytes = (bp - jcr->xattr_data->content)) >= (total_bytes - 1)) {
       goto parse_error;
    }
    acl_text = ++bp;
@@ -1616,7 +1613,7 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible)
          goto bail_out;
       } else {
          if ((bp = strchr(acl_text, '\0')) == (char *)NULL ||
-             (used_bytes = (bp - jcr->xattr_data)) >= total_bytes) {
+             (used_bytes = (bp - jcr->xattr_data->content)) >= total_bytes) {
             goto parse_error;
          }
 
@@ -1643,7 +1640,7 @@ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible)
        * Restore the actual data.
        */
       if (st.st_size > 0) {
-         used_bytes = (data - jcr->xattr_data);
+         used_bytes = (data - jcr->xattr_data->content);
          cnt = total_bytes - used_bytes;
 
          /*
@@ -1782,18 +1779,18 @@ static bxattr_exit_code solaris_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
     * If not just pretend things went ok.
     */
    if (pathconf(jcr->last_fname, _PC_XATTR_EXISTS) > 0) {
-      nr_xattr_saved = 0;
+      jcr->xattr_data->nr_saved = 0;
+      jcr->xattr_data->link_cache = New(alist(10, not_owned_by_alist));
 
       /*
        * As we change the cwd in the save function save the current cwd
        * for restore after return from the solaris_save_xattrs function.
        */
-      xattr_link_cache = New(alist(10, not_owned_by_alist));
       getcwd(cwd, sizeof(cwd));
       retval = solaris_save_xattrs(jcr, NULL, NULL);
       chdir(cwd);
-      delete xattr_link_cache;
-      xattr_link_cache = NULL;
+      delete jcr->xattr_data->link_cache;
+      jcr->xattr_data->link_cache = NULL;
    }
    return retval;
 }
index 16056165e72aaf11725b3742c62a301eaf36d651..90800a038539f0ba2937d4da78cf77654291d163 100644 (file)
@@ -54,6 +54,17 @@ struct xattr_link_cache_entry_t {
    char target[PATH_MAX];
 };
 
+/*
+ * Internal tracking data.
+ */
+struct xattr_data_t {
+   POOLMEM *content;
+   uint32_t content_length;
+   uint32_t nr_errors;
+   uint32_t nr_saved;
+   alist *link_cache;
+};
+
 /*
  * Maximum size of the XATTR stream this prevents us from blowing up the filed.
  */
index efa6820d6d8415ca5d622b6b1f0590e0e2b3f20d..0b6059538d2ea654ef0619d0154d92127f457378 100644 (file)
@@ -240,18 +240,16 @@ bool is_in_fileset(FF_PKT *ff)
             }
          }
       }
-#ifdef xxx
       for (i=0; i<fileset->exclude_list.size(); i++) {
          incexe = (findINCEXE *)fileset->exclude_list.get(i);
          foreach_dlist(node, &incexe->name_list) {
             fname = node->c_str();
-            Dmsg2(000, "Exc fname=%s ff->fname=%s\n", fname, ff->fname);
+            Dmsg2(100, "Exc fname=%s ff->fname=%s\n", fname, ff->fname);
             if (strcmp(fname, ff->fname) == 0) {
                return true;
             }
          }
       }
-#endif
    }
    return false;
 }
index 3c7796f70fb23252ff8a34e7766266fa98dc405e..d35d623c1ae39bd474e5292ec5a6a86357e6cea3 100644 (file)
@@ -148,9 +148,12 @@ struct ATTR_DBR;
 struct Plugin;
 struct save_pkt;
 struct bpContext;
+struct xattr_private_data_t;
 
 #ifdef FILE_DAEMON
 class htable;
+struct acl_data_t;
+struct xattr_data_t;
 
 struct CRYPTO_CTX {
    bool pki_sign;                     /* Enable PKI Signatures? */
@@ -351,12 +354,8 @@ public:
    /* File Daemon specific part of JCR */
    uint32_t num_files_examined;       /* files examined this job */
    POOLMEM *last_fname;               /* last file saved/verified */
-   POOLMEM *acl_data;                 /* data with ACLs for backup/restore */
-   uint32_t acl_data_len;             /* length of acl data buffer */
-   uint32_t total_acl_errors;         /* numbers of errors encountered for acl backup/restore */
-   POOLMEM *xattr_data;               /* data with Extended Attributes for backup/restore */
-   uint32_t xattr_data_len;           /* length of xattr_data buffer */
-   uint32_t total_xattr_errors;       /* numbers of errors encountered for xattr backup/restore */
+   acl_data_t *acl_data;              /* ACLs for backup/restore */
+   xattr_data_t *xattr_data;          /* Extended Attributes for backup/restore */
    int32_t last_type;                 /* type of last file saved/verified */
    int incremental;                   /* set if incremental for SINCE */
    utime_t mtime;                     /* begin time for SINCE */
index 996ce4973e6a36546f147f5c6cef1a07842e1cd3..8c04a6e9cf2229c7708c1ec86688804f7cfa4a11 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2009 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.
@@ -51,6 +51,32 @@ void stop_bsock_timer(btimer_t *wid);
 
 
 class BSOCK {
+/* 
+ * Note, keep this public part before the private otherwise
+ *  bat breaks on some systems such as RedHat.
+ */
+public:
+   uint64_t read_seqno;               /* read sequence number */
+   POOLMEM *msg;                      /* message pool buffer */
+   POOLMEM *errmsg;                   /* edited error message */
+   RES *res;                          /* Resource to which we are connected */
+   FILE *m_spool_fd;                  /* spooling file */
+   TLS_CONNECTION *tls;               /* associated tls connection */
+   IPADDR *src_addr;                  /* IP address to source connections from */
+   uint32_t in_msg_no;                /* input message number */
+   uint32_t out_msg_no;               /* output message number */
+   int32_t msglen;                    /* message length */
+   volatile time_t timer_start;       /* time started read/write */
+   volatile time_t timeout;           /* timeout BSOCK after this interval */
+   int m_fd;                          /* socket file descriptor */
+   int b_errno;                       /* bsock errno */
+   int m_blocking;                    /* blocking state (0 = nonblocking, 1 = blocking) */
+   volatile int errors;               /* incremented for each error on socket */
+   volatile bool m_suppress_error_msgs; /* set to suppress error messages */
+
+   struct sockaddr client_addr;       /* client's IP address */
+   struct sockaddr_in peer_addr;      /* peer's IP address */
+
 private:
    BSOCK *m_next;                     /* next BSOCK if duped */
    JCR *m_jcr;                        /* jcr or NULL for error msgs */
@@ -72,26 +98,6 @@ private:
                int port, utime_t heart_beat, int *fatal);
    
 public:
-   uint64_t read_seqno;               /* read sequence number */
-   uint32_t in_msg_no;                /* input message number */
-   uint32_t out_msg_no;               /* output message number */
-   int m_fd;                          /* socket file descriptor */
-   TLS_CONNECTION *tls;               /* associated tls connection */
-   int32_t msglen;                    /* message length */
-   int b_errno;                       /* bsock errno */
-   int m_blocking;                    /* blocking state (0 = nonblocking, 1 = blocking) */
-   volatile int errors;               /* incremented for each error on socket */
-   volatile bool m_suppress_error_msgs: 1; /* set to suppress error messages */
-   volatile time_t timer_start;       /* time started read/write */
-   volatile time_t timeout;           /* timeout BSOCK after this interval */
-   POOLMEM *msg;                      /* message pool buffer */
-   POOLMEM *errmsg;                   /* edited error message */
-   RES *res;                          /* Resource to which we are connected */
-   FILE *m_spool_fd;                  /* spooling file */
-   struct sockaddr client_addr;       /* client's IP address */
-   struct sockaddr_in peer_addr;      /* peer's IP address */
-   IPADDR *src_addr;                  /* IP address to source connections from */
-
    /* methods -- in bsock.c */
    void init();
    void free_bsock();
index 173c90537223ad0c2e0916e48f400715a27c6cb9..697b84483826ce8da3caa237dbff40982a62f7e4 100644 (file)
@@ -138,9 +138,9 @@ int lmgr_thread_create(pthread_t *thread,
 # define lmgr_dump()
 # define lmgr_init_thread()
 # define lmgr_cleanup_thread()
-# define lmgr_pre_lock(m)
+# define lmgr_pre_lock(m, f, l)
 # define lmgr_post_lock()
-# define lmgr_do_lock(m)
+# define lmgr_do_lock(m, f, l)
 # define lmgr_do_unlock(m)
 # define lmgr_cleanup_main()
 # define P(x) lmgr_p(&(x))
index b8bbff30e178658d89da4687727be7cf22d49782..7acf7447a35e2b2c2f46b664f7a3f0c1bddf4031 100644 (file)
@@ -624,6 +624,7 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
     if (mtime == 1) {
        *dt = 0;
        dtlen = 0;
+       mtime = time(NULL);      /* get time for SQL log */
     } else {
        bstrftime_ny(dt, sizeof(dt), mtime);
        dtlen = strlen(dt);
index 4201d61ce2c809c224924566a240cdfa61fba290..f1075948640c40b06236b2423b5c2139419c4d6a 100644 (file)
@@ -50,6 +50,10 @@ Console::Console(QTabWidget *parent)
    m_console = this;
    m_warningPrevent = false;
    m_dircommCounter = 0;
+
+   /* 
+    * Create a connection to the Director and put it in a hash table
+    */
    m_dircommHash.insert(m_dircommCounter, new DirComm(this, m_dircommCounter));
 
    setupUi(this);
index 95dcc8e6741534e8440b56e64006837c46955851..d131b0bdf9c9366a168c78720de0a56aa0e11a24 100644 (file)
@@ -231,16 +231,7 @@ void JobList::populateTable()
    }
 
    /* make read only */
-   int rcnt = mp_tableWidget->rowCount();
-   int ccnt = mp_tableWidget->columnCount();
-   for(int r=0; r < rcnt; r++) {
-      for(int c=0; c < ccnt; c++) {
-         QTableWidgetItem* item = mp_tableWidget->item(r, c);
-         if (item) {
-            item->setFlags(Qt::ItemFlags(item->flags() & (~Qt::ItemIsEditable)));
-         }
-      }
-   }
+   mp_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
 }
 
 void JobList::prepareFilterWidgets()
index 6d9f917bf05f1d55e1a04f3ac8a5c186c3c68cf9..b34b49755c276d7eaf8e3f14d3bb5cab8d436dd3 100644 (file)
@@ -58,6 +58,7 @@ static char *configfile = NULL;
 int main(int argc, char *argv[])
 {
    int ch;
+   int rc;
    bool no_signals = true;
    bool test_config = false;
 
@@ -158,7 +159,9 @@ int main(int argc, char *argv[])
    mainWin = new MainWin;
    mainWin->show();
 
-   return app->exec();
+   rc = app->exec();
+// sm_dump(false);
+   return rc;
 }
 
 void terminate_console(int /*sig*/)
index bbb4e7df1ddc7a87cd35c0ff5e2cbd0653b52cfd..2de3f2128d45eab621da612697118335b8d1c123 100644 (file)
@@ -254,15 +254,5 @@ void MediaInfo::populateForm()
    tableJob->verticalHeader()->hide();
 
    /* make read only */
-   int rcnt = tableJob->rowCount();
-   int ccnt = tableJob->columnCount();
-   for(int r=0; r < rcnt; r++) {
-      for(int c=0; c < ccnt; c++) {
-         QTableWidgetItem* item = tableJob->item(r, c);
-         if (item) {
-            item->setFlags(Qt::ItemFlags(item->flags() & (~Qt::ItemIsEditable)));
-         }
-      }
-   }
-
+   tableJob->setEditTriggers(QAbstractItemView::NoEditTriggers);
 }
index 293bf70758f63e1ccc3e727c474abdcf63027ee1..49321898149d39cd325fd2a0dc41a2b175edf000 100644 (file)
@@ -87,10 +87,10 @@ void Pages::dockPage()
 
    /* Set docked flag */
    m_docked = true;
+   m_onceDocked = true;
    mainWin->tabWidget->setCurrentWidget(this);
    /* lets set the page selectors action for docking or undocking */
    setContextMenuDockText();
-
 }
 
 /*
@@ -140,6 +140,17 @@ bool Pages::isDocked()
    return m_docked;
 }
 
+/*
+ * This function is because after the tabbed widget was added I could not tell
+ * from is docked if it had been docked yet.  To prevent status pages from requesting
+ * status from the director
+ */
+bool Pages::isOnceDocked()
+{
+   return m_onceDocked;
+}
+
+
 /*
  * To keep m_closeable protected as well
  */
@@ -221,6 +232,7 @@ void Pages::pgInitialize(const QString &name)
 void Pages::pgInitialize(const QString &tname, QTreeWidgetItem *parentTreeWidgetItem)
 {
    m_docked = false;
+   m_onceDocked = false;
    if (tname.size()) {
       m_name = tname;
    }
index 654dd2ad9509fe986415a60ee6622297e85a6b85..4cdacc9aea84ae892ee0dd53edb52bacf56fd153 100644 (file)
@@ -59,6 +59,7 @@ public:
    void undockPage();
    void togglePageDocking();
    bool isDocked();
+   bool isOnceDocked();
    bool isCloseable();
    QTabWidget *m_parent;
    QList<QAction*> m_contextActions;
@@ -91,6 +92,7 @@ protected:
    void setTitle();
    bool m_closeable;
    bool m_docked;
+   bool m_onceDocked;
    Console *m_console;
    QString m_name;
 };
index 890b07c1750e6d7fb64a170ae9d997e2bdd65ed2..91796d04c66049306bcf9de44050957f9ebbb084 100644 (file)
@@ -101,7 +101,7 @@ void DirStat::timerTriggered()
    if (value == 0) {
       value = spinBox->value();
       bool iscurrent = mainWin->tabWidget->currentIndex() == mainWin->tabWidget->indexOf(this);
-      if (((isDocked() && iscurrent) || (!isDocked())) && (checkBox->checkState() == Qt::Checked)) {
+      if (((isDocked() && iscurrent) || ((!isDocked()) && isOnceDocked())) && (checkBox->checkState() == Qt::Checked)) {
          populateAll();
       }
    }
index 51cda83e734837496924ff333752d545f11c8a7a..1d382d1f58f36b1d36e743ff537088a45a590653 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-2009 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.
@@ -245,7 +245,8 @@ bool acquire_device_for_read(DCR *dcr)
          }
          goto default_path;
       case VOL_NAME_ERROR:
-         Dmsg0(50, "Vol name error.\n");
+         Dmsg3(50, "Vol name=%s want=%s drv=%s.\n", dev->VolHdr.VolumeName, 
+               dcr->VolumeName, dev->print_name());
          if (dev->is_volume_to_unload()) {
             goto default_path;
          }
@@ -253,6 +254,7 @@ bool acquire_device_for_read(DCR *dcr)
          if (!unload_autochanger(dcr, -1)) {
             /* at least free the device so we can re-open with correct volume */
             dev->close();                                                          
+            free_volume(dev);
          }
          dev->set_load();
          /* Fall through */
@@ -267,6 +269,7 @@ default_path:
           */
          if (dev->requires_mount()) {
             dev->close();
+            free_volume(dev);
          }
          
          /* Call autochanger only once unless ask_sysop called */
@@ -333,7 +336,6 @@ get_out:
    return ok;
 }
 
-
 /*
  * Acquire device for writing. We permit multiple writers.
  *  If this is the first one, we read the label.
@@ -352,7 +354,8 @@ DCR *acquire_device_for_append(DCR *dcr)
 
    init_device_wait_timers(dcr);
 
-   dev->dblock(BST_DOING_ACQUIRE);
+   P(dev->acquire_mutex);           /* only one job at a time */
+   dev->dlock();
    Dmsg1(100, "acquire_append device is %s\n", dev->is_tape()?"tape":
         (dev->is_dvd()?"DVD":"disk"));
 
@@ -386,6 +389,9 @@ DCR *acquire_device_for_append(DCR *dcr)
    }
 
    if (!have_vol) {
+      dev->r_dlock(true);
+      block_device(dev, BST_DOING_ACQUIRE);
+      dev->dunlock();
       Dmsg1(190, "jid=%u Do mount_next_write_vol\n", (uint32_t)jcr->JobId);
       if (!dcr->mount_next_write_volume()) {
          if (!job_canceled(jcr)) {
@@ -395,9 +401,13 @@ DCR *acquire_device_for_append(DCR *dcr)
             Dmsg1(200, "Could not ready device %s for append.\n", 
                dev->print_name());
          }
+         dev->dlock();
+         unblock_device(dev);
          goto get_out;
       }
       Dmsg2(190, "Output pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num);
+      dev->dlock();
+      unblock_device(dev);
    }
 
    dev->num_writers++;                /* we are now a writer */
@@ -412,9 +422,9 @@ DCR *acquire_device_for_append(DCR *dcr)
    ok = true;
 
 get_out:
-   dev->dlock();
    dcr->clear_reserved();
-   dev->dunblock(DEV_LOCKED);
+   dev->dunlock();
+   V(dev->acquire_mutex);
    return ok ? dcr : NULL;
 }
 
@@ -504,6 +514,7 @@ bool release_device(DCR *dcr)
    if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
       dvd_remove_empty_part(dcr);        /* get rid of any empty spool part */
       dev->close();
+      free_volume(dev);
    }
 
    /* Fire off Alert command and include any output */
index a458d4111ec5db847b8baeb1cd1658ab82507ea4..8fddd1fe05c94a46387da5981e2bfcb6d0f65090 100644 (file)
@@ -264,7 +264,7 @@ bool do_append_data(JCR *jcr)
       job_elapsed = 1;
    }
 
-   Jmsg(dcr->jcr, M_INFO, 0, _("Job write elapsed time = %02d:%02d:%02d, Transfer rate = %s bytes/second\n"),
+   Jmsg(dcr->jcr, M_INFO, 0, _("Job write elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n"),
          job_elapsed / 3600, job_elapsed % 3600 / 60, job_elapsed % 60,
          edit_uint64_with_suffix(jcr->JobBytes / job_elapsed, ec));
 
@@ -277,7 +277,7 @@ bool do_append_data(JCR *jcr)
     */
    if (ok || dev->can_write()) {
       if (!write_session_label(dcr, EOS_LABEL)) {
-         Jmsg1(jcr, M_FATAL, 0, _("Error writting end session label. ERR=%s\n"),
+         Jmsg1(jcr, M_FATAL, 0, _("Error writing end session label. ERR=%s\n"),
                dev->bstrerror());
          set_jcr_job_status(jcr, JS_ErrorTerminated);
          ok = false;
index 765c4ac528005b564774bda060bd98987f5e76da..3cec6dd19d622c99441fb8c4e9d8cb0ef4cabc68 100644 (file)
@@ -427,8 +427,8 @@ static bool unload_other_drive(DCR *dcr, int slot)
       break;
    }
    if (dev->is_busy()) {
-      Jmsg(dcr->jcr, M_WARNING, 0, _("Volume \"%s\" is in use by device %s\n"),
-           dcr->VolumeName, dev->print_name());
+      Jmsg(dcr->jcr, M_WARNING, 0, _("Volume \"%s\" wanted on %s is in use by device %s\n"),
+           dcr->VolumeName, dcr->dev->print_name(), dev->print_name());
       Dmsg4(100, "Vol %s for dev=%s is busy dev=%s slot=%d\n",
            dcr->VolumeName, dcr->dev->print_name(), dev->print_name(), dev->get_slot());
       Dmsg2(100, "num_writ=%d reserv=%d\n", dev->num_writers, dev->num_reserved());
index 8638d2b7ccce15ea0b2a369e1143c8150d8e1b48..61c14e5aafa4e87a0350308fde4ece91afc2938c 100644 (file)
@@ -634,7 +634,7 @@ static void capcmd()
 }
 
 /*
- * Test writting larger and larger records.
+ * Test writing larger and larger records.
  * This is a torture test for records.
  */
 static void rectestcmd()
@@ -643,7 +643,7 @@ static void rectestcmd()
    DEV_RECORD *rec;
    int i, blkno = 0;
 
-   Pmsg0(0, _("Test writting larger and larger records.\n"
+   Pmsg0(0, _("Test writing larger and larger records.\n"
 "This is a torture test for records.\nI am going to write\n"
 "larger and larger records. It will stop when the record size\n"
 "plus the header exceeds the block size (by default about 64K)\n"));
@@ -2024,7 +2024,7 @@ static void fillcmd()
          set_jcr_job_status(jcr, JS_ErrorTerminated);
       }
       if (!write_session_label(dcr, EOS_LABEL)) {
-         Pmsg1(000, _("Error writting end session label. ERR=%s\n"), dev->bstrerror());
+         Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
          ok = false;
       }
       /* Write out final block of this session */
index d17c17f018f7687d8743edfc87ae2c83b789826c..eb4679f7e2b0f8d41f5f280c3570e0d2e4116b1b 100644 (file)
@@ -52,7 +52,7 @@
 
 /*
  * Handling I/O errors and end of tape conditions are a bit tricky.
- * This is how it is currently done when writting.
+ * This is how it is currently done when writing.
  * On either an I/O error or end of tape,
  * we will stop writing on the physical device (no I/O recovery is
  * attempted at least in this daemon). The state flag will be sent
@@ -256,6 +256,12 @@ init_dev(JCR *jcr, DEVRES *device)
       Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat));
       Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
    }
+   if ((errstat = pthread_mutex_init(&dev->acquire_mutex, NULL)) != 0) {
+      berrno be;
+      dev->dev_errno = errstat;
+      Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat));
+      Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
+   }
 #ifdef xxx
    if ((errstat = rwl_init(&dev->lock)) != 0) {
       berrno be;
index 052015e23f2b81d6b673b9cca3e9a34611ea1812..22734bb8052d8e80aada2fc22cc1d5ca1342278d 100644 (file)
@@ -211,17 +211,18 @@ private:
    int m_fd;                          /* file descriptor */
    int m_blocked;                     /* set if we must wait (i.e. change tape) */
    int m_count;                       /* Mutex use count -- DEBUG only */
+   int m_num_reserved;                /* counter of device reservations */
+   int32_t m_slot;                    /* slot loaded in drive or -1 if none */ 
    pthread_t m_pid;                   /* Thread that locked -- DEBUG only */
    bool m_unload;                     /* set when Volume must be unloaded */
    bool m_load;                       /* set when Volume must be loaded */
-   int m_num_reserved;                /* counter of device reservations */
-   int32_t m_slot;                    /* slot loaded in drive or -1 if none */ 
 
 public:
    DEVICE * volatile swap_dev;        /* Swap vol from this device */
    dlist *attached_dcrs;              /* attached DCR list */
    pthread_mutex_t m_mutex;           /* access control */
    pthread_mutex_t spool_mutex;       /* mutex for updating spool_size */
+   pthread_mutex_t acquire_mutex;     /* mutex for acquire code */
    pthread_cond_t wait;               /* thread wait variable */
    pthread_cond_t wait_next_vol;      /* wait for tape to be mounted */
    pthread_t no_wait_id;              /* this thread must not wait */
@@ -443,12 +444,12 @@ public:
     * Locking and blocking calls
     */
 #ifdef  SD_DEBUG_LOCK
-   void _r_dlock(const char *, int);      /* in lock.c */
+   void _r_dlock(const char *, int, bool locked=false);      /* in lock.c */
    void _r_dunlock(const char *, int);    /* in lock.c */
    void _dlock(const char *, int);        /* in lock.c */
    void _dunlock(const char *, int);      /* in lock.c */
 #else
-   void r_dlock();                        /* in lock.c */
+   void r_dlock(bool locked=false);                        /* in lock.c */
    void r_dunlock() { dunlock(); }
    void dlock() { P(m_mutex); } 
    void dunlock() { V(m_mutex); } 
index 3e1e613c6fd0bd9a1631971f50ceafa8e08dc8bc..4f4a2d72f92967f6c3b04b52749ea28b9584191f 100644 (file)
@@ -814,6 +814,7 @@ static bool unmount_cmd(JCR *jcr)
             if (!unload_autochanger(dcr, -1)) {
                /* ***FIXME**** what is this ????  */
                dev->close();
+               free_volume(dev);
             }
             if (dev->is_unmountable() && !dev->unmount(0)) {
                dir->fsend(_("3907 %s"), dev->bstrerror());
@@ -845,6 +846,7 @@ static bool unmount_cmd(JCR *jcr)
             clear_thread_id(dev->no_wait_id);
             if (!unload_autochanger(dcr, -1)) {
                dev->close();
+               free_volume(dev);
             }
             if (dev->is_unmountable() && !dev->unmount(0)) {
                dir->fsend(_("3907 %s"), dev->bstrerror());
index 48656a4f3f1a1b292b184ad6b9eb1adc3dd6c1e1..cfb43128f0f036114f250fdadf76f5e54dac8e9d 100644 (file)
@@ -237,6 +237,7 @@ int read_dev_volume_label(DCR *dcr)
    if (reserve_volume(dcr, dev->VolHdr.VolumeName) == NULL) {
       Mmsg2(jcr->errmsg, _("Could not reserve volume %s on %s\n"),
            dev->VolHdr.VolumeName, dev->print_name());
+      Dmsg2(150, "Could not reserve volume %s on %s\n", dev->VolHdr.VolumeName, dev->print_name());
       stat = VOL_NAME_ERROR;
       goto bail_out;
    }
index a1e7aa69b60261619867d4063327480d94c9e7fd..392eab47a148a7a40f91c5f2fe6ffab790c7ddf1 100644 (file)
@@ -206,17 +206,19 @@ void DEVICE::_r_dunlock(const char *file, int line)
  * and preparing the label.
  */
 #ifdef SD_DEBUG_LOCK
-void DEVICE::_r_dlock(const char *file, int line)
+void DEVICE::_r_dlock(const char *file, int line, bool locked)
 {
    Dmsg3(sd_dbglvl+1, "r_dlock blked=%s from %s:%d\n", this->print_blocked(),
          file, line);
 #else
-void DEVICE::r_dlock()
+void DEVICE::r_dlock(bool locked)
 {
 #endif
    int stat;
-   P(m_mutex); /*    this->dlock();   */
-   m_count++;  /*    this->dlock() */
+   if (!locked) {
+      P(m_mutex); /*    this->dlock();   */
+      m_count++;  /*    this->dlock() */
+   }
    if (this->blocked() && !pthread_equal(this->no_wait_id, pthread_self())) {
       this->num_waiting++;             /* indicate that I am waiting */
       while (this->blocked()) {
index 06d48b36d14fbae78382fbea0608f1b1fbd07825..ea8571c757c1191851f68031eb4873ef53c091e9 100644 (file)
@@ -145,6 +145,7 @@ mount_next_vol:
       autochanger = false;
       VolCatInfo.Slot = 0;
       ask = retry >= 2;
+      do_find = true;           /* do find_a_volume if we retry */
    }
    Dmsg1(150, "autoload_dev returns %d\n", autochanger);
    /*
@@ -180,6 +181,7 @@ mount_next_vol:
 
    if (dev->poll && dev->has_cap(CAP_CLOSEONPOLL)) {
       dev->close();
+      free_volume(dev);
    }
 
    /* Ensure the device is open */
@@ -474,6 +476,7 @@ int DCR::check_volume_label(bool &ask, bool &autochanger)
       /* Needed, so the medium can be changed */
       if (dev->requires_mount()) {
          dev->close();
+         free_volume(dev);
       }
       goto check_next_volume;
    }
@@ -544,6 +547,12 @@ void DCR::do_swapping(bool is_writing)
          Dmsg1(100, "=== set in_use vol=%s\n", dev->vol->vol_name);
          dev->vol->set_in_use();
          dev->VolHdr.VolumeName[0] = 0;  /* don't yet have right Volume */
+      } else {
+         Dmsg1(100, "No vol on dev=%s\n", dev->print_name());
+      }
+      if (dev->swap_dev->vol) {
+         Dmsg2(100, "Vol=%s on dev=%s\n", dev->swap_dev->vol->vol_name,
+              dev->swap_dev->print_name());
       }
       dev->swap_dev = NULL;
    }
index f462538bf7cf837dad512fa4bfa5b91d176cec58..d40f7a85aecc082ee902cd70fdc681496f596e29 100644 (file)
@@ -324,7 +324,7 @@ static bool despool_data(DCR *dcr, bool commit)
       despool_elapsed = 1;
    }
 
-   Jmsg(dcr->jcr, M_INFO, 0, _("Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s bytes/second\n"),
+   Jmsg(dcr->jcr, M_INFO, 0, _("Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n"),
          despool_elapsed / 3600, despool_elapsed % 3600 / 60, despool_elapsed % 60,
          edit_uint64_with_suffix(jcr->dcr->job_spool_size / despool_elapsed, ec1));
 
index 0d6b088912039a914e75408797eca835477e70d6..55b7001e8b014e36814314e1ae31f682bd21dd7e 100644 (file)
@@ -416,6 +416,10 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
       nvol->dev = NULL;                  /* don't zap dev entry */
       free_vol_item(nvol);
 
+      if (vol->dev) {
+         Dmsg2(dbglvl, "dev=%s vol->dev=%s\n", dev->print_name(), vol->dev->print_name());
+      }
+         
       /*
        * Check if we are trying to use the Volume on a different drive
        *  dev      is our device
@@ -442,8 +446,15 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
             vol->dev = dev;              /* point the Volume at our drive */
             dev->vol = vol;              /* point our drive at the Volume */
          } else {
-            Dmsg3(dbglvl, "==== Swap not possible Vol busy vol=%s from dev=%s to %s\n", 
+            Dmsg5(dbglvl, "==== Swap not possible Vol busy=%d swap=%d vol=%s from dev=%s to %s\n", 
+               vol->dev->is_busy(), vol->is_swapping(),
                VolumeName, vol->dev->print_name(), dev->print_name());
+            if (vol->is_swapping() && dev->swap_dev) {
+               Dmsg2(dbglvl, "Swap vol=%s dev=%s\n", vol->vol_name, dev->swap_dev->print_name());
+            } else {
+               Dmsg1(dbglvl, "swap_dev=%p\n", dev->swap_dev);
+            }
+            debug_list_volumes("failed swap");
             vol = NULL;                  /* device busy */
             goto get_out;
          }
@@ -610,12 +621,14 @@ bool free_volume(DEVICE *dev)
    vol = dev->vol;
    /* Don't free a volume while it is being swapped */
    if (!vol->is_swapping()) {
-      Dmsg1(dbglvl, "=== clear in_use vol=%s\n", dev->vol->vol_name);
+      Dmsg1(dbglvl, "=== clear in_use vol=%s\n", vol->vol_name);
       dev->vol = NULL;
       vol_list->remove(vol);
       Dmsg2(dbglvl, "=== remove volume %s dev=%s\n", vol->vol_name, dev->print_name());
       free_vol_item(vol);
       debug_list_volumes("free_volume");
+   } else {
+      Dmsg1(dbglvl, "=== cannot clear swapping vol=%s\n", vol->vol_name);
    }
    unlock_volumes();
    return true;
index 573f97bacae8101bc10c9f789150ccdfdf123390..f8fbb970f65f85e39431936fe51902d82590cb5d 100644 (file)
@@ -104,11 +104,12 @@ int wait_for_sysop(DCR *dcr)
       Dmsg4(dbglvl, "I'm going to sleep on device %s. HB=%d rem_wait=%d add_wait=%d\n", 
          dev->print_name(), (int)me->heartbeat_interval, dev->rem_wait_sec, add_wait);
       start = time(NULL);
+
       /* Wait required time */
       stat = pthread_cond_timedwait(&dev->wait_next_vol, &dev->m_mutex, &timeout);
+
       Dmsg2(dbglvl, "Wokeup from sleep on device stat=%d blocked=%s\n", stat,
          dev->print_blocked());
-
       now = time(NULL);
       total_waited = now - first_start;
       dev->rem_wait_sec -= (now - start);
@@ -135,7 +136,6 @@ int wait_for_sysop(DCR *dcr)
          break;
       }
 
-
       if (dev->rem_wait_sec <= 0) {  /* on exceeding wait time return */
          Dmsg0(dbglvl, "Exceed wait time.\n");
          stat = W_TIMEOUT;
index da24eb4c3d123596f3055c9605e737098dab658c..411f5d59e8d9d5c27237379bb36fde341e5f258b 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "3.0.3"
-#define BDATE   "09 August 2009"
-#define LSMDATE "09Aug09"
+#define BDATE   "22 August 2009"
+#define LSMDATE "22Aug09"
 
 #define PROG_COPYRIGHT "Copyright (C) %d-2009 Free Software Foundation Europe e.V.\n"
 #define BYEAR "2009"       /* year for copyright messages in progs */
index ed456455f6d8ba95daba88c5ec4db499006e9584..7265a48af8fca9177b974074090c0c49cc3cc30a 100644 (file)
@@ -2,6 +2,32 @@
           
 General:
 
+23Aug09
+ebl  Run job when double-click in Jobs list item
+ebl  Simplify the code to make TableWidget in read-only
+kes  Free Volume in several places. Fixes virtual-changer problem
+     and possibly bug #1346.
+kes  Add SD Volume debug code
+22Aug09
+kes  Don't print different filesystem. Will not descend 
+     message if directory explicitly excluded
+21Aug09
+ebl  Tweak status storage slot command to release db lock just
+     after the usage.
+kes  Rework the bsock.h class to put public structures last
+20Aug09
+kes  Integrate patch for building dmg on OSX from Lorenz Schori <lo@znerol.ch>
+kes  Add commas in num files for estimate command
+19Aug09
+kes  Fix bat crash due to alignment diff in bat and core code
+     In bsock.h, exact reason unknown.
+kes  Ensure timestamp put in SQL log
+15Aug09
+kes  Modify acquire alogrithm so jobs do not block during despooling
+     This can give significantly more parallelism
+ebl  Fix couple of segfault with new ACL/XATTR code
+kes  Apply Marco's branch with jcr structure cleanup
+kes  Apply Marco's branch with new acl/xattr code
 13Aug09
 ebl  update lock manager to display file:line all the time
 kes  Make SD lock tracing work again. Has not worked for some time.
index 3546d93b0384903653784f484e358d51df197571..81418ad02ebb353949fa051bba78a50398feb071 100644 (file)
@@ -1,3 +1,4 @@
+time.out
 1
 */1
 config
diff --git a/regress/all-dev-tests b/regress/all-dev-tests
new file mode 100755 (executable)
index 0000000..8026a83
--- /dev/null
@@ -0,0 +1,60 @@
+#!/bin/sh
+#
+# Run a sample of tests. These tests should be relatively short
+#   so that developers can test before committing
+#
+echo " "
+echo " " >>test.out
+echo "Start sample non-root disk tests"
+echo "Start sample non-root disk tests" >>test.out
+nice tests/acl-xattr-test
+nice tests/auto-label-test
+nice tests/backup-bacula-test
+nice tests/bextract-test
+nice tests/compressed-test
+nice tests/compress-encrypt-test
+nice tests/concurrent-jobs-test
+nice tests/copy-job-test
+nice tests/encrypt-bug-test
+nice tests/estimate-test
+nice tests/fifo-test
+nice tests/fileregexp-test
+nice tests/backup-to-null
+nice tests/regexwhere-test
+nice tests/differential-test
+nice tests/four-jobs-test
+nice tests/incremental-test
+nice tests/query-test
+nice tests/recycle-test
+nice tests/restore2-by-file-test
+nice tests/restore-by-file-test
+nice tests/restore-disk-seek-test
+nice tests/next-vol-test
+nice tests/strip-test
+nice tests/two-vol-test
+nice tests/verify-vol-test
+nice tests/weird-files2-test
+nice tests/weird-files-test
+nice tests/migration-job-test
+nice tests/multi-storage-test
+nice tests/hardlink-test
+nice tests/tls-test
+nice tests/virtual-backup-test
+echo "End sample non-root disk tests"
+echo "End sample non-root disk tests" >>test.out
+
+# 
+# The following are Disk Autochanger tests
+echo " "
+echo " " >>test.out
+echo "Start sample non-root disk autochanger tests"
+echo "Start sample non-root disk autochanger tests" >>test.out
+#nice tests/three-pool-recycle-test
+nice tests/fast-two-pool-test
+nice tests/two-volume-test
+nice tests/2drive-concurrent-test
+nice tests/incremental-2media
+nice tests/2drive-3pool-test
+nice tests/2drive-swap-test
+echo "End sample non-root disk autochanger tests"
+echo "End sample non-root disk autochanger tests" >>test.out
diff --git a/regress/do_dev b/regress/do_dev
new file mode 100755 (executable)
index 0000000..5c92853
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Relatively small quick regression for developers to test
+#  before committing
+#
+nice make setup
+echo " " >test.out
+cat build/config.out >>test.out
+echo " " >>test.out
+echo "Test results" >>test.out
+echo " " >>test.out
+./starttime
+nice ./all-dev-tests
+echo " "
+echo "End do_file tests"
+echo "End do_file tests" >>test.out
+scripts/cleanup
+cat test.out
+./endtime
index 614301dcfe5e727f71fbd7373c2606840b086f34..00f88325fdce83c77d1719d6b44a66e36d8ca097 100644 (file)
@@ -83,6 +83,7 @@ Device {
   AlwaysOpen = yes;
   RemovableMedia = yes;
   Maximum Concurrent Jobs = 3
+  Volume Poll Interval = 15
 # Maximum File Size = 1000000
 }
 
@@ -97,6 +98,7 @@ Device {
   AlwaysOpen = yes;
   RemovableMedia = yes;
   Maximum Concurrent Jobs = 3
+  Volume Poll Interval = 15
 # Maximum File Size = 1000000
 }
 
index e46cbe6e689967c59387dd570b0fa92d07c82e75..877e68a90e297969806a7b8353cc3d4764b3199b 100755 (executable)
@@ -12,7 +12,7 @@ out="${cwd}/tmp/sed_tmp"
 #cd ${BACULA_SOURCE}
 #svn update src/version.h
 #cd ${cwd}
-git pull
+#git pull
 
 scripts/create_sed
 
index 8fd26c12d2ecc2fcb8403c44e3b91dcbb5b14536..c0c6f46aa03fbe05fd9d95054251a3950a37ece5 100755 (executable)
@@ -23,10 +23,10 @@ if test  $? -ne 0; then
   exit 0
 fi
 
-# Require getfattr to be installed
-getfattr -d Makefile 2>&1 >/dev/null
+# Require attr to be installed
+attr -l Makefile 2>&1 >/dev/null
 if test $? -ne 0; then
-  echo "$TestName skipped: getfattr not installed"
+  echo "$TestName skipped: attr not installed"
   exit 0
 fi
 
@@ -57,11 +57,11 @@ setfacl -m user:nobody:--- $d/bconsole
 setfacl -m group:nogroup:--x $d/bconsole
 cp ${cwd}/bin/bconsole $d/testdir
 cp ${cwd}/bin/bconsole $d/other
-setfattr -n bacula.test -v rulez $d/other
+attr -s bacula.test -V rulez $d/other 2>/dev/null 1>/dev/null
 
 ( cd $cwd/build
   getfacl -R acl > $cwd/tmp/org
-  getfattr -R acl > $cwd/tmp/attr.org
+  attr -g bacula.test $d/other > $cwd/tmp/attr.org
 )
 
 change_jobname BackupClient1 $JobName
@@ -96,10 +96,10 @@ stop_bacula
 
 ( cd $cwd/tmp/bacula-restores/$cwd/build
   getfacl -R acl > $cwd/tmp/new
-  getfattr -R acl > $cwd/tmp/attr.new
+  attr -g bacula.test $d/other > $cwd/tmp/attr.new
 )
 
-diff $cwd/tmp/org $cwd/tmp/new
+diff -u $cwd/tmp/org $cwd/tmp/new
 if [ $? -ne 0 ]; then
    rstat=1
 fi
index d38847daa3928769226434b6b764e6cfb5404182..43fd6464ee73850b11b8968bb9ad856953cf7ce8 100755 (executable)
@@ -8,10 +8,8 @@
 #  This test the SD Virtual autochanger feature.  It is a disk based
 #    "autochanger", but does not use any changer script.
 #
-# This script uses the Virtual disk autochanger and two drives
-#
-TestName="virtual-changer-disk"
-JobName="virtualchangerdisk"
+TestName="big-virtual-changer"
+JobName="bigvirtualchanger"
 . scripts/functions
 
 scripts/cleanup
index 474c98d402ef81ec8dadc374eaf85ee5c7629eb7..7c06fcbfc94cca64ea43054b7a7826429ea83509 100755 (executable)
@@ -8,10 +8,18 @@
 #  This test the SD Virtual autochanger feature.  It is a disk based
 #    "autochanger", but does not use any changer script.
 #
-# This script uses the Virtual disk autochanger and two drives
+#  Note, because we limit each drive to a maximum of 3 jobs,
+#  the first three start on Drive-0, and the second three start
+#  on drive-1 (Prefer Mounted Volumes = no).  Thus since there
+#  is only one Volume (TestVolume001) that is valid, three jobs
+#  block and ask the user to create a new volume.  However, at some
+#  point, the first three jobs finish and free up TestVolum001, and
+#  Since we set a poll interval of 15 seconds, after a short wait
+#  TestVolume001 will be mounted on drive-1 and the job will
+#  complete.  This tests a good number of things.
 #
-TestName="virtual-changer-disk"
-JobName="virtualchangerdisk"
+TestName="virtual-changer-test"
+JobName="virtualchangertest"
 . scripts/functions
 
 scripts/cleanup