1 # This file was automatically generated by SWIG (http://www.swig.org).
4 # Do not make changes to this file unless you know what you are doing--modify
5 # the SWIG interface file instead.
7 package Amanda::Device;
9 use base qw(DynaLoader);
10 require Amanda::Header;
11 package Amanda::Devicec;
12 bootstrap Amanda::Device;
13 package Amanda::Device;
16 # ---------- BASE METHODS -------------
18 package Amanda::Device;
21 my ($classname,$obj) = @_;
22 return bless $obj, $classname;
32 my ($self,$field) = @_;
33 my $member_func = "swig_${field}_get";
34 $self->$member_func();
38 my ($self,$field,$newval) = @_;
39 my $member_func = "swig_${field}_set";
40 $self->$member_func($newval);
49 # ------- FUNCTION WRAPPERS --------
51 package Amanda::Device;
53 *unaliased_name = *Amanda::Devicec::unaliased_name;
54 *rait_device_open_from_children = *Amanda::Devicec::rait_device_open_from_children;
55 *write_random_to_device = *Amanda::Devicec::write_random_to_device;
56 *verify_random_from_device = *Amanda::Devicec::verify_random_from_device;
57 *IS_WRITABLE_ACCESS_MODE = *Amanda::Devicec::IS_WRITABLE_ACCESS_MODE;
59 ############# Class : Amanda::Device::DirectTCPConnection ##############
61 package Amanda::Device::DirectTCPConnection;
62 use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
63 @ISA = qw( Amanda::Device );
67 return unless $_[0]->isa('HASH');
68 my $self = tied(%{$_[0]});
69 return unless defined $self;
70 delete $ITERATORS{$self};
71 if (exists $OWNER{$self}) {
72 Amanda::Devicec::delete_DirectTCPConnection($self);
77 *close = *Amanda::Devicec::DirectTCPConnection_close;
80 my $self = Amanda::Devicec::new_DirectTCPConnection(@_);
81 bless $self, $pkg if defined($self);
86 my $ptr = tied(%$self);
92 my $ptr = tied(%$self);
97 ############# Class : Amanda::Device::Device ##############
99 package Amanda::Device::Device;
100 use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
101 @ISA = qw( Amanda::Device );
106 my $self = Amanda::Devicec::new_Device(@_);
107 bless $self, $pkg if defined($self);
111 return unless $_[0]->isa('HASH');
112 my $self = tied(%{$_[0]});
113 return unless defined $self;
114 delete $ITERATORS{$self};
115 if (exists $OWNER{$self}) {
116 Amanda::Devicec::delete_Device($self);
117 delete $OWNER{$self};
121 *configure = *Amanda::Devicec::Device_configure;
122 *error = *Amanda::Devicec::Device_error;
123 *status_error = *Amanda::Devicec::Device_status_error;
124 *error_or_status = *Amanda::Devicec::Device_error_or_status;
125 *read_label = *Amanda::Devicec::Device_read_label;
126 *start = *Amanda::Devicec::Device_start;
127 *finish = *Amanda::Devicec::Device_finish;
128 *get_bytes_read = *Amanda::Devicec::Device_get_bytes_read;
129 *get_bytes_written = *Amanda::Devicec::Device_get_bytes_written;
130 *start_file = *Amanda::Devicec::Device_start_file;
131 *write_block = *Amanda::Devicec::Device_write_block;
132 *finish_file = *Amanda::Devicec::Device_finish_file;
133 *seek_file = *Amanda::Devicec::Device_seek_file;
134 *seek_block = *Amanda::Devicec::Device_seek_block;
135 *read_block = *Amanda::Devicec::Device_read_block;
136 *erase = *Amanda::Devicec::Device_erase;
137 *eject = *Amanda::Devicec::Device_eject;
138 *directtcp_supported = *Amanda::Devicec::Device_directtcp_supported;
139 *listen = *Amanda::Devicec::Device_listen;
140 *use_connection = *Amanda::Devicec::Device_use_connection;
141 *property_list = *Amanda::Devicec::Device_property_list;
142 *property_get = *Amanda::Devicec::Device_property_get;
143 *property_set = *Amanda::Devicec::Device_property_set;
144 *property_set_ex = *Amanda::Devicec::Device_property_set_ex;
145 *recycle_file = *Amanda::Devicec::Device_recycle_file;
146 *file = *Amanda::Devicec::Device_file;
147 *block = *Amanda::Devicec::Device_block;
148 *in_file = *Amanda::Devicec::Device_in_file;
149 *device_name = *Amanda::Devicec::Device_device_name;
150 *access_mode = *Amanda::Devicec::Device_access_mode;
151 *is_eof = *Amanda::Devicec::Device_is_eof;
152 *is_eom = *Amanda::Devicec::Device_is_eom;
153 *volume_label = *Amanda::Devicec::Device_volume_label;
154 *volume_time = *Amanda::Devicec::Device_volume_time;
155 *status = *Amanda::Devicec::Device_status;
156 *min_block_size = *Amanda::Devicec::Device_min_block_size;
157 *max_block_size = *Amanda::Devicec::Device_max_block_size;
158 *block_size = *Amanda::Devicec::Device_block_size;
159 *header_block_size = *Amanda::Devicec::Device_header_block_size;
160 *volume_header = *Amanda::Devicec::Device_volume_header;
163 my $ptr = tied(%$self);
169 my $ptr = tied(%$self);
174 # ------- VARIABLE STUBS --------
176 package Amanda::Device;
178 *ACCESS_NULL = *Amanda::Devicec::ACCESS_NULL;
179 *ACCESS_READ = *Amanda::Devicec::ACCESS_READ;
180 *ACCESS_WRITE = *Amanda::Devicec::ACCESS_WRITE;
181 *ACCESS_APPEND = *Amanda::Devicec::ACCESS_APPEND;
182 *DEVICE_STATUS_SUCCESS = *Amanda::Devicec::DEVICE_STATUS_SUCCESS;
183 *DEVICE_STATUS_DEVICE_ERROR = *Amanda::Devicec::DEVICE_STATUS_DEVICE_ERROR;
184 *DEVICE_STATUS_DEVICE_BUSY = *Amanda::Devicec::DEVICE_STATUS_DEVICE_BUSY;
185 *DEVICE_STATUS_VOLUME_MISSING = *Amanda::Devicec::DEVICE_STATUS_VOLUME_MISSING;
186 *DEVICE_STATUS_VOLUME_UNLABELED = *Amanda::Devicec::DEVICE_STATUS_VOLUME_UNLABELED;
187 *DEVICE_STATUS_VOLUME_ERROR = *Amanda::Devicec::DEVICE_STATUS_VOLUME_ERROR;
188 *DEVICE_STATUS_FLAGS_MAX = *Amanda::Devicec::DEVICE_STATUS_FLAGS_MAX;
189 *PROPERTY_PHASE_BEFORE_START = *Amanda::Devicec::PROPERTY_PHASE_BEFORE_START;
190 *PROPERTY_PHASE_BETWEEN_FILE_WRITE = *Amanda::Devicec::PROPERTY_PHASE_BETWEEN_FILE_WRITE;
191 *PROPERTY_PHASE_INSIDE_FILE_WRITE = *Amanda::Devicec::PROPERTY_PHASE_INSIDE_FILE_WRITE;
192 *PROPERTY_PHASE_BETWEEN_FILE_READ = *Amanda::Devicec::PROPERTY_PHASE_BETWEEN_FILE_READ;
193 *PROPERTY_PHASE_INSIDE_FILE_READ = *Amanda::Devicec::PROPERTY_PHASE_INSIDE_FILE_READ;
194 *PROPERTY_PHASE_MAX = *Amanda::Devicec::PROPERTY_PHASE_MAX;
195 *PROPERTY_PHASE_MASK = *Amanda::Devicec::PROPERTY_PHASE_MASK;
196 *PROPERTY_PHASE_SHIFT = *Amanda::Devicec::PROPERTY_PHASE_SHIFT;
197 *PROPERTY_ACCESS_GET_BEFORE_START = *Amanda::Devicec::PROPERTY_ACCESS_GET_BEFORE_START;
198 *PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE = *Amanda::Devicec::PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE;
199 *PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE = *Amanda::Devicec::PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE;
200 *PROPERTY_ACCESS_GET_BETWEEN_FILE_READ = *Amanda::Devicec::PROPERTY_ACCESS_GET_BETWEEN_FILE_READ;
201 *PROPERTY_ACCESS_GET_INSIDE_FILE_READ = *Amanda::Devicec::PROPERTY_ACCESS_GET_INSIDE_FILE_READ;
202 *PROPERTY_ACCESS_SET_BEFORE_START = *Amanda::Devicec::PROPERTY_ACCESS_SET_BEFORE_START;
203 *PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE = *Amanda::Devicec::PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE;
204 *PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE = *Amanda::Devicec::PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE;
205 *PROPERTY_ACCESS_SET_BETWEEN_FILE_READ = *Amanda::Devicec::PROPERTY_ACCESS_SET_BETWEEN_FILE_READ;
206 *PROPERTY_ACCESS_SET_INSIDE_FILE_READ = *Amanda::Devicec::PROPERTY_ACCESS_SET_INSIDE_FILE_READ;
207 *PROPERTY_ACCESS_GET_MASK = *Amanda::Devicec::PROPERTY_ACCESS_GET_MASK;
208 *PROPERTY_ACCESS_SET_MASK = *Amanda::Devicec::PROPERTY_ACCESS_SET_MASK;
209 *CONCURRENCY_PARADIGM_EXCLUSIVE = *Amanda::Devicec::CONCURRENCY_PARADIGM_EXCLUSIVE;
210 *CONCURRENCY_PARADIGM_SHARED_READ = *Amanda::Devicec::CONCURRENCY_PARADIGM_SHARED_READ;
211 *CONCURRENCY_PARADIGM_RANDOM_ACCESS = *Amanda::Devicec::CONCURRENCY_PARADIGM_RANDOM_ACCESS;
212 *STREAMING_REQUIREMENT_NONE = *Amanda::Devicec::STREAMING_REQUIREMENT_NONE;
213 *STREAMING_REQUIREMENT_DESIRED = *Amanda::Devicec::STREAMING_REQUIREMENT_DESIRED;
214 *STREAMING_REQUIREMENT_REQUIRED = *Amanda::Devicec::STREAMING_REQUIREMENT_REQUIRED;
215 *MEDIA_ACCESS_MODE_READ_ONLY = *Amanda::Devicec::MEDIA_ACCESS_MODE_READ_ONLY;
216 *MEDIA_ACCESS_MODE_WORM = *Amanda::Devicec::MEDIA_ACCESS_MODE_WORM;
217 *MEDIA_ACCESS_MODE_READ_WRITE = *Amanda::Devicec::MEDIA_ACCESS_MODE_READ_WRITE;
218 *MEDIA_ACCESS_MODE_WRITE_ONLY = *Amanda::Devicec::MEDIA_ACCESS_MODE_WRITE_ONLY;
219 *PROPERTY_SURETY_BAD = *Amanda::Devicec::PROPERTY_SURETY_BAD;
220 *PROPERTY_SURETY_GOOD = *Amanda::Devicec::PROPERTY_SURETY_GOOD;
221 *PROPERTY_SOURCE_DEFAULT = *Amanda::Devicec::PROPERTY_SOURCE_DEFAULT;
222 *PROPERTY_SOURCE_DETECTED = *Amanda::Devicec::PROPERTY_SOURCE_DETECTED;
223 *PROPERTY_SOURCE_USER = *Amanda::Devicec::PROPERTY_SOURCE_USER;
231 Amanda::Device - interact with Amanda data-storage devices
235 use Amanda::Device qw( :constants );
237 my $dev = Amanda::Device->new($device_name);
238 if ($dev->read_label() == $DEVICE_STATUS_SUCCESS) {
239 print "Label on $device_name is '$dev->volume_label'\n";
244 A volume is a container for data which can be "loaded" into a particular
245 device. For tape devices, a volume is a tape, but most other devices do not
246 deal with such physical objects. Each volume has a volume header giving, among
247 other things, the label of the volume and the timestamp on which it was
248 written. The header may also indicate that the volume is not an Amanda volume.
249 Aside from the header, a volume contains a sequence of files, numbered starting
250 at 1. While writing, devices number files sequentially, but devices that
251 support partial volume recycling may have "holes" in the sequence of file
252 numbers where files have been deleted. The C<seek_file> method, below,
253 describes how the API represents this situation. Each file has a header, too,
254 which contains lots of information about the file. See L<Amanda::Header> for
255 the full list. After the header, a file is just a sequence of bytes.
257 Reads and writes to devices take place in blocks. Unlike a typical
258 operating-system file, in which any block boundaries are lost after the file is
259 written, devices must be read back with the block sizes that were used to read.
260 See C<amanda-devices(7)> for more in block sizes, and the read_block and
261 write_block sections, below, for more information.
263 =head1 USING THE DEVICE API
265 The Device API is object-oriented, so the first task in using the API is to
266 make a Device object:
268 $dev = Amanda::Device->new("tape:/dev/nst0");
270 This function takes a device name (possibly a device alias) and returns a
271 device object. This function always returns a Device, although it may be a Null
272 device with an error condition. Any C<new> call should be followed by a check
273 of the device's status:
275 $dev = Amanda::Device->new($device_name);
276 if ($dev->status() != $Amanda::Device::DEVICE_STATUS_SUCCESS) {
277 die "Could not open '$device_name': " . $dev->error();
280 This function does not access the underlying hardware or any other external
281 systems in any way: that doesn't happen until C<read_label> or C<start>. An
282 Amanda configuration must be loaded when this function is called, as it
283 searches the configuation for device definitions. The member variable
284 C<device_name> is set when this function has returned.
286 It is unusual for higher-level code to call C<< Amanda::Device->new >>.
287 Intead, use L<Amanda::Changer> to load a volume and reserve access to it; the
288 resulting reservation will contain an already-created Device object.
290 While Amanda proivdes multiple implementations of the Device class, they are
291 not distinguishable via the usual Perl methods (C<ref> or C<< $dev->isa >>).
293 Device users generally call device methods in the following order for reading:
295 read_label (optional)
298 read_block (repeated)
300 or, when writing or appending:
302 read_label (optional)
305 write_block (repeated)
309 =head2 Alternate Constructor
311 To create a new RAIT device from a collection of device objects, call
312 C<< Amanda::Device->new_rait_from_children($child1, $child2, ..) >>.
313 If one of the child objects is C<undef>, the resulting RAIT device
314 will operate in degraded mode.
316 =head2 Error Handling
318 Device methods return a particular value to signal the presence of an error
319 condition. In many cases, this is simply false (exceptions are listed below).
321 When a device signals an error, C<< $dev->status >> and C<< $dev->error >>
322 contain details of what went wrong. Status is a bitfield where each bit that is
323 set indicates a possible problem. Unfortunately, some devices are unable to
324 distinguish states due to limitations of an external system. For example, the
325 tape device often cannot distinguish an empty drive
326 (C<$DEVICE_STATUS_VOLUME_MISSING>) from a hard device error
327 (C<$DEVICE_STATUS_DEVICE_ERROR>), leading to the status
328 C<$DEVICE_STATUS_VOLUME_MISSING>|C<$DEVICE_STATUS_DEVICE_ERROR>. To be clear:
329 as few as one of the status bits may represent a actual problem. If
330 C<$DEVICE_STATUS_VOLUME_UNLABELED> is set along with other bits, it is I<not>
331 safe to assume that an unlabeled volume is available. However, if the bit is
332 not set, then it is safe to assume there is no unlabeled volume present.
336 =item C<$DEVICE_STATUS_SUCCESS>
340 =item C<$DEVICE_STATUS_DEVICE_ERROR>
342 The device is in an unresolvable error state, and further retries are unlikely
345 =item C<$DEVICE_STATUS_DEVICE_BUSY>
347 The device is in use, and should be retried later
349 =item C<$DEVICE_STATUS_VOLUME_MISSING>
351 The device itself is OK, but has no media loaded. This may change if media is
352 loaded by the user or a changer
354 =item C<$DEVICE_STATUS_VOLUME_UNLABELED>
356 The device is OK and media is laoded, but there is no Amanda header or an
357 invalid header on the media.
359 =item C<$DEVICE_STATUS_VOLUME_ERROR>
361 The device is OK, but there was an unresolvable error loading the header from
362 the media, so subsequent reads or writes will probably fail.
366 At the risk of being repetitive, never test a device's status with C<==>,
367 unless it is to C<$DEVICE_STATUS_SUCCESS>. Furthermore, never try to parse the
368 device error messages -- they are only for user consumption, and may differ
369 from device to device.
371 In addition to the status bitfield, a Device also provides a
372 user-comprehensible error message, available from the methods C<error>
373 (returning the error message), C<status_error> (returning the string form of
374 the status), or C<status_or_error> (returning the error message if one is set,
375 otherwise the string form of the status). None of these functions will ever
380 Device properties provide a bidirectional means of communication between
381 devices and their users. A device provides values for some properties, which
382 other parts of Amanda can use to adjust their behavior to suit the device. For
383 example, Amanda will only attempt to append to a volume if the device's
384 properties indicate that it supports this activity. Some devices have
385 additional properties that can be set to control its activity. For example, the
386 S3 Device requires that the users' keys be given via properties.
388 See C<amanda-devices(7)> for more information on device properties and their
391 The methods C<property_get> and C<property_set> are used to get and set
392 properties, respectively. If the indicated property simply does not exist,
393 these functions return an error indication (FALSE), but the device's status
394 remains C<$DEVICE_STATUS_SUCCESS>. If a more serious error occurs, then the
395 device's status is set appropriately.
397 Device properties are easy to handle, as the Perl-to-C glue takes care of all
398 necessary type conversions:
400 $success = $device->property_set("BLOCK_SIZE", $blocksize);
401 $blocksize = $device->property_get("BLOCK_SIZE");
403 If C<property_get> is called in an array context, it returns the property
404 value, its surety, and its source, in that order. If there is an error
405 fetching the property, C<property_get> returns C<undef>.
407 The C<property_list()> method returns a list of all properties:
409 my @props = $device->property_list();
411 its return is an array of hashes:
413 ( { 'access' => $access_flags,
414 'name' => $property_name,
415 'description' => $property_description },
419 =head3 Surety and Source
421 All properties have a source - where the value came from - and surety - a level
422 of confidence in the value. This can be used to decide which of two potentially
423 contradictory properties to believe. For example, the RAIT device examines the
424 source and surety of child devices' block sizes, prefering properties set by
425 the user (C<$PROPERTY_SOURCE_USER>) over others.
427 Set a property's source and surety with C<property_set_ex>:
428 $dev->property_set_ex("my_prop", 13, $PROPERTY_SURETY_BAD, $PROPERTY_SOURCE_DEFAULT);
429 The surety and source are returned after the property value in list context:
430 my ($val, $sur, $sou) = $dev->property_get("my_prop");
432 The available sureties are:
434 $PROPERTY_SURETY_GOOD
439 $PROPERTY_SOURCE_DEFAULT
440 $PROPERTY_SOURCE_DETECTED
441 $PROPERTY_SOURCE_USER
445 Some devices can perform more than one operation simultaneously, while others
446 are more limited. For example, a tape device is exclusive to a single process
447 while it is in use, while a VFS device can support concurrent reads and writes
450 As of this writing, device locking is not correctly implemented in many
451 devices; consult the source code and check with the Amanda developers before
452 depending on concurrent operation of devices.
456 When writing to a volume, an EOM (end-of-media) condition occurs when no more
457 space is available on the volume. Some devices (currently only those
458 supporting DirectTCP) distinguish a logical EOM (LEOM) from a physical EOM
459 (PEOM). The logical EOM comes some distance before the physical EOM, with
460 enough space left to finish a data block and write any additional bookkeeping
463 In such devices, the C<is_eom> attribute is set once LEOM is detected. Such
464 detection can happen in any method that writes to the volume, including
465 C<start>, C<start_file>, C<finish_file>, and C<finish>. API users that
466 understand LEOM should take this as a signal to complete writing to the device
467 and move on before hitting PEOM.
469 Devices which do not support LEOM simply return a VOLUME_ERROR when the volume
470 is full. If this occurs during a C<write_block> operation, then the volume may
471 or may not contain the block - the situation is indeterminate.
473 Devices indicate their support for LEOM with the LEOM property.
475 =head2 Device Resources
477 Some device types have a "locking" mechanism that prevents other parts of the
478 system from accessing the underlying resource while an operation is in
479 progress. For example, a typical UNIX tape driver cannot be opened by two
482 Amanda Devices will lock the underlying resource when C<start> or C<read_label>
483 is called, and unlock the resource either when the Device object is
484 garbage-collected or in the C<finish> method. Thus in a calling sequence such as
492 the underlying resource remains locked for the entire sequence, even between
493 read_label and finish.
495 It is unwise to rely on Perl's garbage-collection to automatically release
496 resources. Instead, always explicitly release resources with a C<finish> call.
497 The Changer API is careful to do this in its C<release> method.
499 =head2 Member Variables
501 All member variables are implemented using accessor methods, rather than the
502 more common hashref technique. Use
504 print $dev->device_name, "\n";
508 print $dev->{'device_name'}, "\n";
510 The member variables are:
516 the current file number, if any
520 the current block number, if any
524 true if the device is in the middle of reading or writing a file
528 the name with which the device was constructed; note that this is not set until after open_device is finished -- it is an error to access this variable in an open_device implementation
532 the current access mode (C<$ACCESS_NULL>, or that supplied to start)
536 true if an EOF occurred while reading; also used by C<write_from_connection>
540 true if a write operation reached the end of the volume (end-of-medium)
542 =item C<volume_label>
544 the label of the current volume, set by start and read_label
548 the timestamp of the current volume, set by start and read_label
550 =item C<volume_header>
552 the header of the current volume, set by read_label
556 the device's error status (bit flags) as an integer
558 =item C<status_error>
560 the device's error status (bit flags) as a string
564 the device's error message
566 =item C<error_or_status>
568 the device's error message, if set, otherwise the same as C<status_error> --
569 use this to display error messages from devices
573 the device's currently configured block size. This is also available via the
574 BLOCK_SIZE property. Writers should use block_size-byte blocks, and readers
575 should initially use block_size, and expand buffers as directed by
578 =item C<min_block_size>
580 minimum allowed block size for this device
582 =item C<max_block_size>
584 maximum allowed block size for this device
588 =head2 Object Methods
590 =head3 configure($use_global_config)
594 Once you have a new device, you should configure it. This sets properties on
595 the device based on the user's configuation. If C<$use_global_config> is true,
596 then any global C<device_property> parameters are processed, along with
597 tapetype and other relevant parameters. Otherwise, only parameters from the
598 device definition (if the device was opened via an alias) are processed.
600 This method is I<deprecated>. All access to Devices should be via the Changer
601 API (see L<Amanda::Changer>), which implements its own, more advanced method of
602 configuring devices. The C<configure> method may be removed in a future
607 $status = $dev->read_label();
609 This function reads the tape header of the current volume, returning the
610 Device's status (see "Error Handling", above). Since this is often the first
611 function to accses the underlying hardware, its error status is the one most
612 often reported to the user. In fact, C<amdevcheck(8)> is little more than a
613 wrapper around read_label.
615 The method sets the following member variables:
619 =item C<volume_header>
621 if any header data was read from the volume, it is represented here. The
622 header's type may be F_WEIRD if the header was not recognized by Amanda.
624 =item C<volume_label>
626 if read_label read the header successfully, then volume_label contains the
631 smililarly, if read_label read the header successfully, then volume_time
632 contains the timestamp from the header
638 $succss = $dev->start($ACCESS_WRITE, $label, $timestamp);
640 Start starts the device and prepares it for the use described by its second
641 parameter. This function can be called regardless of whether C<read_label> has
644 If the access mode is C<$ACCESS_WRITE>, then the label and timestamp must be
645 supplied (although leaving the timestamp undef will use the current time), and
646 they will be used to write a new volume header. Otherwise, these parameters
649 On completion, start leaves the device's C<access_mode>, C<volume_label> and
650 C<volume_time> member variables set, by reading the tape header if necessary.
651 Note that in mode C<$ACCESS_APPEND>, the C<file> member variable is not set
652 until after C<start_file> has been called.
656 $success = $dev->start_file($header);
658 This method prepares the device to write data into a file, beginning by writing
659 the supplied header to the volume. On successful completion, the device's
660 C<file> is set to the current file number, C<block> is zero, and C<in_file> is
661 true. If the volume is out of space, the C<is_eom> member is set to true and
662 the method returns false with status C<DEVICE_STATUS_VOLUME_ERROR>.
666 # (not available from Perl)
667 success = device_write_block(dev, blocksize, buf);
669 This method writes a single block of data to the volume. It is only available
670 from C -- Perl code should not be handling raw data, as it is far too slow.
671 Use the transfer architecture (L<Amanda::Xfer>) for that purpose.
673 The C<blocksize> must be the device's block size, unless
674 this is a short write. A short write must be the last block
675 of a file. Some devices will zero-pad a short write to a full
676 blocksize. This method returns false on error. If the volume is
677 out of space, C<is_eom> is set and the method returns false with
678 status C<DEVICE_STATUS_VOLUME_ERROR>. Note that not all devices can
679 differentiate an EOM condition from other errors; these devices will
680 set C<is_eom> whenever the situation is ambiguous.
682 This function ensures that C<block> is correct on exit. Even in an
683 error condition, it does not finish the current file for the caller.
687 $success = $dev->finish_file();
689 Once an entire file has been written, finish_file performs any
690 cleanup required on the volume, such as writing filemarks. On exit,
691 C<in_file> is false. If the device runs out of space while finishing
692 (e.g., the filemark does not fit), then this method returns false
693 with status C<DEVICE_STATUS_VOLUME_ERROR> and C<is_eom> is set.
695 This function should not be used while reading -- instead, just seek
700 $header = $dev->seek_file($fileno);
702 In C<$ACCESS_READ>, C<seek_file> sets up the device to read from file
703 C<$fileno>. This function is not available in C<$ACCESS_WRITE> and
704 C<$ACCESS_APPEND>. It returns the header from the requested file on success, or
707 If the requested file doesn't exist, as might happen when a volume has had
708 files recycled, then C<seek_file> will seek to the next file that does exist. The
709 file this function selected is indicated by the C<file> member variable on exit.
710 If the requested file number is exactly one more than the last valid file, this
711 function returns a C<$F_TAPEEND> header.
713 As an example, on a volume with only files 1 and 3:
715 $dev->seek_file(1) returns header for file 1, $dev->file == 1
716 $dev->seek_file(2) returns header for file 3, $dev->file == 3
717 $dev->seek_file(3) returns header for file 3, $dev->file == 3
718 $dev->seek_file(4) returns a tapend header, $dev->file == 4
719 $dev->seek_file(5) returns NULL/undef
721 On exit, C<is_eof> is false, C<in_file> is true unless no file was found (tapeend or NULL), C<file> is the discovered file, and C<block> is zero.
725 $success = $dev->seek_block($block);
727 After seeking to a file, the caller can optionally seek to a particular block
728 in the file. This function will set C<block> appropriately. Note that it may
729 not be possible to detect EOF, so this function may fail to set C<is_eof> even
730 though a subsequent C<read_block> will return no data.
734 # (not available from Perl)
735 bytes_read = device_read_block(dev, buffer, *blocksize);
737 This method is the complement of C<write_block>, and reads the next block from
738 the device, or returns -1 on error. Pass a buffer and its size. If the buffer
739 is not big enough, no read is performed, the parameter C<blocksize> is set to
740 the required blocksize, and the method returns 0. As a special case, passing a
741 C<NULL> buffer and C<*blocksize == 0> is treated as a request for the required block
742 size. It is not an error to pass a buffer that is too large (and, in fact, this
743 is precisely the effect of setting the C<read_block_size> configuration
746 On EOF, this method returns -1, but sets C<is_eof> and leaves the device's
747 status set to C<$DEVICE_STATUS_SUCCESS>. Some devices may be able to detect EOF
748 while reading the last block, and will set C<is_eof> at that time. Others must
749 wait for the next read to fail. It is never an error to call C<read_block>
750 after an EOF, so there is no need to check C<is_eof> except when C<read_block>
755 $success = $dev->finish();
757 This undoes the effects of start, returning the device to a neutral state
758 (C<$ACCESS_NULL>). It will also release any resources acquired by
759 C<read_label>, even if C<start> was not called. After C<finish>, it is not an
760 error to call C<start> again, even with a different mode.
764 $success = $dev->recycle_file(fileno);
766 On devices that support it, this removes the indicated file from the volume,
767 presumably freeing its space to be used for other files. File numbers of
768 existing files will not change, so this operation may leave "holes" in the
769 sequence of file numbers. See C<seek_file> to see how this is handled.
771 This method cannot be called while in a file, nor while in C<$ACCESS_READ>
776 $success = $dev->erase(fileno);
778 On devices that support it, this erases all data from the volume, presumably
779 freeing the space. This method must be called before start and after finish --
780 that is, while the device is in a neutral state (C<$ACCESS_NULL>). You can
781 detect whether or not this operation is supported using the C<full_deletion>
786 $success = $dev->eject();
788 On devices that support it, this eject the volume. This method can be called
789 before start and after finish.
791 =head3 directtcp_supported
793 $supp = $dev->directtcp_supported();
795 This method returns TRUE if the DirectTCP-related methods (C<listen>,
796 C<accept>, C<write_from_connection>, and C<read_to_connection>) are implemented
801 $addrs = $dev->listen($for_writing);
803 The C<listen> method starts the device listening for an incoming DirectTCP
804 connection. The method returns a set of IP:PORT pairs to which a TCP
805 connection can be made. The boolean C<for_writing> is TRUE if
806 this connection will be used to write to the device.
808 This method can be called at any time, but between the time C<listen> is called
809 and when C<accept> returns, no other methods of the device should be called.
811 The return value might look like:
813 $addrs = [ [ "127.0.0.1", 9382 ] ]
815 In C, the memory for these addresses remains the responsibility of the device,
816 and will remain unchanged until C<accept> returns.
820 $conn = $dev->accept();
822 This method accepts a connection to one of the addresses returned by C<listen>,
823 returning an established DirectTCPConnection object (see below). It returns
824 C<undef> on failure. Note that this method may block indefinitely if no
825 connection ever occurs. The C implementation returns an already-referenced
826 connection object, so the caller should call C<g_object_unref> when the
827 connection is no longer needed.
831 $conn = $dev->connect($for_writing, $addrs);
833 This method initiates a connection to one of the addresses in C<$addrs>,
834 returning an established DirectTCPConnection object (see below). The
835 C<$for_writing> parameter is TRUE if the connection will be used to write to
836 the device. It returns C<undef> on failure. Note that this method may block
837 indefinitely if no connection ever occurs. The C implementation returns an
838 already-referenced connection object, so the caller should call
839 C<g_object_unref> when the connection is no longer needed.
841 =head3 use_connection
843 my $ok = $dev->use_connection($conn);
845 Call this method to use a DirectTCPConnection object created with another
846 device. The method must be called before the device is started (so
847 C<access_mode> is C<$ACCESS_NULL>), as some devices cannot support switching
848 connections without rewinding. Any subsequent C<read_to_connection> or
849 C<write_from_connection> calls will use this connection.
851 =head3 write_from_connection
853 ($ok, $actual_size) = $dev->write_from_connection($size);
855 This method reads data from the DirectTCPConnection specified with
856 C<use_connection> or returned from C<accept> or C<connect> and writes it to the
857 volume. It writes at most C<$size> bytes, and returns the number of bytes
858 written in C<$actual_size>. If C<$size> is zero, it will write until EOF, EOM,
859 or a device error. On error, C<$ok> is false.
861 When an EOF is received over the connection, signalling the end of the data
862 stream, then this method returns without error (C<$ok> is true), with
863 C<$actual_size> indicating the number of bytes written to the device (which may
864 be zero). In this case, the C<is_eof> attribute is true on return.
866 Similarly, when the device encounters logical EOM in this method, it returns
867 the total bytes transferred in C<$actual_size>, with C<$ok> true, and the
868 C<is_eom> attribute true. No data is lost. If writes continue until physical
869 EOM, data may be lost.
871 =head3 read_to_connection
873 ($ok, $actual_size) = $dev->read_to_connection($size);
875 This method is similar to C<write_from_connection> but the data flows in the
876 opposite direction. It reads at most C<$size> bytes, and returns the total
877 number of bytes read in C<$actual_size>.
879 When the method encounters an EOF, it stops early and returns successfully with
880 the number of bytes actually read (which may be zero).
884 Get a property value, where the property is specified by name. See "Properties", above.
888 Set a simple property value. See "Properties", above.
890 =head3 property_set_ex
892 Set a property value with surety and source. See "Properties", above.
896 This module defines a large number of constant scalars. These constants are
897 available from the package namespace (e.g., C<$Amanda::Device::ACCESS_WRITE>),
898 or imported with the C<:constant> import tag.
900 =head2 DirectTCPConnection objects
902 The C<accept> and C<connect> methods return an object to represent the ongoing
903 DirectTCP connection. This object is mostly useful as a "token" to be passed
904 to C<write_from_connection> and C<read_to_connection>. In particular, a
905 connection created by one device can be used with another device; this is how
906 DirectTCP dumps are spanned over multiple volumes.
908 The class does have one critical method, though:
912 This method closes the connection, releasing all resources allocated to it. It
913 can be called at any time, whether the remote side has closed the connection
919 sub new_rait_from_children {
920 my $class = shift; # strip the $class from the arguments
921 return rait_device_open_from_children([@_]);
924 push @EXPORT_OK, qw(DeviceAccessMode_to_strings);
925 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw(DeviceAccessMode_to_strings);
927 my %_DeviceAccessMode_VALUES;
928 #Convert a flag value to a list of names for flags that are set.
929 sub DeviceAccessMode_to_strings {
933 for my $k (keys %_DeviceAccessMode_VALUES) {
934 my $v = $_DeviceAccessMode_VALUES{$k};
936 #is this a matching flag?
937 if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
942 #by default, just return the number as a 1-element list
950 push @EXPORT_OK, qw($ACCESS_NULL);
951 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw($ACCESS_NULL);
953 $_DeviceAccessMode_VALUES{"NULL"} = $ACCESS_NULL;
955 push @EXPORT_OK, qw($ACCESS_READ);
956 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw($ACCESS_READ);
958 $_DeviceAccessMode_VALUES{"READ"} = $ACCESS_READ;
960 push @EXPORT_OK, qw($ACCESS_WRITE);
961 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw($ACCESS_WRITE);
963 $_DeviceAccessMode_VALUES{"WRITE"} = $ACCESS_WRITE;
965 push @EXPORT_OK, qw($ACCESS_APPEND);
966 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw($ACCESS_APPEND);
968 $_DeviceAccessMode_VALUES{"APPEND"} = $ACCESS_APPEND;
970 push @EXPORT_OK, qw(IS_WRITABLE_ACCESS_MODE);
971 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw(IS_WRITABLE_ACCESS_MODE);
973 #copy symbols in DeviceAccessMode to constants
974 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"DeviceAccessMode"}};
976 push @EXPORT_OK, qw(DeviceStatusFlags_to_strings);
977 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw(DeviceStatusFlags_to_strings);
979 my %_DeviceStatusFlags_VALUES;
980 #Convert a flag value to a list of names for flags that are set.
981 sub DeviceStatusFlags_to_strings {
985 for my $k (keys %_DeviceStatusFlags_VALUES) {
986 my $v = $_DeviceStatusFlags_VALUES{$k};
988 #is this a matching flag?
989 if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
994 #by default, just return the number as a 1-element list
1002 push @EXPORT_OK, qw($DEVICE_STATUS_SUCCESS);
1003 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_SUCCESS);
1005 $_DeviceStatusFlags_VALUES{"SUCCESS"} = $DEVICE_STATUS_SUCCESS;
1007 push @EXPORT_OK, qw($DEVICE_STATUS_DEVICE_ERROR);
1008 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_DEVICE_ERROR);
1010 $_DeviceStatusFlags_VALUES{"DEVICE_ERROR"} = $DEVICE_STATUS_DEVICE_ERROR;
1012 push @EXPORT_OK, qw($DEVICE_STATUS_DEVICE_BUSY);
1013 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_DEVICE_BUSY);
1015 $_DeviceStatusFlags_VALUES{"DEVICE_BUSY"} = $DEVICE_STATUS_DEVICE_BUSY;
1017 push @EXPORT_OK, qw($DEVICE_STATUS_VOLUME_MISSING);
1018 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_VOLUME_MISSING);
1020 $_DeviceStatusFlags_VALUES{"VOLUME_MISSING"} = $DEVICE_STATUS_VOLUME_MISSING;
1022 push @EXPORT_OK, qw($DEVICE_STATUS_VOLUME_UNLABELED);
1023 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_VOLUME_UNLABELED);
1025 $_DeviceStatusFlags_VALUES{"VOLUME_UNLABELED"} = $DEVICE_STATUS_VOLUME_UNLABELED;
1027 push @EXPORT_OK, qw($DEVICE_STATUS_VOLUME_ERROR);
1028 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_VOLUME_ERROR);
1030 $_DeviceStatusFlags_VALUES{"VOLUME_ERROR"} = $DEVICE_STATUS_VOLUME_ERROR;
1032 push @EXPORT_OK, qw($DEVICE_STATUS_FLAGS_MAX);
1033 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_FLAGS_MAX);
1035 #copy symbols in DeviceStatusFlags to constants
1036 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"DeviceStatusFlags"}};
1038 push @EXPORT_OK, qw(PropertyPhaseFlags_to_strings);
1039 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw(PropertyPhaseFlags_to_strings);
1041 my %_PropertyPhaseFlags_VALUES;
1042 #Convert a flag value to a list of names for flags that are set.
1043 sub PropertyPhaseFlags_to_strings {
1047 for my $k (keys %_PropertyPhaseFlags_VALUES) {
1048 my $v = $_PropertyPhaseFlags_VALUES{$k};
1050 #is this a matching flag?
1051 if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
1056 #by default, just return the number as a 1-element list
1064 push @EXPORT_OK, qw($PROPERTY_PHASE_BEFORE_START);
1065 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_BEFORE_START);
1067 $_PropertyPhaseFlags_VALUES{"BEFORE_START"} = $PROPERTY_PHASE_BEFORE_START;
1069 push @EXPORT_OK, qw($PROPERTY_PHASE_BETWEEN_FILE_WRITE);
1070 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_BETWEEN_FILE_WRITE);
1072 $_PropertyPhaseFlags_VALUES{"BETWEEN_FILE_WRITE"} = $PROPERTY_PHASE_BETWEEN_FILE_WRITE;
1074 push @EXPORT_OK, qw($PROPERTY_PHASE_INSIDE_FILE_WRITE);
1075 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_INSIDE_FILE_WRITE);
1077 $_PropertyPhaseFlags_VALUES{"INSIDE_FILE_WRITE"} = $PROPERTY_PHASE_INSIDE_FILE_WRITE;
1079 push @EXPORT_OK, qw($PROPERTY_PHASE_BETWEEN_FILE_READ);
1080 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_BETWEEN_FILE_READ);
1082 $_PropertyPhaseFlags_VALUES{"BETWEEN_FILE_READ"} = $PROPERTY_PHASE_BETWEEN_FILE_READ;
1084 push @EXPORT_OK, qw($PROPERTY_PHASE_INSIDE_FILE_READ);
1085 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_INSIDE_FILE_READ);
1087 $_PropertyPhaseFlags_VALUES{"INSIDE_FILE_READ"} = $PROPERTY_PHASE_INSIDE_FILE_READ;
1089 push @EXPORT_OK, qw($PROPERTY_PHASE_MAX);
1090 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_MAX);
1092 push @EXPORT_OK, qw($PROPERTY_PHASE_MASK);
1093 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_MASK);
1095 push @EXPORT_OK, qw($PROPERTY_PHASE_SHIFT);
1096 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_SHIFT);
1098 #copy symbols in PropertyPhaseFlags to constants
1099 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"PropertyPhaseFlags"}};
1101 push @EXPORT_OK, qw(PropertyAccessFlags_to_strings);
1102 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw(PropertyAccessFlags_to_strings);
1104 my %_PropertyAccessFlags_VALUES;
1105 #Convert a flag value to a list of names for flags that are set.
1106 sub PropertyAccessFlags_to_strings {
1110 for my $k (keys %_PropertyAccessFlags_VALUES) {
1111 my $v = $_PropertyAccessFlags_VALUES{$k};
1113 #is this a matching flag?
1114 if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
1119 #by default, just return the number as a 1-element list
1127 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_BEFORE_START);
1128 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_BEFORE_START);
1130 $_PropertyAccessFlags_VALUES{"GET_BEFORE_START"} = $PROPERTY_ACCESS_GET_BEFORE_START;
1132 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE);
1133 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE);
1135 $_PropertyAccessFlags_VALUES{"GET_BETWEEN_FILE_WRITE"} = $PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE;
1137 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE);
1138 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE);
1140 $_PropertyAccessFlags_VALUES{"GET_INSIDE_FILE_WRITE"} = $PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE;
1142 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_BETWEEN_FILE_READ);
1143 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_BETWEEN_FILE_READ);
1145 $_PropertyAccessFlags_VALUES{"GET_BETWEEN_FILE_READ"} = $PROPERTY_ACCESS_GET_BETWEEN_FILE_READ;
1147 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_INSIDE_FILE_READ);
1148 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_INSIDE_FILE_READ);
1150 $_PropertyAccessFlags_VALUES{"GET_INSIDE_FILE_READ"} = $PROPERTY_ACCESS_GET_INSIDE_FILE_READ;
1152 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_BEFORE_START);
1153 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_BEFORE_START);
1155 $_PropertyAccessFlags_VALUES{"SET_BEFORE_START"} = $PROPERTY_ACCESS_SET_BEFORE_START;
1157 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE);
1158 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE);
1160 $_PropertyAccessFlags_VALUES{"SET_BETWEEN_FILE_WRITE"} = $PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE;
1162 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE);
1163 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE);
1165 $_PropertyAccessFlags_VALUES{"SET_INSIDE_FILE_WRITE"} = $PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE;
1167 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_BETWEEN_FILE_READ);
1168 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_BETWEEN_FILE_READ);
1170 $_PropertyAccessFlags_VALUES{"SET_BETWEEN_FILE_READ"} = $PROPERTY_ACCESS_SET_BETWEEN_FILE_READ;
1172 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_INSIDE_FILE_READ);
1173 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_INSIDE_FILE_READ);
1175 $_PropertyAccessFlags_VALUES{"SET_INSIDE_FILE_READ"} = $PROPERTY_ACCESS_SET_INSIDE_FILE_READ;
1177 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_MASK);
1178 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_MASK);
1180 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_MASK);
1181 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_MASK);
1183 #copy symbols in PropertyAccessFlags to constants
1184 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"PropertyAccessFlags"}};
1186 push @EXPORT_OK, qw(ConcurrencyParadigm_to_string);
1187 push @{$EXPORT_TAGS{"ConcurrencyParadigm"}}, qw(ConcurrencyParadigm_to_string);
1189 my %_ConcurrencyParadigm_VALUES;
1190 #Convert an enum value to a single string
1191 sub ConcurrencyParadigm_to_string {
1194 for my $k (keys %_ConcurrencyParadigm_VALUES) {
1195 my $v = $_ConcurrencyParadigm_VALUES{$k};
1197 #is this a matching flag?
1198 if ($enumval == $v) {
1203 #default, just return the number
1207 push @EXPORT_OK, qw($CONCURRENCY_PARADIGM_EXCLUSIVE);
1208 push @{$EXPORT_TAGS{"ConcurrencyParadigm"}}, qw($CONCURRENCY_PARADIGM_EXCLUSIVE);
1210 $_ConcurrencyParadigm_VALUES{"EXCLUSIVE"} = $CONCURRENCY_PARADIGM_EXCLUSIVE;
1212 push @EXPORT_OK, qw($CONCURRENCY_PARADIGM_SHARED_READ);
1213 push @{$EXPORT_TAGS{"ConcurrencyParadigm"}}, qw($CONCURRENCY_PARADIGM_SHARED_READ);
1215 $_ConcurrencyParadigm_VALUES{"SHARED_READ"} = $CONCURRENCY_PARADIGM_SHARED_READ;
1217 push @EXPORT_OK, qw($CONCURRENCY_PARADIGM_RANDOM_ACCESS);
1218 push @{$EXPORT_TAGS{"ConcurrencyParadigm"}}, qw($CONCURRENCY_PARADIGM_RANDOM_ACCESS);
1220 $_ConcurrencyParadigm_VALUES{"RANDOM_ACCESS"} = $CONCURRENCY_PARADIGM_RANDOM_ACCESS;
1222 #copy symbols in ConcurrencyParadigm to constants
1223 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"ConcurrencyParadigm"}};
1225 push @EXPORT_OK, qw(StreamingRequirement_to_string);
1226 push @{$EXPORT_TAGS{"StreamingRequirement"}}, qw(StreamingRequirement_to_string);
1228 my %_StreamingRequirement_VALUES;
1229 #Convert an enum value to a single string
1230 sub StreamingRequirement_to_string {
1233 for my $k (keys %_StreamingRequirement_VALUES) {
1234 my $v = $_StreamingRequirement_VALUES{$k};
1236 #is this a matching flag?
1237 if ($enumval == $v) {
1242 #default, just return the number
1246 push @EXPORT_OK, qw($STREAMING_REQUIREMENT_NONE);
1247 push @{$EXPORT_TAGS{"StreamingRequirement"}}, qw($STREAMING_REQUIREMENT_NONE);
1249 $_StreamingRequirement_VALUES{"NONE"} = $STREAMING_REQUIREMENT_NONE;
1251 push @EXPORT_OK, qw($STREAMING_REQUIREMENT_DESIRED);
1252 push @{$EXPORT_TAGS{"StreamingRequirement"}}, qw($STREAMING_REQUIREMENT_DESIRED);
1254 $_StreamingRequirement_VALUES{"DESIRED"} = $STREAMING_REQUIREMENT_DESIRED;
1256 push @EXPORT_OK, qw($STREAMING_REQUIREMENT_REQUIRED);
1257 push @{$EXPORT_TAGS{"StreamingRequirement"}}, qw($STREAMING_REQUIREMENT_REQUIRED);
1259 $_StreamingRequirement_VALUES{"REQUIRED"} = $STREAMING_REQUIREMENT_REQUIRED;
1261 #copy symbols in StreamingRequirement to constants
1262 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"StreamingRequirement"}};
1264 push @EXPORT_OK, qw(MediaAccessMode_to_string);
1265 push @{$EXPORT_TAGS{"MediaAccessMode"}}, qw(MediaAccessMode_to_string);
1267 my %_MediaAccessMode_VALUES;
1268 #Convert an enum value to a single string
1269 sub MediaAccessMode_to_string {
1272 for my $k (keys %_MediaAccessMode_VALUES) {
1273 my $v = $_MediaAccessMode_VALUES{$k};
1275 #is this a matching flag?
1276 if ($enumval == $v) {
1281 #default, just return the number
1285 push @EXPORT_OK, qw($MEDIA_ACCESS_MODE_READ_ONLY);
1286 push @{$EXPORT_TAGS{"MediaAccessMode"}}, qw($MEDIA_ACCESS_MODE_READ_ONLY);
1288 $_MediaAccessMode_VALUES{"READ_ONLY"} = $MEDIA_ACCESS_MODE_READ_ONLY;
1290 push @EXPORT_OK, qw($MEDIA_ACCESS_MODE_WORM);
1291 push @{$EXPORT_TAGS{"MediaAccessMode"}}, qw($MEDIA_ACCESS_MODE_WORM);
1293 $_MediaAccessMode_VALUES{"WORM"} = $MEDIA_ACCESS_MODE_WORM;
1295 push @EXPORT_OK, qw($MEDIA_ACCESS_MODE_READ_WRITE);
1296 push @{$EXPORT_TAGS{"MediaAccessMode"}}, qw($MEDIA_ACCESS_MODE_READ_WRITE);
1298 $_MediaAccessMode_VALUES{"READ_WRITE"} = $MEDIA_ACCESS_MODE_READ_WRITE;
1300 push @EXPORT_OK, qw($MEDIA_ACCESS_MODE_WRITE_ONLY);
1301 push @{$EXPORT_TAGS{"MediaAccessMode"}}, qw($MEDIA_ACCESS_MODE_WRITE_ONLY);
1303 $_MediaAccessMode_VALUES{"WRITE_ONLY"} = $MEDIA_ACCESS_MODE_WRITE_ONLY;
1305 #copy symbols in MediaAccessMode to constants
1306 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"MediaAccessMode"}};
1308 push @EXPORT_OK, qw(PropertySurety_to_strings);
1309 push @{$EXPORT_TAGS{"PropertySurety"}}, qw(PropertySurety_to_strings);
1311 my %_PropertySurety_VALUES;
1312 #Convert a flag value to a list of names for flags that are set.
1313 sub PropertySurety_to_strings {
1317 for my $k (keys %_PropertySurety_VALUES) {
1318 my $v = $_PropertySurety_VALUES{$k};
1320 #is this a matching flag?
1321 if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
1326 #by default, just return the number as a 1-element list
1334 push @EXPORT_OK, qw($PROPERTY_SURETY_BAD);
1335 push @{$EXPORT_TAGS{"PropertySurety"}}, qw($PROPERTY_SURETY_BAD);
1337 $_PropertySurety_VALUES{"SURETY_BAD"} = $PROPERTY_SURETY_BAD;
1339 push @EXPORT_OK, qw($PROPERTY_SURETY_GOOD);
1340 push @{$EXPORT_TAGS{"PropertySurety"}}, qw($PROPERTY_SURETY_GOOD);
1342 $_PropertySurety_VALUES{"SURETY_GOOD"} = $PROPERTY_SURETY_GOOD;
1344 #copy symbols in PropertySurety to constants
1345 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"PropertySurety"}};
1347 push @EXPORT_OK, qw(PropertySource_to_strings);
1348 push @{$EXPORT_TAGS{"PropertySource"}}, qw(PropertySource_to_strings);
1350 my %_PropertySource_VALUES;
1351 #Convert a flag value to a list of names for flags that are set.
1352 sub PropertySource_to_strings {
1356 for my $k (keys %_PropertySource_VALUES) {
1357 my $v = $_PropertySource_VALUES{$k};
1359 #is this a matching flag?
1360 if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
1365 #by default, just return the number as a 1-element list
1373 push @EXPORT_OK, qw($PROPERTY_SOURCE_DEFAULT);
1374 push @{$EXPORT_TAGS{"PropertySource"}}, qw($PROPERTY_SOURCE_DEFAULT);
1376 $_PropertySource_VALUES{"SOURCE_DEFAULT"} = $PROPERTY_SOURCE_DEFAULT;
1378 push @EXPORT_OK, qw($PROPERTY_SOURCE_DETECTED);
1379 push @{$EXPORT_TAGS{"PropertySource"}}, qw($PROPERTY_SOURCE_DETECTED);
1381 $_PropertySource_VALUES{"SOURCE_DETECTED"} = $PROPERTY_SOURCE_DETECTED;
1383 push @EXPORT_OK, qw($PROPERTY_SOURCE_USER);
1384 push @{$EXPORT_TAGS{"PropertySource"}}, qw($PROPERTY_SOURCE_USER);
1386 $_PropertySource_VALUES{"SOURCE_USER"} = $PROPERTY_SOURCE_USER;
1388 #copy symbols in PropertySource to constants
1389 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"PropertySource"}};
1392 # SWIG produces a sub-package for the Device "class", in this case named
1393 # Amanda::Device::Device. For user convenience, we allow Amanda::Device->new(..) to
1394 # do the same thing. This is a wrapper function, and not just a typeglob assignment,
1395 # because we want to get the right blessing.
1398 Amanda::Device::Device->new(@_);