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
24 #include "glib-util.h"
27 * Property-specific Types, etc.
30 static const GEnumValue _concurrency_paradigm_values[] = {
31 { CONCURRENCY_PARADIGM_EXCLUSIVE,
32 "CONCURRENCY_PARADIGM_EXCLUSIVE",
34 { CONCURRENCY_PARADIGM_SHARED_READ,
35 "CONCURRENCY_PARADIGM_SHARED_READ",
37 { CONCURRENCY_PARADIGM_RANDOM_ACCESS,
38 "CONCURRENCY_PARADIGM_RANDOM_ACCESS",
43 GType concurrency_paradigm_get_type (void) {
44 static GType type = 0;
45 if (G_UNLIKELY(type == 0)) {
46 type = g_enum_register_static ("ConcurrencyParadigm",
47 _concurrency_paradigm_values);
52 static const GEnumValue _streaming_requirement_values[] = {
53 { STREAMING_REQUIREMENT_NONE,
54 "STREAMING_REQUIREMENT_NONE",
56 { STREAMING_REQUIREMENT_DESIRED,
57 "STREAMING_REQUIREMENT_DESIRED",
59 { STREAMING_REQUIREMENT_REQUIRED,
60 "STREAMING_REQUIREMENT_REQUIRED",
65 GType streaming_requirement_get_type (void) {
66 static GType type = 0;
67 if (G_UNLIKELY(type == 0)) {
68 type = g_enum_register_static ("StreamingRequirement",
69 _streaming_requirement_values);
74 static const GEnumValue _media_access_mode_values[] = {
75 { MEDIA_ACCESS_MODE_READ_ONLY,
76 "MEDIA_ACCESS_MODE_READ_ONLY",
77 (char *)"read-only" },
78 { MEDIA_ACCESS_MODE_WORM,
79 "MEDIA_ACCESS_MODE_WORM",
80 (char *)"write-once-read-many" },
81 { MEDIA_ACCESS_MODE_READ_WRITE,
82 "MEDIA_ACCESS_MODE_READ_WRITE",
83 (char *)"read-write" },
84 { MEDIA_ACCESS_MODE_WRITE_ONLY,
85 "MEDIA_ACCESS_MODE_WRITE_ONLY",
86 (char *)"write-many-read-never" },
90 GType media_access_mode_get_type (void) {
91 static GType type = 0;
92 if (G_UNLIKELY(type == 0)) {
93 type = g_enum_register_static ("MediaAccessMode",
94 _media_access_mode_values);
99 /* Copy function for GBoxed QualifiedSize. */
100 static gpointer qualified_size_copy(gpointer source) {
101 gpointer rval = g_new(QualifiedSize, 1);
102 memcpy(rval, source, sizeof(QualifiedSize));
106 GType qualified_size_get_type (void) {
107 static GType type = 0;
108 if (G_UNLIKELY(type == 0)) {
109 type = g_boxed_type_register_static ("QualifiedSize",
117 * Property registration and lookup
120 static GPtrArray *device_property_bases = NULL;
121 static GHashTable *device_property_bases_by_name = NULL;
123 DevicePropertyBase* device_property_get_by_id(DevicePropertyId id) {
124 if (!device_property_bases || id >= device_property_bases->len)
127 return g_ptr_array_index(device_property_bases, id);
130 DevicePropertyBase* device_property_get_by_name(const char *name) {
133 if (!device_property_bases_by_name)
136 rv = g_hash_table_lookup(device_property_bases_by_name, name);
138 return (DevicePropertyBase *)rv;
143 #define toupper_and_underscore(c) (((c)=='-')? '_' : g_ascii_toupper((c)))
145 device_property_hash(
148 /* modified version of glib's hash function, copyright
149 * GLib Team and others 1997-2000. */
151 guint h = toupper_and_underscore(*p);
154 for (p += 1; *p != '\0'; p++)
155 h = (h << 5) - h + toupper_and_underscore(*p);
161 device_property_equal(
165 const char *s1 = v1, *s2 = v2;
168 if (toupper_and_underscore(*s1) != toupper_and_underscore(*s2))
179 device_property_fill_and_register(DevicePropertyBase *base,
180 GType type, const char * name, const char * desc) {
182 /* create the hash table and array if necessary */
183 if (!device_property_bases) {
184 device_property_bases = g_ptr_array_new();
185 device_property_bases_by_name = g_hash_table_new(device_property_hash, device_property_equal);
188 /* check for a duplicate */
189 if (device_property_get_by_name(name)) {
190 g_critical("A property named '%s' already exists!", name);
193 /* allocate space for this DPB and fill it in */
194 base->ID = device_property_bases->len;
196 base->name = name; /* no strdup -- it's statically allocated */
197 base->description = desc; /* ditto */
199 /* add it to the array and hash table; note that its array index and its
200 * ID are the same. */
201 g_ptr_array_add(device_property_bases, base);
202 g_hash_table_insert(device_property_bases_by_name, (gpointer)name, (gpointer)base);
209 void device_property_init(void) {
210 device_property_fill_and_register(&device_property_concurrency,
211 CONCURRENCY_PARADIGM_TYPE, "concurrency",
212 "Supported concurrency mode (none, multiple readers, multiple writers)");
213 device_property_fill_and_register(&device_property_streaming,
214 STREAMING_REQUIREMENT_TYPE, "streaming",
215 "Streaming desirability (unnecessary, desired, required)");
216 device_property_fill_and_register(&device_property_compression,
217 G_TYPE_BOOLEAN, "compression",
218 "Is device performing data compression?");
219 device_property_fill_and_register(&device_property_compression_rate,
220 G_TYPE_DOUBLE, "compression_rate",
222 "averaged for some (currently undefined) period of time)");
223 device_property_fill_and_register(&device_property_block_size,
224 G_TYPE_INT, "block_size",
225 "Block size to use while writing.");
226 device_property_fill_and_register(&device_property_min_block_size,
227 G_TYPE_UINT, "min_block_size",
228 "Minimum supported blocking factor.");
229 device_property_fill_and_register(&device_property_max_block_size,
230 G_TYPE_UINT, "max_block_size",
231 "Maximum supported blocking factor.");
232 device_property_fill_and_register(&device_property_read_buffer_size,
233 G_TYPE_UINT, "read_buffer_size",
234 "Minimum size of a read for this device (maximum expected block size)");
235 device_property_fill_and_register(&device_property_appendable,
236 G_TYPE_BOOLEAN, "appendable",
237 "Does device support appending to previously-written media?");
238 device_property_fill_and_register(&device_property_canonical_name,
239 G_TYPE_STRING, "canonical_name",
240 "The most reliable device name to use to refer to this device.");
241 device_property_fill_and_register(&device_property_medium_access_type,
242 MEDIA_ACCESS_MODE_TYPE,
243 "medium_access_type",
244 "What kind of media (RO/WORM/RW/WORN) do we have here?");
245 device_property_fill_and_register(&device_property_partial_deletion,
246 G_TYPE_BOOLEAN, "partial_deletion",
247 "Does this device support recycling just part of a volume?" );
248 device_property_fill_and_register(&device_property_free_space,
249 QUALIFIED_SIZE_TYPE, "free_space",
250 "Remaining capacity of the device.");
251 device_property_fill_and_register(&device_property_max_volume_usage,
252 G_TYPE_UINT64, "max_volume_usage",
253 "Artificial limit to data written to volume.");
254 device_property_fill_and_register(&device_property_verbose,
255 G_TYPE_BOOLEAN, "verbose",
256 "Should the device produce verbose output?");
259 DevicePropertyBase device_property_concurrency;
260 DevicePropertyBase device_property_streaming;
261 DevicePropertyBase device_property_compression;
262 DevicePropertyBase device_property_compression_rate;
263 DevicePropertyBase device_property_block_size;
264 DevicePropertyBase device_property_min_block_size;
265 DevicePropertyBase device_property_max_block_size;
266 DevicePropertyBase device_property_read_buffer_size;
267 DevicePropertyBase device_property_appendable;
268 DevicePropertyBase device_property_canonical_name;
269 DevicePropertyBase device_property_medium_access_type;
270 DevicePropertyBase device_property_partial_deletion;
271 DevicePropertyBase device_property_free_space;
272 DevicePropertyBase device_property_max_volume_usage;
273 DevicePropertyBase device_property_verbose;