2 * Copyright (c) 2005-2008 Zmanda Inc. All Rights Reserved.
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 2.1 as
6 * published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
11 * License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 * Contact information: Zmanda Inc., 465 S Mathlida Ave, Suite 300
18 * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
21 /* The Device API abstracts device workings, interaction, properties, and
22 * capabilities from the rest of the Amanda code base. It supports
23 * pluggable modules for different kinds of devices. */
29 #include <glib-object.h>
32 #include "fileheader.h"
34 /* Device API version. */
35 #define DEVICE_API_VERSION 0
37 extern void device_api_init(void);
39 /* Different access modes */
41 ACCESS_NULL, /* Device is not yet opened. */
47 #define IS_WRITABLE_ACCESS_MODE(mode) ((mode) == ACCESS_WRITE || \
48 (mode) == ACCESS_APPEND)
50 /* Device object definition follows. */
53 * Type checking and casting macros
55 GType device_get_type (void);
56 #define TYPE_DEVICE (device_get_type())
57 #define DEVICE(obj) G_TYPE_CHECK_INSTANCE_CAST((obj), device_get_type(), Device)
58 #define DEVICE_CONST(obj) G_TYPE_CHECK_INSTANCE_CAST((obj), device_get_type(), Device const)
59 #define DEVICE_CLASS(klass) G_TYPE_CHECK_CLASS_CAST((klass), device_get_type(), DeviceClass)
60 #define IS_DEVICE(obj) G_TYPE_CHECK_INSTANCE_TYPE((obj), device_get_type ())
61 #define DEVICE_GET_CLASS(obj) G_TYPE_INSTANCE_GET_CLASS((obj), device_get_type(), DeviceClass)
63 typedef struct DevicePrivate_s DevicePrivate;
65 /* This structure is a Flags (bitwise OR of values). Zero indicates success;
66 * any other value indicates some kind of problem reading the label. If
67 * multiple bits are set, it does not necessarily indicate that /all/ of
68 * the specified issues occured, but rather that /at least one/ did. */
70 /* When changing, Also update device_status_flags_values in
71 * device-src/device.c and perl/Amanda/Device.swg */
72 DEVICE_STATUS_SUCCESS = 0,
74 /* The device is in an unresolvable error state, and
75 * further retries are unlikely to change the status */
76 DEVICE_STATUS_DEVICE_ERROR = (1 << 0),
78 /* The device is in use, and should be retried later */
79 DEVICE_STATUS_DEVICE_BUSY = (1 << 1),
81 /* The device itself is OK, but has no media loaded. This
82 * may change if media is loaded by the user or a changer */
83 DEVICE_STATUS_VOLUME_MISSING = (1 << 2),
85 /* The device is OK and media is laoded, but there is
86 * no Amanda header or an invalid header on the media. */
87 DEVICE_STATUS_VOLUME_UNLABELED = (1 << 3),
89 /* The device is OK, but there was an unresolvable error
90 * loading the header from the media, so subsequent reads
91 * or writes will probably fail. */
92 DEVICE_STATUS_VOLUME_ERROR = (1 << 4),
94 DEVICE_STATUS_FLAGS_MAX = (1 << 5)
97 #define DEVICE_STATUS_FLAGS_MASK (DEVICE_STATUS_MAX-1)
98 #define DEVICE_STATUS_FLAGS_TYPE (device_status_flags_get_type())
99 GType device_status_flags_get_type(void);
102 * Main object structure
104 typedef struct Device {
107 /* You can peek at the stuff below, but only subclasses should
108 change these values.*/
110 /* What file, block are we at? (and are we in the middle of a * file?) */
115 /* Holds the user-specified device name, which may be an alias */
118 /* Holds the user-specified access-mode, or ACCESS_NULL if the device
119 * has not yet been started*/
120 DeviceAccessMode access_mode;
122 /* In reading mode, FALSE unless all the data from the current file
123 * was successfully read. In writing mode, TRUE if the end of tape
124 * has been reached. */
127 /* Holds the label and time of the currently-inserted volume,
128 * or NULL if it has not been read/written yet. */
132 /* The most recently read volume header, or NULL if no header was
133 * read from this device. Callers can use this to glean information
134 * about the volume beyond volume_label and volume_time. */
135 dumpfile_t *volume_header;
137 /* The latest status for the device */
138 DeviceStatusFlags status;
140 /* device block-size ranges. These are also available as properties,
141 * and by default users can set block_size via property BLOCK_SIZE.
142 * Writers should use block_size, and readers should initially use
143 * block_size, and expand buffers as directed by read_block. */
144 gsize min_block_size;
145 gsize max_block_size;
148 /* surety and source for the block size; if you set block_size directly,
150 PropertySurety block_size_surety;
151 PropertySource block_size_source;
153 DevicePrivate * private;
156 /* Pointer to factory function for device types.
158 * device_name is the full name ("tape:/dev/nst0")
159 * device_prefix is the prefix ("tape")
160 * device_node is what follows the prefix ("/dev/nst0")
162 * The caller retains responsibility to free or otherwise handle
163 * the passed strings.
165 typedef Device* (*DeviceFactory)(char *device_name,
166 char * device_prefix,
169 /* This function registers a new device with the allocation system.
170 * Call it after you register your type with the GLib type system.
171 * This function assumes that the strings in device_prefix_list are
172 * statically allocated. */
173 extern void register_device(DeviceFactory factory,
174 const char ** device_prefix_list);
179 typedef struct _DeviceClass DeviceClass;
180 struct _DeviceClass {
181 GObjectClass __parent__;
182 void (* open_device) (Device * self, char * device_name,
183 char * device_prefix, char * device_node);
184 gboolean (* configure) (Device * self, gboolean use_global_config);
185 DeviceStatusFlags (* read_label)(Device * self);
186 gboolean (* start) (Device * self, DeviceAccessMode mode,
187 char * label, char * timestamp);
188 gboolean (* start_file) (Device * self, dumpfile_t * info);
189 gboolean (* write_block) (Device * self, guint size, gpointer data);
190 gboolean (* write_from_fd) (Device * self, queue_fd_t *queue_fd);
191 gboolean (* finish_file) (Device * self);
192 dumpfile_t* (* seek_file) (Device * self, guint file);
193 gboolean (* seek_block) (Device * self, guint64 block);
194 int (* read_block) (Device * self, gpointer buf, int * size);
195 gboolean (* read_to_fd) (Device * self, queue_fd_t *queue_fd);
196 gboolean (* property_get_ex) (Device * self, DevicePropertyId id,
198 PropertySurety *surety,
199 PropertySource *source);
200 gboolean (* property_set_ex) (Device * self,
203 PropertySurety surety,
204 PropertySource source);
205 gboolean (* recycle_file) (Device * self, guint filenum);
206 gboolean (* finish) (Device * self);
208 /* array of DeviceProperty objects for this class, keyed by ID */
209 GArray *class_properties;
211 /* The return value of device_property_get_list */
212 GSList * class_properties_list;
216 * Device Instantiation
219 /* This is how you get a new Device. Pass in a device name or alias.
221 * A Device is *always* returned, even for an invalid device name. You
222 * must check the resulting device->status to know if the device is valid
223 * to be used. If device->status is not DEVICE_STATUS_SUCCESS, then there
224 * was an error opening the device.
226 * Note that the Amanda configuration must be initialized, as this function
227 * looks for device definitions and other configuration information.
229 Device* device_open (char * device_name);
231 /* Once you have a new device, you should configure it. This sets properties
232 * on the device based on the user's configuation. If USE_GLOBAL_CONFIG is
233 * true, then any global device_property parameters are processed, along with
234 * tapetype and othe relevant parameters.
236 gboolean device_configure(Device *self, gboolean use_global_config);
242 /* return the error message or the string "Unknown Device error". The
243 * string remains the responsibility of the Device, and should not
244 * be freed by the caller. */
245 char *device_error(Device * self);
247 /* return a string version of the status. The string remains the
248 * responsibility of the Device, and should not be freed by the
250 char *device_status_error(Device * self);
252 /* Return errmsg if it is set or a string version of the status. The
253 * string remains the responsibility of the Device, and should not
254 * be freed by the caller. */
255 char *device_error_or_status(Device * self);
257 /* Set the error message for this device; for use internally to the
258 * API. The string becomes the responsibility of the Device. If
259 * ERRMSG is NULL, the message is cleared. Note that the given flags
260 * are OR'd with any existing status flags. */
261 void device_set_error(Device * self, char *errmsg, DeviceStatusFlags new_flags);
263 /* Mostly for internal use, this is a boolean check to see whether a given
264 * device is in an error state. If this is TRUE, most operations on the
267 * The check is for DEVICE_STATUS_DEVICE_ERROR *alone*; if any other bits
268 * (e.g., VOLUME_UNLABELED) are set, then the device may not actually be in
271 #define device_in_error(dev) \
272 ((DEVICE(dev))->status == DEVICE_STATUS_DEVICE_ERROR)
278 /* This instructs the device to read the label on the current volume.
279 * device->volume_label will not be initalized until read_label or start is
280 * called. You are encouraged to read the label only after setting any
281 * properties that may affect the label-reading process. Also, after
282 * calling this function, device->volume_label and device->volume_time
283 * will be non-NULL if and only if this function returns
284 * DEVICE_STATUS_SUCCESS. */
285 DeviceStatusFlags device_read_label (Device * self);
287 /* This tells the Device that it's OK to start reading and writing
288 * data. Before you call this, you can only call
289 * device_property_{get, set} and device_read_label. You can only call
290 * this a second time if you call device_finish() first.
292 * You should pass a label and timestamp if and only if you are
293 * opening in WRITE mode (not READ or APPEND). The label and timestamp
294 * remain the caller's responsibility in terms of memory management. The
295 * passed timestamp may be NULL, in which case it will be filled in with
298 * Note that implementations need not calculate a the current time: the
299 * dispatch function does it for you. */
300 gboolean device_start (Device * self,
301 DeviceAccessMode mode, char * label,
304 /* This undoes device_start, returning you to the NULL state. Do this
305 * if you want to (for example) change access mode.
307 * Note to subclass implementors: Call this function first from your
308 * finalization function. */
309 gboolean device_finish (Device * self);
311 /* But you can't write any data until you call this function, too. This
312 * function does not take ownership of the passed dumpfile_t; you must free it
313 * yourself. Note that this function *does* set the blocksize field of the
314 * header properly, based on the size of the header block. */
315 gboolean device_start_file (Device * self,
316 dumpfile_t * jobInfo);
318 /* Does what you expect. Size must be device->block_size or less.
319 * If less, then this is the final block in the file, and no more blocks
320 * may be written until finish_file and start_file have been called. */
321 gboolean device_write_block (Device * self,
325 /* This will drain the given fd (reading until EOF), and write the
326 * resulting data out to the device using maximally-sized blocks.
327 * This function does not call device_finish_file automatically.
329 gboolean device_write_from_fd (Device * self,
330 queue_fd_t *queue_fd);
332 /* Call this when you are finished writing a file.
333 * This function will write a filemark or the local
334 * equivalent, flush the buffers, and do whatever dirty work needs
335 * to be done at such a point in time. */
336 gboolean device_finish_file (Device * self);
338 /* For reading only: Seeks to the beginning of a particular
339 * filemark. Only do this when reading; opening in
340 * ACCESS_WRITE will start you out at the first file, and opening in
341 * ACCESS_APPEND will automatically seek to the end of the medium.
343 * If the requested file doesn't exist, as might happen when a volume has
344 * had files recycled, then this function will seek to the next file that
345 * does exist. You can check which file this function selected by
346 * examining the file field of the Device structure. If the requested
347 * file number is *exactly* one more than the last valid file, this
348 * function returns a TAPEEND header.
350 * If an error occurs or if the requested file is two or more beyond the
351 * last valid file, this function returns NULL.
353 * Example results for a volume that has only files 1 and 3:
354 * 1 -> Seeks to file 1
355 * 2 -> Seeks to file 3
356 * 3 -> Seeks to file 3
357 * 4 -> Returns TAPEEND
360 * The returned dumpfile_t is yours to keep, at no extra charge. */
361 dumpfile_t* device_seek_file (Device * self,
364 /* After you have called device_seek_file (and /only/ after having
365 * called device_seek_file), you can call this to seek to a particular
366 * block inside the file. It works like SEEK_SET, only in blocks. */
367 gboolean device_seek_block (Device * self,
370 /* After you have called device_seek_file and/or device_seek_block,
371 * you can start calling this function. It always reads exactly one whole
372 * block at a time, however big that might be. You must pass in a buffer and
373 * specify its size. If the buffer is big enough, the read is
374 * performed, and both *size and the return value are equal to the
375 * number of bytes actually read. If the buffer is not big enough, then
376 * no read is performed, the function returns 0, and *size is set
377 * to the minimum buffer size required to read the next block. If an
378 * error occurs, the function returns -1 and *size is left unchanged.
380 * Note that this function may request a block size bigger than
381 * dev->block_size, if it discovers an oversized block. This allows Amanda to
382 * read from volumes regardless of the block size used to write them. It is not
383 * an error if buffer == NULL and *size == 0. This should be treated as a query
384 * as to the possible size of the next block, although it is not an error for
385 * the next read to request an even larger block size. */
386 int device_read_block (Device * self, gpointer buffer, int * size);
388 /* This is the reading equivalent of device_write_from_fd(). It will
389 * read from the device from the current location until end of file,
390 * and drains the results out into the specified fd. Returns FALSE if
391 * there is a problem writing to the fd. */
392 gboolean device_read_to_fd (Device * self,
393 queue_fd_t *queue_fd);
395 /* This function tells you what properties are supported by this device, and
396 * when you are allowed to get and set them. The return value is an list of
397 * DeviceProperty structs. Do not free the resulting list. */
398 const GSList * device_property_get_list (Device * self);
400 /* These functions get or set a particular property. The val should be
401 * compatible with the DevicePropertyBase associated with the given
402 * DevicePropertyId, and these functions should only be called when
403 * DeviceProperty.access says it is OK. Otherwise you will get an error and not
404 * the tasty property action you wanted.
406 * All device_property_get_ex parameters but the first two are output
407 * parameters, and can be left NULL if you are not interested in their value.
408 * If you only need the value, use the simpler device_property_get macro. */
410 gboolean device_property_get_ex (Device * self,
413 PropertySurety *surety,
414 PropertySource *source);
415 #define device_property_get(self, id, val) \
416 device_property_get_ex((self), (id), (val), NULL, NULL)
418 gboolean device_property_set_ex (Device * self,
421 PropertySurety surety,
422 PropertySource source);
423 #define device_property_set(self, id, val) \
424 device_property_set_ex((self), (id), (val), \
425 PROPERTY_SURETY_GOOD, PROPERTY_SOURCE_USER)
427 /* On devices that support it (check PROPERTY_PARTIAL_DELETION),
428 * this will free only the space associated with a particular file.
429 * This way, you can apply a different retention policy to every file
430 * on the volume, appending new data at the end and recycling anywhere
431 * in the middle -- even simultaneously (via different Device
432 * handles)! Note that you generally can't recycle a file that is presently in
433 * use (being read or written).
435 * To use this, open the device as DEVICE_MODE_APPEND. But you don't
436 * have to call device_start_file(), unless you want to write some
438 gboolean device_recycle_file (Device * self,
441 /* Protected methods. Don't call these except in subclass implementations. */
443 /* This method provides post-construction initalization once the
444 * device name is known. It should only be used by Device
445 * factories. It is provided here as a virtual method (instead of
446 * a static function) because some devices may want to chain
447 * initilization to their parents. */
448 void device_open_device (Device * self, char *device_name, char *device_type, char *device_node);
450 /* Builds a proper header based on device block size possibilities.
451 * If non-null, size is filled in with the number of bytes that should
453 * If non-null, oneblock is filled in with TRUE if the header will fit
454 * in a single Device block (FALSE otherwise). */
455 char * device_build_amanda_header(Device * self, const dumpfile_t * jobinfo,
456 int * size, gboolean * oneblock);
458 /* Does what you expect. You have to free the returned header. Ensures
459 that self->volume_time matches the header written to tape. */
460 dumpfile_t * make_tapestart_header(Device * self, char * label,
463 /* Does what you expect. Uses the current time. */
464 dumpfile_t * make_tapeend_header(void);
466 /* Erase any stored volume information. Use this if something happens (e.g.,
467 * a property is set) that voids previously-read volume details.
468 * This function is a NOOP unless the device is in the NULL state. */
469 void device_clear_volume_details(Device * device);
471 /* Property Handling */
473 /* Registers a property for a new device class; device drivers' GClassInitFunc
474 * should call this function for each device-specific property of the class.
475 * If either getter or setter is NULL, then the corresponding operation will
478 * Note that this will replace any existing registration (e.g., from a parent
481 void device_class_register_property(DeviceClass *klass, DevicePropertyId id,
482 PropertyAccessFlags access,
483 PropertyGetFn getter,
484 PropertySetFn setter);
486 /* Set a 'simple' property on the device. This tucks the value away in the
487 * object, to be retrieved by device_simple_property_get_fn. This is most
488 * often used in GInstanceInit functions, but can be used at any time to set or
489 * change the value of a simple property */
490 gboolean device_set_simple_property(Device *self, DevicePropertyId id,
491 GValue *val, PropertySurety surety,
492 PropertySource source);
494 /* Get a simple property set with device_set_simple_property. This is a little
495 * bit quicker than calling device_property_get_ex(), and does not affect the
496 * device's error state. Returns FALSE if the property has not been set.
497 * Surety and source are output parameters and will be ignored if they are
499 gboolean device_get_simple_property(Device *self, DevicePropertyId id,
500 GValue *val, PropertySurety *surety,
501 PropertySource *source);
503 /* A useful PropertySetFn. If your subclass also needs to intercept sets, for
504 * example to flush a cache or update a member variable, then write a stub
505 * function which "calls up" to this function. */
506 gboolean device_simple_property_set_fn(Device *self, DevicePropertyBase *base,
507 GValue *val, PropertySurety surety,
508 PropertySource source);
510 /* A useful PropertyGetFn -- returns the value, source, and surety set with
511 * device_set_simple_property */
512 gboolean device_simple_property_get_fn(Device *self, DevicePropertyBase *base,
513 GValue *val, PropertySurety *surety,
514 PropertySource *source);
516 #endif /* DEVICE_H */