[Box Backup-commit] COMMIT r1176 - in box/chris/merge: . lib lib/intercept test/raidfile

boxbackup-dev at fluffy.co.uk boxbackup-dev at fluffy.co.uk
Sun Nov 26 19:43:20 GMT 2006


Author: chris
Date: 2006-11-26 19:43:20 +0000 (Sun, 26 Nov 2006)
New Revision: 1176

Added:
   box/chris/merge/lib/intercept/
   box/chris/merge/lib/intercept/intercept.cpp
Removed:
   box/chris/merge/test/raidfile/intercept.cpp
Modified:
   box/chris/merge/modules.txt
Log:
Moved intercept code to a library module to allow it to be used by 
test/bbackupd as well (refs #3)


Copied: box/chris/merge/lib/intercept/intercept.cpp (from rev 1139, box/chris/merge/test/raidfile/intercept.cpp)
===================================================================
--- box/chris/merge/lib/intercept/intercept.cpp	                        (rev 0)
+++ box/chris/merge/lib/intercept/intercept.cpp	2006-11-26 19:43:20 UTC (rev 1176)
@@ -0,0 +1,315 @@
+// --------------------------------------------------------------------------
+//
+// File
+//		Name:    intercept.cpp
+//		Purpose: Syscall interception code for the raidfile test
+//		Created: 2003/07/22
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#ifdef HAVE_SYS_SYSCALL_H
+	#include <sys/syscall.h>
+#endif
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
+#include <errno.h>
+
+#ifndef PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE
+
+#if !defined(HAVE_SYSCALL) && !defined(HAVE___SYSCALL) && !defined(HAVE___SYSCALL_NEED_DEFN)
+	#define PLATFORM_NO_SYSCALL
+#endif
+
+#ifdef PLATFORM_NO_SYSCALL
+	// For some reason, syscall just doesn't work on Darwin
+	// so instead, we build functions using assembler in a varient
+	// of the technique used in the Darwin Libc
+	extern "C" int
+	TEST_open(const char *path, int flags, mode_t mode);
+	extern "C" int
+	TEST_close(int d);
+	extern "C" ssize_t
+	TEST_write(int d, const void *buf, size_t nbytes);
+	extern "C" ssize_t
+	TEST_read(int d, void *buf, size_t nbytes);
+	extern "C" ssize_t
+	TEST_readv(int d, const struct iovec *iov, int iovcnt);
+	extern "C" off_t
+	TEST_lseek(int fildes, off_t offset, int whence);
+#else
+	#ifdef HAVE___SYSCALL_NEED_DEFN
+		// Need this, not declared in syscall.h nor unistd.h
+		extern "C" off_t __syscall(quad_t number, ...);
+	#endif
+	#ifndef HAVE_SYSCALL
+		#undef syscall
+		#define syscall __syscall
+	#endif
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+#include "MemLeakFindOn.h"
+
+bool intercept_enabled = false;
+const char *intercept_filename = 0;
+int intercept_filedes = -1;
+off_t intercept_errorafter = 0;
+int intercept_errno = 0;
+int intercept_syscall = 0;
+off_t intercept_filepos = 0;
+int intercept_delay_ms = 0;
+
+#define SIZE_ALWAYS_ERROR	-773
+
+void intercept_clear_setup()
+{
+	intercept_enabled = false;
+	intercept_filename = 0;
+	intercept_filedes = -1;
+	intercept_errorafter = 0;
+	intercept_syscall = 0;
+	intercept_filepos = 0;
+	intercept_delay_ms = 0;
+}
+
+bool intercept_triggered()
+{
+	return !intercept_enabled;
+}
+
+void intercept_setup_error(const char *filename, unsigned int errorafter, int errortoreturn, int syscalltoerror)
+{
+	TRACE4("Setup for error: %s, after %d, err %d, syscall %d\n", filename, errorafter, errortoreturn, syscalltoerror);
+	intercept_enabled = true;
+	intercept_filename = filename;
+	intercept_filedes = -1;
+	intercept_errorafter = errorafter;
+	intercept_syscall = syscalltoerror;
+	intercept_errno = errortoreturn;
+	intercept_filepos = 0;
+	intercept_delay_ms = 0;
+}
+
+void intercept_setup_delay(const char *filename, unsigned int delay_after, 
+	int delay_ms, int syscall_to_delay)
+{
+	TRACE4("Setup for delay: %s, after %d, wait %d ms, syscall %d\n", 
+		filename, delay_after, delay_ms, syscall_to_delay);
+	intercept_enabled = true;
+	intercept_filename = filename;
+	intercept_filedes = -1;
+	intercept_errorafter = delay_after;
+	intercept_syscall = syscall_to_delay;
+	intercept_errno = 0;
+	intercept_filepos = 0;
+	intercept_delay_ms = delay_ms;
+}
+bool intercept_errornow(int d, int size, int syscallnum)
+{
+	if(intercept_filedes != -1 && d == intercept_filedes && syscallnum == intercept_syscall)
+	{
+		//printf("Checking for err, %d, %d, %d\n", d, size, syscallnum);
+		if(size == SIZE_ALWAYS_ERROR)
+		{
+			// Looks good for an error!
+			TRACE2("Returning error %d for syscall %d\n", intercept_errno, syscallnum);
+			return true;
+		}
+		// where are we in the file?
+		if(intercept_filepos >= intercept_errorafter || intercept_filepos >= ((off_t)intercept_errorafter - size))
+		{
+			if (intercept_errno != 0)
+			{
+				TRACE3("Returning error %d for syscall %d, "
+					"file pos %d\n", intercept_errno, 
+					syscallnum, (int)intercept_filepos);
+			}
+			else if (intercept_delay_ms != 0)
+			{
+				TRACE3("Delaying %d ms for syscall %d, "
+					"file pos %d\n", intercept_delay_ms, 
+					syscallnum, (int)intercept_filepos);
+			}
+
+			return true;
+		}
+	}
+	return false;	// no error please!
+}
+
+int intercept_reterr()
+{
+	int err = intercept_errno;
+	intercept_clear_setup();
+	return err;
+}
+
+#define CHECK_FOR_FAKE_ERROR_COND(D, S, CALL, FAILRES)	\
+	if(intercept_enabled)					\
+	{										\
+		if(intercept_errornow(D, S, CALL))	\
+		{									\
+			if(intercept_delay_ms > 0) \
+			{ \
+				struct timespec tm; \
+				tm.tv_sec = intercept_delay_ms / 1000; \
+				tm.tv_nsec = (intercept_delay_ms % 1000) \
+					* 1000000; \
+				while (nanosleep(&tm, &tm) != 0 && \
+					errno == EINTR) { } \
+				intercept_clear_setup(); \
+			} \
+			else \
+			{ \
+				errno = intercept_reterr();		\
+				return FAILRES;					\
+			} \
+		}									\
+	}
+
+extern "C" int
+open(const char *path, int flags, mode_t mode)
+{
+	if(intercept_enabled)
+	{
+		if(intercept_syscall == SYS_open && strcmp(path, intercept_filename) == 0)
+		{
+			errno = intercept_reterr();
+			return -1;
+		}
+	}
+#ifdef PLATFORM_NO_SYSCALL
+	int r = TEST_open(path, flags, mode);
+#else
+	int r = syscall(SYS_open, path, flags, mode);
+#endif
+	if(intercept_enabled && intercept_filedes == -1)
+	{
+		// Right file?
+		if(strcmp(intercept_filename, path) == 0)
+		{
+			intercept_filedes = r;
+			//printf("Found file to intercept, h = %d\n", r);
+		}
+	}
+	return r;
+}
+
+extern "C" int
+open64(const char *path, int flags, mode_t mode)
+{
+	// With _FILE_OFFSET_BITS set to 64 this should really use (flags |
+	// O_LARGEFILE) here, but not actually necessary for the tests and not
+	// worth the trouble finding O_LARGEFILE
+	return open(path, flags, mode);
+}
+
+extern "C" int
+close(int d)
+{
+	CHECK_FOR_FAKE_ERROR_COND(d, SIZE_ALWAYS_ERROR, SYS_close, -1);
+#ifdef PLATFORM_NO_SYSCALL
+	int r = TEST_close(d);
+#else
+	int r = syscall(SYS_close, d);
+#endif
+	if(r == 0)
+	{
+		if(d == intercept_filedes)
+		{
+			intercept_filedes = -1;
+		}
+	}
+	return r;
+}
+
+extern "C" ssize_t
+write(int d, const void *buf, size_t nbytes)
+{
+	CHECK_FOR_FAKE_ERROR_COND(d, nbytes, SYS_write, -1);
+#ifdef PLATFORM_NO_SYSCALL
+	int r = TEST_write(d, buf, nbytes);
+#else
+	int r = syscall(SYS_write, d, buf, nbytes);
+#endif
+	if(r != -1)
+	{
+		intercept_filepos += r;
+	}
+	return r;
+}
+
+extern "C" ssize_t
+read(int d, void *buf, size_t nbytes)
+{
+	CHECK_FOR_FAKE_ERROR_COND(d, nbytes, SYS_read, -1);
+#ifdef PLATFORM_NO_SYSCALL
+	int r = TEST_read(d, buf, nbytes);
+#else
+	int r = syscall(SYS_read, d, buf, nbytes);
+#endif
+	if(r != -1)
+	{
+		intercept_filepos += r;
+	}
+	return r;
+}
+
+extern "C" ssize_t
+readv(int d, const struct iovec *iov, int iovcnt)
+{
+	// how many bytes?
+	int nbytes = 0;
+	for(int b = 0; b < iovcnt; ++b)
+	{
+		nbytes += iov[b].iov_len;
+	}
+
+	CHECK_FOR_FAKE_ERROR_COND(d, nbytes, SYS_readv, -1);
+#ifdef PLATFORM_NO_SYSCALL
+	int r = TEST_readv(d, iov, iovcnt);
+#else
+	int r = syscall(SYS_readv, d, iov, iovcnt);
+#endif
+	if(r != -1)
+	{
+		intercept_filepos += r;
+	}
+	return r;
+}
+
+extern "C" off_t
+lseek(int fildes, off_t offset, int whence)
+{
+	// random magic for lseek syscall, see /usr/src/lib/libc/sys/lseek.c
+	CHECK_FOR_FAKE_ERROR_COND(fildes, 0, SYS_lseek, -1);
+#ifdef PLATFORM_NO_SYSCALL
+	int r = TEST_lseek(fildes, offset, whence);
+#else
+	#ifdef HAVE_LSEEK_DUMMY_PARAM
+		off_t r = syscall(SYS_lseek, fildes, 0 /* extra 0 required here! */, offset, whence);
+	#elif defined(_FILE_OFFSET_BITS)
+		// Don't bother trying to call SYS__llseek on 32 bit since it is
+		// fiddly and not needed for the tests
+		off_t r = syscall(SYS_lseek, fildes, (uint32_t)offset, whence);
+	#else
+		off_t r = syscall(SYS_lseek, fildes, offset, whence);
+	#endif
+#endif
+	if(r != -1)
+	{
+		intercept_filepos = r;
+	}
+	return r;
+}
+
+#endif // n PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE

Modified: box/chris/merge/modules.txt
===================================================================
--- box/chris/merge/modules.txt	2006-11-26 19:41:12 UTC (rev 1175)
+++ box/chris/merge/modules.txt	2006-11-26 19:43:20 UTC (rev 1176)
@@ -18,6 +18,7 @@
 lib/server
 lib/win32		lib/server
 lib/compress
+lib/intercept
 test/common		lib/win32
 test/crypto		lib/crypto	lib/win32
 test/compress		lib/compress	lib/win32
@@ -25,7 +26,7 @@
 OMIT:mingw32
 test/basicserver	lib/server	lib/win32
 OMIT:CYGWIN
-test/raidfile		lib/raidfile
+test/raidfile		lib/raidfile	lib/intercept
 END-OMIT
 
 # IF_DISTRIBUTION(boxbackup)
@@ -52,7 +53,7 @@
 test/backupstorefix	bin/bbstored	bin/bbstoreaccounts	lib/backupstore	lib/raidfile	bin/bbackupquery	bin/bbackupd
 test/backupstorepatch	bin/bbstored	bin/bbstoreaccounts	lib/backupstore	lib/raidfile
 test/backupdiff		lib/backupclient
-test/bbackupd		bin/bbackupd	bin/bbstored bin/bbstoreaccounts bin/bbackupquery bin/bbackupctl lib/server lib/backupstore lib/backupclient
+test/bbackupd		bin/bbackupd	bin/bbstored bin/bbstoreaccounts bin/bbackupquery bin/bbackupctl lib/server lib/backupstore lib/backupclient	lib/intercept
 END-OMIT
 
 # END_IF_DISTRIBUTION

Deleted: box/chris/merge/test/raidfile/intercept.cpp
===================================================================
--- box/chris/merge/test/raidfile/intercept.cpp	2006-11-26 19:41:12 UTC (rev 1175)
+++ box/chris/merge/test/raidfile/intercept.cpp	2006-11-26 19:43:20 UTC (rev 1176)
@@ -1,276 +0,0 @@
-// --------------------------------------------------------------------------
-//
-// File
-//		Name:    intercept.cpp
-//		Purpose: Syscall interception code for the raidfile test
-//		Created: 2003/07/22
-//
-// --------------------------------------------------------------------------
-
-#include "Box.h"
-
-#ifdef HAVE_SYS_SYSCALL_H
-	#include <sys/syscall.h>
-#endif
-#include <sys/types.h>
-#include <unistd.h>
-
-#ifdef HAVE_SYS_UIO_H
-#include <sys/uio.h>
-#endif
-
-#include <errno.h>
-
-#ifndef PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE
-
-#if !defined(HAVE_SYSCALL) && !defined(HAVE___SYSCALL) && !defined(HAVE___SYSCALL_NEED_DEFN)
-	#define PLATFORM_NO_SYSCALL
-#endif
-
-#ifdef PLATFORM_NO_SYSCALL
-	// For some reason, syscall just doesn't work on Darwin
-	// so instead, we build functions using assembler in a varient
-	// of the technique used in the Darwin Libc
-	extern "C" int
-	TEST_open(const char *path, int flags, mode_t mode);
-	extern "C" int
-	TEST_close(int d);
-	extern "C" ssize_t
-	TEST_write(int d, const void *buf, size_t nbytes);
-	extern "C" ssize_t
-	TEST_read(int d, void *buf, size_t nbytes);
-	extern "C" ssize_t
-	TEST_readv(int d, const struct iovec *iov, int iovcnt);
-	extern "C" off_t
-	TEST_lseek(int fildes, off_t offset, int whence);
-#else
-	#ifdef HAVE___SYSCALL_NEED_DEFN
-		// Need this, not declared in syscall.h nor unistd.h
-		extern "C" off_t __syscall(quad_t number, ...);
-	#endif
-	#ifndef HAVE_SYSCALL
-		#undef syscall
-		#define syscall __syscall
-	#endif
-#endif
-
-#include <string.h>
-#include <stdio.h>
-
-#include "MemLeakFindOn.h"
-
-bool intercept_enabled = false;
-const char *intercept_filename = 0;
-int intercept_filedes = -1;
-off_t intercept_errorafter = 0;
-int intercept_errno = 0;
-int intercept_syscall = 0;
-off_t intercept_filepos = 0;
-
-#define SIZE_ALWAYS_ERROR	-773
-
-void intercept_clear_setup()
-{
-	intercept_enabled = false;
-	intercept_filename = 0;
-	intercept_filedes = -1;
-	intercept_errorafter = 0;
-	intercept_syscall = 0;
-	intercept_filepos = 0;
-}
-
-bool intercept_triggered()
-{
-	return !intercept_enabled;
-}
-
-void intercept_setup_error(const char *filename, unsigned int errorafter, int errortoreturn, int syscalltoerror)
-{
-	TRACE4("Setup for error: %s, after %d, err %d, syscall %d\n", filename, errorafter, errortoreturn, syscalltoerror);
-	intercept_enabled = true;
-	intercept_filename = filename;
-	intercept_filedes = -1;
-	intercept_errorafter = errorafter;
-	intercept_syscall = syscalltoerror;
-	intercept_errno = errortoreturn;
-	intercept_filepos = 0;
-}
-
-bool intercept_errornow(int d, int size, int syscallnum)
-{
-	if(intercept_filedes != -1 && d == intercept_filedes && syscallnum == intercept_syscall)
-	{
-		//printf("Checking for err, %d, %d, %d\n", d, size, syscallnum);
-		if(size == SIZE_ALWAYS_ERROR)
-		{
-			// Looks good for an error!
-			TRACE2("Returning error %d for syscall %d\n", intercept_errno, syscallnum);
-			return true;
-		}
-		// where are we in the file?
-		if(intercept_filepos >= intercept_errorafter || intercept_filepos >= ((off_t)intercept_errorafter - size))
-		{
-			TRACE3("Returning error %d for syscall %d, file pos %d\n", intercept_errno, syscallnum, (int)intercept_filepos);
-			return true;
-		}
-	}
-	return false;	// no error please!
-}
-
-int intercept_reterr()
-{
-	intercept_enabled = false;
-	intercept_filename = 0;
-	intercept_filedes = -1;
-	intercept_errorafter = 0;
-	intercept_syscall = 0;
-	return intercept_errno;
-}
-
-#define CHECK_FOR_FAKE_ERROR_COND(D, S, CALL, FAILRES)	\
-	if(intercept_enabled)					\
-	{										\
-		if(intercept_errornow(D, S, CALL))	\
-		{									\
-			errno = intercept_reterr();		\
-			return FAILRES;					\
-		}									\
-	}
-
-extern "C" int
-open(const char *path, int flags, mode_t mode)
-{
-	if(intercept_enabled)
-	{
-		if(intercept_syscall == SYS_open && strcmp(path, intercept_filename) == 0)
-		{
-			errno = intercept_reterr();
-			return -1;
-		}
-	}
-#ifdef PLATFORM_NO_SYSCALL
-	int r = TEST_open(path, flags, mode);
-#else
-	int r = syscall(SYS_open, path, flags, mode);
-#endif
-	if(intercept_enabled && intercept_filedes == -1)
-	{
-		// Right file?
-		if(strcmp(intercept_filename, path) == 0)
-		{
-			intercept_filedes = r;
-			//printf("Found file to intercept, h = %d\n", r);
-		}
-	}
-	return r;
-}
-
-extern "C" int
-open64(const char *path, int flags, mode_t mode)
-{
-	// With _FILE_OFFSET_BITS set to 64 this should really use (flags |
-	// O_LARGEFILE) here, but not actually necessary for the tests and not
-	// worth the trouble finding O_LARGEFILE
-	return open(path, flags, mode);
-}
-
-extern "C" int
-close(int d)
-{
-	CHECK_FOR_FAKE_ERROR_COND(d, SIZE_ALWAYS_ERROR, SYS_close, -1);
-#ifdef PLATFORM_NO_SYSCALL
-	int r = TEST_close(d);
-#else
-	int r = syscall(SYS_close, d);
-#endif
-	if(r == 0)
-	{
-		if(d == intercept_filedes)
-		{
-			intercept_filedes = -1;
-		}
-	}
-	return r;
-}
-
-extern "C" ssize_t
-write(int d, const void *buf, size_t nbytes)
-{
-	CHECK_FOR_FAKE_ERROR_COND(d, nbytes, SYS_write, -1);
-#ifdef PLATFORM_NO_SYSCALL
-	int r = TEST_write(d, buf, nbytes);
-#else
-	int r = syscall(SYS_write, d, buf, nbytes);
-#endif
-	if(r != -1)
-	{
-		intercept_filepos += r;
-	}
-	return r;
-}
-
-extern "C" ssize_t
-read(int d, void *buf, size_t nbytes)
-{
-	CHECK_FOR_FAKE_ERROR_COND(d, nbytes, SYS_read, -1);
-#ifdef PLATFORM_NO_SYSCALL
-	int r = TEST_read(d, buf, nbytes);
-#else
-	int r = syscall(SYS_read, d, buf, nbytes);
-#endif
-	if(r != -1)
-	{
-		intercept_filepos += r;
-	}
-	return r;
-}
-
-extern "C" ssize_t
-readv(int d, const struct iovec *iov, int iovcnt)
-{
-	// how many bytes?
-	int nbytes = 0;
-	for(int b = 0; b < iovcnt; ++b)
-	{
-		nbytes += iov[b].iov_len;
-	}
-
-	CHECK_FOR_FAKE_ERROR_COND(d, nbytes, SYS_readv, -1);
-#ifdef PLATFORM_NO_SYSCALL
-	int r = TEST_readv(d, iov, iovcnt);
-#else
-	int r = syscall(SYS_readv, d, iov, iovcnt);
-#endif
-	if(r != -1)
-	{
-		intercept_filepos += r;
-	}
-	return r;
-}
-
-extern "C" off_t
-lseek(int fildes, off_t offset, int whence)
-{
-	// random magic for lseek syscall, see /usr/src/lib/libc/sys/lseek.c
-	CHECK_FOR_FAKE_ERROR_COND(fildes, 0, SYS_lseek, -1);
-#ifdef PLATFORM_NO_SYSCALL
-	int r = TEST_lseek(fildes, offset, whence);
-#else
-	#ifdef HAVE_LSEEK_DUMMY_PARAM
-		off_t r = syscall(SYS_lseek, fildes, 0 /* extra 0 required here! */, offset, whence);
-	#elif defined(_FILE_OFFSET_BITS)
-		// Don't bother trying to call SYS__llseek on 32 bit since it is
-		// fiddly and not needed for the tests
-		off_t r = syscall(SYS_lseek, fildes, (uint32_t)offset, whence);
-	#else
-		off_t r = syscall(SYS_lseek, fildes, offset, whence);
-	#endif
-#endif
-	if(r != -1)
-	{
-		intercept_filepos = r;
-	}
-	return r;
-}
-
-#endif // n PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE




More information about the Boxbackup-commit mailing list