+2012-07-24 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * VERSION: 3.3.2
+
+2012-07-24 Jean-Louis Martineau <martineau@zmanda.com>
+ * device-src/s3-device.c: Fix a big memory leak.
+
+2012-07-23 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amanda.conf.5.xml: Typo.
+
+2012-07-23 Jean-Louis Martineau <martineau@zmanda.com>
+ * ReleaseNotes, NEWS: Add new features in 3.3.2.
+
+2012-07-20 Dan Locks <dwlocks@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * common-src/timestamp.c (get_time_from_timestamp): Initialize to 0.
+
+2012-07-19 Jean-Louis Martineau <martineau@zmanda.com>
+ Patch by crocket
+ * perl/Makefile.am: Fix cygwin build.
+
+2012-07-18 Jean-Louis Martineau <martineau@zmanda.com>
+ * device-src/s3.c: Parse application/json reply from cloudena.
+
+2012-07-18 Jean-Louis Martineau <martineau@zmanda.com>
+ * installcheck/Amanda_IPC_LineProtocol.pl: Add synchonization to fix
+ race.
+
+2012-07-17 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <dwlocks@zmanda.com>
+ * 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 <dwlocks@zmanda.com>
+ * 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 <dwlocks@zmanda.com>
+ * 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 <dwlocks@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * server-src/amstatus.pl: Print 'dump done' if the dump succeeded.
+
+2012-07-09 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * server-src/driver.c (tape_action): Fix for flush_*.
+ Change debug level.
+
+2012-06-29 Jean-Louis Martineau <martineau@zmanda.com>
+ * perl/Amanda/Taper/Scan/traditional.pm,
+ perl/Amanda/Taper/Scribe.pm: Correctly report error.
+
+2012-06-29 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * device-src/s3.c: Fix compiler warning.
+
+2012-06-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * device-src/s3.c: Renew swift v2 x-auth-token before it expires, use
+ glib if >= 2.26.
+
+2012-06-27 Dan Locks <dwlocks@zmanda.com>
+ * configure.in: update ac_prereq to 2.64
+
+2012-06-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * device-src/s3.c: remove code to Renew swift v2 x-auth-token, it
+ require glib 2.26.
+
+2012-06-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * device-src/s3.c: Remove bogus code.
+
+2012-06-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * device-src/s3.c: Renew swift v2 x-auth-token before it expires.
+
+2012-06-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/conffile.c: Fix crash when parsing an invalid config file.
+
+2012-06-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * device-src/s3.c: Cloudena do not have xml_version of html tag in
+ their reply.
+
+2012-06-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * device-src/s3.c: Renew OAUTH2 token.
+
+2012-06-21 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * device-src/s3.c: OAUTH2 use 'max-keys'.
+
+2012-06-20 Jean-Louis Martineau <martineau@zmanda.com>
+ * perl/Amanda/Taper/Worker.pm: Fix update of the status file.
+
+2012-06-20 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/security-util.c: Fix memory corruption.
+
+2012-06-20 Jean-Louis Martineau <martineau@zmanda.com>
+ * perl/Amanda/Taper/Scribe.pm: Cancel call dump_cb.
+ * perl/Amanda/Taper/Worker.pm: Cancel the header xfer.
+
+2012-06-20 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/planner.c: Fix 32 bits overflow.
+
+2012-06-19 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * server-src/planner.c: Coorectly delay full dump if it doesn't fit in
+ the schedule.
+
+2012-06-14 Dan Locks <dwlocks@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * application-src/amgtar.c: Check gtar support --no-check-device.
+
+2012-06-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * device-src/s3.c: Parse message attribute in cloudena error reply.
+ Parse details in HP error reply.
+
+2012-06-04 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amrestore.pl: Typo.
+
+2012-06-01 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amrestore.pl: Use the blocksize argument.
+
+2012-06-01 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * application-src/amzfs-sendrecv.pl: fix print_to_server argument.
+
+2012-05-24 Jean-Louis Martineau <martineau@zmanda.com>
+ * application-src/amsamba.pl: Do not send a chomped line to index.
+
+2012-05-24 Jean-Louis Martineau <martineau@zmanda.com>
+ * perl/Amanda/Application.swg: Use IO::Handle to open mesgout.
+
+2012-05-23 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <dwlocks@zmanda.com>
+ * packaging/sun-pkg/buildpkg: add missing --with-libcurl= for server
+
+2012-05-17 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/event.c: Add missing "\n" in debugging.
+ * perl/Amanda/Application.swg: Make mesgout autoflush.
+
+2012-05-15 Jean-Louis Martineau <martineau@zmanda.com>
+ * installcheck/Amanda_Device.pl: Correctly count NDMP test.
+
+2012-05-15 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amvault.pl: Abort if log file already exists.
+
+2012-05-15 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/find.c: Fix crash when log are corrupted.
+
+2012-05-15 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * common-src/util.c, device-src/s3.c: Fix for pragma and gcc-4.5.2.
+
+2012-05-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * perl/Amanda/Taper/Worker.pm (FAILED): Do it correctly.
+
+2012-05-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amstatus.pl: Improve output on taper error.
+
+2012-05-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * perl/Amanda/Taper/Worker.pm (FAILED): Ignore if dump is already
+ cancelled.
+
+2012-05-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/event.c: Improve debugging.
+ * server-src/dumper.c: Close data output in stop_dump.
+
+2012-05-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <dwlocks@zmanda.com>
+ * 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 <dwlocks@zmanda.com>
+ * Makefile.am: update required automake version
+
+2012-05-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * installcheck/Amanda_Device.pl: sleep to allow other process the time
+ to start listening.
+
+2012-05-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * installcheck/Amanda_Device.pl: Fix indirect tcp.
+
+2012-05-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * server-src/amfetchdump.pl: Fix.
+
+2012-04-20 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amadmin.c: Fix handling of optional arguments.
+ * installcheck/amadmin.pl: Check it.
+
+2012-04-19 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/amdump_client.pl: Fix warning.
+
+2012-04-18 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amfetchdump.pl: add --decompress and --decrypt options.
+ * man/xml-source/amfetchdump.8.xml: Document new options.
+
+2012-04-18 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * ndmp-src/ndmpconnobj.c: Remove useless g_source_is_destroyed check.
+
+2012-04-17 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * application-src/amstar.c: Remove spurious space on directory entry.
+
+2012-04-13 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * application-src/amsamba.pl: Create incremental empty archive.
+
+2012-04-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ 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 <martineau@zmanda.com>
+ * man/xml-source/amgtar.8.xml: s/APPLCIATION/APPLICATION/
+
+2012-04-06 Jean-Louis Martineau <martineau@zmanda.com>
+ * application-src/ampgsql.pl: psql /could not connect to server/
+ message result in STRANGE.
+
+2012-04-06 Jean-Louis Martineau <martineau@zmanda.com>
+ * perl/Amanda/ScanInventory.pm: Fix for label not matching labelstr.
+
+2012-04-06 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * man/xml-source/amfetchdump.8.xml: Document -l do not unencrypt.
+
+2012-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * application-src/amsamba.pl: Do not set unc prematurely.
+
+2012-04-02 Jean-Louis Martineau <martineau@zmanda.com>
+ * device-src/ndmp-device.c (listen_impl): Set the window offset and
+ length to blocksize when reading.
+
+2012-03-29 Dan Locks <dwlocks@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * server-src/driver.c: Fix hang if taper crash.
+
+2012-03-29 Jean-Louis Martineau <martineau@zmanda.com>
+ * device-src/s3.c: Retry on {500, S3_ERROR_None} error.
+ Improving debugging.
+
+2012-03-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amadmin.c: Fix bumpsize.
+
+2012-03-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * application-src/amgtar.c: Use "TAR-BLOCKSIZE" on restore.
+
+2012-03-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * application-src/ampgsql.pl: Use statefile to find end_wal on
+ estimate.
+
+2012-03-15 Jean-Louis Martineau <martineau@zmanda.com>
+ * application-src/amgtar.c: Add IGNORE-ZEROS property.
+ * man/xml-source/amgtar.8.xml: Document IGNORE-ZEROS property.
+
+2012-03-13 Jean-Louis Martineau <martineau@zmanda.com>
+ * application-src/ampgsql.pl: Do not Execute pg_start_backup for
+ estimate.
+
+2012-03-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/glib-util.c: g_thread_supported always return TRUE on
+ newer version.
+
+2012-03-10 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/glib-util.c, common-src/glib-util.h: Remove
+ g_queue_free_full.
+
+2012-03-09 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * perl/Amanda/Recovery/Scan.pm: Do not rescan the same slot
+ indefinitely.
+
+2012-03-09 Jean-Louis Martineau <martineau@zmanda.com>
+ * perl/Amanda/Changer/multi.pm: Fix warning.
+
+2012-03-09 Jean-Louis Martineau <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * 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 <martineau@zmanda.com>
+ * server-src/amvault.pl: Use the write-timestamp, not the
+ dump-timestamp.
+
+2012-03-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/ssh-security.c: use default port if client-port is not
+ set.
+
+2012-03-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * application-src/amsamba.pl: Fix use of subdir for restore,
+ prepend subdir on include for restore.
+
+2012-03-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * ndmp-src/ndmjob_args.c: Add '-o D-agent-fd' argument.
+
+2012-03-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * application-src/ampgsql.pl: Do not execute pg_start_backup and
+ pg_stop_backup on selfcheck.
+
+2012-02-23 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amzfs-sendrecv.8.xml: Typo.
+
+2012-02-23 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/disklist.5.xml: Document includefile directive.
+
2012-02-21 Jean-Louis Martineau <martineau@zmanda.com>
* perl/make_html.pl: Add link at top, better list display.
* perl/Makefile.am: Execute make_html with a --homeurl argument.
## 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
@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
$(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 \
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@
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 \
+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
+ 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
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
# 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
$(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
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@
char *service_path = NULL;
GSList *errlist = NULL;
int i;
+ char *peer_name;
pkt_out.body = NULL;
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.
#include "amanda.h"
#include "amfeatures.h"
-#include "sl.h"
+#include "am_sl.h"
#include "util.h" /* for bstrncmp() */
typedef struct g_option_s {
# 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
$(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
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@
/*
- * 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
/*
- * 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
/*
- * 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
# 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
# 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
$(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
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@
# 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
# 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
$(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
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@
int argc;
char **argv;
int verbose;
+ int ignore_zeros;
} application_argument_t;
enum { CMD_ESTIMATE, CMD_BACKUP };
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);
{"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}
};
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;
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;
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) {
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,
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);
#!@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
#!@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
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);
_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`;
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");
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.
-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?
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);
};
".");
$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");
}
}
#!@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
#!@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
use Amanda::Debug qw( :logging );
use Amanda::Paths;
use Amanda::Util qw( :constants :quoting);
+use Amanda::MainLoop qw( :GIOCondition );
sub new {
my $class = shift;
} else {
$self->{device} = $disk;
}
- if ($self->{disk} =~ /^\\\\/) {
- $self->{unc} = 1;
- } else {
- $self->{unc} = 0;
- }
$self->{level} = [ @{$level} ];
$self->{index} = $index;
$self->{message} = $message;
next;
}
while (<FF>) {
+ if (defined $self->{'subdir'}) {
+ $_ =~ s/^\./$self->{'subdir'}/;
+ }
print INC_FILE;
}
close(FF);
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;
}
while (<FF>) {
chomp;
+ if ($self->{action} eq "restore" and
+ defined $self->{'subdir'}) {
+ $_ =~ s/^\./$self->{'subdir'}/;
+ }
push @{$self->{include}}, $_;
}
close(FF);
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;
}
}
$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,^(\\\\[^\\]+\\[^\\]+)\\(.*)$,) {
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;
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);
}
#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");
}
$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;
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);
}
#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);
}
}
+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;
$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}));
}
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) {
$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};
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;
#!@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
#!@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
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);
#!@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
#!@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
# 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
# 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
$(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
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@
# 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
# 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
$(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
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@
#! @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
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 /)
}
}
}
#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)))
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(
/*
* =========================================================================
*/
-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");
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));
#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 */
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);
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);
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);
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");
#include "getfsent.h"
#include "conffile.h"
#include "amandates.h"
+#include "stream.h"
#define sendbackup_debug(i, ...) do { \
if ((i) <= debug_sendbackup) { \
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);
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);
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);
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));
}
fcntl(indexfd, F_SETFD, 0);
}
- application_api_info_tapeheader(mesgfd, dle->program, dle);
if (indexfd != 0) {
safe_fd(3, 2);
} else {
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 */
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);
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)
/* 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;
}
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);
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)
libamanda_la_SOURCES = \
alloc.c \
+ am_sl.c \
amfeatures.c \
amflock.c \
ipc-binary.c \
security.c \
security-util.c \
simpleprng.c \
- sl.c \
sockaddr-util.c \
stream.c \
tapelist.c \
security.h \
security-util.h \
simpleprng.h \
- sl.h \
+ am_sl.h \
sockaddr-util.h \
stream.h \
tapelist.h \
# 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
# 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
$(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
"$(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 \
@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)
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@
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
security.h \
security-util.h \
simpleprng.h \
- sl.h \
+ am_sl.h \
sockaddr-util.h \
stream.h \
tapelist.h \
-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@
@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@
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ * Computer Science Department
+ * University of Maryland at College Park
+ */
+/*
+ * $Id: sl.c,v 1.6 2006/05/25 01:47:12 johnfranks Exp $
+ *
+ * A doubly linked list of string (char *)
+ */
+
+#include "amanda.h"
+#include "am_sl.h"
+
+
+void init_sl(
+ am_sl_t *sl)
+{
+ sl->first = NULL;
+ sl->last = NULL;
+ sl->nb_element = 0;
+}
+
+
+am_sl_t *
+new_sl(void)
+{
+ am_sl_t *sl;
+ sl = alloc(SIZEOF(am_sl_t));
+ init_sl(sl);
+ return(sl);
+}
+
+
+am_sl_t *
+insert_sl(
+ am_sl_t *sl,
+ char *name)
+{
+ sle_t *a;
+
+ if(!sl) {
+ sl = new_sl();
+ }
+ a = alloc(SIZEOF(sle_t));
+ a->name = stralloc(name);
+ a->next = sl->first;
+ a->prev = NULL;
+ if(a->next)
+ a->next->prev = a;
+ else
+ sl->last = a;
+ sl->first = a;
+ sl->nb_element++;
+ return(sl);
+}
+
+
+am_sl_t *
+append_sl(
+ am_sl_t * sl,
+ char * name)
+{
+ sle_t *a;
+
+ if(!sl) {
+ sl = new_sl();
+ }
+ a = alloc(SIZEOF(sle_t));
+ a->name = stralloc(name);
+ a->prev = sl->last;
+ a->next = NULL;
+ if(a->prev)
+ a->prev->next = a;
+ else
+ sl->first = a;
+ sl->last = a;
+ sl->nb_element++;
+ return(sl);
+}
+
+
+am_sl_t *
+insert_sort_sl(
+ am_sl_t * sl,
+ char * name)
+{
+ sle_t *a, *b;
+
+ if(!sl) {
+ sl = new_sl();
+ }
+
+ for(b=sl->first; b != NULL; b=b->next) {
+ int i = strcmp(b->name, name);
+ if(i==0) return(sl); /* already there, no need to insert */
+ if(i>0) break;
+ }
+
+ if(b == sl->first) return insert_sl(sl, name);
+ if(b == NULL) return append_sl(sl, name);
+
+ a = alloc(SIZEOF(sle_t));
+ a->name = stralloc(name);
+
+ /* insert before b */
+ a->next = b;
+ a->prev = b->prev;
+ b->prev->next = a;
+ b->prev = a;
+ sl->nb_element++;
+ return(sl);
+}
+
+
+void
+free_sl(
+ am_sl_t * sl)
+{
+ sle_t *a, *b;
+
+ if(!sl) return;
+
+ a = sl->first;
+ while(a != NULL) {
+ b = a;
+ a = a->next;
+ amfree(b->name);
+ amfree(b);
+ }
+ amfree(sl);
+}
+
+
+void
+remove_sl(
+ am_sl_t * sl,
+ sle_t * elem)
+{
+ if(elem->prev)
+ elem->prev->next = elem->next;
+ else
+ sl->first = elem->next;
+
+ if(elem->next)
+ elem->next->prev = elem->prev;
+ else
+ sl->last = elem->prev;
+
+ sl->nb_element--;
+
+ amfree(elem->name);
+ amfree(elem);
+}
+
+
+am_sl_t *
+duplicate_sl(
+ am_sl_t * sl)
+{
+ am_sl_t *new_sl = NULL;
+ sle_t *a;
+
+ if(!sl) return new_sl;
+
+ for(a = sl->first; a != NULL; a = a->next) {
+ new_sl = append_sl(new_sl, a->name);
+ }
+
+ return new_sl;
+}
+
+/*
+ * Return "true" iff sl is empty (i.e. contains no elements).
+ */
+int
+is_empty_sl(
+ am_sl_t * sl)
+{
+ if (sl == NULL)
+ return 1;
+
+ return (sl->nb_element == 0);
+}
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ * Computer Science Department
+ * University of Maryland at College Park
+ */
+/*
+ * $Id: sl.h,v 1.4 2006/05/25 01:47:12 johnfranks Exp $
+ *
+ * A doubly linked list of string (char *)
+ */
+
+/*
+ * To scan over all element of the list
+ *
+ * for(sle=sl->first; sle != NULL; sle = sle->next) {
+ * }
+ */
+#ifndef STRINGLIST_H
+#define STRINGLIST_H
+
+#include "amanda.h"
+
+typedef struct sle_s {
+ struct sle_s *next, *prev;
+ char *name;
+} sle_t;
+
+typedef struct sl_s {
+ struct sle_s *first, *last;
+ int nb_element;
+} am_sl_t;
+
+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
#! @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
#!@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
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);
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);
* 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);
#! @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
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
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();
#!@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
$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 {
/*
- * 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
/*
- * 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
/*
- * 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
property_t *property_data;
proplist_t property;
script_t *script;
- level_t *alevel;
+ am_level_t *alevel;
char *encoding;
char *raw;
} amgxml_t;
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) {
}
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';
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;
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;
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,
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,
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. */
struct changer_config_s {
struct changer_config_s *next;
- int seen;
+ seen_t seen;
char *name;
val_t value[CHANGER_CONFIG_CHANGER_CONFIG];
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 *);
* 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);
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);
/*
* 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);
/* 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
{ "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 },
{ "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 },
{ 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 },
{ 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 },
{ 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 }
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;
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:
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;
{
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
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;
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);
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);
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]);
}
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;
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();
{
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
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;
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
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;
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;
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;
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;
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], "");
}
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;
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"),
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;
}
val_t *val)
{
ckseen(&val->seen);
- val_t__int(val) = get_int();
+ val_t__int(val) = get_int(val->unit);
}
static void
val_t *val)
{
ckseen(&val->seen);
- val_t__int64(val) = get_int64();
+ val_t__int64(val) = get_int64(val->unit);
}
static void
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
val_t *val)
{
int file, got_one = 0;
- sl_t *exclude;
+ am_sl_t *exclude;
int optional = 0;
get_conftoken(CONF_ANY);
val_t *val)
{
char *key;
+ gboolean set_seen = TRUE;
property_t *property = malloc(sizeof(property_t));
property_t *old_property;
property->append = 0;
}
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);
property->priority = 1;
property->values = old_property->values;
old_property->values = NULL;
+ set_seen = FALSE;
}
}
while(tok == CONF_STRING) {
}
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);
+ }
}
}
static int
-get_int(void)
+get_int(
+ confunit_t unit)
{
int val;
keytab_t *save_kt;
}
/* 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;
}
/* 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;
}
/* 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;
}
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;
}
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
*/
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
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;
}
{
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;
}
{
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
{
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
{
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));
{
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;
}
{
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;
}
{
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;
}
{
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;
}
{
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;
}
{
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;
}
{
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;
{
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;
}
{
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;
}
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;
}
{
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;
}
{
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;
}
{
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;
}
{
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;
}
{
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;
{
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;
}
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;
}
{
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);
{
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;
}
{
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;
}
{
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;
}
{
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,
}
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;
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) {
}
val->seen.linenum = 0;
val->seen.filename = NULL;
+ val->seen.block = NULL;
}
/*
}
void
-dump_configuration(void)
+dump_configuration(
+ gboolean print_default,
+ gboolean print_source)
{
tapetype_t *tp;
dumptype_t *dp;
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) {
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");
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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,
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
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;
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:
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;
}
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;
}
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) {
**msg = vstrextend(*msg, " ", qstr, NULL);
amfree(qstr);
}
+ if (user_data->print_source) {
+ **msg = vstrextend(*msg, source_string(&property->seen));
+ }
(*msg)++;
}
val_t *val,
int file)
{
- sl_t *sl;
+ am_sl_t *sl;
sle_t *excl;
char *rval;
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. */
if (*s == '-') *s = '_';
}
- subsec_key = strchr(subsec_name,':');
+ subsec_key = strrchr(subsec_name,':');
if(!subsec_key) goto out; /* failure */
*subsec_key = '\0';
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 */
* 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 */
} 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;
int append;
int priority;
GSList* values;
+ seen_t seen;
} property_t;
typedef GHashTable* proplist_t;
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
} v;
seen_t seen;
conftype_t type;
+ confunit_t unit;
} val_t;
/* Functions to typecheck and extract a particular type of
CNF_TAPERSCAN,
CNF_MAX_DLE_BY_VOLUME,
CNF_EJECT_VOLUME,
+ CNF_TMPDIR,
CNF_CNF /* sentinel */
} confparm_key;
DUMPTYPE_ALLOW_SPLIT,
DUMPTYPE_RECOVERY_LIMIT,
DUMPTYPE_DUMP_LIMIT,
+ DUMPTYPE_MAX_WARNINGS,
DUMPTYPE_DUMPTYPE /* sentinel */
} dumptype_key;
#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
* 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
* @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.
/*
* 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
/*
- * 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
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;
}
/*
- * 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
if (strcmp(tok, "NETDUMP:") != 0 && strcmp(tok, "AMANDA:") != 0) {
amfree(buf);
- file->type = F_UNKNOWN;
+ file->type = F_WEIRD;
amfree(line1);
return;
}
/*
- * 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
#ifdef HAVE_LIBCURL
#include <curl/curl.h>
-#endif
+
+#ifdef LIBCURL_USE_OPENSSL
+#include <openssl/crypto.h>
+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<CRYPTO_num_locks(); i++) {
+ openssl_mutex_array[i] = g_mutex_new();
+ }
+ CRYPTO_set_locking_callback(openssl_lock_callback);
+
+}
+
+#else /* LIBCURL_USE_OPENSSL */
+#if defined LIBCURL_USE_GNUTLS
+
+#include <gcrypt.h>
+#include <errno.h>
+
+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) {
* 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
if (!g_thread_supported())
g_thread_init(NULL);
#endif
+
+ /* initialize ssl */
+ init_ssl();
+
}
typedef enum {
}
#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;
/*
- * 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
/* 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
/*
* 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
/*
* 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
/*
- * 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
* 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;
/*
/*
- * 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
/*
- * 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
return server_hostname;
}
amfree(server_hostname);
- return "localhost";
+ return strdup("localhost");
}
char *
char *hostname = ((struct sec_handle *)hdl)->hostname;
if (!hostname)
hostname = "";
- return hostname;
+ return strdup(hostname);
}
/*
- * 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
/*
- * 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
+++ /dev/null
-/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 1991-1998 University of Maryland at College Park
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of U.M. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. U.M. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: James da Silva, Systems Design and Analysis Group
- * Computer Science Department
- * University of Maryland at College Park
- */
-/*
- * $Id: sl.c,v 1.6 2006/05/25 01:47:12 johnfranks Exp $
- *
- * A doubly linked list of string (char *)
- */
-
-#include "amanda.h"
-#include "sl.h"
-
-
-void init_sl(
- sl_t *sl)
-{
- sl->first = NULL;
- sl->last = NULL;
- sl->nb_element = 0;
-}
-
-
-sl_t *
-new_sl(void)
-{
- sl_t *sl;
- sl = alloc(SIZEOF(sl_t));
- init_sl(sl);
- return(sl);
-}
-
-
-sl_t *
-insert_sl(
- sl_t *sl,
- char *name)
-{
- sle_t *a;
-
- if(!sl) {
- sl = new_sl();
- }
- a = alloc(SIZEOF(sle_t));
- a->name = stralloc(name);
- a->next = sl->first;
- a->prev = NULL;
- if(a->next)
- a->next->prev = a;
- else
- sl->last = a;
- sl->first = a;
- sl->nb_element++;
- return(sl);
-}
-
-
-sl_t *
-append_sl(
- sl_t * sl,
- char * name)
-{
- sle_t *a;
-
- if(!sl) {
- sl = new_sl();
- }
- a = alloc(SIZEOF(sle_t));
- a->name = stralloc(name);
- a->prev = sl->last;
- a->next = NULL;
- if(a->prev)
- a->prev->next = a;
- else
- sl->first = a;
- sl->last = a;
- sl->nb_element++;
- return(sl);
-}
-
-
-sl_t *
-insert_sort_sl(
- sl_t * sl,
- char * name)
-{
- sle_t *a, *b;
-
- if(!sl) {
- sl = new_sl();
- }
-
- for(b=sl->first; b != NULL; b=b->next) {
- int i = strcmp(b->name, name);
- if(i==0) return(sl); /* already there, no need to insert */
- if(i>0) break;
- }
-
- if(b == sl->first) return insert_sl(sl, name);
- if(b == NULL) return append_sl(sl, name);
-
- a = alloc(SIZEOF(sle_t));
- a->name = stralloc(name);
-
- /* insert before b */
- a->next = b;
- a->prev = b->prev;
- b->prev->next = a;
- b->prev = a;
- sl->nb_element++;
- return(sl);
-}
-
-
-void
-free_sl(
- sl_t * sl)
-{
- sle_t *a, *b;
-
- if(!sl) return;
-
- a = sl->first;
- while(a != NULL) {
- b = a;
- a = a->next;
- amfree(b->name);
- amfree(b);
- }
- amfree(sl);
-}
-
-
-void
-remove_sl(
- sl_t * sl,
- sle_t * elem)
-{
- if(elem->prev)
- elem->prev->next = elem->next;
- else
- sl->first = elem->next;
-
- if(elem->next)
- elem->next->prev = elem->prev;
- else
- sl->last = elem->prev;
-
- sl->nb_element--;
-
- amfree(elem->name);
- amfree(elem);
-}
-
-
-sl_t *
-duplicate_sl(
- sl_t * sl)
-{
- sl_t *new_sl = NULL;
- sle_t *a;
-
- if(!sl) return new_sl;
-
- for(a = sl->first; a != NULL; a = a->next) {
- new_sl = append_sl(new_sl, a->name);
- }
-
- return new_sl;
-}
-
-/*
- * Return "true" iff sl is empty (i.e. contains no elements).
- */
-int
-is_empty_sl(
- sl_t * sl)
-{
- if (sl == NULL)
- return 1;
-
- return (sl->nb_element == 0);
-}
+++ /dev/null
-/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 1991-1998 University of Maryland at College Park
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of U.M. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. U.M. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: James da Silva, Systems Design and Analysis Group
- * Computer Science Department
- * University of Maryland at College Park
- */
-/*
- * $Id: sl.h,v 1.4 2006/05/25 01:47:12 johnfranks Exp $
- *
- * A doubly linked list of string (char *)
- */
-
-/*
- * To scan over all element of the list
- *
- * for(sle=sl->first; sle != NULL; sle = sle->next) {
- * }
- */
-#ifndef STRINGLIST_H
-#define STRINGLIST_H
-
-#include "amanda.h"
-
-typedef struct sle_s {
- struct sle_s *next, *prev;
- char *name;
-} sle_t;
-
-typedef struct sl_s {
- struct sle_s *first, *last;
- int nb_element;
-} 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);
-
-#endif
/*
- * 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
/*
- * 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
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);
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));
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:
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 */
-#define BUILT_REV "4553"
-#define BUILT_BRANCH "community_3_3_1"
+#define BUILT_REV "4847"
+#define BUILT_BRANCH "community_3_3_2"
/*
- * 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
/*
- * 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
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);
char * source)
{
GPtrArray *rval = g_ptr_array_new();
+ gpointer *pdata;
g_ptr_array_add(rval, g_strdup(""));
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;
}
}
}
+ 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;
}
# 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
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) {
#define UTIL_H
#include "amanda.h"
-#include "sl.h"
+#include "am_sl.h"
#include <glib.h>
#include <glib-object.h>
$(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
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@
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
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
fi
])
+AC_DEFUN([AMANDA_PROG_NC],
+[
+ AC_PATH_PROG(NC,nc,,$LOCSYSPATH)
+ AC_PATH_PROG(NC6,nc6,,$LOCSYSPATH)
+ AC_PATH_PROG(NETCAT,netcat,,$LOCSYSPATH)
+])
# 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")
])
# 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
# 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
# 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
/* 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) */
#
# 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
#
# 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
#
# 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
#
# 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
#! /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,
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.
AMANDA_SWIG_PERL_CFLAGS
GCC_COMPILER_FALSE
GCC_COMPILER_TRUE
+NETCAT
+NC6
+NC
RPCGEN
PS_ARGUMENT_ARGS
PS_ARGUMENT
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}'
# 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]...
--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]
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:
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.
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 $@
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;}
# Define the identity of the package.
- PACKAGE=amanda
- VERSION=$VERSION
+ PACKAGE='amanda'
+ VERSION='3.3.2'
cat >>confdefs.h <<_ACEOF
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 <conftest.tar" >&5
+ ($am__untar <conftest.tar) >&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; }
+ # 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
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
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
# 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
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\\"
-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)
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
AMANDA_PROG_SWIG
AMANDA_PS_ARGUMENT
AMANDA_PROG_RPCGEN
+AMANDA_PROG_NC
dnl -------------------------------------------------------------------------
# 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
# 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
$(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
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@
#! @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
#! @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
/*
- * 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
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);
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)
{
}
}
+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,
}
}
+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,
/*
- * 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
/* 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;
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;
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);
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,
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);
/*
- * 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
/*
- * 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
/*
- * 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
#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
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;
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)
/*
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
}
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 */
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;
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;
}
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;
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 */
}
/* 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);
}
*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,
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
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 */
return FALSE;
}
self->listen_addrs = *addrs;
- self->for_writing = for_writing;
return TRUE;
}
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
/* reference it for the caller */
g_object_ref(*dtcpconn);
- return TRUE;
+ return 0;
}
static gboolean
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,
if (device_in_error(self)) return FALSE;
+ g_debug("write_from_connection_impl");
if (actual_size)
*actual_size = 0;
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)) {
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 */
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);
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)
{
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;
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,
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
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");
}
/*
/*
- * 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
typedef struct _NullDeviceClass NullDeviceClass;
struct _NullDeviceClass {
DeviceClass __parent__;
- gboolean in_file;
};
void null_device_register(void);
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);
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)
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;
}
/*
- * 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
/*
- * 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
/*
- * 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
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);
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;
}
return FALSE;
} else {
dself->block ++;
+ g_mutex_lock(dself->device_mutex);
+ dself->bytes_written += size;
+ g_mutex_unlock(dself->device_mutex);
return TRUE;
}
return FALSE;
}
+ g_mutex_lock(dself->device_mutex);
dself->in_file = FALSE;
+ g_mutex_unlock(dself->device_mutex);
return TRUE;
}
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 ++) {
}
/* 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;
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")),
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;
/*
- * 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
* Main object structure
*/
typedef struct _S3MetadataFile S3MetadataFile;
+typedef struct _S3Device S3Device;
typedef struct _S3_by_thread S3_by_thread;
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__;
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;
/* 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;
guint64 volume_limit;
gboolean enforce_volume_limit;
gboolean use_subdomain;
+ gboolean use_s3_multi_delete;
int nb_threads;
int nb_threads_backup;
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;
};
/*
#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;
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)
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;
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
*/
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);
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);
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);
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,
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);
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);
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;
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");
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");
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);
Device * dself = DEVICE(self);
GValue response;
+ self->s3_api = S3_API_S3;
self->volume_bytes = 0;
self->volume_limit = 0;
self->leom = TRUE;
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()
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;
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,
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,
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,
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
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,
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)
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);
}
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,
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)
{
/* 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();
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);
}
}
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);
}
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);
}
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")),
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,
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();
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,
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;
- }
}
}
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;
+ }
+ }
}
}
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;
}
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),
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);
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)) {
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)) {
/* 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);
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,
}
self->volume_bytes += header_size;
- for (thread = 0; thread < self->nb_threads; thread++) {
- self->s3t[thread].idle = 1;
- }
return TRUE;
}
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) {
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);
}
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;
}
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);
/*
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);
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;
}
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) {
/* 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);
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);
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) {
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);
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);
}
/*
- * 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
/*
- * 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
/*
- * 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
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;
/* offset with s3 */
time_t time_offset_with_s3;
+ char *content_type;
+
+ gboolean reuse_connection;
};
typedef struct {
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 {
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
* 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;
/*
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);
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,
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
*/
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)
{
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 {
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, "?");
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;
static const char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
/* calculate the date */
t = time(NULL);
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);
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
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 */
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);
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;
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++;
}
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--;
}
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. */
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, "<html>")) {
char *body_copy = g_strndup(body, body_len);
char *b = body_copy;
char *p = strchr(b, '\n');
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 */
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);
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;
}
char *lineprefix;
char *message;
char **lines, **line;
+ size_t i;
switch (type) {
case CURLINFO_TEXT:
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<len;i++) {
+ if (!g_ascii_isprint(s[i])) {
+ return 0;
+ }
+ }
lineprefix="Data In: ";
break;
case CURLINFO_DATA_OUT:
- if (len > 1000) return 0;
+ if (len > 3000) return 0;
+ for (i=0;i<len;i++) {
+ if (!g_ascii_isprint(s[i])) {
+ return 0;
+ }
+ }
lineprefix="Data Out: ";
break;
-*/
+
default:
/* ignore data in/out -- nobody wants to see that in the
* debug logs! */
g_free(message);
for (line = lines; *line; line++) {
- if (**line == '\0') continue; /* skip blank lines */
- g_debug("%s%s", lineprefix, *line);
+ if (**line == '\0') continue; /* skip blank lines */
+ g_debug("%s%s", lineprefix, *line);
}
g_strfreev(lines);
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,
g_assert(hdl != NULL && hdl->curl != 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);
/* 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;
}
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;
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()) {
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)))
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);
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,
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))
{"^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},
{"<Message>[[:space:]]*([^<]*)[[:space:]]*</Message>", REG_EXTENDED | REG_ICASE, &message_regex},
{"^[a-z0-9](-*[a-z0-9]){2,62}$", REG_EXTENDED | REG_NOSUB, &subdomain_regex},
{"(/>)|(>([^<]*)</LocationConstraint>)", 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];
{"^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},
{"<Message>\\s*([^<]*)\\s*</Message>",
G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
&message_regex},
{"^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;
* 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;
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)
}
static gboolean
-get_openstack_swift_api_setting(
+get_openstack_swift_api_v1_setting(
S3Handle *hdl)
{
s3_result_t result = S3_RESULT_FAIL;
};
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("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ if (hdl->username && hdl->password) {
+ g_string_append_printf(body, "<auth xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://docs.openstack.org/identity/api/v2.0\"");
+ } else {
+ g_string_append_printf(body, "<auth xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.hp.com/identity/api/ext/HP-IDM/v1.0\"");
+ }
+
+ if (hdl->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, "<passwordCredentials username=\"%s\" password=\"%s\"/>", hdl->username, hdl->password);
+ } else {
+ g_string_append_printf(body, "<apiAccessKeyCredentials accessKey=\"%s\" secretKey=\"%s\"/>", hdl->access_key, hdl->secret_key);
+ }
+ g_string_append(body, "</auth>");
+
+ 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 *
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 */
/* 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);
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] == '/')) {
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:
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)
{
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);
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;
}
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);
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);
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);
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, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ g_string_append(query, "<Delete>\n");
+ if (!hdl->verbose) {
+ g_string_append(query, " <Quiet>true</Quiet>\n");
+ }
+ while (*key != NULL) {
+ g_string_append(query, " <Object>\n");
+ g_string_append(query, " <Key>");
+ g_string_append(query, *key);
+ g_string_append(query, "</Key>\n");
+ g_string_append(query, " </Object>\n");
+ key++;
+ }
+ g_string_append(query, "</Delete>\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;
}
}
- 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);
* 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);
}
}
+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 },
{ 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);
/*
- * 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
* 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. */
S3_ERROR(Accepted), \
S3_ERROR(Forbidden), \
S3_ERROR(Conflict), \
+ S3_ERROR(AuthenticationRequired), \
S3_ERROR(END)
typedef enum {
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
*
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
*/
gboolean
s3_make_bucket(S3Handle *hdl,
- const char *bucket);
+ const char *bucket,
+ const char *project_id);
/* Check if a bucket exists.
*
*/
gboolean
s3_is_bucket_exists(S3Handle *hdl,
- const char *bucket);
+ const char *bucket,
+ const char *project_id);
/* Delete a bucket
*
/*
- * 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
}
pself->block++;
+ g_mutex_lock(pself->device_mutex);
+ pself->bytes_written += size;
+ g_mutex_unlock(pself->device_mutex);
return TRUE;
}
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;
}
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);
}
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) {
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;
}
return FALSE;
}
+ g_mutex_lock(d_self->device_mutex);
d_self->in_file = FALSE;
+ g_mutex_unlock(d_self->device_mutex);
return TRUE;
}
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) {
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;
}
/* 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
/*
- * 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
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;
}
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;
}
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);
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);
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;
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;
}
/* 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;
release_file(self);
+ g_mutex_lock(dself->device_mutex);
dself->in_file = FALSE;
+ g_mutex_unlock(dself->device_mutex);
return TRUE;
}
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);
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;
/*
- * 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
/*
* 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
/*
* 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
/* 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
/*
* 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
* corresponding condition variable. */
volatile gboolean paused;
GCond *paused_cond;
+ GCond *abort_accept_cond; /* condition to trigger to abort an accept */
} XferDestTaperDirectTCP;
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 */
/* 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");
* 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;
self->conn = NULL;
self->state_mutex = g_mutex_new();
self->paused_cond = g_cond_new();
+ self->abort_accept_cond = g_cond_new();
}
static void
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);
/*
* 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
/* 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
/*
* 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
/*
* 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
/*
* 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
XferElement *self,
Device *device);
+guint64
+xfer_source_recovery_get_bytes_read(
+ XferElement *elt);
+
#endif
/*
* 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
/*
* 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
* 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;
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) {
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;
+}
+
# 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
$(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
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@
$(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
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@
-# 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
-# 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
-# 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
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,
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
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>;
-# 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
-# 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
-# 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
-# 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
-# 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
# 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;
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;
}
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");
}
}
+ #
+ # 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
{
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
POSIX::exit(0);
};
+ $wrh->write("SIMPLE\n");
+
# and sleep forever, or until killed.
while (1) { sleep(100); }
});
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 @_, { @_ } ];
});
# 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" ],
],
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
# 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
# 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
-# 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
# 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
-# 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
# 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
-# 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
# 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
# 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
@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
# 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
$(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
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@
-# 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
# 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;
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");
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
$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' ]);
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
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)
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)
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)
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)
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)
\f
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
\f
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
\f
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
\f
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
\f
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
-# 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
-# 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
-# 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
#! @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
#! @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
#! @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
-# 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
-# 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
-# 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
#! @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
-# 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
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";
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$),
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();
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();
$(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
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@
.\" Title: amaddclient
.\" Author: Kevin Till <kevin.till@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amadmin
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
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
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
.\" Title: amaespipe
.\" Author: Kevin Till <kevin.till@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda-applications
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda-archive-format
.\" Author: Dustin J. Mitchell <dustin@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda-auth
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda-changers
.\" Author: Dustin J. Mitchell <dustin@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda-client.conf
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda-compatibility
.\" Author: Dustin J. Mitchell <dustin@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda-devices
.\" Author: Ian Turner <ian@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
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
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
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
(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
\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
.\" Title: amanda-interactivity
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda-match
.\" Author: Dustin J. Mitchell <dustin@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda-scripts
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda-taperscan
.\" Author: Dustin J. Mitchell <dustin@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amanda.conf
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.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
.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
\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:
\fBplugin\fR \fIstring\fR
.RS 4
No default\&. Must be set to the name of the taperscan module\&. See
-<man></man>
+\fBamanda-taperscan\fR(7)
for a list of defined taperscan modules\&.
.RE
.PP
.\" Title: amarchiver
.\" Author: Dustin J. Mitchell <dustin@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amcheck
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amcheckdb
.\" Author: Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amcheckdump
.\" Author: Ian Turner <ian@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amcleanup
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amcleanupdisk
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amcrypt-ossl-asym
.\" Author: Kevin Till <kevin.till@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amcrypt-ossl
.\" Author: Kevin Till <kevin.till@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amcrypt
.\" Author: Kevin Till <kevin.till@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amcryptsimple
.\" Author: Kevin Till <kevin.till@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amdevcheck
.\" Author: Ian Turner <ian@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amdump
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amdump_client
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amfetchdump
.\" Author: John Stange <building@nap.edu>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
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
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
.\" Title: amflush
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amgetconf
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amgpgcrypt
.\" Author: Kevin Till <kevin.till@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amgtar
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
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
Note that the
\fIprogram\fR
parameter must be set to
-\fI"APPLCIATION"\fR
+\fI"APPLICATION"\fR
to use the
\fIapplication\fR
parameter\&.
.\" Title: amlabel
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amoverview
.\" Author: Stefan G. Weichinger <sgw@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: ampgsql
.\" Author: Nikolas Coukouma <atrus@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amplot
.\" Author: Olafur Gudmundsson <ogud@tis.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amraw
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amrecover
.\" Author: Alan M. McIvor <alan@kauri.auck.irl.cri.nz>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amreport
.\" Author: Stefan G. Weichinger <sgw@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amrestore
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amrmtape
.\" Author: Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amsamba
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amserverconfig
.\" Author: Kevin Till <kevin.till@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amservice
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amstar
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amstatus
.\" Author: Stefan G. Weichinger <sgw@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amsuntar
.\" Author: Satya Ganga <gast@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amtape
.\" Author: Dustin J. Mitchell <dustin@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amtapetype
.\" Author: Dustin J. Mitchell <dustin@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amtoc
.\" Author: Nicolas Mayencourt <Nicolas.Mayencourt@cui.unige.ch>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amvault
.\" Author: Dustin J. Mitchell <dustin@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: amzfs-sendrecv
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
}
define dumptype user\-zfs\-sendrecv {
- program "APPLICATAION"
+ program "APPLICATION"
application "amzfs_sendrecv"
}
.fi
.\" Title: amzfs-snapshot
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: disklist
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.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
.\" Title: script-email
.\" Author: Jean-Louis Martineau <martineau@zmanda.com>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
.\" Title: tapelist
.\" Author: James da Silva <jds@amanda.org>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" 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
.\" -----------------------------------------------------------------
<refsynopsisdiv>
<cmdsynopsis>
<command>amadmin</command>
+ <arg choice='opt'>--version</arg>
+ <arg choice='opt'>--no-default</arg>
+ <arg choice='opt'>--print-source</arg>
&configoverride.synopsis;
<arg choice='plain'><replaceable>config</replaceable></arg>
<arg choice='plain'><replaceable>command</replaceable></arg>
man page for more details about Amanda.</para>
</refsect1>
+<refsect1><title>OPTIONS</title>
+<variablelist remap='TP'>
+ <varlistentry>
+ <term><option>--version</option></term>
+<listitem><para>Print the version and exit.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--no-default</option></term>
+<listitem><para>Do not print default values for <emphasis remap='B'>config</emphasis>
+and <emphasis remap='B'>disklist</emphasis> commands.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--print-source</option></term>
+<listitem><para>Print where a value is definedi for <emphasis remap='B'>config</emphasis>
+and <emphasis remap='B'>disklist</emphasis> commands.</para></listitem>
+ </varlistentry>
+
+</variablelist>
+</refsect1>
+
<refsect1><title>COMMANDS</title>
<para>Commands that take a <emphasis remap='I'>hostname</emphasis> [ <emphasis remap='I'>disks</emphasis> ]
parameter pair operate on all disks in the &disklist; for that
<!-- PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER -->
<variablelist>
+ <!-- ==== -->
+ <varlistentry><term>CLIENT_ID</term><listitem>
+(read-write) The client_id for oauth2.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>CLIENT_SECRET</term><listitem>
+(read-write) The client_secret for oauth2.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>CREATE-BUCKET</term><listitem>
+(read-write) Default: yes. If amanda create/delete the bucket.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>REFRESH_TOKEN</term><listitem>
+(read-write) The refresh-token for oauth2.
+</listitem></varlistentry>
<!-- ==== -->
<varlistentry><term>MAX_RECV_SPEED</term><listitem>
(read-write) Maximum speed, in bytes per second, that this device will receive
(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.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>S3_MULTI_DELETE</term><listitem>
+(read-write) If the server support the multi delete protocol (only Amazon S3),
+default is "YES". If it fail, it revert to single delete.
</listitem></varlistentry>
<!-- ==== -->
<varlistentry><term>NB_THREADS_BACKUP</term><listitem>
</listitem></varlistentry>
<!-- ==== -->
<varlistentry><term>OPENSTACK_SWIFT_API</term><listitem>
- (read-write) Set to yes if it is an openstack storage device.
+ (read-write) Deprecated, set "STORAGE_API to "SWIFT-1.0".
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>PROXY</term><listitem>
+ (read-write) The proxy hostname or IP in the format "host[:port]".
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>PASSWORD</term><listitem>
+(read-write) The password (for swift v2).
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>PROJECT-ID</term><listitem>
+(read-write) The projectid (for google).
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>REUSE-CONNECTION</term><listitem>
+(read-write) Default: YES. Set it to "NO" if reusing a connection cause some bug, this is sometime the case with big block size.
</listitem></varlistentry>
<!-- ==== -->
<varlistentry><term>S3_ACCESS_KEY</term><listitem>
<!-- ==== -->
<varlistentry><term>S3_USER_TOKEN</term><listitem>
(read-write) This property specifies the user token for Amanda Enterprise Edition customers.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>STORAGE_API</term><listitem>
+ (read-write) Which API to use for the cloud:
+<programlisting>
+ S3 Amanzon S3 api
+ SWITF-1.0 Openstack swift v1.0
+ SWIFT-2.0 Openstack swift v2.0
+</programlisting>
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>TENANT_ID</term><listitem>
+(read-write) The tenant_id (for swift v2).
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>TENANT_NAME</term><listitem>
+(read-write) The tenant_name (for swift v2).
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>USERNAME</term><listitem>
+(read-write) The username (for swift v2).
</listitem></varlistentry>
<!-- ==== -->
<varlistentry><term>VERBOSE</term><listitem>
<!-- PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER -->
<variablelist>
<!-- ==== -->
+<varlistentry><term>INDIRECT</term><listitem>
+(read-write) Set to "yes" if the ndmp server doesn't allow to set a window length to 0.
+The default is "no".
+</listitem></varlistentry>
+ <!-- ==== -->
<varlistentry><term>NDMP_AUTH</term><listitem>
(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
<varlistentry>
<term><amkeyword>columnspec</amkeyword> <amtype>string</amtype></term>
<listitem>
-<para> 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"</para>
+<para> 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"</para>
<para>Defines the width of columns <emphasis remap='B'>amreport</emphasis>
should use.
<emphasis remap='I'>String</emphasis>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><amkeyword>tmpdir</amkeyword> <amtype>string</amtype></term>
+ <listitem>
+<para>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'.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
<amdefault>10000</amdefault>.
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.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><amkeyword>max-warnings</amkeyword> <amtype>int</amtype></term>
+ <listitem>
+<para>Default:
+<amdefault>20</amdefault>.
+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.</para>
</listitem>
</varlistentry>
<varlistentry>
<varlistentry>
<term><amkeyword>plugin</amkeyword> <amtype>string</amtype></term>
<listitem>
-<para>No default. Must be set to the name of the taperscan module. See <man name="amanda-taperscan" vol="7" /> for a list of defined taperscan modules.</para>
+<para>No default. Must be set to the name of the taperscan module. See <manref name="amanda-taperscan" vol="7" /> for a list of defined taperscan modules.</para>
</listitem>
</varlistentry>
<varlistentry>
<refsynopsisdiv>
<cmdsynopsis>
<command>amfetchdump</command>
- <arg choice='opt'>-c|-C|-L</arg>
- <arg choice='opt'>-p|-n</arg>
+ <group choice='opt'>
+ <arg choice='plain'>-c</arg>
+ <arg choice='plain'>-C</arg>
+ <arg choice='plain'>-l</arg>
+ </group>
+ <group choice='opt'>
+ <arg choice='plain'>-p</arg>
+ <arg choice='plain'>-n</arg>
+ </group>
<arg choice='opt'>-a</arg>
<arg choice='opt'>-O <replaceable>directory</replaceable></arg>
<arg choice='opt'>-d <replaceable>device</replaceable></arg>
- <arg choice='opt'>-h</arg>
- <arg choice='opt'>--header-file <replaceable>filename</replaceable></arg>
- <arg choice='opt'>--header-fd <replaceable>fd</replaceable></arg>
+ <group choice='opt'>
+ <arg choice='plain'>-h</arg>
+ <arg choice='plain'>--header-file <replaceable>filename</replaceable></arg>
+ <arg choice='plain'>--header-fd <replaceable>fd</replaceable></arg>
+ </group>
+ <group choice='opt'>
+ <arg choice='plain'>--decompress</arg>
+ <arg choice='plain'>--no-decompress</arg>
+ <arg choice='plain'>--server-decompress</arg>
+ <arg choice='plain'>--client-decompress</arg>
+ </group>
+ <group choice='opt'>
+ <arg choice='plain'>--decrypt</arg>
+ <arg choice='plain'>--no-decrypt</arg>
+ <arg choice='plain'>--server-decrypt</arg>
+ <arg choice='plain'>--client-decrypt</arg>
+ </group>
&configoverride.synopsis;
<arg choice='plain'><replaceable>config</replaceable></arg>
<arg choice='plain'><replaceable>hostname</replaceable></arg>
<para><emphasis remap='B'>Amfetchdump</emphasis>
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.</para>
+tape autochanger operations. The dump are by default decompressed and decrypted.
+</para>
<para>It will automatically use the Amanda catalog
to locate available dumps on tape, in the same way that the <emphasis
<listitem><para>Compress output, smallest file size method
available.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--decompress</option></term>
+ <listitem><para>Always do the decompression, this is the default.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--no-decompress</option></term>
+ <listitem><para>Never do the decompression.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--server-decompress</option></term>
+ <listitem><para>Do the decompression only if the compression was done on
+the server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--client-decompress</option></term>
+ <listitem><para>Do the decompression only if the compression was done on
+the client.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--decrypt</option></term>
+ <listitem><para>Always do the decryption, this is the default.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--no-decrypt</option></term>
+ <listitem><para>Never do the decryption.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--server-decrypt</option></term>
+ <listitem><para>Do the decryption only if the encryption was done on
+the server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>--client-decrypt</option></term>
+ <listitem><para>Do the decryption only if the encryption was done on
+the client.</para></listitem>
+ </varlistentry>
<varlistentry>
<term><option>-l</option></term>
-<listitem><para>Leave dumps in the compressed/uncompressed state in which they
-were found on tape. By default, <emphasis
-remap='B'>amfetchdump</emphasis> will automatically uncompress when
-restoring.</para></listitem>
+<listitem><para>Leave dumps in the compressed/uncompressed and
+encrypted/unencrypted state in which they were found on tape.
+It is a synonym for <option>--no-decompression</option>
+<option>--no-decryption</option></para></listitem>
</varlistentry>
<varlistentry>
<term><option>-a</option></term>
<!-- ==== -->
<varlistentry><term>GNUTAR-PATH</term><listitem>
The path to the gnutar binary. The default is set when Amanda is built.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>IGNORE-ZEROS</term><listitem>
+If "YES" (the default), use the <emphasis>--ignore-zeros</emphasis> argument of gtar on recovery,
+set it to "NO" if you do not want that argument.
</listitem></varlistentry>
<!-- ==== -->
<varlistentry><term>INCLUDE-LIST-GLOB</term><listitem>
}
</programlisting>
Note that the <emphasis>program</emphasis> parameter must be set to
-<emphasis>"APPLCIATION"</emphasis> to use the <emphasis>application</emphasis>
+<emphasis>"APPLICATION"</emphasis> to use the <emphasis>application</emphasis>
parameter.
</para>
</refsect1>
}
define dumptype user-zfs-sendrecv {
- program "APPLICATAION"
+ program "APPLICATION"
application "amzfs_sendrecv"
}
</programlisting>
<refsect1><title>DESCRIPTION</title>
<para>The
<emphasis remap='I'>disklist</emphasis>
-file determines which disks will be backed up by Amanda.
-The file usually contains one line per disk:</para>
+file determines which disks will be backed up by Amanda. The file contains
+<amkeyword>includefile</amkeyword> directive or disklist entry
+(<amkeyword>DLE</amkeyword>).</para>
+
+<variablelist remap='TP'>
+ <varlistentry>
+ <term><amkeyword>includefile</amkeyword> <amtype>string</amtype></term>
+ <listitem>
+<para>Default:
+<amdefault>no default</amdefault>.
+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.
+</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>A <amkeyword>DLE</amkeyword> usually contains one line per disk:</para>
<programlisting>
<emphasis>hostname diskname</emphasis> [<emphasis>diskdevice</emphasis>] <emphasis>dumptype</emphasis> [<emphasis>spindle</emphasis> [<emphasis>interface</emphasis>] ]
#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
$(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
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@
" -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=<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)",
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");
#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 */
#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
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
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
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,
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
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,
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,
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,
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,
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,
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
},
{
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,
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,
#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; };
/*
/*
- * 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
*/
#include "amanda.h"
+#include "event.h"
#include "sockaddr-util.h"
#include "ndmpconnobj.h"
}
}
+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
*/
/*
- * 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
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
*/
# 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
$(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
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@
$(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
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@
# 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=$?
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
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
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
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; }
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.
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; }
;;
# 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"
# 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"
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() {
###############
# 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"
# 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
# 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
# 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
# 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
}
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 -----------------
# 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
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=
-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
}
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 '<username> : '.
+ 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
# 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 -----------------
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
# 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.
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
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
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
# Source our mock utils.
. ${SHUNIT_INC}/mock_utils.sh
+
######################################
# Common functions
# 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}"
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}`
rm ${MOCKDIR}/success
reload_xinetd "reload"
assertEquals "reload_xinetd" 1 $?
- tail -4 ${LOGFILE}|grep "\<xinetd.*Attempting restart"
+ tail -4 ${LOGFILE}|grep "\<xinetd.*Attempting restart" >/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 $?
}
rm ${MOCKDIR}/success
reload_inetd "reload"
assertEquals "reload_inetd" 1 $?
- tail -4 ${LOGFILE}|grep "\<inetd.*Attempting restart"
+ tail -4 ${LOGFILE}|grep "\<inetd.*Attempting restart" >/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 $?
}
######################################
# 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
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}
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
#!/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
+#!/bin/sh -e
+pkg_type=client
+other_pkg_type=server
#!/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
+#!/bin/sh -e
+pkg_type=server
+other_pkg_type=client
# 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() {
--- /dev/null
+# 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}'.";
+
+++ /dev/null
-#!/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
--- /dev/null
+# 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
+++ /dev/null
-#!/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
-
--- /dev/null
+#!/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'."
#!/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.
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 " \
--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
$(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 \
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
#
-# 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
# --- 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}
# 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
# 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"
{ 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 \
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.
(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
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
# 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
# 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
# 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.
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
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 \
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
#!/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
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."
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
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
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
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 ------------
# -------- 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'."
#!/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%%
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."
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"
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
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
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
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 ------------
# -------- 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'."
use strict;
use warnings;
+use IO::Handle;
use Amanda::Config qw( :init :getconf config_dir_relative );
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;
/*
- * 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
/*
- * 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
use strict;
use warnings;
+use IO::Handle;
use Amanda::Config qw( :init :getconf config_dir_relative );
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;
}
%}
-# 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
/*
- * 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
/*
- * 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
-# 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
-# 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
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;
-# 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
use strict;
use warnings;
+use Carp;
use vars qw( @ISA );
@ISA = qw( Amanda::Changer );
($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'} ];
-# 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
-# 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
use strict;
use warnings;
+use Carp;
use vars qw( @ISA );
@ISA = qw( Amanda::Changer );
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");
}
-# 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
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) {
-# 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
package Amanda::Changer::ndmp::Interface;
+use Carp;
use Amanda::NDMP qw( :constants );
use Amanda::Debug qw( debug warning );
use Amanda::MainLoop;
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
-# 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
-# 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
use strict;
use warnings;
+use Carp;
use vars qw( @ISA );
@ISA = qw( Amanda::Changer );
($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'} ];
-# 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
@check_order = (@{$self->{'driveorder'}});
} else {
# the constructor should detect this circumstance
- die "invalid drive_choice";
+ confess "invalid drive_choice";
}
my %checked;
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");
}
$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'},
$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;
}
$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;
}
} else {
my %status;
for my $line (split '\n', $output) {
+ debug("mtx: $line");
my ($slot, $ie, $slinfo);
# drives (data transfer elements)
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) {
-# 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
use strict;
use warnings;
+use Carp;
use vars qw( @ISA );
@ISA = qw( Amanda::Changer );
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'},
-# 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
/*
- * 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
/*
- * 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
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);
}
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();
}
}
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);
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)));
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)));
*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;
*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;
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"}};
=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
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"}};
=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
/*
- * 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
/*
- * 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
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);
APPLY(DUMPTYPE_PROPERTY)\
APPLY(DUMPTYPE_DATA_PATH)\
APPLY(DUMPTYPE_ALLOW_SPLIT)\
+APPLY(DUMPTYPE_MAX_WARNINGS)\
APPLY(DUMPTYPE_RECOVERY_LIMIT) \
APPLY(DUMPTYPE_DUMP_LIMIT)
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);
}
%}
* 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);
amglue_export_ok(string_to_boolean);
+%newobject amandaify_property_name;
gchar * amandaify_property_name(const gchar *name);
amglue_export_ok(amandaify_property_name);
# 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
$VXRESTORE = "@VXRESTORE@";
$XFSDUMP = "@XFSDUMP@";
$XFSRESTORE = "@XFSRESTORE@";
+$NC = "@NC@";
+$NC6 = "@NC6@";
+$NETCAT = "@NETCAT@";
# non-AC_SUBST'd constants
-# 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
-# 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
-# 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
/*
- * 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
/*
- * 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
#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)
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);
}
}
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;
}
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);
}
}
+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 ;
}
+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 ;
+ 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();
}
}
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};
&_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,
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}};
_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,
{"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},
{"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},
*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;
*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;
/*
- * 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
/*
- * 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
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);
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) {
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);
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
#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};
}
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:
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 ;
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();
void *argp1 = 0 ;
int res1 = 0 ;
int argvi = 0;
- sl_t *result = 0 ;
+ am_sl_t *result = 0 ;
dXSARGS;
if ((items < 1) || (items > 1)) {
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:
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 ;
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();
void *argp1 = 0 ;
int res1 = 0 ;
int argvi = 0;
- sl_t *result = 0 ;
+ am_sl_t *result = 0 ;
dXSARGS;
if ((items < 1) || (items > 1)) {
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:
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 ;
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();
void *argp1 = 0 ;
int res1 = 0 ;
int argvi = 0;
- sl_t *result = 0 ;
+ am_sl_t *result = 0 ;
dXSARGS;
if ((items < 1) || (items > 1)) {
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:
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 ;
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();
void *argp1 = 0 ;
int res1 = 0 ;
int argvi = 0;
- sl_t *result = 0 ;
+ am_sl_t *result = 0 ;
dXSARGS;
if ((items < 1) || (items > 1)) {
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:
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};
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,
&_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}};
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,
_swigc__p_off_t,
_swigc__p_proplist_t,
_swigc__p_scriptlist_t,
- _swigc__p_sl_t,
_swigc__p_unsigned_char,
};
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;
/*
- * 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
/*
- * 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
}
} dumpfile_t;
-%newobject C_from_string;
%inline %{
static dumpfile_t *C_from_string(const char *string) {
dumpfile_t *result = g_new(dumpfile_t, 1);
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;
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;
-# 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
/*
- * 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
/*
- * 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
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
# 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
-# 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
-# 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
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'} = {
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'};
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
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'");
return $xfer_state->{'recovery_cb'}->(
result => $result,
errors => $xfer_state->{'errors'},
+ bytes_read => $xfer_state->{'xfer_src'}->get_bytes_read()
);
}
# 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
-# 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
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 {
-# 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
# 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'}->(
$scan_method = $self->{'scan_conf'}->{$err->{'reason'}};
}
} else {
- die("error not defined");
+ confess("error not defined");
$scan_method = SCAN_ASK_POLL;
}
}
} 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");
}
};
$interactivity_running = 0;
$poll_src->remove() if defined $poll_src;
$poll_src = undef;
- $last_err = undef;
if ($err) {
if ($scan_running) {
if ($new_chg->isa("Amanda::Changer::Error")) {
return $steps->{'scan_interactivity'}->("$new_chg");
}
+ $last_err = undef;
$self->{'chg'}->quit();
$self->{'chg'} = $new_chg;
%seen = ();
-# 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
-# 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
use strict;
use warnings;
+use Carp;
use POSIX;
use Data::Dumper;
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();
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%" ],
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]
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
-# 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
-# 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
-# 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
$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;
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;
}
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;
}
# 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
# 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
result = (char *)list_new_tapes(arg1);
ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ;
+ free((char*)result);
XSRETURN(argvi);
fail:
/*
- * 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
/*
- * 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
%}
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 */
-# 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
-# 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
-# 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
-# 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
-# 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
-# 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
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'}->();
}
-# 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
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'};
$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
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();
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;
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();
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)
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 {
$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
# _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";
}
}
}
$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
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'};
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 ");
} 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");
} 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();
-# 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
package Amanda::Taper::Worker;
+use Carp;
use POSIX qw( :errno_h );
use Amanda::Changer;
use Amanda::Config qw( :getconf config_dir_relative );
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
}
}
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'});
}
}
$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();
});
}
my $self = shift;
my ($finished_cb) = @_;
- my $header_xfer;
my ($xsrc, $xdst);
my $errmsg;
($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];
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");
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)
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
$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 {
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
/*
- * 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
/*
- * 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
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);
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);
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);
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);
/*
- * 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
/*
- * 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
for (iter = $1; *iter; iter++) {
$result = sv_2mortal(newSVpv(*iter, 0));
+ g_free(*iter);
argvi++;
}
+ g_free($1);
}
}
%}
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);
typedef struct file_lock {
%extend {
+ %newobject file_lock;
file_lock(const char *filename) {
return file_lock_new(filename);
}
/*
- * 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
/*
- * 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
}
+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 ;
}
+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) -------- */
{"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},
{"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}
};
/* -----------------------------------------------------------------------------
*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;
*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 --------
Amanda::XferServer::xfer_source_holding(@_);
}
+*get_bytes_read = *Amanda::XferServer::xfer_source_holding_get_bytes_read;
package Amanda::Xfer::Dest::Taper;
}
*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;
/*
- * 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
/*
- * 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
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,
XferElement *self,
Device *device);
+guint64 xfer_source_recovery_get_bytes_read(
+ XferElement *self);
+
+
/* ---- */
PACKAGE(Amanda::Xfer::Source::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)
/* ---- */
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)
+
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
@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
# 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
$(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
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@
# 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
@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
# 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
$(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
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@
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
/*
- * 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
$(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
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@
# 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
$(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
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@
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);
}
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,
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,
# 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
# 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
$(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
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@
#!@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
#include "util.h"
#include "timestamp.h"
#include "server_util.h"
+#include <getopt.h>
disklist_t diskq;
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;
};
#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,
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);
{
int i;
- g_fprintf(stderr, _("\nUsage: %s [-o configoption]* <conf> <command> {<args>} ...\n"),
+ g_fprintf(stderr, _("\nUsage: %s [--version] [--no-default] [--print-source] [-o configoption]*\n <conf> <command> {<args>} ...\n"),
get_pname());
g_fprintf(stderr, _(" Valid <command>s are:\n"));
for (i = 0; i < NCMDS; i++)
void
balance(
- int argc,
- char ** argv)
+ int argc G_GNUC_UNUSED,
+ char ** argv G_GNUC_UNUSED)
{
disk_t *dp;
struct balance_stats {
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;
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':
}
}
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 */
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) {
bump_thresh(
int level)
{
- int bump = getconf_int(CNF_BUMPSIZE);
+ gint64 bump = getconf_int64(CNF_BUMPSIZE);
double mult = getconf_real(CNF_BUMPMULT);
while(--level)
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"),
{
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;
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");
}
int argc G_GNUC_UNUSED,
char **argv G_GNUC_UNUSED)
{
- dump_configuration();
+ dump_configuration(print_default, print_source);
}
#! @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
} 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";
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'}->();
#! @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
"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}) {
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,
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 ".
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;
}
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'});
};
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");
}
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) {
$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(); });
#!@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
#!@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
#! @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
#! @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
#! @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
my ($msg) = @_;
print STDERR <<EOF;
Usage: amfetchdump [-c|-C|-l] [-p|-n] [-a] [-O directory] [-d device]
- [-h] [--header-file file] [--header-fd fd] [-o configoption]* config
+ [-h|--header-file file|--header-fd fd]i
+ [--decrypt|--no-decrypt|--server-decrypt|--client-decrypt]
+ [--decompress|--no-decompress|--server-decompress|--client-decompress]
+ [-o configoption]* config
hostname [diskname [datestamp [hostname [diskname [datestamp ... ]]]]]
EOF
print STDERR "ERROR: $msg\n" if $msg;
my ($opt_config, $opt_no_reassembly, $opt_compress, $opt_compress_best, $opt_pipe,
$opt_assume, $opt_leave, $opt_blocksize, $opt_device, $opt_chdir, $opt_header,
- $opt_header_file, $opt_header_fd, @opt_dumpspecs);
+ $opt_header_file, $opt_header_fd, @opt_dumpspecs,
+ $opt_decrypt, $opt_server_decrypt, $opt_client_decrypt,
+ $opt_decompress, $opt_server_decompress, $opt_client_decompress);
+
+my $NEVER = 0;
+my $ALWAYS = 1;
+my $ONLY_SERVER = 2;
+my $ONLY_CLIENT = 3;
+my $decrypt;
+my $decompress;
debug("Arguments: " . join(' ', @ARGV));
Getopt::Long::Configure(qw(bundling));
'h' => \$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,
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.")
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();
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;
}
my $self = shift;
my ($label, $filenum, $header) = @_;
+ print STDERR "\n" if $self->{'is_tty'};
print STDERR "amfetchdump: $filenum: restoring ", $header->summary(), "\n";
}
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";
}
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;
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
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(
$clerk = Amanda::Recovery::Clerk->new(
changer => $chg,
- feedback => main::Feedback->new($chg, undef),
+ feedback => main::Feedback->new($chg, undef, $is_tty),
scan => $scan);
}
# 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]);
}
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'});
}
}
+ $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(
$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);
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;
};
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'}->();
};
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->();
};
}
#! @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
return Amanda::Recovery::Planner::make_plan(
filelist => $filelist,
+ chg => $chg,
$spec? (dumpspec => $spec) : (),
plan_cb => sub { $self->plan_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
$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,
/* 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 */
#! @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
#! @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
#!@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
#! @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
#! @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
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);
}
#!@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
#!@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
$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];
}
$running_dumper{$dumper} = $hostpart;
$error{$hostpart}="";
+ $taper_error{$hostpart}="";
$size{$hostpart} = 0;
$dumpers_active++;
if(! defined($dumpers_active[$dumpers_active])) {
$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") {
$taper_started{$hostpart}=1;
$taper_finished{$hostpart}=0;
$taper_time{$hostpart}=$current_time;
+ $taper_error{$hostpart}="";
$size{$hostpart} = 0;
$ntchunk_size = 0;
}
$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") {
}
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;
}
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;
$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;
$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 ||
$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 {
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";
}
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}), ")";
#! @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
} 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";
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) = @_;
#! @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
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
}, $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) = @_;
# 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;
# 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
/*
- * 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
/*
- * 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
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;
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);
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 */
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) {
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);
}
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) {
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;
}
}
}
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;
(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 "
(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) &&
(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
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;
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);
" ", dp->auth,
" ", data_path_to_string(dp->data_path),
" ", dp->dataport_list,
+ " ", maxwarnings,
" |", o,
"\n", NULL);
amfree(qplugin);
pid_t encryptpid; /* valid if fd is pipe to encrypt */
};
+struct databuf *g_databuf = NULL;
+
typedef struct filter_s {
int fd;
char *name;
static char *dle_str = NULL;
static char *errfname = NULL;
static int errf_lines = 0;
+static int max_warnings = 0;
static dumpfile_t file;
}
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]"));
}
break;
}
databuf_init(&db, outfd);
+ g_databuf = &db;
if (am_has_feature(their_features, fe_req_xml))
xml_check_options(options); /* note: modifies globals */
{
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);
}
}
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;
}
/* ------------- */
}
}
aclose(indexout);
+ aclose(g_databuf->fd);
timeout(0);
}
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));
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]);
return (-1);
}
+ g_debug("execute: %s", srv_encrypt);
switch (*pid = fork()) {
case -1:
errstr = newvstrallocf(errstr, _("couldn't fork: %s"), strerror(errno));
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: {
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;
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"),
}
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) &&
double fullcomp, incrcomp;
char *errstr;
char *degr_mesg;
+ info_t *info;
} est_t;
#define est(dp) ((est_t *)(dp)->up)
disk_t *dp)
{
est_t *ep;
- info_t info;
+ info_t *info;
int i;
char *qname;
int overwrite_runs;
/* 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);
}
ep = alloc(SIZEOF(est_t));
dp->up = (void *) ep;
+ ep->info = info;
ep->state = DISK_READY;
ep->dump_priority = dp->priority;
ep->errstr = 0;
/* 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) {
/*
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;
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);
}
}
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 */
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*/
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]"),
}
}
- 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"),
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);
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 */
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);
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
"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);
break;
case DS_INCRONLY:
- if (ISSET(info.command, FORCE_FULL))
+ if (ISSET(info->command, FORCE_FULL))
ep->last_level = 0;
break;
}
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 */
}
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
* 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" :
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);
/* 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) {
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 */
int delete;
char * message;
gint64 full_size;
+ time_t timestamps;
+ int priority;
biq.head = biq.tail = NULL;
}
else {
delete = 0;
- message = _("full dump delayed");
+ message = _("full dump delayed, doing incremental");
}
}
else {
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) {
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 */
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);
}
}
amfree(tp->datestamp);
amfree(tp->label);
+ amfree(tp->meta);
+ amfree(tp->comment);
+ amfree(tp->barcode);
amfree(tp);
}
}
/* 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;
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';
s[-1] = '\0';
skip_whitespace(s, ch);
tp->barcode = stralloc(s1);
- } else {
- tp->barcode = NULL;
}
if (strncmp_const(s - 1, "META:") == 0) {
s[-1] = '\0';
skip_whitespace(s, ch);
tp->meta = stralloc(s1);
- } else {
- tp->meta = NULL;
}
if (strncmp_const(s - 1, "BLOCKSIZE:") == 0) {
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;
#! @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
/*
* 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
XferElement *xfer_source_holding(
const char *filename);
+guint64
+xfer_source_holding_get_bytes_read(
+ XferElement *elt);
#endif
/*
* 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
int fd;
char *next_filename;
+ guint64 bytes_read;
XferElement *dest_taper;
} XferSourceHolding;
bytes_read = full_read(self->fd, buf, HOLDING_BLOCK_SIZE);
if (bytes_read > 0) {
*size = bytes_read;
+ self->bytes_read += bytes_read;
return buf;
}
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;
+}
+
# 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
$(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
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@
/*
- * 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/* 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,
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
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);
/*
* 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
/*
- * 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
/*
- * 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
{
/* 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));
}
/*
- * 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
/* Used to coordinate handing off file descriptors among elements of this
* xfer */
GMutex *fd_mutex;
+
+ int cancelled;
};
typedef struct Xfer Xfer;
/*
- * 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
/*
- * 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