-# 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
-# published by the Free Software Foundation.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+#* License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
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! $self->{'dump_header'}->{'partnum'} $msg->{'partnum'}"
unless ($self->{'dump_header'}->{'partnum'} == $msg->{'partnum'});
# notify
}
}
+sub abort_setup {
+ my $self = shift;
+ my %params = @_;
+
+ $self->{'dump_cb'} = $params{'dump_cb'};
+ $self->_dump_done();
+}
+
sub _dump_done {
my $self = shift;
# determine the correct final status - DONE if we're done, PARTIAL
# if we've started writing to the volume, otherwise FAILED
- if (@{$self->{'device_errors'}} or $self->{'config_denial_message'} or
- !$self->{'last_part_successful'}) {
- $result = $self->{'started_writing'}? 'PARTIAL' : 'FAILED';
+ if (!$self->{'started_writing'}) {
+ $result = 'FAILED';
+ } elsif (@{$self->{'device_errors'}} or $self->{'config_denial_message'} or
+ !$self->{'last_part_successful'}) {
+ $result = 'PARTIAL';
} else {
$result = 'DONE';
}
my $dump_cb = $self->{'dump_cb'};
+
+ return if !defined $dump_cb;
+
my %dump_cb_args = (
result => $result,
device_errors => $self->{'device_errors'},
if (defined $self->{'dump_cb'}) {
# _dump_done constructs the dump_cb from $self parameters
$self->_dump_done();
- } else {
- die "error with no callback to handle it: $error_message";
}
}
}
step device_started => sub {
my $result = shift;
- if ($result == 0) {
+ if ($result =~ /\D/) {
+ $self->{'feedback'}->scribe_notif_new_tape(
+ error => $result,
+ volume_label => undef);
+ $self->_get_new_volume();
+ return $cbX->();
+ } elsif ($result == 0) {
# try reading the label to see whether we erased the tape
my $erased = 0;
CHECK_READ_LABEL: {
$self->_get_new_volume();
return $cbX->();
- } elsif ($result != 1) {
- $self->{'feedback'}->scribe_notif_new_tape(
- error => $result,
- volume_label => undef);
- $self->_get_new_volume();
- return $cbX->();
}
$new_label = $device->volume_label;
$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
unless defined $params{'part_cache_type'};
}
- # if any of the dle_* parameters are set, use those to set the part_*
- # parameters, which are emptied out first.
- if (defined $params{'dle_tape_splitsize'} or
- defined $params{'dle_split_diskbuffer'} or
- defined $params{'dle_fallback_splitsize'}) {
+ if (defined $splitting_args{'data_path'} and
+ $splitting_args{'data_path'} eq "DIRECTTCP") {
+ my $ps = $params{'dle_tape_splitsize'};
+ if (defined $ps and $ps > 0) {
+ $params{'part_cache_max_size'} = undef
+ } else {
+ $ps = $params{'part_size'};
+ my $pcms = $params{'part_cache_max_size'};
+ $ps = $pcms if (!defined $ps or (defined $pcms and $pcms < $ps));
+ }
+ $splitting_args{'allow_split'} = 1 if ((defined $ps and $ps > 0) or
+ $params{'leom_supported'});
+ $params{'part_size'} = $ps;
+ $params{'part_cache_type'} = 'none';
+ $params{'part_cache_dir'} = undef;
+ } elsif (defined $params{'dle_tape_splitsize'} or
+ defined $params{'dle_split_diskbuffer'} or
+ defined $params{'dle_fallback_splitsize'}) {
+ # if any of the dle_* parameters are set, use those to set the part_*
+ # parameters, which are emptied out first.
$params{'part_size'} = $params{'dle_tape_splitsize'} || 0;
$params{'part_cache_type'} = 'none';
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();