sync_file_range01.c revision 43337a3cf6f8809647cf9fc6c0054241f44b1fb1
1/****************************************************************************** 2 * sync_file_range01.c 3 * Copyright (c) International Business Machines Corp., 2008 4 * Email: bnpoorni@in.ibm.com 5 *****************************************************************************/ 6 7/******************************************************************************/ 8/* */ 9/* This program is free software; you can redistribute it and/or modify */ 10/* it under the terms of the GNU General Public License as published by */ 11/* the Free Software Foundation; either version 2 of the License, or */ 12/* (at your option) any later version. */ 13/* */ 14/* This program is distributed in the hope that it will be useful, */ 15/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 16/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ 17/* the GNU General Public License for more details. */ 18/* */ 19/* You should have received a copy of the GNU General Public License */ 20/* along with this program; if not, write to the Free Software */ 21/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 22/* */ 23/******************************************************************************/ 24 25 26/***************************************************************************** 27 * TEST IDENTIFIER : sync_file_range01 28 * 29 * EXECUTED BY : anyone 30 * 31 * TEST TITLE : Checks for Errors from sync_file_range() 32 * 33 * TEST CASE TOTAL : 5 34 * 35 * CPU ARCHITECTURES : All 36 * 37 * AUTHOR : B N Poornima 38 * 39 * DATE STARTED : 21/07/2008 40 * 41 * TEST CASES 42 * (Tests sync_file_range() for different test cases as reported in the man 43 * page) 44 * 45 * INPUT SPECIFICATIONS 46 * No input needs to be specified 47 * sync_file_data() in-puts are specified through test_data 48 * 49 * OUTPUT SPECIFICATIONS 50 * sync_file_data() error message matches with the expected error 51 * message. 52 * 53 * ENVIRONMENTAL NEEDS 54 * Kernel version 2.6.17 and above 55 * Kernel version 2.6.22 and above in case of PPC and PPC64 56 * 57 * SPECIAL PROCEDURAL REQUIREMENTS 58 * None 59 * 60 * DETAILED DESCRIPTION 61 * This is a test case for sync_file_range() system call. 62 * This test suite tests various error messages from the system call 63 * If the error message received matches with the expected 64 * test is considered passed else test fails 65 * 66 * Total 5 Test Cases :- 67 * Various error messages from the man page 68 * 69 * Setup: 70 * Setup files on which sync_file_range is to be called 71 * 72 * Test: 73 * Loop if the proper options are given. 74 * Execute system call 75 * Check return code. 76 * If error obtained matches with the expected error 77 * PASS the test, otherwise TEST FAILS 78 * 79 * Cleanup: 80 * Cleanup the temporary folder 81 * 82 ******************************************************************************/ 83#define _GNU_SOURCE 84 85/* Standard Include Files */ 86#include <stdio.h> 87#include <stdlib.h> 88#include <errno.h> 89#include <sys/stat.h> 90#include <sys/types.h> 91#include <fcntl.h> 92#include <sys/utsname.h> 93#include <unistd.h> 94 95/* Harness Specific Include Files. */ 96#include "test.h" 97#include "usctest.h" 98#include "linux_syscall_numbers.h" 99 100 101#if defined(__powerpc__) || defined(__powerpc64__) 102 #ifndef __NR_sync_file_range2 103 #define __NR_sync_file_range2 -1 //DUMMY VALUE 104 int arch_support = 0; //Architecure is not supported 105 #else 106 int arch_support = 1; //Architecture is supported 107 #endif 108#else 109 #ifndef __NR_sync_file_range 110 #define __NR_sync_file_range -1 //DUMMY Value 111 int arch_support = 0; 112 #else 113 int arch_support = 1; 114 #endif 115#endif 116 117 118#ifndef SYNC_FILE_RANGE_WAIT_BEFORE 119#define SYNC_FILE_RANGE_WAIT_BEFORE 1 120#define SYNC_FILE_RANGE_WRITE 2 //DUMMY VALUES 121#define SYNC_FILE_RANGE_WAIT_AFTER 4 122#endif 123 124#define SYNC_FILE_RANGE_INVALID 8 125 126/* Extern Global Variables */ 127extern int Tst_count; /* counter for tst_xxx routines. */ 128extern char *TESTDIR; /* temporary dir created by tst_tmpdir() */ 129 130/* Global Variables */ 131char *TCID = "sync_file_range01"; /* test program identifier. */ 132char filename[255]; /* file used for testing */ 133char spl_file[] = "/dev/null"; 134int filed, sfd; /* normal and special fds */ 135int bfd = -1; /* Bad file descriptor */ 136 137struct test_data_t 138{ 139 int *fd; 140 off64_t offset; 141 off64_t nbytes; 142 unsigned int flags; 143 int error; 144} test_data[] = { 145 {&bfd, 0, 1, SYNC_FILE_RANGE_WRITE, EBADF}, 146 {&sfd, 0, 1, SYNC_FILE_RANGE_WAIT_AFTER, ESPIPE}, 147 {&filed, -1, 1, SYNC_FILE_RANGE_WAIT_BEFORE, EINVAL}, 148 {&filed, 0, -1, SYNC_FILE_RANGE_WRITE, EINVAL}, 149 {&filed, 0, 1, SYNC_FILE_RANGE_INVALID, EINVAL} 150 }; 151 152int TST_TOTAL = sizeof(test_data) / sizeof(test_data[0]); 153 154 155 156 157/* Extern Global Functions */ 158/******************************************************************************/ 159/* */ 160/* Function: cleanup */ 161/* */ 162/* Description: Performs all one time clean up for this test on successful */ 163/* completion, premature exit or failure. Closes all temporary */ 164/* files, removes all temporary directories exits the test with */ 165/* appropriate return code by calling tst_exit() function. */ 166/* */ 167/* Input: None. */ 168/* */ 169/* Output: None. */ 170/* */ 171/* Return: On failure - Exits calling tst_exit(). Non '0' return code. */ 172/* On success - Exits calling tst_exit(). With '0' return code. */ 173/* */ 174/******************************************************************************/ 175extern void 176cleanup() 177{ 178 /* 179 * print timing stats if that option was specified. 180 * print errno log if that option was specified. 181 */ 182 TEST_CLEANUP; 183 184 /* close the file we have open */ 185 if (close(filed) == -1) { 186 tst_resm(TWARN, "close(%s) Failed, errno=%d : %s", filename, errno, strerror(errno)); 187 } 188 189 /* Remove tmp dir and all files in it */ 190 tst_rmdir(); 191 192 /* exit with return code appropriate for results */ 193 tst_exit(); 194 195 tst_exit(); 196} 197 198 199/* Local Functions */ 200/******************************************************************************/ 201/* */ 202/* Function: setup */ 203/* */ 204/* Description: Performs all one time setup for this test. This function is */ 205/* typically used to capture signals, create temporary dirs */ 206/* and temporary files that may be used in the course of this */ 207/* test. */ 208/* */ 209/* Input: None. */ 210/* */ 211/* Output: None. */ 212/* */ 213/* Return: On failure - Exits by calling cleanup(). */ 214/* On success - returns 0. */ 215/* */ 216/******************************************************************************/ 217void 218setup() 219{ 220/* capture signals */ 221 tst_sig(NOFORK, DEF_HANDLER, cleanup); 222 223 /* Pause if that option was specified */ 224 TEST_PAUSE; 225 226 /* make a temp directory and cd to it */ 227 tst_tmpdir(); 228 229 sprintf(filename,"tmpfile_%d",getpid()); 230 if ((filed = open(filename,O_RDWR|O_CREAT,0700)) == -1) { 231 tst_brkm(TBROK, cleanup, 232 "open(%s, O_RDWR|O_CREAT,0700) Failed, errno=%d : %s", 233 filename, errno, strerror(errno)); 234 235 sfd = open(spl_file, O_RDWR|O_CREAT, 0700); 236 237 } 238 239return; 240} 241 242/***************************************************************************** 243 * Wraper function to call sync_file_range system call 244 ******************************************************************************/ 245static inline long syncfilerange(int fd, off64_t offset, off64_t nbytes, unsigned int flags) 246{ 247 248 #if (defined(__powerpc64__) || defined(__powerpc__)) && (__WORDSIZE==32) 249 250 return syscall(__NR_sync_file_range2, fd, flags, (int)(offset >>32), \ 251 (int)offset, (int)(nbytes >>32), (int)nbytes); 252 253 #elif (defined(__powerpc64__) || defined(__powerpc__)) && (__WORDSIZE==64) 254 255 return syscall(__NR_sync_file_range2, fd, flags, offset, nbytes); 256 #else 257 258 return syscall(__NR_sync_file_range, fd, offset, nbytes, flags); 259 #endif 260 261 return 0; 262} 263 264 265 266 267 268/******************************************************************************/ 269/* */ 270/* Function: main */ 271/* */ 272/* Description: Entry point to this test-case. It parses all the command line */ 273/* inputs, calls the global setup and executes the test. It logs */ 274/* the test status and results appropriately using the LTP API's */ 275/* On successful completion or premature failure, cleanup() func */ 276/* is called and test exits with an appropriate return code. */ 277/* */ 278/* Input: Describe input arguments to this test-case */ 279/* -l - Number of iteration */ 280/* -v - Prints verbose output */ 281/* -V - Prints the version number */ 282/* */ 283/* Exit: On failure - Exits by calling cleanup(). */ 284/* On success - exits with 0 exit value. */ 285/* */ 286/******************************************************************************/ 287int 288main(int ac, /* number of command line parameters */ 289 char **av) /* pointer to the array of the command line parameters. */ 290{ 291 292 int test_index = 0; 293 int lc; 294 char *msg; 295 296 /*************************************************************** 297 parse standard options 298 ********************************************************************/ 299 if ( (msg=parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *) NULL ) 300 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); 301 302 303#if defined(__powerpc__) || defined(__powerpc64__) /* for PPC, kernel version > 2.6.21 needed */ 304 if ( !arch_support || (tst_kvercmp(2,16,22) < 0)) { 305 tst_resm(TCONF, "System doesn't support execution of the test"); 306 tst_exit(); 307 } 308#else 309 /* For other archs, need kernel version > 2.6.16 */ 310 311 if ( !arch_support || (tst_kvercmp(2,6,17) < 0)) { 312 tst_resm(TCONF, "System doesn't support execution of the test"); 313 tst_exit(); 314 } 315 316#endif 317 318/* perform global test setup, call setup() function. */ 319setup(); 320 321for (lc=0; TEST_LOOPING(lc); lc++) { 322 /* reset Tst_count in case we are looping. */ 323 Tst_count=0; 324 325 for(test_index = 0 ; test_index < TST_TOTAL; test_index ++) 326 { 327 TEST(syncfilerange(*(test_data[test_index].fd), test_data[test_index].offset, \ 328 test_data[test_index].nbytes, test_data[test_index].flags)); 329 330 331 if (TEST_RETURN != -1) { 332 tst_resm(TFAIL, "call succeeded unexpectedly"); 333 continue; 334 } 335 336 TEST_ERROR_LOG(TEST_ERRNO); 337 338 if (TEST_ERRNO == test_data[test_index].error) { 339 tst_resm(TPASS, "expected failure - " 340 "errno = %d : %s", TEST_ERRNO, 341 strerror(TEST_ERRNO)); 342 } else { 343 tst_resm(TFAIL, "unexpected error - %d : %s - " 344 "expected %d", TEST_ERRNO, 345 strerror(TEST_ERRNO), test_data[test_index].error); 346 } 347 } 348 349 } 350 351cleanup(); 352return 0; 353} 354