Author: cfinck Date: Tue Mar 24 23:36:53 2009 New Revision: 40210
URL: http://svn.reactos.org/svn/reactos?rev=40210&view=rev Log: - Remove the readln function, it did more than it should and had quite a hacky interface The same functionality is implemented inside ProcessDebugData now, with cleaner and no duplicated code :-) - Add more error and result messages - Change the value for "maxcrashes" to 10 (the value used on the Buildslave) - Add more comments - Fix indentation a bit
Modified: trunk/tools/sysreg2/console.c trunk/tools/sysreg2/sysreg.h trunk/tools/sysreg2/sysreg.xml trunk/tools/sysreg2/utils.c trunk/tools/sysreg2/virt.c
Modified: trunk/tools/sysreg2/console.c URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/console.c?rev=40210&a... ============================================================================== --- trunk/tools/sysreg2/console.c [iso-8859-1] (original) +++ trunk/tools/sysreg2/console.c [iso-8859-1] Tue Mar 24 23:36:53 2009 @@ -1,20 +1,29 @@ #include "sysreg.h"
-bool ProcessDebugData(const char* tty, int timeout, int stage ) +int ProcessDebugData(const char* tty, int timeout, int stage ) { + char buf[512]; + char rbuf[512]; + char* bp; + int got; int ttyfd, i; struct termios ttyattr, rawattr; - bool Ret = true; + int Ret = EXIT_NONCONTINUABLE_ERROR; int KdbgHit = 0;
+ /* ttyfd is the file descriptor of the virtual COM port */ if ((ttyfd = open(tty, O_NOCTTY | O_RDWR)) < 0) { SysregPrintf("error opening tty\n"); return false; }
+ /* We also monitor STDIN_FILENO, so a user can cancel the process with ESC */ if (tcgetattr(STDIN_FILENO, &ttyattr) < 0) - return false; + { + SysregPrintf("tcgetattr failed with error %d\n", errno); + return false; + }
rawattr = ttyattr; rawattr.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP @@ -25,98 +34,132 @@ rawattr.c_cflag |= CS8;
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &rawattr) < 0) + { + SysregPrintf("tcsetattr failed with error %d\n", errno); return false; + }
while (1) { - int ret; struct pollfd fds[] = { { STDIN_FILENO, POLLIN, 0 }, { ttyfd, POLLIN, 0 }, };
- ret = poll(fds, (sizeof(fds) / sizeof(struct pollfd)), timeout); - if (ret < 0) + got = poll(fds, (sizeof(fds) / sizeof(struct pollfd)), timeout); + if (got < 0) { + /* Just try it again on simple errors */ if (errno == EINTR || errno == EAGAIN) continue; + + SysregPrintf("poll failed with error %d\n", errno); goto cleanup; } - else if (ret == 0) + else if (got == 0) { /* timeout */ SysregPrintf("timeout\n"); - Ret = false; + Ret = EXIT_ERROR; goto cleanup; }
- for (i=0; i<(sizeof(fds) / sizeof(struct pollfd)); i++) + for (i = 0; i < (sizeof(fds) / sizeof(struct pollfd)); i++) { - if (!fds[i].revents) + /* Wait till we get some input from the fd */ + if (!(fds[i].revents & POLLIN)) continue; - if (fds[i].revents & POLLIN) + + bp = buf; + + /* Read one line or a maximum of 512 bytes into a buffer */ + while (bp - buf < sizeof(buf)) { - char buf[512]; - char rbuf[512]; - int got, sent = 0; - - memset(buf, 0, sizeof(buf)); - got = readln(fds[i].fd, buf, sizeof(buf)); + got = read(fds[i].fd, bp, 1);
- if (got == KDBG_READY) + if (got < 0) { - KdbgHit++; - switch (KdbgHit) + SysregPrintf("read failed with error %d\n", errno); + goto cleanup; + } + else if (got == 0) + { + /* No more data */ + break; + } + + /* Also break on newlines */ + if(*bp++ == '\n') + break; + } + + if (bp == buf) + { + /* This usually means the machine shut down (like in 1st or 2nd stage) */ + Ret = EXIT_SHUTDOWN; + goto cleanup; + } + + *bp = 0; + + /* Now check the output */ + if (fds[i].fd == STDIN_FILENO) + { + /* Check whether the user pressed ESC and cancel in that case */ + if (strchr(buf, '\33')) + goto cleanup; + } + else + { + /* Check for "magic" sequences */ + if (strstr(buf, "kdb:>")) + { + ++KdbgHit; + + if (KdbgHit == 1) { - case 1: - safewrite(ttyfd, "bt\r", 3); - continue; - default: - Ret = false; - goto cleanup; - + /* We hit Kdbg for the first time, get a backtrace for the log */ + safewrite(ttyfd, "bt\r", 3); + continue; + } + else + { + /* We hit it yet another time, give up here */ + Ret = EXIT_ERROR; + goto cleanup; } } - else if (got == KDBG_CONFIRM) + else if (strstr(buf, "--- Press q")) { - /* send <Return> - * to get more data */ + /* Send Return to get more data from Kdbg */ safewrite(ttyfd, "\r", 1); continue; } - else if (got <= 0) { + else if (strstr(buf, "SYSREG_ROSAUTOTEST_FAILURE")) + { + /* rosautotest itself has problems, so there's no reason to continue */ + goto cleanup; + } + else if (*AppSettings.Stage[stage].Checkpoint && strstr(buf, AppSettings.Stage[stage].Checkpoint)) + { + /* We reached a checkpoint, so return success */ + Ret = EXIT_CHECKPOINT_REACHED; goto cleanup; }
- if (fds[i].fd != STDIN_FILENO) - { - if ((AppSettings.Stage[stage].Checkpoint[0] != '\0') && - (strstr(buf,AppSettings.Stage[stage].Checkpoint) != NULL)) - { - /* Checkpoint reached, - * kill the vm and return success */ - goto cleanup; - } - - if (ResolveAddressFromFile(rbuf, sizeof(rbuf), buf)) - printf("%s", rbuf); - else - printf("%s", buf); - } + if (ResolveAddressFromFile(rbuf, sizeof(rbuf), buf)) + printf("%s", rbuf); else - { - if (got == 1 && buf[0] == '\33') - goto cleanup; - } - + printf("%s", buf); } } - } + }
cleanup: tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttyattr); close(ttyfd); + return Ret; }
Modified: trunk/tools/sysreg2/sysreg.h URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/sysreg.h?rev=40210&am... ============================================================================== --- trunk/tools/sysreg2/sysreg.h [iso-8859-1] (original) +++ trunk/tools/sysreg2/sysreg.h [iso-8859-1] Tue Mar 24 23:36:53 2009 @@ -15,29 +15,31 @@ #include <libxml/xpathInternals.h> #include <sys/sysinfo.h>
-#define KDBG_CONFIRM -3 -#define KDBG_READY -2 +#define EXIT_CHECKPOINT_REACHED 0 +#define EXIT_SHUTDOWN 1 +#define EXIT_ERROR 2 +#define EXIT_NONCONTINUABLE_ERROR 3 +#define NUM_STAGES 3
typedef struct { - char BootDevice[8]; - char Checkpoint[80]; + char BootDevice[8]; + char Checkpoint[80]; } stage;
typedef struct { - int MaxCrashes; - int Timeout; - char Filename[255]; - char Name[80]; - char HardDiskImage[255]; - int ImageSize; - stage Stage[3]; + int MaxCrashes; + int Timeout; + char Filename[255]; + char Name[80]; + char HardDiskImage[255]; + int ImageSize; + stage Stage[3]; } Settings;
Settings AppSettings;
/* utils.c */ char* ReadFile (const char* filename); -int readln(int fd, char* buffer, int size); ssize_t safewrite(int fd, const void *buf, size_t count); void SysregPrintf(const char* format, ...);
@@ -45,7 +47,7 @@ bool LoadSettings(const char* XmlConfig);
/* console.c */ -bool ProcessDebugData(const char* tty, int timeout, int stage); +int ProcessDebugData(const char* tty, int timeout, int stage);
/* raddr2line.c */ bool GetPackagePath(char* Buffer, int BuffSize, char* Module);
Modified: trunk/tools/sysreg2/sysreg.xml URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/sysreg.xml?rev=40210&... ============================================================================== --- trunk/tools/sysreg2/sysreg.xml [iso-8859-1] (original) +++ trunk/tools/sysreg2/sysreg.xml [iso-8859-1] Tue Mar 24 23:36:53 2009 @@ -7,7 +7,7 @@ <hdd size="512"/>
<!-- Maximum number of crashes allowed before we kill the VM --> - <maxcrashes value="20" /> + <maxcrashes value="10" /> </general> <firststage bootdevice="cdrom"> </firststage>
Modified: trunk/tools/sysreg2/utils.c URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/utils.c?rev=40210&... ============================================================================== --- trunk/tools/sysreg2/utils.c [iso-8859-1] (original) +++ trunk/tools/sysreg2/utils.c [iso-8859-1] Tue Mar 24 23:36:53 2009 @@ -1,33 +1,4 @@ #include "sysreg.h" - -int readln(int fd, char* buffer, int size) -{ - char* bp = buffer, ch; - int got; - - while ((bp - buffer < size) && (got = read(fd, bp, 1))) - { - if (fd == STDIN_FILENO) - { - if (*bp == '\33') - return 1; - } - else - { - if (strstr(buffer, "kdb:>")) - return -2; - if (strstr(buffer, "--- Press q")) - return -3; - } - if (*bp++ == '\n') - return (bp - buffer); - } - if (got < 0) - return -1; - if (bp - buffer == size) - while (read(fd, &ch, 1)) - return (bp - buffer); -}
ssize_t safewrite(int fd, const void *buf, size_t count) {
Modified: trunk/tools/sysreg2/virt.c URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/virt.c?rev=40210&... ============================================================================== --- trunk/tools/sysreg2/virt.c [iso-8859-1] (original) +++ trunk/tools/sysreg2/virt.c [iso-8859-1] Tue Mar 24 23:36:53 2009 @@ -142,16 +142,15 @@
int main(int argc, char **argv) { - virConnectPtr vConn; + virConnectPtr vConn = NULL; virDomainPtr vDom; virDomainInfo info; int Crashes; int Stage; - int Stages = 3; char qemu_img_cmdline[300]; FILE* file; char config[255]; - int Ret = EXIT_FAILURE; + int Ret = EXIT_NONCONTINUABLE_ERROR; char console[50];
if (argc == 2) @@ -172,12 +171,14 @@ goto cleanup; }
+ /* If the HD image already exists, delete it */ if (file = fopen(AppSettings.HardDiskImage, "r")) { fclose(file); remove(AppSettings.HardDiskImage); }
+ /* Create a new HD image */ sprintf(qemu_img_cmdline, "qemu-img create -f qcow2 %s %dM", AppSettings.HardDiskImage, AppSettings.ImageSize); FILE* p = popen(qemu_img_cmdline, "r"); @@ -187,11 +188,9 @@ fgets(buf,100,p); SysregPrintf("%s\n",buf); } - pclose(p); - - Stage = 0; - - while(Stage < Stages) + pclose(p); + + for(Stage = 0; Stage < NUM_STAGES; Stage++) { for(Crashes = 0; Crashes < AppSettings.MaxCrashes; Crashes++) { @@ -209,7 +208,7 @@ SysregPrintf("Domain %s started.\n", virDomainGetName(vDom));
GetConsole(vDom, console); - Ret = (ProcessDebugData(console, AppSettings.Timeout, Stage) ? EXIT_SUCCESS : EXIT_FAILURE); + Ret = ProcessDebugData(console, AppSettings.Timeout, Stage);
/* Kill the VM */ virDomainGetInfo(vDom, &info); @@ -223,7 +222,7 @@ /* If we have a checkpoint to reach for success, assume that the application used for running the tests (probably "rosautotest") continues with the next test after a VM restart. */ - if (Ret == EXIT_FAILURE && *AppSettings.Stage[Stage].Checkpoint) + if (Ret == EXIT_ERROR && *AppSettings.Stage[Stage].Checkpoint) SysregPrintf("Crash %d encountered, resuming the testing process\n", Crashes); else break; @@ -235,21 +234,33 @@ break; }
- if (Ret == EXIT_FAILURE) - break; - - ++Stage; + if (Ret == EXIT_ERROR || Ret == EXIT_NONCONTINUABLE_ERROR) + break; }
cleanup: - virConnectClose(vConn); - - if (Ret == EXIT_SUCCESS) - SysregPrintf("Test status: Reached the checkpoint!\n"); - else - SysregPrintf("Test status: Failed to reach the checkpoint!\n"); + if (vConn) + virConnectClose(vConn); + + switch (Ret) + { + case EXIT_CHECKPOINT_REACHED: + SysregPrintf("Status: Reached the checkpoint!\n"); + break; + + case EXIT_SHUTDOWN: + SysregPrintf("Status: Machine shut down, but did not reach the checkpoint!\n"); + break; + + case EXIT_ERROR: + SysregPrintf("Status: Failed to reach the checkpoint!\n"); + break; + + case EXIT_NONCONTINUABLE_ERROR: + SysregPrintf("Status: Testing process aborted!\n"); + break; + }
return Ret; } -