4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 #include <nbdkit-plugin.h>
42 #include "allocator.h"
43 #include "allocator-internal.h"
47 /* The list of registered allocators. */
48 DEFINE_VECTOR_TYPE (allocator_list
, const struct allocator_functions
*);
49 static allocator_list allocators
= empty_vector
;
52 register_allocator (const struct allocator_functions
*f
)
54 if (allocator_list_append (&allocators
, f
) == -1) {
61 free_key_value (struct key_value kv
)
68 free_allocator_parameters (allocator_parameters
*params
)
70 allocator_parameters_iter (params
, free_key_value
);
74 /* The type may be followed by parameters "type,key=value[,...]" */
76 parse_parameters (const char *type
, size_t *type_len
,
77 allocator_parameters
*params
)
81 *type_len
= strcspn (type
, ",");
83 nbdkit_debug ("allocator: %*s", (int) *type_len
, type
);
85 /* Split the parameters. */
86 for (i
= *type_len
; type
[i
] == ',';) {
90 len
= strcspn (&type
[i
], ",");
96 j
= strcspn (&type
[i
], "=");
98 nbdkit_error ("invalid allocator parameter");
99 free_allocator_parameters (params
);
103 kv
.key
= strndup (&type
[i
], j
);
104 kv
.value
= strndup (&type
[i
+j
+1], len
-j
-1);
107 kv
.key
= strndup (&type
[i
], len
);
108 kv
.value
= strdup ("1");
110 if (kv
.key
== NULL
|| kv
.value
== NULL
) {
111 nbdkit_error ("strdup: %m");
114 free_allocator_parameters (params
);
118 nbdkit_debug ("allocator parameter: %s=%s", kv
.key
, kv
.value
);
119 if (allocator_parameters_append (params
, kv
) == -1) {
120 nbdkit_error ("realloc: %m");
121 free_allocator_parameters (params
);
131 create_allocator (const char *type
, bool debug
)
133 struct allocator
*ret
= NULL
;
134 allocator_parameters params
= empty_vector
;
137 if (parse_parameters (type
, &type_len
, ¶ms
) == -1)
140 /* See if we can find the allocator. */
141 for (i
= 0; i
< allocators
.len
; ++i
) {
142 if (strncmp (type
, allocators
.ptr
[i
]->type
, type_len
) == 0) {
143 ret
= allocators
.ptr
[i
]->create (¶ms
);
149 nbdkit_error ("unknown allocator \"%s\"", type
);
151 /* Free the parameters allocated above. */
152 free_allocator_parameters (¶ms
);
156 ret
->f
= allocators
.ptr
[i
];
162 cleanup_free_allocator (struct allocator
**ap
)
164 struct allocator
*a
= *ap
;