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&…
==============================================================================
--- 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&a…
==============================================================================
--- 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&am…
==============================================================================
--- 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;
}
-