OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
3 """ | 3 """ |
4 Auxiliary script used to send data between ports on guests. | 4 Auxiliary script used to send data between ports on guests. |
5 | 5 |
6 @copyright: 2010 Red Hat, Inc. | 6 @copyright: 2008-2009 Red Hat Inc. |
7 @author: Jiri Zupka (jzupka@redhat.com) | 7 @author: Jiri Zupka (jzupka@redhat.com) |
8 @author: Lukas Doktor (ldoktor@redhat.com) | 8 @author: Lukas Doktor (ldoktor@redhat.com) |
9 """ | 9 """ |
| 10 #from _pydev_SimpleXMLRPCServer import fcntl |
| 11 |
| 12 """ |
| 13 TODO: |
| 14 virt.init([consoles]) # sysfs, udev, OK |
| 15 virt.open(name) |
| 16 virt.close(name) |
| 17 virt.poll(name, eventmask, timeout) # poll.register(), poll.poll(), |
| 18 return event |
| 19 virt.send(name, length) # host disconnected |
| 20 virt.recv(name, length) # host disconnected |
| 21 virt.blocking(name, true) # true = blocking, false = nonblocking |
| 22 virt.loopback(in_names, out_names, type="None") # use select/poll |
| 23 """ |
| 24 |
10 import threading | 25 import threading |
11 from threading import Thread | 26 from threading import Thread |
12 import os, time, select, re, random, sys, array | 27 import os, time, select, re, random, sys, array, fcntl, array, subprocess |
13 import fcntl, array, subprocess, traceback, signal | |
14 | 28 |
15 DEBUGPATH = "/sys/kernel/debug" | 29 DEBUGPATH = "/sys/kernel/debug" |
16 SYSFSPATH = "/sys/class/virtio-ports/" | 30 SYSFSPATH = "/sys/class/virtio-ports/" |
17 | 31 |
18 | 32 |
19 class VirtioGuest: | 33 class virtio_guest(): |
20 """ | 34 |
21 Test tools of virtio_ports. | |
22 """ | |
23 LOOP_NONE = 0 | 35 LOOP_NONE = 0 |
24 LOOP_POLL = 1 | 36 LOOP_POLL = 1 |
25 LOOP_SELECT = 2 | 37 LOOP_SELECT = 2 |
26 | 38 |
27 def __init__(self): | 39 def __init__(self): |
28 self.files = {} | 40 self.files = {} |
29 self.exit_thread = threading.Event() | 41 self.exit_thread = threading.Event() |
30 self.threads = [] | 42 self.threads = [] |
31 self.ports = {} | 43 self.ports = {} |
32 self.poll_fds = {} | |
33 self.catch_signal = None | |
34 self.use_config = threading.Event() | |
35 | 44 |
36 | 45 |
37 def _readfile(self, name): | 46 def _readfile(self, name): |
38 """ | 47 """ |
39 Read file and return content as string | 48 Read file and return content as string |
40 | 49 |
41 @param name: Name of file | 50 @param name: Name of file |
42 @return: Content of file as string | 51 @return: Content of file as string |
43 """ | 52 """ |
44 out = "" | 53 out = "" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 """ | 118 """ |
110 self.ports = self._get_port_status() | 119 self.ports = self._get_port_status() |
111 | 120 |
112 for item in in_files: | 121 for item in in_files: |
113 if (item[1] != self.ports[item[0]]["is_console"]): | 122 if (item[1] != self.ports[item[0]]["is_console"]): |
114 print self.ports | 123 print self.ports |
115 print "FAIL: Host console is not like console on guest side\n" | 124 print "FAIL: Host console is not like console on guest side\n" |
116 print "PASS: Init and check virtioconsole files in system." | 125 print "PASS: Init and check virtioconsole files in system." |
117 | 126 |
118 | 127 |
119 class Switch(Thread): | 128 class switch(Thread): |
120 """ | 129 """ |
121 Thread that sends data between ports. | 130 Thread that sends data between ports. |
122 """ | 131 """ |
123 def __init__ (self, in_files, out_files, event, | 132 def __init__ (self, in_files, out_files, event, |
124 cachesize=1024, method=0): | 133 cachesize=1024, method=0): |
125 """ | 134 """ |
126 @param in_files: Array of input files. | 135 @param in_files: Array of input files. |
127 @param out_files: Array of output files. | 136 @param out_files: Array of output files. |
128 @param method: Method of read/write access. | 137 @param method: Method of read/write access. |
129 @param cachesize: Block to receive and send. | 138 @param cachesize: Block to receive and send. |
130 """ | 139 """ |
131 Thread.__init__(self, name="Switch") | 140 Thread.__init__(self) |
132 | 141 |
133 self.in_files = in_files | 142 self.in_files = in_files |
134 self.out_files = out_files | 143 self.out_files = out_files |
135 self.exit_thread = event | 144 self.exit_thread = event |
136 self.method = method | 145 self.method = method |
137 | 146 |
138 self.cachesize = cachesize | 147 self.cachesize = cachesize |
139 | 148 |
140 | 149 |
141 def _none_mode(self): | 150 def _none_mode(self): |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 if data != "": | 204 if data != "": |
196 ret = select.select([], self.out_files, [], 1.0) | 205 ret = select.select([], self.out_files, [], 1.0) |
197 while ((len(self.out_files) != len(ret[1])) and not | 206 while ((len(self.out_files) != len(ret[1])) and not |
198 self.exit_thread.isSet()): | 207 self.exit_thread.isSet()): |
199 ret = select.select([], self.out_files, [], 1.0) | 208 ret = select.select([], self.out_files, [], 1.0) |
200 for desc in ret[1]: | 209 for desc in ret[1]: |
201 os.write(desc, data) | 210 os.write(desc, data) |
202 | 211 |
203 | 212 |
204 def run(self): | 213 def run(self): |
205 if (self.method == VirtioGuest.LOOP_POLL): | 214 if (self.method == virtio_guest.LOOP_POLL): |
206 self._poll_mode() | 215 self._poll_mode() |
207 elif (self.method == VirtioGuest.LOOP_SELECT): | 216 elif (self.method == virtio_guest.LOOP_SELECT): |
208 self._select_mode() | 217 self._select_mode() |
209 else: | 218 else: |
210 self._none_mode() | 219 self._none_mode() |
211 | 220 |
212 | 221 |
213 class Sender(Thread): | 222 class sender(Thread): |
214 """ | 223 """ |
215 Creates a thread which sends random blocks of data to dst port. | 224 Creates a thread which sends random blocks of data to dst port. |
216 """ | 225 """ |
217 def __init__(self, port, event, length): | 226 def __init__(self, port, event, length): |
218 """ | 227 """ |
219 @param port: Destination port | 228 @param port: Destination port |
220 @param length: Length of the random data block | 229 @param length: Length of the random data block |
221 """ | 230 """ |
222 Thread.__init__(self, name="Sender") | 231 Thread.__init__(self) |
223 self.port = port | 232 self.port = port |
224 self.exit_thread = event | 233 self.exit_thread = event |
225 self.data = array.array('L') | 234 self.data = array.array('L') |
226 for i in range(max(length / self.data.itemsize, 1)): | 235 for i in range(max(length / self.data.itemsize, 1)): |
227 self.data.append(random.randrange(sys.maxint)) | 236 self.data.append(random.randrange(sys.maxint)) |
228 | 237 |
229 def run(self): | 238 def run(self): |
230 while not self.exit_thread.isSet(): | 239 while not self.exit_thread.isSet(): |
231 os.write(self.port, self.data) | 240 os.write(self.port, self.data) |
232 | 241 |
(...skipping 11 matching lines...) Expand all Loading... |
244 name = self.ports[item]["path"] | 253 name = self.ports[item]["path"] |
245 if (name in self.files): | 254 if (name in self.files): |
246 f.append(self.files[name]) | 255 f.append(self.files[name]) |
247 else: | 256 else: |
248 try: | 257 try: |
249 self.files[name] = os.open(name, os.O_RDWR) | 258 self.files[name] = os.open(name, os.O_RDWR) |
250 if (self.ports[item]["is_console"] == "yes"): | 259 if (self.ports[item]["is_console"] == "yes"): |
251 print os.system("stty -F %s raw -echo" % (name)) | 260 print os.system("stty -F %s raw -echo" % (name)) |
252 print os.system("stty -F %s -a" % (name)) | 261 print os.system("stty -F %s -a" % (name)) |
253 f.append(self.files[name]) | 262 f.append(self.files[name]) |
254 except Exception, inst: | 263 except Exception as inst: |
255 print "FAIL: Failed to open file %s" % (name) | 264 print "FAIL: Failed to open file %s" % (name) |
256 raise inst | 265 raise inst |
257 return f | 266 return f |
258 | 267 |
259 @staticmethod | |
260 def pollmask_to_str(mask): | |
261 """ | |
262 Conver pool mast to string | |
263 | |
264 @param mask: poll return mask | |
265 """ | |
266 str = "" | |
267 if (mask & select.POLLIN): | |
268 str += "IN " | |
269 if (mask & select.POLLPRI): | |
270 str += "PRI IN " | |
271 if (mask & select.POLLOUT): | |
272 str += "OUT " | |
273 if (mask & select.POLLERR): | |
274 str += "ERR " | |
275 if (mask & select.POLLHUP): | |
276 str += "HUP " | |
277 if (mask & select.POLLMSG): | |
278 str += "MSG " | |
279 return str | |
280 | |
281 | 268 |
282 def poll(self, port, expected, timeout=500): | 269 def poll(self, port, expected, timeout=500): |
283 """ | 270 """ |
284 Pool event from device and print event like text. | 271 Pool event from device and print event like text. |
285 | 272 |
286 @param file: Device. | 273 @param file: Device. |
287 """ | 274 """ |
288 in_f = self._open([port]) | 275 in_f = self._open([port]) |
289 | 276 |
290 p = select.poll() | 277 p = select.poll() |
291 p.register(in_f[0]) | 278 p.register(in_f[0]) |
292 | 279 |
293 mask = p.poll(timeout) | 280 mask = p.poll(timeout) |
294 | 281 |
295 maskstr = VirtioGuest.pollmask_to_str(mask[0][1]) | 282 str = "" |
| 283 if (mask[0][1] & select.POLLIN): |
| 284 str += "IN " |
| 285 if (mask[0][1] & select.POLLPRI): |
| 286 str += "PRI IN " |
| 287 if (mask[0][1] & select.POLLOUT): |
| 288 str += "OUT " |
| 289 if (mask[0][1] & select.POLLERR): |
| 290 str += "ERR " |
| 291 if (mask[0][1] & select.POLLHUP): |
| 292 str += "HUP " |
| 293 if (mask[0][1] & select.POLLMSG): |
| 294 str += "MSG " |
| 295 |
296 if (mask[0][1] & expected) == expected: | 296 if (mask[0][1] & expected) == expected: |
297 print "PASS: Events: " + maskstr | 297 print "PASS: Events: " + str |
298 else: | 298 else: |
299 emaskstr = VirtioGuest.pollmask_to_str(expected) | 299 print "FAIL: Events: " + str |
300 print "FAIL: Events: " + maskstr + " Expected: " + emaskstr | |
301 | |
302 | |
303 def lseek(self, port, pos, how): | |
304 """ | |
305 Use lseek on the device. The device is unseekable so PASS is returned | |
306 when lseek command fails and vice versa. | |
307 | |
308 @param port: Name of the port | |
309 @param pos: Offset | |
310 @param how: Relativ offset os.SEEK_{SET,CUR,END} | |
311 """ | |
312 fd = self._open([port])[0] | |
313 | |
314 try: | |
315 os.lseek(fd, pos, how) | |
316 except Exception, inst: | |
317 if inst.errno == 29: | |
318 print "PASS: the lseek failed as expected" | |
319 else: | |
320 print inst | |
321 print "FAIL: unknown error" | |
322 else: | |
323 print "FAIL: the lseek unexpectedly passed" | |
324 | 300 |
325 | 301 |
326 def blocking(self, port, mode=False): | 302 def blocking(self, port, mode=False): |
327 """ | 303 """ |
328 Set port function mode blocking/nonblocking | 304 Set port function mode blocking/nonblocking |
329 | 305 |
330 @param port: port to set mode | 306 @param port: port to set mode |
331 @param mode: False to set nonblock mode, True for block mode | 307 @param mode: False to set nonblock mode, True for block mode |
332 """ | 308 """ |
333 fd = self._open([port])[0] | 309 path = self.ports[port]["path"] |
| 310 fd = self.files[path] |
334 | 311 |
335 try: | 312 try: |
336 fl = fcntl.fcntl(fd, fcntl.F_GETFL) | 313 fl = fcntl.fcntl(fd, fcntl.F_GETFL) |
337 if not mode: | 314 if not mode: |
338 fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) | 315 fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) |
339 else: | 316 else: |
340 fcntl.fcntl(fd, fcntl.F_SETFL, fl & ~os.O_NONBLOCK) | 317 fcntl.fcntl(fd, fcntl.F_SETFL, fl & ~os.O_NONBLOCK) |
341 | 318 |
342 except Exception, inst: | 319 except Exception as inst: |
343 print "FAIL: Setting (non)blocking mode: " + str(inst) | 320 print "FAIL: Setting (non)blocking mode: " + str(inst) |
344 return | 321 return |
345 | 322 |
346 if mode: | 323 print ("PASS: set blocking mode to %s mode" % |
347 print "PASS: set to blocking mode" | 324 ("blocking" if mode else "nonblocking")) |
348 else: | |
349 print "PASS: set to nonblocking mode" | |
350 | |
351 | |
352 def __call__(self, sig, frame): | |
353 """ | |
354 Call function. Used for signal handle. | |
355 """ | |
356 if (sig == signal.SIGIO): | |
357 self.sigio_handler(sig, frame) | |
358 | |
359 | |
360 def sigio_handler(self, sig, frame): | |
361 """ | |
362 Handler for sigio operation. | |
363 | |
364 @param sig: signal which call handler. | |
365 @param frame: frame of caller | |
366 """ | |
367 if self.poll_fds: | |
368 p = select.poll() | |
369 map(p.register, self.poll_fds.keys()) | |
370 | |
371 masks = p.poll(1) | |
372 print masks | |
373 for mask in masks: | |
374 self.poll_fds[mask[0]][1] |= mask[1] | |
375 | |
376 | |
377 def get_sigio_poll_return(self, port): | |
378 """ | |
379 Return PASS, FAIL and poll walue in string format. | |
380 | |
381 @param port: Port to check poll information. | |
382 """ | |
383 fd = self._open([port])[0] | |
384 | |
385 maskstr = VirtioGuest.pollmask_to_str(self.poll_fds[fd][1]) | |
386 if (self.poll_fds[fd][0] ^ self.poll_fds[fd][1]): | |
387 emaskstr = VirtioGuest.pollmask_to_str(self.poll_fds[fd][0]) | |
388 print "FAIL: Events: " + maskstr + " Expected: " + emaskstr | |
389 else: | |
390 print "PASS: Events: " + maskstr | |
391 self.poll_fds[fd][1] = 0 | |
392 | |
393 | |
394 def set_pool_want_return(self, port, poll_value): | |
395 """ | |
396 Set value to static variable. | |
397 | |
398 @param port: Port which should be set excepted mask | |
399 @param poll_value: Value to check sigio signal. | |
400 """ | |
401 fd = self._open([port])[0] | |
402 self.poll_fds[fd] = [poll_value, 0] | |
403 print "PASS: Events: " + VirtioGuest.pollmask_to_str(poll_value) | |
404 | |
405 | |
406 def catching_signal(self): | |
407 """ | |
408 return: True if should set catch signal, False if ignore signal and | |
409 none when configuration is not changed. | |
410 """ | |
411 ret = self.catch_signal | |
412 self.catch_signal = None | |
413 return ret | |
414 | |
415 | |
416 def async(self, port, mode=True, exp_val = 0): | |
417 """ | |
418 Set port function mode async/sync. | |
419 | |
420 @param port: port which should be pooled. | |
421 @param mode: False to set sync mode, True for sync mode. | |
422 @param exp_val: Value which should be pooled. | |
423 """ | |
424 fd = self._open([port])[0] | |
425 | |
426 try: | |
427 fcntl.fcntl(fd, fcntl.F_SETOWN, os.getpid()) | |
428 fl = fcntl.fcntl(fd, fcntl.F_GETFL) | |
429 | |
430 self.use_config.clear() | |
431 if mode: | |
432 fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_ASYNC) | |
433 self.poll_fds[fd] = [exp_val, 0] | |
434 self.catch_signal = True | |
435 else: | |
436 del self.poll_fds[fd] | |
437 fcntl.fcntl(fd, fcntl.F_SETFL, fl & ~os.O_ASYNC) | |
438 self.catch_signal = False | |
439 | |
440 os.kill(os.getpid(), signal.SIGUSR1) | |
441 self.use_config.wait() | |
442 | |
443 except Exception, inst: | |
444 print "FAIL: Setting (a)sync mode: " + str(inst) | |
445 return | |
446 | |
447 if mode: | |
448 print "PASS: Set to async mode" | |
449 else: | |
450 print "PASS: Set to sync mode" | |
451 | 325 |
452 | 326 |
453 def close(self, file): | 327 def close(self, file): |
454 """ | 328 """ |
455 Close open port. | 329 Close open port. |
456 | 330 |
457 @param file: File to close. | 331 @param file: File to close. |
458 """ | 332 """ |
459 descriptor = None | 333 descriptor = None |
460 path = self.ports[file]["path"] | 334 path = self.ports[file]["path"] |
461 if path != None: | 335 if path != None: |
462 if path in self.files.keys(): | 336 if path in self.files.keys(): |
463 descriptor = self.files[path] | 337 descriptor = self.files[path] |
464 del self.files[path] | 338 del self.files[path] |
465 if descriptor != None: | 339 try: |
466 try: | 340 os.close(descriptor) |
467 os.close(descriptor) | 341 except Exception as inst: |
468 except Exception, inst: | 342 print "FAIL: Closing the file: " + str(inst) |
469 print "FAIL: Closing the file: " + str(inst) | 343 return |
470 return | |
471 print "PASS: Close" | 344 print "PASS: Close" |
472 | 345 |
473 | 346 |
474 def open(self, in_file): | 347 def open(self, in_files): |
475 """ | 348 """ |
476 Direct open devices. | 349 Direct open devices. |
477 | 350 |
478 @param in_file: Array of files. | 351 @param in_files: Array of files. |
479 @return: Array of descriptors. | 352 @return: Array of descriptors. |
480 """ | 353 """ |
481 name = self.ports[in_file]["path"] | 354 name = self.ports[in_files]["path"] |
482 try: | 355 try: |
483 self.files[name] = os.open(name, os.O_RDWR) | 356 self.files[name] = os.open(name, os.O_RDWR) |
484 if (self.ports[in_file]["is_console"] == "yes"): | |
485 print os.system("stty -F %s raw -echo" % (name)) | |
486 print "PASS: Open all filles correctly." | 357 print "PASS: Open all filles correctly." |
487 except Exception, inst: | 358 except Exception as inst: |
488 print "%s\nFAIL: Failed open file %s" % (str(inst), name) | 359 print "%s\nFAIL: Failed open file %s" % (str(inst), name) |
489 | 360 |
490 | 361 |
491 def loopback(self, in_files, out_files, cachesize=1024, mode=LOOP_NONE): | 362 def loopback(self, in_files, out_files, cachesize=1024, mode=LOOP_NONE): |
492 """ | 363 """ |
493 Start a switch thread. | 364 Start a switch thread. |
494 | 365 |
495 (There is a problem with multiple opens of a single file). | 366 (There is a problem with multiple opens of a single file). |
496 | 367 |
497 @param in_files: Array of input files. | 368 @param in_files: Array of input files. |
498 @param out_files: Array of output files. | 369 @param out_files: Array of output files. |
499 @param cachesize: Cachesize. | 370 @param cachesize: Cachesize. |
500 """ | 371 """ |
501 self.ports = self._get_port_status() | 372 self.ports = self._get_port_status() |
502 | 373 |
503 in_f = self._open(in_files) | 374 in_f = self._open(in_files) |
504 out_f = self._open(out_files) | 375 out_f = self._open(out_files) |
505 | 376 |
506 s = self.Switch(in_f, out_f, self.exit_thread, cachesize, mode) | 377 s = self.switch(in_f, out_f, self.exit_thread, cachesize, mode) |
507 s.start() | 378 s.start() |
508 self.threads.append(s) | 379 self.threads.append(s) |
509 print "PASS: Start switch" | 380 print "PASS: Start switch" |
510 | 381 |
511 | 382 |
512 def exit_threads(self): | 383 def exit_threads(self): |
513 """ | 384 """ |
514 Function end all running data switch. | 385 Function end all running data switch. |
515 """ | 386 """ |
516 self.exit_thread.set() | 387 self.exit_thread.set() |
(...skipping 17 matching lines...) Expand all Loading... |
534 exit() | 405 exit() |
535 | 406 |
536 | 407 |
537 def send_loop_init(self, port, length): | 408 def send_loop_init(self, port, length): |
538 """ | 409 """ |
539 Prepares the sender thread. Requires clean thread structure. | 410 Prepares the sender thread. Requires clean thread structure. |
540 """ | 411 """ |
541 self.ports = self._get_port_status() | 412 self.ports = self._get_port_status() |
542 in_f = self._open([port]) | 413 in_f = self._open([port]) |
543 | 414 |
544 self.threads.append(self.Sender(in_f[0], self.exit_thread, length)) | 415 self.threads.append(self.sender(in_f[0], self.exit_thread, length)) |
545 print "PASS: Sender prepare" | 416 print "PASS: Sender prepare" |
546 | 417 |
547 | 418 |
548 def send_loop(self): | 419 def send_loop(self): |
549 """ | 420 """ |
550 Start sender data transfer. Requires senderprepare run first. | 421 Start sender data transfer. Requires senderprepare run first. |
551 """ | 422 """ |
552 self.threads[0].start() | 423 self.threads[0].start() |
553 print "PASS: Sender start" | 424 print "PASS: Sender start" |
554 | 425 |
555 | 426 |
556 def send(self, port, length=1, mode=True): | 427 def send(self, port, length=1, mode=True): |
557 """ | 428 """ |
558 Send a data of some length | 429 Send a data of some length |
559 | 430 |
560 @param port: Port to write data | 431 @param port: Port to write data |
561 @param length: Length of data | 432 @param length: Length of data |
562 @param mode: True = loop mode, False = one shoot mode | 433 @param mode: True = loop mode, False = one shoot mode |
563 """ | 434 """ |
564 in_f = self._open([port]) | 435 in_f = self._open([port]) |
565 | 436 |
566 data = "" | 437 data = "" |
567 while len(data) < length: | 438 while len(data) < length: |
568 data += "%c" % random.randrange(255) | 439 data += "%c" % random.randrange(255) |
569 try: | 440 try: |
570 writes = os.write(in_f[0], data) | 441 writes = os.write(in_f[0], data) |
571 except Exception, inst: | 442 except Exception as inst: |
572 print inst | 443 print inst |
573 if not writes: | 444 if not writes: |
574 writes = 0 | 445 writes = 0 |
575 if mode: | 446 if mode: |
576 while (writes < length): | 447 while (writes < length): |
577 try: | 448 try: |
578 writes += os.write(in_f[0], data) | 449 writes += os.write(in_f[0], data) |
579 except Exception, inst: | 450 except Exception as inst: |
580 print inst | 451 print inst |
581 if writes >= length: | 452 if writes >= length: |
582 print "PASS: Send data length %d" % writes | 453 print "PASS: Send data length %d" % writes |
583 else: | 454 else: |
584 print ("FAIL: Partial send: desired %d, transfered %d" % | 455 print ("FAIL: Partial send: desired %d, transfered %d" % |
585 (length, writes)) | 456 (length, writes)) |
586 | 457 |
587 | 458 |
588 def recv(self, port, length=1, buffer=1024, mode=True): | 459 def recv(self, port, length=1, buffer=1024, mode=True): |
589 """ | 460 """ |
590 Recv a data of some length | 461 Recv a data of some length |
591 | 462 |
592 @param port: Port to write data | 463 @param port: Port to write data |
593 @param length: Length of data | 464 @param length: Length of data |
594 @param mode: True = loop mode, False = one shoot mode | 465 @param mode: True = loop mode, False = one shoot mode |
595 """ | 466 """ |
596 in_f = self._open([port]) | 467 in_f = self._open([port]) |
597 | 468 |
598 recvs = "" | 469 recvs = "" |
599 try: | 470 try: |
600 recvs = os.read(in_f[0], buffer) | 471 recvs = os.read(in_f[0], buffer) |
601 except Exception, inst: | 472 except Exception as inst: |
602 print inst | 473 print inst |
603 if mode: | 474 if mode: |
604 while (len(recvs) < length): | 475 while (len(recvs) < length): |
605 try: | 476 try: |
606 recvs += os.read(in_f[0], buffer) | 477 recvs += os.read(in_f[0], buffer) |
607 except Exception, inst: | 478 except Exception as inst: |
608 print inst | 479 print inst |
609 if len(recvs) >= length: | 480 if len(recvs) >= length: |
610 print "PASS: Recv data length %d" % len(recvs) | 481 print "PASS: Recv data length %d" % len(recvs) |
611 else: | 482 else: |
612 print ("FAIL: Partial recv: desired %d, transfered %d" % | 483 print ("FAIL: Partial recv: desired %d, transfered %d" % |
613 (length, len(recvs))) | 484 (length, len(recvs))) |
614 | 485 |
615 | 486 |
616 def clean_port(self, port, buffer=1024): | |
617 in_f = self._open([port]) | |
618 ret = select.select([in_f[0]], [], [], 1.0) | |
619 buf = "" | |
620 if ret[0]: | |
621 buf = os.read(in_f[0], buffer) | |
622 print ("PASS: Rest in socket: " + buf) | |
623 | |
624 | |
625 def is_alive(): | |
626 """ | |
627 Check is only main thread is alive and if guest react. | |
628 """ | |
629 if threading.activeCount() == 2: | |
630 print ("PASS: Guest is ok no thread alive") | |
631 else: | |
632 threads = "" | |
633 for thread in threading.enumerate(): | |
634 threads += thread.name + ", " | |
635 print ("FAIL: On guest run thread. Active thread:" + threads) | |
636 | |
637 | |
638 def compile(): | 487 def compile(): |
639 """ | 488 """ |
640 Compile virtio_guest.py to speed up. | 489 Compile virtio_guest.py to speed up. |
641 """ | 490 """ |
642 import py_compile | 491 import py_compile |
643 py_compile.compile(sys.path[0] + "/virtio_guest.py") | 492 py_compile.compile(sys.path[0] + "/virtio_guest.py") |
644 print "PASS: compile" | 493 print "PASS: compile" |
645 sys.exit() | 494 exit(0) |
646 | 495 |
647 | 496 |
648 def worker(virt): | 497 def main(): |
649 """ | 498 """ |
650 Worker thread (infinite) loop of virtio_guest. | 499 Main (infinite) loop of virtio_guest. |
651 """ | 500 """ |
| 501 if (len(sys.argv) > 1) and (sys.argv[1] == "-c"): |
| 502 compile() |
| 503 |
| 504 virt = virtio_guest() |
652 print "PASS: Start" | 505 print "PASS: Start" |
653 | 506 |
654 while True: | 507 while True: |
655 str = raw_input() | 508 str = raw_input() |
656 try: | 509 exec str |
657 exec str | |
658 except: | |
659 exc_type, exc_value, exc_traceback = sys.exc_info() | |
660 print "On Guest exception from: \n" + "".join( | |
661 traceback.format_exception(exc_type, | |
662 exc_value, | |
663 exc_traceback)) | |
664 sys.exit(0) | |
665 | |
666 | |
667 def sigusr_handler(sig, frame): | |
668 pass | |
669 | |
670 | |
671 def main(): | |
672 """ | |
673 Main function with infinite loop to catch signal from system. | |
674 """ | |
675 if (len(sys.argv) > 1) and (sys.argv[1] == "-c"): | |
676 compile() | |
677 | |
678 virt = VirtioGuest() | |
679 slave = Thread(target=worker, args=(virt, )) | |
680 slave.start() | |
681 signal.signal(signal.SIGUSR1, sigusr_handler) | |
682 while True: | |
683 signal.pause() | |
684 catch = virt.catching_signal() | |
685 if catch: | |
686 signal.signal(signal.SIGIO, virt) | |
687 elif catch == False: | |
688 signal.signal(signal.SIGIO, signal.SIG_DFL) | |
689 if (catch != None): | |
690 virt.use_config.set() | |
691 | 510 |
692 | 511 |
693 if __name__ == "__main__": | 512 if __name__ == "__main__": |
694 main() | 513 main() |
OLD | NEW |