1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (c) 2004, Bull S.A.. All rights reserved. 3f08c3bdfSopenharmony_ci * Created by: Sebastien Decugis 4f08c3bdfSopenharmony_ci 5f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify it 6f08c3bdfSopenharmony_ci * under the terms of version 2 of the GNU General Public License as 7f08c3bdfSopenharmony_ci * published by the Free Software Foundation. 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful, but 10f08c3bdfSopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 11f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12f08c3bdfSopenharmony_ci * 13f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License along 14f08c3bdfSopenharmony_ci * with this program; if not, write the Free Software Foundation, Inc., 15f08c3bdfSopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16f08c3bdfSopenharmony_ci 17f08c3bdfSopenharmony_ci */ 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_ci/* 20f08c3bdfSopenharmony_ci * The purpose of this file is to provide a monitor process 21f08c3bdfSopenharmony_ci * for the stress/threads/ * / *.c testcases in the OPTS. 22f08c3bdfSopenharmony_ci * 23f08c3bdfSopenharmony_ci * The goal is: 24f08c3bdfSopenharmony_ci * -> if the testcase returns, the monitor returns the error code. 25f08c3bdfSopenharmony_ci * -> after a specified timeout, the monitor let the stress test terminate 26f08c3bdfSopenharmony_ci 27f08c3bdfSopenharmony_ci * This allows for the stress tests to be run in an automatic maneer 28f08c3bdfSopenharmony_ci * with a script such as: 29f08c3bdfSopenharmony_ci#!/bin/sh 30f08c3bdfSopenharmony_ci 31f08c3bdfSopenharmony_ci#monitor the system 32f08c3bdfSopenharmony_civmstat -n 120 180 >monitor.txt 2>&1 & 33f08c3bdfSopenharmony_ci 34f08c3bdfSopenharmony_ci#run the tests 35f08c3bdfSopenharmony_cifor TS in `ls -1 *.c`; 36f08c3bdfSopenharmony_cido <compile $TS>; 37f08c3bdfSopenharmony_ciif [ $? -eq 0 ]; 38f08c3bdfSopenharmony_cithen <run in background:> 39f08c3bdfSopenharmony_ci helper 6 $TS.exe & 40f08c3bdfSopenharmony_cifi 41f08c3bdfSopenharmony_cidone 42f08c3bdfSopenharmony_ci 43f08c3bdfSopenharmony_ci#wait for the end 44f08c3bdfSopenharmony_ciwhile [ "`ps -e | grep helper`" ]; 45f08c3bdfSopenharmony_cido sleep 30; 46f08c3bdfSopenharmony_cidone 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci*/ 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci#include <pthread.h> 51f08c3bdfSopenharmony_ci#include <stdio.h> 52f08c3bdfSopenharmony_ci#include <stdlib.h> 53f08c3bdfSopenharmony_ci#include <unistd.h> 54f08c3bdfSopenharmony_ci#include <signal.h> 55f08c3bdfSopenharmony_ci#include <sys/wait.h> 56f08c3bdfSopenharmony_ci#include <assert.h> 57f08c3bdfSopenharmony_ci#include <time.h> 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_cistatic pid_t child; 60f08c3bdfSopenharmony_cistatic int timeout; 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_ci/* Note that there could be a race between 63f08c3bdfSopenharmony_cithe moment the stress test terminates and 64f08c3bdfSopenharmony_ciwhen the timeout expires. As this is highly 65f08c3bdfSopenharmony_ciimprobable, we don't care... */ 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_cistatic void *timer(void *arg) 68f08c3bdfSopenharmony_ci{ 69f08c3bdfSopenharmony_ci int ret = 0; 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci unsigned remaining = timeout * 3600; 72f08c3bdfSopenharmony_ci do { 73f08c3bdfSopenharmony_ci remaining = sleep(remaining); 74f08c3bdfSopenharmony_ci } while (remaining); 75f08c3bdfSopenharmony_ci ret = kill(child, SIGUSR1); 76f08c3bdfSopenharmony_ci if (ret != 0) { 77f08c3bdfSopenharmony_ci perror("Failed to kill the stress test"); 78f08c3bdfSopenharmony_ci exit(2); 79f08c3bdfSopenharmony_ci } 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_ci return NULL; 82f08c3bdfSopenharmony_ci} 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ciint main(int argc, char *argv[]) 85f08c3bdfSopenharmony_ci{ 86f08c3bdfSopenharmony_ci int ret; 87f08c3bdfSopenharmony_ci pthread_t th; 88f08c3bdfSopenharmony_ci pid_t chk; 89f08c3bdfSopenharmony_ci int status; 90f08c3bdfSopenharmony_ci char *ts = "[??:??:??]"; 91f08c3bdfSopenharmony_ci struct tm *now; 92f08c3bdfSopenharmony_ci time_t nw; 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_ci /* check args */ 95f08c3bdfSopenharmony_ci if (argc < 3) { 96f08c3bdfSopenharmony_ci printf("\nUsage: \n"); 97f08c3bdfSopenharmony_ci printf(" $ %s n exe arglist\n", argv[0]); 98f08c3bdfSopenharmony_ci printf("\nWhere:\n"); 99f08c3bdfSopenharmony_ci printf(" n is the timeout duration in hours,\n"); 100f08c3bdfSopenharmony_ci printf(" exe is the stress test executable to monitor,\n"); 101f08c3bdfSopenharmony_ci printf 102f08c3bdfSopenharmony_ci (" arglist is the arguments to be passed to executable.\n\n"); 103f08c3bdfSopenharmony_ci return 2; 104f08c3bdfSopenharmony_ci } 105f08c3bdfSopenharmony_ci 106f08c3bdfSopenharmony_ci timeout = atoi(argv[1]); 107f08c3bdfSopenharmony_ci if (timeout < 1) { 108f08c3bdfSopenharmony_ci fprintf(stderr, 109f08c3bdfSopenharmony_ci "Invalid timeout value \"%s\". Timeout must be a positive integer.\n", 110f08c3bdfSopenharmony_ci argv[1]); 111f08c3bdfSopenharmony_ci return 2; 112f08c3bdfSopenharmony_ci } 113f08c3bdfSopenharmony_ci 114f08c3bdfSopenharmony_ci /* create the timer thread */ 115f08c3bdfSopenharmony_ci ret = pthread_create(&th, NULL, timer, NULL); 116f08c3bdfSopenharmony_ci if (ret != 0) { 117f08c3bdfSopenharmony_ci perror("Failed to create the timeout thread\n"); 118f08c3bdfSopenharmony_ci return 2; 119f08c3bdfSopenharmony_ci } 120f08c3bdfSopenharmony_ci 121f08c3bdfSopenharmony_ci /* Create the new process for the stress test */ 122f08c3bdfSopenharmony_ci child = fork(); 123f08c3bdfSopenharmony_ci 124f08c3bdfSopenharmony_ci if (child == (pid_t) - 1) { 125f08c3bdfSopenharmony_ci perror("Failed to create a new process"); 126f08c3bdfSopenharmony_ci exit(2); 127f08c3bdfSopenharmony_ci } 128f08c3bdfSopenharmony_ci 129f08c3bdfSopenharmony_ci /* The child process executes the test */ 130f08c3bdfSopenharmony_ci if (child == (pid_t) 0) { 131f08c3bdfSopenharmony_ci 132f08c3bdfSopenharmony_ci /* Execute the command */ 133f08c3bdfSopenharmony_ci ret = execvp(argv[2], &argv[2]); 134f08c3bdfSopenharmony_ci if (ret == -1) { 135f08c3bdfSopenharmony_ci /* Application was not launched */ 136f08c3bdfSopenharmony_ci perror("Unable to run child application"); 137f08c3bdfSopenharmony_ci return 2; 138f08c3bdfSopenharmony_ci } 139f08c3bdfSopenharmony_ci assert(0); 140f08c3bdfSopenharmony_ci perror("Should not see me"); 141f08c3bdfSopenharmony_ci return 2; 142f08c3bdfSopenharmony_ci } 143f08c3bdfSopenharmony_ci 144f08c3bdfSopenharmony_ci /* The parent: */ 145f08c3bdfSopenharmony_ci 146f08c3bdfSopenharmony_ci /* wait for the child process to terminate */ 147f08c3bdfSopenharmony_ci chk = waitpid(child, &status, 0); 148f08c3bdfSopenharmony_ci if (chk != child) { 149f08c3bdfSopenharmony_ci perror("Got the wrong process image status"); 150f08c3bdfSopenharmony_ci return 2; 151f08c3bdfSopenharmony_ci } 152f08c3bdfSopenharmony_ci 153f08c3bdfSopenharmony_ci /* Cancel the timer thread in case the process returned by itself */ 154f08c3bdfSopenharmony_ci (void)pthread_cancel(th); 155f08c3bdfSopenharmony_ci 156f08c3bdfSopenharmony_ci ret = pthread_join(th, NULL); 157f08c3bdfSopenharmony_ci if (ret != 0) { 158f08c3bdfSopenharmony_ci perror("Unable to join the timer thread"); 159f08c3bdfSopenharmony_ci return 2; 160f08c3bdfSopenharmony_ci } 161f08c3bdfSopenharmony_ci 162f08c3bdfSopenharmony_ci /* return */ 163f08c3bdfSopenharmony_ci nw = time(NULL); 164f08c3bdfSopenharmony_ci now = localtime(&nw); 165f08c3bdfSopenharmony_ci if (now == NULL) 166f08c3bdfSopenharmony_ci printf(ts); 167f08c3bdfSopenharmony_ci else 168f08c3bdfSopenharmony_ci printf("[%2.2d:%2.2d:%2.2d]\n", now->tm_hour, now->tm_min, 169f08c3bdfSopenharmony_ci now->tm_sec); 170f08c3bdfSopenharmony_ci if (!WIFEXITED(status)) { 171f08c3bdfSopenharmony_ci printf("The stress sample did not exit\n"); 172f08c3bdfSopenharmony_ci if (WIFSIGNALED(status)) { 173f08c3bdfSopenharmony_ci printf("It was killed with signal %i\n", 174f08c3bdfSopenharmony_ci WTERMSIG(status)); 175f08c3bdfSopenharmony_ci } else { 176f08c3bdfSopenharmony_ci printf("and it was not killed...\n"); 177f08c3bdfSopenharmony_ci } 178f08c3bdfSopenharmony_ci exit(1); 179f08c3bdfSopenharmony_ci } 180f08c3bdfSopenharmony_ci if (WEXITSTATUS(status) == 0) { 181f08c3bdfSopenharmony_ci printf("Test %s PASSED\n", argv[2]); 182f08c3bdfSopenharmony_ci } else { 183f08c3bdfSopenharmony_ci printf("Test %s: returned %d\n", argv[2], WEXITSTATUS(status)); 184f08c3bdfSopenharmony_ci } 185f08c3bdfSopenharmony_ci exit(WEXITSTATUS(status)); 186f08c3bdfSopenharmony_ci} 187