[PATCHv3,1/3] runqemu: Allow to store more than one lock for network interfaces

Message ID 20190701212350.32503-1-anibal.limon@linaro.org
State Superseded
Headers show
Series
  • [PATCHv3,1/3] runqemu: Allow to store more than one lock for network interfaces
Related show

Commit Message

Anibal Limon July 1, 2019, 9:23 p.m.
In order to support multiple tap devices in the same qemu virtual
machine.

Signed-off-by: Aníbal Limón <anibal.limon@linaro.org>
---
 scripts/runqemu | 50 +++++++++++++++++++++++++------------------------
 1 file changed, 26 insertions(+), 24 deletions(-)

Comments

Anibal Limon July 1, 2019, 9:26 p.m. | #1
I squashed the fix in the wrong patch that's because the v3 that are no
functional changes between v2 and v3.

Fixed acquired_lock method to only add the lock when acquire succeed.

Regards,
Anibal

On Mon, 1 Jul 2019 at 16:23, Aníbal Limón <anibal.limon@linaro.org> wrote:

> In order to support multiple tap devices in the same qemu virtual

> machine.

>

> Signed-off-by: Aníbal Limón <anibal.limon@linaro.org>

> ---

>  scripts/runqemu | 50 +++++++++++++++++++++++++------------------------

>  1 file changed, 26 insertions(+), 24 deletions(-)

>

> diff --git a/scripts/runqemu b/scripts/runqemu

> index 4079f2b17d..38dd1c30d9 100755

> --- a/scripts/runqemu

> +++ b/scripts/runqemu

> @@ -181,8 +181,7 @@ class BaseConfig(object):

>          self.audio_enabled = False

>          self.tcpserial_portnum = ''

>          self.custombiosdir = ''

> -        self.lock = ''

> -        self.lock_descriptor = None

> +        self.lock_descriptors = {}

>          self.bitbake_e = ''

>          self.snapshot = False

>          self.wictypes = ('wic', 'wic.vmdk', 'wic.qcow2', 'wic.vdi')

> @@ -204,30 +203,32 @@ class BaseConfig(object):

>          # avoid cleanup twice

>          self.cleaned = False

>

> -    def acquire_lock(self, error=True):

> -        logger.debug("Acquiring lockfile %s..." % self.lock)

> +    def acquire_lock(self, lock, error=True):

> +        logger.debug("Acquiring lockfile %s..." % lock)

> +        descriptor = None

>          try:

> -            self.lock_descriptor = open(self.lock, 'w')

> -            fcntl.flock(self.lock_descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)

> +            descriptor = open(lock, 'w')

> +            fcntl.flock(descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)

>          except Exception as e:

> -            msg = "Acquiring lockfile %s failed: %s" % (self.lock, e)

> +            msg = "Acquiring lockfile %s failed: %s" % (lock, e)

>              if error:

>                  logger.error(msg)

>              else:

>                  logger.info(msg)

> -            if self.lock_descriptor:

> -                self.lock_descriptor.close()

> -                self.lock_descriptor = None

> +            if descriptor:

> +                descriptor.close()

> +                descriptor = None

>              return False

> +        self.lock_descriptors[lock] = descriptor

>          return True

>

> -    def release_lock(self):

> -        if self.lock_descriptor:

> -            logger.debug("Releasing lockfile for tap device '%s'" %

> self.tap)

> -            fcntl.flock(self.lock_descriptor, fcntl.LOCK_UN)

> -            self.lock_descriptor.close()

> -            os.remove(self.lock)

> -            self.lock_descriptor = None

> +    def release_lock(self, lock):

> +        if self.lock_descriptors[lock]:

> +            logger.debug("Releasing lockfile for tap device '%s'" % lock)

> +            fcntl.flock(self.lock_descriptors[lock], fcntl.LOCK_UN)

> +            self.lock_descriptors[lock].close()

> +            os.remove(lock)

> +            self.lock_descriptors[lock] = None

>

>      def get(self, key):

>          if key in self.d:

> @@ -1016,8 +1017,8 @@ class BaseConfig(object):

>              if os.path.exists('%s.skip' % lockfile):

>                  logger.info('Found %s.skip, skipping %s' % (lockfile, p))

>                  continue

> -            self.lock = lockfile + '.lock'

> -            if self.acquire_lock(error=False):

> +            lock = lockfile + '.lock'

> +            if self.acquire_lock(lock, error=False):

>                  tap = p

>                  logger.info("Using preconfigured tap device %s" % tap)

>                  logger.info("If this is not intended, touch %s.skip to

> make runqemu skip %s." %(lockfile, tap))

> @@ -1035,8 +1036,8 @@ class BaseConfig(object):

>              cmd = ('sudo', self.qemuifup, str(uid), str(gid),

> self.bindir_native)

>              tap = subprocess.check_output(cmd).decode('utf-8').strip()

>              lockfile = os.path.join(lockdir, tap)

> -            self.lock = lockfile + '.lock'

> -            self.acquire_lock()

> +            lock = lockfile + '.lock'

> +            self.acquire_lock(lock)

>              self.cleantap = True

>              logger.debug('Created tap: %s' % tap)

>

> @@ -1268,8 +1269,8 @@ class BaseConfig(object):

>          cmds = shlex.split(cmd)

>          logger.info('Running %s\n' % cmd)

>          pass_fds = []

> -        if self.lock_descriptor:

> -            pass_fds = [self.lock_descriptor.fileno()]

> +        if self.lock_descriptors.keys():

> +            pass_fds = [self.lock_descriptors[lock].fileno() for lock in

> self.lock_descriptors.keys()]

>          process = subprocess.Popen(cmds, stderr=subprocess.PIPE,

> pass_fds=pass_fds)

>          self.qemupid = process.pid

>          retcode = process.wait()

> @@ -1291,7 +1292,8 @@ class BaseConfig(object):

>              cmd = ('sudo', self.qemuifdown, self.tap, self.bindir_native)

>              logger.debug('Running %s' % str(cmd))

>              subprocess.check_call(cmd)

> -        self.release_lock()

> +        for lock in self.lock_descriptors.keys():

> +            self.release_lock(lock)

>

>          if self.nfs_running:

>              logger.info("Shutting down the userspace NFS server...")

> --

> 2.20.1

>

>
<div dir="ltr">I squashed the fix in the wrong patch that&#39;s because the v3 that are no functional changes between v2 and v3.<div><br></div><div>Fixed acquired_lock method to only add the lock when acquire succeed.</div><div><br></div><div>Regards,</div><div>Anibal</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 1 Jul 2019 at 16:23, Aníbal Limón &lt;<a href="mailto:anibal.limon@linaro.org">anibal.limon@linaro.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">In order to support multiple tap devices in the same qemu virtual<br>
machine.<br>
<br>
Signed-off-by: Aníbal Limón &lt;<a href="mailto:anibal.limon@linaro.org" target="_blank">anibal.limon@linaro.org</a>&gt;<br>

---<br>
 scripts/runqemu | 50 +++++++++++++++++++++++++------------------------<br>
 1 file changed, 26 insertions(+), 24 deletions(-)<br>
<br>
diff --git a/scripts/runqemu b/scripts/runqemu<br>
index 4079f2b17d..38dd1c30d9 100755<br>
--- a/scripts/runqemu<br>
+++ b/scripts/runqemu<br>
@@ -181,8 +181,7 @@ class BaseConfig(object):<br>
         self.audio_enabled = False<br>
         self.tcpserial_portnum = &#39;&#39;<br>
         self.custombiosdir = &#39;&#39;<br>
-        self.lock = &#39;&#39;<br>
-        self.lock_descriptor = None<br>
+        self.lock_descriptors = {}<br>
         self.bitbake_e = &#39;&#39;<br>
         self.snapshot = False<br>
         self.wictypes = (&#39;wic&#39;, &#39;wic.vmdk&#39;, &#39;wic.qcow2&#39;, &#39;wic.vdi&#39;)<br>
@@ -204,30 +203,32 @@ class BaseConfig(object):<br>
         # avoid cleanup twice<br>
         self.cleaned = False<br>
<br>
-    def acquire_lock(self, error=True):<br>
-        logger.debug(&quot;Acquiring lockfile %s...&quot; % self.lock)<br>
+    def acquire_lock(self, lock, error=True):<br>
+        logger.debug(&quot;Acquiring lockfile %s...&quot; % lock)<br>
+        descriptor = None<br>
         try:<br>
-            self.lock_descriptor = open(self.lock, &#39;w&#39;)<br>
-            fcntl.flock(self.lock_descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)<br>
+            descriptor = open(lock, &#39;w&#39;)<br>
+            fcntl.flock(descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)<br>
         except Exception as e:<br>
-            msg = &quot;Acquiring lockfile %s failed: %s&quot; % (self.lock, e)<br>
+            msg = &quot;Acquiring lockfile %s failed: %s&quot; % (lock, e)<br>
             if error:<br>
                 logger.error(msg)<br>
             else:<br>
                 <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(msg)<br>
-            if self.lock_descriptor:<br>
-                self.lock_descriptor.close()<br>
-                self.lock_descriptor = None<br>
+            if descriptor:<br>
+                descriptor.close()<br>
+                descriptor = None<br>
             return False<br>
+        self.lock_descriptors[lock] = descriptor<br>
         return True<br>
<br>
-    def release_lock(self):<br>
-        if self.lock_descriptor:<br>
-            logger.debug(&quot;Releasing lockfile for tap device &#39;%s&#39;&quot; % self.tap)<br>
-            fcntl.flock(self.lock_descriptor, fcntl.LOCK_UN)<br>
-            self.lock_descriptor.close()<br>
-            os.remove(self.lock)<br>
-            self.lock_descriptor = None<br>
+    def release_lock(self, lock):<br>
+        if self.lock_descriptors[lock]:<br>
+            logger.debug(&quot;Releasing lockfile for tap device &#39;%s&#39;&quot; % lock)<br>
+            fcntl.flock(self.lock_descriptors[lock], fcntl.LOCK_UN)<br>
+            self.lock_descriptors[lock].close()<br>
+            os.remove(lock)<br>
+            self.lock_descriptors[lock] = None<br>
<br>
     def get(self, key):<br>
         if key in self.d:<br>
@@ -1016,8 +1017,8 @@ class BaseConfig(object):<br>
             if os.path.exists(&#39;%s.skip&#39; % lockfile):<br>
                 <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(&#39;Found %s.skip, skipping %s&#39; % (lockfile, p))<br>
                 continue<br>
-            self.lock = lockfile + &#39;.lock&#39;<br>
-            if self.acquire_lock(error=False):<br>
+            lock = lockfile + &#39;.lock&#39;<br>
+            if self.acquire_lock(lock, error=False):<br>
                 tap = p<br>
                 <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(&quot;Using preconfigured tap device %s&quot; % tap)<br>
                 <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(&quot;If this is not intended, touch %s.skip to make runqemu skip %s.&quot; %(lockfile, tap))<br>
@@ -1035,8 +1036,8 @@ class BaseConfig(object):<br>
             cmd = (&#39;sudo&#39;, self.qemuifup, str(uid), str(gid), self.bindir_native)<br>
             tap = subprocess.check_output(cmd).decode(&#39;utf-8&#39;).strip()<br>
             lockfile = os.path.join(lockdir, tap)<br>
-            self.lock = lockfile + &#39;.lock&#39;<br>
-            self.acquire_lock()<br>
+            lock = lockfile + &#39;.lock&#39;<br>
+            self.acquire_lock(lock)<br>
             self.cleantap = True<br>
             logger.debug(&#39;Created tap: %s&#39; % tap)<br>
<br>
@@ -1268,8 +1269,8 @@ class BaseConfig(object):<br>
         cmds = shlex.split(cmd)<br>
         <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(&#39;Running %s\n&#39; % cmd)<br>
         pass_fds = []<br>
-        if self.lock_descriptor:<br>
-            pass_fds = [self.lock_descriptor.fileno()]<br>
+        if self.lock_descriptors.keys():<br>
+            pass_fds = [self.lock_descriptors[lock].fileno() for lock in self.lock_descriptors.keys()]<br>
         process = subprocess.Popen(cmds, stderr=subprocess.PIPE, pass_fds=pass_fds)<br>
         self.qemupid = process.pid<br>
         retcode = process.wait()<br>
@@ -1291,7 +1292,8 @@ class BaseConfig(object):<br>
             cmd = (&#39;sudo&#39;, self.qemuifdown, self.tap, self.bindir_native)<br>
             logger.debug(&#39;Running %s&#39; % str(cmd))<br>
             subprocess.check_call(cmd)<br>
-        self.release_lock()<br>
+        for lock in self.lock_descriptors.keys():<br>
+            self.release_lock(lock)<br>
<br>
         if self.nfs_running:<br>
             <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(&quot;Shutting down the userspace NFS server...&quot;)<br>
-- <br>
2.20.1<br>
<br>
</blockquote></div>
-- 
_______________________________________________
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core
ChenQi July 3, 2019, 2:19 a.m. | #2
Could you please help check if the following failures are related to 
this patch series?
https://autobuilder.yoctoproject.org/typhoon/#/builders/47/builds/785/steps/7/logs/step1c
https://autobuilder.yoctoproject.org/typhoon/#/builders/63/builds/766/steps/7/logs/step1c

Regards,
Chen Qi

On 07/02/2019 05:23 AM, Aníbal Limón wrote:
> In order to support multiple tap devices in the same qemu virtual
> machine.
>
> Signed-off-by: Aníbal Limón <anibal.limon@linaro.org>
> ---
>   scripts/runqemu | 50 +++++++++++++++++++++++++------------------------
>   1 file changed, 26 insertions(+), 24 deletions(-)
>
> diff --git a/scripts/runqemu b/scripts/runqemu
> index 4079f2b17d..38dd1c30d9 100755
> --- a/scripts/runqemu
> +++ b/scripts/runqemu
> @@ -181,8 +181,7 @@ class BaseConfig(object):
>           self.audio_enabled = False
>           self.tcpserial_portnum = ''
>           self.custombiosdir = ''
> -        self.lock = ''
> -        self.lock_descriptor = None
> +        self.lock_descriptors = {}
>           self.bitbake_e = ''
>           self.snapshot = False
>           self.wictypes = ('wic', 'wic.vmdk', 'wic.qcow2', 'wic.vdi')
> @@ -204,30 +203,32 @@ class BaseConfig(object):
>           # avoid cleanup twice
>           self.cleaned = False
>   
> -    def acquire_lock(self, error=True):
> -        logger.debug("Acquiring lockfile %s..." % self.lock)
> +    def acquire_lock(self, lock, error=True):
> +        logger.debug("Acquiring lockfile %s..." % lock)
> +        descriptor = None
>           try:
> -            self.lock_descriptor = open(self.lock, 'w')
> -            fcntl.flock(self.lock_descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)
> +            descriptor = open(lock, 'w')
> +            fcntl.flock(descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)
>           except Exception as e:
> -            msg = "Acquiring lockfile %s failed: %s" % (self.lock, e)
> +            msg = "Acquiring lockfile %s failed: %s" % (lock, e)
>               if error:
>                   logger.error(msg)
>               else:
>                   logger.info(msg)
> -            if self.lock_descriptor:
> -                self.lock_descriptor.close()
> -                self.lock_descriptor = None
> +            if descriptor:
> +                descriptor.close()
> +                descriptor = None
>               return False
> +        self.lock_descriptors[lock] = descriptor
>           return True
>   
> -    def release_lock(self):
> -        if self.lock_descriptor:
> -            logger.debug("Releasing lockfile for tap device '%s'" % self.tap)
> -            fcntl.flock(self.lock_descriptor, fcntl.LOCK_UN)
> -            self.lock_descriptor.close()
> -            os.remove(self.lock)
> -            self.lock_descriptor = None
> +    def release_lock(self, lock):
> +        if self.lock_descriptors[lock]:
> +            logger.debug("Releasing lockfile for tap device '%s'" % lock)
> +            fcntl.flock(self.lock_descriptors[lock], fcntl.LOCK_UN)
> +            self.lock_descriptors[lock].close()
> +            os.remove(lock)
> +            self.lock_descriptors[lock] = None
>   
>       def get(self, key):
>           if key in self.d:
> @@ -1016,8 +1017,8 @@ class BaseConfig(object):
>               if os.path.exists('%s.skip' % lockfile):
>                   logger.info('Found %s.skip, skipping %s' % (lockfile, p))
>                   continue
> -            self.lock = lockfile + '.lock'
> -            if self.acquire_lock(error=False):
> +            lock = lockfile + '.lock'
> +            if self.acquire_lock(lock, error=False):
>                   tap = p
>                   logger.info("Using preconfigured tap device %s" % tap)
>                   logger.info("If this is not intended, touch %s.skip to make runqemu skip %s." %(lockfile, tap))
> @@ -1035,8 +1036,8 @@ class BaseConfig(object):
>               cmd = ('sudo', self.qemuifup, str(uid), str(gid), self.bindir_native)
>               tap = subprocess.check_output(cmd).decode('utf-8').strip()
>               lockfile = os.path.join(lockdir, tap)
> -            self.lock = lockfile + '.lock'
> -            self.acquire_lock()
> +            lock = lockfile + '.lock'
> +            self.acquire_lock(lock)
>               self.cleantap = True
>               logger.debug('Created tap: %s' % tap)
>   
> @@ -1268,8 +1269,8 @@ class BaseConfig(object):
>           cmds = shlex.split(cmd)
>           logger.info('Running %s\n' % cmd)
>           pass_fds = []
> -        if self.lock_descriptor:
> -            pass_fds = [self.lock_descriptor.fileno()]
> +        if self.lock_descriptors.keys():
> +            pass_fds = [self.lock_descriptors[lock].fileno() for lock in self.lock_descriptors.keys()]
>           process = subprocess.Popen(cmds, stderr=subprocess.PIPE, pass_fds=pass_fds)
>           self.qemupid = process.pid
>           retcode = process.wait()
> @@ -1291,7 +1292,8 @@ class BaseConfig(object):
>               cmd = ('sudo', self.qemuifdown, self.tap, self.bindir_native)
>               logger.debug('Running %s' % str(cmd))
>               subprocess.check_call(cmd)
> -        self.release_lock()
> +        for lock in self.lock_descriptors.keys():
> +            self.release_lock(lock)
>   
>           if self.nfs_running:
>               logger.info("Shutting down the userspace NFS server...")
Anibal Limon July 3, 2019, 2:21 p.m. | #3
Hi Chen,

Thanks for report, may be related to the name of the NIC inside qemu. I
will investigate.

Regards!,
Anibal

On Tue, 2 Jul 2019 at 21:08, ChenQi <Qi.Chen@windriver.com> wrote:

> Could you please help check if the following failures are related to

> this patch series?

>

> https://autobuilder.yoctoproject.org/typhoon/#/builders/47/builds/785/steps/7/logs/step1c

>

> https://autobuilder.yoctoproject.org/typhoon/#/builders/63/builds/766/steps/7/logs/step1c

>

> Regards,

> Chen Qi

>

> On 07/02/2019 05:23 AM, Aníbal Limón wrote:

> > In order to support multiple tap devices in the same qemu virtual

> > machine.

> >

> > Signed-off-by: Aníbal Limón <anibal.limon@linaro.org>

> > ---

> >   scripts/runqemu | 50 +++++++++++++++++++++++++------------------------

> >   1 file changed, 26 insertions(+), 24 deletions(-)

> >

> > diff --git a/scripts/runqemu b/scripts/runqemu

> > index 4079f2b17d..38dd1c30d9 100755

> > --- a/scripts/runqemu

> > +++ b/scripts/runqemu

> > @@ -181,8 +181,7 @@ class BaseConfig(object):

> >           self.audio_enabled = False

> >           self.tcpserial_portnum = ''

> >           self.custombiosdir = ''

> > -        self.lock = ''

> > -        self.lock_descriptor = None

> > +        self.lock_descriptors = {}

> >           self.bitbake_e = ''

> >           self.snapshot = False

> >           self.wictypes = ('wic', 'wic.vmdk', 'wic.qcow2', 'wic.vdi')

> > @@ -204,30 +203,32 @@ class BaseConfig(object):

> >           # avoid cleanup twice

> >           self.cleaned = False

> >

> > -    def acquire_lock(self, error=True):

> > -        logger.debug("Acquiring lockfile %s..." % self.lock)

> > +    def acquire_lock(self, lock, error=True):

> > +        logger.debug("Acquiring lockfile %s..." % lock)

> > +        descriptor = None

> >           try:

> > -            self.lock_descriptor = open(self.lock, 'w')

> > -            fcntl.flock(self.lock_descriptor,

> fcntl.LOCK_EX|fcntl.LOCK_NB)

> > +            descriptor = open(lock, 'w')

> > +            fcntl.flock(descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)

> >           except Exception as e:

> > -            msg = "Acquiring lockfile %s failed: %s" % (self.lock, e)

> > +            msg = "Acquiring lockfile %s failed: %s" % (lock, e)

> >               if error:

> >                   logger.error(msg)

> >               else:

> >                   logger.info(msg)

> > -            if self.lock_descriptor:

> > -                self.lock_descriptor.close()

> > -                self.lock_descriptor = None

> > +            if descriptor:

> > +                descriptor.close()

> > +                descriptor = None

> >               return False

> > +        self.lock_descriptors[lock] = descriptor

> >           return True

> >

> > -    def release_lock(self):

> > -        if self.lock_descriptor:

> > -            logger.debug("Releasing lockfile for tap device '%s'" %

> self.tap)

> > -            fcntl.flock(self.lock_descriptor, fcntl.LOCK_UN)

> > -            self.lock_descriptor.close()

> > -            os.remove(self.lock)

> > -            self.lock_descriptor = None

> > +    def release_lock(self, lock):

> > +        if self.lock_descriptors[lock]:

> > +            logger.debug("Releasing lockfile for tap device '%s'" %

> lock)

> > +            fcntl.flock(self.lock_descriptors[lock], fcntl.LOCK_UN)

> > +            self.lock_descriptors[lock].close()

> > +            os.remove(lock)

> > +            self.lock_descriptors[lock] = None

> >

> >       def get(self, key):

> >           if key in self.d:

> > @@ -1016,8 +1017,8 @@ class BaseConfig(object):

> >               if os.path.exists('%s.skip' % lockfile):

> >                   logger.info('Found %s.skip, skipping %s' % (lockfile,

> p))

> >                   continue

> > -            self.lock = lockfile + '.lock'

> > -            if self.acquire_lock(error=False):

> > +            lock = lockfile + '.lock'

> > +            if self.acquire_lock(lock, error=False):

> >                   tap = p

> >                   logger.info("Using preconfigured tap device %s" % tap)

> >                   logger.info("If this is not intended, touch %s.skip

> to make runqemu skip %s." %(lockfile, tap))

> > @@ -1035,8 +1036,8 @@ class BaseConfig(object):

> >               cmd = ('sudo', self.qemuifup, str(uid), str(gid),

> self.bindir_native)

> >               tap = subprocess.check_output(cmd).decode('utf-8').strip()

> >               lockfile = os.path.join(lockdir, tap)

> > -            self.lock = lockfile + '.lock'

> > -            self.acquire_lock()

> > +            lock = lockfile + '.lock'

> > +            self.acquire_lock(lock)

> >               self.cleantap = True

> >               logger.debug('Created tap: %s' % tap)

> >

> > @@ -1268,8 +1269,8 @@ class BaseConfig(object):

> >           cmds = shlex.split(cmd)

> >           logger.info('Running %s\n' % cmd)

> >           pass_fds = []

> > -        if self.lock_descriptor:

> > -            pass_fds = [self.lock_descriptor.fileno()]

> > +        if self.lock_descriptors.keys():

> > +            pass_fds = [self.lock_descriptors[lock].fileno() for lock

> in self.lock_descriptors.keys()]

> >           process = subprocess.Popen(cmds, stderr=subprocess.PIPE,

> pass_fds=pass_fds)

> >           self.qemupid = process.pid

> >           retcode = process.wait()

> > @@ -1291,7 +1292,8 @@ class BaseConfig(object):

> >               cmd = ('sudo', self.qemuifdown, self.tap,

> self.bindir_native)

> >               logger.debug('Running %s' % str(cmd))

> >               subprocess.check_call(cmd)

> > -        self.release_lock()

> > +        for lock in self.lock_descriptors.keys():

> > +            self.release_lock(lock)

> >

> >           if self.nfs_running:

> >               logger.info("Shutting down the userspace NFS server...")

>

>

>
<div dir="ltr">Hi Chen,<div><br></div><div>Thanks for report, may be related to the name of the NIC inside qemu. I will investigate.</div><div><br></div><div>Regards!,</div><div>Anibal</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 2 Jul 2019 at 21:08, ChenQi &lt;<a href="mailto:Qi.Chen@windriver.com">Qi.Chen@windriver.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Could you please help check if the following failures are related to <br>
this patch series?<br>
<a href="https://autobuilder.yoctoproject.org/typhoon/#/builders/47/builds/785/steps/7/logs/step1c" rel="noreferrer" target="_blank">https://autobuilder.yoctoproject.org/typhoon/#/builders/47/builds/785/steps/7/logs/step1c</a><br>
<a href="https://autobuilder.yoctoproject.org/typhoon/#/builders/63/builds/766/steps/7/logs/step1c" rel="noreferrer" target="_blank">https://autobuilder.yoctoproject.org/typhoon/#/builders/63/builds/766/steps/7/logs/step1c</a><br>
<br>
Regards,<br>
Chen Qi<br>
<br>
On 07/02/2019 05:23 AM, Aníbal Limón wrote:<br>
&gt; In order to support multiple tap devices in the same qemu virtual<br>
&gt; machine.<br>
&gt;<br>
&gt; Signed-off-by: Aníbal Limón &lt;<a href="mailto:anibal.limon@linaro.org" target="_blank">anibal.limon@linaro.org</a>&gt;<br>
&gt; ---<br>
&gt;   scripts/runqemu | 50 +++++++++++++++++++++++++------------------------<br>
&gt;   1 file changed, 26 insertions(+), 24 deletions(-)<br>
&gt;<br>
&gt; diff --git a/scripts/runqemu b/scripts/runqemu<br>
&gt; index 4079f2b17d..38dd1c30d9 100755<br>
&gt; --- a/scripts/runqemu<br>
&gt; +++ b/scripts/runqemu<br>
&gt; @@ -181,8 +181,7 @@ class BaseConfig(object):<br>
&gt;           self.audio_enabled = False<br>
&gt;           self.tcpserial_portnum = &#39;&#39;<br>
&gt;           self.custombiosdir = &#39;&#39;<br>
&gt; -        self.lock = &#39;&#39;<br>
&gt; -        self.lock_descriptor = None<br>
&gt; +        self.lock_descriptors = {}<br>
&gt;           self.bitbake_e = &#39;&#39;<br>
&gt;           self.snapshot = False<br>
&gt;           self.wictypes = (&#39;wic&#39;, &#39;wic.vmdk&#39;, &#39;wic.qcow2&#39;, &#39;wic.vdi&#39;)<br>
&gt; @@ -204,30 +203,32 @@ class BaseConfig(object):<br>
&gt;           # avoid cleanup twice<br>
&gt;           self.cleaned = False<br>
&gt;   <br>
&gt; -    def acquire_lock(self, error=True):<br>
&gt; -        logger.debug(&quot;Acquiring lockfile %s...&quot; % self.lock)<br>
&gt; +    def acquire_lock(self, lock, error=True):<br>
&gt; +        logger.debug(&quot;Acquiring lockfile %s...&quot; % lock)<br>
&gt; +        descriptor = None<br>
&gt;           try:<br>
&gt; -            self.lock_descriptor = open(self.lock, &#39;w&#39;)<br>
&gt; -            fcntl.flock(self.lock_descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)<br>
&gt; +            descriptor = open(lock, &#39;w&#39;)<br>
&gt; +            fcntl.flock(descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)<br>
&gt;           except Exception as e:<br>
&gt; -            msg = &quot;Acquiring lockfile %s failed: %s&quot; % (self.lock, e)<br>
&gt; +            msg = &quot;Acquiring lockfile %s failed: %s&quot; % (lock, e)<br>
&gt;               if error:<br>
&gt;                   logger.error(msg)<br>
&gt;               else:<br>
&gt;                   <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(msg)<br>
&gt; -            if self.lock_descriptor:<br>
&gt; -                self.lock_descriptor.close()<br>
&gt; -                self.lock_descriptor = None<br>
&gt; +            if descriptor:<br>
&gt; +                descriptor.close()<br>
&gt; +                descriptor = None<br>
&gt;               return False<br>
&gt; +        self.lock_descriptors[lock] = descriptor<br>
&gt;           return True<br>
&gt;   <br>
&gt; -    def release_lock(self):<br>
&gt; -        if self.lock_descriptor:<br>
&gt; -            logger.debug(&quot;Releasing lockfile for tap device &#39;%s&#39;&quot; % self.tap)<br>
&gt; -            fcntl.flock(self.lock_descriptor, fcntl.LOCK_UN)<br>
&gt; -            self.lock_descriptor.close()<br>
&gt; -            os.remove(self.lock)<br>
&gt; -            self.lock_descriptor = None<br>
&gt; +    def release_lock(self, lock):<br>
&gt; +        if self.lock_descriptors[lock]:<br>
&gt; +            logger.debug(&quot;Releasing lockfile for tap device &#39;%s&#39;&quot; % lock)<br>
&gt; +            fcntl.flock(self.lock_descriptors[lock], fcntl.LOCK_UN)<br>
&gt; +            self.lock_descriptors[lock].close()<br>
&gt; +            os.remove(lock)<br>
&gt; +            self.lock_descriptors[lock] = None<br>
&gt;   <br>
&gt;       def get(self, key):<br>
&gt;           if key in self.d:<br>
&gt; @@ -1016,8 +1017,8 @@ class BaseConfig(object):<br>
&gt;               if os.path.exists(&#39;%s.skip&#39; % lockfile):<br>
&gt;                   <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(&#39;Found %s.skip, skipping %s&#39; % (lockfile, p))<br>
&gt;                   continue<br>
&gt; -            self.lock = lockfile + &#39;.lock&#39;<br>
&gt; -            if self.acquire_lock(error=False):<br>
&gt; +            lock = lockfile + &#39;.lock&#39;<br>
&gt; +            if self.acquire_lock(lock, error=False):<br>
&gt;                   tap = p<br>
&gt;                   <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(&quot;Using preconfigured tap device %s&quot; % tap)<br>
&gt;                   <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(&quot;If this is not intended, touch %s.skip to make runqemu skip %s.&quot; %(lockfile, tap))<br>
&gt; @@ -1035,8 +1036,8 @@ class BaseConfig(object):<br>
&gt;               cmd = (&#39;sudo&#39;, self.qemuifup, str(uid), str(gid), self.bindir_native)<br>
&gt;               tap = subprocess.check_output(cmd).decode(&#39;utf-8&#39;).strip()<br>
&gt;               lockfile = os.path.join(lockdir, tap)<br>
&gt; -            self.lock = lockfile + &#39;.lock&#39;<br>
&gt; -            self.acquire_lock()<br>
&gt; +            lock = lockfile + &#39;.lock&#39;<br>
&gt; +            self.acquire_lock(lock)<br>
&gt;               self.cleantap = True<br>
&gt;               logger.debug(&#39;Created tap: %s&#39; % tap)<br>
&gt;   <br>
&gt; @@ -1268,8 +1269,8 @@ class BaseConfig(object):<br>
&gt;           cmds = shlex.split(cmd)<br>
&gt;           <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(&#39;Running %s\n&#39; % cmd)<br>
&gt;           pass_fds = []<br>
&gt; -        if self.lock_descriptor:<br>
&gt; -            pass_fds = [self.lock_descriptor.fileno()]<br>
&gt; +        if self.lock_descriptors.keys():<br>
&gt; +            pass_fds = [self.lock_descriptors[lock].fileno() for lock in self.lock_descriptors.keys()]<br>
&gt;           process = subprocess.Popen(cmds, stderr=subprocess.PIPE, pass_fds=pass_fds)<br>
&gt;           self.qemupid = process.pid<br>
&gt;           retcode = process.wait()<br>
&gt; @@ -1291,7 +1292,8 @@ class BaseConfig(object):<br>
&gt;               cmd = (&#39;sudo&#39;, self.qemuifdown, self.tap, self.bindir_native)<br>
&gt;               logger.debug(&#39;Running %s&#39; % str(cmd))<br>
&gt;               subprocess.check_call(cmd)<br>
&gt; -        self.release_lock()<br>
&gt; +        for lock in self.lock_descriptors.keys():<br>
&gt; +            self.release_lock(lock)<br>
&gt;   <br>
&gt;           if self.nfs_running:<br>
&gt;               <a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(&quot;Shutting down the userspace NFS server...&quot;)<br>
<br>
<br>
</blockquote></div>
-- 
_______________________________________________
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core

Patch

diff --git a/scripts/runqemu b/scripts/runqemu
index 4079f2b17d..38dd1c30d9 100755
--- a/scripts/runqemu
+++ b/scripts/runqemu
@@ -181,8 +181,7 @@  class BaseConfig(object):
         self.audio_enabled = False
         self.tcpserial_portnum = ''
         self.custombiosdir = ''
-        self.lock = ''
-        self.lock_descriptor = None
+        self.lock_descriptors = {}
         self.bitbake_e = ''
         self.snapshot = False
         self.wictypes = ('wic', 'wic.vmdk', 'wic.qcow2', 'wic.vdi')
@@ -204,30 +203,32 @@  class BaseConfig(object):
         # avoid cleanup twice
         self.cleaned = False
 
-    def acquire_lock(self, error=True):
-        logger.debug("Acquiring lockfile %s..." % self.lock)
+    def acquire_lock(self, lock, error=True):
+        logger.debug("Acquiring lockfile %s..." % lock)
+        descriptor = None
         try:
-            self.lock_descriptor = open(self.lock, 'w')
-            fcntl.flock(self.lock_descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)
+            descriptor = open(lock, 'w')
+            fcntl.flock(descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)
         except Exception as e:
-            msg = "Acquiring lockfile %s failed: %s" % (self.lock, e)
+            msg = "Acquiring lockfile %s failed: %s" % (lock, e)
             if error:
                 logger.error(msg)
             else:
                 logger.info(msg)
-            if self.lock_descriptor:
-                self.lock_descriptor.close()
-                self.lock_descriptor = None
+            if descriptor:
+                descriptor.close()
+                descriptor = None
             return False
+        self.lock_descriptors[lock] = descriptor
         return True
 
-    def release_lock(self):
-        if self.lock_descriptor:
-            logger.debug("Releasing lockfile for tap device '%s'" % self.tap)
-            fcntl.flock(self.lock_descriptor, fcntl.LOCK_UN)
-            self.lock_descriptor.close()
-            os.remove(self.lock)
-            self.lock_descriptor = None
+    def release_lock(self, lock):
+        if self.lock_descriptors[lock]:
+            logger.debug("Releasing lockfile for tap device '%s'" % lock)
+            fcntl.flock(self.lock_descriptors[lock], fcntl.LOCK_UN)
+            self.lock_descriptors[lock].close()
+            os.remove(lock)
+            self.lock_descriptors[lock] = None
 
     def get(self, key):
         if key in self.d:
@@ -1016,8 +1017,8 @@  class BaseConfig(object):
             if os.path.exists('%s.skip' % lockfile):
                 logger.info('Found %s.skip, skipping %s' % (lockfile, p))
                 continue
-            self.lock = lockfile + '.lock'
-            if self.acquire_lock(error=False):
+            lock = lockfile + '.lock'
+            if self.acquire_lock(lock, error=False):
                 tap = p
                 logger.info("Using preconfigured tap device %s" % tap)
                 logger.info("If this is not intended, touch %s.skip to make runqemu skip %s." %(lockfile, tap))
@@ -1035,8 +1036,8 @@  class BaseConfig(object):
             cmd = ('sudo', self.qemuifup, str(uid), str(gid), self.bindir_native)
             tap = subprocess.check_output(cmd).decode('utf-8').strip()
             lockfile = os.path.join(lockdir, tap)
-            self.lock = lockfile + '.lock'
-            self.acquire_lock()
+            lock = lockfile + '.lock'
+            self.acquire_lock(lock)
             self.cleantap = True
             logger.debug('Created tap: %s' % tap)
 
@@ -1268,8 +1269,8 @@  class BaseConfig(object):
         cmds = shlex.split(cmd)
         logger.info('Running %s\n' % cmd)
         pass_fds = []
-        if self.lock_descriptor:
-            pass_fds = [self.lock_descriptor.fileno()]
+        if self.lock_descriptors.keys():
+            pass_fds = [self.lock_descriptors[lock].fileno() for lock in self.lock_descriptors.keys()]
         process = subprocess.Popen(cmds, stderr=subprocess.PIPE, pass_fds=pass_fds)
         self.qemupid = process.pid
         retcode = process.wait()
@@ -1291,7 +1292,8 @@  class BaseConfig(object):
             cmd = ('sudo', self.qemuifdown, self.tap, self.bindir_native)
             logger.debug('Running %s' % str(cmd))
             subprocess.check_call(cmd)
-        self.release_lock()
+        for lock in self.lock_descriptors.keys():
+            self.release_lock(lock)
 
         if self.nfs_running:
             logger.info("Shutting down the userspace NFS server...")