Merge pull request #61 from marcosps/mpdesouza_blk-disks

run.py: Add blk-disks argument
diff --git a/bin/virtme-prep-kdir-mods b/bin/virtme-prep-kdir-mods
index d34e280..dd80ad5 100755
--- a/bin/virtme-prep-kdir-mods
+++ b/bin/virtme-prep-kdir-mods
@@ -1,12 +1,6 @@
 #!/bin/sh
 
 # This is still a bit of an experiment.
-
-if ! [ -f modules.order ]; then
-    echo 'virtme-prep-kdir-mods must be run from a kernel build directory' >&2
-    exit 1
-fi
-
 FAKEVER=0.0.0
 MODDIR=".virtme_mods/lib/modules/$FAKEVER"
 
@@ -16,6 +10,7 @@
 PATH=$PATH:/sbin:/usr/sbin
 
 if ! [ -f "modules.order" ]; then
+    echo 'virtme-prep-kdir-mods must be run from a kernel build directory' >&2
     echo "modules.order is missing.  Your kernel may be too old or you didn't make modules." >&2
     exit 1
 fi
diff --git a/virtme-configkernel b/virtme-configkernel
index cdeb06b..7e84d4b 100755
--- a/virtme-configkernel
+++ b/virtme-configkernel
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
 # -*- mode: python -*-
 # virtme-configkernel: Configure a kernel for virtme
 # Copyright © 2014 Andy Lutomirski
diff --git a/virtme-mkinitramfs b/virtme-mkinitramfs
index ed62d14..3e06732 100755
--- a/virtme-mkinitramfs
+++ b/virtme-mkinitramfs
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
 # -*- mode: python -*-
 # virtme-mkinitramfs: Generate an initramfs image for virtme
 # Copyright © 2019 Marcos Paulo de Souza
diff --git a/virtme-run b/virtme-run
index d472f81..ac6231a 100755
--- a/virtme-run
+++ b/virtme-run
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
 # -*- mode: python -*-
 # virtme-run: The main command-line virtme frontend
 # Copyright © 2014 Andy Lutomirski
diff --git a/virtme/architectures.py b/virtme/architectures.py
index 35bd338..c284416 100644
--- a/virtme/architectures.py
+++ b/virtme/architectures.py
@@ -6,9 +6,10 @@
 # 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643
 
 import os
+from typing import List, Optional
 
 class Arch(object):
-    def __init__(self, name):
+    def __init__(self, name) -> None:
         self.virtmename = name
         self.qemuname = name
         self.linuxname = name
@@ -17,40 +18,40 @@
     defconfig_target = 'defconfig'
 
     @staticmethod
-    def serial_dev_name(index):
+    def serial_dev_name(index) -> str:
         return 'ttyS%d' % index
 
     @staticmethod
-    def qemuargs(is_native):
+    def qemuargs(is_native) -> List[str]:
         return []
 
     @staticmethod
-    def virtio_dev_type(virtiotype):
+    def virtio_dev_type(virtiotype) -> str:
         # Return a full name for a virtio device.  It would be
         # nice if QEMU abstracted this away, but it doesn't.
         return 'virtio-%s-pci' % virtiotype
 
     @staticmethod
-    def earlyconsole_args():
+    def earlyconsole_args() -> List[str]:
         return []
 
     @staticmethod
-    def serial_console_args():
+    def serial_console_args() -> List[str]:
         return []
 
     @staticmethod
-    def qemu_nodisplay_args():
+    def qemu_nodisplay_args() -> List[str]:
         return ['-vga', 'none', '-display', 'none']
 
     @staticmethod
-    def config_base():
+    def config_base() -> List[str]:
         return []
 
-    def kimg_path(self):
+    def kimg_path(self) -> str:
         return 'arch/%s/boot/bzImage' % self.linuxname
 
     @staticmethod
-    def dtb_path():
+    def dtb_path() -> Optional[str]:
         return None
 
 class Arch_unknown(Arch):
@@ -294,7 +295,7 @@
     Arch_s390x(),
 ]}
 
-def get(arch):
+def get(arch: str) -> Arch:
     if arch in ARCHES:
         return ARCHES[arch]
     else:
diff --git a/virtme/commands/configkernel.py b/virtme/commands/configkernel.py
index 8199294..043e720 100644
--- a/virtme/commands/configkernel.py
+++ b/virtme/commands/configkernel.py
@@ -72,6 +72,7 @@
     'CONFIG_VT=y',
     'CONFIG_UNIX98_PTYS=y',
     'CONFIG_EARLY_PRINTK=y',
+    'CONFIG_INOTIFY_USER=y',
     '',
     '# virtio-scsi support',
     'CONFIG_BLOCK=y',
diff --git a/virtme/commands/run.py b/virtme/commands/run.py
index d4c3233..d900b41 100644
--- a/virtme/commands/run.py
+++ b/virtme/commands/run.py
@@ -238,13 +238,16 @@
 
     return kernel
 
-def export_virtfs(qemu, arch, qemuargs, path, mount_tag, security_model='none', readonly=True) -> None:
+def export_virtfs(qemu: qemu_helpers.Qemu, arch: architectures.Arch,
+                  qemuargs: List[str], path: str,
+                  mount_tag: str, security_model='none', readonly=True) -> None:
     # NB: We can't use -virtfs for this, because it can't handle a mount_tag
     # that isn't a valid QEMU identifier.
     fsid = 'virtfs%d' % len(qemuargs)
-    qemuargs.extend(['-fsdev', 'local,id=%s,path=%s,security_model=%s%s' %
+    qemuargs.extend(['-fsdev', 'local,id=%s,path=%s,security_model=%s%s%s' %
                      (fsid, qemu.quote_optarg(path),
-                      security_model, ',readonly' if readonly else '')])
+                      security_model, ',readonly' if readonly else '',
+                      ',multidevs=remap' if qemu.has_multidevs else '')])
     qemuargs.extend(['-device', '%s,fsdev=%s,mount_tag=%s' % (arch.virtio_dev_type('9p'), fsid, qemu.quote_optarg(mount_tag))])
 
 def quote_karg(arg: str) -> str:
@@ -430,7 +433,7 @@
 
     has_script = False
 
-    def do_script(shellcmd, use_exec=False, show_boot_console=False):
+    def do_script(shellcmd: str, use_exec=False, show_boot_console=False) -> None:
         if args.graphics:
             arg_fail('scripts and --graphics are mutually exclusive')
 
diff --git a/virtme/qemu_helpers.py b/virtme/qemu_helpers.py
index 8ddc3dd..96ed693 100644
--- a/virtme/qemu_helpers.py
+++ b/virtme/qemu_helpers.py
@@ -9,9 +9,13 @@
 import re
 import shutil
 import subprocess
+from typing import Optional
 
 class Qemu(object):
-    def __init__(self, arch):
+    qemubin: str
+    version: Optional[str]
+
+    def __init__(self, arch) -> None:
         self.arch = arch
 
         qemubin = shutil.which('qemu-system-%s' % arch)
@@ -23,14 +27,18 @@
         self.qemubin = qemubin
         self.version = None
 
-    def probe(self):
+    def probe(self) -> None:
         if self.version is None:
             self.version = subprocess.check_output([self.qemubin, '--version'])\
                                      .decode('utf-8')
             self.cannot_overmount_virtfs = (
                 re.search(r'version 1\.[012345]', self.version) is not None)
 
-    def quote_optarg(self, a):
+            # QEMU 4.2+ supports -fsdev multidevs=remap
+            self.has_multidevs = (
+                re.search(r'version (?:1\.|2\.|3\.|4\.[01][^\d])', self.version) is None)
+
+    def quote_optarg(self, a: str) -> str:
         """Quote an argument to an option."""
         return a.replace(',', ',,')