From 949b8910a5e23c4285d0b1aedacfc82a14dc97a5 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Mon, 8 Oct 2012 17:45:26 -0600 Subject: [PATCH] Imported Upstream version 3.3.2 --- ChangeLog | 806 ++++++++++ FULL_VERSION | 2 +- Makefile.am | 2 +- Makefile.in | 10 +- NEWS | 33 + ReleaseNotes | 34 + VERSION | 2 +- aclocal.m4 | 17 + amandad-src/Makefile.in | 8 +- amandad-src/amandad.c | 5 +- amandad-src/amandad.h | 2 +- amar-src/Makefile.in | 8 +- amar-src/amar.c | 2 +- amar-src/amar.h | 2 +- amar-src/amarchiver.c | 2 +- amplot/Makefile.in | 10 +- application-src/Makefile.in | 10 +- application-src/amgtar.c | 51 +- application-src/amlog-script.pl | 2 +- application-src/ampgsql.pl | 70 +- application-src/amraw.pl | 2 +- application-src/amsamba.pl | 259 ++-- application-src/amstar.c | 2 +- application-src/amsuntar.pl | 2 +- application-src/amzfs-sendrecv.pl | 5 +- application-src/amzfs-snapshot.pl | 2 +- application-src/script-email.pl | 2 +- changer-src/Makefile.in | 10 +- client-src/Makefile.in | 10 +- client-src/amdump_client.pl | 4 +- client-src/calcsize.c | 10 +- client-src/client_util.c | 2 +- client-src/client_util.h | 2 +- client-src/selfcheck.c | 4 +- client-src/sendbackup-dump.c | 2 +- client-src/sendbackup-gnutar.c | 2 +- client-src/sendbackup.c | 51 +- client-src/sendsize.c | 10 +- common-src/Makefile.am | 6 +- common-src/Makefile.in | 46 +- common-src/{sl.c => am_sl.c} | 34 +- common-src/{sl.h => am_sl.h} | 20 +- common-src/amaespipe.sh | 2 +- common-src/amcryptsimple.pl | 20 +- common-src/amflock.c | 9 +- common-src/amgetconf.pl | 11 +- common-src/amgpgcrypt.pl | 32 +- common-src/amsemaphore-test.c | 2 +- common-src/amsemaphore.c | 2 +- common-src/amsemaphore.h | 2 +- common-src/amxml.c | 6 +- common-src/amxml.h | 12 +- common-src/conffile.c | 743 ++++++---- common-src/conffile.h | 37 +- common-src/directtcp.h | 2 +- common-src/event-test.c | 2 +- common-src/event.c | 1 + common-src/fileheader-test.c | 2 +- common-src/fileheader.c | 2 +- common-src/glib-util.c | 76 +- common-src/glib-util.h | 3 +- common-src/ipc-binary.c | 2 +- common-src/ipc-binary.h | 2 +- common-src/match-test.c | 2 +- common-src/match.c | 9 +- common-src/match.h | 2 +- common-src/quoting-test.c | 2 +- common-src/security-util.c | 4 +- common-src/simpleprng.c | 2 +- common-src/simpleprng.h | 2 +- common-src/sockaddr-util.c | 2 +- common-src/sockaddr-util.h | 2 +- common-src/ssh-security.c | 48 +- common-src/svn-info.h | 4 +- common-src/testutils.c | 2 +- common-src/testutils.h | 2 +- common-src/timestamp.c | 6 + common-src/util.c | 15 + common-src/util.h | 2 +- config/Makefile.in | 6 +- config/amanda/libs.m4 | 37 + config/amanda/progs.m4 | 6 + config/amanda/version.m4 | 35 +- config/automake/scripts.am | 2 +- config/automake/vars.am | 2 +- config/config.h.in | 9 + config/macro-archive/docbook-dtd.m4 | 2 +- config/macro-archive/docbook-xslt-min.m4 | 2 +- config/macro-archive/docbook-xslt.m4 | 2 +- config/macro-archive/xsltproc.m4 | 2 +- configure | 295 +++- configure.in | 8 +- device-src/Makefile.in | 10 +- device-src/amdevcheck.pl | 2 +- device-src/amtapetype.pl | 2 +- device-src/device.c | 85 +- device-src/device.h | 24 +- device-src/directtcp-connection.c | 2 +- device-src/directtcp-connection.h | 2 +- device-src/ndmp-device.c | 513 ++++++- device-src/null-device.c | 9 +- device-src/property.c | 2 +- device-src/property.h | 2 +- device-src/rait-device.c | 26 +- device-src/s3-device.c | 860 +++++++++-- device-src/s3-util.c | 2 +- device-src/s3-util.h | 2 +- device-src/s3.c | 816 ++++++++++- device-src/s3.h | 50 +- device-src/tape-device.c | 33 +- device-src/vfs-device.c | 34 +- device-src/vfs-device.h | 2 +- device-src/xfer-dest-device.c | 2 +- device-src/xfer-dest-taper-cacher.c | 9 +- device-src/xfer-dest-taper-directtcp.c | 15 +- device-src/xfer-dest-taper-splitter.c | 8 +- device-src/xfer-dest-taper.c | 2 +- device-src/xfer-dest-taper.h | 2 +- device-src/xfer-device.h | 6 +- device-src/xfer-source-device.c | 2 +- device-src/xfer-source-recovery.c | 20 +- example/Makefile.in | 8 +- gnulib/Makefile.in | 6 +- installcheck/=setupcache.pl | 2 +- installcheck/Amanda_Archive.pl | 2 +- installcheck/Amanda_Changer.pl | 5 +- installcheck/Amanda_Changer_compat.pl | 2 +- installcheck/Amanda_Changer_disk.pl | 2 +- installcheck/Amanda_Changer_multi.pl | 2 +- installcheck/Amanda_Changer_ndmp.pl | 2 +- installcheck/Amanda_Changer_null.pl | 2 +- installcheck/Amanda_Changer_rait.pl | 2 +- installcheck/Amanda_Changer_robot.pl | 2 +- installcheck/Amanda_Changer_single.pl | 2 +- installcheck/Amanda_ClientService.pl | 2 +- installcheck/Amanda_Cmdline.pl | 2 +- installcheck/Amanda_Config.pl | 4 +- installcheck/Amanda_Config_FoldingHash.pl | 2 +- installcheck/Amanda_Curinfo.pl | 2 +- installcheck/Amanda_DB_Catalog.pl | 2 +- installcheck/Amanda_Debug.pl | 2 +- installcheck/Amanda_Device.pl | 107 +- installcheck/Amanda_Disklist.pl | 2 +- installcheck/Amanda_Feature.pl | 2 +- installcheck/Amanda_Header.pl | 2 +- installcheck/Amanda_Holding.pl | 2 +- installcheck/Amanda_IPC_Binary.pl | 2 +- installcheck/Amanda_IPC_LineProtocol.pl | 21 +- installcheck/Amanda_Logfile.pl | 2 +- installcheck/Amanda_MainLoop.pl | 2 +- installcheck/Amanda_NDMP.pl | 2 +- installcheck/Amanda_Process.pl | 2 +- installcheck/Amanda_Recovery_Clerk.pl | 2 +- installcheck/Amanda_Recovery_Planner.pl | 2 +- installcheck/Amanda_Recovery_Scan.pl | 2 +- installcheck/Amanda_Report.pl | 2 +- installcheck/Amanda_Tapelist.pl | 2 +- installcheck/Amanda_Taper_Scan_lexical.pl | 2 +- installcheck/Amanda_Taper_Scan_oldest.pl | 2 +- installcheck/Amanda_Taper_Scan_traditional.pl | 2 +- installcheck/Amanda_Taper_Scribe.pl | 2 +- installcheck/Amanda_Util.pl | 2 +- installcheck/Amanda_Xfer.pl | 2 +- installcheck/Installcheck.pm | 2 +- installcheck/Installcheck/Application.pm | 2 +- installcheck/Installcheck/Catalogs.pm | 2 +- installcheck/Installcheck/Changer.pm | 2 +- installcheck/Installcheck/ClientService.pm | 2 +- installcheck/Installcheck/Config.pm | 2 +- installcheck/Installcheck/Dumpcache.pm | 2 +- installcheck/Installcheck/Mock.pm | 2 +- installcheck/Installcheck/Run.pm | 2 +- installcheck/Makefile.in | 10 +- installcheck/amadmin.pl | 8 +- installcheck/amarchiver.pl | 2 +- installcheck/amcheck-device.pl | 2 +- installcheck/amcheck.pl | 2 +- installcheck/amcheckdump.pl | 2 +- installcheck/amdevcheck.pl | 2 +- installcheck/amdump.pl | 2 +- installcheck/amdump_client.pl | 2 +- installcheck/amfetchdump.pl | 2 +- installcheck/amflush.pl | 2 +- installcheck/amgetconf.pl | 4 +- installcheck/amgtar.pl | 2 +- installcheck/amidxtaped.pl | 2 +- installcheck/amlabel.pl | 2 +- installcheck/amoverview.pl | 2 +- installcheck/ampgsql.pl | 2 +- installcheck/amraw.pl | 2 +- installcheck/amrecover.pl | 2 +- installcheck/amreport.pl | 2 +- installcheck/amrestore.pl | 2 +- installcheck/amrmtape.pl | 2 +- installcheck/amserverconfig.pl | 2 +- installcheck/amservice.pl | 2 +- installcheck/amstatus.pl | 2 +- installcheck/amtape.pl | 2 +- installcheck/amtapetype.pl | 2 +- installcheck/amvault.pl | 2 +- installcheck/bigint.pl | 2 +- installcheck/catalogs/bigdb.cat | 2 +- installcheck/catalogs/bigestimate.cat | 6 +- installcheck/catalogs/doublefailure.cat | 6 +- installcheck/catalogs/filesystemstaped.cat | 8 +- installcheck/catalogs/longstrange.cat | 6 +- installcheck/catalogs/multi-taper.cat | 14 +- installcheck/catalogs/normal.cat | 110 +- installcheck/catalogs/plannerfail.cat | 12 +- installcheck/catalogs/resultsmissing.cat | 14 +- installcheck/catalogs/retried-nofinish.cat | 6 +- installcheck/catalogs/retried-strange.cat | 6 +- installcheck/catalogs/retried.cat | 6 +- installcheck/catalogs/shortstrange.cat | 6 +- installcheck/catalogs/skipped.cat | 6 +- installcheck/catalogs/spanned.cat | 6 +- installcheck/catalogs/strontium.cat | 14 +- installcheck/chunker.pl | 2 +- installcheck/example.pl | 2 +- installcheck/gnutar.pl | 2 +- installcheck/mock/lpr.pl | 2 +- installcheck/mock/mail.pl | 2 +- installcheck/mock/mtx.pl | 2 +- installcheck/mock_mtx.pl | 2 +- installcheck/noop.pl | 2 +- installcheck/pp-scripts.pl | 2 +- installcheck/run-ndmp.pl | 2 +- installcheck/taper.pl | 10 +- man/Makefile.in | 6 +- man/amaddclient.8 | 6 +- man/amadmin.8 | 32 +- man/amaespipe.8 | 6 +- man/amanda-applications.7 | 6 +- man/amanda-archive-format.5 | 6 +- man/amanda-auth.7 | 6 +- man/amanda-changers.7 | 6 +- man/amanda-client.conf.5 | 6 +- man/amanda-compatibility.7 | 6 +- man/amanda-devices.7 | 99 +- man/amanda-interactivity.7 | 6 +- man/amanda-match.7 | 6 +- man/amanda-scripts.7 | 6 +- man/amanda-taperscan.7 | 6 +- man/amanda.8 | 6 +- man/amanda.conf.5 | 21 +- man/amarchiver.8 | 6 +- man/amcheck.8 | 6 +- man/amcheckdb.8 | 6 +- man/amcheckdump.8 | 6 +- man/amcleanup.8 | 6 +- man/amcleanupdisk.8 | 6 +- man/amcrypt-ossl-asym.8 | 6 +- man/amcrypt-ossl.8 | 6 +- man/amcrypt.8 | 6 +- man/amcryptsimple.8 | 6 +- man/amdevcheck.8 | 6 +- man/amdump.8 | 6 +- man/amdump_client.8 | 6 +- man/amfetchdump.8 | 56 +- man/amflush.8 | 6 +- man/amgetconf.8 | 6 +- man/amgpgcrypt.8 | 6 +- man/amgtar.8 | 15 +- man/amlabel.8 | 6 +- man/amoverview.8 | 6 +- man/ampgsql.8 | 6 +- man/amplot.8 | 6 +- man/amraw.8 | 6 +- man/amrecover.8 | 6 +- man/amreport.8 | 6 +- man/amrestore.8 | 6 +- man/amrmtape.8 | 6 +- man/amsamba.8 | 6 +- man/amserverconfig.8 | 6 +- man/amservice.8 | 6 +- man/amstar.8 | 6 +- man/amstatus.8 | 6 +- man/amsuntar.8 | 6 +- man/amtape.8 | 6 +- man/amtapetype.8 | 6 +- man/amtoc.8 | 6 +- man/amvault.8 | 6 +- man/amzfs-sendrecv.8 | 8 +- man/amzfs-snapshot.8 | 6 +- man/disklist.5 | 20 +- man/script-email.8 | 6 +- man/tapelist.5 | 6 +- man/xml-source/amadmin.8.xml | 23 + man/xml-source/amanda-devices.7.xml | 65 +- man/xml-source/amanda.conf.5.xml | 22 +- man/xml-source/amfetchdump.8.xml | 78 +- man/xml-source/amgtar.8.xml | 7 +- man/xml-source/amzfs-sendrecv.8.xml | 2 +- man/xml-source/disklist.5.xml | 21 +- ndmp-src/Makefile.in | 8 +- ndmp-src/ndmjob_args.c | 17 + ndmp-src/ndmos.h | 4 + ndmp-src/ndmos_glib.h | 1 + ndmp-src/ndmp4_translate.c | 84 +- ndmp-src/ndmp_translate.h | 2 + ndmp-src/ndmpconnobj.c | 162 +- ndmp-src/ndmpconnobj.h | 16 +- oldrecover-src/Makefile.in | 8 +- packaging/Makefile.in | 6 +- packaging/common/common_functions.sh | 28 +- packaging/common/mock_utils.sh | 86 +- packaging/common/post_inst_functions.sh | 10 +- packaging/common/post_rm_functions.sh | 2 +- packaging/common/pre_inst_functions.sh | 308 ++-- packaging/common/test_sh_libs.sh | 234 ++- packaging/deb/amanda-backup-client.postinst | 107 +- packaging/deb/amanda-backup-client.postrm | 3 + packaging/deb/amanda-backup-server.postinst | 143 +- packaging/deb/amanda-backup-server.postrm | 3 + packaging/deb/buildpkg | 9 +- packaging/deb/postinst.src | 75 + packaging/deb/postrm | 39 - packaging/deb/postrm.src | 86 ++ packaging/deb/preinst | 127 -- packaging/deb/preinst.src | 40 + packaging/deb/rules | 25 +- packaging/rpm/amanda.spec.src | 1305 ++++------------- packaging/rpm/buildpkg | 5 +- packaging/sun-pkg/buildpkg | 30 +- packaging/sun-pkg/client/postinstall.src | 16 +- packaging/sun-pkg/client/postremove.src | 17 +- packaging/sun-pkg/client/preinstall.src | 29 +- packaging/sun-pkg/server/postinstall.src | 27 +- packaging/sun-pkg/server/postremove.src | 17 +- packaging/sun-pkg/server/preinstall.src | 30 +- perl/Amanda/Application.pm | 8 +- perl/Amanda/Application.pod | 2 +- perl/Amanda/Application.swg | 10 +- perl/Amanda/Application/Zfs.pm | 2 +- perl/Amanda/Archive.pod | 2 +- perl/Amanda/Archive.swg | 2 +- perl/Amanda/BigIntCompat.pm | 2 +- perl/Amanda/Changer.pm | 16 +- perl/Amanda/Changer/aggregate.pm | 5 +- perl/Amanda/Changer/compat.pm | 2 +- perl/Amanda/Changer/disk.pm | 5 +- perl/Amanda/Changer/multi.pm | 5 +- perl/Amanda/Changer/ndmp.pm | 9 +- perl/Amanda/Changer/null.pm | 2 +- perl/Amanda/Changer/rait.pm | 5 +- perl/Amanda/Changer/robot.pm | 36 +- perl/Amanda/Changer/single.pm | 5 +- perl/Amanda/ClientService.pm | 2 +- perl/Amanda/Cmdline.pod | 2 +- perl/Amanda/Cmdline.swg | 2 +- perl/Amanda/Config.c | 31 +- perl/Amanda/Config.pm | 18 +- perl/Amanda/Config.pod | 2 +- perl/Amanda/Config.swg | 11 +- perl/Amanda/Constants.pm.in | 5 +- perl/Amanda/Curinfo.pm | 2 +- perl/Amanda/Curinfo/Info.pm | 2 +- perl/Amanda/DB/Catalog.pm | 2 +- perl/Amanda/Debug.pod | 2 +- perl/Amanda/Debug.swg | 2 +- perl/Amanda/Device.c | 291 +++- perl/Amanda/Device.pm | 4 + perl/Amanda/Device.pod | 2 +- perl/Amanda/Device.swg | 44 +- perl/Amanda/Disklist.pod | 2 +- perl/Amanda/Disklist.swg | 2 +- perl/Amanda/Feature.pod | 2 +- perl/Amanda/Feature.swg | 2 +- perl/Amanda/Header.c | 92 +- perl/Amanda/Header.pm | 6 +- perl/Amanda/Header.pod | 2 +- perl/Amanda/Header.swg | 17 +- perl/Amanda/Holding.pm | 2 +- perl/Amanda/IPC/Binary.pod | 2 +- perl/Amanda/IPC/Binary.swg | 2 +- perl/Amanda/IPC/LineProtocol.pm | 2 +- perl/Amanda/Interactivity.pm | 2 +- perl/Amanda/Interactivity/email.pm | 2 +- perl/Amanda/Interactivity/stdin.pm | 2 +- perl/Amanda/Interactivity/tty.pm | 2 +- perl/Amanda/Interactivity/tty_email.pm | 2 +- perl/Amanda/Logfile.pod | 2 +- perl/Amanda/Logfile.swg | 2 +- perl/Amanda/MainLoop.pod | 2 +- perl/Amanda/MainLoop.swg | 2 +- perl/Amanda/NDMP.pod | 2 +- perl/Amanda/NDMP.swg | 2 +- perl/Amanda/Paths.pm.in | 2 +- perl/Amanda/Process.pm | 2 +- perl/Amanda/Recovery/Clerk.pm | 15 +- perl/Amanda/Recovery/Planner.pm | 158 +- perl/Amanda/Recovery/Scan.pm | 13 +- perl/Amanda/Report.pm | 2 +- perl/Amanda/Report/human.pm | 34 +- perl/Amanda/Report/postscript.pm | 2 +- perl/Amanda/Report/xml.pm | 2 +- perl/Amanda/ScanInventory.pm | 11 +- perl/Amanda/Script.pm | 2 +- perl/Amanda/Script_App.pm | 2 +- perl/Amanda/Tapelist.c | 1 + perl/Amanda/Tapelist.pod | 2 +- perl/Amanda/Tapelist.swg | 3 +- perl/Amanda/Taper/Controller.pm | 2 +- perl/Amanda/Taper/Protocol.pm | 2 +- perl/Amanda/Taper/Scan.pm | 2 +- perl/Amanda/Taper/Scan/lexical.pm | 2 +- perl/Amanda/Taper/Scan/oldest.pm | 2 +- perl/Amanda/Taper/Scan/traditional.pm | 42 +- perl/Amanda/Taper/Scribe.pm | 70 +- perl/Amanda/Taper/Worker.pm | 48 +- perl/Amanda/Tests.pod | 2 +- perl/Amanda/Tests.swg | 2 +- perl/Amanda/Util.c | 5 + perl/Amanda/Util.pod | 2 +- perl/Amanda/Util.swg | 9 +- perl/Amanda/Xfer.pod | 2 +- perl/Amanda/Xfer.swg | 2 +- perl/Amanda/XferServer.c | 64 + perl/Amanda/XferServer.pm | 4 + perl/Amanda/XferServer.pod | 2 +- perl/Amanda/XferServer.swg | 12 +- perl/Makefile.am | 2 +- perl/Makefile.in | 12 +- perl/amglue/Makefile.in | 10 +- perl/amglue/amglue.h | 2 +- perl/amglue/amglue.swg | 2 +- perl/amglue/bigint.c | 2 +- perl/amglue/constants.swg | 2 +- perl/amglue/directtcp.swg | 2 +- perl/amglue/dumpspecs.swg | 2 +- perl/amglue/exports.swg | 2 +- perl/amglue/filehandles.swg | 2 +- perl/amglue/ghashtable.c | 2 +- perl/amglue/glib.swg | 2 +- perl/amglue/integers.swg | 2 +- perl/amglue/objwrap.c | 2 +- perl/amglue/source.c | 2 +- perl/amglue/xferwrap.c | 2 +- po/Makefile.in | 6 +- recover-src/Makefile.in | 8 +- recover-src/extract_list.c | 12 +- server-src/Makefile.in | 10 +- server-src/amaddclient.pl | 2 +- server-src/amadmin.c | 316 +--- server-src/amcheck-device.pl | 16 +- server-src/amcheckdump.pl | 42 +- server-src/amcleanup.pl | 2 +- server-src/amcleanupdisk.pl | 2 +- server-src/amdump.pl | 2 +- server-src/amdumpd.pl | 2 +- server-src/amfetchdump.pl | 204 ++- server-src/amidxtaped.pl | 12 +- server-src/amindexd.c | 13 +- server-src/amlabel.pl | 2 +- server-src/amlogroll.pl | 2 +- server-src/amoverview.pl | 2 +- server-src/amreport.pl | 2 +- server-src/amrestore.pl | 12 +- server-src/amrmtape.pl | 2 +- server-src/amserverconfig.pl | 2 +- server-src/amstatus.pl | 36 +- server-src/amtape.pl | 16 +- server-src/amvault.pl | 59 +- server-src/cmdline.c | 2 +- server-src/cmdline.h | 2 +- server-src/diskfile.c | 2 + server-src/diskfile.h | 9 +- server-src/driver.c | 56 +- server-src/driverio.c | 3 + server-src/dumper.c | 31 +- server-src/find.c | 8 +- server-src/planner.c | 199 +-- server-src/tapefile.c | 26 +- server-src/taper.pl | 2 +- server-src/xfer-server.h | 5 +- server-src/xfer-source-holding.c | 14 +- xfer-src/Makefile.in | 8 +- xfer-src/amxfer.h | 2 +- xfer-src/dest-buffer.c | 2 +- xfer-src/dest-directtcp-connect.c | 2 +- xfer-src/dest-directtcp-listen.c | 2 +- xfer-src/dest-fd.c | 2 +- xfer-src/dest-null.c | 2 +- xfer-src/element-glue.c | 4 +- xfer-src/element-glue.h | 2 +- xfer-src/filter-process.c | 2 +- xfer-src/filter-xor.c | 2 +- xfer-src/source-directtcp-connect.c | 2 +- xfer-src/source-directtcp-listen.c | 2 +- xfer-src/source-fd.c | 2 +- xfer-src/source-pattern.c | 2 +- xfer-src/source-random.c | 2 +- xfer-src/xfer-element.c | 8 +- xfer-src/xfer-element.h | 2 +- xfer-src/xfer-test.c | 2 +- xfer-src/xfer.c | 7 +- xfer-src/xfer.h | 4 +- xfer-src/xmsg.c | 2 +- xfer-src/xmsg.h | 2 +- 499 files changed, 8549 insertions(+), 3993 deletions(-) rename common-src/{sl.c => am_sl.c} (92%) rename common-src/{sl.h => am_sl.h} (84%) create mode 100644 packaging/deb/postinst.src delete mode 100755 packaging/deb/postrm create mode 100755 packaging/deb/postrm.src delete mode 100755 packaging/deb/preinst create mode 100755 packaging/deb/preinst.src diff --git a/ChangeLog b/ChangeLog index d7f5466..743f563 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,809 @@ +2012-07-24 Jean-Louis Martineau + * device-src/s3-device.c: New REUSE-CONNECTION property. + * device-src/s3.c: Do not reuse connection if REUSE-CONNECTION is + FALSE. + * device-src/s3.h (s3_open): New reuse_connection argument. + * man/xml-source/amanda-devices.7.xml: Document REUSE-CONNECTION + property. + * ReleaseNotes, NEWS: Add REUSE-CONNECTION. + +2012-07-24 Jean-Louis Martineau + * VERSION: 3.3.2 + +2012-07-24 Jean-Louis Martineau + * device-src/s3-device.c: Fix a big memory leak. + +2012-07-23 Jean-Louis Martineau + * man/xml-source/amanda.conf.5.xml: Typo. + +2012-07-23 Jean-Louis Martineau + * ReleaseNotes, NEWS: Add new features in 3.3.2. + +2012-07-20 Dan Locks + * perl/Amanda/Feature.pod, perl/Amanda/MainLoop.swg, + perl/Amanda/Script.pm, perl/Amanda/NDMP.pod, + perl/Amanda/Logfile.swg, perl/Amanda/Curinfo.pm, + perl/Amanda/Changer.pm, perl/Amanda/Tests.pod, + perl/Amanda/Application.pod, perl/Amanda/Debug.swg, + perl/Amanda/Disklist.swg, perl/Amanda/Report.pm, + perl/Amanda/Config.pod, perl/Amanda/Header.swg, + perl/Amanda/Feature.swg, perl/Amanda/BigIntCompat.pm, + perl/Amanda/NDMP.swg, perl/Amanda/Recovery/Scan.pm, + perl/Amanda/Recovery/Planner.pm, perl/Amanda/Recovery/Clerk.pm, + perl/Amanda/Util.pod, perl/Amanda/Tests.swg, + perl/Amanda/Archive.pod, perl/Amanda/Application.swg, + perl/Amanda/Config.swg, perl/Amanda/Curinfo/Info.pm, + perl/Amanda/Tapelist.pod, perl/Amanda/Changer/disk.pm, + perl/Amanda/Changer/multi.pm, perl/Amanda/Changer/null.pm, + perl/Amanda/Changer/ndmp.pm, perl/Amanda/Changer/rait.pm, + perl/Amanda/Changer/single.pm, perl/Amanda/Changer/compat.pm, + perl/Amanda/Changer/robot.pm, perl/Amanda/Changer/aggregate.pm, + perl/Amanda/Report/human.pm, perl/Amanda/Report/postscript.pm, + perl/Amanda/Report/xml.pm, perl/Amanda/IPC/Binary.swg, + perl/Amanda/IPC/LineProtocol.pm, perl/Amanda/IPC/Binary.pod, + perl/Amanda/XferServer.pod, perl/Amanda/Util.swg, + perl/Amanda/ScanInventory.pm, perl/Amanda/Script_App.pm, + perl/Amanda/Device.pod, perl/Amanda/Archive.swg, + perl/Amanda/Tapelist.swg, perl/Amanda/Xfer.pod, + perl/Amanda/DB/Catalog.pm, perl/Amanda/Process.pm, + perl/Amanda/XferServer.swg, perl/Amanda/Constants.pm.in, + perl/Amanda/Cmdline.pod, perl/Amanda/Device.swg, + perl/Amanda/Interactivity/stdin.pm, + perl/Amanda/Interactivity/email.pm, + perl/Amanda/Interactivity/tty_email.pm, + perl/Amanda/Interactivity/tty.pm, perl/Amanda/MainLoop.pod, + perl/Amanda/Holding.pm, perl/Amanda/Paths.pm.in, + perl/Amanda/Logfile.pod, perl/Amanda/Application/Zfs.pm, + perl/Amanda/Xfer.swg, perl/Amanda/Debug.pod, + perl/Amanda/Disklist.pod, perl/Amanda/Interactivity.pm, + perl/Amanda/Header.pod, perl/Amanda/Cmdline.swg, + perl/Amanda/ClientService.pm, perl/Amanda/Taper/Protocol.pm, + perl/Amanda/Taper/Controller.pm, perl/Amanda/Taper/Scan.pm, + perl/Amanda/Taper/Scribe.pm, perl/Amanda/Taper/Scan/oldest.pm, + perl/Amanda/Taper/Scan/traditional.pm, + perl/Amanda/Taper/Scan/lexical.pm, + perl/Amanda/Taper/Worker.pm, perl/amglue/objwrap.c, + perl/amglue/bigint.c, perl/amglue/amglue.h, + perl/amglue/dumpspecs.swg, perl/amglue/exports.swg, + perl/amglue/amglue.swg, perl/amglue/constants.swg, + perl/amglue/glib.swg, perl/amglue/filehandles.swg, + perl/amglue/integers.swg, perl/amglue/xferwrap.c, + perl/amglue/directtcp.swg, perl/amglue/source.c, + perl/amglue/ghashtable.c, perl/make_html.pl, + installcheck/amoverview.pl, installcheck/Amanda_Holding.pl, + installcheck/Amanda_Disklist.pl, + installcheck/Amanda_Taper_Scan_oldest.pl, + installcheck/amlabel.pl, installcheck/Amanda_NDMP.pl, + installcheck/amflush.pl, installcheck/Amanda_ClientService.pl, + installcheck/run-ndmp.pl, installcheck/amstatus.pl, + installcheck/Amanda_Taper_Scribe.pl, + installcheck/Amanda_Recovery_Scan.pl, + installcheck/Amanda_Curinfo.pl, installcheck/Amanda_Changer.pl, + installcheck/Amanda_Changer_single.pl, + installcheck/Amanda_Taper_Scan_traditional.pl, + installcheck/bigint.pl, installcheck/Amanda_Cmdline.pl, + installcheck/Amanda_Changer_robot.pl, installcheck/amservice.pl, + installcheck/Amanda_Recovery_Clerk.pl, + installcheck/Amanda_Taper_Scan_lexical.pl, + installcheck/amarchiver.pl, installcheck/amrecover.pl, + installcheck/Amanda_Changer_ndmp.pl, + installcheck/Installcheck/ClientService.pm, + installcheck/Installcheck/Application.pm, + installcheck/Installcheck/Run.pm, + installcheck/Installcheck/Config.pm, + installcheck/Installcheck/Changer.pm, + installcheck/Installcheck/Dumpcache.pm, + installcheck/Installcheck/Mock.pm, + installcheck/Installcheck/Catalogs.pm, installcheck/example.pl, + installcheck/gnutar.pl, installcheck/amrestore.pl, + installcheck/amgetconf.pl, installcheck/pp-scripts.pl, + installcheck/Amanda_IPC_LineProtocol.pl, installcheck/amtape.pl, + installcheck/amraw.pl, installcheck/amserverconfig.pl, + installcheck/amgtar.pl, installcheck/taper.pl, + installcheck/Amanda_Util.pl, + installcheck/Amanda_Recovery_Planner.pl, + installcheck/mock/mail.pl, installcheck/mock/mtx.pl, + installcheck/mock/lpr.pl, installcheck/Amanda_IPC_Binary.pl, + installcheck/=setupcache.pl, installcheck/amcheckdump.pl, + installcheck/amdump_client.pl, installcheck/Amanda_Tapelist.pl, + installcheck/Amanda_Debug.pl, installcheck/Amanda_Changer_rait.pl, + installcheck/amcheck-device.pl, installcheck/Amanda_Header.pl, + installcheck/amdevcheck.pl, installcheck/Amanda_Device.pl, + installcheck/Amanda_Changer_null.pl, installcheck/ampgsql.pl, + installcheck/Installcheck.pm, installcheck/amadmin.pl, + installcheck/amvault.pl, installcheck/Amanda_Changer_compat.pl, + installcheck/Amanda_Report.pl, installcheck/amidxtaped.pl, + installcheck/mock_mtx.pl, installcheck/Amanda_Changer_disk.pl, + installcheck/Amanda_Logfile.pl, + installcheck/Amanda_Changer_multi.pl, + installcheck/amdump.pl, installcheck/catalogs/bigdb.cat, + installcheck/amreport.pl, installcheck/amcheck.pl, + installcheck/Amanda_Feature.pl, installcheck/amfetchdump.pl, + installcheck/chunker.pl, installcheck/Amanda_Xfer.pl, + installcheck/amrmtape.pl, installcheck/Amanda_Config.pl, + installcheck/amtapetype.pl, installcheck/noop.pl, + installcheck/Amanda_Config_FoldingHash.pl, + installcheck/Amanda_Process.pl, + installcheck/Amanda_MainLoop.pl, installcheck/Amanda_DB_Catalog.pl, + installcheck/Amanda_Archive.pl, amar-src/amar.c, + amar-src/amarchiver.c, amar-src/amar.h, + config/automake/scripts.am, config/automake/vars.am, + config/macro-archive/docbook-xslt.m4, + config/macro-archive/docbook-dtd.m4, + config/macro-archive/docbook-xslt-min.m4, + config/macro-archive/xsltproc.m4, + common-src/directtcp.h, common-src/amgetconf.pl, + common-src/sockaddr-util.c, common-src/sockaddr-util.h, + common-src/glib-util.c, common-src/glib-util.h, + common-src/ipc-binary.c, common-src/event-test.c, + common-src/ipc-binary.h, common-src/match-test.c, + common-src/amsemaphore-test.c, common-src/simpleprng.c, + common-src/simpleprng.h, common-src/amsemaphore.c, + common-src/quoting-test.c, common-src/fileheader-test.c, + common-src/amsemaphore.h, common-src/amcryptsimple.pl, + common-src/amaespipe.sh, common-src/testutils.c, + common-src/match.h, common-src/testutils.h, + common-src/amgpgcrypt.pl, application-src/script-email.pl, + application-src/amsuntar.pl, application-src/amzfs-snapshot.pl, + application-src/amlog-script.pl, application-src/amsamba.pl, + application-src/ampgsql.pl, application-src/amraw.pl, + application-src/amzfs-sendrecv.pl, contrib/amreport.rnc, + client-src/amdump_client.pl, ndmp-src/ndmpconnobj.c, + ndmp-src/ndmpconnobj.h, device-src/xfer-device.h, + device-src/s3-device.c, device-src/property.c, + device-src/s3.c, device-src/property.h, + device-src/xfer-dest-taper-directtcp.c, device-src/s3.h, + device-src/rait-device.c, device-src/device.c, + device-src/amtapetype.pl, device-src/device.h, + device-src/null-device.c, device-src/xfer-dest-taper.c, + device-src/directtcp-connection.c, + device-src/xfer-dest-taper-splitter.c, + device-src/xfer-dest-taper.h, device-src/amdevcheck.pl, + device-src/directtcp-connection.h, device-src/tape-device.c, + device-src/ndmp-device.c, device-src/vfs-device.c, + device-src/xfer-dest-taper-cacher.c, device-src/xfer-dest-device.c, + device-src/xfer-source-recovery.c, device-src/xfer-source-device.c, + device-src/s3-util.c, device-src/vfs-device.h, + device-src/s3-util.h, packaging/rpm/amanda.spec.src, + xfer-src/xfer-element.h, xfer-src/filter-process.c, + xfer-src/xfer.c, xfer-src/dest-directtcp-connect.c, + xfer-src/dest-buffer.c, xfer-src/source-directtcp-connect.c, + xfer-src/dest-null.c, xfer-src/xfer.h, + xfer-src/dest-directtcp-listen.c, xfer-src/source-pattern.c, + xfer-src/source-directtcp-listen.c, xfer-src/source-random.c, + xfer-src/xmsg.c, xfer-src/xfer-test.c, + xfer-src/xmsg.h, xfer-src/element-glue.c, + xfer-src/dest-fd.c, xfer-src/amxfer.h, + xfer-src/source-fd.c, xfer-src/element-glue.h, + xfer-src/filter-xor.c, xfer-src/xfer-element.c, + server-src/amcheckdump.pl, server-src/amoverview.pl, + server-src/amdumpd.pl, server-src/amcheck-device.pl, + server-src/amlogroll.pl, server-src/xfer-source-holding.c, + server-src/amlabel.pl, server-src/amvault.pl, + server-src/amcleanupdisk.pl, server-src/amidxtaped.pl, + server-src/cmdline.c, server-src/amdump.pl, + server-src/xfer-server.h, server-src/cmdline.h, + server-src/amreport.pl, server-src/amfetchdump.pl, + server-src/amrestore.pl, server-src/amcleanup.pl, + server-src/amaddclient.pl, server-src/amrmtape.pl, + server-src/amtape.pl, server-src/amserverconfig.pl, + server-src/taper.pl: update copyright dates + +2012-07-20 Jean-Louis Martineau + * common-src/timestamp.c (get_time_from_timestamp): Initialize to 0. + +2012-07-19 Jean-Louis Martineau + Patch by crocket + * perl/Makefile.am: Fix cygwin build. + +2012-07-18 Jean-Louis Martineau + * device-src/s3.c: Parse application/json reply from cloudena. + +2012-07-18 Jean-Louis Martineau + * installcheck/Amanda_IPC_LineProtocol.pl: Add synchonization to fix + race. + +2012-07-17 Jean-Louis Martineau + * server-src/amcheckdump.pl: Wait for all filters to terminate before + going to next image. Do not use '--ignore-zeros' for SMBCLIENT + backup. Pass the dump size to $xfer->start(). + * server-src/amfetchdump.pl: Wait for all filters to terminate before + going to next image. + +2012-07-16 Dan Locks + * packaging/sun-pkg/buildpkg: + * packaging/sun-pkg/client/postremove.src, + packaging/sun-pkg/server/postremove.src: remove redundant usage of + basedir. + * packaging/sun-pkg/client/postinstall.src, + packaging/sun-pkg/server/postinstall.src: same as above, plus fix + case statement. + * packaging/sun-pkg/server/preinstall.src, + packaging/sun-pkg/client/preinstall.src: remove redundant basedir, + use new check_user_* functions. + +2012-07-16 Dan Locks + * packaging/rpm/amanda.spec.src: refactor to use common functions + * packaging/rpm/buildpkg: check for ./configure, and exit if + substitute.pl fails. + +2012-07-16 Dan Locks + * packaging/deb/rules: use FULL_VERSION file to fill AMVER var, use + * concatenation trick for postinst, rm trailing whitespace + * packaging/deb/buildpkg: process postinst.src postrm.src preinst.src with substitute.pl + * packaging/deb/postinst.src: refactor to use common functions. + * packaging/deb/amanda-backup-server.postrm, + packaging/deb/amanda-backup-client.postrm, + packaging/deb/amanda-backup-client.postinst, + packaging/deb/amanda-backup-server.postinst: delete everything, add + variables pkg_type and other_pkg_type. + * packaging/deb/preinst: moved to... + * packaging/deb/preinst.src: here. refactor using common functions + * packaging/deb/postrm: moved to... + * packaging/deb/postrm.src: here. refactor using common functions. + +2012-07-16 Dan Locks + * packaging/common/common_functions.sh: remove trailing whitespace, + remove redundant usage of ${BASEDIR} in solaris functions, avoid + potentially non-portable test invocations. + * packaging/common/test_sh_libs.sh: fix some log messages, redirect + some unused output, split check_user_* tests into shorter testsr, + add tests for supplemental groups, fix running single test. + * packaging/common/mock_utils.sh: change id to error if any flags are + given, add mock for groups. + * packaging/common/post_inst_functions.sh: remove redundant leading / + * packaging/common/post_rm_functions.sh: rm trailing whitespace. + * packaging/common/pre_inst_functions.sh: use variable for user + shell, clarify log messages regarding user accounts, split + check_user into separate functions, mostly to ease testing, add + check_user_supplemental_group. + +2012-07-12 Jean-Louis Martineau + * device-src/s3-device.c: Do not free ca_info if use_ssl is not set. + * device-src/s3.c:: Set CURLOPT_CAINFO even if use_ssl is not set. + +2012-07-10 Jean-Louis Martineau + * server-src/amstatus.pl: Print 'dump done' if the dump succeeded. + +2012-07-09 Jean-Louis Martineau + * common-src/conffile.c (val_t_display_strs): Add a print_unit argument. + * common-src/conffile.h (val_t_display_strs): Change prototype. + * perl/Amanda/Config.swg (getconf_byname_strs): Use val_t_display_strs + with a FALSE print_unit. + +2012-07-09 Jean-Louis Martineau + * common-src/conffile.c: Correctly parse byte suffix. + * common-src/conffile.h: Add confunit_t. + * installcheck/amgetconf.pl: Fix for byte parsing. + +2012-07-09 Jean-Louis Martineau + * server-src/driver.c (tape_action): Fix for flush_*. + Change debug level. + +2012-06-29 Jean-Louis Martineau + * perl/Amanda/Taper/Scan/traditional.pm, + perl/Amanda/Taper/Scribe.pm: Correctly report error. + +2012-06-29 Jean-Louis Martineau + * common-src/glib-util.c: Add initialization code for openssl and + gnutls. + * config/amanda/libs.m4: Detect ssl library used by libcurl. + +2012-06-28 Jean-Louis Martineau + * device-src/s3.c: Fix compiler warning. + +2012-06-28 Jean-Louis Martineau + * device-src/s3.c: Renew swift v2 x-auth-token before it expires, use + glib if >= 2.26. + +2012-06-27 Dan Locks + * configure.in: update ac_prereq to 2.64 + +2012-06-27 Jean-Louis Martineau + * device-src/s3.c: remove code to Renew swift v2 x-auth-token, it + require glib 2.26. + +2012-06-27 Jean-Louis Martineau + * device-src/s3-device.c: New CREATE-BUCKET property. + * device-src/s3.c: Improving error message parsing. + * man/xml-source/amanda-devices.7.xml: document new CREATE-BUCKET + property. + +2012-06-26 Jean-Louis Martineau + * device-src/s3.c: Remove bogus code. + +2012-06-26 Jean-Louis Martineau + * device-src/s3.c: Renew swift v2 x-auth-token before it expires. + +2012-06-26 Jean-Louis Martineau + * common-src/conffile.c: Fix crash when parsing an invalid config file. + +2012-06-26 Jean-Louis Martineau + * device-src/s3.c: Cloudena do not have xml_version of html tag in + their reply. + +2012-06-26 Jean-Louis Martineau + * device-src/s3.c: Renew OAUTH2 token. + +2012-06-21 Jean-Louis Martineau + * perl/Amanda/Report/human.pm: Change the default columspec to: HostName=0:-12:12,Disk=1:-11:11,Level=1:-1:1,OrigKB=1:-7:0,OutKB=1:-7:0,Compress=1:-6:1,DumpTime=1:-7:7,Dumprate=1:-6:1,TapeTime=1:-6:6,TapeRate=1:-6:1 + * man/xml-source/amanda.conf.5.xml: Document new default columnspec. + * installcheck/catalogs/bigestimate.cat, + installcheck/catalogs/doublefailure.cat, + installcheck/catalogs/filesystemstaped.cat, + installcheck/catalogs/longstrange.cat, + installcheck/catalogs/multi-taper.cat, + installcheck/catalogs/normal.cat, + installcheck/catalogs/plannerfail.cat, + installcheck/catalogs/resultsmissing.cat, + installcheck/catalogs/retried-nofinish.cat, + installcheck/catalogs/retried-strange.cat, + installcheck/catalogs/retried.cat, + installcheck/catalogs/shortstrange.cat, + installcheck/catalogs/skipped.cat, + installcheck/catalogs/spanned.cat, + installcheck/catalogs/strontium.cat: fix for new default columnspec. + +2012-06-21 Jean-Louis Martineau + * device-src/s3.c: OAUTH2 use 'max-keys'. + +2012-06-20 Jean-Louis Martineau + * perl/Amanda/Taper/Worker.pm: Fix update of the status file. + +2012-06-20 Jean-Louis Martineau + * common-src/security-util.c: Fix memory corruption. + +2012-06-20 Jean-Louis Martineau + * perl/Amanda/Taper/Scribe.pm: Cancel call dump_cb. + * perl/Amanda/Taper/Worker.pm: Cancel the header xfer. + +2012-06-20 Jean-Louis Martineau + * server-src/planner.c: Fix 32 bits overflow. + +2012-06-19 Jean-Louis Martineau + * amandad-src/amandad.c, common-src/amxml.c, + common-src/security-util.c, common-src/util.c, + server-src/tapefile.c: Fix small memory leak. + * perl/Amanda/Config.swg: Mark amandaify_property_name as %newobject + * perl/Amanda/Header.swg: Mark C_from_string as %newobject + * perl/Amanda/Tapelist.swg: Mark list_new_tapes as %newobject + * perl/Amanda/Util.swg: Mark sanitise_filename, quote_string, + unquote_string and split_quoted_strings as %newobject + * xfer-src/xfer-element.c: lock elt->xfer->status_mutex before looking + at elt->xfer->status. + * device-src/device.h (Device): Add a GMutex device_mutex to protect + method with concurent access. + * device-src/device.c, device-src/ndmp-device.c, + device-src/null-device.c, device-src/rait-device.c, + device-src/s3-device.c, device-src/tape-device.c, + device-src/vfs-device.c: Use the mutex to protext some Device field. + +2012-06-18 Jean-Louis Martineau + * server-src/planner.c: Coorectly delay full dump if it doesn't fit in + the schedule. + +2012-06-14 Dan Locks + * packaging/common/mock_utils.sh: update id mock to handle -Gn flags, + add groupadd mock, add usermod mock, correct silent errors in inetd + and install mocks + * packaging/common/pre_inst_functions.sh: add_group now attempts to + create a potentially missing suppmemental group, add_group does not + use -A or -a, instead generates a list of current groups from id -Gn, + update error_group_member to use the name of the group passed to + add_group. + * packaging/common/test_sh_libs.sh: add 2 add_group unit tests, update + check_user_group test. + +2012-06-13 Jean-Louis Martineau + * application-src/amgtar.c: Check gtar support --no-check-device. + +2012-06-08 Jean-Louis Martineau + * perl/Amanda/Changer/aggregate.pm, perl/Amanda/Changer/disk.pm, + perl/Amanda/Changer/ndmp.pm perl/Amanda/Changer/rait.pm, + perl/Amanda/Changer/robot.pm, perl/Amanda/Changer/single.pm, + perl/Amanda/Chunker/Controller.pm, perl/Amanda/Chunker/Scribe.pm, + perl/Amanda/Recovery/Clerk.pm, perl/Amanda/Recovery/Planner.pm, + perl/Amanda/Recovery/Scan.pm, perl/Amanda/Report/human.pm, + perl/Amanda/Taper/Scribe.pm, + perl/Amanda/Taper/Worker.pm: Change many die by confess. + +2012-06-07 Jean-Louis Martineau + * device-src/s3.c: Parse message attribute in cloudena error reply. + Parse details in HP error reply. + +2012-06-04 Jean-Louis Martineau + * server-src/amrestore.pl: Typo. + +2012-06-01 Jean-Louis Martineau + * server-src/amrestore.pl: Use the blocksize argument. + +2012-06-01 Jean-Louis Martineau + * perl/Amanda/Changer/robot.pm: Print to debug if bc2lb change the + label for a barcode. Print to debug the mtx output. + * perl/Amanda/Taper/Scribe.pm: Do not use a tape if the barcode from + tapelist differ from the changer. + +2012-05-28 Jean-Louis Martineau + * application-src/amzfs-sendrecv.pl: fix print_to_server argument. + +2012-05-24 Jean-Louis Martineau + * application-src/amsamba.pl: Do not send a chomped line to index. + +2012-05-24 Jean-Louis Martineau + * perl/Amanda/Application.swg: Use IO::Handle to open mesgout. + +2012-05-23 Jean-Louis Martineau + * device-src/s3-device.c: Add project_id. + * device-src/s3.c: Add project_id. Add x-goog-project-id and + x-goo-api-version to headers. + * device-src/s3.h (s3_make_bucket, s3_is_bucket_exists) Add project_id + argument. + * man/xml-source/amanda-devices.7.xml: Document project-id property. + +2012-05-23 Jean-Louis Martineau + * device-src/s3-device.c: Call s3_open2 after setting properties. + * device-src/s3.c (s3_open2): New function. + * device-src/s3.h (s3_open2): Prototype. + +2012-05-17 Dan Locks + * packaging/sun-pkg/buildpkg: add missing --with-libcurl= for server + +2012-05-17 Jean-Louis Martineau + * common-src/event.c: Add missing "\n" in debugging. + * perl/Amanda/Application.swg: Make mesgout autoflush. + +2012-05-15 Jean-Louis Martineau + * installcheck/Amanda_Device.pl: Correctly count NDMP test. + +2012-05-15 Jean-Louis Martineau + * server-src/amvault.pl: Abort if log file already exists. + +2012-05-15 Jean-Louis Martineau + * server-src/find.c: Fix crash when log are corrupted. + +2012-05-15 Jean-Louis Martineau + * perl/Amanda/Recovery/Planner.pm (make_plan_from_filelist): Use the + changer inventory to try to use an already available dump. + * server-src/amidxtaped.pl: Pass the changer to make_plan. + +2012-05-14 Jean-Louis Martineau + * common-src/util.c, device-src/s3.c: Fix for pragma and gcc-4.5.2. + +2012-05-11 Jean-Louis Martineau + * perl/Amanda/Taper/Worker.pm (FAILED): Do it correctly. + +2012-05-11 Jean-Louis Martineau + * server-src/amstatus.pl: Improve output on taper error. + +2012-05-11 Jean-Louis Martineau + * perl/Amanda/Taper/Worker.pm (FAILED): Ignore if dump is already + cancelled. + +2012-05-11 Jean-Louis Martineau + * common-src/event.c: Improve debugging. + * server-src/dumper.c: Close data output in stop_dump. + +2012-05-11 Jean-Louis Martineau + * config/amanda/progs.m4: Define AMANDA_PROG_NC, set NC, NC6 and + NETCAT. + * configure.in: use AMANDA_PROG_NC. + * installcheck/Amanda_Device.pl: Use them. + * perl/Amanda/Constants.pm.in: Add NC, NC6 and NETCAT. + +2012-05-10 Dan Locks + * configure.in: update AC_INIT usage, specify tar-ustar and minimum + automake version. + * config/amanda/version.m4: create new AMANDA_INIT_VERSION macro to + read FULL_VERSION or VERSION before AC_INIT. + +2012-05-10 Dan Locks + * Makefile.am: update required automake version + +2012-05-08 Jean-Louis Martineau + * installcheck/Amanda_Device.pl: sleep to allow other process the time + to start listening. + +2012-05-08 Jean-Louis Martineau + * common-src/amflock.c, common-src/match.c, common-src/util.c, + device-src/s3.c: Fix for deprecated G_STATIC_MUTEX_INIT. + +2012-05-08 Jean-Louis Martineau + * installcheck/Amanda_Device.pl: Fix indirect tcp. + +2012-05-08 Jean-Louis Martineau + * client-src/sendbackup.c: Handle indirect tcp. + * device-src/ndmp-device.c: Add INDIRECT property. + * installcheck/Amanda_Device.pl: Test indirect tcp. + * man/xml-source/amanda-devices.7.xml: Document INDIRECT property. + * ndmp-src/ndmp4_translate.c: remove debugging statement. + +2012-05-01 Jean-Louis Martineau + * man/xml-source/amfetchdump.8.xml: Add --decrypt, --no-decrypt, + --server-decrypt, --client-decrypt, --compress, --no-compress, + --server-compress, --client-compress. + * server-src/amfetchdump.pl: Document new options. + +2012-04-25 Jean-Louis Martineau + * ndmp-src/ndmos.h: Define NDMOS_MACRO_FREE + * ndmp-src/ndmos_glib.h: Define NDMOS_MACRO_FREE + * ndmp-src/ndmp_translate.h: define CNVT_FREE. + * ndmp-src/ndmp4_translate.c:#Add many free function. + +2012-04-20 Jean-Louis Martineau + * server-src/amfetchdump.pl: Fix. + +2012-04-20 Jean-Louis Martineau + * server-src/amadmin.c: Fix handling of optional arguments. + * installcheck/amadmin.pl: Check it. + +2012-04-19 Jean-Louis Martineau + * client-src/amdump_client.pl: Fix warning. + +2012-04-18 Jean-Louis Martineau + * server-src/amfetchdump.pl: add --decompress and --decrypt options. + * man/xml-source/amfetchdump.8.xml: Document new options. + +2012-04-18 Jean-Louis Martineau + * common-src/conffile.c: Parse MAX_WARNINGS in dumptype. + * common-src/conffile.h: Add DUMPTYPE_MAX_WARNINGS and + dumptype_get_max_warnings + * man/xml-source/amanda.conf.5.xml: Document max_warning in dumptype. + * perl/Amanda/Config.swg: Add DUMPTYPE_MAX_WARNINGS. + * server-src/diskfile.c (add_disk): Copy max_warnings from dumptype. + * server-src/diskfile.h: Add max_warnings in disk_t. + * server-src/driverio.c (dumper_cmd): Send max_warnings to dumper. + * server-src/dumper.c: Use max_warnings. + +2012-04-18 Jean-Louis Martineau + * ndmp-src/ndmpconnobj.c: Remove useless g_source_is_destroyed check. + +2012-04-17 Jean-Louis Martineau + * common-src/amgetconf.pl: Read the disklist. + * common-src/conffile.h (seen_t): Add block. + * common-src/conffile.c: Set seen.block + * common-src/conffile.c (dump_configuration): New print_default and + print_source arguments. + * installcheck/Amanda_Config.pl: Fix dump_configuration call. + * server-src/amadmin.c: Add --no-default and --print-source arguments + for config and disklist command. + * man/xml-source/amadmin.8.xml: Document new arguments. + * perl/Amanda/Config.swg: Fix for new dump_configuration arguments. + +2012-04-16 Jean-Louis Martineau + * application-src/amstar.c: Remove spurious space on directory entry. + +2012-04-13 Jean-Louis Martineau + * common-src/conffile.c: Add TMPDIR. + * common-src/conffile.h: Add CNF_TMPDIR. + * man/xml-source/amanda.conf.5.xml: Document TMPDIR. + * perl/Amanda/Config.swg: Add CNF_TMPDIR. + * server-src/amindexd.c: Use CNF_TMPDIR. + +2012-04-12 Jean-Louis Martineau + * application-src/amsamba.pl: Create incremental empty archive. + +2012-04-11 Jean-Louis Martineau + * perl/Amanda/Changer.pm (make_new_tape_label): Fix error return. + * perl/Amanda/Taper/Scribe.pm ($_user_msg_fn): Improve message if tape + is relabeled with a new label. + * perl/Amanda/ScanInventory.pm: Set relabeled. + * installcheck/Amanda_Changer.pl: Fix for new message. + +2012-04-11 Jean-Louis Martineau + Patch by Nathan Stratton Treadway + * device-src/vfs-device.c: Improve message for MAX_VOLUME_USAGE. + * installcheck/taper.pl: Fix. + +2012-04-11 Jean-Louis Martineau + * man/xml-source/amgtar.8.xml: s/APPLCIATION/APPLICATION/ + +2012-04-06 Jean-Louis Martineau + * application-src/ampgsql.pl: psql /could not connect to server/ + message result in STRANGE. + +2012-04-06 Jean-Louis Martineau + * perl/Amanda/ScanInventory.pm: Fix for label not matching labelstr. + +2012-04-06 Jean-Louis Martineau + * device-src/device.c (device_get_bytes_written): New function. + * device-src/device.h (device_get_bytes_written): New prototype. + * device-src/ndmp-device.c, device-src/rait-device.c, + device-src/s3-device.c, device-src/tape-device.c, + device-src/vfs-device.c: Implement get_bytes_written. + * device-src/xfer-dest-taper-cacher.c, + device-src/xfer-dest-taper-splitter.c: Use device_get_bytes_written. + * perl/Amanda/Device.swg: Swig device_get_bytes_written. + +2012-04-05 Jean-Louis Martineau + * device-src/s3-device.c: New CLIENT_ID, CLIENT_SECRET and + REFRESH_TOKEN properties. Handle OAUTH2. + * device-src/s3.c: Handle OAUTH2. + * device-src/s3.h (S3_api): Add S3_API_OAUTH2. + * man/xml-source/amanda-devices.7.xml: Document new CLIENT_ID, + CLIENT_SECRET and REFRESH_TOKEN properties. + +2012-04-05 Jean-Louis Martineau + * man/xml-source/amfetchdump.8.xml: Document -l do not unencrypt. + +2012-04-05 Jean-Louis Martineau + * device-src/device.c (device_accept_with_cond, + device_connect_with_cond): New functions. + * device-src/device.h (device_accept_with_cond, + device_connect_with_cond): New prototypes. + * device-src/ndmp-device.c (accept_with_cond_impl, + connect_with_cond_impl): new functions. + * device-src/xfer-dest-taper-directtcp.c: Use device_accept_with_cond. + * ndmp-src/ndmpconnobj.c (ndmp_connection_wait_for_notify_with_cond): + new function. + * ndmp-src/ndmpconnobj.h (ndmp_connection_wait_for_notify_with_cond): + new prototype. + * perl/Amanda/Device.swg: swig accept_with_cond and connect_with_cond. + * perl/Amanda/Taper/Worker.pm: Ignore duplicate DONe message. + * server-src/driver.c (handle_dumper_result): Always send dumper + result to taper. + * server-src/dumper.c: Remove debugging statement. + * xfer-src/element-glue.c: Add debugging statement. + * xfer-src/xfer.c (xfer_cancel): Ignore duplicate cancel. + * xfer-src/xfer.h (struct Xfer): Add cancelled field. + +2012-04-05 Jean-Louis Martineau + * common-src/amcryptsimple.pl: Use gpg if available. + * common-src/amgpgcrypt.pl: Use gpg-agent and/or gpg2 if available. + * server-src/dumper.c: Log compression/encryption executed. + +2012-04-05 Jean-Louis Martineau + * device-src/s3-device.c: New S3_MULTI_DELETE property. + * device-src/s3.c: New S3_MULTI_DELETE property. + * device-src/s3.h (s3_multi_delete): New prototype. + * man/xml-source/amanda-devices.7.xml: Document new S3_MULTI_DELETE s3 + device property. + +2012-04-05 Jean-Louis Martineau + * device-src/s3-device.c: New PASSWORD, USERNAME, TENANT_ID, + TENANT_NAME and STORAGE_API property. Handle SWIFT-2. + * device-src/s3.c: Handle SWIFT-2. + * device-src/s3.h (s3_open): New prototype. + * device-src/s3.h (S3_api): New enum. + * man/xml-source/amanda-devices.7.xml: Document new PASSWORD, + USERNAME, TENANT_ID, TENANT_NAME and STORAGE_API S3 device + properties. + +2012-04-02 Jean-Louis Martineau + * application-src/amsamba.pl: Do not set unc prematurely. + +2012-04-02 Jean-Louis Martineau + * device-src/ndmp-device.c (listen_impl): Set the window offset and + length to blocksize when reading. + +2012-03-29 Dan Locks + * packaging/sun-pkg/buildpkg: add missing GLIB_LIBS variable to intel + builds. Add flags to make invocation to reduce output. + +2012-03-29 Jean-Louis Martineau + * server-src/driver.c: Fix hang if taper crash. + +2012-03-29 Jean-Louis Martineau + * device-src/s3.c: Retry on {500, S3_ERROR_None} error. + Improving debugging. + +2012-03-28 Jean-Louis Martineau + * server-src/amadmin.c: Fix bumpsize. + +2012-03-22 Jean-Louis Martineau + * common-src/fileheader.c: header type for non-amanda header is + F_WEIRD. + * server-src/amcheck-device.pl, + server-src/amtape.pl: Improve output for non-Amanda volume. + +2012-03-19 Jean-Louis Martineau + * application-src/amgtar.c: Use "TAR-BLOCKSIZE" on restore. + +2012-03-16 Jean-Louis Martineau + * application-src/ampgsql.pl: Use statefile to find end_wal on + estimate. + +2012-03-15 Jean-Louis Martineau + * application-src/amgtar.c: Add IGNORE-ZEROS property. + * man/xml-source/amgtar.8.xml: Document IGNORE-ZEROS property. + +2012-03-13 Jean-Louis Martineau + * application-src/ampgsql.pl: Do not Execute pg_start_backup for + estimate. + +2012-03-11 Jean-Louis Martineau + * common-src/glib-util.c: g_thread_supported always return TRUE on + newer version. + +2012-03-10 Jean-Louis Martineau + * common-src/glib-util.c, common-src/glib-util.h: Remove + g_queue_free_full. + +2012-03-09 Jean-Louis Martineau + * client-src/client_util.c, common-src/Makefile.am, common-src/am_sl.c, + common-src/amxml.c: typo. + +2012-03-09 Jean-Louis Martineau + * client-src/client_util.c, client-src/selfcheck.c, + client-src/sendbackup-dump.c, client-src/sendbackup-gnutar.c, + client-src/sendbackup.c, client-src/sendsize.c, + common-src/amxml.c, common-src/amxml.h, + recover-src/extract_list.c: s/level_t/am_level_t/g + * client-src/calcsize.c, common-src/amxml.h, + common-src/conffile.c, common-src/conffile.h, + common-src/sl.c, common-src/sl.h, + perl/Amanda/Header.swg: s/sl_t/am_sl_t/g + * amandad-src/amandad.h, client-src/calcsize.c, + client-src/client_util.h, common-src/Makefile.am: s/sl.h/am_sl.h + * common-src/am_sl.h: renamed from common-src/sl.h + * common-src/am_sl.c: renamed from common-src/sl.c + +2012-03-09 Jean-Louis Martineau + * server-src/amfetchdump.pl: Print progress. + * device-src/device.c (device_get_bytes_read ): New API method. + * device-src/device.h (Device): Add bytes_read. + * device-src/device.h (_DeviceClass): Add get_bytes_read. + * device-src/device.h (device_get_bytes_read): Add prototype. + * device-src/ndmp-device.c: Set bytes_read. + * device-src/rait-device.c: Set bytes_read. + * device-src/s3-device.c: Use curl progress callback to set bytes_read. + * device-src/s3.c: Set a progress callback. + * device-src/tape-device.c: Set bytes_read. + * device-src/vfs-device.c: Set bytes_read. + * device-src/xfer-device.h (xfer_source_recovery_get_bytes_read): Add + prototype. + * device-src/xfer-source-recovery.c + (xfer_source_recovery_get_bytes_read): new function. + * perl/Amanda/Device.swg (device_get_bytes_read): New function. + * perl/Amanda/Recovery/Clerk.pm: Call get_bytes_read. + * perl/Amanda/XferServer.swg: (xfer_source_holding_get_bytes_read, + * xfer_source_recovery_get_bytes_read): New prototypes. + * server-src/xfer-server.h (xfer_source_holding_get_bytes_read): + New protoype. + * server-src/xfer-source-holding.c (xfer_source_holding_get_bytes_read): + New function. + +2012-03-09 Jean-Louis Martineau + * perl/Amanda/Recovery/Scan.pm: Do not rescan the same slot + indefinitely. + +2012-03-09 Jean-Louis Martineau + * perl/Amanda/Changer/multi.pm: Fix warning. + +2012-03-09 Jean-Louis Martineau + * device-src/s3-device.c: New PROXY property. + * device-src/s3.c: Set CURLOPT_PROXY from PROXY property. + * device-src/s3.h (s3_open): Add proxy argument. + * man/xml-source/amanda-devices.7.xml: Document PROXY property. + +2012-03-08 Jean-Louis Martineau + * perl/Amanda/Header.swg (get_dle): Return undef if not set. + * server-src/amidxtaped.pl: Check dle is set. + +2012-03-08 Jean-Louis Martineau + * server-src/amvault.pl: Use the write-timestamp, not the + dump-timestamp. + +2012-03-08 Jean-Louis Martineau + * common-src/ssh-security.c: use default port if client-port is not + set. + +2012-03-07 Jean-Louis Martineau + * application-src/amsamba.pl: Fix use of subdir for restore, + prepend subdir on include for restore. + +2012-03-07 Jean-Louis Martineau + * ndmp-src/ndmjob_args.c: Add '-o D-agent-fd' argument. + +2012-03-07 Jean-Louis Martineau + * application-src/ampgsql.pl: Do not execute pg_start_backup and + pg_stop_backup on selfcheck. + +2012-02-23 Jean-Louis Martineau + * man/xml-source/amzfs-sendrecv.8.xml: Typo. + +2012-02-23 Jean-Louis Martineau + * man/xml-source/disklist.5.xml: Document includefile directive. + 2012-02-21 Jean-Louis Martineau * perl/make_html.pl: Add link at top, better list display. * perl/Makefile.am: Execute make_html with a --homeurl argument. diff --git a/FULL_VERSION b/FULL_VERSION index bea438e..4772543 100644 --- a/FULL_VERSION +++ b/FULL_VERSION @@ -1 +1 @@ -3.3.1 +3.3.2 diff --git a/Makefile.am b/Makefile.am index 7e8d4c2..81589ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ ## Process this file with automake to produce Makefile.in -AUTOMAKE_OPTIONS = 1.4 foreign +AUTOMAKE_OPTIONS = 1.10 foreign include $(top_srcdir)/config/automake/vars.am include $(top_srcdir)/config/automake/installperms.am diff --git a/Makefile.in b/Makefile.in index 8a973bc..f6defc6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,7 +16,7 @@ @SET_MAKE@ # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -261,7 +261,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ @@ -855,6 +856,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ @@ -1151,7 +1155,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = 1.4 foreign +AUTOMAKE_OPTIONS = 1.10 foreign SUFFIXES = EXTRA_DIST = $(SNAPSHOT_STAMP) $(pkgdata_DATA) autogen contrib/README \ contrib/dbbackup.README contrib/dbbackup.ksh \ diff --git a/NEWS b/NEWS index 48f53ef..5f5c570 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,36 @@ +Changes in release 3.3.2 + + * amgtar + o New IGNORE-ZEROS property. + * amsamba + o Fix use of subdir for restore. + * s3 device + o New PROXY property. + o New PASSWORD, USERNAME, TENANT_ID, TENANT_NAME properties. + o New STORAGE_API property. + o New S3_MULTI_DELETE property + o New CLIENT_ID, CLIENT_SECRET and REFRESH_TOKEN properties. + o New CREATE-BUCKET property. + o New PROJECT-ID property. + o New REUSE-CONNECTION property. + o Works with swift and google storage. + * NDMP device + o Add INDIRECT property. + * amanda.conf + o Add 'max-warnings', The maximum number of warning lines in the report. + o Default 'columspec' changed to: HostName=0:-12:12,Disk=1:-11:11,Level=1:-1:1,OrigKB=1:-7:0,OutKB=1:-7:0,Compress=1:-6:1,DumpTime=1:-7:7,Dumprate=1:-6:1,TapeTime=1:-6:6,TapeRate=1:-6:1 + * amadmin + o Add --no-default and --print-source arguments for config and + disklist command. + * amfetchdump + o Print progress. + o Add --decrypt, --no-decrypt, --server-decrypt, --client-decrypt, + --compress, --no-compress, --server-compress and --client-compress + options. + * fix for compilation with newer glib. + * fix for compilation on cigwin. + * Many bug fix. + Changes in release 3.3.1 * amrecover diff --git a/ReleaseNotes b/ReleaseNotes index d4f5e8c..d3286fd 100644 --- a/ReleaseNotes +++ b/ReleaseNotes @@ -1,3 +1,37 @@ + Release Notes for amanda-3.3.2 + +* amgtar + o New IGNORE-ZEROS property. +* amsamba + o Fix use of subdir for restore. +* s3 device + o New PROXY property. + o New PASSWORD, USERNAME, TENANT_ID, TENANT_NAME properties. + o New STORAGE_API property. + o New S3_MULTI_DELETE property + o New CLIENT_ID, CLIENT_SECRET and REFRESH_TOKEN properties. + o New CREATE-BUCKET property. + o New PROJECT-ID property. + o New REUSE-CONNECTION property. + o Works with swift and google storage. +* NDMP device + o Add INDIRECT property. +* amanda.conf + o Add 'max-warnings', The maximum number of warning lines in the report. + o Default 'columspec' changed to: HostName=0:-12:12,Disk=1:-11:11,Level=1:-1:1,OrigKB=1:-7:0,OutKB=1:-7:0,Compress=1:-6:1,DumpTime=1:-7:7,Dumprate=1:-6:1,TapeTime=1:-6:6,TapeRate=1:-6:1 +* amadmin + o Add --no-default and --print-source arguments for config and + disklist command. +* amfetchdump + o Print progress. + o Add --decrypt, --no-decrypt, --server-decrypt, --client-decrypt, + --compress, --no-compress, --server-compress and --client-compress + options. +* fix for compilation with newer glib. +* fix for compilation on cigwin. +* Many bug fix. + + Release Notes for amanda-3.3.1 * amrecover diff --git a/VERSION b/VERSION index bea438e..4772543 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.3.1 +3.3.2 diff --git a/aclocal.m4 b/aclocal.m4 index f5a2ff7..258a742 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1167,6 +1167,23 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 diff --git a/amandad-src/Makefile.in b/amandad-src/Makefile.in index 7f309a0..f57f64f 100644 --- a/amandad-src/Makefile.in +++ b/amandad-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda client programs. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -268,7 +268,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -835,6 +836,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/amandad-src/amandad.c b/amandad-src/amandad.c index e3f11a0..11009d8 100644 --- a/amandad-src/amandad.c +++ b/amandad-src/amandad.c @@ -564,6 +564,7 @@ protocol_accept( char *service_path = NULL; GSList *errlist = NULL; int i; + char *peer_name; pkt_out.body = NULL; @@ -600,7 +601,9 @@ protocol_accept( return; } - g_debug("authenticated peer name is '%s'", security_get_authenticated_peer_name(handle)); + peer_name = security_get_authenticated_peer_name(handle); + g_debug("authenticated peer name is '%s'", peer_name); + amfree(peer_name); /* * If pkt is NULL, then there was a problem with the new connection. diff --git a/amandad-src/amandad.h b/amandad-src/amandad.h index d58eaf3..2bbf727 100644 --- a/amandad-src/amandad.h +++ b/amandad-src/amandad.h @@ -33,7 +33,7 @@ #include "amanda.h" #include "amfeatures.h" -#include "sl.h" +#include "am_sl.h" #include "util.h" /* for bstrncmp() */ typedef struct g_option_s { diff --git a/amar-src/Makefile.in b/amar-src/Makefile.in index 1bea528..e508a17 100644 --- a/amar-src/Makefile.in +++ b/amar-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda archive library # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -270,7 +270,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -843,6 +844,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/amar-src/amar.c b/amar-src/amar.c index 67cc109..f237fe5 100644 --- a/amar-src/amar.c +++ b/amar-src/amar.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/amar-src/amar.h b/amar-src/amar.h index 527802d..9ba1c7c 100644 --- a/amar-src/amar.h +++ b/amar-src/amar.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/amar-src/amarchiver.c b/amar-src/amarchiver.c index 2147929..71821e7 100644 --- a/amar-src/amarchiver.c +++ b/amar-src/amarchiver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/amplot/Makefile.in b/amplot/Makefile.in index 9fd64b9..914cd1c 100644 --- a/amplot/Makefile.in +++ b/amplot/Makefile.in @@ -18,7 +18,7 @@ # Makefile for amplot. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -40,7 +40,7 @@ # scripts in this directory. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -337,7 +337,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -877,6 +878,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/application-src/Makefile.in b/application-src/Makefile.in index c73b974..fa34068 100644 --- a/application-src/Makefile.in +++ b/application-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda wrapper programs. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -40,7 +40,7 @@ # scripts in this directory. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -339,7 +339,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -914,6 +915,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/application-src/amgtar.c b/application-src/amgtar.c index 7cf28a1..47103ad 100644 --- a/application-src/amgtar.c +++ b/application-src/amgtar.c @@ -122,6 +122,7 @@ typedef struct application_argument_s { int argc; char **argv; int verbose; + int ignore_zeros; } application_argument_t; enum { CMD_ESTIMATE, CMD_BACKUP }; @@ -137,6 +138,7 @@ static void amgtar_build_exinclude(dle_t *dle, int verbose, int *nb_include, char **file_include); static char *amgtar_get_incrname(application_argument_t *argument, int level, FILE *mesgstream, int command); +static void check_no_check_device(void); static GPtrArray *amgtar_build_argv(application_argument_t *argument, char *incrname, char **file_exclude, char **file_include, int command); @@ -194,6 +196,7 @@ static struct option long_options[] = { {"include-list-glob", 1, NULL, 34}, {"exclude-list-glob", 1, NULL, 35}, {"verbose" , 1, NULL, 36}, + {"ignore-zeros" , 1, NULL, 37}, {NULL, 0, NULL, 0} }; @@ -370,6 +373,7 @@ main( argument.include_list_glob = NULL; argument.exclude_list_glob = NULL; argument.verbose = 0; + argument.ignore_zeros = 1; init_dle(&argument.dle); argument.dle.record = 0; @@ -501,6 +505,9 @@ main( case 36: if (optarg && strcasecmp(optarg, "YES") == 0) argument.verbose = 1; break; + case 37: if (strcasecmp(optarg, "YES") != 0) + argument.ignore_zeros = 0; + break; case ':': case '?': break; @@ -1118,7 +1125,13 @@ amgtar_restore( if (gnutar_xattrs) g_ptr_array_add(argv_ptr, stralloc("--xattrs")); /* ignore trailing zero blocks on input (this was the default until tar-1.21) */ - g_ptr_array_add(argv_ptr, stralloc("--ignore-zeros")); + if (argument->ignore_zeros) { + g_ptr_array_add(argv_ptr, stralloc("--ignore-zeros")); + } + if (argument->tar_blocksize) { + g_ptr_array_add(argv_ptr, stralloc("--blocking-factor")); + g_ptr_array_add(argv_ptr, stralloc(argument->tar_blocksize)); + } g_ptr_array_add(argv_ptr, stralloc("-xpGvf")); g_ptr_array_add(argv_ptr, stralloc("-")); if (gnutar_directory) { @@ -1451,6 +1464,41 @@ amgtar_get_incrname( return incrname; } +static void +check_no_check_device(void) +{ + if (gnutar_checkdevice == 0) { + GPtrArray *argv_ptr = g_ptr_array_new(); + int dumpin; + int dataf; + int outf; + int size; + char buf[32768]; + + g_ptr_array_add(argv_ptr, gnutar_path); + g_ptr_array_add(argv_ptr, "-x"); + g_ptr_array_add(argv_ptr, "--no-check-device"); + g_ptr_array_add(argv_ptr, "-f"); + g_ptr_array_add(argv_ptr, "-"); + g_ptr_array_add(argv_ptr, NULL); + + pipespawnv(gnutar_path, STDIN_PIPE|STDOUT_PIPE|STDERR_PIPE, 0, + &dumpin, &dataf, &outf, (char **)argv_ptr->pdata); + aclose(dumpin); + aclose(dataf); + size = read(outf, buf, 32767); + if (size > 0) { + buf[size] = '\0'; + if (strstr(buf, "--no-check-device")) { + g_debug("disabling --no-check-device since '%s' doesn't support it", gnutar_path); + gnutar_checkdevice = 1; + } + } + aclose(outf); + g_ptr_array_free(argv_ptr, TRUE); + } +} + GPtrArray *amgtar_build_argv( application_argument_t *argument, char *incrname, @@ -1465,6 +1513,7 @@ GPtrArray *amgtar_build_argv( GPtrArray *argv_ptr = g_ptr_array_new(); GSList *copt; + check_no_check_device(); amgtar_build_exinclude(&argument->dle, 1, &nb_exclude, file_exclude, &nb_include, file_include); diff --git a/application-src/amlog-script.pl b/application-src/amlog-script.pl index 284e68f..eaf2a6d 100644 --- a/application-src/amlog-script.pl +++ b/application-src/amlog-script.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/application-src/ampgsql.pl b/application-src/ampgsql.pl index 0150af1..652345f 100644 --- a/application-src/ampgsql.pl +++ b/application-src/ampgsql.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -273,6 +273,9 @@ sub _run_psql_command { chomp $line; debug("psql stderr: $line"); if ($line =~ /NOTICE: pg_stop_backup complete, all required WAL segments have been archived/) { + } elsif ($line =~ /could not connect to server/) { + $self->print_to_server("psql stderr: $line", + $Amanda::Script_App::ERROR); } else { $self->print_to_server("psql stderr: $line", $Amanda::Script_App::GOOD); @@ -425,19 +428,6 @@ sub command_selfcheck { _check("Connecting to database server", "succeeded", "failed", \&_run_psql_command, $self, ''); } - - if ($try_connect) { - my $label = "$self->{'label-prefix'}-selfcheck-" . time(); - if (_check("Call pg_start_backup", "succeeded", - "failed (is another backup running?)", - \&_run_psql_command, $self, "SELECT pg_start_backup('$label')") - and _check("Call pg_stop_backup", "succeeded", "failed", - \&_run_psql_command, $self, "SELECT pg_stop_backup()")) { - - _check("Get info from .backup file", "succeeded", "failed", - sub {my ($start, $end) = _get_backup_info($self, $label); $start and $end}); - } - } { my @gv = `$self->{'args'}->{'gnutar-path'} --version`; @@ -479,9 +469,11 @@ sub _write_state_file { sub _get_prev_state { my $self = shift @_; + my $initial_level = shift; + $initial_level = $self->{'args'}->{'level'} - 1 if !defined $initial_level; my $end_wal; - for (my $level = $self->{'args'}->{'level'} - 1; $level >= 0; $level--) { + for (my $level = $initial_level; $level >= 0; $level--) { my $fn = _state_filename($self, $level); debug("reading state file: $fn"); my $h = new IO::File($fn, "r"); @@ -708,7 +700,10 @@ sub _wait_for_wal { my $count = 0; # try at least 4 cycles my $stoptime = time() + $maxwait; while ($maxwait == 0 || time < $stoptime || $count++ < 4) { - return if -f "$archive_dir/$wal"; + if (-f "$archive_dir/$wal") { + sleep(1); + return; + } # for versions 8.0 or 8.1, the only way to "force" a WAL archive is to write # garbage to the database. @@ -732,8 +727,10 @@ sub _base_backup { -d $self->{'props'}->{'pg-archivedir'} or die("WAL file archive directory does not exist (or is not a directory)"); - _run_psql_command($self, "SELECT pg_start_backup('$label')") or - $self->{'die_cb'}->("Failed to call pg_start_backup"); + if ($self->{'action'} eq 'backup') { + _run_psql_command($self, "SELECT pg_start_backup('$label')") or + $self->{'die_cb'}->("Failed to call pg_start_backup"); + } # tar data dir, using symlink to prefix # XXX: tablespaces and their symlinks? @@ -741,8 +738,10 @@ sub _base_backup { my $old_die_cb = $self->{'die_cb'}; $self->{'die_cb'} = sub { my $msg = shift @_; - unless(_run_psql_command($self, "SELECT pg_stop_backup()")) { - $msg .= " and failed to call pg_stop_backup"; + if ($self->{'action'} eq 'backup') { + unless(_run_psql_command($self, "SELECT pg_stop_backup()")) { + $msg .= " and failed to call pg_stop_backup"; + } } $old_die_cb->($msg); }; @@ -754,28 +753,39 @@ sub _base_backup { "."); $self->{'die_cb'} = $old_die_cb; - unless (_run_psql_command($self, "SELECT pg_stop_backup()")) { - $self->{'die_cb'}->("Failed to call pg_stop_backup"); + if ($self->{'action'} eq 'backup') { + unless (_run_psql_command($self, "SELECT pg_stop_backup()")) { + $self->{'die_cb'}->("Failed to call pg_stop_backup"); + } } # determine WAL files and append and create their tar file - my ($start_wal, $end_wal) = _get_backup_info($self, $label); + my $start_wal; + my $end_wal; - ($start_wal and $end_wal) - or $self->{'die_cb'}->("A .backup file was never found in the archive " - . "dir $self->{'props'}->{'pg-archivedir'}"); - - $self->_wait_for_wal($end_wal); + if ($self->{'action'} eq 'backup') { + ($start_wal, $end_wal) = _get_backup_info($self, $label); + ($start_wal and $end_wal) + or $self->{'die_cb'}->("A .backup file was never found in the archive " + . "dir $self->{'props'}->{'pg-archivedir'}"); + $self->_wait_for_wal($end_wal); + } else { + $start_wal = undef; + $end_wal = _get_prev_state($self, 0); + } # now grab all of the WAL files, *inclusive* of $start_wal my @wal_files; my $adir = new IO::Dir($self->{'props'}->{'pg-archivedir'}); while (defined(my $fname = $adir->read())) { if ($fname =~ /^$_WAL_FILE_PAT$/) { - if (($fname ge $start_wal) and ($fname le $end_wal)) { + if (!defined $end_wal || + (!defined $start_wal and ($fname le $end_wal)) || + (defined $start_wal and ($fname ge $start_wal) and + ($fname le $end_wal))) { push @wal_files, $fname; debug("will store: $fname"); - } elsif ($fname lt $start_wal) { + } elsif (defined $start_wal and $fname lt $start_wal) { $self->{'unlink_cb'}->("$self->{'props'}->{'pg-archivedir'}/$fname"); } } diff --git a/application-src/amraw.pl b/application-src/amraw.pl index 5502657..1987586 100644 --- a/application-src/amraw.pl +++ b/application-src/amraw.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/application-src/amsamba.pl b/application-src/amsamba.pl index d1f0bda..7a6ffd8 100644 --- a/application-src/amsamba.pl +++ b/application-src/amsamba.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -36,6 +36,7 @@ use Amanda::Config qw( :init :getconf config_dir_relative ); use Amanda::Debug qw( :logging ); use Amanda::Paths; use Amanda::Util qw( :constants :quoting); +use Amanda::MainLoop qw( :GIOCondition ); sub new { my $class = shift; @@ -70,11 +71,6 @@ sub new { } else { $self->{device} = $disk; } - if ($self->{disk} =~ /^\\\\/) { - $self->{unc} = 1; - } else { - $self->{unc} = 0; - } $self->{level} = [ @{$level} ]; $self->{index} = $index; $self->{message} = $message; @@ -146,6 +142,9 @@ sub validate_inexclude { next; } while () { + if (defined $self->{'subdir'}) { + $_ =~ s/^\./$self->{'subdir'}/; + } print INC_FILE; } close(FF); @@ -155,7 +154,11 @@ sub validate_inexclude { for(my $i=1;defined $ARGV[$i]; $i++) { my $param = $ARGV[$i]; $param =~ /^(.*)$/; - print INC_FILE "$1\n"; + $_ = $1; + if (defined $self->{'subdir'}) { + $_ =~ s/^\./$self->{'subdir'}/; + } + print INC_FILE "$_\n"; } close INC_FILE; @@ -176,6 +179,10 @@ sub validate_inexclude { } while () { chomp; + if ($self->{action} eq "restore" and + defined $self->{'subdir'}) { + $_ =~ s/^\./$self->{'subdir'}/; + } push @{$self->{include}}, $_; } close(FF); @@ -186,6 +193,10 @@ sub validate_inexclude { for(my $i=1;defined $ARGV[$i]; $i++) { my $param = $ARGV[$i]; $param =~ /^(.*)$/; + $_ = $1; + if (defined $self->{'subdir'}) { + $_ =~ s/^\./$self->{'subdir'}/; + } push @{$self->{include}}, $1; } } @@ -207,6 +218,11 @@ sub parsesharename { $to_parse = $self->{device} if !defined $to_parse;; return if !defined $to_parse; + if ($to_parse =~ /^\\\\/) { + $self->{unc} = 1; + } else { + $self->{unc} = 0; + } if ($self->{unc}) { if ($to_parse =~ m,^(\\\\[^\\]+\\[^\\]+)\\(.*)$,) { @@ -375,13 +391,13 @@ sub command_selfcheck { print "OK " . $self->{device} . "\n"; print "OK " . $self->{directory} . "\n" if defined $self->{directory}; - my ($child_rdr, $parent_wtr); + my ($password_rdr, $password_wtr); if (defined $self->{password}) { # Don't set close-on-exec $^F=10; - pipe($child_rdr, $parent_wtr); + pipe($password_rdr, $password_wtr); $^F=2; - $parent_wtr->autoflush(1); + $password_wtr->autoflush(1); } my($wtr, $rdr, $err); $err = Symbol::gensym; @@ -389,10 +405,10 @@ sub command_selfcheck { if ($pid == 0) { #child if (defined $self->{password}) { - my $ff = $child_rdr->fileno; - debug("child_rdr $ff"); - $parent_wtr->close(); - $ENV{PASSWD_FD} = $child_rdr->fileno; + my $ff = $password_rdr->fileno; + debug("password_rdr $ff"); + $password_wtr->close(); + $ENV{PASSWD_FD} = $password_rdr->fileno; } close(1); close(2); @@ -414,11 +430,11 @@ sub command_selfcheck { } #parent if (defined $self->{password}) { - my $ff = $parent_wtr->fileno; - debug("parent_wtr $ff"); - $parent_wtr->print($self->{password}); - $parent_wtr->close(); - $child_rdr->close(); + my $ff = $password_wtr->fileno; + debug("password_wtr $ff"); + $password_wtr->print($self->{password}); + $password_wtr->close(); + $password_rdr->close(); } else { debug("No password"); } @@ -447,13 +463,13 @@ sub command_estimate { $self->validate_inexclude(); my $level = $self->{level}[0]; - my ($child_rdr, $parent_wtr); + my ($password_rdr, $password_wtr); if (defined $self->{password}) { # Don't set close-on-exec $^F=10; - pipe($child_rdr, $parent_wtr); + pipe($password_rdr, $password_wtr); $^F=2; - $parent_wtr->autoflush(1); + $password_wtr->autoflush(1); } my($wtr, $rdr, $err); $err = Symbol::gensym; @@ -461,10 +477,10 @@ sub command_estimate { if ($pid == 0) { #child if (defined $self->{password}) { - my $ff = $child_rdr->fileno; - debug("child_rdr $ff"); - $parent_wtr->close(); - $ENV{PASSWD_FD} = $child_rdr->fileno; + my $ff = $password_rdr->fileno; + debug("password_rdr $ff"); + $password_wtr->close(); + $ENV{PASSWD_FD} = $password_rdr->fileno; } close(0); close(1); @@ -491,12 +507,12 @@ sub command_estimate { } #parent if (defined $self->{password}) { - my $ff = $parent_wtr->fileno; - debug("parent_wtr $ff"); + my $ff = $password_wtr->fileno; + debug("password_wtr $ff"); debug("password $self->{password}"); - $parent_wtr->print($self->{password}); - $parent_wtr->close(); - $child_rdr->close(); + $password_wtr->print($self->{password}); + $password_wtr->close(); + $password_rdr->close(); } close($wtr); close($rdr); @@ -546,6 +562,22 @@ sub output_size { } } +sub send_empty_tar_file { + my $self = shift; + my ($out1, $out2) = @_; + my $out; + my $buf; + my $size; + + Amanda::Debug::debug("Create empty archive with: tar --create --file=- --files-from=/dev/null"); + open2($out, undef, "tar", "--create", "--file=-", "--files-from=/dev/null"); + + while(($size = sysread($out, $buf, 32768))) { + syswrite($out1, $buf, $size); + syswrite($out2, $buf, $size); + } +} + sub command_backup { my $self = shift; @@ -555,38 +587,25 @@ sub command_backup { $self->findpass(); $self->validate_inexclude(); - my $pid_tee = open3(\*INDEX_IN, '>&STDOUT', \*INDEX_TEE, "-"); - if ($pid_tee == 0) { - close(INDEX_IN); - close(INDEX_TEE); - my $buf; - my $size = -1; - while (($size = POSIX::read(0, $buf, 32768)) > 0) { - POSIX::write(1, $buf, $size); - POSIX::write(2, $buf, $size); - } - exit 0; - } - my ($child_rdr, $parent_wtr); + my ($password_rdr, $password_wtr); if (defined $self->{password}) { # Don't set close-on-exec $^F=10; - pipe($child_rdr, $parent_wtr); + pipe($password_rdr, $password_wtr); $^F=2; - $parent_wtr->autoflush(1); + $password_wtr->autoflush(1); } - my($wtr, $err); - $err = Symbol::gensym; - my $pid = open3($wtr, ">&INDEX_IN", $err, "-"); + my($smbclient_wtr, $smbclient_rdr, $smbclient_err); + $smbclient_err = Symbol::gensym; + my $pid = open3($smbclient_wtr, $smbclient_rdr, $smbclient_err, "-"); if ($pid == 0) { #child if (defined $self->{password}) { - my $ff = $child_rdr->fileno; - debug("child_rdr $ff"); - $parent_wtr->close(); - $ENV{PASSWD_FD} = $child_rdr->fileno; + my $ff = $password_rdr->fileno; + debug("password_rdr $ff"); + $password_wtr->close(); + $ENV{PASSWD_FD} = $password_rdr->fileno; } - close(0); my @ARGV = (); push @ARGV, $self->{smbclient}, $self->{share}; push @ARGV, "" if (!defined($self->{password})); @@ -627,53 +646,126 @@ sub command_backup { } if (defined $self->{password}) { - my $ff = $parent_wtr->fileno; - debug("parent_wtr $ff"); - debug("password $self->{password}"); - $parent_wtr->print($self->{password}); - $parent_wtr->close(); - $child_rdr->close(); + my $ff = $password_wtr->fileno; + debug("password_wtr $ff"); + $password_wtr->print($self->{password}); + $password_wtr->close(); + $password_rdr->close(); } else { debug("No password"); } - close($wtr); + close($smbclient_wtr); #index process - my $index; + my $index_rdr; + my $index_wtr; debug("$self->{gnutar} -tf -"); - my $pid_index1 = open2($index, '<&INDEX_TEE', $self->{gnutar}, "-tf", "-"); - close(INDEX_IN); + my $pid_index1 = open2($index_rdr, $index_wtr, $self->{gnutar}, "-tf", "-"); my $size = -1; - my $index_fd = $index->fileno; + my $index_fd = $index_rdr->fileno; debug("index $index_fd"); + my $indexout_fd; if (defined($self->{index})) { - my $indexout_fd; open($indexout_fd, '>&=4') || $self->print_to_server_and_die("Can't open indexout_fd: $!", $Amanda::Script_App::ERROR); - $self->parse_backup($index, $self->{mesgout}, $indexout_fd); - close($indexout_fd); } - else { - $self->parse_backup($index_fd, $self->{mesgout}, undef); - } - close($index); - while (<$err>) { - chomp; - debug("stderr: " . $_); - next if /^Domain=/; - next if /^tarmode is now /; - next if /dumped (\d+) files and directories/; + my $file_to_close = 3; + my $smbclient_stdout_src = Amanda::MainLoop::fd_source($smbclient_rdr, + $G_IO_IN|$G_IO_HUP|$G_IO_ERR); + my $smbclient_stderr_src = Amanda::MainLoop::fd_source($smbclient_err, + $G_IO_IN|$G_IO_HUP|$G_IO_ERR); + my $index_tar_stdout_src = Amanda::MainLoop::fd_source($index_rdr, + $G_IO_IN|$G_IO_HUP|$G_IO_ERR); + + my $smbclient_stdout_done = 0; + my $smbclient_stderr_done = 0; + my $data_size = 0; + my $nb_files = 0; + $smbclient_stdout_src->set_callback(sub { + my $buf; + my $blocksize = -1; + $blocksize = sysread($smbclient_rdr, $buf, 32768); + if (!$blocksize) { + $file_to_close--; + $smbclient_stdout_src->remove(); + $smbclient_stdout_done = 1; + if ($smbclient_stderr_done) { + if ($data_size == 0 and $nb_files == 0 and $size == 0) { + $self->send_empty_tar_file(*STDOUT, $index_wtr); + } + close($index_wtr); + close(STDOUT); + } + close($smbclient_rdr); + Amanda::MainLoop::quit() if $file_to_close == 0; + return; + } + $data_size += $blocksize; + syswrite(STDOUT, $buf, $blocksize); + syswrite($index_wtr, $buf, $blocksize); + }); + + $smbclient_stderr_src->set_callback(sub { + my $line = <$smbclient_err>; + if (!defined $line) { + $file_to_close--; + $smbclient_stderr_src->remove(); + $smbclient_stderr_done = 1; + if ($smbclient_stdout_done) { + if ($data_size == 0 and $nb_files == 0 and $size == 0) { + $self->send_empty_tar_file(*STDOUT, $index_wtr); + } + close($index_wtr); + close(STDOUT); + } + close ($smbclient_err); + Amanda::MainLoop::quit() if $file_to_close == 0; + return; + } + chomp $line; + debug("stderr: " . $line); + return if $line =~ /^Domain=/; + return if $line =~ /^tarmode is now /; + if ($line =~ /dumped (\d+) files and directories/) { + $nb_files = $1; + return; + } # message if samba server is configured with 'security = share' - next if /Server not using user level security and no password supplied./; - if (/^Total bytes written: (\d*)/) { + return if $line =~$line =~ /Server not using user level security and no password supplied./; + if ($line =~ /^Total bytes written: (\d*)/) { $size = $1; + return; + } + $self->print_to_server("smbclient: $line", $Amanda::Script_App::ERROR); + }); + + $index_tar_stdout_src->set_callback(sub { + my $line = <$index_rdr>; + if (!defined $line) { + $file_to_close--; + $index_tar_stdout_src->remove(); + close($index_rdr); + close($indexout_fd); + Amanda::MainLoop::quit() if $file_to_close == 0; + return; + } + if ($line =~ /^\.\//) { + if(defined($indexout_fd)) { + if(defined($self->{index})) { + $line =~ s/^\.//; + print $indexout_fd $line; + } + } } else { - $self->print_to_server("smbclient: $_", - $Amanda::Script_App::ERROR); + chomp $line; + $self->print_to_server($line, $Amanda::Script_App::ERROR); } - } + }); + + Amanda::MainLoop::run(); + if ($size >= 0) { my $ksize = $size / 1024; if ($ksize < 32) { @@ -746,6 +838,7 @@ sub command_restore { $self->validate_inexclude(); $self->findpass(); push @cmd, $self->{smbclient}, $self->{share}; + push @cmd, "-D", $self->{'subdir'} if defined $self->{'subdir'}; push @cmd, "" if (!defined $self->{password}); push @cmd, "-d", "0", "-U", $self->{username}; diff --git a/application-src/amstar.c b/application-src/amstar.c index 0959a16..c351d2c 100644 --- a/application-src/amstar.c +++ b/application-src/amstar.c @@ -758,7 +758,7 @@ amstar_backup( if (regexec(®ex_dir, line, 3, regmatch, 0) == 0) { if (argument->dle.create_index && regmatch[1].rm_so == 2) { - line[regmatch[1].rm_eo+1]='\0'; + line[regmatch[1].rm_eo]='\0'; fprintf(indexstream, "/%s\n", &line[regmatch[1].rm_so]); } continue; diff --git a/application-src/amsuntar.pl b/application-src/amsuntar.pl index bc2db31..96917d1 100755 --- a/application-src/amsuntar.pl +++ b/application-src/amsuntar.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/application-src/amzfs-sendrecv.pl b/application-src/amzfs-sendrecv.pl index 1bbbb9c..7e6b457 100644 --- a/application-src/amzfs-sendrecv.pl +++ b/application-src/amzfs-sendrecv.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -102,7 +102,8 @@ sub command_support { sub command_selfcheck { my $self = shift; - $self->print_to_server("disk " . quote_string($self->{disk})); + $self->print_to_server("disk " . quote_string($self->{disk}), + $Amanda::Script_App::GOOD); $self->print_to_server("amzfs-sendrecv version " . $Amanda::Constants::VERSION, $Amanda::Script_App::GOOD); diff --git a/application-src/amzfs-snapshot.pl b/application-src/amzfs-snapshot.pl index 676e60e..9deee6c 100644 --- a/application-src/amzfs-snapshot.pl +++ b/application-src/amzfs-snapshot.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/application-src/script-email.pl b/application-src/script-email.pl index 07694ac..14ed1ad 100644 --- a/application-src/script-email.pl +++ b/application-src/script-email.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/changer-src/Makefile.in b/changer-src/Makefile.in index f6e3b92..226ff6e 100644 --- a/changer-src/Makefile.in +++ b/changer-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda tape changer programs. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -40,7 +40,7 @@ # scripts in this directory. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -334,7 +334,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -875,6 +876,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/client-src/Makefile.in b/client-src/Makefile.in index 9bf098d..aff1a68 100644 --- a/client-src/Makefile.in +++ b/client-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda client programs. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -40,7 +40,7 @@ # scripts in this directory. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -345,7 +345,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -973,6 +974,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/client-src/amdump_client.pl b/client-src/amdump_client.pl index 560747c..f0fd0bb 100644 --- a/client-src/amdump_client.pl +++ b/client-src/amdump_client.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -101,7 +101,7 @@ if ($cmd eq 'list') { debug("send: DISK " . Amanda::Util::quote_string($diskname)); print {$amservice_in} "DISK " . Amanda::Util::quote_string($diskname) . "\n"; my $a = <$amservice_out>; - print if ($a != /^DISK /) + print if ($a !~ /^DISK /) } } } diff --git a/client-src/calcsize.c b/client-src/calcsize.c index 5c77ef5..9b23647 100644 --- a/client-src/calcsize.c +++ b/client-src/calcsize.c @@ -35,7 +35,7 @@ #include "match.h" #include "conffile.h" #include "fsusage.h" -#include "sl.h" +#include "am_sl.h" #include "util.h" #define ROUND(n,x) ((x) + (n) - 1 - (((x) + (n) - 1) % (n))) @@ -108,12 +108,12 @@ void add_file_name_unknown(int, char *); void add_file_unknown(int, struct stat *); off_t final_size_unknown(int, char *); -sl_t *calc_load_file(char *filename); +am_sl_t *calc_load_file(char *filename); int calc_check_exclude(char *filename); int use_star_excl = 0; int use_gtar_excl = 0; -sl_t *include_sl=NULL, *exclude_sl=NULL; +am_sl_t *include_sl=NULL, *exclude_sl=NULL; int main( @@ -682,13 +682,13 @@ final_size_unknown( /* * ========================================================================= */ -sl_t * +am_sl_t * calc_load_file( char * filename) { char pattern[1025]; - sl_t *sl_list; + am_sl_t *sl_list; FILE *file = fopen(filename, "r"); diff --git a/client-src/client_util.c b/client-src/client_util.c index 513d9ba..27694a6 100644 --- a/client-src/client_util.c +++ b/client-src/client_util.c @@ -1166,7 +1166,7 @@ run_client_script( levellist_t levellist; char number[NUM_STR_SIZE]; for (levellist=dle->levellist; levellist; levellist=levellist->next) { - level_t *alevel = (level_t *)levellist->data; + am_level_t *alevel = (am_level_t *)levellist->data; g_ptr_array_add(argv_ptr, stralloc("--level")); g_snprintf(number, SIZEOF(number), "%d", alevel->level); g_ptr_array_add(argv_ptr, stralloc(number)); diff --git a/client-src/client_util.h b/client-src/client_util.h index a2c7442..b714d8c 100644 --- a/client-src/client_util.h +++ b/client-src/client_util.h @@ -34,7 +34,7 @@ #include "amanda.h" #include "conffile.h" #include "amfeatures.h" -#include "sl.h" +#include "am_sl.h" #include "util.h" /* for bstrncmp() */ #include "amandad.h" /* for g_option_t */ #include "amxml.h" /* for dle_t */ diff --git a/client-src/selfcheck.c b/client-src/selfcheck.c index e044a6c..8cd7b53 100644 --- a/client-src/selfcheck.c +++ b/client-src/selfcheck.c @@ -95,7 +95,7 @@ main( dle_t *dle; int level; GSList *errlist; - level_t *alevel; + am_level_t *alevel; if (argc > 1 && argv && argv[1] && g_str_equal(argv[1], "--version")) { printf("selfcheck-%s\n", VERSION); @@ -260,7 +260,7 @@ main( if (ch == '\0' || sscanf(s - 1, "%d", &level) != 1) { goto err; /* bad level */ } - alevel = g_new0(level_t, 1); + alevel = g_new0(am_level_t, 1); alevel->level = level; dle->levellist = g_slist_append(dle->levellist, alevel); skip_integer(s, ch); diff --git a/client-src/sendbackup-dump.c b/client-src/sendbackup-dump.c index 036d380..14fd27e 100644 --- a/client-src/sendbackup-dump.c +++ b/client-src/sendbackup-dump.c @@ -143,7 +143,7 @@ start_backup( char *encryptopt = skip_argument; char *qdisk; char *config; - level_t *alevel = (level_t *)dle->levellist->data; + am_level_t *alevel = (am_level_t *)dle->levellist->data; int level = alevel->level; g_snprintf(level_str, SIZEOF(level_str), "%d", level); diff --git a/client-src/sendbackup-gnutar.c b/client-src/sendbackup-gnutar.c index 3b718ae..1aeb399 100644 --- a/client-src/sendbackup-gnutar.c +++ b/client-src/sendbackup-gnutar.c @@ -156,7 +156,7 @@ start_backup( ssize_t nb; char buf[32768]; char *amandates_file = NULL; - level_t *alevel = (level_t *)dle->levellist->data; + am_level_t *alevel = (am_level_t *)dle->levellist->data; int level = alevel->level; error_pn = stralloc2(get_pname(), "-smbclient"); diff --git a/client-src/sendbackup.c b/client-src/sendbackup.c index 506d45b..5b9b7e9 100644 --- a/client-src/sendbackup.c +++ b/client-src/sendbackup.c @@ -39,6 +39,7 @@ #include "getfsent.h" #include "conffile.h" #include "amandates.h" +#include "stream.h" #define sendbackup_debug(i, ...) do { \ if ((i) <= debug_sendbackup) { \ @@ -124,7 +125,7 @@ main( int ch; GSList *errlist; FILE *mesgstream; - level_t *alevel; + am_level_t *alevel; if (argc > 1 && argv && argv[1] && g_str_equal(argv[1], "--version")) { printf("sendbackup-%s\n", VERSION); @@ -304,7 +305,7 @@ main( goto err; /* bad level */ } skip_integer(s, ch); - alevel = g_new0(level_t, 1); + alevel = g_new0(am_level_t, 1); alevel->level = level; dle->levellist = g_slist_append(dle->levellist, alevel); @@ -384,7 +385,7 @@ main( goto err; } - alevel = (level_t *)dle->levellist->data; + alevel = (am_level_t *)dle->levellist->data; level = alevel->level; dbprintf(_(" Parsed request as: program `%s'\n"), dle->program); dbprintf(_(" disk `%s'\n"), qdisk); @@ -586,6 +587,49 @@ main( switch(application_api_pid=fork()) { case 0: + application_api_info_tapeheader(mesgfd, dle->program, dle); + + /* find directt-tcp address from indirect direct-tcp */ + if (dle->data_path == DATA_PATH_DIRECTTCP && + bsu->data_path_set & DATA_PATH_DIRECTTCP && + strncmp(dle->directtcp_list->data, "255.255.255.255:", 16) == 0) { + char *indirect_tcp; + char *str_port; + in_port_t port; + int fd; + char buffer[32770]; + int size; + char *s, *s1; + + indirect_tcp = g_strdup(dle->directtcp_list->data); + g_slist_free(dle->directtcp_list); + dle->directtcp_list = NULL; + str_port = strchr(indirect_tcp, ':'); + str_port++; + port = atoi(str_port); + fd = stream_client("localhost", port, 32768, 32768, NULL, 0); + if (fd <= 0) { + g_debug("Failed to connect to indirect-direct-tcp port: %s", + strerror(errno)); + exit(1); + } + size = full_read(fd, buffer, 32768); + if (size <= 0) { + g_debug("Failed to read from indirect-direct-tcp port: %s", + strerror(errno)); + exit(1); + } + buffer[size++] = ' '; + buffer[size] = '\0'; + s1 = buffer; + while ((s = strchr(s1, ' ')) != NULL) { + *s++ = '\0'; + dle->directtcp_list = g_slist_append(dle->directtcp_list, g_strdup(s1)); + s1 = s; + } + amfree(indirect_tcp); + } + argv_ptr = g_ptr_array_new(); cmd = vstralloc(APPLICATION_DIR, "/", dle->program, NULL); g_ptr_array_add(argv_ptr, stralloc(dle->program)); @@ -655,7 +699,6 @@ main( } fcntl(indexfd, F_SETFD, 0); } - application_api_info_tapeheader(mesgfd, dle->program, dle); if (indexfd != 0) { safe_fd(3, 2); } else { diff --git a/client-src/sendsize.c b/client-src/sendsize.c index 083ec65..a82637c 100644 --- a/client-src/sendsize.c +++ b/client-src/sendsize.c @@ -135,7 +135,7 @@ main( char *qamdevice = NULL; dle_t *dle; GSList *errlist; - level_t *alevel; + am_level_t *alevel; (void)argc; /* Quiet unused parameter warning */ (void)argv; /* Quiet unused parameter warning */ @@ -322,7 +322,7 @@ main( goto err; } skip_integer(s, ch); - alevel = g_new0(level_t, 1); + alevel = g_new0(am_level_t, 1); alevel->level = level; dle->levellist = g_slist_append(dle->levellist, alevel); @@ -637,7 +637,7 @@ dle_add_diskest( levellist = dle->levellist; while (levellist != NULL) { - level_t *alevel = (level_t *)levellist->data; + am_level_t *alevel = (am_level_t *)levellist->data; if (alevel->level < 0) alevel->level = 0; if (alevel->level >= DUMP_LEVELS) @@ -650,7 +650,7 @@ dle_add_diskest( /* already have disk info, just note the level request */ levellist = dle->levellist; while (levellist != NULL) { - level_t *alevel = (level_t *)levellist->data; + am_level_t *alevel = (am_level_t *)levellist->data; int level = alevel->level; curp->est[level].needestimate = 1; curp->est[level].server = alevel->server; @@ -677,7 +677,7 @@ dle_add_diskest( } levellist = dle->levellist; while (levellist != NULL) { - level_t *alevel = (level_t *)levellist->data; + am_level_t *alevel = (am_level_t *)levellist->data; newp->est[alevel->level].needestimate = 1; newp->est[alevel->level].server = alevel->server; levellist = g_slist_next(levellist); diff --git a/common-src/Makefile.am b/common-src/Makefile.am index d1686f1..40e2eb6 100644 --- a/common-src/Makefile.am +++ b/common-src/Makefile.am @@ -5,7 +5,7 @@ include $(top_srcdir)/config/automake/scripts.am include $(top_srcdir)/config/automake/installperms.am include $(top_srcdir)/config/automake/precompile.am -INCLUDES = -I$(top_srcdir)/gnulib +INCLUDES = -I$(top_srcdir)/gnulib AM_CFLAGS = $(AMANDA_WARNING_CFLAGS) AM_LDFLAGS = $(AMANDA_STATIC_LDFLAGS) $(AS_NEEDED_FLAGS) @@ -19,6 +19,7 @@ LINTFLAGS=$(AMLINTFLAGS) libamanda_la_SOURCES = \ alloc.c \ + am_sl.c \ amfeatures.c \ amflock.c \ ipc-binary.c \ @@ -40,7 +41,6 @@ libamanda_la_SOURCES = \ security.c \ security-util.c \ simpleprng.c \ - sl.c \ sockaddr-util.c \ stream.c \ tapelist.c \ @@ -123,7 +123,7 @@ noinst_HEADERS = \ security.h \ security-util.h \ simpleprng.h \ - sl.h \ + am_sl.h \ sockaddr-util.h \ stream.h \ tapelist.h \ diff --git a/common-src/Makefile.in b/common-src/Makefile.in index 4b10810..9d35e45 100644 --- a/common-src/Makefile.in +++ b/common-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda library. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -40,7 +40,7 @@ # scripts in this directory. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -358,7 +358,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -391,11 +392,11 @@ am__installdirs = "$(DESTDIR)$(amlibdir)" "$(DESTDIR)$(sbindir)" \ "$(DESTDIR)$(amlibexecdir)" LTLIBRARIES = $(amlib_LTLIBRARIES) $(noinst_LTLIBRARIES) libamanda_la_DEPENDENCIES = ../gnulib/libgnu.la -am__libamanda_la_SOURCES_DIST = alloc.c amfeatures.c amflock.c \ +am__libamanda_la_SOURCES_DIST = alloc.c am_sl.c amfeatures.c amflock.c \ ipc-binary.c amxml.c clock.c columnar.c conffile.c debug.c \ dgram.c event.c file.c fileheader.c glib-util.c match.c \ packet.c pipespawn.c protocol.c amsemaphore.c security.c \ - security-util.c simpleprng.c sl.c sockaddr-util.c stream.c \ + security-util.c simpleprng.c sockaddr-util.c stream.c \ tapelist.c timestamp.c util.c amflock-posix.c amflock-flock.c \ amflock-lockf.c amflock-lnlock.c rsh-security.c ssh-security.c \ bsd-security.c bsdtcp-security.c bsdudp-security.c \ @@ -410,16 +411,16 @@ am__libamanda_la_SOURCES_DIST = alloc.c amfeatures.c amflock.c \ @WANT_BSDTCP_SECURITY_TRUE@am__objects_8 = bsdtcp-security.lo @WANT_BSDUDP_SECURITY_TRUE@am__objects_9 = bsdudp-security.lo @WANT_KRB5_SECURITY_TRUE@am__objects_10 = krb5-security.lo -am_libamanda_la_OBJECTS = alloc.lo amfeatures.lo amflock.lo \ +am_libamanda_la_OBJECTS = alloc.lo am_sl.lo amfeatures.lo amflock.lo \ ipc-binary.lo amxml.lo clock.lo columnar.lo conffile.lo \ debug.lo dgram.lo event.lo file.lo fileheader.lo glib-util.lo \ match.lo packet.lo pipespawn.lo protocol.lo amsemaphore.lo \ - security.lo security-util.lo simpleprng.lo sl.lo \ - sockaddr-util.lo stream.lo tapelist.lo timestamp.lo util.lo \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) $(am__objects_5) $(am__objects_6) \ - $(am__objects_7) $(am__objects_8) $(am__objects_9) \ - $(am__objects_10) local-security.lo + security.lo security-util.lo simpleprng.lo sockaddr-util.lo \ + stream.lo tapelist.lo timestamp.lo util.lo $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) $(am__objects_4) \ + $(am__objects_5) $(am__objects_6) $(am__objects_7) \ + $(am__objects_8) $(am__objects_9) $(am__objects_10) \ + local-security.lo nodist_libamanda_la_OBJECTS = version.lo libamanda_la_OBJECTS = $(am_libamanda_la_OBJECTS) \ $(nodist_libamanda_la_OBJECTS) @@ -1015,6 +1016,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ @@ -1360,18 +1364,18 @@ do_installperms = dest=; chown=; chmod=; \ esac; \ done -INCLUDES = -I$(top_srcdir)/gnulib +INCLUDES = -I$(top_srcdir)/gnulib AM_CFLAGS = $(AMANDA_WARNING_CFLAGS) AM_LDFLAGS = $(AMANDA_STATIC_LDFLAGS) $(AS_NEEDED_FLAGS) amlib_LTLIBRARIES = libamanda.la LINT = $(AMLINT) LINTFLAGS = $(AMLINTFLAGS) -libamanda_la_SOURCES = alloc.c amfeatures.c amflock.c ipc-binary.c \ - amxml.c clock.c columnar.c conffile.c debug.c dgram.c event.c \ - file.c fileheader.c glib-util.c match.c packet.c pipespawn.c \ - protocol.c amsemaphore.c security.c security-util.c \ - simpleprng.c sl.c sockaddr-util.c stream.c tapelist.c \ - timestamp.c util.c $(am__append_2) $(am__append_3) \ +libamanda_la_SOURCES = alloc.c am_sl.c amfeatures.c amflock.c \ + ipc-binary.c amxml.c clock.c columnar.c conffile.c debug.c \ + dgram.c event.c file.c fileheader.c glib-util.c match.c \ + packet.c pipespawn.c protocol.c amsemaphore.c security.c \ + security-util.c simpleprng.c sockaddr-util.c stream.c \ + tapelist.c timestamp.c util.c $(am__append_2) $(am__append_3) \ $(am__append_4) $(am__append_5) $(am__append_6) \ $(am__append_7) $(am__append_8) $(am__append_9) \ $(am__append_10) $(am__append_11) local-security.c @@ -1411,7 +1415,7 @@ noinst_HEADERS = \ security.h \ security-util.h \ simpleprng.h \ - sl.h \ + am_sl.h \ sockaddr-util.h \ stream.h \ tapelist.h \ @@ -1760,6 +1764,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/am_sl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amfeatures.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amflock-flock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amflock-lnlock.Plo@am__quote@ @@ -1803,7 +1808,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleprng.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sockaddr-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh-security.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream.Plo@am__quote@ diff --git a/common-src/sl.c b/common-src/am_sl.c similarity index 92% rename from common-src/sl.c rename to common-src/am_sl.c index f84ebb3..e20c310 100644 --- a/common-src/sl.c +++ b/common-src/am_sl.c @@ -31,11 +31,11 @@ */ #include "amanda.h" -#include "sl.h" +#include "am_sl.h" void init_sl( - sl_t *sl) + am_sl_t *sl) { sl->first = NULL; sl->last = NULL; @@ -43,19 +43,19 @@ void init_sl( } -sl_t * +am_sl_t * new_sl(void) { - sl_t *sl; - sl = alloc(SIZEOF(sl_t)); + am_sl_t *sl; + sl = alloc(SIZEOF(am_sl_t)); init_sl(sl); return(sl); } -sl_t * +am_sl_t * insert_sl( - sl_t *sl, + am_sl_t *sl, char *name) { sle_t *a; @@ -77,9 +77,9 @@ insert_sl( } -sl_t * +am_sl_t * append_sl( - sl_t * sl, + am_sl_t * sl, char * name) { sle_t *a; @@ -101,9 +101,9 @@ append_sl( } -sl_t * +am_sl_t * insert_sort_sl( - sl_t * sl, + am_sl_t * sl, char * name) { sle_t *a, *b; @@ -136,7 +136,7 @@ insert_sort_sl( void free_sl( - sl_t * sl) + am_sl_t * sl) { sle_t *a, *b; @@ -155,7 +155,7 @@ free_sl( void remove_sl( - sl_t * sl, + am_sl_t * sl, sle_t * elem) { if(elem->prev) @@ -175,11 +175,11 @@ remove_sl( } -sl_t * +am_sl_t * duplicate_sl( - sl_t * sl) + am_sl_t * sl) { - sl_t *new_sl = NULL; + am_sl_t *new_sl = NULL; sle_t *a; if(!sl) return new_sl; @@ -196,7 +196,7 @@ duplicate_sl( */ int is_empty_sl( - sl_t * sl) + am_sl_t * sl) { if (sl == NULL) return 1; diff --git a/common-src/sl.h b/common-src/am_sl.h similarity index 84% rename from common-src/sl.h rename to common-src/am_sl.h index 7671d79..ecdd5e6 100644 --- a/common-src/sl.h +++ b/common-src/am_sl.h @@ -49,16 +49,16 @@ typedef struct sle_s { typedef struct sl_s { struct sle_s *first, *last; int nb_element; -} sl_t; +} am_sl_t; -void init_sl(sl_t *sl); -sl_t *new_sl(void); -sl_t *insert_sl(sl_t *sl, char *name); -sl_t *append_sl(sl_t *sl, char *name); -sl_t *insert_sort_sl(sl_t *sl, char *name); -void free_sl(sl_t *sl); -void remove_sl(sl_t *sl,sle_t *elem); -sl_t *duplicate_sl(sl_t *sl); -int is_empty_sl(sl_t *sl); +void init_sl(am_sl_t *sl); +am_sl_t *new_sl(void); +am_sl_t *insert_sl(am_sl_t *sl, char *name); +am_sl_t *append_sl(am_sl_t *sl, char *name); +am_sl_t *insert_sort_sl(am_sl_t *sl, char *name); +void free_sl(am_sl_t *sl); +void remove_sl(am_sl_t *sl,sle_t *elem); +am_sl_t *duplicate_sl(am_sl_t *sl); +int is_empty_sl(am_sl_t *sl); #endif diff --git a/common-src/amaespipe.sh b/common-src/amaespipe.sh index d9593cd..ac14eea 100755 --- a/common-src/amaespipe.sh +++ b/common-src/amaespipe.sh @@ -1,6 +1,6 @@ #! @SHELL@ # -# Copyright (c) 2007, 2008, 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/common-src/amcryptsimple.pl b/common-src/amcryptsimple.pl index e8d4922..dd8760f 100755 --- a/common-src/amcryptsimple.pl +++ b/common-src/amcryptsimple.pl @@ -1,6 +1,6 @@ #!@PERL@ -w # -# Copyright (c) 2007,2008 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -62,9 +62,22 @@ sub do_gpg_agent() { return "" } +sub which_gpg() { + my $path=`which gpg2 2>/dev/null`; + if (!$path) { + $path=`which gpg 2>/dev/null`; + } + if (!$path) { + die("no gpg or gpg2"); + } + chomp $path; + return $path; +} + sub encrypt() { my $gpg_agent_cmd = do_gpg_agent(); - system "$gpg_agent_cmd gpg --batch --no-secmem-warning --disable-mdc --symmetric --cipher-algo AES256 --passphrase-fd 3 3<$AM_PASS"; + my $gpg = which_gpg(); + system "$gpg_agent_cmd $gpg --batch --no-secmem-warning --disable-mdc --symmetric --cipher-algo AES256 --passphrase-fd 3 3<$AM_PASS"; if ($? == -1) { print STDERR "failed to execute gpg: $!\n"; exit (1); @@ -79,7 +92,8 @@ sub encrypt() { sub decrypt() { my $gpg_agent_cmd = do_gpg_agent(); - system "$gpg_agent_cmd gpg --batch --quiet --no-mdc-warning --decrypt --passphrase-fd 3 3<$AM_PASS"; + my $gpg = which_gpg(); + system "$gpg_agent_cmd $gpg --batch --quiet --no-mdc-warning --decrypt --passphrase-fd 3 3<$AM_PASS"; if ($? == -1) { print STDERR "failed to execute gpg: $!\n"; exit (1); diff --git a/common-src/amflock.c b/common-src/amflock.c index 858c288..20fad47 100644 --- a/common-src/amflock.c +++ b/common-src/amflock.c @@ -36,7 +36,14 @@ * New Implementation */ -static GStaticMutex lock_lock = G_STATIC_MUTEX_INIT; +#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31)) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" + static GStaticMutex lock_lock = G_STATIC_MUTEX_INIT; +# pragma GCC diagnostic pop +#else + static GStaticMutex lock_lock = G_STATIC_MUTEX_INIT; +#endif static GHashTable *locally_locked_files = NULL; static int lock_rw_rd(file_lock *lock, short l_type); diff --git a/common-src/amgetconf.pl b/common-src/amgetconf.pl index 23a9f1e..b35cf20 100644 --- a/common-src/amgetconf.pl +++ b/common-src/amgetconf.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -25,6 +25,7 @@ use Amanda::Debug qw( :logging ); use Amanda::Util qw( :constants ); use Amanda::Paths; use Amanda::Constants; +eval 'use Amanda::Disklist;'; # can fail if compiled for client only use Getopt::Long; # Implementation note: this application is a bit funny, because it does not @@ -350,6 +351,14 @@ if ($cfgerr_level >= $CFGERR_WARNINGS) { Amanda::Util::finish_setup($RUNNING_AS_ANY); +if ($execute_where != $CONFIG_INIT_CLIENT) { + my $diskfile = Amanda::Config::config_dir_relative(getconf($CNF_DISKFILE)); + $cfgerr_level = Amanda::Disklist::read_disklist('filename' => $diskfile); +# if ($cfgerr_level >= $CFGERR_ERRORS) { +# die "Errors processing disklist"; +# } +} + conf_param($parameter, $opt_list); Amanda::Util::finish_application(); diff --git a/common-src/amgpgcrypt.pl b/common-src/amgpgcrypt.pl index 2a0c2eb..50db13a 100755 --- a/common-src/amgpgcrypt.pl +++ b/common-src/amgpgcrypt.pl @@ -1,6 +1,6 @@ #!@PERL@ -w # -# Copyright (c) 2007,2008 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -46,13 +46,37 @@ $ENV{'PATH'} = '/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin:/opt/csw/bin'; $ENV{'GNUPGHOME'} = "$AMANDA_HOME/.gnupg"; +sub do_gpg_agent() { + my $path=`which gpg-agent 2>/dev/null`; + chomp $path; + if (-x $path) { + return "gpg-agent --daemon --"; + } + return "" +} + +sub which_gpg() { + my $path=`which gpg2 2>/dev/null`; + if (!$path) { + $path=`which gpg 2>/dev/null`; + } + if (!$path) { + die("no gpg or gpg2"); + } + chomp $path; + return $path; +} + sub encrypt() { -# system "gpg --armor --encrypt --recipient $AMANDA"; - system "gpg --batch --disable-mdc --encrypt --cipher-algo AES256 --recipient $AMANDA"; + my $gpg_agent_cmd = do_gpg_agent(); + my $gpg = which_gpg(); + system "$gpg_agent_cmd $gpg --batch --disable-mdc --encrypt --cipher-algo AES256 --recipient $AMANDA"; } sub decrypt() { - system "gpg --batch --quiet --no-mdc-warning --secret-keyring $AM_PRIV --decrypt --passphrase-fd 3 3<$AM_PASS"; + my $gpg_agent_cmd = do_gpg_agent(); + my $gpg = which_gpg(); + system "$gpg_agent_cmd $gpg --batch --quiet --no-mdc-warning --secret-keyring $AM_PRIV --decrypt --passphrase-fd 3 3<$AM_PASS"; } sub my_sig_catcher { diff --git a/common-src/amsemaphore-test.c b/common-src/amsemaphore-test.c index 5ca4a40..eb4c915 100644 --- a/common-src/amsemaphore-test.c +++ b/common-src/amsemaphore-test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/amsemaphore.c b/common-src/amsemaphore.c index 554e758..52cf869 100644 --- a/common-src/amsemaphore.c +++ b/common-src/amsemaphore.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/amsemaphore.h b/common-src/amsemaphore.h index cf0b974..9b7a3ac 100644 --- a/common-src/amsemaphore.h +++ b/common-src/amsemaphore.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/amxml.c b/common-src/amxml.c index 7aab3f6..6f1e7a6 100644 --- a/common-src/amxml.c +++ b/common-src/amxml.c @@ -60,7 +60,7 @@ typedef struct amgxml_s { property_t *property_data; proplist_t property; script_t *script; - level_t *alevel; + am_level_t *alevel; char *encoding; char *raw; } amgxml_t; @@ -315,7 +315,7 @@ amstart_element( if (strcmp(element_name, "exclude") == 0 || strcmp(element_name, "include") == 0) data_user->has_optional = 0; if (strcmp(element_name, "level") == 0) { - data_user->alevel = g_new0(level_t, 1); + data_user->alevel = g_new0(am_level_t, 1); } } else if (strcmp(element_name, "server") == 0) { if (strcmp(last_element_name, "level") != 0) { @@ -555,7 +555,7 @@ amtext( } last_element_name = last_element->data; - tt = malloc(text_len + 1); + tt = malloc(text_len + 8 + 1); strncpy(tt,text,text_len); tt[text_len] = '\0'; diff --git a/common-src/amxml.h b/common-src/amxml.h index a8d4045..063fb11 100644 --- a/common-src/amxml.h +++ b/common-src/amxml.h @@ -49,8 +49,8 @@ typedef GSList *scriptlist_t; typedef struct level_s { int level; int server; /* if server can do the estimate */ -} level_t; -typedef GSList *levellist_t; /* A list where each element is a (level_t *) */ +} am_level_t; +typedef GSList *levellist_t; /* A list where each element is a (am_level_t *) */ typedef struct a_dle_s { char *disk; @@ -73,10 +73,10 @@ typedef struct a_dle_s { int record; int create_index; char *auth; - sl_t *exclude_file; - sl_t *exclude_list; - sl_t *include_file; - sl_t *include_list; + am_sl_t *exclude_file; + am_sl_t *exclude_list; + am_sl_t *include_file; + am_sl_t *include_list; int exclude_optional; int include_optional; proplist_t property; diff --git a/common-src/conffile.c b/common-src/conffile.c index 7277e48..4d48220 100644 --- a/common-src/conffile.c +++ b/common-src/conffile.c @@ -91,7 +91,7 @@ typedef enum { CONF_DEVICE, CONF_ORDER, CONF_SINGLE_EXECUTION, CONF_DATA_PATH, CONF_AMANDA, CONF_DIRECTTCP, CONF_TAPER_PARALLEL_WRITE, CONF_INTERACTIVITY, CONF_TAPERSCAN, - CONF_MAX_DLE_BY_VOLUME, CONF_EJECT_VOLUME, + CONF_MAX_DLE_BY_VOLUME, CONF_EJECT_VOLUME, CONF_TMPDIR, /* execute on */ CONF_PRE_AMCHECK, CONF_POST_AMCHECK, @@ -128,6 +128,7 @@ typedef enum { CONF_CLNTCOMPPROG, CONF_SRV_ENCRYPT, CONF_CLNT_ENCRYPT, CONF_SRV_DECRYPT_OPT, CONF_CLNT_DECRYPT_OPT, CONF_AMANDAD_PATH, CONF_CLIENT_USERNAME, CONF_CLIENT_PORT, CONF_ALLOW_SPLIT, + CONF_MAX_WARNINGS, /* tape type */ /*COMMENT,*/ CONF_BLOCKSIZE, @@ -229,6 +230,7 @@ static FILE *current_file = NULL; static char *current_filename = NULL; static char *current_line = NULL; static char *current_char = NULL; +static char *current_block = NULL; static int current_line_num = 0; /* (technically, managed by the parser) */ /* A static buffer for storing tokens while they are being scanned. */ @@ -357,7 +359,7 @@ struct device_config_s { struct changer_config_s { struct changer_config_s *next; - int seen; + seen_t seen; char *name; val_t value[CHANGER_CONFIG_CHANGER_CONFIG]; @@ -521,7 +523,6 @@ static void read_str(conf_var_t *, val_t *); static void read_ident(conf_var_t *, val_t *); static void read_time(conf_var_t *, val_t *); static void read_size(conf_var_t *, val_t *); -static void read_size_byte(conf_var_t *, val_t *); static void read_bool(conf_var_t *, val_t *); static void read_no_yes_all(conf_var_t *, val_t *); static void read_compress(conf_var_t *, val_t *); @@ -566,11 +567,11 @@ static taperscan_t *read_taperscan(char *name, FILE *from, char *fname, * values can be written: integers can have units, boolean values can be * specified with a number of names, etc. They form utility functions * for the read_functions, below. */ +static gint64 get_multiplier(gint64 val, confunit_t unit); static time_t get_time(void); -static int get_int(void); -static ssize_t get_size(void); -static ssize_t get_size_byte(void); -static gint64 get_int64(void); +static int get_int(confunit_t unit); +static ssize_t get_size(confunit_t unit); +static gint64 get_int64(confunit_t unit); static int get_bool(void); static int get_no_yes_all(void); @@ -603,6 +604,8 @@ static void validate_reserved_port_range(conf_var_t *, val_t *); static void validate_unreserved_port_range(conf_var_t *, val_t *); static void validate_program(conf_var_t *, val_t *); static void validate_dump_limit(conf_var_t *, val_t *); +static void validate_tmpdir(conf_var_t *, val_t *); + gint compare_pp_script_order(gconstpointer a, gconstpointer b); /* @@ -691,14 +694,14 @@ static cfgerr_level_t apply_config_overrides(config_overrides_t *co, * These set the value's type and seen flags, as well as copying * the relevant value into the 'v' field. */ -static void conf_init_int(val_t *val, int i); -static void conf_init_int64(val_t *val, gint64 l); +static void conf_init_int(val_t *val, confunit_t unit, int i); +static void conf_init_int64(val_t *val, confunit_t unit, gint64 l); static void conf_init_real(val_t *val, float r); static void conf_init_str(val_t *val, char *s); static void conf_init_ident(val_t *val, char *s); static void conf_init_identlist(val_t *val, char *s); static void conf_init_time(val_t *val, time_t t); -static void conf_init_size(val_t *val, ssize_t sz); +static void conf_init_size(val_t *val, confunit_t unit, ssize_t sz); static void conf_init_bool(val_t *val, int i); static void conf_init_no_yes_all(val_t *val, int i); static void conf_init_compress(val_t *val, comp_t i); @@ -756,7 +759,7 @@ void free_property_t(gpointer p); /* Utility functions/structs for val_t_display_strs */ static char *exinclude_display_str(val_t *val, int file); static void proplist_display_str_foreach_fn(gpointer key_p, gpointer value_p, gpointer user_data_p); -static void val_t_print_token(FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val); +static void val_t_print_token(gboolean print_default, gboolean print_source, FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val); /* Given a key name as used in config overwrites, return a pointer to the corresponding * conf_var_t in the current parsetable, and the val_t representing that value. This @@ -1002,6 +1005,7 @@ keytab_t server_keytab[] = { { "MAXDUMPS", CONF_MAXDUMPS }, { "MAXDUMPSIZE", CONF_MAXDUMPSIZE }, { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY }, + { "MAX_WARNINGS", CONF_MAX_WARNINGS }, { "MEMORY", CONF_MEMORY }, { "MEDIUM", CONF_MEDIUM }, { "META_AUTOLABEL", CONF_META_AUTOLABEL }, @@ -1090,6 +1094,7 @@ keytab_t server_keytab[] = { { "TAPERFLUSH", CONF_TAPERFLUSH }, { "TAPETYPE", CONF_TAPETYPE }, { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE }, + { "TMPDIR", CONF_TMPDIR }, { "TPCHANGER", CONF_TPCHANGER }, { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT }, { "USE", CONF_USE }, @@ -1264,7 +1269,7 @@ conf_var_t server_var [] = { { CONF_ETIMEOUT , CONFTYPE_INT , read_int , CNF_ETIMEOUT , validate_non_zero }, { CONF_DTIMEOUT , CONFTYPE_INT , read_int , CNF_DTIMEOUT , validate_positive }, { CONF_CTIMEOUT , CONFTYPE_INT , read_int , CNF_CTIMEOUT , validate_positive }, - { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size_byte , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive }, + { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive }, { CONF_COLUMNSPEC , CONFTYPE_STR , read_str , CNF_COLUMNSPEC , NULL }, { CONF_TAPERALGO , CONFTYPE_TAPERALGO, read_taperalgo , CNF_TAPERALGO , NULL }, { CONF_TAPER_PARALLEL_WRITE , CONFTYPE_INT , read_int , CNF_TAPER_PARALLEL_WRITE , NULL }, @@ -1282,6 +1287,7 @@ conf_var_t server_var [] = { { CONF_AUTOLABEL , CONFTYPE_AUTOLABEL, read_autolabel , CNF_AUTOLABEL , NULL }, { CONF_META_AUTOLABEL , CONFTYPE_STR , read_str , CNF_META_AUTOLABEL , NULL }, { CONF_EJECT_VOLUME , CONFTYPE_BOOLEAN , read_bool , CNF_EJECT_VOLUME , NULL }, + { CONF_TMPDIR , CONFTYPE_STR , read_str , CNF_TMPDIR , validate_tmpdir }, { CONF_USETIMESTAMPS , CONFTYPE_BOOLEAN , read_bool , CNF_USETIMESTAMPS , NULL }, { CONF_AMRECOVER_DO_FSF , CONFTYPE_BOOLEAN , read_bool , CNF_AMRECOVER_DO_FSF , NULL }, { CONF_AMRECOVER_CHANGER , CONFTYPE_STR , read_str , CNF_AMRECOVER_CHANGER , NULL }, @@ -1376,6 +1382,7 @@ conf_var_t dumptype_var [] = { { CONF_SCRIPT , CONFTYPE_STR , read_dpp_script, DUMPTYPE_SCRIPTLIST , NULL }, { CONF_DATA_PATH , CONFTYPE_DATA_PATH, read_data_path, DUMPTYPE_DATA_PATH , NULL }, { CONF_ALLOW_SPLIT , CONFTYPE_BOOLEAN , read_bool , DUMPTYPE_ALLOW_SPLIT , NULL }, + { CONF_MAX_WARNINGS , CONFTYPE_INT , read_int , DUMPTYPE_MAX_WARNINGS , validate_nonnegative }, { CONF_RECOVERY_LIMIT , CONFTYPE_HOST_LIMIT, read_host_limit, DUMPTYPE_RECOVERY_LIMIT , NULL }, { CONF_DUMP_LIMIT , CONFTYPE_HOST_LIMIT, read_host_limit, DUMPTYPE_DUMP_LIMIT , validate_dump_limit }, { CONF_UNKNOWN , CONFTYPE_INT , NULL , DUMPTYPE_DUMPTYPE , NULL } @@ -1903,6 +1910,7 @@ read_confline( else if(tok == CONF_INTERACTIVITY) get_interactivity(); else if(tok == CONF_TAPERSCAN) get_taperscan(); else conf_parserror(_("DUMPTYPE, INTERFACE, TAPETYPE, HOLDINGDISK, APPLICATION, SCRIPT, DEVICE, CHANGER, INTERACTIVITY or TAPERSCAN expected")); + current_block = NULL; } break; @@ -1912,6 +1920,20 @@ read_confline( case CONF_END: /* end of file */ return 0; + /* These should never be at the begining of a line */ + case CONF_LBRACE: + case CONF_RBRACE: + case CONF_IDENT: + case CONF_INT: + case CONF_INT64: + case CONF_BOOL: + case CONF_REAL: + case CONF_STRING: + case CONF_TIME: + case CONF_SIZE: + conf_parserror("error: not a keyword."); + break; + /* if it's not a known punctuation mark, then check the parse table and use the * read_function we find there. */ default: @@ -2175,6 +2197,8 @@ get_holdingdisk( get_conftoken(CONF_IDENT); hdcur.name = stralloc(tokenval.v.s); + current_block = g_strconcat("holdingdisk ", hdcur.name, NULL); + hdcur.seen.block = current_block; hdcur.seen.filename = current_filename; hdcur.seen.linenum = current_line_num; @@ -2239,9 +2263,9 @@ init_holdingdisk_defaults( { conf_init_str(&hdcur.value[HOLDING_COMMENT] , ""); conf_init_str(&hdcur.value[HOLDING_DISKDIR] , ""); - conf_init_int64(&hdcur.value[HOLDING_DISKSIZE] , (gint64)0); + conf_init_int64(&hdcur.value[HOLDING_DISKSIZE] , CONF_UNIT_K, (gint64)0); /* 1 Gb = 1M counted in 1Kb blocks */ - conf_init_int64(&hdcur.value[HOLDING_CHUNKSIZE], (gint64)1024*1024); + conf_init_int64(&hdcur.value[HOLDING_CHUNKSIZE], CONF_UNIT_K, (gint64)1024*1024); } static void @@ -2315,6 +2339,8 @@ read_dumptype( get_conftoken(CONF_IDENT); dpcur.name = stralloc(tokenval.v.s); } + current_block = g_strconcat("dumptype ", dpcur.name, NULL); + dpcur.seen.block = current_block; dpcur.seen.filename = current_filename; dpcur.seen.linenum = current_line_num; @@ -2369,12 +2395,12 @@ init_dumptype_defaults(void) conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]); conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]); conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY] , 1); - conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , conf_data[CNF_DUMPCYCLE].v.i); - conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , conf_data[CNF_MAXDUMPS].v.i); - conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , 10000); - conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , conf_data[CNF_BUMPPERCENT].v.i); - conf_init_int64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , conf_data[CNF_BUMPSIZE].v.int64); - conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , conf_data[CNF_BUMPDAYS].v.i); + conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , CONF_UNIT_NONE, conf_data[CNF_DUMPCYCLE].v.i); + conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , CONF_UNIT_NONE, conf_data[CNF_MAXDUMPS].v.i); + conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , CONF_UNIT_NONE, 10000); + conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , CONF_UNIT_NONE, conf_data[CNF_BUMPPERCENT].v.i); + conf_init_int64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , CONF_UNIT_K , conf_data[CNF_BUMPSIZE].v.int64); + conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , CONF_UNIT_NONE, conf_data[CNF_BUMPDAYS].v.i); conf_init_real (&dpcur.value[DUMPTYPE_BUMPMULT] , conf_data[CNF_BUMPMULT].v.r); conf_init_time (&dpcur.value[DUMPTYPE_STARTTIME] , (time_t)0); conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY] , DS_STANDARD); @@ -2385,8 +2411,8 @@ init_dumptype_defaults(void) conf_init_str (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT] , "-d"); conf_init_str (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT] , "-d"); conf_init_rate (&dpcur.value[DUMPTYPE_COMPRATE] , 0.50, 0.50); - conf_init_int64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , (gint64)0); - conf_init_int64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (gint64)10 * 1024); + conf_init_int64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , CONF_UNIT_K, (gint64)0); + conf_init_int64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], CONF_UNIT_K, (gint64)10 * 1024); conf_init_str (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER] , NULL); conf_init_bool (&dpcur.value[DUMPTYPE_RECORD] , 1); conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_INCR] , 0); @@ -2399,6 +2425,7 @@ init_dumptype_defaults(void) conf_init_identlist(&dpcur.value[DUMPTYPE_SCRIPTLIST], NULL); conf_init_proplist(&dpcur.value[DUMPTYPE_PROPERTY]); conf_init_bool (&dpcur.value[DUMPTYPE_ALLOW_SPLIT] , 1); + conf_init_int (&dpcur.value[DUMPTYPE_MAX_WARNINGS] , CONF_UNIT_NONE, 20); conf_init_host_limit(&dpcur.value[DUMPTYPE_RECOVERY_LIMIT]); conf_init_host_limit_server(&dpcur.value[DUMPTYPE_DUMP_LIMIT]); } @@ -2471,6 +2498,8 @@ get_tapetype(void) get_conftoken(CONF_IDENT); tpcur.name = stralloc(tokenval.v.s); + current_block = g_strconcat("tapetype ", tpcur.name, NULL); + tpcur.seen.block = current_block; tpcur.seen.filename = current_filename; tpcur.seen.linenum = current_line_num; @@ -2481,7 +2510,7 @@ get_tapetype(void) if (tapetype_get_readblocksize(&tpcur) < tapetype_get_blocksize(&tpcur)) { - conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE], + conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE], CONF_UNIT_K, tapetype_get_blocksize(&tpcur)); } save_tapetype(); @@ -2494,15 +2523,15 @@ init_tapetype_defaults(void) { conf_init_str(&tpcur.value[TAPETYPE_COMMENT] , ""); conf_init_str(&tpcur.value[TAPETYPE_LBL_TEMPL] , ""); - conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE] , DISK_BLOCK_KB); - conf_init_size (&tpcur.value[TAPETYPE_READBLOCKSIZE], DISK_BLOCK_KB); - conf_init_int64 (&tpcur.value[TAPETYPE_LENGTH] , ((gint64)2000)); - conf_init_int64 (&tpcur.value[TAPETYPE_FILEMARK] , (gint64)1); - conf_init_int (&tpcur.value[TAPETYPE_SPEED] , 200); - conf_init_int64(&tpcur.value[TAPETYPE_PART_SIZE], 0); + conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE] , CONF_UNIT_K, DISK_BLOCK_KB); + conf_init_size (&tpcur.value[TAPETYPE_READBLOCKSIZE], CONF_UNIT_K, DISK_BLOCK_KB); + conf_init_int64 (&tpcur.value[TAPETYPE_LENGTH] , CONF_UNIT_K, ((gint64)2000)); + conf_init_int64 (&tpcur.value[TAPETYPE_FILEMARK] , CONF_UNIT_K, (gint64)1); + conf_init_int (&tpcur.value[TAPETYPE_SPEED] , CONF_UNIT_NONE, 200); + conf_init_int64(&tpcur.value[TAPETYPE_PART_SIZE], CONF_UNIT_K, 0); conf_init_part_cache_type(&tpcur.value[TAPETYPE_PART_CACHE_TYPE], PART_CACHE_TYPE_NONE); conf_init_str(&tpcur.value[TAPETYPE_PART_CACHE_DIR], ""); - conf_init_int64(&tpcur.value[TAPETYPE_PART_CACHE_MAX_SIZE], 0); + conf_init_int64(&tpcur.value[TAPETYPE_PART_CACHE_MAX_SIZE], CONF_UNIT_K, 0); } static void @@ -2566,6 +2595,8 @@ get_interface(void) get_conftoken(CONF_IDENT); ifcur.name = stralloc(tokenval.v.s); + current_block = g_strconcat("interface ", ifcur.name, NULL); + ifcur.seen.block = current_block; ifcur.seen.filename = current_filename; ifcur.seen.linenum = current_line_num; @@ -2585,7 +2616,7 @@ static void init_interface_defaults(void) { conf_init_str(&ifcur.value[INTER_COMMENT] , ""); - conf_init_int (&ifcur.value[INTER_MAXUSAGE], 80000); + conf_init_int (&ifcur.value[INTER_MAXUSAGE], CONF_UNIT_K, 80000); } static void @@ -2670,6 +2701,8 @@ read_application( get_conftoken(CONF_IDENT); apcur.name = stralloc(tokenval.v.s); } + current_block = g_strconcat("application ", apcur.name, NULL); + apcur.seen.block = current_block; apcur.seen.filename = current_filename; apcur.seen.linenum = current_line_num; @@ -2797,6 +2830,8 @@ read_interactivity( get_conftoken(CONF_IDENT); ivcur.name = stralloc(tokenval.v.s); } + current_block = g_strconcat("interactivity ", ivcur.name, NULL); + ivcur.seen.block = current_block; ivcur.seen.filename = current_filename; ivcur.seen.linenum = current_line_num; @@ -2923,6 +2958,8 @@ read_taperscan( get_conftoken(CONF_IDENT); tscur.name = stralloc(tokenval.v.s); } + current_block = g_strconcat("taperscan ", tscur.name, NULL); + tscur.seen.block = current_block; tscur.seen.filename = current_filename; tscur.seen.linenum = current_line_num; @@ -3049,6 +3086,8 @@ read_pp_script( get_conftoken(CONF_IDENT); pscur.name = stralloc(tokenval.v.s); } + current_block = g_strconcat("script ", pscur.name, NULL); + pscur.seen.block = current_block; pscur.seen.filename = current_filename; pscur.seen.linenum = current_line_num; @@ -3092,7 +3131,7 @@ init_pp_script_defaults( conf_init_proplist(&pscur.value[PP_SCRIPT_PROPERTY]); conf_init_execute_on(&pscur.value[PP_SCRIPT_EXECUTE_ON], 0); conf_init_execute_where(&pscur.value[PP_SCRIPT_EXECUTE_WHERE], ES_CLIENT); - conf_init_int(&pscur.value[PP_SCRIPT_ORDER], 5000); + conf_init_int(&pscur.value[PP_SCRIPT_ORDER], CONF_UNIT_NONE, 5000); conf_init_bool(&pscur.value[PP_SCRIPT_SINGLE_EXECUTION], 0); conf_init_str(&pscur.value[PP_SCRIPT_CLIENT_NAME], ""); } @@ -3180,6 +3219,8 @@ read_device_config( get_conftoken(CONF_IDENT); dccur.name = stralloc(tokenval.v.s); } + current_block = g_strconcat("device ", dccur.name, NULL); + dccur.seen.block = current_block; dccur.seen.filename = current_filename; dccur.seen.linenum = current_line_num; @@ -3306,7 +3347,10 @@ read_changer_config( get_conftoken(CONF_IDENT); cccur.name = stralloc(tokenval.v.s); } - cccur.seen = current_line_num; + current_block = g_strconcat("changer ", cccur.name, NULL); + cccur.seen.block = current_block; + cccur.seen.filename = current_filename; + cccur.seen.linenum = current_line_num; read_block(changer_config_var, cccur.value, _("changer parameter expected"), @@ -3361,8 +3405,8 @@ save_changer_config( dc = lookup_changer_config(cccur.name); if(dc != (changer_config_t *)0) { - conf_parserror(_("changer %s already defined on line %d"), - dc->name, dc->seen); + conf_parserror(_("changer %s already defined at %s:%d"), + dc->name, dc->seen.filename, dc->seen.linenum); return; } @@ -3409,7 +3453,7 @@ read_int( val_t *val) { ckseen(&val->seen); - val_t__int(val) = get_int(); + val_t__int(val) = get_int(val->unit); } static void @@ -3418,7 +3462,7 @@ read_int64( val_t *val) { ckseen(&val->seen); - val_t__int64(val) = get_int64(); + val_t__int64(val) = get_int64(val->unit); } static void @@ -3466,16 +3510,7 @@ read_size( val_t *val) { ckseen(&val->seen); - val_t__size(val) = get_size(); -} - -static void -read_size_byte( - conf_var_t *np G_GNUC_UNUSED, - val_t *val) -{ - ckseen(&val->seen); - val_t__size(val) = get_size_byte(); + val_t__size(val) = get_size(val->unit); } static void @@ -3808,7 +3843,7 @@ read_exinclude( val_t *val) { int file, got_one = 0; - sl_t *exclude; + am_sl_t *exclude; int optional = 0; get_conftoken(CONF_ANY); @@ -3888,6 +3923,7 @@ read_property( val_t *val) { char *key; + gboolean set_seen = TRUE; property_t *property = malloc(sizeof(property_t)); property_t *old_property; property->append = 0; @@ -3921,8 +3957,7 @@ read_property( } if(val->seen.linenum == 0) { - val->seen.filename = current_filename; - val->seen.linenum = current_line_num; + ckseen(&val->seen); // first property } old_property = g_hash_table_lookup(val->v.proplist, key); @@ -3934,6 +3969,7 @@ read_property( property->priority = 1; property->values = old_property->values; old_property->values = NULL; + set_seen = FALSE; } } while(tok == CONF_STRING) { @@ -3943,6 +3979,12 @@ read_property( } unget_conftoken(); g_hash_table_insert(val->v.proplist, key, property); + if (set_seen) { + property->seen.linenum = 0; + property->seen.filename = NULL; + property->seen.block = NULL; + ckseen(&property->seen); + } } @@ -4324,7 +4366,8 @@ get_time(void) } static int -get_int(void) +get_int( + confunit_t unit) { int val; keytab_t *save_kt; @@ -4369,153 +4412,15 @@ get_int(void) } /* get multiplier, if any */ - get_conftoken(CONF_ANY); - switch(tok) { - case CONF_NL: /* multiply by one */ - case CONF_END: - case CONF_MULT1: - case CONF_MULT1K: - break; - - case CONF_MULT7: - if (val > (INT_MAX / 7)) - conf_parserror(_("value too large")); - if (val < (INT_MIN / 7)) - conf_parserror(_("value too small")); - val *= 7; - break; - - case CONF_MULT1M: - if (val > (INT_MAX / 1024)) - conf_parserror(_("value too large")); - if (val < (INT_MIN / 1024)) - conf_parserror(_("value too small")); - val *= 1024; - break; - - case CONF_MULT1G: - if (val > (INT_MAX / (1024 * 1024))) - conf_parserror(_("value too large")); - if (val < (INT_MIN / (1024 * 1024))) - conf_parserror(_("value too small")); - val *= 1024 * 1024; - break; - - case CONF_MULT1T: - if (val > (INT_MAX / (1024 * 1024 * 1024))) - conf_parserror(_("value too large")); - if (val < (INT_MIN / (1024 * 1024 * 1024))) - conf_parserror(_("value too small")); - val *= 1024 * 1024 * 1024; - break; - - default: /* it was not a multiplier */ - unget_conftoken(); - break; - } - - keytable = save_kt; - return val; -} - -static ssize_t -get_size(void) -{ - ssize_t val; - keytab_t *save_kt; - - save_kt = keytable; - keytable = numb_keytable; - - get_conftoken(CONF_ANY); - - switch(tok) { - case CONF_SIZE: - val = tokenval.v.size; - break; - - case CONF_INT: -#if SIZEOF_SIZE_T < SIZEOF_INT - if ((gint64)tokenval.v.i > (gint64)SSIZE_MAX) - conf_parserror(_("value too large")); - if ((gint64)tokenval.v.i < (gint64)SSIZE_MIN) - conf_parserror(_("value too small")); -#endif - val = (ssize_t)tokenval.v.i; - break; - - case CONF_INT64: -#if SIZEOF_SIZE_T < SIZEOF_GINT64 - if (tokenval.v.int64 > (gint64)SSIZE_MAX) - conf_parserror(_("value too large")); - if (tokenval.v.int64 < (gint64)SSIZE_MIN) - conf_parserror(_("value too small")); -#endif - val = (ssize_t)tokenval.v.int64; - break; - - case CONF_AMINFINITY: - val = (ssize_t)SSIZE_MAX; - break; - - default: - conf_parserror(_("an integer is expected")); - val = 0; - break; - } - - /* get multiplier, if any */ - get_conftoken(CONF_ANY); - - switch(tok) { - case CONF_NL: /* multiply by one */ - case CONF_MULT1: - case CONF_MULT1K: - break; - - case CONF_MULT7: - if (val > (ssize_t)(SSIZE_MAX / 7)) - conf_parserror(_("value too large")); - if (val < (ssize_t)(SSIZE_MIN / 7)) - conf_parserror(_("value too small")); - val *= (ssize_t)7; - break; - - case CONF_MULT1M: - if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024)) - conf_parserror(_("value too large")); - if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024)) - conf_parserror(_("value too small")); - val *= (ssize_t)1024; - break; - - case CONF_MULT1G: - if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024))) - conf_parserror(_("value too large")); - if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024))) - conf_parserror(_("value too small")); - val *= (ssize_t)(1024 * 1024); - break; - - case CONF_MULT1T: - if (val > (INT_MAX / (1024 * 1024 * 1024))) - conf_parserror(_("value too large")); - if (val < (INT_MIN / (1024 * 1024 * 1024))) - conf_parserror(_("value too small")); - val *= 1024 * 1024 * 1024; - break; - - default: /* it was not a multiplier */ - unget_conftoken(); - break; - } + val = get_multiplier(val, unit); keytable = save_kt; return val; } static ssize_t -get_size_byte(void) +get_size( + confunit_t unit) { ssize_t val; keytab_t *save_kt; @@ -4561,58 +4466,15 @@ get_size_byte(void) } /* get multiplier, if any */ - get_conftoken(CONF_ANY); - - switch(tok) { - case CONF_NL: /* multiply by one */ - case CONF_MULT1: - break; - case CONF_MULT1K: - if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024)) - conf_parserror(_("value too large")); - if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024)) - conf_parserror(_("value too small")); - val *= (ssize_t)1024; - - case CONF_MULT7: - if (val > (ssize_t)(SSIZE_MAX / 7)) - conf_parserror(_("value too large")); - if (val < (ssize_t)(SSIZE_MIN / 7)) - conf_parserror(_("value too small")); - val *= (ssize_t)7; - break; - - case CONF_MULT1M: - if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024 * 1024)) - conf_parserror(_("value too large")); - if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024 * 1024)) - conf_parserror(_("value too small")); - val *= (ssize_t)(1024 * 1024); - break; - - case CONF_MULT1G: - if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024 * 1024))) - conf_parserror(_("value too large")); - if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024 * 1024))) - conf_parserror(_("value too small")); - val *= (ssize_t)(1024 * 1024 * 1024); - break; - - case CONF_MULT1T: - conf_parserror(_("value too large")); - break; - - default: /* it was not a multiplier */ - unget_conftoken(); - break; - } + val = get_multiplier(val, unit); keytable = save_kt; return val; } static gint64 -get_int64(void) +get_int64( + confunit_t unit) { gint64 val; keytab_t *save_kt; @@ -4646,45 +4508,54 @@ get_int64(void) } /* get multiplier, if any */ - get_conftoken(CONF_ANY); + val = get_multiplier(val, unit); - switch(tok) { - case CONF_NL: /* multiply by one */ - case CONF_MULT1: - case CONF_MULT1K: - break; + keytable = save_kt; + + return val; +} - case CONF_MULT7: +gint64 +get_multiplier( + gint64 val, + confunit_t unit) +{ + /* get multiplier, if any */ + get_conftoken(CONF_ANY); + + if (tok == CONF_MULT1 && unit == CONF_UNIT_K) { + val /= 1024; + } else if (tok == CONF_NL || tok == CONF_MULT1 || + (tok == CONF_MULT1K && unit == CONF_UNIT_K)) { + val *= 1; /* multiply by one */ + } else if (tok == CONF_MULT7) { if (val > G_MAXINT64/7 || val < ((gint64)G_MININT64)/7) conf_parserror(_("value too large")); val *= 7; - break; - - case CONF_MULT1M: + } else if (tok == CONF_MULT1K || + (tok == CONF_MULT1M && unit == CONF_UNIT_K)) { if (val > G_MAXINT64/1024 || val < ((gint64)G_MININT64)/1024) conf_parserror(_("value too large")); val *= 1024; - break; - - case CONF_MULT1G: + } else if (tok == CONF_MULT1M || + (tok == CONF_MULT1G && unit == CONF_UNIT_K)) { if (val > G_MAXINT64/(1024*1024) || val < ((gint64)G_MININT64)/(1024*1024)) conf_parserror(_("value too large")); val *= 1024*1024; - break; - - case CONF_MULT1T: + } else if (tok == CONF_MULT1G || + (tok == CONF_MULT1T && unit == CONF_UNIT_K)) { if (val > G_MAXINT64/(1024*1024*1024) || val < ((gint64)G_MININT64)/(1024*1024*1024)) conf_parserror(_("value too large")); val *= 1024*1024*1024; - break; - - default: /* it was not a multiplier */ + } else if (tok == CONF_MULT1T) { + if (val > G_MAXINT64/(1024*1024*1024*1024LL) || val < ((gint64)G_MININT64)/(1024*1024*1024*1024LL)) + conf_parserror(_("value too large")); + val *= 1024*1024*1024*1024LL; + } else { + val *= 1; unget_conftoken(); - break; } - keytable = save_kt; - return val; } @@ -4805,6 +4676,7 @@ ckseen( conf_parserror(_("duplicate parameter; previous definition %s:%d"), seen->filename, seen->linenum); } + seen->block = current_block; seen->filename = current_filename; seen->linenum = current_line_num; } @@ -5047,6 +4919,31 @@ validate_unreserved_port_range( validate_port_range(val, IPPORT_RESERVED, 65535); } +/* + * Validate tmpdir, the directory must exist and be writable by the user. + */ + +static void validate_tmpdir(conf_var_t *var G_GNUC_UNUSED, val_t *value) +{ + struct stat stat_buf; + gchar *tmpdir = val_t_to_str(value); + + if (stat(tmpdir, &stat_buf)) { + conf_parserror(_("invalid TMPDIR: directory '%s': %s."), + tmpdir, strerror(errno)); + } else if (!S_ISDIR(stat_buf.st_mode)) { + conf_parserror(_("invalid TMPDIR: '%s' is not a directory."), + tmpdir); + } else { + gchar *dir = g_strconcat(tmpdir, "/.", NULL); + if (access(dir, R_OK|W_OK) == -1) { + conf_parserror(_("invalid TMPDIR: '%s': can not read/write: %s."), + tmpdir, strerror(errno)); + } + g_free(dir); + } +} + /* * Initialization Implementation */ @@ -5335,65 +5232,66 @@ init_defaults( conf_init_str (&conf_data[CNF_INDEXDIR] , "/usr/adm/amanda/index"); conf_init_ident (&conf_data[CNF_TAPETYPE] , "DEFAULT_TAPE"); conf_init_identlist(&conf_data[CNF_HOLDINGDISK] , NULL); - conf_init_int (&conf_data[CNF_DUMPCYCLE] , 10); - conf_init_int (&conf_data[CNF_RUNSPERCYCLE] , 0); - conf_init_int (&conf_data[CNF_TAPECYCLE] , 15); - conf_init_int (&conf_data[CNF_NETUSAGE] , 80000); - conf_init_int (&conf_data[CNF_INPARALLEL] , 10); + conf_init_int (&conf_data[CNF_DUMPCYCLE] , CONF_UNIT_NONE, 10); + conf_init_int (&conf_data[CNF_RUNSPERCYCLE] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_TAPECYCLE] , CONF_UNIT_NONE, 15); + conf_init_int (&conf_data[CNF_NETUSAGE] , CONF_UNIT_K , 80000); + conf_init_int (&conf_data[CNF_INPARALLEL] , CONF_UNIT_NONE, 10); conf_init_str (&conf_data[CNF_DUMPORDER] , "ttt"); - conf_init_int (&conf_data[CNF_BUMPPERCENT] , 0); - conf_init_int64 (&conf_data[CNF_BUMPSIZE] , (gint64)10*1024); + conf_init_int (&conf_data[CNF_BUMPPERCENT] , CONF_UNIT_NONE, 0); + conf_init_int64 (&conf_data[CNF_BUMPSIZE] , CONF_UNIT_K , (gint64)10*1024); conf_init_real (&conf_data[CNF_BUMPMULT] , 1.5); - conf_init_int (&conf_data[CNF_BUMPDAYS] , 2); + conf_init_int (&conf_data[CNF_BUMPDAYS] , CONF_UNIT_NONE, 2); conf_init_str (&conf_data[CNF_TPCHANGER] , ""); - conf_init_int (&conf_data[CNF_RUNTAPES] , 1); - conf_init_int (&conf_data[CNF_MAXDUMPS] , 1); - conf_init_int (&conf_data[CNF_MAX_DLE_BY_VOLUME] , 1000000000); - conf_init_int (&conf_data[CNF_ETIMEOUT] , 300); - conf_init_int (&conf_data[CNF_DTIMEOUT] , 1800); - conf_init_int (&conf_data[CNF_CTIMEOUT] , 30); - conf_init_size (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], 40*32768); + conf_init_int (&conf_data[CNF_RUNTAPES] , CONF_UNIT_NONE, 1); + conf_init_int (&conf_data[CNF_MAXDUMPS] , CONF_UNIT_NONE, 1); + conf_init_int (&conf_data[CNF_MAX_DLE_BY_VOLUME] , CONF_UNIT_NONE, 1000000000); + conf_init_int (&conf_data[CNF_ETIMEOUT] , CONF_UNIT_NONE, 300); + conf_init_int (&conf_data[CNF_DTIMEOUT] , CONF_UNIT_NONE, 1800); + conf_init_int (&conf_data[CNF_CTIMEOUT] , CONF_UNIT_NONE, 30); + conf_init_size (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], CONF_UNIT_NONE, 40*32768); conf_init_str (&conf_data[CNF_PRINTER] , ""); conf_init_str (&conf_data[CNF_MAILER] , DEFAULT_MAILER); conf_init_no_yes_all(&conf_data[CNF_AUTOFLUSH] , 0); - conf_init_int (&conf_data[CNF_RESERVE] , 100); - conf_init_int64 (&conf_data[CNF_MAXDUMPSIZE] , (gint64)-1); + conf_init_int (&conf_data[CNF_RESERVE] , CONF_UNIT_NONE, 100); + conf_init_int64 (&conf_data[CNF_MAXDUMPSIZE] , CONF_UNIT_K , (gint64)-1); conf_init_str (&conf_data[CNF_COLUMNSPEC] , ""); conf_init_bool (&conf_data[CNF_AMRECOVER_DO_FSF] , 1); conf_init_str (&conf_data[CNF_AMRECOVER_CHANGER] , ""); conf_init_bool (&conf_data[CNF_AMRECOVER_CHECK_LABEL], 1); conf_init_taperalgo(&conf_data[CNF_TAPERALGO] , 0); - conf_init_int (&conf_data[CNF_TAPER_PARALLEL_WRITE] , 1); - conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED] , 0); - conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], 0); - conf_init_int (&conf_data[CNF_TAPERFLUSH] , 0); + conf_init_int (&conf_data[CNF_TAPER_PARALLEL_WRITE] , CONF_UNIT_NONE, 1); + conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_TAPERFLUSH] , CONF_UNIT_NONE, 0); conf_init_str (&conf_data[CNF_DISPLAYUNIT] , "k"); conf_init_str (&conf_data[CNF_KRB5KEYTAB] , "/.amanda-v5-keytab"); conf_init_str (&conf_data[CNF_KRB5PRINCIPAL] , "service/amanda"); conf_init_str (&conf_data[CNF_LABEL_NEW_TAPES] , ""); conf_init_bool (&conf_data[CNF_EJECT_VOLUME] , 0); + conf_init_str (&conf_data[CNF_TMPDIR] , ""); conf_init_bool (&conf_data[CNF_USETIMESTAMPS] , 1); - conf_init_int (&conf_data[CNF_CONNECT_TRIES] , 3); - conf_init_int (&conf_data[CNF_REP_TRIES] , 5); - conf_init_int (&conf_data[CNF_REQ_TRIES] , 3); - conf_init_int (&conf_data[CNF_DEBUG_DAYS] , AMANDA_DEBUG_DAYS); - conf_init_int (&conf_data[CNF_DEBUG_AMANDAD] , 0); - conf_init_int (&conf_data[CNF_DEBUG_RECOVERY] , 1); - conf_init_int (&conf_data[CNF_DEBUG_AMIDXTAPED] , 0); - conf_init_int (&conf_data[CNF_DEBUG_AMINDEXD] , 0); - conf_init_int (&conf_data[CNF_DEBUG_AMRECOVER] , 0); - conf_init_int (&conf_data[CNF_DEBUG_AUTH] , 0); - conf_init_int (&conf_data[CNF_DEBUG_EVENT] , 0); - conf_init_int (&conf_data[CNF_DEBUG_HOLDING] , 0); - conf_init_int (&conf_data[CNF_DEBUG_PROTOCOL] , 0); - conf_init_int (&conf_data[CNF_DEBUG_PLANNER] , 0); - conf_init_int (&conf_data[CNF_DEBUG_DRIVER] , 0); - conf_init_int (&conf_data[CNF_DEBUG_DUMPER] , 0); - conf_init_int (&conf_data[CNF_DEBUG_CHUNKER] , 0); - conf_init_int (&conf_data[CNF_DEBUG_TAPER] , 0); - conf_init_int (&conf_data[CNF_DEBUG_SELFCHECK] , 0); - conf_init_int (&conf_data[CNF_DEBUG_SENDSIZE] , 0); - conf_init_int (&conf_data[CNF_DEBUG_SENDBACKUP] , 0); + conf_init_int (&conf_data[CNF_CONNECT_TRIES] , CONF_UNIT_NONE, 3); + conf_init_int (&conf_data[CNF_REP_TRIES] , CONF_UNIT_NONE, 5); + conf_init_int (&conf_data[CNF_REQ_TRIES] , CONF_UNIT_NONE, 3); + conf_init_int (&conf_data[CNF_DEBUG_DAYS] , CONF_UNIT_NONE, AMANDA_DEBUG_DAYS); + conf_init_int (&conf_data[CNF_DEBUG_AMANDAD] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_RECOVERY] , CONF_UNIT_NONE, 1); + conf_init_int (&conf_data[CNF_DEBUG_AMIDXTAPED] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_AMINDEXD] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_AMRECOVER] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_AUTH] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_EVENT] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_HOLDING] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_PROTOCOL] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_PLANNER] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_DRIVER] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_DUMPER] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_CHUNKER] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_TAPER] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_SELFCHECK] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_SENDSIZE] , CONF_UNIT_NONE, 0); + conf_init_int (&conf_data[CNF_DEBUG_SENDBACKUP] , CONF_UNIT_NONE, 0); #ifdef UDPPORTRANGE conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT] , UDPPORTRANGE); #else @@ -5666,22 +5564,28 @@ update_derived_values( static void conf_init_int( val_t *val, + confunit_t unit, int i) { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_INT; + val->unit = unit; val_t__int(val) = i; } static void conf_init_int64( val_t *val, + confunit_t unit, gint64 l) { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_INT64; + val->unit = unit; val_t__int64(val) = l; } @@ -5692,7 +5596,9 @@ conf_init_real( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_REAL; + val->unit = CONF_UNIT_NONE; val_t__real(val) = r; } @@ -5703,7 +5609,9 @@ conf_init_str( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_STR; + val->unit = CONF_UNIT_NONE; if(s) val->v.s = stralloc(s); else @@ -5717,7 +5625,9 @@ conf_init_ident( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_IDENT; + val->unit = CONF_UNIT_NONE; if(s) val->v.s = stralloc(s); else @@ -5731,7 +5641,9 @@ conf_init_identlist( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_IDENTLIST; + val->unit = CONF_UNIT_NONE; val->v.identlist = NULL; if (s) val->v.identlist = g_slist_append(val->v.identlist, stralloc(s)); @@ -5744,18 +5656,23 @@ conf_init_time( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_TIME; + val->unit = CONF_UNIT_NONE; val_t__time(val) = t; } static void conf_init_size( val_t *val, + confunit_t unit, ssize_t sz) { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_SIZE; + val->unit = unit; val_t__size(val) = sz; } @@ -5766,7 +5683,9 @@ conf_init_bool( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_BOOLEAN; + val->unit = CONF_UNIT_NONE; val_t__boolean(val) = i; } @@ -5777,7 +5696,9 @@ conf_init_no_yes_all( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_NO_YES_ALL; + val->unit = CONF_UNIT_NONE; val_t__int(val) = i; } @@ -5788,7 +5709,9 @@ conf_init_compress( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_COMPRESS; + val->unit = CONF_UNIT_NONE; val_t__compress(val) = (int)i; } @@ -5799,7 +5722,9 @@ conf_init_encrypt( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_ENCRYPT; + val->unit = CONF_UNIT_NONE; val_t__encrypt(val) = (int)i; } @@ -5810,7 +5735,9 @@ conf_init_part_cache_type( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_PART_CACHE_TYPE; + val->unit = CONF_UNIT_NONE; val_t__part_cache_type(val) = (int)i; } @@ -5820,7 +5747,9 @@ conf_init_host_limit( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_HOST_LIMIT; + val->unit = CONF_UNIT_NONE; val_t__host_limit(val).match_pats = NULL; val_t__host_limit(val).same_host = FALSE; val_t__host_limit(val).server = FALSE; @@ -5841,7 +5770,9 @@ conf_init_data_path( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_DATA_PATH; + val->unit = CONF_UNIT_NONE; val_t__data_path(val) = (int)i; } @@ -5852,7 +5783,9 @@ conf_init_holding( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_HOLDING; + val->unit = CONF_UNIT_NONE; val_t__holding(val) = (int)i; } @@ -5864,7 +5797,9 @@ conf_init_estimatelist( GSList *estimates = NULL; val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_ESTIMATELIST; + val->unit = CONF_UNIT_NONE; estimates = g_slist_append(estimates, GINT_TO_POINTER(i)); val_t__estimatelist(val) = estimates; } @@ -5876,6 +5811,8 @@ conf_init_strategy( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; + val->unit = CONF_UNIT_NONE; val->type = CONFTYPE_STRATEGY; val_t__strategy(val) = i; } @@ -5887,7 +5824,9 @@ conf_init_taperalgo( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_TAPERALGO; + val->unit = CONF_UNIT_NONE; val_t__taperalgo(val) = i; } @@ -5898,7 +5837,9 @@ conf_init_priority( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_PRIORITY; + val->unit = CONF_UNIT_NONE; val_t__priority(val) = i; } @@ -5910,7 +5851,9 @@ conf_init_rate( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_RATE; + val->unit = CONF_UNIT_NONE; val_t__rate(val)[0] = r1; val_t__rate(val)[1] = r2; } @@ -5921,7 +5864,9 @@ conf_init_exinclude( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_EXINCLUDE; + val->unit = CONF_UNIT_NONE; val_t__exinclude(val).optional = 0; val_t__exinclude(val).sl_list = NULL; val_t__exinclude(val).sl_file = NULL; @@ -5935,7 +5880,9 @@ conf_init_intrange( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_INTRANGE; + val->unit = CONF_UNIT_NONE; val_t__intrange(val)[0] = i1; val_t__intrange(val)[1] = i2; } @@ -5945,7 +5892,9 @@ conf_init_autolabel( val_t *val) { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_AUTOLABEL; + val->unit = CONF_UNIT_NONE; val->v.autolabel.template = NULL; val->v.autolabel.autolabel = 0; } @@ -5965,7 +5914,9 @@ conf_init_proplist( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_PROPLIST; + val->unit = CONF_UNIT_NONE; val_t__proplist(val) = g_hash_table_new_full(g_str_amanda_hash, g_str_amanda_equal, &g_free, &free_property_t); @@ -5978,7 +5929,9 @@ conf_init_execute_on( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_EXECUTE_ON; + val->unit = CONF_UNIT_NONE; val->v.i = i; } @@ -5989,7 +5942,9 @@ conf_init_execute_where( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_EXECUTE_WHERE; + val->unit = CONF_UNIT_NONE; val->v.i = i; } @@ -6000,14 +5955,18 @@ conf_init_send_amreport( { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_SEND_AMREPORT_ON; + val->unit = CONF_UNIT_NONE; val->v.i = i; } static void conf_init_application(val_t *val) { val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; val->type = CONFTYPE_APPLICATION; + val->unit = CONF_UNIT_NONE; val->v.s = NULL; } @@ -6939,6 +6898,12 @@ merge_val_t( { if (valsrc->type == CONFTYPE_PROPLIST) { if (valsrc->v.proplist) { + if (valdst->v.proplist == NULL || + g_hash_table_size(valdst->v.proplist) == 0) { + valdst->seen.block = current_block; + valdst->seen.filename = current_filename; + valdst->seen.linenum = current_line_num; + } if (valdst->v.proplist == NULL) { valdst->v.proplist = g_hash_table_new_full(g_str_amanda_hash, g_str_amanda_equal, @@ -7105,6 +7070,7 @@ merge_proplist_foreach_fn( } if (!new_property) { new_property = malloc(sizeof(property_t)); + new_property->seen = property->seen; new_property->append = property->append; new_property->priority = property->priority; new_property->values = NULL; @@ -7132,6 +7098,7 @@ copy_proplist_foreach_fn( property_t *new_property = malloc(sizeof(property_t)); new_property->append = property->append; new_property->priority = property->priority; + new_property->seen = property->seen; new_property->values = NULL; for(elem = property->values;elem != NULL; elem=elem->next) { @@ -7203,6 +7170,7 @@ free_val_t( } val->seen.linenum = 0; val->seen.filename = NULL; + val->seen.block = NULL; } /* @@ -7269,7 +7237,9 @@ generic_client_get_security_conf( } void -dump_configuration(void) +dump_configuration( + gboolean print_default, + gboolean print_source) { tapetype_t *tp; dumptype_t *dp; @@ -7301,7 +7271,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("server bad token")); - val_t_print_token(stdout, NULL, "%-21s ", kt, &conf_data[np->parm]); + val_t_print_token(print_default, print_source, stdout, NULL, "%-21s ", kt, &conf_data[np->parm]); } for(hp = holdinglist; hp != NULL; hp = hp->next) { @@ -7322,7 +7292,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("holding bad token")); - val_t_print_token(stdout, NULL, " %-9s ", kt, &hd->value[i]); + val_t_print_token(print_default, print_source, stdout, NULL, " %-9s ", kt, &hd->value[i]); } g_printf("}\n"); } @@ -7344,7 +7314,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("tapetype bad token")); - val_t_print_token(stdout, prefix, " %-9s ", kt, &tp->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-9s ", kt, &tp->value[i]); } g_printf("%s}\n", prefix); } @@ -7367,7 +7337,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("dumptype bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &dp->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &dp->value[i]); } g_printf("%s}\n", prefix); } @@ -7393,7 +7363,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("interface bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &ip->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ip->value[i]); } g_printf("%s}\n",prefix); } @@ -7415,7 +7385,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("application bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &ap->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ap->value[i]); } g_printf("%s}\n",prefix); } @@ -7437,7 +7407,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("script bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &ps->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ps->value[i]); } g_printf("%s}\n",prefix); } @@ -7456,7 +7426,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("device bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &dc->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &dc->value[i]); } g_printf("%s}\n",prefix); } @@ -7475,7 +7445,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("changer bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &cc->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &cc->value[i]); } g_printf("%s}\n",prefix); } @@ -7494,7 +7464,7 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("interactivity bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &iv->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &iv->value[i]); } g_printf("%s}\n",prefix); } @@ -7513,14 +7483,41 @@ dump_configuration(void) if(kt->token == CONF_UNKNOWN) error(_("taperscan bad token")); - val_t_print_token(stdout, prefix, " %-19s ", kt, &ts->value[i]); + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &ts->value[i]); } g_printf("%s}\n",prefix); } } +void dump_dumptype( + dumptype_t *dp, + char *prefix, + gboolean print_default, + gboolean print_source) +{ + int i; + conf_var_t *np; + keytab_t *kt; + + for(i=0; i < DUMPTYPE_DUMPTYPE; i++) { + for(np=dumptype_var; np->token != CONF_UNKNOWN; np++) + if(np->parm == i) break; + if(np->token == CONF_UNKNOWN) + error(_("dumptype bad value")); + + for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) + if(kt->token == np->token) break; + if(kt->token == CONF_UNKNOWN) + error(_("dumptype bad token")); + + val_t_print_token(print_default, print_source, stdout, prefix, " %-19s ", kt, &dp->value[i]); + } +} + static void val_t_print_token( + gboolean print_default, + gboolean print_source, FILE *output, char *prefix, char *format, @@ -7528,7 +7525,12 @@ val_t_print_token( val_t *val) { char **dispstrs, **dispstr; - dispstrs = val_t_display_strs(val, 1); + + if (print_default == 0 && !val_t_seen(val)) { + return; + } + + dispstrs = val_t_display_strs(val, 1, print_source, TRUE); /* For most configuration types, this outputs * PREFIX KEYWORD DISPSTR @@ -7555,11 +7557,40 @@ val_t_print_token( g_strfreev(dispstrs); } +typedef struct proplist_display_str_foreach_user_data { + char **msg; + gboolean print_source; +} proplist_display_str_foreach_user_data; + +char *source_string(seen_t *seen); +char *source_string( + seen_t *seen) +{ + char *buf; + + if (seen->linenum) { + if (seen->block) { + buf = g_strdup_printf(" (%s file %s line %d)", + seen->block, seen->filename, seen->linenum); + } else { + buf = g_strdup_printf(" (file %s line %d)", + seen->filename, seen->linenum); + } + } else { + buf = g_strdup(" (default)"); + } + return buf; +} + char ** val_t_display_strs( val_t *val, - int str_need_quote) + int str_need_quote, + gboolean print_source, + gboolean print_unit) { + gboolean add_source = TRUE; + int i; char **buf; buf = malloc(3*SIZEOF(char *)); buf[0] = NULL; @@ -7568,15 +7599,33 @@ val_t_display_strs( switch(val->type) { case CONFTYPE_INT: - buf[0] = vstrallocf("%d", val_t__int(val)); + buf[0] = vstrallocf("%d ", val_t__int(val)); + i = strlen(buf[0]) - 1; + if (print_unit && val->unit == CONF_UNIT_K) { + buf[0][i] = 'K'; + } else { + buf[0][i] = '\0'; + } break; case CONFTYPE_SIZE: - buf[0] = vstrallocf("%zd", (ssize_t)val_t__size(val)); + buf[0] = vstrallocf("%zd ", (ssize_t)val_t__size(val)); + i = strlen(buf[0]) - 1; + if (print_unit && val->unit == CONF_UNIT_K) { + buf[0][i] = 'K'; + } else { + buf[0][i] = '\0'; + } break; case CONFTYPE_INT64: - buf[0] = vstrallocf("%lld", (long long)val_t__int64(val)); + buf[0] = vstrallocf("%lld ", (long long)val_t__int64(val)); + i = strlen(buf[0]) - 1; + if (print_unit && val->unit == CONF_UNIT_K) { + buf[0][i] = 'K'; + } else { + buf[0][i] = '\0'; + } break; case CONFTYPE_REAL: @@ -7892,16 +7941,18 @@ val_t_display_strs( case CONFTYPE_PROPLIST: { int nb_property; - char **mybuf; + proplist_display_str_foreach_user_data user_data; nb_property = g_hash_table_size(val_t__proplist(val)); - amfree(buf); + g_free(buf); buf = malloc((nb_property+1)*SIZEOF(char*)); buf[nb_property] = NULL; - mybuf = buf; + user_data.msg = buf; + user_data.print_source = print_source; g_hash_table_foreach(val_t__proplist(val), proplist_display_str_foreach_fn, - &mybuf); + &user_data); + add_source = FALSE; break; } @@ -8014,6 +8065,16 @@ val_t_display_strs( break; } + + /* add source */ + if (print_source && add_source) { + char **buf1; + for (buf1 = buf; *buf1 != NULL; buf1++) { + char *buf2 = g_strjoin("", *buf1, source_string(&val->seen), NULL); + g_free(*buf1); + *buf1 = buf2; + } + } return buf; } @@ -8060,7 +8121,8 @@ proplist_display_str_foreach_fn( char *property_s = quote_string_always(key_p); property_t *property = value_p; GSList *value; - char ***msg = (char ***)user_data_p; + proplist_display_str_foreach_user_data *user_data = user_data_p; + char ***msg = (char ***)&user_data->msg; /* What to do with property->append? it should be printed only on client */ if (property->priority) { @@ -8075,6 +8137,9 @@ proplist_display_str_foreach_fn( **msg = vstrextend(*msg, " ", qstr, NULL); amfree(qstr); } + if (user_data->print_source) { + **msg = vstrextend(*msg, source_string(&property->seen)); + } (*msg)++; } @@ -8083,7 +8148,7 @@ exinclude_display_str( val_t *val, int file) { - sl_t *sl; + am_sl_t *sl; sle_t *excl; char *rval; @@ -8163,6 +8228,8 @@ parm_key_info( pp_script_t *pp; device_config_t *dc; changer_config_t *cc; + taperscan_t *ts; + interactivity_t *iv; int success = FALSE; /* WARNING: assumes globals keytable and parsetable are set correctly. */ @@ -8190,7 +8257,7 @@ parm_key_info( if (*s == '-') *s = '_'; } - subsec_key = strchr(subsec_name,':'); + subsec_key = strrchr(subsec_name,':'); if(!subsec_key) goto out; /* failure */ *subsec_key = '\0'; @@ -8311,6 +8378,30 @@ parm_key_info( if (val) *val = &cc->value[np->parm]; if (parm) *parm = np; success = TRUE; + } else if (g_str_equal(subsec_type, "INTERACTIVITY")) { + iv = lookup_interactivity(subsec_name); + if (!iv) goto out; + for(np = interactivity_var; np->token != CONF_UNKNOWN; np++) { + if(np->token == kt->token) + break; + } + if (np->token == CONF_UNKNOWN) goto out; + + if (val) *val = &iv->value[np->parm]; + if (parm) *parm = np; + success = TRUE; + } else if (g_str_equal(subsec_type, "TAPERSCAN")) { + ts = lookup_taperscan(subsec_name); + if (!ts) goto out; + for(np = taperscan_var; np->token != CONF_UNKNOWN; np++) { + if(np->token == kt->token) + break; + } + if (np->token == CONF_UNKNOWN) goto out; + + if (val) *val = &ts->value[np->parm]; + if (parm) *parm = np; + success = TRUE; } /* No delimiters -- we're referencing a global config parameter */ diff --git a/common-src/conffile.h b/common-src/conffile.h index 2c867cc..a9a6504 100644 --- a/common-src/conffile.h +++ b/common-src/conffile.h @@ -81,6 +81,15 @@ * this works and it's here. */ +/* A "seen" struct. Rather than allocate strings all over the place, this + * string is in the "parsed_filenames" GSList and will be freed when that + * GSList is freed. This struct should be opaque to other modules. */ +typedef struct seen_s { + char *block; + char *filename; + int linenum; +} seen_t; + /* holdingdisk types */ typedef enum { HOLD_NEVER, /* Always direct to tape */ @@ -195,8 +204,8 @@ typedef enum { } data_path_t; typedef struct exinclude_s { - sl_t *sl_list; - sl_t *sl_file; + am_sl_t *sl_list; + am_sl_t *sl_file; int optional; } exinclude_t; @@ -204,6 +213,7 @@ typedef struct { int append; int priority; GSList* values; + seen_t seen; } property_t; typedef GHashTable* proplist_t; @@ -258,13 +268,10 @@ typedef enum { CONFTYPE_NO_YES_ALL, } conftype_t; -/* A "seen" struct. Rather than allocate strings all over the place, this - * string is in the "parsed_filenames" GSList and will be freed when that - * GSList is freed. This struct should be opaque to other modules. */ -typedef struct seen_s { - char *filename; - int linenum; -} seen_t; +typedef enum { + CONF_UNIT_NONE, + CONF_UNIT_K, +} confunit_t; /* This should be considered an opaque type for any other modules. The complete * struct is included here to allow quick access via macros. Access it *only* through @@ -288,6 +295,7 @@ typedef struct val_s { } v; seen_t seen; conftype_t type; + confunit_t unit; } val_t; /* Functions to typecheck and extract a particular type of @@ -488,6 +496,7 @@ typedef enum { CNF_TAPERSCAN, CNF_MAX_DLE_BY_VOLUME, CNF_EJECT_VOLUME, + CNF_TMPDIR, CNF_CNF /* sentinel */ } confparm_key; @@ -715,6 +724,7 @@ typedef enum { DUMPTYPE_ALLOW_SPLIT, DUMPTYPE_RECOVERY_LIMIT, DUMPTYPE_DUMP_LIMIT, + DUMPTYPE_MAX_WARNINGS, DUMPTYPE_DUMPTYPE /* sentinel */ } dumptype_key; @@ -806,6 +816,7 @@ char *dumptype_name(dumptype_t *dtyp); #define dumptype_get_allow_split(dtyp) (val_t_to_boolean(dumptype_getconf((dtyp), DUMPTYPE_ALLOW_SPLIT))) #define dumptype_get_recovery_limit(dtyp) (val_t_to_host_limit(dumptype_getconf((dtyp), DUMPTYPE_RECOVERY_LIMIT))) #define dumptype_get_dump_limit(dtyp) (val_t_to_host_limit(dumptype_getconf((dtyp), DUMPTYPE_DUMP_LIMIT))) +#define dumptype_get_max_warnings(dtyp) (val_t_to_int(dumptype_getconf((dtyp), DUMPTYPE_MAX_WARNINGS))) /* * Interface parameter access @@ -1481,7 +1492,10 @@ char *generic_get_security_conf(char *, void *); * This function only dumps the server configuration, and will fail on * clients. */ -void dump_configuration(void); +void dump_configuration(gboolean print_default, gboolean print_source); + +void dump_dumptype(dumptype_t *dp, char *prefix, gboolean print_default, + gboolean print_source); /* Return a sequence of strings giving the printable representation * of the given val_t. If str_needs_quotes is true and each string is @@ -1500,7 +1514,8 @@ void dump_configuration(void); * @param str_needs_quotes: add quotes to CONFTYPE_STR values? * @returns: NULL-terminated string vector */ -char **val_t_display_strs(val_t *val, int str_needs_quotes); +char **val_t_display_strs(val_t *val, int str_needs_quotes, gboolean print_source, + gboolean print_unit); /* Read a dumptype; this is used by this module as well as by diskfile.c to * read the disklist. The two are carefully balanced in their parsing process. diff --git a/common-src/directtcp.h b/common-src/directtcp.h index 9fa8f2c..33c4577 100644 --- a/common-src/directtcp.h +++ b/common-src/directtcp.h @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/event-test.c b/common-src/event-test.c index e4c67c5..832147e 100644 --- a/common-src/event-test.c +++ b/common-src/event-test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/event.c b/common-src/event.c index 97e7c29..218d638 100644 --- a/common-src/event.c +++ b/common-src/event.c @@ -311,6 +311,7 @@ any_mainloop_events(void) for (iter = all_events; iter != NULL; iter = g_slist_next(iter)) { event_handle_t *hdl = (event_handle_t *)iter->data; + event_debug(2, _("list %p: %s/%jd\n"), hdl, event_type2str((hdl)->type), (hdl)->data); if (hdl->type != EV_WAIT) return TRUE; } diff --git a/common-src/fileheader-test.c b/common-src/fileheader-test.c index ec8057d..589f5ca 100644 --- a/common-src/fileheader-test.c +++ b/common-src/fileheader-test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Zmanda Inc. All Rights Reserved. + * Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 2.1 as diff --git a/common-src/fileheader.c b/common-src/fileheader.c index 5193837..381c40d 100644 --- a/common-src/fileheader.c +++ b/common-src/fileheader.c @@ -139,7 +139,7 @@ parse_file_header( if (strcmp(tok, "NETDUMP:") != 0 && strcmp(tok, "AMANDA:") != 0) { amfree(buf); - file->type = F_UNKNOWN; + file->type = F_WEIRD; amfree(line1); return; } diff --git a/common-src/glib-util.c b/common-src/glib-util.c index 91985e5..9fd8ced 100644 --- a/common-src/glib-util.c +++ b/common-src/glib-util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -30,7 +30,64 @@ #ifdef HAVE_LIBCURL #include -#endif + +#ifdef LIBCURL_USE_OPENSSL +#include +static GMutex **openssl_mutex_array; +static void openssl_lock_callback(int mode, int type, const char *file, int line) +{ + (void)file; + (void)line; + if (mode & CRYPTO_LOCK) { + g_mutex_lock(openssl_mutex_array[type]); + } + else { + g_mutex_unlock(openssl_mutex_array[type]); + } +} + +static void +init_ssl(void) +{ + int i; + + openssl_mutex_array = g_new0(GMutex *, CRYPTO_num_locks()); + + for (i=0; i +#include + +GCRY_THREAD_OPTION_PTHREAD_IMPL; +static void +init_ssl(void) +{ + gcry_control(GCRYCTL_SET_THREAD_CBS); +} + +#else /* LIBCURL_USE_GNUTLS */ + +static void +init_ssl(void) +{ +} +#endif /* LIBCURL_USE_GNUTLS */ +#endif /* LIBCURL_USE_OPENSSL */ + +#else /* HAVE_LIBCURL */ +static void +init_ssl(void) +{ +} +#endif /* HAVE_LIBCURL */ void glib_init(void) { @@ -42,7 +99,9 @@ glib_init(void) { * is initialized) */ #ifdef HAVE_LIBCURL # ifdef G_THREADS_ENABLED +# if (GLIB_MAJOR_VERSION < 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 31)) g_assert(!g_thread_supported()); /* assert threads aren't initialized yet */ +# endif # endif g_assert(curl_global_init(CURL_GLOBAL_ALL) == 0); #endif @@ -70,6 +129,10 @@ glib_init(void) { if (!g_thread_supported()) g_thread_init(NULL); #endif + + /* initialize ssl */ + init_ssl(); + } typedef enum { @@ -120,15 +183,6 @@ void slist_free_full(GSList * list, GDestroyNotify free_fn) { } #endif -void g_queue_free_full(GQueue * queue) { - while (!g_queue_is_empty(queue)) { - gpointer data; - data = g_queue_pop_head(queue); - amfree(data); - } - g_queue_free(queue); -} - void g_ptr_array_free_full(GPtrArray * array) { size_t i; diff --git a/common-src/glib-util.h b/common-src/glib-util.h index f687fcd..a9b24ee 100644 --- a/common-src/glib-util.h +++ b/common-src/glib-util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -72,7 +72,6 @@ void slist_free_full(GSList * list, GDestroyNotify free_fn); /* These functions all take a GLib container, and call free() on all the * pointers in the container before free()ing the container itself. */ -void g_queue_free_full(GQueue * queue); void g_ptr_array_free_full(GPtrArray * array); /* g_value_compare() does what you expect. It returns TRUE if and diff --git a/common-src/ipc-binary.c b/common-src/ipc-binary.c index 4d2363a..9925164 100644 --- a/common-src/ipc-binary.c +++ b/common-src/ipc-binary.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/ipc-binary.h b/common-src/ipc-binary.h index e36efb7..3d8b54b 100644 --- a/common-src/ipc-binary.h +++ b/common-src/ipc-binary.h @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/match-test.c b/common-src/match-test.c index 9be05ef..30f21b2 100644 --- a/common-src/match-test.c +++ b/common-src/match-test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/match.c b/common-src/match.c index 0981a43..cd363e4 100644 --- a/common-src/match.c +++ b/common-src/match.c @@ -153,7 +153,14 @@ static struct mword_regexes mword_slash_regexes = { * be called from within threads, so play it safe. */ -static GStaticMutex re_cache_mutex = G_STATIC_MUTEX_INIT; +#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31)) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" + static GStaticMutex re_cache_mutex = G_STATIC_MUTEX_INIT; +# pragma GCC diagnostic pop +#else + static GStaticMutex re_cache_mutex = G_STATIC_MUTEX_INIT; +#endif static GHashTable *regex_cache = NULL, *regex_cache_newline = NULL; /* diff --git a/common-src/match.h b/common-src/match.h index 967c852..97adac0 100644 --- a/common-src/match.h +++ b/common-src/match.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/quoting-test.c b/common-src/quoting-test.c index b2df6ac..9edac6c 100644 --- a/common-src/quoting-test.c +++ b/common-src/quoting-test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/security-util.c b/common-src/security-util.c index 2e0c0d0..e3942e6 100644 --- a/common-src/security-util.c +++ b/common-src/security-util.c @@ -2672,7 +2672,7 @@ sec_get_authenticated_peer_name_gethostname( return server_hostname; } amfree(server_hostname); - return "localhost"; + return strdup("localhost"); } char * @@ -2682,5 +2682,5 @@ sec_get_authenticated_peer_name_hostname( char *hostname = ((struct sec_handle *)hdl)->hostname; if (!hostname) hostname = ""; - return hostname; + return strdup(hostname); } diff --git a/common-src/simpleprng.c b/common-src/simpleprng.c index 46c6360..c988a6d 100644 --- a/common-src/simpleprng.c +++ b/common-src/simpleprng.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/simpleprng.h b/common-src/simpleprng.h index 9614124..e6e5950 100644 --- a/common-src/simpleprng.h +++ b/common-src/simpleprng.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/sockaddr-util.c b/common-src/sockaddr-util.c index 0417575..1cf79da 100644 --- a/common-src/sockaddr-util.c +++ b/common-src/sockaddr-util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/sockaddr-util.h b/common-src/sockaddr-util.h index 2b16201..5277742 100644 --- a/common-src/sockaddr-util.h +++ b/common-src/sockaddr-util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/ssh-security.c b/common-src/ssh-security.c index 1d84ab6..bcd1d98 100644 --- a/common-src/ssh-security.c +++ b/common-src/ssh-security.c @@ -114,7 +114,7 @@ ssh_connect( int result; struct sec_handle *rh; char *amandad_path=NULL, *client_username=NULL, *ssh_keys=NULL; - char *client_port = "22"; + char *client_port = NULL; assert(fn != NULL); assert(hostname != NULL); @@ -304,6 +304,10 @@ runssh( char *xclient_username = (char *)client_username; char *xssh_keys = (char *)ssh_keys; char *xclient_port = (char *)client_port; + GPtrArray *myargs; + gchar *ssh_options[100] = {SSH_OPTIONS, NULL}; + gchar **ssh_option; + gchar *cmd; memset(rpipe, -1, SIZEOF(rpipe)); memset(wpipe, -1, SIZEOF(wpipe)); @@ -317,18 +321,31 @@ runssh( if(!xclient_username || strlen(xclient_username) <= 1) xclient_username = CLIENT_LOGIN; if(!xclient_port || strlen(xclient_port) <= 1) - xclient_port = "22"; + xclient_port = NULL; - if(!ssh_keys || strlen(ssh_keys) <= 1) { - g_debug("exec: %s %s %s %s %s %s %s %s %s", - SSH, "SSH_OPTIONS", "-l", xclient_username, "-p", client_port, - rc->hostname, xamandad_path, "-auth=ssh"); + myargs = g_ptr_array_sized_new(20); + g_ptr_array_add(myargs, SSH); + for (ssh_option = ssh_options; *ssh_option != NULL; ssh_option++) { + g_ptr_array_add(myargs, *ssh_option); } - else { - g_debug("exec: %s %s %s %s %s %s %s %s %s %s %s", - SSH, "SSH_OPTIONS", "-l", xclient_username, "-p", client_port, - "-i", xssh_keys, rc->hostname, xamandad_path, "-auth=ssh"); + g_ptr_array_add(myargs, "-l"); + g_ptr_array_add(myargs, xclient_username); + if (xclient_port) { + g_ptr_array_add(myargs, "-p"); + g_ptr_array_add(myargs, xclient_port); } + if (ssh_keys && strlen(ssh_keys) > 1) { + g_ptr_array_add(myargs, "-i"); + g_ptr_array_add(myargs, xssh_keys); + } + g_ptr_array_add(myargs, rc->hostname); + g_ptr_array_add(myargs, xamandad_path); + g_ptr_array_add(myargs, "-auth=ssh"); + g_ptr_array_add(myargs, NULL); + + cmd = g_strjoinv(" ", (gchar **)myargs->pdata); + g_debug("exec: %s", cmd); + g_free(cmd); switch (rc->pid = fork()) { case -1: @@ -355,15 +372,8 @@ runssh( safe_fd(-1, 0); - if(!ssh_keys || strlen(ssh_keys) <= 1) { - execlp(SSH, SSH, SSH_OPTIONS, "-l", xclient_username, "-p", client_port, - rc->hostname, xamandad_path, "-auth=ssh", (char *)NULL); - } - else { - execlp(SSH, SSH, SSH_OPTIONS, "-l", xclient_username, "-p", client_port, - "-i", xssh_keys, rc->hostname, xamandad_path, "-auth=ssh", - (char *)NULL); - } + execvp(SSH, (gchar **)myargs->pdata); + error("error: couldn't exec %s: %s", SSH, strerror(errno)); /* should never go here, shut up compiler warning */ diff --git a/common-src/svn-info.h b/common-src/svn-info.h index 1711f25..da674f6 100644 --- a/common-src/svn-info.h +++ b/common-src/svn-info.h @@ -1,2 +1,2 @@ -#define BUILT_REV "4553" -#define BUILT_BRANCH "community_3_3_1" +#define BUILT_REV "4847" +#define BUILT_BRANCH "community_3_3_2" diff --git a/common-src/testutils.c b/common-src/testutils.c index b957e87..3d642af 100644 --- a/common-src/testutils.c +++ b/common-src/testutils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/testutils.h b/common-src/testutils.h index 256f104..288d34e 100644 --- a/common-src/testutils.h +++ b/common-src/testutils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/common-src/timestamp.c b/common-src/timestamp.c index 3096355..8589b9a 100644 --- a/common-src/timestamp.c +++ b/common-src/timestamp.c @@ -74,6 +74,12 @@ time_t get_time_from_timestamp(char *timestamp) struct tm tm; char t[5]; time_t tt; + tm.tm_year = 0; + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; if (strlen(timestamp) >= 4) { memcpy(t, timestamp, 4); diff --git a/common-src/util.c b/common-src/util.c index b9172ca..eed9d98 100644 --- a/common-src/util.c +++ b/common-src/util.c @@ -960,6 +960,7 @@ expand_braced_alternates( char * source) { GPtrArray *rval = g_ptr_array_new(); + gpointer *pdata; g_ptr_array_add(rval, g_strdup("")); @@ -971,6 +972,8 @@ expand_braced_alternates( new_components = parse_braced_component(&source); if (!new_components) { /* parse error */ + for (i = 0, pdata = rval->pdata; i < rval->len; i++) + g_free(*pdata++); g_ptr_array_free(rval, TRUE); return NULL; } @@ -987,7 +990,11 @@ expand_braced_alternates( } } + for (i = 0, pdata = rval->pdata; i < rval->len; i++) + g_free(*pdata++); g_ptr_array_free(rval, TRUE); + for (i = 0, pdata = new_components->pdata; i < new_components->len; i++) + g_free(*pdata++); g_ptr_array_free(new_components, TRUE); rval = new_rval; } @@ -1139,6 +1146,11 @@ add_history( # error No readdir() or readdir64() available! #endif +#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31)) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + char * portable_readdir(DIR* handle) { #ifdef USE_DIRENT64 @@ -1168,6 +1180,9 @@ char * portable_readdir(DIR* handle) { sure what to do about that case. */ return strdup(entry_p->d_name); } +#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31)) +# pragma GCC diagnostic pop +#endif int search_directory(DIR * handle, const char * regex, SearchDirectoryFunctor functor, gpointer user_data) { diff --git a/common-src/util.h b/common-src/util.h index 140982f..fe951b5 100644 --- a/common-src/util.h +++ b/common-src/util.h @@ -30,7 +30,7 @@ #define UTIL_H #include "amanda.h" -#include "sl.h" +#include "am_sl.h" #include #include diff --git a/config/Makefile.in b/config/Makefile.in index 9f8e8e6..de1f943 100644 --- a/config/Makefile.in +++ b/config/Makefile.in @@ -189,7 +189,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -705,6 +706,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/config/amanda/libs.m4 b/config/amanda/libs.m4 index b853132..e6acb04 100644 --- a/config/amanda/libs.m4 +++ b/config/amanda/libs.m4 @@ -381,6 +381,41 @@ x=CURLOPT_VERBOSE; fi fi + LIBCURL_USE_NSS=no + LIBCURL_USE_GNUTLS=no + LIBCURL_USE_OPENSSL=yes + _libcurl_configures=`$_libcurl_config --configure` + for _libcurl_configure in $_libcurl_configures ; do + if [[[ $_libcurl_configure = \'--with-nss* ]]]; then + LIBCURL_USE_NSS=yes + fi + if [[[ $_libcurl_configure = \'--without-nss* ]]]; then + LIBCURL_USE_NSS=no + fi + if [[[ $_libcurl_configure = \'--with-gnutls* ]]]; then + LIBCURL_USE_GNUTLS=yes + fi + if [[[ $_libcurl_configure = \'--without-gnutls* ]]]; then + LIBCURL_USE_GNUTLS=no + fi + if [[[ $_libcurl_configure = \'--with-ssl* ]]]; then + LIBCURL_USE_OPENSSL=yes + fi + if [[[ $_libcurl_configure = \'--without-ssl* ]]]; then + LIBCURL_USE_OPENSSL=no + fi + done + + if test "x$LIBCURL_USE_NSS" = "xyes"; then + AC_DEFINE(LIBCURL_USE_NSS, 1, [Defined if libcurl use NSS]) + fi + if test "x$LIBCURL_USE_GNUTLS" = "xyes"; then + AC_DEFINE(LIBCURL_USE_GNUTLS, , [Defined if libcurl use GnuTLS]) + fi + if test "x$LIBCURL_USE_OPENSSL" = "xyes"; then + AC_DEFINE(LIBCURL_USE_OPENSSL, 1, [Defined if libcurl use OpenSSL]) + fi + unset _libcurl_try_link unset _libcurl_version_parse unset _libcurl_config @@ -390,6 +425,8 @@ x=CURLOPT_VERBOSE; unset _libcurl_protocols unset _libcurl_version unset _libcurl_ldflags + unset _libcurl_configure + unset _libcurl_configures fi if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then diff --git a/config/amanda/progs.m4 b/config/amanda/progs.m4 index 128b03d..31e7007 100644 --- a/config/amanda/progs.m4 +++ b/config/amanda/progs.m4 @@ -395,3 +395,9 @@ AC_DEFUN([AMANDA_PROG_LEX], fi ]) +AC_DEFUN([AMANDA_PROG_NC], +[ + AC_PATH_PROG(NC,nc,,$LOCSYSPATH) + AC_PATH_PROG(NC6,nc6,,$LOCSYSPATH) + AC_PATH_PROG(NETCAT,netcat,,$LOCSYSPATH) +]) diff --git a/config/amanda/version.m4 b/config/amanda/version.m4 index da26e94..736362e 100644 --- a/config/amanda/version.m4 +++ b/config/amanda/version.m4 @@ -1,18 +1,35 @@ # Amanda version handling macros +# SYNOPSIS +# +# AMANDA_INIT_VERSION +# +# DESCRIPTION +# +# Create a macro, AMANDA_F_VERSION using only m4 which can expand +# legally before AC_INIT. AC_INIT requires the version to be a +# string not a shell variable. Include FULL_VERSION if it exists, otherwise +# use VERSION. -I dirs are searched for FULL_VERSION and VERSION. +# +AC_DEFUN([AMANDA_INIT_VERSION], +[ + m4_syscmd([test -f FULL_VERSION]) + m4_if(m4_sysval, [0], + [ + m4_define([AMANDA_F_VERSION], m4_chomp(m4_include([FULL_VERSION]))) + ], + [ + m4_define([AMANDA_F_VERSION], m4_chomp(m4_include([VERSION]))) + + ]) + VERSION=AMANDA_F_VERSION +]) + AC_DEFUN([AMANDA_VERSION], [ AMANDA_GET_SVN_INFO AMANDA_GET_GIT_INFO - if test -f FULL_VERSION; then - VERSION=`cat FULL_VERSION` - else if test -f $srcdir/FULL_VERSION; then - VERSION=`cat $srcdir/FULL_VERSION` - else - VERSION=`cat $srcdir/VERSION` - fi - fi AC_MSG_NOTICE("version: $VERSION") ]) @@ -49,7 +66,7 @@ AC_DEFUN([AMANDA_SNAPSHOT_STAMP], # DESCRIPTION # # Set the version number of this release of Amanda from the VERSION -# string, which is set in AM_INIT_AUTOMAKE. Sets VERSION_MAJOR, +# string, which is set in AC_INIT. Sets VERSION_MAJOR, # VERSION_MINOR, VERSION_PATCH, and VERSION_COMMENT to the # corresponding components of VERSION. These four variables are # also AC_DEFINE'd diff --git a/config/automake/scripts.am b/config/automake/scripts.am index 7d38cf3..3997189 100644 --- a/config/automake/scripts.am +++ b/config/automake/scripts.am @@ -1,5 +1,5 @@ # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/config/automake/vars.am b/config/automake/vars.am index ea75add..00d24e8 100644 --- a/config/automake/vars.am +++ b/config/automake/vars.am @@ -1,5 +1,5 @@ # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/config/config.h.in b/config/config.h.in index d91daf7..c2557ce 100644 --- a/config/config.h.in +++ b/config/config.h.in @@ -1820,6 +1820,15 @@ /* Defined if libcurl supports TFTP */ #undef LIBCURL_PROTOCOL_TFTP +/* Defined if libcurl use GnuTLS */ +#undef LIBCURL_USE_GNUTLS + +/* Defined if libcurl use NSS */ +#undef LIBCURL_USE_NSS + +/* Defined if libcurl use OpenSSL */ +#undef LIBCURL_USE_OPENSSL + /* A comma-separated list of two integers, determining the minimum and maximum * reserved TCP port numbers sockets should be bound to. (mainly for amrecover) */ diff --git a/config/macro-archive/docbook-dtd.m4 b/config/macro-archive/docbook-dtd.m4 index b2d269b..db6eae4 100644 --- a/config/macro-archive/docbook-dtd.m4 +++ b/config/macro-archive/docbook-dtd.m4 @@ -32,7 +32,7 @@ # # COPYRIGHT # -# Copyright (c) 2007,2008 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/config/macro-archive/docbook-xslt-min.m4 b/config/macro-archive/docbook-xslt-min.m4 index 453c79c..5ac1b08 100644 --- a/config/macro-archive/docbook-xslt-min.m4 +++ b/config/macro-archive/docbook-xslt-min.m4 @@ -27,7 +27,7 @@ # # COPYRIGHT # -# Copyright (c) 2007,2008 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/config/macro-archive/docbook-xslt.m4 b/config/macro-archive/docbook-xslt.m4 index 36788de..4c3f4df 100644 --- a/config/macro-archive/docbook-xslt.m4 +++ b/config/macro-archive/docbook-xslt.m4 @@ -32,7 +32,7 @@ # # COPYRIGHT # -# Copyright (c) 2007,2008 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/config/macro-archive/xsltproc.m4 b/config/macro-archive/xsltproc.m4 index 12a2bd7..386a34c 100644 --- a/config/macro-archive/xsltproc.m4 +++ b/config/macro-archive/xsltproc.m4 @@ -27,7 +27,7 @@ # # COPYRIGHT # -# Copyright (c) 2007,2008 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/configure b/configure index a8b2b55..c0e7761 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68. +# Generated by GNU Autoconf 2.68 for amanda 3.3.2. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -565,12 +565,12 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= -PACKAGE_URL= +PACKAGE_NAME='amanda' +PACKAGE_TARNAME='amanda' +PACKAGE_VERSION='3.3.2' +PACKAGE_STRING='amanda 3.3.2' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' ac_unique_file="common-src/amanda.h" # Factoring default headers for most tests. @@ -664,6 +664,9 @@ LIBTOOL AMANDA_SWIG_PERL_CFLAGS GCC_COMPILER_FALSE GCC_COMPILER_TRUE +NETCAT +NC6 +NC RPCGEN PS_ARGUMENT_ARGS PS_ARGUMENT @@ -1644,7 +1647,7 @@ sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE}' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' @@ -2146,7 +2149,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. +\`configure' configures amanda 3.3.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -2194,7 +2197,7 @@ Fine tuning of the installation directories: --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --docdir=DIR documentation root [DATAROOTDIR/doc/amanda] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -2215,7 +2218,9 @@ _ACEOF fi if test -n "$ac_init_help"; then - + case $ac_init_help in + short | recursive ) echo "Configuration of amanda 3.3.2:";; + esac cat <<\_ACEOF Optional Features: @@ -2490,7 +2495,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -configure +amanda configure 3.3.2 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -3190,7 +3195,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by $as_me, which was +It was created by amanda $as_me 3.3.2, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -3883,14 +3888,6 @@ $as_echo "not available" >&6; } rm -f conftemp.git - if test -f FULL_VERSION; then - VERSION=`cat FULL_VERSION` - else if test -f $srcdir/FULL_VERSION; then - VERSION=`cat $srcdir/FULL_VERSION` - else - VERSION=`cat $srcdir/VERSION` - fi - fi { $as_echo "$as_me:${as_lineno-$LINENO}: \"version: $VERSION\"" >&5 $as_echo "$as_me: \"version: $VERSION\"" >&6;} @@ -4332,8 +4329,8 @@ fi # Define the identity of the package. - PACKAGE=amanda - VERSION=$VERSION + PACKAGE='amanda' + VERSION='3.3.2' cat >>confdefs.h <<_ACEOF @@ -4367,7 +4364,88 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} AMTAR=${AMTAR-"${am_missing_run}tar"} -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a ustar tar archive" >&5 +$as_echo_n "checking how to create a ustar tar archive... " >&6; } +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar plaintar pax cpio none' +_am_tools=${am_cv_prog_tar_ustar-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + { echo "$as_me:$LINENO: $_am_tar --version" >&5 + ($_am_tar --version) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && break + done + am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=ustar -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x ustar -w "$$tardir"' + am__tar_='pax -L -x ustar -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H ustar -L' + am__tar_='find "$tardir" -print | cpio -o -H ustar -L' + am__untar='cpio -i -H ustar -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_ustar}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5 + (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + rm -rf conftest.dir + if test -s conftest.tar; then + { echo "$as_me:$LINENO: $am__untar &5 + ($am__untar &5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +if ${am_cv_prog_tar_ustar+:} false; then : + $as_echo_n "(cached) " >&6 +else + am_cv_prog_tar_ustar=$_am_tool +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_ustar" >&5 +$as_echo "$am_cv_prog_tar_ustar" >&6; } @@ -28418,6 +28496,128 @@ fi + # Extract the first word of "nc", so it can be a program name with args. +set dummy nc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_NC+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $NC in + [\\/]* | ?:[\\/]*) + ac_cv_path_NC="$NC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $LOCSYSPATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_NC="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +NC=$ac_cv_path_NC +if test -n "$NC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NC" >&5 +$as_echo "$NC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + # Extract the first word of "nc6", so it can be a program name with args. +set dummy nc6; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_NC6+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $NC6 in + [\\/]* | ?:[\\/]*) + ac_cv_path_NC6="$NC6" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $LOCSYSPATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_NC6="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +NC6=$ac_cv_path_NC6 +if test -n "$NC6"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NC6" >&5 +$as_echo "$NC6" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + # Extract the first word of "netcat", so it can be a program name with args. +set dummy netcat; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_NETCAT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $NETCAT in + [\\/]* | ?:[\\/]*) + ac_cv_path_NETCAT="$NETCAT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $LOCSYSPATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_NETCAT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +NETCAT=$ac_cv_path_NETCAT +if test -n "$NETCAT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NETCAT" >&5 +$as_echo "$NETCAT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + # # Compiler / system characteristics @@ -44270,6 +44470,47 @@ _ACEOF unset LIBCURL unset LIBCURL_CPPFLAGS fi + fi + + LIBCURL_USE_NSS=no + LIBCURL_USE_GNUTLS=no + LIBCURL_USE_OPENSSL=yes + _libcurl_configures=`$_libcurl_config --configure` + for _libcurl_configure in $_libcurl_configures ; do + if [[ $_libcurl_configure = \'--with-nss* ]]; then + LIBCURL_USE_NSS=yes + fi + if [[ $_libcurl_configure = \'--without-nss* ]]; then + LIBCURL_USE_NSS=no + fi + if [[ $_libcurl_configure = \'--with-gnutls* ]]; then + LIBCURL_USE_GNUTLS=yes + fi + if [[ $_libcurl_configure = \'--without-gnutls* ]]; then + LIBCURL_USE_GNUTLS=no + fi + if [[ $_libcurl_configure = \'--with-ssl* ]]; then + LIBCURL_USE_OPENSSL=yes + fi + if [[ $_libcurl_configure = \'--without-ssl* ]]; then + LIBCURL_USE_OPENSSL=no + fi + done + + if test "x$LIBCURL_USE_NSS" = "xyes"; then + +$as_echo "#define LIBCURL_USE_NSS 1" >>confdefs.h + + fi + if test "x$LIBCURL_USE_GNUTLS" = "xyes"; then + +$as_echo "#define LIBCURL_USE_GNUTLS /**/" >>confdefs.h + + fi + if test "x$LIBCURL_USE_OPENSSL" = "xyes"; then + +$as_echo "#define LIBCURL_USE_OPENSSL 1" >>confdefs.h + fi unset _libcurl_try_link @@ -44281,6 +44522,8 @@ _ACEOF unset _libcurl_protocols unset _libcurl_version unset _libcurl_ldflags + unset _libcurl_configure + unset _libcurl_configures fi if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then @@ -45494,7 +45737,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by $as_me, which was +This file was extended by amanda $as_me 3.3.2, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -45560,7 +45803,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -config.status +amanda config.status 3.3.2 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/configure.in b/configure.in index 1030009..72c255d 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,5 @@ -AC_INIT +AMANDA_INIT_VERSION +AC_INIT([amanda], [AMANDA_F_VERSION]) AC_CONFIG_SRCDIR([common-src/amanda.h]) AC_CONFIG_AUX_DIR(config) AC_CONFIG_MACRO_DIR(config) @@ -8,11 +9,11 @@ PACKAGE=amanda AC_SUBST(PACKAGE) AMANDA_VERSION -AM_INIT_AUTOMAKE(amanda, $VERSION) +AM_INIT_AUTOMAKE(tar-ustar 1.10) AC_CONFIG_HEADERS([config/config.h]) dnl Minimum Autoconf version required. -AC_PREREQ(2.59) +AC_PREREQ(2.64) # # Take care of some early Amanda-specific setup @@ -145,6 +146,7 @@ AMANDA_PROG_PERL AMANDA_PROG_SWIG AMANDA_PS_ARGUMENT AMANDA_PROG_RPCGEN +AMANDA_PROG_NC dnl ------------------------------------------------------------------------- diff --git a/device-src/Makefile.in b/device-src/Makefile.in index 3900ade..1e2d68d 100644 --- a/device-src/Makefile.in +++ b/device-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda tape library. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -40,7 +40,7 @@ # scripts in this directory. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -300,7 +300,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -893,6 +894,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/device-src/amdevcheck.pl b/device-src/amdevcheck.pl index 7839264..43cfa98 100644 --- a/device-src/amdevcheck.pl +++ b/device-src/amdevcheck.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/device-src/amtapetype.pl b/device-src/amtapetype.pl index ef40d57..8e38957 100644 --- a/device-src/amtapetype.pl +++ b/device-src/amtapetype.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/device-src/device.c b/device-src/device.c index f0258d5..2413dfc 100644 --- a/device-src/device.c +++ b/device-src/device.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -526,6 +526,7 @@ device_open (char * device_name) device = factory(device_name, device_type, device_node); g_assert(device != NULL); /* factories must always return a device */ + device->device_mutex = g_mutex_new(); amfree(device_type); amfree(device_node); @@ -1116,6 +1117,46 @@ device_finish (Device * self) { return (klass->finish)(self); } +guint64 +device_get_bytes_read (Device * self) { + DeviceClass *klass; + guint64 bytes = 0; + + g_assert(IS_DEVICE (self)); + + g_mutex_lock(self->device_mutex); + if (self->in_file) { + klass = DEVICE_GET_CLASS(self); + if (klass->get_bytes_read) { + bytes = (klass->get_bytes_read)(self); + } else { + bytes = self->bytes_read; + } + } + g_mutex_unlock(self->device_mutex); + return bytes; +} + +guint64 +device_get_bytes_written (Device * self) { + DeviceClass *klass; + guint64 bytes = 0; + + g_assert(IS_DEVICE (self)); + + g_mutex_lock(self->device_mutex); + if (self->in_file) { + klass = DEVICE_GET_CLASS(self); + if (klass->get_bytes_written) { + bytes = (klass->get_bytes_written)(self); + } else { + bytes = self->bytes_written; + } + } + g_mutex_unlock(self->device_mutex); + return bytes; +} + gboolean device_configure (Device * self, gboolean use_global_config) { @@ -1392,6 +1433,26 @@ device_accept( } } +gboolean +device_accept_with_cond( + Device *self, + DirectTCPConnection **conn, + GMutex *abort_mutex, + GCond *abort_cond) +{ + DeviceClass *klass; + + klass = DEVICE_GET_CLASS(self); + if(klass->accept_with_cond) { + return (klass->accept_with_cond)(self, conn, abort_mutex, abort_cond); + } else { + device_set_error(self, + g_strdup(_("Unimplemented method")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } +} + gboolean device_connect( Device *self, @@ -1414,6 +1475,28 @@ device_connect( } } +gboolean +device_connect_with_cond( + Device *self, + gboolean for_writing, + DirectTCPAddr *addrs, + DirectTCPConnection **conn, + GMutex *abort_mutex, + GCond *abort_cond) +{ + DeviceClass *klass; + + klass = DEVICE_GET_CLASS(self); + if(klass->connect) { + return (klass->connect_with_cond)(self, for_writing, addrs, conn, abort_mutex, abort_cond); + } else { + device_set_error(self, + g_strdup(_("Unimplemented method")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } +} + gboolean device_write_from_connection( Device *self, diff --git a/device-src/device.h b/device-src/device.h index 57f6b37..0945b0b 100644 --- a/device-src/device.h +++ b/device-src/device.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -91,6 +91,11 @@ typedef struct Device { /* You can peek at the stuff below, but only subclasses should change these values.*/ + /* A mutex to protect field accessed from another thread. + * Only get_bytes_read and get_bytes_written are allowed from another + * Only in_file, bytes_read and bytes_written are protected */ + GMutex *device_mutex; + /* What file, block are we at? (and are we in the middle of a file?) */ int file; guint64 block; @@ -134,6 +139,9 @@ typedef struct Device { gsize block_size; gsize header_block_size; + guint64 bytes_read; + guint64 bytes_written; + /* surety and source for the block size; if you set block_size directly, * set these, too! */ PropertySurety block_size_surety; @@ -193,13 +201,20 @@ struct _DeviceClass { gboolean (* erase) (Device * self); gboolean (* eject) (Device * self); gboolean (* finish) (Device * self); + guint64 (* get_bytes_read) (Device * self); + guint64 (* get_bytes_written) (Device * self); gboolean (* listen)(Device *self, gboolean for_writing, DirectTCPAddr **addrs); gboolean (* accept)(Device *self, DirectTCPConnection **conn, ProlongProc prolong, gpointer prolong_data); + int (* accept_with_cond)(Device *self, DirectTCPConnection **conn, + GMutex *abort_mutex, GCond *abort_cond); gboolean (* connect)(Device *self, gboolean for_writing, DirectTCPAddr *addrs, DirectTCPConnection **conn, ProlongProc prolong, gpointer prolong_data); + gboolean (* connect_with_cond)(Device *self, gboolean for_writing, + DirectTCPAddr *addrs, DirectTCPConnection **conn, + GMutex *abort_mutex, GCond *abort_cond); gboolean (* write_from_connection)(Device *self, guint64 size, guint64 *actual_size); gboolean (* read_to_connection)(Device *self, guint64 size, guint64 *actual_size); gboolean (* use_connection)(Device *self, DirectTCPConnection *conn); @@ -294,6 +309,8 @@ gboolean device_start (Device * self, DeviceAccessMode mode, char * label, char * timestamp); gboolean device_finish (Device * self); +guint64 device_get_bytes_read (Device * self); +guint64 device_get_bytes_written(Device * self); gboolean device_start_file (Device * self, dumpfile_t * jobInfo); gboolean device_write_block (Device * self, @@ -331,9 +348,14 @@ gboolean device_eject (Device * self); gboolean device_listen(Device *self, gboolean for_writing, DirectTCPAddr **addrs); gboolean device_accept(Device *self, DirectTCPConnection **conn, ProlongProc prolong, gpointer prolong_data); +int device_accept_with_cond(Device *self, DirectTCPConnection **conn, + GMutex *abort_mutex, GCond *abort_cond); gboolean device_connect(Device *self, gboolean for_writing, DirectTCPAddr *addrs, DirectTCPConnection **conn, ProlongProc prolong, gpointer prolong_data); +gboolean device_connect_with_cond(Device *self, gboolean for_writing, + DirectTCPAddr *addrs, DirectTCPConnection **conn, + GMutex *abort_mutex, GCond *abort_cond); gboolean device_write_from_connection(Device *self, guint64 size, guint64 *actual_size); gboolean device_read_to_connection(Device *self, guint64 size, guint64 *actual_size); gboolean device_use_connection(Device *self, DirectTCPConnection *conn); diff --git a/device-src/directtcp-connection.c b/device-src/directtcp-connection.c index a7ce071..442fd8a 100644 --- a/device-src/directtcp-connection.c +++ b/device-src/directtcp-connection.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/device-src/directtcp-connection.h b/device-src/directtcp-connection.h index 89c0894..8961626 100644 --- a/device-src/directtcp-connection.h +++ b/device-src/directtcp-connection.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/device-src/ndmp-device.c b/device-src/ndmp-device.c index f4e39bd..865f740 100644 --- a/device-src/ndmp-device.c +++ b/device-src/ndmp-device.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -22,8 +22,10 @@ #include "util.h" #include "device.h" #include "directtcp.h" +#include "stream.h" #include "ndmlib.h" #include "ndmpconnobj.h" +#include "sockaddr-util.h" /* * Type checking and casting macros @@ -54,6 +56,10 @@ struct NdmpDevice_ { DirectTCPAddr *listen_addrs; gboolean for_writing; + /* support for IndirectTCP */ + int indirecttcp_sock; /* -1 if not in use */ + int indirect; + /* Current DirectTCPConnectionNDMP */ struct DirectTCPConnectionNDMP_ *directtcp_conn; @@ -136,9 +142,11 @@ typedef enum { static DevicePropertyBase device_property_ndmp_username; static DevicePropertyBase device_property_ndmp_password; static DevicePropertyBase device_property_ndmp_auth; +static DevicePropertyBase device_property_indirect; #define PROPERTY_NDMP_USERNAME (device_property_ndmp_username.ID) #define PROPERTY_NDMP_PASSWORD (device_property_ndmp_password.ID) #define PROPERTY_NDMP_AUTH (device_property_ndmp_auth.ID) +#define PROPERTY_INDIRECT (device_property_indirect.ID) /* @@ -453,6 +461,8 @@ static void ndmp_device_finalize(GObject * obj_self) g_free(self->ndmp_password); if (self->ndmp_auth) g_free(self->ndmp_auth); + if (self->indirecttcp_sock != -1) + close(self->indirecttcp_sock); } static DeviceStatusFlags @@ -580,7 +590,9 @@ ndmp_device_start( } dself->access_mode = mode; + g_mutex_lock(dself->device_mutex); dself->in_file = FALSE; + g_mutex_unlock(dself->device_mutex); if (!single_ndmp_mtio(self, NDMP9_MTIO_REW)) { /* single_ndmp_mtio already set our error message */ @@ -714,6 +726,9 @@ ndmp_device_start_file( dself->is_eof = FALSE; dself->is_eom = FALSE; + g_mutex_lock(dself->device_mutex); + dself->bytes_written = 0; + g_mutex_unlock(dself->device_mutex); /* set the blocksize in the header properly */ header->blocksize = dself->block_size; @@ -751,7 +766,9 @@ ndmp_device_start_file( amfree(header_buf); /* arrange the file numbers correctly */ + g_mutex_lock(dself->device_mutex); dself->in_file = TRUE; + g_mutex_unlock(dself->device_mutex); if (!ndmp_get_state(self)) { /* error already set by ndmp_get_state */ return FALSE; @@ -809,6 +826,9 @@ ndmp_device_write_block( } dself->block++; + g_mutex_lock(dself->device_mutex); + dself->bytes_written += size; + g_mutex_unlock(dself->device_mutex); if (replacement_buffer) g_free(replacement_buffer); return TRUE; @@ -823,7 +843,9 @@ ndmp_device_finish_file( if (device_in_error(dself)) return FALSE; /* we're not in a file anymore */ + g_mutex_lock(dself->device_mutex); dself->in_file = FALSE; + g_mutex_unlock(dself->device_mutex); if (!single_ndmp_mtio(self, NDMP9_MTIO_EOF)) { /* error was set by single_ndmp_mtio */ @@ -911,9 +933,14 @@ incomplete_bsf: } /* fix up status */ + g_mutex_lock(dself->device_mutex); dself->in_file = TRUE; + g_mutex_unlock(dself->device_mutex); dself->file = file; dself->block = 0; + g_mutex_lock(dself->device_mutex); + dself->bytes_read = 0; + g_mutex_unlock(dself->device_mutex); /* now read the header */ read_block_size = ndmp_device_read_size(self); @@ -988,10 +1015,37 @@ ndmp_device_read_block (Device * dself, gpointer data, int *size_req) { } *size_req = (int)actual; /* cast is OK - requested size was < INT_MAX too */ + g_mutex_lock(dself->device_mutex); + dself->bytes_read += actual; + g_mutex_unlock(dself->device_mutex); return *size_req; } +static gboolean +indirecttcp_listen( + NdmpDevice *self, + DirectTCPAddr **addrs) +{ + in_port_t port; + + self->indirecttcp_sock = stream_server(AF_INET, &port, 0, STREAM_BUFSIZE, 0); + if (self->indirecttcp_sock < 0) { + device_set_error(DEVICE(self), + g_strdup_printf("Could not bind indirecttcp socket: %s", strerror(errno)), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + + /* An IndirectTCP address is 255.255.255.255:$port */ + self->listen_addrs = *addrs = g_new0(DirectTCPAddr, 2); + addrs[0]->sin.sin_family = AF_INET; + addrs[0]->sin.sin_addr.s_addr = htonl(0xffffffff); + SU_SET_PORT(addrs[0], port); + + return TRUE; +} + static gboolean listen_impl( Device *dself, @@ -1010,6 +1064,8 @@ listen_impl( return FALSE; } + self->for_writing = for_writing; + /* first, set the window to an empty span so that the mover doesn't start * reading or writing data immediately. NDMJOB tends to reset the record * size periodically (in direct contradiction to the spec), so we reset it @@ -1020,9 +1076,34 @@ listen_impl( return FALSE; } - if (!ndmp_connection_mover_set_window(self->ndmp, 0, 0)) { - set_error_from_ndmp(self); - return FALSE; + if (for_writing) { + /* if we're forcing indirecttcp, just do it */ + if (self->indirect) { + return indirecttcp_listen(self, addrs); + } + if (!ndmp_connection_mover_set_window(self->ndmp, 0, 0)) { + /* NDMP4_ILLEGAL_ARGS_ERR means the NDMP server doesn't like a zero-byte + * mover window, so we'll ignore it */ + if (ndmp_connection_err_code(self->ndmp) != NDMP4_ILLEGAL_ARGS_ERR) { + set_error_from_ndmp(self); + return FALSE; + } + + g_debug("NDMP Device: cannot set zero-length mover window; " + "falling back to IndirectTCP"); + /* In this case, we need to set up IndirectTCP */ + return indirecttcp_listen(self, addrs); + } + } else { + /* For reading, set the window to the second mover record, so that the + * mover will pause immediately when it wants to read the first mover + * record. */ + if (!ndmp_connection_mover_set_window(self->ndmp, + dself->block_size, + dself->block_size)) { + set_error_from_ndmp(self); + return FALSE; + } } /* then tell it to start listening */ @@ -1034,7 +1115,6 @@ listen_impl( return FALSE; } self->listen_addrs = *addrs; - self->for_writing = for_writing; return TRUE; } @@ -1106,35 +1186,175 @@ accept_impl( return FALSE; } + /* now we should expect a notice that the mover has paused */ + } else { + /* when writing, the mover will pause as soon as the first byte comes + * in, so there's no need to do anything to trigger the pause. + * + * Well, sometimes it won't - specifically, when it does not allow a + * zero-byte mover window, which means we've set up IndirectTCP. But in + * that case, there's nothing interesting to do here.*/ + } + + if (self->indirecttcp_sock == -1) { + /* NDMJOB sends NDMP9_MOVER_PAUSE_SEEK to indicate that it wants to write + * outside the window, while the standard specifies .._EOW, instead. When + * reading to a connection, we get the appropriate .._SEEK. It's easy + * enough to handle both. */ + + if (!ndmp_connection_wait_for_notify(self->ndmp, + NULL, + NULL, + &reason, &seek_position)) { + set_error_from_ndmp(self); + return FALSE; + } + + if (reason != NDMP9_MOVER_PAUSE_SEEK && reason != NDMP9_MOVER_PAUSE_EOW) { + device_set_error(DEVICE(self), + g_strdup_printf("got NOTIFY_MOVER_PAUSED, but not because of EOW or SEEK"), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + } + + /* at this point, if we're doing directtcp, the mover is paused and ready + * to go, and the listen addrs are no longer required; if we're doing + * indirecttcp, then the other end may not even know of our listen_addrs + * yet, so we can't free them. + */ + + if (self->indirecttcp_sock == -1) { + g_free(self->listen_addrs); + self->listen_addrs = NULL; + } + + if (self->for_writing) + mode = NDMP9_MOVER_MODE_READ; + else + mode = NDMP9_MOVER_MODE_WRITE; + + /* set up the new directtcp connection */ + if (self->directtcp_conn) + g_object_unref(self->directtcp_conn); + self->directtcp_conn = + directtcp_connection_ndmp_new(self->ndmp, mode); + *dtcpconn = DIRECTTCP_CONNECTION(self->directtcp_conn); + + /* reference it for the caller */ + g_object_ref(*dtcpconn); + + return TRUE; +} + +static int +accept_with_cond_impl( + Device *dself, + DirectTCPConnection **dtcpconn, + GMutex *abort_mutex, + GCond *abort_cond) +{ + NdmpDevice *self = NDMP_DEVICE(dself); + ndmp9_mover_state state; + guint64 bytes_moved; + ndmp9_mover_mode mode; + ndmp9_mover_pause_reason reason; + guint64 seek_position; + int result; + + if (device_in_error(self)) return 1; + + g_assert(self->listen_addrs); + + *dtcpconn = NULL; + + if (!self->for_writing) { + /* when reading, we don't get any kind of notification that the + * connection has been established, but we can't call NDMP_MOVER_READ + * until the mover is active. So we have to poll, waiting for ACTIVE. + * This is ugly. */ + gulong backoff = G_USEC_PER_SEC/20; /* 5 msec */ + while (1) { + if (!ndmp_connection_mover_get_state(self->ndmp, + &state, &bytes_moved, NULL, NULL)) { + set_error_from_ndmp(self); + return 1; + } + + if (state != NDMP9_MOVER_STATE_LISTEN) + break; + + /* back off a little bit to give the other side time to breathe, + * but not more than one second */ + g_usleep(backoff); + backoff *= 2; + if (backoff > G_USEC_PER_SEC) + backoff = G_USEC_PER_SEC; + } + + /* double-check state */ + if (state != NDMP9_MOVER_STATE_ACTIVE) { + device_set_error(DEVICE(self), + g_strdup("mover did not enter the ACTIVE state as expected"), + DEVICE_STATUS_DEVICE_ERROR); + return 1; + } + + /* now, we need to get this into the PAUSED state, since right now we + * aren't allowed to perform any tape movement commands. So we issue a + * MOVER_READ request for the whole darn image stream after setting the + * usual empty window. Note that this means the whole dump will be read + * in one MOVER_READ operation, even if it does not begin at the + * beginning of a part. */ + if (!ndmp_connection_mover_read(self->ndmp, 0, G_MAXUINT64)) { + set_error_from_ndmp(self); + return 1; + } + /* now we should expect a notice that the mover has paused */ } else { /* when writing, the mover will pause as soon as the first byte comes * in, so there's no need to do anything to trigger the pause. */ } + if (self->indirecttcp_sock == -1) { + /* NDMJOB sends NDMP9_MOVER_PAUSE_SEEK to indicate that it wants to + * write outside the window, while the standard specifies .._EOW, + * instead. When reading to a connection, we get the appropriate + * .._SEEK. It's easy enough to handle both. */ + result = ndmp_connection_wait_for_notify_with_cond(self->ndmp, + NULL, + NULL, + &reason, &seek_position, + abort_mutex, abort_cond); + + if (result == 1) { + set_error_from_ndmp(self); + return 1; + } else if (result == 2) { + return 2; + } + + if (reason != NDMP9_MOVER_PAUSE_SEEK && + reason != NDMP9_MOVER_PAUSE_EOW) { + device_set_error(DEVICE(self), + g_strdup_printf( + "got NOTIFY_MOVER_PAUSED, but not because of EOW or SEEK"), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + } + /* NDMJOB sends NDMP9_MOVER_PAUSE_SEEK to indicate that it wants to write * outside the window, while the standard specifies .._EOW, instead. When * reading to a connection, we get the appropriate .._SEEK. It's easy * enough to handle both. */ - if (!ndmp_connection_wait_for_notify(self->ndmp, - NULL, - NULL, - &reason, &seek_position)) { - set_error_from_ndmp(self); - return FALSE; - } - - if (reason != NDMP9_MOVER_PAUSE_SEEK && reason != NDMP9_MOVER_PAUSE_EOW) { - device_set_error(DEVICE(self), - g_strdup_printf("got NOTIFY_MOVER_PAUSED, but not because of EOW or SEEK"), - DEVICE_STATUS_DEVICE_ERROR); - return FALSE; + if (self->indirecttcp_sock == -1) { + g_free(self->listen_addrs); + self->listen_addrs = NULL; } - g_free(self->listen_addrs); - self->listen_addrs = NULL; - if (self->for_writing) mode = NDMP9_MOVER_MODE_READ; else @@ -1150,7 +1370,7 @@ accept_impl( /* reference it for the caller */ g_object_ref(*dtcpconn); - return TRUE; + return 0; } static gboolean @@ -1260,6 +1480,191 @@ connect_impl( return TRUE; } +static gboolean +connect_with_cond_impl( + Device *dself, + gboolean for_writing, + DirectTCPAddr *addrs, + DirectTCPConnection **dtcpconn, + GMutex *abort_mutex, + GCond *abort_cond) +{ + NdmpDevice *self = NDMP_DEVICE(dself); + ndmp9_mover_mode mode; + ndmp9_mover_pause_reason reason; + guint64 seek_position; + int result; + + g_assert(!self->listen_addrs); + + *dtcpconn = NULL; + self->for_writing = for_writing; + + if (!open_tape_agent(self)) { + /* error message was set by open_tape_agent */ + return 1; + } + + /* first, set the window to an empty span so that the mover doesn't start + * reading or writing data immediately. NDMJOB tends to reset the record + * size periodically (in direct contradiction to the spec), so we reset it + * here as well. */ + if (!ndmp_connection_mover_set_record_size(self->ndmp, + DEVICE(self)->block_size)) { + set_error_from_ndmp(self); + return 1; + } + + if (!ndmp_connection_mover_set_window(self->ndmp, 0, 0)) { + set_error_from_ndmp(self); + return 1; + } + + if (self->for_writing) + mode = NDMP9_MOVER_MODE_READ; + else + mode = NDMP9_MOVER_MODE_WRITE; + + if (!ndmp_connection_mover_connect(self->ndmp, mode, addrs)) { + set_error_from_ndmp(self); + return 1; + } + + if (!self->for_writing) { + /* The agent is in the ACTIVE state, and will remain so until we tell + * it to do something else. The thing we want to is for it to start + * reading data from the tape, which will immediately trigger an EOW or + * SEEK pause. */ + if (!ndmp_connection_mover_read(self->ndmp, 0, G_MAXUINT64)) { + set_error_from_ndmp(self); + return 1; + } + + /* now we should expect a notice that the mover has paused */ + } else { + /* when writing, the mover will pause as soon as the first byte comes + * in, so there's no need to do anything to trigger the pause. */ + } + + /* NDMJOB sends NDMP9_MOVER_PAUSE_SEEK to indicate that it wants to write + * outside the window, while the standard specifies .._EOW, instead. When + * reading to a connection, we get the appropriate .._SEEK. It's easy + * enough to handle both. */ + + result = ndmp_connection_wait_for_notify_with_cond(self->ndmp, + NULL, + NULL, + &reason, &seek_position, + abort_mutex, abort_cond); + + if (result == 1) { + set_error_from_ndmp(self); + return 1; + } else if (result == 2) { + return 2; + } + + if (reason != NDMP9_MOVER_PAUSE_SEEK && reason != NDMP9_MOVER_PAUSE_EOW) { + device_set_error(DEVICE(self), + g_strdup_printf("got NOTIFY_MOVER_PAUSED, but not because of EOW or SEEK"), + DEVICE_STATUS_DEVICE_ERROR); + return 1; + } + + if (self->listen_addrs) { + g_free(self->listen_addrs); + self->listen_addrs = NULL; + } + + /* set up the new directtcp connection */ + if (self->directtcp_conn) + g_object_unref(self->directtcp_conn); + self->directtcp_conn = + directtcp_connection_ndmp_new(self->ndmp, mode); + *dtcpconn = DIRECTTCP_CONNECTION(self->directtcp_conn); + + /* reference it for the caller */ + g_object_ref(*dtcpconn); + + return 0; +} + +static gboolean +indirecttcp_start_writing( + NdmpDevice *self) +{ + DirectTCPAddr *real_addrs, *iter; + int conn_sock; + + /* The current state is that the other end is trying to connect to + * indirecttcp_sock. The mover remains IDLE, although its window is set + * correctly for the part we are about to write. */ + + g_debug("indirecttcp_start_writing, ready to accept"); + conn_sock = accept(self->indirecttcp_sock, NULL, NULL); + if (conn_sock < 0) { + device_set_error(DEVICE(self), + g_strdup_printf("Could not accept indirecttcp socket: %s", strerror(errno)), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + g_debug("indirecttcp_start_writing, accepted"); + + close(self->indirecttcp_sock); + self->indirecttcp_sock = -1; + + /* tell mover to start listening */ + g_assert(self->for_writing); + if (!ndmp_connection_mover_listen(self->ndmp, + NDMP4_MOVER_MODE_READ, + NDMP4_ADDR_TCP, + &real_addrs)) { + set_error_from_ndmp(self); + return FALSE; + } + + /* format the addresses and send them down the socket */ + for (iter = real_addrs; iter && SU_GET_FAMILY(iter) != 0; iter++) { + char inet[INET_ADDRSTRLEN]; + const char *addr; + char *addrspec; + + addr = inet_ntop(AF_INET, &iter->sin.sin_addr.s_addr, inet, 40); + + addrspec = g_strdup_printf("%s:%d%s", addr, SU_GET_PORT(iter), + SU_GET_FAMILY(iter+1) !=0? " ":""); + g_debug("indirecttcp_start_writing, send %s", addrspec); + if (full_write(conn_sock, addrspec, strlen(addrspec)) < strlen(addrspec)) { + device_set_error(DEVICE(self), + g_strdup_printf("writing to indirecttcp socket: %s", strerror(errno)), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + } + + /* close the socket for good. This ensures that the next call to + * write_from_connection_impl will not go through the mover setup process. + * */ + if (close(conn_sock) < 0) { + device_set_error(DEVICE(self), + g_strdup_printf("closing indirecttcp socket: %s", strerror(errno)), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + conn_sock = -1; + + /* and free the listen_addrs, since we didn't free them in accept_impl */ + if (self->listen_addrs) { + g_free(self->listen_addrs); + self->listen_addrs = NULL; + } + + /* Now it's up to the remote end to connect to the mover and start sending + * data. We won't get any notification when this happens, although we could + * in principle poll for such a thing. */ + return TRUE; +} + static gboolean write_from_connection_impl( Device *dself, @@ -1277,6 +1682,7 @@ write_from_connection_impl( if (device_in_error(self)) return FALSE; + g_debug("write_from_connection_impl"); if (actual_size) *actual_size = 0; @@ -1291,9 +1697,20 @@ write_from_connection_impl( return FALSE; } - /* the mover had best be PAUSED right now */ - g_assert(mover_state == NDMP9_MOVER_STATE_PAUSED); + if (self->indirecttcp_sock != -1) { + /* If we're doing IndirectTCP, then we've deferred the whole + * mover_set_window mover_listen process.. until now. + * So the mover should be IDLE. + */ + g_assert(mover_state == NDMP9_MOVER_STATE_IDLE); + } else { + /* the mover had best be PAUSED right now */ + g_assert(mover_state == NDMP9_MOVER_STATE_PAUSED); + } + /* we want to set the window regardless of whether this is directtcp or + * indirecttcp + */ if (!ndmp_connection_mover_set_window(self->ndmp, nconn->offset, size? size : G_MAXUINT64 - nconn->offset)) { @@ -1301,9 +1718,16 @@ write_from_connection_impl( return FALSE; } - if (!ndmp_connection_mover_continue(self->ndmp)) { - set_error_from_ndmp(self); - return FALSE; + /* for DirectTCP, we just tell the mover to continue; IndirectTCP is more complicated. */ + if (self->indirecttcp_sock != -1) { + if (!indirecttcp_start_writing(self)) { + return FALSE; + } + } else { + if (!ndmp_connection_mover_continue(self->ndmp)) { + set_error_from_ndmp(self); + return FALSE; + } } /* now wait for the mover to pause itself again, or halt on EOF or an error */ @@ -1407,6 +1831,9 @@ read_to_connection_impl( if (device_in_error(self)) return FALSE; + /* read_to_connection does not support IndirectTCP */ + g_assert(self->indirecttcp_sock == -1); + /* if this is false, then the caller did not use use_connection correctly */ g_assert(nconn != NULL); g_assert(self->ndmp == nconn->ndmp); @@ -1642,6 +2069,18 @@ ndmp_device_set_read_block_size_fn(Device *p_self, DevicePropertyBase *base G_GN val, surety, source); } +static gboolean +ndmp_device_set_indirect_fn(Device *dself, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source) +{ + NdmpDevice *self = NDMP_DEVICE(dself); + + self->indirect = g_value_get_boolean(val); + + return device_simple_property_set_fn(dself, base, val, surety, source); +} + static void ndmp_device_class_init(NdmpDeviceClass * c G_GNUC_UNUSED) { @@ -1667,7 +2106,9 @@ ndmp_device_class_init(NdmpDeviceClass * c G_GNUC_UNUSED) device_class->directtcp_supported = TRUE; device_class->listen = listen_impl; device_class->accept = accept_impl; + device_class->accept_with_cond = accept_with_cond_impl; device_class->connect = connect_impl; + device_class->connect_with_cond = connect_with_cond_impl; device_class->write_from_connection = write_from_connection_impl; device_class->read_to_connection = read_to_connection_impl; device_class->use_connection = use_connection_impl; @@ -1693,6 +2134,12 @@ ndmp_device_class_init(NdmpDeviceClass * c G_GNUC_UNUSED) PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_MASK, device_simple_property_get_fn, ndmp_device_set_verbose_fn); + + device_class_register_property(device_class, PROPERTY_INDIRECT, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_MASK, + device_simple_property_get_fn, + ndmp_device_set_indirect_fn); + device_class_register_property(device_class, PROPERTY_READ_BLOCK_SIZE, PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, device_simple_property_get_fn, @@ -1785,6 +2232,14 @@ ndmp_device_init(NdmpDevice *self) g_value_unset(&response); self->ndmp_auth = g_strdup("md5"); + g_value_init(&response, G_TYPE_BOOLEAN); + g_value_set_boolean(&response, FALSE); + device_set_simple_property(dself, PROPERTY_INDIRECT, + &response, PROPERTY_SURETY_GOOD, PROPERTY_SOURCE_DEFAULT); + g_value_unset(&response); + self->indirect = FALSE; + + self->indirecttcp_sock = -1; } static GType @@ -1844,6 +2299,10 @@ ndmp_device_register(void) device_property_fill_and_register(&device_property_ndmp_auth, G_TYPE_STRING, "ndmp_auth", "Authentication method for the NDMP agent - md5 (default), text, none, or void"); + device_property_fill_and_register(&device_property_indirect, + G_TYPE_BOOLEAN, "indirect", + "Use Indirect TCP mode, even if the NDMP server supports " + "window length 0"); } /* diff --git a/device-src/null-device.c b/device-src/null-device.c index 3f1bf34..d5f7106 100644 --- a/device-src/null-device.c +++ b/device-src/null-device.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -50,7 +50,6 @@ struct _NullDevice { typedef struct _NullDeviceClass NullDeviceClass; struct _NullDeviceClass { DeviceClass __parent__; - gboolean in_file; }; void null_device_register(void); @@ -237,7 +236,9 @@ null_device_start (Device * pself, DeviceAccessMode mode, if (device_in_error(self)) return FALSE; pself->access_mode = mode; + g_mutex_lock(pself->device_mutex); pself->in_file = FALSE; + g_mutex_unlock(pself->device_mutex); if (mode == ACCESS_WRITE) { pself->volume_label = newstralloc(pself->volume_label, label); @@ -266,7 +267,9 @@ static gboolean null_device_start_file(Device * d_self, dumpfile_t * jobInfo G_GNUC_UNUSED) { + g_mutex_lock(d_self->device_mutex); d_self->in_file = TRUE; + g_mutex_unlock(d_self->device_mutex); d_self->is_eom = FALSE; d_self->block = 0; if (d_self->file <= 0) @@ -294,6 +297,8 @@ static gboolean null_device_finish_file(Device * pself) { if (device_in_error(pself)) return FALSE; + g_mutex_lock(pself->device_mutex); pself->in_file = FALSE; + g_mutex_unlock(pself->device_mutex); return TRUE; } diff --git a/device-src/property.c b/device-src/property.c index e438dd5..c951724 100644 --- a/device-src/property.c +++ b/device-src/property.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/device-src/property.h b/device-src/property.h index c2ea8f0..15b3440 100644 --- a/device-src/property.h +++ b/device-src/property.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/device-src/rait-device.c b/device-src/rait-device.c index dda81fb..fa17458 100644 --- a/device-src/rait-device.c +++ b/device-src/rait-device.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -1222,7 +1222,9 @@ rait_device_start (Device * dself, DeviceAccessMode mode, char * label, return FALSE; dself->access_mode = mode; + g_mutex_lock(dself->device_mutex); dself->in_file = FALSE; + g_mutex_unlock(dself->device_mutex); amfree(dself->volume_label); amfree(dself->volume_time); dumpfile_free(dself->volume_header); @@ -1404,9 +1406,12 @@ rait_device_start_file (Device * dself, dumpfile_t * info) { return FALSE; } - dself->in_file = TRUE; g_assert(actual_file >= 1); dself->file = actual_file; + g_mutex_lock(dself->device_mutex); + dself->in_file = TRUE; + dself->bytes_written = 0; + g_mutex_unlock(dself->device_mutex); return TRUE; } @@ -1584,6 +1589,9 @@ rait_device_write_block (Device * dself, guint size, gpointer data) { return FALSE; } else { dself->block ++; + g_mutex_lock(dself->device_mutex); + dself->bytes_written += size; + g_mutex_unlock(dself->device_mutex); return TRUE; } @@ -1626,7 +1634,9 @@ rait_device_finish_file (Device * dself) { return FALSE; } + g_mutex_lock(dself->device_mutex); dself->in_file = FALSE; + g_mutex_unlock(dself->device_mutex); return TRUE; } @@ -1655,9 +1665,12 @@ rait_device_seek_file (Device * dself, guint file) { if (rait_device_in_error(self)) return NULL; - dself->in_file = FALSE; dself->is_eof = FALSE; dself->block = 0; + g_mutex_lock(dself->device_mutex); + dself->in_file = FALSE; + dself->bytes_read = 0; + g_mutex_unlock(dself->device_mutex); ops = g_ptr_array_sized_new(self->private->children->len); for (i = 0; i < self->private->children->len; i ++) { @@ -1722,7 +1735,9 @@ rait_device_seek_file (Device * dself, guint file) { } /* update our state */ + g_mutex_lock(dself->device_mutex); dself->in_file = in_file; + g_mutex_unlock(dself->device_mutex); dself->file = actual_file; return rval; @@ -1990,7 +2005,9 @@ rait_device_read_block (Device * dself, gpointer buf, int * size) { stralloc(_("EOF")), DEVICE_STATUS_SUCCESS); dself->is_eof = TRUE; + g_mutex_lock(dself->device_mutex); dself->in_file = FALSE; + g_mutex_unlock(dself->device_mutex); } else { device_set_error(dself, stralloc(_("All child devices failed to read, but not all are at eof")), @@ -2007,6 +2024,9 @@ rait_device_read_block (Device * dself, gpointer buf, int * size) { if (success) { dself->block++; *size = blocksize; + g_mutex_lock(dself->device_mutex); + dself->bytes_read += blocksize; + g_mutex_unlock(dself->device_mutex); return blocksize; } else { return -1; diff --git a/device-src/s3-device.c b/device-src/s3-device.c index 7a98750..8c545c3 100644 --- a/device-src/s3-device.c +++ b/device-src/s3-device.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -65,6 +65,7 @@ static GType s3_device_get_type (void); * Main object structure */ typedef struct _S3MetadataFile S3MetadataFile; +typedef struct _S3Device S3Device; typedef struct _S3_by_thread S3_by_thread; struct _S3_by_thread { @@ -77,9 +78,10 @@ struct _S3_by_thread { char volatile * volatile filename; DeviceStatusFlags volatile errflags; /* device_status */ char volatile * volatile errmsg; /* device error message */ + GMutex *now_mutex; + guint64 dlnow, ulnow; }; -typedef struct _S3Device S3Device; struct _S3Device { Device __parent__; @@ -99,11 +101,17 @@ struct _S3Device { char *swift_account_id; char *swift_access_key; + char *username; + char *password; + char *tenant_id; + char *tenant_name; + char *bucket_location; char *storage_class; char *host; char *service_path; char *server_side_encryption; + char *proxy; char *ca_info; @@ -118,9 +126,12 @@ struct _S3Device { /* Produce verbose output? */ gboolean verbose; + /* create the bucket? */ + gboolean create_bucket; + /* Use SSL? */ gboolean use_ssl; - gboolean openstack_swift_api; + S3_api s3_api; /* Throttling */ guint64 max_send_speed; @@ -131,6 +142,7 @@ struct _S3Device { guint64 volume_limit; gboolean enforce_volume_limit; gboolean use_subdomain; + gboolean use_s3_multi_delete; int nb_threads; int nb_threads_backup; @@ -142,6 +154,17 @@ struct _S3Device { GMutex *thread_idle_mutex; int next_block_to_read; GSList *keys; + + guint64 dltotal; + guint64 ultotal; + + /* google OAUTH2 */ + char *client_id; + char *client_secret; + char *refresh_token; + char *project_id; + + gboolean reuse_connection; }; /* @@ -191,6 +214,16 @@ static DevicePropertyBase device_property_swift_access_key; #define PROPERTY_SWIFT_ACCOUNT_ID (device_property_swift_account_id.ID) #define PROPERTY_SWIFT_ACCESS_KEY (device_property_swift_access_key.ID) +/* Authentication information for Openstack Swift. Both of these are strings. */ +static DevicePropertyBase device_property_username; +static DevicePropertyBase device_property_password; +static DevicePropertyBase device_property_tenant_id; +static DevicePropertyBase device_property_tenant_name; +#define PROPERTY_USERNAME (device_property_username.ID) +#define PROPERTY_PASSWORD (device_property_password.ID) +#define PROPERTY_TENANT_ID (device_property_tenant_id.ID) +#define PROPERTY_TENANT_NAME (device_property_tenant_name.ID) + /* Host and path */ static DevicePropertyBase device_property_s3_host; static DevicePropertyBase device_property_s3_service_path; @@ -209,15 +242,24 @@ static DevicePropertyBase device_property_s3_bucket_location; static DevicePropertyBase device_property_s3_storage_class; #define PROPERTY_S3_STORAGE_CLASS (device_property_s3_storage_class.ID) -/* Storage class */ +/* Server side encryption */ static DevicePropertyBase device_property_s3_server_side_encryption; #define PROPERTY_S3_SERVER_SIDE_ENCRYPTION (device_property_s3_server_side_encryption.ID) +/* proxy */ +static DevicePropertyBase device_property_proxy; +#define PROPERTY_PROXY (device_property_proxy.ID) + /* Path to certificate authority certificate */ static DevicePropertyBase device_property_ssl_ca_info; #define PROPERTY_SSL_CA_INFO (device_property_ssl_ca_info.ID) +/* Which strotage api to use. */ +static DevicePropertyBase device_property_storage_api; +#define PROPERTY_STORAGE_API (device_property_storage_api.ID) + /* Whether to use openstack protocol. */ +/* DEPRECATED */ static DevicePropertyBase device_property_openstack_swift_api; #define PROPERTY_OPENSTACK_SWIFT_API (device_property_openstack_swift_api.ID) @@ -225,6 +267,10 @@ static DevicePropertyBase device_property_openstack_swift_api; static DevicePropertyBase device_property_s3_ssl; #define PROPERTY_S3_SSL (device_property_s3_ssl.ID) +/* Whether to re-use connection. */ +static DevicePropertyBase device_property_reuse_connection; +#define PROPERTY_REUSE_CONNECTION (device_property_reuse_connection.ID) + /* Speed limits for sending and receiving */ static DevicePropertyBase device_property_max_send_speed; static DevicePropertyBase device_property_max_recv_speed; @@ -241,6 +287,30 @@ static DevicePropertyBase device_property_nb_threads_backup; static DevicePropertyBase device_property_nb_threads_recovery; #define PROPERTY_NB_THREADS_RECOVERY (device_property_nb_threads_recovery.ID) +/* If the s3 server have the multi-delete functionality */ +static DevicePropertyBase device_property_s3_multi_delete; +#define PROPERTY_S3_MULTI_DELETE (device_property_s3_multi_delete.ID) + +/* The client_id for OAUTH2 */ +static DevicePropertyBase device_property_client_id; +#define PROPERTY_CLIENT_ID (device_property_client_id.ID) + +/* The client_secret for OAUTH2 */ +static DevicePropertyBase device_property_client_secret; +#define PROPERTY_CLIENT_SECRET (device_property_client_secret.ID) + +/* The refresh token for OAUTH2 */ +static DevicePropertyBase device_property_refresh_token; +#define PROPERTY_REFRESH_TOKEN (device_property_refresh_token.ID) + +/* The PROJECT ID */ +static DevicePropertyBase device_property_project_id; +#define PROPERTY_PROJECT_ID (device_property_project_id.ID) + +/* The PROJECT ID */ +static DevicePropertyBase device_property_create_bucket; +#define PROPERTY_CREATE_BUCKET (device_property_create_bucket.ID) + /* * prototypes */ @@ -365,6 +435,22 @@ static gboolean s3_device_set_swift_access_key_fn(Device *self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source); +static gboolean s3_device_set_username(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + +static gboolean s3_device_set_password(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + +static gboolean s3_device_set_tenant_id(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + +static gboolean s3_device_set_tenant_name(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + static gboolean s3_device_set_user_token_fn(Device *self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source); @@ -381,6 +467,10 @@ static gboolean s3_device_set_server_side_encryption_fn(Device *self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source); +static gboolean s3_device_set_proxy_fn(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + static gboolean s3_device_set_ca_info_fn(Device *self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source); @@ -389,14 +479,30 @@ static gboolean s3_device_set_verbose_fn(Device *self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source); +static gboolean s3_device_set_create_bucket_fn(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + +static gboolean s3_device_set_storage_api(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + static gboolean s3_device_set_openstack_swift_api_fn(Device *self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source); +static gboolean s3_device_set_s3_multi_delete_fn(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + static gboolean s3_device_set_ssl_fn(Device *self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source); +static gboolean s3_device_set_reuse_connection_fn(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + static gboolean s3_device_set_max_send_speed_fn(Device *self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source); @@ -437,6 +543,22 @@ static gboolean s3_device_set_service_path_fn(Device *p_self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source); +static gboolean s3_device_set_client_id_fn(Device *p_self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + +static gboolean s3_device_set_client_secret_fn(Device *p_self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + +static gboolean s3_device_set_refresh_token_fn(Device *p_self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + +static gboolean s3_device_set_project_id_fn(Device *p_self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + static void s3_thread_read_block(gpointer thread_data, gpointer data); static void s3_thread_write_block(gpointer thread_data, @@ -465,6 +587,12 @@ s3_device_start(Device * self, static gboolean s3_device_finish(Device * self); +static guint64 +s3_device_get_bytes_read(Device * self); + +static guint64 +s3_device_get_bytes_written(Device * self); + static gboolean s3_device_start_file(Device * self, dumpfile_t * jobInfo); @@ -732,19 +860,21 @@ delete_file(S3Device *self, guint64 total_size = 0; Device *d_self = DEVICE(self); char *my_prefix; + if (file == -1) { my_prefix = g_strdup_printf("%sf", self->prefix); } else { my_prefix = g_strdup_printf("%sf%08x-", self->prefix, file); } - result = s3_list_keys(self->s3t[0].s3, self->bucket, my_prefix, NULL, &keys, - &total_size); + result = s3_list_keys(self->s3t[0].s3, self->bucket, my_prefix, NULL, + &keys, &total_size); if (!result) { device_set_error(d_self, - vstrallocf(_("While listing S3 keys: %s"), s3_strerror(self->s3t[0].s3)), - DEVICE_STATUS_DEVICE_ERROR | DEVICE_STATUS_VOLUME_ERROR); - return FALSE; + g_strdup_printf(_("While listing S3 keys: %s"), + s3_strerror(self->s3t[0].s3)), + DEVICE_STATUS_DEVICE_ERROR | DEVICE_STATUS_VOLUME_ERROR); + return FALSE; } g_mutex_lock(self->thread_idle_mutex); @@ -793,26 +923,70 @@ s3_thread_delete_block( S3_by_thread *s3t = (S3_by_thread *)thread_data; Device *pself = (Device *)data; S3Device *self = S3_DEVICE(pself); - gboolean result = 1; + int result = 1; char *filename; g_mutex_lock(self->thread_idle_mutex); while (result && self->keys) { - filename = self->keys->data; - self->keys = g_slist_remove(self->keys, self->keys->data); - count++; - if (count >= 1000) { - g_debug("Deleting %s ...", filename); - count = 0; - } - g_mutex_unlock(self->thread_idle_mutex); - result = s3_delete(s3t->s3, (const char *)self->bucket, (const char *)filename); - if (!result) { - s3t->errflags = DEVICE_STATUS_DEVICE_ERROR | DEVICE_STATUS_VOLUME_ERROR; - s3t->errmsg = g_strdup_printf(_("While deleting key '%s': %s"), + if (self->use_s3_multi_delete) { + char **filenames = g_new(char *, 1001); + char **f = filenames; + int n = 0; + while (self->keys && n<1000) { + *f++ = self->keys->data; + self->keys = g_slist_remove(self->keys, self->keys->data); + n++; + } + *f++ = NULL; + g_mutex_unlock(self->thread_idle_mutex); + result = s3_multi_delete(s3t->s3, (const char *)self->bucket, + (const char **)filenames); + if (result != 1) { + char **f; + + if (result == 2) { + g_debug("Deleting multiple keys not implemented"); + } else { /* result == 0 */ + g_debug("Deleteing multiple keys failed: %s", + s3_strerror(s3t->s3)); + } + + self->use_s3_multi_delete = 0; + /* re-add all filenames */ + f = filenames; + g_mutex_lock(self->thread_idle_mutex); + while(*f) { + self->keys = g_slist_prepend(self->keys, *f++); + } + g_mutex_unlock(self->thread_idle_mutex); + g_free(filenames); + result = 1; + g_mutex_lock(self->thread_idle_mutex); + continue; + } + f = filenames; + while(*f) { + g_free(*f++); + } + g_free(filenames); + } else { + filename = self->keys->data; + self->keys = g_slist_remove(self->keys, self->keys->data); + count++; + if (count >= 1000) { + g_debug("Deleting %s ...", filename); + count = 0; + } + g_mutex_unlock(self->thread_idle_mutex); + result = s3_delete(s3t->s3, (const char *)self->bucket, + (const char *)filename); + if (!result) { + s3t->errflags = DEVICE_STATUS_DEVICE_ERROR | DEVICE_STATUS_VOLUME_ERROR; + s3t->errmsg = g_strdup_printf(_("While deleting key '%s': %s"), filename, s3_strerror(s3t->s3)); + } + g_free(filename); } - g_free(filename); g_mutex_lock(self->thread_idle_mutex); } s3t->idle = 1; @@ -880,6 +1054,18 @@ s3_device_register(void) device_property_fill_and_register(&device_property_swift_access_key, G_TYPE_STRING, "swift_access_key", "Access key to authenticate with openstack swift"); + device_property_fill_and_register(&device_property_username, + G_TYPE_STRING, "username", + "Username to authenticate with"); + device_property_fill_and_register(&device_property_password, + G_TYPE_STRING, "password", + "password to authenticate with"); + device_property_fill_and_register(&device_property_tenant_id, + G_TYPE_STRING, "tenant_id", + "tenant_id to authenticate with"); + device_property_fill_and_register(&device_property_tenant_name, + G_TYPE_STRING, "tenant_name", + "tenant_name to authenticate with"); device_property_fill_and_register(&device_property_s3_host, G_TYPE_STRING, "s3_host", "hostname:port of the server"); @@ -898,15 +1084,39 @@ s3_device_register(void) device_property_fill_and_register(&device_property_s3_server_side_encryption, G_TYPE_STRING, "s3_server_side_encryption", "Serve side encryption as specified by Amazon (AES256)"); + device_property_fill_and_register(&device_property_proxy, + G_TYPE_STRING, "proxy", + "The proxy"); device_property_fill_and_register(&device_property_ssl_ca_info, G_TYPE_STRING, "ssl_ca_info", "Path to certificate authority certificate"); + device_property_fill_and_register(&device_property_storage_api, + G_TYPE_STRING, "storage_api", + "Which cloud API to use."); device_property_fill_and_register(&device_property_openstack_swift_api, - G_TYPE_BOOLEAN, "openstack_swift_api", + G_TYPE_STRING, "openstack_swift_api", "Whether to use openstack protocol"); + device_property_fill_and_register(&device_property_client_id, + G_TYPE_STRING, "client_id", + "client_id for use with oauth2"); + device_property_fill_and_register(&device_property_client_secret, + G_TYPE_STRING, "client_secret", + "client_secret for use with oauth2"); + device_property_fill_and_register(&device_property_refresh_token, + G_TYPE_STRING, "refresh_token", + "refresh_token for use with oauth2"); + device_property_fill_and_register(&device_property_project_id, + G_TYPE_STRING, "project_id", + "project id for use with google"); device_property_fill_and_register(&device_property_s3_ssl, G_TYPE_BOOLEAN, "s3_ssl", "Whether to use SSL with Amazon S3"); + device_property_fill_and_register(&device_property_reuse_connection, + G_TYPE_BOOLEAN, "reuse_connection", + "Whether to reuse connection"); + device_property_fill_and_register(&device_property_create_bucket, + G_TYPE_BOOLEAN, "create_bucket", + "Whether to create/delete bucket"); device_property_fill_and_register(&device_property_s3_subdomain, G_TYPE_BOOLEAN, "s3_subdomain", "Whether to use subdomain"); @@ -922,6 +1132,9 @@ s3_device_register(void) device_property_fill_and_register(&device_property_nb_threads_recovery, G_TYPE_UINT64, "nb_threads_recovery", "Number of reader thread"); + device_property_fill_and_register(&device_property_s3_multi_delete, + G_TYPE_BOOLEAN, "s3_multi_delete", + "Whether to use multi-delete"); /* register the device itself */ register_device(s3_device_factory, device_prefix_list); @@ -959,6 +1172,7 @@ s3_device_init(S3Device * self) Device * dself = DEVICE(self); GValue response; + self->s3_api = S3_API_S3; self->volume_bytes = 0; self->volume_limit = 0; self->leom = TRUE; @@ -972,6 +1186,7 @@ s3_device_init(S3Device * self) self->thread_pool_read = NULL; self->thread_idle_cond = NULL; self->thread_idle_mutex = NULL; + self->use_s3_multi_delete = 1; /* Register property values * Note: Some aren't added until s3_device_open_device() @@ -1052,6 +1267,8 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED) device_class->read_label = s3_device_read_label; device_class->start = s3_device_start; device_class->finish = s3_device_finish; + device_class->get_bytes_read = s3_device_get_bytes_read; + device_class->get_bytes_written = s3_device_get_bytes_written; device_class->start_file = s3_device_start_file; device_class->write_block = s3_device_write_block; @@ -1086,6 +1303,26 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED) device_simple_property_get_fn, s3_device_set_swift_access_key_fn); + device_class_register_property(device_class, PROPERTY_USERNAME, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_username); + + device_class_register_property(device_class, PROPERTY_PASSWORD, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_password); + + device_class_register_property(device_class, PROPERTY_TENANT_ID, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_tenant_id); + + device_class_register_property(device_class, PROPERTY_TENANT_NAME, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_tenant_name); + device_class_register_property(device_class, PROPERTY_S3_HOST, PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, device_simple_property_get_fn, @@ -1116,6 +1353,11 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED) device_simple_property_get_fn, s3_device_set_server_side_encryption_fn); + device_class_register_property(device_class, PROPERTY_PROXY, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_proxy_fn); + device_class_register_property(device_class, PROPERTY_SSL_CA_INFO, PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, device_simple_property_get_fn, @@ -1126,16 +1368,36 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED) device_simple_property_get_fn, s3_device_set_verbose_fn); + device_class_register_property(device_class, PROPERTY_CREATE_BUCKET, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_create_bucket_fn); + + device_class_register_property(device_class, PROPERTY_STORAGE_API, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_storage_api); + device_class_register_property(device_class, PROPERTY_OPENSTACK_SWIFT_API, PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, device_simple_property_get_fn, s3_device_set_openstack_swift_api_fn); + device_class_register_property(device_class, PROPERTY_S3_MULTI_DELETE, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_s3_multi_delete_fn); + device_class_register_property(device_class, PROPERTY_S3_SSL, PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, device_simple_property_get_fn, s3_device_set_ssl_fn); + device_class_register_property(device_class, PROPERTY_REUSE_CONNECTION, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_reuse_connection_fn); + device_class_register_property(device_class, PROPERTY_MAX_SEND_SPEED, PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, device_simple_property_get_fn, @@ -1179,10 +1441,29 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED) s3_device_set_enforce_max_volume_usage_fn); device_class_register_property(device_class, PROPERTY_S3_SUBDOMAIN, - (PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_MASK) & - (~ PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE), + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, device_simple_property_get_fn, s3_device_set_use_subdomain_fn); + + device_class_register_property(device_class, PROPERTY_CLIENT_ID, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_client_id_fn); + + device_class_register_property(device_class, PROPERTY_CLIENT_SECRET, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_client_secret_fn); + + device_class_register_property(device_class, PROPERTY_REFRESH_TOKEN, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_refresh_token_fn); + + device_class_register_property(device_class, PROPERTY_PROJECT_ID, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_project_id_fn); } static gboolean @@ -1237,6 +1518,58 @@ s3_device_set_swift_access_key_fn(Device *p_self, DevicePropertyBase *base, return device_simple_property_set_fn(p_self, base, val, surety, source); } +static gboolean +s3_device_set_username(Device *p_self, DevicePropertyBase *base, + GValue *val, PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + amfree(self->username); + self->username = g_value_dup_string(val); + device_clear_volume_details(p_self); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + +static gboolean +s3_device_set_password(Device *p_self, DevicePropertyBase *base, + GValue *val, PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + amfree(self->password); + self->password = g_value_dup_string(val); + device_clear_volume_details(p_self); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + +static gboolean +s3_device_set_tenant_id(Device *p_self, DevicePropertyBase *base, + GValue *val, PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + amfree(self->tenant_id); + self->tenant_id = g_value_dup_string(val); + device_clear_volume_details(p_self); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + +static gboolean +s3_device_set_tenant_name(Device *p_self, DevicePropertyBase *base, + GValue *val, PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + amfree(self->tenant_name); + self->tenant_name = g_value_dup_string(val); + device_clear_volume_details(p_self); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + static gboolean s3_device_set_host_fn(Device *p_self, DevicePropertyBase *base, GValue *val, @@ -1340,6 +1673,20 @@ s3_device_set_server_side_encryption_fn(Device *p_self, DevicePropertyBase *base return device_simple_property_set_fn(p_self, base, val, surety, source); } +static gboolean +s3_device_set_proxy_fn(Device *p_self, DevicePropertyBase *base, + GValue *val, PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + char *str_val = g_value_dup_string(val); + + amfree(self->proxy); + self->proxy = str_val; + device_clear_volume_details(p_self); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + static gboolean s3_device_set_ca_info_fn(Device *p_self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source) @@ -1373,13 +1720,73 @@ s3_device_set_verbose_fn(Device *p_self, DevicePropertyBase *base, return device_simple_property_set_fn(p_self, base, val, surety, source); } +static gboolean +s3_device_set_create_bucket_fn(Device *p_self, DevicePropertyBase *base, + GValue *val, PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + int thread; + + self->create_bucket = g_value_get_boolean(val); + /* Our S3 handle may not yet have been instantiated; if so, it will + * get the proper verbose setting when it is created */ + if (self->s3t) { + for (thread = 0; thread < self->nb_threads; thread++) { + if (self->s3t[thread].s3) + s3_verbose(self->s3t[thread].s3, self->verbose); + } + } + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + +static gboolean +s3_device_set_storage_api(Device *p_self, DevicePropertyBase *base, + GValue *val, PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + const char *storage_api = g_value_get_string(val); + if (g_str_equal(storage_api, "S3")) { + self->s3_api = S3_API_S3; + } else if (g_str_equal(storage_api, "SWIFT-1.0")) { + self->s3_api = S3_API_SWIFT_1; + } else if (g_str_equal(storage_api, "SWIFT-2.0")) { + self->s3_api = S3_API_SWIFT_2; + } else if (g_str_equal(storage_api, "OAUTH2")) { + self->s3_api = S3_API_OAUTH2; + } else { + g_debug("Invalid STORAGE_API, using \"S3\"."); + self->s3_api = S3_API_S3; + } + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + static gboolean s3_device_set_openstack_swift_api_fn(Device *p_self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source) { + + const gboolean openstack_swift_api = g_value_get_boolean(val); + if (openstack_swift_api) { + GValue storage_api_val; + g_value_init(&storage_api_val, G_TYPE_STRING); + g_value_set_static_string(&storage_api_val, "SWIFT-1.0"); + return s3_device_set_storage_api(p_self, base, &storage_api_val, + surety, source); + } + return TRUE; +} + +static gboolean +s3_device_set_s3_multi_delete_fn(Device *p_self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source) +{ S3Device *self = S3_DEVICE(p_self); - self->openstack_swift_api = g_value_get_boolean(val); + self->use_s3_multi_delete = g_value_get_boolean(val); return device_simple_property_set_fn(p_self, base, val, surety, source); } @@ -1411,6 +1818,17 @@ s3_device_set_ssl_fn(Device *p_self, DevicePropertyBase *base, return device_simple_property_set_fn(p_self, base, val, surety, source); } +static gboolean +s3_device_set_reuse_connection_fn(Device *p_self, DevicePropertyBase *base, + GValue *val, PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + self->reuse_connection = g_value_get_boolean(val); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + static gboolean s3_device_set_max_send_speed_fn(Device *p_self, DevicePropertyBase *base, GValue *val, @@ -1545,6 +1963,59 @@ property_set_leom_fn(Device *p_self, return device_simple_property_set_fn(p_self, base, val, surety, source); } + +static gboolean +s3_device_set_client_id_fn(Device *p_self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + amfree(self->client_id); + self->client_id = g_value_dup_string(val); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + +static gboolean +s3_device_set_client_secret_fn(Device *p_self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + amfree(self->client_secret); + self->client_secret = g_value_dup_string(val); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + +static gboolean +s3_device_set_refresh_token_fn(Device *p_self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + amfree(self->refresh_token); + self->refresh_token = g_value_dup_string(val); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + +static gboolean +s3_device_set_project_id_fn(Device *p_self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + amfree(self->project_id); + self->project_id = g_value_dup_string(val); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + static Device* s3_device_factory(char * device_name, char * device_type, char * device_node) { @@ -1596,7 +2067,7 @@ s3_device_open_device(Device *pself, char *device_name, /* default values */ self->verbose = FALSE; - self->openstack_swift_api = FALSE; + self->s3_api = S3_API_S3; /* use SSL if available */ self->use_ssl = s3_curl_supports_ssl(); @@ -1606,6 +2077,22 @@ s3_device_open_device(Device *pself, char *device_name, device_set_simple_property(pself, device_property_s3_ssl.ID, &tmp_value, PROPERTY_SURETY_GOOD, PROPERTY_SOURCE_DEFAULT); + /* reuse connection */ + self->reuse_connection = TRUE; + bzero(&tmp_value, sizeof(GValue)); + g_value_init(&tmp_value, G_TYPE_BOOLEAN); + g_value_set_boolean(&tmp_value, self->reuse_connection); + device_set_simple_property(pself, device_property_reuse_connection.ID, + &tmp_value, PROPERTY_SURETY_GOOD, PROPERTY_SOURCE_DEFAULT); + + /* Set default create_bucket */ + self->create_bucket = TRUE; + bzero(&tmp_value, sizeof(GValue)); + g_value_init(&tmp_value, G_TYPE_BOOLEAN); + g_value_set_boolean(&tmp_value, self->create_bucket); + device_set_simple_property(pself, device_property_create_bucket.ID, + &tmp_value, PROPERTY_SURETY_GOOD, PROPERTY_SOURCE_DEFAULT); + if (parent_class->open_device) { parent_class->open_device(pself, device_name, device_type, device_node); } @@ -1640,7 +2127,9 @@ static void s3_device_finalize(GObject * obj_self) { } if (self->s3t) { for (thread = 0; thread < self->nb_threads; thread++) { + g_mutex_free(self->s3t[thread].now_mutex); if(self->s3t[thread].s3) s3_free(self->s3t[thread].s3); + g_free(self->s3t[thread].curl_buffer.buffer); } g_free(self->s3t); } @@ -1650,12 +2139,17 @@ static void s3_device_finalize(GObject * obj_self) { if(self->secret_key) g_free(self->secret_key); if(self->swift_account_id) g_free(self->swift_account_id); if(self->swift_access_key) g_free(self->swift_access_key); + if(self->username) g_free(self->username); + if(self->password) g_free(self->password); + if(self->tenant_id) g_free(self->tenant_id); + if(self->tenant_name) g_free(self->tenant_name); if(self->host) g_free(self->host); if(self->service_path) g_free(self->service_path); if(self->user_token) g_free(self->user_token); if(self->bucket_location) g_free(self->bucket_location); if(self->storage_class) g_free(self->storage_class); if(self->server_side_encryption) g_free(self->server_side_encryption); + if(self->proxy) g_free(self->proxy); if(self->ca_info) g_free(self->ca_info); } @@ -1667,15 +2161,7 @@ static gboolean setup_handle(S3Device * self) { CURLcode curl_code; if (self->s3t == NULL) { - self->s3t = g_new(S3_by_thread, self->nb_threads); - if (self->s3t == NULL) { - device_set_error(d_self, - stralloc(_("Can't allocate S3Handle array")), - DEVICE_STATUS_DEVICE_ERROR); - return FALSE; - } - - if (!self->openstack_swift_api) { + if (self->s3_api == S3_API_S3) { if (self->access_key == NULL || self->access_key[0] == '\0') { device_set_error(d_self, g_strdup(_("No Amazon access key specified")), @@ -1689,7 +2175,7 @@ static gboolean setup_handle(S3Device * self) { DEVICE_STATUS_DEVICE_ERROR); return FALSE; } - } else { + } else if (self->s3_api == S3_API_SWIFT_1) { if (self->swift_account_id == NULL || self->swift_account_id[0] == '\0') { device_set_error(d_self, @@ -1704,10 +2190,53 @@ static gboolean setup_handle(S3Device * self) { DEVICE_STATUS_DEVICE_ERROR); return FALSE; } + } else if (self->s3_api == S3_API_SWIFT_2) { + if (!((self->username && self->password && self->tenant_id) || + (self->username && self->password && self->tenant_name) || + (self->access_key && self->secret_key && self->tenant_id) || + (self->access_key && self->secret_key && self->tenant_name))) { + device_set_error(d_self, + g_strdup(_("Missing authorization properties")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + } else if (self->s3_api == S3_API_OAUTH2) { + if (self->client_id == NULL || + self->client_id[0] == '\0') { + device_set_error(d_self, + g_strdup(_("Missing client_id properties")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + if (self->client_secret == NULL || + self->client_secret[0] == '\0') { + device_set_error(d_self, + g_strdup(_("Missing client_secret properties")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + if (self->refresh_token == NULL || + self->refresh_token[0] == '\0') { + device_set_error(d_self, + g_strdup(_("Missing refresh_token properties")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + if (self->project_id == NULL || + self->project_id[0] == '\0') { + device_set_error(d_self, + g_strdup(_("Missing project_id properties")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } } - if (!self->use_ssl && self->ca_info) { - amfree(self->ca_info); + self->s3t = g_new0(S3_by_thread, self->nb_threads); + if (self->s3t == NULL) { + device_set_error(d_self, + g_strdup(_("Can't allocate S3Handle array")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; } self->thread_idle_cond = g_cond_new(); @@ -1722,6 +2251,7 @@ static gboolean setup_handle(S3Device * self) { self->s3t[thread].filename = NULL; self->s3t[thread].curl_buffer.buffer = NULL; self->s3t[thread].curl_buffer.buffer_len = 0; + self->s3t[thread].now_mutex = g_mutex_new(); self->s3t[thread].s3 = s3_open(self->access_key, self->secret_key, self->swift_account_id, self->swift_access_key, @@ -1730,24 +2260,22 @@ static gboolean setup_handle(S3Device * self) { self->user_token, self->bucket_location, self->storage_class, self->ca_info, self->server_side_encryption, - self->openstack_swift_api); + self->proxy, + self->s3_api, + self->username, + self->password, + self->tenant_id, + self->tenant_name, + self->client_id, + self->client_secret, + self->refresh_token, + self->reuse_connection); if (self->s3t[thread].s3 == NULL) { device_set_error(d_self, stralloc(_("Internal error creating S3 handle")), DEVICE_STATUS_DEVICE_ERROR); self->nb_threads = thread+1; return FALSE; - } else if (self->openstack_swift_api) { - s3_error(self->s3t[0].s3, NULL, &response_code, - &s3_error_code, NULL, &curl_code, NULL); - if (response_code != 200) { - device_set_error(d_self, - g_strdup_printf(_("Internal error creating S3 handle: %s"), - s3_strerror(self->s3t[0].s3)), - DEVICE_STATUS_DEVICE_ERROR); - self->nb_threads = thread+1; - return FALSE; - } } } @@ -1759,33 +2287,56 @@ static gboolean setup_handle(S3Device * self) { self->nb_threads, 0, NULL); self->thread_pool_read = g_thread_pool_new(s3_thread_read_block, self, self->nb_threads, 0, NULL); - } - for (thread = 0; thread < self->nb_threads; thread++) { - s3_verbose(self->s3t[thread].s3, self->verbose); + for (thread = 0; thread < self->nb_threads; thread++) { + s3_verbose(self->s3t[thread].s3, self->verbose); - if (!s3_use_ssl(self->s3t[thread].s3, self->use_ssl)) { - device_set_error(d_self, g_strdup_printf(_( - "Error setting S3 SSL/TLS use " - "(tried to enable SSL/TLS for S3, but curl doesn't support it?)")), - DEVICE_STATUS_DEVICE_ERROR); - return FALSE; - } + if (!s3_use_ssl(self->s3t[thread].s3, self->use_ssl)) { + device_set_error(d_self, g_strdup_printf(_( + "Error setting S3 SSL/TLS use " + "(tried to enable SSL/TLS for S3, but curl doesn't support it?)")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } - if (self->max_send_speed && - !s3_set_max_send_speed(self->s3t[thread].s3, self->max_send_speed)) { - device_set_error(d_self, - g_strdup("Could not set S3 maximum send speed"), - DEVICE_STATUS_DEVICE_ERROR); - return FALSE; + if (self->max_send_speed && + !s3_set_max_send_speed(self->s3t[thread].s3, + self->max_send_speed)) { + device_set_error(d_self, + g_strdup("Could not set S3 maximum send speed"), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + + if (self->max_recv_speed && + !s3_set_max_recv_speed(self->s3t[thread].s3, + self->max_recv_speed)) { + device_set_error(d_self, + g_strdup("Could not set S3 maximum recv speed"), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } } - if (self->max_recv_speed && - !s3_set_max_recv_speed(self->s3t[thread].s3, self->max_recv_speed)) { - device_set_error(d_self, - g_strdup("Could not set S3 maximum recv speed"), - DEVICE_STATUS_DEVICE_ERROR); - return FALSE; + for (thread = 0; thread < self->nb_threads; thread++) { + if (!s3_open2(self->s3t[thread].s3)) { + if (self->s3_api == S3_API_SWIFT_1 || + self->s3_api == S3_API_SWIFT_2) { + s3_error(self->s3t[0].s3, NULL, &response_code, + &s3_error_code, NULL, &curl_code, NULL); + device_set_error(d_self, + g_strdup_printf(_("s3_open2 failed: %s"), + s3_strerror(self->s3t[0].s3)), + DEVICE_STATUS_DEVICE_ERROR); + self->nb_threads = thread+1; + return FALSE; + } else { + device_set_error(d_self, + g_strdup("s3_open2 failed"), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + } } } @@ -1801,7 +2352,7 @@ make_bucket( s3_error_code_t s3_error_code; CURLcode curl_code; - if (s3_is_bucket_exists(self->s3t[0].s3, self->bucket)) { + if (s3_is_bucket_exists(self->s3t[0].s3, self->bucket, self->project_id)) { return TRUE; } @@ -1817,7 +2368,15 @@ make_bucket( return FALSE; } - if (!s3_make_bucket(self->s3t[0].s3, self->bucket)) { + if (!self->create_bucket) { + device_set_error(pself, + g_strdup_printf(_("Can't list bucket: %s"), + s3_strerror(self->s3t[0].s3)), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } + + if (!s3_make_bucket(self->s3t[0].s3, self->bucket, self->project_id)) { s3_error(self->s3t[0].s3, NULL, &response_code, &s3_error_code, NULL, NULL, NULL); /* if it isn't an expected error (bucket already exists), @@ -1834,6 +2393,23 @@ make_bucket( return TRUE; } +static int progress_func( + void *thread_data, + double dltotal G_GNUC_UNUSED, + double dlnow, + double ultotal G_GNUC_UNUSED, + double ulnow) +{ + S3_by_thread *s3t = (S3_by_thread *)thread_data; + + g_mutex_lock(s3t->now_mutex); + s3t->dlnow = dlnow; + s3t->ulnow = ulnow; + g_mutex_unlock(s3t->now_mutex); + + return 0; +} + static DeviceStatusFlags s3_device_read_label(Device *pself) { S3Device *self = S3_DEVICE(pself); @@ -1936,7 +2512,9 @@ s3_device_start (Device * pself, DeviceAccessMode mode, reset_thread(self); pself->access_mode = mode; + g_mutex_lock(pself->device_mutex); pself->in_file = FALSE; + g_mutex_unlock(pself->device_mutex); /* try creating the bucket, in case it doesn't exist */ if (!make_bucket(pself)) { @@ -1953,7 +2531,9 @@ s3_device_start (Device * pself, DeviceAccessMode mode, break; case ACCESS_WRITE: - delete_all_files(self); + if (!delete_all_files(self)) { + return FALSE; + } /* write a new amanda header */ if (!write_amanda_header(self, label, timestamp)) { @@ -2011,6 +2591,54 @@ s3_device_finish ( /* functions for writing */ +static guint64 +s3_device_get_bytes_read( + Device * pself) +{ + S3Device *self = S3_DEVICE(pself); + int thread; + guint64 dltotal; + + g_mutex_unlock(pself->device_mutex); + /* Add per thread */ + g_mutex_lock(self->thread_idle_mutex); + dltotal = self->dltotal; + for (thread = 0; thread < self->nb_threads_recovery; thread++) { + g_mutex_lock(self->s3t[thread].now_mutex); + dltotal += self->s3t[thread].dlnow; + g_mutex_unlock(self->s3t[thread].now_mutex); + } + g_mutex_unlock(self->thread_idle_mutex); + g_mutex_lock(pself->device_mutex); + + return dltotal; +} + + +static guint64 +s3_device_get_bytes_written( + Device * pself) +{ + S3Device *self = S3_DEVICE(pself); + int thread; + guint64 ultotal; + + g_mutex_unlock(pself->device_mutex); + /* Add per thread */ + g_mutex_lock(self->thread_idle_mutex); + ultotal = self->ultotal; + for (thread = 0; thread < self->nb_threads_backup; thread++) { + g_mutex_lock(self->s3t[thread].now_mutex); + ultotal += self->s3t[thread].ulnow; + g_mutex_unlock(self->s3t[thread].now_mutex); + } + g_mutex_unlock(self->thread_idle_mutex); + g_mutex_lock(pself->device_mutex); + + return ultotal; +} + + static gboolean s3_device_start_file (Device *pself, dumpfile_t *jobInfo) { S3Device *self = S3_DEVICE(pself); @@ -2052,10 +2680,22 @@ s3_device_start_file (Device *pself, dumpfile_t *jobInfo) { g_free(amanda_header.buffer); return FALSE; } + + for (thread = 0; thread < self->nb_threads; thread++) { + self->s3t[thread].idle = 1; + self->s3t[thread].ulnow = 0; + } + /* set the file and block numbers correctly */ pself->file = (pself->file > 0)? pself->file+1 : 1; pself->block = 0; + g_mutex_lock(pself->device_mutex); pself->in_file = TRUE; + pself->bytes_written = 0; + g_mutex_unlock(pself->device_mutex); + g_mutex_lock(self->thread_idle_mutex); + self->ultotal = 0; + g_mutex_unlock(self->thread_idle_mutex); /* write it out as a special block (not the 0th) */ key = special_file_to_key(self, "filestart", pself->file); result = s3_upload(self->s3t[0].s3, self->bucket, key, S3_BUFFER_READ_FUNCS, @@ -2070,9 +2710,6 @@ s3_device_start_file (Device *pself, dumpfile_t *jobInfo) { } self->volume_bytes += header_size; - for (thread = 0; thread < self->nb_threads; thread++) { - self->s3t[thread].idle = 1; - } return TRUE; } @@ -2167,7 +2804,8 @@ s3_thread_write_block( gboolean result; result = s3_upload(s3t->s3, self->bucket, (char *)s3t->filename, - S3_BUFFER_READ_FUNCS, (CurlBuffer *)&s3t->curl_buffer, NULL, NULL); + S3_BUFFER_READ_FUNCS, (CurlBuffer *)&s3t->curl_buffer, + progress_func, s3t); g_free((void *)s3t->filename); s3t->filename = NULL; if (!result) { @@ -2177,7 +2815,10 @@ s3_thread_write_block( g_mutex_lock(self->thread_idle_mutex); s3t->idle = 1; s3t->done = 1; + if (result) + self->ultotal += s3t->curl_buffer.buffer_len; s3t->curl_buffer.buffer_len = s3t->buffer_len; + s3t->ulnow = 0; g_cond_broadcast(self->thread_idle_cond); g_mutex_unlock(self->thread_idle_mutex); } @@ -2209,12 +2850,16 @@ s3_device_finish_file (Device * pself) { g_cond_wait(self->thread_idle_cond, self->thread_idle_mutex); } } + self->ultotal = 0; g_mutex_unlock(self->thread_idle_mutex); if (device_in_error(pself)) return FALSE; /* we're not in a file anymore */ + g_mutex_lock(pself->device_mutex); pself->in_file = FALSE; + pself->bytes_written = 0;; + g_mutex_unlock(pself->device_mutex); return TRUE; } @@ -2264,7 +2909,8 @@ s3_device_erase(Device *pself) { device_set_error(pself, g_strdup("Unlabeled volume"), DEVICE_STATUS_VOLUME_UNLABELED); - if (!s3_delete_bucket(self->s3t[0].s3, self->bucket)) { + if (self->create_bucket && + !s3_delete_bucket(self->s3t[0].s3, self->bucket)) { s3_error(self->s3t[0].s3, NULL, &response_code, &s3_error_code, NULL, NULL, NULL); /* @@ -2303,9 +2949,15 @@ s3_device_seek_file(Device *pself, guint file) { pself->file = file; pself->is_eof = FALSE; - pself->in_file = FALSE; pself->block = 0; + g_mutex_lock(pself->device_mutex); + pself->in_file = FALSE; + pself->bytes_read = 0; + g_mutex_unlock(pself->device_mutex); self->next_block_to_read = 0; + g_mutex_lock(self->thread_idle_mutex); + self->dltotal = 0; + g_mutex_unlock(self->thread_idle_mutex); /* read it in */ key = special_file_to_key(self, "filestart", pself->file); @@ -2374,11 +3026,14 @@ s3_device_seek_file(Device *pself, guint file) { return NULL; } - pself->in_file = TRUE; for (thread = 0; thread < self->nb_threads; thread++) { self->s3t[thread].idle = 1; self->s3t[thread].eof = FALSE; + self->s3t[thread].ulnow = 0; } + g_mutex_lock(pself->device_mutex); + pself->in_file = TRUE; + g_mutex_unlock(pself->device_mutex); return amanda_header; } @@ -2413,6 +3068,8 @@ s3_device_read_block (Device * pself, gpointer data, int *size_req) { s3t->done = 0; s3t->idle = 0; s3t->eof = FALSE; + s3t->dlnow = 0; + s3t->ulnow = 0; s3t->errflags = DEVICE_STATUS_SUCCESS; if (self->s3t[thread].curl_buffer.buffer && (int)self->s3t[thread].curl_buffer.buffer_len < *size_req) { @@ -2448,7 +3105,9 @@ s3_device_read_block (Device * pself, gpointer data, int *size_req) { /* return eof */ g_free(key); pself->is_eof = TRUE; + g_mutex_lock(pself->device_mutex); pself->in_file = FALSE; + g_mutex_unlock(pself->device_mutex); device_set_error(pself, stralloc(_("EOF")), DEVICE_STATUS_SUCCESS); g_mutex_unlock(self->thread_idle_mutex); @@ -2495,6 +3154,8 @@ s3_device_read_block (Device * pself, gpointer data, int *size_req) { s3t->done = 0; s3t->idle = 0; s3t->eof = FALSE; + s3t->dlnow = 0; + s3t->ulnow = 0; s3t->errflags = DEVICE_STATUS_SUCCESS; if (!self->s3t[thread].curl_buffer.buffer) { self->s3t[thread].curl_buffer.buffer = g_malloc(*size_req); @@ -2521,8 +3182,9 @@ s3_thread_read_block( S3Device *self = S3_DEVICE(pself); gboolean result; - result = s3_read(s3t->s3, self->bucket, (char *)s3t->filename, s3_buffer_write_func, - s3_buffer_reset_func, (CurlBuffer *)&s3t->curl_buffer, NULL, NULL); + result = s3_read(s3t->s3, self->bucket, (char *)s3t->filename, + S3_BUFFER_WRITE_FUNCS, + (CurlBuffer *)&s3t->curl_buffer, progress_func, s3t); g_mutex_lock(self->thread_idle_mutex); if (!result) { @@ -2543,7 +3205,11 @@ s3_thread_read_block( s3t->errmsg = g_strdup_printf(_("While reading data block from S3: %s"), s3_strerror(s3t->s3)); } + } else { + self->dltotal += s3t->curl_buffer.buffer_len; } + s3t->dlnow = 0; + s3t->ulnow = 0; s3t->done = 1; g_cond_broadcast(self->thread_idle_cond); g_mutex_unlock(self->thread_idle_mutex); @@ -2589,16 +3255,18 @@ reset_thread( int thread; int nb_done = 0; - g_mutex_lock(self->thread_idle_mutex); - while(nb_done != self->nb_threads) { - nb_done = 0; - for (thread = 0; thread < self->nb_threads; thread++) { - if (self->s3t[thread].done == 1) - nb_done++; - } - if (nb_done != self->nb_threads) { - g_cond_wait(self->thread_idle_cond, self->thread_idle_mutex); + if (self->thread_idle_mutex) { + g_mutex_lock(self->thread_idle_mutex); + while(nb_done != self->nb_threads) { + nb_done = 0; + for (thread = 0; thread < self->nb_threads; thread++) { + if (self->s3t[thread].done == 1) + nb_done++; + } + if (nb_done != self->nb_threads) { + g_cond_wait(self->thread_idle_cond, self->thread_idle_mutex); + } } + g_mutex_unlock(self->thread_idle_mutex); } - g_mutex_unlock(self->thread_idle_mutex); } diff --git a/device-src/s3-util.c b/device-src/s3-util.c index d1d7f21..a17a506 100644 --- a/device-src/s3-util.c +++ b/device-src/s3-util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/device-src/s3-util.h b/device-src/s3-util.h index f928558..5f20b88 100644 --- a/device-src/s3-util.h +++ b/device-src/s3-util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/device-src/s3.c b/device-src/s3.c index 1c61291..a3c030b 100644 --- a/device-src/s3.c +++ b/device-src/s3.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -139,15 +139,27 @@ struct S3Handle { char *user_token; char *swift_account_id; char *swift_access_key; + char *username; + char *password; + char *tenant_id; + char *tenant_name; + char *client_id; + char *client_secret; + char *refresh_token; + char *access_token; + time_t expires; + gboolean getting_oauth2_access_token; + gboolean getting_swift_2_token; /* attributes for new objects */ char *bucket_location; char *storage_class; char *server_side_encryption; + char *proxy; char *host; char *service_path; gboolean use_subdomain; - gboolean openstack_swift_api; + S3_api s3_api; char *ca_info; char *x_auth_token; char *x_storage_url; @@ -171,6 +183,9 @@ struct S3Handle { /* offset with s3 */ time_t time_offset_with_s3; + char *content_type; + + gboolean reuse_connection; }; typedef struct { @@ -248,7 +263,8 @@ s3_error_name_from_code(s3_error_code_t s3_error_code); typedef enum { S3_RESULT_RETRY = -1, S3_RESULT_FAIL = 0, - S3_RESULT_OK = 1 + S3_RESULT_OK = 1, + S3_RESULT_NOTIMPL = 2 } s3_result_t; typedef struct result_handling { @@ -258,6 +274,11 @@ typedef struct result_handling { s3_result_t result; } result_handling_t; +/* + * get the access token for OAUTH2 + */ +static gboolean oauth2_get_access_token(S3Handle *hdl); + /* Lookup a result in C{result_handling}. * * @param result_handling: array of handling specifications @@ -276,7 +297,8 @@ lookup_result(const result_handling_t *result_handling, * Precompiled regular expressions */ static regex_t etag_regex, error_name_regex, message_regex, subdomain_regex, location_con_regex, date_sync_regex, x_auth_token_regex, - x_storage_url_regex; + x_storage_url_regex, access_token_regex, expires_in_regex, + content_type_regex, details_regex, code_regex; /* @@ -335,7 +357,10 @@ authenticate_request(S3Handle *hdl, const char *bucket, const char *key, const char *subresource, - const char *md5_hash); + const char *md5_hash, + const char *content_type, + const size_t content_length, + const char *project_id); @@ -401,6 +426,8 @@ perform_request(S3Handle *hdl, const char *key, const char *subresource, const char *query, + const char *content_type, + const char *project_id, s3_read_func read_func, s3_reset_func read_reset_func, s3_size_func size_func, @@ -435,6 +462,9 @@ s3_internal_header_func(void *ptr, size_t size, size_t nmemb, void * stream); static gboolean compile_regexes(void); +static gboolean get_openstack_swift_api_v1_setting(S3Handle *hdl); +static gboolean get_openstack_swift_api_v2_setting(S3Handle *hdl); + /* * Static function implementations */ @@ -520,6 +550,130 @@ lookup_result(const result_handling_t *result_handling, return result_handling->result; } +static time_t +rfc3339_date( + const char *date) +{ + gint year, month, day, hour, minute, seconds; + const char *atz; + + if (strlen(date) < 19) + return 1073741824; + + year = atoi(date); + month = atoi(date+5); + day = atoi(date+8); + hour = atoi(date+11); + minute = atoi(date+14); + seconds = atoi(date+17); + atz = date+19; + if (*atz == '.') { /* skip decimal seconds */ + atz++; + while (*atz >= '0' && *atz <= '9') { + atz++; + } + } + +#if GLIB_CHECK_VERSION(2,26,0) + if (!glib_check_version(2,26,0)) { + GTimeZone *tz; + GDateTime *dt; + time_t a; + + tz = g_time_zone_new(atz); + dt = g_date_time_new(tz, year, month, day, hour, minute, seconds); + a = g_date_time_to_unix(dt); + g_time_zone_unref(tz); + g_date_time_unref(dt); + return a; + } else +#endif + { + struct tm tm; + time_t t; + + tm.tm_year = year - 1900; + tm.tm_mon = month - 1; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = minute; + tm.tm_sec = seconds; + tm.tm_wday = 0; + tm.tm_yday = 0; + tm.tm_isdst = -1; + t = time(NULL); + + if (*atz == '-' || *atz == '+') { /* numeric timezone */ + time_t lt, gt; + time_t a; + struct tm ltt, gtt; + gint Hour = atoi(atz); + gint Min = atoi(atz+4); + + if (Hour < 0) + Min = -Min; + tm.tm_hour -= Hour; + tm.tm_min -= Min; + tm.tm_isdst = 0; + localtime_r(&t, <t); + lt = mktime(<t); + gmtime_r(&t, >t); + gt = mktime(>t); + tm.tm_sec += lt - gt; + a = mktime(&tm); + return a; + } else if (*atz == 'Z' && *(atz+1) == '\0') { /* Z timezone */ + time_t lt, gt; + time_t a; + struct tm ltt, gtt; + + tm.tm_isdst = 0; + localtime_r(&t, <t); + lt = mktime(<t); + gmtime_r(&t, >t); + gt = mktime(>t); + tm.tm_sec += lt - gt; + a = mktime(&tm); + return a; + } else { /* named timezone */ + int pid; + int fd[2]; + char buf[101]; + time_t a; + size_t size; + + if (pipe(fd) == -1) + return 1073741824; + pid = fork(); + switch (pid) { + case -1: + close(fd[0]); + close(fd[1]); + return 1073741824; + break; + case 0: + close(fd[0]); + setenv("TZ", atz, 1); + tzset(); + a = mktime(&tm); + g_snprintf(buf, 100, "%d", (int)a); + size = write(fd[1], buf, strlen(buf)); + close(fd[1]); + exit(0); + default: + close(fd[1]); + size = read(fd[0], buf, 100); + close(fd[0]); + buf[size] = '\0'; + waitpid(pid, NULL, 0); + break; + } + return atoi(buf); + } + } +} + + static gboolean is_non_empty_string(const char *str) { @@ -537,7 +691,9 @@ build_url( GString *url = NULL; char *esc_bucket = NULL, *esc_key = NULL; - if (hdl->openstack_swift_api && hdl->x_storage_url) { + if ((hdl->s3_api == S3_API_SWIFT_1 || hdl->s3_api == S3_API_SWIFT_2 || + hdl->s3_api == S3_API_OAUTH2) && + hdl->x_storage_url) { url = g_string_new(hdl->x_storage_url); g_string_append(url, "/"); } else { @@ -600,6 +756,10 @@ build_url( curl_free(esc_key); } + if (url->str[strlen(url->str)-1] == '/') { + g_string_truncate(url, strlen(url->str)-1); + } + /* query string */ if (subresource || query) g_string_append(url, "?"); @@ -624,7 +784,10 @@ authenticate_request(S3Handle *hdl, const char *bucket, const char *key, const char *subresource, - const char *md5_hash) + const char *md5_hash, + const char *content_type, + const size_t content_length, + const char *project_id) { time_t t; struct tm tmp; @@ -642,7 +805,6 @@ authenticate_request(S3Handle *hdl, static const char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - /* calculate the date */ t = time(NULL); @@ -660,7 +822,7 @@ authenticate_request(S3Handle *hdl, wkday[tmp.tm_wday], tmp.tm_mday, month[tmp.tm_mon], 1900+tmp.tm_year, tmp.tm_hour, tmp.tm_min, tmp.tm_sec); - if (hdl->openstack_swift_api) { + if (hdl->s3_api == S3_API_SWIFT_1) { if (!bucket) { buf = g_strdup_printf("X-Auth-User: %s", hdl->swift_account_id); headers = curl_slist_append(headers, buf); @@ -673,6 +835,21 @@ authenticate_request(S3Handle *hdl, headers = curl_slist_append(headers, buf); g_free(buf); } + } else if (hdl->s3_api == S3_API_SWIFT_2) { + if (bucket) { + buf = g_strdup_printf("X-Auth-Token: %s", hdl->x_auth_token); + headers = curl_slist_append(headers, buf); + g_free(buf); + } + buf = g_strdup_printf("Accept: %s", "application/xml"); + headers = curl_slist_append(headers, buf); + g_free(buf); + } else if (hdl->s3_api == S3_API_OAUTH2) { + if (bucket) { + buf = g_strdup_printf("Authorization: Bearer %s", hdl->access_token); + headers = curl_slist_append(headers, buf); + g_free(buf); + } } else { /* Build the string to sign, per the S3 spec. * See: "Authenticating REST Requests" - API Version 2006-03-01 pg 58 @@ -687,7 +864,9 @@ authenticate_request(S3Handle *hdl, g_string_append(auth_string, md5_hash); g_string_append(auth_string, "\n"); - /* Content-Type is empty*/ + if (content_type) { + g_string_append(auth_string, content_type); + } g_string_append(auth_string, "\n"); /* Date */ @@ -797,6 +976,29 @@ authenticate_request(S3Handle *hdl, headers = curl_slist_append(headers, buf); g_free(buf); } + if (content_length > 0) { + buf = g_strdup_printf("Content-Length: %zu", content_length); + headers = curl_slist_append(headers, buf); + g_free(buf); + } + + if (content_type) { + buf = g_strdup_printf("Content-Type: %s", content_type); + headers = curl_slist_append(headers, buf); + g_free(buf); + } + + if (hdl->s3_api == S3_API_OAUTH2) { + buf = g_strdup_printf("x-goog-api-version: 2"); + headers = curl_slist_append(headers, buf); + g_free(buf); + } + + if (project_id && hdl->s3_api == S3_API_OAUTH2) { + buf = g_strdup_printf("x-goog-project-id: %s", project_id); + headers = curl_slist_append(headers, buf); + g_free(buf); + } buf = g_strdup_printf("Date: %s", date); headers = curl_slist_append(headers, buf); @@ -824,24 +1026,36 @@ struct failure_thunk { gboolean in_body; gboolean in_code; gboolean in_message; + gboolean in_details; + gboolean in_access; + gboolean in_token; + gboolean in_serviceCatalog; + gboolean in_service; + gboolean in_endpoint; gint in_others; gchar *text; gsize text_len; gchar *message; + gchar *details; gchar *error_name; + gchar *token_id; + gchar *service_type; + gchar *service_public_url; + gint64 expires; }; static void failure_start_element(GMarkupParseContext *context G_GNUC_UNUSED, const gchar *element_name, - const gchar **attribute_names G_GNUC_UNUSED, - const gchar **attribute_values G_GNUC_UNUSED, + const gchar **attribute_names, + const gchar **attribute_values, gpointer user_data, GError **error G_GNUC_UNUSED) { struct failure_thunk *thunk = (struct failure_thunk *)user_data; + const gchar **att_name, **att_value; if (g_ascii_strcasecmp(element_name, "title") == 0) { thunk->in_title = 1; @@ -859,6 +1073,60 @@ failure_start_element(GMarkupParseContext *context G_GNUC_UNUSED, thunk->in_message = 1; thunk->in_others = 0; thunk->want_text = 1; + } else if (g_ascii_strcasecmp(element_name, "details") == 0) { + thunk->in_details = 1; + thunk->in_others = 0; + thunk->want_text = 1; + } else if (g_ascii_strcasecmp(element_name, "access") == 0) { + thunk->in_access = 1; + thunk->in_others = 0; + } else if (g_ascii_strcasecmp(element_name, "token") == 0) { + thunk->in_token = 1; + thunk->in_others = 0; + for (att_name=attribute_names, att_value=attribute_values; + *att_name != NULL; + att_name++, att_value++) { + if (g_str_equal(*att_name, "id")) { + thunk->token_id = g_strdup(*att_value); + } + if (g_str_equal(*att_name, "expires") && strlen(*att_value) >= 19) { + thunk->expires = rfc3339_date(*att_value) - 600; + } + } + } else if (g_ascii_strcasecmp(element_name, "serviceCatalog") == 0) { + thunk->in_serviceCatalog = 1; + thunk->in_others = 0; + } else if (g_ascii_strcasecmp(element_name, "service") == 0) { + thunk->in_service = 1; + thunk->in_others = 0; + for (att_name=attribute_names, att_value=attribute_values; + *att_name != NULL; + att_name++, att_value++) { + if (g_str_equal(*att_name, "type")) { + thunk->service_type = g_strdup(*att_value); + } + } + } else if (g_ascii_strcasecmp(element_name, "endpoint") == 0) { + thunk->in_endpoint = 1; + thunk->in_others = 0; + if (thunk->service_type && + g_str_equal(thunk->service_type, "object-store")) { + for (att_name=attribute_names, att_value=attribute_values; + *att_name != NULL; + att_name++, att_value++) { + if (g_str_equal(*att_name, "publicURL")) { + thunk->service_public_url = g_strdup(*att_value); + } + } + } + } else if (g_ascii_strcasecmp(element_name, "error") == 0) { + for (att_name=attribute_names, att_value=attribute_values; + *att_name != NULL; + att_name++, att_value++) { + if (g_str_equal(*att_name, "message")) { + thunk->message = g_strdup(*att_value); + } + } } else { thunk->in_others++; } @@ -896,6 +1164,32 @@ failure_end_element(GMarkupParseContext *context G_GNUC_UNUSED, thunk->message = thunk->text; thunk->text = NULL; thunk->in_message = 0; + } else if (g_ascii_strcasecmp(element_name, "details") == 0) { + thunk->details = thunk->text; + thunk->text = NULL; + thunk->in_details = 0; + } else if (g_ascii_strcasecmp(element_name, "access") == 0) { + thunk->message = thunk->text; + thunk->text = NULL; + thunk->in_access = 0; + } else if (g_ascii_strcasecmp(element_name, "token") == 0) { + thunk->message = thunk->text; + thunk->text = NULL; + thunk->in_token = 0; + } else if (g_ascii_strcasecmp(element_name, "serviceCatalog") == 0) { + thunk->message = thunk->text; + thunk->text = NULL; + thunk->in_serviceCatalog = 0; + } else if (g_ascii_strcasecmp(element_name, "service") == 0) { + thunk->message = thunk->text; + thunk->text = NULL; + g_free(thunk->service_type); + thunk->service_type = NULL; + thunk->in_service = 0; + } else if (g_ascii_strcasecmp(element_name, "endpoint") == 0) { + thunk->message = thunk->text; + thunk->text = NULL; + thunk->in_endpoint = 0; } else { thunk->in_others--; } @@ -963,11 +1257,6 @@ interpret_response(S3Handle *hdl, ret = FALSE; return ret; } - if (200 <= response_code && response_code < 400) { - /* 2xx and 3xx codes won't have a response body we care about */ - hdl->last_s3_error_code = S3_ERROR_None; - return FALSE; - } /* Now look at the body to try to get the actual Amazon error message. */ @@ -976,24 +1265,45 @@ interpret_response(S3Handle *hdl, hdl->last_message = g_strdup("S3 Error: Unknown (response body too large to parse)"); return FALSE; } else if (!body || body_len == 0) { - hdl->last_message = g_strdup("S3 Error: Unknown (empty response body)"); - return TRUE; /* perhaps a network error; retry the request */ + if (response_code < 100 || response_code >= 400) { + hdl->last_message = + g_strdup("S3 Error: Unknown (empty response body)"); + return TRUE; /* perhaps a network error; retry the request */ + } else { + /* 2xx and 3xx codes without body are good result */ + hdl->last_s3_error_code = S3_ERROR_None; + return FALSE; + } } thunk.in_title = FALSE; thunk.in_body = FALSE; thunk.in_code = FALSE; thunk.in_message = FALSE; + thunk.in_details = FALSE; + thunk.in_access = FALSE; + thunk.in_token = FALSE; + thunk.in_serviceCatalog = FALSE; + thunk.in_service = FALSE; + thunk.in_endpoint = FALSE; thunk.in_others = 0; thunk.text = NULL; thunk.want_text = FALSE; thunk.text_len = 0; thunk.message = NULL; + thunk.details = NULL; thunk.error_name = NULL; + thunk.token_id = NULL; + thunk.service_type = NULL; + thunk.service_public_url = NULL; + thunk.expires = 0; + + if ((hdl->s3_api == S3_API_SWIFT_1 || + hdl->s3_api == S3_API_SWIFT_2) && + hdl->content_type && + (g_str_equal(hdl->content_type, "text/html") || + g_str_equal(hdl->content_type, "text/plain"))) { - if (hdl->openstack_swift_api && - !g_strstr_len(body, body_len, "xml version") && - !g_strstr_len(body, body_len, "")) { char *body_copy = g_strndup(body, body_len); char *b = body_copy; char *p = strchr(b, '\n'); @@ -1019,6 +1329,37 @@ interpret_response(S3Handle *hdl, b = p; } goto parsing_done; + } else if ((hdl->s3_api == S3_API_SWIFT_1 || + hdl->s3_api == S3_API_SWIFT_2) && + hdl->content_type && + g_str_equal(hdl->content_type, "application/json")) { + char *body_copy = g_strndup(body, body_len); + char *code = NULL; + char *details = NULL; + regmatch_t pmatch[2]; + + if (!s3_regexec_wrap(&code_regex, body_copy, 2, pmatch, 0)) { + code = find_regex_substring(body_copy, pmatch[1]); + } + if (!s3_regexec_wrap(&details_regex, body_copy, 2, pmatch, 0)) { + details = find_regex_substring(body_copy, pmatch[1]); + } + if (code && details) { + hdl->last_message = g_strdup_printf("%s (%s)", details, code); + } else if (code) { + hdl->last_message = g_strdup_printf("(%s)", code); + } else if (details) { + hdl->last_message = g_strdup_printf("%s", details); + } else { + hdl->last_message = NULL; + } + g_free(code); + g_free(details); + g_free(body_copy); + return FALSE; + } else if (!hdl->content_type || + !g_str_equal(hdl->content_type, "application/xml")) { + return FALSE; } /* run the parser over it */ @@ -1038,6 +1379,20 @@ interpret_response(S3Handle *hdl, g_markup_parse_context_free(ctxt); ctxt = NULL; + if (hdl->s3_api == S3_API_SWIFT_2) { + if (!hdl->x_auth_token && thunk.token_id) { + hdl->x_auth_token = thunk.token_id; + thunk.token_id = NULL; + } + if (!hdl->x_storage_url && thunk.service_public_url) { + hdl->x_storage_url = thunk.service_public_url; + thunk.service_public_url = NULL; + } + } + + if (thunk.expires > 0) { + hdl->expires = thunk.expires; + } parsing_done: if (thunk.error_name) { hdl->last_s3_error_code = s3_error_code_from_name(thunk.error_name); @@ -1047,14 +1402,24 @@ parsing_done: if (thunk.message) { g_free(hdl->last_message); - hdl->last_message = thunk.message; - thunk.message = NULL; /* steal the reference to the string */ + if (thunk.details) { + hdl->last_message = g_strdup_printf("%s: %s", thunk.message, + thunk.details); + amfree(thunk.message); + amfree(thunk.details); + } else { + hdl->last_message = thunk.message; + thunk.message = NULL; /* steal the reference to the string */ + } } cleanup: g_free(thunk.text); g_free(thunk.message); g_free(thunk.error_name); + g_free(thunk.token_id); + g_free(thunk.service_public_url); + g_free(thunk.service_type); return FALSE; } @@ -1251,6 +1616,7 @@ curl_debug_message(CURL *curl G_GNUC_UNUSED, char *lineprefix; char *message; char **lines, **line; + size_t i; switch (type) { case CURLINFO_TEXT: @@ -1264,17 +1630,27 @@ curl_debug_message(CURL *curl G_GNUC_UNUSED, case CURLINFO_HEADER_OUT: lineprefix="Hdr Out: "; break; -/* + case CURLINFO_DATA_IN: - if (len > 1000) return 0; + if (len > 3000) return 0; + for (i=0;i 1000) return 0; + if (len > 3000) return 0; + for (i=0;icurl != NULL); + if (hdl->s3_api == S3_API_OAUTH2 && !hdl->getting_oauth2_access_token && + (!hdl->access_token || hdl->expires < time(NULL))) { + result = oauth2_get_access_token(hdl); + if (!result) { + g_debug("oauth2_get_access_token returned %d", result); + return result; + } + } else if (hdl->s3_api == S3_API_SWIFT_2 && !hdl->getting_swift_2_token && + (!hdl->x_auth_token || hdl->expires < time(NULL))) { + result = get_openstack_swift_api_v2_setting(hdl); + if (!result) { + g_debug("get_openstack_swift_api_v2_setting returned %d", result); + return result; + } + } + s3_reset(hdl); url = build_url(hdl, bucket, key, subresource, query); @@ -1395,9 +1789,9 @@ perform_request(S3Handle *hdl, /* set up the request */ headers = authenticate_request(hdl, verb, bucket, key, subresource, - md5_hash_b64); + md5_hash_b64, content_type, request_body_size, project_id); - if (hdl->use_ssl && hdl->ca_info) { + if (hdl->ca_info) { if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_CAINFO, hdl->ca_info))) goto curl_error; } @@ -1433,6 +1827,10 @@ perform_request(S3Handle *hdl, goto curl_error; if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_PROGRESSFUNCTION, progress_func))) goto curl_error; + if (progress_func) { + if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_NOPROGRESS,0))) + goto curl_error; + } if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_PROGRESSDATA, progress_data))) goto curl_error; @@ -1444,6 +1842,15 @@ perform_request(S3Handle *hdl, if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_INFILESIZE, (long)request_body_size))) goto curl_error; #endif +/* CURLOPT_POSTFIELDSIZE_LARGE added in 7.11.1 */ +#if LIBCURL_VERSION_NUM >= 0x070b01 + if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)request_body_size))) + goto curl_error; +#else + if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_POSTFIELDSIZE, (long)request_body_size))) + goto curl_error; +#endif + /* CURLOPT_MAX_{RECV,SEND}_SPEED_LARGE added in 7.15.5 */ #if LIBCURL_VERSION_NUM >= 0x070f05 if (s3_curl_throttling_compat()) { @@ -1470,7 +1877,7 @@ perform_request(S3Handle *hdl, goto curl_error; - if (curlopt_upload) { + if (curlopt_upload || curlopt_post) { if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_READFUNCTION, read_func))) goto curl_error; if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_READDATA, read_data))) @@ -1484,6 +1891,20 @@ perform_request(S3Handle *hdl, NULL))) goto curl_error; } + if (hdl->proxy) { + if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_PROXY, + hdl->proxy))) + goto curl_error; + } + + if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_FRESH_CONNECT, + (long)(hdl->reuse_connection? 0 : 1)))) { + goto curl_error; + } + if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_FORBID_REUSE, + (long)(hdl->reuse_connection? 0 : 1)))) { + goto curl_error; + } /* Perform the request */ curl_code = curl_easy_perform(hdl->curl); @@ -1494,6 +1915,11 @@ perform_request(S3Handle *hdl, should_retry = interpret_response(hdl, curl_code, curl_error_buffer, int_writedata.resp_buf.buffer, int_writedata.resp_buf.buffer_pos, int_writedata.etag, md5_hash_hex); + if (hdl->s3_api == S3_API_OAUTH2 && + hdl->last_response_code == 401 && + hdl->last_s3_error_code == S3_ERROR_AuthenticationRequired) { + should_retry = oauth2_get_access_token(hdl); + } /* and, unless we know we need to retry, see what we're to do now */ if (!should_retry) { result = lookup_result(result_handling, hdl->last_response_code, @@ -1603,6 +2029,9 @@ s3_internal_header_func(void *ptr, size_t size, size_t nmemb, void * stream) if (!s3_regexec_wrap(&x_storage_url_regex, header, 2, pmatch, 0)) data->hdl->x_storage_url = find_regex_substring(header, pmatch[1]); + if (!s3_regexec_wrap(&content_type_regex, header, 2, pmatch, 0)) + data->hdl->content_type = find_regex_substring(header, pmatch[1]); + if (strlen(header) == 0) data->headers_done = TRUE; if (g_str_equal(final_header, header)) @@ -1646,10 +2075,15 @@ compile_regexes(void) {"^ETag:[[:space:]]*\"([^\"]+)\"[[:space:]]*$", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &etag_regex}, {"^X-Auth-Token:[[:space:]]*([^ ]+)[[:space:]]*$", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &x_auth_token_regex}, {"^X-Storage-Url:[[:space:]]*([^ ]+)[[:space:]]*$", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &x_storage_url_regex}, + {"^Content-Type:[[:space:]]*([^ ;]+).*$", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &content_type_regex}, {"[[:space:]]*([^<]*)[[:space:]]*", REG_EXTENDED | REG_ICASE, &message_regex}, {"^[a-z0-9](-*[a-z0-9]){2,62}$", REG_EXTENDED | REG_NOSUB, &subdomain_regex}, {"(/>)|(>([^<]*))", REG_EXTENDED | REG_ICASE, &location_con_regex}, {"^Date:(.*)\r",REG_EXTENDED | REG_ICASE | REG_NEWLINE, &date_sync_regex}, + {"\"access_token\" : \"([^\"]*)\",", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &access_token_regex}, + {"\"expires_in\" : (.*)", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &expires_in_regex}, + {"\"details\": \"([^\"]*)\",", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &details_regex}, + {"\"code\": (.*),", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &code_regex}, {NULL, 0, NULL} }; char regmessage[1024]; @@ -1673,6 +2107,15 @@ compile_regexes(void) {"^ETag:\\s*\"([^\"]+)\"\\s*$", G_REGEX_OPTIMIZE | G_REGEX_CASELESS, &etag_regex}, + {"^X-Auth-Token:\\s*([^ ]+)\\s*$", + G_REGEX_OPTIMIZE | G_REGEX_CASELESS, + &x_auth_token_regex}, + {"^X-Storage-Url:\\s*([^ ]+)\\s*$", + G_REGEX_OPTIMIZE | G_REGEX_CASELESS, + &x_storage_url_regex}, + {"^Content-Type:\\s*([^ ]+)\\s*$", + G_REGEX_OPTIMIZE | G_REGEX_CASELESS, + &content_type_regex}, {"\\s*([^<]*)\\s*", G_REGEX_OPTIMIZE | G_REGEX_CASELESS, &message_regex}, @@ -1685,6 +2128,18 @@ compile_regexes(void) {"^Date:(.*)\\r", G_REGEX_OPTIMIZE | G_REGEX_CASELESS, &date_sync_regex}, + {"\"access_token\" : \"([^\"]*)\"", + G_REGEX_OPTIMIZE | G_REGEX_CASELESS, + &access_token_regex}, + {"\"expires_n\" : (.*)", + G_REGEX_OPTIMIZE | G_REGEX_CASELESS, + &expires_in_regex}, + {"\"details\" : \"([^\"]*)\"", + G_REGEX_OPTIMIZE | G_REGEX_CASELESS, + &details_regex}, + {"\"code\" : (.*)", + G_REGEX_OPTIMIZE | G_REGEX_CASELESS, + &code_regex}, {NULL, 0, NULL} }; int i; @@ -1706,6 +2161,10 @@ compile_regexes(void) * Public function implementations */ +#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31)) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif gboolean s3_init(void) { static GStaticMutex mutex = G_STATIC_MUTEX_INIT; @@ -1721,6 +2180,9 @@ gboolean s3_init(void) g_static_mutex_unlock(&mutex); return ret; } +#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31)) +# pragma GCC diagnostic pop +#endif gboolean s3_curl_location_compat(void) @@ -1738,7 +2200,7 @@ s3_bucket_location_compat(const char *bucket) } static gboolean -get_openstack_swift_api_setting( +get_openstack_swift_api_v1_setting( S3Handle *hdl) { s3_result_t result = S3_RESULT_FAIL; @@ -1749,12 +2211,60 @@ get_openstack_swift_api_setting( }; s3_verbose(hdl, 1); - result = perform_request(hdl, "GET", NULL, NULL, NULL, NULL, + result = perform_request(hdl, "GET", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, result_handling); return result == S3_RESULT_OK; +} +static gboolean +get_openstack_swift_api_v2_setting( + S3Handle *hdl) +{ + s3_result_t result = S3_RESULT_FAIL; + static result_handling_t result_handling[] = { + { 200, 0, 0, S3_RESULT_OK }, + RESULT_HANDLING_ALWAYS_RETRY, + { 0, 0, 0, /* default: */ S3_RESULT_FAIL } + }; + + CurlBuffer buf = {NULL, 0, 0, 0}; + GString *body = g_string_new(""); + if (hdl->username && hdl->password) { + g_string_append_printf(body, "tenant_id) { + g_string_append_printf(body, " tenantId=\"%s\"", hdl->tenant_id); + } + if (hdl->tenant_name) { + g_string_append_printf(body, " tenantName=\"%s\"", hdl->tenant_name); + } + g_string_append(body, ">"); + if (hdl->username && hdl->password) { + g_string_append_printf(body, "", hdl->username, hdl->password); + } else { + g_string_append_printf(body, "", hdl->access_key, hdl->secret_key); + } + g_string_append(body, ""); + + buf.buffer = g_string_free(body, FALSE); + buf.buffer_len = strlen(buf.buffer); + s3_verbose(hdl, 1); + hdl->getting_swift_2_token = 1; + g_free(hdl->x_storage_url); + hdl->x_storage_url = NULL; + result = perform_request(hdl, "POST", NULL, NULL, NULL, NULL, + "application/xml", NULL, + S3_BUFFER_READ_FUNCS, &buf, + NULL, NULL, NULL, + NULL, NULL, result_handling); + hdl->getting_swift_2_token = 0; + + return result == S3_RESULT_OK; } S3Handle * @@ -1770,26 +2280,49 @@ s3_open(const char *access_key, const char *storage_class, const char *ca_info, const char *server_side_encryption, - const gboolean openstack_swift_api) + const char *proxy, + const S3_api s3_api, + const char *username, + const char *password, + const char *tenant_id, + const char *tenant_name, + const char *client_id, + const char *client_secret, + const char *refresh_token, + const gboolean reuse_connection) { S3Handle *hdl; hdl = g_new0(S3Handle, 1); if (!hdl) goto error; - hdl->verbose = FALSE; + hdl->verbose = TRUE; hdl->use_ssl = s3_curl_supports_ssl(); + hdl->reuse_connection = reuse_connection; - if (!openstack_swift_api) { + if (s3_api == S3_API_S3) { g_assert(access_key); hdl->access_key = g_strdup(access_key); g_assert(secret_key); hdl->secret_key = g_strdup(secret_key); - } else { + } else if (s3_api == S3_API_SWIFT_1) { g_assert(swift_account_id); hdl->swift_account_id = g_strdup(swift_account_id); g_assert(swift_access_key); hdl->swift_access_key = g_strdup(swift_access_key); + } else if (s3_api == S3_API_SWIFT_2) { + g_assert((username && password) || (access_key && secret_key)); + hdl->username = g_strdup(username); + hdl->password = g_strdup(password); + hdl->access_key = g_strdup(access_key); + hdl->secret_key = g_strdup(secret_key); + g_assert(tenant_id || tenant_name); + hdl->tenant_id = g_strdup(tenant_id); + hdl->tenant_name = g_strdup(tenant_name); + } else if (s3_api == S3_API_OAUTH2) { + hdl->client_id = g_strdup(client_id); + hdl->client_secret = g_strdup(client_secret); + hdl->refresh_token = g_strdup(refresh_token); } /* NULL is okay */ @@ -1804,6 +2337,9 @@ s3_open(const char *access_key, /* NULL is ok */ hdl->server_side_encryption = g_strdup(server_side_encryption); + /* NULL is ok */ + hdl->proxy = g_strdup(proxy); + /* NULL is okay */ hdl->ca_info = g_strdup(ca_info); @@ -1813,7 +2349,7 @@ s3_open(const char *access_key, hdl->use_subdomain = use_subdomain || (strcmp(hdl->host, "s3.amazonaws.com") == 0 && is_non_empty_string(hdl->bucket_location)); - hdl->openstack_swift_api = openstack_swift_api; + hdl->s3_api = s3_api; if (service_path) { if (strlen(service_path) == 0 || (strlen(service_path) == 1 && service_path[0] == '/')) { @@ -1836,9 +2372,6 @@ s3_open(const char *access_key, hdl->curl = curl_easy_init(); if (!hdl->curl) goto error; - if (openstack_swift_api) { /* get the X-Storage-Url and X-Auth-Token */ - get_openstack_swift_api_setting(hdl); - } return hdl; error: @@ -1846,6 +2379,22 @@ error: return NULL; } +gboolean +s3_open2( + S3Handle *hdl) +{ + gboolean ret = TRUE; + + /* get the X-Storage-Url and X-Auth-Token */ + if (hdl->s3_api == S3_API_SWIFT_1) { + ret = get_openstack_swift_api_v1_setting(hdl); + } else if (hdl->s3_api == S3_API_SWIFT_2) { + ret = get_openstack_swift_api_v2_setting(hdl); + } + + return ret; +} + void s3_free(S3Handle *hdl) { @@ -1856,6 +2405,18 @@ s3_free(S3Handle *hdl) g_free(hdl->secret_key); g_free(hdl->swift_account_id); g_free(hdl->swift_access_key); + g_free(hdl->content_type); + g_free(hdl->user_token); + g_free(hdl->ca_info); + g_free(hdl->proxy); + g_free(hdl->username); + g_free(hdl->password); + g_free(hdl->tenant_id); + g_free(hdl->tenant_name); + g_free(hdl->client_id); + g_free(hdl->client_secret); + g_free(hdl->refresh_token); + g_free(hdl->access_token); if (hdl->user_token) g_free(hdl->user_token); if (hdl->bucket_location) g_free(hdl->bucket_location); if (hdl->storage_class) g_free(hdl->storage_class); @@ -1889,6 +2450,10 @@ s3_reset(S3Handle *hdl) g_free(hdl->last_response_body); hdl->last_response_body = NULL; } + if (hdl->content_type) { + g_free(hdl->content_type); + hdl->content_type = NULL; + } hdl->last_response_body_size = 0; } @@ -2023,7 +2588,7 @@ s3_upload(S3Handle *hdl, g_assert(hdl != NULL); - result = perform_request(hdl, "PUT", bucket, key, NULL, NULL, + result = perform_request(hdl, "PUT", bucket, key, NULL, NULL, NULL, NULL, read_func, reset_func, size_func, md5_func, read_data, NULL, NULL, NULL, progress_func, progress_data, result_handling); @@ -2180,21 +2745,24 @@ list_fetch(S3Handle *hdl, have_prev_part = TRUE; esc_value = curl_escape(pos_parts[i][1], 0); keyword = pos_parts[i][0]; - if (hdl->openstack_swift_api && strcmp(keyword, "max-keys") == 0) { + if ((hdl->s3_api == S3_API_SWIFT_1 || + hdl->s3_api == S3_API_SWIFT_2) && + strcmp(keyword, "max-keys") == 0) { keyword = "limit"; } g_string_append_printf(query, "%s=%s", keyword, esc_value); curl_free(esc_value); } } - if (hdl->openstack_swift_api) { + if (hdl->s3_api == S3_API_SWIFT_1 || hdl->s3_api == S3_API_SWIFT_2) { if (have_prev_part) g_string_append(query, "&"); g_string_append(query, "format=xml"); } /* and perform the request on that URI */ - result = perform_request(hdl, "GET", bucket, NULL, NULL, query->str, + result = perform_request(hdl, "GET", bucket, NULL, NULL, query->str, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, S3_BUFFER_WRITE_FUNCS, buf, NULL, NULL, result_handling); @@ -2313,7 +2881,8 @@ s3_read(S3Handle *hdl, g_assert(hdl != NULL); g_assert(write_func != NULL); - result = perform_request(hdl, "GET", bucket, key, NULL, NULL, + + result = perform_request(hdl, "GET", bucket, key, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, write_func, reset_func, write_data, progress_func, progress_data, result_handling); @@ -2337,16 +2906,73 @@ s3_delete(S3Handle *hdl, g_assert(hdl != NULL); - result = perform_request(hdl, "DELETE", bucket, key, NULL, NULL, + result = perform_request(hdl, "DELETE", bucket, key, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, result_handling); return result == S3_RESULT_OK; } +int +s3_multi_delete(S3Handle *hdl, + const char *bucket, + const char **key) +{ + GString *query; + CurlBuffer data; + s3_result_t result = S3_RESULT_FAIL; + static result_handling_t result_handling[] = { + { 200, 0, 0, S3_RESULT_OK }, + { 204, 0, 0, S3_RESULT_OK }, + { 400, 0, 0, S3_RESULT_NOTIMPL }, + { 404, S3_ERROR_NoSuchBucket, 0, S3_RESULT_OK }, + RESULT_HANDLING_ALWAYS_RETRY, + { 0, 0, 0, /* default: */ S3_RESULT_FAIL } + }; + + g_assert(hdl != NULL); + + query = g_string_new(NULL); + g_string_append(query, "\n"); + g_string_append(query, "\n"); + if (!hdl->verbose) { + g_string_append(query, " true\n"); + } + while (*key != NULL) { + g_string_append(query, " \n"); + g_string_append(query, " "); + g_string_append(query, *key); + g_string_append(query, "\n"); + g_string_append(query, " \n"); + key++; + } + g_string_append(query, "\n"); + + data.buffer_len = query->len; + data.buffer = query->str; + data.buffer_pos = 0; + data.max_buffer_size = data.buffer_len; + + result = perform_request(hdl, "POST", bucket, NULL, "delete", NULL, + "application/xml", NULL, + s3_buffer_read_func, s3_buffer_reset_func, + s3_buffer_size_func, s3_buffer_md5_func, + &data, NULL, NULL, NULL, NULL, NULL, + result_handling); + + g_string_free(query, TRUE); + if (result == S3_RESULT_OK) + return 1; + else if (result == S3_RESULT_NOTIMPL) + return 2; + else + return 0; +} + gboolean s3_make_bucket(S3Handle *hdl, - const char *bucket) + const char *bucket, + const char *project_id) { char *body = NULL; s3_result_t result = S3_RESULT_FAIL; @@ -2393,7 +3019,8 @@ s3_make_bucket(S3Handle *hdl, } } - result = perform_request(hdl, "PUT", bucket, NULL, NULL, NULL, + result = perform_request(hdl, "PUT", bucket, NULL, NULL, NULL, NULL, + project_id, read_func, reset_func, size_func, md5_func, ptr, NULL, NULL, NULL, NULL, NULL, result_handling); @@ -2404,11 +3031,11 @@ s3_make_bucket(S3Handle *hdl, * the one that's configured. */ if (is_non_empty_string(hdl->bucket_location)) { - result = perform_request(hdl, "GET", bucket, NULL, "location", NULL, + result = perform_request(hdl, "GET", bucket, NULL, "location", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, result_handling); } else { - result = perform_request(hdl, "GET", bucket, NULL, NULL, NULL, + result = perform_request(hdl, "GET", bucket, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, result_handling); } @@ -2459,11 +3086,81 @@ cleanup: } +static s3_result_t +oauth2_get_access_token( + S3Handle *hdl) +{ + GString *query; + CurlBuffer data; + s3_result_t result = S3_RESULT_FAIL; + static result_handling_t result_handling[] = { + { 200, 0, 0, S3_RESULT_OK }, + { 204, 0, 0, S3_RESULT_OK }, + RESULT_HANDLING_ALWAYS_RETRY, + { 0, 0, 0, /* default: */ S3_RESULT_FAIL } + }; + char *body; + regmatch_t pmatch[2]; + + g_assert(hdl != NULL); + + query = g_string_new(NULL); + g_string_append(query, "client_id="); + g_string_append(query, hdl->client_id); + g_string_append(query, "&client_secret="); + g_string_append(query, hdl->client_secret); + g_string_append(query, "&refresh_token="); + g_string_append(query, hdl->refresh_token); + g_string_append(query, "&grant_type=refresh_token"); + + data.buffer_len = query->len; + data.buffer = query->str; + data.buffer_pos = 0; + data.max_buffer_size = data.buffer_len; + + hdl->x_storage_url = "https://accounts.google.com/o/oauth2/token"; + hdl->getting_oauth2_access_token = 1; + result = perform_request(hdl, "POST", NULL, NULL, NULL, NULL, + "application/x-www-form-urlencoded", NULL, + s3_buffer_read_func, s3_buffer_reset_func, + s3_buffer_size_func, s3_buffer_md5_func, + &data, NULL, NULL, NULL, NULL, NULL, + result_handling); + hdl->x_storage_url = NULL; + hdl->getting_oauth2_access_token = 0; + + /* use strndup to get a null-terminated string */ + body = g_strndup(hdl->last_response_body, hdl->last_response_body_size); + if (!body) { + hdl->last_message = g_strdup(_("No body received for location request")); + goto cleanup; + } else if ('\0' == body[0]) { + hdl->last_message = g_strdup(_("Empty body received for location request")); + goto cleanup; + } + + if (!s3_regexec_wrap(&access_token_regex, body, 2, pmatch, 0)) { + hdl->access_token = find_regex_substring(body, pmatch[1]); + hdl->x_auth_token = g_strdup(hdl->access_token); + } + if (!s3_regexec_wrap(&expires_in_regex, body, 2, pmatch, 0)) { + char *expires_in = find_regex_substring(body, pmatch[1]); + hdl->expires = time(NULL) + atoi(expires_in) - 600; + g_free(expires_in); + } + +cleanup: + g_free(body); + return result == S3_RESULT_OK; +} + gboolean s3_is_bucket_exists(S3Handle *hdl, - const char *bucket) + const char *bucket, + const char *project_id) { s3_result_t result = S3_RESULT_FAIL; + char *query; static result_handling_t result_handling[] = { { 200, 0, 0, S3_RESULT_OK }, { 204, 0, 0, S3_RESULT_OK }, @@ -2471,8 +3168,15 @@ s3_is_bucket_exists(S3Handle *hdl, { 0, 0, 0, /* default: */ S3_RESULT_FAIL } }; - result = perform_request(hdl, "GET", bucket, NULL, NULL, - hdl->openstack_swift_api?"limit=1":"max-keys=1", + if (hdl->s3_api == S3_API_SWIFT_1 || + hdl->s3_api == S3_API_SWIFT_2) { + query = "limit=1"; + } else { + query = "max-keys=1"; + } + + result = perform_request(hdl, "GET", bucket, NULL, NULL, query, + NULL, project_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, result_handling); diff --git a/device-src/s3.h b/device-src/s3.h index 24ad960..e8fd74d 100644 --- a/device-src/s3.h +++ b/device-src/s3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -27,6 +27,13 @@ * Data types */ +typedef enum { + S3_API_S3, + S3_API_SWIFT_1, + S3_API_SWIFT_2, + S3_API_OAUTH2 +} S3_api; + /* An opaque handle. S3Handles should only be accessed from a single * thread at any given time, although it is fine to use different handles * in different threads simultaneously. */ @@ -171,6 +178,7 @@ typedef curl_progress_callback s3_progress_func; S3_ERROR(Accepted), \ S3_ERROR(Forbidden), \ S3_ERROR(Conflict), \ + S3_ERROR(AuthenticationRequired), \ S3_ERROR(END) typedef enum { @@ -245,7 +253,26 @@ s3_open(const char * access_key, const char *secret_key, const char * user_token, const char * bucket_location, const char * storage_class, const char * ca_info, const char * server_side_encryption, - const gboolean openstack_swift_api); + const char *proxy, + const S3_api s3_api, + const char *username, + const char *password, + const char *tenant_id, + const char *tenant_name, + const char *client_id, + const char *client_secret, + const char *refresh_token, + const gboolean reuse_connection); + +/* latest step of setting up the S3Handle. + * + * Must be done after all properties are set. + * + * @param hdl: the S3Handle to set up. + * @returns: false if an error occured + */ +gboolean +s3_open2(S3Handle *hdl); /* Deallocate an S3Handle * @@ -423,6 +450,19 @@ s3_delete(S3Handle *hdl, const char *bucket, const char *key); +/* Delete multiple file. + * + * @param hdl: the S3Handle object + * @param bucket: the bucket to delete from + * @param key: the key array to delete + * @returns: 0 on sucess, 1 if multi_delete is not supported, 2 if an error + * occurs; a non-existent file is I{not} considered an error. + */ +int +s3_multi_delete(S3Handle *hdl, + const char *bucket, + const char **key); + /* Create a bucket. * * @param hdl: the S3Handle object @@ -431,7 +471,8 @@ s3_delete(S3Handle *hdl, */ gboolean s3_make_bucket(S3Handle *hdl, - const char *bucket); + const char *bucket, + const char *project_id); /* Check if a bucket exists. * @@ -441,7 +482,8 @@ s3_make_bucket(S3Handle *hdl, */ gboolean s3_is_bucket_exists(S3Handle *hdl, - const char *bucket); + const char *bucket, + const char *project_id); /* Delete a bucket * diff --git a/device-src/tape-device.c b/device-src/tape-device.c index 5e4b449..0c7fe24 100644 --- a/device-src/tape-device.c +++ b/device-src/tape-device.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -995,6 +995,9 @@ tape_device_write_block(Device * pself, guint size, gpointer data) { } pself->block++; + g_mutex_lock(pself->device_mutex); + pself->bytes_written += size; + g_mutex_unlock(pself->device_mutex); return TRUE; } @@ -1025,6 +1028,9 @@ static int tape_device_read_block (Device * pself, gpointer buf, case RESULT_SUCCESS: *size_req = size; pself->block++; + g_mutex_lock(pself->device_mutex); + pself->bytes_read += size; + g_mutex_unlock(pself->device_mutex); return size; case RESULT_SMALL_BUFFER: { gsize new_size; @@ -1059,7 +1065,9 @@ static int tape_device_read_block (Device * pself, gpointer buf, } case RESULT_NO_DATA: pself->is_eof = TRUE; + g_mutex_lock(pself->device_mutex); pself->in_file = FALSE; + g_mutex_unlock(pself->device_mutex); device_set_error(pself, stralloc(_("EOF")), DEVICE_STATUS_SUCCESS); @@ -1160,7 +1168,9 @@ tape_device_start (Device * d_self, DeviceAccessMode mode, char * label, } d_self->access_mode = mode; + g_mutex_lock(d_self->device_mutex); d_self->in_file = FALSE; + g_mutex_unlock(d_self->device_mutex); if (IS_WRITABLE_ACCESS_MODE(mode)) { if (self->write_open_errno != 0) { @@ -1272,10 +1282,13 @@ static gboolean tape_device_start_file(Device * d_self, amfree(amanda_header); /* arrange the file numbers correctly */ - d_self->in_file = TRUE; d_self->block = 0; if (d_self->file >= 0) d_self->file ++; + g_mutex_lock(d_self->device_mutex); + d_self->in_file = TRUE; + d_self->bytes_written = 0; + g_mutex_unlock(d_self->device_mutex); return TRUE; } @@ -1295,7 +1308,9 @@ tape_device_finish_file (Device * d_self) { return FALSE; } + g_mutex_lock(d_self->device_mutex); d_self->in_file = FALSE; + g_mutex_unlock(d_self->device_mutex); return TRUE; } @@ -1323,9 +1338,12 @@ tape_device_seek_file (Device * d_self, guint file) { difference --; } - d_self->in_file = FALSE; d_self->is_eof = FALSE; d_self->block = 0; + g_mutex_lock(d_self->device_mutex); + d_self->in_file = FALSE; + d_self->bytes_read = 0; + g_mutex_unlock(d_self->device_mutex); reseek: if (difference > 0) { @@ -1452,7 +1470,9 @@ reseek: return NULL; } + g_mutex_lock(d_self->device_mutex); d_self->in_file = TRUE; + g_mutex_unlock(d_self->device_mutex); d_self->file = file; return rval; @@ -1546,9 +1566,14 @@ tape_device_finish (Device * d_self) { } /* Polish off this file, if relevant. */ + g_mutex_lock(d_self->device_mutex); if (d_self->in_file && IS_WRITABLE_ACCESS_MODE(d_self->access_mode)) { - if (!device_finish_file(d_self)) + g_mutex_unlock(d_self->device_mutex); + if (!device_finish_file(d_self)) { goto finish_error; + } + } else { + g_mutex_unlock(d_self->device_mutex); } /* Straighten out the filemarks. We already wrote one in finish_file, and diff --git a/device-src/vfs-device.c b/device-src/vfs-device.c index 122a6ef..5733995 100644 --- a/device-src/vfs-device.c +++ b/device-src/vfs-device.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010, 2011 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -795,9 +795,10 @@ static gboolean vfs_device_write_block(Device * pself, guint size, gpointer data pself->is_eom = TRUE; if (check_at_peom(self, size)) { + /* check_at_peom() only checks against MAX_VOLUME_USAGE limit */ pself->is_eom = TRUE; device_set_error(pself, - stralloc(_("No space left on device")), + stralloc(_("No space left on device: more than MAX_VOLUME_USAGE bytes written")), DEVICE_STATUS_VOLUME_ERROR); return FALSE; } @@ -811,6 +812,9 @@ static gboolean vfs_device_write_block(Device * pself, guint size, gpointer data self->volume_bytes += size; self->checked_bytes_used += size; pself->block ++; + g_mutex_lock(pself->device_mutex); + pself->bytes_written += size; + g_mutex_unlock(pself->device_mutex); return TRUE; } @@ -837,11 +841,16 @@ vfs_device_read_block(Device * pself, gpointer data, int * size_req) { switch (result) { case RESULT_SUCCESS: *size_req = size; + g_mutex_lock(pself->device_mutex); + pself->bytes_read += size; + g_mutex_unlock(pself->device_mutex); pself->block++; return size; case RESULT_NO_DATA: pself->is_eof = TRUE; + g_mutex_lock(pself->device_mutex); pself->in_file = FALSE; + g_mutex_unlock(pself->device_mutex); device_set_error(pself, stralloc(_("EOF")), DEVICE_STATUS_SUCCESS); @@ -867,7 +876,9 @@ vfs_device_start(Device * dself, return FALSE; } + g_mutex_lock(dself->device_mutex); dself->in_file = FALSE; + g_mutex_unlock(dself->device_mutex); if (mode == ACCESS_WRITE) { promote_volume_lock(self); @@ -907,7 +918,9 @@ vfs_device_finish (Device * pself) { release_file(self); pself->access_mode = ACCESS_NULL; + g_mutex_lock(pself->device_mutex); pself->in_file = FALSE; + g_mutex_unlock(pself->device_mutex); if (device_in_error(self)) return FALSE; @@ -1059,9 +1072,10 @@ vfs_device_start_file (Device * dself, dumpfile_t * ji) { dself->is_eom = TRUE; if (check_at_peom(self, VFS_DEVICE_LABEL_SIZE)) { + /* check_at_peom() only checks against MAX_VOLUME_USAGE limit */ dself->is_eom = TRUE; device_set_error(dself, - stralloc(_("No space left on device")), + stralloc(_("No space left on device: more than MAX_VOLUME_USAGE bytes written")), DEVICE_STATUS_DEVICE_ERROR); return FALSE; } @@ -1102,8 +1116,11 @@ vfs_device_start_file (Device * dself, dumpfile_t * ji) { /* handle some accounting business */ self->volume_bytes += VFS_DEVICE_LABEL_SIZE; self->checked_bytes_used += VFS_DEVICE_LABEL_SIZE; - dself->in_file = TRUE; dself->block = 0; + g_mutex_lock(dself->device_mutex); + dself->in_file = TRUE; + dself->bytes_written = 0; + g_mutex_unlock(dself->device_mutex); /* make_new_file_name set pself->file for us */ return TRUE; @@ -1117,7 +1134,9 @@ vfs_device_finish_file(Device * dself) { release_file(self); + g_mutex_lock(dself->device_mutex); dself->in_file = FALSE; + g_mutex_unlock(dself->device_mutex); return TRUE; } @@ -1137,9 +1156,12 @@ vfs_device_seek_file (Device * dself, guint requested_file) { if (device_in_error(self)) return NULL; - dself->in_file = FALSE; dself->is_eof = FALSE; dself->block = 0; + g_mutex_lock(dself->device_mutex); + dself->in_file = FALSE; + dself->bytes_read = 0; + g_mutex_unlock(dself->device_mutex); release_file(self); @@ -1232,7 +1254,9 @@ vfs_device_seek_file (Device * dself, guint requested_file) { if (requested_file == 0) { dself->header_block_size = header_buffer_size; } + g_mutex_lock(dself->device_mutex); dself->in_file = TRUE; + g_mutex_unlock(dself->device_mutex); dself->file = file; return rval; diff --git a/device-src/vfs-device.h b/device-src/vfs-device.h index 09c3942..e37346f 100644 --- a/device-src/vfs-device.h +++ b/device-src/vfs-device.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005-2008, 2010 Zmanda Inc. All Rights Reserved. + * Copyright (c) 2005-2012 Zmanda Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 2.1 as diff --git a/device-src/xfer-dest-device.c b/device-src/xfer-dest-device.c index 28fd058..7836f56 100644 --- a/device-src/xfer-dest-device.c +++ b/device-src/xfer-dest-device.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/device-src/xfer-dest-taper-cacher.c b/device-src/xfer-dest-taper-cacher.c index 7564304..0bf02cd 100644 --- a/device-src/xfer-dest-taper-cacher.c +++ b/device-src/xfer-dest-taper-cacher.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -1328,7 +1328,12 @@ get_part_bytes_written_impl( /* NOTE: this access is unsafe and may return inconsistent results (e.g, a * partial write to the 64-bit value on a 32-bit system). This is ok for * the moment, as it's only informational, but be warned. */ - return self->bytes_written + self->slab_bytes_written; + if (self->device) { + return device_get_bytes_written(self->device); + } else { + return self->bytes_written + self->slab_bytes_written; + } + } static void diff --git a/device-src/xfer-dest-taper-directtcp.c b/device-src/xfer-dest-taper-directtcp.c index 6d9d12d..91738d0 100644 --- a/device-src/xfer-dest-taper-directtcp.c +++ b/device-src/xfer-dest-taper-directtcp.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -74,6 +74,7 @@ typedef struct XferDestTaperDirectTCP { * corresponding condition variable. */ volatile gboolean paused; GCond *paused_cond; + GCond *abort_accept_cond; /* condition to trigger to abort an accept */ } XferDestTaperDirectTCP; @@ -108,6 +109,7 @@ worker_thread( XferElement *elt = (XferElement *)data; XferDestTaperDirectTCP *self = (XferDestTaperDirectTCP *)data; GTimer *timer = g_timer_new(); + int result; /* This thread's job is to accept() an incoming connection, then call * write_from_connection for each part, and then close the connection */ @@ -124,12 +126,18 @@ worker_thread( /* first, accept a new connection from the device */ DBG(2, "accepting DirectTCP connection on device %s", self->device->device_name); - if (!device_accept(self->device, &self->conn, NULL, NULL)) { + result = device_accept_with_cond(self->device, &self->conn, + self->state_mutex, + self->abort_accept_cond); + if (result == 2) { xfer_cancel_with_error(XFER_ELEMENT(self), "accepting DirectTCP connection: %s", device_error_or_status(self->device)); g_mutex_unlock(self->state_mutex); return NULL; + } else if (result == 1) { + g_mutex_unlock(self->state_mutex); + return NULL; } DBG(2, "connection accepted; sending XMSG_READY"); @@ -327,6 +335,7 @@ cancel_impl( * longer paused */ g_mutex_lock(self->state_mutex); g_cond_broadcast(self->paused_cond); + g_cond_broadcast(self->abort_accept_cond); g_mutex_unlock(self->state_mutex); return rv; @@ -418,6 +427,7 @@ instance_init( self->conn = NULL; self->state_mutex = g_mutex_new(); self->paused_cond = g_cond_new(); + self->abort_accept_cond = g_cond_new(); } static void @@ -440,6 +450,7 @@ finalize_impl( g_mutex_free(self->state_mutex); g_cond_free(self->paused_cond); + g_cond_free(self->abort_accept_cond); if (self->part_header) dumpfile_free(self->part_header); diff --git a/device-src/xfer-dest-taper-splitter.c b/device-src/xfer-dest-taper-splitter.c index ccd7fde..081e9b8 100644 --- a/device-src/xfer-dest-taper-splitter.c +++ b/device-src/xfer-dest-taper-splitter.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -873,7 +873,11 @@ get_part_bytes_written_impl( /* NOTE: this access is unsafe and may return inconsistent results (e.g, a * partial write to the 64-bit value on a 32-bit system). This is ok for * the moment, as it's only informational, but be warned. */ - return self->part_bytes_written; + if (self->device) { + return device_get_bytes_written(self->device); + } else { + return self->part_bytes_written; + } } static void diff --git a/device-src/xfer-dest-taper.c b/device-src/xfer-dest-taper.c index 88ef247..4b7a481 100644 --- a/device-src/xfer-dest-taper.c +++ b/device-src/xfer-dest-taper.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/device-src/xfer-dest-taper.h b/device-src/xfer-dest-taper.h index e7b8537..c157a19 100644 --- a/device-src/xfer-dest-taper.h +++ b/device-src/xfer-dest-taper.h @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/device-src/xfer-device.h b/device-src/xfer-device.h index f18916b..cad34d0 100644 --- a/device-src/xfer-device.h +++ b/device-src/xfer-device.h @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -143,4 +143,8 @@ void xfer_source_recovery_use_device( XferElement *self, Device *device); +guint64 +xfer_source_recovery_get_bytes_read( + XferElement *elt); + #endif diff --git a/device-src/xfer-source-device.c b/device-src/xfer-source-device.c index c709313..e89a72a 100644 --- a/device-src/xfer-source-device.c +++ b/device-src/xfer-source-device.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/device-src/xfer-source-recovery.c b/device-src/xfer-source-recovery.c index 16673e0..f305f0c 100644 --- a/device-src/xfer-source-recovery.c +++ b/device-src/xfer-source-recovery.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -76,6 +76,9 @@ typedef struct XferSourceRecovery { * part) */ size_t block_size; + /* bytes read for this image */ + guint64 bytes_read; + /* part size (potentially including any zero-padding from the * device) */ guint64 part_size; @@ -426,6 +429,7 @@ pull_buffer_impl( self->paused = TRUE; g_object_unref(self->device); self->device = NULL; + self->bytes_read += self->part_size; self->part_size = 0; self->block_size = 0; if (self->part_timer) { @@ -700,3 +704,17 @@ xfer_source_recovery_use_device( klass = XFER_SOURCE_RECOVERY_GET_CLASS(elt); klass->use_device(XFER_SOURCE_RECOVERY(elt), device); } + +guint64 +xfer_source_recovery_get_bytes_read( + XferElement *elt) +{ + XferSourceRecovery *self = XFER_SOURCE_RECOVERY(elt); + guint64 bytes_read = self->bytes_read; + + if (self->device) + bytes_read += device_get_bytes_read(self->device); + + return bytes_read; +} + diff --git a/example/Makefile.in b/example/Makefile.in index a4b63bd..9827d7a 100644 --- a/example/Makefile.in +++ b/example/Makefile.in @@ -18,7 +18,7 @@ # Makefile for sample configuration files # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -261,7 +261,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -803,6 +804,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/gnulib/Makefile.in b/gnulib/Makefile.in index 6c669fd..cfd6f9b 100644 --- a/gnulib/Makefile.in +++ b/gnulib/Makefile.in @@ -199,7 +199,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -779,6 +780,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/installcheck/=setupcache.pl b/installcheck/=setupcache.pl index 1a0e0e6..09c8c1e 100644 --- a/installcheck/=setupcache.pl +++ b/installcheck/=setupcache.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Archive.pl b/installcheck/Amanda_Archive.pl index 58d8ed2..8bfa704 100644 --- a/installcheck/Amanda_Archive.pl +++ b/installcheck/Amanda_Archive.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Changer.pl b/installcheck/Amanda_Changer.pl index ce3dbab..4165865 100644 --- a/installcheck/Amanda_Changer.pl +++ b/installcheck/Amanda_Changer.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -256,7 +256,8 @@ my $chg = Amanda::Changer->new("mychanger", tapelist => $tl); is($chg->{'config'}->get_property("testprop"), "testval", "changer properties are correctly represented"); is($chg->have_inventory(), 1, "changer have inventory"); -is($chg->make_new_tape_label(), undef, "no make_new_tape_label"); +my @new_tape_label = $chg->make_new_tape_label(); +is_deeply(\@new_tape_label, [undef, "template is not set, you must set autolabel"], "no make_new_tape_label"); is($chg->make_new_meta_label(), undef, "no make_new_meta_label"); $chg = Amanda::Changer->new("mychanger", tapelist => $tl, diff --git a/installcheck/Amanda_Changer_compat.pl b/installcheck/Amanda_Changer_compat.pl index b2e311e..29c6952 100644 --- a/installcheck/Amanda_Changer_compat.pl +++ b/installcheck/Amanda_Changer_compat.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Changer_disk.pl b/installcheck/Amanda_Changer_disk.pl index c5b144b..e88d214 100644 --- a/installcheck/Amanda_Changer_disk.pl +++ b/installcheck/Amanda_Changer_disk.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Changer_multi.pl b/installcheck/Amanda_Changer_multi.pl index ae3466d..dfcc99f 100644 --- a/installcheck/Amanda_Changer_multi.pl +++ b/installcheck/Amanda_Changer_multi.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Changer_ndmp.pl b/installcheck/Amanda_Changer_ndmp.pl index 209a60e..70a9eed 100644 --- a/installcheck/Amanda_Changer_ndmp.pl +++ b/installcheck/Amanda_Changer_ndmp.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Changer_null.pl b/installcheck/Amanda_Changer_null.pl index 50a98c1..eccca06 100644 --- a/installcheck/Amanda_Changer_null.pl +++ b/installcheck/Amanda_Changer_null.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Changer_rait.pl b/installcheck/Amanda_Changer_rait.pl index 2139296..c0cb966 100644 --- a/installcheck/Amanda_Changer_rait.pl +++ b/installcheck/Amanda_Changer_rait.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Changer_robot.pl b/installcheck/Amanda_Changer_robot.pl index 7eadaa2..d7ddb60 100644 --- a/installcheck/Amanda_Changer_robot.pl +++ b/installcheck/Amanda_Changer_robot.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Changer_single.pl b/installcheck/Amanda_Changer_single.pl index 1f876d6..e95c837 100644 --- a/installcheck/Amanda_Changer_single.pl +++ b/installcheck/Amanda_Changer_single.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_ClientService.pl b/installcheck/Amanda_ClientService.pl index 7975a57..5aa7127 100644 --- a/installcheck/Amanda_ClientService.pl +++ b/installcheck/Amanda_ClientService.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Cmdline.pl b/installcheck/Amanda_Cmdline.pl index e752fc7..d8f412d 100644 --- a/installcheck/Amanda_Cmdline.pl +++ b/installcheck/Amanda_Cmdline.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2007, 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Config.pl b/installcheck/Amanda_Config.pl index 4a00337..362dcb5 100644 --- a/installcheck/Amanda_Config.pl +++ b/installcheck/Amanda_Config.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -602,7 +602,7 @@ is($error_level, $CFGERR_ERRORS, "bogus config overwrite flagged as an error"); my $pid = open(my $kid, "-|"); die "Can't fork: $!" unless defined($pid); if (!$pid) { - Amanda::Config::dump_configuration(); + Amanda::Config::dump_configuration(1, 0); exit 1; } my $dump_first_line = <$kid>; diff --git a/installcheck/Amanda_Config_FoldingHash.pl b/installcheck/Amanda_Config_FoldingHash.pl index 582e497..50648e6 100644 --- a/installcheck/Amanda_Config_FoldingHash.pl +++ b/installcheck/Amanda_Config_FoldingHash.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Curinfo.pl b/installcheck/Amanda_Curinfo.pl index 465b4d5..e377043 100644 --- a/installcheck/Amanda_Curinfo.pl +++ b/installcheck/Amanda_Curinfo.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_DB_Catalog.pl b/installcheck/Amanda_DB_Catalog.pl index 41a5d8a..4a87c7b 100644 --- a/installcheck/Amanda_DB_Catalog.pl +++ b/installcheck/Amanda_DB_Catalog.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Debug.pl b/installcheck/Amanda_Debug.pl index d6dee29..98f6345 100644 --- a/installcheck/Amanda_Debug.pl +++ b/installcheck/Amanda_Debug.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Device.pl b/installcheck/Amanda_Device.pl index 7fdccef..92ab162 100644 --- a/installcheck/Amanda_Device.pl +++ b/installcheck/Amanda_Device.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -16,7 +16,7 @@ # Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com -use Test::More tests => 593; +use Test::More tests => 609; use File::Path qw( mkpath rmtree ); use Sys::Hostname; use Carp; @@ -33,6 +33,7 @@ use Amanda::Config qw( :getconf :init ); use Amanda::Xfer qw( :constants ); use Amanda::Header qw( :constants ); use Amanda::Paths; +use Amanda::Constants; use Amanda::Util; use Amanda::MainLoop; use IO::Socket; @@ -1312,7 +1313,7 @@ SKIP: { } SKIP: { - skip "not built with ndmp and server", 78 unless + skip "not built with ndmp and server", 94 unless Amanda::Util::built_with_component("ndmp") and Amanda::Util::built_with_component("server"); @@ -1548,6 +1549,106 @@ SKIP: { } } + # + # Test indirecttcp + # + + { + ok($dev->directtcp_supported(), "is a directtcp target"); + + $dev->property_set("indirect", 1); + + my $addrs = $dev->listen(1); + ok($addrs, "listen returns successfully") or die($dev->error_or_status()); + + # fork off to evaluate the indirecttcp addresses and then set up an + # xfer to write to the device + if (POSIX::fork() == 0) { + # allow other process to start listening. + sleep 1; + my $nc = $Amanda::Constants::NC; + $nc = $Amanda::Constants::NC6 if !$nc; + $nc = $Amanda::Constants::NETCAT if !$nc; + my $sockresult = `$nc localhost $addrs->[0][1] < /dev/null`; + + my @sockresult = map { [ split(/:/, $_) ] } split(/ /, $sockresult); + $addrs = [ map { $_->[1] = 0 + $_->[1]; $_ } @sockresult ]; + + my $xfer = Amanda::Xfer->new([ + Amanda::Xfer::Source::Random->new(32768*34, 0xB00), + Amanda::Xfer::Dest::DirectTCPConnect->new($addrs) ]); + + $xfer->start(make_cb(xmsg_cb => sub { + my ($src, $msg, $xfer) = @_; + if ($msg->{'type'} == $XMSG_ERROR) { + die $msg->{'elt'} . " failed: " . $msg->{'message'}; + } elsif ($msg->{'type'} == $XMSG_DONE) { + Amanda::MainLoop::quit(); + } + })); + + Amanda::MainLoop::run(); + exit(0); + } + + # write files from the connection until EOF + my @messages; + my $num_files; + my $conn; + my ($call_accept, $start_device, $write_file_cb); + + $call_accept = make_cb(call_accept => sub { + $conn = $dev->accept(); + Amanda::MainLoop::call_later($start_device); + }); + + $start_device = make_cb(start_device => sub { + ok($dev->start($ACCESS_WRITE, "TEST2", "20090915000000"), + "start device in write mode") + or diag $dev->error_or_status(); + + Amanda::MainLoop::call_later($write_file_cb); + }); + + $write_file_cb = make_cb(write_file_cb => sub { + ++$num_files < 20 or die "I seem to be in a loop!"; + + ok($dev->start_file($hdr), "start file $num_files for writing"); + is($dev->file, $num_files, "..file number is correct"); + + my ($ok, $size) = $dev->write_from_connection(32768*15); + push @messages, sprintf("WRITE-%s-%d-%s-%s", + $ok?"OK":"ERR", $size, + $dev->is_eof()? "EOF":"!eof", + $dev->is_eom()? "EOM":"!eom"); + ok($ok, "..write from connection succeeds"); + my $eof = $dev->is_eof(); + + ok($dev->finish_file(), "..finish file after writing"); + + if (!$eof) { + Amanda::MainLoop::call_later($write_file_cb); + } else { + Amanda::MainLoop::quit(); + } + }); + + Amanda::MainLoop::call_later($call_accept); + Amanda::MainLoop::run(); + is_deeply([@messages], [ + 'WRITE-OK-491520-!eof-!eom', + 'WRITE-OK-491520-!eof-!eom', + 'WRITE-OK-131072-EOF-!eom', + ], + "a sequence of write_from_connection calls works correctly"); + + $dev->finish(); + + if (my $err = $conn->close()) { + die $err; + } + } + # now try reading that back piece by piece { diff --git a/installcheck/Amanda_Disklist.pl b/installcheck/Amanda_Disklist.pl index 4d64934..da3a59e 100644 --- a/installcheck/Amanda_Disklist.pl +++ b/installcheck/Amanda_Disklist.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Feature.pl b/installcheck/Amanda_Feature.pl index 7940f05..89288bb 100644 --- a/installcheck/Amanda_Feature.pl +++ b/installcheck/Amanda_Feature.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Header.pl b/installcheck/Amanda_Header.pl index a09134f..3deca30 100644 --- a/installcheck/Amanda_Header.pl +++ b/installcheck/Amanda_Header.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Holding.pl b/installcheck/Amanda_Holding.pl index 3f354dc..6497637 100644 --- a/installcheck/Amanda_Holding.pl +++ b/installcheck/Amanda_Holding.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_IPC_Binary.pl b/installcheck/Amanda_IPC_Binary.pl index ca646e0..ee3d6ff 100644 --- a/installcheck/Amanda_IPC_Binary.pl +++ b/installcheck/Amanda_IPC_Binary.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_IPC_LineProtocol.pl b/installcheck/Amanda_IPC_LineProtocol.pl index 5717bfc..b1f1484 100644 --- a/installcheck/Amanda_IPC_LineProtocol.pl +++ b/installcheck/Amanda_IPC_LineProtocol.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -305,6 +305,8 @@ my $NMSGS = 10000; POSIX::exit(0); }; + $wrh->write("SIMPLE\n"); + # and sleep forever, or until killed. while (1) { sleep(100); } }); @@ -313,6 +315,15 @@ $proto = TestProtocol->new( rx_fh => $rx_fh, tx_fh => $tx_fh, message_cb => $message_cb); $proto->set_message_cb(TestProtocol::QUIT, $quit_cb); +$proto->set_message_cb(TestProtocol::SIMPLE, sub { + push @events, [ shift @_ ]; + # send $NMSGS messages to the child, which isn't listening yet! + for (my $i = 0; $i < $NMSGS; $i++) { + $proto->send(TestProtocol::SIMPLE); + } + # and then send it SIGUSR1, so it reads those + kill USR1 => $pid; + }); $proto->set_message_cb(TestProtocol::BAR, sub { push @events, [ shift @_, { @_ } ]; }); @@ -320,19 +331,13 @@ $proto->set_message_cb(TestProtocol::BAR, sub { # die after 10 minutes alarm 600; -# send $NMSGS messages to the child, which isn't listening yet! -for (my $i = 0; $i < $NMSGS; $i++) { - $proto->send(TestProtocol::SIMPLE); -} -# and then send it SIGUSR1, so it reads those -kill USR1 => $pid; - Amanda::MainLoop::run(); waitpid($pid, 0); alarm 0; # cancel the alarm is_deeply([ @events ], [ + [ "SIMPLE" ], [ "BAR", { mandatory => "got your inputs" } ], [ "QUIT" ], ], diff --git a/installcheck/Amanda_Logfile.pl b/installcheck/Amanda_Logfile.pl index 9aaf304..deec0e5 100644 --- a/installcheck/Amanda_Logfile.pl +++ b/installcheck/Amanda_Logfile.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_MainLoop.pl b/installcheck/Amanda_MainLoop.pl index 5ce0b52..13abc47 100644 --- a/installcheck/Amanda_MainLoop.pl +++ b/installcheck/Amanda_MainLoop.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_NDMP.pl b/installcheck/Amanda_NDMP.pl index 25e80c1..0456d69 100644 --- a/installcheck/Amanda_NDMP.pl +++ b/installcheck/Amanda_NDMP.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Process.pl b/installcheck/Amanda_Process.pl index da94346..b82ac35 100644 --- a/installcheck/Amanda_Process.pl +++ b/installcheck/Amanda_Process.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Recovery_Clerk.pl b/installcheck/Amanda_Recovery_Clerk.pl index 7841f99..5a14d1b 100644 --- a/installcheck/Amanda_Recovery_Clerk.pl +++ b/installcheck/Amanda_Recovery_Clerk.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Recovery_Planner.pl b/installcheck/Amanda_Recovery_Planner.pl index 3e382c4..61a5985 100644 --- a/installcheck/Amanda_Recovery_Planner.pl +++ b/installcheck/Amanda_Recovery_Planner.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Recovery_Scan.pl b/installcheck/Amanda_Recovery_Scan.pl index dd704c7..354d0f9 100644 --- a/installcheck/Amanda_Recovery_Scan.pl +++ b/installcheck/Amanda_Recovery_Scan.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Report.pl b/installcheck/Amanda_Report.pl index f30e985..ebfd095 100755 --- a/installcheck/Amanda_Report.pl +++ b/installcheck/Amanda_Report.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Tapelist.pl b/installcheck/Amanda_Tapelist.pl index 1509ed9..37dac01 100644 --- a/installcheck/Amanda_Tapelist.pl +++ b/installcheck/Amanda_Tapelist.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Taper_Scan_lexical.pl b/installcheck/Amanda_Taper_Scan_lexical.pl index f6200f3..ad853ef 100644 --- a/installcheck/Amanda_Taper_Scan_lexical.pl +++ b/installcheck/Amanda_Taper_Scan_lexical.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Taper_Scan_oldest.pl b/installcheck/Amanda_Taper_Scan_oldest.pl index fd218ac..2b38b66 100644 --- a/installcheck/Amanda_Taper_Scan_oldest.pl +++ b/installcheck/Amanda_Taper_Scan_oldest.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Taper_Scan_traditional.pl b/installcheck/Amanda_Taper_Scan_traditional.pl index 97f3595..4e51bf6 100644 --- a/installcheck/Amanda_Taper_Scan_traditional.pl +++ b/installcheck/Amanda_Taper_Scan_traditional.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Taper_Scribe.pl b/installcheck/Amanda_Taper_Scribe.pl index 607013a..630334a 100644 --- a/installcheck/Amanda_Taper_Scribe.pl +++ b/installcheck/Amanda_Taper_Scribe.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Util.pl b/installcheck/Amanda_Util.pl index 352e257..0a83d0d 100644 --- a/installcheck/Amanda_Util.pl +++ b/installcheck/Amanda_Util.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Amanda_Xfer.pl b/installcheck/Amanda_Xfer.pl index 7a97c37..5e86e12 100644 --- a/installcheck/Amanda_Xfer.pl +++ b/installcheck/Amanda_Xfer.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Installcheck.pm b/installcheck/Installcheck.pm index 7d8cf36..ff5eb55 100644 --- a/installcheck/Installcheck.pm +++ b/installcheck/Installcheck.pm @@ -1,5 +1,5 @@ # vim:ft=perl -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Installcheck/Application.pm b/installcheck/Installcheck/Application.pm index 4c41157..daaef5b 100644 --- a/installcheck/Installcheck/Application.pm +++ b/installcheck/Installcheck/Application.pm @@ -1,5 +1,5 @@ # vim:ft=perl -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Installcheck/Catalogs.pm b/installcheck/Installcheck/Catalogs.pm index 5c38b1b..6c8fe5a 100644 --- a/installcheck/Installcheck/Catalogs.pm +++ b/installcheck/Installcheck/Catalogs.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Installcheck/Changer.pm b/installcheck/Installcheck/Changer.pm index 3864868..8c4432d 100644 --- a/installcheck/Installcheck/Changer.pm +++ b/installcheck/Installcheck/Changer.pm @@ -1,5 +1,5 @@ # vim:ft=perl -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Installcheck/ClientService.pm b/installcheck/Installcheck/ClientService.pm index 92b98df..e77b659 100644 --- a/installcheck/Installcheck/ClientService.pm +++ b/installcheck/Installcheck/ClientService.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Installcheck/Config.pm b/installcheck/Installcheck/Config.pm index 835bcf9..cf69801 100644 --- a/installcheck/Installcheck/Config.pm +++ b/installcheck/Installcheck/Config.pm @@ -1,5 +1,5 @@ # vim:ft=perl -# Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Installcheck/Dumpcache.pm b/installcheck/Installcheck/Dumpcache.pm index 784d6f9..7358428 100644 --- a/installcheck/Installcheck/Dumpcache.pm +++ b/installcheck/Installcheck/Dumpcache.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Installcheck/Mock.pm b/installcheck/Installcheck/Mock.pm index 0e46418..631b117 100644 --- a/installcheck/Installcheck/Mock.pm +++ b/installcheck/Installcheck/Mock.pm @@ -1,5 +1,5 @@ # vim:ft=perl -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Installcheck/Run.pm b/installcheck/Installcheck/Run.pm index 4b1d3a2..e3e29c3 100644 --- a/installcheck/Installcheck/Run.pm +++ b/installcheck/Installcheck/Run.pm @@ -1,5 +1,5 @@ # vim:ft=perl -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/Makefile.in b/installcheck/Makefile.in index 73b4c83..4388a2f 100644 --- a/installcheck/Makefile.in +++ b/installcheck/Makefile.in @@ -16,7 +16,7 @@ @SET_MAKE@ # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -38,7 +38,7 @@ # scripts in this directory. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -299,7 +299,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -816,6 +817,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/installcheck/amadmin.pl b/installcheck/amadmin.pl index 3868117..657c460 100644 --- a/installcheck/amadmin.pl +++ b/installcheck/amadmin.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -16,7 +16,7 @@ # Contact information: Zmanda Inc, 465 S Mathilda Ave, Suite 300 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com -use Test::More tests => 17; +use Test::More tests => 18; use strict; use warnings; @@ -120,3 +120,7 @@ amadmin: localhost:\\\\windows\\share-b is set to a forced level 0 at next run.$ like(run_get('amadmin TESTCONF force localhost share-a share-a'), qr/^amadmin: localhost:\\\\windows\\share-a is set to a forced level 0 at next run.$/, "shell 13"); + +like(run_get('amadmin TESTCONF balance --days 12'), + qr/No data to report on yet.$/, + "shell 13"); diff --git a/installcheck/amarchiver.pl b/installcheck/amarchiver.pl index 0c58e30..c0c6dff 100644 --- a/installcheck/amarchiver.pl +++ b/installcheck/amarchiver.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amcheck-device.pl b/installcheck/amcheck-device.pl index 02f1acb..45caa2f 100644 --- a/installcheck/amcheck-device.pl +++ b/installcheck/amcheck-device.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amcheck.pl b/installcheck/amcheck.pl index f186d25..c9214c6 100644 --- a/installcheck/amcheck.pl +++ b/installcheck/amcheck.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2007, 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amcheckdump.pl b/installcheck/amcheckdump.pl index 21fbdd5..7e7d97a 100644 --- a/installcheck/amcheckdump.pl +++ b/installcheck/amcheckdump.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2007, 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amdevcheck.pl b/installcheck/amdevcheck.pl index b26f487..d8423a5 100644 --- a/installcheck/amdevcheck.pl +++ b/installcheck/amdevcheck.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2007, 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amdump.pl b/installcheck/amdump.pl index 603d459..5c7e9fe 100644 --- a/installcheck/amdump.pl +++ b/installcheck/amdump.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amdump_client.pl b/installcheck/amdump_client.pl index 893a9e5..f938367 100644 --- a/installcheck/amdump_client.pl +++ b/installcheck/amdump_client.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amfetchdump.pl b/installcheck/amfetchdump.pl index 6cebfb8..a1adf9a 100644 --- a/installcheck/amfetchdump.pl +++ b/installcheck/amfetchdump.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amflush.pl b/installcheck/amflush.pl index 526b92e..009b207 100644 --- a/installcheck/amflush.pl +++ b/installcheck/amflush.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amgetconf.pl b/installcheck/amgetconf.pl index 5ae66d9..2854d20 100644 --- a/installcheck/amgetconf.pl +++ b/installcheck/amgetconf.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -216,7 +216,7 @@ is_deeply([sort(+split(qr/\n/, run_get('amgetconf', 'TESTCONF', 'device_property $testconf = Installcheck::Config->new(); $testconf->add_tapetype("cassette", [ length => "32 k" ]); $testconf->add_tapetype("reel2reel", [ length => "1 M" ]); -$testconf->add_tapetype("scotch", [ length => "500 bytes" ]); # (use a sharpie) +$testconf->add_tapetype("scotch", [ length => "512000 bytes" ]); $testconf->add_dumptype("testdump", [ comment => '"testdump-dumptype"', auth => '"bsd"' ]); $testconf->add_dumptype("testdump1", [ inherit => 'testdump' ]); diff --git a/installcheck/amgtar.pl b/installcheck/amgtar.pl index 2d87e5b..14bdb42 100644 --- a/installcheck/amgtar.pl +++ b/installcheck/amgtar.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amidxtaped.pl b/installcheck/amidxtaped.pl index e6ebc65..b29ac6f 100644 --- a/installcheck/amidxtaped.pl +++ b/installcheck/amidxtaped.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amlabel.pl b/installcheck/amlabel.pl index 5326f0b..dea6ea3 100644 --- a/installcheck/amlabel.pl +++ b/installcheck/amlabel.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amoverview.pl b/installcheck/amoverview.pl index 60ef71c..65d6ceb 100644 --- a/installcheck/amoverview.pl +++ b/installcheck/amoverview.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2007, 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/ampgsql.pl b/installcheck/ampgsql.pl index a2aa380..4c21d86 100644 --- a/installcheck/ampgsql.pl +++ b/installcheck/ampgsql.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amraw.pl b/installcheck/amraw.pl index 6931e12..c8eb5aa 100644 --- a/installcheck/amraw.pl +++ b/installcheck/amraw.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amrecover.pl b/installcheck/amrecover.pl index 2362d97..f7bedcc 100644 --- a/installcheck/amrecover.pl +++ b/installcheck/amrecover.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amreport.pl b/installcheck/amreport.pl index 3b48861..d8532d5 100644 --- a/installcheck/amreport.pl +++ b/installcheck/amreport.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amrestore.pl b/installcheck/amrestore.pl index 68fa881..032c9a6 100644 --- a/installcheck/amrestore.pl +++ b/installcheck/amrestore.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amrmtape.pl b/installcheck/amrmtape.pl index 585a353..1ddfa89 100644 --- a/installcheck/amrmtape.pl +++ b/installcheck/amrmtape.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amserverconfig.pl b/installcheck/amserverconfig.pl index 22e7c18..8c1567d 100644 --- a/installcheck/amserverconfig.pl +++ b/installcheck/amserverconfig.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amservice.pl b/installcheck/amservice.pl index 560ca27..9a93bc7 100644 --- a/installcheck/amservice.pl +++ b/installcheck/amservice.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amstatus.pl b/installcheck/amstatus.pl index fd2a1c3..1b71d9f 100644 --- a/installcheck/amstatus.pl +++ b/installcheck/amstatus.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amtape.pl b/installcheck/amtape.pl index 3220e70..9601b51 100644 --- a/installcheck/amtape.pl +++ b/installcheck/amtape.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amtapetype.pl b/installcheck/amtapetype.pl index c8cd108..38b70cc 100644 --- a/installcheck/amtapetype.pl +++ b/installcheck/amtapetype.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/amvault.pl b/installcheck/amvault.pl index b8a3971..917d6b4 100644 --- a/installcheck/amvault.pl +++ b/installcheck/amvault.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/bigint.pl b/installcheck/bigint.pl index 6fa8a35..011ac76 100644 --- a/installcheck/bigint.pl +++ b/installcheck/bigint.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/catalogs/bigdb.cat b/installcheck/catalogs/bigdb.cat index 37623f1..41351b7 100644 --- a/installcheck/catalogs/bigdb.cat +++ b/installcheck/catalogs/bigdb.cat @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/catalogs/bigestimate.cat b/installcheck/catalogs/bigestimate.cat index 7883b75..5af7180 100644 --- a/installcheck/catalogs/bigestimate.cat +++ b/installcheck/catalogs/bigestimate.cat @@ -54,9 +54,9 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ---------------------------------------- -------------- -home.slikon. /opt/public 0 72987320 50917369 69.8 46:57 18078.1 31:06 27287.8 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +------------------------------- ---------------------------------------- -------------- +home.slikon.local /opt/public 0 72987320 50917369 69.8 46:57 18078.1 31:06 27287.8 (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/doublefailure.cat b/installcheck/catalogs/doublefailure.cat index 9023244..67387f7 100644 --- a/installcheck/catalogs/doublefailure.cat +++ b/installcheck/catalogs/doublefailure.cat @@ -108,9 +108,9 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ------------------------------------- -------------- -ns-new.sliko /opt/var 0 54929 -- PARTIAL 0:04 15451.0 PARTIAL +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +--------------------------------- ------------------------------------- -------------- +ns-new.slikon.local /opt/var 0 54929 -- PARTIAL 0:04 15451.0 PARTIAL (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/filesystemstaped.cat b/installcheck/catalogs/filesystemstaped.cat index e5a4af3..d7c78d4 100644 --- a/installcheck/catalogs/filesystemstaped.cat +++ b/installcheck/catalogs/filesystemstaped.cat @@ -66,9 +66,9 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS - HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s - -------------------------- ------------------------------------- --------------- - localhost.lo /boot 2 10240 10240 -- FLUSH 0:00 446100.0 - localhost.lo /boot 1 20480 20480 -- FLUSH 0:00 446100.0 + HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s + ----------------------------------- ------------------------------------- --------------- + localhost.localdomain /boot 2 10240 10240 -- FLUSH 0:00 446100.0 + localhost.localdomain /boot 1 20480 20480 -- FLUSH 0:00 446100.0 (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/longstrange.cat b/installcheck/catalogs/longstrange.cat index 70f0f4b..2fe98ed 100644 --- a/installcheck/catalogs/longstrange.cat +++ b/installcheck/catalogs/longstrange.cat @@ -1177,8 +1177,8 @@ sendbackup: info end DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ------------------------------------- -------------- -bsdfw.slikon / 0 5401240 2293470 42.5 29:36 1305.4 2:37 14596.6 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +-------------------------------- ------------------------------------- -------------- +bsdfw.slikon.local / 0 5401240 2293470 42.5 29:36 1305.4 2:37 14596.6 (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/multi-taper.cat b/installcheck/catalogs/multi-taper.cat index cfff2bc..f53b040 100644 --- a/installcheck/catalogs/multi-taper.cat +++ b/installcheck/catalogs/multi-taper.cat @@ -140,13 +140,13 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS - HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s - -------------------------- ------------------------------------- -------------- - localhost.lo /bootAMGTAR 1 44610 44610 -- FLUSH 0:01 44610.0 - localhost.lo /bootAMGTAR 1 44610 44610 -- FLUSH 0:01 44610.0 - localhost.lo /bootAMGTAR 1 44610 44610 -- FLUSH 0:01 44610.0 - localhost.lo /bootAMGTAR 1 44610 44610 -- FLUSH 0:01 44610.0 - localhost.lo /bootAMGTAR 1 44610 44610 -- FLUSH 0:01 44610.0 + HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s + ----------------------------------- ------------------------------------- -------------- + localhost.localdomain /bootAMGTAR 1 44610 44610 -- FLUSH 0:01 44610.0 + localhost.localdomain /bootAMGTAR 1 44610 44610 -- FLUSH 0:01 44610.0 + localhost.localdomain /bootAMGTAR 1 44610 44610 -- FLUSH 0:01 44610.0 + localhost.localdomain /bootAMGTAR 1 44610 44610 -- FLUSH 0:01 44610.0 + localhost.localdomain /bootAMGTAR 1 44610 44610 -- FLUSH 0:01 44610.0 (brought to you by Amanda version 3.2.0alpha.git.8dca8d1f) diff --git a/installcheck/catalogs/normal.cat b/installcheck/catalogs/normal.cat index 1e73d43..9a1acfb 100644 --- a/installcheck/catalogs/normal.cat +++ b/installcheck/catalogs/normal.cat @@ -293,17 +293,17 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- -------------------------------------------- --------------- -localhost.lo /boot1 0 16 12 75.0 0:02 24748.4 0:00 156611.1 -localhost.lo /boot2 0 167 123 73.7 0:02 24748.4 0:00 156611.1 -localhost.lo /boot3 0 1678 1234 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot4 0 16789 12345 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot5 0 167890 123456 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot6 0 1678901 1234567 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot7 0 16789012 12345678 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot8 0 167890123 123456789 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot9 0 1678901234 1234567890 73.5 0:02 24748.4 0:00 156611.1 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +----------------------------------- -------------------------------------------- --------------- +localhost.localdomain /boot1 0 16 12 75.0 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot2 0 167 123 73.7 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot3 0 1678 1234 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot4 0 16789 12345 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot5 0 167890 123456 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot6 0 1678901 1234567 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot7 0 16789012 12345678 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot8 0 167890123 123456789 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot9 0 1678901234 1234567890 73.5 0:02 24748.4 0:00 156611.1 (brought to you by Amanda version x.y.z) %T rpt2 @@ -347,17 +347,17 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ----------------------------------------------- --------------- -localhost.lo /boot1 0 16.00 12 75.0 0:02 24748.4 0:00 156611.1 -localhost.lo /boot2 0 167.00 123 73.7 0:02 24748.4 0:00 156611.1 -localhost.lo /boot3 0 1678.00 1234 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot4 0 16789.00 12345 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot5 0 167890.00 123456 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot6 0 1678901.00 1234567 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot7 0 16789012.00 12345678 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot8 0 167890123.00 123456789 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot9 0 1678901234.00 1234567890 73.5 0:02 24748.4 0:00 156611.1 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +----------------------------------- ----------------------------------------------- --------------- +localhost.localdomain /boot1 0 16.00 12 75.0 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot2 0 167.00 123 73.7 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot3 0 1678.00 1234 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot4 0 16789.00 12345 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot5 0 167890.00 123456 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot6 0 1678901.00 1234567 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot7 0 16789012.00 12345678 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot8 0 167890123.00 123456789 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot9 0 1678901234.00 1234567890 73.5 0:02 24748.4 0:00 156611.1 (brought to you by Amanda version x.y.z) %T rpt3 @@ -401,17 +401,17 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- --------------------------------------- --------------- -localhost.lo /boot1 0 16 12 75.0 0:02 24748.4 0:00 156611.1 -localhost.lo /boot2 0 167 123 73.7 0:02 24748.4 0:00 156611.1 -localhost.lo /boot3 0 1678 1234 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot4 0 16789 12345 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot5 0 167890 123456 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot6 0 1678901 1234567 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot7 0 16789012 12345678 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot8 0 167890123 123456789 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot9 0 1678901234 1234567890 73.5 0:02 24748.4 0:00 156611.1 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +----------------------------------- --------------------------------------- --------------- +localhost.localdomain /boot1 0 16 12 75.0 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot2 0 167 123 73.7 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot3 0 1678 1234 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot4 0 16789 12345 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot5 0 167890 123456 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot6 0 1678901 1234567 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot7 0 16789012 12345678 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot8 0 167890123 123456789 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot9 0 1678901234 1234567890 73.5 0:02 24748.4 0:00 156611.1 (brought to you by Amanda version x.y.z) %T rpt4 @@ -455,17 +455,17 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- --------------------------------------- --------------- -localhost.lo /boot1 0 16.000000 12 75.0 0:02 24748.4 0:00 156611.1 -localhost.lo /boot2 0 167.000000 123 73.7 0:02 24748.4 0:00 156611.1 -localhost.lo /boot3 0 1678.000000 1234 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot4 0 16789.000000 12345 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot5 0 167890.000000 123456 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot6 0 1678901.000000 1234567 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot7 0 16789012.000000 12345678 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot8 0 167890123.000000 123456789 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot9 0 1678901234.000000 1234567890 73.5 0:02 24748.4 0:00 156611.1 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +----------------------------------- --------------------------------------- --------------- +localhost.localdomain /boot1 0 16.000000 12 75.0 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot2 0 167.000000 123 73.7 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot3 0 1678.000000 1234 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot4 0 16789.000000 12345 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot5 0 167890.000000 123456 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot6 0 1678901.000000 1234567 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot7 0 16789012.000000 12345678 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot8 0 167890123.000000 123456789 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot9 0 1678901234.000000 1234567890 73.5 0:02 24748.4 0:00 156611.1 (brought to you by Amanda version x.y.z) %T rpt5 @@ -509,16 +509,16 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-MB OUT-MB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- -------------------------------------- --------------- -localhost.lo /boot1 0 0 0 75.0 0:02 24748.4 0:00 156611.1 -localhost.lo /boot2 0 0 0 73.7 0:02 24748.4 0:00 156611.1 -localhost.lo /boot3 0 2 1 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot4 0 16 12 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot5 0 164 121 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot6 0 1640 1206 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot7 0 16396 12056 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot8 0 163955 120563 73.5 0:02 24748.4 0:00 156611.1 -localhost.lo /boot9 0 1639552 1205633 73.5 0:02 24748.4 0:00 156611.1 +HOSTNAME DISK L ORIG-MB OUT-MB COMP% MMM:SS KB/s MMM:SS KB/s +----------------------------------- -------------------------------------- --------------- +localhost.localdomain /boot1 0 0 0 75.0 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot2 0 0 0 73.7 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot3 0 2 1 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot4 0 16 12 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot5 0 164 121 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot6 0 1640 1206 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot7 0 16396 12056 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot8 0 163955 120563 73.5 0:02 24748.4 0:00 156611.1 +localhost.localdomain /boot9 0 1639552 1205633 73.5 0:02 24748.4 0:00 156611.1 (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/plannerfail.cat b/installcheck/catalogs/plannerfail.cat index dee6e55..3534461 100644 --- a/installcheck/catalogs/plannerfail.cat +++ b/installcheck/catalogs/plannerfail.cat @@ -64,11 +64,11 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ------------------------------------- ------------- -1.2.3.4 "C:/" FAILED -1.2.3.4 "-/Scripts" FAILED -1.2.3.4 "G:/" FAILED -1.2.3.4 SystemState FAILED +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +--------------------------------------- ------------------------------------- ------------- +1.2.3.4 "C:/" FAILED +1.2.3.4 "E:/Replication/Scripts" FAILED +1.2.3.4 "G:/" FAILED +1.2.3.4 SystemState FAILED (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/resultsmissing.cat b/installcheck/catalogs/resultsmissing.cat index a57d482..39ba210 100644 --- a/installcheck/catalogs/resultsmissing.cat +++ b/installcheck/catalogs/resultsmissing.cat @@ -67,13 +67,13 @@ USAGE BY TAPE: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ------------------------------------- -------------- -cnc.slikon.l / MISSING -------------------------------------------- -cnc.slikon.l /boot 0 20670 17245 83.4 0:04 4052.7 0:01 23216.5 -ns-new.sliko //usr/local 0 30 1 3.3 0:00 24.6 0:00 153.5 -ns-new.sliko /boot FAILED -ns-new.sliko /home MISSING -------------------------------------------- +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +--------------------------------- ------------------------------------- -------------- +cnc.slikon.local / MISSING -------------------------------------------- +cnc.slikon.local /boot 0 20670 17245 83.4 0:04 4052.7 0:01 23216.5 +ns-new.slikon.local //usr/local 0 30 1 3.3 0:00 24.6 0:00 153.5 +ns-new.slikon.local /boot FAILED +ns-new.slikon.local /home MISSING -------------------------------------------- (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/retried-nofinish.cat b/installcheck/catalogs/retried-nofinish.cat index 0e477e0..d3c55f1 100644 --- a/installcheck/catalogs/retried-nofinish.cat +++ b/installcheck/catalogs/retried-nofinish.cat @@ -66,8 +66,8 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ------------------------------------- -------------- -jamon.slikon /var 0 2985670 268356 9.0 0:53 5029.5 0:16 17213.6 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +-------------------------------- ------------------------------------- -------------- +jamon.slikon.local /var 0 2985670 268356 9.0 0:53 5029.5 0:16 17213.6 (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/retried-strange.cat b/installcheck/catalogs/retried-strange.cat index 6286eb8..006218b 100644 --- a/installcheck/catalogs/retried-strange.cat +++ b/installcheck/catalogs/retried-strange.cat @@ -134,8 +134,8 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ------------------------------------------ -------------- -lead.zmanda. -asurements 0 539140000 258237053 47.9 817:48 10987.7 57:16 75156.3 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +--------------------------------------- ------------------------------------------ -------------- +lead.zmanda.com /tensile-measurements 0 539140000 258237053 47.9 817:48 10987.7 57:16 75156.3 (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/retried.cat b/installcheck/catalogs/retried.cat index cf5ad06..7cebd7e 100644 --- a/installcheck/catalogs/retried.cat +++ b/installcheck/catalogs/retried.cat @@ -66,9 +66,9 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ------------------------------------- -------------- -jamon.slikon /var 0 2985670 268356 9.0 0:53 5029.5 0:16 17213.6 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +-------------------------------- ------------------------------------- -------------- +jamon.slikon.local /var 0 2985670 268356 9.0 0:53 5029.5 0:16 17213.6 (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/shortstrange.cat b/installcheck/catalogs/shortstrange.cat index 5c529c4..cc0ff9d 100644 --- a/installcheck/catalogs/shortstrange.cat +++ b/installcheck/catalogs/shortstrange.cat @@ -84,9 +84,9 @@ sendbackup: end DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ------------------------------------- -------------- -bsdfw.slikon / 0 5401240 2293470 42.5 29:36 1305.4 2:37 14596.6 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +-------------------------------- ------------------------------------- -------------- +bsdfw.slikon.local / 0 5401240 2293470 42.5 29:36 1305.4 2:37 14596.6 (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/skipped.cat b/installcheck/catalogs/skipped.cat index 314b068..b51dc30 100644 --- a/installcheck/catalogs/skipped.cat +++ b/installcheck/catalogs/skipped.cat @@ -45,8 +45,8 @@ USAGE BY TAPE: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ------------------------------------- ------------- -ns-new.sliko /boot SKIPPED ------------------------------------------- +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +--------------------------------- ------------------------------------- ------------- +ns-new.slikon.local /boot SKIPPED ------------------------------------------- (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/spanned.cat b/installcheck/catalogs/spanned.cat index 9328d6a..1e06ca6 100644 --- a/installcheck/catalogs/spanned.cat +++ b/installcheck/catalogs/spanned.cat @@ -87,9 +87,9 @@ NOTES: DUMP SUMMARY: DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- -------------------------------------- --------------- -euclid -server-src 0 21830 21830 -- 0:00 82641.8 0:00 244170.0 +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +------------------------------ -------------------------------------- --------------- +euclid /A/b/server-src 0 21830 21830 -- 0:00 82641.8 0:00 244170.0 (brought to you by Amanda version x.y.z) diff --git a/installcheck/catalogs/strontium.cat b/installcheck/catalogs/strontium.cat index 9503a71..6bc536f 100644 --- a/installcheck/catalogs/strontium.cat +++ b/installcheck/catalogs/strontium.cat @@ -105,13 +105,13 @@ NOTES: DUMP SUMMARY: - DUMPER STATS TAPER STATS -HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s --------------------------- ------------------------------------- --------------- -strontium /etc 1 270 270 -- 0:00 1146.3 0:00 140918.6 -strontium -me/elantra 1 10 10 -- 0:00 65.6 0:00 9033.4 -strontium /local 0 20 20 -- 0:00 133.9 0:00 27624.3 -strontium -ository_13 1 1350 1350 -- 0:01 2568.5 0:00 175006.5 + DUMPER STATS TAPER STATS +HOSTNAME DISK L ORIG-kB OUT-kB COMP% MMM:SS KB/s MMM:SS KB/s +--------------------------------------------------------------------------- ------------------------------------- --------------- +strontium /etc 1 270 270 -- 0:00 1146.3 0:00 140918.6 +strontium /home/elantra 1 10 10 -- 0:00 65.6 0:00 9033.4 +strontium /local 0 20 20 -- 0:00 133.9 0:00 27624.3 +strontium /zones/data/strontium.example.com/repositories/repository_13 1 1350 1350 -- 0:01 2568.5 0:00 175006.5 (brought to you by Amanda version x.y.z) diff --git a/installcheck/chunker.pl b/installcheck/chunker.pl index ccafbd7..540492b 100644 --- a/installcheck/chunker.pl +++ b/installcheck/chunker.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/example.pl b/installcheck/example.pl index 7d90484..3e889e7 100644 --- a/installcheck/example.pl +++ b/installcheck/example.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/gnutar.pl b/installcheck/gnutar.pl index 4136780..d54617a 100644 --- a/installcheck/gnutar.pl +++ b/installcheck/gnutar.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/mock/lpr.pl b/installcheck/mock/lpr.pl index f08ecf3..438f9ee 100644 --- a/installcheck/mock/lpr.pl +++ b/installcheck/mock/lpr.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/mock/mail.pl b/installcheck/mock/mail.pl index d77983f..dd88a1a 100644 --- a/installcheck/mock/mail.pl +++ b/installcheck/mock/mail.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/mock/mtx.pl b/installcheck/mock/mtx.pl index e2bedf9..6d154e7 100644 --- a/installcheck/mock/mtx.pl +++ b/installcheck/mock/mtx.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/mock_mtx.pl b/installcheck/mock_mtx.pl index 84a4970..ffc81f6 100644 --- a/installcheck/mock_mtx.pl +++ b/installcheck/mock_mtx.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/noop.pl b/installcheck/noop.pl index 285118f..9e1318b 100644 --- a/installcheck/noop.pl +++ b/installcheck/noop.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/pp-scripts.pl b/installcheck/pp-scripts.pl index 311e633..6451a93 100644 --- a/installcheck/pp-scripts.pl +++ b/installcheck/pp-scripts.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/run-ndmp.pl b/installcheck/run-ndmp.pl index 4f56fb1..6b76e09 100644 --- a/installcheck/run-ndmp.pl +++ b/installcheck/run-ndmp.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/installcheck/taper.pl b/installcheck/taper.pl index 17a63e4..9e56234 100644 --- a/installcheck/taper.pl +++ b/installcheck/taper.pl @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -643,7 +643,7 @@ taper_cmd("START-SCAN worker0 $handle"); taper_cmd("NEW-TAPE worker0 $handle"); like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/, "got proper NEW-TAPE worker0 $handle") or die; -like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes 0 kps [\d.]+\]" "" "No space left on device, splitting not enabled"$/, +like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes 0 kps [\d.]+\]" "" "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$/, "got PARTIAL") or die; # retry on the next tape $handle = "11-88899"; @@ -671,7 +671,7 @@ check_logs([ qr(^INFO taper Slot 1 without label can be labeled$), qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$), qr(^PARTPARTIAL taper TESTCONF01 1 localhost /var/log $datestamp 1/-1 0 \[sec [\d.]+ bytes 983040 kps [\d.]+\] "No space left on device"$), - qr(^PARTIAL taper localhost /var/log $datestamp 1 0 \[sec [\d.]+ bytes 0 kps [\d.]+\] "No space left on device, splitting not enabled"$), + qr(^PARTIAL taper localhost /var/log $datestamp 1 0 \[sec [\d.]+ bytes 0 kps [\d.]+\] "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$), qr(^INFO taper tape TESTCONF01 kb 0 fm 1 \[OK\]$), qr(^INFO taper Slot 2 without label can be labeled$), qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$), @@ -1201,7 +1201,7 @@ taper_cmd("START-SCAN worker0 $handle"); taper_cmd("NEW-TAPE worker0 $handle"); like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/, "got proper NEW-TAPE worker0 $handle") or die; -like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes \d* kps [\d.]+ orig-kb 1612\]" "" "No space left on device, splitting not enabled"$/, +like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes \d* kps [\d.]+ orig-kb 1612\]" "" "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$/, "got PARTIAL for filenum 1") or die; taper_cmd("QUIT"); wait_for_exit(); @@ -1210,7 +1210,7 @@ check_logs([ qr(^INFO taper Slot 1 without label can be labeled$), qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$), qr(^PARTPARTIAL taper TESTCONF01 1 localhost /usr $datestamp 1/-1 0 \[sec [\d.]+ bytes 983040 kps [\d.]+ orig-kb 1612\] \"No space left on device\"$), - qr(^PARTIAL taper localhost /usr $datestamp 1 0 \[sec [\d.]+ bytes 0 kps [\d.]+ orig-kb 1612\] "No space left on device, splitting not enabled"$), + qr(^PARTIAL taper localhost /usr $datestamp 1 0 \[sec [\d.]+ bytes 0 kps [\d.]+ orig-kb 1612\] "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$), qr(^INFO taper tape TESTCONF01 kb 0 fm 1 \[OK\]$), ], "without LEOM and without allow-split logged correctly"); cleanup_log(); diff --git a/man/Makefile.in b/man/Makefile.in index d396ddd..854aa64 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -190,7 +190,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -735,6 +736,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/man/amaddclient.8 b/man/amaddclient.8 index 9272624..775c21c 100644 --- a/man/amaddclient.8 +++ b/man/amaddclient.8 @@ -2,12 +2,12 @@ .\" Title: amaddclient .\" Author: Kevin Till .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMADDCLIENT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMADDCLIENT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amadmin.8 b/man/amadmin.8 index 85513f0..5e82985 100644 --- a/man/amadmin.8 +++ b/man/amadmin.8 @@ -2,12 +2,12 @@ .\" Title: amadmin .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMADMIN" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMADMIN" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -31,7 +31,7 @@ amadmin \- administrative interface to control Amanda backups .SH "SYNOPSIS" .HP \w'\fBamadmin\fR\ 'u -\fBamadmin\fR [\fB\-o\fR\ \fIconfigoption\fR...] \fIconfig\fR \fIcommand\fR [\fIcommand_options\fR...] +\fBamadmin\fR [\-\-version] [\-\-no\-default] [\-\-print\-source] [\fB\-o\fR\ \fIconfigoption\fR...] \fIconfig\fR \fIcommand\fR [\fIcommand_options\fR...] .SH "DESCRIPTION" .PP \fBAmadmin\fR @@ -42,6 +42,30 @@ Amanda configuration\&. See the \fBamanda\fR(8) man page for more details about Amanda\&. +.SH "OPTIONS" +.PP +\fB\-\-version\fR +.RS 4 +Print the version and exit\&. +.RE +.PP +\fB\-\-no\-default\fR +.RS 4 +Do not print default values for +\fBconfig\fR +and +\fBdisklist\fR +commands\&. +.RE +.PP +\fB\-\-print\-source\fR +.RS 4 +Print where a value is definedi for +\fBconfig\fR +and +\fBdisklist\fR +commands\&. +.RE .SH "COMMANDS" .PP Commands that take a diff --git a/man/amaespipe.8 b/man/amaespipe.8 index c01a2d4..36f9e89 100644 --- a/man/amaespipe.8 +++ b/man/amaespipe.8 @@ -2,12 +2,12 @@ .\" Title: amaespipe .\" Author: Kevin Till .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMAESPIPE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMAESPIPE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda-applications.7 b/man/amanda-applications.7 index a43f7f8..a52a711 100644 --- a/man/amanda-applications.7 +++ b/man/amanda-applications.7 @@ -2,12 +2,12 @@ .\" Title: amanda-applications .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: Miscellanea -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-APPLICATIONS" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea" +.TH "AMANDA\-APPLICATIONS" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda-archive-format.5 b/man/amanda-archive-format.5 index e673887..19cfe80 100644 --- a/man/amanda-archive-format.5 +++ b/man/amanda-archive-format.5 @@ -2,12 +2,12 @@ .\" Title: amanda-archive-format .\" Author: Dustin J. Mitchell .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: File formats and conventions -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-ARCHIVE\-FOR" "5" "02/21/2012" "Amanda 3\&.3\&.1" "File formats and conventions" +.TH "AMANDA\-ARCHIVE\-FOR" "5" "07/25/2012" "Amanda 3\&.3\&.2" "File formats and conventions" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda-auth.7 b/man/amanda-auth.7 index b9d3933..c4d9db1 100644 --- a/man/amanda-auth.7 +++ b/man/amanda-auth.7 @@ -2,12 +2,12 @@ .\" Title: amanda-auth .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: Miscellanea -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-AUTH" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea" +.TH "AMANDA\-AUTH" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda-changers.7 b/man/amanda-changers.7 index 230657f..1cef29e 100644 --- a/man/amanda-changers.7 +++ b/man/amanda-changers.7 @@ -2,12 +2,12 @@ .\" Title: amanda-changers .\" Author: Dustin J. Mitchell .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: Miscellanea -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-CHANGERS" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea" +.TH "AMANDA\-CHANGERS" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda-client.conf.5 b/man/amanda-client.conf.5 index c907c19..b040bd3 100644 --- a/man/amanda-client.conf.5 +++ b/man/amanda-client.conf.5 @@ -2,12 +2,12 @@ .\" Title: amanda-client.conf .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: File formats and conventions -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-CLIENT\&.CON" "5" "02/21/2012" "Amanda 3\&.3\&.1" "File formats and conventions" +.TH "AMANDA\-CLIENT\&.CON" "5" "07/25/2012" "Amanda 3\&.3\&.2" "File formats and conventions" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda-compatibility.7 b/man/amanda-compatibility.7 index 44850b0..afea373 100644 --- a/man/amanda-compatibility.7 +++ b/man/amanda-compatibility.7 @@ -2,12 +2,12 @@ .\" Title: amanda-compatibility .\" Author: Dustin J. Mitchell .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: Miscellanea -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-COMPATIBILIT" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea" +.TH "AMANDA\-COMPATIBILIT" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda-devices.7 b/man/amanda-devices.7 index 732fce5..3248c19 100644 --- a/man/amanda-devices.7 +++ b/man/amanda-devices.7 @@ -2,12 +2,12 @@ .\" Title: amanda-devices .\" Author: Ian Turner .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: Miscellanea -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-DEVICES" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea" +.TH "AMANDA\-DEVICES" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -397,6 +397,30 @@ device\-property "S3_ACCESS_KEY" "27D3B8C6C4E7AA423C2B37C72A0D22C8" device\-property "S3_SECRET_KEY" "agphc2Q7Zmxragphc2RmO2xragpzZGY7a2xqCgr" .fi .PP +CLIENT_ID +.RS 4 + +(read\-write) The client_id for oauth2\&. +.RE +.PP +CLIENT_SECRET +.RS 4 + +(read\-write) The client_secret for oauth2\&. +.RE +.PP +CREATE\-BUCKET +.RS 4 + +(read\-write) Default: yes\&. If amanda create/delete the bucket\&. +.RE +.PP +REFRESH_TOKEN +.RS 4 + +(read\-write) The refresh\-token for oauth2\&. +.RE +.PP MAX_RECV_SPEED .RS 4 @@ -413,6 +437,13 @@ data to S3\&. If the average speed exceeds this value, the device will stop writing long enough to bring the average below this value\&. .RE .PP +S3_MULTI_DELETE +.RS 4 + +(read\-write) If the server support the multi delete protocol (only Amazon S3), +default is "YES"\&. If it fail, it revert to single delete\&. +.RE +.PP NB_THREADS_BACKUP .RS 4 @@ -428,7 +459,31 @@ NB_THREADS_RECOVERY OPENSTACK_SWIFT_API .RS 4 - (read\-write) Set to yes if it is an openstack storage device\&. + (read\-write) Deprecated, set "STORAGE_API to "SWIFT\-1\&.0"\&. +.RE +.PP +PROXY +.RS 4 + + (read\-write) The proxy hostname or IP in the format "host[:port]"\&. +.RE +.PP +PASSWORD +.RS 4 + +(read\-write) The password (for swift v2)\&. +.RE +.PP +PROJECT\-ID +.RS 4 + +(read\-write) The projectid (for google)\&. +.RE +.PP +REUSE\-CONNECTION +.RS 4 + +(read\-write) Default: YES\&. Set it to "NO" if reusing a connection cause some bug, this is sometime the case with big block size\&. .RE .PP S3_ACCESS_KEY @@ -512,6 +567,35 @@ S3_USER_TOKEN (read\-write) This property specifies the user token for Amanda Enterprise Edition customers\&. .RE .PP +STORAGE_API +.RS 4 + + (read\-write) Which API to use for the cloud: +.nf + S3 Amanzon S3 api + SWITF\-1\&.0 Openstack swift v1\&.0 + SWIFT\-2\&.0 Openstack swift v2\&.0 +.fi +.RE +.PP +TENANT_ID +.RS 4 + +(read\-write) The tenant_id (for swift v2)\&. +.RE +.PP +TENANT_NAME +.RS 4 + +(read\-write) The tenant_name (for swift v2)\&. +.RE +.PP +USERNAME +.RS 4 + +(read\-write) The username (for swift v2)\&. +.RE +.PP VERBOSE .RS 4 @@ -627,6 +711,13 @@ and \fBNDMP_PASSWORD\fR set the username and password with which to access the NDMP server\&. The default for both is "ndmp"\&. .PP +INDIRECT +.RS 4 + +(read\-write) Set to "yes" if the ndmp server doesn\*(Aqt allow to set a window length to 0\&. +The default is "no"\&. +.RE +.PP NDMP_AUTH .RS 4 diff --git a/man/amanda-interactivity.7 b/man/amanda-interactivity.7 index 682da04..c3e8019 100644 --- a/man/amanda-interactivity.7 +++ b/man/amanda-interactivity.7 @@ -2,12 +2,12 @@ .\" Title: amanda-interactivity .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: Miscellanea -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-INTERACTIVIT" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea" +.TH "AMANDA\-INTERACTIVIT" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda-match.7 b/man/amanda-match.7 index 8a5a7dc..5777aec 100644 --- a/man/amanda-match.7 +++ b/man/amanda-match.7 @@ -2,12 +2,12 @@ .\" Title: amanda-match .\" Author: Dustin J. Mitchell .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: Miscellanea -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-MATCH" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea" +.TH "AMANDA\-MATCH" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda-scripts.7 b/man/amanda-scripts.7 index 762698d..62e5d1a 100644 --- a/man/amanda-scripts.7 +++ b/man/amanda-scripts.7 @@ -2,12 +2,12 @@ .\" Title: amanda-scripts .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: Miscellanea -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-SCRIPTS" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea" +.TH "AMANDA\-SCRIPTS" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda-taperscan.7 b/man/amanda-taperscan.7 index e380148..e0da8fd 100644 --- a/man/amanda-taperscan.7 +++ b/man/amanda-taperscan.7 @@ -2,12 +2,12 @@ .\" Title: amanda-taperscan .\" Author: Dustin J. Mitchell .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: Miscellanea -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\-TAPERSCAN" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea" +.TH "AMANDA\-TAPERSCAN" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda.8 b/man/amanda.8 index a0fac58..d18764d 100644 --- a/man/amanda.8 +++ b/man/amanda.8 @@ -2,12 +2,12 @@ .\" Title: amanda .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMANDA" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amanda.conf.5 b/man/amanda.conf.5 index 0fba0e2..d71edae 100644 --- a/man/amanda.conf.5 +++ b/man/amanda.conf.5 @@ -2,12 +2,12 @@ .\" Title: amanda.conf .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: File formats and conventions -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMANDA\&.CONF" "5" "02/21/2012" "Amanda 3\&.3\&.1" "File formats and conventions" +.TH "AMANDA\&.CONF" "5" "07/25/2012" "Amanda 3\&.3\&.2" "File formats and conventions" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -887,7 +887,7 @@ setting\&. .PP \fBcolumnspec\fR \fIstring\fR .RS 4 -default: "HostName=0:12:12,Disk=1:11:11,Level=1:1:1,OrigKB=1:\-7:0,OutKB=1:\-7:0,Compress=1:\-6:1,DumpTime=1:\-7:7,Dumprate=1:\-6:1,TapeTime=1:\-6:6,TapeRate=1:\-6:1" +default: "HostName=0:\-12:12,Disk=1:\-11:11,Level=1:\-1:1,OrigKB=1:\-7:0,OutKB=1:\-7:0,Compress=1:\-6:1,DumpTime=1:\-7:7,Dumprate=1:\-6:1,TapeTime=1:\-6:6,TapeRate=1:\-6:1" .sp Defines the width of columns \fBamreport\fR @@ -1130,6 +1130,11 @@ The error messages that appear in amrecover are intentionally vague to avoid inf .sp Recovery limits can be refined on a per\-DLE basis using the dumptype parameter of the same name\&. Note that the default value will apply to any dumpfiles for disks which no longer appear in the disklist; thus leaving the global parameter at its default value but setting it for all DLEs is not sufficient to maintain secure backups\&. .RE +.PP +\fBtmpdir\fR \fIstring\fR +.RS 4 +Default: none (system default)\&. Set it to a directory with lots of free space if sort in amindexd fail with \*(AqNo space left on device\*(Aq\&. +.RE .SH "HOLDINGDISK SECTION" .PP The @@ -1650,6 +1655,12 @@ Default: \fI10000\fR\&. The maximum number of day for a promotion, set it 0 if you don\*(Aqt want promotion, set it to 1 or 2 if your disks get overpromoted\&. .RE .PP +\fBmax\-warnings\fR \fIint\fR +.RS 4 +Default: +\fI20\fR\&. The maximum number of error lines in the report for a dle\&. A value of \*(Aq0\*(Aq means unlimited\&. This is useful to reduce the size of the log file and the size of the report\&. All errors are put in separate files if a dle have more errors\&. +.RE +.PP \fBpriority\fR [ \fBlow\fR | \fBmedium\fR | \fBhigh\fR ] .RS 4 Default: @@ -2443,7 +2454,7 @@ Default: not set\&. A comment string describing this taperscan\&. \fBplugin\fR \fIstring\fR .RS 4 No default\&. Must be set to the name of the taperscan module\&. See - +\fBamanda-taperscan\fR(7) for a list of defined taperscan modules\&. .RE .PP diff --git a/man/amarchiver.8 b/man/amarchiver.8 index 18e802b..460de8a 100644 --- a/man/amarchiver.8 +++ b/man/amarchiver.8 @@ -2,12 +2,12 @@ .\" Title: amarchiver .\" Author: Dustin J. Mitchell .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMARCHIVER" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMARCHIVER" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amcheck.8 b/man/amcheck.8 index a8d414c..717690f 100644 --- a/man/amcheck.8 +++ b/man/amcheck.8 @@ -2,12 +2,12 @@ .\" Title: amcheck .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMCHECK" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMCHECK" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amcheckdb.8 b/man/amcheckdb.8 index 1fda719..faa3586 100644 --- a/man/amcheckdb.8 +++ b/man/amcheckdb.8 @@ -2,12 +2,12 @@ .\" Title: amcheckdb .\" Author: Adrian T. Filipi-Martin .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMCHECKDB" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMCHECKDB" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amcheckdump.8 b/man/amcheckdump.8 index 7a73f7d..0879e84 100644 --- a/man/amcheckdump.8 +++ b/man/amcheckdump.8 @@ -2,12 +2,12 @@ .\" Title: amcheckdump .\" Author: Ian Turner .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMCHECKDUMP" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMCHECKDUMP" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amcleanup.8 b/man/amcleanup.8 index 600e272..5f6376d 100644 --- a/man/amcleanup.8 +++ b/man/amcleanup.8 @@ -2,12 +2,12 @@ .\" Title: amcleanup .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMCLEANUP" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMCLEANUP" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amcleanupdisk.8 b/man/amcleanupdisk.8 index e7409b6..80568c9 100644 --- a/man/amcleanupdisk.8 +++ b/man/amcleanupdisk.8 @@ -2,12 +2,12 @@ .\" Title: amcleanupdisk .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMCLEANUPDISK" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMCLEANUPDISK" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amcrypt-ossl-asym.8 b/man/amcrypt-ossl-asym.8 index e2c19b9..1f53dec 100644 --- a/man/amcrypt-ossl-asym.8 +++ b/man/amcrypt-ossl-asym.8 @@ -2,12 +2,12 @@ .\" Title: amcrypt-ossl-asym .\" Author: Kevin Till .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMCRYPT\-OSSL\-ASYM" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMCRYPT\-OSSL\-ASYM" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amcrypt-ossl.8 b/man/amcrypt-ossl.8 index 4f23318..598913e 100644 --- a/man/amcrypt-ossl.8 +++ b/man/amcrypt-ossl.8 @@ -2,12 +2,12 @@ .\" Title: amcrypt-ossl .\" Author: Kevin Till .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMCRYPT\-OSSL" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMCRYPT\-OSSL" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amcrypt.8 b/man/amcrypt.8 index a8cadc1..294a3c6 100644 --- a/man/amcrypt.8 +++ b/man/amcrypt.8 @@ -2,12 +2,12 @@ .\" Title: amcrypt .\" Author: Kevin Till .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMCRYPT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMCRYPT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amcryptsimple.8 b/man/amcryptsimple.8 index 282ac80..60ac4d7 100644 --- a/man/amcryptsimple.8 +++ b/man/amcryptsimple.8 @@ -2,12 +2,12 @@ .\" Title: amcryptsimple .\" Author: Kevin Till .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMCRYPTSIMPLE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMCRYPTSIMPLE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amdevcheck.8 b/man/amdevcheck.8 index 7dce8a9..c3c4fc4 100644 --- a/man/amdevcheck.8 +++ b/man/amdevcheck.8 @@ -2,12 +2,12 @@ .\" Title: amdevcheck .\" Author: Ian Turner .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMDEVCHECK" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMDEVCHECK" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amdump.8 b/man/amdump.8 index 59d1e9c..4736555 100644 --- a/man/amdump.8 +++ b/man/amdump.8 @@ -2,12 +2,12 @@ .\" Title: amdump .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMDUMP" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMDUMP" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amdump_client.8 b/man/amdump_client.8 index 8408481..05dab6f 100644 --- a/man/amdump_client.8 +++ b/man/amdump_client.8 @@ -2,12 +2,12 @@ .\" Title: amdump_client .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMDUMP_CLIENT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMDUMP_CLIENT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amfetchdump.8 b/man/amfetchdump.8 index 63e155a..b039c37 100644 --- a/man/amfetchdump.8 +++ b/man/amfetchdump.8 @@ -2,12 +2,12 @@ .\" Title: amfetchdump .\" Author: John Stange .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMFETCHDUMP" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMFETCHDUMP" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -31,11 +31,11 @@ amfetchdump \- extract backup images from multiple Amanda tapes\&. .SH "SYNOPSIS" .HP \w'\fBamfetchdump\fR\ 'u -\fBamfetchdump\fR [\-c|\-C|\-L] [\-p|\-n] [\-a] [\-O\ \fIdirectory\fR] [\-d\ \fIdevice\fR] [\-h] [\-\-header\-file\ \fIfilename\fR] [\-\-header\-fd\ \fIfd\fR] [\fB\-o\fR\ \fIconfigoption\fR...] \fIconfig\fR \fIhostname\fR [\fIdisk\fR\ [\ \fIdate\fR\ [\ \fIlevel\fR\ [\ \fIhostname\fR\ [\&.\&.\&.]\ ]\ ]\ ]] +\fBamfetchdump\fR [\-c | \-C | \-l] [\-p | \-n] [\-a] [\-O\ \fIdirectory\fR] [\-d\ \fIdevice\fR] [\-h | \-\-header\-file\ \fIfilename\fR | \-\-header\-fd\ \fIfd\fR] [\-\-decompress | \-\-no\-decompress | \-\-server\-decompress | \-\-client\-decompress] [\-\-decrypt | \-\-no\-decrypt | \-\-server\-decrypt | \-\-client\-decrypt] [\fB\-o\fR\ \fIconfigoption\fR...] \fIconfig\fR \fIhostname\fR [\fIdisk\fR\ [\ \fIdate\fR\ [\ \fIlevel\fR\ [\ \fIhostname\fR\ [\&.\&.\&.]\ ]\ ]\ ]] .SH "DESCRIPTION" .PP \fBAmfetchdump\fR -pulls one or more matching dumps from tape or from the holding disk, handling the reassembly of multi\-tape split dump files as well as any tape autochanger operations\&. +pulls one or more matching dumps from tape or from the holding disk, handling the reassembly of multi\-tape split dump files as well as any tape autochanger operations\&. The dump are by default decompressed and decrypted\&. .PP It will automatically use the Amanda catalog to locate available dumps on tape, in the same way that the \fBfind\fR @@ -105,11 +105,51 @@ Compress output, fastest method available\&. Compress output, smallest file size method available\&. .RE .PP +\fB\-\-decompress\fR +.RS 4 +Always do the decompression, this is the default\&. +.RE +.PP +\fB\-\-no\-decompress\fR +.RS 4 +Never do the decompression\&. +.RE +.PP +\fB\-\-server\-decompress\fR +.RS 4 +Do the decompression only if the compression was done on the server\&. +.RE +.PP +\fB\-\-client\-decompress\fR +.RS 4 +Do the decompression only if the compression was done on the client\&. +.RE +.PP +\fB\-\-decrypt\fR +.RS 4 +Always do the decryption, this is the default\&. +.RE +.PP +\fB\-\-no\-decrypt\fR +.RS 4 +Never do the decryption\&. +.RE +.PP +\fB\-\-server\-decrypt\fR +.RS 4 +Do the decryption only if the encryption was done on the server\&. +.RE +.PP +\fB\-\-client\-decrypt\fR +.RS 4 +Do the decryption only if the encryption was done on the client\&. +.RE +.PP \fB\-l\fR .RS 4 -Leave dumps in the compressed/uncompressed state in which they were found on tape\&. By default, -\fBamfetchdump\fR -will automatically uncompress when restoring\&. +Leave dumps in the compressed/uncompressed and encrypted/unencrypted state in which they were found on tape\&. It is a synonym for +\fB\-\-no\-decompression\fR +\fB\-\-no\-decryption\fR .RE .PP \fB\-a\fR diff --git a/man/amflush.8 b/man/amflush.8 index a36d55b..d37d063 100644 --- a/man/amflush.8 +++ b/man/amflush.8 @@ -2,12 +2,12 @@ .\" Title: amflush .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMFLUSH" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMFLUSH" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amgetconf.8 b/man/amgetconf.8 index adcc61d..fe77723 100644 --- a/man/amgetconf.8 +++ b/man/amgetconf.8 @@ -2,12 +2,12 @@ .\" Title: amgetconf .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMGETCONF" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMGETCONF" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amgpgcrypt.8 b/man/amgpgcrypt.8 index fc8e3e4..6489a6d 100644 --- a/man/amgpgcrypt.8 +++ b/man/amgpgcrypt.8 @@ -2,12 +2,12 @@ .\" Title: amgpgcrypt .\" Author: Kevin Till .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMGPGCRYPT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMGPGCRYPT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amgtar.8 b/man/amgtar.8 index e6d1f8e..9cc2abd 100644 --- a/man/amgtar.8 +++ b/man/amgtar.8 @@ -2,12 +2,12 @@ .\" Title: amgtar .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMGTAR" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMGTAR" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -87,6 +87,13 @@ GNUTAR\-PATH The path to the gnutar binary\&. The default is set when Amanda is built\&. .RE .PP +IGNORE\-ZEROS +.RS 4 + +If "YES" (the default), use the \fI\-\-ignore\-zeros\fR argument of gtar on recovery, +set it to "NO" if you do not want that argument\&. +.RE +.PP INCLUDE\-LIST\-GLOB .RS 4 @@ -251,7 +258,7 @@ A dumptype using this application might look like: Note that the \fIprogram\fR parameter must be set to -\fI"APPLCIATION"\fR +\fI"APPLICATION"\fR to use the \fIapplication\fR parameter\&. diff --git a/man/amlabel.8 b/man/amlabel.8 index 66c1862..0d8203c 100644 --- a/man/amlabel.8 +++ b/man/amlabel.8 @@ -2,12 +2,12 @@ .\" Title: amlabel .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMLABEL" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMLABEL" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amoverview.8 b/man/amoverview.8 index 8041bb8..dc93d12 100644 --- a/man/amoverview.8 +++ b/man/amoverview.8 @@ -2,12 +2,12 @@ .\" Title: amoverview .\" Author: Stefan G. Weichinger .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMOVERVIEW" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMOVERVIEW" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/ampgsql.8 b/man/ampgsql.8 index 2ef913a..a51fbf3 100644 --- a/man/ampgsql.8 +++ b/man/ampgsql.8 @@ -2,12 +2,12 @@ .\" Title: ampgsql .\" Author: Nikolas Coukouma .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMPGSQL" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMPGSQL" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amplot.8 b/man/amplot.8 index a26efa0..5b8b4e8 100644 --- a/man/amplot.8 +++ b/man/amplot.8 @@ -2,12 +2,12 @@ .\" Title: amplot .\" Author: Olafur Gudmundsson .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMPLOT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMPLOT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amraw.8 b/man/amraw.8 index 66133d0..81e9894 100644 --- a/man/amraw.8 +++ b/man/amraw.8 @@ -2,12 +2,12 @@ .\" Title: amraw .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMRAW" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMRAW" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amrecover.8 b/man/amrecover.8 index 6c6dd4d..c52e765 100644 --- a/man/amrecover.8 +++ b/man/amrecover.8 @@ -2,12 +2,12 @@ .\" Title: amrecover .\" Author: Alan M. McIvor .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMRECOVER" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMRECOVER" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amreport.8 b/man/amreport.8 index 95b8a7f..dd3ccda 100644 --- a/man/amreport.8 +++ b/man/amreport.8 @@ -2,12 +2,12 @@ .\" Title: amreport .\" Author: Stefan G. Weichinger .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMREPORT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMREPORT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amrestore.8 b/man/amrestore.8 index a6bb8e9..2dfb3b5 100644 --- a/man/amrestore.8 +++ b/man/amrestore.8 @@ -2,12 +2,12 @@ .\" Title: amrestore .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMRESTORE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMRESTORE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amrmtape.8 b/man/amrmtape.8 index 66699bf..18c67e4 100644 --- a/man/amrmtape.8 +++ b/man/amrmtape.8 @@ -2,12 +2,12 @@ .\" Title: amrmtape .\" Author: Adrian T. Filipi-Martin .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMRMTAPE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMRMTAPE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amsamba.8 b/man/amsamba.8 index 291e71f..afd7ae4 100644 --- a/man/amsamba.8 +++ b/man/amsamba.8 @@ -2,12 +2,12 @@ .\" Title: amsamba .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMSAMBA" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMSAMBA" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amserverconfig.8 b/man/amserverconfig.8 index a038d9a..fb5607d 100644 --- a/man/amserverconfig.8 +++ b/man/amserverconfig.8 @@ -2,12 +2,12 @@ .\" Title: amserverconfig .\" Author: Kevin Till .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMSERVERCONFIG" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMSERVERCONFIG" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amservice.8 b/man/amservice.8 index 1cd2768..f68ce63 100644 --- a/man/amservice.8 +++ b/man/amservice.8 @@ -2,12 +2,12 @@ .\" Title: amservice .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMSERVICE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMSERVICE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amstar.8 b/man/amstar.8 index 1434d7e..854757c 100644 --- a/man/amstar.8 +++ b/man/amstar.8 @@ -2,12 +2,12 @@ .\" Title: amstar .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMSTAR" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMSTAR" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amstatus.8 b/man/amstatus.8 index 3c7663e..cf2716c 100644 --- a/man/amstatus.8 +++ b/man/amstatus.8 @@ -2,12 +2,12 @@ .\" Title: amstatus .\" Author: Stefan G. Weichinger .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMSTATUS" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMSTATUS" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amsuntar.8 b/man/amsuntar.8 index cb6d161..6e10904 100644 --- a/man/amsuntar.8 +++ b/man/amsuntar.8 @@ -2,12 +2,12 @@ .\" Title: amsuntar .\" Author: Satya Ganga .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMSUNTAR" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMSUNTAR" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amtape.8 b/man/amtape.8 index ce9be5c..3c68fab 100644 --- a/man/amtape.8 +++ b/man/amtape.8 @@ -2,12 +2,12 @@ .\" Title: amtape .\" Author: Dustin J. Mitchell .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMTAPE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMTAPE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amtapetype.8 b/man/amtapetype.8 index a3f8c4e..174dcd0 100644 --- a/man/amtapetype.8 +++ b/man/amtapetype.8 @@ -2,12 +2,12 @@ .\" Title: amtapetype .\" Author: Dustin J. Mitchell .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMTAPETYPE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMTAPETYPE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amtoc.8 b/man/amtoc.8 index baf93a4..25df1ec 100644 --- a/man/amtoc.8 +++ b/man/amtoc.8 @@ -2,12 +2,12 @@ .\" Title: amtoc .\" Author: Nicolas Mayencourt .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMTOC" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMTOC" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amvault.8 b/man/amvault.8 index 8fbc661..8e211a3 100644 --- a/man/amvault.8 +++ b/man/amvault.8 @@ -2,12 +2,12 @@ .\" Title: amvault .\" Author: Dustin J. Mitchell .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMVAULT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMVAULT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/amzfs-sendrecv.8 b/man/amzfs-sendrecv.8 index bdaacba..bef01fb 100644 --- a/man/amzfs-sendrecv.8 +++ b/man/amzfs-sendrecv.8 @@ -2,12 +2,12 @@ .\" Title: amzfs-sendrecv .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMZFS\-SENDRECV" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMZFS\-SENDRECV" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -111,7 +111,7 @@ In this example, a dumptype is defined to use amzfs\-sendrecv application to bac } define dumptype user\-zfs\-sendrecv { - program "APPLICATAION" + program "APPLICATION" application "amzfs_sendrecv" } .fi diff --git a/man/amzfs-snapshot.8 b/man/amzfs-snapshot.8 index e32a9ab..acdc3f2 100644 --- a/man/amzfs-snapshot.8 +++ b/man/amzfs-snapshot.8 @@ -2,12 +2,12 @@ .\" Title: amzfs-snapshot .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "AMZFS\-SNAPSHOT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "AMZFS\-SNAPSHOT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/disklist.5 b/man/disklist.5 index 84bd2d4..83d9687 100644 --- a/man/disklist.5 +++ b/man/disklist.5 @@ -2,12 +2,12 @@ .\" Title: disklist .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: File formats and conventions -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "DISKLIST" "5" "02/21/2012" "Amanda 3\&.3\&.1" "File formats and conventions" +.TH "DISKLIST" "5" "07/25/2012" "Amanda 3\&.3\&.2" "File formats and conventions" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -33,7 +33,19 @@ disklist \- List of partitions to back up for Amanda .PP The \fIdisklist\fR -file determines which disks will be backed up by Amanda\&. The file usually contains one line per disk: +file determines which disks will be backed up by Amanda\&. The file contains +\fBincludefile\fR +directive or disklist entry (\fBDLE\fR)\&. +.PP +\fBincludefile\fR \fIstring\fR +.RS 4 +Default: +\fIno default\fR\&. The name of a disklist file to include within the current file\&. Useful for sharing disklist among several configurations\&. Relative pathnames are relative to the configuration directory\&. +.RE +.PP +A +\fBDLE\fR +usually contains one line per disk: .nf \fIhostname diskname\fR [\fIdiskdevice\fR] \fIdumptype\fR [\fIspindle\fR [\fIinterface\fR] ] .fi diff --git a/man/script-email.8 b/man/script-email.8 index bd636da..4681668 100644 --- a/man/script-email.8 +++ b/man/script-email.8 @@ -2,12 +2,12 @@ .\" Title: script-email .\" Author: Jean-Louis Martineau .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: System Administration Commands -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "SCRIPT\-EMAIL" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands" +.TH "SCRIPT\-EMAIL" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/tapelist.5 b/man/tapelist.5 index 83fce3e..eed93ba 100644 --- a/man/tapelist.5 +++ b/man/tapelist.5 @@ -2,12 +2,12 @@ .\" Title: tapelist .\" Author: James da Silva .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 02/21/2012 +.\" Date: 07/25/2012 .\" Manual: File formats and conventions -.\" Source: Amanda 3.3.1 +.\" Source: Amanda 3.3.2 .\" Language: English .\" -.TH "TAPELIST" "5" "02/21/2012" "Amanda 3\&.3\&.1" "File formats and conventions" +.TH "TAPELIST" "5" "07/25/2012" "Amanda 3\&.3\&.2" "File formats and conventions" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/man/xml-source/amadmin.8.xml b/man/xml-source/amadmin.8.xml index 5d0905a..4b4aafd 100644 --- a/man/xml-source/amadmin.8.xml +++ b/man/xml-source/amadmin.8.xml @@ -30,6 +30,9 @@ amadmin + --version + --no-default + --print-source &configoverride.synopsis; config command @@ -49,6 +52,26 @@ Amanda configuration. man page for more details about Amanda. +OPTIONS + + + +Print the version and exit. + + + +Do not print default values for config +and disklist commands. + + + +Print where a value is definedi for config +and disklist commands. + + + + + COMMANDS Commands that take a hostname [ disks ] parameter pair operate on all disks in the &disklist; for that diff --git a/man/xml-source/amanda-devices.7.xml b/man/xml-source/amanda-devices.7.xml index 575b065..f122e98 100644 --- a/man/xml-source/amanda-devices.7.xml +++ b/man/xml-source/amanda-devices.7.xml @@ -423,6 +423,22 @@ device-property "S3_SECRET_KEY" "agphc2Q7Zmxragphc2RmO2xragpzZGY7a2xqCgr" + + CLIENT_ID +(read-write) The client_id for oauth2. + + + CLIENT_SECRET +(read-write) The client_secret for oauth2. + + + CREATE-BUCKET +(read-write) Default: yes. If amanda create/delete the bucket. + + + REFRESH_TOKEN +(read-write) The refresh-token for oauth2. + MAX_RECV_SPEED (read-write) Maximum speed, in bytes per second, that this device will receive @@ -434,6 +450,11 @@ reading long enough to bring the average below this value. (read-write) Maximum speed, in bytes per second, that this device will send data to S3. If the average speed exceeds this value, the device will stop writing long enough to bring the average below this value. + + + S3_MULTI_DELETE +(read-write) If the server support the multi delete protocol (only Amazon S3), +default is "YES". If it fail, it revert to single delete. NB_THREADS_BACKUP @@ -445,7 +466,23 @@ writing long enough to bring the average below this value. OPENSTACK_SWIFT_API - (read-write) Set to yes if it is an openstack storage device. + (read-write) Deprecated, set "STORAGE_API to "SWIFT-1.0". + + + PROXY + (read-write) The proxy hostname or IP in the format "host[:port]". + + + PASSWORD +(read-write) The password (for swift v2). + + + PROJECT-ID +(read-write) The projectid (for google). + + + REUSE-CONNECTION +(read-write) Default: YES. Set it to "NO" if reusing a connection cause some bug, this is sometime the case with big block size. S3_ACCESS_KEY @@ -507,6 +544,27 @@ for the most up-to-date list. S3_USER_TOKEN (read-write) This property specifies the user token for Amanda Enterprise Edition customers. + + + STORAGE_API + (read-write) Which API to use for the cloud: + + S3 Amanzon S3 api + SWITF-1.0 Openstack swift v1.0 + SWIFT-2.0 Openstack swift v2.0 + + + + TENANT_ID +(read-write) The tenant_id (for swift v2). + + + TENANT_NAME +(read-write) The tenant_name (for swift v2). + + + USERNAME +(read-write) The username (for swift v2). VERBOSE @@ -634,6 +692,11 @@ access the NDMP server. The default for both is "ndmp". +INDIRECT +(read-write) Set to "yes" if the ndmp server doesn't allow to set a window length to 0. +The default is "no". + + NDMP_AUTH (read-write) Authentication method to use to connect to the NDMP server. One of "md5" (default), "text", "none" (for an empty authentication attempt) or "void" (for diff --git a/man/xml-source/amanda.conf.5.xml b/man/xml-source/amanda.conf.5.xml index 33353eb..e8d1fc0 100644 --- a/man/xml-source/amanda.conf.5.xml +++ b/man/xml-source/amanda.conf.5.xml @@ -1159,7 +1159,7 @@ is the same as the amrecover-changer setting. columnspec string - default: "HostName=0:12:12,Disk=1:11:11,Level=1:1:1,OrigKB=1:-7:0,OutKB=1:-7:0,Compress=1:-6:1,DumpTime=1:-7:7,Dumprate=1:-6:1,TapeTime=1:-6:6,TapeRate=1:-6:1" + default: "HostName=0:-12:12,Disk=1:-11:11,Level=1:-1:1,OrigKB=1:-7:0,OutKB=1:-7:0,Compress=1:-6:1,DumpTime=1:-7:7,Dumprate=1:-6:1,TapeTime=1:-6:6,TapeRate=1:-6:1" Defines the width of columns amreport should use. String @@ -1465,6 +1465,13 @@ Range is inclusive. + + tmpdir string + +Default: none (system default). Set it to a directory with lots of free +space if sort in amindexd fail with 'No space left on device'. + + @@ -2114,6 +2121,17 @@ See also the main section parameter inparallel. 10000. The maximum number of day for a promotion, set it 0 if you don't want promotion, set it to 1 or 2 if your disks get overpromoted. + + + + max-warnings int + +Default: +20. +The maximum number of error lines in the report for a dle. A value of '0' +means unlimited. This is useful to reduce the size of the log file and the +size of the report. All errors are put in separate files if a dle have more +errors. @@ -3081,7 +3099,7 @@ A comment string describing this taperscan. plugin string -No default. Must be set to the name of the taperscan module. See for a list of defined taperscan modules. +No default. Must be set to the name of the taperscan module. See for a list of defined taperscan modules. diff --git a/man/xml-source/amfetchdump.8.xml b/man/xml-source/amfetchdump.8.xml index 89ee3c7..b934b2d 100644 --- a/man/xml-source/amfetchdump.8.xml +++ b/man/xml-source/amfetchdump.8.xml @@ -28,14 +28,35 @@ amfetchdump - -c|-C|-L - -p|-n + + -c + -C + -l + + + -p + -n + -a -O directory -d device - -h - --header-file filename - --header-fd fd + + -h + --header-file filename + --header-fd fd + + + --decompress + --no-decompress + --server-decompress + --client-decompress + + + --decrypt + --no-decrypt + --server-decrypt + --client-decrypt + &configoverride.synopsis; config hostname @@ -60,7 +81,8 @@ Amfetchdump pulls one or more matching dumps from tape or from the holding disk, handling the reassembly of multi-tape split dump files as well as any -tape autochanger operations. +tape autochanger operations. The dump are by default decompressed and decrypted. + It will automatically use the Amanda catalog to locate available dumps on tape, in the same way that the Compress output, smallest file size method available. + + + Always do the decompression, this is the default. + + + + Never do the decompression. + + + + Do the decompression only if the compression was done on +the server. + + + + Do the decompression only if the compression was done on +the client. + + + + Always do the decryption, this is the default. + + + + Never do the decryption. + + + + Do the decryption only if the encryption was done on +the server. + + + + Do the decryption only if the encryption was done on +the client. + -Leave dumps in the compressed/uncompressed state in which they -were found on tape. By default, amfetchdump will automatically uncompress when -restoring. +Leave dumps in the compressed/uncompressed and +encrypted/unencrypted state in which they were found on tape. +It is a synonym for + diff --git a/man/xml-source/amgtar.8.xml b/man/xml-source/amgtar.8.xml index 852b31e..557e563 100644 --- a/man/xml-source/amgtar.8.xml +++ b/man/xml-source/amgtar.8.xml @@ -75,6 +75,11 @@ The directory where gnutar stores the database it uses to generate incremental d GNUTAR-PATH The path to the gnutar binary. The default is set when Amanda is built. + + + IGNORE-ZEROS +If "YES" (the default), use the --ignore-zeros argument of gtar on recovery, +set it to "NO" if you do not want that argument. INCLUDE-LIST-GLOB @@ -218,7 +223,7 @@ A dumptype using this application might look like: } Note that the program parameter must be set to -"APPLCIATION" to use the application +"APPLICATION" to use the application parameter. diff --git a/man/xml-source/amzfs-sendrecv.8.xml b/man/xml-source/amzfs-sendrecv.8.xml index 5fbfbcc..f76823b 100644 --- a/man/xml-source/amzfs-sendrecv.8.xml +++ b/man/xml-source/amzfs-sendrecv.8.xml @@ -108,7 +108,7 @@ In this example, a dumptype is defined to use amzfs-sendrecv application to back } define dumptype user-zfs-sendrecv { - program "APPLICATAION" + program "APPLICATION" application "amzfs_sendrecv" } diff --git a/man/xml-source/disklist.5.xml b/man/xml-source/disklist.5.xml index d8abab6..80c0c96 100644 --- a/man/xml-source/disklist.5.xml +++ b/man/xml-source/disklist.5.xml @@ -30,8 +30,25 @@ DESCRIPTION The disklist -file determines which disks will be backed up by Amanda. -The file usually contains one line per disk: +file determines which disks will be backed up by Amanda. The file contains +includefile directive or disklist entry +(DLE). + + + + includefile string + +Default: +no default. +The name of a disklist file to include within the current file. +Useful for sharing disklist among several configurations. +Relative pathnames are relative to the configuration directory. + + + + + +A DLE usually contains one line per disk: hostname diskname [diskdevice] dumptype [spindle [interface] ] diff --git a/ndmp-src/Makefile.in b/ndmp-src/Makefile.in index 0d5dbd5..f75e3ad 100644 --- a/ndmp-src/Makefile.in +++ b/ndmp-src/Makefile.in @@ -82,7 +82,7 @@ #NDMOS_OPTIONS = -DNDMOS_OPTION_NO_NDMP4 # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -332,7 +332,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -938,6 +939,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/ndmp-src/ndmjob_args.c b/ndmp-src/ndmjob_args.c index dc0e473..f31f597 100644 --- a/ndmp-src/ndmjob_args.c +++ b/ndmp-src/ndmjob_args.c @@ -117,6 +117,7 @@ char *help_text[] = { " -o use-eject=N", " -- use eject when unloading tapes (default 0)", " -o tape-tcp=hostname:port -- send the data directly to that tcp port.", + " -o D-agent-fd= -- file descriptor to read the -D agent.", "CONTROL of ROBOT agent parameters", " -R AGENT -- robot agent if different than -T (see AGENT below)", " -m MEDIA -- add entry to media table (see below)", @@ -660,6 +661,22 @@ handle_long_option (char *str) o_config_file = value; } else if (strcmp (name, "tape-tcp") == 0 && value) { o_tape_tcp = value; + } else if (strcmp (name, "D-agent-fd") == 0 && value) { + char d_agent[1025]; + int fd = atoi(value); + int size; + + if (AGENT_GIVEN(D_data_agent)) { + error_byebye ("more than one of -D or -D-agent-fd"); + } + + size = full_read(fd, d_agent, 1024); + d_agent[size] = '\0'; + if (size > 0 && d_agent[size-1] == '\n') + d_agent[size-1] = '\0'; + if (ndmagent_from_str (&D_data_agent, d_agent)) { + error_byebye ("bad -D-agent-fd argument"); + } } else if (strcmp (name, "tape-limit") == 0) { if (!value) { error_byebye ("tape-limit argument is required"); diff --git a/ndmp-src/ndmos.h b/ndmp-src/ndmos.h index a1180f0..d92cfd3 100644 --- a/ndmp-src/ndmos.h +++ b/ndmp-src/ndmos.h @@ -317,6 +317,10 @@ extern char *ndml_strend(char *s); /* ndml_util.c */ #define NDMOS_MACRO_NEWN(T,N) ((T *) NDMOS_API_MALLOC(sizeof (T) * (N))) #endif /* !NDMOS_MACRO_NEWN */ +#ifndef NDMOS_MACRO_FREE +#define NDMOS_MACRO_FREE(T) free(T) +#endif + #ifndef NDMOS_MACRO_ZEROFILL #define NDMOS_MACRO_ZEROFILL(P) NDMOS_API_BZERO(P,sizeof *(P)) #endif /* !NDMOS_MACRO_ZEROFILL */ diff --git a/ndmp-src/ndmos_glib.h b/ndmp-src/ndmos_glib.h index b8e5cd0..0c5e72f 100644 --- a/ndmp-src/ndmos_glib.h +++ b/ndmp-src/ndmos_glib.h @@ -83,6 +83,7 @@ #define NDMOS_MACRO_SRAND() g_random_set_seed(time(0)) #define NDMOS_MACRO_RAND() g_random_int() /* default: NDMOS_MACRO_OK_TAPE_REC_LEN */ +#define NDMOS_MACRO_FREE(T) g_free(T) /* extra */ #ifdef assert diff --git a/ndmp-src/ndmp4_translate.c b/ndmp-src/ndmp4_translate.c index edeb9ad..69a9adb 100644 --- a/ndmp-src/ndmp4_translate.c +++ b/ndmp-src/ndmp4_translate.c @@ -194,6 +194,27 @@ ndmp_9to4_pval_vec_dup ( return ndmp_9to4_pval_vec (pval9, *pval4_p, n_pval); } +int +ndmp_4to9_pval_free( + ndmp9_pval *pval9) +{ + CNVT_FREE(pval9, name); + CNVT_FREE(pval9, value); + + return 0; +} + +int +ndmp_4to9_pval_vec_free ( + ndmp9_pval *pval9, + unsigned n_pval) +{ + unsigned int i; + + for (i = 0; i < n_pval; i++) + ndmp_4to9_pval_free(&pval9[i]); + NDMOS_MACRO_FREE(pval9); +} /* * ndmp_addr @@ -271,6 +292,15 @@ ndmp_9to4_addr ( return 0; } +int +ndmp_9to4_addr_free ( + ndmp4_addr *addr4) +{ + if (addr4->addr_type == NDMP4_ADDR_TCP) { + NDMOS_MACRO_FREE(addr4->ndmp4_addr_u.tcp_addr.tcp_addr_val); + } + return 0; +} /* * CONNECT INTERFACES @@ -1569,6 +1599,15 @@ ndmp_4to9_tape_open_request ( return n_error; } +int +ndmp_4to9_tape_open_free_request ( + ndmp9_tape_open_request *request9) +{ + NDMOS_API_FREE(request9->device); + request9->device = NULL; + return 0; +} + int ndmp_9to4_tape_open_request ( ndmp9_tape_open_request *request9, @@ -2026,6 +2065,13 @@ ndmp_9to4_mover_get_state_reply ( return 0; } +int +ndmp_9to4_mover_get_state_free_reply( + ndmp4_mover_get_state_reply *reply4) +{ +// ndmp_9to4_addr_free(&reply4->data_connection_addr); + return 0; +} /* * ndmp_mover_listen @@ -2559,6 +2605,13 @@ ndmp_4to9_data_get_env_reply ( return 0; } +int +ndmp_4to9_data_get_env_free_reply ( + ndmp9_data_get_env_reply *reply9) +{ + ndmp_4to9_pval_vec_free(reply9->env.env_val, reply9->env.env_len); +} + int ndmp_9to4_data_get_env_reply ( ndmp9_data_get_env_reply *reply9, @@ -2979,6 +3032,14 @@ ndmp_4to9_log_message_request ( return 0; } +int +ndmp_4to9_log_message_free_request ( + ndmp9_log_message_request *request9) +{ + CNVT_FREE(request9, entry); + return 0; +} + int ndmp_9to4_log_message_request ( ndmp9_log_message_request *request9, @@ -3167,6 +3228,19 @@ ndmp_4to9_fh_add_file_request ( return 0; } +int +ndmp_4to9_fh_add_file_free_request ( + ndmp9_fh_add_file_request *request9) +{ + int i; + + for (i = 0; i < request9->files.files_len; i++) { + NDMOS_API_FREE(request9->files.files_val[i].unix_path); + } + + NDMOS_MACRO_FREE(request9->files.files_val); +} + int ndmp_9to4_fh_add_file_request ( ndmp9_fh_add_file_request *request9, @@ -3602,7 +3676,7 @@ struct reqrep_xlate ndmp4_reqrep_xlate_table[] = { ndmp_4to9_tape_open_request, ndmp_9to4_tape_open_request, JUST_ERROR_REPLY, - NO_MEMUSED /* no memory free routines written yet */ + ndmp_4to9_tape_open_free_request, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused }, { NDMP4_TAPE_CLOSE, NDMP9_TAPE_CLOSE, @@ -3680,7 +3754,7 @@ struct reqrep_xlate ndmp4_reqrep_xlate_table[] = { NO_ARG_REQUEST, ndmp_4to9_data_get_env_reply, ndmp_9to4_data_get_env_reply, - NO_MEMUSED /* no memory free routines written yet */ + ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_4to9_data_get_env_free_reply, ndmp_xtox_no_memused }, { NDMP4_DATA_STOP, NDMP9_DATA_STOP, @@ -3758,7 +3832,7 @@ struct reqrep_xlate ndmp4_reqrep_xlate_table[] = { ndmp_4to9_log_message_request, ndmp_9to4_log_message_request, JUST_ERROR_REPLY, /* no reply actually */ - NO_MEMUSED /* no memory free routines written yet */ + ndmp_4to9_log_message_free_request, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused }, { @@ -3766,7 +3840,7 @@ struct reqrep_xlate ndmp4_reqrep_xlate_table[] = { ndmp_4to9_fh_add_file_request, ndmp_9to4_fh_add_file_request, JUST_ERROR_REPLY, /* no reply actually */ - NO_MEMUSED /* no memory free routines written yet */ + ndmp_4to9_fh_add_file_free_request, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused }, { NDMP4_FH_ADD_DIR, NDMP9_FH_ADD_DIR, @@ -3792,7 +3866,7 @@ struct reqrep_xlate ndmp4_reqrep_xlate_table[] = { NO_ARG_REQUEST, ndmp_4to9_mover_get_state_reply, ndmp_9to4_mover_get_state_reply, - NO_MEMUSED /* no memory free routines written yet */ + ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_9to4_mover_get_state_free_reply }, { NDMP4_MOVER_LISTEN, NDMP9_MOVER_LISTEN, diff --git a/ndmp-src/ndmp_translate.h b/ndmp-src/ndmp_translate.h index cc2d08f..2f8f2fc 100644 --- a/ndmp-src/ndmp_translate.h +++ b/ndmp-src/ndmp_translate.h @@ -100,6 +100,8 @@ #define CNVT_STRDUP_FROM_9x(PX, P9, MEMBERX, MEMBER9) \ convert_strdup ((P9)->MEMBER9, &(PX)->MEMBERX) +#define CNVT_FREE(PX, MEMBERX) \ + { NDMOS_API_FREE((PX)->MEMBERX) ; (PX)->MEMBERX = NULL; }; /* diff --git a/ndmp-src/ndmpconnobj.c b/ndmp-src/ndmpconnobj.c index 1fe040a..41d14ed 100644 --- a/ndmp-src/ndmpconnobj.c +++ b/ndmp-src/ndmpconnobj.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -19,6 +19,7 @@ */ #include "amanda.h" +#include "event.h" #include "sockaddr-util.h" #include "ndmpconnobj.h" @@ -736,6 +737,165 @@ ndmp_connection_wait_for_notify( } } +typedef struct notify_data { + NDMPConnection *self; + ndmp9_data_halt_reason *data_halt_reason; + ndmp9_mover_halt_reason *mover_halt_reason; + ndmp9_mover_pause_reason *mover_pause_reason; + guint64 *mover_pause_seek_position; + GMutex *abort_mutex; + GCond *abort_cond; + int status; + event_handle_t *read_event; +} notify_data; + +static void handle_notify(void *cookie); + +int +ndmp_connection_wait_for_notify_with_cond( + NDMPConnection *self, + ndmp9_data_halt_reason *data_halt_reason, + ndmp9_mover_halt_reason *mover_halt_reason, + ndmp9_mover_pause_reason *mover_pause_reason, + guint64 *mover_pause_seek_position, + GMutex *abort_mutex, + GCond *abort_cond) +{ + struct ndmp_msg_buf nmb; + notify_data ndata; + gboolean found = FALSE; + + ndata.self = self; + ndata.data_halt_reason= data_halt_reason; + ndata.mover_halt_reason= mover_halt_reason; + ndata.mover_pause_reason= mover_pause_reason; + ndata.mover_pause_seek_position = mover_pause_seek_position; + ndata.abort_mutex = abort_mutex; + ndata.abort_cond = abort_cond; + ndata.status = 2; + + g_assert(!self->startup_err); + + /* initialize output parameters */ + if (data_halt_reason) + *data_halt_reason = NDMP4_DATA_HALT_NA; + if (mover_halt_reason) + *mover_halt_reason = NDMP4_MOVER_HALT_NA; + if (mover_pause_reason) + *mover_pause_reason = NDMP4_MOVER_PAUSE_NA; + if (mover_pause_seek_position) + *mover_pause_seek_position = 0; + + /* if any desired notifications have been received, then we're + * done */ + if (data_halt_reason && self->data_halt_reason) { + found = TRUE; + *data_halt_reason = self->data_halt_reason; + self->data_halt_reason = NDMP4_DATA_HALT_NA; + } + + if (mover_halt_reason && self->mover_halt_reason) { + found = TRUE; + *mover_halt_reason = self->mover_halt_reason; + self->mover_halt_reason = NDMP4_MOVER_HALT_NA; + } + + if (mover_pause_reason && self->mover_pause_reason) { + found = TRUE; + *mover_pause_reason = self->mover_pause_reason; + if (mover_pause_seek_position) + *mover_pause_seek_position = self->mover_pause_seek_position; + self->mover_pause_reason = NDMP4_MOVER_PAUSE_NA; + self->mover_pause_seek_position = 0; + } + + if (found) + return TRUE; + + /* otherwise, wait for an incoming packet and handle it, then try + * again. There's some select trickery here to avoid hogging the + * ndmlib_mutex - basically, we want to block as long as possible + * outside of the ndmlib_mutex critical section. This will also be + * useful to allow the wait to be aborted. */ + + ndata.read_event = event_register(self->conn->chan.fd, + EV_READFD, handle_notify, &ndata); + + g_cond_wait(abort_cond, abort_mutex); + + if (ndata.read_event) { + event_release(ndata.read_event); + } + if (ndata.status == 2) { + ndmp_connection_mover_abort(self); + ndmp_connection_mover_stop(self); + } + return ndata.status; + +} + +static void +handle_notify(void *cookie) +{ + notify_data *ndata = cookie; + struct ndmp_msg_buf nmb; + gboolean found = FALSE; + + g_mutex_lock(ndata->abort_mutex); + + event_release(ndata->read_event); + ndata->read_event = NULL; + + g_static_mutex_lock(&ndmlib_mutex); + NDMOS_MACRO_ZEROFILL(&nmb); + nmb.protocol_version = NDMP4VER; + ndata->self->last_rc = ndmconn_recv_nmb(ndata->self->conn, &nmb); + g_static_mutex_unlock(&ndmlib_mutex); + + if (ndata->self->last_rc) { + /* (nothing to free) */ + ndata->status = 1; + goto notify_done; + } + + ndmconn_handle_notify(ndata->self, &nmb); + + + /* if any desired notifications have been received, then we're + * done */ + if (ndata->data_halt_reason && ndata->self->data_halt_reason) { + found = TRUE; + *ndata->data_halt_reason = ndata->self->data_halt_reason; + ndata->self->data_halt_reason = NDMP4_DATA_HALT_NA; + } + + if (ndata->mover_halt_reason && ndata->self->mover_halt_reason) { + found = TRUE; + *ndata->mover_halt_reason = ndata->self->mover_halt_reason; + ndata->self->mover_halt_reason = NDMP4_MOVER_HALT_NA; + } + + if (ndata->mover_pause_reason && ndata->self->mover_pause_reason) { + found = TRUE; + *ndata->mover_pause_reason = ndata->self->mover_pause_reason; + if (ndata->mover_pause_seek_position) + *ndata->mover_pause_seek_position = ndata->self->mover_pause_seek_position; + ndata->self->mover_pause_reason = NDMP4_MOVER_PAUSE_NA; + ndata->self->mover_pause_seek_position = 0; + } + + if (!found) { + ndata->read_event = event_register(ndata->self->conn->chan.fd, + EV_READFD, handle_notify, ndata); + g_mutex_unlock(ndata->abort_mutex); + return; + } + + ndata->status = 0; +notify_done: + g_cond_broadcast(ndata->abort_cond); + g_mutex_unlock(ndata->abort_mutex); +} /* * Class Mechanics */ diff --git a/ndmp-src/ndmpconnobj.h b/ndmp-src/ndmpconnobj.h index 350243b..f34577b 100644 --- a/ndmp-src/ndmpconnobj.h +++ b/ndmp-src/ndmpconnobj.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -224,6 +224,20 @@ gboolean ndmp_connection_wait_for_notify( ndmp9_mover_pause_reason *mover_pause_reason, guint64 *mover_pause_seek_position); +/* Synchronous notification interface. This handles all types of notification, + * returning the result in the appropriate output parameter. */ +gboolean ndmp_connection_wait_for_notify_with_cond( + NDMPConnection *self, + /* NDMP_NOTIFY_DATA_HALTED */ + ndmp9_data_halt_reason *data_halt_reason, + /* NDMP_NOTIFY_MOVER_HALTED */ + ndmp9_mover_halt_reason *mover_halt_reason, + /* NDMP_NOTIFY_MOVER_PAUSED */ + ndmp9_mover_pause_reason *mover_pause_reason, + guint64 *mover_pause_seek_position, + GMutex *abort_mutex, + GCond *abort_cond); + /* * Constructor */ diff --git a/oldrecover-src/Makefile.in b/oldrecover-src/Makefile.in index 48d3930..b2750e6 100644 --- a/oldrecover-src/Makefile.in +++ b/oldrecover-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda file recovery programs. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -268,7 +268,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -819,6 +820,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/packaging/Makefile.in b/packaging/Makefile.in index 880e260..cf72676 100644 --- a/packaging/Makefile.in +++ b/packaging/Makefile.in @@ -184,7 +184,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -700,6 +701,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/packaging/common/common_functions.sh b/packaging/common/common_functions.sh index 28351d9..788d15c 100644 --- a/packaging/common/common_functions.sh +++ b/packaging/common/common_functions.sh @@ -10,13 +10,13 @@ logger() { # A non-annoying way to log stuff # ${@} is all the parameters, also known as the message. Quoting the input # preserves whitespace. - msg="`date +'%b %e %Y %T'`: ${@}" + msg="`date +'%b %e %Y %T'`: ${@}" echo "${msg}" >> ${LOGFILE} } log_output_of() { # A non-annoying way to log output of commands - # ${@} is all the parameters supplied to the function. just execute it, + # ${@} is all the parameters supplied to the function. just execute it, # and capture the output in a variable. then log that. output=`"${@}" 2>&1` ret=$? @@ -38,10 +38,10 @@ check_superserver() { check_xinetd() { # Checks for an xinetd install and a config name passed as the first - # parameter. + # parameter. # Returns: - # 0 if the file exists, - # 1 if it does not, + # 0 if the file exists, + # 1 if it does not, # 2 if xinetd.d/ does not exist or is a file if [ -d ${SYSCONFDIR}/xinetd.d ] ; then @@ -59,7 +59,7 @@ check_xinetd() { check_inetd() { case $os in - SunOS) inetd_conf=${BASEDIR}/${SYSCONFDIR}/inet/inetd.conf ;; + SunOS) inetd_conf=${SYSCONFDIR}/inet/inetd.conf ;; *) inetd_conf=${SYSCONFDIR}/inetd.conf ;; esac if [ -e ${inetd_conf} ] ; then @@ -129,7 +129,7 @@ backup_xinetd() { backup_inetd() { case $os in - SunOS) inetd_conf=${BASEDIR}/${SYSCONFDIR}/inet/inetd.conf ;; + SunOS) inetd_conf=${SYSCONFDIR}/inet/inetd.conf ;; *) inetd_conf=${SYSCONFDIR}/inetd.conf ;; esac # Backs up any amanda configuration it finds @@ -148,7 +148,7 @@ backup_inetd() { backup_smf() { # Solaris only. I *think* this should be consistent across all smf installs - svccfg -s *amanda* > ${BASEDIR}/${AMANDAHOMEDIR}/example/amanda_smf.xml.orig || {\ + svccfg -s *amanda* > ${AMANDAHOMEDIR}/example/amanda_smf.xml.orig || {\ logger "Warning: export of existing amanda service failed."; return 1; } @@ -169,7 +169,7 @@ install_xinetd() { install_inetd() { case $os in - SunOS) inetd_conf=${BASEDIR}/${SYSCONFDIR}/inet/inetd.conf ;; + SunOS) inetd_conf=${SYSCONFDIR}/inet/inetd.conf ;; *) inetd_conf=${SYSCONFDIR}/inetd.conf ;; esac # This one is hard to log because we're just appending. @@ -184,13 +184,13 @@ install_smf() { case $ver in 5.10) # Use inetadm and svcadm. - log_output_of ${BASEDIR}/usr/sbin/inetconv -f -i ${AMANDAHOMEDIR}/example/inetd.conf.${1} || { \ + log_output_of ${basedir}/usr/sbin/inetconv -f -i ${AMANDAHOMEDIR}/example/inetd.conf.${1} || { \ logger "Warning: Failed to create Amanda SMF manifest. Check the system log."; return 1; } - log_output_of ${BASEDIR}/usr/sbin/inetadm -e svc:/network/amanda/tcp || { \ + log_output_of ${basedir}/usr/sbin/inetadm -e svc:/network/amanda/tcp || { \ logger "Warning: Failed to enable Amanda service. See system log for more information."; return 1; } - log_output_of ${BASEDIR}/usr/sbin/svcadm restart network/amanda/tcp || { \ + log_output_of ${basedir}/usr/sbin/svcadm restart network/amanda/tcp || { \ logger "Warning: Failed to restart Amanda service. See system log for details."; return 1; } ;; @@ -212,7 +212,7 @@ reload_xinetd() { # Default action is to try reload. if [ "x$1" = "x" ]; then action="reload" - elif [ "$1" = "reload" -o "$1" = "restart" ]; then + elif [ "$1" = "reload" ] || [ "$1" = "restart" ]; then action="$1" else logger "WARNING: bad argument to reload_xinetd: $1" @@ -238,7 +238,7 @@ reload_inetd() { # Default action is to try reload. if [ "x$1" = "x" ]; then action="reload" - elif [ "$1" = "reload" -o "$1" = "restart" ]; then + elif [ "$1" = "reload" ] || [ "$1" = "restart" ]; then action="$1" else logger "WARNING: bad argument to reload_inetd: $1" diff --git a/packaging/common/mock_utils.sh b/packaging/common/mock_utils.sh index a0989c2..1db24f8 100644 --- a/packaging/common/mock_utils.sh +++ b/packaging/common/mock_utils.sh @@ -11,6 +11,8 @@ MOCKDIR=$TMPDIR/mocks; export MOCKDIR [ -d $MOCKDIR ] || mkdir $MOCKDIR PATH=${MOCKDIR}:$PATH; export PATH +# A list of flag files that must be present to avoid spurious output. +# Each mock util gets one whether it is used or not. mock_flag_files="" mk_mock_util() { @@ -61,24 +63,88 @@ EOF ############### # id replacemnt -# Set defaults for deb_uid and amanda_group, if running outside test_sh_libs +# Set vars for output of -Gn +id_0="biff" +id_1="biff foo" +id_2="biff bar baz" +id_3="biff zip bop whir" + +# Set defaults for uid and amanda_group, if running outside test_sh_libs deb_uid=${deb_uid:=12345} amanda_group=${amanda_group:=disk} mk_mock_util "id" cat << EOF >> "${MOCKDIR}/id" -echo "id args: \${1}" > $mock_id_flags +echo "id args: \${@}" > $mock_id_flags [ -n "\${1}" ] || { echo "Missing a username to id!"; exit 1; } -# We have to return the most basic form of id to be portable -# group file is used for supplemental groups. -if [ -f "${MOCKDIR}/is_member" ]; then - echo "uid=${deb_uid}(\${1}) gid=6(${amanda_group})" +# We can only use id with no flags to have consistent results. Solaris +# /usr/bin/id does not provide any standard flags. Since /usr/xpg4/bin is +# not part of a minimal install we can't depend on it. Any flags *at all* +# should raise an error in the tests. +# group file and /usr/bin/groups can be used (with some tweaks). +for f in "\$@"; do + case \$f in + # -- is ok, surprisingly. + --) : ;; + -?*) echo "id: no options are portable! '\$f'" + # Solaris exits with 2, others with 1. ugh. + exit 2 + ;; + *) : ;; + esac +done + +# Use id_group to control primary group name. +[ -f ${MOCKDIR}/id_group ] && group=\`cat ${MOCKDIR}/id_group\` || group=bar + +# Solaris, Linux and OSX differ in the exact format of the output from id, +# so we provide sample output based on the contents of id_os. We don't +# parse it, but its presence can't break things. +test_os=\`cat ${MOCKDIR}/id_os\` +case \${test_os} in + linux) sup_groups=" groups=999(\${group}),1000(foo)" ;; + solaris) sup_groups="" ;; + osx) sup_groups=" groups=999(\${group}), 1000(foo)" ;; +esac + +if [ -f ${MOCKDIR}/id_exists ]; then + # Note: uid is set when the mock is created. + echo "uid=${deb_uid}(\${1}) gid=6(\${group})\${sup_groups}" else - echo "uid=123(\${1}) gid=123(foobar)" + echo "id: \${1}: no such user" >&2 + exit 1 fi EOF +############### +# groupadd replacement +mk_mock_util "groupadd" +cat << EOF >> "${MOCKDIR}/groupadd" +echo "groupadd args: \${@}" > $mock_groupadd_flags +# We check for return codes of 0 (group added) or 9 (group existed) to +# continue in the function that uses groupadd +groupadd_rc=\`cat ${MOCKDIR}/groupadd_rc\` +exit \${groupadd_rc} +EOF + +############### +# groups replacement +mk_mock_util "groups" +cat << EOF >> "${MOCKDIR}/groups" +echo "groups args: \${@}" > $mock_groups_flags +cat ${MOCKDIR}/groups_output +EOF + +############### +# usermod replacement +mk_mock_util "usermod" +cat << EOF >> "${MOCKDIR}/usermod" +echo "usermod args: \${@}" > $mock_usermod_flags +# Protect against passing a blank username. +[ "x\${1}" = "x" ] && exit 2 || exit 0 +EOF + ############### # svcs replacement mk_mock_util "svcs" @@ -96,7 +162,7 @@ EOF # xinetd init script replacement mk_mock_util xinetd cat << EOF >> "${MOCKDIR}/xinetd" -echo "xinetd args: \${1}" > $mock_xinetd_flags +echo "xinetd args: \${@}" > $mock_xinetd_flags [ -f ${MOCKDIR}/success ] && exit 0 echo "xinetd did not \${1}" exit 1 @@ -106,7 +172,7 @@ EOF # inetd init script replacement mk_mock_util inetd cat << EOF >> "${MOCKDIR}/inetd" -echo "inetd args: \${1}" > $mock_inetd_flags +echo "inetd args: \${@}" > $mock_inetd_flags [ -f ${MOCKDIR}/success ] && exit 0 echo "inetd did not \${1}" exit 1 @@ -116,7 +182,7 @@ EOF # install replacement mk_mock_util install cat << EOF >> "${MOCKDIR}/install" -echo "install args: \$@" > $mock_install_flags +echo "install args: \${@}" > $mock_install_flags [ -f ${MOCKDIR}/success ] && exit 0 echo "Some funky install error, yo!" exit 1 diff --git a/packaging/common/post_inst_functions.sh b/packaging/common/post_inst_functions.sh index 1b131c4..23a20ba 100644 --- a/packaging/common/post_inst_functions.sh +++ b/packaging/common/post_inst_functions.sh @@ -18,16 +18,16 @@ add_service() { # Only needed on Solaris! entry="amanda 10080/tcp # amanda backup services" # make sure amanda is in /etc/services - if [ -z "`grep 'amanda' /${SYSCONFDIR}/services |grep '10080/tcp'`" ] ; then - logger "Adding amanda entry to /${SYSCONFDIR}/services." - echo "${entry}" >> /${SYSCONFDIR}/services + if [ -z "`grep 'amanda' ${SYSCONFDIR}/services |grep '10080/tcp'`" ] ; then + logger "Adding amanda entry to ${SYSCONFDIR}/services." + echo "${entry}" >> ${SYSCONFDIR}/services fi # make sure kamanda is in /etc/services entry_2="amanda 10081/tcp famdc # amanda backup services (kerberos)" if [ -z "`grep 'kamanda' /etc/services |grep '10081/tcp'`" ] ; then - logger "Adding kamanda entry to /${SYSCONFDIR}/services." - echo "${entry_2}" >> /${SYSCONFDIR}/services + logger "Adding kamanda entry to ${SYSCONFDIR}/services." + echo "${entry_2}" >> ${SYSCONFDIR}/services fi } diff --git a/packaging/common/post_rm_functions.sh b/packaging/common/post_rm_functions.sh index d0d43a8..3833644 100644 --- a/packaging/common/post_rm_functions.sh +++ b/packaging/common/post_rm_functions.sh @@ -28,7 +28,7 @@ remove_smf() { rm_user() { # Delete the user provided as first parameter ($1) logger "Deleting user: $1" - log_output_of userdel $1 + log_output_of userdel $1 } # ------------- End Post Removal Functions ----------------- diff --git a/packaging/common/pre_inst_functions.sh b/packaging/common/pre_inst_functions.sh index 878a8af..c2aecac 100644 --- a/packaging/common/pre_inst_functions.sh +++ b/packaging/common/pre_inst_functions.sh @@ -9,6 +9,7 @@ # dist: used on linux for the distro. # LOGFILE: a log file we append to # os: Linux, Darwin, SunOS, `uname`... +# wanted_shell: Linux/SunOS/OSX all keep them in different places # SYSCONFDIR: location of system config files (ie, /etc) # LOGDIR: logging directory for amanda @@ -21,7 +22,7 @@ create_user() { case $os in Linux|SunOS) # Create the amanda user with a specific uid on deb systems - if [ ${dist} = "Debian" -o ${dist} = "Ubuntu" ] ; then + if [ "x${dist}" = "xDebian" ] || [ "x${dist}" = "xUbuntu" ] ; then uid_flag="-u ${deb_uid}" else uid_flag= @@ -36,28 +37,35 @@ create_user() { -g ${amanda_group} \ ${uid_flag} \ -d ${AMANDAHOMEDIR} \ - -s /bin/bash ${amanda_user} || \ + -s ${wanted_shell} ${amanda_user} || \ { logger "WARNING: Could not create user ${amanda_user}. Installation will fail." ; return 1 ; } - r=`uname -r` - if [ "$os" = "Linux"] && [ ${dist} != "SuSE" ]; then + logger "Created ${amanda_user} with blank password." + + if [ "x$os" = "xLinux" ] && [ "x${dist}" != "xSuSE" ]; then # Lock the amanda account until admin sets password - log_output_of passwd -l ${amanda_user} || { \ + log_output_of passwd -l ${amanda_user} && { \ + logger "${info_create_user_success}" + logger "${info_unlock_account}" + } || { \ logger "${warning_user_passwd}"; } fi - if [ "$os" = "SunOS" ]; then + if [ "x$os" = "xSunOS" ]; then + r=`uname -r` case $r in - 5.8|5.9) log_output_of passwd -l ${amanda_user};; + 5.8|5.9) log_output_of passwd -l ${amanda_user} ;; 5.10) # Special login-lock, while allowing execution. - log_ouptut_of passwd -N ${amanda_user} || { \ + log_output_of passwd -N ${amanda_user} && { \ + logger "${info_create_user_success_sol}" + logger "${info_unlock_account}" + } || { \ logger "${warning_user_passwd}"; } ;; esac fi - logger "${info_create_user_success}" else # The user already existed - logger "${info_user_params}" + logger "The Amanda user '${amanda_user}' exists on this system." fi ;; Darwin) : #TODO @@ -66,120 +74,136 @@ create_user() { } add_group() { - # Try to add the group, detect via return code if it already exists. - # This works on linux and solaris... - log_output_of groupadd ${1} + # First, try to add the group, detect via return code if it + # already exists. Then add ${amanda_user} to the group without + # checking if account is already a member. (check_user should + # already have been called). + # + # Works on linux and solaris. OSX has different tools. + + [ "x${1}" = "x" ] && { logger "Error: first argument was not a group to add." ; return 1 ; } + group_to_add=${1} + log_output_of groupadd ${group_to_add} + rc=$? # return of 0 means group was added; 9 means group existed. - if [ $? = "0" ] || [ $? = "9" ]; then - logger "Adding ${amanda_user} to ${1}" - case $os in - Linux) um_flags="-a -G";; - # Solaris does not have -a flag. - SunOS) um_flags="-G `groups ${amanda_user}`";; - esac + if [ $rc -eq 0 ] || [ $rc -eq 9 ]; then + logger "Adding ${amanda_user} to ${group_to_add}" + # Generate a comma separated list of existing supplemental groups. + # Linux prefaces output with ' : '. + existing_sup_groups=`groups ${amanda_user}|sed 's/.*: //;s/ /,/g'` + # usermod append is -A on Suse, all other linux use -a, and + # -A means something else entirely on solaris. So we just use + # -G, and append a list of the current groups from id. # So far, all linux distros have usermod - log_output_of usermod -a -G ${1} ${amanda_user} || \ - { logger "${error_group_member}" ; return 1 ; } + log_output_of usermod -G ${existing_sup_groups},${group_to_add} ${amanda_user} || { \ + logger "Nonfatal ERROR: Failed to add ${group_to_add}." + logger "${error_group_member}" ; return 1 ; } else - logger "Error: groupadd failed in an unexpected way." + logger "Error: groupadd failed in an unexpected way. return code='$rc'" return 1 fi } -check_user() { - # Check parameters of ${amanda_user}'s account. - # $1= user field $2= value to check - # group, shell, homedir, UID are valid for $1. - # group: checks the system group file for ${amanda_user}'s - # membership in the group named $2. - # shell: confirms the passwd file's shell field for - # ${amanda_user} is $2 - # homedir: confirm the passwd file's homedir field for - # ${amanda_user} is $2 - # UID: confirm that ${amanda_user}'s UID is $2. - # - # Extra information about the failed check is written to the log. - # - # Return codes: - # 0 = success - # 1 = error - # 2 = usage error + +# All check_user_* functions check various parameters of ${amanda_user}'s +# account. Return codes: +# 0 = success +# 1 = error +# 2 = usage or other error. more info will be logged + +check_user_group() { + # checks the system group file for ${amanda_user}'s membership in + # the group named $1. err=0 - if [ ! $# -eq 2 ]; then - echo "check_user(): Wrong number of parameters" - return 2 + [ "x" = "x$1" ] && { logger "check_user_group: no group given"; return 1; } + logger "Verify ${amanda_user}'s primary group = $1 " + # Check if the group exists, disregarding membership. + group_entry=`grep "^${2}" ${SYSCONFDIR}/group 2> /dev/null` + if [ ! "x" = "x${group_entry}" ]; then + # Assume the user exists, and check the user's primary group. + GROUP=`id ${amanda_user} 2> /dev/null |\ + cut -d " " -f 2 |\ + sed 's/.*gid=[0-9]*(\([^ ()]*\))/\1/'` + if [ ! "x${GROUP}" = "x${1}" ] ; then + logger "${amanda_user} not a member of ${1}" + err=1 + fi + else + logger "User's primary group '${1}' does not exist" + err=1 fi - logger "Verify ${amanda_user}'s $1 = $2 " - case $1 in - "group") - # Check if the group exists, disregarding membership. - if `grep "^${2}" ${SYSCONFDIR}/group > /dev/null` ; then - # Assume the user exists, and check the user's primary group. - GROUP=`id ${amanda_user} 2> /dev/null | sed 's/.*gid=[0-9]*(\([^ ()]*\))/\1/'` - if [ ! "x${GROUP}" = "x${2}" ] ; then - logger "${amanda_user} not a member of ${2}" - err=1 - fi - else - logger "User group '${2}' does not exist" - err=1 - fi - ;; - "group-sup*") - # Check if a supplementary group exists. - SUP_MEM=`awk -F: "\$1 ~ ${2} { print \$4; }" 2> /dev/null` - if [ -n "$SUP_MEM" ] ; then - # Check if our user is a member. - if echo "${SUP_MEM}"|grep "${amanda_user}" &> /dev/null ; then - : - else - logger "${amanda_user} is not a member of supplemental group ${2}." - err=1 - fi - else - logger "Supplemental group ${2} does not exist" - err=1 - fi + return $err +} + +check_user_supplemental_group() { + # Checks for the group ${1}, and adds ${amanda_user} if missing. + # Other groups are preserved. + err=0 + [ "x" = "x$1" ] && { logger "check_user_supplemental_group: no supplemental group given"; return 1; } + sup_group=${1} + logger "Verify ${amanda_user} is a member of ${sup_group}." + # First, check if the supplementary group exists. + sup_group_entry=`grep "${sup_group}" ${SYSCONFDIR}/group 2>/dev/null` + if [ ! "x" = "x${sup_group_entry}" ]; then + SUP_MEM=`echo ${sup_group_entry} | cut -d: -f4` + # Check if our user is a member. + case ${SUP_MEM} in + *${amanda_user}*) : ;; + *) + logger "${amanda_user} is not a member of supplemental group ${sup_group}." + err=1 ;; - "shell") - SHELL=`grep "^${amanda_user}" ${SYSCONFDIR}/passwd | cut -d: -f7` - wanted_shell=$2; export wanted_shell - if [ ! "x${SHELL}" = "x${2}" ] ; then - logger "${warning_user_shell}" - err=1 - fi - ;; - "homedir") - HOMEDIR=`grep "^${amanda_user}" ${SYSCONFDIR}/passwd | cut -d: -f6` - if [ ! "x${HOMEDIR}" = "x${2}" ] ; then - logger "${warning_user_homedir}" - err=1 - fi - ;; - "UID") - # Debian systems must use a specific UID - ID=`id ${amanda_user} 2> /dev/null | sed 's/uid=\([0-9]*\).*/\1/'` - if [ ! "${ID}" -eq "${2}" ] ; then - checked_uid=${2}; export checked_uid - logger "${warning_user_uid_debian}" - err=1 - fi - ;; - *) - echo "check_user(): unknown user parameter." - err=2 - ;; - esac - + esac + else + logger "Supplemental group ${sup_group} does not exist" + err=1 + fi return $err } +check_user_shell() { + # Confirms the passwd file's shell field for ${amanda_user} is $1 + [ "x" = "x$1" ] && { logger "check_user_shell: no shell given"; return 1; } + wanted_shell=$1; export wanted_shell + logger "Verify ${amanda_user}'s shell is ${wanted_shell}." + real_shell=`grep "^${amanda_user}" ${SYSCONFDIR}/passwd | cut -d: -f7` + export real_shell + if [ ! "x${real_shell}" = "x${wanted_shell}" ] ; then + logger "WARNING: ${amanda_user} default shell= ${wanted_shell}" + logger "WARNING: ${amanda_user} existing shell: ${real_shell}" + logger "${warning_user_shell}" + return 1 + fi +} + +check_user_homedir() { + # Confirm the passwd file's homedir field for ${amanda_user} is $1 + [ "x" = "x$1" ] && { logger "check_user_homedir: no homedir given"; return 1; } + HOMEDIR=`grep "^${amanda_user}" ${SYSCONFDIR}/passwd | cut -d: -f6` + if [ ! "x${HOMEDIR}" = "x${1}" ] ; then + logger "${warning_user_homedir}" + return 1 + fi +} + +check_user_uid() { + # Confirm that ${amanda_user}'s UID is $1. + # Debian systems must use a specific UID + [ "x" = "x$1" ] && { logger "check_user_uid: no uid given"; return 1; } + ID=`id ${amanda_user} 2> /dev/null | sed 's/uid=\([0-9]*\).*/\1/'` + if [ ! ${ID} -eq ${1} ] ; then + checked_uid=${1}; export checked_uid + logger "${warning_user_uid_debian}" + return 1 + fi +} + check_homedir() { # Checks that the homedir has correct permissions and belongs to correct # user. Uses $amanda_user and $amanda_group. if [ -d ${AMANDAHOMEDIR} ] ; then OWNER_GROUP=`ls -dl ${AMANDAHOMEDIR} | awk '{ print $3" "$4; }'` - [ "$OWNER_GROUP" = "${amanda_user} ${amanda_group}" ] || \ + [ "x$OWNER_GROUP" = "x${amanda_user} ${amanda_group}" ] || \ logger "${warning_homedir_owner}" return $? else @@ -218,63 +242,39 @@ create_logdir() { # Info, Warning, and Error strings used by the installer -info_create_user_success="The '${amanda_user}' user account has been successfully created. - Furthermore, the account has been automatically locked for you for security - purposes. Once a password for the '${amanda_user}' account has been set, - the user can be unlocked by issuing the following command as root.: +info_create_user_success="NOTE: Set a password and unlock the ${amanda_user} account before + running Amanda." + +info_create_user_success_sol="NOTE: Account is set as non-login. If interactive login +is required: a password must be set, and the account activated for login." + +info_unlock_account=" The superuser can unlock the account by running: # passwd -u ${amanda_user} +" - If this is not a new installation of Amanda and you have pre-existing Amanda - configurations in ${SYSCONFDIR}/amanda you should ensure that 'dumpuser' - is set to '${amanda_user}' in those configurations. Additionally, you - should ensure that ${AMANDAHOMEDIR}/.amandahosts on your client systems - is properly configured to allow connections for the user '${amanda_user}'." +info_existing_installs="Pre-existing Amanda installations must confirm: + -${SYSCONFDIR}/amanda/* should have 'dumpuser' set to '${amanda_user}'. + -${AMANDAHOMEDIR}/.amandahosts on client systems should allow connections by + '${amanda_user}'." -warning_user_password="!!! WARNING! WARNING! WARNING! WARNING! WARNING! !!! -!!! !!! -!!! The '${amanda_user}' user account for this system has been !!! -!!! created, however the user has no password set. For !!! -!!! security purposes this account is normally locked after !!! -!!! creation. Unfortunately, when locking this account an !!! -!!! error occurred. To ensure the security of your system, !!! -!!! you should set a password for the user account !!! -!!! '${amanda_user}' immediately! To set such a password, !!! -!!! please issue the following command: !!! -!!! !!! -!!! # passwd ${amanda_user} !!! -!!! !!! -!!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" +warning_user_password="WARNING: '${amanda_user}' no password. An error occured when locking the + account. SET A PASSWORD NOW: -info_user_params="The Amanda backup software is configured to operate as the user - '${amanda_user}'. This user exists on your system and has not been modified. - To ensure that Amanda functions properly, please see that the following - parameters are set for that user: - SHELL: /bin/bash - HOME: ${AMANDAHOMEDIR} - Default group: ${amanda_group}" + # passwd ${amanda_user}" -error_group_member="!!! Nonfatal ERROR. Nonfatal ERROR. !!! -!!! user '${amanda_user}' is not part of the '${amanda_group}' group, !!! -!!! Amanda will not run until '${amanda_user}' is a member of '${amanda_group}'. !!! -!!! Nonfatal ERROR. Nonfatal ERROR. Nonfatal Error. !!!" +error_group_member="Nonfatal ERROR: Amanda will not run until '${amanda_user}' is a member the + preceeding group. Install will continue..." -warning_user_shell="WARNING: The user '${amanda_user}' has a non-default shell. -the default shell is ${wanted_shell}. Other shells have not been tested." +warning_user_shell="WARNING: The user '${amanda_user}' has a non-default shell. Other shells have not been tested." -warning_user_homedir="!!! WARNING! WARNING! WARNING! WARNING! WARNING! !!! -!!! The user '${amanda_user}' must have its home directory set to !!! -!!! '${AMANDAHOMEDIR}' Please correct before using Amanda !!! -!!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" +warning_user_homedir="WARNING: The user '${amanda_user}' must have its home directory set to +'${AMANDAHOMEDIR}' Please correct before using Amanda." -warning_user_uid_debian="!!! WARNING! WARNING! WARNING! WARNING! WARNING! !!! -!!! Debian packages were built assuming that ${amanda_user} !!! -!!! uid = ${checked_uid}. The uid of ${amanda_user} is different !!! -!!! different on this system. Files owned by ${checked_uid} must !!! -!!! be chowned to ${amanda_user}. !!! -!!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" +warning_user_uid_debian="WARNING: Debian packages were built assuming that ${amanda_user} +uid = ${checked_uid}. The uid of ${amanda_user} is different on this system. Files +owned by ${checked_uid} must be chowned to ${amanda_user}." -warning_homedir_owner="!!! Please ensure that the directory '${AMANDAHOMEDIR}' is owned by !!! -!!! the user '${amanda_user}' and group '${amanda_group}'. !!!" +warning_homedir_owner="WARNING: The ${amanda_user}'s home directory,'${AMANDAHOMEDIR}' ownership must be changed to '${amanda_user}:${amanda_group}'. " # --------------- End included Functions ----------------- diff --git a/packaging/common/test_sh_libs.sh b/packaging/common/test_sh_libs.sh index 85711f1..22c4fb6 100755 --- a/packaging/common/test_sh_libs.sh +++ b/packaging/common/test_sh_libs.sh @@ -23,9 +23,11 @@ SHUNIT_INC="${srcdir=`pwd`}/packaging/common"; export SHUNIT_INC TMPDIR=`pwd`/shunit-test; export TMPDIR amanda_user=test_amandabackup; export amanda_user amanda_group=test_disk; export amanda_group +sup_group="test_tape"; export sup_group AMANDAHOMEDIR=$TMPDIR/amanda; export AMANDAHOMEDIR AMANDATES=$AMANDAHOMEDIR/amandates; export AMANDATES os=`uname`; export os +wanted_shell='/bin/false'; export wanted_shell dist=Fedora; export dist SYSCONFDIR=$TMPDIR/etc; export SYSCONFDIR SBINDIR=$TMPDIR/sbin; export SBINDIR @@ -34,7 +36,7 @@ deb_uid=63000; export deb_uid # Append stuff to this when you make temp files if they are outside TMPDIR -test_cleanup_files="$TMPDIR"; export sh_cleanup_files +test_cleanup_files="$TMPDIR"; export test_cleanup_files # This can't be part of one-time setup, because TMPDIR must exist before # shunit2 is sourced. @@ -63,6 +65,8 @@ oneTimeSetUp() { grep "${amanda_user}" ${SYSCONFDIR}/passwd &> /dev/null || { \ echo "$msg_prefix ${amanda_user} still exists, or no ${SYSCONFDIR}/passwd."; exit 1; } + groupdel ${amanda_group} || exit 1 + groupdel ${sup_group} || exit 1 else echo "Not root, cleanup skipped" fi @@ -84,7 +88,7 @@ oneTimeTearDown() { test_cleanup_files="$LOGFILE ${test_cleanup_files}" -# errors before the tests are run. +# shows syntax errors before the tests are run. . ${SHUNIT_INC}/common_functions.sh . ${SHUNIT_INC}/pre_inst_functions.sh . ${SHUNIT_INC}/post_inst_functions.sh @@ -99,8 +103,6 @@ if [ "$tester_id" = "0" ]; then else IAmRoot= fi -# A list of flag files that must be present to avoid spurious output. -# Each mock util gets one whether it is used or not. # CAUTION: using real values if we are root. if [ "$IAmRoot" ]; then @@ -111,6 +113,7 @@ fi # Source our mock utils. . ${SHUNIT_INC}/mock_utils.sh + ###################################### # Common functions @@ -118,7 +121,7 @@ fi # to run first. test___logger() { # Write a line to the log, test that it got there. - TEST_MSG="Test01_logger message" + TEST_MSG="test___logger message" LOG_LINE="`date +'%b %e %Y %T'`: ${TEST_MSG}" # It's important for the log messages to be quoted, or funny stuff happens. logger "${TEST_MSG}" @@ -136,7 +139,7 @@ test___logger() { test__log_output_of() { # Use log_output_of to append to the log - TEST_MSG="Test02_log_output_of message" + TEST_MSG="test__log_output_of message" log_output_of echo "${TEST_MSG}" assertEquals "log_output_of()" 0 $? COUNT=`grep -c "${TEST_MSG}" ${LOGFILE}` @@ -285,11 +288,11 @@ test_reload_xinetd() { rm ${MOCKDIR}/success reload_xinetd "reload" assertEquals "reload_xinetd" 1 $? - tail -4 ${LOGFILE}|grep "\/dev/null assertEquals "reload_xinetd should try to restart." 0 $? reload_xinetd "restart" assertEquals "restart should fail." 1 $? - tail -3 ${LOGFILE}|grep "Restarting xinetd" + tail -3 ${LOGFILE}|grep "Restarting xinetd" >/dev/null assertEquals "Should log attempt to restart" 0 $? } @@ -313,11 +316,11 @@ test_reload_inetd() { rm ${MOCKDIR}/success reload_inetd "reload" assertEquals "reload_inetd" 1 $? - tail -4 ${LOGFILE}|grep "\/dev/null assertEquals "reload_inetd should try to restart." 0 $? reload_inetd "restart" assertEquals "restart should fail." 1 $? - tail -3 ${LOGFILE}|grep "Restarting inetd" + tail -3 ${LOGFILE}|grep "Restarting inetd" >/dev/null assertEquals "Should log attempt to restart" 0 $? } @@ -325,89 +328,118 @@ test_reload_inetd() { ###################################### # pre_install_functions -test_check_user_crazy_input() { - logger "test_check_user_crazy_input" - # Case 1: not enough params. - check_user "bar" - assertEquals "'check_user bar'" 2 $? - - # Case 2: bad first param. - check_user "bar" "bell" - assertEquals "'check_user bar bell'" 2 $? -} - test_check_user_group_missing() { - logger "test_check_user_group_missing" + logger "test_check_user_group_missing no param" + check_user_group + assertNotEquals "'check_user_group' should fail" 0 $? + logger "test_check_user_group_missing missing group" + [ ! "$IAmRoot" ] && rm -f ${SYSCONFDIR}/group touch ${SYSCONFDIR}/group - check_user "group" "abracadabra" - assertNotEquals "'check_user group abracadabra' should not be found:" 0 $? -} - -# passwd file entry for Linux systems, maybe others. UID is correct -# for Debian as well. -good_passwd_entry="${amanda_user}:x:${mock_deb_uid}:6::${AMANDAHOMEDIR}:/bin/bash" -export good_passwd_entry -test_create_user() { - logger "test_create_user" - if [ ! "$IAmRoot" ]; then - startSkipping - echo "test_create_user: Creating mock passwd file." - echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd - echo "test_create_user: tests skipped." - #TODO: mock useradd. - return - fi - # Case 1: create_user should succeed. - create_user - assertEquals "create_user()" 0 $? -} - -good_group_entry="${amanda_group}:x:100:${amanda_user}" + for os in linux osx solaris; do + echo $os > ${MOCKDIR}/id_os + check_user_group "abracadabra" + assertNotEquals "'check_user group abracadabra' should not be found:" 0 $? + LOG_TAIL=`tail -1 ${LOGFILE}|cut -d " " -f 5-` + assertEquals "check_user_group should write" \ + "User's primary group 'abracadabra' does not exist" \ + "${LOG_TAIL}" + done +} + +good_group_entry="${amanda_group}:x:100:" export good_group_entry -test_check_user_group() { - logger "test_check_user_group" +test_check_user_group_exists() { + logger "test_check_user_group user and group exist" + touch ${MOCKDIR}/id_exists touch ${SYSCONFDIR}/group # Non-root adds and entry to the mock group file [ ! "$IAmRoot" ] && echo $good_group_entry > ${SYSCONFDIR}/group + for os in linux osx solaris; do + echo $os > ${MOCKDIR}/id_os - # Case 1: Amanda_user is correct. - touch ${MOCKDIR}/is_member - check_user "group" "${amanda_group}" - assertEquals "'check_user group ${amanda_group}': id returns member" \ - 0 $? + # Case 1: Amanda_user is correct. + echo ${amanda_group} > ${MOCKDIR}/id_group + check_user_group "${amanda_group}" + assertEquals "'check_user_group ${amanda_group}': id returns correct groupname" \ + 0 $? - # Case 2: Amanda_user is not a member of the the correct group. - rm ${MOCKDIR}/is_member - check_user "group" "${amanda_group}" - assertEquals "'check_user group ${amanda_group}' when not a member" 1 $? + # Case 2: Amanda_user is not a member of the the correct primary group. + rm ${MOCKDIR}/id_group + check_user_group "${amanda_group}" + assertEquals "'check_user_group ${amanda_group}' when not a member" 1 $? + done } +test_check_user_supplemental_group_missing() { + logger "test_check_user_supplemental_group missing" + [ ! "$IAmRoot" ] && echo $good_group_entry > ${SYSCONFDIR}/group + for os in linux osx solaris; do + echo $os > ${MOCKDIR}/id_os + check_user_supplemental_group ${sup_group} + assertEquals "'check_user supplemental-group ${sup_group}' when group missing" \ + 1 $? + done +} + +missing_group_member="${sup_group}:x:105:nobody" +export missing_group_member +good_sup_group_entry="${missing_group_member},${amanda_user}" +export good_sup_group_entry + +test_check_user_supplemental_group_exists() { + logger "test_check_user_supplemental_group exists" + [ ! "$IAmRoot" ] && echo $missing_group_member > ${SYSCONFDIR}/group + check_user_supplemental_group ${sup_group} + assertEquals "'check_user_supplemental_group ${sup_group}' when amanda_user is not a member" \ + 1 $? + + [ ! "$IAmRoot" ] && echo ${good_sup_group_entry} > ${SYSCONFDIR}/group + check_user_supplemental_group ${sup_group} + assertEquals "'check_user_supplemental_group ${sup_group}' with correct membership" \ + 0 $? +} test_check_user_shell() { logger "test_check_user_shell" if [ ! "$IAmRoot" ]; then - echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd + echo "${good_passwd_entry}" > ${SYSCONFDIR}/passwd fi # Case 1: Provide a matching shell - check_user "shell" "/bin/bash" - assertEquals "check_user shell /bin/bash (matching)" 0 $? - # Case 2: Provid a non-matching shell. - check_user "shell" "/bin/sh" - assertEquals "check_user shell /bin/ksh (not matching)" 1 $? + check_user_shell "/bin/bash" + assertEquals "check_user_shell /bin/bash (matching)" 0 $? + # Case 2: Provide a non-matching shell. + check_user_shell "/bin/ksh" + assertEquals "check_user_shell /bin/ksh (not matching)" 1 $? } test_check_user_homedir() { logger 'test_check_user_homedir' if [ ! "$IAmRoot" ]; then - echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd + echo "${good_passwd_entry}" > ${SYSCONFDIR}/passwd fi # Case 1: Assume amanda_user is correct. - check_user "homedir" "${AMANDAHOMEDIR}" - assertEquals "check_user homedir ${AMANDAHOMEDIR}" 0 $? + check_user_homedir "${AMANDAHOMEDIR}" + assertEquals "check_user_homedir ${AMANDAHOMEDIR}" 0 $? # Case 2: Provide an incorrect homedir - check_user "homedir" "/tmp" - assertEquals "check_user homedir /tmp" 1 $? -} + check_user_homedir "/tmp" + assertEquals "check_user_homedir /tmp" 1 $? +} + +test_check_user_uid() { + echo "${amanda_group}" > ${MOCKDIR}/id_group + touch ${MOCKDIR}/id_exists + logger 'test_check_user_uid' + for os in linux osx solaris; do + echo $os > ${MOCKDIR}/id_os + check_user_uid + assertEquals "check_user_uid without a uid" 1 $? + logger 'test_check_user_uid wrong id' + check_user_uid 123 + assertEquals "check_user_uid uids don't match" 1 $? + logger 'test_check_user_uid correct id' + check_user_uid ${deb_uid} + done +} test_check_homedir_dir_missing() { logger "test_check_homedir_dir_missing" # First make sure the dir is missing @@ -416,6 +448,61 @@ test_check_homedir_dir_missing() { assertNotEquals "check_homedir returned 0, but homedir did not exist" 0 $? } +# passwd file entry for Linux systems, maybe others. UID is correct +# for Debian as well. +good_passwd_entry="${amanda_user}:x:${mock_deb_uid}:6::${AMANDAHOMEDIR}:/bin/bash" +export good_passwd_entry +test_create_user() { + logger "test_create_user" + if [ ! "$IAmRoot" ]; then + startSkipping + echo "test_create_user: Creating mock passwd file." + echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd + echo "test_create_user: tests skipped." + #TODO: mock useradd. + return + fi + # Case 1: create_user should succeed. + create_user + assertEquals "create_user()" 0 $? +} + +test_add_group_check_parameters_logs() { + rm -f ${MOCKDIR}/groupadd_rc ${MOCKDIR}/num_groups + # Return codes are integers. + printf '%i' 0 > ${MOCKDIR}/groupadd_rc + # Test that first parameter is required. + add_group + assertEquals "add_group without a group should fail." 1 $? + LOG_TAIL=`tail -1 ${LOGFILE}|cut -d " " -f 5-` + assertEquals "add_group should write" \ + "Error: first argument was not a group to add." \ + "${LOG_TAIL}" +} + +test_add_group_group_ok() { + # groupadd created group + printf '%i' 0 > ${MOCKDIR}/groupadd_rc + echo '${amanda_user} : prev_grp1' > ${MOCKDIR}/groups_output + add_group twinkle + assertEquals "add_group group ok" 0 $? + flags=`cat ${mock_usermod_flags}` + assertEquals "usermod_flags" \ + "usermod args: -G prev_grp1,twinkle ${amanda_user}" \ + "${flags}" + + # Make sure supplemental groups are preserved when adding groups to an + # existing account + echo '${amanda_user} : prev_grp1 prev_grp2' > ${MOCKDIR}/groups_output + printf '%i' 1 > ${MOCKDIR}/num_groups + add_group twinkle + assertEquals "add_group group ok" 0 $? + flags=`cat ${mock_usermod_flags}` + assertEquals "usermod_flags should contain:" \ + "usermod args: -G prev_grp1,prev_grp2,twinkle ${amanda_user}" \ + "${flags}" +} + test_create_homedir() { logger "test_create_homedir" rm -rf ${AMANDAHOMEDIR} @@ -627,12 +714,11 @@ if [ $# -gt 0 ]; then echo $1 SPECIFIC_TESTS="$*" suite() { - __shunit_suite="test___logger" - __shunit_suite="$__shunit_suite test__log_output_of" - __shunit_suite="$__shunit_suite $SPECIFIC_TESTS" - # Set the test total including the 3 base tests. - __shunit_testsTotal=`expr 2 + $#` suite_addTest test___logger + suite_addTest test__log_output_of + for t in $SPECIFIC_TESTS; do + suite_addTest $t + done } fi diff --git a/packaging/deb/amanda-backup-client.postinst b/packaging/deb/amanda-backup-client.postinst index c28fc4c..5d6cb34 100644 --- a/packaging/deb/amanda-backup-client.postinst +++ b/packaging/deb/amanda-backup-client.postinst @@ -1,104 +1,5 @@ #!/bin/sh - -SYSCONFDIR="/etc" -LOCALSTATEDIR="/var" -LOGDIR="${LOCALSTATEDIR}/log/amanda/" -AMANDAHOMEDIR="${LOCALSTATEDIR}/lib/amanda" -amanda_user=amandabackup -amanda_group=disk -xinetd_reload="restart" - - -# Installing xinetd config and make it active. -if [ -e /etc/xinetd.d ] && [ -d /etc/xinetd.d ] ; then - if [ ! -f /etc/xinetd.d/amandaclient ] ; then - cp ${AMANDAHOMEDIR}/example/xinetd.amandaclient /etc/xinetd.d/amandaclient || exit 1 - echo -n "`date +'%b %e %Y %T'`: Reloading xinetd configuration..." - if [ "${xinetd_reload}" = "reload" ] ; then - /usr/sbin/invoke-rc.d xinetd ${xinetd_reload} # don't exit yet... - if [ $? -ne 0 ] ; then - echo -n "reload failed. Attempting restart..." - /usr/sbin/invoke-rc.d xinetd restart || exit 1 - fi - else - /usr/sbin/invoke-rc.d xinetd ${xinetd_reload} || exit 1 - fi - fi -fi - -echo "`date +'%b %e %Y %T'`: Installing '${LOCALSTATEDIR}/amanda/amandates'." -if [ ! -f ${LOCALSTATEDIR}/amanda/amandates ] ; then - touch ${LOCALSTATEDIR}/amanda/amandates || exit 1 -fi -echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '${LOCALSTATEDIR}/amanda/amandates'." -chown ${amanda_user}:${amanda_group} ${LOCALSTATEDIR}/amanda/amandates || exit 1 -chmod 0640 ${LOCALSTATEDIR}/amanda/amandates || exit 1 -if [ -x /sbin/restorecon ] ; then - /sbin/restorecon ${LOCALSTATEDIR}/amanda/amandates || exit 1 -fi - -# Install .amandahosts to client -echo "`date +'%b %e %Y %T'`: Checking '${AMANDAHOMEDIR}/.amandahosts' file." -if [ ! -f ${AMANDAHOMEDIR}/.amandahosts ] ; then - touch ${AMANDAHOMEDIR}/.amandahosts || exit 1 -fi -for host in localhost localhost.localdomain ; do - if [ -z "`grep \"^${host}[[:blank:]]\+${amanda_user}[[:blank:]]\+amdump\" ${AMANDAHOMEDIR}/.amandahosts`" ] ; then - echo "${host} ${amanda_user} amdump" >> "${AMANDAHOMEDIR}/.amandahosts" || exit 1 - fi -done -chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.amandahosts || exit 1 -chmod 0600 ${AMANDAHOMEDIR}/.amandahosts || exit 1 - -# Install amanda client configuration file -echo "`date +'%b %e %Y %T'`: Checking '${SYSCONFDIR}/amanda/amanda-client.conf' file." -if [ ! -f ${SYSCONFDIR}/amanda/amanda-client.conf ] ; then - cp ${AMANDAHOMEDIR}/example/amanda-client.conf ${SYSCONFDIR}/amanda/amanda-client.conf || exit 1 -fi -chown ${amanda_user}:${amanda_group} ${SYSCONFDIR}/amanda/amanda-client.conf || exit 1 -chmod 0600 ${SYSCONFDIR}/amanda/amanda-client.conf || exit 1 - -# Install .gnupg directory -echo "`date +'%b %e %Y %T'`: Installing '${AMANDAHOMEDIR}/.gnupg'." -if [ ! -d ${AMANDAHOMEDIR}/.gnupg ] ; then - echo "`date +'%b %e %Y %T'`: '${AMANDAHOMEDIR}/.gnupg' will be created." - mkdir ${AMANDAHOMEDIR}/.gnupg || exit 1 -fi -echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '${AMANDAHOMEDIR}/.gnupg'." -chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.gnupg || exit 1 -chmod 700 ${AMANDAHOMEDIR}/.gnupg || exit 1 - -# SSH RSA key generation on client for amrecover -KEYDIR="${AMANDAHOMEDIR}/.ssh" -KEYFILE="id_rsa_amrecover" -COMMENT="root@client" -if [ ! -d ${KEYDIR} ] ; then - if [ -f ${KEYDIR} ] ; then - echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file. Renaming to '${KEYDIR}.save'." - mv ${KEYDIR} ${KEYDIR}.save || exit 1 - fi - echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." - mkdir ${KEYDIR} || exit 1 -fi -if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then - echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" - ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' || exit 1 -fi -echo "`date +'%b %e %Y %T'`: Setting permissions for '${KEYDIR}' and '${KEYDIR}/${KEYFILE}*'" -chown ${amanda_user}:${amanda_group} ${KEYDIR} || exit 1 -chmod 0750 ${KEYDIR} || exit 1 -chmod 0600 ${KEYDIR}/${KEYFILE}* || exit 1 - -# environment variables (~amandabackup/.profile) -echo "`date +'%b %e %Y %T'`: Checking for '${AMANDAHOMEDIR}/.profile' and ensuring correct environment." -if [ ! -f ${AMANDAHOMEDIR}/.profile ] ; then - touch ${AMANDAHOMEDIR}/.profile || exit 1 -fi -if [ -z "`grep PATH ${AMANDAHOMEDIR}/.profile | grep '/usr/sbin'`" ] ; then - echo "export PATH=\"\$PATH:/usr/sbin/\"" >> "${AMANDAHOMEDIR}/.profile" || exit 1 -fi -echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${AMANDAHOMEDIR}/.profile'" -chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.profile || exit 1 -chmod 0640 ${AMANDAHOMEDIR}/.profile || exit 1 - -echo "`date +'%b %e %Y %T'`: === Amanda backup client installation complete. ===" +# Debian recommends this. Script exits on simple command failure. +# set -e +pkg_type=client +other_pkg_type=server diff --git a/packaging/deb/amanda-backup-client.postrm b/packaging/deb/amanda-backup-client.postrm index e69de29..78a6da5 100644 --- a/packaging/deb/amanda-backup-client.postrm +++ b/packaging/deb/amanda-backup-client.postrm @@ -0,0 +1,3 @@ +#!/bin/sh -e +pkg_type=client +other_pkg_type=server diff --git a/packaging/deb/amanda-backup-server.postinst b/packaging/deb/amanda-backup-server.postinst index 2f1ee20..e958104 100644 --- a/packaging/deb/amanda-backup-server.postinst +++ b/packaging/deb/amanda-backup-server.postinst @@ -1,144 +1,5 @@ #!/bin/sh # Debian recommends this. Script exits on simple command failure. # set -e -LOGDIR="/var/log/amanda/" -SYSCONFDIR="/etc" -LOCALSTATEDIR="/var" -AMANDAHOMEDIR="${LOCALSTATEDIR}/lib/amanda" -AMTMP="/tmp/amanda" -amanda_user=amandabackup -amanda_group=disk -xinetd_reload="restart" - -if [ -d /etc/xinetd.d ] ; then - if [ ! -f /etc/xinetd.d/amandaserver ] ; then - cp ${AMANDAHOMEDIR}/example/xinetd.amandaserver /etc/xinetd.d/amandaserver || exit 1 - chmod 0644 /etc/xinetd.d/amandaserver || exit 1 - if [ -f /etc/xinetd.d/amandaclient ] ; then - rm /etc/xinetd.d/amandaclient || exit 1 - fi - echo -n "`date +'%b %e %Y %T'`: Reloading xinetd configuration..." - if [ "${xinetd_reload}" = "reload" ] ; then - /usr/sbin/invoke-rc.d xinetd ${xinetd_reload} # don't exit yet! - if [ $? -ne 0 ] ; then - echo -n "reload failed. Attempting restart..." - /usr/sbin/invoke-rc.d xinetd restart || exit 1 - fi - else - /usr/sbin/invoke-rc.d xinetd ${xinetd_reload} || exit 1 - fi - fi -fi - -echo "`date +'%b %e %Y %T'`: Installing '${LOCALSTATEDIR}/amanda/amandates'." -if [ ! -f ${LOCALSTATEDIR}/amanda/amandates ] ; then - touch ${LOCALSTATEDIR}/amanda/amandates || exit 1 -fi -echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '${LOCALSTATEDIR}/amanda/amandates'." -chown ${amanda_user}:${amanda_group} ${LOCALSTATEDIR}/amanda/amandates || exit 1 -chmod 0640 ${LOCALSTATEDIR}/amanda/amandates || exit 1 -if [ -x /sbin/restorecon ] ; then - /sbin/restorecon ${LOCALSTATEDIR}/amanda/amandates || exit 1 -fi - -# Check for existence of and permissions on ${AMTMP} -if [ ! -d ${AMTMP} ]; then - mkdir ${AMTMP} || exit 1 -fi -echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '${AMTMP}'." -chown ${amanda_user}:${amanda_group} ${AMTMP} || exit 1 -chmod 0640 ${AMTMP} || exit 1 - -# install am_passphrase file to server -echo "`date +'%b %e %Y %T'`: Checking '${AMANDAHOMEDIR}/.am_passphrase' file." -if [ ! -f ${AMANDAHOMEDIR}/.am_passphrase ] ; then - echo "`date +'%b %e %Y %T'`: Create '${AMANDAHOMEDIR}/.am_passphrase' file." - touch ${AMANDAHOMEDIR}/.am_passphrase || exit 1 - phrase=`echo $RANDOM | md5sum | awk '{print $1}'` - echo ${phrase} >>${AMANDAHOMEDIR}/.am_passphrase - - chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.am_passphrase - chmod 0600 ${AMANDAHOMEDIR}/.am_passphrase -fi - -# Install .gnupg directory -echo "`date +'%b %e %Y %T'`: Installing '${AMANDAHOMEDIR}/.gnupg'." -if [ ! -d ${AMANDAHOMEDIR}/.gnupg ] ; then - echo "`date +'%b %e %Y %T'`: '${AMANDAHOMEDIR}/.gnupg' will be created." - mkdir ${AMANDAHOMEDIR}/.gnupg || exit 1 -fi -echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '${AMANDAHOMEDIR}/.gnupg'." -chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.gnupg || exit 1 -chmod 700 ${AMANDAHOMEDIR}/.gnupg || exit 1 - -# Install .amandahosts to server -echo "`date +'%b %e %Y %T'`: Checking '${AMANDAHOMEDIR}/.amandahosts' file." -if [ ! -f ${AMANDAHOMEDIR}/.amandahosts ] ; then - touch ${AMANDAHOMEDIR}/.amandahosts || exit 1 -fi -for host in localhost localhost.localdomain ; do - if [ -z "`grep \"^${host}[[:blank:]]\+root[[:blank:]]\+amindexd[[:blank:]]\+amidxtaped\" ${AMANDAHOMEDIR}/.amandahosts`" ] ; then - echo "${host} root amindexd amidxtaped" >>${AMANDAHOMEDIR}/.amandahosts || exit 1 - fi - if [ -z "`grep \"^${host}[[:blank:]]\+${amanda_user}[[:blank:]]\+amdump\" ${AMANDAHOMEDIR}/.amandahosts`" ] ; then - echo "${host} ${amanda_user} amdump" >>${AMANDAHOMEDIR}/.amandahosts || exit 1 - fi -done -chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.amandahosts || exit 1 -chmod 0600 ${AMANDAHOMEDIR}/.amandahosts || exit 1 - -# SSH RSA key generation for amdump -KEYDIR="${AMANDAHOMEDIR}/.ssh" -KEYFILE="id_rsa_amdump" -COMMENT="${amanda_user}@server" -if [ ! -d ${KEYDIR} ] ; then - if [ -f ${KEYDIR} ] ; then - echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file. Renaming to '${KEYDIR}.save'." - mv ${KEYDIR} ${KEYDIR}.save || exit 1 - fi - echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." - mkdir ${KEYDIR} || exit 1 -fi -if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then - echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" - ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' || exit 1 -fi -echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${KEYDIR}' and '${KEYDIR}/${KEYFILE}*'" -chown ${amanda_user}:${amanda_group} ${KEYDIR} ${KEYDIR}/${KEYFILE}* || exit 1 -chmod 0750 ${KEYDIR} || exit 1 -chmod 0600 ${KEYDIR}/${KEYFILE}* || exit 1 - -# SSH RSA key generation on client for amrecover -KEYDIR="${AMANDAHOMEDIR}/.ssh" -KEYFILE="id_rsa_amrecover" -COMMENT="root@client" -if [ ! -d ${KEYDIR} ] ; then - if [ -f ${KEYDIR} ] ; then - echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file. Renaming to '${KEYDIR}.save'." - mv ${KEYDIR} ${KEYDIR}.save || exit 1 - fi - echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." - mkdir ${KEYDIR} || exit 1 -fi -if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then - echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" - ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' || exit 1 -fi -echo "`date +'%b %e %Y %T'`: Setting permissions for '${KEYDIR}'" -chown ${amanda_user}:${amanda_group} ${KEYDIR} || exit 1 -chmod 0750 ${KEYDIR} || exit 1 -chmod 0600 ${KEYDIR}/${KEYFILE}* || exit 1 - -# environment variables (~amandabackup/.profile) -echo "`date +'%b %e %Y %T'`: Checking for '${AMANDAHOMEDIR}/.profile' and ensuring correct environment." -if [ ! -f ${AMANDAHOMEDIR}/.profile ] ; then - touch ${AMANDAHOMEDIR}/.profile || exit 1 -fi -if [ -z "`grep PATH ${AMANDAHOMEDIR}/.profile | grep '/usr/sbin'`" ] ; then - echo "export PATH=\"\$PATH:/usr/sbin/\"" >> "${AMANDAHOMEDIR}/.profile" || exit 1 -fi -echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${AMANDAHOMEDIR}/.profile'" -chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.profile || exit 1 -chmod 0640 ${AMANDAHOMEDIR}/.profile || exit 1 - -echo "`date +'%b %e %Y %T'`: === Amanda backup server installation complete. ===" +pkg_type=server +other_pkg_type=client diff --git a/packaging/deb/amanda-backup-server.postrm b/packaging/deb/amanda-backup-server.postrm index e69de29..c1f3f41 100644 --- a/packaging/deb/amanda-backup-server.postrm +++ b/packaging/deb/amanda-backup-server.postrm @@ -0,0 +1,3 @@ +#!/bin/sh -e +pkg_type=server +other_pkg_type=client diff --git a/packaging/deb/buildpkg b/packaging/deb/buildpkg index 516d1d9..69889a9 100755 --- a/packaging/deb/buildpkg +++ b/packaging/deb/buildpkg @@ -51,7 +51,14 @@ do_substitute() { # dpkg assumes that packages will have the same name on all releases and # that apt will prevent users from downloading the wrong build. We want # this information helpfully obvious since we can't rely on apt. - /usr/bin/perl packaging/common/substitute.pl packaging/deb/changelog.src packaging/deb/changelog + file_list="packaging/deb/changelog \ + packaging/deb/postinst \ + packaging/deb/postrm \ + packaging/deb/preinst" + for file in ${file_list}; do + /usr/bin/perl packaging/common/substitute.pl \ + ${file}.src ${file} || exit 1 + done } do_resources() { diff --git a/packaging/deb/postinst.src b/packaging/deb/postinst.src new file mode 100644 index 0000000..2497257 --- /dev/null +++ b/packaging/deb/postinst.src @@ -0,0 +1,75 @@ +# This is appended to packaging/deb/amanda-backup-*.postinst +# vim: ft=sh + +# Note: this script needs to do the same things in all maintainer +# script cases: configure, abort-remove, abort-upgrade. + +LOGFILE=`mktemp /tmp/amanda-postinst.log.XXXXXXXXXXX` +if [ $? -ne 0 ]; then + echo "Unable to create log file!" + exit 1 +fi +amanda_user=amandabackup +amanda_group=disk +AMANDAHOMEDIR=%%AMANDAHOMEDIR%% +os=Linux +dist=%%DISTRO%% +LOGDIR=%%LOGDIR%% +INSTALL_LOG="${LOGDIR}/install.log" +SYSCONFDIR=/etc +SBINDIR=/usr/sbin +AMTMP="/tmp/amanda" + +AMANDATES=${SYSCONFDIR}/amandates + +# ---------- Common functions ------------ +%%COMMON_FUNCTIONS%% +%%POST_INST_FUNCTIONS%% + +# -------- End Common functions ---------- + +check_xinetd "amanda${pkg_type}" +case $? in + 0) backup_xinetd "amanda${pkg_type}" + install_xinetd "amanda${pkg_type}" + ;; + 1) install_xinetd "amanda${pkg_type}" ;; + 2) logger "Xinetd config not installed: either xinetd config is not present or xinetd.d is a file." ;; + *) logger "bad return from check_xinetd" + cat ${LOGFILE} >> ${INSTALL_LOG} + exit 1 + ;; +esac + +# amanda${pkg_type} should not have the amanda${other_pkg_type} xinetd installed. +check_xinetd "amanda${other_pkg_type}" +case $? in + 0) backup_xinetd "amanda${other_pkg_type}" ;; +esac + +reload_xinetd +create_amandates +check_amandates +create_gnupg +check_gnupg +create_amandahosts +check_amandahosts_entry root amindexd amidxtaped +check_amandahosts_entry ${amanda_user} amdump +check_amandahosts_perms +create_ssh_key ${pkg_type} +if [ "${pkg_type}" = "server" ]; then + create_ssh_key ${other_pkg_type} +fi +create_profile +check_profile +install_client_conf +create_ampassphrase +create_amtmp + +logger "Amanda ${pkg_type} installation complete." +cat $LOGFILE >> $INSTALL_LOG && { + rm $LOGFILE; + echo "Amanda installation log can be found in '${INSTALL_LOG}'."; +} || \ + echo "Amanda installation log can be found in '${LOGFILE}'."; + diff --git a/packaging/deb/postrm b/packaging/deb/postrm deleted file mode 100755 index e972af6..0000000 --- a/packaging/deb/postrm +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -e -case "$1" in - purge) - if [ -d /etc/amanda ]; then - # remove /etc amanda if there are no files left - rmdir /etc/amanda 2> /dev/null || true - fi - if [ -d /var/log/amanda ]; then - rm -rf /var/log/amanda - fi - if [ -d /var/lib/amanda/gnutar-lists ]; then - rm -rf /var/lib/amanda/gnutar-lists - fi - if [ -d /var/lib/amanda ]; then - rm -rf /var/lib/amanda - fi - if which deluser >/dev/null 2>&1 ; then - for group in disk; do - # only call deluser when amandabackup is in $group - if getent group "$group" | - awk -F: '{ print $4 }' | - awk -F, '{ for (i=1; i <= NF; i++ ) print $i }' | - grep '^amandabackup$' > /dev/null; then - deluser "amandabackup $group" || true - fi - done - fi - ;; - remove|upgrade|deconfigure) - ;; - - failed-upgrade) - ;; - - *) - echo "unknown argument --> $1" >&2 - exit 0 - ;; -esac diff --git a/packaging/deb/postrm.src b/packaging/deb/postrm.src new file mode 100755 index 0000000..20150a4 --- /dev/null +++ b/packaging/deb/postrm.src @@ -0,0 +1,86 @@ +# This get appended to amanda-backup-*-.postrm +# vim: ft=sh + +LOGFILE=`mktemp /tmp/amanda-remove.log.XXXXXXXXXXX` +if [ $? -ne 0 ]; then + echo "Unable to create log file!" + exit 1 +fi +amanda_user=amandabackup +amanda_group=disk +AMANDAHOMEDIR=%%AMANDAHOMEDIR%% +os=Linux +dist=%%DISTRO%% + +LOGDIR=%%LOGDIR%% +SYSCONFDIR=/etc + +# ---------- Common functions ------------ +# see packaging/common/ in the source tree +%%COMMON_FUNCTIONS%% +%%POST_RM_FUNCTIONS%% + +# -------- End Common functions ---------- +remove() { + if check_xinetd "amanda${pkg_type}"; then + rm_xinetd "amanda${pkg_type}" || { \ + logger "Warning: Did not successfully remove amanda${pkg_type} from xinetd."; + exit 1; } + reload_xinetd + fi + +} + +purge() { + if [ -d ${SYSCONFDIR}/amanda ]; then + logger "Removing ${SYSCONFDIR}/amanda if empty..." + rmdir ${SYSCONFDIR}/amanda 2> /dev/null || true + fi + if [ -d ${LOGDIR} ]; then + logger "Removing ${LOGDIR}..." + rm -rf ${LOGDIR} + fi + if [ -d ${AMANDAHOMEDIR} ]; then + logger "Removing ${AMANDAHOMEDIR}..." + rm -rf ${AMANDAHOMEDIR} + fi + if [ -f ${SYSCONFDIR}/amandates ]; then + logger "Removing ${SYSCONFDIR}/amandates..." + rm -rf ${SYSCONFDIR}/amandates + fi + # Remove ${amanda_user} from sensitive groups. + if which deluser >/dev/null 2>&1 ; then + for group in tape; do + # only call deluser when amandabackup is in $group + if getent group "$group" | + awk -F: '{ print $4 }' | + awk -F, '{ for (i=1; i <= NF; i++ ) print $i }' | + grep "^${amanda_user}$" > /dev/null; then + deluser ${amanda_user} $group || true + fi + done + fi +} + +case "$1" in + purge|abort-install) + remove + purge + ;; + remove|upgrade|deconfigure) + remove + ;; + + failed-upgrade) + check_xinetd "amanda${pkg_type}" + if [ $? -eq 1 ] ; then + install_xinetd + reload_xinetd + fi + ;; + + *) + echo "unknown argument --> $1" >&2 + exit 0 + ;; +esac diff --git a/packaging/deb/preinst b/packaging/deb/preinst deleted file mode 100755 index 6180b1f..0000000 --- a/packaging/deb/preinst +++ /dev/null @@ -1,127 +0,0 @@ -#!/bin/sh - -amanda_user=amandabackup -amanda_group=disk - -TMPFILE=`mktemp /tmp/deb-amanda.XXXXXXXXXXX` -if [ $? -ne 0 ]; then - echo "Unable to mktemp!" 1>&2 - exit 1 -fi -LOGDIR="/var/log/amanda" -INSTALL_LOG="${LOGDIR}/install.log" -INSTALL_ERR="${LOGDIR}/install.err" - -echo "`date +'%b %e %Y %T'`: Preparing to install Amanda" >${TMPFILE} - -# Check for the '${amanda_user}' user -echo "`date +'%b %e %Y %T'`: Checking for ${amanda_user} user..." >>${TMPFILE} -if [ "`id -u ${amanda_user} >/dev/null 2>&1 && echo 0 || echo 1`" != "0" ] ; then - useradd -c "Amanda" -g ${amanda_group} -d /var/lib/amanda -s /bin/bash ${amanda_user} - # Lock the ${amanda_user} account until admin sets password - passwd -l ${amanda_user} >>/dev/null - PASSWD_EXIT=$? - if [ ${PASSWD_EXIT} -eq 0 ] ; then - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: The ${amanda_user} user account has been successfully created." >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Furthermore, the account has been automatically locked for you" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: for security purposes. Once a password for the '${amanda_user}'" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: account has been set, the user can be unlocked by issuing" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: the following command as root.:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: # passwd -u ${amanda_user}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: If this is not a new installation of Amanda and you have" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: pre-existing Amanda configurations in /etc/amanda" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: you should ensure that 'dumpuser' is set to '${amanda_user}'" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: in those configurations. Additionally, you should ensure" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: that /var/lib/amanda/.amandahosts on your client systems" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: is properly configured to allow connections for the user" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: '${amanda_user}'." >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - PASSWD_OK=0 - else - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! The '${amanda_user}' user account for this system has been !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! created, however the user has no password set. For !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! security purposes this account is normally locked !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! after creation. Unfortunately, when locking this !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! account an error occurred. To ensure the security !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! of your system you should set a password for the !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user account '${amanda_user}' immediately! To set such a !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! password, please issue the following command.: !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! # passwd ${amanda_user}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - PASSWD_OK=1 - fi -else - # log information about '${amanda_user}' user parameters - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: The Amanda backup software is configured to operate as the" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: user '${amanda_user}'. This user exists on your system and has not" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: been modified. To ensure that Amanda functions properly," >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: please see that the following parameters are set for that" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: user.:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: SHELL: /bin/bash" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: HOME: /var/lib/amanda" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Default group: ${amanda_group}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Verifying ${amanda_user} user parameters :" >>${TMPFILE} - - - if [ "`id -gn ${amanda_user}`" != "${amanda_group}" ] ; then - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user '${amanda_user}' is not part of the ${amanda_group} group, !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! please make sure it is corrected before start using amanda !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: Verified group name of user '${amanda_user}'" >>${TMPFILE} - fi - - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - PASSWD_OK=0 -fi -if [ -d /var/lib/amanda ] ; then - echo -n "`date +'%b %e %Y %T'`: Checking ownership of '/var/lib/amanda'... " >>${TMPFILE} - if [ "`ls -dl /var/lib/amanda | awk '//{split($_,x); print x[3]}'`" = "${amanda_user}" ] && \ - [ "`ls -dl /var/lib/amanda | awk '//{split($_,x); print x[4]}'`" = "${amanda_group}" ] ; then - echo "correct." >>${TMPFILE} - VARLIB_OK=0 - else - echo "incorrect!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Please ensure that the directory '/var/lib/amanda' is owned by" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: the user '${amanda_user}' and group '${amanda_group}'." >>${TMPFILE} - VARLIB_OK=1 - fi -else - VARLIB_OK=0 -fi -echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} -if [ ! -e ${LOGDIR} ] ; then - # create log directory - mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1 - chown ${amanda_user}:${amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1 -fi - -if [ ${PASSWD_OK} -eq 1 ] || [ ${VARLIB_OK} -eq 1 ] ; then - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_ERR} - echo "Please review '${INSTALL_ERR}' to correct errors which have prevented the Amanda installation." >&2 - echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'." - exit 1 -else - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi - -echo "`date +'%b %e %Y %T'`: === Amanda installation started. ===" >${TMPFILE} - -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} -if [ -f "${TMPFILE}" ]; then - rm -f "${TMPFILE}" -fi - diff --git a/packaging/deb/preinst.src b/packaging/deb/preinst.src new file mode 100755 index 0000000..2e67461 --- /dev/null +++ b/packaging/deb/preinst.src @@ -0,0 +1,40 @@ +#!/bin/sh +# This is appended to packaging/deb/amanda-backup-*.preinst +# vim: ft=sh + +LOGFILE=`mktemp /tmp/amanda-preinst.log.XXXXXXXXXXX` +if [ $? -ne 0 ]; then + echo "Unable to mktemp!" 1>&2 + exit 1 +fi +amanda_user=amandabackup +amanda_group=disk +AMANDAHOMEDIR=%%AMANDAHOMEDIR%% +os=`uname` +wanted_shell=/bin/bash +dist=%%DISTRO%% +LOGDIR=%%LOGDIR%% +INSTALL_LOG=${LOGDIR}/install.log +SYSCONFDIR=/etc +# We require amandabackup to have a specific uid because buildtime uid is +# recorded in deb packages. This number should avoid conflict +deb_uid=63998 + +# See packaging/common/ for shell function libraries. +# ---------- Common functions ------------ +%%COMMON_FUNCTIONS%% +%%PRE_INST_FUNCTIONS%% + +# -------- End Common functions ---------- +logger "Preparing to install: Amanda Server %%VERSION%%" +create_user +check_user_group "${amanda_group}" || add_group "${amanda_group}" +check_user_supplemental_group "tape" || add_group "tape" +check_user_shell "${wanted_shell}" +check_user_homedir "${AMANDAHOMEDIR}" +check_homedir || create_homedir +create_logdir + +logger "Preinstall done." +cat $LOGFILE >> $INSTALL_LOG && rm $LOGFILE || \ + echo "Amanda preinstall logs can be found in '$LOGFILE'." diff --git a/packaging/deb/rules b/packaging/deb/rules index 1d75bbe..acf900c 100755 --- a/packaging/deb/rules +++ b/packaging/deb/rules @@ -1,13 +1,13 @@ #!/usr/bin/make -f -# debian/rules for amanda using debhelper. GNU copyright 2008 by Dan Locks, +# debian/rules for amanda using debhelper. GNU copyright 2008 by Dan Locks, # based on work by Bdale Garbee. # Warning - do *not* use -j on an SMP machine, or the build gets -# confused... some sort of race condition in the makefiles? +# confused... some sort of race condition in the makefiles? # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -AMVER=3.2alpha +AMVER=`cat FULL_VERSION` # These are variables that the user can override. They get used in various # places during configure, build, and install. @@ -45,8 +45,8 @@ DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) WD=$(shell pwd) -build: build-stamp -build-stamp: /sbin/dump /usr/bin/smbclient +build: build-stamp +build-stamp: /sbin/dump /usr/bin/smbclient dh_testdir ./configure \ MAKEFLAGS="-j1 " \ @@ -81,11 +81,14 @@ build-stamp: /sbin/dump /usr/bin/smbclient --enable-s3-device \ --disable-installperms touch missing - # There's probably a better way to do this. Preinst and postrm are the - # same for client and server, but we leave room for differences by just - # appending here. + # Preinst is the same for client and server, but we leave room for + # differences by just appending here. cat $(WD)/debian/preinst >> $(WD)/debian/amanda-backup-client.preinst cat $(WD)/debian/preinst >> $(WD)/debian/amanda-backup-server.preinst + # Postinst and postrm keep client/server differences to just variables; + # the postinst/postrm logic is otherwise the same. + cat $(WD)/debian/postinst >> $(WD)/debian/amanda-backup-client.postinst + cat $(WD)/debian/postinst >> $(WD)/debian/amanda-backup-server.postinst cat $(WD)/debian/postrm >> $(WD)/debian/amanda-backup-client.postrm cat $(WD)/debian/postrm >> $(WD)/debian/amanda-backup-server.postrm make -s LIBTOOLFLAGS=--silent @@ -177,8 +180,8 @@ binary-arch: build $(server)$(AMLIBEXECDIR)/planner \ $(server)/usr/sbin/amcheck \ $(server)/usr/sbin/amservice - echo "Amanda version $(AMVER)" > $(server)/$(AMANDAHOMEDIR)/amanda-release - echo "Amanda version $(AMVER)" > $(client)/$(AMANDAHOMEDIR)/amanda-release + echo "Amanda version $(AMVER)" > $(server)/$(AMANDAHOMEDIR)/amanda-release + echo "Amanda version $(AMVER)" > $(client)/$(AMANDAHOMEDIR)/amanda-release install -o root -g root -m 0644 debian/amanda-backup-client.lintian \ $(client)/usr/share/lintian/overrides/amanda-backup-client install -o root -g root -m 0644 debian/amanda-backup-server.lintian \ @@ -191,7 +194,7 @@ binary-arch: build dh_md5sums >> $(log) 2>&1 dh_builddeb >> $(log) 2>&1 -source diff: +source diff: @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false binary: binary-arch diff --git a/packaging/rpm/amanda.spec.src b/packaging/rpm/amanda.spec.src index ec55de8..4e59570 100644 --- a/packaging/rpm/amanda.spec.src +++ b/packaging/rpm/amanda.spec.src @@ -1,5 +1,5 @@ # -# Copyright (C) 2005 Zmanda Incorporated. +# Copyright (C) 2005-2012 Zmanda Incorporated. # All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it @@ -441,1098 +441,319 @@ fi # --- Pre/post (un)installation scripts --- -%pre -TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX` -if [ $? -ne 0 ]; then - echo "Unable to mktemp!" 1>&2 - exit 1 -fi -LOGDIR="%{LOGDIR}" -INSTALL_LOG="${LOGDIR}/install.log" -INSTALL_ERR="${LOGDIR}/install.err" - -echo "`date +'%b %e %Y %T'`: Preparing to install: %{amanda_version_info}" >${TMPFILE} - -# Check for the 'amanda' user -echo "`date +'%b %e %Y %T'`: Checking for '%{amanda_user}' user..." >>${TMPFILE} -if [ "`id -u %{amanda_user} > /dev/null 2>&1 && echo 0 || echo 1`" != "0" ] ; then - useradd -c "Amanda" -M -g %{amanda_group} -d %{AMANDAHOMEDIR} -s /bin/bash %{amanda_user} - if [ %{dist} = "SuSE" ]; then - PASSWD_EXIT=$? - else - # Lock the amanda account until admin sets password - passwd -l %{amanda_user} >>/dev/null - PASSWD_EXIT=$? - fi - if [ ${PASSWD_EXIT} -eq 0 ] ; then - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: The '%{amanda_user}; user account has been successfully created." >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Furthermore, the account has been automatically locked for you" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: for security purposes. Once a password for the '%{amanda_user}'" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: account has been set, the user can be unlocked by issuing" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: the following command as root.:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: # passwd -u %{amanda_user}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: If this is not a new installation of Amanda and you have" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: pre-existing Amanda configurations in %{SYSCONFDIR}/amanda" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: you should ensure that 'dumpuser' is set to '%{amanda_user}'" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: in those configurations. Additionally, you should ensure" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: that %{AMANDAHOMEDIR}/.amandahosts on your client systems" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: is properly configured to allow connections for the user" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: '%{amanda_user}'." >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - PASSWD_OK=0 - else - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! The '%{amanda_user}' user account for this system has been !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! created, however the user has no password set. For !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! security purposes this account is normally locked !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! after creation. Unfortunately, when locking this !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! account an error occurred. To ensure the security !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! of your system you should set a password for the !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user account '%{amanda_user}' immediately! To set such a !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! password, please issue the following command.: !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! # passwd %{amanda_user} !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - PASSWD_OK=1 - fi -else - # log information about 'amanda' user parameters - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: The Amanda backup software is configured to operate as the" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: user '%{amanda_user}'. This user exists on your system and has not" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: been modified. To ensure that Amanda functions properly," >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: please see that the following parameters are set for that" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: user.:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: SHELL: /bin/bash" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: HOME: %{AMANDAHOMEDIR}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Default group: %{amanda_group}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Verifying %{amanda_user} parameters :" >>${TMPFILE} - - if [ "`id -gn %{amanda_user}`" != "disk" ] ; then - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user 'amandabackup' is not part of the disk group,Pl !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! make sure it is corrected before start using amanda !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: Verified group name of user 'amandabackup'" >>${TMPFILE} - fi - - if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f7`" != "/bin/bash" ] ; then - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user 'amandabackup' default shell should be set to !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! /bin/bash, pl correct before start using Amanda !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: Verified Default shell for user 'amandabackup'" >>${TMPFILE} - fi - - if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f6`" != "%{AMANDAHOMEDIR}" ] ; then - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user 'amandabackup' home directory should be set to !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! %{AMANDAHOMEDIR} Pl correct before using Amanda !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: Verified Default home directory for user amandabackup" >>${TMPFILE} - fi - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - PASSWD_OK=0 -fi -if [ -d %{AMANDAHOMEDIR} ] ; then - echo -n "`date +'%b %e %Y %T'`: Checking ownership of '%{AMANDAHOMEDIR}'... " >>${TMPFILE} - if [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[3]}'`" = "%{amanda_user}" ] && \ - [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[4]}'`" = "%{amanda_group}" ] ; then - echo "correct." >>${TMPFILE} - VARLIB_OK=0 - else - echo "incorrect!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Please ensure that the directory '%{AMANDAHOMEDIR}' is owned by" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: the user '%{amanda_user}' and group '%{amanda_group}'." >>${TMPFILE} - VARLIB_OK=1 - fi -else - VARLIB_OK=0 -fi -echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} -if [ ! -e ${LOGDIR} ] ; then - # create log directory - mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1 - chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1 -elif [ ! -d ${LOGDIR} ] ; then - mv ${LOGDIR} ${LOGDIR}.rpmsave >>${TMPFILE} 2>&1 - mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1 - chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1 - mv ${LOGDIR}.rpmsave ${LOGDIR}/ >>${TMPFILE} 2>&1 -fi - -if [ ${PASSWD_OK} -eq 1 ] || [ ${VARLIB_OK} -eq 1 ] ; then - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_ERR} - echo "Please review '${INSTALL_ERR}' to correct errors which have prevented the Amanda installaton." >&2 - echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'." - exit 1 -else - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi - -echo "`date +'%b %e %Y %T'`: === Amanda installation started. ===" >${TMPFILE} - -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} -if [ -f "${TMPFILE}" ]; then - rm -f "${TMPFILE}" -fi - -%post -TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX -if [ $? -ne 0 ]; then - echo "Unable to mktemp!" 1>&2 - exit 1 -fi -LOGDIR="%{LOGDIR}" -INSTALL_LOG="${LOGDIR}/install.log" -INSTALL_ERR="${LOGDIR}/install.err" - -echo -n "`date +'%b %e %Y %T'`: Updating library cache..." >${TMPFILE} -/sbin/ldconfig >>${TMPFILE} 2>&1 -echo "done." >>${TMPFILE} -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -if [ -e /etc/xinetd.d ] && [ -d /etc/xinetd.d ] ; then - if [ ! -f /etc/xinetd.d/amandaserver ] ; then - cp %{AMANDAHOMEDIR}/example/xinetd.amandaserver /etc/xinetd.d/amandaserver - chmod 0644 /etc/xinetd.d/amandaserver >>${TMPFILE} 2>&1 - if [ -f /etc/xinetd.d/amandaclient ] ; then - rm /etc/xinetd.d/amandaclient - fi - echo -n "`date +'%b %e %Y %T'`: Reloading xinetd configuration..." >${TMPFILE} - if [ "%{xinetd_reload}" == "reload" ] ; then - /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -ne 0 ] ; then - echo -n "reload failed. Attempting restart..." >>${TMPFILE} - /etc/init.d/xinetd restart >>${TMPFILE} 2>&1 - ret_val=$? - fi - else - /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1 - ret_val=$? - fi - if [ ${ret_val} -eq 0 ] ; then - echo "success." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} - else - echo "failed. Please check your system logs." >>${TMPFILE} - cat ${TMPFILE} 1>&2 - cat ${TMPFILE} >>${INSTALL_ERR} - fi - fi -fi - -echo "`date +'%b %e %Y %T'`: Installing '%{AMANDATES}'." >${TMPFILE} -ret_val=0 -if [ ! -f %{AMANDATES} ] ; then - touch %{AMANDATES} >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: The file '%{AMANDATES}' has been created." >>${TMPFILE} - fi -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDATES}'." >>${TMPFILE} - chown %{amanda_user}:%{amanda_group} %{AMANDATES} >>${TMPFILE} 2>&1 - chmod 0640 %{AMANDATES} >>${TMPFILE} 2>&1 - if [ -x /sbin/restorecon ] ; then - /sbin/restorecon %{AMANDATES} >>${TMPFILE} 2>&1 - fi -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation successful." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -else - echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation failed." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_ERR} -fi - - -# Install .gnupg directory -echo "`date +'%b %e %Y %T'`: Installing '%{AMANDAHOMEDIR}/.gnupg'." >${TMPFILE} -ret_val=0 -if [ ! -d %{AMANDAHOMEDIR}/.gnupg ] ; then - echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' will be created." >>${TMPFILE} - mkdir %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' created successfully." >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' creation failed." >>${TMPFILE} - fi -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDAHOMEDIR}/.gnupg'." >>${TMPFILE} - chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -eq 0 ]; then - chmod 700 %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1 - ret_val=$? - fi -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation successful." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -else - echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation failed." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_ERR} -fi - -# Install .amandahosts -echo "`date +'%b %e %Y %T'`: Checking '%{AMANDAHOMEDIR}/.amandahosts' file." >${TMPFILE} -if [ ! -f %{AMANDAHOMEDIR}/.amandahosts ] ; then - touch %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1 -fi -for host in localhost localhost.localdomain ; do - if [ -z "`grep \"^${host}[[:blank:]]\+root[[:blank:]]\+amindexd[[:blank:]]\+amidxtaped\" %{AMANDAHOMEDIR}/.amandahosts`" ] ; then - echo "${host} root amindexd amidxtaped" >>%{AMANDAHOMEDIR}/.amandahosts - fi - if [ -z "`grep \"^${host}[[:blank:]]\+%{amanda_user}[[:blank:]]\+amdump\" %{AMANDAHOMEDIR}/.amandahosts`" ] ; then - echo "${host} %{amanda_user} amdump" >>%{AMANDAHOMEDIR}/.amandahosts - fi -done -chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1 -chmod 0600 %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# SSH RSA key generation for amdump -KEYDIR="%{AMANDAHOMEDIR}/.ssh" -KEYFILE="id_rsa_amdump" -COMMENT="%{amanda_user}@server" -if [ ! -d ${KEYDIR} ] ; then - if [ -f ${KEYDIR} ] ; then - echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file. Renaming to '${KEYDIR}.rpmsave'." >${TMPFILE} - mv ${KEYDIR} ${KEYDIR}.rpmsave - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} - fi - echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." >${TMPFILE} - mkdir ${KEYDIR} >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi -if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then - echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" >${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} - ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi -echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${KEYDIR}' and '${KEYDIR}/${KEYFILE}*'" >${TMPFILE} -chown %{amanda_user}:%{amanda_group} ${KEYDIR} ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1 -chmod 0750 ${KEYDIR} >>${TMPFILE} 2>&1 -chmod 0600 ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# SSH RSA key generation on client for amrecover -KEYDIR="%{AMANDAHOMEDIR}/.ssh" -KEYFILE="id_rsa_amrecover" -COMMENT="root@client" -if [ ! -d ${KEYDIR} ] ; then - if [ -f ${KEYDIR} ] ; then - echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file. Renaming to '${KEYDIR}.rpmsave'." >${TMPFILE} - mv ${KEYDIR} ${KEYDIR}.rpmsave >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} - fi - echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." >${TMPFILE} - mkdir ${KEYDIR} >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi -if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then - echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" >${TMPFILE} - ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi -echo "`date +'%b %e %Y %T'`: Setting permissions for '${KEYDIR}'" >${TMPFILE} -chown %{amanda_user}:%{amanda_group} ${KEYDIR} >>${TMPFILE} 2>&1 -chmod 0750 ${KEYDIR} >>${TMPFILE} 2>&1 -chmod 0600 ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# environment variables (~amandabackup/.profile) -echo "`date +'%b %e %Y %T'`: Checking for '%{AMANDAHOMEDIR}/.profile' and ensuring correct environment." >${TMPFILE} -if [ ! -f %{AMANDAHOMEDIR}/.profile ] ; then - touch %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1 -fi -if [ -z "`grep PATH %{AMANDAHOMEDIR}/.profile | grep '%{SBINDIR}'`" ] ; then - echo "export PATH=\"\$PATH:%{SBINDIR}\"" >>%{AMANDAHOMEDIR}/.profile 2>>${TMPFILE} -fi -echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '%{AMANDAHOMEDIR}/.profile'" >>${TMPFILE} -chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1 -chmod 0640 %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -echo "`date +'%b %e %Y %T'`: Sending anonymous distribution and version information to Zmanda" >> ${INSTALL_LOG} -if [ -x /usr/bin/wget ]; then - /usr/bin/wget -q -o /dev/null -O - --timeout=5 http://www.zmanda.com/amanda-tips.php\?version=%{amanda_version}\&os=%{disttag}%{distver}\&type=server -fi - -echo "`date +'%b %e %Y %T'`: === Amanda installation complete. ===" >${TMPFILE} - -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} -if [ -f "${TMPFILE}" ]; then - rm -f "${TMPFILE}" -fi +# Define script variables +# Some versions of rpmbuild do not like multi-line macros in spec files. ugly. +%define script_vars amanda_user=%{amanda_user}; amanda_group=%{amanda_group}; AMANDAHOMEDIR=%{AMANDAHOMEDIR}; os=Linux; wanted_shell=/bin/bash; dist=%{dist}; LOGDIR=%{LOGDIR}; INSTALL_LOG=$LOGDIR/install.log; SYSCONFDIR=%{SYSCONFDIR}; SBINDIR=%{SBINDIR}; +# --- Pre/post (un)installation scripts --- -echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'." -%postun -/sbin/ldconfig %pre backup_server -TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX` +########################################## +LOGFILE=`mktemp /tmp/amanda_server-preinst.log.XXXXXXXXXXX` if [ $? -ne 0 ]; then - echo "Unable to mktemp!" 1>&2 + echo "Unable to create log file!" exit 1 fi +%{script_vars} -LOGDIR="%{LOGDIR}" -INSTALL_LOG="${LOGDIR}/install.log" -INSTALL_ERR="${LOGDIR}/install.err" - -echo "`date +'%b %e %Y %T'`: Preparing to install: %{amanda_version_info}" >${TMPFILE} - -# Check for the 'amanda' user -echo "`date +'%b %e %Y %T'`: Checking for '%{amanda_user}' user..." >>${TMPFILE} -if [ "`id -u %{amanda_user} > /dev/null 2>&1 && echo 0 || echo 1`" != "0" ] ; then - useradd -c "Amanda" -M -g %{amanda_group} -d %{AMANDAHOMEDIR} -s /bin/bash %{amanda_user} - if [ %{dist} = "SuSE" ]; then - PASSWD_EXIT=$? - else - # Lock the amanda account until admin sets password - passwd -l %{amanda_user} >>/dev/null - PASSWD_EXIT=$? - fi - if [ ${PASSWD_EXIT} -eq 0 ] ; then - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: The '%{amanda_user}; user account has been successfully created." >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Furthermore, the account has been automatically locked for you" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: for security purposes. Once a password for the '%{amanda_user}'" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: account has been set, the user can be unlocked by issuing" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: the following command as root.:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: # passwd -u %{amanda_user}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: If this is not a new installation of Amanda and you have" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: pre-existing Amanda configurations in %{SYSCONFDIR}/amanda" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: you should ensure that 'dumpuser' is set to '%{amanda_user}'" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: in those configurations. Additionally, you should ensure" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: that %{AMANDAHOMEDIR}/.amandahosts on your client systems" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: is properly configured to allow connections for the user" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: '%{amanda_user}'." >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - PASSWD_OK=0 - else - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! The '%{amanda_user}' user account for this system has been !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! created, however the user has no password set. For !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! security purposes this account is normally locked !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! after creation. Unfortunately, when locking this !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! account an error occurred. To ensure the security !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! of your system you should set a password for the !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user account '%{amanda_user}' immediately! To set such a !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! password, please issue the following command.: !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! # passwd %{amanda_user} !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - PASSWD_OK=1 - fi -else - # log information about 'amanda' user parameters - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: The Amanda backup software is configured to operate as the" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: user '%{amanda_user}'. This user exists on your system and has not" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: been modified. To ensure that Amanda functions properly," >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: please see that the following parameters are set for that" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: user.:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: SHELL: /bin/bash" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: HOME: %{AMANDAHOMEDIR}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Default group: %{amanda_group}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Verifying %{amanda_user} parameters :" >>${TMPFILE} - - if [ "`id -gn %{amanda_user}`" != "disk" ] ; then - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user 'amandabackup' is not part of the disk group,Pl !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! make sure it is corrected before start using Amanda !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: Verified group name of user 'amandabackup'" >>${TMPFILE} - fi - if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f7`" != "/bin/bash" ] ; then - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user 'amandabackup' default shell should be set to !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! /bin/bash, pl correct before start using Amanda !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: Verified Default shell for user 'amandabackup'" >>${TMPFILE} - fi +# See packaging/common/ for shell function libraries. +# ---------- Common functions ------------ +%%COMMON_FUNCTIONS%% +%%PRE_INST_FUNCTIONS%% - if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f6`" != "%{AMANDAHOMEDIR}" ] ; then - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user 'amandabackup' home directory should be set to !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! %{AMANDAHOMEDIR} Pl correct before using Amanda !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: Verified Default home directory for user amandabackup" >>${TMPFILE} - fi - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - PASSWD_OK=0 -fi -if [ -d %{AMANDAHOMEDIR} ] ; then - echo -n "`date +'%b %e %Y %T'`: Checking ownership of '%{AMANDAHOMEDIR}'... " >>${TMPFILE} - if [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[3]}'`" = "%{amanda_user}" ] && \ - [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[4]}'`" = "%{amanda_group}" ] ; then - echo "correct." >>${TMPFILE} - VARLIB_OK=0 - else - echo "incorrect!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Please ensure that the directory '%{AMANDAHOMEDIR}' is owned by" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: the user '%{amanda_user}' and group '%{amanda_group}'." >>${TMPFILE} - VARLIB_OK=1 - fi -else - VARLIB_OK=0 -fi -echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - -if [ ! -e ${LOGDIR} ] ; then - # create log directory - mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1 - chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1 -elif [ ! -d ${LOGDIR} ] ; then - mv ${LOGDIR} ${LOGDIR}.rpmsave >>${TMPFILE} 2>&1 - mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1 - chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1 - mv ${LOGDIR}.rpmsave ${LOGDIR}/ >>${TMPFILE} 2>&1 -fi -if [ ${PASSWD_OK} -eq 1 ] || [ ${VARLIB_OK} -eq 1 ] ; then - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_ERR} - echo "Please review '${INSTALL_ERR}' to correct errors which have prevented the Amanda installaton." >&2 - echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'." - exit 1 -else - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi +# -------- End Common functions ---------- +logger "Preparing to install: Amanda Server %%VERSION%%" +create_user +check_user_group "${amanda_group}" || add_group "${amanda_group}" +check_user_supplemental_group "tape" || add_group "tape" +check_user_shell "${wanted_shell}" +check_user_homedir "${AMANDAHOMEDIR}" +check_homedir || create_homedir +create_logdir -echo "`date +'%b %e %Y %T'`: === Amanda backup server installation started. ===" >${TMPFILE} +logger "Preinstall done." +cat $LOGFILE > $INSTALL_LOG && rm $LOGFILE || \ + echo "Amanda preinstall logs can be found in '$LOGFILE'." -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} -if [ -f "${TMPFILE}" ]; then - rm -f "${TMPFILE}" -fi %post backup_server -TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX` +########################################## +LOGFILE=`mktemp /tmp/amanda_server-postinst.log.XXXXXXXXXXX` if [ $? -ne 0 ]; then - echo "Unable to mktemp!" 1>&2 + echo "Unable to create log file!" exit 1 fi -LOGDIR="%{LOGDIR}" -INSTALL_LOG="${LOGDIR}/install.log" -INSTALL_ERR="${LOGDIR}/install.err" +%{script_vars} +AMANDATES=%{AMANDATES} -echo -n "`date +'%b %e %Y %T'`: Updating system library cache..." >${TMPFILE} -/sbin/ldconfig -echo "done." >>${TMPFILE} -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -if [ -e /etc/xinetd.d ] && [ -d /etc/xinetd.d ] ; then - if [ ! -f /etc/xinetd.d/amandaserver ] ; then - cp %{AMANDAHOMEDIR}/example/xinetd.amandaserver /etc/xinetd.d/amandaserver - chmod 0644 /etc/xinetd.d/amandaserver >>${TMPFILE} 2>&1 - if [ -f /etc/xinetd.d/amandaclient ] ; then - rm /etc/xinetd.d/amandaclient - fi - - echo -n "`date +'%b %e %Y %T'`: Reloading xinetd configuration..." >${TMPFILE} - if [ "%{xinetd_reload}" == "reload" ] ; then - /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -ne 0 ] ; then - echo -n "reload failed. Attempting restart..." >>${TMPFILE} - /etc/init.d/xinetd restart >>${TMPFILE} 2>&1 - ret_val=$? - fi - else - /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1 - ret_val=$? - fi - if [ ${ret_val} -eq 0 ] ; then - echo "success." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} - else - echo "failed. Please check your system logs." >>${TMPFILE} - cat ${TMPFILE} 1>&2 - cat ${TMPFILE} >>${INSTALL_ERR} - fi - fi -fi +# ---------- Common functions ------------ +%%COMMON_FUNCTIONS%% +%%POST_INST_FUNCTIONS%% -echo "`date +'%b %e %Y %T'`: Installing '%{AMANDATES}'." >${TMPFILE} -ret_val=0 -if [ ! -f %{AMANDATES} ] ; then - touch %{AMANDATES} >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: The file '%{AMANDATES}' has been created." >>${TMPFILE} - fi -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDATES}'." >>${TMPFILE} - chown %{amanda_user}:%{amanda_group} %{AMANDATES} >>${TMPFILE} 2>&1 - chmod 0640 %{AMANDATES} >>${TMPFILE} 2>&1 -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation successful." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -else - echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation failed." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_ERR} -fi - -# Install .amandahosts to server -echo "`date +'%b %e %Y %T'`: Checking '%{AMANDAHOMEDIR}/.amandahosts' file." >${TMPFILE} -if [ ! -f %{AMANDAHOMEDIR}/.amandahosts ] ; then - touch %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1 -fi -for host in localhost localhost.localdomain ; do - if [ -z "`grep \"^${host}[[:blank:]]\+root[[:blank:]]\+amindexd[[:blank:]]\+amidxtaped\" %{AMANDAHOMEDIR}/.amandahosts`" ] ; then - echo "${host} root amindexd amidxtaped" >>%{AMANDAHOMEDIR}/.amandahosts - fi - if [ -z "`grep \"^${host}[[:blank:]]\+%{amanda_user}[[:blank:]]\+amdump\" %{AMANDAHOMEDIR}/.amandahosts`" ] ; then - echo "${host} %{amanda_user} amdump" >>%{AMANDAHOMEDIR}/.amandahosts - fi -done -chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1 -chmod 0600 %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# Install amanda client configuration file -echo "`date +'%b %e %Y %T'`: Checking '%{SYSCONFDIR}/amanda/amanda-client.conf' file." >${TMPFILE} -if [ ! -f %{SYSCONFDIR}/amanda/amanda-client.conf ] ; then - cp %{AMANDAHOMEDIR}/example/amanda-client.conf %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1 -fi -chown %{amanda_user}:%{amanda_group} %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1 -chmod 0600 %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# install am_passphrase file to server -echo "`date +'%b %e %Y %T'`: Checking '%{AMANDAHOMEDIR}/.am_passphrase' file." >${TMPFILE} -if [ ! -f %{AMANDAHOMEDIR}/.am_passphrase ] ; then - echo "`date +'%b %e %Y %T'`: Create '%{AMANDAHOMEDIR}/.am_passphrase' file." >${TMPFILE} - touch %{AMANDAHOMEDIR}/.am_passphrase >>${TMPFILE} 2>&1 - phrase=`echo $RANDOM | md5sum | awk '{print $1}'` - echo ${phrase} >>%{AMANDAHOMEDIR}/.am_passphrase - - chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.am_passphrase >>${TMPFILE} 2>&1 - chmod 0700 %{AMANDAHOMEDIR}/.am_passphrase >>${TMPFILE} 2>&1 -fi -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# Install .gnupg directory -echo "`date +'%b %e %Y %T'`: Installing '%{AMANDAHOMEDIR}/.gnupg'." >${TMPFILE} -ret_val=0 -if [ ! -d %{AMANDAHOMEDIR}/.gnupg ] ; then - echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' will be created." >>${TMPFILE} - mkdir %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' created successfully." >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' creation failed." >>${TMPFILE} - fi -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDAHOMEDIR}/.gnupg'." >>${TMPFILE} - chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -eq 0 ]; then - chmod 700 %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1 - ret_val=$? - fi -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation successful." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -else - echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation failed." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_ERR} -fi - -# SSH RSA key generation on server for amdump -KEYDIR="%{AMANDAHOMEDIR}/.ssh" -KEYFILE="id_rsa_amdump" -COMMENT="%{amanda_user}@server" -if [ ! -d ${KEYDIR} ] ; then - if [ -f ${KEYDIR} ] ; then - echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file. Renaming to '${KEYDIR}.rpmsave'." >${TMPFILE} - mv ${KEYDIR} ${KEYDIR}.rpmsave >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} - fi - echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." >${TMPFILE} - mkdir ${KEYDIR} >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi -if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then - echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" >${TMPFILE} - ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi -echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${KEYDIR}' and '${KEYDIR}/${KEYFILE}*'" >${TMPFILE} -chown %{amanda_user}:%{amanda_group} ${KEYDIR} ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1 -chmod 0750 ${KEYDIR} >>${TMPFILE} 2>&1 -chmod 0600 ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# SSH RSA key generation on client for amrecover -KEYDIR="%{AMANDAHOMEDIR}/.ssh" -KEYFILE="id_rsa_amrecover" -COMMENT="root@client" -if [ ! -d ${KEYDIR} ] ; then - if [ -f ${KEYDIR} ] ; then - echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file. Renaming to '${KEYDIR}.rpmsave'." >${TMPFILE} - mv ${KEYDIR} ${KEYDIR}.rpmsave >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} - fi - echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." >${TMPFILE} - mkdir ${KEYDIR} >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi -if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then - echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" >${TMPFILE} - ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi -echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${KEYDIR}'" >${TMPFILE} -chown %{amanda_user}:%{amanda_group} ${KEYDIR} >>${TMPFILE} 2>&1 -chmod 0750 ${KEYDIR} >>${TMPFILE} 2>&1 -chmod 0600 ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# environment variables (~amandabackup/.profile) -echo "`date +'%b %e %Y %T'`: Checking for '%{AMANDAHOMEDIR}/.profile' and ensuring correct environment." >${TMPFILE} -if [ ! -f %{AMANDAHOMEDIR}/.profile ] ; then - touch %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1 -fi -if [ -z "`grep PATH %{AMANDAHOMEDIR}/.profile | grep '%{SBINDIR}'`" ] ; then - echo "export PATH=\"\$PATH:%{SBINDIR}\"" >>%{AMANDAHOMEDIR}/.profile 2>>${TMPFILE} -fi -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '%{AMANDAHOMEDIR}/.profile'" >${TMPFILE} -chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1 -chmod 0640 %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -echo "`date +'%b %e %Y %T'`: Sending anonymous distribution and version information to Zmanda" >> ${INSTALL_LOG} -if [ -x /usr/bin/wget ]; then - /usr/bin/wget -q -o /dev/null -O - --timeout=5 http://www.zmanda.com/amanda-tips.php\?version=%{amanda_version}\&os=%{disttag}%{distver}\&type=server -fi - -echo "`date +'%b %e %Y %T'`: === Amanda backup server installation complete. ===" >${TMPFILE} +# -------- End Common functions ---------- +/sbin/ldconfig -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} +check_xinetd "amandaserver" +case $? in + 0) backup_xinetd "amandaserver" + install_xinetd "amandaserver" + ;; + 1) install_xinetd "amandaserver" ;; + 2) logger "Xinetd config not installed: either xinetd config is not present or xinetd.d is a file." ;; + *) logger "bad return from check_xinetd"; exit 1 ;; +esac + +# Amanda servers should not have the client xinetd installed. +check_xinetd "amandaclient" +case $? in + 0) backup_xinetd "amandaclient" ;; +esac + +reload_xinetd +create_amandates +check_amandates +create_gnupg +check_gnupg +create_amandahosts +check_amandahosts_entry root amindexd amidxtaped +check_amandahosts_entry ${amanda_user} amdump +check_amandahosts_perms +create_ssh_key server +create_ssh_key client +create_profile +check_profile +install_client_conf +create_ampassphrase + +logger "Amanda installation complete." +cat $LOGFILE >> $INSTALL_LOG && { + rm $LOGFILE; + echo "Amanda installation log can be found in '${INSTALL_LOG}'."; +} || \ + echo "Amanda postinstall logs can be found in '$LOGFILE'." -if [ -f "${TMPFILE}" ]; then - rm -f "${TMPFILE}" >>${TMPFILE} 2>&1 -fi - -echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'." %postun backup_server -/sbin/ldconfig -%pre backup_client -TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX` +########################################## +LOGFILE=`mktemp /tmp/amanda_server-remove.log.XXXXXXXXXXX` if [ $? -ne 0 ]; then - echo "Unable to mktemp!" 1>&2 + echo "Unable to create log file!" exit 1 fi -LOGDIR="%{LOGDIR}" -INSTALL_LOG="${LOGDIR}/install.log" -INSTALL_ERR="${LOGDIR}/install.err" - -echo "`date +'%b %e %Y %T'`: Preparing to install: %{amanda_version_info}" >${TMPFILE} - -# Check for the 'amanda' user -echo "`date +'%b %e %Y %T'`: Checking for '%{amanda_user}' user..." >>${TMPFILE} -if [ "`id -u %{amanda_user} > /dev/null 2>&1 && echo 0 || echo 1`" != "0" ] ; then - useradd -c "Amanda" -M -g %{amanda_group} -d %{AMANDAHOMEDIR} -s /bin/bash %{amanda_user} >>${TMPFILE} 2>&1 - if [ %{dist} = "SuSE" ]; then - PASSWD_EXIT=$? - else - # Lock the amanda account until admin sets password - passwd -l %{amanda_user} >>/dev/null - PASSWD_EXIT=$? - fi - if [ ${PASSWD_EXIT} -eq 0 ] ; then - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: The '%{amanda_user}; user account has been successfully created." >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Furthermore, the account has been automatically locked for you" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: for security purposes. Once a password for the '%{amanda_user}'" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: account has been set, the user can be unlocked by issuing" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: the following command as root.:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: # passwd -u %{amanda_user}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: If this is not a new installation of Amanda and you have" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: pre-existing Amanda configurations in %{SYSCONFDIR}/amanda" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: you should ensure that 'dumpuser' is set to '%{amanda_user}'" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: in those configurations. Additionally, you should ensure" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: that %{AMANDAHOMEDIR}/.amandahosts on your client systems" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: is properly configured to allow connections for the user" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: '%{amanda_user}'." >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - PASSWD_OK=0 - else - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! The '%{amanda_user}' user account for this system has been !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! created, however the user has no password set. For !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! security purposes this account is normally locked !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! after creation. Unfortunately, when locking this !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! account an error occurred. To ensure the security !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! of your system you should set a password for the !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user account '%{amanda_user}' immediately! To set such a !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! password, please issue the following command.: !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! # passwd %{amanda_user} !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - PASSWD_OK=1 - fi -else - # log information about 'amanda' user parameters - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: The Amanda backup software is configured to operate as the" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: user '%{amanda_user}'. This user exists on your system and has not" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: been modified. To ensure that Amanda functions properly," >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: please see that the following parameters are set for that" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: user.:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: SHELL: /bin/bash" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: HOME: %{AMANDAHOMEDIR}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Default group: %{amanda_group}" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Verifying %{amanda_user} parameters :" >>${TMPFILE} - - if [ "`id -gn %{amanda_user}`" != "disk" ] ; then - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user 'amandabackup' is not part of the disk group,Pl !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! make sure it is corrected before start using Amanda !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: Verified group name of user 'amandabackup'" >>${TMPFILE} - fi +%{script_vars} - if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f7`" != "/bin/bash" ] ; then - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user 'amandabackup' default shell should be set to !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! /bin/bash, pl correct before start using Amanda !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: Verified Default shell for user 'amandabackup'" >>${TMPFILE} - fi +# ---------- Common functions ------------ +%%COMMON_FUNCTIONS%% +%%POST_RM_FUNCTIONS%% - if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f6`" != "%{AMANDAHOMEDIR}" ] ; then - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! user 'amandabackup' home directory should be set to !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! %{AMANDAHOMEDIR} Pl correct before using Amanda !!!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: Verified Default home directory for user amandabackup" >>${TMPFILE} - fi - echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - PASSWD_OK=0 -fi -if [ -d %{AMANDAHOMEDIR} ] ; then - echo -n "`date +'%b %e %Y %T'`: Checking ownership of '%{AMANDAHOMEDIR}'... " >>${TMPFILE} - if [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[3]}'`" = "%{amanda_user}" ] && \ - [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[4]}'`" = "%{amanda_group}" ] ; then - echo "correct." >>${TMPFILE} - VARLIB_OK=0 - else - echo "incorrect!" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: Please ensure that the directory '%{AMANDAHOMEDIR}' is owned by" >>${TMPFILE} - echo "`date +'%b %e %Y %T'`: the user '%{amanda_user}' and group '%{amanda_group}'." >>${TMPFILE} - VARLIB_OK=1 - fi +# -------- End Common functions ---------- +/sbin/ldconfig +# Check for parameter to script (are we upgrading?) +if [ $1 -gt 0 ]; then + # We're upgrading + action="upgrade" else - VARLIB_OK=0 -fi -echo "`date +'%b %e %Y %T'`:" >>${TMPFILE} - -if [ ! -e ${LOGDIR} ] ; then - # create log directory - mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1 - chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1 -elif [ ! -d ${LOGDIR} ] ; then - mv ${LOGDIR} ${LOGDIR}.rpmsave >>${TMPFILE} 2>&1 - mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1 - chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1 - mv ${LOGDIR}.rpmsave ${LOGDIR}/ >>${TMPFILE} 2>&1 -fi -if [ ${PASSWD_OK} -eq 1 ] || [ ${VARLIB_OK} -eq 1 ] ; then - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_ERR} - echo "Please review '${INSTALL_ERR}' to correct errors which have prevented the Amanda installaton." >&2 - echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'." + # We're uninstalling + action="uninstall" +fi + +# See http://fedoraproject.org/wiki/Packaging/ScriptletSnippets for the reason +# we only remove xinetd on uninstall. +if [ "$action" = "uninstall" ]; then + # Check for and remove existing xinetd configs + check_xinetd "amandaserver" + if [ $? -eq 0 ] ; then + rm_xinetd "amandaserver" + reload_xinetd + fi + check_inetd "amandaserver" + if [ $? -eq 0 ] ; then + rm_inetd "amandaserver" + reload_inetd + fi + if [ -d ${SYSCONFDIR}/amanda ]; then + logger "Removing ${SYSCONFDIR}/amanda if empty..." + rmdir ${SYSCONFDIR}/amanda 2> /dev/null || true + fi + if [ -d ${AMANDAHOMEDIR} ]; then + logger "Removing ${AMANDAHOMEDIR}..." + rm -rf ${AMANDAHOMEDIR} + fi + if [ -f ${SYSCONFDIR}/amandates ]; then + logger "Removing ${SYSCONFDIR}/amandates..." + rm -rf ${SYSCONFDIR}/amandates + fi + # Remove ${amanda_user} from sensitive groups. + if which deluser >/dev/null 2>&1 ; then + for group in tape; do + # only call deluser when amandabackup is in $group + if getent group "$group" | + awk -F: '{ print $4 }' | + awk -F, '{ for (i=1; i <= NF; i++ ) print $i }' | + grep "^${amanda_user}$" > /dev/null; then + deluser ${amanda_user} $group || true + fi + done + fi + +fi + +echo "Amanda removal log can be found in '$LOGFILE'." + +%pre backup_client +########################################## +LOGFILE=`mktemp /tmp/amanda_client-preinst.log.XXXXXXXXXXX` +if [ $? -ne 0 ]; then + echo "Unable to create log file!" exit 1 -else - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} fi +%{script_vars} -echo "`date +'%b %e %Y %T'`: === Amanda backup client installation started. ===" >${TMPFILE} +# ---------- Common functions ------------ +%%COMMON_FUNCTIONS%% +%%PRE_INST_FUNCTIONS%% -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} +# -------- End Common functions ---------- +logger "Preparing to install: %{amanda_version_info}" +create_user +check_user_group "${amanda_group}" || add_group "${amanda_group}" +check_user_shell "${wanted_shell}" +check_user_homedir "${AMANDAHOMEDIR}" +check_homedir || create_homedir +create_logdir -if [ -f "${TMPFILE}" ]; then - rm -f "${TMPFILE}" -fi +logger "Preinstall done." +cat $LOGFILE >> $INSTALL_LOG && rm $LOGFILE || \ + echo "Amanda preinstall logs can be found in '$LOGFILE'." %post backup_client -TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX` +########################################## +LOGFILE=`mktemp /tmp/amanda_client-postinst.log.XXXXXXXXXXX` if [ $? -ne 0 ]; then - echo "Unable to mktemp!" 1>&2 + echo "Unable to create log file!" exit 1 fi -LOGDIR="%{LOGDIR}" -INSTALL_LOG="${LOGDIR}/install.log" -INSTALL_ERR="${LOGDIR}/install.err" +%{script_vars} +AMANDATES=%{AMANDATES} -echo -n "`date +'%b %e %Y %T'`: Updating system library cache..." >${TMPFILE} -/sbin/ldconfig -echo "done." >>${TMPFILE} -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -if [ -e /etc/xinetd.d ] && [ -d /etc/xinetd.d ] ; then - if [ ! -f /etc/xinetd.d/amandaclient ] ; then - cp %{AMANDAHOMEDIR}/example/xinetd.amandaclient /etc/xinetd.d/amandaclient - - echo -n "`date +'%b %e %Y %T'`: Reloading xinetd configuration..." >${TMPFILE} - if [ "%{xinetd_reload}" == "reload" ] ; then - /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -ne 0 ] ; then - echo -n "reload failed. Attempting restart..." >>${TMPFILE} - /etc/init.d/xinetd restart >>${TMPFILE} 2>&1 - ret_val=$? - fi - else - /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1 - ret_val=$? - fi - if [ ${ret_val} -eq 0 ] ; then - echo "success." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} - else - echo "failed. Please check your system logs." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} - fi - fi -fi - -echo "`date +'%b %e %Y %T'`: Installing '%{AMANDATES}'." >${TMPFILE} -ret_val=0 -if [ ! -f %{AMANDATES} ] ; then - touch %{AMANDATES} >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: The file '%{AMANDATES}' has been created." >>${TMPFILE} - fi -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDATES}'." >>${TMPFILE} - chown %{amanda_user}:%{amanda_group} %{AMANDATES} >>${TMPFILE} 2>&1 - chmod 0640 %{AMANDATES} >>${TMPFILE} 2>&1 -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation successful." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -else - echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation failed." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_ERR} -fi +# ---------- Common functions ------------ +%%COMMON_FUNCTIONS%% +%%POST_INST_FUNCTIONS%% -# Install .amandahosts to client -echo "`date +'%b %e %Y %T'`: Checking '%{AMANDAHOMEDIR}/.amandahosts' file." >${TMPFILE} -if [ ! -f %{AMANDAHOMEDIR}/.amandahosts ] ; then - touch %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1 -fi -for host in localhost localhost.localdomain ; do - if [ -z "`grep \"^${host}[[:blank:]]\+\" %{AMANDAHOMEDIR}/.amandahosts | grep \"[[:blank:]]\+%{amanda_user}[[:blank:]]\+amdump\"`" ] ; then - echo "${host} %{amanda_user} amdump" >>%{AMANDAHOMEDIR}/.amandahosts - fi -done -chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1 -chmod 0600 %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# Install amanda client configuration file -echo "`date +'%b %e %Y %T'`: Checking '%{SYSCONFDIR}/amanda/amanda-client.conf' file." >${TMPFILE} -if [ ! -f %{SYSCONFDIR}/amanda/amanda-client.conf ] ; then - cp %{AMANDAHOMEDIR}/example/amanda-client.conf %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1 -fi -chown %{amanda_user}:%{amanda_group} %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1 -chmod 0600 %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# Install .gnupg directory -echo "`date +'%b %e %Y %T'`: Installing '%{AMANDAHOMEDIR}/.gnupg'." >${TMPFILE} -ret_val=0 -if [ ! -d %{AMANDAHOMEDIR}/.gnupg ] ; then - echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' will be created." >>${TMPFILE} - mkdir %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' created successfully." >>${TMPFILE} - else - echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' creation failed." >>${TMPFILE} - fi -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDAHOMEDIR}/.gnupg'." >>${TMPFILE} - chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1 - ret_val=$? - if [ ${ret_val} -eq 0 ]; then - chmod 700 %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1 - ret_val=$? - fi -fi -if [ ${ret_val} -eq 0 ]; then - echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation successful." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -else - echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation failed." >>${TMPFILE} - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_ERR} -fi +# -------- End Common functions ---------- +/sbin/ldconfig -# SSH RSA key generation on client for amrecover -KEYDIR="%{AMANDAHOMEDIR}/.ssh" -KEYFILE="id_rsa_amrecover" -COMMENT="root@client" -if [ ! -d ${KEYDIR} ] ; then - if [ -f ${KEYDIR} ] ; then - echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file. Renaming to '${KEYDIR}.rpmsave'." >${TMPFILE} - mv ${KEYDIR} ${KEYDIR}.rpmsave >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} - fi - echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." >${TMPFILE} - mkdir ${KEYDIR} >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi -if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then - echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" >${TMPFILE} - ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' >>${TMPFILE} 2>&1 - cat ${TMPFILE} - cat ${TMPFILE} >>${INSTALL_LOG} -fi -echo "`date +'%b %e %Y %T'`: Setting permissions for '${KEYDIR}' and '${KEYDIR}/${KEYFILE}*'" >${TMPFILE} -chown %{amanda_user}:%{amanda_group} ${KEYDIR} >>${TMPFILE} 2>&1 -chmod 0750 ${KEYDIR} >>${TMPFILE} 2>&1 -chmod 0600 ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -# environment variables (~amandabackup/.profile) -echo "`date +'%b %e %Y %T'`: Checking for '%{AMANDAHOMEDIR}/.profile' and ensuring correct environment." >${TMPFILE} -if [ ! -f %{AMANDAHOMEDIR}/.profile ] ; then - touch %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1 -fi -if [ -z "`grep PATH %{AMANDAHOMEDIR}/.profile | grep '%{SBINDIR}'`" ] ; then - echo "export PATH=\"\$PATH:%{SBINDIR}\"" >>%{AMANDAHOMEDIR}/.profile 2>>${TMPFILE} -fi -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} -echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '%{AMANDAHOMEDIR}/.profile'" >${TMPFILE} -chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1 -chmod 0640 %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1 -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} +check_xinetd "amandaclient" +case $? in + 0) backup_xinetd "amandaclient" + install_xinetd "amandaclient" + ;; + 1) install_xinetd "amandaclient" ;; + 2) logger "Xinetd config not installed: either xinetd config is not present or xinetd.d is a file." ;; + *) logger "bad return from check_xinetd"; exit 1 ;; +esac + +# Amanda clients should not have the server xinetd installed. +check_xinetd "amandaserver" +case $? in + 0) backup_xinetd "amandaserver" ;; +esac + +reload_xinetd +create_amandates +check_amandates +create_gnupg +check_gnupg +create_amandahosts +check_amandahosts_entry ${amanda_user} amdump +check_amandahosts_perms +create_ssh_key server +create_ssh_key client +create_profile +check_profile +install_client_conf + +logger "Amanda installation complete." +cat $LOGFILE >> $INSTALL_LOG && { + rm $LOGFILE; + echo "Amanda installation log can be found in '${INSTALL_LOG}'."; +} || \ + echo "Amanda postinstall logs can be found in '$LOGFILE'." echo "`date +'%b %e %Y %T'`: Sending anonymous distribution and version information to Zmanda" >> ${INSTALL_LOG} if [ -x /usr/bin/wget ]; then /usr/bin/wget -q -o /dev/null -O - --timeout=5 http://www.zmanda.com/amanda-tips.php\?version=%{amanda_version}\&os=%{disttag}%{distver}\&type=client fi -echo "`date +'%b %e %Y %T'`: === Amanda backup client installation complete. ===" >>${TMPFILE} -cat ${TMPFILE} -cat ${TMPFILE} >>${INSTALL_LOG} - -if [ -f "${TMPFILE}" ]; then - rm -f "${TMPFILE}" +%postun backup_client +########################################## +LOGFILE=`mktemp /tmp/amanda_client-remove.log.XXXXXXXXXXX` +if [ $? -ne 0 ]; then + echo "Unable to create log file!" + exit 1 fi +%{script_vars} -echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'." -%postun backup_client +# ---------- Common functions ------------ +%%COMMON_FUNCTIONS%% +%%POST_RM_FUNCTIONS%% + +# -------- End Common functions ---------- /sbin/ldconfig +# Check for parameter to script (are we upgrading?) +if [ $1 -gt 0 ]; then + # We're upgrading + action="upgrade" +else + # We're uninstalling + action="uninstall" +fi + +# See http://fedoraproject.org/wiki/Packaging/ScriptletSnippets for the reason +# we only remove xinetd on uninstall. +if [ "$action" = "uninstall" ]; then + # Check for and remove existing xinetd configs + check_xinetd "amandaclient" + if [ $? -eq 0 ] ; then + rm_xinetd "amandaclient" + reload_xinetd + fi + check_inetd "amandaclient" + if [ $? -eq 0 ] ; then + rm_inetd "amandaclient" + reload_inetd + fi + if [ -d ${SYSCONFDIR}/amanda ]; then + logger "Removing ${SYSCONFDIR}/amanda if empty..." + rmdir ${SYSCONFDIR}/amanda 2> /dev/null || true + fi + if [ -d ${AMANDAHOMEDIR} ]; then + logger "Removing ${AMANDAHOMEDIR}..." + rm -rf ${AMANDAHOMEDIR} + fi + if [ -f ${SYSCONFDIR}/amandates ]; then + logger "Removing ${SYSCONFDIR}/amandates..." + rm -rf ${SYSCONFDIR}/amandates + fi + # Remove ${amanda_user} from sensitive groups. + if which deluser >/dev/null 2>&1 ; then + for group in tape; do + # only call deluser when amandabackup is in $group + if getent group "$group" | + awk -F: '{ print $4 }' | + awk -F, '{ for (i=1; i <= NF; i++ ) print $i }' | + grep "^${amanda_user}$" > /dev/null; then + deluser ${amanda_user} $group || true + fi + done + fi +fi + +echo "Amanda removal log can be found in '$LOGFILE'." + +%files backup_client # --- Files to install --- # Notes: Do not use wildcards on directories not wholly owned by amanda. An # uninstall of the software will attempt to delete whatever matches here. -%files backup_client %defattr(0755,%{amanda_user},%{amanda_group},0755) %{AMLIBEXECDIR} %{AMLIBDIR} diff --git a/packaging/rpm/buildpkg b/packaging/rpm/buildpkg index ef6974c..eaaa0d5 100755 --- a/packaging/rpm/buildpkg +++ b/packaging/rpm/buildpkg @@ -30,9 +30,12 @@ fi # Until we get package revisioning in community. [ -f "PKG_REV" ] || echo "1" > PKG_REV +[ -f "./configure" ] || \ + { echo "./configure does not exist, please run ./autogen"; exit 1; } + # Substitute amanda.spec.src /usr/bin/perl packaging/common/substitute.pl \ - packaging/rpm/amanda.spec.src packaging/rpm/amanda.spec + packaging/rpm/amanda.spec.src packaging/rpm/amanda.spec || exit 1 PKG_TARBALL=${AMVER}.tar.gz if [ ! -f "${PKG_TARBALL}" ]; then diff --git a/packaging/sun-pkg/buildpkg b/packaging/sun-pkg/buildpkg index af5d0a3..32ad7b2 100755 --- a/packaging/sun-pkg/buildpkg +++ b/packaging/sun-pkg/buildpkg @@ -2,6 +2,12 @@ # This is useful for debugging #set -x +if [ "$1" = "-v" ]; then + silent_make_flags="" + shift +else + silent_make_flags="-s LIBTOOLFLAGS=--silent" +fi #### CHECKS if [ ! -f common-src/amanda.h ]; then echo "Error: 'buildpkg' must be run from the root of an otherwise unused amanda source" @@ -52,7 +58,7 @@ do_build() { { echo "client or server not given" && exit 1; } rm -rf ${INSTALL_DEST} ${PKG_DEST} mkdir ${INSTALL_DEST} ${PKG_DEST} || exit 1 - make distclean + make ${silent_make_flags} distclean echo "Running configure.." CONF="$CONF \ STAR=/opt/csw/bin/star \ @@ -99,7 +105,7 @@ do_build() { GLIB_MKENUMS=glib-mkenums \ ${CONF} || exit 1 - echo "Building.." + echo "Building $1.." # rpcgen should be run natively on solaris, linux generated XDR stubs # are not compatible. Specially when being compiled in 64 bit mode. @@ -107,8 +113,8 @@ do_build() { (cd ndmp-src;rpcgen ndmp0.x;rpcgen ndmp2.x;rpcgen ndmp3.x;rpcgen ndmp4.x; rpcgen ndmp9.x) - make || exit 1 - make DESTDIR=${INSTALL_DEST} install || exit 1 + make ${silent_make_flags}|| exit 1 + make ${silent_make_flags} DESTDIR=${INSTALL_DEST} install || exit 1 # the gnulib makefiles create $amlibdir/charset.alias in hopes of "merging" # it with a similar file from other applications. This doesn't work with @@ -136,7 +142,7 @@ do_package() { cp ${src_dir}/${pkg_root}/${subpkg}/* ${PKG_DEST} || exit 1 cd ${INSTALL_DEST} || exit 1 - # amanda does not create /etc/amanda + # amanda does not create /etc/amanda mkdir -p ${AMSTATEDIR} || exit 1 mkdir -p ${ETCDIR}/amanda || exit 1 @@ -147,7 +153,7 @@ do_package() { # permissions and ownership per pkg settings if included. cat "${PKG_DEST}/pkgproto" \ >> ${PKG_DEST}/prototype || exit 1 - pkgproto $PREFIX >> ${PKG_DEST}/prototype || exit 1 + pkgproto $PREFIX ${AMSTATEDIR} ${ETCDIR}/amanda >> ${PKG_DEST}/prototype || exit 1 # Using --disable-installperms creates installperms.sh, which this bit of # perl will merge into the prototype. Note that this perl script is @@ -210,12 +216,11 @@ PKG_DEST=${PKG_TMP}/pkg; export PKG_DEST # Explanation of solaris paths: # /opt/SUNWspro/*: Sun compiler, NOT USED FOR PACKAGING. -# /opt/csw/*: blastwave. +# /opt/csw/*: OpenCSW. # /usr/ccs/*: sun compilation tools (ld, lex, yacc) # /usr/sfw/*: SunFreeware, sometimes. (solaris 10) # /usr/local/*: SunFreeware, othertimes. (solaris 8) -# Not Absolute! Remember to prefix a "/" except in pkgproto. # sparc or intel arch=`uname -p` # 5.8 or 5.10 @@ -228,14 +233,15 @@ PATH=/opt/csw/bin:/usr/bin:/usr/sbin:/usr/ccs/bin;export PATH # Compile 32bit because csw perl is 32bit and native is too old. CFLAGS="-O2 -pipe -m32"; export CFLAGS CPPFLAGS="-I/opt/csw/include"; export CPPFLAGS -PREFIX=opt/amanda; export PREFIX # Not absolute. Pkgprot needs this. +# Not Absolute! Remember to prefix a "/" except in pkgproto. +PREFIX=opt/amanda; export PREFIX # Not absolute. amlibdir=${PREFIX}/lib # Not absolute LOCALSTATEDIR=var; export LOCALSTATEDIR AMSTATEDIR=${LOCALSTATEDIR}/lib/amanda; export AMSTATEDIR ETCDIR=etc; export ETCDIR DBGDIR=${LOCALSTATEDIR}/log; export DBGDIR # Each client and server and platform combination gets different compile options -if [ "x${1}" = "xclient" -o "x${1}" = "x" ]; then +if [ "x${1}" = "xclient" ] || [ "x${1}" = "x" ]; then CC=/usr/sfw/bin/gcc # Variables with spaces must be entered on the configure line separate from # CONF to maintain quoting. @@ -250,6 +256,7 @@ if [ "x${1}" = "xclient" -o "x${1}" = "x" ]; then GLIB_LIBS="-lglib-2.0 -lgobject-2.0 -lgthread-2.0"; export GLIB_LIBS elif [ "x$arch" = "xi386" -a "x$os_rel" = "x5.10" ]; then GLIB_CFLAGS="-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include"; export GLIB_CFLAGS + GLIB_LIBS="-lglib-2.0 -lgobject-2.0 -lgthread-2.0"; export GLIB_LIBS elif [ "x$arch" = "xsparc" -a "x$os_rel" = "x5.8" ]; then # CSW glib2.0 flags for gcc. CSW compiles with Sunstudio, so some # flags may not work @@ -267,7 +274,7 @@ if [ "x${1}" = "xclient" -o "x${1}" = "x" ]; then do_package "client" fi -if [ "x${1}" = "xserver" -o "x${1}" = "x" ]; then +if [ "x${1}" = "xserver" ] || [ "x${1}" = "x" ]; then LDFLAGS="-L/usr/lib -R/usr/lib \ -L/opt/csw/lib -R/opt/csw/lib \ -L/usr/sfw/lib \ @@ -294,6 +301,7 @@ if [ "x${1}" = "xserver" -o "x${1}" = "x" ]; then fi CONF="--with-amlibdir=/${amlibdir} \ --enable-s3-device \ + --with-libcurl=/opt/csw \ CC=/usr/sfw/bin/gcc \ PERL=/opt/csw/bin/perl \ MTX=/opt/csw/sbin/mtx" ; export CONF diff --git a/packaging/sun-pkg/client/postinstall.src b/packaging/sun-pkg/client/postinstall.src index 5cb9cc9..e6ef6eb 100755 --- a/packaging/sun-pkg/client/postinstall.src +++ b/packaging/sun-pkg/client/postinstall.src @@ -1,19 +1,22 @@ #!/bin/sh -LOGFILE=`mktemp /tmp/deb-log-amanda_enterprise-client.XXXXXXXXXXX` +LOGFILE=`mktemp /tmp/amanda-client-postinstall.log.XXXXXXXXXXX` if [ $? -ne 0 ]; then echo "Unable to mktemp!" 1>&2 exit 1 fi amanda_user=amandabackup; export amanda_user amanda_group=disk; export amanda_group -AMANDAHOMEDIR="${BASEDIR}/%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR +# BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime. +# Unfortunately, it messes things up to have basedir="/". +[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR} +AMANDAHOMEDIR="${basedir}%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR os=SunOS; export os arch=%%ARCH%%; export arch -LOGDIR="${BASEDIR}/%%LOGDIR%%"; export LOGDIR +LOGDIR="${basedir}%%LOGDIR%%"; export LOGDIR INSTALL_LOG="${LOGDIR}/install.log"; export INSTALL_LOG -SYSCONFDIR="${BASEDIR}/etc"; export SYSCONFDIR -SBINDIR="${BASEDIR}/usr/sbin"; export SBINDIR +SYSCONFDIR="${basedir}/etc"; export SYSCONFDIR +SBINDIR="${basedir}/usr/sbin"; export SBINDIR AMTMP="/tmp/amanda" AMANDATES=${SYSCONFDIR}/amandates; export AMANDATES @@ -46,7 +49,8 @@ if [ "$rel" = "5.8" ]; then else # Solaris 10+ uses smf, but we can't differentiate server from client, all # entries end up named "amanda" - case check_smf "amanda" + check_smf "amanda" + case $? in 0) backup_smf || logger "Warning: Backup of existing service failed. continuing..." install_smf "amandaclient" || \ logger "Warning: Amanda service not installed." diff --git a/packaging/sun-pkg/client/postremove.src b/packaging/sun-pkg/client/postremove.src index 287d939..c4479ec 100755 --- a/packaging/sun-pkg/client/postremove.src +++ b/packaging/sun-pkg/client/postremove.src @@ -7,13 +7,15 @@ if [ $? -ne 0 ]; then fi amanda_user=amandabackup amanda_group=disk -AMANDAHOMEDIR=%%AMANDAHOMEDIR%% +# BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime. +# Unfortunately, it messes things up to have basedir="/". +[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR} +AMANDAHOMEDIR=${basedir}%%AMANDAHOMEDIR%% os=SunOS dist=%%DISTRO%% -LOGDIR=%%LOGDIR%% -REMOVE_LOG="/tmp/amanda-remove.log" -SYSCONFDIR=/etc +LOGDIR=${basedir}%%LOGDIR%% +SYSCONFDIR=${basedir}/etc # ---------- Common functions ------------ # see packaging/common/ in the source tree @@ -28,7 +30,7 @@ case $rel in 5.8|5.9) if check_inetd "amanda"; then rm_inetd "amanda" || { \ - logger "Warning: Did not successfully remove $net_svc_name from SMF."; + logger "Warning: Did not successfully remove amanda from SMF."; exit 1; } reload_inetd fi @@ -36,13 +38,10 @@ case $rel in 5.10) if check_smf "amanda"; then rm_smf "amanda" || { \ - logger "Warning: Did not successfully remove $net_svc_name from SMF."; + logger "Warning: Did not successfully remove amanda from SMF."; exit 1; } fi ;; esac logger "Amanda Client removed." - -cat $LOGFILE >> $REMOVE_LOG -rm $LOGFILE diff --git a/packaging/sun-pkg/client/preinstall.src b/packaging/sun-pkg/client/preinstall.src index 28228b0..035cb9f 100755 --- a/packaging/sun-pkg/client/preinstall.src +++ b/packaging/sun-pkg/client/preinstall.src @@ -11,11 +11,14 @@ export LOGFILE amanda_user=amandabackup; export amanda_user amanda_group=disk; export amanda_group # BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime. -AMANDAHOMEDIR="${BASEDIR}/%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR +# Unfortunately, it messes things up to have basedir="/". +[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR} +AMANDAHOMEDIR="${basedir}%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR os=`uname`; export os -dist=%%DISTRO%%; export dist -LOGDIR="/var/log/amanda"; export LOGDIR -SYSCONFDIR=/etc; export SYSCONFDIR +wanted_shell=/usr/bin/bash; export wanted_shell +LOGDIR="${basedir}%%LOGDIR%%"; export LOGDIR +INSTALL_LOG=${LOGDIR}/install.log; export INSTALL_LOG +SYSCONFDIR="${basedir}/etc"; export SYSCONFDIR # See packaging/common/ for shell function libraries. # ---------- Common functions ------------ @@ -25,17 +28,13 @@ SYSCONFDIR=/etc; export SYSCONFDIR # -------- End Common functions ---------- logger "Preparing to install: Amanda Client %%VERSION%%" create_user -if ! check_user "group" "${amanda_group}" ; then - add_group "${amanda_group}" -fi -if ! check_user "group" "tape" ; then - add_group "tape" -fi -check_user "shell" "/usr/bin/bash" -check_user "homedir" "${AMANDAHOMEDIR}" -if ! check_homedir ; then - create_homedir -fi +check_user_group "${amanda_group}" || add_group "${amanda_group}" +check_user_shell "${wanted_shell}" +check_user_homedir "${AMANDAHOMEDIR}" +check_homedir || create_homedir create_logdir logger "Preinstall done." + +cat $LOGFILE > $INSTALL_LOG && rm $LOGFILE || \ + echo "Amanda preinstall logs can be found in '$LOGFILE'." diff --git a/packaging/sun-pkg/server/postinstall.src b/packaging/sun-pkg/server/postinstall.src index c4ab56e..5860799 100755 --- a/packaging/sun-pkg/server/postinstall.src +++ b/packaging/sun-pkg/server/postinstall.src @@ -1,25 +1,26 @@ #!/bin/sh -LOGFILE=`mktemp /tmp/deb-log-amanda_enterprise-client.XXXXXXXXXXX` +LOGFILE=`mktemp /tmp/amanda-server-postinstall.log.XXXXXXXXXXX` if [ $? -ne 0 ]; then echo "Unable to mktemp!" 1>&2 exit 1 fi amanda_user=amandabackup; export amanda_user amanda_group=disk; export amanda_group -AMANDAHOMEDIR="${BASEDIR}/%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR +# BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime. +# Unfortunately, it messes things up to have basedir="/". +[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR} +AMANDAHOMEDIR="${basedir}%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR os=SunOS; export os arch=%%ARCH%%; export arch -LOGDIR="${BASEDIR}/%%LOGDIR%%"; export LOGDIR +LOGDIR="${basedir}%%LOGDIR%%"; export LOGDIR INSTALL_LOG="${LOGDIR}/install.log"; export INSTALL_LOG -SYSCONFDIR="${BASEDIR}/etc"; export SYSCONFDIR -SBINDIR="${BASEDIR}/usr/sbin"; export SBINDIR +SYSCONFDIR="${basedir}/etc"; export SYSCONFDIR +SBINDIR="${basedir}/usr/sbin"; export SBINDIR AMTMP="/tmp/amanda" AMANDATES=${SYSCONFDIR}/amandates; export AMANDATES -exit_msg="Amanda installation log can be found in '${INSTALL_LOG}'." - # ---------- Common functions ------------ %%COMMON_FUNCTIONS%% %%POST_INST_FUNCTIONS%% @@ -46,7 +47,8 @@ if [ "$rel" = "5.8" ]; then else # Solaris 10+ uses smf, but we can't differentiate server from client, all # entries end up named "amanda" - case check_smf "amanda" + check_smf "amanda" + case $? in 0) backup_smf || logger "Warning: Backup of existing service failed. continuing..." install_smf "amandaserver" || \ logger "Warning: Amanda service not installed." @@ -69,7 +71,8 @@ install_client_conf create_amtmp logger "Amanda installation complete." -cat $LOGFILE >> $INSTALL_LOG -rm $LOGFILE - -echo "${exit_msg}" +cat $LOGFILE >> $INSTALL_LOG && { + rm $LOGFILE + echo "Amanda installation log can be found in '${INSTALL_LOG}'." +} || \ + echo "Amanda postinstall log can be found in $LOGFILE" diff --git a/packaging/sun-pkg/server/postremove.src b/packaging/sun-pkg/server/postremove.src index e0184ac..e307ee8 100755 --- a/packaging/sun-pkg/server/postremove.src +++ b/packaging/sun-pkg/server/postremove.src @@ -7,13 +7,15 @@ if [ $? -ne 0 ]; then fi amanda_user=amandabackup amanda_group=disk -AMANDAHOMEDIR=%%AMANDAHOMEDIR%% +# BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime. +# Unfortunately, it messes things up to have basedir="/". +[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR} +AMANDAHOMEDIR=${basedir}%%AMANDAHOMEDIR%% os=SunOS dist=%%DISTRO%% -LOGDIR=%%LOGDIR%% -REMOVE_LOG="/tmp/amanda-remove.log" -SYSCONFDIR=/etc +LOGDIR=${basedir}%%LOGDIR%% +SYSCONFDIR=${basedir}/etc # ---------- Common functions ------------ # see packaging/common/ in the source tree @@ -28,7 +30,7 @@ case $rel in 5.8|5.9) if check_inetd "amanda"; then rm_inetd "amanda" || { \ - logger "Warning: Did not successfully remove $net_svc_name from SMF."; + logger "Warning: Did not successfully remove amanda from SMF."; exit 1; } reload_inetd fi @@ -36,13 +38,10 @@ case $rel in 5.10) if check_smf "amanda"; then rm_smf "amanda" || { \ - logger "Warning: Did not successfully remove $net_svc_name from SMF."; + logger "Warning: Did not successfully remove amanda from SMF."; exit 1; } fi ;; esac logger "Amanda Server removed." - -cat $LOGFILE >> $REMOVE_LOG -rm $LOGFILE diff --git a/packaging/sun-pkg/server/preinstall.src b/packaging/sun-pkg/server/preinstall.src index b986e4e..4451b9d 100755 --- a/packaging/sun-pkg/server/preinstall.src +++ b/packaging/sun-pkg/server/preinstall.src @@ -11,11 +11,14 @@ export LOGFILE amanda_user=amandabackup; export amanda_user amanda_group=disk; export amanda_group # BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime. -AMANDAHOMEDIR="${BASEDIR}/%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR +# Unfortunately, it messes things up to have basedir="/". +[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR} +AMANDAHOMEDIR="${basedir}%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR os=`uname`; export os -dist=%%DISTRO%%; export dist -LOGDIR="${BASEDIR}/%%LOGDIR%%"; export LOGDIR -SYSCONFDIR="${BASEDIR}/%%SYSCONFDIR%%"; export SYSCONFDIR +wanted_shell=/usr/bin/bash; export wanted_shell +LOGDIR="${basedir}%%LOGDIR%%"; export LOGDIR +INSTALL_LOG=${LOGDIR}/install.log; export INSTALL_LOG +SYSCONFDIR="${basedir}/etc"; export SYSCONFDIR # See packaging/common/ for shell function libraries. # ---------- Common functions ------------ @@ -25,17 +28,14 @@ SYSCONFDIR="${BASEDIR}/%%SYSCONFDIR%%"; export SYSCONFDIR # -------- End Common functions ---------- logger "Preparing to install: Amanda Server %%VERSION%%" create_user -if ! check_user "group" "${amanda_group}" ; then - add_group "${amanda_group}" -fi -if ! check_user "group" "tape" ; then - add_group "tape" -fi -check_user "shell" "/usr/bin/bash" -check_user "homedir" "${AMANDAHOMEDIR}" -if ! check_homedir ; then - create_homedir -fi +check_user_group "${amanda_group}" || add_group "${amanda_group}" +check_user_supplemental_group "tape" || add_group "tape" +check_user_shell "${wanted_shell}" +check_user_homedir "${AMANDAHOMEDIR}" +check_homedir || create_homedir create_logdir logger "Preinstall done." + +cat $LOGFILE > $INSTALL_LOG && rm $LOGFILE || \ + echo "Amanda preinstall logs can be found in '$LOGFILE'." diff --git a/perl/Amanda/Application.pm b/perl/Amanda/Application.pm index a0b22be..e2dc296 100644 --- a/perl/Amanda/Application.pm +++ b/perl/Amanda/Application.pm @@ -114,6 +114,7 @@ require Amanda::Script_App; use strict; use warnings; +use IO::Handle; use Amanda::Config qw( :init :getconf config_dir_relative ); @@ -173,9 +174,10 @@ sub read_magic_block { sub _set_mesgout { my $self = shift; - my $mesgout_fd; - open ($mesgout_fd, '>&=3') || die("Can't open mesgout_fd: $!"); - $self->{mesgout} = $mesgout_fd; + my $mesgout = IO::Handle->new(); + $mesgout->fdopen(3,"a") || die("Can't open mesgout_fd: $!"); + $mesgout->autoflush(1); + $self->{mesgout} = $mesgout; } 1; diff --git a/perl/Amanda/Application.pod b/perl/Amanda/Application.pod index 57c3045..5af1d3c 100644 --- a/perl/Amanda/Application.pod +++ b/perl/Amanda/Application.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Application.swg b/perl/Amanda/Application.swg index c58cfd0..a73a77d 100644 --- a/perl/Amanda/Application.swg +++ b/perl/Amanda/Application.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -31,6 +31,7 @@ require Amanda::Script_App; use strict; use warnings; +use IO::Handle; use Amanda::Config qw( :init :getconf config_dir_relative ); @@ -90,9 +91,10 @@ sub read_magic_block { sub _set_mesgout { my $self = shift; - my $mesgout_fd; - open ($mesgout_fd, '>&=3') || die("Can't open mesgout_fd: $!"); - $self->{mesgout} = $mesgout_fd; + my $mesgout = IO::Handle->new(); + $mesgout->fdopen(3,"a") || die("Can't open mesgout_fd: $!"); + $mesgout->autoflush(1); + $self->{mesgout} = $mesgout; } %} diff --git a/perl/Amanda/Application/Zfs.pm b/perl/Amanda/Application/Zfs.pm index 6fd92b2..26bd6bf 100644 --- a/perl/Amanda/Application/Zfs.pm +++ b/perl/Amanda/Application/Zfs.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Archive.pod b/perl/Amanda/Archive.pod index 728b1c8..e7b2b26 100644 --- a/perl/Amanda/Archive.pod +++ b/perl/Amanda/Archive.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Archive.swg b/perl/Amanda/Archive.swg index dc8057c..a3fd2e0 100644 --- a/perl/Amanda/Archive.swg +++ b/perl/Amanda/Archive.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/BigIntCompat.pm b/perl/Amanda/BigIntCompat.pm index ae4d77f..18e6b88 100644 --- a/perl/Amanda/BigIntCompat.pm +++ b/perl/Amanda/BigIntCompat.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Changer.pm b/perl/Amanda/Changer.pm index ddb7f66..419c1a0 100644 --- a/perl/Amanda/Changer.pm +++ b/perl/Amanda/Changer.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2007,2008,2009,2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -1253,15 +1253,19 @@ sub make_new_tape_label { my $tl = $self->{'tapelist'}; die ("make_new_tape_label: no tapelist") if !$tl; - return undef if !defined $self->{'autolabel'}->{'template'}; - return undef if !defined $self->{'labelstr'}; + if (!defined $self->{'autolabel'}) { + return (undef, "autolabel not set"); + } + if (!defined $self->{'autolabel'}->{'template'}) { + return (undef, "template is not set, you must set autolabel"); + } + if (!defined $self->{'labelstr'}) { + return (undef, "labelstr not set"); + } my $template = $self->{'autolabel'}->{'template'}; my $labelstr = $self->{'labelstr'}; my $slot_digit = 1; - if (!$template) { - return (undef, "template is not set, you must set autolabel"); - } $template =~ s/\$\$/SUBSTITUTE_DOLLAR/g; $template =~ s/\$b/SUBSTITUTE_BARCODE/g; $template =~ s/\$m/SUBSTITUTE_META/g; diff --git a/perl/Amanda/Changer/aggregate.pm b/perl/Amanda/Changer/aggregate.pm index a7c333d..4f59be3 100644 --- a/perl/Amanda/Changer/aggregate.pm +++ b/perl/Amanda/Changer/aggregate.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009,2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -20,6 +20,7 @@ package Amanda::Changer::aggregate; use strict; use warnings; +use Carp; use vars qw( @ISA ); @ISA = qw( Amanda::Changer ); @@ -655,7 +656,7 @@ sub _for_each_child { ($params{'oksub'}, $params{'errsub'}, $params{'parent_cb'}, $params{'args'}); if (defined($args)) { - die "number of args did not match number of children" + confess "number of args did not match number of children" unless (@$args == $self->{'num_children'}); } else { $args = [ ( undef ) x $self->{'num_children'} ]; diff --git a/perl/Amanda/Changer/compat.pm b/perl/Amanda/Changer/compat.pm index fccc226..4f57d5c 100644 --- a/perl/Amanda/Changer/compat.pm +++ b/perl/Amanda/Changer/compat.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Changer/disk.pm b/perl/Amanda/Changer/disk.pm index 8172791..8c18e65 100644 --- a/perl/Amanda/Changer/disk.pm +++ b/perl/Amanda/Changer/disk.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2008,2009,2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -20,6 +20,7 @@ package Amanda::Changer::disk; use strict; use warnings; +use Carp; use vars qw( @ISA ); @ISA = qw( Amanda::Changer ); @@ -497,7 +498,7 @@ sub _get_slot_label { sub _load_drive { my ($self, $drive, $slot) = @_; - die "'$drive' does not exist" unless (-d $drive); + confess "'$drive' does not exist" unless (-d $drive); if (-e "$drive/data") { unlink("$drive/data"); } diff --git a/perl/Amanda/Changer/multi.pm b/perl/Amanda/Changer/multi.pm index 9324a54..85de8fd 100644 --- a/perl/Amanda/Changer/multi.pm +++ b/perl/Amanda/Changer/multi.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2008,2009,2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -410,7 +410,8 @@ sub inventory { my $s = { slot => $slot, state => $state->{slots}->{$unaliased}->{state} || Amanda::Changer::SLOT_UNKNOWN, reserved => $self->_is_slot_in_use($state, $slot) }; - if (defined $state->{slots}->{$unaliased}) { + if (defined $state->{slots}->{$unaliased} and + exists $state->{slots}->{$unaliased}->{device_status}) { $s->{'device_status'} = $state->{slots}->{$unaliased}->{device_status}; if ($s->{'device_status'} != $DEVICE_STATUS_SUCCESS) { diff --git a/perl/Amanda/Changer/ndmp.pm b/perl/Amanda/Changer/ndmp.pm index 016db8f..0314d32 100644 --- a/perl/Amanda/Changer/ndmp.pm +++ b/perl/Amanda/Changer/ndmp.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009,2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License version 2.1 as @@ -110,6 +110,7 @@ sub get_device { package Amanda::Changer::ndmp::Interface; +use Carp; use Amanda::NDMP qw( :constants ); use Amanda::Debug qw( debug warning ); use Amanda::MainLoop; @@ -422,9 +423,9 @@ sub _parse_read_element_status { my $all_descrips_len = ($all_descrips_len_msb << 16) + $all_descrips_len_lsw; my $have_pvoltag = $flags & 0x80; my $have_avoltag = $flags & 0x40; - die unless $all_descrips_len % $descrip_len == 0; - die unless $all_descrips_len >= $descrip_len; - die length($data) unless $all_descrips_len <= length($data); + confess unless $all_descrips_len % $descrip_len == 0; + confess unless $all_descrips_len >= $descrip_len; + confess (length($data)) unless $all_descrips_len <= length($data); $data = substr($data, 8); while ($all_descrips_len > 0) { # for each element status descriptor diff --git a/perl/Amanda/Changer/null.pm b/perl/Amanda/Changer/null.pm index 86628b7..7fb2eaf 100644 --- a/perl/Amanda/Changer/null.pm +++ b/perl/Amanda/Changer/null.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Changer/rait.pm b/perl/Amanda/Changer/rait.pm index 26486bc..d387c84 100644 --- a/perl/Amanda/Changer/rait.pm +++ b/perl/Amanda/Changer/rait.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009,2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -20,6 +20,7 @@ package Amanda::Changer::rait; use strict; use warnings; +use Carp; use vars qw( @ISA ); @ISA = qw( Amanda::Changer ); @@ -525,7 +526,7 @@ sub _for_each_child { ($params{'oksub'}, $params{'errsub'}, $params{'parent_cb'}, $params{'args'}); if (defined($args)) { - die "number of args did not match number of children" + confess "number of args did not match number of children" unless (@$args == $self->{'num_children'}); } else { $args = [ ( undef ) x $self->{'num_children'} ]; diff --git a/perl/Amanda/Changer/robot.pm b/perl/Amanda/Changer/robot.pm index d13e342..dae6af0 100644 --- a/perl/Amanda/Changer/robot.pm +++ b/perl/Amanda/Changer/robot.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009,2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License version 2.1 as @@ -471,7 +471,7 @@ sub load_unlocked { @check_order = (@{$self->{'driveorder'}}); } else { # the constructor should detect this circumstance - die "invalid drive_choice"; + confess "invalid drive_choice"; } my %checked; @@ -587,7 +587,7 @@ sub load_unlocked { step check_device => sub { my $device_name = $self->{'drive2device'}->{$drive}; - die "drive $drive not found in drive2device" unless $device_name; # shouldn't happen + confess "drive $drive not found in drive2device" unless $device_name; # shouldn't happen $self->_debug("polling '$device_name' to see if it's ready"); @@ -644,7 +644,13 @@ sub load_unlocked { } $state->{'slots'}->{$slot}->{'label'} = $label; if ($state->{'slots'}->{$slot}->{'barcode'}) { - $state->{'bc2lb'}->{$state->{'slots'}->{$slot}->{'barcode'}} = $label; + my $barcode = $state->{'slots'}->{$slot}->{'barcode'}; + my $old_label = $state->{'bc2lb'}->{$barcode}; + if ($label ne $old_label) { + $self->_debug("make_res: slot $slot"); + $self->_debug("update label '$label' for barcode '$barcode', old label was '$old_label'"); + } + $state->{'bc2lb'}->{$barcode} = $label; } return $self->make_error("failed", $params{'res_cb'}, @@ -689,11 +695,17 @@ sub load_unlocked { $state->{'drives'}->{$drive}->{'state'} = Amanda::Changer::SLOT_FULL; $state->{'drives'}->{$drive}->{'barcode'} = $state->{'slots'}->{$slot}->{'barcode'}; $state->{'slots'}->{$slot}->{'device_status'} = $device->status; - if ($label and $state->{'slots'}->{$slot}->{'barcode'}) { - $state->{'bc2lb'}->{$state->{'slots'}->{$slot}->{'barcode'}} = $label; + my $barcode = $state->{'slots'}->{$slot}->{'barcode'}; + if ($label and $barcode) { + my $old_label = $state->{'bc2lb'}->{$barcode}; + if (defined $old_label and $old_label ne $label) { + $self->_debug("load drive $drive slot $slot"); + $self->_debug("update label '$label' for barcode '$barcode', old label was '$old_label'"); + } + $state->{'bc2lb'}->{$barcode} = $label; } if ($params{'set_current'}) { - $self->_debug("setting current slot to $slot"); + $self->_debug("setting current slot to $slot"); $state->{'current_slot'} = $slot; } @@ -845,6 +857,11 @@ sub _set_label_unlocked { $state->{'slots'}->{$slot}->{'label'} = $label; } if (defined $barcode) { + if (defined $state->{'bc2lb'}->{$barcode} and + $state->{'bc2lb'}->{$barcode} ne $label) { + my $old_label = $state->{'bc2lb'}->{$barcode}; + $self->_debug("update barcode '$barcode' to label '$label', old label was '$old_label'"); + } $state->{'bc2lb'}->{$barcode} = $label; } @@ -1914,6 +1931,7 @@ sub status { } else { my %status; for my $line (split '\n', $output) { + debug("mtx: $line"); my ($slot, $ie, $slinfo); # drives (data transfer elements) @@ -2025,12 +2043,12 @@ sub _run_system_command { my ($readfd, $writefd) = POSIX::pipe(); if (!defined($writefd)) { - die("Error creating pipe: $!"); + confess("Error creating pipe: $!"); } my $pid = fork(); if (!defined($pid) or $pid < 0) { - die("Can't fork to run changer script: $!"); + confess("Can't fork to run changer script: $!"); } if (!$pid) { diff --git a/perl/Amanda/Changer/single.pm b/perl/Amanda/Changer/single.pm index 75e0469..06a15e2 100644 --- a/perl/Amanda/Changer/single.pm +++ b/perl/Amanda/Changer/single.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2008,2009,2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -20,6 +20,7 @@ package Amanda::Changer::single; use strict; use warnings; +use Carp; use vars qw( @ISA ); @ISA = qw( Amanda::Changer ); @@ -77,7 +78,7 @@ sub load { return if $self->check_error($params{'res_cb'}); - die "no res_cb supplied" unless (exists $params{'res_cb'}); + confess "no res_cb supplied" unless (exists $params{'res_cb'}); if ($self->{'reserved'}) { return $self->make_error("failed", $params{'res_cb'}, diff --git a/perl/Amanda/ClientService.pm b/perl/Amanda/ClientService.pm index 07989aa..8d59382 100644 --- a/perl/Amanda/ClientService.pm +++ b/perl/Amanda/ClientService.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Cmdline.pod b/perl/Amanda/Cmdline.pod index 9746795..1051b23 100644 --- a/perl/Amanda/Cmdline.pod +++ b/perl/Amanda/Cmdline.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Cmdline.swg b/perl/Amanda/Cmdline.swg index b908c95..e31d766 100644 --- a/perl/Amanda/Cmdline.swg +++ b/perl/Amanda/Cmdline.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Config.c b/perl/Amanda/Config.c index cacd064..6a585e6 100644 --- a/perl/Amanda/Config.c +++ b/perl/Amanda/Config.c @@ -1968,7 +1968,7 @@ typedef char **val_t_strs; val_t_strs getconf_byname_strs(char *key, int str_needs_quotes) { val_t *val = getconf_byname(key); if (!val) return NULL; - return val_t_display_strs(val, str_needs_quotes); + return val_t_display_strs(val, str_needs_quotes, FALSE, FALSE); } @@ -4808,16 +4808,28 @@ XS(_wrap_set_config_overrides) { XS(_wrap_dump_configuration) { { + gboolean arg1 ; + gboolean arg2 ; int argvi = 0; dXSARGS; - if ((items < 0) || (items > 0)) { - SWIG_croak("Usage: dump_configuration();"); + if ((items < 2) || (items > 2)) { + SWIG_croak("Usage: dump_configuration(print_default,print_source);"); } - dump_configuration(); + { + arg1 = SvTRUE(ST(0)); + } + { + arg2 = SvTRUE(ST(1)); + } + dump_configuration(arg1,arg2); ST(argvi) = sv_newmortal(); + + XSRETURN(argvi); fail: + + SWIG_croak_null(); } } @@ -4980,6 +4992,7 @@ XS(_wrap_amandaify_property_name) { result = (gchar *)amandaify_property_name((char const *)arg1); ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + free((char*)result); XSRETURN(argvi); fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); @@ -5934,6 +5947,11 @@ XS(SWIG_init) { sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1((int)(CNF_EJECT_VOLUME))); SvREADONLY_on(sv); } while(0) /*@SWIG@*/; + /*@SWIG:/usr/share/swig/2.0.4/perl5/perltypemaps.swg,65,%set_constant@*/ do { + SV *sv = get_sv((char*) SWIG_prefix "CNF_TMPDIR", TRUE | 0x2 | GV_ADDMULTI); + sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1((int)(CNF_TMPDIR))); + SvREADONLY_on(sv); + } while(0) /*@SWIG@*/; /*@SWIG:/usr/share/swig/2.0.4/perl5/perltypemaps.swg,65,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "TAPETYPE_COMMENT", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1((int)(TAPETYPE_COMMENT))); @@ -6209,6 +6227,11 @@ XS(SWIG_init) { sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1((int)(DUMPTYPE_ALLOW_SPLIT))); SvREADONLY_on(sv); } while(0) /*@SWIG@*/; + /*@SWIG:/usr/share/swig/2.0.4/perl5/perltypemaps.swg,65,%set_constant@*/ do { + SV *sv = get_sv((char*) SWIG_prefix "DUMPTYPE_MAX_WARNINGS", TRUE | 0x2 | GV_ADDMULTI); + sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1((int)(DUMPTYPE_MAX_WARNINGS))); + SvREADONLY_on(sv); + } while(0) /*@SWIG@*/; /*@SWIG:/usr/share/swig/2.0.4/perl5/perltypemaps.swg,65,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "DUMPTYPE_RECOVERY_LIMIT", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1((int)(DUMPTYPE_RECOVERY_LIMIT))); diff --git a/perl/Amanda/Config.pm b/perl/Amanda/Config.pm index 79b2e5b..bcd636c 100644 --- a/perl/Amanda/Config.pm +++ b/perl/Amanda/Config.pm @@ -217,6 +217,7 @@ package Amanda::Config; *CNF_INTERACTIVITY = *Amanda::Configc::CNF_INTERACTIVITY; *CNF_TAPERSCAN = *Amanda::Configc::CNF_TAPERSCAN; *CNF_EJECT_VOLUME = *Amanda::Configc::CNF_EJECT_VOLUME; +*CNF_TMPDIR = *Amanda::Configc::CNF_TMPDIR; *TAPETYPE_COMMENT = *Amanda::Configc::TAPETYPE_COMMENT; *TAPETYPE_LBL_TEMPL = *Amanda::Configc::TAPETYPE_LBL_TEMPL; *TAPETYPE_BLOCKSIZE = *Amanda::Configc::TAPETYPE_BLOCKSIZE; @@ -272,6 +273,7 @@ package Amanda::Config; *DUMPTYPE_PROPERTY = *Amanda::Configc::DUMPTYPE_PROPERTY; *DUMPTYPE_DATA_PATH = *Amanda::Configc::DUMPTYPE_DATA_PATH; *DUMPTYPE_ALLOW_SPLIT = *Amanda::Configc::DUMPTYPE_ALLOW_SPLIT; +*DUMPTYPE_MAX_WARNINGS = *Amanda::Configc::DUMPTYPE_MAX_WARNINGS; *DUMPTYPE_RECOVERY_LIMIT = *Amanda::Configc::DUMPTYPE_RECOVERY_LIMIT; *DUMPTYPE_DUMP_LIMIT = *Amanda::Configc::DUMPTYPE_DUMP_LIMIT; *INTER_COMMENT = *Amanda::Configc::INTER_COMMENT; @@ -738,9 +740,9 @@ sub confparm_key_to_string { return $enumval; } -push @EXPORT_OK, qw( $CNF_ORG $CNF_CONF $CNF_AMDUMP_SERVER $CNF_INDEX_SERVER $CNF_TAPE_SERVER $CNF_AUTH $CNF_SSH_KEYS $CNF_AMANDAD_PATH $CNF_CLIENT_USERNAME $CNF_CLIENT_PORT $CNF_GNUTAR_LIST_DIR $CNF_AMANDATES $CNF_MAILER $CNF_MAILTO $CNF_DUMPUSER $CNF_TAPEDEV $CNF_DEVICE_PROPERTY $CNF_PROPERTY $CNF_CHANGERDEV $CNF_CHANGERFILE $CNF_LABELSTR $CNF_AUTOLABEL $CNF_META_AUTOLABEL $CNF_TAPELIST $CNF_DISKFILE $CNF_INFOFILE $CNF_LOGDIR $CNF_INDEXDIR $CNF_TAPETYPE $CNF_DUMPCYCLE $CNF_RUNSPERCYCLE $CNF_TAPECYCLE $CNF_NETUSAGE $CNF_INPARALLEL $CNF_DUMPORDER $CNF_BUMPPERCENT $CNF_BUMPSIZE $CNF_BUMPMULT $CNF_BUMPDAYS $CNF_TPCHANGER $CNF_RUNTAPES $CNF_MAX_DLE_BY_VOLUME $CNF_MAXDUMPS $CNF_ETIMEOUT $CNF_DTIMEOUT $CNF_CTIMEOUT $CNF_DEVICE_OUTPUT_BUFFER_SIZE $CNF_PRINTER $CNF_AUTOFLUSH $CNF_RESERVE $CNF_MAXDUMPSIZE $CNF_COLUMNSPEC $CNF_AMRECOVER_DO_FSF $CNF_AMRECOVER_CHECK_LABEL $CNF_AMRECOVER_CHANGER $CNF_TAPERALGO $CNF_FLUSH_THRESHOLD_DUMPED $CNF_FLUSH_THRESHOLD_SCHEDULED $CNF_TAPERFLUSH $CNF_DISPLAYUNIT $CNF_KRB5KEYTAB $CNF_KRB5PRINCIPAL $CNF_LABEL_NEW_TAPES $CNF_USETIMESTAMPS $CNF_REP_TRIES $CNF_CONNECT_TRIES $CNF_REQ_TRIES $CNF_DEBUG_AMANDAD $CNF_DEBUG_RECOVERY $CNF_DEBUG_AMIDXTAPED $CNF_DEBUG_AMINDEXD $CNF_DEBUG_AMRECOVER $CNF_DEBUG_AUTH $CNF_DEBUG_EVENT $CNF_DEBUG_HOLDING $CNF_DEBUG_PROTOCOL $CNF_DEBUG_PLANNER $CNF_DEBUG_DRIVER $CNF_DEBUG_DUMPER $CNF_DEBUG_CHUNKER $CNF_DEBUG_TAPER $CNF_DEBUG_SELFCHECK $CNF_DEBUG_SENDSIZE $CNF_DEBUG_SENDBACKUP $CNF_RESERVED_UDP_PORT $CNF_RESERVED_TCP_PORT $CNF_UNRESERVED_TCP_PORT $CNF_HOLDINGDISK $CNF_SEND_AMREPORT_ON $CNF_TAPER_PARALLEL_WRITE $CNF_RECOVERY_LIMIT $CNF_INTERACTIVITY $CNF_TAPERSCAN $CNF_EJECT_VOLUME); -push @{$EXPORT_TAGS{"confparm_key"}}, qw( $CNF_ORG $CNF_CONF $CNF_AMDUMP_SERVER $CNF_INDEX_SERVER $CNF_TAPE_SERVER $CNF_AUTH $CNF_SSH_KEYS $CNF_AMANDAD_PATH $CNF_CLIENT_USERNAME $CNF_CLIENT_PORT $CNF_GNUTAR_LIST_DIR $CNF_AMANDATES $CNF_MAILER $CNF_MAILTO $CNF_DUMPUSER $CNF_TAPEDEV $CNF_DEVICE_PROPERTY $CNF_PROPERTY $CNF_CHANGERDEV $CNF_CHANGERFILE $CNF_LABELSTR $CNF_AUTOLABEL $CNF_META_AUTOLABEL $CNF_TAPELIST $CNF_DISKFILE $CNF_INFOFILE $CNF_LOGDIR $CNF_INDEXDIR $CNF_TAPETYPE $CNF_DUMPCYCLE $CNF_RUNSPERCYCLE $CNF_TAPECYCLE $CNF_NETUSAGE $CNF_INPARALLEL $CNF_DUMPORDER $CNF_BUMPPERCENT $CNF_BUMPSIZE $CNF_BUMPMULT $CNF_BUMPDAYS $CNF_TPCHANGER $CNF_RUNTAPES $CNF_MAX_DLE_BY_VOLUME $CNF_MAXDUMPS $CNF_ETIMEOUT $CNF_DTIMEOUT $CNF_CTIMEOUT $CNF_DEVICE_OUTPUT_BUFFER_SIZE $CNF_PRINTER $CNF_AUTOFLUSH $CNF_RESERVE $CNF_MAXDUMPSIZE $CNF_COLUMNSPEC $CNF_AMRECOVER_DO_FSF $CNF_AMRECOVER_CHECK_LABEL $CNF_AMRECOVER_CHANGER $CNF_TAPERALGO $CNF_FLUSH_THRESHOLD_DUMPED $CNF_FLUSH_THRESHOLD_SCHEDULED $CNF_TAPERFLUSH $CNF_DISPLAYUNIT $CNF_KRB5KEYTAB $CNF_KRB5PRINCIPAL $CNF_LABEL_NEW_TAPES $CNF_USETIMESTAMPS $CNF_REP_TRIES $CNF_CONNECT_TRIES $CNF_REQ_TRIES $CNF_DEBUG_AMANDAD $CNF_DEBUG_RECOVERY $CNF_DEBUG_AMIDXTAPED $CNF_DEBUG_AMINDEXD $CNF_DEBUG_AMRECOVER $CNF_DEBUG_AUTH $CNF_DEBUG_EVENT $CNF_DEBUG_HOLDING $CNF_DEBUG_PROTOCOL $CNF_DEBUG_PLANNER $CNF_DEBUG_DRIVER $CNF_DEBUG_DUMPER $CNF_DEBUG_CHUNKER $CNF_DEBUG_TAPER $CNF_DEBUG_SELFCHECK $CNF_DEBUG_SENDSIZE $CNF_DEBUG_SENDBACKUP $CNF_RESERVED_UDP_PORT $CNF_RESERVED_TCP_PORT $CNF_UNRESERVED_TCP_PORT $CNF_HOLDINGDISK $CNF_SEND_AMREPORT_ON $CNF_TAPER_PARALLEL_WRITE $CNF_RECOVERY_LIMIT $CNF_INTERACTIVITY $CNF_TAPERSCAN $CNF_EJECT_VOLUME); - foreach (qw( CNF_ORG CNF_CONF CNF_AMDUMP_SERVER CNF_INDEX_SERVER CNF_TAPE_SERVER CNF_AUTH CNF_SSH_KEYS CNF_AMANDAD_PATH CNF_CLIENT_USERNAME CNF_CLIENT_PORT CNF_GNUTAR_LIST_DIR CNF_AMANDATES CNF_MAILER CNF_MAILTO CNF_DUMPUSER CNF_TAPEDEV CNF_DEVICE_PROPERTY CNF_PROPERTY CNF_CHANGERDEV CNF_CHANGERFILE CNF_LABELSTR CNF_AUTOLABEL CNF_META_AUTOLABEL CNF_TAPELIST CNF_DISKFILE CNF_INFOFILE CNF_LOGDIR CNF_INDEXDIR CNF_TAPETYPE CNF_DUMPCYCLE CNF_RUNSPERCYCLE CNF_TAPECYCLE CNF_NETUSAGE CNF_INPARALLEL CNF_DUMPORDER CNF_BUMPPERCENT CNF_BUMPSIZE CNF_BUMPMULT CNF_BUMPDAYS CNF_TPCHANGER CNF_RUNTAPES CNF_MAX_DLE_BY_VOLUME CNF_MAXDUMPS CNF_ETIMEOUT CNF_DTIMEOUT CNF_CTIMEOUT CNF_DEVICE_OUTPUT_BUFFER_SIZE CNF_PRINTER CNF_AUTOFLUSH CNF_RESERVE CNF_MAXDUMPSIZE CNF_COLUMNSPEC CNF_AMRECOVER_DO_FSF CNF_AMRECOVER_CHECK_LABEL CNF_AMRECOVER_CHANGER CNF_TAPERALGO CNF_FLUSH_THRESHOLD_DUMPED CNF_FLUSH_THRESHOLD_SCHEDULED CNF_TAPERFLUSH CNF_DISPLAYUNIT CNF_KRB5KEYTAB CNF_KRB5PRINCIPAL CNF_LABEL_NEW_TAPES CNF_USETIMESTAMPS CNF_REP_TRIES CNF_CONNECT_TRIES CNF_REQ_TRIES CNF_DEBUG_AMANDAD CNF_DEBUG_RECOVERY CNF_DEBUG_AMIDXTAPED CNF_DEBUG_AMINDEXD CNF_DEBUG_AMRECOVER CNF_DEBUG_AUTH CNF_DEBUG_EVENT CNF_DEBUG_HOLDING CNF_DEBUG_PROTOCOL CNF_DEBUG_PLANNER CNF_DEBUG_DRIVER CNF_DEBUG_DUMPER CNF_DEBUG_CHUNKER CNF_DEBUG_TAPER CNF_DEBUG_SELFCHECK CNF_DEBUG_SENDSIZE CNF_DEBUG_SENDBACKUP CNF_RESERVED_UDP_PORT CNF_RESERVED_TCP_PORT CNF_UNRESERVED_TCP_PORT CNF_HOLDINGDISK CNF_SEND_AMREPORT_ON CNF_TAPER_PARALLEL_WRITE CNF_RECOVERY_LIMIT CNF_INTERACTIVITY CNF_TAPERSCAN CNF_EJECT_VOLUME)) { $_confparm_key_VALUES{$_} = $$_; } +push @EXPORT_OK, qw( $CNF_ORG $CNF_CONF $CNF_AMDUMP_SERVER $CNF_INDEX_SERVER $CNF_TAPE_SERVER $CNF_AUTH $CNF_SSH_KEYS $CNF_AMANDAD_PATH $CNF_CLIENT_USERNAME $CNF_CLIENT_PORT $CNF_GNUTAR_LIST_DIR $CNF_AMANDATES $CNF_MAILER $CNF_MAILTO $CNF_DUMPUSER $CNF_TAPEDEV $CNF_DEVICE_PROPERTY $CNF_PROPERTY $CNF_CHANGERDEV $CNF_CHANGERFILE $CNF_LABELSTR $CNF_AUTOLABEL $CNF_META_AUTOLABEL $CNF_TAPELIST $CNF_DISKFILE $CNF_INFOFILE $CNF_LOGDIR $CNF_INDEXDIR $CNF_TAPETYPE $CNF_DUMPCYCLE $CNF_RUNSPERCYCLE $CNF_TAPECYCLE $CNF_NETUSAGE $CNF_INPARALLEL $CNF_DUMPORDER $CNF_BUMPPERCENT $CNF_BUMPSIZE $CNF_BUMPMULT $CNF_BUMPDAYS $CNF_TPCHANGER $CNF_RUNTAPES $CNF_MAX_DLE_BY_VOLUME $CNF_MAXDUMPS $CNF_ETIMEOUT $CNF_DTIMEOUT $CNF_CTIMEOUT $CNF_DEVICE_OUTPUT_BUFFER_SIZE $CNF_PRINTER $CNF_AUTOFLUSH $CNF_RESERVE $CNF_MAXDUMPSIZE $CNF_COLUMNSPEC $CNF_AMRECOVER_DO_FSF $CNF_AMRECOVER_CHECK_LABEL $CNF_AMRECOVER_CHANGER $CNF_TAPERALGO $CNF_FLUSH_THRESHOLD_DUMPED $CNF_FLUSH_THRESHOLD_SCHEDULED $CNF_TAPERFLUSH $CNF_DISPLAYUNIT $CNF_KRB5KEYTAB $CNF_KRB5PRINCIPAL $CNF_LABEL_NEW_TAPES $CNF_USETIMESTAMPS $CNF_REP_TRIES $CNF_CONNECT_TRIES $CNF_REQ_TRIES $CNF_DEBUG_AMANDAD $CNF_DEBUG_RECOVERY $CNF_DEBUG_AMIDXTAPED $CNF_DEBUG_AMINDEXD $CNF_DEBUG_AMRECOVER $CNF_DEBUG_AUTH $CNF_DEBUG_EVENT $CNF_DEBUG_HOLDING $CNF_DEBUG_PROTOCOL $CNF_DEBUG_PLANNER $CNF_DEBUG_DRIVER $CNF_DEBUG_DUMPER $CNF_DEBUG_CHUNKER $CNF_DEBUG_TAPER $CNF_DEBUG_SELFCHECK $CNF_DEBUG_SENDSIZE $CNF_DEBUG_SENDBACKUP $CNF_RESERVED_UDP_PORT $CNF_RESERVED_TCP_PORT $CNF_UNRESERVED_TCP_PORT $CNF_HOLDINGDISK $CNF_SEND_AMREPORT_ON $CNF_TAPER_PARALLEL_WRITE $CNF_RECOVERY_LIMIT $CNF_INTERACTIVITY $CNF_TAPERSCAN $CNF_EJECT_VOLUME $CNF_TMPDIR); +push @{$EXPORT_TAGS{"confparm_key"}}, qw( $CNF_ORG $CNF_CONF $CNF_AMDUMP_SERVER $CNF_INDEX_SERVER $CNF_TAPE_SERVER $CNF_AUTH $CNF_SSH_KEYS $CNF_AMANDAD_PATH $CNF_CLIENT_USERNAME $CNF_CLIENT_PORT $CNF_GNUTAR_LIST_DIR $CNF_AMANDATES $CNF_MAILER $CNF_MAILTO $CNF_DUMPUSER $CNF_TAPEDEV $CNF_DEVICE_PROPERTY $CNF_PROPERTY $CNF_CHANGERDEV $CNF_CHANGERFILE $CNF_LABELSTR $CNF_AUTOLABEL $CNF_META_AUTOLABEL $CNF_TAPELIST $CNF_DISKFILE $CNF_INFOFILE $CNF_LOGDIR $CNF_INDEXDIR $CNF_TAPETYPE $CNF_DUMPCYCLE $CNF_RUNSPERCYCLE $CNF_TAPECYCLE $CNF_NETUSAGE $CNF_INPARALLEL $CNF_DUMPORDER $CNF_BUMPPERCENT $CNF_BUMPSIZE $CNF_BUMPMULT $CNF_BUMPDAYS $CNF_TPCHANGER $CNF_RUNTAPES $CNF_MAX_DLE_BY_VOLUME $CNF_MAXDUMPS $CNF_ETIMEOUT $CNF_DTIMEOUT $CNF_CTIMEOUT $CNF_DEVICE_OUTPUT_BUFFER_SIZE $CNF_PRINTER $CNF_AUTOFLUSH $CNF_RESERVE $CNF_MAXDUMPSIZE $CNF_COLUMNSPEC $CNF_AMRECOVER_DO_FSF $CNF_AMRECOVER_CHECK_LABEL $CNF_AMRECOVER_CHANGER $CNF_TAPERALGO $CNF_FLUSH_THRESHOLD_DUMPED $CNF_FLUSH_THRESHOLD_SCHEDULED $CNF_TAPERFLUSH $CNF_DISPLAYUNIT $CNF_KRB5KEYTAB $CNF_KRB5PRINCIPAL $CNF_LABEL_NEW_TAPES $CNF_USETIMESTAMPS $CNF_REP_TRIES $CNF_CONNECT_TRIES $CNF_REQ_TRIES $CNF_DEBUG_AMANDAD $CNF_DEBUG_RECOVERY $CNF_DEBUG_AMIDXTAPED $CNF_DEBUG_AMINDEXD $CNF_DEBUG_AMRECOVER $CNF_DEBUG_AUTH $CNF_DEBUG_EVENT $CNF_DEBUG_HOLDING $CNF_DEBUG_PROTOCOL $CNF_DEBUG_PLANNER $CNF_DEBUG_DRIVER $CNF_DEBUG_DUMPER $CNF_DEBUG_CHUNKER $CNF_DEBUG_TAPER $CNF_DEBUG_SELFCHECK $CNF_DEBUG_SENDSIZE $CNF_DEBUG_SENDBACKUP $CNF_RESERVED_UDP_PORT $CNF_RESERVED_TCP_PORT $CNF_UNRESERVED_TCP_PORT $CNF_HOLDINGDISK $CNF_SEND_AMREPORT_ON $CNF_TAPER_PARALLEL_WRITE $CNF_RECOVERY_LIMIT $CNF_INTERACTIVITY $CNF_TAPERSCAN $CNF_EJECT_VOLUME $CNF_TMPDIR); + foreach (qw( CNF_ORG CNF_CONF CNF_AMDUMP_SERVER CNF_INDEX_SERVER CNF_TAPE_SERVER CNF_AUTH CNF_SSH_KEYS CNF_AMANDAD_PATH CNF_CLIENT_USERNAME CNF_CLIENT_PORT CNF_GNUTAR_LIST_DIR CNF_AMANDATES CNF_MAILER CNF_MAILTO CNF_DUMPUSER CNF_TAPEDEV CNF_DEVICE_PROPERTY CNF_PROPERTY CNF_CHANGERDEV CNF_CHANGERFILE CNF_LABELSTR CNF_AUTOLABEL CNF_META_AUTOLABEL CNF_TAPELIST CNF_DISKFILE CNF_INFOFILE CNF_LOGDIR CNF_INDEXDIR CNF_TAPETYPE CNF_DUMPCYCLE CNF_RUNSPERCYCLE CNF_TAPECYCLE CNF_NETUSAGE CNF_INPARALLEL CNF_DUMPORDER CNF_BUMPPERCENT CNF_BUMPSIZE CNF_BUMPMULT CNF_BUMPDAYS CNF_TPCHANGER CNF_RUNTAPES CNF_MAX_DLE_BY_VOLUME CNF_MAXDUMPS CNF_ETIMEOUT CNF_DTIMEOUT CNF_CTIMEOUT CNF_DEVICE_OUTPUT_BUFFER_SIZE CNF_PRINTER CNF_AUTOFLUSH CNF_RESERVE CNF_MAXDUMPSIZE CNF_COLUMNSPEC CNF_AMRECOVER_DO_FSF CNF_AMRECOVER_CHECK_LABEL CNF_AMRECOVER_CHANGER CNF_TAPERALGO CNF_FLUSH_THRESHOLD_DUMPED CNF_FLUSH_THRESHOLD_SCHEDULED CNF_TAPERFLUSH CNF_DISPLAYUNIT CNF_KRB5KEYTAB CNF_KRB5PRINCIPAL CNF_LABEL_NEW_TAPES CNF_USETIMESTAMPS CNF_REP_TRIES CNF_CONNECT_TRIES CNF_REQ_TRIES CNF_DEBUG_AMANDAD CNF_DEBUG_RECOVERY CNF_DEBUG_AMIDXTAPED CNF_DEBUG_AMINDEXD CNF_DEBUG_AMRECOVER CNF_DEBUG_AUTH CNF_DEBUG_EVENT CNF_DEBUG_HOLDING CNF_DEBUG_PROTOCOL CNF_DEBUG_PLANNER CNF_DEBUG_DRIVER CNF_DEBUG_DUMPER CNF_DEBUG_CHUNKER CNF_DEBUG_TAPER CNF_DEBUG_SELFCHECK CNF_DEBUG_SENDSIZE CNF_DEBUG_SENDBACKUP CNF_RESERVED_UDP_PORT CNF_RESERVED_TCP_PORT CNF_UNRESERVED_TCP_PORT CNF_HOLDINGDISK CNF_SEND_AMREPORT_ON CNF_TAPER_PARALLEL_WRITE CNF_RECOVERY_LIMIT CNF_INTERACTIVITY CNF_TAPERSCAN CNF_EJECT_VOLUME CNF_TMPDIR)) { $_confparm_key_VALUES{$_} = $$_; } #copy symbols in confparm_key to getconf push @{$EXPORT_TAGS{"getconf"}}, @{$EXPORT_TAGS{"confparm_key"}}; @@ -749,7 +751,7 @@ use Amanda::Config::FoldingHash; =pod -Global Parameters: C<$CNF_ORG> C<$CNF_CONF> C<$CNF_AMDUMP_SERVER> C<$CNF_INDEX_SERVER> C<$CNF_TAPE_SERVER> C<$CNF_AUTH> C<$CNF_SSH_KEYS> C<$CNF_AMANDAD_PATH> C<$CNF_CLIENT_USERNAME> C<$CNF_CLIENT_PORT> C<$CNF_GNUTAR_LIST_DIR> C<$CNF_AMANDATES> C<$CNF_MAILER> C<$CNF_MAILTO> C<$CNF_DUMPUSER> C<$CNF_TAPEDEV> C<$CNF_DEVICE_PROPERTY> C<$CNF_PROPERTY> C<$CNF_CHANGERDEV> C<$CNF_CHANGERFILE> C<$CNF_LABELSTR> C<$CNF_AUTOLABEL> C<$CNF_META_AUTOLABEL> C<$CNF_TAPELIST> C<$CNF_DISKFILE> C<$CNF_INFOFILE> C<$CNF_LOGDIR> C<$CNF_INDEXDIR> C<$CNF_TAPETYPE> C<$CNF_DUMPCYCLE> C<$CNF_RUNSPERCYCLE> C<$CNF_TAPECYCLE> C<$CNF_NETUSAGE> C<$CNF_INPARALLEL> C<$CNF_DUMPORDER> C<$CNF_BUMPPERCENT> C<$CNF_BUMPSIZE> C<$CNF_BUMPMULT> C<$CNF_BUMPDAYS> C<$CNF_TPCHANGER> C<$CNF_RUNTAPES> C<$CNF_MAX_DLE_BY_VOLUME> C<$CNF_MAXDUMPS> C<$CNF_ETIMEOUT> C<$CNF_DTIMEOUT> C<$CNF_CTIMEOUT> C<$CNF_DEVICE_OUTPUT_BUFFER_SIZE> C<$CNF_PRINTER> C<$CNF_AUTOFLUSH> C<$CNF_RESERVE> C<$CNF_MAXDUMPSIZE> C<$CNF_COLUMNSPEC> C<$CNF_AMRECOVER_DO_FSF> C<$CNF_AMRECOVER_CHECK_LABEL> C<$CNF_AMRECOVER_CHANGER> C<$CNF_TAPERALGO> C<$CNF_FLUSH_THRESHOLD_DUMPED> C<$CNF_FLUSH_THRESHOLD_SCHEDULED> C<$CNF_TAPERFLUSH> C<$CNF_DISPLAYUNIT> C<$CNF_KRB5KEYTAB> C<$CNF_KRB5PRINCIPAL> C<$CNF_LABEL_NEW_TAPES> C<$CNF_USETIMESTAMPS> C<$CNF_REP_TRIES> C<$CNF_CONNECT_TRIES> C<$CNF_REQ_TRIES> C<$CNF_DEBUG_AMANDAD> C<$CNF_DEBUG_RECOVERY> C<$CNF_DEBUG_AMIDXTAPED> C<$CNF_DEBUG_AMINDEXD> C<$CNF_DEBUG_AMRECOVER> C<$CNF_DEBUG_AUTH> C<$CNF_DEBUG_EVENT> C<$CNF_DEBUG_HOLDING> C<$CNF_DEBUG_PROTOCOL> C<$CNF_DEBUG_PLANNER> C<$CNF_DEBUG_DRIVER> C<$CNF_DEBUG_DUMPER> C<$CNF_DEBUG_CHUNKER> C<$CNF_DEBUG_TAPER> C<$CNF_DEBUG_SELFCHECK> C<$CNF_DEBUG_SENDSIZE> C<$CNF_DEBUG_SENDBACKUP> C<$CNF_RESERVED_UDP_PORT> C<$CNF_RESERVED_TCP_PORT> C<$CNF_UNRESERVED_TCP_PORT> C<$CNF_HOLDINGDISK> C<$CNF_SEND_AMREPORT_ON> C<$CNF_TAPER_PARALLEL_WRITE> C<$CNF_RECOVERY_LIMIT> C<$CNF_INTERACTIVITY> C<$CNF_TAPERSCAN> C<$CNF_EJECT_VOLUME> +Global Parameters: C<$CNF_ORG> C<$CNF_CONF> C<$CNF_AMDUMP_SERVER> C<$CNF_INDEX_SERVER> C<$CNF_TAPE_SERVER> C<$CNF_AUTH> C<$CNF_SSH_KEYS> C<$CNF_AMANDAD_PATH> C<$CNF_CLIENT_USERNAME> C<$CNF_CLIENT_PORT> C<$CNF_GNUTAR_LIST_DIR> C<$CNF_AMANDATES> C<$CNF_MAILER> C<$CNF_MAILTO> C<$CNF_DUMPUSER> C<$CNF_TAPEDEV> C<$CNF_DEVICE_PROPERTY> C<$CNF_PROPERTY> C<$CNF_CHANGERDEV> C<$CNF_CHANGERFILE> C<$CNF_LABELSTR> C<$CNF_AUTOLABEL> C<$CNF_META_AUTOLABEL> C<$CNF_TAPELIST> C<$CNF_DISKFILE> C<$CNF_INFOFILE> C<$CNF_LOGDIR> C<$CNF_INDEXDIR> C<$CNF_TAPETYPE> C<$CNF_DUMPCYCLE> C<$CNF_RUNSPERCYCLE> C<$CNF_TAPECYCLE> C<$CNF_NETUSAGE> C<$CNF_INPARALLEL> C<$CNF_DUMPORDER> C<$CNF_BUMPPERCENT> C<$CNF_BUMPSIZE> C<$CNF_BUMPMULT> C<$CNF_BUMPDAYS> C<$CNF_TPCHANGER> C<$CNF_RUNTAPES> C<$CNF_MAX_DLE_BY_VOLUME> C<$CNF_MAXDUMPS> C<$CNF_ETIMEOUT> C<$CNF_DTIMEOUT> C<$CNF_CTIMEOUT> C<$CNF_DEVICE_OUTPUT_BUFFER_SIZE> C<$CNF_PRINTER> C<$CNF_AUTOFLUSH> C<$CNF_RESERVE> C<$CNF_MAXDUMPSIZE> C<$CNF_COLUMNSPEC> C<$CNF_AMRECOVER_DO_FSF> C<$CNF_AMRECOVER_CHECK_LABEL> C<$CNF_AMRECOVER_CHANGER> C<$CNF_TAPERALGO> C<$CNF_FLUSH_THRESHOLD_DUMPED> C<$CNF_FLUSH_THRESHOLD_SCHEDULED> C<$CNF_TAPERFLUSH> C<$CNF_DISPLAYUNIT> C<$CNF_KRB5KEYTAB> C<$CNF_KRB5PRINCIPAL> C<$CNF_LABEL_NEW_TAPES> C<$CNF_USETIMESTAMPS> C<$CNF_REP_TRIES> C<$CNF_CONNECT_TRIES> C<$CNF_REQ_TRIES> C<$CNF_DEBUG_AMANDAD> C<$CNF_DEBUG_RECOVERY> C<$CNF_DEBUG_AMIDXTAPED> C<$CNF_DEBUG_AMINDEXD> C<$CNF_DEBUG_AMRECOVER> C<$CNF_DEBUG_AUTH> C<$CNF_DEBUG_EVENT> C<$CNF_DEBUG_HOLDING> C<$CNF_DEBUG_PROTOCOL> C<$CNF_DEBUG_PLANNER> C<$CNF_DEBUG_DRIVER> C<$CNF_DEBUG_DUMPER> C<$CNF_DEBUG_CHUNKER> C<$CNF_DEBUG_TAPER> C<$CNF_DEBUG_SELFCHECK> C<$CNF_DEBUG_SENDSIZE> C<$CNF_DEBUG_SENDBACKUP> C<$CNF_RESERVED_UDP_PORT> C<$CNF_RESERVED_TCP_PORT> C<$CNF_UNRESERVED_TCP_PORT> C<$CNF_HOLDINGDISK> C<$CNF_SEND_AMREPORT_ON> C<$CNF_TAPER_PARALLEL_WRITE> C<$CNF_RECOVERY_LIMIT> C<$CNF_INTERACTIVITY> C<$CNF_TAPERSCAN> C<$CNF_EJECT_VOLUME> C<$CNF_TMPDIR> =cut @@ -810,9 +812,9 @@ sub dumptype_key_to_string { return $enumval; } -push @EXPORT_OK, qw( $DUMPTYPE_COMMENT $DUMPTYPE_PROGRAM $DUMPTYPE_SRVCOMPPROG $DUMPTYPE_CLNTCOMPPROG $DUMPTYPE_SRV_ENCRYPT $DUMPTYPE_CLNT_ENCRYPT $DUMPTYPE_AMANDAD_PATH $DUMPTYPE_CLIENT_USERNAME $DUMPTYPE_CLIENT_PORT $DUMPTYPE_SSH_KEYS $DUMPTYPE_AUTH $DUMPTYPE_EXCLUDE $DUMPTYPE_INCLUDE $DUMPTYPE_PRIORITY $DUMPTYPE_DUMPCYCLE $DUMPTYPE_MAXDUMPS $DUMPTYPE_MAXPROMOTEDAY $DUMPTYPE_BUMPPERCENT $DUMPTYPE_BUMPSIZE $DUMPTYPE_BUMPDAYS $DUMPTYPE_BUMPMULT $DUMPTYPE_STARTTIME $DUMPTYPE_STRATEGY $DUMPTYPE_ESTIMATELIST $DUMPTYPE_COMPRESS $DUMPTYPE_ENCRYPT $DUMPTYPE_SRV_DECRYPT_OPT $DUMPTYPE_CLNT_DECRYPT_OPT $DUMPTYPE_COMPRATE $DUMPTYPE_TAPE_SPLITSIZE $DUMPTYPE_FALLBACK_SPLITSIZE $DUMPTYPE_SPLIT_DISKBUFFER $DUMPTYPE_RECORD $DUMPTYPE_SKIP_INCR $DUMPTYPE_SKIP_FULL $DUMPTYPE_HOLDINGDISK $DUMPTYPE_KENCRYPT $DUMPTYPE_IGNORE $DUMPTYPE_INDEX $DUMPTYPE_APPLICATION $DUMPTYPE_SCRIPTLIST $DUMPTYPE_PROPERTY $DUMPTYPE_DATA_PATH $DUMPTYPE_ALLOW_SPLIT $DUMPTYPE_RECOVERY_LIMIT $DUMPTYPE_DUMP_LIMIT); -push @{$EXPORT_TAGS{"dumptype_key"}}, qw( $DUMPTYPE_COMMENT $DUMPTYPE_PROGRAM $DUMPTYPE_SRVCOMPPROG $DUMPTYPE_CLNTCOMPPROG $DUMPTYPE_SRV_ENCRYPT $DUMPTYPE_CLNT_ENCRYPT $DUMPTYPE_AMANDAD_PATH $DUMPTYPE_CLIENT_USERNAME $DUMPTYPE_CLIENT_PORT $DUMPTYPE_SSH_KEYS $DUMPTYPE_AUTH $DUMPTYPE_EXCLUDE $DUMPTYPE_INCLUDE $DUMPTYPE_PRIORITY $DUMPTYPE_DUMPCYCLE $DUMPTYPE_MAXDUMPS $DUMPTYPE_MAXPROMOTEDAY $DUMPTYPE_BUMPPERCENT $DUMPTYPE_BUMPSIZE $DUMPTYPE_BUMPDAYS $DUMPTYPE_BUMPMULT $DUMPTYPE_STARTTIME $DUMPTYPE_STRATEGY $DUMPTYPE_ESTIMATELIST $DUMPTYPE_COMPRESS $DUMPTYPE_ENCRYPT $DUMPTYPE_SRV_DECRYPT_OPT $DUMPTYPE_CLNT_DECRYPT_OPT $DUMPTYPE_COMPRATE $DUMPTYPE_TAPE_SPLITSIZE $DUMPTYPE_FALLBACK_SPLITSIZE $DUMPTYPE_SPLIT_DISKBUFFER $DUMPTYPE_RECORD $DUMPTYPE_SKIP_INCR $DUMPTYPE_SKIP_FULL $DUMPTYPE_HOLDINGDISK $DUMPTYPE_KENCRYPT $DUMPTYPE_IGNORE $DUMPTYPE_INDEX $DUMPTYPE_APPLICATION $DUMPTYPE_SCRIPTLIST $DUMPTYPE_PROPERTY $DUMPTYPE_DATA_PATH $DUMPTYPE_ALLOW_SPLIT $DUMPTYPE_RECOVERY_LIMIT $DUMPTYPE_DUMP_LIMIT); - foreach (qw( DUMPTYPE_COMMENT DUMPTYPE_PROGRAM DUMPTYPE_SRVCOMPPROG DUMPTYPE_CLNTCOMPPROG DUMPTYPE_SRV_ENCRYPT DUMPTYPE_CLNT_ENCRYPT DUMPTYPE_AMANDAD_PATH DUMPTYPE_CLIENT_USERNAME DUMPTYPE_CLIENT_PORT DUMPTYPE_SSH_KEYS DUMPTYPE_AUTH DUMPTYPE_EXCLUDE DUMPTYPE_INCLUDE DUMPTYPE_PRIORITY DUMPTYPE_DUMPCYCLE DUMPTYPE_MAXDUMPS DUMPTYPE_MAXPROMOTEDAY DUMPTYPE_BUMPPERCENT DUMPTYPE_BUMPSIZE DUMPTYPE_BUMPDAYS DUMPTYPE_BUMPMULT DUMPTYPE_STARTTIME DUMPTYPE_STRATEGY DUMPTYPE_ESTIMATELIST DUMPTYPE_COMPRESS DUMPTYPE_ENCRYPT DUMPTYPE_SRV_DECRYPT_OPT DUMPTYPE_CLNT_DECRYPT_OPT DUMPTYPE_COMPRATE DUMPTYPE_TAPE_SPLITSIZE DUMPTYPE_FALLBACK_SPLITSIZE DUMPTYPE_SPLIT_DISKBUFFER DUMPTYPE_RECORD DUMPTYPE_SKIP_INCR DUMPTYPE_SKIP_FULL DUMPTYPE_HOLDINGDISK DUMPTYPE_KENCRYPT DUMPTYPE_IGNORE DUMPTYPE_INDEX DUMPTYPE_APPLICATION DUMPTYPE_SCRIPTLIST DUMPTYPE_PROPERTY DUMPTYPE_DATA_PATH DUMPTYPE_ALLOW_SPLIT DUMPTYPE_RECOVERY_LIMIT DUMPTYPE_DUMP_LIMIT)) { $_dumptype_key_VALUES{$_} = $$_; } +push @EXPORT_OK, qw( $DUMPTYPE_COMMENT $DUMPTYPE_PROGRAM $DUMPTYPE_SRVCOMPPROG $DUMPTYPE_CLNTCOMPPROG $DUMPTYPE_SRV_ENCRYPT $DUMPTYPE_CLNT_ENCRYPT $DUMPTYPE_AMANDAD_PATH $DUMPTYPE_CLIENT_USERNAME $DUMPTYPE_CLIENT_PORT $DUMPTYPE_SSH_KEYS $DUMPTYPE_AUTH $DUMPTYPE_EXCLUDE $DUMPTYPE_INCLUDE $DUMPTYPE_PRIORITY $DUMPTYPE_DUMPCYCLE $DUMPTYPE_MAXDUMPS $DUMPTYPE_MAXPROMOTEDAY $DUMPTYPE_BUMPPERCENT $DUMPTYPE_BUMPSIZE $DUMPTYPE_BUMPDAYS $DUMPTYPE_BUMPMULT $DUMPTYPE_STARTTIME $DUMPTYPE_STRATEGY $DUMPTYPE_ESTIMATELIST $DUMPTYPE_COMPRESS $DUMPTYPE_ENCRYPT $DUMPTYPE_SRV_DECRYPT_OPT $DUMPTYPE_CLNT_DECRYPT_OPT $DUMPTYPE_COMPRATE $DUMPTYPE_TAPE_SPLITSIZE $DUMPTYPE_FALLBACK_SPLITSIZE $DUMPTYPE_SPLIT_DISKBUFFER $DUMPTYPE_RECORD $DUMPTYPE_SKIP_INCR $DUMPTYPE_SKIP_FULL $DUMPTYPE_HOLDINGDISK $DUMPTYPE_KENCRYPT $DUMPTYPE_IGNORE $DUMPTYPE_INDEX $DUMPTYPE_APPLICATION $DUMPTYPE_SCRIPTLIST $DUMPTYPE_PROPERTY $DUMPTYPE_DATA_PATH $DUMPTYPE_ALLOW_SPLIT $DUMPTYPE_MAX_WARNINGS $DUMPTYPE_RECOVERY_LIMIT $DUMPTYPE_DUMP_LIMIT); +push @{$EXPORT_TAGS{"dumptype_key"}}, qw( $DUMPTYPE_COMMENT $DUMPTYPE_PROGRAM $DUMPTYPE_SRVCOMPPROG $DUMPTYPE_CLNTCOMPPROG $DUMPTYPE_SRV_ENCRYPT $DUMPTYPE_CLNT_ENCRYPT $DUMPTYPE_AMANDAD_PATH $DUMPTYPE_CLIENT_USERNAME $DUMPTYPE_CLIENT_PORT $DUMPTYPE_SSH_KEYS $DUMPTYPE_AUTH $DUMPTYPE_EXCLUDE $DUMPTYPE_INCLUDE $DUMPTYPE_PRIORITY $DUMPTYPE_DUMPCYCLE $DUMPTYPE_MAXDUMPS $DUMPTYPE_MAXPROMOTEDAY $DUMPTYPE_BUMPPERCENT $DUMPTYPE_BUMPSIZE $DUMPTYPE_BUMPDAYS $DUMPTYPE_BUMPMULT $DUMPTYPE_STARTTIME $DUMPTYPE_STRATEGY $DUMPTYPE_ESTIMATELIST $DUMPTYPE_COMPRESS $DUMPTYPE_ENCRYPT $DUMPTYPE_SRV_DECRYPT_OPT $DUMPTYPE_CLNT_DECRYPT_OPT $DUMPTYPE_COMPRATE $DUMPTYPE_TAPE_SPLITSIZE $DUMPTYPE_FALLBACK_SPLITSIZE $DUMPTYPE_SPLIT_DISKBUFFER $DUMPTYPE_RECORD $DUMPTYPE_SKIP_INCR $DUMPTYPE_SKIP_FULL $DUMPTYPE_HOLDINGDISK $DUMPTYPE_KENCRYPT $DUMPTYPE_IGNORE $DUMPTYPE_INDEX $DUMPTYPE_APPLICATION $DUMPTYPE_SCRIPTLIST $DUMPTYPE_PROPERTY $DUMPTYPE_DATA_PATH $DUMPTYPE_ALLOW_SPLIT $DUMPTYPE_MAX_WARNINGS $DUMPTYPE_RECOVERY_LIMIT $DUMPTYPE_DUMP_LIMIT); + foreach (qw( DUMPTYPE_COMMENT DUMPTYPE_PROGRAM DUMPTYPE_SRVCOMPPROG DUMPTYPE_CLNTCOMPPROG DUMPTYPE_SRV_ENCRYPT DUMPTYPE_CLNT_ENCRYPT DUMPTYPE_AMANDAD_PATH DUMPTYPE_CLIENT_USERNAME DUMPTYPE_CLIENT_PORT DUMPTYPE_SSH_KEYS DUMPTYPE_AUTH DUMPTYPE_EXCLUDE DUMPTYPE_INCLUDE DUMPTYPE_PRIORITY DUMPTYPE_DUMPCYCLE DUMPTYPE_MAXDUMPS DUMPTYPE_MAXPROMOTEDAY DUMPTYPE_BUMPPERCENT DUMPTYPE_BUMPSIZE DUMPTYPE_BUMPDAYS DUMPTYPE_BUMPMULT DUMPTYPE_STARTTIME DUMPTYPE_STRATEGY DUMPTYPE_ESTIMATELIST DUMPTYPE_COMPRESS DUMPTYPE_ENCRYPT DUMPTYPE_SRV_DECRYPT_OPT DUMPTYPE_CLNT_DECRYPT_OPT DUMPTYPE_COMPRATE DUMPTYPE_TAPE_SPLITSIZE DUMPTYPE_FALLBACK_SPLITSIZE DUMPTYPE_SPLIT_DISKBUFFER DUMPTYPE_RECORD DUMPTYPE_SKIP_INCR DUMPTYPE_SKIP_FULL DUMPTYPE_HOLDINGDISK DUMPTYPE_KENCRYPT DUMPTYPE_IGNORE DUMPTYPE_INDEX DUMPTYPE_APPLICATION DUMPTYPE_SCRIPTLIST DUMPTYPE_PROPERTY DUMPTYPE_DATA_PATH DUMPTYPE_ALLOW_SPLIT DUMPTYPE_MAX_WARNINGS DUMPTYPE_RECOVERY_LIMIT DUMPTYPE_DUMP_LIMIT)) { $_dumptype_key_VALUES{$_} = $$_; } #copy symbols in dumptype_key to getconf push @{$EXPORT_TAGS{"getconf"}}, @{$EXPORT_TAGS{"dumptype_key"}}; @@ -821,7 +823,7 @@ use Amanda::Config::FoldingHash; =pod -Dumptype Parameters: C<$DUMPTYPE_COMMENT> C<$DUMPTYPE_PROGRAM> C<$DUMPTYPE_SRVCOMPPROG> C<$DUMPTYPE_CLNTCOMPPROG> C<$DUMPTYPE_SRV_ENCRYPT> C<$DUMPTYPE_CLNT_ENCRYPT> C<$DUMPTYPE_AMANDAD_PATH> C<$DUMPTYPE_CLIENT_USERNAME> C<$DUMPTYPE_CLIENT_PORT> C<$DUMPTYPE_SSH_KEYS> C<$DUMPTYPE_AUTH> C<$DUMPTYPE_EXCLUDE> C<$DUMPTYPE_INCLUDE> C<$DUMPTYPE_PRIORITY> C<$DUMPTYPE_DUMPCYCLE> C<$DUMPTYPE_MAXDUMPS> C<$DUMPTYPE_MAXPROMOTEDAY> C<$DUMPTYPE_BUMPPERCENT> C<$DUMPTYPE_BUMPSIZE> C<$DUMPTYPE_BUMPDAYS> C<$DUMPTYPE_BUMPMULT> C<$DUMPTYPE_STARTTIME> C<$DUMPTYPE_STRATEGY> C<$DUMPTYPE_ESTIMATELIST> C<$DUMPTYPE_COMPRESS> C<$DUMPTYPE_ENCRYPT> C<$DUMPTYPE_SRV_DECRYPT_OPT> C<$DUMPTYPE_CLNT_DECRYPT_OPT> C<$DUMPTYPE_COMPRATE> C<$DUMPTYPE_TAPE_SPLITSIZE> C<$DUMPTYPE_FALLBACK_SPLITSIZE> C<$DUMPTYPE_SPLIT_DISKBUFFER> C<$DUMPTYPE_RECORD> C<$DUMPTYPE_SKIP_INCR> C<$DUMPTYPE_SKIP_FULL> C<$DUMPTYPE_HOLDINGDISK> C<$DUMPTYPE_KENCRYPT> C<$DUMPTYPE_IGNORE> C<$DUMPTYPE_INDEX> C<$DUMPTYPE_APPLICATION> C<$DUMPTYPE_SCRIPTLIST> C<$DUMPTYPE_PROPERTY> C<$DUMPTYPE_DATA_PATH> C<$DUMPTYPE_ALLOW_SPLIT> C<$DUMPTYPE_RECOVERY_LIMIT> C<$DUMPTYPE_DUMP_LIMIT> +Dumptype Parameters: C<$DUMPTYPE_COMMENT> C<$DUMPTYPE_PROGRAM> C<$DUMPTYPE_SRVCOMPPROG> C<$DUMPTYPE_CLNTCOMPPROG> C<$DUMPTYPE_SRV_ENCRYPT> C<$DUMPTYPE_CLNT_ENCRYPT> C<$DUMPTYPE_AMANDAD_PATH> C<$DUMPTYPE_CLIENT_USERNAME> C<$DUMPTYPE_CLIENT_PORT> C<$DUMPTYPE_SSH_KEYS> C<$DUMPTYPE_AUTH> C<$DUMPTYPE_EXCLUDE> C<$DUMPTYPE_INCLUDE> C<$DUMPTYPE_PRIORITY> C<$DUMPTYPE_DUMPCYCLE> C<$DUMPTYPE_MAXDUMPS> C<$DUMPTYPE_MAXPROMOTEDAY> C<$DUMPTYPE_BUMPPERCENT> C<$DUMPTYPE_BUMPSIZE> C<$DUMPTYPE_BUMPDAYS> C<$DUMPTYPE_BUMPMULT> C<$DUMPTYPE_STARTTIME> C<$DUMPTYPE_STRATEGY> C<$DUMPTYPE_ESTIMATELIST> C<$DUMPTYPE_COMPRESS> C<$DUMPTYPE_ENCRYPT> C<$DUMPTYPE_SRV_DECRYPT_OPT> C<$DUMPTYPE_CLNT_DECRYPT_OPT> C<$DUMPTYPE_COMPRATE> C<$DUMPTYPE_TAPE_SPLITSIZE> C<$DUMPTYPE_FALLBACK_SPLITSIZE> C<$DUMPTYPE_SPLIT_DISKBUFFER> C<$DUMPTYPE_RECORD> C<$DUMPTYPE_SKIP_INCR> C<$DUMPTYPE_SKIP_FULL> C<$DUMPTYPE_HOLDINGDISK> C<$DUMPTYPE_KENCRYPT> C<$DUMPTYPE_IGNORE> C<$DUMPTYPE_INDEX> C<$DUMPTYPE_APPLICATION> C<$DUMPTYPE_SCRIPTLIST> C<$DUMPTYPE_PROPERTY> C<$DUMPTYPE_DATA_PATH> C<$DUMPTYPE_ALLOW_SPLIT> C<$DUMPTYPE_MAX_WARNINGS> C<$DUMPTYPE_RECOVERY_LIMIT> C<$DUMPTYPE_DUMP_LIMIT> =cut diff --git a/perl/Amanda/Config.pod b/perl/Amanda/Config.pod index 535869e..e101eff 100644 --- a/perl/Amanda/Config.pod +++ b/perl/Amanda/Config.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Config.swg b/perl/Amanda/Config.swg index 4780ce9..f3481a8 100644 --- a/perl/Amanda/Config.swg +++ b/perl/Amanda/Config.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -145,7 +145,8 @@ APPLY(CNF_TAPER_PARALLEL_WRITE)\ APPLY(CNF_RECOVERY_LIMIT) \ APPLY(CNF_INTERACTIVITY) \ APPLY(CNF_TAPERSCAN) \ -APPLY(CNF_EJECT_VOLUME) +APPLY(CNF_EJECT_VOLUME) \ +APPLY(CNF_TMPDIR) amglue_add_enum_tag_fns(confparm_key); amglue_add_constants(FOR_ALL_CONFPARM_KEY, confparm_key); @@ -215,6 +216,7 @@ APPLY(DUMPTYPE_SCRIPTLIST)\ APPLY(DUMPTYPE_PROPERTY)\ APPLY(DUMPTYPE_DATA_PATH)\ APPLY(DUMPTYPE_ALLOW_SPLIT)\ +APPLY(DUMPTYPE_MAX_WARNINGS)\ APPLY(DUMPTYPE_RECOVERY_LIMIT) \ APPLY(DUMPTYPE_DUMP_LIMIT) @@ -693,7 +695,7 @@ typedef char **val_t_strs; val_t_strs getconf_byname_strs(char *key, int str_needs_quotes) { val_t *val = getconf_byname(key); if (!val) return NULL; - return val_t_display_strs(val, str_needs_quotes); + return val_t_display_strs(val, str_needs_quotes, FALSE, FALSE); } %} @@ -909,7 +911,7 @@ amglue_export_tag(init, * Miscellaneous */ -void dump_configuration(void); +void dump_configuration(gboolean print_default, gboolean print_source); %newobject config_dir_relative; char *config_dir_relative(char *filename); char *taperalgo2str(taperalgo_t taperalgo); @@ -934,5 +936,6 @@ sub string_to_boolean { amglue_export_ok(string_to_boolean); +%newobject amandaify_property_name; gchar * amandaify_property_name(const gchar *name); amglue_export_ok(amandaify_property_name); diff --git a/perl/Amanda/Constants.pm.in b/perl/Amanda/Constants.pm.in index e3692c9..0b8294a 100644 --- a/perl/Amanda/Constants.pm.in +++ b/perl/Amanda/Constants.pm.in @@ -1,5 +1,5 @@ # vim:ft=perl -# Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -106,6 +106,9 @@ $VXDUMP = "@VXDUMP@"; $VXRESTORE = "@VXRESTORE@"; $XFSDUMP = "@XFSDUMP@"; $XFSRESTORE = "@XFSRESTORE@"; +$NC = "@NC@"; +$NC6 = "@NC6@"; +$NETCAT = "@NETCAT@"; # non-AC_SUBST'd constants diff --git a/perl/Amanda/Curinfo.pm b/perl/Amanda/Curinfo.pm index 7af789e..062c3a3 100644 --- a/perl/Amanda/Curinfo.pm +++ b/perl/Amanda/Curinfo.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Curinfo/Info.pm b/perl/Amanda/Curinfo/Info.pm index f05e0da..1cd8e78 100644 --- a/perl/Amanda/Curinfo/Info.pm +++ b/perl/Amanda/Curinfo/Info.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/DB/Catalog.pm b/perl/Amanda/DB/Catalog.pm index 0aa88fa..dc849da 100644 --- a/perl/Amanda/DB/Catalog.pm +++ b/perl/Amanda/DB/Catalog.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Debug.pod b/perl/Amanda/Debug.pod index f6ba2f5..f6e432c 100644 --- a/perl/Amanda/Debug.pod +++ b/perl/Amanda/Debug.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Debug.swg b/perl/Amanda/Debug.swg index 7c51edf..852965d 100644 --- a/perl/Amanda/Debug.swg +++ b/perl/Amanda/Debug.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Device.c b/perl/Amanda/Device.c index cfbb55f..395ffeb 100644 --- a/perl/Amanda/Device.c +++ b/perl/Amanda/Device.c @@ -1510,21 +1510,23 @@ SWIG_Perl_SetModule(swig_module_info *module) { #define SWIGTYPE_p_DevicePropertyBase swig_types[1] #define SWIGTYPE_p_DirectTCPAddr swig_types[2] #define SWIGTYPE_p_DirectTCPConnection swig_types[3] -#define SWIGTYPE_p_GSList swig_types[4] -#define SWIGTYPE_p_GValue swig_types[5] -#define SWIGTYPE_p_a_STRMAX__char swig_types[6] -#define SWIGTYPE_p_char swig_types[7] -#define SWIGTYPE_p_double swig_types[8] -#define SWIGTYPE_p_dumpfile_t swig_types[9] -#define SWIGTYPE_p_float swig_types[10] -#define SWIGTYPE_p_guint swig_types[11] -#define SWIGTYPE_p_guint32 swig_types[12] -#define SWIGTYPE_p_guint64 swig_types[13] -#define SWIGTYPE_p_int swig_types[14] -#define SWIGTYPE_p_p_DirectTCPAddr swig_types[15] -#define SWIGTYPE_p_unsigned_char swig_types[16] -static swig_type_info *swig_types[18]; -static swig_module_info swig_module = {swig_types, 17, 0, 0, 0, 0}; +#define SWIGTYPE_p_GCond swig_types[4] +#define SWIGTYPE_p_GMutex swig_types[5] +#define SWIGTYPE_p_GSList swig_types[6] +#define SWIGTYPE_p_GValue swig_types[7] +#define SWIGTYPE_p_a_STRMAX__char swig_types[8] +#define SWIGTYPE_p_char swig_types[9] +#define SWIGTYPE_p_double swig_types[10] +#define SWIGTYPE_p_dumpfile_t swig_types[11] +#define SWIGTYPE_p_float swig_types[12] +#define SWIGTYPE_p_guint swig_types[13] +#define SWIGTYPE_p_guint32 swig_types[14] +#define SWIGTYPE_p_guint64 swig_types[15] +#define SWIGTYPE_p_int swig_types[16] +#define SWIGTYPE_p_p_DirectTCPAddr swig_types[17] +#define SWIGTYPE_p_unsigned_char swig_types[18] +static swig_type_info *swig_types[20]; +static swig_module_info swig_module = {swig_types, 19, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -1985,6 +1987,12 @@ SWIGINTERN gboolean Device_start(Device *self,DeviceAccessMode mode,char *label, SWIGINTERN gboolean Device_finish(Device *self){ return device_finish(self); } +SWIGINTERN guint64 Device_get_bytes_read(Device *self){ + return device_get_bytes_read(self); + } +SWIGINTERN guint64 Device_get_bytes_written(Device *self){ + return device_get_bytes_written(self); + } SWIGINTERN gboolean Device_start_file(Device *self,dumpfile_t *jobInfo){ return device_start_file(self, jobInfo); } @@ -2029,6 +2037,18 @@ SWIGINTERN DirectTCPConnection *Device_accept(Device *self){ } return conn; } +SWIGINTERN DirectTCPConnection *Device_accept_with_cond(Device *self,GMutex *abort_mutex,GCond *abort_cond){ + DirectTCPConnection *conn = NULL; + gboolean rv; + + rv = device_accept_with_cond(self, &conn, abort_mutex, abort_cond); + if (!rv && conn) { + /* conn is ref'd for our convenience, but we don't want it */ + g_object_unref(conn); + conn = NULL; + } + return conn; + } SWIGINTERN DirectTCPConnection *Device_connect(Device *self,gboolean for_writing,DirectTCPAddr *addrs){ DirectTCPConnection *conn = NULL; gboolean rv; @@ -2041,6 +2061,19 @@ SWIGINTERN DirectTCPConnection *Device_connect(Device *self,gboolean for_writing } return conn; } +SWIGINTERN DirectTCPConnection *Device_connect_with_cond(Device *self,gboolean for_writing,DirectTCPAddr *addrs,GMutex *abort_mutex,GCond *abort_cond){ + DirectTCPConnection *conn = NULL; + gboolean rv; + + rv = device_connect_with_cond(self, for_writing, addrs, &conn, + abort_mutex, abort_cond); + if (!rv && conn) { + /* conn is ref'd for our convenience, but we don't want it */ + g_object_unref(conn); + conn = NULL; + } + return conn; + } SWIGINTERN gboolean Device_use_connection(Device *self,DirectTCPConnection *conn){ return device_use_connection(self, conn); } @@ -2713,6 +2746,76 @@ XS(_wrap_Device_finish) { } +XS(_wrap_Device_get_bytes_read) { + { + Device *arg1 = (Device *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int argvi = 0; + guint64 result; + dXSARGS; + + if ((items < 1) || (items > 1)) { + SWIG_croak("Usage: Device_get_bytes_read(self);"); + } + res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_Device, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Device_get_bytes_read" "', argument " "1"" of type '" "Device *""'"); + } + arg1 = (Device *)(argp1); + result = Device_get_bytes_read(arg1); + { + SV *for_stack; + SP += argvi; PUTBACK; + for_stack = sv_2mortal(amglue_newSVu64(result)); + SPAGAIN; SP -= argvi; + ST(argvi) = for_stack; + argvi++; + } + + XSRETURN(argvi); + fail: + + SWIG_croak_null(); + } +} + + +XS(_wrap_Device_get_bytes_written) { + { + Device *arg1 = (Device *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int argvi = 0; + guint64 result; + dXSARGS; + + if ((items < 1) || (items > 1)) { + SWIG_croak("Usage: Device_get_bytes_written(self);"); + } + res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_Device, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Device_get_bytes_written" "', argument " "1"" of type '" "Device *""'"); + } + arg1 = (Device *)(argp1); + result = Device_get_bytes_written(arg1); + { + SV *for_stack; + SP += argvi; PUTBACK; + for_stack = sv_2mortal(amglue_newSVu64(result)); + SPAGAIN; SP -= argvi; + ST(argvi) = for_stack; + argvi++; + } + + XSRETURN(argvi); + fail: + + SWIG_croak_null(); + } +} + + XS(_wrap_Device_start_file) { { Device *arg1 = (Device *) 0 ; @@ -3171,6 +3274,54 @@ XS(_wrap_Device_accept) { } +XS(_wrap_Device_accept_with_cond) { + { + Device *arg1 = (Device *) 0 ; + GMutex *arg2 = (GMutex *) 0 ; + GCond *arg3 = (GCond *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + int argvi = 0; + DirectTCPConnection *result = 0 ; + dXSARGS; + + if ((items < 3) || (items > 3)) { + SWIG_croak("Usage: Device_accept_with_cond(self,abort_mutex,abort_cond);"); + } + res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_Device, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Device_accept_with_cond" "', argument " "1"" of type '" "Device *""'"); + } + arg1 = (Device *)(argp1); + res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_GMutex, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Device_accept_with_cond" "', argument " "2"" of type '" "GMutex *""'"); + } + arg2 = (GMutex *)(argp2); + res3 = SWIG_ConvertPtr(ST(2), &argp3,SWIGTYPE_p_GCond, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "Device_accept_with_cond" "', argument " "3"" of type '" "GCond *""'"); + } + arg3 = (GCond *)(argp3); + result = (DirectTCPConnection *)Device_accept_with_cond(arg1,arg2,arg3); + ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DirectTCPConnection, SWIG_OWNER | SWIG_SHADOW); argvi++ ; + + + + XSRETURN(argvi); + fail: + + + + SWIG_croak_null(); + } +} + + XS(_wrap_Device_connect) { { Device *arg1 = (Device *) 0 ; @@ -3244,6 +3395,104 @@ XS(_wrap_Device_connect) { + SWIG_croak_null(); + } +} + + +XS(_wrap_Device_connect_with_cond) { + { + Device *arg1 = (Device *) 0 ; + gboolean arg2 ; + DirectTCPAddr *arg3 = (DirectTCPAddr *) 0 ; + GMutex *arg4 = (GMutex *) 0 ; + GCond *arg5 = (GCond *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp4 = 0 ; + int res4 = 0 ; + void *argp5 = 0 ; + int res5 = 0 ; + int argvi = 0; + DirectTCPConnection *result = 0 ; + dXSARGS; + + if ((items < 5) || (items > 5)) { + SWIG_croak("Usage: Device_connect_with_cond(self,for_writing,addrs,abort_mutex,abort_cond);"); + } + res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_Device, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Device_connect_with_cond" "', argument " "1"" of type '" "Device *""'"); + } + arg1 = (Device *)(argp1); + { + arg2 = SvTRUE(ST(1)); + } + { + AV *addrs_av; + int num_addrs, i; + + if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV) { + SWIG_exception_fail(SWIG_TypeError, "must provide an arrayref of DirectTCPAddrs"); + } + addrs_av = (AV *)SvRV(ST(2)); + num_addrs = av_len(addrs_av)+1; + + arg3 = g_new0(DirectTCPAddr, num_addrs+1); + + for (i = 0; i < num_addrs; i++) { + SV **svp = av_fetch(addrs_av, i, 0); + AV *addr_av; + sockaddr_union addr; + IV port; + + if (!svp || !SvROK(*svp) || SvTYPE(SvRV(*svp)) != SVt_PVAV + || av_len((AV *)SvRV(*svp))+1 != 2) { + SWIG_exception_fail(SWIG_TypeError, "each DirectTCPAddr must be a 2-element arrayref"); + } + + addr_av = (AV *)SvRV(*svp); + + /* get address */ + svp = av_fetch(addr_av, 0, 0); + if (!svp || !SvPOK(*svp) || !str_to_sockaddr(SvPV_nolen(*svp), &addr)) { + SWIG_exception_fail(SWIG_TypeError, "invalid IPv4 addr in address"); + } + + /* get port */ + svp = av_fetch(addr_av, 1, 0); + if (!svp || !SvIOK(*svp) || (port = SvIV(*svp)) <= 0 || port >= 65536) { + SWIG_exception_fail(SWIG_TypeError, "invalid port in address"); + } + SU_SET_PORT(&addr, port); + + copy_sockaddr(arg3, &addr); + } + } + res4 = SWIG_ConvertPtr(ST(3), &argp4,SWIGTYPE_p_GMutex, 0 | 0 ); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "Device_connect_with_cond" "', argument " "4"" of type '" "GMutex *""'"); + } + arg4 = (GMutex *)(argp4); + res5 = SWIG_ConvertPtr(ST(4), &argp5,SWIGTYPE_p_GCond, 0 | 0 ); + if (!SWIG_IsOK(res5)) { + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "Device_connect_with_cond" "', argument " "5"" of type '" "GCond *""'"); + } + arg5 = (GCond *)(argp5); + result = (DirectTCPConnection *)Device_connect_with_cond(arg1,arg2,arg3,arg4,arg5); + ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DirectTCPConnection, SWIG_OWNER | SWIG_SHADOW); argvi++ ; + + + + + + XSRETURN(argvi); + fail: + + + + + SWIG_croak_null(); } } @@ -4409,6 +4658,8 @@ static swig_type_info _swigt__p_Device = {"_p_Device", "struct Device *|Device * static swig_type_info _swigt__p_DevicePropertyBase = {"_p_DevicePropertyBase", "DevicePropertyBase *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_DirectTCPAddr = {"_p_DirectTCPAddr", "DirectTCPAddr *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_DirectTCPConnection = {"_p_DirectTCPConnection", "struct DirectTCPConnection *|DirectTCPConnection *", 0, 0, (void*)"Amanda::Device::DirectTCPConnection", 0}; +static swig_type_info _swigt__p_GCond = {"_p_GCond", "GCond *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_GMutex = {"_p_GMutex", "GMutex *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_GSList = {"_p_GSList", "GSList *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_GValue = {"_p_GValue", "GValue *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_a_STRMAX__char = {"_p_a_STRMAX__char", "char (*)[STRMAX]|string_t *", 0, 0, (void*)0, 0}; @@ -4428,6 +4679,8 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_DevicePropertyBase, &_swigt__p_DirectTCPAddr, &_swigt__p_DirectTCPConnection, + &_swigt__p_GCond, + &_swigt__p_GMutex, &_swigt__p_GSList, &_swigt__p_GValue, &_swigt__p_a_STRMAX__char, @@ -4447,6 +4700,8 @@ static swig_cast_info _swigc__p_Device[] = { {&_swigt__p_Device, 0, 0, 0},{0, 0 static swig_cast_info _swigc__p_DevicePropertyBase[] = { {&_swigt__p_DevicePropertyBase, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_DirectTCPAddr[] = { {&_swigt__p_DirectTCPAddr, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_DirectTCPConnection[] = { {&_swigt__p_DirectTCPConnection, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_GCond[] = { {&_swigt__p_GCond, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_GMutex[] = { {&_swigt__p_GMutex, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_GSList[] = { {&_swigt__p_GSList, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_GValue[] = { {&_swigt__p_GValue, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_a_STRMAX__char[] = { {&_swigt__p_a_STRMAX__char, 0, 0, 0},{0, 0, 0, 0}}; @@ -4466,6 +4721,8 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_DevicePropertyBase, _swigc__p_DirectTCPAddr, _swigc__p_DirectTCPConnection, + _swigc__p_GCond, + _swigc__p_GMutex, _swigc__p_GSList, _swigc__p_GValue, _swigc__p_a_STRMAX__char, @@ -4507,6 +4764,8 @@ static swig_command_info swig_commands[] = { {"Amanda::Devicec::Device_read_label", _wrap_Device_read_label}, {"Amanda::Devicec::Device_start", _wrap_Device_start}, {"Amanda::Devicec::Device_finish", _wrap_Device_finish}, +{"Amanda::Devicec::Device_get_bytes_read", _wrap_Device_get_bytes_read}, +{"Amanda::Devicec::Device_get_bytes_written", _wrap_Device_get_bytes_written}, {"Amanda::Devicec::Device_start_file", _wrap_Device_start_file}, {"Amanda::Devicec::Device_write_block", _wrap_Device_write_block}, {"Amanda::Devicec::Device_finish_file", _wrap_Device_finish_file}, @@ -4518,7 +4777,9 @@ static swig_command_info swig_commands[] = { {"Amanda::Devicec::Device_directtcp_supported", _wrap_Device_directtcp_supported}, {"Amanda::Devicec::Device_listen", _wrap_Device_listen}, {"Amanda::Devicec::Device_accept", _wrap_Device_accept}, +{"Amanda::Devicec::Device_accept_with_cond", _wrap_Device_accept_with_cond}, {"Amanda::Devicec::Device_connect", _wrap_Device_connect}, +{"Amanda::Devicec::Device_connect_with_cond", _wrap_Device_connect_with_cond}, {"Amanda::Devicec::Device_use_connection", _wrap_Device_use_connection}, {"Amanda::Devicec::Device_write_from_connection", _wrap_Device_write_from_connection}, {"Amanda::Devicec::Device_read_to_connection", _wrap_Device_read_to_connection}, diff --git a/perl/Amanda/Device.pm b/perl/Amanda/Device.pm index cdd0af6..e6b49c8 100644 --- a/perl/Amanda/Device.pm +++ b/perl/Amanda/Device.pm @@ -125,6 +125,8 @@ sub DESTROY { *read_label = *Amanda::Devicec::Device_read_label; *start = *Amanda::Devicec::Device_start; *finish = *Amanda::Devicec::Device_finish; +*get_bytes_read = *Amanda::Devicec::Device_get_bytes_read; +*get_bytes_written = *Amanda::Devicec::Device_get_bytes_written; *start_file = *Amanda::Devicec::Device_start_file; *write_block = *Amanda::Devicec::Device_write_block; *finish_file = *Amanda::Devicec::Device_finish_file; @@ -136,7 +138,9 @@ sub DESTROY { *directtcp_supported = *Amanda::Devicec::Device_directtcp_supported; *listen = *Amanda::Devicec::Device_listen; *accept = *Amanda::Devicec::Device_accept; +*accept_with_cond = *Amanda::Devicec::Device_accept_with_cond; *connect = *Amanda::Devicec::Device_connect; +*connect_with_cond = *Amanda::Devicec::Device_connect_with_cond; *use_connection = *Amanda::Devicec::Device_use_connection; *write_from_connection = *Amanda::Devicec::Device_write_from_connection; *read_to_connection = *Amanda::Devicec::Device_read_to_connection; diff --git a/perl/Amanda/Device.pod b/perl/Amanda/Device.pod index 10d3f8b..3c8be7e 100644 --- a/perl/Amanda/Device.pod +++ b/perl/Amanda/Device.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Device.swg b/perl/Amanda/Device.swg index d400316..ea46300 100644 --- a/perl/Amanda/Device.swg +++ b/perl/Amanda/Device.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -284,6 +284,16 @@ typedef struct Device { return device_finish(self); } + guint64 + get_bytes_read() { + return device_get_bytes_read(self); + } + + guint64 + get_bytes_written() { + return device_get_bytes_written(self); + } + gboolean start_file(dumpfile_t *jobInfo) { return device_start_file(self, jobInfo); @@ -351,6 +361,21 @@ typedef struct Device { return conn; } + %newobject accept_with_cond; /* connection is already ref'd, so we own it */ + DirectTCPConnection * + accept_with_cond(GMutex *abort_mutex, GCond *abort_cond) { + DirectTCPConnection *conn = NULL; + gboolean rv; + + rv = device_accept_with_cond(self, &conn, abort_mutex, abort_cond); + if (!rv && conn) { + /* conn is ref'd for our convenience, but we don't want it */ + g_object_unref(conn); + conn = NULL; + } + return conn; + } + %newobject connect; /* connection is already ref'd, so we own it */ DirectTCPConnection * connect(gboolean for_writing, DirectTCPAddr *addrs) { @@ -366,6 +391,23 @@ typedef struct Device { return conn; } + %newobject connect_with_cond; /* connection is already ref'd, so we own it */ + DirectTCPConnection * + connect_with_cond(gboolean for_writing, DirectTCPAddr *addrs, + GMutex *abort_mutex, GCond *abort_cond) { + DirectTCPConnection *conn = NULL; + gboolean rv; + + rv = device_connect_with_cond(self, for_writing, addrs, &conn, + abort_mutex, abort_cond); + if (!rv && conn) { + /* conn is ref'd for our convenience, but we don't want it */ + g_object_unref(conn); + conn = NULL; + } + return conn; + } + gboolean use_connection(DirectTCPConnection *conn) { return device_use_connection(self, conn); diff --git a/perl/Amanda/Disklist.pod b/perl/Amanda/Disklist.pod index 230c2cb..f80cc6e 100644 --- a/perl/Amanda/Disklist.pod +++ b/perl/Amanda/Disklist.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Disklist.swg b/perl/Amanda/Disklist.swg index 9a6eb57..da65ae5 100644 --- a/perl/Amanda/Disklist.swg +++ b/perl/Amanda/Disklist.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Feature.pod b/perl/Amanda/Feature.pod index 7a6019d..c22e2a9 100644 --- a/perl/Amanda/Feature.pod +++ b/perl/Amanda/Feature.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Feature.swg b/perl/Amanda/Feature.swg index a66f39a..e21c1e0 100644 --- a/perl/Amanda/Feature.swg +++ b/perl/Amanda/Feature.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Header.c b/perl/Amanda/Header.c index 25b2bc5..faa12da 100644 --- a/perl/Amanda/Header.c +++ b/perl/Amanda/Header.c @@ -1509,19 +1509,19 @@ SWIG_Perl_SetModule(swig_module_info *module) { #define SWIGTYPE_p_GSList swig_types[0] #define SWIGTYPE_p_a_STRMAX__char swig_types[1] #define SWIGTYPE_p_a_dle_s swig_types[2] -#define SWIGTYPE_p_char swig_types[3] -#define SWIGTYPE_p_data_path_t swig_types[4] -#define SWIGTYPE_p_dle_t swig_types[5] -#define SWIGTYPE_p_double swig_types[6] -#define SWIGTYPE_p_dumpfile_t swig_types[7] -#define SWIGTYPE_p_estimatelist_t swig_types[8] -#define SWIGTYPE_p_float swig_types[9] -#define SWIGTYPE_p_int swig_types[10] -#define SWIGTYPE_p_levellist_t swig_types[11] -#define SWIGTYPE_p_off_t swig_types[12] -#define SWIGTYPE_p_proplist_t swig_types[13] -#define SWIGTYPE_p_scriptlist_t swig_types[14] -#define SWIGTYPE_p_sl_t swig_types[15] +#define SWIGTYPE_p_am_sl_t swig_types[3] +#define SWIGTYPE_p_char swig_types[4] +#define SWIGTYPE_p_data_path_t swig_types[5] +#define SWIGTYPE_p_dle_t swig_types[6] +#define SWIGTYPE_p_double swig_types[7] +#define SWIGTYPE_p_dumpfile_t swig_types[8] +#define SWIGTYPE_p_estimatelist_t swig_types[9] +#define SWIGTYPE_p_float swig_types[10] +#define SWIGTYPE_p_int swig_types[11] +#define SWIGTYPE_p_levellist_t swig_types[12] +#define SWIGTYPE_p_off_t swig_types[13] +#define SWIGTYPE_p_proplist_t swig_types[14] +#define SWIGTYPE_p_scriptlist_t swig_types[15] #define SWIGTYPE_p_unsigned_char swig_types[16] static swig_type_info *swig_types[18]; static swig_module_info swig_module = {swig_types, 17, 0, 0, 0, 0}; @@ -4213,7 +4213,7 @@ XS(_wrap_C_from_string) { } arg1 = (char *)(buf1); result = (dumpfile_t *)C_from_string((char const *)arg1); - ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_dumpfile_t, SWIG_OWNER | SWIG_SHADOW); argvi++ ; + ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_dumpfile_t, 0 | SWIG_SHADOW); argvi++ ; if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); XSRETURN(argvi); fail: @@ -5708,7 +5708,7 @@ XS(_wrap_HeaderXML_auth_get) { XS(_wrap_HeaderXML_exclude_file_set) { { dle_t *arg1 = (dle_t *) 0 ; - sl_t *arg2 = (sl_t *) 0 ; + am_sl_t *arg2 = (am_sl_t *) 0 ; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -5724,11 +5724,11 @@ XS(_wrap_HeaderXML_exclude_file_set) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_exclude_file_set" "', argument " "1"" of type '" "dle_t *""'"); } arg1 = (dle_t *)(argp1); - res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_sl_t, SWIG_POINTER_DISOWN | 0 ); + res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_am_sl_t, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_exclude_file_set" "', argument " "2"" of type '" "sl_t *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_exclude_file_set" "', argument " "2"" of type '" "am_sl_t *""'"); } - arg2 = (sl_t *)(argp2); + arg2 = (am_sl_t *)(argp2); if (arg1) (arg1)->exclude_file = arg2; ST(argvi) = sv_newmortal(); @@ -5748,7 +5748,7 @@ XS(_wrap_HeaderXML_exclude_file_get) { void *argp1 = 0 ; int res1 = 0 ; int argvi = 0; - sl_t *result = 0 ; + am_sl_t *result = 0 ; dXSARGS; if ((items < 1) || (items > 1)) { @@ -5759,8 +5759,8 @@ XS(_wrap_HeaderXML_exclude_file_get) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_exclude_file_get" "', argument " "1"" of type '" "dle_t *""'"); } arg1 = (dle_t *)(argp1); - result = (sl_t *) ((arg1)->exclude_file); - ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_sl_t, 0 | 0); argvi++ ; + result = (am_sl_t *) ((arg1)->exclude_file); + ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_am_sl_t, 0 | 0); argvi++ ; XSRETURN(argvi); fail: @@ -5773,7 +5773,7 @@ XS(_wrap_HeaderXML_exclude_file_get) { XS(_wrap_HeaderXML_exclude_list_set) { { dle_t *arg1 = (dle_t *) 0 ; - sl_t *arg2 = (sl_t *) 0 ; + am_sl_t *arg2 = (am_sl_t *) 0 ; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -5789,11 +5789,11 @@ XS(_wrap_HeaderXML_exclude_list_set) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_exclude_list_set" "', argument " "1"" of type '" "dle_t *""'"); } arg1 = (dle_t *)(argp1); - res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_sl_t, SWIG_POINTER_DISOWN | 0 ); + res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_am_sl_t, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_exclude_list_set" "', argument " "2"" of type '" "sl_t *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_exclude_list_set" "', argument " "2"" of type '" "am_sl_t *""'"); } - arg2 = (sl_t *)(argp2); + arg2 = (am_sl_t *)(argp2); if (arg1) (arg1)->exclude_list = arg2; ST(argvi) = sv_newmortal(); @@ -5813,7 +5813,7 @@ XS(_wrap_HeaderXML_exclude_list_get) { void *argp1 = 0 ; int res1 = 0 ; int argvi = 0; - sl_t *result = 0 ; + am_sl_t *result = 0 ; dXSARGS; if ((items < 1) || (items > 1)) { @@ -5824,8 +5824,8 @@ XS(_wrap_HeaderXML_exclude_list_get) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_exclude_list_get" "', argument " "1"" of type '" "dle_t *""'"); } arg1 = (dle_t *)(argp1); - result = (sl_t *) ((arg1)->exclude_list); - ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_sl_t, 0 | 0); argvi++ ; + result = (am_sl_t *) ((arg1)->exclude_list); + ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_am_sl_t, 0 | 0); argvi++ ; XSRETURN(argvi); fail: @@ -5838,7 +5838,7 @@ XS(_wrap_HeaderXML_exclude_list_get) { XS(_wrap_HeaderXML_include_file_set) { { dle_t *arg1 = (dle_t *) 0 ; - sl_t *arg2 = (sl_t *) 0 ; + am_sl_t *arg2 = (am_sl_t *) 0 ; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -5854,11 +5854,11 @@ XS(_wrap_HeaderXML_include_file_set) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_include_file_set" "', argument " "1"" of type '" "dle_t *""'"); } arg1 = (dle_t *)(argp1); - res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_sl_t, SWIG_POINTER_DISOWN | 0 ); + res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_am_sl_t, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_include_file_set" "', argument " "2"" of type '" "sl_t *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_include_file_set" "', argument " "2"" of type '" "am_sl_t *""'"); } - arg2 = (sl_t *)(argp2); + arg2 = (am_sl_t *)(argp2); if (arg1) (arg1)->include_file = arg2; ST(argvi) = sv_newmortal(); @@ -5878,7 +5878,7 @@ XS(_wrap_HeaderXML_include_file_get) { void *argp1 = 0 ; int res1 = 0 ; int argvi = 0; - sl_t *result = 0 ; + am_sl_t *result = 0 ; dXSARGS; if ((items < 1) || (items > 1)) { @@ -5889,8 +5889,8 @@ XS(_wrap_HeaderXML_include_file_get) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_include_file_get" "', argument " "1"" of type '" "dle_t *""'"); } arg1 = (dle_t *)(argp1); - result = (sl_t *) ((arg1)->include_file); - ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_sl_t, 0 | 0); argvi++ ; + result = (am_sl_t *) ((arg1)->include_file); + ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_am_sl_t, 0 | 0); argvi++ ; XSRETURN(argvi); fail: @@ -5903,7 +5903,7 @@ XS(_wrap_HeaderXML_include_file_get) { XS(_wrap_HeaderXML_include_list_set) { { dle_t *arg1 = (dle_t *) 0 ; - sl_t *arg2 = (sl_t *) 0 ; + am_sl_t *arg2 = (am_sl_t *) 0 ; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -5919,11 +5919,11 @@ XS(_wrap_HeaderXML_include_list_set) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_include_list_set" "', argument " "1"" of type '" "dle_t *""'"); } arg1 = (dle_t *)(argp1); - res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_sl_t, SWIG_POINTER_DISOWN | 0 ); + res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_am_sl_t, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_include_list_set" "', argument " "2"" of type '" "sl_t *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_include_list_set" "', argument " "2"" of type '" "am_sl_t *""'"); } - arg2 = (sl_t *)(argp2); + arg2 = (am_sl_t *)(argp2); if (arg1) (arg1)->include_list = arg2; ST(argvi) = sv_newmortal(); @@ -5943,7 +5943,7 @@ XS(_wrap_HeaderXML_include_list_get) { void *argp1 = 0 ; int res1 = 0 ; int argvi = 0; - sl_t *result = 0 ; + am_sl_t *result = 0 ; dXSARGS; if ((items < 1) || (items > 1)) { @@ -5954,8 +5954,8 @@ XS(_wrap_HeaderXML_include_list_get) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_include_list_get" "', argument " "1"" of type '" "dle_t *""'"); } arg1 = (dle_t *)(argp1); - result = (sl_t *) ((arg1)->include_list); - ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_sl_t, 0 | 0); argvi++ ; + result = (am_sl_t *) ((arg1)->include_list); + ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_am_sl_t, 0 | 0); argvi++ ; XSRETURN(argvi); fail: @@ -6559,6 +6559,7 @@ XS(_wrap_delete_HeaderXML) { static swig_type_info _swigt__p_GSList = {"_p_GSList", "GSList *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_a_STRMAX__char = {"_p_a_STRMAX__char", "char (*)[STRMAX]|string_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_a_dle_s = {"_p_a_dle_s", "struct a_dle_s *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_am_sl_t = {"_p_am_sl_t", "am_sl_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "gchar *|char *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_data_path_t = {"_p_data_path_t", "data_path_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_dle_t = {"_p_dle_t", "dle_t *", 0, 0, (void*)"Amanda::Header::HeaderXML", 0}; @@ -6571,13 +6572,13 @@ static swig_type_info _swigt__p_levellist_t = {"_p_levellist_t", "levellist_t *" static swig_type_info _swigt__p_off_t = {"_p_off_t", "off_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_proplist_t = {"_p_proplist_t", "proplist_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_scriptlist_t = {"_p_scriptlist_t", "scriptlist_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_sl_t = {"_p_sl_t", "sl_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "guchar *|unsigned char *", 0, 0, (void*)0, 0}; static swig_type_info *swig_type_initial[] = { &_swigt__p_GSList, &_swigt__p_a_STRMAX__char, &_swigt__p_a_dle_s, + &_swigt__p_am_sl_t, &_swigt__p_char, &_swigt__p_data_path_t, &_swigt__p_dle_t, @@ -6590,13 +6591,13 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_off_t, &_swigt__p_proplist_t, &_swigt__p_scriptlist_t, - &_swigt__p_sl_t, &_swigt__p_unsigned_char, }; static swig_cast_info _swigc__p_GSList[] = { {&_swigt__p_GSList, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_a_STRMAX__char[] = { {&_swigt__p_a_STRMAX__char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_a_dle_s[] = { {&_swigt__p_a_dle_s, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_am_sl_t[] = { {&_swigt__p_am_sl_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_data_path_t[] = { {&_swigt__p_data_path_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_dle_t[] = { {&_swigt__p_dle_t, 0, 0, 0},{0, 0, 0, 0}}; @@ -6609,13 +6610,13 @@ static swig_cast_info _swigc__p_levellist_t[] = { {&_swigt__p_levellist_t, 0, 0 static swig_cast_info _swigc__p_off_t[] = { {&_swigt__p_off_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_proplist_t[] = { {&_swigt__p_proplist_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_scriptlist_t[] = { {&_swigt__p_scriptlist_t, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_sl_t[] = { {&_swigt__p_sl_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info *swig_cast_initial[] = { _swigc__p_GSList, _swigc__p_a_STRMAX__char, _swigc__p_a_dle_s, + _swigc__p_am_sl_t, _swigc__p_char, _swigc__p_data_path_t, _swigc__p_dle_t, @@ -6628,7 +6629,6 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_off_t, _swigc__p_proplist_t, _swigc__p_scriptlist_t, - _swigc__p_sl_t, _swigc__p_unsigned_char, }; diff --git a/perl/Amanda/Header.pm b/perl/Amanda/Header.pm index d8cc692..3b01eac 100644 --- a/perl/Amanda/Header.pm +++ b/perl/Amanda/Header.pm @@ -482,7 +482,11 @@ sub from_string { sub get_dle { my $self = shift; - return Amanda::Header::HeaderXML->new($self->{'dle_str'}); + if ($self->{'dle_str'}) { + return Amanda::Header::HeaderXML->new($self->{'dle_str'}); + } else { + return undef; + } } package Amanda::Header::Header; diff --git a/perl/Amanda/Header.pod b/perl/Amanda/Header.pod index 40898af..8d4569f 100644 --- a/perl/Amanda/Header.pod +++ b/perl/Amanda/Header.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Header.swg b/perl/Amanda/Header.swg index a7d391b..f249d86 100644 --- a/perl/Amanda/Header.swg +++ b/perl/Amanda/Header.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -123,7 +123,6 @@ typedef struct { } } dumpfile_t; -%newobject C_from_string; %inline %{ static dumpfile_t *C_from_string(const char *string) { dumpfile_t *result = g_new(dumpfile_t, 1); @@ -151,7 +150,11 @@ sub from_string { sub get_dle { my $self = shift; - return Amanda::Header::HeaderXML->new($self->{'dle_str'}); + if ($self->{'dle_str'}) { + return Amanda::Header::HeaderXML->new($self->{'dle_str'}); + } else { + return undef; + } } package Amanda::Header::Header; @@ -192,10 +195,10 @@ typedef struct { int record; int create_index; char *auth; - sl_t *exclude_file; - sl_t *exclude_list; - sl_t *include_file; - sl_t *include_list; + am_sl_t *exclude_file; + am_sl_t *exclude_list; + am_sl_t *include_file; + am_sl_t *include_list; int exclude_optional; int include_optional; proplist_t application_property; diff --git a/perl/Amanda/Holding.pm b/perl/Amanda/Holding.pm index a0108fc..d29345d 100644 --- a/perl/Amanda/Holding.pm +++ b/perl/Amanda/Holding.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/IPC/Binary.pod b/perl/Amanda/IPC/Binary.pod index 34ede1c..945cffe 100644 --- a/perl/Amanda/IPC/Binary.pod +++ b/perl/Amanda/IPC/Binary.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/IPC/Binary.swg b/perl/Amanda/IPC/Binary.swg index f80b8f1..49459c0 100644 --- a/perl/Amanda/IPC/Binary.swg +++ b/perl/Amanda/IPC/Binary.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/IPC/LineProtocol.pm b/perl/Amanda/IPC/LineProtocol.pm index cc9b5d8..358501e 100644 --- a/perl/Amanda/IPC/LineProtocol.pm +++ b/perl/Amanda/IPC/LineProtocol.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Interactivity.pm b/perl/Amanda/Interactivity.pm index 25fe79d..23a2341 100644 --- a/perl/Amanda/Interactivity.pm +++ b/perl/Amanda/Interactivity.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Interactivity/email.pm b/perl/Amanda/Interactivity/email.pm index 648d969..f7b70aa 100644 --- a/perl/Amanda/Interactivity/email.pm +++ b/perl/Amanda/Interactivity/email.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Interactivity/stdin.pm b/perl/Amanda/Interactivity/stdin.pm index 2b67216..33a273f 100644 --- a/perl/Amanda/Interactivity/stdin.pm +++ b/perl/Amanda/Interactivity/stdin.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Interactivity/tty.pm b/perl/Amanda/Interactivity/tty.pm index f3a6904..2ba81a7 100644 --- a/perl/Amanda/Interactivity/tty.pm +++ b/perl/Amanda/Interactivity/tty.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Interactivity/tty_email.pm b/perl/Amanda/Interactivity/tty_email.pm index 851dc6c..21e2ecc 100644 --- a/perl/Amanda/Interactivity/tty_email.pm +++ b/perl/Amanda/Interactivity/tty_email.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010, 2011 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Logfile.pod b/perl/Amanda/Logfile.pod index 9c1286c..450d5a4 100644 --- a/perl/Amanda/Logfile.pod +++ b/perl/Amanda/Logfile.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Logfile.swg b/perl/Amanda/Logfile.swg index 07047a0..8d62870 100644 --- a/perl/Amanda/Logfile.swg +++ b/perl/Amanda/Logfile.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/MainLoop.pod b/perl/Amanda/MainLoop.pod index a47e9c5..3504f2b 100644 --- a/perl/Amanda/MainLoop.pod +++ b/perl/Amanda/MainLoop.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/MainLoop.swg b/perl/Amanda/MainLoop.swg index 6b66c45..457ff09 100644 --- a/perl/Amanda/MainLoop.swg +++ b/perl/Amanda/MainLoop.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/NDMP.pod b/perl/Amanda/NDMP.pod index 27d0a51..0efed0f 100644 --- a/perl/Amanda/NDMP.pod +++ b/perl/Amanda/NDMP.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/NDMP.swg b/perl/Amanda/NDMP.swg index b460c69..da63d4e 100644 --- a/perl/Amanda/NDMP.swg +++ b/perl/Amanda/NDMP.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Paths.pm.in b/perl/Amanda/Paths.pm.in index 0d94604..a3e0248 100644 --- a/perl/Amanda/Paths.pm.in +++ b/perl/Amanda/Paths.pm.in @@ -1,5 +1,5 @@ # vim:ft=perl -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Process.pm b/perl/Amanda/Process.pm index 8a03a47..01c6a7b 100644 --- a/perl/Amanda/Process.pm +++ b/perl/Amanda/Process.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Recovery/Clerk.pm b/perl/Amanda/Recovery/Clerk.pm index 7531421..39b3c20 100644 --- a/perl/Amanda/Recovery/Clerk.pm +++ b/perl/Amanda/Recovery/Clerk.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License version 2.1 as @@ -233,7 +233,7 @@ sub get_xfer_src { unless exists $params{$rq_param}; } - die "Clerk is already busy" if $self->{'xfer_state'}; + confess "Clerk is already busy" if $self->{'xfer_state'}; # set up a new xfer_state my $xfer_state = $self->{'xfer_state'} = { @@ -267,8 +267,8 @@ sub start_recovery { unless exists $params{$rq_param}; } - die "no xfer is in progress" unless $self->{'xfer_state'}; - die "get_xfer_src has not finished" + confess "no xfer is in progress" unless $self->{'xfer_state'}; + confess "get_xfer_src has not finished" if defined $self->{'xfer_state'}->{'xfer_src_cb'}; my $xfer_state = $self->{'xfer_state'}; @@ -302,7 +302,7 @@ sub quit { my %params = @_; my $finished_cb = $params{'finished_cb'}; - die "Cannot quit a Clerk while a transfer is in progress" + confess "Cannot quit a Clerk while a transfer is in progress" if $self->{'xfer_state'}; my $steps = define_steps @@ -340,7 +340,7 @@ sub _xmsg_part_done { my $next_label = $xfer_state->{'next_part'}->{'label'}; my $next_filenum = $xfer_state->{'next_part'}->{'filenum'}; - die "read incorrect filenum" + confess "read incorrect filenum" unless $next_filenum == $msg->{'fileno'}; $self->dbg("done reading file $next_filenum on '$next_label'"); @@ -374,6 +374,7 @@ sub _xmsg_done { return $xfer_state->{'recovery_cb'}->( result => $result, errors => $xfer_state->{'errors'}, + bytes_read => $xfer_state->{'xfer_src'}->get_bytes_read() ); } @@ -416,7 +417,7 @@ sub _maybe_start_part { # first, see if anything remains to be done if (!exists $xfer_state->{'dump'}{'parts'}[$xfer_state->{'next_part_idx'}]) { # this should not happen until the xfer is started.. - die "xfer should be running already" + confess "xfer should be running already" unless $xfer_state->{'xfer'}; # tell the source to generate EOF diff --git a/perl/Amanda/Recovery/Planner.pm b/perl/Amanda/Recovery/Planner.pm index a310062..22809be 100644 --- a/perl/Amanda/Recovery/Planner.pm +++ b/perl/Amanda/Recovery/Planner.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License version 2.1 as @@ -395,61 +395,121 @@ sub make_plan_from_filelist { unless exists $params{$rq_param}; } - # This is similarly tricky - in this case, we search for dumps matching - # both the dumpspec and the labels, filter that down to just the parts we - # want, and then check that only one dump remains. Then we look up that - # dump. - - my @labels; - my %files; - my @filelist = @{$params{'filelist'}}; - while (@filelist) { - my $label = shift @filelist; - push @labels, $label; - $files{$label} = shift @filelist; - } + my $steps = define_steps + cb_ref => \$params{'plan_cb'}; - my @parts = Amanda::DB::Catalog::get_parts( - $params{'dumpspec'}? (dumpspecs => [ $params{'dumpspec'} ]) : (), - labels => [ @labels ]); + step get_inventory => sub { + if (defined $params{'chg'} and $params{'chg'}->have_inventory()) { + return $params{'chg'}->inventory( inventory_cb => $steps->{'got_inventory'}); + } else { + return $steps->{'got_inventory'}->(undef, undef); + } + }; + step got_inventory => sub { + my ($err, $inventory) = @_; + + # This is similarly tricky - in this case, we search for dumps matching + # both the dumpspec and the labels, filter that down to just the parts we + # want, and then check that only one dump remains. Then we look up that + # dump. + + my @labels; + my %files; + my @filelist = @{$params{'filelist'}}; + while (@filelist) { + my $label = shift @filelist; + push @labels, $label; + $files{$label} = shift @filelist; + } - # filter down to the parts that match filelist (using %files) - @parts = grep { - my $filenum = $_->{'filenum'}; - grep { $_ == $filenum } @{$files{$_->{'label'}}}; - } @parts; + my @parts = Amanda::DB::Catalog::get_parts( + $params{'dumpspec'}? (dumpspecs => [ $params{'dumpspec'} ]) : (), + labels => [ @labels ]); - # extract the dumps, using a hash (on the perl identity of the dump) to - # ensure uniqueness - my %dumps = map { my $d = $_->{'dump'}; ($d, $d) } @parts; - my @dumps = values %dumps; + # filter down to the parts that match filelist (using %files) + @parts = grep { + my $filenum = $_->{'filenum'}; + grep { $_ == $filenum } @{$files{$_->{'label'}}}; + } @parts; - if (!@dumps) { - return $params{'plan_cb'}->( + # extract the dumps, using a hash (on the perl identity of the dump) to + # ensure uniqueness + my %dumps = map { my $d = $_->{'dump'}; ($d, $d) } @parts; + my @dumps = values %dumps; + + if (!@dumps) { + return $params{'plan_cb'}->( "Specified file list does not match dumpspec"); - } elsif (@dumps > 1) { - return $params{'plan_cb'}->( - "Specified file list matches multiple dumps; cannot continue recovery"); - } + } elsif (@dumps > 1) { + # Check if they are all for the same dump + my $dump_timestamp = $dumps[0]->{'dump_timestamp'}; + my $hostname = $dumps[0]->{'hostname'}; + my $diskname = $dumps[0]->{'diskname'}; + my $level = $dumps[0]->{'level'}; + my $orig_kb = $dumps[0]->{'orig_kb'}; + + foreach my $dump (@dumps) { + if ($dump_timestamp != $dump->{'dump_timestamp'} || + $hostname ne $dump->{'hostname'} || + $diskname ne $dump->{'diskname'} || + $level != $dump->{'level'} || + $orig_kb != $dump->{'orig_kb'}) { + return $params{'plan_cb'}->( + "Specified file list matches multiple dumps; cannot continue recovery"); + } + } - # now, because of the weak linking used by Amanda::DB::Catalog, we need to - # re-query for this dump. If we don't do this, the parts will all be - # garbage-collected when we hand back the plan. This is, chartiably, "less than - # ideal". Note that this has the side-effect of filling in any parts of the - # dump that were missing from the filelist. - @dumps = Amanda::DB::Catalog::get_dumps( - hostname => $dumps[0]->{'hostname'}, - diskname => $dumps[0]->{'diskname'}, - level => $dumps[0]->{'level'}, - dump_timestamp => $dumps[0]->{'dump_timestamp'}, - write_timestamp => $dumps[0]->{'write_timestamp'}, - dumpspecs => $params{'dumpspecs'}); - - # sanity check - die unless @dumps; - $self->{'dumps'} = [ $dumps[0] ]; + # I would prefer the Planner to return alternate dump and the Clerk + # choose which one to use + if (defined $inventory) { + for my $dump (@dumps) { + my $all_part_found = 0; + my $part_found = 1; + for my $part (@{$dump->{'parts'}}) { + next if !defined $part; + my $found = 0; + foreach my $sl (@$inventory) { + if (defined $sl->{'label'} and + $sl->{'label'} eq $part->{'label'}) { + $found = 1; + last; + } + } + if ($found == 0) { + $part_found = 0; + last; + } + } + if ($part_found == 1) { + @dumps = $dumps[0]; + last; + } + } + # the first one will be used + } else { + # will uses the first dump. + } + } - Amanda::MainLoop::call_later($params{'plan_cb'}, undef, $self); + # now, because of the weak linking used by Amanda::DB::Catalog, we need to + # re-query for this dump. If we don't do this, the parts will all be + # garbage-collected when we hand back the plan. This is, chartiably, "less + # than ideal". Note that this has the side-effect of filling in any parts of + # the dump that were missing from the filelist. + @dumps = Amanda::DB::Catalog::get_dumps( + hostname => $dumps[0]->{'hostname'}, + diskname => $dumps[0]->{'diskname'}, + level => $dumps[0]->{'level'}, + dump_timestamp => $dumps[0]->{'dump_timestamp'}, + write_timestamp => $dumps[0]->{'write_timestamp'}, + dumpspecs => $params{'dumpspecs'}); + + # sanity check + confess "no dumps" unless @dumps; + $self->{'dumps'} = [ $dumps[0] ]; + + Amanda::MainLoop::call_later($params{'plan_cb'}, undef, $self); + }; } sub split_dumps_per_part { diff --git a/perl/Amanda/Recovery/Scan.pm b/perl/Amanda/Recovery/Scan.pm index 5a9fa72..96ec8cf 100644 --- a/perl/Amanda/Recovery/Scan.pm +++ b/perl/Amanda/Recovery/Scan.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -283,8 +283,9 @@ sub find_volume { # check if label is in the inventory for my $i (0..(scalar(@$inventory)-1)) { my $sl = $inventory->[$i]; - if (defined $sl->{'label'} && - $sl->{'label'} eq $label) { + if (defined $sl->{'label'} and + $sl->{'label'} eq $label and + !defined $seen{$sl->{'slot'}}) { $slot_scanned = $sl->{'slot'}; if ($sl->{'reserved'}) { return $steps->{'handle_error'}->( @@ -521,7 +522,7 @@ sub find_volume { $scan_method = $self->{'scan_conf'}->{$err->{'reason'}}; } } else { - die("error not defined"); + confess("error not defined"); $scan_method = SCAN_ASK_POLL; } } @@ -561,7 +562,7 @@ sub find_volume { } elsif ($scan_method == SCAN_CONTINUE) { return $continue_cb->($err, undef); } else { - die("Invalid SCAN_* value:$err:$err->{'reason'}:$scan_method"); + confess("Invalid SCAN_* value:$err:$err->{'reason'}:$scan_method"); } }; @@ -591,7 +592,6 @@ sub find_volume { $interactivity_running = 0; $poll_src->remove() if defined $poll_src; $poll_src = undef; - $last_err = undef; if ($err) { if ($scan_running) { @@ -613,6 +613,7 @@ sub find_volume { if ($new_chg->isa("Amanda::Changer::Error")) { return $steps->{'scan_interactivity'}->("$new_chg"); } + $last_err = undef; $self->{'chg'}->quit(); $self->{'chg'} = $new_chg; %seen = (); diff --git a/perl/Amanda/Report.pm b/perl/Amanda/Report.pm index f94b0fc..8c51461 100644 --- a/perl/Amanda/Report.pm +++ b/perl/Amanda/Report.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Report/human.pm b/perl/Amanda/Report/human.pm index b40890a..1726fa1 100644 --- a/perl/Amanda/Report/human.pm +++ b/perl/Amanda/Report/human.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -21,6 +21,7 @@ package Amanda::Report::human; use strict; use warnings; +use Carp; use POSIX; use Data::Dumper; @@ -313,7 +314,7 @@ sub print_human_amreport my ( $self, $fh ) = @_; $fh ||= $self->{fh} - || die "error: no file handle given to print_human_amreport\n"; + || confess "error: no file handle given to print_human_amreport\n"; ## collect statistics $self->calculate_stats(); @@ -1510,9 +1511,9 @@ sub set_col_spec my $disp_unit = $self->{disp_unit}; $self->{col_spec} = [ - [ "HostName", 0, 12, 12, 0, "%-*.*s", "HOSTNAME" ], - [ "Disk", 1, 11, 11, 0, "%-*.*s", "DISK" ], - [ "Level", 1, 1, 1, 0, "%*.*d", "L" ], + [ "HostName", 0, 12, 12, 1, "%-*.*s", "HOSTNAME" ], + [ "Disk", 1, 11, 11, 1, "%-*.*s", "DISK" ], + [ "Level", 1, 1, 1, 1, "%*.*d", "L" ], [ "OrigKB", 1, 7, 0, 1, "%*.*f", "ORIG-" . $disp_unit . "B" ], [ "OutKB", 1, 7, 0, 1, "%*.*f", "OUT-" . $disp_unit . "B" ], [ "Compress", 1, 6, 1, 1, "%*.*f", "COMP%" ], @@ -1531,11 +1532,10 @@ sub apply_col_spec_override my ($self) = @_; my $col_spec = $self->{col_spec}; - my %col_spec_override = read_col_spec_override(); + my %col_spec_override = $self->read_col_spec_override(); foreach my $col (@$col_spec) { if ( my $col_override = $col_spec_override{ $col->[COLSPEC_NAME] } ) { - my $override_col_val_if_def = sub { my ( $field, $or_num ) = @_; if ( defined $col_override->[$or_num] @@ -1554,22 +1554,36 @@ sub apply_col_spec_override sub read_col_spec_override { - ## takes no arguments + my ($self) = @_; + my $col_spec_str = getconf($CNF_COLUMNSPEC) || return; my %col_spec_override = (); + my $col_spec = $self->{col_spec}; foreach (split(",", $col_spec_str)) { $_ =~ m/^(\w+) # field name =([-:\d]+) # field values $/x - or die "error: malformed columnspec string:$col_spec_str"; + or confess "error: malformed columnspec string:$col_spec_str"; my $field = $1; + my $found = 0; + + foreach my $col (@$col_spec) { + if (lc $field eq lc $col->[0]) { + $field = $col->[0]; + $found = 1; + } + } + if ($found == 0) { + die("Invalid field name: $field"); + } + my @field_values = split ':', $2; # too many values - die "error: malformed columnspec string:$col_spec_str" + confess "error: malformed columnspec string:$col_spec_str" if (@field_values > 3); # all values *should* be in the right place. If not enough diff --git a/perl/Amanda/Report/postscript.pm b/perl/Amanda/Report/postscript.pm index 2a8f589..f7c1555 100644 --- a/perl/Amanda/Report/postscript.pm +++ b/perl/Amanda/Report/postscript.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Report/xml.pm b/perl/Amanda/Report/xml.pm index 6b5ea50..51b1eac 100644 --- a/perl/Amanda/Report/xml.pm +++ b/perl/Amanda/Report/xml.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/ScanInventory.pm b/perl/Amanda/ScanInventory.pm index d47f675..f5d4d7b 100644 --- a/perl/Amanda/ScanInventory.pm +++ b/perl/Amanda/ScanInventory.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -264,10 +264,12 @@ sub _scan { $res->{device}->status == $DEVICE_STATUS_SUCCESS) { $label = $res->{device}->volume_label; } + my $relabeled = !defined($label) || $label !~ /$self->{'labelstr'}/; $self->_user_msg(slot_result => 1, slot => $slot_scanned, label => $label, err => $err, + relabeled => $relabeled, res => $res); if ($res) { my $f_type; @@ -500,7 +502,7 @@ sub _scan { return $result_cb->($err, $res); } $label = $res->{'device'}->volume_label; - if (!defined $label) { + if (!defined($label) || $label !~ /$self->{'labelstr'}/) { $res->get_meta_label(finished_cb => $steps->{'got_meta_label'}); return; } @@ -567,12 +569,13 @@ sub volume_is_labelable { err => $sl->{'device_error'}, slot => $slot); return 0; - } elsif ($dev_status & $DEVICE_STATUS_SUCCESS and + } elsif ($dev_status == $DEVICE_STATUS_SUCCESS and $f_type == $Amanda::Header::F_TAPESTART and $label !~ /$self->{'labelstr'}/) { if (!$autolabel->{'other_config'}) { $self->_user_msg(slot_result => 1, - other_config => 1, + label => $label, + does_not_match_labelstr => 1, slot => $slot); return 0; } diff --git a/perl/Amanda/Script.pm b/perl/Amanda/Script.pm index c8333d6..addd6f0 100644 --- a/perl/Amanda/Script.pm +++ b/perl/Amanda/Script.pm @@ -1,5 +1,5 @@ # vim:ft=perl -# Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Script_App.pm b/perl/Amanda/Script_App.pm index aac85e6..f0ce349 100644 --- a/perl/Amanda/Script_App.pm +++ b/perl/Amanda/Script_App.pm @@ -1,5 +1,5 @@ # vim:ft=perl -# Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Tapelist.c b/perl/Amanda/Tapelist.c index 1800253..611b085 100644 --- a/perl/Amanda/Tapelist.c +++ b/perl/Amanda/Tapelist.c @@ -1851,6 +1851,7 @@ XS(_wrap_list_new_tapes) { result = (char *)list_new_tapes(arg1); ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; + free((char*)result); XSRETURN(argvi); fail: diff --git a/perl/Amanda/Tapelist.pod b/perl/Amanda/Tapelist.pod index 1d26670..b696808 100644 --- a/perl/Amanda/Tapelist.pod +++ b/perl/Amanda/Tapelist.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Tapelist.swg b/perl/Amanda/Tapelist.swg index b514cac..0ce1987 100644 --- a/perl/Amanda/Tapelist.swg +++ b/perl/Amanda/Tapelist.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -269,6 +269,7 @@ sub _update_positions { %} char *get_last_reusable_tape_label(int skip); +%newobject list_new_tapes; char *list_new_tapes(int nb); /* C functions -- should be called *only* from within this module */ diff --git a/perl/Amanda/Taper/Controller.pm b/perl/Amanda/Taper/Controller.pm index f6c839f..a1a6c09 100644 --- a/perl/Amanda/Taper/Controller.pm +++ b/perl/Amanda/Taper/Controller.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Taper/Protocol.pm b/perl/Amanda/Taper/Protocol.pm index 89066ec..0475171 100644 --- a/perl/Amanda/Taper/Protocol.pm +++ b/perl/Amanda/Taper/Protocol.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Taper/Scan.pm b/perl/Amanda/Taper/Scan.pm index f757b9b..d8d7a41 100644 --- a/perl/Amanda/Taper/Scan.pm +++ b/perl/Amanda/Taper/Scan.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License version 2.1 as diff --git a/perl/Amanda/Taper/Scan/lexical.pm b/perl/Amanda/Taper/Scan/lexical.pm index c69279c..44c2b0e 100644 --- a/perl/Amanda/Taper/Scan/lexical.pm +++ b/perl/Amanda/Taper/Scan/lexical.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Taper/Scan/oldest.pm b/perl/Amanda/Taper/Scan/oldest.pm index a7945a8..c2bcb6d 100644 --- a/perl/Amanda/Taper/Scan/oldest.pm +++ b/perl/Amanda/Taper/Scan/oldest.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Taper/Scan/traditional.pm b/perl/Amanda/Taper/Scan/traditional.pm index 7c8235c..ec6e96b 100644 --- a/perl/Amanda/Taper/Scan/traditional.pm +++ b/perl/Amanda/Taper/Scan/traditional.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License version 2.1 as @@ -390,10 +390,42 @@ sub stage_2 { if (!defined $autolabel->{'template'} || $autolabel->{'template'} eq "") { - $self->_user_msg(slot_result => 1, - not_autolabel => 1, - slot => $slot, - res => $res); + if ($status & $DEVICE_STATUS_VOLUME_UNLABELED and + $dev->volume_header and + $dev->volume_header->{'type'} == $Amanda::Header::F_EMPTY) { + $self->_user_msg(slot_result => 1, + not_autolabel => 1, + empty => 1, + slot => $slot, + res => $res); + } elsif ($status & $DEVICE_STATUS_VOLUME_UNLABELED and + $dev->volume_header and + $dev->volume_header->{'type'} == $Amanda::Header::F_WEIRD) { + $self->_user_msg(slot_result => 1, + not_autolabel => 1, + non_amanda => 1, + slot => $slot, + res => $res); + } elsif ($status & $DEVICE_STATUS_VOLUME_ERROR) { + $self->_user_msg(slot_result => 1, + not_autolabel => 1, + volume_error => 1, + err => $dev->error_or_status(), + slot => $slot, + res => $res); + } elsif ($status != $DEVICE_STATUS_SUCCESS) { + $self->_user_msg(slot_result => 1, + not_autolabel => 1, + not_success => 1, + err => $dev->error_or_status(), + slot => $slot, + res => $res); + } else { + $self->_user_msg(slot_result => 1, + not_autolabel => 1, + slot => $slot, + res => $res); + } return $steps->{'try_continue'}->(); } diff --git a/perl/Amanda/Taper/Scribe.pm b/perl/Amanda/Taper/Scribe.pm index d135e3a..31831b7 100644 --- a/perl/Amanda/Taper/Scribe.pm +++ b/perl/Amanda/Taper/Scribe.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License version 2.1 as @@ -498,7 +498,7 @@ sub start { unless exists $params{$rq_param}; } - die "scribe already started" if $self->{'started'}; + confess "scribe already started" if $self->{'started'}; $self->dbg("starting"); $self->{'write_timestamp'} = $params{'write_timestamp'}; @@ -527,7 +527,7 @@ sub quit { $self->dbg("quitting"); if ($self->{'xfer'}) { - die "Scribe cannot quit while a transfer is active"; + confess "Scribe cannot quit while a transfer is active"; # Supporting this would be complicated: # - cancel the xfer and wait for it to complete # - ensure that the taperscan not be started afterward @@ -590,7 +590,7 @@ sub check_data_path { my $device = $self->get_device(); if (!defined $device) { - die "no device is available to check the datapath"; + confess "no device is available to check the datapath"; } my $use_directtcp = $device->directtcp_supported(); @@ -622,11 +622,11 @@ sub get_xfer_dest { unless exists $params{$rq_param}; } - die "not yet started" + confess "not yet started" unless $self->{'write_timestamp'} and $self->{'started'}; - die "xfer element already returned" + confess "xfer element already returned" if ($self->{'xdt'}); - die "xfer already running" + confess "xfer already running" if ($self->{'xfer'}); $self->{'xfer'} = undef; @@ -656,7 +656,7 @@ sub get_xfer_dest { my $xdt_first_dev = $self->get_device(); if (!defined $xdt_first_dev) { - die "no device is available to create an xfer_dest"; + confess "no device is available to create an xfer_dest"; } my $leom_supported = $xdt_first_dev->property_get("leom"); my $use_directtcp = $xdt_first_dev->directtcp_supported(); @@ -747,7 +747,7 @@ sub start_dump { my $self = shift; my %params = @_; - die "no xfer dest set up; call get_xfer_dest first" + confess "no xfer dest set up; call get_xfer_dest first" unless defined $self->{'xdt'}; # get the header ready for writing (totalparts was set by the caller) @@ -767,29 +767,17 @@ sub cancel_dump { my $self = shift; my %params = @_; - die "no xfer dest set up; call get_xfer_dest first" + confess "no xfer dest set up; call get_xfer_dest first" unless defined $self->{'xdt'}; # set up the dump_cb for when this dump is done, and keep the xfer $self->{'dump_cb'} = $params{'dump_cb'}; $self->{'xfer'} = $params{'xfer'}; - # XXX The cancel should call dump_cb, but right now the xfer stays hung in - # accept. So we leave the xfer to its hang, and dump_cb is called and xdt - # and xfer are set to undef. This should be fixed in 3.2. + # The cancel will can dump_cb. $self->{'xfer'}->cancel(); - $self->{'dump_cb'}->( - result => "FAILED", - device_errors => [], - config_denial_message => undef, - size => 0, - duration => 0.0, - total_duration => 0, - nparts => 0); - $self->{'xdt'} = undef; - $self->{'xfer'} = undef; } sub close_volume { @@ -886,7 +874,7 @@ sub _xmsg_part_done { $self->dbg("not notifying for empty, successful part"); } else { # double-check partnum - die "Part numbers do not match!" + confess "Part numbers do not match!" unless ($self->{'dump_header'}->{'partnum'} == $msg->{'partnum'}); # notify @@ -1067,7 +1055,7 @@ sub _operation_failed { # _dump_done constructs the dump_cb from $self parameters $self->_dump_done(); } else { - die "error with no callback to handle it: $error_message"; + confess "error with no callback to handle it: $error_message"; } } } @@ -1386,10 +1374,14 @@ sub _device_start { $reservation->{'barcode'}); $tl->write(); $self->dbg("generate new label '$new_label'"); - } elsif (!defined $meta) { + } else { $tl->reload(0); my $tle = $tl->lookup_tapelabel($new_label); - my $meta = $tle->{'meta'}; + $meta = $tle->{'meta'} if !defined $meta && $tle->{'meta'}; + my $barcode = $tle->{'barcode'}; + if (defined $barcode and $barcode ne $reservation->{'barcode'}) { + return $finished_cb->("tapelist for label '$new_label' have barcode '$barcode' but changer report '" . $reservation->{'barcode'} . "'"); + } } # write the label to the device @@ -1689,7 +1681,7 @@ sub get_volume { my $self = shift; my (%params) = @_; - die "already processing a volume request" + confess "already processing a volume request" if ($self->{'volume_cb'}); $self->{'volume_cb'} = $params{'volume_cb'}; @@ -1742,6 +1734,21 @@ sub _start_scanning { if ($params{'label'}) { $self->{'feedback'}->scribe_notif_log_info( message => "Slot $params{'slot'} with label $params{'label'} is not labelable "); + } elsif ($params{'empty'}) { + $self->{'feedback'}->scribe_notif_log_info( + message => "Slot $params{'slot'} is empty, autolabel not set"); + } elsif ($params{'non_amanda'}) { + $self->{'feedback'}->scribe_notif_log_info( + message => "Slot $params{'slot'} is a non-amanda volume, autolabel not set"); + } elsif ($params{'volume_error'}) { + $self->{'feedback'}->scribe_notif_log_info( + message => "Slot $params{'slot'} is a volume in error: $params{'err'}, autolabel not set"); + } elsif ($params{'not_success'}) { + $self->{'feedback'}->scribe_notif_log_info( + message => "Slot $params{'slot'} is a device in error: $params{'err'}, autolabel not set"); + } elsif ($params{'err'}) { + $self->{'feedback'}->scribe_notif_log_info( + message => "$params{'err'}"); } else { $self->{'feedback'}->scribe_notif_log_info( message => "Slot $params{'slot'} without label is not labelable "); @@ -1767,6 +1774,9 @@ sub _start_scanning { } elsif (!defined $params{'label'}) { $self->{'feedback'}->scribe_notif_log_info( message => "Slot $params{'slot'} without label can be labeled"); + } elsif ($params{'relabeled'}) { + $self->{'feedback'}->scribe_notif_log_info( + message => "Slot $params{'slot'} with label $params{'label'} will be relabeled"); } else { $self->{'feedback'}->scribe_notif_log_info( message => "Slot $params{'slot'} with label $params{'label'} is usable"); @@ -1817,10 +1827,10 @@ sub _start_request { } elsif ($params{'cause'} eq 'error') { $self->{'error_denial_message'} = $params{'message'}; } else { - die "bad cause '" . $params{'cause'} . "'"; + confess "bad cause '" . $params{'cause'} . "'"; } } elsif (!defined $params{'allow'}) { - die "no allow or cause defined"; + confess "no allow or cause defined"; } $self->_maybe_callback(); diff --git a/perl/Amanda/Taper/Worker.pm b/perl/Amanda/Taper/Worker.pm index 7e6b9ea..d8802be 100644 --- a/perl/Amanda/Taper/Worker.pm +++ b/perl/Amanda/Taper/Worker.pm @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -38,6 +38,7 @@ use warnings; package Amanda::Taper::Worker; +use Carp; use POSIX qw( :errno_h ); use Amanda::Changer; use Amanda::Config qw( :getconf config_dir_relative ); @@ -221,11 +222,14 @@ sub DONE { my $self = shift; my ($msgtype, %params) = @_; - $self->_assert_in_state("writing") or return; - $self->{'dumper_status'} = "DONE"; - $self->{'orig_kb'} = $params{'orig_kb'}; - if (defined $self->{'result'}) { - $self->result_cb(undef); + if (!defined $self->{'dumper_status'}) { + $self->{'dumper_status'} = "DONE"; + $self->{'orig_kb'} = $params{'orig_kb'}; + if (defined $self->{'result'}) { + $self->result_cb(undef); + } + } else { + # ignore the message } } @@ -233,11 +237,20 @@ sub FAILED { my $self = shift; my ($msgtype, %params) = @_; - $self->_assert_in_state("writing") or return; - $self->{'dumper_status'} = "FAILED"; - if (defined $self->{'result'}) { + if (defined $self->{'header_xfer'}) { + $self->{'header_xfer'}->cancel(); + } elsif (defined $self->{'result'}) { $self->result_cb(undef); + } elsif (!defined $self->{'scribe'}->{'xdt'}) { + # ignore, the dump is already cancelled or not yet started. + } elsif (!defined $self->{'scribe'}->{'xfer'}) { + # ignore, the dump is already cancelled or not yet started. + } else { # Abort the dump + push @{$self->{'input_errors'}}, "dumper failed"; + $self->{'scribe'}->cancel_dump( + xfer => $self->{'scribe'}->{'xfer'}, + dump_cb => $self->{'dump_cb'}); } } @@ -488,7 +501,7 @@ sub create_status_file { $self->{timer}->set_callback(sub { my $size = $self->{scribe}->get_bytes_written(); seek $self->{status_fh}, 0, 0; - print {$self->{status_fh}} $size; + print {$self->{status_fh}} $size, ' '; $self->{status_fh}->flush(); }); } @@ -497,7 +510,6 @@ sub send_port_and_get_header { my $self = shift; my ($finished_cb) = @_; - my $header_xfer; my ($xsrc, $xdst); my $errmsg; @@ -517,8 +529,8 @@ sub send_port_and_get_header { ($xsrc, $xdst) = ( Amanda::Xfer::Source::DirectTCPListen->new(), Amanda::Xfer::Dest::Buffer->new(0)); - $header_xfer = Amanda::Xfer->new([$xsrc, $xdst]); - $header_xfer->start($steps->{'header_xfer_xmsg_cb'}); + $self->{'header_xfer'} = Amanda::Xfer->new([$xsrc, $xdst]); + $self->{'header_xfer'}->start($steps->{'header_xfer_xmsg_cb'}); my $header_addrs = $xsrc->get_addrs(); my $header_port = $header_addrs->[0][1]; @@ -550,7 +562,7 @@ sub send_port_and_get_header { my $hdr_buf = $xdst->get(); # close stuff up - $header_xfer = $xsrc = $xdst = undef; + $self->{'header_xfer'} = $xsrc = $xdst = undef; if (!defined $hdr_buf) { return $finished_cb->("Got empty header"); @@ -570,6 +582,8 @@ sub setup_and_start_dump { my ($msgtype, %params) = @_; my %get_xfer_dest_args; + $self->{'dump_cb'} = $params{'dump_cb'}; + # setting up the dump is a bit complex, due to the requirements of # a directtcp port_write. This function: # 1. creates and starts a transfer (make_xfer) @@ -618,7 +632,7 @@ sub setup_and_start_dump { my $device = $self->{'scribe'}->get_device(); if (!defined $device) { - die "no device is available to create an xfer_dest"; + confess "no device is available to create an xfer_dest"; } $splitting_args{'leom_supported'} = $device->property_get("leom"); # and convert those to get_xfer_dest args @@ -690,7 +704,7 @@ sub setup_and_start_dump { $hdr->{'cont_filename'} = ''; if (!defined $hdr || $hdr->{'type'} != $Amanda::Header::F_DUMPFILE) { - die("Could not read header from '$params{filename}'"); + confess("Could not read header from '$params{filename}'"); } $steps->{'start_dump'}->(undef); } else { @@ -721,7 +735,7 @@ sub setup_and_start_dump { or $hdr->{'name'} ne $params{'hostname'} or $hdr->{'disk'} ne $params{'diskname'} or $hdr->{'datestamp'} ne $params{'datestamp'}) { - die("Header of dumpfile does not match command from driver"); + confess("Header of dumpfile does not match command from driver"); } # start producing status diff --git a/perl/Amanda/Tests.pod b/perl/Amanda/Tests.pod index 8876cf6..27c192c 100644 --- a/perl/Amanda/Tests.pod +++ b/perl/Amanda/Tests.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Tests.swg b/perl/Amanda/Tests.swg index 0877e37..6f83449 100644 --- a/perl/Amanda/Tests.swg +++ b/perl/Amanda/Tests.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Util.c b/perl/Amanda/Util.c index 164245d..4357d9f 100644 --- a/perl/Amanda/Util.c +++ b/perl/Amanda/Util.c @@ -2063,6 +2063,7 @@ XS(_wrap_sanitise_filename) { result = (char *)sanitise_filename(arg1); ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + free((char*)result); XSRETURN(argvi); fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); @@ -2092,6 +2093,7 @@ XS(_wrap_quote_string) { result = (char *)quote_string(arg1); ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + free((char*)result); XSRETURN(argvi); fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); @@ -2121,6 +2123,7 @@ XS(_wrap_unquote_string) { result = (char *)unquote_string(arg1); ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + free((char*)result); XSRETURN(argvi); fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); @@ -2249,8 +2252,10 @@ XS(_wrap_split_quoted_strings) { for (iter = result; *iter; iter++) { ST(argvi) = sv_2mortal(newSVpv(*iter, 0)); + g_free(*iter); argvi++; } + g_free(result); } } if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); diff --git a/perl/Amanda/Util.pod b/perl/Amanda/Util.pod index 1b45a8c..ef97b3e 100644 --- a/perl/Amanda/Util.pod +++ b/perl/Amanda/Util.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Util.swg b/perl/Amanda/Util.swg index e325a9e..43c4a99 100644 --- a/perl/Amanda/Util.swg +++ b/perl/Amanda/Util.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -315,8 +315,10 @@ sub safe_overwrite_file { for (iter = $1; *iter; iter++) { $result = sv_2mortal(newSVpv(*iter, 0)); + g_free(*iter); argvi++; } + g_free($1); } } @@ -338,12 +340,16 @@ char *perl_hexdecode_string(const char *str) { %} amglue_export_tag(encoding, hexencode hexdecode); +%newobject sanitise_filename; char *sanitise_filename(char *inp); +%newobject quote_string; char *quote_string(char *); +%newobject unquote_string; char *unquote_string(char *); GPtrArray *expand_braced_alternates(char *); %newobject collapse_braced_alternates; char *collapse_braced_alternates(GPtrArray *source); +%newobject split_quoted_strings; gchar **split_quoted_strings(const gchar *string); amglue_export_tag(quoting, quote_string unquote_string skip_quoted_string sanitise_filename split_quoted_strings split_quoted_strings_friendly); @@ -443,6 +449,7 @@ set_blocking(int fd, gboolean blocking) typedef struct file_lock { %extend { + %newobject file_lock; file_lock(const char *filename) { return file_lock_new(filename); } diff --git a/perl/Amanda/Xfer.pod b/perl/Amanda/Xfer.pod index f449b51..913ce4c 100644 --- a/perl/Amanda/Xfer.pod +++ b/perl/Amanda/Xfer.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/Xfer.swg b/perl/Amanda/Xfer.swg index 31c5b7d..c5b0fd9 100644 --- a/perl/Amanda/Xfer.swg +++ b/perl/Amanda/Xfer.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/XferServer.c b/perl/Amanda/XferServer.c index 4e4e80d..3ab6e64 100644 --- a/perl/Amanda/XferServer.c +++ b/perl/Amanda/XferServer.c @@ -1946,6 +1946,37 @@ XS(_wrap_xfer_source_holding) { } +XS(_wrap_xfer_source_holding_get_bytes_read) { + { + XferElement *arg1 = (XferElement *) 0 ; + int argvi = 0; + guint64 result; + dXSARGS; + + if ((items < 1) || (items > 1)) { + SWIG_croak("Usage: xfer_source_holding_get_bytes_read(self);"); + } + { + arg1 = xfer_element_from_sv(ST(0)); + } + result = xfer_source_holding_get_bytes_read(arg1); + { + SV *for_stack; + SP += argvi; PUTBACK; + for_stack = sv_2mortal(amglue_newSVu64(result)); + SPAGAIN; SP -= argvi; + ST(argvi) = for_stack; + argvi++; + } + + XSRETURN(argvi); + fail: + + SWIG_croak_null(); + } +} + + XS(_wrap_xfer_dest_taper_splitter) { { Device *arg1 = (Device *) 0 ; @@ -2380,6 +2411,37 @@ XS(_wrap_xfer_source_recovery_use_device) { } +XS(_wrap_xfer_source_recovery_get_bytes_read) { + { + XferElement *arg1 = (XferElement *) 0 ; + int argvi = 0; + guint64 result; + dXSARGS; + + if ((items < 1) || (items > 1)) { + SWIG_croak("Usage: xfer_source_recovery_get_bytes_read(self);"); + } + { + arg1 = xfer_element_from_sv(ST(0)); + } + result = xfer_source_recovery_get_bytes_read(arg1); + { + SV *for_stack; + SP += argvi; PUTBACK; + for_stack = sv_2mortal(amglue_newSVu64(result)); + SPAGAIN; SP -= argvi; + ST(argvi) = for_stack; + argvi++; + } + + XSRETURN(argvi); + fail: + + SWIG_croak_null(); + } +} + + /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ @@ -2459,6 +2521,7 @@ static swig_command_info swig_commands[] = { {"Amanda::XferServerc::xfer_source_device", _wrap_xfer_source_device}, {"Amanda::XferServerc::xfer_dest_device", _wrap_xfer_dest_device}, {"Amanda::XferServerc::xfer_source_holding", _wrap_xfer_source_holding}, +{"Amanda::XferServerc::xfer_source_holding_get_bytes_read", _wrap_xfer_source_holding_get_bytes_read}, {"Amanda::XferServerc::xfer_dest_taper_splitter", _wrap_xfer_dest_taper_splitter}, {"Amanda::XferServerc::xfer_dest_taper_cacher", _wrap_xfer_dest_taper_cacher}, {"Amanda::XferServerc::xfer_dest_taper_directtcp", _wrap_xfer_dest_taper_directtcp}, @@ -2469,6 +2532,7 @@ static swig_command_info swig_commands[] = { {"Amanda::XferServerc::xfer_source_recovery", _wrap_xfer_source_recovery}, {"Amanda::XferServerc::xfer_source_recovery_start_part", _wrap_xfer_source_recovery_start_part}, {"Amanda::XferServerc::xfer_source_recovery_use_device", _wrap_xfer_source_recovery_use_device}, +{"Amanda::XferServerc::xfer_source_recovery_get_bytes_read", _wrap_xfer_source_recovery_get_bytes_read}, {0,0} }; /* ----------------------------------------------------------------------------- diff --git a/perl/Amanda/XferServer.pm b/perl/Amanda/XferServer.pm index a1d30ff..0c9c553 100644 --- a/perl/Amanda/XferServer.pm +++ b/perl/Amanda/XferServer.pm @@ -56,6 +56,7 @@ package Amanda::XferServer; *xfer_source_device = *Amanda::XferServerc::xfer_source_device; *xfer_dest_device = *Amanda::XferServerc::xfer_dest_device; *xfer_source_holding = *Amanda::XferServerc::xfer_source_holding; +*xfer_source_holding_get_bytes_read = *Amanda::XferServerc::xfer_source_holding_get_bytes_read; *xfer_dest_taper_splitter = *Amanda::XferServerc::xfer_dest_taper_splitter; *xfer_dest_taper_cacher = *Amanda::XferServerc::xfer_dest_taper_cacher; *xfer_dest_taper_directtcp = *Amanda::XferServerc::xfer_dest_taper_directtcp; @@ -66,6 +67,7 @@ package Amanda::XferServer; *xfer_source_recovery = *Amanda::XferServerc::xfer_source_recovery; *xfer_source_recovery_start_part = *Amanda::XferServerc::xfer_source_recovery_start_part; *xfer_source_recovery_use_device = *Amanda::XferServerc::xfer_source_recovery_use_device; +*xfer_source_recovery_get_bytes_read = *Amanda::XferServerc::xfer_source_recovery_get_bytes_read; # ------- VARIABLE STUBS -------- @@ -122,6 +124,7 @@ sub new { Amanda::XferServer::xfer_source_holding(@_); } +*get_bytes_read = *Amanda::XferServer::xfer_source_holding_get_bytes_read; package Amanda::Xfer::Dest::Taper; @@ -181,4 +184,5 @@ sub new { } *start_part = *Amanda::XferServer::xfer_source_recovery_start_part; *use_device = *Amanda::XferServer::xfer_source_recovery_use_device; +*get_bytes_read = *Amanda::XferServer::xfer_source_recovery_get_bytes_read; 1; diff --git a/perl/Amanda/XferServer.pod b/perl/Amanda/XferServer.pod index c8707df..054bf93 100644 --- a/perl/Amanda/XferServer.pod +++ b/perl/Amanda/XferServer.pod @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/Amanda/XferServer.swg b/perl/Amanda/XferServer.swg index becc579..4f25a21 100644 --- a/perl/Amanda/XferServer.swg +++ b/perl/Amanda/XferServer.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -47,6 +47,9 @@ XferElement *xfer_dest_device( XferElement * xfer_source_holding( const char *filename); +guint64 xfer_source_holding_get_bytes_read( + XferElement *self); + %newobject xfer_dest_taper_splitter; XferElement *xfer_dest_taper_splitter( Device *first_device, @@ -96,6 +99,10 @@ void xfer_source_recovery_use_device( XferElement *self, Device *device); +guint64 xfer_source_recovery_get_bytes_read( + XferElement *self); + + /* ---- */ PACKAGE(Amanda::Xfer::Source::Device) @@ -113,6 +120,7 @@ DECLARE_CONSTRUCTOR(Amanda::XferServer::xfer_dest_device) PACKAGE(Amanda::Xfer::Source::Holding) XFER_ELEMENT_SUBCLASS() DECLARE_CONSTRUCTOR(Amanda::XferServer::xfer_source_holding) +DECLARE_METHOD(get_bytes_read, Amanda::XferServer::xfer_source_holding_get_bytes_read) /* ---- */ @@ -148,3 +156,5 @@ XFER_ELEMENT_SUBCLASS() DECLARE_CONSTRUCTOR(Amanda::XferServer::xfer_source_recovery) DECLARE_METHOD(start_part, Amanda::XferServer::xfer_source_recovery_start_part) DECLARE_METHOD(use_device, Amanda::XferServer::xfer_source_recovery_use_device) +DECLARE_METHOD(get_bytes_read, Amanda::XferServer::xfer_source_recovery_get_bytes_read) + diff --git a/perl/Makefile.am b/perl/Makefile.am index 7c953c1..cdf7eb1 100644 --- a/perl/Makefile.am +++ b/perl/Makefile.am @@ -526,7 +526,7 @@ EXTRA_DIST += Amanda/Application/Zfs.pm if WANT_CYGWIN_COPY_PERL_DLL amperldirauto="$(DESTDIR)$(amperldir)/auto/Amanda" install-data-hook: - @for cygdll in $(amperldirauto)/bin/cyg*.dll; do \ + @for cygdll in $(wildcard $(amperldirauto)/bin/cyg*.dll); do \ destfname=`echo $$cygdll|sed 's!/bin/cyg\([^.]*\).dll!/\1/\1.dll!'`; \ cp "$$cygdll" "$$destfname"; \ done diff --git a/perl/Makefile.in b/perl/Makefile.in index 87e58ab..241fcc5 100644 --- a/perl/Makefile.in +++ b/perl/Makefile.in @@ -16,7 +16,7 @@ @SET_MAKE@ # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -38,7 +38,7 @@ # scripts in this directory. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -327,7 +327,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -1148,6 +1149,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ @@ -3411,7 +3415,7 @@ html: make_html amperl.css $(PM_FILES) # PACKAGE: Amanda::Feature Amanda/Feature.pm: ../common-src/amfeatures.h @WANT_CYGWIN_COPY_PERL_DLL_TRUE@install-data-hook: -@WANT_CYGWIN_COPY_PERL_DLL_TRUE@ @for cygdll in $(amperldirauto)/bin/cyg*.dll; do \ +@WANT_CYGWIN_COPY_PERL_DLL_TRUE@ @for cygdll in $(wildcard $(amperldirauto)/bin/cyg*.dll); do \ @WANT_CYGWIN_COPY_PERL_DLL_TRUE@ destfname=`echo $$cygdll|sed 's!/bin/cyg\([^.]*\).dll!/\1/\1.dll!'`; \ @WANT_CYGWIN_COPY_PERL_DLL_TRUE@ cp "$$cygdll" "$$destfname"; \ @WANT_CYGWIN_COPY_PERL_DLL_TRUE@ done diff --git a/perl/amglue/Makefile.in b/perl/amglue/Makefile.in index f12ba03..9514960 100644 --- a/perl/amglue/Makefile.in +++ b/perl/amglue/Makefile.in @@ -16,7 +16,7 @@ @SET_MAKE@ # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -38,7 +38,7 @@ # scripts in this directory. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -280,7 +280,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -841,6 +842,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/perl/amglue/amglue.h b/perl/amglue/amglue.h index 9dab77c..67184d0 100644 --- a/perl/amglue/amglue.h +++ b/perl/amglue/amglue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/amglue.swg b/perl/amglue/amglue.swg index f5f3b9a..0949025 100644 --- a/perl/amglue/amglue.swg +++ b/perl/amglue/amglue.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/bigint.c b/perl/amglue/bigint.c index a46c508..33c5a5f 100644 --- a/perl/amglue/bigint.c +++ b/perl/amglue/bigint.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/constants.swg b/perl/amglue/constants.swg index f194ef2..556ed83 100644 --- a/perl/amglue/constants.swg +++ b/perl/amglue/constants.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/directtcp.swg b/perl/amglue/directtcp.swg index 641b918..27d7830 100644 --- a/perl/amglue/directtcp.swg +++ b/perl/amglue/directtcp.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/dumpspecs.swg b/perl/amglue/dumpspecs.swg index 7467874..5a0eba5 100644 --- a/perl/amglue/dumpspecs.swg +++ b/perl/amglue/dumpspecs.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/exports.swg b/perl/amglue/exports.swg index 7b74f95..19b792b 100644 --- a/perl/amglue/exports.swg +++ b/perl/amglue/exports.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/filehandles.swg b/perl/amglue/filehandles.swg index b8b6f53..6499886 100644 --- a/perl/amglue/filehandles.swg +++ b/perl/amglue/filehandles.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/ghashtable.c b/perl/amglue/ghashtable.c index 50d493f..679cf2b 100644 --- a/perl/amglue/ghashtable.c +++ b/perl/amglue/ghashtable.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/glib.swg b/perl/amglue/glib.swg index 2c1ce07..3844b6e 100644 --- a/perl/amglue/glib.swg +++ b/perl/amglue/glib.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/integers.swg b/perl/amglue/integers.swg index 32b7717..038906a 100644 --- a/perl/amglue/integers.swg +++ b/perl/amglue/integers.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/objwrap.c b/perl/amglue/objwrap.c index 29e95f2..5ce1eda 100644 --- a/perl/amglue/objwrap.c +++ b/perl/amglue/objwrap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/source.c b/perl/amglue/source.c index 612dcac..fe07715 100644 --- a/perl/amglue/source.c +++ b/perl/amglue/source.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/perl/amglue/xferwrap.c b/perl/amglue/xferwrap.c index fb50580..5ec9e91 100644 --- a/perl/amglue/xferwrap.c +++ b/perl/amglue/xferwrap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/po/Makefile.in b/po/Makefile.in index 0acd669..24c309e 100644 --- a/po/Makefile.in +++ b/po/Makefile.in @@ -186,7 +186,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -701,6 +702,9 @@ MSGMERGE = msgmerge MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/recover-src/Makefile.in b/recover-src/Makefile.in index fa8f5e4..9acb85c 100644 --- a/recover-src/Makefile.in +++ b/recover-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda file recovery programs. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -268,7 +268,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -819,6 +820,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/recover-src/extract_list.c b/recover-src/extract_list.c index a5a4251..1744ad6 100644 --- a/recover-src/extract_list.c +++ b/recover-src/extract_list.c @@ -2307,7 +2307,7 @@ extract_files(void) g_options.hostname = dump_hostname; for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist)) { - level_t *level = g_new0(level_t, 1); + am_level_t *level = g_new0(am_level_t, 1); level->level = elist->level; all_level = g_slist_append(all_level, level); } @@ -2349,13 +2349,13 @@ extract_files(void) dump_datestamp = newstralloc(dump_datestamp, elist->date); if (last_level != -1 && dump_dle) { - level_t *level; + am_level_t *level; - level = g_new0(level_t, 1); + level = g_new0(am_level_t, 1); level->level = last_level; dump_dle->levellist = g_slist_append(dump_dle->levellist, level); - level = g_new0(level_t, 1); + level = g_new0(am_level_t, 1); level->level = elist->level; dump_dle->levellist = g_slist_append(dump_dle->levellist, level); run_client_scripts(EXECUTE_ON_INTER_LEVEL_RECOVER, &g_options, @@ -2372,9 +2372,9 @@ extract_files(void) return; } if (dump_dle) { - level_t *level; + am_level_t *level; - level = g_new0(level_t, 1); + level = g_new0(am_level_t, 1); level->level = elist->level; dump_dle->levellist = g_slist_append(dump_dle->levellist, level); run_client_scripts(EXECUTE_ON_PRE_LEVEL_RECOVER, &g_options, diff --git a/server-src/Makefile.in b/server-src/Makefile.in index 8d84135..f6532d0 100644 --- a/server-src/Makefile.in +++ b/server-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda server programs. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -40,7 +40,7 @@ # scripts in this directory. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -352,7 +352,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -987,6 +988,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/server-src/amaddclient.pl b/server-src/amaddclient.pl index 8c62d0e..45b161e 100755 --- a/server-src/amaddclient.pl +++ b/server-src/amaddclient.pl @@ -1,6 +1,6 @@ #!@PERL@ # -# Copyright (c) 2007,2008 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amadmin.c b/server-src/amadmin.c index bd26906..b7dea49 100644 --- a/server-src/amadmin.c +++ b/server-src/amadmin.c @@ -42,6 +42,7 @@ #include "util.h" #include "timestamp.h" #include "server_util.h" +#include disklist_t diskq; @@ -88,6 +89,12 @@ static void show_config(int argc, char **argv); static char *conf_tapelist = NULL; static char *displayunit; static long int unitdivisor; +static gboolean print_default = 1; +static gboolean print_source = 0; +static int opt_days = -1; +static char *opt_sort = NULL; +static gboolean opt_long = 0; +static gboolean opt_outdated = 0; static const struct { const char *name; @@ -143,6 +150,15 @@ static const struct { }; #define NCMDS (int)(sizeof(cmdtab) / sizeof(cmdtab[0])) +static struct option long_options[] = { + {"version" , 0, NULL, 1}, + {"no-default" , 0, NULL, 2}, + {"print-source" , 0, NULL, 3}, + {"days" , 1, NULL, 4}, + {"sort" , 1, NULL, 5}, + {NULL, 0, NULL, 0} +}; + int main( int argc, @@ -176,6 +192,35 @@ main( cfg_ovr = extract_commandline_config_overrides(&argc, &argv); + while (1) { + int option_index = 0; + int c; + c = getopt_long(argc, argv, "ld", long_options, &option_index); + + if (c == -1) { + break; + } + + switch(c) { + case 1: printf("amadmin-%s\n", VERSION); + return 0; + case 2: print_default = 0; + break; + case 3: print_source = 1; + break; + case 4: opt_days = atoi(optarg); + break; + case 5: opt_sort = g_strdup(optarg); + break; + case 'l': opt_long = TRUE; + break; + case 'd': opt_outdated = TRUE; + break; + default: usage(); + } + } + argc -= optind-1, argv += optind-1; + if(argc < 3) usage(); set_config_overrides(cfg_ovr); @@ -246,7 +291,7 @@ usage(void) { int i; - g_fprintf(stderr, _("\nUsage: %s [-o configoption]* {} ...\n"), + g_fprintf(stderr, _("\nUsage: %s [--version] [--no-default] [--print-source] [-o configoption]*\n {} ...\n"), get_pname()); g_fprintf(stderr, _(" Valid s are:\n")); for (i = 0; i < NCMDS; i++) @@ -898,8 +943,8 @@ tape( void balance( - int argc, - char ** argv) + int argc G_GNUC_UNUSED, + char ** argv G_GNUC_UNUSED) { disk_t *dp; struct balance_stats { @@ -921,9 +966,10 @@ balance( overdue = 0; max_overdue = 0; - if(argc > 4 && strcmp(argv[3],"--days") == 0) { - later = atoi(argv[4]); - if(later < 0) later = conf_dumpcycle; + if (opt_days > 0) { + later = opt_days; + } else if (opt_days == 0) { + later = conf_dumpcycle; } if(later > 10000) later = 10000; @@ -1118,11 +1164,11 @@ find( sort_order = newstralloc(sort_order, DEFAULT_SORT_ORDER); - if(argc > 4 && strcmp(argv[3],"--sort") == 0) { + if (opt_sort) { size_t i, valid_sort=1; - for(i = strlen(argv[4]); i > 0; i--) { - switch (argv[4][i - 1]) { + for(i = strlen(opt_sort); i > 0; i--) { + switch (opt_sort[i - 1]) { case 'h': case 'H': case 'k': @@ -1144,15 +1190,13 @@ find( } } if(valid_sort) { - sort_order = newstralloc(sort_order, argv[4]); + sort_order = newstralloc(sort_order, opt_sort); } else { - g_printf(_("Invalid sort order: %s\n"), argv[4]); + g_printf(_("Invalid sort order: %s\n"), opt_sort); g_printf(_("Use default sort order: %s\n"), sort_order); } - start_argc=6; - } else { - start_argc=4; } + start_argc=4; errstr = match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1)); /* check all log file exists */ @@ -1454,22 +1498,9 @@ holding( return; case HOLDING_LIST: + long_list = opt_long; + outdated_list = opt_outdated; argc -= 4; argv += 4; - while (argc && argv[0][0] == '-') { - switch (argv[0][1]) { - case 'l': - long_list = 1; - break; - case 'd': /* have to use '-d', and not '-o', because of parse_config */ - outdated_list = 1; - break; - default: - g_fprintf(stderr, _("Unknown option -%c\n"), argv[0][1]); - usage(); - return; - } - argc--; argv++; - } /* header */ if (long_list) { @@ -1539,7 +1570,7 @@ int bump_thresh( int level) { - int bump = getconf_int(CNF_BUMPSIZE); + gint64 bump = getconf_int64(CNF_BUMPSIZE); double mult = getconf_real(CNF_BUMPMULT); while(--level) @@ -1561,8 +1592,8 @@ bumpsize( g_printf(_("Current bump parameters:\n")); if(conf_bumppercent == 0) { - g_printf(_(" bumpsize %5d KB\t- minimum savings (threshold) to bump level 1 -> 2\n"), - getconf_int(CNF_BUMPSIZE)); + g_printf(_(" bumpsize %5jd KB\t- minimum savings (threshold) to bump level 1 -> 2\n"), + (intmax_t)getconf_int64(CNF_BUMPSIZE)); g_printf(_(" bumpdays %5d\t- minimum days at each level\n"), getconf_int(CNF_BUMPDAYS)); g_printf(_(" bumpmult %5.5lg\t- threshold = bumpsize * bumpmult**(level-1)\n\n"), @@ -2092,9 +2123,6 @@ disklist_one( { am_host_t *hp; netif_t *ip; - sle_t *excl; - identlist_t pp_scriptlist; - estimatelist_t estimates; dumptype_t *dtype = lookup_dumptype(dp->dtype_name); hp = dp->host; @@ -2111,222 +2139,10 @@ disklist_one( g_printf(" program \"%s\"\n", dp->program); if (dp->application) g_printf(" application \"%s\"\n", dp->application); - g_printf(" data-path %s\n", data_path_to_string(dp->data_path)); - if (dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) { - g_printf(" exclude file"); - for(excl = dp->exclude_file->first; excl != NULL; excl = excl->next) { - g_printf(" \"%s\"", excl->name); - } - g_printf("\n"); - } - if (dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) { - g_printf(" exclude list"); - if(dp->exclude_optional) g_printf(" optional"); - for(excl = dp->exclude_list->first; excl != NULL; excl = excl->next) { - g_printf(" \"%s\"", excl->name); - } - g_printf("\n"); - } - if (dp->include_file != NULL && dp->include_file->nb_element > 0) { - g_printf(" include file"); - for(excl = dp->include_file->first; excl != NULL; excl = excl->next) { - g_printf(" \"%s\"", excl->name); - } - g_printf("\n"); - } - if (dp->include_list != NULL && dp->include_list->nb_element > 0) { - g_printf(" include list"); - if (dp->include_optional) g_printf(" optional"); - for(excl = dp->include_list->first; excl != NULL; excl = excl->next) { - g_printf(" \"%s\"", excl->name); - } - g_printf("\n"); - } - g_printf(" priority %d\n", dp->priority); - g_printf(" dumpcycle %d\n", dp->dumpcycle); - g_printf(" maxdumps %d\n", dp->maxdumps); - g_printf(" maxpromoteday %d\n", dp->maxpromoteday); - if (dp->bumppercent > 0) { - g_printf(" bumppercent %d\n", dp->bumppercent); - } - else { - g_printf(" bumpsize %lld\n", - (long long)dp->bumpsize); - } - g_printf(" bumpdays %d\n", dp->bumpdays); - g_printf(" bumpmult %lf\n", dp->bumpmult); - - g_printf(" strategy "); - switch(dp->strategy) { - case DS_SKIP: - g_printf("SKIP\n"); - break; - case DS_STANDARD: - g_printf("STANDARD\n"); - break; - case DS_NOFULL: - g_printf("NOFULL\n"); - break; - case DS_NOINC: - g_printf("NOINC\n"); - break; - case DS_HANOI: - g_printf("HANOI\n"); - break; - case DS_INCRONLY: - g_printf("INCRONLY\n"); - break; - } - g_printf(" ignore %s\n", (dp->ignore? "YES" : "NO")); - g_printf(" estimate "); - estimates = dp->estimatelist; - while (estimates) { - switch((estimate_t)GPOINTER_TO_INT(estimates->data)) { - case ES_CLIENT: - g_printf("CLIENT"); - break; - case ES_SERVER: - g_printf("SERVER"); - break; - case ES_CALCSIZE: - g_printf("CALCSIZE"); - break; - case ES_ES: - break; - } - estimates = estimates->next; - if (estimates) - g_printf(", "); - } - g_printf("\n"); - g_printf(" compress "); - switch(dp->compress) { - case COMP_NONE: - g_printf("NONE\n"); - break; - case COMP_FAST: - g_printf("CLIENT FAST\n"); - break; - case COMP_BEST: - g_printf("CLIENT BEST\n"); - break; - case COMP_CUST: - g_printf("CLIENT CUSTOM\n"); - g_printf(" client-custom-compress \"%s\"\n", - dp->clntcompprog? dp->clntcompprog : ""); - break; - case COMP_SERVER_FAST: - g_printf("SERVER FAST\n"); - break; - case COMP_SERVER_BEST: - g_printf("SERVER BEST\n"); - break; - case COMP_SERVER_CUST: - g_printf("SERVER CUSTOM\n"); - g_printf(" server-custom-compress \"%s\"\n", - dp->srvcompprog? dp->srvcompprog : ""); - break; - } - if(dp->compress != COMP_NONE) { - g_printf(" comprate %.2lf %.2lf\n", - dp->comprate[0], dp->comprate[1]); - } - - g_printf(" encrypt "); - switch(dp->encrypt) { - case ENCRYPT_NONE: - g_printf("NONE\n"); - break; - case ENCRYPT_CUST: - g_printf("CLIENT\n"); - g_printf(" client-encrypt \"%s\"\n", - dp->clnt_encrypt? dp->clnt_encrypt : ""); - g_printf(" client-decrypt-option \"%s\"\n", - dp->clnt_decrypt_opt? dp->clnt_decrypt_opt : ""); - break; - case ENCRYPT_SERV_CUST: - g_printf("SERVER\n"); - g_printf(" server-encrypt \"%s\"\n", - dp->srv_encrypt? dp->srv_encrypt : ""); - g_printf(" server-decrypt-option \"%s\"\n", - dp->srv_decrypt_opt? dp->srv_decrypt_opt : ""); - break; - } - - g_printf(" auth \"%s\"\n", dp->auth); - g_printf(" kencrypt %s\n", (dp->kencrypt? "YES" : "NO")); - g_printf(" amandad-path \"%s\"\n", dp->amandad_path); - g_printf(" client-username \"%s\"\n", dp->client_username); - g_printf(" client-port \"%s\"\n", dp->client_port); - g_printf(" ssh-keys \"%s\"\n", dp->ssh_keys); - - g_printf(" holdingdisk "); - switch(dp->to_holdingdisk) { - case HOLD_NEVER: - g_printf("NEVER\n"); - break; - case HOLD_AUTO: - g_printf("AUTO\n"); - break; - case HOLD_REQUIRED: - g_printf("REQUIRED\n"); - break; - } - - g_printf(" record %s\n", (dp->record? "YES" : "NO")); - g_printf(" index %s\n", (dp->index? "YES" : "NO")); - g_printf(" starttime %04d\n", (int)dp->starttime); - if(dp->tape_splitsize > (off_t)0) { - g_printf(" tape-splitsize %lld\n", - (long long)dp->tape_splitsize); - } - if(dp->split_diskbuffer) { - g_printf(" split-diskbuffer %s\n", dp->split_diskbuffer); - } - if(dp->fallback_splitsize > (off_t)0) { - g_printf(" fallback-splitsize %lldMb\n", - (long long)(dp->fallback_splitsize / (off_t)1024)); - } - g_printf(" skip-incr %s\n", (dp->skip_incr? "YES" : "NO")); - g_printf(" skip-full %s\n", (dp->skip_full? "YES" : "NO")); - g_printf(" allow-split %s\n", (dp->allow_split ? "YES" : "NO")); - if (dumptype_seen(dtype, DUMPTYPE_RECOVERY_LIMIT)) { - char **rl, **r1; - rl = val_t_display_strs(dumptype_getconf((dtype), - DUMPTYPE_RECOVERY_LIMIT), 1); - for(r1 = rl; *r1 != NULL; r1++) { - g_printf(" recovery-limit %s\n", *r1); - free(*r1); - } - } - if (dumptype_seen(dtype, DUMPTYPE_DUMP_LIMIT)) { - char **rl, **r1; - rl = val_t_display_strs(dumptype_getconf((dtype), - DUMPTYPE_DUMP_LIMIT), 1); - for(r1 = rl; *r1 != NULL; r1++) { - g_printf(" dump-limit %s\n", *r1); - free(*r1); - } - } - g_printf(" spindle %d\n", dp->spindle); - pp_scriptlist = dp->pp_scriptlist; - while (pp_scriptlist != NULL) { - g_printf(" script \"%s\"\n", (char *)pp_scriptlist->data); - pp_scriptlist = pp_scriptlist->next; - } - - { - char **prop, **p1;; + dump_dumptype(dtype, " ", print_default, print_source); - prop = val_t_display_strs(dumptype_getconf((dtype), DUMPTYPE_PROPERTY), - 0); - for(p1 = prop; *p1 != NULL; p1++) { - g_printf(" property %s\n", *p1); - free(*p1); - } - amfree(prop); - } + g_printf(" spindle %d\n", dp->spindle); g_printf("\n"); } @@ -2402,6 +2218,6 @@ void show_config( int argc G_GNUC_UNUSED, char **argv G_GNUC_UNUSED) { - dump_configuration(); + dump_configuration(print_default, print_source); } diff --git a/server-src/amcheck-device.pl b/server-src/amcheck-device.pl index 3a72bbe..87331a6 100644 --- a/server-src/amcheck-device.pl +++ b/server-src/amcheck-device.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2009, 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -119,7 +119,12 @@ sub _user_msg_fn { } elsif ($dev->status & $DEVICE_STATUS_VOLUME_UNLABELED and $dev->volume_header and $dev->volume_header->{'type'} == $Amanda::Header::F_WEIRD) { - print STDERR " contains a non-Amanda volume; check and relabel it with 'amlabel -f'\n"; + my $autolabel = getconf($CNF_AUTOLABEL); + if ($autolabel->{'non_amanda'}) { + print STDERR " contains a non-Amanda volume\n"; + } else { + print STDERR " contains a non-Amanda volume; check and relabel it with 'amlabel -f'\n"; + } } elsif ($dev->status & $DEVICE_STATUS_VOLUME_ERROR) { my $message = $dev->error_or_status(); print STDERR " Can't read label: $message\n"; @@ -184,7 +189,12 @@ sub do_check { if (defined $res->{'device'} and defined $res->{'device'}->volume_label()) { print "Will $modestr to volume '$label' in slot $slot.\n"; } else { - print "Will $modestr label '$label' to new volume in slot $slot.\n"; + my $header = $res->{'device'}->volume_header(); + if ($header->{'type'} == $Amanda::Header::F_WEIRD) { + print "Will $modestr label '$label' to non-Amanda volume in slot $slot.\n"; + } else { + print "Will $modestr label '$label' to new volume in slot $slot.\n"; + } } $steps->{'check_access_type'}->(); diff --git a/server-src/amcheckdump.pl b/server-src/amcheckdump.pl index 937f78d..92382e9 100644 --- a/server-src/amcheckdump.pl +++ b/server-src/amcheckdump.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -222,7 +222,7 @@ sub find_validation_command { "TAR" => [ $Amanda::Constants::GNUTAR, qw(--ignore-zeros -tf -) ], "GTAR" => [ $Amanda::Constants::GNUTAR, qw(--ignore-zeros -tf -) ], "GNUTAR" => [ $Amanda::Constants::GNUTAR, qw(--ignore-zeros -tf -) ], - "SMBCLIENT" => [ $Amanda::Constants::GNUTAR, qw(--ignore-zeros -tf -) ], + "SMBCLIENT" => [ $Amanda::Constants::GNUTAR, qw(-tf -) ], "PKZIP" => undef, ); if (!exists $validation_programs{$program}) { @@ -261,7 +261,9 @@ sub main { my $all_success = 1; my @xfer_errs; my %all_filter; - my $check_done; + my $current_dump; + my $recovery_done; + my %recovery_params; my $steps = define_steps cb_ref => \$finished_cb, @@ -340,6 +342,10 @@ sub main { step check_dumpfile => sub { my ($dump) = @_; + $current_dump = $dump; + + $recovery_done = 0; + %recovery_params = (); print "Validating image " . $dump->{hostname} . ":" . $dump->{diskname} . " dumped " . $dump->{dump_timestamp} . " level ". @@ -436,8 +442,8 @@ sub main { delete $all_filter{$src}; $src->remove(); POSIX::close($fd); - if (!%all_filter and $check_done) { - $finished_cb->(); + if (!%all_filter and $recovery_done) { + $steps->{'filter_done'}->(); } } else { $buffer .= $b; @@ -453,7 +459,7 @@ sub main { } my $xfer = Amanda::Xfer->new([ $xfer_src, @filters, $xfer_dest ]); - $xfer->start($steps->{'handle_xmsg'}); + $xfer->start($steps->{'handle_xmsg'}, 0, $current_dump->{'bytes'}); $clerk->start_recovery( xfer => $xfer, recovery_cb => $steps->{'recovery_cb'}); @@ -471,12 +477,17 @@ sub main { }; step recovery_cb => sub { - my %params = @_; + %recovery_params = @_; + $recovery_done = 1; + + $steps->{'filter_done'}->() if !%all_filter; + }; + step filter_done => sub { # distinguish device errors from validation errors - if (@{$params{'errors'}}) { + if (@{$recovery_params{'errors'}}) { print STDERR "While reading from volumes:\n"; - print STDERR "$_\n" for @{$params{'errors'}}; + print STDERR "$_\n" for @{$recovery_params{'errors'}}; return $steps->{'quit'}->("validation aborted"); } @@ -500,8 +511,8 @@ sub main { if ($err) { $exit_code = 1; print STDERR $err, "\n"; - return $clerk->quit(finished_cb => $steps->{'quit1'}) if defined $clerk;; - return $steps->{'quit1'}->(); + return $clerk->quit(finished_cb => $finished_cb) if defined $clerk; + return $finished_cb->(); } if ($all_success) { @@ -511,16 +522,9 @@ sub main { $exit_code = 1; } - return $clerk->quit(finished_cb => $steps->{'quit1'}); + return $clerk->quit(finished_cb => $finished_cb); }; - step quit1 => sub { - $check_done = 1; - - if (!%all_filter) { - $finished_cb->(); - } - } } main(sub { Amanda::MainLoop::quit(); }); diff --git a/server-src/amcleanup.pl b/server-src/amcleanup.pl index 915e72f..c97f41b 100644 --- a/server-src/amcleanup.pl +++ b/server-src/amcleanup.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amcleanupdisk.pl b/server-src/amcleanupdisk.pl index 768e7a8..952c5a6 100644 --- a/server-src/amcleanupdisk.pl +++ b/server-src/amcleanupdisk.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amdump.pl b/server-src/amdump.pl index 04499f5..725fa5b 100644 --- a/server-src/amdump.pl +++ b/server-src/amdump.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amdumpd.pl b/server-src/amdumpd.pl index 7e3bba0..2778634 100644 --- a/server-src/amdumpd.pl +++ b/server-src/amdumpd.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amfetchdump.pl b/server-src/amfetchdump.pl index b1e1fb9..652f619 100644 --- a/server-src/amfetchdump.pl +++ b/server-src/amfetchdump.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -113,7 +113,10 @@ sub usage { my ($msg) = @_; print STDERR < \$opt_header, 'header-file=s' => \$opt_header_file, 'header-fd=i' => \$opt_header_fd, + 'decrypt!' => \$opt_decrypt, + 'server-decrypt' => \$opt_server_decrypt, + 'client-decrypt' => \$opt_client_decrypt, + 'decompress!' => \$opt_decompress, + 'server-decompress' => \$opt_server_decompress, + 'client-decompress' => \$opt_client_decompress, 'b=s' => \$opt_blocksize, 'd=s' => \$opt_device, 'O=s' => \$opt_chdir, @@ -153,11 +171,10 @@ GetOptions( usage() unless (@ARGV); $opt_config = shift @ARGV; -$opt_compress = 1 if $opt_compress_best; - -usage("must specify at least a hostname") unless @ARGV; -@opt_dumpspecs = Amanda::Cmdline::parse_dumpspecs([@ARGV], - $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL); +if (defined $opt_compress and defined $opt_compress_best) { + print STDERR "Can't use -c and -C\n"; + usage(); +} usage("The -b option is no longer supported; set readblocksize in the tapetype section\n" . "of amanda.conf instead.") @@ -167,9 +184,85 @@ usage("-l is not compatible with -c or -C") usage("-p is not compatible with -n") if ($opt_leave and $opt_no_reassembly); usage("-h, --header-file, and --header-fd are mutually incompatible") - if (($opt_header and $opt_header_file or $opt_header_fd) + if (($opt_header and ($opt_header_file or $opt_header_fd)) or ($opt_header_file and $opt_header_fd)); +if (defined $opt_leave) { + if (defined $opt_decrypt and $opt_decrypt) { + print STDERR "-l is incompatible with --decrypt\n"; + usage(); + } + if (defined $opt_server_decrypt) { + print STDERR "-l is incompatible with --server-decrypt\n"; + usage(); + } + if (defined $opt_client_decrypt) { + print STDERR "-l is incompatible with --client-decrypt\n"; + usage(); + } + if (defined $opt_decompress and $opt_decompress) { + print STDERR "-l is incompatible with --decompress\n"; + usage(); + } + if (defined $opt_server_decompress) { + print STDERR "-l is incompatible with --server-decompress\n"; + usage(); + } + if (defined $opt_client_decompress) { + print STDERR "-l is incompatible with --client-decompress\n"; + usage(); + } +} + +if (defined($opt_decrypt) + + defined($opt_server_decrypt) + + defined($opt_client_decrypt) > 1) { + print STDERR "Can't use only on of --decrypt, --no-decrypt, --server-decrypt or --client-decrypt\n"; + usage(); +} +if (defined($opt_decompress) + + defined($opt_server_decompress) + + defined($opt_client_decompress) > 1) { + print STDERR "Can't use only on of --decompress, --no-decompress, --server-decompress or --client-decompress\n"; + usage(); +} + +if (defined($opt_compress) and + defined($opt_decompress) + + defined($opt_server_decompress) + + defined($opt_client_decompress) > 0) { + print STDERR "Can't specify -c with one of --decompress, --no-decompress, --server-decompress or --client-decompress\n"; + usage(); +} +if (defined($opt_compress_best) and + defined($opt_decompress) + + defined($opt_server_decompress) + + defined($opt_client_decompress) > 0) { + print STDERR "Can't specify -C with one of --decompress, --no-decompress, --server-decompress or --client-decompress\n"; + usage(); +} + +$decompress = $ALWAYS; +$decrypt = $ALWAYS; +$decrypt = $NEVER if defined $opt_leave; +$decrypt = $NEVER if defined $opt_decrypt and !$opt_decrypt; +$decrypt = $ALWAYS if defined $opt_decrypt and $opt_decrypt; +$decrypt = $ONLY_SERVER if defined $opt_server_decrypt; +$decrypt = $ONLY_CLIENT if defined $opt_client_decrypt; + +$opt_compress = 1 if $opt_compress_best; + +$decompress = $NEVER if defined $opt_compress; +$decompress = $NEVER if defined $opt_leave; +$decompress = $NEVER if defined $opt_decompress and !$opt_decompress; +$decompress = $ALWAYS if defined $opt_decompress and $opt_decompress; +$decompress = $ONLY_SERVER if defined $opt_server_decompress; +$decompress = $ONLY_CLIENT if defined $opt_client_decompress; + +usage("must specify at least a hostname") unless @ARGV; +@opt_dumpspecs = Amanda::Cmdline::parse_dumpspecs([@ARGV], + $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL); + set_config_overrides($config_overrides); config_init($CONFIG_INIT_EXPLICIT_NAME, $opt_config); my ($cfgerr_level, @cfgerr_errors) = config_errors(); @@ -205,11 +298,12 @@ use Amanda::MainLoop; sub new { my $class = shift; - my ($chg, $dev_name) = @_; + my ($chg, $dev_name, $is_tty) = @_; return bless { chg => $chg, dev_name => $dev_name, + is_tty => $is_tty, }, $class; } @@ -217,6 +311,7 @@ sub clerk_notif_part { my $self = shift; my ($label, $filenum, $header) = @_; + print STDERR "\n" if $self->{'is_tty'}; print STDERR "amfetchdump: $filenum: restoring ", $header->summary(), "\n"; } @@ -225,6 +320,7 @@ sub clerk_notif_holding { my ($filename, $header) = @_; # this used to give the fd from which the holding file was being read.. why?? + print STDERR "\n" if $self->{'is_tty'}; print STDERR "Reading '$filename'\n", $header->summary(), "\n"; } @@ -237,7 +333,11 @@ sub main { my $plan; my @xfer_errs; my %all_filter; - my $fetch_done; + my $recovery_done; + my %recovery_params; + my $timer; + my $is_tty; + my $delay; my $steps = define_steps cb_ref => \$finished_cb; @@ -252,6 +352,13 @@ sub main { return failure("Cannot chdir to $destdir: $!", $finished_cb); } + $is_tty = -t STDERR; + if($is_tty) { + $delay = 1000; # 1 second + } else { + $delay = 5000; # 5 seconds + } + my $interactivity = Amanda::Interactivity::amfetchdump->new(); # if we have an explicit device, then the clerk doesn't get a changer -- # we operate the changer via Amanda::Recovery::Scan @@ -263,7 +370,7 @@ sub main { interactivity => $interactivity); return failure($scan, $finished_cb) if $scan->isa("Amanda::Changer::Error"); $clerk = Amanda::Recovery::Clerk->new( - feedback => main::Feedback->new($chg, $opt_device), + feedback => main::Feedback->new($chg, $opt_device, $is_tty), scan => $scan); } else { my $scan = Amanda::Recovery::Scan->new( @@ -272,7 +379,7 @@ sub main { $clerk = Amanda::Recovery::Clerk->new( changer => $chg, - feedback => main::Feedback->new($chg, undef), + feedback => main::Feedback->new($chg, undef, $is_tty), scan => $scan); } @@ -294,6 +401,7 @@ sub main { # if we are doing a -p operation, only keep the first dump if ($opt_pipe) { + print STDERR "WARNING: Fetch first dump only because of -p argument\n" if @{$plan->{'dumps'}} > 1; @{$plan->{'dumps'}} = ($plan->{'dumps'}[0]); } @@ -321,10 +429,14 @@ sub main { step start_dump => sub { $current_dump = shift @{$plan->{'dumps'}}; + if (!$current_dump) { return $steps->{'finished'}->(); } + $recovery_done = 0; + %recovery_params = (); + $clerk->get_xfer_src( dump => $current_dump, xfer_src_cb => $steps->{'xfer_src_cb'}); @@ -359,11 +471,25 @@ sub main { } } + $timer = Amanda::MainLoop::timeout_source($delay); + $timer->set_callback(sub { + my $size = $xfer_src->get_bytes_read(); + if ($is_tty) { + print STDERR "\r" . int($size/1024) . " kb "; + } else { + print STDERR "READ SIZE: " . int($size/1024) . " kb\n"; + } + }); + my $xfer_dest = Amanda::Xfer::Dest::Fd->new($dest_fh); + my $dle = $hdr->get_dle(); + # set up any filters that need to be applied; decryption first my @filters; - if ($hdr->{'encrypted'} and not $opt_leave) { + if ($hdr->{'encrypted'} and + (($hdr->{'srv_encrypt'} and ($decrypt == $ALWAYS || $decrypt == $ONLY_SERVER)) || + ($hdr->{'clnt_encrypt'} and ($decrypt == $ALWAYS || $decrypt == $ONLY_CLIENT)))) { if ($hdr->{'srv_encrypt'}) { push @filters, Amanda::Xfer::Filter::Process->new( @@ -385,16 +511,23 @@ sub main { $hdr->{'encrypt_suffix'} = 'N'; } - if ($hdr->{'compressed'} and not $opt_compress and not $opt_leave) { + if ($hdr->{'compressed'} and not $opt_compress and + (($hdr->{'srvcompprog'} and ($decompress == $ALWAYS || $decompress == $ONLY_SERVER)) || + ($hdr->{'clntcompprog'} and ($decompress == $ALWAYS || $decompress == $ONLY_CLIENT)) || + ($dle->{'compress'} == $Amanda::Config::COMP_SERVER_FAST and ($decompress == $ALWAYS || $decompress == $ONLY_SERVER)) || + ($dle->{'compress'} == $Amanda::Config::COMP_SERVER_BEST and ($decompress == $ALWAYS || $decompress == $ONLY_SERVER)) || + ($dle->{'compress'} == $Amanda::Config::COMP_FAST and ($decompress == $ALWAYS || $decompress == $ONLY_CLIENT)) || + ($dle->{'compress'} == $Amanda::Config::COMP_BEST and ($decompress == $ALWAYS || $decompress == $ONLY_CLIENT)))) { # need to uncompress this file - - if ($hdr->{'srvcompprog'}) { - # TODO: this assumes that srvcompprog takes "-d" to decrypt + if ($hdr->{'encrypted'}) { + print "Not decompressing because the backup image is not decrypted\n"; + } elsif ($hdr->{'srvcompprog'}) { + # TODO: this assumes that srvcompprog takes "-d" to decompress push @filters, Amanda::Xfer::Filter::Process->new( [ $hdr->{'srvcompprog'}, "-d" ], 0); } elsif ($hdr->{'clntcompprog'}) { - # TODO: this assumes that clntcompprog takes "-d" to decrypt + # TODO: this assumes that clntcompprog takes "-d" to decompress push @filters, Amanda::Xfer::Filter::Process->new( [ $hdr->{'clntcompprog'}, "-d" ], 0); @@ -458,8 +591,8 @@ sub main { delete $all_filter{$src}; $src->remove(); POSIX::close($fd); - if (!%all_filter and $fetch_done) { - $finished_cb->(); + if (!%all_filter and $recovery_done) { + $steps->{'filter_done'}->(); } } else { $buffer .= $b; @@ -493,14 +626,24 @@ sub main { }; step recovery_cb => sub { - my %params = @_; + %recovery_params = @_; + $recovery_done = 1; + + $steps->{'filter_done'}->() if !%all_filter; + }; - @xfer_errs = (@xfer_errs, @{$params{'errors'}}) - if $params{'errors'}; + step filter_done => sub { + if ($is_tty) { + print STDERR "\r" . int($recovery_params{'bytes_read'}/1024) . " kb "; + } else { + print STDERR "READ SIZE: " . int($recovery_params{'bytes_read'}/1024) . " kb\n"; + } + @xfer_errs = (@xfer_errs, @{$recovery_params{'errors'}}) + if $recovery_params{'errors'}; return failure(join("; ", @xfer_errs), $finished_cb) if @xfer_errs; return failure("recovery failed", $finished_cb) - if $params{'result'} ne 'DONE'; + if $recovery_params{'result'} ne 'DONE'; $steps->{'start_dump'}->(); }; @@ -516,13 +659,14 @@ sub main { step quit => sub { my ($err) = @_; + if (defined $timer) { + $timer->remove(); + $timer = undef; + } + print STDERR "\n" if $is_tty; return failure($err, $finished_cb) if $err; -#do all filter are done reading stderr - $fetch_done = 1; - if (!%all_filter) { - $finished_cb->(); - } + $finished_cb->(); }; } diff --git a/server-src/amidxtaped.pl b/server-src/amidxtaped.pl index 855d59a..54fe4bd 100644 --- a/server-src/amidxtaped.pl +++ b/server-src/amidxtaped.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -403,6 +403,7 @@ sub make_plan { return Amanda::Recovery::Planner::make_plan( filelist => $filelist, + chg => $chg, $spec? (dumpspec => $spec) : (), plan_cb => sub { $self->plan_cb(@_); }); } @@ -546,7 +547,6 @@ sub xfer_src_cb { if ($header->{'compressed'}) { # need to uncompress this file debug("..with decompression applied"); - my $dle = $header->get_dle(); if ($header->{'srvcompprog'}) { # TODO: this assumes that srvcompprog takes "-d" to decrypt @@ -569,9 +569,11 @@ sub xfer_src_cb { $header->{'clntcompprog'} = ''; } } else { - if (!$self->{'their_features'}->has($Amanda::Feature::fe_amrecover_receive_unfiltered) || - $dle->{'compress'} == $Amanda::Config::COMP_SERVER_FAST || - $dle->{'compress'} == $Amanda::Config::COMP_SERVER_BEST) { + my $dle = $header->get_dle(); + if ($dle && + (!$self->{'their_features'}->has($Amanda::Feature::fe_amrecover_receive_unfiltered) || + $dle->{'compress'} == $Amanda::Config::COMP_SERVER_FAST || + $dle->{'compress'} == $Amanda::Config::COMP_SERVER_BEST)) { push @filters, Amanda::Xfer::Filter::Process->new( [ $Amanda::Constants::UNCOMPRESS_PATH, diff --git a/server-src/amindexd.c b/server-src/amindexd.c index bc56ed4..91d7db6 100644 --- a/server-src/amindexd.c +++ b/server-src/amindexd.c @@ -282,9 +282,16 @@ uncompress_file( /* start the sort process */ putenv(stralloc("LC_ALL=C")); - pid_sort = pipespawn(SORT_PATH, STDIN_PIPE|STDERR_PIPE, 0, - &pipe_to_sort, &indexfd, &sort_errfd, - SORT_PATH, NULL); + if (getconf_seen(CNF_TMPDIR)) { + gchar *tmpdir = getconf_str(CNF_TMPDIR); + pid_sort = pipespawn(SORT_PATH, STDIN_PIPE|STDERR_PIPE, 0, + &pipe_to_sort, &indexfd, &sort_errfd, + SORT_PATH, "-T", tmpdir, NULL); + } else { + pid_sort = pipespawn(SORT_PATH, STDIN_PIPE|STDERR_PIPE, 0, + &pipe_to_sort, &indexfd, &sort_errfd, + SORT_PATH, NULL); + } aclose(indexfd); /* start a subprocess */ diff --git a/server-src/amlabel.pl b/server-src/amlabel.pl index 98c5c78..a054975 100644 --- a/server-src/amlabel.pl +++ b/server-src/amlabel.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amlogroll.pl b/server-src/amlogroll.pl index 9611a8a..bc5cdcc 100644 --- a/server-src/amlogroll.pl +++ b/server-src/amlogroll.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amoverview.pl b/server-src/amoverview.pl index f5e5b31..54d8153 100644 --- a/server-src/amoverview.pl +++ b/server-src/amoverview.pl @@ -1,5 +1,5 @@ #!@PERL@ -# Copyright (c) 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amreport.pl b/server-src/amreport.pl index ae73bab..cd0432f 100755 --- a/server-src/amreport.pl +++ b/server-src/amreport.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2010-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amrestore.pl b/server-src/amrestore.pl index 362ee65..879aec4 100644 --- a/server-src/amrestore.pl +++ b/server-src/amrestore.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -173,6 +173,16 @@ sub main { return failure($err, $finished_cb) if $err; $dev = $res->{'device'}; + + if ($opt_blocksize) { + if ( !$dev->property_set("BLOCK_SIZE", $opt_blocksize)) { + return failure($dev->error_or_status, $finished_cb); + } + + # re-read the label with the correct blocksize + $dev->read_label(); + } + if ($dev->status != $DEVICE_STATUS_SUCCESS) { return failure($dev->error_or_status, $finished_cb); } diff --git a/server-src/amrmtape.pl b/server-src/amrmtape.pl index 7c052a5..f7d3708 100644 --- a/server-src/amrmtape.pl +++ b/server-src/amrmtape.pl @@ -1,6 +1,6 @@ #!@PERL@ # -# Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amserverconfig.pl b/server-src/amserverconfig.pl index 3c53a88..a05dd18 100755 --- a/server-src/amserverconfig.pl +++ b/server-src/amserverconfig.pl @@ -1,6 +1,6 @@ #!@PERL@ # -# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/amstatus.pl b/server-src/amstatus.pl index 7192e18..443e7e5 100644 --- a/server-src/amstatus.pl +++ b/server-src/amstatus.pl @@ -259,8 +259,8 @@ while($lineX = ) { $dump_started{$hostpart}=-1; $level{$hostpart}=$line[5]; $error{$hostpart}="planner: " . $line[6]; - } elsif($line[1] eq "time") { - if($line[3] eq "got") { + } elsif($line[1] eq "time") { + if($line[3] eq "got") { if($line[4] eq "result") { $host = $line[7]; $partition = $line[9]; @@ -410,6 +410,7 @@ while($lineX = ) { } $running_dumper{$dumper} = $hostpart; $error{$hostpart}=""; + $taper_error{$hostpart}=""; $size{$hostpart} = 0; $dumpers_active++; if(! defined($dumpers_active[$dumpers_active])) { @@ -483,6 +484,7 @@ while($lineX = ) { $taper_started{$hostpart}=1; $taper_finished{$hostpart}=0; $taper_time{$hostpart}=$current_time; + $taper_error{$hostpart}=""; $ntchunk_size = 0; } elsif($line[6] eq "PORT-WRITE") { @@ -498,6 +500,7 @@ while($lineX = ) { $taper_started{$hostpart}=1; $taper_finished{$hostpart}=0; $taper_time{$hostpart}=$current_time; + $taper_error{$hostpart}=""; $size{$hostpart} = 0; $ntchunk_size = 0; } @@ -518,10 +521,12 @@ while($lineX = ) { $dump_finished{$hostpart}=-3; } $busy_time{$line[5]}+=($current_time-$dump_time{$hostpart}); - $running_dumper{$line[5]} = "0"; - $dump_time{$hostpart}=$current_time; - $error{$hostpart}="dumper: $error"; - $dumpers_active--; + $running_dumper{$line[5]} = "0"; + $dump_time{$hostpart}=$current_time; + if (!$taper_error{$hostpart}) { + $error{$hostpart}="dumper: $error"; + } + $dumpers_active--; } elsif($line[6] eq "DONE") { @@ -597,15 +602,16 @@ while($lineX = ) { } elsif($line[5] eq "taper") { if($line[6] eq "DONE" || $line[6] eq "PARTIAL") { - #7:handle 8:label 9:filenum 10:errstr + #DONE: 7:handle 8:label 9:filenum 10:errstr + #PARTIAL: 7:handle 8:INPUT-* 9:TAPE-* 10:errstr 11:INPUT-MSG 12:TAPE-MSG $serial=$line[7]; - $label=$line[8]; + $status_taper = "Idle"; $hostpart=$serial{$serial}; $line[10] =~ /sec (\S+) (kb|bytes) (\d+) kps/; if ($2 eq 'kb') { $size=$3 / $unitdivisor; - } else { + } else { $size=$3 / ( $unitdivisor * 1024); } $taper_finished{$hostpart}=1; @@ -624,6 +630,10 @@ while($lineX = ) { } if ($line[6] eq "PARTIAL") { $partial{$hostpart} = 1; + if ($line[9] eq "TAPE-ERROR") { + $error{$hostpart} = "taper: $line[12]"; + $taper_error{$hostpart} = "taper: $line[12]"; + } } else { $partial{$hostpart} = 0; @@ -933,7 +943,7 @@ foreach $host (sort @hosts) { $taper_started{$hostpart}==1 && $dump_finished{$hostpart}!=-3) { if(defined $dump_started{$hostpart} && - $dump_started{$hostpart} == 1 && + $dump_started{$hostpart} == 1 && $dump_finished{$hostpart} == -1) { if(defined $opt_failed) { printf "%8s ", $datestamp if defined $opt_date; @@ -946,7 +956,7 @@ foreach $host (sort @hosts) { $fpartition++; $fsize+=$esize{$hostpart}; } elsif(defined $dump_started{$hostpart} && - $dump_started{$hostpart} == 1 && + $dump_started{$hostpart} == 1 && $dump_finished{$hostpart} == 0 && $taper_started{$hostpart} == 1) { if( defined $opt_dumpingtape || @@ -995,6 +1005,7 @@ foreach $host (sort @hosts) { $exit_status |= $STATUS_FAILED; } if($in_flush == 0) { + print " dump done," if defined $dump_finished{$hostpart} && $dump_finished{$hostpart} == 1; print " writing to tape"; } else { @@ -1065,6 +1076,7 @@ foreach $host (sort @hosts) { printf "%8s ", $datestamp if defined $opt_date; printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart}; printf "%9d$unit", $xsize; + print " dump done," if defined $dump_finished{$hostpart} && $dump_finished{$hostpart} == 1; if($in_flush == 0) { print " failed to tape"; } @@ -1072,7 +1084,7 @@ foreach $host (sort @hosts) { print " failed to flush"; } print ": ",$error{$hostpart} if defined $error{$hostpart}; - + print " (will retry)" unless $taper_finished{$hostpart} < -1; if( defined $starttime ) { print " (", &showtime($taper_time{$hostpart}), ")"; diff --git a/server-src/amtape.pl b/server-src/amtape.pl index bb29001..dec31ea 100644 --- a/server-src/amtape.pl +++ b/server-src/amtape.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -550,7 +550,12 @@ sub { } elsif ($dev->status & $DEVICE_STATUS_VOLUME_UNLABELED and $dev->volume_header and $dev->volume_header->{'type'} == $Amanda::Header::F_WEIRD) { - print STDERR " contains a non-Amanda volume; check and relabel it with 'amlabel -f'\n"; + my $autolabel = getconf($CNF_AUTOLABEL); + if ($autolabel->{'non_amanda'}) { + print STDERR " contains a non-Amanda volume\n"; + } else { + print STDERR " contains a non-Amanda volume; check and relabel it with 'amlabel -f'\n"; + } } elsif ($dev->status & $DEVICE_STATUS_VOLUME_ERROR) { my $message = $dev->error_or_status(); print STDERR " can't read label: $message\n"; @@ -594,7 +599,12 @@ sub { if (defined $res->{'device'} and defined $res->{'device'}->volume_label()) { print STDERR "Will $modestr to volume '$label' in slot $slot.\n"; } else { - print STDERR "Will $modestr label '$label' to new volume in slot $slot.\n"; + my $header = $res->{'device'}->volume_header(); + if ($header->{'type'} == $Amanda::Header::F_WEIRD) { + print STDERR "Will $modestr label '$label' to non-Amanda volume in slot $slot.\n"; + } else { + print STDERR "Will $modestr label '$label' to new volume in slot $slot.\n"; + } } $res->release(finished_cb => sub { my ($err) = @_; diff --git a/server-src/amvault.pl b/server-src/amvault.pl index 87a43fb..88111f7 100644 --- a/server-src/amvault.pl +++ b/server-src/amvault.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -141,6 +141,7 @@ sub new { exporting => 0, # is an export in progress? call_after_export => undef, # call this when export complete config_overrides_opts => $params{'config_overrides_opts'}, + trace_log_filename => getconf($CNF_LOGDIR) . "/log", # called when the operation is complete, with the exit # status @@ -148,6 +149,47 @@ sub new { }, $class; } +sub run_subprocess { + my ($proc, @args) = @_; + + my $pid = POSIX::fork(); + if ($pid == 0) { + my $null = POSIX::open("/dev/null", POSIX::O_RDWR); + POSIX::dup2($null, 0); + POSIX::dup2($null, 1); + POSIX::dup2($null, 2); + exec $proc, @args; + die "Could not exec $proc: $!"; + } + waitpid($pid, 0); + my $s = $? >> 8; + debug("$proc exited with code $s: $!"); +} + +sub do_amcleanup { + my $self = shift; + + return 1 unless -f $self->{'trace_log_filename'}; + + # logfiles are still around. First, try an amcleanup -p to see if + # the actual processes are already dead + debug("runing amcleanup -p"); + run_subprocess("$sbindir/amcleanup", '-p', $self->{'config_name'}, + $self->{'config_overrides_opts'}); + + return 1 unless -f $self->{'trace_log_filename'}; + + return 0; +} + +sub bail_already_running() { + my $self = shift; + my $msg = "An Amanda process is already running - please run amcleanup manually"; + print "$msg\n"; + debug($msg); + $self->{'exit_cb'}->(1); +} + sub run { my $self = shift; my ($exit_cb) = @_; @@ -163,7 +205,20 @@ sub run { # open up a trace log file and put our imprimatur on it, unless dry_runing if (!$self->{'opt_dry_run'}) { + if (!$self->do_amcleanup()) { + return $self->bail_already_running(); + } log_add($L_INFO, "amvault pid $$"); + + # Check we own the log file + open(my $tl, "<", $self->{'trace_log_filename'}) + or die("could not open trace log file '$self->{'trace_log_filename'}': $!"); + if (<$tl> !~ /^INFO amvault amvault pid $$/) { + debug("another amdump raced with this one, and won"); + close($tl); + return $self->bail_already_running(); + } + close($tl); log_add($L_START, "date " . $self->{'dst_write_timestamp'}); Amanda::Debug::add_amanda_log_handler($amanda_log_trace_log); $self->{'cleanup'}{'roll_trace_log'} = 1; @@ -249,7 +304,7 @@ sub setup_src { # convert the timestamp and level to a dumpspec my $level = $self->{'fulls_only'}? "0" : undef; push @dumpspecs, Amanda::Cmdline::dumpspec_t->new( - undef, undef, $self->{'src_write_timestamp'}, $level, undef); + undef, undef, undef, $level, $self->{'src_write_timestamp'}); } # if we ignored all of the dumpspecs and didn't create any, then dump diff --git a/server-src/cmdline.c b/server-src/cmdline.c index 28a842f..600d500 100644 --- a/server-src/cmdline.c +++ b/server-src/cmdline.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/server-src/cmdline.h b/server-src/cmdline.h index 2806c1a..b1e6cad 100644 --- a/server-src/cmdline.h +++ b/server-src/cmdline.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007,2008 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/server-src/diskfile.c b/server-src/diskfile.c index b25b749..544346a 100644 --- a/server-src/diskfile.c +++ b/server-src/diskfile.c @@ -205,6 +205,7 @@ add_disk( bzero(disk, SIZEOF(disk_t)); disk->line = 0; disk->allow_split = 0; + disk->max_warnings = 20; disk->splitsize = (off_t)0; disk->tape_splitsize = (off_t)0; disk->split_diskbuffer = NULL; @@ -687,6 +688,7 @@ parse_diskline( disk->auth = dumptype_get_auth(dtype); disk->maxdumps = dumptype_get_maxdumps(dtype); disk->allow_split = dumptype_get_allow_split(dtype); + disk->max_warnings = dumptype_get_max_warnings(dtype); disk->tape_splitsize = dumptype_get_tape_splitsize(dtype); disk->split_diskbuffer = dumptype_get_split_diskbuffer(dtype); disk->fallback_splitsize = dumptype_get_fallback_splitsize(dtype); diff --git a/server-src/diskfile.h b/server-src/diskfile.h index 28ed50e..f4b930e 100644 --- a/server-src/diskfile.h +++ b/server-src/diskfile.h @@ -79,14 +79,15 @@ typedef struct disk_s { char *client_username; /* username to connect on the client */ char *client_port; /* port to connect on the client */ char *ssh_keys; /* ssh_key file to use */ - sl_t *exclude_file; /* file exclude spec */ - sl_t *exclude_list; /* exclude list */ - sl_t *include_file; /* file include spec */ - sl_t *include_list; /* include list */ + am_sl_t *exclude_file; /* file exclude spec */ + am_sl_t *exclude_list; /* exclude list */ + am_sl_t *include_file; /* file include spec */ + am_sl_t *include_list; /* include list */ int exclude_optional; /* exclude list are optional */ int include_optional; /* include list are optional */ int priority; /* priority of disk */ int allow_split; + int max_warnings; off_t splitsize; off_t tape_splitsize; /* size of dumpfile chunks on tape */ char *split_diskbuffer; /* place where we can buffer PORT-WRITE dumps other than RAM */ diff --git a/server-src/driver.c b/server-src/driver.c index 5560171..af5095a 100644 --- a/server-src/driver.c +++ b/server-src/driver.c @@ -1949,7 +1949,7 @@ handle_taper_result( for (taper = tapetable; taper < tapetable + conf_taper_parallel_write; taper++) { - if (taper && taper->disk && taper->result != LAST_TOK) { + if (taper && taper->disk) { taper->tape_error = newstralloc(taper->tape_error,"BOGUS"); taper->result = cmd; if (taper->dumper) { @@ -2477,14 +2477,12 @@ handle_dumper_result( dumper->chunker->result != LAST_TOK) dumper_chunker_result(dp); } else { /* send the dumper result to the taper */ - if (taper->sendresult) { - if (cmd == DONE) { - taper_cmd(DONE, dp, NULL, 0, NULL); - } else { - taper_cmd(FAILED, dp, NULL, 0, NULL); - } - taper->sendresult = 0; + if (cmd == DONE) { + taper_cmd(DONE, dp, NULL, 0, NULL); + } else { + taper_cmd(FAILED, dp, NULL, 0, NULL); } + taper->sendresult = 0; if (taper->dumper && taper->result != LAST_TOK) { dumper_taper_result(dp); } @@ -3756,19 +3754,19 @@ tape_action( if (dumper->busy && !sched(dumper->dp)->taper) dumpers_size += sched(dumper->dp)->est_size; } - driver_debug(1, _("dumpers_size: %lld\n"), (long long)dumpers_size); + driver_debug(2, _("dumpers_size: %lld\n"), (long long)dumpers_size); runq_size = 0; for(dp = runq.head; dp != NULL; dp = dp->next) { runq_size += sched(dp)->est_size; } - driver_debug(1, _("runq_size: %lld\n"), (long long)runq_size); + driver_debug(2, _("runq_size: %lld\n"), (long long)runq_size); directq_size = 0; for(dp = directq.head; dp != NULL; dp = dp->next) { directq_size += sched(dp)->est_size; } - driver_debug(1, _("directq_size: %lld\n"), (long long)directq_size); + driver_debug(2, _("directq_size: %lld\n"), (long long)directq_size); tapeq_size = directq_size; for(dp = tapeq.head; dp != NULL; dp = dp->next) { @@ -3800,7 +3798,11 @@ tape_action( if (data_to_go > taper1->left) { data_next_tape += data_to_go - taper1->left; data_lost += taper1->written + taper1->left; - dle_free--; + if (taper1->state & TAPER_STATE_TAPE_STARTED) { + dle_free--; + } else { + dle_free += conf_max_dle_by_volume - 2; + } } else { data_free += taper1->left - data_to_go; } @@ -3808,18 +3810,19 @@ tape_action( } } data_lost_next_tape = tape_length + data_free - data_next_tape - runq_size - directq_size - tapeq_size; - driver_debug(1, _("data_lost: %lld\n"), (long long)data_lost); - driver_debug(1, _("data_free: %lld\n"), (long long)data_free); - driver_debug(1, _("data_next_tape: %lld\n"), (long long)data_next_tape); - driver_debug(1, _("data_lost_next_tape: %lld\n"), (long long)data_lost_next_tape); + driver_debug(2, _("dle_free: %d\n"), dle_free); + driver_debug(2, _("data_lost: %lld\n"), (long long)data_lost); + driver_debug(2, _("data_free: %lld\n"), (long long)data_free); + driver_debug(2, _("data_next_tape: %lld\n"), (long long)data_next_tape); + driver_debug(2, _("data_lost_next_tape: %lld\n"), (long long)data_lost_next_tape); ; - driver_debug(1, _("tapeq_size: %lld\n"), (long long)tapeq_size); + driver_debug(2, _("tapeq_size: %lld\n"), (long long)tapeq_size); sched_size = runq_size + directq_size + tapeq_size + dumpers_size; - driver_debug(1, _("sched_size: %lld\n"), (long long)sched_size); + driver_debug(2, _("sched_size: %lld\n"), (long long)sched_size); dump_to_disk_size = dumpers_size + runq_size + directq_size; - driver_debug(1, _("dump_to_disk_size: %lld\n"), (long long)dump_to_disk_size); + driver_debug(2, _("dump_to_disk_size: %lld\n"), (long long)dump_to_disk_size); dump_to_disk_terminated = schedule_done && dump_to_disk_size == 0; @@ -3835,11 +3838,16 @@ tape_action( (dle_free < (queue_length(runq) + queue_length(directq) + queue_length(tapeq))); + driver_debug(2, "queue_length(runq) %d\n", queue_length(runq)); + driver_debug(2, "queue_length(directq) %d\n", queue_length(directq)); + driver_debug(2, "queue_length(tapeq) %d\n", queue_length(tapeq)); + driver_debug(2, "allow_size_or_number %d\n", allow_size_or_number); // Changing conditionals can produce a driver hang, take care. // // when to start writting to a new tape if (taper->state & TAPER_STATE_TAPE_REQUESTED) { + driver_debug(2, "tape_action: TAPER_STATE_TAPE_REQUESTED\n"); if (current_tape >= conf_runtapes && taper_nb_scan_volume == 0 && nb_taper_active == 0) { *why_no_new_tape = g_strdup_printf(_("%d tapes filled; runtapes=%d " @@ -3867,6 +3875,7 @@ tape_action( (force_flush == 1 || // if force_flush dump_to_disk_terminated)) // or all dump to disk terminated )) { + driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE return TAPE_ACTION_NEW_TAPE\n"); result |= TAPE_ACTION_NEW_TAPE; // when to stop using new tape } else if ((taper->state & TAPER_STATE_WAIT_FOR_TAPE) && @@ -3874,19 +3883,24 @@ tape_action( (force_flush == 1 || // if force_flush dump_to_disk_terminated)) // or all dump to disk ) { + driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE B\n"); if (nb_taper_active <= 0) { if (current_tape >= conf_runtapes) { *why_no_new_tape = g_strdup_printf(_("%d tapes filled; runtapes=%d " "does not allow additional tapes"), current_tape, conf_runtapes); - } else { + driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE return TAPE_ACTION_NO_NEW_TAPE\n"); + result |= TAPE_ACTION_NO_NEW_TAPE; + } else if (dumpers_size <= 0) { *why_no_new_tape = _("taperflush criteria not met"); + driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE return TAPE_ACTION_NO_NEW_TAPE\n"); + result |= TAPE_ACTION_NO_NEW_TAPE; } - result |= TAPE_ACTION_NO_NEW_TAPE; } } // when to start a flush if (taper->state & TAPER_STATE_IDLE) { + driver_debug(2, "tape_action: TAPER_STATE_IDLE\n"); if (!degraded_mode && (!empty(tapeq) || !empty(directq)) && (taper->state & TAPER_STATE_TAPE_STARTED || // tape already started !empty(roomq) || // holding disk constraint diff --git a/server-src/driverio.c b/server-src/driverio.c index 5778275..c2632eb 100644 --- a/server-src/driverio.c +++ b/server-src/driverio.c @@ -574,6 +574,7 @@ dumper_cmd( char *cmdline = NULL; char number[NUM_STR_SIZE]; char numberport[NUM_STR_SIZE]; + char maxwarnings[NUM_STR_SIZE]; char *o, *oo; char *device; char *features; @@ -611,6 +612,7 @@ dumper_cmd( qname = quote_string(dp->name); g_snprintf(number, SIZEOF(number), "%d", sched(dp)->level); g_snprintf(numberport, SIZEOF(numberport), "%d", dumper->output_port); + g_snprintf(maxwarnings, SIZEOF(maxwarnings), "%d", dp->max_warnings); features = am_feature_to_string(dp->host->features); if (am_has_feature(dp->host->features, fe_req_xml)) { o = xml_optionstr(dp, 1); @@ -664,6 +666,7 @@ dumper_cmd( " ", dp->auth, " ", data_path_to_string(dp->data_path), " ", dp->dataport_list, + " ", maxwarnings, " |", o, "\n", NULL); amfree(qplugin); diff --git a/server-src/dumper.c b/server-src/dumper.c index 32f9258..d9fd9ca 100644 --- a/server-src/dumper.c +++ b/server-src/dumper.c @@ -73,6 +73,8 @@ struct databuf { pid_t encryptpid; /* valid if fd is pipe to encrypt */ }; +struct databuf *g_databuf = NULL; + typedef struct filter_s { int fd; char *name; @@ -124,6 +126,7 @@ static int set_datafd; static char *dle_str = NULL; static char *errfname = NULL; static int errf_lines = 0; +static int max_warnings = 0; static dumpfile_t file; @@ -535,6 +538,11 @@ main( } dataport_list = newstralloc(dataport_list, cmdargs->argv[a++]); + if(a >= cmdargs->argc) { + error(_("error [dumper PORT-DUMP: not enough args: max_warnings]")); + } + max_warnings = atoi(cmdargs->argv[a++]); + if(a >= cmdargs->argc) { error(_("error [dumper PORT-DUMP: not enough args: options]")); } @@ -576,6 +584,7 @@ main( break; } databuf_init(&db, outfd); + g_databuf = &db; if (am_has_feature(their_features, fe_req_xml)) xml_check_options(options); /* note: modifies globals */ @@ -1006,14 +1015,18 @@ log_msgout( { char *line; int count = 0; + int to_unlink = 1; fflush(errf); if (fseeko(errf, 0L, SEEK_SET) < 0) { dbprintf(_("log_msgout: warning - seek failed: %s\n"), strerror(errno)); } while ((line = agets(errf)) != NULL) { - if (errf_lines >= 100 && count >= 20) + if (max_warnings > 0 && errf_lines >= max_warnings && count >= max_warnings) { + log_add(typ, "Look in the '%s' file for full error messages", errfname); + to_unlink = 0; break; + } if (line[0] != '\0') { log_add(typ, "%s", line); } @@ -1022,11 +1035,7 @@ log_msgout( } amfree(line); - if (errf_lines >= 100) { - log_add(typ, "Look in the '%s' file for full error messages", errfname); - } - - return errf_lines < 100; + return to_unlink; } /* ------------- */ @@ -1889,6 +1898,7 @@ stop_dump(void) } } aclose(indexout); + aclose(g_databuf->fd); timeout(0); } @@ -1925,6 +1935,12 @@ runcompress( return (-1); } + if (comptype != COMP_SERVER_CUST) { + g_debug("execute: %s %s", COMPRESS_PATH, + comptype == COMP_BEST ? COMPRESS_BEST_OPT : COMPRESS_FAST_OPT); + } else { + g_debug("execute: %s", srvcompprog); + } switch (*pid = fork()) { case -1: errstr = newvstrallocf(errstr, _("couldn't fork: %s"), strerror(errno)); @@ -1948,7 +1964,6 @@ runcompress( filter->allocated_size = 0; filter->event = event_register((event_id_t)filter->fd, EV_READFD, handle_filter_stderr, filter); -g_debug("event register %s %d", name, filter->fd); return (rval); case 0: close(outpipe[1]); @@ -2021,6 +2036,7 @@ runencrypt( return (-1); } + g_debug("execute: %s", srv_encrypt); switch (*pid = fork()) { case -1: errstr = newvstrallocf(errstr, _("couldn't fork: %s"), strerror(errno)); @@ -2047,7 +2063,6 @@ runencrypt( filter->allocated_size = 0; filter->event = event_register((event_id_t)filter->fd, EV_READFD, handle_filter_stderr, filter); -g_debug("event register %s %d", "encrypt data", filter->fd); return (rval); } case 0: { diff --git a/server-src/find.c b/server-src/find.c index 0edd6af..0b0348f 100644 --- a/server-src/find.c +++ b/server-src/find.c @@ -711,7 +711,8 @@ search_logfile( char *ck_label=NULL; int level = 0; off_t filenum; - char *ck_datestamp, *datestamp; + char *ck_datestamp=NULL; + char *datestamp; char *s; int ch; disk_t *dp; @@ -745,6 +746,8 @@ search_logfile( filenum = (off_t)0; while(get_logline(logf)) { if (curlog == L_START && curprog == P_TAPER) { + amfree(ck_label); + ck_datestamp = NULL; if(parse_taper_datestamp_log(curstr, &ck_datestamp, &ck_label) == 0) { g_printf(_("strange log line in %s \"start taper %s\"\n"), @@ -770,11 +773,14 @@ search_logfile( } amfree(current_label); current_label = ck_label; + ck_label = NULL; if (datestamp == NULL) { datestamp = g_strdup(ck_datestamp); } filenum = (off_t)0; } + if (!datestamp) + continue; if (right_label && (curlog == L_SUCCESS || curlog == L_CHUNK || curlog == L_PART || curlog == L_PARTPARTIAL) && diff --git a/server-src/planner.c b/server-src/planner.c index c8501e2..aa81629 100644 --- a/server-src/planner.c +++ b/server-src/planner.c @@ -108,6 +108,7 @@ typedef struct est_s { double fullcomp, incrcomp; char *errstr; char *degr_mesg; + info_t *info; } est_t; #define est(dp) ((est_t *)(dp)->up) @@ -756,7 +757,7 @@ setup_estimate( disk_t *dp) { est_t *ep; - info_t info; + info_t *info; int i; char *qname; int overwrite_runs; @@ -770,7 +771,8 @@ setup_estimate( /* get current information about disk */ - if(get_info(dp->host->hostname, dp->name, &info)) { + info = g_new0(info_t, 1); + if(get_info(dp->host->hostname, dp->name, info)) { /* no record for this disk, make a note of it */ log_add(L_INFO, _("Adding new disk %s:%s."), dp->host->hostname, qname); } @@ -810,6 +812,7 @@ setup_estimate( ep = alloc(SIZEOF(est_t)); dp->up = (void *) ep; + ep->info = info; ep->state = DISK_READY; ep->dump_priority = dp->priority; ep->errstr = 0; @@ -821,7 +824,7 @@ setup_estimate( /* calculated fields */ - if (ISSET(info.command, FORCE_FULL)) { + if (ISSET(info->command, FORCE_FULL)) { /* force a level 0, kind of like a new disk */ if(dp->strategy == DS_NOFULL) { /* @@ -840,18 +843,18 @@ setup_estimate( dp->host->hostname, qname); /* clear force command */ - CLR(info.command, FORCE_FULL); - ep->last_level = last_level(&info); - ep->next_level0 = next_level0(dp, &info); + CLR(info->command, FORCE_FULL); + ep->last_level = last_level(info); + ep->next_level0 = next_level0(dp, info); } else if (dp->strategy == DS_INCRONLY) { log_add(L_WARNING, _("Cannot force full dump of %s:%s with incronly option."), dp->host->hostname, qname); /* clear force command */ - CLR(info.command, FORCE_FULL); - ep->last_level = last_level(&info); - ep->next_level0 = next_level0(dp, &info); + CLR(info->command, FORCE_FULL); + ep->last_level = last_level(info); + ep->next_level0 = next_level0(dp, info); } else { ep->degr_mesg = _("Skipping: force-full disk can't be dumped in degraded mode"); ep->last_level = -1; @@ -863,44 +866,44 @@ setup_estimate( else if(dp->strategy == DS_NOFULL) { /* force estimate of level 1 */ ep->last_level = 1; - ep->next_level0 = next_level0(dp, &info); + ep->next_level0 = next_level0(dp, info); } else { - ep->last_level = last_level(&info); - ep->next_level0 = next_level0(dp, &info); + ep->last_level = last_level(info); + ep->next_level0 = next_level0(dp, info); } /* adjust priority levels */ /* warn if dump will be overwritten */ - if (ep->last_level > -1 && strlen(info.inf[0].label) > 0) { - overwrite_runs = when_overwrite(info.inf[0].label); + if (ep->last_level > -1 && strlen(info->inf[0].label) > 0) { + overwrite_runs = when_overwrite(info->inf[0].label); if(overwrite_runs == 0) { log_add(L_WARNING, _("Last full dump of %s:%s " "on tape %s overwritten on this run."), - dp->host->hostname, qname, info.inf[0].label); + dp->host->hostname, qname, info->inf[0].label); } else if(overwrite_runs <= RUNS_REDZONE) { log_add(L_WARNING, plural(_("Last full dump of %s:%s on tape %s overwritten in %d run."), _("Last full dump of %s:%s on tape %s overwritten in %d runs."), overwrite_runs), - dp->host->hostname, qname, info.inf[0].label, + dp->host->hostname, qname, info->inf[0].label, overwrite_runs); } } /* warn if last level 1 will be overwritten */ - if (ep->last_level > 1 && strlen(info.inf[1].label) > 0) { - overwrite_runs = when_overwrite(info.inf[1].label); + if (ep->last_level > 1 && strlen(info->inf[1].label) > 0) { + overwrite_runs = when_overwrite(info->inf[1].label); if(overwrite_runs == 0) { log_add(L_WARNING, _("Last level 1 dump of %s:%s " "on tape %s overwritten on this run, resetting to level 1"), - dp->host->hostname, qname, info.inf[1].label); + dp->host->hostname, qname, info->inf[1].label); ep->last_level = 0; } else if(overwrite_runs <= RUNS_REDZONE) { log_add(L_WARNING, plural(_("Last level 1 dump of %s:%s on tape %s overwritten in %d run."), _("Last level 1 dump of %s:%s on tape %s overwritten in %d runs."), overwrite_runs), - dp->host->hostname, qname, info.inf[1].label, + dp->host->hostname, qname, info->inf[1].label, overwrite_runs); } } @@ -912,7 +915,7 @@ setup_estimate( dp->host->hostname, qname, (-ep->next_level0)); ep->dump_priority -= ep->next_level0; } - else if (ISSET(info.command, FORCE_FULL)) + else if (ISSET(info->command, FORCE_FULL)) ep->dump_priority += 1; /* else XXX bump up the priority of incrementals that failed last night */ @@ -921,11 +924,11 @@ setup_estimate( if(dp->skip_full && dp->strategy != DS_NOINC) { if(ep->next_level0 <= 0) { /* update the date field */ - info.inf[0].date = today; - CLR(info.command, FORCE_FULL); + info->inf[0].date = today; + CLR(info->command, FORCE_FULL); ep->next_level0 += conf_dumpcycle; ep->last_level = 0; - if(put_info(dp->host->hostname, dp->name, &info)) { + if(put_info(dp->host->hostname, dp->name, info)) { error(_("could not put info record for %s:%s: %s"), dp->host->hostname, qname, strerror(errno)); /*NOTREACHED*/ @@ -935,9 +938,9 @@ setup_estimate( g_fprintf(stderr,_("%s:%s lev 0 skipped due to skip-full flag\n"), dp->host->hostname, qname); /* don't enqueue the disk */ - askfor(ep, 0, -1, &info); - askfor(ep, 1, -1, &info); - askfor(ep, 2, -1, &info); + askfor(ep, 0, -1, info); + askfor(ep, 1, -1, info); + askfor(ep, 2, -1, info); g_fprintf(stderr, _("%s: SKIPPED %s %s 0 [skip-full]\n"), get_pname(), dp->host->hostname, qname); log_add(L_SUCCESS, _("%s %s %s 0 [skipped: skip-full]"), @@ -957,11 +960,11 @@ setup_estimate( } } - if(dp->strategy == DS_INCRONLY && ep->last_level == -1 && !ISSET(info.command, FORCE_FULL)) { + if(dp->strategy == DS_INCRONLY && ep->last_level == -1 && !ISSET(info->command, FORCE_FULL)) { /* don't enqueue the disk */ - askfor(ep, 0, -1, &info); - askfor(ep, 1, -1, &info); - askfor(ep, 2, -1, &info); + askfor(ep, 0, -1, info); + askfor(ep, 1, -1, info); + askfor(ep, 2, -1, info); log_add(L_FAIL, _("%s %s 19000101 1 [Skipping incronly because no full dump were done]"), dp->host->hostname, qname); g_fprintf(stderr,_("%s:%s lev 1 skipped due to strategy incronly and no full dump were done\n"), @@ -976,9 +979,9 @@ setup_estimate( g_fprintf(stderr,_("%s:%s lev 1 skipped due to skip-incr flag\n"), dp->host->hostname, qname); /* don't enqueue the disk */ - askfor(ep, 0, -1, &info); - askfor(ep, 1, -1, &info); - askfor(ep, 2, -1, &info); + askfor(ep, 0, -1, info); + askfor(ep, 1, -1, info); + askfor(ep, 2, -1, info); g_fprintf(stderr, _("%s: SKIPPED %s %s 1 [skip-incr]\n"), get_pname(), dp->host->hostname, qname); @@ -998,15 +1001,16 @@ setup_estimate( ep->next_level0 = 0; } - if(ep->last_level == 0) ep->level_days = 0; - else ep->level_days = runs_at(&info, ep->last_level); - ep->last_lev0size = info.inf[0].csize; + //if(ep->last_level == 0) ep->level_days = 0; + //else ep->level_days = runs_at(info, ep->last_level); + ep->level_days = runs_at(info, ep->last_level); + ep->last_lev0size = info->inf[0].csize; - ep->fullrate = perf_average(info.full.rate, 0.0); - ep->incrrate = perf_average(info.incr.rate, 0.0); + ep->fullrate = perf_average(info->full.rate, 0.0); + ep->incrrate = perf_average(info->incr.rate, 0.0); - ep->fullcomp = perf_average(info.full.comp, dp->comprate[0]); - ep->incrcomp = perf_average(info.incr.comp, dp->comprate[1]); + ep->fullcomp = perf_average(info->full.comp, dp->comprate[0]); + ep->incrcomp = perf_average(info->incr.comp, dp->comprate[1]); /* determine which estimates to get */ @@ -1014,10 +1018,10 @@ setup_estimate( if (dp->strategy == DS_NOINC || (!dp->skip_full && - (!ISSET(info.command, FORCE_BUMP) || + (!ISSET(info->command, FORCE_BUMP) || dp->skip_incr || ep->last_level == -1))) { - if(ISSET(info.command, FORCE_BUMP) && ep->last_level == -1) { + if(ISSET(info->command, FORCE_BUMP) && ep->last_level == -1) { log_add(L_INFO, _("Remove force-bump command of %s:%s because it's a new disk."), dp->host->hostname, qname); @@ -1025,7 +1029,7 @@ setup_estimate( switch (dp->strategy) { case DS_STANDARD: case DS_NOINC: - askfor(ep, i++, 0, &info); + askfor(ep, i++, 0, info); if (ep->last_level == -1) ep->degr_mesg = _("Skipping: new disk can't be dumped in degraded mode"); else @@ -1035,7 +1039,7 @@ setup_estimate( "because the strategy is NOINC."), dp->host->hostname, qname); } - if(ISSET(info.command, FORCE_BUMP)) { + if(ISSET(info->command, FORCE_BUMP)) { log_add(L_INFO, _("Ignoring FORCE_BUMP for %s:%s because the strategy is NOINC."), dp->host->hostname, qname); @@ -1047,7 +1051,7 @@ setup_estimate( break; case DS_INCRONLY: - if (ISSET(info.command, FORCE_FULL)) + if (ISSET(info->command, FORCE_FULL)) ep->last_level = 0; break; } @@ -1058,7 +1062,7 @@ setup_estimate( if (ep->degr_mesg == NULL) ep->degr_mesg = _("Skipping: new disk can't be dumped in degraded mode"); if(dp->strategy == DS_NOFULL || dp->strategy == DS_INCRONLY) { - askfor(ep, i++, 1, &info); + askfor(ep, i++, 1, info); } else { assert(!dp->skip_full); /* should be handled above */ } @@ -1067,23 +1071,23 @@ setup_estimate( curr_level = ep->last_level; - if (ISSET(info.command, FORCE_NO_BUMP)) { + if (ISSET(info->command, FORCE_NO_BUMP)) { if(curr_level > 0) { /* level 0 already asked for */ - askfor(ep, i++, curr_level, &info); + askfor(ep, i++, curr_level, info); } log_add(L_INFO,_("Preventing bump of %s:%s as directed."), dp->host->hostname, qname); ep->degr_mesg = _("Skipping: force-no-bump disk can't be dumped in degraded mode"); - } else if (ISSET(info.command, FORCE_BUMP) + } else if (ISSET(info->command, FORCE_BUMP) && curr_level + 1 < DUMP_LEVELS) { - askfor(ep, i++, curr_level+1, &info); + askfor(ep, i++, curr_level+1, info); log_add(L_INFO,_("Bumping of %s:%s at level %d as directed."), dp->host->hostname, qname, curr_level+1); ep->degr_mesg = _("Skipping: force-bump disk can't be dumped in degraded mode"); } else if (curr_level == 0) { - askfor(ep, i++, 1, &info); + askfor(ep, i++, 1, info); } else { - askfor(ep, i++, curr_level, &info); + askfor(ep, i++, curr_level, info); /* * If last time we dumped less than the threshold, then this * time we will too, OR the extra size will be charged to both @@ -1091,25 +1095,25 @@ setup_estimate( * if we haven't been at this level 2 days, or the dump failed * last night, we can't bump. */ - if((info.inf[curr_level].size == (gint64)0 || /* no data, try it anyway */ - (((info.inf[curr_level].size > bump_thresh(curr_level, info.inf[0].size,dp->bumppercent, dp->bumpsize, dp->bumpmult))) + if((info->inf[curr_level].size == (gint64)0 || /* no data, try it anyway */ + (((info->inf[curr_level].size > bump_thresh(curr_level, info->inf[0].size,dp->bumppercent, dp->bumpsize, dp->bumpmult))) && ep->level_days >= dp->bumpdays)) && curr_level + 1 < DUMP_LEVELS) { - askfor(ep, i++, curr_level+1, &info); + askfor(ep, i++, curr_level+1, info); } - } + } } } - while(i < MAX_LEVELS) /* mark end of estimates */ - askfor(ep, i++, -1, &info); + while(i < MAX_LEVELS) /* mark end of estimates */ + askfor(ep, i++, -1, info); /* debug output */ g_fprintf(stderr, _("setup_estimate: %s:%s: command %u, options: %s " - "last_level %d next_level0 %d level_days %d getting estimates " + "last_level %d next_level0 %d level_days %d getting estimates " "%d (%lld) %d (%lld) %d (%lld)\n"), - dp->host->hostname, qname, info.command, + dp->host->hostname, qname, info->command, dp->strategy == DS_NOFULL ? "no-full" : dp->strategy == DS_INCRONLY ? "incr-only" : dp->skip_full ? "skip-full" : @@ -1287,10 +1291,9 @@ static int runs_at( last = last_level(info); if(lev != last) return 0; - if(lev == 0) return 1; - if(info->consecutive_runs != -1) return info->consecutive_runs; + if(lev == 0) return 1; /* to keep compatibility with old infofile */ cur_tape = lookup_tapelabel(info->inf[lev].label); @@ -2226,7 +2229,8 @@ static void analyze_estimate( /* fill in degraded mode info */ g_fprintf(stderr,_("(picking inclevel for degraded mode)")); ep->degr_est = pick_inclevel(dp); - if (ep->degr_est->csize == (gint64)-1) { + if (ep->degr_est->level >= 0 && + ep->degr_est->csize == (gint64)-1) { ep->degr_est = est_for_level(dp, ep->degr_est->level + 1); } if (ep->degr_est->csize == (gint64)-1) { @@ -2476,6 +2480,7 @@ static void delay_dumps(void) disk_t * dp; disk_t * ndp; disk_t * preserve; + disk_t * delayed_dp; bi_t * bi; bi_t * nbi; gint64 new_total; /* New total_size */ @@ -2485,6 +2490,8 @@ static void delay_dumps(void) int delete; char * message; gint64 full_size; + time_t timestamps; + int priority; biq.head = biq.tail = NULL; @@ -2550,7 +2557,7 @@ static void delay_dumps(void) } else { delete = 0; - message = _("full dump delayed"); + message = _("full dump delayed, doing incremental"); } } else { @@ -2576,51 +2583,71 @@ static void delay_dumps(void) nb_forced_level_0 = 0; preserve = NULL; - for(dp = schedq.head; dp != NULL && preserve == NULL; dp = dp->next) - if(est(dp)->dump_est->level == 0) - preserve = dp; + timestamps = 2147483647; + priority = 0; + for(dp = schedq.head; dp != NULL; dp = dp->next) { + if (est(dp)->dump_est->level == 0) { + if (!preserve || + est(dp)->dump_priority > priority || + (est(dp)->dump_priority == priority && + est(dp)->info->inf[0].date < timestamps)) { + priority = est(dp)->dump_priority; + timestamps = est(dp)->info->inf[0].date; + preserve = dp; + } + } + } /* 2.a. Do not delay forced full */ - for(dp = schedq.tail; + delayed_dp = NULL; + do { + delayed_dp = 0; + timestamps = 0; + for(dp = schedq.tail; dp != NULL && total_size > tape_length; dp = ndp) { - ndp = dp->prev; - - if(est(dp)->dump_est->level != 0) continue; + ndp = dp->prev; - get_info(dp->host->hostname, dp->name, &info); - if(ISSET(info.command, FORCE_FULL)) { - nb_forced_level_0 += 1; - preserve = dp; - continue; - } + if(est(dp)->dump_est->level != 0) continue; - if(dp != preserve) { + get_info(dp->host->hostname, dp->name, &info); + if(ISSET(info.command, FORCE_FULL)) { + nb_forced_level_0 += 1; + preserve = dp; + continue; + } + if (dp != preserve && + est(dp)->info->inf[0].date > timestamps) { + delayed_dp = dp; + timestamps = est(dp)->info->inf[0].date; + } + } + if (delayed_dp) { /* Format dumpsize for messages */ g_snprintf(est_kb, 20, "%lld KB,", - (long long)est(dp)->dump_est->csize); + (long long)est(delayed_dp)->dump_est->csize); - if(dp->skip_incr) { + if(delayed_dp->skip_incr) { delete = 1; message = _("but cannot incremental dump skip-incr disk"); } - else if(est(dp)->last_level < 0) { + else if(est(delayed_dp)->last_level < 0) { delete = 1; message = _("but cannot incremental dump new disk"); } - else if(est(dp)->degr_est->level < 0) { + else if(est(delayed_dp)->degr_est->level < 0) { delete = 1; message = _("but no incremental estimate"); } else { delete = 0; - message = _("full dump delayed"); + message = _("full dump delayed, doing incremental"); } - delay_one_dump(dp, delete, _("dumps too big,"), est_kb, + delay_one_dump(delayed_dp, delete, _("dumps too big,"), est_kb, message, NULL); } - } + } while (delayed_dp); /* 2.b. Delay forced full if needed */ if(nb_forced_level_0 > 0 && total_size > tape_length) { diff --git a/server-src/tapefile.c b/server-src/tapefile.c index 8e4400b..faf5875 100644 --- a/server-src/tapefile.c +++ b/server-src/tapefile.c @@ -50,7 +50,7 @@ read_tapelist( char *line = NULL; int status = 0; - tape_list = NULL; + clear_tapelist(); if((tapef = fopen(tapefile,"r")) == NULL) { if (errno == ENOENT) { /* no tapelist is equivalent to an empty tapelist */ @@ -132,6 +132,9 @@ clear_tapelist(void) for(tp = tape_list; tp; tp = next) { amfree(tp->label); amfree(tp->datestamp); + amfree(tp->barcode); + amfree(tp->meta); + amfree(tp->comment); next = tp->next; amfree(tp); } @@ -275,6 +278,9 @@ remove_tapelabel( } amfree(tp->datestamp); amfree(tp->label); + amfree(tp->meta); + amfree(tp->comment); + amfree(tp->barcode); amfree(tp); } } @@ -289,7 +295,7 @@ add_tapelabel( /* insert a new record to the front of the list */ - new = (tape_t *) alloc(SIZEOF(tape_t)); + new = g_new0(tape_t, 1); new->datestamp = stralloc(datestamp); new->position = 0; @@ -362,19 +368,17 @@ parse_tapeline( int ch; *status = 0; - tp = (tape_t *) alloc(SIZEOF(tape_t)); - - tp->prev = NULL; - tp->next = NULL; s = line; ch = *s++; skip_whitespace(s, ch); if(ch == '\0') { - amfree(tp); return NULL; } + + tp = g_new0(tape_t, 1); + s1 = s - 1; skip_non_whitespace(s, ch); s[-1] = '\0'; @@ -409,8 +413,6 @@ parse_tapeline( s[-1] = '\0'; skip_whitespace(s, ch); tp->barcode = stralloc(s1); - } else { - tp->barcode = NULL; } if (strncmp_const(s - 1, "META:") == 0) { @@ -419,8 +421,6 @@ parse_tapeline( s[-1] = '\0'; skip_whitespace(s, ch); tp->meta = stralloc(s1); - } else { - tp->meta = NULL; } if (strncmp_const(s - 1, "BLOCKSIZE:") == 0) { @@ -429,13 +429,9 @@ parse_tapeline( s[-1] = '\0'; skip_whitespace(s, ch); tp->blocksize = atol(s1); - } else { - tp->blocksize = 0; } if (*(s - 1) == '#') { tp->comment = stralloc(s); /* skip leading '#' */ - } else { - tp->comment = NULL; } return tp; diff --git a/server-src/taper.pl b/server-src/taper.pl index b685a52..8422dbc 100644 --- a/server-src/taper.pl +++ b/server-src/taper.pl @@ -1,5 +1,5 @@ #! @PERL@ -# Copyright (c) 2009, 2010 Zmanda Inc. All Rights Reserved. +# Copyright (c) 2009-2012 Zmanda Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published diff --git a/server-src/xfer-server.h b/server-src/xfer-server.h index f8178d1..34e1814 100644 --- a/server-src/xfer-server.h +++ b/server-src/xfer-server.h @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -38,5 +38,8 @@ XferElement *xfer_source_holding( const char *filename); +guint64 +xfer_source_holding_get_bytes_read( + XferElement *elt); #endif diff --git a/server-src/xfer-source-holding.c b/server-src/xfer-source-holding.c index a53c512..4776acc 100644 --- a/server-src/xfer-source-holding.c +++ b/server-src/xfer-source-holding.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2009-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -49,6 +49,7 @@ typedef struct XferSourceHolding { int fd; char *next_filename; + guint64 bytes_read; XferElement *dest_taper; } XferSourceHolding; @@ -195,6 +196,7 @@ pull_buffer_impl( bytes_read = full_read(self->fd, buf, HOLDING_BLOCK_SIZE); if (bytes_read > 0) { *size = bytes_read; + self->bytes_read += bytes_read; return buf; } @@ -296,7 +298,17 @@ xfer_source_holding( XferElement *elt = XFER_ELEMENT(self); self->next_filename = g_strdup(filename); + self->bytes_read = 0; return elt; } +guint64 +xfer_source_holding_get_bytes_read( + XferElement *elt) +{ + XferSourceHolding *self = (XferSourceHolding *)elt; + + return self->bytes_read; +} + diff --git a/xfer-src/Makefile.in b/xfer-src/Makefile.in index 86690cf..c83f280 100644 --- a/xfer-src/Makefile.in +++ b/xfer-src/Makefile.in @@ -18,7 +18,7 @@ # Makefile for Amanda library. # vim:ft=automake -# Copyright (c) 2007,2008,2009 Zmanda, Inc. All Rights Reserved. +# Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published @@ -269,7 +269,8 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/ltoptions.m4 \ $(top_srcdir)/config/ltsugar.m4 \ $(top_srcdir)/config/ltversion.m4 \ - $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in + $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -842,6 +843,9 @@ MSGMERGE = @MSGMERGE@ MT = @MT@ MTX = @MTX@ MT_FILE_FLAG = @MT_FILE_FLAG@ +NC = @NC@ +NC6 = @NC6@ +NETCAT = @NETCAT@ NETINET_IN_H = @NETINET_IN_H@ NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ diff --git a/xfer-src/amxfer.h b/xfer-src/amxfer.h index 2333dea..ab89d2f 100644 --- a/xfer-src/amxfer.h +++ b/xfer-src/amxfer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/dest-buffer.c b/xfer-src/dest-buffer.c index 1d41e5a..4e85a70 100644 --- a/xfer-src/dest-buffer.c +++ b/xfer-src/dest-buffer.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/dest-directtcp-connect.c b/xfer-src/dest-directtcp-connect.c index 72c5961..d739bf8 100644 --- a/xfer-src/dest-directtcp-connect.c +++ b/xfer-src/dest-directtcp-connect.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/dest-directtcp-listen.c b/xfer-src/dest-directtcp-listen.c index da3cc7f..345bbbe 100644 --- a/xfer-src/dest-directtcp-listen.c +++ b/xfer-src/dest-directtcp-listen.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/dest-fd.c b/xfer-src/dest-fd.c index 6eee1d4..962d3dd 100644 --- a/xfer-src/dest-fd.c +++ b/xfer-src/dest-fd.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/dest-null.c b/xfer-src/dest-null.c index c5260a5..c4a49ef 100644 --- a/xfer-src/dest-null.c +++ b/xfer-src/dest-null.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/element-glue.c b/xfer-src/element-glue.c index 319b576..bb31e93 100644 --- a/xfer-src/element-glue.c +++ b/xfer-src/element-glue.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -220,7 +220,7 @@ do_directtcp_connect( /* set up the sockaddr -- IPv4 only */ copy_sockaddr(&addr, addrs); - g_debug("making data connection to %s", str_sockaddr(&addr)); + g_debug("do_directtcp_connect making data connection to %s", str_sockaddr(&addr)); sock = socket(SU_GET_FAMILY(&addr), SOCK_STREAM, 0); if (sock < 0) { xfer_cancel_with_error(elt, diff --git a/xfer-src/element-glue.h b/xfer-src/element-glue.h index d4f94e5..1838bfd 100644 --- a/xfer-src/element-glue.h +++ b/xfer-src/element-glue.h @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/filter-process.c b/xfer-src/filter-process.c index aa23b0b..fbbe8e8 100644 --- a/xfer-src/filter-process.c +++ b/xfer-src/filter-process.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/filter-xor.c b/xfer-src/filter-xor.c index 7d83665..112570c 100644 --- a/xfer-src/filter-xor.c +++ b/xfer-src/filter-xor.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/source-directtcp-connect.c b/xfer-src/source-directtcp-connect.c index 61c6070..b7ddc5b 100644 --- a/xfer-src/source-directtcp-connect.c +++ b/xfer-src/source-directtcp-connect.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/source-directtcp-listen.c b/xfer-src/source-directtcp-listen.c index 82bac75..8d3611c 100644 --- a/xfer-src/source-directtcp-listen.c +++ b/xfer-src/source-directtcp-listen.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/source-fd.c b/xfer-src/source-fd.c index 9d1814a..fedeba6 100644 --- a/xfer-src/source-fd.c +++ b/xfer-src/source-fd.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/source-pattern.c b/xfer-src/source-pattern.c index 5a4aad8..1a9432f 100644 --- a/xfer-src/source-pattern.c +++ b/xfer-src/source-pattern.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2011 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/source-random.c b/xfer-src/source-random.c index b7c8f4b..0683b6f 100644 --- a/xfer-src/source-random.c +++ b/xfer-src/source-random.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/xfer-element.c b/xfer-src/xfer-element.c index dd94e3c..37e3377 100644 --- a/xfer-src/xfer-element.c +++ b/xfer-src/xfer-element.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -238,11 +238,15 @@ xfer_element_pull_buffer( XferElement *elt, size_t *size) { + xfer_status status; /* Make sure that the xfer is running before calling upstream's * pull_buffer method; this avoids a race condition where upstream * hasn't finished its xfer_element_start yet, and isn't ready for * a pull */ - if (elt->xfer->status == XFER_START) + g_mutex_lock(elt->xfer->status_mutex); + status = elt->xfer->status; + g_mutex_unlock(elt->xfer->status_mutex); + if (status == XFER_START) wait_until_xfer_running(elt->xfer); return XFER_ELEMENT_GET_CLASS(elt)->pull_buffer(elt, size); diff --git a/xfer-src/xfer-element.h b/xfer-src/xfer-element.h index 5d45ac0..6c4ebed 100644 --- a/xfer-src/xfer-element.h +++ b/xfer-src/xfer-element.h @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/xfer-test.c b/xfer-src/xfer-test.c index f83448a..9c43b4a 100644 --- a/xfer-src/xfer-test.c +++ b/xfer-src/xfer-test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/xfer.c b/xfer-src/xfer.c index ac97198..97b7147 100644 --- a/xfer-src/xfer.c +++ b/xfer-src/xfer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -269,7 +269,10 @@ xfer_cancel( { /* Since xfer_cancel can be called from any thread, we just send a message. * The action takes place when the message is received. */ - XferElement *src = g_ptr_array_index(xfer->elements, 0); + XferElement *src; + if (xfer->cancelled > 0) return; + xfer->cancelled++; + src = g_ptr_array_index(xfer->elements, 0); xfer_queue_message(xfer, xmsg_new(src, XMSG_CANCEL, 0)); } diff --git a/xfer-src/xfer.h b/xfer-src/xfer.h index 3d6773a..16a6a78 100644 --- a/xfer-src/xfer.h +++ b/xfer-src/xfer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -90,6 +90,8 @@ struct Xfer { /* Used to coordinate handing off file descriptors among elements of this * xfer */ GMutex *fd_mutex; + + int cancelled; }; typedef struct Xfer Xfer; diff --git a/xfer-src/xmsg.c b/xfer-src/xmsg.c index 99c9a54..a67624c 100644 --- a/xfer-src/xmsg.c +++ b/xfer-src/xmsg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/xfer-src/xmsg.h b/xfer-src/xmsg.h index 172561a..85ba2ca 100644 --- a/xfer-src/xmsg.h +++ b/xfer-src/xmsg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008,2009 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published -- 2.30.2