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