mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
Permit several segment types to be registered by a single shared object.
This commit is contained in:
parent
3d425215a8
commit
dd1d42d5d0
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.49 -
|
Version 2.02.49 -
|
||||||
================================
|
================================
|
||||||
|
Permit several segment types to be registered by a single shared object.
|
||||||
Update the man pages to document size units uniformly.
|
Update the man pages to document size units uniformly.
|
||||||
Allow commandline sizes to be specified in terms of bytes and sectors.
|
Allow commandline sizes to be specified in terms of bytes and sectors.
|
||||||
Update 'md_chunk_alignment' to use stripe-width to align PV data area.
|
Update 'md_chunk_alignment' to use stripe-width to align PV data area.
|
||||||
|
@ -806,12 +806,59 @@ int init_lvmcache_orphans(struct cmd_context *cmd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct segtype_library {
|
||||||
|
struct cmd_context *cmd;
|
||||||
|
void *lib;
|
||||||
|
const char *libname;
|
||||||
|
};
|
||||||
|
|
||||||
|
int lvm_register_segtype(struct segtype_library *seglib,
|
||||||
|
struct segment_type *segtype)
|
||||||
|
{
|
||||||
|
struct segment_type *segtype2;
|
||||||
|
|
||||||
|
segtype->library = seglib->lib;
|
||||||
|
segtype->cmd = seglib->cmd;
|
||||||
|
|
||||||
|
dm_list_iterate_items(segtype2, &seglib->cmd->segtypes) {
|
||||||
|
if (strcmp(segtype2->name, segtype->name))
|
||||||
|
continue;
|
||||||
|
log_error("Duplicate segment type %s: "
|
||||||
|
"unloading shared library %s",
|
||||||
|
segtype->name, seglib->libname);
|
||||||
|
segtype->ops->destroy(segtype);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dm_list_add(&seglib->cmd->segtypes, &segtype->list);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _init_single_segtype(struct segtype_library *seglib)
|
||||||
|
{
|
||||||
|
struct segment_type *(*init_segtype_fn) (struct cmd_context *);
|
||||||
|
struct segment_type *segtype;
|
||||||
|
|
||||||
|
if (!(init_segtype_fn = dlsym(seglib->lib, "init_segtype"))) {
|
||||||
|
log_error("Shared library %s does not contain segment type "
|
||||||
|
"functions", seglib->libname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(segtype = init_segtype_fn(seglib->cmd)))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
return lvm_register_segtype(seglib, segtype);
|
||||||
|
}
|
||||||
|
|
||||||
static int _init_segtypes(struct cmd_context *cmd)
|
static int _init_segtypes(struct cmd_context *cmd)
|
||||||
{
|
{
|
||||||
struct segment_type *segtype;
|
struct segment_type *segtype;
|
||||||
|
|
||||||
#ifdef HAVE_LIBDL
|
#ifdef HAVE_LIBDL
|
||||||
const struct config_node *cn;
|
const struct config_node *cn;
|
||||||
|
struct segtype_library seglib;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(segtype = init_striped_segtype(cmd)))
|
if (!(segtype = init_striped_segtype(cmd)))
|
||||||
@ -854,9 +901,9 @@ static int _init_segtypes(struct cmd_context *cmd)
|
|||||||
(cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
|
(cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
|
||||||
|
|
||||||
struct config_value *cv;
|
struct config_value *cv;
|
||||||
struct segment_type *(*init_segtype_fn) (struct cmd_context *);
|
int (*init_multiple_segtypes_fn) (struct segtype_library *);
|
||||||
void *lib;
|
|
||||||
struct segment_type *segtype2;
|
seglib.cmd = cmd;
|
||||||
|
|
||||||
for (cv = cn->v; cv; cv = cv->next) {
|
for (cv = cn->v; cv; cv = cv->next) {
|
||||||
if (cv->type != CFG_STRING) {
|
if (cv->type != CFG_STRING) {
|
||||||
@ -864,32 +911,37 @@ static int _init_segtypes(struct cmd_context *cmd)
|
|||||||
"global/segment_libraries");
|
"global/segment_libraries");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!(lib = load_shared_library(cmd, cv->v.str,
|
seglib.libname = cv->v.str;
|
||||||
|
if (!(seglib.lib = load_shared_library(cmd,
|
||||||
|
seglib.libname,
|
||||||
"segment type", 0)))
|
"segment type", 0)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(init_segtype_fn = dlsym(lib, "init_segtype"))) {
|
if ((init_multiple_segtypes_fn =
|
||||||
log_error("Shared library %s does not contain "
|
dlsym(seglib.lib, "init_multiple_segtypes"))) {
|
||||||
"segment type functions", cv->v.str);
|
if (dlsym(seglib.lib, "init_segtype"))
|
||||||
dlclose(lib);
|
log_warn("WARNING: Shared lib %s has "
|
||||||
return 0;
|
"conflicting init fns. Using"
|
||||||
}
|
" init_multiple_segtypes().",
|
||||||
|
seglib.libname);
|
||||||
|
} else
|
||||||
|
init_multiple_segtypes_fn =
|
||||||
|
_init_single_segtype;
|
||||||
|
|
||||||
if (!(segtype = init_segtype_fn(cmd)))
|
if (!init_multiple_segtypes_fn(&seglib)) {
|
||||||
return 0;
|
struct dm_list *sgtl, *tmp;
|
||||||
segtype->library = lib;
|
log_error("init_multiple_segtypes() failed: "
|
||||||
dm_list_add(&cmd->segtypes, &segtype->list);
|
"Unloading shared library %s",
|
||||||
|
seglib.libname);
|
||||||
dm_list_iterate_items(segtype2, &cmd->segtypes) {
|
dm_list_iterate_safe(sgtl, tmp, &cmd->segtypes) {
|
||||||
if ((segtype == segtype2) ||
|
segtype = dm_list_item(sgtl, struct segment_type);
|
||||||
strcmp(segtype2->name, segtype->name))
|
if (segtype->library == seglib.lib) {
|
||||||
continue;
|
|
||||||
log_error("Duplicate segment type %s: "
|
|
||||||
"unloading shared library %s",
|
|
||||||
segtype->name, cv->v.str);
|
|
||||||
dm_list_del(&segtype->list);
|
dm_list_del(&segtype->list);
|
||||||
segtype->ops->destroy(segtype);
|
segtype->ops->destroy(segtype);
|
||||||
dlclose(lib);
|
}
|
||||||
|
}
|
||||||
|
dlclose(seglib.lib);
|
||||||
|
return_0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1154,8 +1206,18 @@ static void _destroy_segtypes(struct dm_list *segtypes)
|
|||||||
lib = segtype->library;
|
lib = segtype->library;
|
||||||
segtype->ops->destroy(segtype);
|
segtype->ops->destroy(segtype);
|
||||||
#ifdef HAVE_LIBDL
|
#ifdef HAVE_LIBDL
|
||||||
if (lib)
|
/*
|
||||||
|
* If no segtypes remain from this library, close it.
|
||||||
|
*/
|
||||||
|
if (lib) {
|
||||||
|
struct segment_type *segtype2;
|
||||||
|
dm_list_iterate_items(segtype2, segtypes)
|
||||||
|
if (segtype2->library == lib)
|
||||||
|
goto skip_dlclose;
|
||||||
dlclose(lib);
|
dlclose(lib);
|
||||||
|
skip_dlclose:
|
||||||
|
;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,13 +47,13 @@ struct dev_manager;
|
|||||||
#define segtype_is_virtual(segtype) ((segtype)->flags & SEG_VIRTUAL ? 1 : 0)
|
#define segtype_is_virtual(segtype) ((segtype)->flags & SEG_VIRTUAL ? 1 : 0)
|
||||||
|
|
||||||
struct segment_type {
|
struct segment_type {
|
||||||
struct dm_list list;
|
struct dm_list list; /* Internal */
|
||||||
struct cmd_context *cmd;
|
struct cmd_context *cmd; /* lvm_register_segtype() sets this. */
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
struct segtype_handler *ops;
|
struct segtype_handler *ops;
|
||||||
const char *name;
|
const char *name;
|
||||||
void *library;
|
void *library; /* lvm_register_segtype() sets this. */
|
||||||
void *private;
|
void *private; /* For the segtype handler to use. */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct segtype_handler {
|
struct segtype_handler {
|
||||||
@ -93,6 +93,10 @@ struct segtype_handler {
|
|||||||
struct segment_type *get_segtype_from_string(struct cmd_context *cmd,
|
struct segment_type *get_segtype_from_string(struct cmd_context *cmd,
|
||||||
const char *str);
|
const char *str);
|
||||||
|
|
||||||
|
struct segtype_library;
|
||||||
|
int lvm_register_segtype(struct segtype_library *seglib,
|
||||||
|
struct segment_type *segtype);
|
||||||
|
|
||||||
struct segment_type *init_striped_segtype(struct cmd_context *cmd);
|
struct segment_type *init_striped_segtype(struct cmd_context *cmd);
|
||||||
struct segment_type *init_zero_segtype(struct cmd_context *cmd);
|
struct segment_type *init_zero_segtype(struct cmd_context *cmd);
|
||||||
struct segment_type *init_error_segtype(struct cmd_context *cmd);
|
struct segment_type *init_error_segtype(struct cmd_context *cmd);
|
||||||
|
Loading…
Reference in New Issue
Block a user