|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 --for 4.6 COLOPre 24/25] tools/libxl: move remus state into a seperate structure
On Thu, 2015-07-16 at 12:10 +0100, Ian Jackson wrote:
> Ian Campbell writes ("Re: [Xen-devel] [PATCH v4 --for 4.6 COLOPre 24/25]
> tools/libxl: move remus state into a seperate structure"):
> > On Wed, 2015-07-15 at 21:50 +0800, Yang Hongyang wrote:
> > > Yes, checkpoint device is an abstract layer, used by both Remus & colo,
> > > in the abstract layer, we do not aware of remus or colo, in Remus or colo,
> > > we can use container of cds to retrive Remus/colo state.
> >
> > This is because the cds callbacks receive a
> > libxl__checkpoint_devices_state * but are specific to either Remus of
> > Colo?
> >
> > I think the usual way to solve that would be for the callback to take a
> > void *data "closure" field, which is registered along with the callbacks
> > and passed to all callbacks, or in this case perhaps you can get away
> > with just including it in the cds itself.
> >
> > Ian, what do you think?
>
> This is rather an unusual situation. Normally there are two patterns:
>
>
> 1.
>
> Things like:
>
> static void device_disk_add(libxl__egc *egc, uint32_t domid,
> libxl_device_disk *disk,
> libxl__ao_device *aodev,
> char *get_vdev(libxl__gc *, void *,
> xs_transaction_t),
> void *get_vdev_user)
>
> and similar patterns in much code in libxl and elsewhere. This is the
> normal case. (It is of course essential to use this when there are
> multiple call sites, so the void* data pointer might vary.)
>
>
> 2.
>
> Things like (NB not very like real code):
>
> struct libxl_some_operation_state {
> libxl_inner_generic_operation_state igos;
>
> void someop_innerop_make_happen(libxl_some_operation_state *sos) {
> sos->igos.callback = someop_innerop_done;
>
> void someop_innerop_done(libxl_inner_generic_operation_state *igos) {
> sos = CONTAINER_OF(igos);
>
> Here the callback someop_innerop_done can be sure that CONTAINER_OF is
> correct because the callback is set up only in one place where it is
> obvious that the igos is part of a sos.
>
> IMO this is an exception to the usual rule that you have to accompany
> the function pointer with a void*. The exception is justified because
> it is very easy to see that the code is correct. And, if any mistake
> is made, the setup is unconditional, so it will _always_ get the wrong
> container and go wrong (which will hopefully be spotted in testing).
>
>
>
> In this particular situation the plumbing that relates a particular
> callback to the remus or colo state is rather more complicated. I
> don't think it will be as obvious that the appropriate CONTAINER_OF is
> being used, let alone obvious that this it's always the same.
>
> OTOH for any particular callback the context pointer is supposed to be
> a particular CONTAINER_OF. It would be nice to write this in the
> code.
>
> I think in this case the best answer would be:
>
> struct libxl__checkpoint_devices_state {
> void (*postsuspend)(libxl__egc *egc, libxl__remus_device *dev);
ITYM s/libxl__remus_device/libxl__checkpoint_devices_state here?
If so then this is pretty much what I meant by "in this case perhaps you
can get away with just including it in the cds itself", but more clearly
explained.
> void *callbacks_context;
>
> and in the callback
>
> void libxl__remus_devices_postsuspend(libxl__egc *egc,
> libxl__check_devices_state *cds)
> {
> libxl__remus_state *rs = cds->callbacks_context;
> assert(cds = &rs->cds);
>
> or some such.
>
>
> Thanks,
> Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |