mirror of
https://git.proxmox.com/git/mirror_corosync
synced 2025-07-21 21:27:25 +00:00

git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1637 fd59a12c-fef9-0310-b244-a6a79926bd2f
114 lines
4.0 KiB
Plaintext
114 lines
4.0 KiB
Plaintext
Live Component Replacement
|
|
--------------------------
|
|
All software is composed of components, which contain multiple software classes.
|
|
Components generally depend upon other components and sometimes classes from
|
|
other components.
|
|
|
|
Some components of corosync are the evt service, the ckpt service, the clm
|
|
service, the totem protocol, and others. If a defect is found in any of
|
|
these components, the entire ais executive must be stopped, replaced, and
|
|
restarted.
|
|
|
|
The lcr code formalizes the concept of components into dynamic libraries. A
|
|
component may have multiple classes. Each class (the lcr code uses the word
|
|
interface) may have multiple functions within the class. Each interface may
|
|
depend upon other interfaces, and those interfaces are then loaded prior to the
|
|
requested interface being referenced.
|
|
|
|
Note that with recent changes, the lcr interface factory can be used when
|
|
statically linking without additional steps. The interface for notifying
|
|
lcr of a component has changed.
|
|
|
|
A list of shared objects is scanned each time an interface is requested to
|
|
load via the following interface:
|
|
|
|
int lcr_ifact_reference (
|
|
void **handle,
|
|
char *iface_name,
|
|
int version,
|
|
void **interface,
|
|
void *context);
|
|
|
|
The iface_name is the name of the interface, the version is the version,
|
|
the void **interface is the list of functions returned once the interface
|
|
has been dynamically loaded and referenced, and context is passed to the
|
|
constructor and destructor.
|
|
|
|
The interface is loaded, the interface constructor is called, and the list
|
|
of interfaces is returned back to the caller.
|
|
|
|
First the list of interfaces is described in an iface_list data structure:
|
|
struct iface_list iface_list = {
|
|
.iface1_func1 = iface1_func1,
|
|
.iface1_func2 = iface1_func2,
|
|
.iface1_func3 = iface1_func3,
|
|
};
|
|
iface1_func1 is a simple function call.
|
|
|
|
Then the lcr_iface data structure is defined for the c file:
|
|
|
|
struct lcr_iface iface1_ver0 = {
|
|
.name = "iface1",
|
|
.version = 0,
|
|
.versions_replace = 0,
|
|
.versions_replace_count = 0,
|
|
.dependencies = 0,
|
|
.dependency_count = 0,
|
|
.constructor = iface1_constructor,
|
|
.destructor = iface1_destructor,
|
|
.interfaces = (void **)&iface_list,
|
|
};
|
|
|
|
The name and version fields provide naming and versioning. The constructor
|
|
and destructor functions execute at reference and release times. Finally
|
|
the .interfaces type describes the list of functions used for the interface.
|
|
|
|
Next, an lcr_comp must be described:
|
|
|
|
struct lcr_comp test_comp = {
|
|
.iface_count = 2,
|
|
.ifaces = lcr_ifaces
|
|
};
|
|
|
|
the iface count describes the number of interfaces within the component,
|
|
and lcr_ifaces is an array of pointers to lcr_iface data types.
|
|
|
|
The lcr_comp_get method has been replaced. The final step is to setup a
|
|
constructor that is started when the task is started. This ctor will
|
|
register the component with the lcr framework.
|
|
|
|
static void register_this_component (void) {
|
|
lcr_component_register (&test_comp);
|
|
}
|
|
|
|
static void (*const __init_this_component[1]) (void) __attribute__ ((section(".ctors"))) = { register_this_component };
|
|
|
|
|
|
Now the component can be referenced and used in another application.
|
|
int main ()
|
|
{
|
|
|
|
.....
|
|
|
|
lcr_ifact_reference (
|
|
&ifact_handle_ver0,
|
|
"iface1",
|
|
0, /* version 0 */
|
|
(void **)&iface_ver0,
|
|
(void *)0xdeadbeef);
|
|
|
|
iface_ver0->func1();
|
|
iface_ver0->func2();
|
|
iface_ver0->func3();
|
|
}
|
|
|
|
|
|
See libtest_a and libtest_b for two sample components. The test program
|
|
demonstrates usage. The test_static demonstrates operation when statically
|
|
linked. Note the dynamic inteface factory is still available for use when
|
|
statically linking components.
|
|
|
|
On startup, a thread is created which listens for requests from the "uic"
|
|
application. These requests are then processed by the lcr service which
|
|
would execute a live replacement.
|