<html><body>
<p>pushed<br>
<br>
Sharad Mishra<br>
Open Virtualization<br>
Linux Technology Center<br>
IBM<br>
<br>
<tt>"Eduardo Lima (Etrunko)" <eblima@linux.vnet.ibm.com> wrote on 08/31/2011 06:41:56 AM:<br>
<br>
> "Eduardo Lima (Etrunko)" <eblima@linux.vnet.ibm.com> </tt><br>
<tt>> 08/31/2011 06:41 AM</tt><br>
<tt>> <br>
> Please respond to<br>
> eblima@br.ibm.com</tt><br>
<tt>> <br>
> To</tt><br>
<tt>> <br>
> List for discussion and development of libvirt CIM <libvirt-cim@redhat.com></tt><br>
<tt>> <br>
> cc</tt><br>
<tt>> <br>
> Sharad Mishra/Beaverton/IBM@IBMUS</tt><br>
<tt>> <br>
> Subject</tt><br>
<tt>> <br>
> Re: [Libvirt-cim] [PATCH] (#2) Workaround to fix race condition <br>
> around libvirt init</tt><br>
<tt>> <br>
> On 08/30/2011 02:14 PM, Sharad Mishra wrote:<br>
> > # HG changeset patch<br>
> > # User Sharad Mishra<snmishra@us.ibm.com><br>
> > # Date 1314719316 25200<br>
> > # Node ID c54aafd0b2c6414f91b96bc30e2f148bb78d5c59<br>
> > # Parent  277b56b3863b5f81a3faa18aeb7b9951b963b489<br>
> > (#2) Workaround to fix race condition around libvirt init.<br>
> ><br>
> > This patch fixes the race condition caused when mutiple<br>
> > threads try to start VMs at the same time. This patch<br>
> > also fixes the issue of incorrect mem allocation for<br>
> > VSSD property - emulator.<br>
> ><br>
> > #2: included Edurdo's patch for make_space<br>
> >      took care of coding guidelines.<br>
> ><br>
> > Signed-off-by: Sharad Mishra<snmishra@us.ibm.com><br>
> ><br>
> > diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c<br>
> > --- a/libxkutil/misc_util.c<br>
> > +++ b/libxkutil/misc_util.c<br>
> > @@ -28,6 +28,7 @@<br>
> >   #include<stdbool.h><br>
> >   #include<stdarg.h><br>
> >   #include<unistd.h><br>
> > +#include<pthread.h><br>
> >   #include<libvirt/libvirt.h><br>
> >   #include<libvirt/virterror.h><br>
> ><br>
> > @@ -45,6 +46,9 @@<br>
> >   #include "misc_util.h"<br>
> >   #include "cs_util.h"<br>
> ><br>
> > +static pthread_mutex_t libvirt_mutex = PTHREAD_MUTEX_INITIALIZER;<br>
> > +/* libvirt library not initialized */<br>
> > +static int libvirt_initialized = 0;<br>
> ><br>
> >   #define URI_ENV "HYPURI"<br>
> ><br>
> > @@ -114,11 +118,15 @@<br>
> ><br>
> >           CU_DEBUG("Connecting to libvirt with uri `%s'", uri);<br>
> ><br>
> > +        pthread_mutex_lock(&libvirt_mutex);<br>
> > +<br>
> >           if (is_read_only())<br>
> >                   conn = virConnectOpenReadOnly(uri);<br>
> >           else<br>
> >                   conn = virConnectOpen(uri);<br>
> ><br>
> > +        pthread_mutex_unlock(&libvirt_mutex);<br>
> > +<br>
> >           if (!conn) {<br>
> >                   CU_DEBUG("Unable to connect to `%s'", uri);<br>
> >                   return NULL;<br>
> > @@ -530,7 +538,19 @@<br>
> ><br>
> >   bool libvirt_cim_init(void)<br>
> >   {<br>
> > -        return virInitialize() == 0;<br>
> > +        int ret = 0;<br>
> > +<br>
> > +        /* double-check lock pattern used for performance reasons */<br>
> > +        if (libvirt_initialized == 0) {<br>
> > +                pthread_mutex_lock(&libvirt_mutex);<br>
> > +                if (libvirt_initialized == 0) {<br>
> > +                        ret = virInitialize();<br>
> > +                        if (ret == 0)<br>
> > +                                libvirt_initialized = 1;<br>
> > +                }<br>
> > +                pthread_mutex_unlock(&libvirt_mutex);<br>
> > +        }<br>
> > +        return (ret == 0);<br>
> >   }<br>
> ><br>
> >   bool check_refs_pfx_match(const CMPIObjectPath *refa,<br>
> > diff --git a/src/Virt_VirtualSystemManagementService.c b/src/<br>
> Virt_VirtualSystemManagementService.c<br>
> > --- a/src/Virt_VirtualSystemManagementService.c<br>
> > +++ b/src/Virt_VirtualSystemManagementService.c<br>
> > @@ -188,6 +188,24 @@<br>
> >           return 1;<br>
> >   }<br>
> ><br>
> > +static bool make_space(struct virt_device **list, int cur, int new)<br>
> > +{<br>
> > +        struct virt_device *tmp;<br>
> > +<br>
> > +        tmp = calloc(cur + new, sizeof(*tmp));<br>
> > +        if (tmp == NULL)<br>
> > +                return false;<br>
> > +<br>
> > +        if (*list) {<br>
> > +                memcpy(tmp, *list, sizeof(*tmp) * cur);<br>
> > +                free(*list);<br>
> > +        }<br>
> > +<br>
> > +        *list = tmp;<br>
> > +<br>
> > +        return true;<br>
> > +}<br>
> > +<br>
> >   static bool fv_set_emulator(struct domain *domain,<br>
> >                               const char *emu)<br>
> >   {<br>
> > @@ -198,6 +216,11 @@<br>
> >           if (emu == NULL)<br>
> >                   return true;<br>
> ><br>
> > +        if (!make_space(&domain->dev_emu, 0, 1)) {<br>
> > +                CU_DEBUG("Failed to alloc disk list");<br>
> > +                return false;<br>
> > +        }<br>
> > +<br>
> >           cleanup_virt_device(domain->dev_emu);<br>
> ><br>
> >           domain->dev_emu->type = CIM_RES_TYPE_EMU;<br>
> > @@ -1369,24 +1392,6 @@<br>
> >           return msg;<br>
> >   }<br>
> ><br>
> > -static bool make_space(struct virt_device **list, int cur, int new)<br>
> > -{<br>
> > -        struct virt_device *tmp;<br>
> > -<br>
> > -        tmp = calloc(cur + new, sizeof(*tmp));<br>
> > -        if (tmp == NULL)<br>
> > -                return false;<br>
> > -<br>
> > -        if (*list) {<br>
> > -                memcpy(tmp, *list, sizeof(*tmp) * cur);<br>
> > -                free(*list);<br>
> > -        }<br>
> > -<br>
> > -        *list = tmp;<br>
> > -<br>
> > -        return true;<br>
> > -}<br>
> > -<br>
> >   static char *add_device_nodup(struct virt_device *dev,<br>
> >                                 struct virt_device *list,<br>
> >                                 int max,<br>
> ><br>
> <br>
> +1. Tricky stuff. :)<br>
> <br>
> -- <br>
> Eduardo de Barros Lima<br>
> Software Engineer, Open Virtualization<br>
> Linux Technology Center - IBM/Brazil<br>
> eblima@br.ibm.com<br>
> <br>
</tt></body></html>