summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--DEVELOPERS42
-rw-r--r--Makefile99
-rw-r--r--inc.mak28
-rw-r--r--tests/Makefile73
-rw-r--r--tests/clean.sql (renamed from clean.sql)0
-rw-r--r--tests/testfsync.c (renamed from testfsync.c)0
-rw-r--r--tests/testpgsql.c (renamed from testpgsql.c)0
7 files changed, 132 insertions, 110 deletions
diff --git a/DEVELOPERS b/DEVELOPERS
index c9e31f0..dbee0e0 100644
--- a/DEVELOPERS
+++ b/DEVELOPERS
@@ -16,10 +16,14 @@ Coding guidelines
8-character TABs.
Standard C89, portable to all platforms supporting FUSE (Linux,
- FreeBSD, OpenBSD, NetBSD, Darwin/MacOSX). No C++, no C99.
+ FreeBSD, OpenBSD, NetBSD, Darwin/MacOSX). No C++, no C99. Some
+ newer 64-bit things like 'endian.h' are allowed, if there is no
+ other option.
Do not introduce unnecessary 3rd party dependencies in addition
to the required 'libfuse' and 'libpq'.
+
+ Use the internal fuse_opts to parse command line options.
Use native 'libpq', not abstractions. The database operations
are simple enough. If possible avoid string manipulations as
@@ -38,7 +42,7 @@ One ByteA field
All data in a big bytea column: needs memory of the size of the
complete file on client (pgfuse) and server (PostgreSQL) side,
- is ok for small files (first proof-of-concept implementation)
+ is ok for small files (first proof-of-concept implementation).
Multiple ByteA of equal size
@@ -76,32 +80,36 @@ not really sure if that is good or bad.
Directory tree in database
--------------------------
-Naive implementation
-
- Complete path as string. Has high mutation costs for renames,
- storage overhead. But is very fast for queries (no joins).
-
-TODO...
+Every inode has a 'parent_id', self-referencing. To avoid the NULL
+reference there is a root element point to itself. Pathes are decomposed
+programatically by descending the tree. This requires no additional
+redudant storage is easy to change in renames and gives acceptable
+read performance.
Transaction Policies
--------------------
-Fundamental querstion: What file operations should form a database transaction?
+Fundamental question: What file operations should form a database transaction?
-one extreme: isolate threads and all file operations in one transaction
+one extreme: isolate threads and all file operations in one transaction.
+This is most likely an illution, as we can't assume that FUSE threads
+are assigned fix to a specific file (on the contrary!).
+
other extreme: "autocommit" (every write, every read, etc.), this allows
-for parallel usage, as long as we have ref_count and an exclusive
-locking, this extreme makes no sense
+for parallel usage. We trust in FUSE and the locking there. The database
+should help us sequentiallize the operations.
-specify transaction strategy as mount options?
+Currently the second option was choosen.
Self-containment
----------------
React decently to loss of database connections. Try to reestablish
the connection, the loss of database connection could be temporary.
+Try to reexecute the file system operation.
-What should be reported back as temporary error state to FUSE?
+What should be reported back as permanent error state to FUSE after
+a certain timeout when the database doesn't appear again?
EIO seems a good option (as if the disk would have temporary I/O
problems).
@@ -114,13 +122,17 @@ commands of the shell).
bonnie is a good stress and performance tester. Don't despair because
of poor performance, that's normal. :-)
-Several shells in parallel doing:
+Another option is to have many shells open and do some things in
+parallel, like:
while(true);do
mkdir mnt/bla
rmdir mnt/bla
done
+We should actually write a filesystem operation simulator doing all
+kind of random weird operations with certain probabilities.
+
References
----------
diff --git a/Makefile b/Makefile
index 46bd188..b0a5a88 100644
--- a/Makefile
+++ b/Makefile
@@ -13,93 +13,14 @@ execdir=$(DESTDIR)$(prefix)
bindir=$(execdir)/bin
datadir=$(execdir)/share
-# for debugging
-#CFLAGS = -Wall -Werror -g -O0 -pthread
-# for releasing
-CFLAGS = -Wall -O2
-
-# redhat has libpq-fe.h and fuse.h in /usr/include, ok
-
-# suse has libpq-fe.h in
-CFLAGS += -I/usr/include/pgsql
-
-# debianish systems have libpg-fe.h in
-CFLAGS += -I/usr/include/postgresql
-
-# declare version of FUSE API we want to program against
-CFLAGS += -DFUSE_USE_VERSION=26
-
-CFLAGS += -D_FILE_OFFSET_BITS=64
-
-# debug
-#CFLAGS += -I/usr/local/include/fuse
-#LDFLAGS = -lpq /usr/local/lib/libfuse.a -pthread -ldl -lrt
-
-# release
-# use pkg-config to detemine compiler/linker flags for libfuse
-CFLAGS += `pkg-config fuse --cflags`
-LDFLAGS = `pkg-config fuse --libs` -lpq -pthread
-
-PG_CONNINFO = ""
+include inc.mak
clean:
rm -f pgfuse pgfuse.o pgsql.o pool.o
- rm -f testfsync testfsync.o
- rm -f testpgsql testpgsql.o
+ cd tests && $(MAKE) clean
-test: pgfuse testfsync testpgsql
- psql < clean.sql
- psql < schema.sql
- test -d mnt || mkdir mnt
- ./pgfuse -s -v "$(PG_CONNINFO)" mnt
- mount | grep pgfuse
- # expect success for making directories
- -mkdir mnt/dir
- -mkdir mnt/dir/dir2
- -mkdir mnt/dir/dir3
- # expect success on open and file write
- -echo "hello" > mnt/dir/dir2/afile
- -cp Makefile mnt/dir/dir2/bfile
- # expect success on open and file read
- -cat mnt/dir/dir2/afile
- -ls -al mnt
- -ls -al mnt/dir/dir2
- # expect success on rmdir
- -rmdir mnt/dir/dir3
- # expect success on chmod
- -chmod 777 mnt/dir/dir2/bfile
- -ls -al mnt/dir/dir2/bfile
- # expect success on symlink creation
- -ln -s bfile mnt/dir/dir2/clink
- -ls -al mnt/dir/dir2/clink
- # expect success on file removal
- -rm mnt/dir/dir2/bfile
- # expect success on rename
- -mkdir mnt/dir/dir3
- -mv mnt/dir/dir3 mnt/dir/dir4
- -mv mnt/dir/dir2/afile mnt/dir/dir4/bfile
- # expect fail (directory not empty)
- -rmdir mnt/dir
- # expect fail (not a directory)
- -rmdir mnt/dir/dir2/bfile
- # test fdatasync and fsync
- ./testfsync
- # show times of dirs, files and symlinks
- -stat mnt/dir/dir2/afile
- -stat mnt/dir/dir3
- -stat mnt/dir/dir2/clink
- # show filesystem stats (statvfs)
- -stat -f mnt
- # expect success, truncate a file (grow and shrink)
- -touch mnt/trunc
- -ls -al mnt/trunc
- -truncate --size 2049 mnt/trunc
- -ls -al mnt/trunc
- -dd if=/dev/zero of=mnt/trunc bs=512 count=10
- -truncate --size 513 mnt/trunc
- -ls -al mnt/trunc
- # END: unmount FUSE file system
- fusermount -u mnt
+test:
+ cd tests && $(MAKE) test
pgfuse: pgfuse.o pgsql.o pool.o
$(CC) -o pgfuse pgfuse.o pgsql.o pool.o $(LDFLAGS)
@@ -112,18 +33,6 @@ pgsql.o: pgsql.c pgsql.h config.h
pool.o: pool.c pool.h
$(CC) -c $(CFLAGS) -o pool.o pool.c
-
-testfsync: testfsync.o
- $(CC) -o testfsync testfsync.o
-
-testfsync.o: testfsync.c
- $(CC) -c $(CFLAGS) -o testfsync.o testfsync.c
-
-testpgsql: testpgsql.o
- $(CC) -o testpgsql testpgsql.o $(LDFLAGS)
-
-testpgsql.o: testpgsql.c
- $(CC) -c $(CFLAGS) -o testpgsql.o testpgsql.c
install: all
test -d "$(bindir)" || mkdir -p "$(bindir)"
diff --git a/inc.mak b/inc.mak
new file mode 100644
index 0000000..a26cc19
--- /dev/null
+++ b/inc.mak
@@ -0,0 +1,28 @@
+CC=gcc
+
+# for debugging
+CFLAGS = -Wall -Werror -g -O0 -pthread
+# for releasing
+#CFLAGS = -Wall -O2
+
+# redhat has libpq-fe.h and fuse.h in /usr/include, ok
+
+# suse has libpq-fe.h in
+CFLAGS += -I/usr/include/pgsql
+
+# debianish systems have libpg-fe.h in
+CFLAGS += -I/usr/include/postgresql
+
+# declare version of FUSE API we want to program against
+CFLAGS += -DFUSE_USE_VERSION=26
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+
+# debug
+#CFLAGS += -I/usr/local/include/fuse
+#LDFLAGS = -lpq /usr/local/lib/libfuse.a -pthread -ldl -lrt
+
+# release
+# use pkg-config to detemine compiler/linker flags for libfuse
+CFLAGS += `pkg-config fuse --cflags`
+LDFLAGS = `pkg-config fuse --libs` -lpq -pthread
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..d4aec77
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,73 @@
+include ../inc.mak
+
+PG_CONNINFO = ""
+
+test: testfsync testpgsql
+ psql < clean.sql
+ psql < ../schema.sql
+ test -d mnt || mkdir mnt
+ ../pgfuse -s -v "$(PG_CONNINFO)" mnt
+ mount | grep pgfuse
+ # expect success for making directories
+ -mkdir mnt/dir
+ -mkdir mnt/dir/dir2
+ -mkdir mnt/dir/dir3
+ # expect success on open and file write
+ -echo "hello" > mnt/dir/dir2/afile
+ -cp Makefile mnt/dir/dir2/bfile
+ # expect success on open and file read
+ -cat mnt/dir/dir2/afile
+ -ls -al mnt
+ -ls -al mnt/dir/dir2
+ # expect success on rmdir
+ -rmdir mnt/dir/dir3
+ # expect success on chmod
+ -chmod 777 mnt/dir/dir2/bfile
+ -ls -al mnt/dir/dir2/bfile
+ # expect success on symlink creation
+ -ln -s bfile mnt/dir/dir2/clink
+ -ls -al mnt/dir/dir2/clink
+ # expect success on file removal
+ -rm mnt/dir/dir2/bfile
+ # expect success on rename
+ -mkdir mnt/dir/dir3
+ -mv mnt/dir/dir3 mnt/dir/dir4
+ -mv mnt/dir/dir2/afile mnt/dir/dir4/bfile
+ # expect fail (directory not empty)
+ -rmdir mnt/dir
+ # expect fail (not a directory)
+ -rmdir mnt/dir/dir2/bfile
+ # test fdatasync and fsync
+ ./testfsync
+ # show times of dirs, files and symlinks
+ -stat mnt/dir/dir2/afile
+ -stat mnt/dir/dir3
+ -stat mnt/dir/dir2/clink
+ # show filesystem stats (statvfs)
+ -stat -f mnt
+ # expect success, truncate a file (grow and shrink)
+ -touch mnt/trunc
+ -ls -al mnt/trunc
+ -truncate --size 2049 mnt/trunc
+ -ls -al mnt/trunc
+ -dd if=/dev/zero of=mnt/trunc bs=512 count=10
+ -truncate --size 513 mnt/trunc
+ -ls -al mnt/trunc
+ # END: unmount FUSE file system
+ fusermount -u mnt
+
+clean:
+ rm -f testfsync testfsync.o
+ rm -f testpgsql testpgsql.o
+
+testfsync: testfsync.o
+ $(CC) -o testfsync testfsync.o
+
+testfsync.o: testfsync.c
+ $(CC) -c $(CFLAGS) -o testfsync.o testfsync.c
+
+testpgsql: testpgsql.o
+ $(CC) -o testpgsql testpgsql.o $(LDFLAGS)
+
+testpgsql.o: testpgsql.c
+ $(CC) -c $(CFLAGS) -o testpgsql.o testpgsql.c
diff --git a/clean.sql b/tests/clean.sql
index 6d94089..6d94089 100644
--- a/clean.sql
+++ b/tests/clean.sql
diff --git a/testfsync.c b/tests/testfsync.c
index 571b816..571b816 100644
--- a/testfsync.c
+++ b/tests/testfsync.c
diff --git a/testpgsql.c b/tests/testpgsql.c
index 3159e2d..3159e2d 100644
--- a/testpgsql.c
+++ b/tests/testpgsql.c