Imported Upstream version 3.3.3
[debian/amanda] / device-src / device.h
1 /*
2  * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17  *
18  * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
19  * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
20  */
21
22 /* The Device API abstracts device workings, interaction, properties, and
23  * capabilities from the rest of the Amanda code base. It supports
24  * pluggable modules for different kinds of devices. */
25
26 #ifndef DEVICE_H
27 #define DEVICE_H
28
29 #include <glib.h>
30 #include <glib-object.h>
31
32 #include "property.h"
33 #include "fileheader.h"
34 #include "directtcp.h"
35 #include "directtcp-connection.h"
36
37 /* Device API version. */
38 #define DEVICE_API_VERSION 0
39
40 extern void device_api_init(void);
41
42 /* Different access modes */
43 typedef enum {
44     ACCESS_NULL, /* Device is not yet opened. */
45     ACCESS_READ,
46     ACCESS_WRITE,
47     ACCESS_APPEND
48 } DeviceAccessMode;
49
50 #define IS_WRITABLE_ACCESS_MODE(mode) ((mode) == ACCESS_WRITE || \
51                                        (mode) == ACCESS_APPEND)
52
53 /* Device object definition follows. */
54
55 /*
56  * Type checking and casting macros
57  */
58 GType   device_get_type (void);
59 #define TYPE_DEVICE     (device_get_type())
60 #define DEVICE(obj)     G_TYPE_CHECK_INSTANCE_CAST((obj), device_get_type(), Device)
61 #define DEVICE_CONST(obj)       G_TYPE_CHECK_INSTANCE_CAST((obj), device_get_type(), Device const)
62 #define DEVICE_CLASS(klass)     G_TYPE_CHECK_CLASS_CAST((klass), device_get_type(), DeviceClass)
63 #define IS_DEVICE(obj)  G_TYPE_CHECK_INSTANCE_TYPE((obj), device_get_type ())
64 #define DEVICE_GET_CLASS(obj)   G_TYPE_INSTANCE_GET_CLASS((obj), device_get_type(), DeviceClass)
65
66 typedef struct DevicePrivate_s DevicePrivate;
67
68 /* See Amanda::Device POD for a description of these constants */
69 typedef enum {
70     DEVICE_STATUS_SUCCESS          = 0,
71     DEVICE_STATUS_DEVICE_ERROR     = (1 << 0),
72     DEVICE_STATUS_DEVICE_BUSY      = (1 << 1),
73     DEVICE_STATUS_VOLUME_MISSING   = (1 << 2),
74     DEVICE_STATUS_VOLUME_UNLABELED = (1 << 3),
75     DEVICE_STATUS_VOLUME_ERROR     = (1 << 4),
76     DEVICE_STATUS_FLAGS_MAX        = (1 << 5)
77 } DeviceStatusFlags;
78
79 #define DEVICE_STATUS_FLAGS_MASK (DEVICE_STATUS_MAX-1)
80 #define DEVICE_STATUS_FLAGS_TYPE (device_status_flags_get_type())
81 GType device_status_flags_get_type(void);
82
83 /* a callback to prolong an operation */
84 typedef gboolean (* ProlongProc)(gpointer data);
85
86 /*
87  * Main object structure
88  */
89 typedef struct Device {
90     GObject __parent__;
91
92     /* You can peek at the stuff below, but only subclasses should
93        change these values.*/
94
95     /* A mutex to protect field accessed from another thread.
96      * Only get_bytes_read and get_bytes_written are allowed from another
97      * Only in_file, bytes_read and bytes_written are protected */
98     GMutex  *device_mutex;
99
100     /* What file, block are we at? (and are we in the middle of a file?) */
101     int file;
102     guint64 block;
103     gboolean in_file;
104
105     /* Holds the user-specified device name, which may be an alias */
106     char * device_name;
107
108     /* Holds the user-specified access-mode, or ACCESS_NULL if the device
109      * has not yet been started*/
110     DeviceAccessMode access_mode;
111
112     /* In reading mode, FALSE unless all the data from the current file
113      * was successfully read.  In writing mode, TRUE if the last byte
114      * of a file has been written by write_from_connection. */
115     gboolean is_eof;
116
117     /* In writing mode, indicates that the volume is at (or near, if possible)
118      * EOM. */
119     gboolean is_eom;
120
121     /* Holds the label and time of the currently-inserted volume,
122      * or NULL if it has not been read/written yet. */
123     char * volume_label;
124     char * volume_time;
125
126     /* The most recently read volume header, or NULL if no header was
127      * read from this device.  Callers can use this to glean information
128      * about the volume beyond volume_label and volume_time.  */
129     dumpfile_t *volume_header;
130
131     /* The latest status for the device */
132     DeviceStatusFlags status;
133
134     /* device block-size ranges.  These are also available as properties,
135      * and by default users can set block_size via property BLOCK_SIZE.
136      * Writers should use block_size, and readers should initially use
137      * block_size, and expand buffers as directed by read_block. */
138     gsize min_block_size;
139     gsize max_block_size;
140     gsize block_size;
141     gsize header_block_size;
142
143     guint64 bytes_read;
144     guint64 bytes_written;
145
146     /* surety and source for the block size; if you set block_size directly,
147      * set these, too! */
148     PropertySurety block_size_surety;
149     PropertySource block_size_source;
150
151     DevicePrivate * private;
152 } Device;
153
154 /* Pointer to factory function for device types.
155  *
156  * device_name is the full name ("tape:/dev/nst0")
157  * device_prefix is the prefix ("tape")
158  * device_node is what follows the prefix ("/dev/nst0")
159  *
160  * The caller retains responsibility to free or otherwise handle
161  * the passed strings.
162  */
163 typedef Device* (*DeviceFactory)(char *device_name,
164                                  char * device_prefix,
165                                  char * device_node);
166
167 /* This function registers a new device with the allocation system.
168  * Call it after you register your type with the GLib type system.
169  * This function assumes that the strings in device_prefix_list are
170  * statically allocated. */
171 extern void register_device(DeviceFactory factory,
172                             const char ** device_prefix_list);
173
174 /*
175  * Class definition
176  */
177 typedef struct _DeviceClass DeviceClass;
178 struct _DeviceClass {
179     GObjectClass __parent__;
180     void (* open_device) (Device * self, char * device_name,
181                     char * device_prefix, char * device_node);
182     gboolean (* configure) (Device * self, gboolean use_global_config);
183     DeviceStatusFlags (* read_label)(Device * self);
184     gboolean (* start) (Device * self, DeviceAccessMode mode,
185                         char * label, char * timestamp);
186     gboolean (* start_file) (Device * self, dumpfile_t * info);
187     gboolean (* write_block) (Device * self, guint size, gpointer data);
188     gboolean (* finish_file) (Device * self);
189     dumpfile_t* (* seek_file) (Device * self, guint file);
190     gboolean (* seek_block) (Device * self, guint64 block);
191     int (* read_block) (Device * self, gpointer buf, int * size);
192     gboolean (* property_get_ex) (Device * self, DevicePropertyId id,
193                                   GValue * val,
194                                   PropertySurety *surety,
195                                   PropertySource *source);
196     gboolean (* property_set_ex) (Device * self,
197                                   DevicePropertyId id,
198                                   GValue * val,
199                                   PropertySurety surety,
200                                   PropertySource source);
201     gboolean (* recycle_file) (Device * self, guint filenum);
202     gboolean (* erase) (Device * self);
203     gboolean (* eject) (Device * self);
204     gboolean (* finish) (Device * self);
205     guint64  (* get_bytes_read) (Device * self);
206     guint64  (* get_bytes_written) (Device * self);
207
208     gboolean (* listen)(Device *self, gboolean for_writing, DirectTCPAddr **addrs);
209     /* The MainLoop must be running, but the following 4 methods must not be
210      * called from an event. they must be called from a different thread.
211      * They return:
212      *   0 - success
213      *   1 - failed
214      *   2 - interupted
215      */
216     int (* accept)(Device *self, DirectTCPConnection **conn,
217                         int *cancelled, GMutex *abort_mutex, GCond *abort_cond);
218     int (* connect)(Device *self, gboolean for_writing,
219                         DirectTCPAddr *addrs, DirectTCPConnection **conn,
220                         int *cancelled,
221                         GMutex *abort_mutex, GCond *abort_cond);
222     int (* write_from_connection)(Device *self, guint64 size,
223                         guint64 *actual_size, int *cancelled,
224                         GMutex *abort_mutex, GCond *abort_cond);
225     int (* read_to_connection)(Device *self, guint64 size,
226                         guint64 *actual_size, int *cancelled,
227                         GMutex *abort_mutex, GCond *abort_cond);
228
229     gboolean (* use_connection)(Device *self, DirectTCPConnection *conn);
230
231     /* array of DeviceProperty objects for this class, keyed by ID */
232     GArray *class_properties;
233
234     /* The return value of device_property_get_list */
235     GSList * class_properties_list;
236
237     /* TRUE if the directtcp methods are implemented by this device class */
238     gboolean directtcp_supported;
239 };
240
241 /*
242  * Device Instantiation
243  */
244
245 /* Return the unaliased device name of a device.
246  * The returned string must not be freed by the caller.
247  */
248 char*           device_unaliased_name(char * device_name);
249
250 /* This is how you get a new Device. Pass in a device name or alias.
251  *
252  * A Device is *always* returned, even for an invalid device name. You
253  * must check the resulting device->status to know if the device is valid
254  * to be used. If device->status is not DEVICE_STATUS_SUCCESS, then there
255  * was an error opening the device.
256  *
257  * Note that the Amanda configuration must be initialized, as this function
258  * looks for device definitions and other configuration information.
259  */
260 Device*         device_open     (char * device_name);
261
262 /* As a special case, a RAIT device can be created from a collection of child
263  * devices.  This is used by the RAIT changer, for example.  This function is
264  * implemented in rait-device.c.  */
265 Device*         rait_device_open_from_children(GSList *child_devices);
266
267 /* Once you have a new device, you should configure it.  This sets properties
268  * on the device based on the user's configuation.  If USE_GLOBAL_CONFIG is
269  * true, then any global device_property parameters are processed, along with
270  * tapetype and othe relevant parameters.
271  */
272 gboolean device_configure(Device *self, gboolean use_global_config);
273
274 /*
275  * Error Handling
276  */
277
278 /* return the error message or the string "Unknown Device error".  The
279  * string remains the responsibility of the Device, and should not
280  * be freed by the caller. */
281 char *device_error(Device * self);
282
283 /* return a string version of the status.  The string remains the
284  * responsibility of the Device, and should not be freed by the
285  * caller. */
286 char *device_status_error(Device * self);
287
288 /* Return errmsg if it is set or a string version of the status.  The
289  * string remains the responsibility of the Device, and should not
290  * be freed by the caller. */
291 char *device_error_or_status(Device * self);
292
293 /* Set the error message for this device; for use internally to the
294  * API.  The string becomes the responsibility of the Device.  If
295  * ERRMSG is NULL, the message is cleared.  Note that the given flags
296  * are OR'd with any existing status flags. */
297 void device_set_error(Device * self, char *errmsg, DeviceStatusFlags new_flags);
298
299 /* Mostly for internal use, this is a boolean check to see whether a given
300  * device is in an error state.  If this is TRUE, most operations on the
301  * device will fail.
302  *
303  * The check is for DEVICE_STATUS_DEVICE_ERROR *alone*; if any other bits
304  * (e.g., VOLUME_UNLABELED) are set, then the device may not actually be in
305  * an error state.
306  */
307 #define device_in_error(dev) \
308     ((DEVICE(dev))->status == DEVICE_STATUS_DEVICE_ERROR)
309
310 /*
311  * Public methods
312  *
313  * See the Amanda::Device POD for more information here
314  */
315
316 DeviceStatusFlags        device_read_label (Device * self);
317 gboolean        device_start    (Device * self,
318                                  DeviceAccessMode mode, char * label,
319                                  char * timestamp);
320 gboolean        device_finish   (Device * self);
321 guint64         device_get_bytes_read   (Device * self);
322 guint64         device_get_bytes_written(Device * self);
323 gboolean        device_start_file       (Device * self,
324                                          dumpfile_t * jobInfo);
325 gboolean        device_write_block      (Device * self,
326                                          guint size,
327                                          gpointer data);
328 gboolean        device_finish_file      (Device * self);
329 dumpfile_t*     device_seek_file        (Device * self,
330                                         guint file);
331 gboolean        device_seek_block       (Device * self,
332                                         guint64 block);
333 int     device_read_block       (Device * self, gpointer buffer, int * size);
334 const GSList *  device_property_get_list        (Device * self);
335 gboolean        device_property_get_ex  (Device * self,
336                                          DevicePropertyId id,
337                                          GValue * val,
338                                          PropertySurety *surety,
339                                          PropertySource *source);
340 #define         device_property_get(self, id, val) \
341     device_property_get_ex((self), (id), (val), NULL, NULL)
342 gboolean        device_property_set_ex  (Device * self,
343                                          DevicePropertyId id,
344                                          GValue * val,
345                                          PropertySurety surety,
346                                          PropertySource source);
347 #define         device_property_set(self, id, val) \
348     device_property_set_ex((self), (id), (val), \
349             PROPERTY_SURETY_GOOD, PROPERTY_SOURCE_USER)
350 gboolean        device_recycle_file     (Device * self,
351                                         guint filenum);
352
353 gboolean        device_erase    (Device * self);
354 gboolean        device_eject    (Device * self);
355
356 #define device_directtcp_supported(self) (DEVICE_GET_CLASS((self))->directtcp_supported)
357 gboolean device_listen(Device *self, gboolean for_writing, DirectTCPAddr **addrs);
358 int device_accept(Device *self, DirectTCPConnection **conn,
359                         int *cancelled, GMutex *abort_mutex, GCond *abort_cond);
360 int device_connect(Device *self, gboolean for_writing,
361                         DirectTCPAddr *addrs, DirectTCPConnection **conn,
362                         int *cancelled,
363                         GMutex *abort_mutex, GCond *abort_cond);
364 int device_write_from_connection(Device *self, guint64 size,
365                         guint64 *actual_size, int *cancelled,
366                         GMutex *abort_mutex, GCond *abort_cond);
367 int device_read_to_connection(Device *self, guint64 size,
368                         guint64 *actual_size, int *cancelled,
369                         GMutex *abort_mutex, GCond *abort_cond);
370 gboolean device_use_connection(Device *self, DirectTCPConnection *conn);
371
372 /* Protected methods. Don't call these except in subclass implementations. */
373
374 /* This method provides post-construction initalization once the
375  * device name is known. It should only be used by Device
376  * factories. It is provided here as a virtual method (instead of
377  * a static function) because some devices may want to chain
378  * initilization to their parents. */
379 void device_open_device (Device * self, char *device_name, char *device_type, char *device_node);
380
381 /* Builds a proper header of between *size and self->block_size bytes.
382  * Returns NULL if the header does not fit in a single block.  The result
383  * must be free'd.  If size is NULL, the block size is used.
384  *
385  * If size is not NULL, *size is set to the actual size of the generated header.
386  */
387 char * device_build_amanda_header(Device * self, const dumpfile_t * jobinfo,
388                                   size_t *size);
389
390 /* Does what you expect. You have to free the returned header. Ensures
391    that self->volume_time matches the header written to tape. */
392 dumpfile_t * make_tapestart_header(Device * self, char * label,
393                                    char * timestamp);
394
395 /* Does what you expect. Uses the current time. */
396 dumpfile_t * make_tapeend_header(void);
397
398 /* Erase any stored volume information. Use this if something happens (e.g.,
399  * a property is set) that voids previously-read volume details.
400  * This function is a NOOP unless the device is in the NULL state. */
401 void device_clear_volume_details(Device * device);
402
403 /* Property Handling */
404
405 /* Registers a property for a new device class; device drivers' GClassInitFunc
406  * should call this function for each device-specific property of the class.
407  * If either getter or setter is NULL, then the corresponding operation will
408  * return FALSE.
409  *
410  * Note that this will replace any existing registration (e.g., from a parent
411  * class).
412  */
413 void device_class_register_property(DeviceClass *klass, DevicePropertyId id,
414                                     PropertyAccessFlags access,
415                                     PropertyGetFn getter,
416                                     PropertySetFn setter);
417
418 /* Set a 'simple' property on the device.  This tucks the value away in the
419  * object, to be retrieved by device_simple_property_get_fn.  This is most
420  * often used in GInstanceInit functions, but can be used at any time to set or
421  * change the value of a simple property */
422 gboolean device_set_simple_property(Device *self, DevicePropertyId id,
423                                 GValue *val, PropertySurety surety,
424                                 PropertySource source);
425
426 /* Get a simple property set with device_set_simple_property.  This is a little
427  * bit quicker than calling device_property_get_ex(), and does not affect the
428  * device's error state.  Returns FALSE if the property has not been set.
429  * Surety and source are output parameters and will be ignored if they are
430  * NULL. */
431 gboolean device_get_simple_property(Device *self, DevicePropertyId id,
432                                     GValue *val, PropertySurety *surety,
433                                     PropertySource *source);
434
435 /* A useful PropertySetFn.  If your subclass also needs to intercept sets, for
436  * example to flush a cache or update a member variable, then write a stub
437  * function which "calls up" to this function. */
438 gboolean device_simple_property_set_fn(Device *self, DevicePropertyBase *base,
439                                        GValue *val, PropertySurety surety,
440                                        PropertySource source);
441
442 /* A useful PropertyGetFn -- returns the value, source, and surety set with
443  * device_set_simple_property */
444 gboolean device_simple_property_get_fn(Device *self, DevicePropertyBase *base,
445                                        GValue *val, PropertySurety *surety,
446                                        PropertySource *source);
447
448 #endif /* DEVICE_H */