gns3-qemu-config - QEMU config disk
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
4.6KB

  1. From c2e829749c08157d4dc9611620e2a59e2cea0971 Mon Sep 17 00:00:00 2001
  2. From: Bernhard Ehlers <none@bernhard-ehlers.de>
  3. Date: Wed, 15 Apr 2020 20:50:59 +0200
  4. Subject: [PATCH 3/4] QEMU config disk - get rid of mtoolsrc
  5. ---
  6. gns3server/compute/qemu/qemu_vm.py | 43 +++++++++++++++++++++++---------------
  7. 1 file changed, 26 insertions(+), 17 deletions(-)
  8. diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py
  9. index 0b08df7e..f4a9aa9c 100644
  10. --- a/gns3server/compute/qemu/qemu_vm.py
  11. +++ b/gns3server/compute/qemu/qemu_vm.py
  12. @@ -26,6 +26,7 @@ import re
  13. import shlex
  14. import math
  15. import shutil
  16. +import struct
  17. import asyncio
  18. import socket
  19. import gns3server
  20. @@ -1597,11 +1598,26 @@ class QemuVM(BaseNode):
  21. log.info("{} returned with {}".format(self._get_qemu_img(), retcode))
  22. return retcode
  23. - async def _mcopy(self, *args):
  24. - env = os.environ
  25. - env["MTOOLSRC"] = 'mtoolsrc'
  26. + async def _mcopy(self, image, *args):
  27. try:
  28. - process = await asyncio.create_subprocess_exec("mcopy", *args, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.working_dir, env=env)
  29. + # read offset of first partition from MBR
  30. + with open(image, "rb") as img_file:
  31. + mbr = img_file.read(512)
  32. + part_type, offset, signature = struct.unpack("<450xB3xL52xH", mbr)
  33. + if signature != 0xAA55:
  34. + log.error("mcopy failure: {}: invalid MBR".format(image))
  35. + return 1
  36. + if part_type not in (1, 4, 6, 11, 12, 14):
  37. + log.error("mcopy failure: {}: invalid partition type {:02X}"
  38. + .format(image, part_type))
  39. + return 1
  40. + part_image = image + "@@{}S".format(offset)
  41. +
  42. + process = await asyncio.create_subprocess_exec(
  43. + "mcopy", "-i", part_image, *args,
  44. + stdin=subprocess.DEVNULL,
  45. + stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
  46. + cwd=self.working_dir)
  47. (stdout, _) = await process.communicate()
  48. retcode = process.returncode
  49. except (OSError, subprocess.SubprocessError) as e:
  50. @@ -1617,8 +1633,10 @@ class QemuVM(BaseNode):
  51. async def _export_config(self):
  52. disk_name = getattr(self, "config_disk_name")
  53. - if not disk_name or \
  54. - not os.path.exists(os.path.join(self.working_dir, disk_name)):
  55. + if not disk_name:
  56. + return
  57. + disk = os.path.join(self.working_dir, disk_name)
  58. + if not os.path.exists(disk):
  59. return
  60. config_dir = os.path.join(self.working_dir, "configs")
  61. zip_file = os.path.join(self.working_dir, "config.zip")
  62. @@ -1627,7 +1645,7 @@ class QemuVM(BaseNode):
  63. os.mkdir(config_dir)
  64. if os.path.exists(zip_file):
  65. os.remove(zip_file)
  66. - if await self._mcopy("-s", "-m", "-n", "--", "x:/", config_dir) == 0:
  67. + if await self._mcopy(disk, "-s", "-m", "-n", "--", "::/", config_dir) == 0:
  68. pack_zip(zip_file, config_dir)
  69. except OSError as e:
  70. log.error("Can't export config: {}".format(e))
  71. @@ -1649,7 +1667,7 @@ class QemuVM(BaseNode):
  72. config_files = [os.path.join(config_dir, fname)
  73. for fname in os.listdir(config_dir)]
  74. if config_files:
  75. - if await self._mcopy("-s", "-m", "-o", "--", *config_files, "x:/") != 0:
  76. + if await self._mcopy(disk, "-s", "-m", "-o", "--", *config_files, "::/") != 0:
  77. os.remove(disk)
  78. os.remove(zip_file)
  79. except OSError as e:
  80. @@ -1764,15 +1782,6 @@ class QemuVM(BaseNode):
  81. shutil.copyfile(disk_image, disk)
  82. except OSError as e:
  83. raise QemuError("Could not create '{}' disk image: {}".format(disk_name, e))
  84. - mtoolsrc = os.path.join(self.working_dir, "mtoolsrc")
  85. - if not os.path.exists(mtoolsrc):
  86. - try:
  87. - with open(mtoolsrc, 'w') as outfile:
  88. - outfile.write('drive x:\n')
  89. - outfile.write(' file="{}"\n'.format(disk))
  90. - outfile.write(' partition=1\n')
  91. - except OSError as e:
  92. - raise QemuError("Could not create 'mtoolsrc': {}".format(e))
  93. options.extend(self._disk_interface_options(disk, 3, interface, "raw"))
  94. return options
  95. --
  96. 2.15.1 (Apple Git-101)