1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 5f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 6f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 7f08c3bdfSopenharmony_ci * (at your option) any later version. 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 10f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 15f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 16f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17f08c3bdfSopenharmony_ci */ 18f08c3bdfSopenharmony_ci/* 19f08c3bdfSopenharmony_ci * FUNCTIONS: Scheduler Test Suite 20f08c3bdfSopenharmony_ci */ 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_ci/*---------------------------------------------------------------------+ 23f08c3bdfSopenharmony_ci| sched_tc6 | 24f08c3bdfSopenharmony_ci| ==================================================================== | 25f08c3bdfSopenharmony_ci| | 26f08c3bdfSopenharmony_ci| Description: Creates short-term disk I/O bound process | 27f08c3bdfSopenharmony_ci| | 28f08c3bdfSopenharmony_ci| Creates a situation where a real time process is | 29f08c3bdfSopenharmony_ci| waiting on a file lock owned by a user process. The | 30f08c3bdfSopenharmony_ci| scheduler should elevate the user process priority to | 31f08c3bdfSopenharmony_ci| the same level as the real time process to avoid | 32f08c3bdfSopenharmony_ci| deadlock situations and to decrease wait time | 33f08c3bdfSopenharmony_ci| required of the real time process. | 34f08c3bdfSopenharmony_ci| | 35f08c3bdfSopenharmony_ci| Algorithm: o Set process priority | 36f08c3bdfSopenharmony_ci| o Continuously multiply matrices together until | 37f08c3bdfSopenharmony_ci| interrupted. | 38f08c3bdfSopenharmony_ci| | 39f08c3bdfSopenharmony_ci| To compile: cc -o sched_tc6 sched_tc6.c -L. -lpsc | 40f08c3bdfSopenharmony_ci| | 41f08c3bdfSopenharmony_ci| Usage: sched_tc6 [-t priority_type] [-p priority] | 42f08c3bdfSopenharmony_ci| [-l log] [-f] [-v] [-d] | 43f08c3bdfSopenharmony_ci| | 44f08c3bdfSopenharmony_ci| Last update: Ver. 1.3, 4/10/94 23:05:03 | 45f08c3bdfSopenharmony_ci| | 46f08c3bdfSopenharmony_ci| Change Activity | 47f08c3bdfSopenharmony_ci| | 48f08c3bdfSopenharmony_ci| Version Date Name Reason | 49f08c3bdfSopenharmony_ci| 0.1 050689 CTU Initial version | 50f08c3bdfSopenharmony_ci| 0.2 010402 Manoj Iyer Ported to Linux | 51f08c3bdfSopenharmony_ci| | 52f08c3bdfSopenharmony_ci+---------------------------------------------------------------------*/ 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_ci#include <fcntl.h> 55f08c3bdfSopenharmony_ci#include <stdlib.h> 56f08c3bdfSopenharmony_ci#include <sys/time.h> 57f08c3bdfSopenharmony_ci#include <time.h> 58f08c3bdfSopenharmony_ci#include <sys/resource.h> 59f08c3bdfSopenharmony_ci#include "sched.h" 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_ci/* 62f08c3bdfSopenharmony_ci * Defines: 63f08c3bdfSopenharmony_ci * 64f08c3bdfSopenharmony_ci * USAGE: usage statement 65f08c3bdfSopenharmony_ci * 66f08c3bdfSopenharmony_ci * DEFAULT_PRIORITY_TYPE: default priority 67f08c3bdfSopenharmony_ci * 68f08c3bdfSopenharmony_ci * BLOCK_SIZE: block size (in bytes) for raw I/O 69f08c3bdfSopenharmony_ci * 70f08c3bdfSopenharmony_ci * TIMES: number of times to read raw I/O device (~25MB) 71f08c3bdfSopenharmony_ci * 72f08c3bdfSopenharmony_ci */ 73f08c3bdfSopenharmony_ci#define DEFAULT_PRIORITY_TYPE "variable" 74f08c3bdfSopenharmony_ci#define DEFAULT_LOGFILE "sched_tc6.log" 75f08c3bdfSopenharmony_ci#define BLOCK_SIZE 512 76f08c3bdfSopenharmony_ci#define TIMES 10 77f08c3bdfSopenharmony_ci#define MAX_TRIES 20 78f08c3bdfSopenharmony_ci#define NAPTIME 1 79f08c3bdfSopenharmony_ci#define REAL_TIME "1" 80f08c3bdfSopenharmony_ci#define NO_FORK "0" 81f08c3bdfSopenharmony_ci#define USAGE "Usage: %s [-l log] [-t type] [-p priority] [-f] [-v] [-d]\n" \ 82f08c3bdfSopenharmony_ci " -l log log file \n" \ 83f08c3bdfSopenharmony_ci " -t type priority type 'variable' or 'fixed' \n" \ 84f08c3bdfSopenharmony_ci " -p priority priority value \n" \ 85f08c3bdfSopenharmony_ci " -f fork child \n" \ 86f08c3bdfSopenharmony_ci " -v verbose \n" \ 87f08c3bdfSopenharmony_ci " -d enable debugging messages \n" 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_ci/* 90f08c3bdfSopenharmony_ci * Function prototypes: 91f08c3bdfSopenharmony_ci * 92f08c3bdfSopenharmony_ci * process_file: reads data file 93f08c3bdfSopenharmony_ci * 94f08c3bdfSopenharmony_ci * parse_args: parse command line arguments 95f08c3bdfSopenharmony_ci */ 96f08c3bdfSopenharmony_civoid parse_args(int, char **); 97f08c3bdfSopenharmony_ciint fork_realtime(char **); 98f08c3bdfSopenharmony_ciint read_file(int, char *); 99f08c3bdfSopenharmony_ciint lock_file(int, short, char *); 100f08c3bdfSopenharmony_ciint unlock_file(int, char *); 101f08c3bdfSopenharmony_ciint lock_error(int, char *); 102f08c3bdfSopenharmony_ci 103f08c3bdfSopenharmony_ci/* 104f08c3bdfSopenharmony_ci * Global variables: 105f08c3bdfSopenharmony_ci * 106f08c3bdfSopenharmony_ci * verbose: enable normal messages 107f08c3bdfSopenharmony_ci * 108f08c3bdfSopenharmony_ci * debug: enable debugging messages 109f08c3bdfSopenharmony_ci * 110f08c3bdfSopenharmony_ci * priority: process type (fixed priority, variable priority) 111f08c3bdfSopenharmony_ci */ 112f08c3bdfSopenharmony_ciint verbose = 0; 113f08c3bdfSopenharmony_ciint debug = 0; 114f08c3bdfSopenharmony_ciint fork_flag = 0; 115f08c3bdfSopenharmony_ciint priority = DEFAULT_PRIORITY; 116f08c3bdfSopenharmony_cichar *logfile = DEFAULT_LOGFILE; 117f08c3bdfSopenharmony_cichar *priority_type = DEFAULT_PRIORITY_TYPE; 118f08c3bdfSopenharmony_cistruct flock flock_struct; 119f08c3bdfSopenharmony_cistruct flock *flock_ptr = &flock_struct; 120f08c3bdfSopenharmony_ci 121f08c3bdfSopenharmony_ciint open_file(char *, int); 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_ci/*---------------------------------------------------------------------+ 124f08c3bdfSopenharmony_ci| main | 125f08c3bdfSopenharmony_ci| ==================================================================== | 126f08c3bdfSopenharmony_ci| | 127f08c3bdfSopenharmony_ci| Function: ... | 128f08c3bdfSopenharmony_ci| | 129f08c3bdfSopenharmony_ci+---------------------------------------------------------------------*/ 130f08c3bdfSopenharmony_ciint main(int argc, char **argv) 131f08c3bdfSopenharmony_ci{ 132f08c3bdfSopenharmony_ci char *filename = NULL; 133f08c3bdfSopenharmony_ci FILE *statfile; 134f08c3bdfSopenharmony_ci pid_t pid = 0; 135f08c3bdfSopenharmony_ci int fd; 136f08c3bdfSopenharmony_ci int rc; 137f08c3bdfSopenharmony_ci clock_t start_time; /* start & stop times */ 138f08c3bdfSopenharmony_ci clock_t stop_time; 139f08c3bdfSopenharmony_ci float elapsed_time; 140f08c3bdfSopenharmony_ci#ifdef __linux__ 141f08c3bdfSopenharmony_ci time_t timer_info; 142f08c3bdfSopenharmony_ci#else 143f08c3bdfSopenharmony_ci struct tms timer_info; /* time accounting info */ 144f08c3bdfSopenharmony_ci#endif 145f08c3bdfSopenharmony_ci 146f08c3bdfSopenharmony_ci if ((filename = getenv("KERNEL")) == NULL) { 147f08c3bdfSopenharmony_ci errno = ENODATA; 148f08c3bdfSopenharmony_ci sys_error("environment variable KERNEL not set", __FILE__, 149f08c3bdfSopenharmony_ci __LINE__); 150f08c3bdfSopenharmony_ci } 151f08c3bdfSopenharmony_ci 152f08c3bdfSopenharmony_ci /* Process command line arguments... */ 153f08c3bdfSopenharmony_ci parse_args(argc, argv); 154f08c3bdfSopenharmony_ci if (verbose) 155f08c3bdfSopenharmony_ci printf("%s: Scheduler TestSuite program\n\n", *argv); 156f08c3bdfSopenharmony_ci if (debug) { 157f08c3bdfSopenharmony_ci printf("\tpriority type: %s\n", priority_type); 158f08c3bdfSopenharmony_ci printf("\tpriority: %d\n", priority); 159f08c3bdfSopenharmony_ci printf("\tlogfile: %s\n", logfile); 160f08c3bdfSopenharmony_ci } 161f08c3bdfSopenharmony_ci 162f08c3bdfSopenharmony_ci /* Adjust the priority of this process if the real time flag is set */ 163f08c3bdfSopenharmony_ci if (!strcmp(priority_type, "fixed")) { 164f08c3bdfSopenharmony_ci#ifndef __linux__ 165f08c3bdfSopenharmony_ci if (setpri(0, DEFAULT_PRIORITY) < 0) 166f08c3bdfSopenharmony_ci sys_error("setpri failed", __FILE__, __LINE__); 167f08c3bdfSopenharmony_ci#else 168f08c3bdfSopenharmony_ci if (setpriority(PRIO_PROCESS, 0, 0) < 0) 169f08c3bdfSopenharmony_ci sys_error("setpri failed", __FILE__, __LINE__); 170f08c3bdfSopenharmony_ci#endif 171f08c3bdfSopenharmony_ci } else { 172f08c3bdfSopenharmony_ci if (nice((priority - 50) - (nice(0) + 20)) < 0 && errno != 0) 173f08c3bdfSopenharmony_ci sys_error("nice failed", __FILE__, __LINE__); 174f08c3bdfSopenharmony_ci } 175f08c3bdfSopenharmony_ci 176f08c3bdfSopenharmony_ci /* Read from raw I/O device and record elapsed time... */ 177f08c3bdfSopenharmony_ci start_time = time(&timer_info); 178f08c3bdfSopenharmony_ci 179f08c3bdfSopenharmony_ci /* Open and lock file file... */ 180f08c3bdfSopenharmony_ci fd = open_file(filename, O_RDWR); 181f08c3bdfSopenharmony_ci if (!lock_file(fd, F_WRLCK, filename)) /* set exclusive lock */ 182f08c3bdfSopenharmony_ci error("lock_file failed", __FILE__, __LINE__); 183f08c3bdfSopenharmony_ci 184f08c3bdfSopenharmony_ci /* If fork flag set, fork a real process */ 185f08c3bdfSopenharmony_ci if (fork_flag) 186f08c3bdfSopenharmony_ci pid = fork_realtime(argv); 187f08c3bdfSopenharmony_ci 188f08c3bdfSopenharmony_ci /* Read file */ 189f08c3bdfSopenharmony_ci if (debug) { 190f08c3bdfSopenharmony_ci printf("\tprocess id %d successfully locked %s\n", 191f08c3bdfSopenharmony_ci getpid(), filename); 192f08c3bdfSopenharmony_ci printf("\tprocess id %d starting to read %s\n", 193f08c3bdfSopenharmony_ci getpid(), filename); 194f08c3bdfSopenharmony_ci } 195f08c3bdfSopenharmony_ci 196f08c3bdfSopenharmony_ci if (!read_file(fd, filename)) 197f08c3bdfSopenharmony_ci error("read_file failed", __FILE__, __LINE__); 198f08c3bdfSopenharmony_ci 199f08c3bdfSopenharmony_ci /* Stop the timer and calculate the elapsed time */ 200f08c3bdfSopenharmony_ci stop_time = time(&timer_info); 201f08c3bdfSopenharmony_ci elapsed_time = (float)(stop_time - start_time) / 100.0; 202f08c3bdfSopenharmony_ci 203f08c3bdfSopenharmony_ci /* Write the elapsed time to the temporary file... */ 204f08c3bdfSopenharmony_ci if ((statfile = fopen(logfile, "w")) == NULL) 205f08c3bdfSopenharmony_ci sys_error("fopen failed", __FILE__, __LINE__); 206f08c3bdfSopenharmony_ci 207f08c3bdfSopenharmony_ci fprintf(statfile, "%f\n", elapsed_time); 208f08c3bdfSopenharmony_ci if (debug) 209f08c3bdfSopenharmony_ci printf("\n\telapsed time: %f\n", elapsed_time); 210f08c3bdfSopenharmony_ci 211f08c3bdfSopenharmony_ci if (fclose(statfile) < 0) 212f08c3bdfSopenharmony_ci sys_error("fclose failed", __FILE__, __LINE__); 213f08c3bdfSopenharmony_ci 214f08c3bdfSopenharmony_ci /* Unlock file at latest possible time to prevent real time child from 215f08c3bdfSopenharmony_ci * writing throughput results before user process parent */ 216f08c3bdfSopenharmony_ci unlock_file(fd, filename); 217f08c3bdfSopenharmony_ci close(fd); 218f08c3bdfSopenharmony_ci 219f08c3bdfSopenharmony_ci if (debug) 220f08c3bdfSopenharmony_ci printf("\tprocess id %d completed read and unlocked file\n", 221f08c3bdfSopenharmony_ci getpid()); 222f08c3bdfSopenharmony_ci 223f08c3bdfSopenharmony_ci /* The parent waits for child process to complete before exiting 224f08c3bdfSopenharmony_ci * so the driver will not read the throughput results file before 225f08c3bdfSopenharmony_ci * child writes to the file */ 226f08c3bdfSopenharmony_ci if (pid != 0) { /* if parent process ... *//* wait for child process */ 227f08c3bdfSopenharmony_ci if (debug) 228f08c3bdfSopenharmony_ci printf 229f08c3bdfSopenharmony_ci ("parent waiting on child process %d to complete\n", 230f08c3bdfSopenharmony_ci pid); 231f08c3bdfSopenharmony_ci 232f08c3bdfSopenharmony_ci while ((rc = wait(NULL)) != pid) 233f08c3bdfSopenharmony_ci if (rc == -1) 234f08c3bdfSopenharmony_ci sys_error("wait failed", __FILE__, __LINE__); 235f08c3bdfSopenharmony_ci/* 236f08c3bdfSopenharmony_ciDARA: which one to use 237f08c3bdfSopenharmony_ci1st -- hangs 238f08c3bdfSopenharmony_ci2nd -- ERROR message 239f08c3bdfSopenharmony_ci 240f08c3bdfSopenharmony_ci while (wait((void *) 0) != pid) ; 241f08c3bdfSopenharmony_ci while ((rc=wait ((void *) 0)) != pid) 242f08c3bdfSopenharmony_ci if (rc == -1) 243f08c3bdfSopenharmony_ci sys_error ("wait failed", __FILE__, __LINE__); 244f08c3bdfSopenharmony_ci*/ 245f08c3bdfSopenharmony_ci } 246f08c3bdfSopenharmony_ci 247f08c3bdfSopenharmony_ci /* Exit with success! */ 248f08c3bdfSopenharmony_ci if (verbose) 249f08c3bdfSopenharmony_ci printf("\nsuccessful!\n"); 250f08c3bdfSopenharmony_ci return (0); 251f08c3bdfSopenharmony_ci} 252f08c3bdfSopenharmony_ci 253f08c3bdfSopenharmony_ci/*---------------------------------------------------------------------+ 254f08c3bdfSopenharmony_ci| open_file () | 255f08c3bdfSopenharmony_ci| ==================================================================== | 256f08c3bdfSopenharmony_ci| | 257f08c3bdfSopenharmony_ci| Function: ... | 258f08c3bdfSopenharmony_ci| | 259f08c3bdfSopenharmony_ci+---------------------------------------------------------------------*/ 260f08c3bdfSopenharmony_ciint open_file(char *file, int open_mode) 261f08c3bdfSopenharmony_ci{ 262f08c3bdfSopenharmony_ci int file_desc; 263f08c3bdfSopenharmony_ci 264f08c3bdfSopenharmony_ci if ((file_desc = open(file, open_mode)) < 0) 265f08c3bdfSopenharmony_ci sys_error("open failed", __FILE__, __LINE__); 266f08c3bdfSopenharmony_ci return (file_desc); 267f08c3bdfSopenharmony_ci} 268f08c3bdfSopenharmony_ci 269f08c3bdfSopenharmony_ci/*---------------------------------------------------------------------+ 270f08c3bdfSopenharmony_ci| fork_realtime () | 271f08c3bdfSopenharmony_ci| ==================================================================== | 272f08c3bdfSopenharmony_ci| | 273f08c3bdfSopenharmony_ci| Function: ... | 274f08c3bdfSopenharmony_ci| | 275f08c3bdfSopenharmony_ci+---------------------------------------------------------------------*/ 276f08c3bdfSopenharmony_ciint fork_realtime(char **args) 277f08c3bdfSopenharmony_ci{ 278f08c3bdfSopenharmony_ci int pid; 279f08c3bdfSopenharmony_ci char *results_file = args[2]; 280f08c3bdfSopenharmony_ci char *priority = args[3]; 281f08c3bdfSopenharmony_ci 282f08c3bdfSopenharmony_ci /* fork process then determine if process is parent or child */ 283f08c3bdfSopenharmony_ci pid = fork(); 284f08c3bdfSopenharmony_ci switch (pid) { 285f08c3bdfSopenharmony_ci /* fork failed */ 286f08c3bdfSopenharmony_ci case -1: 287f08c3bdfSopenharmony_ci sys_error("fork failed", __FILE__, __LINE__); 288f08c3bdfSopenharmony_ci 289f08c3bdfSopenharmony_ci /* child process */ 290f08c3bdfSopenharmony_ci case 0: 291f08c3bdfSopenharmony_ci if (execl(*args, *args, REAL_TIME, results_file, priority, 292f08c3bdfSopenharmony_ci NO_FORK, NULL) < 0) 293f08c3bdfSopenharmony_ci sys_error("execl failed", __FILE__, __LINE__); 294f08c3bdfSopenharmony_ci 295f08c3bdfSopenharmony_ci /* parent process */ 296f08c3bdfSopenharmony_ci default: 297f08c3bdfSopenharmony_ci#ifdef DEBUG 298f08c3bdfSopenharmony_ci printf("\tparent process id = %d\n", getpid()); 299f08c3bdfSopenharmony_ci printf("\tchild process id = %d\n\n", pid); 300f08c3bdfSopenharmony_ci#endif 301f08c3bdfSopenharmony_ci 302f08c3bdfSopenharmony_ci break; 303f08c3bdfSopenharmony_ci } 304f08c3bdfSopenharmony_ci return (pid); 305f08c3bdfSopenharmony_ci} 306f08c3bdfSopenharmony_ci 307f08c3bdfSopenharmony_ci/*---------------------------------------------------------------------+ 308f08c3bdfSopenharmony_ci| read_file () | 309f08c3bdfSopenharmony_ci| ==================================================================== | 310f08c3bdfSopenharmony_ci| | 311f08c3bdfSopenharmony_ci| Function: ... | 312f08c3bdfSopenharmony_ci| | 313f08c3bdfSopenharmony_ci+---------------------------------------------------------------------*/ 314f08c3bdfSopenharmony_ciint read_file(int fd, char *filename) 315f08c3bdfSopenharmony_ci{ 316f08c3bdfSopenharmony_ci int bytes_read; 317f08c3bdfSopenharmony_ci int loop_count; 318f08c3bdfSopenharmony_ci long total_bytes; 319f08c3bdfSopenharmony_ci off_t lseek(); 320f08c3bdfSopenharmony_ci off_t file_offset = 0; 321f08c3bdfSopenharmony_ci int whence = 0; 322f08c3bdfSopenharmony_ci 323f08c3bdfSopenharmony_ci char buf[BLOCK_SIZE]; 324f08c3bdfSopenharmony_ci 325f08c3bdfSopenharmony_ci /* read file for "TIMES" number of times */ 326f08c3bdfSopenharmony_ci total_bytes = 0; 327f08c3bdfSopenharmony_ci if (debug) 328f08c3bdfSopenharmony_ci printf("\n"); 329f08c3bdfSopenharmony_ci for (loop_count = 1; loop_count <= TIMES; loop_count++) { 330f08c3bdfSopenharmony_ci while ((bytes_read = read(fd, buf, BLOCK_SIZE)) > 0) { 331f08c3bdfSopenharmony_ci if (bytes_read == -1) { 332f08c3bdfSopenharmony_ci sys_error("read failed", __FILE__, __LINE__); 333f08c3bdfSopenharmony_ci } else 334f08c3bdfSopenharmony_ci total_bytes = total_bytes + bytes_read; 335f08c3bdfSopenharmony_ci } 336f08c3bdfSopenharmony_ci if (lseek(fd, file_offset, whence) < 0) 337f08c3bdfSopenharmony_ci sys_error("lseek failed", __FILE__, __LINE__); 338f08c3bdfSopenharmony_ci 339f08c3bdfSopenharmony_ci if (debug) { 340f08c3bdfSopenharmony_ci printf("\r\ttotal bytes read = %ld", total_bytes); 341f08c3bdfSopenharmony_ci fflush(stdout); 342f08c3bdfSopenharmony_ci } 343f08c3bdfSopenharmony_ci total_bytes = 0; 344f08c3bdfSopenharmony_ci } 345f08c3bdfSopenharmony_ci if (debug) 346f08c3bdfSopenharmony_ci printf("\n"); 347f08c3bdfSopenharmony_ci return 1; 348f08c3bdfSopenharmony_ci} 349f08c3bdfSopenharmony_ci 350f08c3bdfSopenharmony_ci/*---------------------------------------------------------------------+ 351f08c3bdfSopenharmony_ci| lock_file () | 352f08c3bdfSopenharmony_ci| ==================================================================== | 353f08c3bdfSopenharmony_ci| | 354f08c3bdfSopenharmony_ci| Function: ... | 355f08c3bdfSopenharmony_ci| | 356f08c3bdfSopenharmony_ci+---------------------------------------------------------------------*/ 357f08c3bdfSopenharmony_ciint lock_file(int fd, short lock_type, char *file) 358f08c3bdfSopenharmony_ci{ 359f08c3bdfSopenharmony_ci int lock_attempt = 1; 360f08c3bdfSopenharmony_ci int lock_mode; 361f08c3bdfSopenharmony_ci 362f08c3bdfSopenharmony_ci#ifdef DEBUG 363f08c3bdfSopenharmony_ci lock_mode = F_SETLK; /* return if lock fails */ 364f08c3bdfSopenharmony_ci#else 365f08c3bdfSopenharmony_ci lock_mode = F_SETLKW; /* set lock and use system wait */ 366f08c3bdfSopenharmony_ci#endif 367f08c3bdfSopenharmony_ci 368f08c3bdfSopenharmony_ci /* file segment locking set data type flock - information 369f08c3bdfSopenharmony_ci * passed to system by user -- 370f08c3bdfSopenharmony_ci * l_whence: starting point of relative offset of file 371f08c3bdfSopenharmony_ci * l_start: defines relative offset in bytes from l_whence 372f08c3bdfSopenharmony_ci * l_len: number of consecutive bytes to be locked 373f08c3bdfSopenharmony_ci */ 374f08c3bdfSopenharmony_ci flock_ptr->l_whence = 0; 375f08c3bdfSopenharmony_ci flock_ptr->l_start = 0; 376f08c3bdfSopenharmony_ci flock_ptr->l_len = 0; 377f08c3bdfSopenharmony_ci flock_ptr->l_type = lock_type; 378f08c3bdfSopenharmony_ci 379f08c3bdfSopenharmony_ci while (fcntl(fd, lock_mode, flock_ptr) == -1) { 380f08c3bdfSopenharmony_ci if (lock_error(fd, file)) { 381f08c3bdfSopenharmony_ci sleep(NAPTIME); 382f08c3bdfSopenharmony_ci if (++lock_attempt > MAX_TRIES) { 383f08c3bdfSopenharmony_ci printf 384f08c3bdfSopenharmony_ci ("ERROR: max lock attempts of %d reached\n", 385f08c3bdfSopenharmony_ci MAX_TRIES); 386f08c3bdfSopenharmony_ci return (0); 387f08c3bdfSopenharmony_ci } 388f08c3bdfSopenharmony_ci } else 389f08c3bdfSopenharmony_ci return (0); 390f08c3bdfSopenharmony_ci } 391f08c3bdfSopenharmony_ci return (1); 392f08c3bdfSopenharmony_ci} 393f08c3bdfSopenharmony_ci 394f08c3bdfSopenharmony_ci/*---------------------------------------------------------------------+ 395f08c3bdfSopenharmony_ci| unlock_file () | 396f08c3bdfSopenharmony_ci| ==================================================================== | 397f08c3bdfSopenharmony_ci| | 398f08c3bdfSopenharmony_ci| Function: ... | 399f08c3bdfSopenharmony_ci| | 400f08c3bdfSopenharmony_ci+---------------------------------------------------------------------*/ 401f08c3bdfSopenharmony_ciint unlock_file(int fd, char *file) 402f08c3bdfSopenharmony_ci{ 403f08c3bdfSopenharmony_ci flock_ptr->l_type = F_UNLCK; 404f08c3bdfSopenharmony_ci 405f08c3bdfSopenharmony_ci if (fcntl(fd, F_SETLK, flock_ptr) < 0) 406f08c3bdfSopenharmony_ci sys_error("fcntl failed", __FILE__, __LINE__); 407f08c3bdfSopenharmony_ci 408f08c3bdfSopenharmony_ci return 1; 409f08c3bdfSopenharmony_ci} 410f08c3bdfSopenharmony_ci 411f08c3bdfSopenharmony_ci/*---------------------------------------------------------------------+ 412f08c3bdfSopenharmony_ci| main | 413f08c3bdfSopenharmony_ci| ==================================================================== | 414f08c3bdfSopenharmony_ci| | 415f08c3bdfSopenharmony_ci| Function: ... | 416f08c3bdfSopenharmony_ci| | 417f08c3bdfSopenharmony_ci+---------------------------------------------------------------------*/ 418f08c3bdfSopenharmony_ciint lock_error(int fd, char *file) 419f08c3bdfSopenharmony_ci{ 420f08c3bdfSopenharmony_ci int ret = 1; 421f08c3bdfSopenharmony_ci 422f08c3bdfSopenharmony_ci printf("ERROR: lock failed: %s\n", file); 423f08c3bdfSopenharmony_ci switch (errno) { 424f08c3bdfSopenharmony_ci case EACCES: /* access not allowed */ 425f08c3bdfSopenharmony_ci fcntl(fd, F_GETLK, flock_ptr); 426f08c3bdfSopenharmony_ci#ifndef __linux__ 427f08c3bdfSopenharmony_ci printf("ERROR: lock exists - nid: %lX pid: %ld\n", 428f08c3bdfSopenharmony_ci flock_ptr->l_sysid, flock_ptr->l_pid); 429f08c3bdfSopenharmony_ci#else 430f08c3bdfSopenharmony_ci printf("ERROR: lock exists - nid:\n"); 431f08c3bdfSopenharmony_ci#endif 432f08c3bdfSopenharmony_ci break; 433f08c3bdfSopenharmony_ci 434f08c3bdfSopenharmony_ci /* 435f08c3bdfSopenharmony_ci * This was a DS error code, and DS does not exist V3.1 436f08c3bdfSopenharmony_ci */ 437f08c3bdfSopenharmony_ci#ifndef __linux__ 438f08c3bdfSopenharmony_ci case EDIST: /* DS file server blocking requests */ 439f08c3bdfSopenharmony_ci printf("ERROR: errno == EDIST\n"); 440f08c3bdfSopenharmony_ci printf("The server has blocked new inbound requests\n"); 441f08c3bdfSopenharmony_ci printf("or outbound requests are currently blocked.\n"); 442f08c3bdfSopenharmony_ci break; 443f08c3bdfSopenharmony_ci#endif 444f08c3bdfSopenharmony_ci 445f08c3bdfSopenharmony_ci case EAGAIN: /* server too busy */ 446f08c3bdfSopenharmony_ci printf("ERROR: Server too busy to accept the request\n"); 447f08c3bdfSopenharmony_ci break; 448f08c3bdfSopenharmony_ci 449f08c3bdfSopenharmony_ci case EDEADLK: /* only when F_SETLKW cmd is used */ 450f08c3bdfSopenharmony_ci printf("ERROR: Putting the calling process to sleep\n"); 451f08c3bdfSopenharmony_ci printf("would cause a dead lock\n"); 452f08c3bdfSopenharmony_ci ret = 0; 453f08c3bdfSopenharmony_ci break; 454f08c3bdfSopenharmony_ci 455f08c3bdfSopenharmony_ci case ENOLCK: /* out of locks */ 456f08c3bdfSopenharmony_ci printf("ERROR: No more file locks available\n"); 457f08c3bdfSopenharmony_ci ret = 0; 458f08c3bdfSopenharmony_ci break; 459f08c3bdfSopenharmony_ci 460f08c3bdfSopenharmony_ci case ENOMEM: /* out of memory */ 461f08c3bdfSopenharmony_ci printf("ERROR: The server or client does not have enough\n"); 462f08c3bdfSopenharmony_ci printf("memory to service the request.\n"); 463f08c3bdfSopenharmony_ci ret = 0; 464f08c3bdfSopenharmony_ci break; 465f08c3bdfSopenharmony_ci 466f08c3bdfSopenharmony_ci default: /* miscellaneous errors */ 467f08c3bdfSopenharmony_ci printf("ERROR: Unknown lock error\n"); 468f08c3bdfSopenharmony_ci perror("reason"); 469f08c3bdfSopenharmony_ci ret = 0; 470f08c3bdfSopenharmony_ci break; 471f08c3bdfSopenharmony_ci } 472f08c3bdfSopenharmony_ci 473f08c3bdfSopenharmony_ci printf("errno = %d\n", errno); /* log the errno value */ 474f08c3bdfSopenharmony_ci sleep(10); 475f08c3bdfSopenharmony_ci 476f08c3bdfSopenharmony_ci return (ret); 477f08c3bdfSopenharmony_ci} 478f08c3bdfSopenharmony_ci 479f08c3bdfSopenharmony_ci/*---------------------------------------------------------------------+ 480f08c3bdfSopenharmony_ci| parse_args () | 481f08c3bdfSopenharmony_ci| ==================================================================== | 482f08c3bdfSopenharmony_ci| | 483f08c3bdfSopenharmony_ci| Function: Parse the command line arguments & initialize global | 484f08c3bdfSopenharmony_ci| variables. | 485f08c3bdfSopenharmony_ci| | 486f08c3bdfSopenharmony_ci| Updates: (command line options) | 487f08c3bdfSopenharmony_ci| | 488f08c3bdfSopenharmony_ci| [-t] type: priority type "fixed" or "variable" | 489f08c3bdfSopenharmony_ci| [-p] priority: priority value | 490f08c3bdfSopenharmony_ci| [-l] logfile: log file name | 491f08c3bdfSopenharmony_ci| [-v] verbose | 492f08c3bdfSopenharmony_ci| [-d] enable debugging messages | 493f08c3bdfSopenharmony_ci| | 494f08c3bdfSopenharmony_ci+---------------------------------------------------------------------*/ 495f08c3bdfSopenharmony_civoid parse_args(int argc, char **argv) 496f08c3bdfSopenharmony_ci{ 497f08c3bdfSopenharmony_ci int opt; 498f08c3bdfSopenharmony_ci int lflg = 0, pflg = 0, tflg = 0; 499f08c3bdfSopenharmony_ci int errflag = 0; 500f08c3bdfSopenharmony_ci char *program_name = *argv; 501f08c3bdfSopenharmony_ci extern char *optarg; /* Command line option */ 502f08c3bdfSopenharmony_ci 503f08c3bdfSopenharmony_ci /* 504f08c3bdfSopenharmony_ci * Parse command line options. 505f08c3bdfSopenharmony_ci */ 506f08c3bdfSopenharmony_ci while ((opt = getopt(argc, argv, "fl:t:p:vd")) != EOF) { 507f08c3bdfSopenharmony_ci switch (opt) { 508f08c3bdfSopenharmony_ci case 'f': /* fork flag */ 509f08c3bdfSopenharmony_ci fork_flag++; 510f08c3bdfSopenharmony_ci break; 511f08c3bdfSopenharmony_ci case 'l': /* log file */ 512f08c3bdfSopenharmony_ci lflg++; 513f08c3bdfSopenharmony_ci logfile = optarg; 514f08c3bdfSopenharmony_ci break; 515f08c3bdfSopenharmony_ci case 't': /* process type */ 516f08c3bdfSopenharmony_ci tflg++; 517f08c3bdfSopenharmony_ci priority_type = optarg; 518f08c3bdfSopenharmony_ci break; 519f08c3bdfSopenharmony_ci case 'p': /* process priority */ 520f08c3bdfSopenharmony_ci pflg++; 521f08c3bdfSopenharmony_ci priority = atoi(optarg); 522f08c3bdfSopenharmony_ci break; 523f08c3bdfSopenharmony_ci case 'v': /* verbose */ 524f08c3bdfSopenharmony_ci verbose++; 525f08c3bdfSopenharmony_ci break; 526f08c3bdfSopenharmony_ci case 'd': /* enable debugging messages */ 527f08c3bdfSopenharmony_ci verbose++; 528f08c3bdfSopenharmony_ci debug++; 529f08c3bdfSopenharmony_ci break; 530f08c3bdfSopenharmony_ci default: 531f08c3bdfSopenharmony_ci errflag++; 532f08c3bdfSopenharmony_ci break; 533f08c3bdfSopenharmony_ci } 534f08c3bdfSopenharmony_ci } 535f08c3bdfSopenharmony_ci 536f08c3bdfSopenharmony_ci /* 537f08c3bdfSopenharmony_ci * Check percentage and process slots... 538f08c3bdfSopenharmony_ci */ 539f08c3bdfSopenharmony_ci if (tflg) { 540f08c3bdfSopenharmony_ci if (strcmp(priority_type, "fixed") && 541f08c3bdfSopenharmony_ci strcmp(priority_type, "variable")) { 542f08c3bdfSopenharmony_ci errflag++; 543f08c3bdfSopenharmony_ci fprintf(stderr, "Error: priority type must be: " 544f08c3bdfSopenharmony_ci "\'fixed\' or \'variable\'\n"); 545f08c3bdfSopenharmony_ci } 546f08c3bdfSopenharmony_ci } 547f08c3bdfSopenharmony_ci if (pflg) { 548f08c3bdfSopenharmony_ci if (priority < 50 || priority > 100) { 549f08c3bdfSopenharmony_ci errflag++; 550f08c3bdfSopenharmony_ci fprintf(stderr, "Error: priority range [50..100]\n"); 551f08c3bdfSopenharmony_ci } 552f08c3bdfSopenharmony_ci } 553f08c3bdfSopenharmony_ci if (errflag) { 554f08c3bdfSopenharmony_ci fprintf(stderr, USAGE, program_name); 555f08c3bdfSopenharmony_ci exit(2); 556f08c3bdfSopenharmony_ci } 557f08c3bdfSopenharmony_ci} 558