Skip to content

Commit 3377bf0

Browse files
committed
boot: fix merge conflict between debug- and solo5 flags
2 parents 5008fce + 1dc40d3 commit 3377bf0

3 files changed

Lines changed: 152 additions & 38 deletions

File tree

etc/boot

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ parser.add_argument('vm_location', action="store", type = str, default=".",
6767
parser.add_argument("-d", "--debug", dest="debug", action="store_true",
6868
help="Start hypervisor in debug mode if available")
6969

70+
parser.add_argument("--with-solo5", dest="solo5", action="store_true",
71+
help="Run includeOS on solo5 kernel with ukvm-bin as monitor")
72+
7073
parser.add_argument('vmargs', nargs='*', help="Arguments to pass on to the VM start / main")
7174

7275
args = parser.parse_args()
@@ -153,7 +156,17 @@ if args.config:
153156
config = os.path.abspath(args.config)
154157
if VERB: print INFO, "Using config file", config
155158

156-
vm = vmrunner.vm(config = config)
159+
hyper_name = "qemu"
160+
if args.solo5:
161+
hyper_name = "ukvm"
162+
os.environ['PLATFORM'] = "x86_solo5"
163+
qkvm_bin = INCLUDEOS_PREFIX + "/includeos/x86_64/lib/ukvm-bin"
164+
165+
subprocess.call(['touch', INCLUDEOS_PREFIX + 'dummy.disk'])
166+
subprocess.call(['chmod', '+x', qkvm_bin])
167+
subprocess.call(['sudo', INCLUDEOS_PREFIX + "/includeos/scripts/ukvm-ifup.sh" ])
168+
169+
vm = vmrunner.vm(config = config, hyper_name = hyper_name)
157170

158171
# Don't listen to events needed by testrunner
159172
vm.on_success(lambda(x): None, do_exit = False)

test_ukvm.sh

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,6 @@ fi
1212

1313
pushd examples/demo_service
1414
mkdir -p build
15-
pushd build
16-
PLATFORM=x86_solo5 cmake ..
17-
make
15+
boot --with-solo5 .
1816
popd
19-
popd
20-
21-
echo -e "Build complete \n"
22-
echo -e "Starting VM with ukvm/solo5. "
23-
24-
# The default ukvm-bin needs a disk, even if it's a dummy 0 byte one.
25-
# If you want ukvm-bin with just the net module, you need to re-build it.
26-
touch dummy.disk
27-
28-
# Create a tap100 device
29-
sudo ./etc/scripts/ukvm-ifup.sh
30-
31-
# XXX: fix this during installation
32-
chmod +x ./build_x86_64/precompiled/src/solo5_repo/ukvm/ukvm-bin
33-
34-
# XXX: should be using the installation directory instead
35-
sudo ./build_x86_64/precompiled/src/solo5_repo/ukvm/ukvm-bin --disk=dummy.disk --net=tap100 ./examples/demo_service/build/IncludeOS_example
36-
3717
trap - EXIT

vmrunner/vmrunner.py

Lines changed: 137 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,136 @@ def name(self):
180180
def image_name(self):
181181
abstract()
182182

183+
def start_process(self, cmdlist):
184+
185+
if cmdlist[0] == "sudo": # and have_sudo():
186+
print color.WARNING("Running with sudo")
187+
self._sudo = True
188+
189+
# Start a subprocess
190+
self._proc = subprocess.Popen(cmdlist,
191+
stdout = subprocess.PIPE,
192+
stderr = subprocess.PIPE,
193+
stdin = subprocess.PIPE)
194+
195+
return self._proc
196+
197+
198+
# Ukvm Hypervisor interface
199+
class ukvm(hypervisor):
200+
201+
def __init__(self, config):
202+
# config is not yet used for ukvm
203+
super(ukvm, self).__init__(config)
204+
self._proc = None
205+
self._stopped = False
206+
self._sudo = False
207+
self._image_name = self._config if "image" in self._config else self.name() + " vm"
208+
209+
# Pretty printing
210+
self.info = Logger(color.INFO("<" + type(self).__name__ + ">"))
211+
212+
def name(self):
213+
return "Ukvm"
214+
215+
def image_name(self):
216+
return self._image_name
217+
218+
def drive_arg(self):
219+
return ["--disk=" + INCLUDEOS_HOME + "dummy.disk"]
220+
221+
def net_arg(self):
222+
return ["--net=tap100"]
223+
224+
def get_final_output(self):
225+
return self._proc.communicate()
226+
227+
def boot(self, multiboot, kernel_args = "", image_name = None):
228+
self._stopped = False
229+
230+
qkvm_bin = INCLUDEOS_HOME + "/includeos/x86_64/lib/ukvm-bin"
231+
232+
# Use provided image name if set, otherwise raise an execption
233+
if not image_name:
234+
raise Exception("No image name provided as param")
235+
236+
self._image_name = image_name
237+
238+
command = ["sudo", qkvm_bin]
239+
command += self.drive_arg()
240+
command += self.net_arg()
241+
command += [self._image_name]
242+
243+
try:
244+
self.start_process(command)
245+
self.info("Started process PID ",self._proc.pid)
246+
except Exception as e:
247+
raise e
248+
249+
def stop(self):
250+
251+
signal = "-SIGTERM"
252+
253+
# Don't try to kill twice
254+
if self._stopped:
255+
self.wait()
256+
return self
257+
else:
258+
self._stopped = True
259+
260+
if self._proc and self._proc.poll() == None :
261+
262+
if not self._sudo:
263+
info ("Stopping child process (no sudo required)")
264+
self._proc.terminate()
265+
else:
266+
# Find and terminate all child processes, since parent is "sudo"
267+
parent = psutil.Process(self._proc.pid)
268+
children = parent.children()
269+
270+
info ("Stopping", self._image_name, "PID",self._proc.pid, "with", signal)
271+
272+
for child in children:
273+
info (" + child process ", child.pid)
274+
275+
# The process might have gotten an exit status by now so check again to avoid negative exit
276+
if (not self._proc.poll()):
277+
subprocess.call(["sudo", "kill", signal, str(child.pid)])
278+
279+
# Wait for termination (avoids the need to reset the terminal etc.)
280+
self.wait()
281+
282+
return self
283+
284+
def wait(self):
285+
if (self._proc): self._proc.wait()
286+
return self
287+
288+
def read_until_EOT(self):
289+
chars = ""
290+
291+
while (not self._proc.poll()):
292+
char = self._proc.stdout.read(1)
293+
if char == chr(4):
294+
return chars
295+
chars += char
296+
297+
return chars
298+
299+
300+
def readline(self):
301+
if self._proc.poll():
302+
raise Exception("Process completed")
303+
return self._proc.stdout.readline()
304+
305+
306+
def writeline(self, line):
307+
if self._proc.poll():
308+
raise Exception("Process completed")
309+
return self._proc.stdin.write(line + "\n")
310+
311+
def poll(self):
312+
return self._proc.poll()
183313

184314
# Qemu Hypervisor interface
185315
class qemu(hypervisor):
@@ -259,21 +389,6 @@ def kvm_present(self):
259389
# Note: if the command failed, we can't know until we have exit status,
260390
# but we can't wait since we expect no exit. Checking for program start error
261391
# is therefore deferred to the callee
262-
def start_process(self, cmdlist):
263-
264-
if cmdlist[0] == "sudo": # and have_sudo():
265-
print color.WARNING("Running with sudo")
266-
self._sudo = True
267-
268-
# Start a subprocess
269-
self._proc = subprocess.Popen(cmdlist,
270-
stdout = subprocess.PIPE,
271-
stderr = subprocess.PIPE,
272-
stdin = subprocess.PIPE)
273-
self.info("Started process PID ",self._proc.pid)
274-
275-
return self._proc
276-
277392

278393
def get_final_output(self):
279394
return self._proc.communicate()
@@ -414,6 +529,7 @@ def boot(self, multiboot, debug = False, kernel_args = "", image_name = None):
414529

415530
try:
416531
self.start_process(command)
532+
self.info("Started process PID ",self._proc.pid)
417533
except Exception as e:
418534
print self.INFO,"Starting subprocess threw exception:", e
419535
raise e
@@ -486,7 +602,7 @@ def poll(self):
486602
# VM class
487603
class vm:
488604

489-
def __init__(self, config = None, hyper = qemu):
605+
def __init__(self, config = None, hyper_name = "qemu"):
490606

491607
self._exit_status = None
492608
self._exit_msg = ""
@@ -500,6 +616,11 @@ def __init__(self, config = None, hyper = qemu):
500616
panic_signature : self._on_panic,
501617
"SUCCESS" : self._on_success }
502618

619+
if hyper_name == "ukvm":
620+
hyper = ukvm
621+
else:
622+
hyper = qemu
623+
503624
# Initialize hypervisor with config
504625
assert(issubclass(hyper, hypervisor))
505626
self._hyper = hyper(self._config)

0 commit comments

Comments
 (0)