Kern Sibbald
Kjetil Torgrim Homme
Landon Fuller
+Lorenz Schori
Luca Berra
Lucas B. Cohen
Lucas Di Pentima
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
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"
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
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"
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
--- /dev/null
+#
+# 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}"
+
--- /dev/null
+<?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>
--- /dev/null
+#!/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
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<!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>
--- /dev/null
+#!/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"
--- /dev/null
+#!/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
+
%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>
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,
mr.VolumeName, mr.VolStatus, mr.MediaType, pr.Name);
}
- db_unlock(ua->db);
continue;
} else { /* TODO: get information from catalog */
if (ua->api) {
#include "bacula.h"
#include "filed.h"
-#include "acl.h"
#if !defined(HAVE_ACL)
/*
/*
* Sanity check
*/
- if (jcr->acl_data_len <= 0)
+ if (jcr->acl_data->content_length <= 0) {
return bacl_exit_ok;
+ }
/*
* Send header
/*
* 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;
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);
}
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;
* 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;
}
* 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;
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;
}
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 */
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;
}
* 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;
}
}
}
- 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;
}
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;
}
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;
}
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;
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;
}
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;
}
/*
* 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;
}
* 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;
}
* 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;
}
/*
* 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"),
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) {
* 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);
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;
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;
}
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;
}
}
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) {
* 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;
}
#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)) {
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:
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;
}
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;
}
* 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);
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);
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;
}
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;
}
#define BACL_ENOTSUP ENOTSUP
#endif
+/*
+ * Internal tracking data.
+ */
+struct acl_data_t {
+ POOLMEM *content;
+ uint32_t content_length;
+ uint32_t nr_errors;
+};
+
#endif
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 */
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 */
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) {
* 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;
* 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;
#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"
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";
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);
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;
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)) {
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;
* 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;
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;
* 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;
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) {
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;
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
#include "bacula.h"
#include "filed.h"
-#include "xattr.h"
#if !defined(HAVE_XATTR)
/*
/*
* Sanity check
*/
- if (jcr->xattr_data_len <= 0)
+ if (jcr->xattr_data->content_length <= 0) {
return bxattr_exit_ok;
+ }
/*
* Send header
/*
* 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;
* 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.
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)
* 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.
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;
}
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;
}
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;
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)
* 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;
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.
*/
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 {
/*
/*
* 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.
*/
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);
/*
* 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);
}
/*
}
}
break;
-
case S_IFLNK:
/*
* The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
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.
}
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) {
if (retval) {
retval = send_xattr_stream(jcr, stream);
- nr_xattr_saved++;
+ if (retval == bxattr_exit_ok) {
+ jcr->xattr_data->nr_saved++;
+ }
}
/*
* 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;
* 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;
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;
}
* 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;
/*
* 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;
}
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.
*/
}
}
}
-#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;
}
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? */
/* 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 */
/*
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.
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 */
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();
# 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))
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);
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);
}
/* 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()
int main(int argc, char *argv[])
{
int ch;
+ int rc;
bool no_signals = true;
bool test_config = false;
mainWin = new MainWin;
mainWin->show();
- return app->exec();
+ rc = app->exec();
+// sm_dump(false);
+ return rc;
}
void terminate_console(int /*sig*/)
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);
}
/* Set docked flag */
m_docked = true;
+ m_onceDocked = true;
mainWin->tabWidget->setCurrentWidget(this);
/* lets set the page selectors action for docking or undocking */
setContextMenuDockText();
-
}
/*
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
*/
void Pages::pgInitialize(const QString &tname, QTreeWidgetItem *parentTreeWidgetItem)
{
m_docked = false;
+ m_onceDocked = false;
if (tname.size()) {
m_name = tname;
}
void undockPage();
void togglePageDocking();
bool isDocked();
+ bool isOnceDocked();
bool isCloseable();
QTabWidget *m_parent;
QList<QAction*> m_contextActions;
void setTitle();
bool m_closeable;
bool m_docked;
+ bool m_onceDocked;
Console *m_console;
QString m_name;
};
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();
}
}
/*
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.
}
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;
}
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 */
*/
if (dev->requires_mount()) {
dev->close();
+ free_volume(dev);
}
/* Call autochanger only once unless ask_sysop called */
return ok;
}
-
/*
* Acquire device for writing. We permit multiple writers.
* If this is the first one, we read the label.
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"));
}
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)) {
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 */
ok = true;
get_out:
- dev->dlock();
dcr->clear_reserved();
- dev->dunblock(DEV_LOCKED);
+ dev->dunlock();
+ V(dev->acquire_mutex);
return ok ? dcr : NULL;
}
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 */
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));
*/
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;
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());
}
/*
- * Test writting larger and larger records.
+ * Test writing larger and larger records.
* This is a torture test for records.
*/
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"));
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 */
/*
* 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
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;
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 */
* 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); }
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());
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());
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;
}
* 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()) {
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);
/*
if (dev->poll && dev->has_cap(CAP_CLOSEONPOLL)) {
dev->close();
+ free_volume(dev);
}
/* Ensure the device is open */
/* Needed, so the medium can be changed */
if (dev->requires_mount()) {
dev->close();
+ free_volume(dev);
}
goto check_next_volume;
}
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;
}
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));
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
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;
}
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;
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);
break;
}
-
if (dev->rem_wait_sec <= 0) { /* on exceeding wait time return */
Dmsg0(dbglvl, "Exceed wait time.\n");
stat = W_TIMEOUT;
#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 */
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.
--- /dev/null
+#!/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
--- /dev/null
+#!/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
AlwaysOpen = yes;
RemovableMedia = yes;
Maximum Concurrent Jobs = 3
+ Volume Poll Interval = 15
# Maximum File Size = 1000000
}
AlwaysOpen = yes;
RemovableMedia = yes;
Maximum Concurrent Jobs = 3
+ Volume Poll Interval = 15
# Maximum File Size = 1000000
}
#cd ${BACULA_SOURCE}
#svn update src/version.h
#cd ${cwd}
-git pull
+#git pull
scripts/create_sed
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
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
( 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
# 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
# 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