2 * Copyright (c) 2005 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., 505 N Mathlida Ave, Suite 120
18 * Sunnyvale, CA 94085, 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 #define TYPE_DEVICE (device_get_type())
56 #define DEVICE(obj) G_TYPE_CHECK_INSTANCE_CAST((obj), device_get_type(), Device)
57 #define DEVICE_CONST(obj) G_TYPE_CHECK_INSTANCE_CAST((obj), device_get_type(), Device const)
58 #define DEVICE_CLASS(klass) G_TYPE_CHECK_CLASS_CAST((klass), device_get_type(), DeviceClass)
59 #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;
66 * Main object structure
71 /* You can peek at the stuff below, but only subclasses should
72 change these values.*/
74 /* What file, block are we at? (and are we in the middle of a
75 * file?) This is automatically updated by
76 * the default implementations of start_file, finish_file,
77 * write_block, read_block, seek_file, and seek_block. */
81 /* Holds the user-specified device name. */
83 /* Holds the user-specified access-mode. */
84 DeviceAccessMode access_mode;
85 /* In reading mode, FALSE unless all the data from the current file
86 * was successfully read. */
88 /* Holds the label and time of the currently-inserted volume,
89 * or NULL if it has not been read/written yet. */
93 DevicePrivate * private;
96 /* Pointer to factory function for device types. The factory functions
97 take control of their arguments, which should be dynamically
98 allocated. The factory should call open_device() with this
100 typedef Device* (*DeviceFactory)(char * device_type,
103 /* This function registers a new device with the allocation system.
104 * Call it after you register your type with the GLib type system.
105 * This function takes ownership of the strings inside device_prefix_list,
106 * but not the device_prefix_list itself. */
107 extern void register_device(DeviceFactory factory,
108 const char ** device_prefix_list);
110 /* This structure is a Flags (bitwise OR of values). Zero indicates success;
111 * any other value indicates some kind of problem reading the label. If
112 * multiple bits are set, it does not necessarily indicate that /all/ of
113 * the specified issues occured, but rather that /at least one/ did. */
115 /* When changing, Also update read_label_status_flags_values in device.c */
116 READ_LABEL_STATUS_SUCCESS = 0,
117 READ_LABEL_STATUS_DEVICE_MISSING = (1 << 0),
118 READ_LABEL_STATUS_DEVICE_ERROR = (1 << 1),
119 READ_LABEL_STATUS_VOLUME_MISSING = (1 << 2),
120 READ_LABEL_STATUS_VOLUME_UNLABELED = (1 << 3),
121 READ_LABEL_STATUS_VOLUME_ERROR = (1 << 4),
122 READ_LABEL_STATUS_FLAGS_MAX = (1 << 5)
123 } ReadLabelStatusFlags;
125 #define READ_LABEL_STATUS_FLAGS_MASK (READ_LABEL_STATUS_MAX-1)
126 #define READ_LABEL_STATUS_FLAGS_TYPE (read_label_status_flags_get_type())
127 GType read_label_status_flags_get_type(void);
132 typedef struct _DeviceClass DeviceClass;
133 struct _DeviceClass {
134 GObjectClass __parent__;
135 gboolean (* open_device) (Device * self,
136 char * device_name); /* protected */
137 ReadLabelStatusFlags (* read_label)(Device * self);
138 gboolean (* start) (Device * self, DeviceAccessMode mode,
139 char * label, char * timestamp);
140 gboolean (* start_file) (Device * self, const dumpfile_t * info);
141 gboolean (* write_block) (Device * self, guint size, gpointer data,
142 gboolean last_block);
143 gboolean (* write_from_fd) (Device * self, int fd);
144 gboolean (* finish_file) (Device * self);
145 dumpfile_t* (* seek_file) (Device * self, guint file);
146 gboolean (* seek_block) (Device * self, guint64 block);
147 gboolean (* read_block) (Device * self, gpointer buf, int * size);
148 gboolean (* read_to_fd) (Device * self, int fd);
149 gboolean (* property_get) (Device * self, DevicePropertyId id,
151 gboolean (* property_set) (Device * self, DevicePropertyId id,
153 gboolean (* recycle_file) (Device * self, guint filenum);
154 gboolean (* finish) (Device * self);
161 * Note to implementors: The default implementation of many of these
162 * methods does not follow the documentation. For example, the default
163 * implementation of device_read_block will always return -1, but
164 * nonetheless update the block index in the Device structure. In
165 * general, it is OK to chain up to the default implmentation after
166 * successfully implementing whatever appears below. The particulars
167 * of what the default implementations do is documented in device.c.
169 GType device_get_type (void);
171 /* This is how you get a new Device. Pass in a device name like
172 * file:/path/to/storage, and (assuming everything goes OK) you will get
173 * back a nice happy Device* that you can do operations on. Note that you
174 * must device_start() it before you can do anything besides talk about
175 * properties or read the label. device_name remains the responsibility
177 Device* device_open (char * device_name);
179 /* This instructs the device to read the label on the current
180 * volume. device->volume_label will not be initalized until after this
181 * is called. You are encouraged to read the label only after setting any
182 * properties that may affect the label-reading process. */
183 ReadLabelStatusFlags device_read_label (Device * self);
185 /* This tells the Device that it's OK to start reading and writing
186 * data. Before you call this, you can only call
187 * device_property_{get, set} and device_read_label. You can only call
188 * this a second time if you call device_finish() first.
190 * You should pass a label and timestamp if and only if you are
191 * opening in WRITE mode (not READ or APPEND). The label and timestamp
192 * remain the caller's responsibility in terms of memory management. The
193 * passed timestamp may be NULL, in which case it will be filled in with
194 * the current time. */
195 gboolean device_start (Device * self,
196 DeviceAccessMode mode, char * label,
199 /* This undoes device_start, returning you to the NULL state. Do this
200 * if you want to (for example) change access mode.
202 * Note to subclass implementors: Call this function first from your
203 * finalization function. */
204 gboolean device_finish (Device * self);
206 /* But you can't write any data until you call this function, too.
207 * This function does not take ownership of the passed dumpfile_t; you must
208 * free it yourself. */
209 gboolean device_start_file (Device * self,
210 const dumpfile_t * jobInfo);
212 guint device_write_min_size (Device * self);
213 guint device_write_max_size (Device * self);
214 guint device_read_max_size (Device * self);
216 /* Does what you expect. size had better be inside the block size
217 * range, or this function will write nothing.
219 * The short_block parameter needs some additional explanation: If
220 * short_block is set to TRUE, then this function will accept a write
221 * smaller than the minimum block size, subject to the following
223 * % The block may be padded with NULL bytes, which will be present on
225 * % device_write_block will automatically call device_finish_file()
226 * after writing this short block.
227 * It is permitted to use short_block with a block that is not short;
228 * in this case, it is equivalent to calling device_write() and then
229 * calling device_finish_file(). */
230 gboolean device_write_block (Device * self,
233 gboolean short_block);
235 /* This will drain the given fd (reading until EOF), and write the
236 * resulting data out to the device using maximally-sized blocks. */
237 gboolean device_write_from_fd (Device * self,
240 /* Call this when you are finished writing a file. This function will
241 * write a filemark or the local equivalent, flush the buffers, and do
242 * whatever dirty work needs to be done at such a point in time. */
243 gboolean device_finish_file (Device * self);
245 /* For reading only: Seeks to the beginning of a particular
246 * filemark. Only do this when reading; opening in
247 * ACCESS_WRITE will start you out at the first file, and opening in
248 * ACCESS_APPEND will automatically seek to the end of the medium.
250 * If the requested file doesn't exist, this function will seek to the
251 * next-numbered valid file. You can check where this function seeked to
252 * by examining the file field of the Device structure. If the requested
253 * file number is exactly one more than the last valid file, this
254 * function returns a TAPEEND header.
256 * If an error occurs or if the requested file is two or more beyond the
257 * last valid file, this function returns NULL.
259 * Example results for a volume that has only files 1 and 3:
260 * 1 -> Seeks to file 1
261 * 2 -> Seeks to file 3
262 * 3 -> Seeks to file 3
263 * 4 -> Returns TAPEEND
266 * The returned dumpfile_t is yours to keep, at no extra charge. */
267 dumpfile_t* device_seek_file (Device * self,
270 /* After you have called device_seek_file (and /only/ after having
271 * called device_seek_file), you can call this to seek to a particular
272 * block inside the file. It works like SEEK_SET, only in blocks. */
273 gboolean device_seek_block (Device * self,
276 /* After you have called device_seek_file and/or device_seek_block,
277 * you can start calling this function. It always reads exactly one whole
278 * block at a time, however big that might be. You must pass in a buffer and
279 * specify its size. If the buffer is big enough, the read is
280 * performed, and both *size and the return value are equal to the
281 * number of bytes actually read. If the buffer is not big enough, then
282 * no read is performed, the function returns 0, and *size is set
283 * to the minimum buffer size required to read the next block. If an
284 * error occurs, the function returns -1 and *size is left unchanged.
286 * It is not an error if buffer == NULL and *size == 0. This should be
287 * treated as a query as to the possible size of the next block. */
288 int device_read_block (Device * self,
292 /* This is the reading equivalent of device_write_from_fd(). It will
293 * read from the device from the current location until end of file,
294 * and drains the results out into the specified fd. Returns FALSE if
295 * there is a problem writing to the fd. */
296 gboolean device_read_to_fd (Device * self,
299 /* This function tells you what properties are supported by this
300 * device, and when you are allowed to get and set them. The return
301 * value is an array of DeviceProperty structs. The last struct in
302 * the array is zeroed, so you know when the end is (check the
303 * pointer element "base"). The return value from this function on any
304 * given object (or physical device) should be invariant. */
305 const DeviceProperty * device_property_get_list (Device * self);
307 /* These functions get or set a particular property. The val should be
308 * compatible with the DevicePropertyBase associated with the given
309 * DevicePropertyId, and this function should only be called when
310 * DeviceProperty.access says it is OK. Otherwise you will get an
311 * error and not the tasty property action you wanted. */
312 gboolean device_property_get (Device * self,
315 gboolean device_property_set (Device * self,
319 /* On devices that support it (check PROPERTY_PARTIAL_DELETION),
320 * this will free only the space associated with a particular file.
321 * This way, you can apply a different retention policy to every file
322 * on the volume, appending new data at the end and recycling anywhere
323 * in the middle -- even simultaneously (via different Device
324 * handles)! Note that you generally can't recycle a file that is presently in
325 * use (being read or written).
327 * To use this, open the device as DEVICE_MODE_APPEND. But you don't
328 * have to call device_start_file(), unless you want to write some
330 gboolean device_recycle_file (Device * self,
333 /* Protected methods. Don't call these except in subclass implementations. */
335 /* Registers a new device / property pair. Every superclass of Device
336 * should call this in its init() function. At the moment, any
337 * particular property Id can only be registered once per object.
339 * If you want to register a standard response to a property (e.g.,
340 * whether or not the device supports compression), you can pass a
341 * non-NULL response. Then the default implementation of
342 * device_get_property (which you may override) will return this
344 * The contents of prop and response are copied into a private array, so the
345 * calling function retains ownership of all arguments.
347 void device_add_property(Device * self, DeviceProperty * prop,
350 /* This method provides post-construction initalization once the
351 * device name is known. It should only be used by Device
352 * factories. It is provided here as a virtual method (instead of
353 * a static function) because some devices may want to chain
354 * initilization to their parents. */
355 gboolean device_open_device (Device * self,
358 /* Builds a proper header based on device block size possibilities.
359 * If non-null, size is filled in with the number of bytes that should
361 * If non-null, oneblock is filled in with TRUE if the header will fit
362 * in a single Device block (FALSE otherwise). */
363 char * device_build_amanda_header(Device * self, const dumpfile_t * jobinfo,
364 int * size, gboolean * oneblock);
366 /* Does what you expect. You have to free the returned header. Ensures
367 that self->volume_time matches the header written to tape. */
368 dumpfile_t * make_tapestart_header(Device * self, char * label,
371 /* Does what you expect. Uses the current time. */
372 dumpfile_t * make_tapeend_header(void);
374 /* Set up first-run properties from loaded configuration file, including
375 * DEVICE_MAX_VOLUME_USAGE property based on the tapetype. */
376 void device_set_startup_properties_from_config(Device * device);
378 /* Erase any stored volume information. Use this if something happens (e.g.,
379 * a property is set) that voids previously-read volume details.
380 * This function is a NOOP unless the device is in the NULL state. */
381 void device_clear_volume_details(Device * device);
383 #endif /* DEVICE_H */