0

I am trying to implement a custom locking library for LVM. Setting locking_type to external (2) in lvm.conf and providing a shared library implementing the required functions seems enough and relatively simple, in theory.

Looking into this I started with the sources for LVM2, specifically the external locking mechanism implementation, which can be found here.

Basically, what I figured out that I need to do is to implement functions with the headers described like this:

static void (*_reset_fn) (void) = NULL;
static void (*_end_fn) (void) = NULL;
static int (*_lock_fn) (struct cmd_context * cmd, const char *resource, uint32_t flags) = NULL;
static int (*_init_fn) (int type, struct dm_config_tree * cft, uint32_t *flags) = NULL;
static int (*_lock_query_fn) (const char *resource, int *mode) = NULL;

Now, everything peachy up to this point. However, looking at the _lock_fn definition, it takes a pointer to struct cmd_context as first argument. That struct can easily be found in the LVM2 sources (and it is a fairly complex one!), but it is not inside the headers exposed by the package as an API (eg. the lvm2-devel package in RHEL7). As I imagine (I am definitely not the best C programmer around), since that struct is supposed to be used by external libraries, it is mandatory that it should be in the headers.

Am I thinking this wrong or is it just a "bug" and I should discuss with LVM2 developers? Are there any workarounds, other than copy/pasting that struct and all other types that it depends on to a header file in my project? Doing this "workaround", does it break the GNU GPL license in any way?

Florin Asăvoaie
  • 849
  • 1
  • 6
  • 20
  • See also questions on 'opaque pointer types', etc. That seems to be what you're using here. They're a good idea when the calling code doesn't need to know about the internals of the structure — or allocate instances of the structure as local or global variables. As long as a pointer alone is sufficient, opaque types are good. – Jonathan Leffler Jul 10 '16 at 19:56

1 Answers1

2

The source file you linked, indirectly includes the config.h header which has this line:

struct cmd_context;

This tells the C compiler that there is a struct with that name. That's all the compiler needs to know to generate correct machine code.

If you were to access members of that struct or directly create an object of it, you would get errors thrown your way because the compiler doesn't know size or members of the struct.

But as long you use it as an opaque data type passing a known-size pointer to it in and out of functions, you are ok. This is called forward declaration and is a primary way of achieving encapsulation in C (check stdio's FILE).

a3f
  • 8,517
  • 1
  • 41
  • 46