diff options
Diffstat (limited to 'doc')
82 files changed, 3693 insertions, 13120 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am index 1103b607dba..de68c20b4d7 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,6 +1,9 @@ EXTRA_DIST = glusterfs.8 mount.glusterfs.8 gluster.8 \ glusterd.8 glusterfsd.8 -man8_MANS = glusterfs.8 mount.glusterfs.8 gluster.8 glusterd.8 glusterfsd.8 +man8_MANS = glusterfs.8 mount.glusterfs.8 gluster.8 +if WITH_SERVER +man8_MANS += glusterd.8 glusterfsd.8 +endif CLEANFILES = diff --git a/doc/README.md b/doc/README.md index e057437fcba..6aa28642ef4 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,6 +1,14 @@ +## Developer Guide + +Gluster's contributors can check about the internals by visiting [Developer Guide Section](developer-guide). While it is not 'comprehensive', it can help you to get started. + +Also while coding, keep [Coding Standard](developer-guide/coding-standard.md) in mind. + +When you are ready to commit the changes, make sure you meet our [Commit message standard](developer-guide/commit-guidelines.md). + ## Admin Guide ## -The gluster administration guide is maintained at [github](https://github.com/gluster/glusterdocs). The browsable admin guide can be found [here](http://gluster.readthedocs.org/en/latest/Administrator%20Guide/README/). +The gluster administration guide is maintained at [github](https://github.com/gluster/glusterdocs). The browsable admin guide can be found [here](http://docs.gluster.org/en/latest/Administrator%20Guide/). The doc patch has to be sent against the above mentioned repository. @@ -10,7 +18,7 @@ The Gluster features which are 'in progress' or implemented can be found at [git ## Upgrade Guide ## -The gluster upgrade guide is maintained at [github](https://github.com/gluster/glusterdocs). The browsable upgrade guide can be found [here](http://gluster.readthedocs.org/en/latest/Upgrade-Guide/README/) +The gluster upgrade guide is maintained at [github](https://github.com/gluster/glusterdocs). The browsable upgrade guide can be found [here](http://docs.gluster.org/en/latest/Upgrade-Guide) The doc patch has to be sent against the above mentioned repository. diff --git a/doc/debugging/analyzing-regression-cores.md b/doc/debugging/analyzing-regression-cores.md new file mode 100644 index 00000000000..5e10f41c6eb --- /dev/null +++ b/doc/debugging/analyzing-regression-cores.md @@ -0,0 +1,54 @@ +# Analyzing Regression Cores +This document explains how to analyze core-dumps obtained from regression machines, with examples. +1. Download the core-tarball and extract it. +2. `cd` into directory where the tarball is extracted. +``` +[sh]# pwd +/home/user/Downloads +[sh]# ls +build build-install-20150625_05_42_39.tar.bz2 lib64 usr +``` +3. Determine the core file you need to examine. There can be more than one core file. You can list them from './build/install/cores' directory. +``` +[sh]# ls build/install/cores/ +core.9341 liblist.txt liblist.txt.tmp +``` +In case you are unsure which binary generated the core-file, executing 'file' command on it will help. +``` +[sh]# file ./build/install/cores/core.9341 +./build/install/cores/core.9341: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from '/build/install/sbin/glusterfsd -s slave26.cloud.gluster.org --volfile-id patchy' +``` +As seen, the core file was generated by glusterfsd binary, and path to it is provided (/build/install/sbin/glusterfsd). + +4. Now, run the following command on the core: +``` +gdb -ex 'set sysroot ./' -ex 'core-file ./build/install/cores/core.xxx' <target, say ./build/install/sbin/glusterd> +In this case, +gdb -ex 'set sysroot ./' -ex 'core-file ./build/install/cores/core.9341' ./build/install/sbin/glusterfsd +``` +5. You can cross check if all shared libraries are available and loaded by using 'info sharedlibrary' command from inside gdb. +6. Once verified, usual gdb commands based on requirement can be used to debug the core. + `bt` or `backtrace` from gdb of core used in examples: +``` +Core was generated by `/build/install/sbin/glusterfsd -s slave26.cloud.gluster.org --volfile-id patchy'. +Program terminated with signal SIGABRT, Aborted. +#0 0x00007f512a54e625 in raise () from ./lib64/libc.so.6 +(gdb) bt +#0 0x00007f512a54e625 in raise () from ./lib64/libc.so.6 +#1 0x00007f512a54fe05 in abort () from ./lib64/libc.so.6 +#2 0x00007f512a54774e in __assert_fail_base () from ./lib64/libc.so.6 +#3 0x00007f512a547810 in __assert_fail () from ./lib64/libc.so.6 +#4 0x00007f512b9fc434 in __gf_free (free_ptr=0x7f50f4000e50) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/libglusterfs/src/mem-pool.c:304 +#5 0x00007f512b9b6657 in loc_wipe (loc=0x7f510c20d1a0) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/libglusterfs/src/xlator.c:685 +#6 0x00007f511cb8201d in mq_start_quota_txn_v2 (this=0x7f5118019b60, loc=0x7f510c20d2b8, ctx=0x7f50f4000bf0, contri=0x7f50f4000d60) + at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/xlators/features/marker/src/marker-quota.c:2921 +#7 0x00007f511cb82c55 in mq_initiate_quota_task (opaque=0x7f510c20d2b0) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/xlators/features/marker/src/marker-quota.c:3199 +#8 0x00007f511cb81820 in mq_synctask (this=0x7f5118019b60, task=0x7f511cb829fa <mq_initiate_quota_task>, spawn=_gf_false, loc=0x7f510c20d430, dict=0x0, buf=0x0, contri=0) + at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/xlators/features/marker/src/marker-quota.c:2789 +#9 0x00007f511cb82f82 in mq_initiate_quota_blocking_txn (this=0x7f5118019b60, loc=0x7f510c20d430) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/xlators/features/marker/src/marker-quota.c:3230 +#10 0x00007f511cb82844 in mq_reduce_parent_size_task (opaque=0x7f510c000df0) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/xlators/features/marker/src/marker-quota.c:3117 +#11 0x00007f512ba0f9dc in synctask_wrap (old_task=0x7f510c0053e0) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/libglusterfs/src/syncop.c:370 +#12 0x00007f512a55f8f0 in ?? () from ./lib64/libc.so.6 +#13 0x0000000000000000 in ?? () +(gdb) +``` diff --git a/doc/debugging/coredump-analysis.md b/doc/debugging/coredump-analysis.md deleted file mode 100644 index f9ecf73216e..00000000000 --- a/doc/debugging/coredump-analysis.md +++ /dev/null @@ -1,31 +0,0 @@ -This document explains how to analyze core-dumps obtained from regression -machines, with examples. -1) Download the core-tarball and extract it. -2) 'cd' into the root of extracted tarball. -~~~ -[root@atalur Downloads]# pwd -/home/atalur/Downloads -[root@atalur Downloads]# ls -build build-install-20150625_05_42_39.tar.bz2 lib64 usr -~~~ -3) Determine the core file you need to examine. There can be more than one core file. -You can list them from './build/install/cores' directory. -~~~ -[root@atalur Downloads]# ls build/install/cores/ -core.9341 liblist.txt liblist.txt.tmp -~~~ -In case you are unsure which binary generated the core-file, executing 'file' command on it will help. -~~~ -[root@atalur Downloads]# file ./build/install/cores/core.9341 -./build/install/cores/core.9341: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from '/build/install/sbin/glusterfsd -s slave26.cloud.gluster.org --volfile-id patchy' -~~~ -As seen, the core file was generated by glusterfsd binary, and path to it is provide (/build/install/sbin/glusterfsd). -4) Now, run the following command on the core: -~~~ -gdb -ex 'set sysroot ./' -ex 'core-file ./build/install/cores/core.xxx' <target, say ./build/install/sbin/glusterd> -In this case, -gdb -ex 'set sysroot ./' -ex 'core-file ./build/install/cores/core.9341' ./build/install/sbin/glusterfsd -~~~ -5) You can cross check if all shared libraries are available and loaded by using 'info sharedlibrary' command from -inside gdb. -6) Once verified, usual gdb commands based on requirement can be used to debug the core. diff --git a/doc/debugging/gfid-to-path.md b/doc/debugging/gfid-to-path.md index 09c459e52c8..1917bf2cca1 100644 --- a/doc/debugging/gfid-to-path.md +++ b/doc/debugging/gfid-to-path.md @@ -1,37 +1,37 @@ -#Convert GFID to Path +# Convert GFID to Path GlusterFS internal file identifier (GFID) is a uuid that is unique to each file across the entire cluster. This is analogous to inode number in a normal filesystem. The GFID of a file is stored in its xattr named `trusted.gfid`. -####Special mount using [gfid-access translator][1]: -~~~ +#### Special mount using [gfid-access translator][1]: +``` mount -t glusterfs -o aux-gfid-mount vm1:test /mnt/testvol -~~~ +``` Assuming, you have `GFID` of a file from changelog (or somewhere else). For trying this out, you can get `GFID` of a file from mountpoint: -~~~ +``` getfattr -n glusterfs.gfid.string /mnt/testvol/dir/file -~~~ +``` --- -###Get file path from GFID (Method 1): +### Get file path from GFID (Method 1): **(Lists hardlinks delimited by `:`, returns path as seen from mountpoint)** -####Turn on build-pgfid option -~~~ +#### Turn on build-pgfid option +``` gluster volume set test build-pgfid on -~~~ +``` Read virtual xattr `glusterfs.ancestry.path` which contains the file path -~~~ +``` getfattr -n glusterfs.ancestry.path -e text /mnt/testvol/.gfid/<GFID> -~~~ +``` **Example:** -~~~ +``` [root@vm1 glusterfs]# ls -il /mnt/testvol/dir/ total 1 10610563327990022372 -rw-r--r--. 2 root root 3 Jul 17 18:05 file @@ -46,28 +46,23 @@ glusterfs.gfid.string="11118443-1894-4273-9340-4b212fa1c0e4" getfattr: Removing leading '/' from absolute path names # file: mnt/testvol/.gfid/11118443-1894-4273-9340-4b212fa1c0e4 glusterfs.ancestry.path="/dir/file:/dir/file3" -~~~ +``` --- -###Get file path from GFID (Method 2): +### Get file path from GFID (Method 2): **(Does not list all hardlinks, returns backend brick path)** -~~~ +``` getfattr -n trusted.glusterfs.pathinfo -e text /mnt/testvol/.gfid/<GFID> -~~~ +``` **Example:** -~~~ +``` [root@vm1 glusterfs]# getfattr -n trusted.glusterfs.pathinfo -e text /mnt/testvol/.gfid/11118443-1894-4273-9340-4b212fa1c0e4 getfattr: Removing leading '/' from absolute path names # file: mnt/testvol/.gfid/11118443-1894-4273-9340-4b212fa1c0e4 trusted.glusterfs.pathinfo="(<DISTRIBUTE:test-dht> <POSIX(/mnt/brick-test/b):vm1:/mnt/brick-test/b/dir//file3>)" -~~~ +``` --- -###Get file path from GFID (Method 3): -https://gist.github.com/semiosis/4392640 - ---- -####References and links: +#### References and links: [posix: placeholders for GFID to path conversion](http://review.gluster.org/5951) -[1]: https://github.com/gluster/glusterfs/blob/master/doc/features/gfid-access.md diff --git a/doc/debugging/mem-alloc-list.md b/doc/debugging/mem-alloc-list.md new file mode 100644 index 00000000000..1c68e65d323 --- /dev/null +++ b/doc/debugging/mem-alloc-list.md @@ -0,0 +1,19 @@ +## Viewing Memory Allocations + +While statedumps provide stats of the number of allocations, size etc for a +particular mem type, there is no easy way to examine all the allocated objects of that type +in memory.Being able to view this information could help with determining how an object is used, +and if there are any memory leaks. + +The mem_acct_rec structures have been updated to include lists to which the allocated object is +added. These can be examined in gdb using simple scripts. + +`gdb> plist xl->mem_acct.rec[$type]->obj_list` + +will print out the pointers of all allocations of $type. + +These changes are primarily targeted at developers and need to enabled +at compile-time using `configure --enable-debug`. + + + diff --git a/doc/debugging/split-brain.md b/doc/debugging/split-brain.md index b0d938e26bc..6b122c40551 100644 --- a/doc/debugging/split-brain.md +++ b/doc/debugging/split-brain.md @@ -1,33 +1,36 @@ -Steps to recover from File split-brain. -====================================== - -Quick Start: -============ -1. Get the path of the file that is in split-brain: -> It can be obtained either by -> a) The command `gluster volume heal info split-brain`. -> b) Identify the files for which file operations performed - from the client keep failing with Input/Output error. - -2. Close the applications that opened this file from the mount point. +# Steps to recover from File split-brain +This document contains steps to recover from a file split-brain. +## Quick Start: +### Step 1. Get the path of the file that is in split-brain: +It can be obtained either by +1. The command `gluster volume heal info split-brain`. +2. Identify the files for which file operations performed from the client keep failing with Input/Output error. + +### Step 2. Close the applications that opened this file from the mount point. In case of VMs, they need to be powered-off. -3. Decide on the correct copy: -> This is done by observing the afr changelog extended attributes of the file on +### Step 3. Decide on the correct copy: +This is done by observing the afr changelog extended attributes of the file on the bricks using the getfattr command; then identifying the type of split-brain (data split-brain, metadata split-brain, entry split-brain or split-brain due to gfid-mismatch); and finally determining which of the bricks contains the 'good copy' of the file. -> `getfattr -d -m . -e hex <file-path-on-brick>`. +``` +getfattr -d -m . -e hex <file-path-on-brick> +``` + It is also possible that one brick might contain the correct data while the other might contain the correct metadata. -4. Reset the relevant extended attribute on the brick(s) that contains the -'bad copy' of the file data/metadata using the setfattr command. -> `setfattr -n <attribute-name> -v <attribute-value> <file-path-on-brick>` +### Step 4. Reset the relevant extended attribute on the brick(s) that contains the 'bad copy' of the file data/metadata using the setfattr command. +``` +setfattr -n <attribute-name> -v <attribute-value> <file-path-on-brick> +``` -5. Trigger self-heal on the file by performing lookup from the client: -> `ls -l <file-path-on-gluster-mount>` +### Step 5. Trigger self-heal on the file by performing lookup from the client: +``` +ls -l <file-path-on-gluster-mount> +``` Detailed Instructions for steps 3 through 5: =========================================== @@ -36,13 +39,15 @@ afr changelog extended attributes. Execute `getfattr -d -m . -e hex <file-path-on-brick>` -* Example: +Example: +``` [root@store3 ~]# getfattr -d -e hex -m. brick-a/file.txt \#file: brick-a/file.txt security.selinux=0x726f6f743a6f626a6563745f723a66696c655f743a733000 trusted.afr.vol-client-2=0x000000000000000000000000 trusted.afr.vol-client-3=0x000000000200000000000000 trusted.gfid=0x307a5c9efddd4e7c96e94fd4bcdcbd1b +``` The extended attributes with `trusted.afr.<volname>-client-<subvolume-index>` are used by afr to maintain changelog of the file.The values of the @@ -51,10 +56,11 @@ client (fuse or nfs-server) processes. When the glusterfs client modifies a file or directory, the client contacts each brick and updates the changelog extended attribute according to the response of the brick. -'subvolume-index' is nothing but (brick number - 1) in +`subvolume-index` is nothing but (brick number - 1) in `gluster volume info <volname>` output. -* Example: +Example: +``` [root@pranithk-laptop ~]# gluster volume info vol Volume Name: vol Type: Distributed-Replicate @@ -71,6 +77,7 @@ attribute according to the response of the brick. brick-f: pranithk-laptop:/gfs/brick-f brick-g: pranithk-laptop:/gfs/brick-g brick-h: pranithk-laptop:/gfs/brick-h +``` In the example above: ``` @@ -91,12 +98,15 @@ present in all the other bricks in it's replica set as seen by that brick. In the example volume given above, all files in brick-a will have 2 entries, one for itself and the other for the file present in it's replica pair, i.e.brick-b: +``` trusted.afr.vol-client-0=0x000000000000000000000000 -->changelog for itself (brick-a) trusted.afr.vol-client-1=0x000000000000000000000000 -->changelog for brick-b as seen by brick-a - +``` Likewise, all files in brick-b will have: +``` trusted.afr.vol-client-0=0x000000000000000000000000 -->changelog for brick-a as seen by brick-b trusted.afr.vol-client-1=0x000000000000000000000000 -->changelog for itself (brick-b) +``` The same can be extended for other replica pairs. @@ -122,7 +132,8 @@ When a file split-brain happens it could be either data split-brain or meta-data split-brain or both. When a split-brain happens the changelog of the file would be something like this: -* Example:(Lets consider both data, metadata split-brain on same file). +Example:(Lets consider both data, metadata split-brain on same file). +``` [root@pranithk-laptop vol]# getfattr -d -m . -e hex /gfs/brick-?/a getfattr: Removing leading '/' from absolute path names \#file: gfs/brick-a/a @@ -133,10 +144,11 @@ trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57 trusted.afr.vol-client-0=0x000003b00000000100000000 trusted.afr.vol-client-1=0x000000000000000000000000 trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57 +``` -###Observations: +### Observations: -####According to changelog extended attributes on file /gfs/brick-a/a: +#### According to changelog extended attributes on file /gfs/brick-a/a: The first 8 digits of trusted.afr.vol-client-0 are all zeros (0x00000000................), and the first 8 digits of trusted.afr.vol-client-1 are not all zeros (0x000003d7................). @@ -149,7 +161,7 @@ trusted.afr.vol-client-1 are not all zeros (0x........00000001........). So the changelog on /gfs/brick-a/a implies that some metadata operations succeeded on itself but failed on /gfs/brick-b/a. -####According to Changelog extended attributes on file /gfs/brick-b/a: +#### According to Changelog extended attributes on file /gfs/brick-b/a: The first 8 digits of trusted.afr.vol-client-0 are not all zeros (0x000003b0................), and the first 8 digits of trusted.afr.vol-client-1 are all zeros (0x00000000................). @@ -205,6 +217,7 @@ Hence execute `setfattr -n trusted.afr.vol-client-1 -v 0x000003d70000000000000000 /gfs/brick-a/a` Thus after the above operations are done, the changelogs look like this: +``` [root@pranithk-laptop vol]# getfattr -d -m . -e hex /gfs/brick-?/a getfattr: Removing leading '/' from absolute path names \#file: gfs/brick-a/a @@ -216,7 +229,7 @@ trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57 trusted.afr.vol-client-0=0x000000000000000100000000 trusted.afr.vol-client-1=0x000000000000000000000000 trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57 - +``` Triggering Self-heal: --------------------- @@ -243,9 +256,9 @@ needs to be removed.The gfid-link files are present in the .glusterfs folder in the top-level directory of the brick. If the gfid of the file is 0x307a5c9efddd4e7c96e94fd4bcdcbd1b (the trusted.gfid extended attribute got from the getfattr command earlier),the gfid-link file can be found at -> /gfs/brick-a/.glusterfs/30/7a/307a5c9efddd4e7c96e94fd4bcdcbd1b +`/gfs/brick-a/.glusterfs/30/7a/307a5c9efddd4e7c96e94fd4bcdcbd1b` -####Word of caution: +#### Word of caution: Before deleting the gfid-link, we have to ensure that there are no hard links to the file present on that brick. If hard-links exist,they must be deleted as well. diff --git a/doc/debugging/statedump.md b/doc/debugging/statedump.md index f34a5c3436a..9dfdce15fad 100644 --- a/doc/debugging/statedump.md +++ b/doc/debugging/statedump.md @@ -1,31 +1,53 @@ -#Statedump +# Statedump Statedump is a file generated by glusterfs process with different data structure state which may contain the active inodes, fds, mempools, iobufs, memory allocation stats of different types of datastructures per xlator etc. -##How to generate statedump -We can find the directory where statedump files are created using 'gluster --print-statedumpdir' command. +## How to generate statedump +We can find the directory where statedump files are created using `gluster --print-statedumpdir` command. Create that directory if not already present based on the type of installation. Lets call this directory `statedump-directory`. -We can generate statedump using 'kill -USR1 <pid-of-gluster-process>'. +We can generate statedump using `kill -USR1 <pid-of-gluster-process>`. gluster-process is nothing but glusterd/glusterfs/glusterfsd process. There are also commands to generate statedumps for brick processes/nfs server/quotad -For bricks: `gluster volume statedump <volname>` +For bricks: +``` +gluster volume statedump <volname> +``` -For nfs server: `gluster volume statedump <volname> nfs` +For nfs server: +``` +gluster volume statedump <volname> nfs +``` -For quotad: `gluster volume statedump <volname> quotad` +For quotad: +``` +gluster volume statedump <volname> quotad +``` For brick-processes files will be created in `statedump-directory` with name of the file as `hyphenated-brick-path.<pid>.dump.timestamp`. For all other processes it will be `glusterdump.<pid>.dump.timestamp`. -##How to read statedump +For applications using libgfapi, `SIGUSR1` cannot be used, eg: smbd/libvirtd +processes could have used the `SIGUSR1` signal already for other purposes. +To generate statedump for the processes, using libgfapi, below command can be +executed from one of the nodes in the gluster cluster to which the libgfapi +application is connected to. +``` +gluster volume statedump <volname> client <hostname>:<process id> +``` +The statedumps can be found in the `statedump-directory`, the name of the +statedumps being `glusterdump.<pid>.dump.timestamp`. For a process there can be +multiple such files created depending on the number of times the volume is +accessed by the process (related to the number of `glfs_init()` calls). + +## How to read statedump We shall see snippets of each type of statedump. First and last lines of the file have starting and ending time of writing the statedump file. Times will be in UTC timezone. mallinfo return status is printed in the following format. Please read man mallinfo for more information about what each field means. -###Mallinfo +### Mallinfo ``` [mallinfo] mallinfo_arena=100020224 /* Non-mmapped space allocated (bytes) */ @@ -40,7 +62,7 @@ mallinfo_fordblks=3310112 /* Total free space (bytes) */ mallinfo_keepcost=133712 /* Top-most, releasable space (bytes) */ ``` -###Data structure allocation stats +### Data structure allocation stats For every xlator data structure memory per translator loaded in the call-graph is displayed in the following format: For xlator with name: glusterfs @@ -61,7 +83,7 @@ max_num_allocs=3 #Maximum number of active allocations at any point in the life total_allocs=7 #Number of times this data is allocated in the life of the process. ``` -###Mempools +### Mempools Mempools are optimization to reduce the number of allocations of a data type. If we create a mem-pool of lets say 1024 elements for a data-type, new elements will be allocated from heap using syscalls like calloc, only if all the 1024 elements in the pool are in active use. @@ -81,7 +103,7 @@ cur-stdalloc=0 #Denotes the number of allocations made from heap once cold-count max-stdalloc=0 #Maximum number of allocations from heap that are in active use at any point in the life of the process. ``` -###Iobufs +### Iobufs ``` [iobuf.global] iobuf_pool=0x1f0d970 #The memory pool for iobufs @@ -92,7 +114,7 @@ iobuf_pool.arena_cnt=8 #Total number of arenas in the pool iobuf_pool.request_misses=0 #The number of iobufs that were stdalloc'd (as they exceeded the default max page size provided by iobuf_pool). ``` -There are 3 lists of arenas +There are 3 lists of arenas: 1. Arena list: arenas allocated during iobuf pool creation and the arenas that are in use(active_cnt != 0) will be part of this list. 2. Purge list: arenas that can be purged(no active iobufs, active_cnt == 0). @@ -129,7 +151,7 @@ arena.6.active_iobuf.2.ptr=0x7fdb92189000 At any given point in time if there are lots of filled arenas then that could be a sign of iobuf leaks. -###Call stack +### Call stack All the fops received by gluster are handled using call-stacks. Call stack contains the information about uid/gid/pid etc of the process that is executing the fop. Each call-stack contains different call-frames per xlator which handles that fop. ``` @@ -144,7 +166,7 @@ op=LOOKUP #Fop type=1 #Type of the op i.e. FOP/MGMT-OP cnt=9 #Number of frames in this stack. ``` -###Call-frame +### Call-frame Each frame will have information about which xlator the frame belongs to, what is the function it wound to/from and will be unwind to. It also mentions if the unwind happened or not. If we observe hangs in the system and want to find out which xlator is causing it. Take a statedump and see what is the final xlator which is yet to be unwound. ``` @@ -159,7 +181,7 @@ wind_to=priv->children[i]->fops->lookup unwind_to=afr_lookup_cbk #Parent xlator function to which unwind happened ``` -###History of operations in Fuse +### History of operations in Fuse Fuse maintains history of operations that happened in fuse. @@ -175,7 +197,7 @@ TIME=2014-07-09 16:44:57.523394 message=[0] fuse_getattr_resume: 4591, STAT, path: (/iozone.tmp), gfid: (3afb4968-5100-478d-91e9-76264e634c9f) ``` -###Xlator configuration +### Xlator configuration ``` [cluster/replicate.r2-replicate-0] #Xlator type, name information child_count=2 #Number of children to the xlator @@ -195,7 +217,7 @@ favorite_child=-1 wait_count=1 ``` -###Graph/inode table +### Graph/inode table ``` [active graph - 1] @@ -207,7 +229,7 @@ conn.1.bound_xl./data/brick01a/homegfs.lru_size=183 #Number of inodes present in conn.1.bound_xl./data/brick01a/homegfs.purge_size=0 #Number of inodes present in purge list ``` -###Inode +### Inode ``` [conn.1.bound_xl./data/brick01a/homegfs.active.324] #324th inode in active inode list gfid=e6d337cf-97eb-44b3-9492-379ba3f6ad42 #Gfid of the inode @@ -215,6 +237,7 @@ nlookup=13 #Number of times lookups happened from the client or from fuse kernel fd-count=4 #Number of fds opened on the inode ref=11 #Number of refs taken on the inode ia_type=1 #Type of the inode. This should be changed to some string :-( +Ref by xl:.patchy-md-cache=11 #Further this there will be a list of xlators, and the ref count taken by each of them on this inode at the time of statedump [conn.1.bound_xl./data/brick01a/homegfs.lru.1] #1st inode in lru list. Note that ref count is zero for these inodes. gfid=5114574e-69bc-412b-9e52-f13ff087c6fc @@ -222,8 +245,10 @@ nlookup=5 fd-count=0 ref=0 ia_type=2 +Ref by xl:.fuse=1 +Ref by xl:.patchy-client-0=-1 ``` -###Inode context +### Inode context For each inode per xlator some context could be stored. This context can also be printed in the statedump. Here is the inode ctx of locks xlator ``` [xlator.features.locks.homegfs-locks.inode] @@ -240,12 +265,12 @@ lock-dump.domain.domain=homegfs-replicate-0 #Domain name where entry/data operat inodelk.inodelk[0](ACTIVE)=type=WRITE, whence=0, start=11141120, len=131072, pid = 18446744073709551615, owner=080b1ada117f0000, client=0xb7fc30, connection-id=compute-30-029.com-3505-2014/06/29-14:46:12:477358-homegfs-client-0-0-1, granted at Sun Jun 29 11:10:36 2014 #Active lock information ``` -##FAQ -###How to debug Memory leaks using statedump? +## FAQ +### How to debug Memory leaks using statedump? -####Using memory accounting feature: +#### Using memory accounting feature: -`https://bugzilla.redhat.com/show_bug.cgi?id=1120151` is one of the bugs which was debugged using statedump to see which data-structure is leaking. Here is the process used to find what the leak is using statedump. According to the bug the observation is that the process memory usage is increasing whenever one of the bricks is wiped in a replicate volume and a `full` self-heal is invoked to heal the contents. Statedump of the process is taken using kill -USR1 `<pid-of-gluster-self-heal-daemon>`. +[Bug 1120151](https://bugzilla.redhat.com/show_bug.cgi?id=1120151) is one of the bugs which was debugged using statedump to see which data-structure is leaking. Here is the process used to find what the leak is using statedump. According to the bug the observation is that the process memory usage is increasing whenever one of the bricks is wiped in a replicate volume and a `full` self-heal is invoked to heal the contents. Statedump of the process is taken using `kill -USR1 <pid-of-gluster-self-heal-daemon>`. ``` grep -w num_allocs glusterdump.5225.dump.1405493251 num_allocs=77078 @@ -268,10 +293,10 @@ grep of the statedump revealed too many allocations for the following data-types 3. gf_common_mt_mem_pool. After checking afr-code for allocations with tag `gf_common_mt_char` found `data-self-heal` code path does not free one such allocated memory. `gf_common_mt_mem_pool` suggests that there is a leak in pool memory. `replicate-0:dict_t`, `glusterfs:data_t` and `glusterfs:data_pair_t` pools are using lot of memory, i.e. cold_count is `0` and too many allocations. Checking source code of dict.c revealed that `key` in `dict` is allocated with `gf_common_mt_char` i.e. `2.` tag and value is created using gf_asprintf which in-turn uses `gf_common_mt_asprintf` i.e. `1.`. Browsing the code for leak in self-heal code paths lead to a line which over-writes a variable with new dictionary even when it was already holding a reference to another dictionary. After fixing these leaks, ran the same test to verify that none of the `num_allocs` are increasing even after healing 10,000 files directory hierarchy in statedump of self-heal daemon. -Please check http://review.gluster.org/8316 for more info about patch/code. +Please check this [patch](http://review.gluster.org/8316) for more info about the fix. -####Debugging leaks in memory pools: -Statedump output of memory pools was used to test and verify the fixes to https://bugzilla.redhat.com/show_bug.cgi?id=1134221. On code analysis, dict_t objects were found to be leaking (in terms of not being unref'd enough number of times, during name self-heal. The test involved creating 100 files on plain replicate volume, removing them from one of the bricks's backend, and then triggering lookup on them from the mount point. Statedump of the mount process was taken before executing the test case and after it, after compiling glusterfs with -DDEBUG flags (to have cold count set to 0 by default). +#### Debugging leaks in memory pools: +Statedump output of memory pools was used to test and verify the fixes to [Bug 1134221](https://bugzilla.redhat.com/show_bug.cgi?id=1134221). On code analysis, dict_t objects were found to be leaking (in terms of not being unref'd enough number of times, during name self-heal. The test involved creating 100 files on plain replicate volume, removing them from one of the brick's backend, and then triggering lookup on them from the mount point. Statedump of the mount process was taken before executing the test case and after it, after compiling glusterfs with -DDEBUG flags (to have cold count set to 0 by default). Statedump output of the fuse mount process before the test case was executed: @@ -303,7 +328,7 @@ cur-stdalloc=214 max-stdalloc=220 ``` -Here, with cold count being 0 by default, cur-stdalloc indicated the number of dict_t objects that were allocated in heap using mem_get(), and yet to be freed using mem_put() (refer to https://github.com/gluster/glusterfs/blob/master/doc/data-structures/mem-pool.md for more details on how mempool works). After the test case (name selfheal of 100 files), there was a rise in the cur-stdalloc value (from 14 to 214) for dict_t. +Here, with cold count being 0 by default, `cur-stdalloc` indicated the number of `dict_t` objects that were allocated in heap using `mem_get()`, and yet to be freed using `mem_put()` (refer to this [page](../developer-guide/datastructure-mem-pool.md) for more details on how mempool works). After the test case (name selfheal of 100 files), there was a rise in the cur-stdalloc value (from 14 to 214) for `dict_t`. After these leaks were fixed, glusterfs was again compiled with -DDEBUG flags, and the same steps were performed again and statedump was taken before and after executing the test case, of the mount. This was done to ascertain the validity of the fix. And the following are the results: @@ -337,8 +362,8 @@ max-stdalloc=119 ``` The value of cur-stdalloc remained 14 before and after the test, indicating that the fix indeed does what it's supposed to do. -###How to debug hangs because of frame-loss? -`https://bugzilla.redhat.com/show_bug.cgi?id=994959` is one of the bugs where statedump was helpful in finding where the frame was lost. Here is the process used to find where the hang is using statedump. +### How to debug hangs because of frame-loss? +[Bug 994959](https://bugzilla.redhat.com/show_bug.cgi?id=994959) is one of the bugs where statedump was helpful in finding where the frame was lost. Here is the process used to find where the hang is using statedump. When the hang was observed, statedumps are taken for all the processes. On mount's statedump the following stack is shown: ``` [global.callpool.stack.1.frame.1] @@ -386,4 +411,4 @@ unwind_to=qr_readdirp_cbk ``` `unwind_to` shows that call was unwound to `afr_readdirp_cbk` from client xlator. Inspecting that function revealed that afr is not unwinding the stack when fop failed. -Check http://review.gluster.org/5531 for more info about patch/code changes. +Check this [patch](http://review.gluster.org/5531) for more info about the fix. diff --git a/doc/developer-guide/Language-Bindings.md b/doc/developer-guide/Language-Bindings.md new file mode 100644 index 00000000000..951f5fae2f6 --- /dev/null +++ b/doc/developer-guide/Language-Bindings.md @@ -0,0 +1,45 @@ +# Language Bindings +GlusterFS 3.4 introduced the libgfapi client API for C programs. This +page lists bindings to the libgfapi C library from other languages. + +Go +-- + +- [gogfapi](https://github.com/gluster/gogfapi) - Go language bindings + for libgfapi, aiming to provide an api consistent with the default + Go file apis. + +Java +---- + +- [libgfapi-jni](https://github.com/semiosis/libgfapi-jni/) - Low + level JNI binding for libgfapi +- [glusterfs-java-filesystem](https://github.com/semiosis/glusterfs-java-filesystem) + - High level NIO.2 FileSystem Provider implementation for the Java + platform +- [libgfapi-java-io](https://github.com/gluster/libgfapi-java-io) - + Java bindings for libgfapi, similar to java.io + +Python +------ + +- [libgfapi-python](https://github.com/gluster/libgfapi-python) - + Libgfapi bindings for Python + +Ruby +---- + +- [libgfapi-ruby](https://github.com/spajus/libgfapi-ruby) - Libgfapi + bindings for Ruby using FFI + +Rust +---- + +- [gfapi-sys](https://github.com/cholcombe973/Gfapi-sys) - Libgfapi + bindings for Rust using FFI + +Perl +---- + +- [libgfapi-perl](https://github.com/gluster/libgfapi-perl) - Libgfapi + bindings for Perl using FFI diff --git a/doc/developer-guide/README.md b/doc/developer-guide/README.md new file mode 100644 index 00000000000..aaf9c7476b0 --- /dev/null +++ b/doc/developer-guide/README.md @@ -0,0 +1,81 @@ +Developers +========== + +### From GlusterDocumentation + +Contributing to the Gluster community +------------------------------------- + +Are you itching to send in patches and participate as a developer in the +Gluster community? Here are a number of starting points for getting +involved. We don't require a signed contributor license agreement or +copyright assignment, but we do require a "signed-off-by" line on each +code check-in. + +- [License + Change](http://www.gluster.org/2012/05/glusterfs-license-change/) - + we recently changed the client library code to a dual license under + the GPL v2 and the LGPL v3 or later +- [GlusterFS Coding Standards](./coding-standard.md) + +- If you are not sure of where to start, and what to do, we have a small + write-up on what you can pick. [Check it out](./options-to-contribute.md) + + +Adding File operations +---------------------- + +- [Steps to be followed when adding a new FOP to GlusterFS ](./adding-fops.md) + +Automatic File Replication +-------------------------- + +- [Cluster/afr translator](./afr.md) +- [History of Locking in AFR](./afr-locks-evolution.md) +- [Self heal Daemon](./afr-self-heal-daemon.md) + +Data Structures +--------------- + +- [inode data structure](./datastructure-inode.md) +- [iobuf data structure](./datastructure-iobuf.md) +- [mem-pool data structure](./datastructure-mem-pool.md) + +Find the gfapi symbol versions [here](./gfapi-symbol-versions.md) + +Daemon Management Framework +--------------------------- + +- [How to introduce new daemons using daemon management framework](./daemon-management-framework.md) + +Translators +----------- + +- [Performance/write-Behind Translator](./write-behind.md) +- [Translator Development](./translator-development.md) +- [Storage/posix Translator](./posix.md) + + +Brick multiplex +--------------- + +- [Brick mux resource reduction](./brickmux-thread-reduction.md) + +Fuse +---- + +- [Interrupt handling](./fuse-interrupt.md) + +Testing/Debugging +----------------- + +- [Unit Tests in GlusterFS](./unittest.md) +- [Using the Gluster Test + Framework](./Using-Gluster-Test-Framework.md) - Step by + step instructions for running the Gluster Test Framework +- [Coredump Analysis](../debugging/analyzing-regression-cores.md) - Steps to analize coredumps generated by regression machines. +- [Identifying Resource Leaks](./identifying-resource-leaks.md) + +Release Process +--------------- +- [Versioning](./versioning.md) diff --git a/doc/developer-guide/Using-Gluster-Test-Framework.md b/doc/developer-guide/Using-Gluster-Test-Framework.md new file mode 100644 index 00000000000..d2bb1c391da --- /dev/null +++ b/doc/developer-guide/Using-Gluster-Test-Framework.md @@ -0,0 +1,271 @@ +# USing Gluster Test Framwork +Description +----------- + +The Gluster Test Framework, is a suite of scripts used for regression +testing of Gluster. + +It runs well on RHEL and CentOS (possibly Fedora too, presently being +tested), and is automatically run against every patch submitted to +Gluster [for review](http://review.gluster.org). + +The Gluster Test Framework is part of the main Gluster code base, living +under the "tests" subdirectory: + + http://git.gluster.org/?p=glusterfs.git;a=summary + +WARNING +------- + +Running the Gluster Test Framework deletes “/var/lib/glusterd/\*”. + +**DO NOT run it on a server with any data.** + +Preparation steps for Ubuntu 14.04 LTS +-------------------------------------- + +1. \# apt-get install dbench git libacl1-dev mock nfs-common +nfs-kernel-server libtest-harness-perl libyajl-dev xfsprogs psmisc attr +acl lvm2 rpm + +2. \# apt-get install python-webob python-paste python-sphinx + +3. \# apt-get install autoconf automake bison dos2unix flex libfuse-dev +libaio-dev libibverbs-dev librdmacm-dev libtool libxml2-dev +libxml2-utils liblvm2-dev make libssl-dev pkg-config libpython-dev +python-eventlet python-netifaces python-simplejson python-pyxattr +libreadline-dev tar + +4) Install cmockery2 from github (https://github.com/lpabon/cmockery2) +and compile and make install as in Readme + +5) + + sudo groupadd mock + sudo useradd -g mock mock + +6) mkdir /var/run/gluster + +**Note**: redhat-rpm-config package is not found in ubuntu + +Preparation steps for CentOS 7 (only) +------------------------------------- + +1. Install EPEL: + + $ sudo yum install -y http://epel.mirror.net.in/epel/7/x86_64/e/epel-release-7-1.noarch.rpm + +2. Install the CentOS 7.x dependencies: + + $ sudo yum install -y --enablerepo=epel cmockery2-devel dbench git libacl-devel mock nfs-utils perl-Test-Harness yajl xfsprogs psmisc + + $ sudo yum install -y --enablerepo=epel python-webob1.0 python-paste-deploy1.5 python-sphinx10 redhat-rpm-config + +==\> Despite below missing packages it worked for me + + No package python-webob1.0 available. + No package python-paste-deploy1.5 available. + No package python-sphinx10 available. + + $ sudo yum install -y --enablerepo=epel autoconf automake bison dos2unix flex fuse-devel libaio-devel libibverbs-devel \ + librdmacm-devel libtool libxml2-devel lvm2-devel make openssl-devel pkgconfig \ + python-devel python-eventlet python-netifaces python-paste-deploy \ + python-simplejson python-sphinx python-webob pyxattr readline-devel rpm-build \ + tar + +3. Create the mock user + + $ sudo useradd -g mock mock + +Preparation steps for CentOS 6.3+ (only) +---------------------------------------- + +1. Install EPEL: + + $ sudo yum install -y http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm + +2. Install the CentOS 6.x dependencies: + + $ sudo yum install -y --enablerepo=epel cmockery2-devel dbench git libacl-devel mock nfs-utils perl-Test-Harness yajl xfsprogs + $ sudo yum install -y --enablerepo=epel python-webob1.0 python-paste-deploy1.5 python-sphinx10 redhat-rpm-config + $ sudo yum install -y --enablerepo=epel autoconf automake bison dos2unix flex fuse-devel libaio-devel libibverbs-devel \ + librdmacm-devel libtool libxml2-devel lvm2-devel make openssl-devel pkgconfig \ + python-devel python-eventlet python-netifaces python-paste-deploy \ + python-simplejson python-sphinx python-webob pyxattr readline-devel rpm-build \ + tar + +3. Create the mock user + + $ sudo useradd -g mock mock + +Preparation steps for RHEL 6.3+ (only) +-------------------------------------- + +1. Ensure you have the "Scalable Filesystem Support" group installed + +This provides the xfsprogs package, which is required by the test +framework. + +2. Install EPEL: + + $ sudo yum install -y http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm + +3. Install the CentOS 6.x dependencies: + + $ sudo yum install -y --enablerepo=epel cmockery2-devel dbench git libacl-devel mock nfs-utils yajl perl-Test-Harness + $ sudo yum install -y --enablerepo=rhel-6-server-optional-rpms python-webob1.0 python-paste-deploy1.5 python-sphinx10 redhat-rpm-config + $ sudo yum install -y --disablerepo=rhs* --enablerepo=*optional-rpms autoconf \ + automake bison dos2unix flex fuse-devel libaio-devel libibverbs-devel \ + librdmacm-devel libtool libxml2-devel lvm2-devel make openssl-devel pkgconfig \ + python-devel python-eventlet python-netifaces python-paste-deploy \ + python-simplejson python-sphinx python-webob pyxattr readline-devel rpm-build \ + tar + +4. Create the mock user + + $ sudo useradd -g mock mock + +Preparation steps for Fedora 16-19 (only) +----------------------------------------- + +**Still in development** + +1. Install the Fedora dependencies: + + $ sudo yum install -y attr cmockery2-devel dbench git mock nfs-utils perl-Test-Harness psmisc xfsprogs + $ sudo yum install -y python-webob1.0 python-paste-deploy1.5 python-sphinx10 redhat-rpm-config + $ sudo yum install -y autoconf automake bison dos2unix flex fuse-devel libaio-devel libibverbs-devel \ + librdmacm-devel libtool libxml2-devel lvm2-devel make openssl-devel pkgconfig \ + python-devel python-eventlet python-netifaces python-paste-deploy \ + python-simplejson python-sphinx python-webob pyxattr readline-devel rpm-build \ + tar + +3. Create the mock user + + $ sudo useradd -g mock mock + +Common steps +------------ + +1. Ensure DNS for your server is working + +The Gluster Test Framework fails miserably if the full domain name for +your server doesn't resolve back to itself. + +If you don't have a working DNS infrastructure in place, adding an entry +for your server to its /etc/hosts file will work. + +2. Install the version of Gluster you are testing + +Either install an existing set of rpms: + + $ sudo yum install [your gluster rpms here] + +Or compile your own ones (fairly easy): + + http://www.gluster.org/community/documentation/index.php/CompilingRPMS + +3. Clone the GlusterFS git repository + + $ git clone git://git.gluster.org/glusterfs + $ cd glusterfs + +Ensure mock can access the directory +------------------------------------ + +Some tests run as the user "mock". If the mock user can't access the +tests subdirectory directory, these tests fail. (rpm.t is one such test) + +This is a known gotcha when the git repo is cloned to your home +directory. Home directories generally don't have world readable +permissions. You can fix this by adjusting your home directory +permissions, or placing the git repo somewhere else (with access for the +mock user). + +Running the tests +----------------- + +The tests need to run as root, so they can mount volumes and manage +gluster processes as needed. + +It's also best to run them directly as the root user, instead of through +sudo. Strange things sporadicly happen (for me) when using the full test +framework through sudo, that haven't happened (yet) when running +directly as root. Hangs in dbench particularly, which are part of at +least one test. + + # ./run-tests.sh + +The test framework takes just over 45 minutes to run in a VM here (4 +cpu's assigned, 8GB ram, SSD storage). It may take significantly more or +less time for you, depending on the hardware and software you're using. + +Showing debug information +------------------------- + +To display verbose information while the tests are running, set the +DEBUG environment variable to 1 prior to running the tests. + + # DEBUG=1 ./run-tests.sh + +Log files +--------- + +Verbose output from the rpm.t test goes into "rpmbuild-mock.log", +located in the same directory the test is run from. + +Reporting bugs +-------------- + +If you hit a bug when running the test framework, **please** create a +bug report for it on Bugzilla so it gets fixed: + + https://bugzilla.redhat.com/enter_bug.cgi?product=GlusterFS&component=tests + +Creating your own tests +----------------------- + +The test scripts are written in bash, with their filenames ending in .t +instead of .sh. + +When creating your own test scripts, create them in an appropriate +subdirectory under "tests" (eg "bugs" or "features") and use descriptive +names like "bug-XXXXXXX-checking-feature-X.t" + +Also include the "include.rc" file, which defines the test types and +host/brick/volume defaults: + + . $(dirname $0)/../include.rc + +There are 5 test types available at present, but feel free to add more +if you need something that doesn't yet exist. The test types are +explained in more detail below. + +Also essential is the "cleanup" command, which removes any existing +Gluster configuration (**without backing it up**), and also kills any +running gluster processes. + +There is a basic test template you can copy, named bug-000000.t in the +bugs subdirectory: + + $ cp bugs/bug-000000.t somedir/descriptive-name.t + +### TEST + +- Example of usage in basic/volume.t + +### TEST\_IN\_LOOP + +- Example of usage in basic/rpm.t + +### EXPECT + +- Example of usage in basic/volume.t + +### EXPECT\_WITHIN + +- Example of usage in basic/volume-status.t + +### EXPECT\_KEYWORD + +- Defined in include.rc, but seems to be unused? diff --git a/doc/developer-guide/afr/afr-locks-evolution.md b/doc/developer-guide/afr-locks-evolution.md index 7d2a136d871..2dabbcfeb13 100644 --- a/doc/developer-guide/afr/afr-locks-evolution.md +++ b/doc/developer-guide/afr-locks-evolution.md @@ -32,10 +32,10 @@ AFR makes use of locks xlator extensively: * For Entry self-heal, it is `entrylk(NULL name, parent inode)`. Specifying NULL for the name takes full lock on the directory referred to by the inode. * For data self-heal, there is a bit of history as to how locks evolved: -###Initial version (say version 1) : +### Initial version (say version 1) : There was no concept of selfheal daemon (shd). Only client lookups triggered heals. so AFR always took `inodelk(0,0,DATA_DOMAIN)` for healing. The issue with this approach was that when heal was in progress, I/O from clients was blocked . -###version 2: +### version 2: shd was introduced. We needed to allow I/O to go through when heal was going,provided the ranges did not overlap. To that extent, the following approach was adopted: + 1.shd takes (full inodelk in DATA_DOMAIN). Thus client FOPS are blocked and cannot modify changelog-xattrs @@ -79,7 +79,7 @@ It modifies data but the FOP succeeds only on brick 2. writev returns success, a and thus goes ahead and copies stale 128Kb from brick 1 to brick2. Thus as far as application is concerned, `writev` returned success but bricks have stale data. What needs to be done is `writev` must return success only if it succeeded on atleast one source brick (brick b1 in this case). Otherwise The heal still happens in reverse direction but as far as the application is concerned, it received an error. -###Note on lock **domains** +### Note on lock **domains** We have used conceptual names in this document like DATA_DOMAIN/ METADATA_DOMAIN/ SELF_HEAL_DOMAIN. In the code, these are mapped to strings that are based on the AFR xlator name like so: DATA_DOMAIN --->"vol_name-replicate-n" diff --git a/doc/developer-guide/afr/self-heal-daemon.md b/doc/developer-guide/afr-self-heal-daemon.md index 1fd8f08062a..65940d420b7 100644 --- a/doc/developer-guide/afr/self-heal-daemon.md +++ b/doc/developer-guide/afr-self-heal-daemon.md @@ -8,12 +8,13 @@ This document only describes how the shd works for replicate (AFR) volumes. The shd is launched by glusterd when the volume starts (only if the volume includes a replicate configuration). The graph of the shd process in every node contains the following: The io-stats which is the top most xlator, its children being the -replicate xlators (subvolumes) of *only* the bricks present in that particular node node, and finally *all* the client xlators that are the children of the replicate xlators. +replicate xlators (subvolumes) of *only* the bricks present in that particular node, and finally *all* the client xlators that are the children of the replicate xlators. The shd does two types of self-heal crawls: Index heal and Full heal. For both these types of crawls, the basic idea is the same: For each file encountered while crawling, perform metadata, data and entry heals under appropriate locks. * An overview of how each of these heals is performed is detailed in the 'Self-healing' section of *doc/features/afr-v1.md* -* The different file locks which the shd takes for each of these heals is detailed in *doc/code/xlators/cluster/afr/afr-locks-evolution.md* +* The different file locks which the shd takes for each of these heals is detailed in *doc/developer +-guide/afr-locks-evolution.md* Metadata heal refers to healing extended attributes, mode and permissions of a file or directory. Data heal refers to healing the file contents. @@ -30,18 +31,18 @@ Only one heal can be in progress at one time, irrespective of reason why it was Only one heal can be queued while the first one is running. If an Index heal is queued, it can be overridden by queuing a Full heal and not vice-versa. Also, before processing each entry in index heal, a check is made if a full heal is queued. If it is, then the index heal is aborted so that the full heal can proceed. -In index heal, each shd reads the entries present inside .glusterfs/indices/xattrop folder and triggers heal on each entry with appropriate locks. -The .glusterfs/indices/xattrop directory contains a base entry of the name "xattrop-<virtual-gfid-string>". All other entries are hardlinks to the base entry. The +In index heal, each shd reads the entries present inside .glusterfs/indices/xattrop/ folder and triggers heal on each entry with appropriate locks. +The .glusterfs/indices/xattrop/ directory contains a base entry of the name "xattrop-<virtual-gfid-string>". All other entries are hardlinks to the base entry. The *names* of the hardlinks are the gfid strings of the files that may need heal. When a client (mount) performs an operation on the file, the index xlator present in each brick process adds the hardlinks in the pre-op phase of the FOP's transaction -and removes it in post-op phase if the operation is successful. Thus if an entry is present inside the .glusterfs/indices/xattrop directory when there is no I/O +and removes it in post-op phase if the operation is successful. Thus if an entry is present inside the .glusterfs/indices/xattrop/ directory when there is no I/O happening on the file, it means the file needs healing (or atleast an examination if the brick crashed after the post-op completed but just before the removal of the hardlink). -####Index heal steps: +#### Index heal steps: <pre><code> In shd process of *each node* { - opendir +readdir (.glusterfs/indices/xattrop) + opendir +readdir (.glusterfs/indices/xattrop/) for each entry inside it { self_heal_entry() //Explained below. } @@ -54,15 +55,15 @@ self_heal_entry() { take appropriate locks determine source and sinks from AFR changelog xattrs perform whatever heal is needed (any of metadata, data and entry heal in that order) - clear changelog xattrs and hardlink inside .glusterfs/indices/xattrop + clear changelog xattrs and hardlink inside .glusterfs/indices/xattrop/ } } </code></pre> Note: -* If the gfid hardlink is present in the .glusterfs/indices/xattrop of both replica bricks, then each shd will try to heal the file but only one of them will be able to proceed due to the self-heal domain lock. +* If the gfid hardlink is present in the .glusterfs/indices/xattrop/ of both replica bricks, then each shd will try to heal the file but only one of them will be able to proceed due to the self-heal domain lock. -* While processing entries inside .glusterfs/indices/xattrop, if shd encounters an entry whose parent is yet to be healed, it will skip it and it will be picked up in the next crawl. +* While processing entries inside .glusterfs/indices/xattrop/, if shd encounters an entry whose parent is yet to be healed, it will skip it and it will be picked up in the next crawl. * If a file is in data/ metadata split-brain, it will not be healed. diff --git a/doc/developer-guide/afr/afr.md b/doc/developer-guide/afr.md index 566573a4e26..566573a4e26 100644 --- a/doc/developer-guide/afr/afr.md +++ b/doc/developer-guide/afr.md diff --git a/doc/developer-guide/bd-xlator.md b/doc/developer-guide/bd-xlator.md deleted file mode 100644 index 1771fb6e24b..00000000000 --- a/doc/developer-guide/bd-xlator.md +++ /dev/null @@ -1,469 +0,0 @@ -#Block device translator - -Block device translator (BD xlator) is a translator added to GlusterFS which provides block backend for GlusterFS. This replaces the existing bd_map translator in GlusterFS that provided similar but very limited functionality. GlusterFS expects the underlying brick to be formatted with a POSIX compatible file system. BD xlator changes that and allows for having bricks that are raw block devices like LVM which needn’t have any file systems on them. Hence with BD xlator, it becomes possible to build a GlusterFS volume comprising of bricks that are logical volumes (LV). - -##bd - -BD xlator maps underlying LVs to files and hence the LVs appear as files to GlusterFS clients. Though BD volume externally appears very similar to the usual Posix volume, not all operations are supported or possible for the files on a BD volume. Only those operations that make sense for a block device are supported and the exact semantics are described in subsequent sections. - -While Posix volume takes a file system directory as brick, BD volume needs a volume group (VG) as brick. In the usual use case of BD volume, a file created on BD volume will result in an LV being created in the brick VG. In addition to a VG, BD volume also needs a file system directory that should be specified at the volume creation time. This directory is necessary for supporting the notion of directories and directory hierarchy for the BD volume. Metadata about LVs (size, mapping info) is stored in this directory. - -BD xlator was mainly developed to use block devices directly as VM images when GlusterFS is used as storage for KVM virtualization. Some of the salient points of BD xlator are - -* Since BD supports file level snapshots and clones by leveraging the snapshot and clone capabilities of LVM, it can be used to fully off-load snapshot and cloning operations from QEMU to the storage (GlusterFS) itself. - -* BD understands dm-thin LVs and hence can support files that are backed by thinly provisioned LVs. This capability of BD xlator translates to having thinly provisioned raw VM images. - -* BD enables thin LVs from a thin pool to be used from multiple nodes that have visibility to GlusterFS BD volume. Thus thin pool can be used as a VM image repository allowing access/visibility to it from multiple nodes. - -* BD supports true zerofill by using BLKZEROOUT ioctl on underlying block devices. Thus BD allows SCSI WRITESAME to be used on underlying block device if the device supports it. - -Though BD xlator is primarily intended to be used with block devices, it does provide full Posix xlator compatibility for files that are created on BD volume but are not backed by or mapped to a block device. Such files which don’t have a block device mapping exist on the Posix directory that is specified during BD volume creation. BD xlator is available from GlusterFS-3.5 release. - -###Compiling BD translator - -BD xlator needs lvm2 development library. –enable-bd-xlator option can be used with `./configure` script to explicitly enable BD translator. The following snippet from the output of configure script shows that BD xlator is enabled for compilation. - - -#####GlusterFS configure summary - - … - Block Device xlator : yes - - -###Creating a BD volume - -BD supports hosting of both linear LV and thin LV within the same volume. However seperate examples are provided below. As noted above, the prerequisite for a BD volume is VG which is created from a loop device here, but it can be any other device too. - - -* Creating BD volume with linear LV backend - -* Create a loop device - - - [root@node ~]# dd if=/dev/zero of=bd-loop count=1024 bs=1M - - [root@node ~]# losetup /dev/loop0 bd-loop - - -* Prepare a brick by creating a VG - - [root@node ~]# pvcreate /dev/loop0 - - [root@node ~]# vgcreate bd-vg /dev/loop0 - - -* Create the BD volume - -* Create a POSIX directory first - - - [root@node ~]# mkdir /bd-meta - -It is recommended that this directory is created on an LV in the brick VG itself so that both data and metadata live together on the same device. - - -* Create and mount the volume - - [root@node ~]# gluster volume create bd node:/bd-meta?bd-vg force - - -The general syntax for specifying the brick is `host:/posix-dir?volume-group-name` where “?” is the separator. - - - - [root@node ~]# gluster volume start bd - [root@node ~]# gluster volume info bd - Volume Name: bd - Type: Distribute - Volume ID: cb042d2a-f435-4669-b886-55f5927a4d7f - Status: Started - Xlator 1: BD - Capability 1: offload_copy - Capability 2: offload_snapshot - Number of Bricks: 1 - Transport-type: tcp - Bricks: - Brick1: node:/bd-meta - Brick1 VG: bd-vg - - - - [root@node ~]# mount -t glusterfs node:/bd /mnt - -* Create a file that is backed by an LV - - [root@node ~]# ls /mnt - - [root@node ~]# - -Since the volume is empty now, so is the underlying VG. - - [root@node ~]# lvdisplay bd-vg - [root@node ~]# - -Creating a file that is mapped to an LV is a 2 step operation. First the file should be created on the mount point and a specific extended attribute should be set to map the file to LV. - - [root@node ~]# touch /mnt/lv - [root@node ~]# setfattr -n “user.glusterfs.bd” -v “lv” /mnt/lv - -Now an LV got created in the VG brick and the file /mnt/lv maps to this LV. Any read/write to this file ends up as read/write to the underlying LV. - - [root@node ~]# lvdisplay bd-vg - — Logical volume — - LV Path /dev/bd-vg/6ff0f25f-2776-4d19-adfb-df1a3cab8287 - LV Name 6ff0f25f-2776-4d19-adfb-df1a3cab8287 - VG Name bd-vg - LV UUID PjMPcc-RkD5-RADz-6ixG-UYsk-oclz-vL0nv6 - LV Write Access read/write - LV Creation host, time node, 2013-11-26 16:15:45 +0530 - LV Status available - open 0 - LV Size 4.00 MiB - Current LE 1 - Segments 1 - Allocation inherit - Read ahead sectors 0 - Block device 253:6 - -The file gets created with default LV size which is 1 LE which is 4MB in this case. - - [root@node ~]# ls -lh /mnt/lv - -rw-r–r–. 1 root root 4.0M Nov 26 16:15 /mnt/lv - -truncate can be used to set the required file size. - - [root@node ~]# truncate /mnt/lv -s 256M - [root@node ~]# lvdisplay bd-vg - — Logical volume — - LV Path /dev/bd-vg/6ff0f25f-2776-4d19-adfb-df1a3cab8287 - LV Name 6ff0f25f-2776-4d19-adfb-df1a3cab8287 - VG Name bd-vg - LV UUID PjMPcc-RkD5-RADz-6ixG-UYsk-oclz-vL0nv6 - LV Write Access read/write - LV Creation host, time node, 2013-11-26 16:15:45 +0530 - LV Status available - # open 0 - LV Size 256.00 MiB - Current LE 64 - Segments 1 - Allocation inherit - Read ahead sectors 0 - Block device 253:6 - - - [root@node ~]# ls -lh /mnt/lv - -rw-r–r–. 1 root root 256M Nov 26 16:15 /mnt/lv - - currently LV size has been set to 256 - -The size of the file/LV can be specified during creation/mapping time itself like this: - - setfattr -n “user.glusterfs.bd” -v “lv:256MB” /mnt/lv - -2. Creating BD volume with thin LV backend - -* Create a loop device - - - [root@node ~]# dd if=/dev/zero of=bd-loop-thin count=1024 bs=1M - - [root@node ~]# losetup /dev/loop0 bd-loop-thin - - -* Prepare a brick by creating a VG and thin pool - - - [root@node ~]# pvcreate /dev/loop0 - - [root@node ~]# vgcreate bd-vg-thin /dev/loop0 - - -* Create a thin pool - - - [root@node ~]# lvcreate –thin bd-vg-thin -L 1000M - - Rounding up size to full physical extent 4.00 MiB - Logical volume “lvol0″ created - -lvdisplay shows the thin pool - - [root@node ~]# lvdisplay bd-vg-thin - — Logical volume — - LV Name lvol0 - VG Name bd-vg-thin - LV UUID HVa3EM-IVMS-QG2g-oqU6-1UxC-RgqS-g8zhVn - LV Write Access read/write - LV Creation host, time node, 2013-11-26 16:39:06 +0530 - LV Pool transaction ID 0 - LV Pool metadata lvol0_tmeta - LV Pool data lvol0_tdata - LV Pool chunk size 64.00 KiB - LV Zero new blocks yes - LV Status available - # open 0 - LV Size 1000.00 MiB - Allocated pool data 0.00% - Allocated metadata 0.88% - Current LE 250 - Segments 1 - Allocation inherit - Read ahead sectors auto - Block device 253:9 - -* Create the BD volume - -* Create a POSIX directory first - - - [root@node ~]# mkdir /bd-meta-thin - -* Create and mount the volume - - [root@node ~]# gluster volume create bd-thin node:/bd-meta-thin?bd-vg-thin force - - [root@node ~]# gluster volume start bd-thin - - - [root@node ~]# gluster volume info bd-thin - Volume Name: bd-thin - Type: Distribute - Volume ID: 27aa7eb0-4ffa-497e-b639-7cbda0128793 - Status: Started - Xlator 1: BD - Capability 1: thin - Capability 2: offload_copy - Capability 3: offload_snapshot - Number of Bricks: 1 - Transport-type: tcp - Bricks: - Brick1: node:/bd-meta-thin - Brick1 VG: bd-vg-thin - - - [root@node ~]# mount -t glusterfs node:/bd-thin /mnt - -* Create a file that is backed by a thin LV - - - [root@node ~]# ls /mnt - - [root@node ~]# - -Creating a file that is mapped to a thin LV is a 2 step operation. First the file should be created on the mount point and a specific extended attribute should be set to map the file to a thin LV. - - [root@node ~]# touch /mnt/thin-lv - - [root@node ~]# setfattr -n “user.glusterfs.bd” -v “thin:256MB” /mnt/thin-lv - -Now /mnt/thin-lv is a thin provisioned file that is backed by a thin LV and size has been set to 256. - - [root@node ~]# lvdisplay bd-vg-thin - — Logical volume — - LV Name lvol0 - VG Name bd-vg-thin - LV UUID HVa3EM-IVMS-QG2g-oqU6-1UxC-RgqS-g8zhVn - LV Write Access read/write - LV Creation host, time node, 2013-11-26 16:39:06 +0530 - LV Pool transaction ID 1 - LV Pool metadata lvol0_tmeta - LV Pool data lvol0_tdata - LV Pool chunk size 64.00 KiB - LV Zero new blocks yes - LV Status available - # open 0 - LV Size 000.00 MiB - Allocated pool data 0.00% - Allocated metadata 0.98% - Current LE 250 - Segments 1 - Allocation inherit - Read ahead sectors auto - Block device 253:9 - - - - - — Logical volume — - LV Path dev/bd-vg-thin/081b01d1-1436-4306-9baf-41c7bf5a2c73 - LV Name 081b01d1-1436-4306-9baf-41c7bf5a2c73 - VG Name bd-vg-thin - LV UUID coxpTY-2UZl-9293-8H2X-eAZn-wSp6-csZIeB - LV Write Access read/write - LV Creation host, time node, 2013-11-26 16:43:19 +0530 - LV Pool name lvol0 - LV Status available - # open 0 - LV Size 256.00 MiB - Mapped size 0.00% - Current LE 64 - Segments 1 - Allocation inherit - Read ahead sectors auto - Block device 253:10 - - - - - -As can be seen from above, creation of a file resulted in creation of a thin LV in the brick. - - -###Improvisation on BD translator: - -First version of BD xlator ( block backend) had few limitations such as - -* Creation of directories not supported -* Supports only single brick -* Does not use extended attributes (and client gfid) like posix xlator -* Creation of special files (symbolic links, device nodes etc) not - supported - -Basic limitation of not allowing directory creation was blocking -oVirt/VDSM to consume BD xlator as part of Gluster domain since VDSM -creates multi-level directories when GlusterFS is used as storage -backend for storing VM images. - -To overcome these limitations a new BD xlator with following -improvements are implemented. - -* New hybrid BD xlator that handles both regular files and block device - files -* The volume will have both POSIX and BD bricks. Regular files are - created on POSIX bricks, block devices are created on the BD brick (VG) -* BD xlator leverages exiting POSIX xlator for most POSIX calls and - hence sits above the POSIX xlator -* Block device file is differentiated from regular file by an extended - attribute -* The xattr 'user.glusterfs.bd' (BD_XATTR) plays a role in mapping a - posix file to Logical Volume (LV). -* When a client sends a request to set BD_XATTR on a posix file, a new - LV is created and mapped to posix file. So every block device will - have a representative file in POSIX brick with 'user.glusterfs.bd' - (BD_XATTR) set. -* Here after all operations on this file results in LV related - operations. - -For example, opening a file that has BD_XATTR set results in opening -the LV block device, reading results in reading the corresponding LV -block device. - -When BD xlator gets request to set BD_XATTR via setxattr call, it -creates a LV and information about this LV is placed in the xattr of the -posix file. xattr "user.glusterfs.bd" used to identify that posix file -is mapped to BD. - -Usage: -Server side: - - [root@host1 ~]# gluster volume create bdvol host1:/storage/vg1_info?vg1 host2:/storage/vg2_info?vg2 - -It creates a distributed gluster volume 'bdvol' with Volume Group vg1 -using posix brick /storage/vg1_info in host1 and Volume Group vg2 using -/storage/vg2_info in host2. - - - [root@host1 ~]# gluster volume start bdvol - -Client side: - - [root@node ~]# mount -t glusterfs host1:/bdvol /media - [root@node ~]# touch /media/posix - -It creates regular posix file 'posix' in either host1:/vg1 or host2:/vg2 brick - - [root@node ~]# mkdir /media/image - - [root@node ~]# touch /media/image/lv1 - - -It also creates regular posix file 'lv1' in either host1:/vg1 or -host2:/vg2 brick - - [root@node ~]# setfattr -n "user.glusterfs.bd" -v "lv" /media/image/lv1 - - [root@node ~]# - - -Above setxattr results in creating a new LV in corresponding brick's VG -and it sets 'user.glusterfs.bd' with value 'lv:<default-extent-size'' - - - [root@node ~]# truncate -s5G /media/image/lv1 - - -It results in resizig LV 'lv1'to 5G - -New BD xlator code is placed in `xlators/storage/bd` directory. - -Also add volume-uuid to the VG so that same VG cannot be used for other -bricks/volumes. After deleting a gluster volume, one has to manually -remove the associated tag using vgchange <vg-name> --deltag -`<trusted.glusterfs.volume-id:<volume-id>>` - - -#### Exposing volume capabilities - -With multiple storage translators (posix and bd) being supported in GlusterFS, it becomes -necessary to know the volume type so that user can issue appropriate calls that are relevant -only to the a given volume type. Hence there needs to be a way to expose the type of -the storage translator of the volume to the user. - -BD xlator is capable of providing server offloaded file copy, server/storage offloaded -zeroing of a file etc. This capabilities should be visible to the client/user, so that these -features can be exploited. - -BD xlator exports capability information through gluster volume info (and --xml) output. For eg: - -`snip of gluster volume info output for a BD based volume` - - Xlator 1: BD - Capability 1: thin - -`snip of gluster volume info --xml output for a BD based volume` - - <xlators> - <xlator> - <name>BD</name> - <capabilities> - <capability>thin</capability> - </capabilities> - </xlator> - </xlators> - -But this capability information should also exposed through some other means so that a host -which is not part of Gluster peer could also avail this capabilities. - -* Type - -BD translator supports both regular files and block device, i,e., one can create files on -GlusterFS volume backed by BD translator and this file could end up as regular posix file or -a logical volume (block device) based on the user''s choice. User can do a setxattr on the -created file to convert it to a logical volume. - -Users of BD backed volume like QEMU would like to know that it is working with BD type of volume -so that it can issue an additional setxattr call after creating a VM image on GlusterFS backend. -This is necessary to ensure that the created VM image is backed by LV instead of file. - -There are different ways to expose this information (BD type of volume) to user. -One way is to export it via a `getxattr` call. That said, When a client issues getxattr("volume_type") -on a root gfid, bd xlator will return 1 implying its BD xlator. But posix xlator will return ENODATA -and client code can interpret this as posix xlator. Also capability list can be returned via -getxattr("caps") for root gfid. - -* Capabilities - -BD xlator supports new features such as server offloaded file copy, thin provisioned VM images etc. - -There is no standard way of exploiting these features from client side (such as syscall -to exploit server offloaded copy). So these features need to be exported to the client so that -they can be used. BD xlator latest version exports these capabilities information through -gluster volume info (and --xml) output. But if a client is not part of GlusterFS peer -it can''t run volume info command to get the list of capabilities of a given GlusterFS volume. -For example, GlusterFS block driver in qemu need to get the capability list so that these features are used. - - - -Parts of this documentation were originally published here -#http://raobharata.wordpress.com/2013/11/27/glusterfs-block-device-translator/ diff --git a/doc/developer-guide/brickmux-thread-reduction.md b/doc/developer-guide/brickmux-thread-reduction.md new file mode 100644 index 00000000000..7d76e8ff579 --- /dev/null +++ b/doc/developer-guide/brickmux-thread-reduction.md @@ -0,0 +1,64 @@ +# Resource usage reduction in brick multiplexing + +Each brick is regresented with a graph of translators in a brick process. +Each translator in the graph has its own set of threads and mem pools +and other system resources allocations. Most of the times all these +resources are not put to full use. Reducing the resource consumption +of each brick is a problem in itself that needs to be addressed. The other +aspect to it is, sharing of resources across brick graph, this becomes +critical in brick multiplexing scenario. In this document we will be discussing +only about the threads. + +If a brick mux process hosts 50 bricks there are atleast 600+ threads created +in that process. Some of these are global threads that are shared by all the +brick graphs, and others are per translator threads. The global threads like +synctask threads, timer threads, sigwaiter, poller etc. are configurable and +do not needs to be reduced. The per translator threads keeps growing as the +number of bricks in the process increases. Each brick spawns atleast 10+ +threads: +- io-threads +- posix threads: + 1. Janitor + 2. Fsyncer + 3. Helper + 4. aio-thread +- changelog and bitrot threads(even when the features are not enabled) + +## io-threads + +io-threads should be made global to the process, having 16+ threads for +each brick does not make sense. But io-thread translator is loaded in +the graph, and the position of io-thread translator decides from when +the fops will be parallelised across threads. We cannot entirely move +the io-threads to libglusterfs and say the multiplexing happens from +the master translator or so. Hence, the io-thread orchestrator code +is moved to libglusterfs, which ensures there is only one set of +io-threads that is shared among the io-threads translator in each brick. +This poses performance issues due to lock-contention in the io-threds +layer. This also shall be addressed by having multiple locks instead of +one global lock for io-threads. + +## Posix threads +Most of the posix threads execute tasks in a timely manner, hence it can be +replaced with a timer whose handler register a task to synctask framework, once +the task is complete, the timer is registered again. With this we can eliminate +the need of one thread for each task. The problem with using synctasks is +the performance impact it will have due to make/swapcontext. For task that +does not involve network wait, we need not do makecontext, instead the task +function with arg can be stored and executed when a synctask thread is free. +We need to implement an api in synctask to execute atomic tasks(no network wait) +without the overhead of make/swapcontext. This will solve the performance +impact associated with using synctask framework. + +And the other challenge, is to cancel all the tasks pending from a translator. +This is important to cleanly detach brick. For this, we need to implement an +api in synctask that can cancel all the tasks from a given translator. + +For future, this will be replced to use global thread-pool(once implemented). + +## Changelog and bitrot threads + +In the initial implementation, the threads are not created if the feature is +not enabled. We need to share threads across changelog instances if we plan +to enable these features in brick mux scenario. + diff --git a/doc/developer-guide/coding-standard.md b/doc/developer-guide/coding-standard.md index 368c5553464..031c6c0da99 100644 --- a/doc/developer-guide/coding-standard.md +++ b/doc/developer-guide/coding-standard.md @@ -1,11 +1,38 @@ GlusterFS Coding Standards ========================== +Before you get started +---------------------- +Before starting with other part of coding standard, install `clang-format` + +On Fedora: +``` +$ dnf install clang +``` +On debian/Ubuntu: +``` +$ apt-get install clang +``` +Once you are done with all the local changes, you need to run below set of commands, +before submitting the patch for review. +``` +$ git add $file # if any +$ git commit -a -s -m "commit message" +$ git show --pretty="format:" --name-only | grep -v "contrib/" | egrep "*\.[ch]$" | xargs clang-format -i +$ git diff # see if there are any changes +$ git commit -a --amend # get the format changes done +$ ./submit-for-review.sh +``` + + Structure definitions should have a comment per member ------------------------------------------------------ -Every member in a structure definition must have a comment about its -purpose. The comment should be descriptive without being overly verbose. +Every member in a structure definition must have a comment about its purpose. +The comment should be descriptive without being overly verbose. For pointer +members, lifecycle concerns for the pointed-to object should be noted. For lock +members, the relationship between the lock member and the other members it +protects should be explicit. *Bad:* @@ -23,59 +50,182 @@ DBTYPE access_mode; /* access mode for accessing */ ``` -Declare all variables at the beginning of the function ------------------------------------------------------- +Structure members should be aligned based on the padding requirements +--------------------------------------------------------------------- -All local variables in a function must be declared immediately after the -opening brace. This makes it easy to keep track of memory that needs to be freed -during exit. It also helps debugging, since gdb cannot handle variables -declared inside loops or other such blocks. +The compiler will make sure that structure members have optimum alignment, +but at the expense of suboptimal padding. More important is to optimize the +padding. The compiler won't do that for you. -Always initialize local variables ---------------------------------- +This also will help utilize the memory better -Every local variable should be initialized to a sensible default value -at the point of its declaration. All pointers should be initialized to NULL, -and all integers should be zero or (if it makes sense) an error value. +*Bad:* +``` +struct bad { + bool b; /* 0 */ + /* 1..7 pad */ + void *p; /* 8..15 */ + char c; /* 16 */ + char a[16]; /* 17..33 */ + /* 34..39 pad */ + int64_t ii; /* 40..47 */ + int32_t i; /* 48..51 */ + /* 52..55 pad */ + int64_t iii; /* 56..63 */ +}; +``` +*Good:* +``` +struct good { + int64_t ii; /* explicit 64-bit types */ + void *p; /* may be 64- or 32-bit */ + long l; /* may be 64- or 32-bit */ + int i; /* 32-bit */ + short s; /* 16-bit */ + char c; /* 8-bit */ + bool b; /* 8-bit */ + char a[1024]; +); +``` +Make sure the items with the most stringent alignment requirements will need +to come earliest (ie, pointers and perhaps uint64_t etc), and those with less +stringent alignment requirements at the end (uint16/uint8 and char). Also note +that the long array (if any) should be at the end of the structure, regardless +of the type. + +Also note, if your structure's overall size is crossing 1k-4k limit, it is +recommended to mention the reason why the particular structure needs so much +memory as a comment at the top. + +Use \_typename for struct tags and typename\_t for typedefs +--------------------------------------------------------- + +Being consistent here makes it possible to automate navigation from use of a +type to its true definition (not just the typedef). + +*Bad:* + +``` +struct thing {...}; +struct thing_t {...}; +typedef struct _thing thing; +``` *Good:* ``` -int ret = 0; -char *databuf = NULL; -int _fd = -1; +typedef struct _thing {...} thing_t; ``` -Initialization should always be done with a constant value ----------------------------------------------------------- +No double underscores +--------------------- + +Identifiers beginning with double underscores are supposed to reserved for the +compiler. -Never use a non-constant expression as the initialization value for a variable. +http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf +When you need to define inner/outer functions, use a different prefix/suffix. *Bad:* ``` +void __do_something (void); + +void +do_something (void) +{ + LOCK (); + __do_something (); + UNLOCK (); +} +``` + +*Good:* + +``` +void do_something_locked (void); +``` + +Only use safe pointers in initializers +---------------------------------------------------------- + +Some pointers, such as `this` in a fop function, can be assumed to be non-NULL. +However, other parameters and further-derived values might be NULL. + +*Good:* + +``` pid_t pid = frame->root->pid; -char *databuf = malloc (1024); ``` + +*Bad:* + +``` +data_t *my_data = dict_get (xdata, "fubar"); +``` + +No giant stack allocations +-------------------------- + +Synctasks have small finite stacks. To avoid overflowing these stacks, avoid +allocating any large data structures on the stack. Use dynamic allocation +instead. + +*Bad:* + +``` +gf_boolean_t port_inuse[65536]; /* 256KB, this actually happened */ +``` + +NOTE: Ideal is to limit the stack array to less than 256 bytes. + + +Character array initializing +---------------------------- + +It is recommended to keep the character array initializing to empty string. + +*Good:* +``` +char msg[1024] = ""; +``` + +Not so much recommended, even though it means the same. + +``` +char msg[1024] = {0,}; +``` + +We recommend above to structure initialization. + + + Validate all arguments to a function ------------------------------------ All pointer arguments to a function must be checked for `NULL`. -A macro named `VALIDATE` (in `common-utils.h`) -takes one argument, and if it is `NULL`, writes a log message and -jumps to a label called `err` after setting op_ret and op_errno -appropriately. It is recommended to use this template. +A macro named `GF_VALIDATE_OR_GOTO` (in `common-utils.h`) +takes two arguments; if the first is `NULL`, it writes a log message and +jumps to a label specified by the second aergument after setting errno +appropriately. There are several variants of this function for more +specific purposes, and their use is recommended. + +*Bad:* +``` +/* top of function */ +ret = dict_get (xdata, ...) +``` *Good:* ``` -VALIDATE(frame); -VALIDATE(this); -VALIDATE(inode); +/* top of function */ +GF_VALIDATE_OR_GOTO(xdata,out); +ret = dict_get (xdata, ...) ``` Never rely on precedence of operators @@ -83,25 +233,34 @@ Never rely on precedence of operators Never write code that relies on the precedence of operators to execute correctly. Such code can be hard to read and someone else might not -know the precedence of operators as accurately as you do. +know the precedence of operators as accurately as you do. This includes +precedence of increment/decrement vs. field/subscript. The only exceptions are +arithmetic operators (which have had defined precedence since before computers +even existed) and boolean negation. *Bad:* ``` if (op_ret == -1 && errno != ENOENT) +++foo->bar /* incrementing foo, or incrementing foo->bar? */ +a && b || !c ``` *Good:* ``` if ((op_ret == -1) && (errno != ENOENT)) +(++foo)->bar +++(foo->bar) +(a && b) || !c +a && (b || !c) ``` Use exactly matching types -------------------------- Use a variable of the exact type declared in the manual to hold the -return value of a function. Do not use an ``equivalent'' type. +return value of a function. Do not use an 'equivalent' type. *Bad:* @@ -116,42 +275,56 @@ int len = strlen (path); size_t len = strlen (path); ``` -Never write code such as `foo->bar->baz`; check every pointer +Avoid code such as `foo->bar->baz`; check every pointer ------------------------------------------------------------- -Do not write code that blindly follows a chain of pointer -references. Any pointer in the chain may be `NULL` and thus -cause a crash. Verify that each pointer is non-null before following -it. +Do not write code that blindly follows a chain of pointer references. Any +pointer in the chain may be `NULL` and thus cause a crash. Verify that each +pointer is non-null before following it. Even if `foo->bar` has been checked +and is known safe, repeating it can make code more verbose and less clear. -Check return value of all functions and system calls +This rule includes `[]` as well as `->` because both dereference pointers. + +*Bad:* + +``` +foo->bar->field1 = value1; +xyz = foo->bar->field2 + foo->bar->field3 * foo->bar->field4; +foo->bar[5].baz +``` + +*Good:* + +``` +my_bar = foo->bar; +if (!my_bar) ... return; +my_bar->field1 = value1; +xyz = my_bar->field2 + my_bar->field3 * my_bar->field4; +``` + +Document unchecked return values ---------------------------------------------------- -The return value of all system calls and API functions must be checked -for success or failure. +In general, return values should be checked. If a function is being called +for its side effects and the return value really doesn't matter, an explicit +cast to void is required (to keep static analyzers happy) and a comment is +recommended. *Bad:* ``` close (fd); +do_important_thing (); ``` -*Good:* +*Good (or at least OK):* ``` -op_ret = close (_fd); -if (op_ret == -1) { - gf_log (this->name, GF_LOG_ERROR, - "close on file %s failed (%s)", real_path, - strerror (errno)); - op_errno = errno; - goto out; -} +(void) sleep (1); ``` - -Gracefully handle failure of malloc ------------------------------------ +Gracefully handle failure of malloc (and other allocation functions) +-------------------------------------------------------------------- GlusterFS should never crash or exit due to lack of memory. If a memory allocation fails, the call should be unwound and an error @@ -176,7 +349,7 @@ int32_t dict_get_int32 (dict_t *this, char *key); int dict_get_int32 (dict_t *this, char *key, int32_t *val); ``` -Always use the `n' versions of string functions +Always use the 'n' versions of string functions ----------------------------------------------- Unless impossible, use the length-limited versions of the string functions. @@ -193,18 +366,43 @@ strcpy (entry_path, real_path); strncpy (entry_path, real_path, entry_path_len); ``` +Do not use memset prior to sprintf/snprintf/vsnprintf etc... +------------------------------------------------------------ +snprintf(and other similar string functions) terminates the buffer with a +'\0'(null character). Hence, there is no need to do a memset before using +snprintf. (Of course you need to account one extra byte for the null character +in your allocation). + +Note: Similarly if you are doing pre-memory allocation for the buffer, use +GF_MALLOC instead of GF_CALLOC, since the later is bit costlier. + +*Bad:* + +``` +char buffer[x]; +memset (buffer, 0, x); +bytes_read = snprintf (buffer, sizeof buffer, "bad standard"); +``` + +*Good:* +``` +char buffer[x]; +bytes_read = snprintf (buffer, sizeof (buffer), "good standard"); +``` + +And it is always to good initialize the char array if the string is static. + +E.g. +``` +char buffer[] = "good standard"; +``` + No dead or commented code ------------------------- There must be no dead code (code to which control can never be passed) or commented out code in the codebase. -Only one unwind and return per function ---------------------------------------- - -There must be only one exit out of a function. `UNWIND` and return -should happen at only point in the function. - Function length or Keep functions small --------------------------------------- @@ -226,20 +424,35 @@ same_owner (posix_lock_t *l1, posix_lock_t *l2) } ``` -Defining functions as static ----------------------------- +Define functions as static +-------------------------- + +Declare functions as static unless they're exposed via a module-level API for +use from other modules. + +No nested functions +------------------- + +Nested functions have proven unreliable, e.g. as callbacks in code that uses +ucontext (green) threads, + +Use inline functions instead of macros whenever possible +-------------------------------------------------------- -Define internal functions as static only if you're -very sure that there will not be a crash(..of any kind..) emanating in -that function. If there is even a remote possibility, perhaps due to -pointer derefering, etc, declare the function as non-static. This -ensures that when a crash does happen, the function name shows up the -in the back-trace generated by libc. However, doing so has potential -for polluting the function namespace, so to avoid conflicts with other -components in other parts, ensure that the function names are -prepended with a prefix that identify the component to which it -belongs. For eg. non-static functions in io-threads translator start -with iot_. +Inline functions enforce type safety; macros do not. Use macros only for things +that explicitly need to be type-agnostic (e.g. cases where one might use +generics or templates in other languages), or that use other preprocessor +features such as `#` for stringification or `##` for token pasting. In general, +"static inline" is the preferred form. + +Avoid copypasta +--------------- + +Code that is copied and then pasted into multiple functions often creates +maintenance problems later, e.g. updating all but one instance for a subsequent +change. If you find yourself copying the same "boilerplate" many places, +consider refactoring to use helper functions (including inline) or macros, or +code generation. Ensure function calls wrap around after 80-columns -------------------------------------------------- @@ -335,13 +548,95 @@ pthread_mutex_lock (&mutex); pthread_mutex_unlock (&mutex); ``` -*A skeleton fop function:* +### Always use braces + +Even around single statements. + +*Bad:* + +``` +if (condition) action (); + +if (condition) + action (); +``` + +*Good:* + +``` +if (condition) { + action (); +} +``` + +### Avoid multi-line conditionals + +These can be hard to read and even harder to modify later. Predicate functions +and helper variables are always better for maintainability. + +*Bad:* + +``` +if ((thing1 && other_complex_condition (thing1, lots, of, args)) + || (!thing2 || even_more_complex_condition (thing2)) + || all_sorts_of_stuff_with_thing3) { + return; +} + +``` + +*Better:* + +``` +thing1_ok = predicate1 (thing1, lots, of, args +thing2_ok = predicate2 (thing2); +thing3_ok = predicate3 (thing3); + +if (!thing1_ok || !thing2_ok || !thing3_ok) { + return; +} +``` + +*Best:* + +``` +if (thing1 && other_complex_condition (thing1, lots, of, args)) { + return; +} +if (!thing2 || even_more_complex_condition (thing2)) { + /* Note potential for a different message here. */ + return; +} +if (all_sorts_of_stuff_with_thing3) { + /* And here too. */ + return; +} +``` + +### Use 'const' liberally + +If a value isn't supposed/expected to change, there's no cost to adding a +'const' keyword and it will help prevent violation of expectations. + +### Avoid global variables (including 'static' auto variables) +Almost all state in Gluster is contextual and should be contained in the +appropriate structure reflecting its scope (e.g. `call\_frame\_t`, `call\_stack\_t`, +`xlator\_t`, `glusterfs\_ctx\_t`). With dynamic loading and graph switches in play, +each global requires careful consideration of when it should be initialized or +reinitialized, when it might _accidentally_ be reinitialized, when its value +might become stale, and so on. A few global variables are needed to serve as +'anchor points' for these structures, and more exceptions to the rule might be +approved in the future, but new globals should not be added to the codebase +without explicit approval. + +## A skeleton fop function -This is the recommended template for any fop. In the beginning come -the initializations. After that, the `success' control flow should be -linear. Any error conditions should cause a `goto` to a single -point, `out`. At that point, the code should detect the error -that has occurred and do appropriate cleanup. +This is the recommended template for any fop. In the beginning come the +initializations. After that, the 'success' control flow should be linear. Any +error conditions should cause a `goto` to a label at the end. By convention +this is 'out' if there is only one such label, but a cascade of such labels is +allowable to support multi-stage cleanup. At that point, the code should detect +the error that has occurred and do appropriate cleanup. ``` int32_t diff --git a/doc/developer-guide/commit-guidelines.md b/doc/developer-guide/commit-guidelines.md new file mode 100644 index 00000000000..38bbe525cbd --- /dev/null +++ b/doc/developer-guide/commit-guidelines.md @@ -0,0 +1,136 @@ +## Git Commit Good Practice + +The following document is based on experience doing code development, bug troubleshooting and code review across a number of projects using Git. The document is mostly borrowed from [Open Stack](https://wiki.openstack.org/wiki/GitCommitMessages), but made more meaningful in the context of GlusterFS project. + +This topic can be split into two areas of concern + +* The structured set/split of the code changes +* The information provided in the commit message + +### Executive Summary +The points and examples that will be raised in this document ought to clearly demonstrate the value in splitting up changes into a sequence of individual commits, and the importance in writing good commit messages to go along with them. If these guidelines were widely applied it would result in a significant improvement in the quality of the GlusterFS Git history. Both a carrot & stick will be required to effect changes. This document intends to be the carrot by alerting people to the benefits, while anyone doing Gerrit code review can act as the stick ;-P + +In other words, when reviewing a change in Gerrit: +* Do not simply look at the correctness of the code. +* Review the commit message itself and request improvements to its content. +* Look out for commits which are mixing multiple logical changes and require the submitter to split them into separate commits. +* Ensure whitespace changes are not mixed in with functional changes. +* Ensure no-op code refactoring is done separately from functional changes. + +And so on. + +It might be mentioned that Gerrit's handling of patch series is not entirely perfect. Let that not become a valid reason to avoid creating patch series. The tools being used should be subservient to developers needs, and since they are open source they can be fixed / improved. Software source code is "read mostly, write occassionally" and thus the most important criteria is to improve the long term maintainability by the large pool of developers in the community, and not to sacrifice too much for the sake of the single author who may never touch the code again. + +And now the long detailed guidelines & examples of good & bad practice + +### Structural split of changes +The cardinal rule for creating good commits is to ensure there is only one "logical change" per commit. There are many reasons why this is an important rule: + +* The smaller the amount of code being changed, the quicker & easier it is to review & identify potential flaws. +* If a change is found to be flawed later, it may be necessary to revert the broken commit. This is much easier to do if there are not other unrelated code changes entangled with the original commit. +* When troubleshooting problems using Git's bisect capability, small well defined changes will aid in isolating exactly where the code problem was introduced. +* When browsing history using Git annotate/blame, small well defined changes also aid in isolating exactly where & why a piece of code came from. + +#### Things to avoid when creating commits +With the above points in mind, there are some commonly encountered examples of bad things to avoid + +* Mixing whitespace changes with functional code changes. + +The whitespace changes will obscure the important functional changes, making it harder for a reviewer to correctly determine whether the change is correct. Solution: Create 2 commits, one with the whitespace changes, one with the functional changes. Typically the whitespace change would be done first, but that need not be a hard rule. + +* Mixing two unrelated functional changes. + +Again the reviewer will find it harder to identify flaws if two unrelated changes are mixed together. If it becomes necessary to later revert a broken commit, the two unrelated changes will need to be untangled, with further risk of bug creation. + +* Sending large new features in a single giant commit. + +It may well be the case that the code for a new feature is only useful when all of it is present. This does not, however, imply that the entire feature should be provided in a single commit. New features often entail refactoring existing code. It is highly desirable that any refactoring is done in commits which are separate from those implementing the new feature. This helps reviewers and test suites validate that the refactoring has no unintentional functional changes. + +Even the newly written code can often be split up into multiple pieces that can be independently reviewed. For example, changes which add new internal fops or library functions, can be in self-contained commits. Again this leads to easier code review. It also allows other developers to cherry-pick small parts of the work, if the entire new feature is not immediately ready for merge. This will encourage the author & reviewers to think about the generic library functions' design, and not simply pick a design that is easier for their currently chosen internal implementation. + +The basic rule to follow is + +If a code change can be split into a sequence of patches/commits, then it should be split. Less is not more. More is more. + +##### Examples of bad practice + +TODO: Pick glusterfs specific example. + + +##### Examples of good practice + + +### Information in commit messages +As important as the content of the change, is the content of the commit message describing it. When writing a commit message there are some important things to remember + +* Do not assume the reviewer understands what the original problem was. + +When reading bug reports, after a number of back & forth comments, it is often as clear as mud, what the root cause problem is. The commit message should have a clear statement as to what the original problem is. The bug is merely interesting historical background on /how/ the problem was identified. It should be possible to review a proposed patch for correctness without needing to read the bug ticket. + +* Do not assume the reviewer has access to external web services/site. + +In 6 months time when someone is on a train/plane/coach/beach/pub troubleshooting a problem & browsing Git history, there is no guarantee they will have access to the online bug tracker, or online blueprint documents. The great step forward with distributed SCM is that you no longer need to be "online" to have access to all information about the code repository. The commit message should be totally self-contained, to maintain that benefit. + +* Do not assume the code is self-evident/self-documenting. + +What is self-evident to one person, might be clear as mud to another person. Always document what the original problem was and how it is being fixed, for any change except the most obvious typos, or whitespace only commits. + +* Describe why a change is being made. + +A common mistake is to just document how the code has been written, without describing /why/ the developer chose to do it that way. By all means describe the overall code structure, particularly for large changes, but more importantly describe the intent/motivation behind the changes. + +* Read the commit message to see if it hints at improved code structure. + +Often when describing a large commit message, it becomes obvious that a commit should have in fact been split into 2 or more parts. Don't be afraid to go back and rebase the change to split it up into separate commits. + +* Ensure sufficient information to decide whether to review. + +When Gerrit sends out email alerts for new patch submissions there is minimal information included, principally the commit message and the list of files changes. Given the high volume of patches, it is not reasonable to expect all reviewers to examine the patches in detail. The commit message must thus contain sufficient information to alert the potential reviewers to the fact that this is a patch they need to look at. + +* The first commit line is the most important. + +In Git commits the first line of the commit message has special significance. It is used as email subject line, git annotate messages, gitk viewer annotations, merge commit messages and many more places where space is at a premium. As well as summarizing the change itself, it should take care to detail what part of the code is affected. eg if it is 'afr', 'dht' or any translator. Or in some cases, it can be touching all these components, but the commit message can be 'coverity:', 'txn-framework:', 'new-fop: ', etc. + +* Describe any limitations of the current code. + +If the code being changed still has future scope for improvements, or any known limitations then mention these in the commit message. This demonstrates to the reviewer that the broader picture has been considered and what tradeoffs have been done in terms of short term goals vs. long term wishes. + +* Do not include patch set-specific comments. + +In other words, if you rebase your change please don't add "Patch set 2: rebased" to your commit message. That isn't going to be relevant once your change has merged. Please do make a note of that in Gerrit as a comment on your change, however. It helps reviewers know what changed between patch sets. This also applies to comments such as "Added unit tests", "Fixed localization problems", or any other such patch set to patch set changes that don't affect the overall intent of your commit. + +**The main rule to follow is:** + +The commit message must contain all the information required to fully understand & review the patch for correctness. Less is not more. More is more. + + +#### Including external references + +The commit message is primarily targeted towards human interpretation, but there is always some metadata provided for machine use. In the case of GlusterFS this includes at least the 'Change-id', "bug"/"feature" ID references and "Signed-off-by" tag (generated by 'git commit -s'). + +The 'Change-id' line is a unique hash describing the change, which is generated by a Git commit hook. This should not be changed when rebasing a commit following review feedback, since it is used by Gerrit, to track versions of a patch. + +The 'bug' line can reference a bug in a few ways. Gerrit creates a link to the bug when viewing the patch on review.gluster.org so that reviewers can quickly access the bug/issue on Bugzilla or Github. + +**Fixes: bz#1601166** -- use 'Fixes: bz#NNNNN' if the commit is intended to fully fix and close the bug being referenced. +**Fixes: #411** -- use 'Fixes: #NNN' if the patch fixes the github issue completely. + +**Updates: bz#1193929** -- use 'Updates: bz#NNNN' if the commit is only a partial fix and more work is needed. +**Updates: #175** -- use 'Updates: #NNNN' if the commit is only a partial fix and more work is needed for the feature completion. + +We encourage the use of `Co-Authored-By: name <name@example.com>` in commit messages to indicate people who worked on a particular patch. It's a convention for recognizing multiple authors, and our projects would encourage the stats tools to observe it when collecting statistics. + +### Summary of Git commit message structure + +* Provide a brief description of the change in the first line. +* The first line should be limited to 50 characters and should not end with a period. + +* Insert a single blank line after the first line. + +* Provide a detailed description of the change in the following lines, breaking paragraphs where needed. + +* Subsequent lines should be wrapped at 72 characters. + +Put the 'Change-id', 'Fixes bz#NNNNN' and 'Signed-off-by: <>' lines at the very end. + +TODO: Add good examples diff --git a/doc/developer-guide/daemon-management-framework.md b/doc/developer-guide/daemon-management-framework.md index cf29caa95ce..592192e665d 100644 --- a/doc/developer-guide/daemon-management-framework.md +++ b/doc/developer-guide/daemon-management-framework.md @@ -25,12 +25,9 @@ Data members & functions of different management objects - connection object - process object - online status - - Methods - -- manager, start, stop which can be abstracted as a common - methods or specific to service requirements - -- init API is invoked on demand of the service and currently integrated - into manager. - -- build method is to initialize the method pointers + - Methods - manager, start, stop which can be abstracted as a common methods + or specific to service requirements + - init API can be invoked using the service management object The above structures defines the skeleton of the daemon management framework. Introduction of new daemons in GlusterFS needs to inherit these properties. Any diff --git a/doc/developer-guide/data-structures/inode.md b/doc/developer-guide/datastructure-inode.md index a340ab9ca8e..45d7a941e5f 100644 --- a/doc/developer-guide/data-structures/inode.md +++ b/doc/developer-guide/datastructure-inode.md @@ -1,6 +1,6 @@ -#Inode and dentry management in GlusterFS: +# Inode and dentry management in GlusterFS: -##Background +## Background Filesystems internally refer to files and directories via inodes. Inodes are unique identifiers of the entities stored in a filesystem. Whenever an application has to operate on a file/directory (read/modify), the filesystem @@ -41,11 +41,10 @@ struct _inode_table { }; ``` -#Life-cycle +# Life-cycle ``` - inode_table_new (size_t lru_limit, xlator_t *xl) - +``` This is a function which allocates a new inode table. Usually the top xlators in the graph such as protocol/server (for bricks), fuse and nfs (for fuse and nfs mounts) and libgfapi do inode managements. Hence they are the ones which will @@ -59,11 +58,8 @@ new inode table. Thus an allocated inode table is destroyed only when the filesystem daemon is killed or unmounted. -``` - -#what it contains. -``` +# what it contains. Inode table in glusterfs mainly contains a hash table for maintaining inodes. In general a file/directory is considered to be existing if there is a corresponding inode present in the inode table. If a inode for a file/directory @@ -76,21 +72,21 @@ size of the hash table (as of now it is hard coded to 14057. The hash value of a inode is calculated using its gfid). Apart from the hash table, inode table also maintains 3 important list of inodes -1) Active list: +1. Active list: Active list contains all the active inodes (i.e inodes which are currently part of some fop). -2) Lru list: +2. Lru list: Least recently used inodes list. A limit can be set for the size of the lru list. For bricks it is 16384 and for clients it is infinity. -3) Purge list: +3. Purge list: List of all the inodes which have to be purged (i.e inodes which have to be deleted from the inode table due to unlink/rmdir/forget). And at last it also contains the mem-pool for allocating inodes, dentries so that frequent malloc/calloc and free of the data structures can be avoided. -``` -#Data structure (inode) + +# Data structure (inode) ``` struct _inode { inode_table_t *table; /* the table this inode belongs to */ @@ -108,7 +104,7 @@ struct _inode { struct _inode_ctx *_ctx; /* place holder for keeping the information about the inode by different xlators */ }; - +``` As said above, inodes are internal way of identifying the files/directories. A inode uniquely represents a file/directory. A new inode is created whenever a create/mkdir/symlink/mknod operations are performed. Apart from that a new inode @@ -128,9 +124,9 @@ inodes are those inodes whose refcount is greater than zero. Whenever some operation comes on a file/directory, and the resolver tries to find the inode for it, it increments the refcount of the inode before returning the inode. The refcount of an inode can be incremented by calling the below function - +``` inode_ref (inode_t *inode) - +``` Any xlator which wants to operate on a inode as part of some fop (or wants the inode in the callback), should hold a ref on the inode. Once the fop is completed before sending the reply of the fop to the above @@ -139,18 +135,18 @@ zero, it is removed from the active inodes list and put into LRU list maintained by the inode table. Thus in short if some fop is happening on a file/directory, the corresponding inode will be in the active list or it will be in the LRU list. -``` -#Life Cycle + +# Life Cycle A new inode is created whenever a new file/directory/symlink is created OR a successful lookup of an existing entry is done. The xlators which does inode management (as of now protocol/server, fuse, nfs, gfapi) will perform inode_link operation upon successful lookup or successful creation of a new entry. - +``` inode_link (inode_t *inode, inode_t *parent, const char *name, struct iatt *buf); - +``` inode_link actually adds the inode to the inode table (to be precise it adds the inode to the hash table maintained by the inode table. The hash value is calculated based on the gfid). Copies the gfid to the inode (the gfid is @@ -160,7 +156,7 @@ A inode is removed from the inode table and eventually destroyed when unlink or rmdir operation is performed on a file/directory, or the the lru limit of the inode table has been exceeded. -#Data structure (dentry) +# Data structure (dentry) ``` struct _dentry { @@ -170,22 +166,22 @@ struct _dentry { char *name; /* name of the directory entry */ inode_t *parent; /* directory of the entry */ }; - +``` A dentry is the presence of an entry for a file/directory within its parent directory. A dentry usually points to the inode to which it belongs to. In glusterfs a dentry contains the following fields. -1) a hook using which it can add itself to the list of +1. a hook using which it can add itself to the list of the dentries maintained by the inode to which it points to. -2) A hash table pointer. -3) Pointer to the inode to which it belongs to. -4) Name of the dentry -5) Pointer to the inode of the parent directory in which the dentry is present +2. A hash table pointer. +3. Pointer to the inode to which it belongs to. +4. Name of the dentry +5. Pointer to the inode of the parent directory in which the dentry is present A new dentry is created when a new file/directory/symlink is created or a hard link to an existing file is created. - +``` __dentry_create (inode_t *inode, inode_t *parent, const char *name); - +``` A dentry holds a refcount on the parent directory so that the parent inode is never removed from the active inode's list and put to the lru list (If the lru limit of the lru list is exceeded, there is @@ -212,15 +208,14 @@ deleted due to file removal or lru limit being exceeded the inode is retired purge list maintained by the inode table), the nlookup count is set to 0 via inode_forget api. The inode table, then prunes all the inodes from the purge list by destroying the inode contexts maintained by each xlator. - +``` unlinking of the dentry is done via inode_unlink; void inode_unlink (inode_t *inode, inode_t *parent, const char *name); - +``` If the inode has multiple hard links, then the unlink operation performed by the application results just in the removal of the dentry with the name provided by the application. For the inode to be removed, all the dentries of the inode should be unlinked. -``` diff --git a/doc/developer-guide/data-structures/iobuf.md b/doc/developer-guide/datastructure-iobuf.md index 5f521f1485f..03604e3672c 100644 --- a/doc/developer-guide/data-structures/iobuf.md +++ b/doc/developer-guide/datastructure-iobuf.md @@ -1,6 +1,6 @@ -#Iobuf-pool -##Datastructures -###iobuf +# Iobuf-pool +## Datastructures +### iobuf Short for IO Buffer. It is one allocatable unit for the consumers of the IOBUF API, each unit hosts @page_size(defined in arena structure) bytes of memory. As initial step of processing a fop, the IO buffer passed onto GlusterFS by the @@ -28,7 +28,7 @@ struct iobuf { }; ``` -###iobref +### iobref There may be need of multiple iobufs for a single fop, like in vectored read/write. Hence multiple iobufs(default 16) are encapsulated under one iobref. ``` @@ -40,7 +40,7 @@ struct iobref { int used; /* number of iobufs added to this iobref */ }; ``` -###iobuf_arenas +### iobuf_arenas One region of memory MMAPed from the operating system. Each region MMAPs @arena_size bytes of memory, and hosts @arena_size / @page_size IOBUFs. The same sized iobufs are grouped into one arena, for sanity of access. @@ -77,7 +77,7 @@ struct iobuf_arena { }; ``` -###iobuf_pool +### iobuf_pool Pool of Iobufs. As there may be many Io buffers required by the filesystem, a pool of iobufs are preallocated and kept, if these preallocated ones are exhausted only then the standard malloc/free is called, thus improving the @@ -139,8 +139,8 @@ arenas in the purge list are destroyed only if there is atleast one arena in (e.g: If there is an arena (page_size=128KB, count=32) in purge list, this arena is destroyed(munmap) only if there is an arena in 'arenas' list with page_size=128KB). -##APIs -###iobuf_get +## APIs +### iobuf_get ``` struct iobuf *iobuf_get (struct iobuf_pool *iobuf_pool); @@ -149,7 +149,7 @@ Creates a new iobuf of the default page size(128KB hard coded as of yet). Also takes a reference(increments ref count), hence no need of doing it explicitly after getting iobuf. -###iobuf_get2 +### iobuf_get2 ``` struct iobuf * iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size); @@ -179,7 +179,7 @@ if (requested iobuf size > Max iobuf size in the pool(1MB as of yet)) Also takes a reference(increments ref count), hence no need of doing it explicitly after getting iobuf. -###iobuf_ref +### iobuf_ref ``` struct iobuf *iobuf_ref (struct iobuf *iobuf); @@ -188,7 +188,7 @@ struct iobuf *iobuf_ref (struct iobuf *iobuf); xlator/function/, its a good practice to take a reference so that iobuf is not deleted by the allocator. -###iobuf_unref +### iobuf_unref ``` void iobuf_unref (struct iobuf *iobuf); ``` @@ -203,33 +203,33 @@ Unreference the iobuf, if the ref count is zero iobuf is considered free. Every iobuf_ref should have a corresponding iobuf_unref, and also every iobuf_get/2 should have a correspondning iobuf_unref. -###iobref_new +### iobref_new ``` struct iobref *iobref_new (); ``` Creates a new iobref structure and returns its pointer. -###iobref_ref +### iobref_ref ``` struct iobref *iobref_ref (struct iobref *iobref); ``` Take a reference on the iobref. -###iobref_unref +### iobref_unref ``` void iobref_unref (struct iobref *iobref); ``` Decrements the reference count of the iobref. If the ref count is 0, then unref all the iobufs(iobuf_unref) in the iobref, and destroy the iobref. -###iobref_add +### iobref_add ``` int iobref_add (struct iobref *iobref, struct iobuf *iobuf); ``` Adds the given iobuf into the iobref, it takes a ref on the iobuf before adding it, hence explicit iobuf_ref is not required if adding to the iobref. -###iobref_merge +### iobref_merge ``` int iobref_merge (struct iobref *to, struct iobref *from); ``` @@ -239,13 +239,13 @@ on all the iobufs added to the 'to' iobref. Hence iobref_unref should be performed both on 'from' and 'to' iobrefs (performing iobref_unref only on 'to' will not free the iobufs and may result in leak). -###iobref_clear +### iobref_clear ``` void iobref_clear (struct iobref *iobref); ``` Unreference all the iobufs in the iobref, and also unref the iobref. -##Iobuf Leaks +## Iobuf Leaks If all iobuf_refs/iobuf_new do not have correspondning iobuf_unref, then the iobufs are not freed and recurring execution of such code path may lead to huge memory leaks. The easiest way to identify if a memory leak is caused by iobufs diff --git a/doc/developer-guide/data-structures/mem-pool.md b/doc/developer-guide/datastructure-mem-pool.md index c71aa2a8ddd..225567cbf9f 100644 --- a/doc/developer-guide/data-structures/mem-pool.md +++ b/doc/developer-guide/datastructure-mem-pool.md @@ -1,5 +1,5 @@ -#Mem-pool -##Background +# Mem-pool +## Background There was a time when every fop in glusterfs used to incur cost of allocations/de-allocations for every stack wind/unwind between xlators because stack/frame/*_localt_t in every wind/unwind was allocated and de-allocated. Because of all these system calls in the fop path there was lot of latency and the worst part is that most of the times the number of frames/stacks active at any time wouldn't cross a threshold. So it was decided that this threshold number of frames/stacks would be allocated in the beginning of the process only once. Get one of them from the pool of stacks/frames whenever `STACK_WIND` is performed and put it back into the pool in `STACK_UNWIND`/`STACK_DESTROY` without incurring any extra system calls. The data structures are allocated only when threshold number of such items are in active use i.e. pool is in complete use.% increase in the performance once this was added to all the common data structures (inode/fd/dict etc) in xlators throughout the stack was tremendous. ## Data structure @@ -27,7 +27,7 @@ will be served from here until all the elements in the pool are in use i.e. cold }; ``` -##Life-cycle +## Life-cycle ``` mem_pool_new (data_type, unsigned long count) @@ -120,5 +120,5 @@ mem_pool_destroy (struct mem_pool *pool) Deletes this pool from the `global_list` maintained by `glusterfs-ctx` and frees all the memory allocated in `mem_pool_new`. -###How to pick pool-size +### How to pick pool-size This varies from work-load to work-load. Create the mem-pool with some random size and run the work-load. Take the statedump after the work-load is complete. In the statedump if `max_alloc` is always less than `cold_count` may be reduce the size of the pool closer to `max_alloc`. On the otherhand if there are lots of `pool-misses` then increase the `pool_size` by `max_stdalloc` to achieve better 'hit-rate' of the pool. diff --git a/doc/developer-guide/dirops-transactions-in-dht.md b/doc/developer-guide/dirops-transactions-in-dht.md new file mode 100644 index 00000000000..909a97001aa --- /dev/null +++ b/doc/developer-guide/dirops-transactions-in-dht.md @@ -0,0 +1,273 @@ +# dirops transactions in dht +Need for transactions during operations on directories arise from two +basic design elements of DHT: + + 1. A directory is created on all subvolumes of dht. Since glusterfs + associates each file-system object with an unique gfid, every + subvolume should have the same unique mapping of (path of directory, + gfid). To elaborate, + * Each subvolume should've same gfid associated with a path to + directory. + * A gfid should not be associated with more than one path in any + subvolume. + + So, entire operations like mkdir, renamedir, rmdir and creation of + directories during self-heal need to be atomic in dht. In other words, + any of these operations shouldn't begin on an inode if one of them is + already in progress on the same inode, till it completes on all + subvolumes of dht. If not, more than one of these operations + happening in parallel can break any or all of the two requirements + listed above. This is referred in the rest of the document by the + name _Atomicity during namespace operations_. + + 2. Each directory has an independent layout persisted on + subvolumes. Each subvolume contains only part of the layout relevant + to it. For performance reasons _and_ since _only_ dht has aggregated + view, this layout is cached in memory of client. To make sure dht + reads or modifies a single complete layout while parallel modifications of the layout are in progress, we need atomicity during layout modification and reading. This is referred in the rest of the document as _Atomicity during layout modification and reading_. + +Rest of the document explains how atomicity is achieved for each of +the case above. + +**Atomicity during layout modification and reading** +File operations a.k.a fops can be classified into two categories based on how they consume layout. + + - Layout writer. Setting of layout during selfheal of a directory is + layout writer of _that_ directory. + - Layout reader. + * Any entry fop like create, unlink, rename, link, symlink, + unlink, mknod, rename, mkdir, rmdir, renamedir which needs layout of the parent directory. Each of these fops are readers of layout on parent directory. + * setting of layout during mkdir of a directory is considered as + a reader of the same directory's layout. The reason for this is that + only a parallel lookup on that directory can be a competing fop that modifies the layout (Other fops need gfid of the directory which can be got only after either lookup or mkdir completes). However, healing of layout is considered as a writer and a single writer blocks all readers. + +*Algorithm* +Atomicity is achieved by locking on the inode of directory whose +layout is being modified or read. The fop used is inodelk. + - Writer acquires blocking inodelk (directory-inode, write-lock) on + all subvolumes serially. The order of subvols in which they are + locked by different clients remains constant for a directory. If locking fails on any subvolume, layout modification is abandoned. + - Reader acquires an inodelk (directory-inode, read-lock) on _any_ + one subvolume. If locking fails on a subvolume (say with + ESTALE/ENOTCONN error), locking can be tried on other subvolumes till + we get one lock. If we cannot get lock on at least one subvolume, + consistency of layout is not guaranteed. Based on the consistency + requirements of fops, they can be failed or continued. + +Reasons why writer has to lock on _all_ subvols: + + - DHT don't have a metadata server and locking is implemented by brick. So, there is no well-defined subvol/brick that can be used as an arbitrator by different clients while acquiring locks. + - readers should acquire as minimum number of locks as possible. In + other words, the algorithm aims to have less synchronization cost to + readers. + - The subvolume to which a directory hashes could be used as a + lock server. However, in the case of an entry fop like create + (/a/b/c) where we want to block modification of layout of b for the + duration of create, we would be required to acquire lock on the + subvol to which /a/b hashes. To find out the hashed-subvol of + /a/b, we would need layout of /a. Note that how there is a dependency + of locking the layouts of ancestors all the way to root. So this + locking is not preferred. Also, note that only the immediate parent + inode is available in arguments of a fop like create. + +**Atomicity during namespace operations** + + - We use locks on inode of parent directory in the namespace of + _"basename"_ during mkdir, rmdir, renamedir and directory + creation phase of self-heal. The exact fop we use is _entrylk + (parent-inode, "basename")_. + - refresh in-memory layout of parent-inode from values stored on backend + - _entrylk (parent-inode, "basename")_ is done on subvolume to which + _"basename" hashes_. So, this operation is a _reader_ of the + layout on _parent-inode_. Which means an _inodelk (parent-inode, + read-lock)_ has to be completed before _entrylk (parent-inode, + "basename")_ is issued. Both the locks have to be held till the + operation is tried on all subvolumes. If acquiring of any/all of + these locks fail, the operation should be failed. + +With the above details, algorithms for mkdir, rmdir, renamedir, +self-heal of directory are explicitly detailed below. + +**Self-heal of a directory** + + - creation of directories on subvolumes is done only during + _named-lookup_ of a directory as we need < parent-inode, + "basename" >. + - If a directory is missing on one or more subvolumes, + * acquire _inodelk (parent-inode, read-lock)_ on _any one_ of the + subvolumes. + * refresh the in-memory layout of parent-inode from values stored on backend + * acquire _entrylk (parent-inode, "basename")_ on the subvolume + to which _"basename"_ hashes. + * If any/all of the locks fail, self-heal is aborted. + * create directories on missing subvolumes. + * release _entrylk (parent-inode, "basename")_. + * release _inodelk (parent-inode, read-lock)_. + + - If layout of a directory needs healing + * acquire _inodelk (directory-inode, write-lock)_ on _all_ the + subvolumes. If locking fails on any of the subvolumes, + self-heal is aborted. Blocking Locks are acquired serially across subvolumes in a _well-defined_ order which is _constant_ across all the healers of a directory. One order could be the order in which subvolumes are stored in the array _children_ of dht xlator. + * heal the layout. + * release _inodelk (directory-inode, write-lock)_ on _all_ the + subvolumes in parallel. + * Note that healing of layout can be done in both _named_ and + _nameless_ lookups of a directory as _only directory-inode_ is needed + for healing and it is available during both. + +**mkdir (parent-inode, "basename")** + +* while creating directory across subvolumes, + + - acquire _inodelk (parent-inode, read-lock)_ on _any one_ of the + subvolumes. + - refresh in-memory layout of parent-inode from values stored on backend + - acquire _entrylk (parent-inode, "basename")_ on the subvolume to + which _"basename"_ hashes. + - If any/all of the above two locks fail, release the locks that + were acquired successfully and mkdir should be failed (as perceived by application). + - do _mkdir (parent-inode, "basename")_ on the subvolume to which + _"basename"_ hashes. If this mkdir fails, mkdir is failed. + - do _mkdir (parent-inode, "basename")_ on the remaining subvolumes. + - release _entrylk (parent-inode, "basename")_. + - release _inodelk (parent-inode, "read-lock")_. +* while setting the layout of a directory, + - acquire _inodelk (directory-inode, read-lock)_ on _any one_ of the + subvolumes. + - If locking fails, cleanup the locks that were acquired + successfully and abort layout setting. Note that we'll have a + directory without a layout till a lookup happens on the + directory. This means entry operations within this directory fail + in this time window. We can also consider failing mkdir. The + problem of dealing with a directory without layout is out of the + scope of this document. + - set the layout on _directory-inode_. + - release _inodelk (directory-inode, read-lock)_. +* Note that during layout setting we consider mkdir as a _reader_ not + _writer_, though it is setting the layout. Reasons are: + - Before any of other readers like create, link etc that operate on + this directory to happen, _gfid_ of this directory has to be + resolved. But _gfid_ is only available only if either of following + conditions are true: + * after mkdir is complete. + * a lookup on the same path happens parallel to in-progress + mkdir. + + But, on completion of any of the above two operations, layout + will be healed. So, none of the _readers_ will happen on a + directory with partial layout. + +* Note that since we've an _entrylk (parent-inode, "basename")_ for + the entire duration of (attempting) creating directories, parallel + mkdirs will no longer contend on _mkdir_ on subvolume _to which "basename" hashes_. But instead, contend on _entrylk (parent-inode, "basename")_ on the subvolume _to which "basename" hashes_. So, we can attempt the _mkdir_ in _parallel_ on all subvolumes instead of two stage mkdir on hashed first and the rest of them in parallel later. However, we need to make sure that mkdir is successful on the subvolume _to which "basename" hashes_ for mkdir to be successful (as perceived by application). In the case of failed mkdir (as perceived by application), a cleanup should be performed on all the subvolumes before _entrylk (parent-inode, "basename")_ is released. + +**rmdir (parent-inode, "basename", directory-inode)** + + - acquire _inodelk (parent-inode, read-lock)_ on _any one_ + subvolume. + - refresh in-memory layout of parent-inode from values stored on backend + - acquire _entrylk (parent-inode, "basename")_ on the subvolume to + which _"basename" hashes_. + - If any/all of the above locks fail, rmdir is failed after cleanup + of the locks that were acquired successfully. + - do _rmdir (parent-inode, "basename")_ on the subvolumes to which + _"basename" doesn't hash to_. + * If successful, continue. + * Else, + * recreate directories on those subvolumes where rmdir + succeeded. + * heal the layout of _directory-inode_. Note that this will have + same synchronization requirements as discussed during layout + healing part of the section "Directoy self-heal" above. + * release _entrylk (parent-inode, "basename")_. + * release _inodelk (parent-inode, read-lock)_. + * fail _rmdir (parent-inode, "basename")_ to application. + - do _rmdir (parent-inode, "basename")_ on the subvolume to which + _"basename" hashes_. + - If successful, continue. + - Else, Go to the failure part of _rmdir (parent-inode, "basename")_ + on subvolumes to which "basename" _doesn't hash to_. + - release _entrylk (parent-inode, "basename")_. + - release _inodelk (parent-inode, read-lock)_. + - return success to application. + +**renamedir (src-parent-inode, "src-basename", src-directory-inode, dst-parent-inode, "dst-basename", dst-directory-inode)** + + - requirement is to prevent any operation in both _src-namespace_ + and _dst-namespace_. So, we need to acquire locks on both + namespaces.We also need to have constant ordering while acquiring + locks during parallel renames of the form _rename (src, dst)_ and + _rename (dst, src)_ to prevent deadlocks. We can sort gfids of + _src-parent-inode_ and _dst-parent-inode_ and use that order to + acquire locks. For the sake of explanation lets say we ended up + with order of _src_ followed by _dst_. + - acquire _inodelk (src-parent-inode, read-lock)_. + - refresh in-memory layout of src-parent-inode from values stored on backend + - acquire _entrylk (src-parent-inode, "src-basename")_. + - acquire _inodelk (dst-parent-inode, read-lock)_. + - refresh in-memory layout of dst-parent-inode from values stored on backend + - acquire _entrylk (dst-parent-inode, "dst-basename")_. + - If acquiring any/all of the locks above fail, + * release the locks that were successfully acquired. + * fail the renamedir operation to application + * done + - do _renamedir ("src", "dst")_ on the subvolume _to which "dst-basename" hashes_. + * If failure, Goto point _If acquiring any/all of the locks above fail_. + * else, continue. + - do _renamedir ("src", "dst")_ on rest of the subvolumes. + * If there is any failure, + * revert the successful renames. + * Goto to point _If acquiring any/all of the locks above fail_. + * else, + - release all the locks acquired. + - return renamedir as success to application. + +**Some examples of races** +This section gives concrete examples of races that can result in inconsistencies explained in the beginning of the document. + +Some assumptions are: + +* We consider an example distribute of three subvols s1, s2 and s3. +* For examples of renamedir ("src", "dst"), _src_ hashes to s1 and _dst_ hashes to s2. _src_ and _dst_ are associated with _gfid-src_ and _gfid-dst_ respectively +* For non renamedir examples, _dir_ is the name of directory and it hashes to s1. + +And the examples are: + + - mkdir vs rmdir - inconsistency in namespace. + * mkdir ("dir", gfid1) is complete on s1 + * rmdir is issued on same directory. Note that, since rmdir needs a gfid, a lookup should be complete before rmdir. lookup creates the directory on rest of the subvols as part of self-heal. + * rmdir (gfid1) deletes directory from all subvols. + * A new mkdir ("dir", gfid2) is issued. It is successful on s1 associating "dir" with gfid2. + * mkdir ("dir", gfid1) resumes and creates directory on s2 and s3 associating "dir" with gfid1. + * mkdir ("dir", gfid2) fails with EEXIST on s2 and s3. Since, EEXIST errors are ignored, mkdir is considered successful to application. + * In this example we have multiple inconsitencies + * "dir" is associated with gfid1 on s2, s3 and with gfid2 on s1 + * Even if mkdir ("dir", gfid2) was not issued, we would've a case of a directory magically reappearing after a successful rmdir. + - lookup heal vs rmdir + * rmdir ("dir", gfid1) is issued. It is successful on s2 and s3 (non-hashed subvols for name "dir") + * lookup ("dir") is issued. Since directory is present on s1 yet, it is created on s2 and s3 associating with gfid1 as part of self-heal + * rmdir ("dir", gfid1) is complete on s1 and it is successful + * Another lookup ("dir") creates the directory on s1 too + * "dir" magically reappears after a successful rmdir + - lookup heal (src) vs renamedir ("src", "dst") + * renamedir ("src", "dst") complete on s2 + * lookup ("src") recreates _src_ with _gfid-src_ on s2 + * renamedir ("src", "dst") completes on s1, s3. After rename is complete path _dst_ will be associated with gfid _gfid-src_ + * Another lookup ("src") recreates _src_ on subvols s1 and s3, associating it with gfid _gfid-src_ + * Inconsistencies are + * after a successful renamedir ("src", "dst"), both src and dst exist + * Two directories - src and dst - are associated with same gfid. One common symptom is that some entries (of the earlier _src_ and current _dst_ directory) being missed out in readdir listing as the gfid handle might be pointing to the empty healed directory than the actual directory containing entries + - lookup heal (dst) vs renamedir ("src", "dst") + * dst exists and empty when renamdir started + * dst doesn't exist when renamedir started + - renamedir ("src", "dst") complete on s2 and s3 + - lookup ("dst") creates _dst_ associating it with _gfid-src_ on s1 + - An entry is created in _dst_ on either s1 + - renamedir ("src", "dst") on s1 will result in a directory _dst/dst_ as _dst_ is no longer empty and _man 2 rename_ states that if _dst_ is not empty, _src_ is renamed _as a subdirectory of dst_ + - A lookup ( _dst/dst_) creates _dst/dst_ on s2 and s3 associating with _gfid-src_ as part of self-heal + - Inconsistencies are: + * Two directories - _dst_ and _dst/dst_ - exist even though both of them didn't exist at the beginning of renamedir + * Both _dst_ and _dst/dst_ have same gfid - _gfid-src_. As observed earlier, symptom might be directory listing being incomplete + - mkdir (dst) vs renamedir ("src", "dst") + - rmdir (src) vs renamedir ("src", "dst") + - rmdir (dst) vs renamedir ("src", "dst") diff --git a/doc/developer-guide/ec-implementation.md b/doc/developer-guide/ec-implementation.md new file mode 100644 index 00000000000..77e62583caa --- /dev/null +++ b/doc/developer-guide/ec-implementation.md @@ -0,0 +1,588 @@ +Erasure coding implementation +============================= + +This document provides information about how [erasure code][1] has +been implemented into ec translator. It describes the algorithm used +and the optimizations made, but it doesn't contain a full description +of the mathematical background needed to understand erasure coding in +general. It either describes the other parts of ec not directly +related to the encoding/decoding procedure, like synchronization or +fop management. + + +Introduction +------------ + +EC is based on [Reed-Solomon][2] erasure code. It's a very old code. +It's not considered the best one nowadays, but is good enough and it's +one of the few codes that is not covered by any patent and can be +freely used. + +To define the Reed-Solomon code we use 3 parameters: + + * __Key fragments (K)__ + It represents the minimum number of healthy fragments that will be + needed to be able to recover the original data. Any subset of K + out of the total number of fragments will serve. + + * __Redundancy fragments (R)__ + It represents the number of extra fragments to compute for each + original data block. This value determines how many fragments can + be lost before being unable to recover the original data. + + * __Fragment size (S)__ + This determines the size of each fragment. The original data + block size is computed as S * K. Currently this values is fixed + to 512 bytes. + + * __Total number of fragments (N = K + R)__ + This isn't a real parameter but it will be useful to simplify + the following descriptions. + +From the point of view of the implementation, it only consists on +matrix multiplications. There are two kinds of matrices to use for +Reed-Solomon: + + * __[Systematic][3]__ + This kind of matrix has the particularity that K of the encoded + fragments are simply a copy of the original data, divided into K + pieces. Thus no real encoding needs to be done for them and only + the R redundancy fragments need to be computed. + + This kind of matrices contain one KxK submatrix that is the + [identity matrix][4]. + + * __Non-systematic__ + This kind of matrix doesn't contain an identity submatrix. This + means that all of the N fragments need to be encoded, requiring + more computation. On the other hand, these matrices have some nice + properties that allow faster implementations of some algorithms, + like the matrix inversion used to decode the data. + + Another advantage of non-systematic matrices is that the decoding + time is constant, independently of how many fragments are lost, + while systematic approach can suffer from performance degradation + when one fragment is lost. + +All non-systematic matrices can be converted to systematic ones, but +then we lose the good properties of the non-systematic. We have to +choose betwee best peek performance (systematic) and performance +stability (non-systematic). + + +Encoding procedure +------------------ + +To encode a block of data we need a KxN matrix where each subset of K +rows is [linearly independent][5]. In other words, the determinant of +each KxK submatrix is not 0. + +There are some known ways to obtain this kind of matrices. EC uses a +small variation of a matrix known as [Vandermonde Matrix][6] where +each element of the matrix is defined as: + + a(i, j) = i ^ (K - j) + + where i is the row from 1 to N, and j is the column from 1 to K. + +This is exactly the Vandermonde Matrix but with the elements of each +row in reverse order. This change is made to be able to implement a +small optimization in the matrix multiplication. + +Once we have the matrix, we only need to compute the multiplication +of this matrix by a vector composed of K elements of data coming from +the original data block. + + / \ / \ + | 1 1 1 1 1 | / \ | a + b + c + d + e = t | + | 16 8 4 2 1 | | a | | 16a + 8b + 4c + 2d + e = u | + | 81 27 9 3 1 | | b | = | 81a + 27b + 9c + 3d + e = v | + | 256 64 16 4 1 | * | c | | 256a + 64b + 16c + 4d + e = w | + | 625 125 25 5 1 | | d | | 625a + 125b + 25c + 5d + e = x | + | 1296 216 36 6 1 | | e | | 1296a + 216b + 36c + 6d + e = y | + | 2401 343 49 7 1 | \ / | 2401a + 343b + 49c + 7d + e = z | + \ / \ / + +The optimization that can be done here is this: + + 16a + 8b + 4c + 2d + e = 2(2(2(2a + b) + c) + d) + e + +So all the multiplications are always by the number of the row (2 in +this case) and we don't need temporal storage for intermediate +results: + + a *= 2 + a += b + a *= 2 + a += c + a *= 2 + a += d + a *= 2 + a += e + +Once we have the result vector, each element is a fragment that needs +to be stored in a separate place. + + +Decoding procedure +------------------ + +To recover the data we need exactly K of the fragments. We need to +know which K fragments we have (i.e. the original row number from +which each fragment was calculated). Once we have this data we build +a square KxK matrix composed by the rows corresponding to the given +fragments and invert it. + +With the inverted matrix, we can recover the original data by +multiplying it with the vector composed by the K fragments. + +In our previous example, if we consider that we have recovered +fragments t, u, v, x and z, corresponding to rows 1, 2, 3, 5 and 7, +we can build the following matrix: + + / \ + | 1 1 1 1 1 | + | 16 8 4 2 1 | + | 81 27 9 3 1 | + | 625 125 25 5 1 | + | 2401 343 49 7 1 | + \ / + +And invert it: + + / \ + | 1/48 -1/15 1/16 -1/48 1/240 | + | -17/48 16/15 -15/16 13/48 -11/240 | + | 101/48 -86/15 73/16 -53/48 41/240 | + | -247/48 176/15 -129/16 83/48 -61/240 | + | 35/8 -7 35/8 -7/8 1/8 | + \ / + +Multiplying it by the vector (t, u, v, x, z) we recover the original +data (a, b, c, d, e): + + / \ / \ / \ + | 1/48 -1/15 1/16 -1/48 1/240 | | t | | a | + | -17/48 16/15 -15/16 13/48 -11/240 | | u | | b | + | 101/48 -86/15 73/16 -53/48 41/240 | * | v | = | c | + | -247/48 176/15 -129/16 83/48 -61/240 | | x | | d | + | 35/8 -7 35/8 -7/8 1/8 | | z | | e | + \ / \ / \ / + + +Galois Field +------------ + +This encoding/decoding procedure is quite complex to compute using +regular mathematical operations and it's not well suited for what +we want to do (note that matrix elements can grow unboundly). + +To solve this problem, exactly the same procedure is done inside a +[Galois Field][7] of characteristic 2, which is a finite field with +some interesting properties that make it specially useful for fast +operations using computers. + +There are two main differences when we use this specific Galois Field: + + * __All regular additions are replaced by bitwise xor's__ + For todays computers it's not really faster to execute an xor + compared to an addition, however replacing additions by xor's + inside a multiplication has many advantages (we will make use of + this to optimize the multiplication). + + Another consequence of this change is that additions and + substractions are really the same xor operation. + + * __The elements of the matrix are bounded__ + The field uses a modulus that keep all possible elements inside + a delimited region, avoiding really big numbers and fixing the + number of bits needed to represent each value. + + In the current implementation EC uses 8 bits per field element. + +It's very important to understand how multiplications are computed +inside a Galois Field to be able to understand how has it been +optimized. + +We'll start with a simple 'old school' multiplication but in base 2. +For example, if we want to multiply 7 * 5 (111b * 101b in binary), we +do the following: + + 1 1 1 (= 7) + * 1 0 1 (= 5) + ----------- + 1 1 1 (= 7) + + 0 0 0 (= 0) + + 1 1 1 (= 7) + ----------- + 1 0 0 0 1 1 (= 35) + +This is quite simple. Note that the addition of the third column +generates a carry that is propagated to all the other left columns. + +The next step is to define the modulus of the field. Suppose we use +11 as the modulus. Then we convert the result into an element of the +field by dividing by the modulus and taking the residue. We also use +the 'old school' method in binary: + + + 1 0 0 0 1 1 (= 35) | 1 0 1 1 (= 11) + - 0 0 0 0 ---------------- + --------- 0 1 1 (= 3) + 1 0 0 0 1 + - 1 0 1 1 + ----------- + 0 0 1 1 0 1 + - 1 0 1 1 + ------------- + 0 0 1 0 (= 2) + +So, 7 * 5 in a field with modulus 11 is 2. Note that the main +objective in each iteration of the division is to make higher bits +equal to 0 when possible (if it's not possible in one iteration, it +will be zeroed on the next). + +If we do the same but changing additions with xors we get this: + + 1 1 1 (= 7) + * 1 0 1 (= 5) + ----------- + 1 1 1 (= 7) + x 0 0 0 (= 0) + x 1 1 1 (= 7) + ----------- + 1 1 0 1 1 (= 27) + +In this case, the xor of the third column doesn't generate any carry. + +Now we need to divide by the modulus. We can also use 11 as the +modulus since it still satisfies the needed conditions to work on a +Galois Field of characteristic 2 with 3 bits: + + 1 1 0 1 1 (= 27) | 1 0 1 1 (= 11) + x 1 0 1 1 ---------------- + --------- 1 1 1 (= 7) + 0 1 1 0 1 + x 1 0 1 1 + ----------- + 0 1 1 0 1 + x 1 0 1 1 + ------------- + 0 1 1 0 (= 6) + +Note that, in this case, to make zero the higher bit we need to +consider the result of the xor operation, not the addition operation. + +So, 7 * 5 in a Galois Field of 3 bits with modulus 11 is 6. + + +Optimization +------------ + +To compute all these operations in a fast way some methods have been +traditionally used. Maybe the most common is the [lookup table][8]. + +The problem with this method is that it requires 3 lookups for each +byte multiplication, greatly amplifying the needed memory bandwidth +and making it difficult to take advantage of any SIMD support on the +processor. + +What EC does to improve the performance is based on the following +property (using the 3 bits Galois Field of the last example): + + A * B mod N = (A * b{2} * 4 mod N) x + (A * b{1} * 2 mod N) x + (A * b{0} mod N) + +This is basically a rewrite of the steps made in the previous example +to multiply two numbers but moving the modulus calculation inside each +intermediate result. What we can see here is that each term of the +xor can be zeroed if the corresponding bit of B is 0, so we can ignore +that factor. If the bit is 1, we need to compute A multiplied by a +power of two and take the residue of the division by the modulus. We +can precompute these values: + + A0 = A (we don't need to compute the modulus here) + A1 = A0 * 2 mod N + A2 = A1 * 2 mod N + +Having these values we only need to add those corresponding to bits +set to 1 in B. Using our previous example: + + A = 1 1 1 (= 7) + B = 1 0 1 (= 5) + + A0 = 1 1 1 (= 7) + A1 = 1 1 1 * 1 0 mod 1 0 1 1 = 1 0 1 (= 5) + A2 = 1 0 1 * 1 0 mod 1 0 1 1 = 0 0 1 (= 1) + + Since only bits 0 and 2 are 1 in B, we add A0 and A2: + + A0 + A2 = 1 1 1 x 0 0 1 = 1 1 0 (= 6) + +If we carefully look at what we are doing when computing each Ax, we +see that we do two basic things: + + - Shift the original value one bit to the left + - If the highest bit is 1, xor with the modulus + +Let's write this in a detailed way (representing each bit): + + Original value: a{2} a{1} a{0} + Shift 1 bit: a{2} a{1} a{0} 0 + + If a{2} is 0 we already have the result: + a{1} a{0} 0 + + If a{2} is 1 we need to xor with the modulus: + 1 a{1} a{0} 0 x 1 0 1 1 = a{1} (a{0} x 1) 1 + +An important thing to see here is that if a{2} is 0, we can get the +same result by xoring with all 0 instead of the modulus. For this +reason we can rewrite the modulus as this: + + Modulus: a{2} 0 a{2} a{2} + +This means that the modulus will be 0 0 0 0 is a{2} is 0, so the value +won't change, and it will be 1 0 1 1 if a{2} is 1, giving the correct +result. So, the computation is simply: + + Original value: a{2} a{1} a{0} + Shift 1 bit: a{2} a{1} a{0} 0 + Apply modulus: a{1} (a{0} x a{2}) a{2} + +We can compute all Ax using this method. We'll get this: + + A0 = a{2} a{1} a{0} + A1 = a{1} (a{0} x a{2}) a{2} + A2 = (a{0} x a{2}) (a{1} x a{2}) a{1} + +Once we have all terms, we xor the ones corresponding to the bits set +to 1 in B. In out example this will be A0 and A2: + + Result: (a{2} x a{0} x a{2}) (a{1} x a{1} x a{2}) (a{0} x a{1}) + +We can easily see that we can remove some redundant factors: + + Result: a{0} a{2} (a{0} x a{1}) + +This way we have come up with a simply set of equations to compute the +multiplication of any number by 5. If A is 1 1 1 (= 7), the result +must be 1 1 0 (= 6) using the equations, as we expected. If we try +another numbe for A, like 0 1 0 (= 2), the result must be 0 0 1 (= 1). + +This seems a really fast way to compute the multiplication without +using any table lookup. The problem is that this is only valid for +B = 5. For other values of B another set of equations will be found. +To solve this problem we can pregenerate the equations for all +possible values of B. Since the Galois Field we use is small, this is +feasible. + +One thing to be aware of is that, in general, two equations for +different bits of the same B can share common subexpressions. This +gives space for further optimizations to reduce the total number of +xors used in the final equations for a given B. However this is not +easy to find, since finding the smallest number of xors that give the +correct result is an NP-Problem. For EC an exhaustive search has been +made to find the best combinations for each possible value. + + +Implementation +-------------- + +All this seems great from the hardware point of view, but implementing +this using normal processor instructions is not so easy because we +would need a lot of shifts, ands, xors and ors to move the bits of +each number to the correct position to compute the equation and then +another shift to put each bit back to its final place. + +For example, to implement the functions to multiply by 5, we would +need something like this: + + Bit 2: T2 = (A & 1) << 2 + Bit 1: T1 = (A & 4) >> 1 + Bit 0: T0 = ((A >> 1) x A) & 1 + Result: T2 + T1 + T0 + +This doesn't look good. So here we make a change in the way we get +and process the data: instead of reading full numbers into variables +and operate with them afterwards, we use a single independent variable +for each bit of the number. + +Assume that we can read and write independent bits from memory (later +we'll see how to solve this problem when this is not possible). In +this case, the code would look something like this: + + Bit 2: T2 = Mem[2] + Bit 1: T1 = Mem[1] + Bit 0: T0 = Mem[0] + Computation: T1 ^= T0 + Store result: Mem[2] = T0 + Mem[1] = T2 + Mem[0] = T1 + +Note that in this case we handle the final reordering of bits simply +by storing the right variable to the right place, without any shifts, +ands nor ors. In fact we only have memory loads, memory stores and +xors. Note also that we can do all the computations directly using the +variables themselves, without additional storage. This true for most +of the values, but in some cases an additional one or two temporal +variables will be needed to store intermediate results. + +The drawback of this approach is that additions, that are simply a +xor of two numbers will need as many xors as bits are in each number. + + +SIMD optimization +----------------- + +So we have a good way to compute the multiplications, but even using +this we'll need several operations for each byte of the original data. +We can improve this by doing multiple multiplications using the same +set of instructions. + +With the approach taken in the implementation section, we can see that +in fact it's really easy to add SIMD support to this method. We only +need to store in each variable one bit from multiple numbers. For +example, when we load T2 from memory, instead of reading the bit 2 of +the first number, we can read the bit 2 of the first, second, third, +fourth, ... numbers. The same can be done when loading T1 and T0. + +Obviously this needs to have a special encoding of the numbers into +memory to be able to do that in a single operation, but since we can +choose whatever encoding we want for EC, we have chosen to have +exactly that. We interpret the original data as a stream of bits, and +we split it into subsequences of length L, each containing one bit of +a number. Every S subsequences form a set of numbers of S bits that +are encoded and decoded as a single group. This repeats for any +remaining data. + +For example, in a simple case with L = 8 and S = 3, the original data +would contain something like this (interpreted as a sequence of bits, +offsets are also bit-based): + + Offset 0: a{0} b{0} c{0} d{0} e{0} f{0} g{0} h{0} + Offset 8: a{1} b{1} c{1} d{1} e{1} f{1} g{1} h{1} + Offset 16: a{2} b{2} c{2} d{2} e{2} f{2} g{2} h{2} + Offset 24: i{0} j{0} k{0} l{0} m{0} n{0} o{0} p{0} + Offset 32: i{1} j{1} k{1} l{1} m{1} n{1} o{1} p{1} + Offset 40: i{2} j{2} k{2} l{2} m{2} n{2} o{2} p{2} + +Note: If the input file is not a multiple of S * L, 0-padding is done. + +Here we have 16 numbers encoded, from A to P. This way we can easily +see that reading the first byte of the file will read all bits 0 of +number A, B, C, D, E, F, G and H. The same happens with bits 1 and 2 +when we read the second and third bytes respectively. Using this +encoding and the implementation described above, we can see that the +same set of instructions will be computing the multiplication of 8 +numbers at the same time. + +This can be further improved if we use L = 64 with 64 bits variables +on 64-bits processor. It's even faster if we use L = 128 using SSE +registers or L = 256 using AVX registers on Intel processors. + +Currently EC uses L = 512 and S = 8. This means that numbers are +packed in blocks of 512 bytes and gives space for even bigger +processor registers up to 512 bits. + + +Conclusions +----------- + +This method requires a single variable/processor register for each +bit. This can be challenging if we want to avoid additional memory +accesses, even if we use modern processors that have many registers. +However, the implementation we chose for the Vandermonde Matrix +doesn't require temporary storage, so we don't need a full set of 8 +new registers (one for each bit) to store partial computations. +Additionally, the computation of the multiplications requires, at +most, 2 extra registers, but this is afordable. + +Xors are a really fast operation in modern processors. Intel CPU's +can dispatch up to 3 xors per CPU cycle if there are no dependencies +with ongoing previous instructions. Worst case is 1 xor per cycle. So, +in some configurations, this method could be very near to the memory +speed. + +Another interesting thing of this method is that all data it needs to +operate is packed in small sequential blocks of memory, meaning that +it can take advantage of the faster internal CPU caches. + + +Results +------- + +For the particular case of 8 bits, EC can compute each multiplication +using 12.8 xors on average (without counting 0 and 1 that do not +require any xor). Some numbers require less, like 2 that only requires +3 xors. + +Having all this, we can check some numbers to see the performance of +this method. + +Maybe the most interesting thing is the average number of xors needed +to encode a single byte of data. To compute this we'll need to define +some variables: + + * K: Number of data fragments + * R: Number of redundancy fragments + * N: K + R + * B: Number of bits per number + * A: Average number of xors per number + * Z: Bits per CPU register (can be up to 256 for AVX registers) + * X: Average number of xors per CPU cycle + * L: Average cycles per load + * S: Average cycles per store + * G: Core speed in Hz + +_Total number of bytes processed for a single matrix multiplication_: + + * __Read__: K * B * Z / 8 + * __Written__: N * B * Z / 8 + +_Total number of memory accesses_: + + * __Loads__: K * B * N + * __Stores__: B * N + +> We need to read the same K * B * Z bits, in registers of Z bits, N +> times, one for each row of the matrix. However the last N - 1 reads +> could be made from the internal CPU caches if conditions are good. + +_Total number of operations_: + + * __Additions__: (K - 1) * N + * __Multiplications__: K * N + +__Total number of xors__: B * (K - 1) * N + A * K * N = + N * ((A + B) * K - B) + +__Xors per byte__: 8 * N * ((A + B) * K - B) / (K * B * Z) + +__CPU cycles per byte__: 8 * N * ((A + B) * K - B) / (K * B * Z * X) + + 8 * L * N / Z + (loads) + 8 * S * N / (K * Z) (stores) + +__Bytes per second__: G / {CPU cycles per byte} + +Some xors per byte numbers for specific configurations (B=8): + + Z=64 Z=128 Z=256 + K=2/R=1 0.79 0.39 0.20 + K=4/R=2 1.76 0.88 0.44 + K=4/R=3 2.06 1.03 0.51 + K=8/R=3 3.40 1.70 0.85 + K=8/R=4 3.71 1.86 0.93 + K=16/R=4 6.34 3.17 1.59 + + + +[1]: https://en.wikipedia.org/wiki/Erasure_code +[2]: https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction +[3]: https://en.wikipedia.org/wiki/Systematic_code +[4]: https://en.wikipedia.org/wiki/Identity_matrix +[5]: https://en.wikipedia.org/wiki/Linear_independence +[6]: https://en.wikipedia.org/wiki/Vandermonde_matrix +[7]: https://en.wikipedia.org/wiki/Finite_field +[8]: https://en.wikipedia.org/wiki/Finite_field_arithmetic#Implementation_tricks diff --git a/doc/developer-guide/fuse-interrupt.md b/doc/developer-guide/fuse-interrupt.md new file mode 100644 index 00000000000..ec991b81ec5 --- /dev/null +++ b/doc/developer-guide/fuse-interrupt.md @@ -0,0 +1,211 @@ +# Fuse interrupt handling + +## Conventions followed + +- *FUSE* refers to the "wire protocol" between kernel and userspace and + related specifications. +- *fuse* refers to the kernel subsystem and also to the GlusterFs translator. + +## FUSE interrupt handling spec + +The [Linux kernel FUSE documentation](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/fuse.txt?h=v4.18#n148) +desrcibes how interrupt handling happens in fuse. + +## Interrupt handling in the fuse translator + +### Declarations + +This document describes the internal API in the fuse translator with which +interrupt can be handled. + +The API being internal (to be used only in fuse-bridge.c; the functions are +not exported to a header file). + +``` +enum fuse_interrupt_state { + /* ... */ + INTERRUPT_SQUELCHED, + INTERRUPT_HANDLED, + /* ... */ +}; +typedef enum fuse_interrupt_state fuse_interrupt_state_t; +struct fuse_interrupt_record; +typedef struct fuse_interrupt_record fuse_interrupt_record_t; +typedef void (*fuse_interrupt_handler_t)(xlator_t *this, + fuse_interrupt_record_t *); +struct fuse_interrupt_record { + fuse_in_header_t fuse_in_header; + void *data; + /* + ... + */ +}; + +fuse_interrupt_record_t * +fuse_interrupt_record_new(fuse_in_header_t *finh, + fuse_interrupt_handler_t handler); + +void +fuse_interrupt_record_insert(xlator_t *this, fuse_interrupt_record_t *fir); + +gf_boolean_t +fuse_interrupt_finish_fop(call_frame_t *frame, xlator_t *this, + gf_boolean_t sync, void **datap); + +void +fuse_interrupt_finish_interrupt(xlator_t *this, fuse_interrupt_record_t *fir, + fuse_interrupt_state_t intstat, + gf_boolean_t sync, void **datap); +``` + +The code demonstrates the usage of the API through `fuse_flush()`. (It's a +dummy implementation only for demonstration purposes.) Flush is chosen +because a `FLUSH` interrupt is easy to trigger (see +*tests/features/interrupt.t*). Interrupt handling for flush is switched on +by `--fuse-flush-handle-interrupt` (a hidden glusterfs command line flag). +The implementation of flush interrupt is contained in the +`fuse_flush_interrupt_handler()` function and blocks guarded by the + +``` +if (priv->flush_handle_interrupt) { ... +``` + +conditional (where `priv` is a `*fuse_private_t`). + +### Overview + +"Regular" fuse fops and interrupt handlers interact via a list containing +interrupt records. + +If a fop wishes to have its interrupts handled, it needs to set up an +interrupt record and insert it into the list; also when it's to finish +(ie. in its "cbk" stage) it needs to delete the record from the list. + +If no interrupt happens, basically that's all to it - a list insertion +and deletion. + +However, if an interrupt comes for the fop, the interrupt FUSE request +will carry the data identifying an ongoing fop (that is, its `unique`), +and based on that, the interrupt record will be looked up in the list, and +the specific interrupt handler (a member of the interrupt record) will be +called. + +Usually the fop needs to share some data with the interrupt handler to +enable it to perform its task (also shared via the interrupt record). +The interrupt API offers two approaches to manage shared data: +- _Async or reference-counting strategy_: from the point on when the interrupt + record is inserted to the list, it's owned jointly by the regular fop and + the prospective interrupt handler. Both of them need to check before they + return if the other is still holding a reference; if not, then they are + responsible for reclaiming the shared data. +- _Sync or borrow strategy_: the interrupt handler is considered a borrower + of the shared data. The interrupt handler should not reclaim the shared + data. The fop will wait for the interrupt handler to finish (ie., the borrow + to be returned), then it has to reclaim the shared data. + +The user of the interrupt API need to call the following functions to +instrument this control flow: +- `fuse_interrupt_record_insert()` in the fop to insert the interrupt record to + the list; +- `fuse_interrupt_finish_fop()`in the fop (cbk) and +- `fuse_interrupt_finish_interrupt()`in the interrupt handler + +to perform needed synchronization at the end their tenure. The data management +strategies are implemented by the `fuse_interrupt_finish_*()` functions (which +have an argument to specify which strategy to use); these routines take care +of freeing the interrupt record itself, while the reclamation of the shared data +is left to the API user. + +### Usage + +A given FUSE fop can be enabled to handle interrupts via the following +steps: + +- Define a handler function (of type `fuse_interrupt_handler_t`). + It should implement the interrupt handling logic and in the end + call (directly or as async callback) `fuse_interrupt_finish_interrupt()`. + The `intstat` argument to `fuse_interrupt_finish_interrupt` should be + either `INTERRUPT_SQUELCHED` or `INTERRUPT_HANDLED`. + - `INTERRUPT_SQUELCHED` means that the interrupt could not be delivered + and the fop is going on uninterrupted. + - `INTERRUPT_HANDLED` means that the interrupt was actually handled. In + this case the fop will be answered from interrupt context with errno + `EINTR` (that is, the fop should not send a response to the kernel). + + (the enum `fuse_interrupt_state` includes further members, which are reserved + for internal use). + + We return to the `sync` and `datap` arguments later. +- In the `fuse_<FOP>` function create an interrupt record using + `fuse_interrupt_record_new()`, passing the incoming `fuse_in_header` and + the above handler function to it. + - Arbitrary further data can be referred to via the `data` member of the + interrupt record that is to be passed on from fop context to + interrupt context. +- When it's set up, pass the interrupt record to + `fuse_interrupt_record_insert()`. +- In `fuse_<FOP>_cbk` call `fuse_interrupt_finish_fop()`. + - `fuse_interrupt_finish_fop()` returns a Boolean according to whether the + interrupt was handled. If it was, then the FUSE request is already + answered and the stack gets destroyed in `fuse_interrupt_finish_fop` so + `fuse_<FOP>_cbk()` can just return (zero). Otherwise follow the standard + cbk logic (answer the FUSE request and destroy the stack -- these are + typically accomplished by `fuse_err_cbk()`). +- The last two argument of `fuse_interrupt_finish_fop()` and + `fuse_interrupt_finish_interrupt()` are `gf_boolean_t sync` and + `void **datap`. + - `sync` represents the strategy for freeing the interrupt record. The + interrupt handler and the fop handler are in race to get at the interrupt + record first (interrupt handler for purposes of doing the interrupt + handling, fop handler for purposes of deactivating the interrupt record + upon completion of the fop handling). + - If `sync` is true, then the fop handler will wait for the interrupt + handler to finish and it takes care of freeing. + - If `sync` is false, the loser of the above race will perform freeing. + + Freeing is done within the respective interrupt finish routines, except + for the `data` field of the interrupt record; with respect to that, see + the discussion of the `datap` parameter below. The strategy has to be + consensual, that is, `fuse_interrupt_finish_fop()` and + `fuse_interrupt_finish_interrupt()` must pass the same value for `sync`. + If dismantling the resources associated with the interrupt record is + simple, `sync = _gf_false` is the suggested choice; `sync = _gf_true` can + be useful in the opposite case, when dismantling those resources would + be inconvenient to implement in two places or to enact in non-fop context. + - If `datap` is `NULL`, the `data` member of the interrupt record will be + freed within the interrupt finish routine. If it points to a valid + `void *` pointer, and if caller is doing the cleanup (see `sync` above), + then that pointer will be directed to the `data` member of the interrupt + record and it's up to the caller what it's doing with it. + - If `sync` is true, interrupt handler can use `datap = NULL`, and + fop handler will have `datap` point to a valid pointer. + - If `sync` is false, and handlers pass a pointer to a pointer for + `datap`, they should check if the pointed pointer is NULL before + attempting to deal with the data. + +### FUSE answer for the interrupted fop + +The kernel acknowledges a successful interruption for a given FUSE request +if the filesystem daemon answers it with errno EINTR; upon that, the syscall +which induced the request will be abruptly terminated with an interrupt, rather +than returning a value. + +In glusterfs, this can be arranged in two ways. + +- If the interrupt handler wins the race for the interrupt record, ie. + `fuse_interrupt_finish_fop()` returns true to `fuse_<FOP>_cbk()`, then, as + said above, `fuse_<FOP>_cbk()` does not need to answer the FUSE request. + That's because then the interrupt handler will take care about answering + it (with errno EINTR). +- If `fuse_interrupt_finish_fop()` returns false to `fuse_<FOP>_cbk()`, then + this return value does not inform the fop handler whether there was an interrupt + or not. This return value occurs both when fop handler won the race for the + interrupt record against the interrupt handler, and when there was no interrupt + at all. + + However, the internal logic of the fop handler might detect from other + circumstances that an interrupt was delivered. For example, the fop handler + might be sleeping, waiting for some data to arrive, so that a premature + wakeup (with no data present) occurs if the interrupt handler intervenes. In + such cases it's the responsibility of the fop handler to reply the FUSE + request with errro EINTR. diff --git a/doc/developer-guide/gfapi-symbol-versions/gfapi-symbol-versions.md b/doc/developer-guide/gfapi-symbol-versions.md index e4f4fe9f052..e4f4fe9f052 100644 --- a/doc/developer-guide/gfapi-symbol-versions/gfapi-symbol-versions.md +++ b/doc/developer-guide/gfapi-symbol-versions.md diff --git a/doc/developer-guide/identifying-resource-leaks.md b/doc/developer-guide/identifying-resource-leaks.md new file mode 100644 index 00000000000..950cae79b0a --- /dev/null +++ b/doc/developer-guide/identifying-resource-leaks.md @@ -0,0 +1,200 @@ +# Identifying Resource Leaks + +Like most other pieces of software, GlusterFS is not perfect in how it manages +its resources like memory, threads and the like. Gluster developers try hard to +prevent leaking resources but releasing and unallocating the used structures. +Unfortunately every now and then some resource leaks are unintentionally added. + +This document tries to explain a few helpful tricks to identify resource leaks +so that they can be addressed. + + +## Debug Builds + +There are certain techniques used in GlusterFS that make it difficult to use +tools like Valgrind for memory leak detection. There are some build options +that make it more practical to use Valgrind and other tools. When running +Valgrind, it is important to have GlusterFS builds that contain the +debuginfo/symbols. Some distributions (try to) strip the debuginfo to get +smaller executables. Fedora and RHEL based distributions have sub-packages +called ...-debuginfo that need to be installed for symbol resolving. + + +### Memory Pools + +By using memory pools, there are no allocation/freeing of single structures +needed. This improves performance, but also makes it impossible to track the +allocation and freeing of srtuctures. + +It is possible to disable the use of memory pools, and use standard `malloc()` +and `free()` functions provided by the C library. Valgrind is then able to +track the allocated areas and verify if they have been free'd. In order to +disable memory pools, the Gluster sources needs to be configured with the +`--enable-debug` option: + +```shell +./configure --enable-debug +``` + +When building RPMs, the `.spec` handles the `--with=debug` option too: + +```shell +make dist +rpmbuild -ta --with=debug glusterfs-....tar.gz +``` + +### Dynamically Loaded xlators + +Valgrind tracks the call chain of functions that do memory allocations. The +addresses of the functions are stored and before Valgrind exits the addresses +are resolved into human readable function names and offsets (line numbers in +source files). Because Gluster loads xlators dynamically, and unloads then +before exiting, Valgrind is not able to resolve the function addresses into +symbols anymore. Whenever this happend, Valgrind shows `???` in the output, +like + +``` + ==25170== 344 bytes in 1 blocks are definitely lost in loss record 233 of 324 + ==25170== at 0x4C29975: calloc (vg_replace_malloc.c:711) + ==25170== by 0x52C7C0B: __gf_calloc (mem-pool.c:117) + ==25170== by 0x12B0638A: ??? + ==25170== by 0x528FCE6: __xlator_init (xlator.c:472) + ==25170== by 0x528FE16: xlator_init (xlator.c:498) + ... +``` + +These `???` can be prevented by not calling `dlclose()` for unloading the +xlator. This will cause a small leak of the handle that was returned with +`dlopen()`, but for improved debugging this can be acceptible. For this and +other Valgrind features, a `--enable-valgrind` option is available to +`./configure`. When GlusterFS is built with this option, Valgrind will be able +to resolve the symbol names of the functions that do memory allocations inside +xlators. + +```shell +./configure --enable-valgrind +``` + +When building RPMs, the `.spec` handles the `--with=valgrind` option too: + +```shell +make dist +rpmbuild -ta --with=valgrind glusterfs-....tar.gz +``` + +## Running Valgrind against a single xlator + +Debugging a single xlator is not trivial. But there are some tools to make it +easier. The `sink` xlator does not do any memory allocations itself, but +contains just enough functionality to mount a volume with only the `sink` +xlator. There is a little gfapi application under `tests/basic/gfapi/` in the +GlusterFS sources that can be used to run only gfapi and the core GlusterFS +infrastructure with the `sink` xlator. By extending the `.vol` file to load +more xlators, each xlator can be debugged pretty much separately (as long as +the xlators have no dependencies on each other). A basic Valgrind run with the +suitable configure options looks like this: + +```shell +./autogen.sh +./configure --enable-debug --enable-valgrind +make && make install +cd tests/basic/gfapi/ +make gfapi-load-volfile +valgrind ./gfapi-load-volfile sink.vol +``` + +Combined with other very useful options to Valgrind, the following execution +shows many more useful details: + +```shell +valgrind \ + --fullpath-after= --leak-check=full --show-leak-kinds=all \ + ./gfapi-load-volfile sink.vol +``` + +Note that the `--fullpath-after=` option is left empty, this makes Valgrind +print the full path and filename that contains the functions: + +``` +==2450== 80 bytes in 1 blocks are definitely lost in loss record 8 of 60 +==2450== at 0x4C29975: calloc (/builddir/build/BUILD/valgrind-3.11.0/coregrind/m_replacemalloc/vg_replace_malloc.c:711) +==2450== by 0x52C6F73: __gf_calloc (/usr/src/debug/glusterfs-3.11dev/libglusterfs/src/mem-pool.c:117) +==2450== by 0x12F10CDA: init (/usr/src/debug/glusterfs-3.11dev/xlators/meta/src/meta.c:231) +==2450== by 0x528EFD5: __xlator_init (/usr/src/debug/glusterfs-3.11dev/libglusterfs/src/xlator.c:472) +==2450== by 0x528F105: xlator_init (/usr/src/debug/glusterfs-3.11dev/libglusterfs/src/xlator.c:498) +==2450== by 0x52D9D8B: glusterfs_graph_init (/usr/src/debug/glusterfs-3.11dev/libglusterfs/src/graph.c:321) +... +``` + +In the above example, the `init` function in `xlators/meta/src/meta.c` does a +memory allocation on line 231. This memory is never free'd again, and hence +Valgrind logs this call stack. When looking in the code, it seems that the +allocation of `priv` is assigned to the `this->private` member of the +`xlator_t` structure. Because the allocation is done in `init()`, free'ing is +expected to happen in `fini()`. Both functions are shown below, with the +inclusion of the empty `fini()`: + + +``` +226 int +227 init (xlator_t *this) +228 { +229 meta_priv_t *priv = NULL; +230 +231 priv = GF_CALLOC (sizeof(*priv), 1, gf_meta_mt_priv_t); +232 if (!priv) +233 return -1; +234 +235 GF_OPTION_INIT ("meta-dir-name", priv->meta_dir_name, str, out); +236 +237 this->private = priv; +238 out: +239 return 0; +240 } +241 +242 +243 int +244 fini (xlator_t *this) +245 { +246 return 0; +247 } +``` + +In this case, the resource leak can be addressed by adding a single line to the +`fini()` function: + +``` +243 int +244 fini (xlator_t *this) +245 { +246 GF_FREE (this->private); +247 return 0; +248 } +``` + +Running the same Valgrind command and comparing the output will show that the +memory leak in `xlators/meta/src/meta.c:init` is not reported anymore. + +### Running DRD, the Valgrind thread error detector + +When configuring GlusterFS with: + +```shell +./configure --enable-valgrind +``` + +the default Valgrind tool (Memcheck) is enabled. But it's also possble to select +one of Memcheck or DRD by using: + +```shell +./configure --enable-valgrind=memcheck +``` + +or: + +```shell +./configure --enable-valgrind=drd +``` + +respectively. When using DRD, it's recommended to consult +https://valgrind.org/docs/manual/drd-manual.html before running. diff --git a/doc/developer-guide/logging-guidelines.md b/doc/developer-guide/logging-guidelines.md index 58adf944b67..0e6b2588535 100644 --- a/doc/developer-guide/logging-guidelines.md +++ b/doc/developer-guide/logging-guidelines.md @@ -62,7 +62,7 @@ There are 2 interfaces provided to log messages, headers (like the time stamp, dom, errnum etc.). The primary users of the above interfaces are, when printing the final graph, or printing the configuration when a process is about dump core or abort, or - printing the backtrace when a process recieves a critical signal + printing the backtrace when a process receives a critical signal - These interfaces should not be used outside the scope of the users above, unless you know what you are doing diff --git a/doc/developer-guide/network_compression.md b/doc/developer-guide/network_compression.md index 7327591ef63..1222a765276 100644 --- a/doc/developer-guide/network_compression.md +++ b/doc/developer-guide/network_compression.md @@ -1,9 +1,9 @@ -#On-Wire Compression + Decompression +# On-Wire Compression + Decompression The 'compression translator' compresses and decompresses data in-flight between client and bricks. -###Working +### Working When a writev call occurs, the client compresses the data before sending it to brick. On the brick, compressed data is decompressed. Similarly, when a readv call occurs, the brick compresses the data before sending it to client. On the @@ -19,7 +19,7 @@ During normal operation, this is the format of data sent over wire: The trailer contains the CRC32 checksum and length of original uncompressed data. This is used for validation. -###Usage +### Usage Turning on compression xlator: @@ -27,7 +27,7 @@ Turning on compression xlator: gluster volume set <vol_name> network.compression on ~~~ -###Configurable parameters (optional) +### Configurable parameters (optional) **Compression level** ~~~ @@ -35,10 +35,10 @@ gluster volume set <vol_name> network.compression.compression-level 8 ~~~ ~~~ -0 : no compression -1 : best speed -9 : best compression --1 : default compression + 0 : no compression + 1 : best speed + 9 : best compression +-1 : default compression ~~~ **Minimum file size** @@ -55,7 +55,7 @@ Other less frequently used parameters include `network.compression.mem-level` and `network.compression.window-size`. More details can about these options can be found by running `gluster volume set help` command. -###Known Issues and Limitations +### Known Issues and Limitations * Compression translator cannot work with striped volumes. * Mount point hangs when writing a file with write-behind xlator turned on. To @@ -65,7 +65,7 @@ set`performance.strict-write-ordering` to on. distribute volumes. This limitation is caused by AFR not being able to propagate xdata. This issue has been fixed in glusterfs versions > 3.5 -###TODO +### TODO Although zlib offers high compression ratio, it is very slow. We can make the translator pluggable to add support for other compression methods such as [lz4 compression](https://code.google.com/p/lz4/) diff --git a/doc/developer-guide/options-to-contribute.md b/doc/developer-guide/options-to-contribute.md new file mode 100644 index 00000000000..3f0d84e7645 --- /dev/null +++ b/doc/developer-guide/options-to-contribute.md @@ -0,0 +1,212 @@ +# A guide for contributors + +While you have gone through 'how to contribute' guides, if you are +not sure what to work on, but really want to help the project, you +have now landed on the right document :-) + +### Basic + +Instead of planning to fix **all** the below issues in one patch, +we recommend you to have a a constant, continuous flow of improvements +for the project. We recommend you to pick 1 file (or just few files) at +a time to address below issues. +Pick any `.c` (or `.h`) file, and you can send a patch which fixes **any** +of the below themes. Ideally, fix all such occurrences in the file, even +though, the reviewers would review even a single line change patch +from you. + +1. Check for variable definitions, and if there is an array definition, +which is very large at the top of the function, see if you can re-scope +the variable to relevant sections (if it helps). + +Most of the time, some of these arrays may be used for 'error' handling, +and it is possible to use them only in that scope. + +Reference: https://review.gluster.org/20846/ + + +2. Check for complete string initialization at the beginning of a function. +Ideally, there is no reason to initialize a string. Fix it across the file. + +Example: + +`char new_path_name[PATH_MAX] = {0};` to `char new_path_name[PATH_MAX];` + + +3. Change `calloc()` to `malloc()` wherever it makes sense. + +In a case of allocating a structures, where you expect certain (or most of) +variables to be 0 (or NULL), it makes sense to use calloc(). But otherwise, +there is an extra cost to `memset()` the whole object after allocating it. +While it is not a significant improvement in performance, code which gets +hit 1000s of times in a second, it would add some value. + +Reference: https://review.gluster.org/20878/ + + +4. You can consider using `snprintf()`, instead of `strncpy()` while dealing +with strings. + +strncpy() won't null terminate if the dest buffer isn't big enough; snprintf() +does. While most of the string operations in the code is on array, and larger +size than required, strncpy() does an extra copy of 0s at the end of +string till the size of the array. It makes sense to use `snprintf()`, +which doesn't suffer from that behavior. + +Also check the return value from snprintf() for buffer overflow and handle +accordingly + +Reference: https://review.gluster.org/20925/ + + +5. Now, pick a `.h` file, and see if a structure is very large, and see +if re-aligning them as per [coding-standard](./coding-standard.md) gives any size benefit, +if yes, go ahead and change it. Make sure you check all the structures +in the file for similar pattern. + +Reference: [Check this section](https://github.com/gluster/glusterfs/blob/master/doc/developer-guide/coding-standard.md#structure-members-should-be-aligned-based-on-the-padding-requirements + + +### If you are up for more :-) + +Good progress! Glad you are interested to know more. We are surely interested +in next level of contributions from you! + +#### Coverity + +Visit [Coverity Dashboard](https://scan.coverity.com/projects/gluster-glusterfs?tab=overview). + +Now, if the number of defect is not 0, you have an opportunity to contribute. + +You get all the detail on why the particular defect is mentioned there, and +most probable hint on how to fix it. Do it! + +Reference: https://review.gluster.org/21394/ + +Use the same reference Id (789278) as the patch, so we can capture it is in +single bugzilla. + +#### Clang-Scan + +Clang-Scan is a tool which scans the .c files and reports the possible issues, +similar to coverity, but a different tool. Over the years we have seen, they +both report very different set of issues, and hence there is a value in fixing it. + +GlusterFS project gets tested with clang-scan job every night, and the report is +posted in the [job details page](https://build.gluster.org/job/clang-scan/lastCompletedBuild/clangScanBuildBugs/). +As long as the number is not 0 in the report here, you have an opportunity to +contribute! Similar to coverity dashboard, click on 'Details' to find out the +reason behind that report, and send a patch. + +Reference: https://review.gluster.org/21025 + +Again, you can use reference Id (1622665) for these patches! + + +### I am good with programming, I would like to do more than above! + +#### Locked regions / Critical sections + +In the file you open, see if the lock is taken only to increment or decrement +a flag, counter etc. If yes, then recommend you to convert it to ATOMIC locks. +It is simple activity, but, if you know programing, you would know the benefit +here. + +NOTE: There may not always a possibility to do this! You may have to check +with developers first before going ahead. + +Reference: https://review.gluster.org/21221/ + + +#### ASan (address sanitizer) + +[The job](https://build.gluster.org/job/asan/) runs regression with asan builds, +and you can also run glusterfs with asan on your workload to identify the leaks. +If there are any leaks reported, feel free to check it, and send us patch. + +You can also run `valgrind` and let us know what it reports. + +Reference: https://review.gluster.org/21397 + + +#### Porting to different architecture + +This is something which we are not focusing right now, happy to collaborate! + +Reference: https://review.gluster.org/21276 + + +#### Fix 'TODO/FIXME' in codebase + +There are few cases of pending features, or pending validations, which are +pending from sometime. You can pick them in the given file, and choose to +fix it. + + +### I don't know C, but I am interested to contribute in some way! + +You are most welcome! Our community is open for your contribution! First thing +which comes to our mind is **documentation**. Next is, **testing** or validation. + +If you have some hardware, and want to run some performance comparisons with +different version, or options, and help us to tune better is also a great help. + + +#### Documentation + +1. We have some documentation in [glusterfs repo](../), go through these, and +see if you can help us to keep up-to-date. + +2. The https://docs.gluster.org is powered by https://github.com/gluster/glusterdocs +repo. You can check out the repo, and help in keeping that up-to-date. + +3. [Our website](https://gluster.org) is maintained by https://github.com/gluster/glusterweb +repo. Help us to keep this up-to-date, and add content there. + +4. Write blogs about Gluster, and your experience, and make world know little +more about Gluster, and your use-case, and how it helped to solve the problem. + + +#### Testing + +1. There is a regression test suite in glusterfs, which runs with every patch, and is +triggered by just running `./run-tests.sh` from the root of the project repo. + +You can add more test case to match your use-case, and send it as a patch, so you +can make sure all future patches in glusterfs would keep your usecase intact. + +2. [Glusto-Tests](https://github.com/gluster/glusto-tests): This is another testing +framework written for gluster, and makes use of clustered setup to test different +use-cases, and helps to validate many bugs. + + +#### Ansible + +Gluster Organization has rich set of ansible roles, which are actively maintained. +Feel free to check them out here - https://github.com/gluster/gluster-ansible + + +#### Monitoring + +We have prometheus repo, and are actively working on adding more metrics. Add what +you need @ https://github.com/gluster/gluster-prometheus + + +#### Health-Report + +This is a project, where at any given point in time, you want to run some set of +commands locally, and get an output to analyze the status, it can be added. +Contribute @ https://github.com/gluster/gluster-health-report + + +### All these C/bash/python is old-school, I want something in containers. + +We have something for you too :-) + +Please visit our https://github.com/gluster/gcs repo for checking how you can help, +and how gluster can help you in container world. + + +### Note + +For any queries, best way is to contact us through mailing-list, <mailto:gluster-devel@gluster.org> diff --git a/doc/developer-guide/rpc-for-glusterfs.new-versions.md b/doc/developer-guide/rpc-for-glusterfs.new-versions.md new file mode 100644 index 00000000000..e3da5efa4a2 --- /dev/null +++ b/doc/developer-guide/rpc-for-glusterfs.new-versions.md @@ -0,0 +1,32 @@ +# GlusterFS RPC program versions + +## Compatibility + +RPC layer of glusterfs is implemented with possible changes over the protocol layers in mind. If there are any changes in the FOPs from what is assumed to be client side, and whats in serverside, they are to be added as a separate program table. + +### Program tables and Versions + +A given RPC program has a specific Task, and Version along with actors belonging to the program. In any of the programs, if a new actor is added, it is very important to define one more program with different version, and then keep both, if both are supported. Or else, it is important to handle the 'handshake' properly. + +#### Server details + +More info on RPC program is at `rpc/rpc-lib/src/rpcsvc.h` and check for structure `rpcsvc_actor_t` and `struct rpcsvc_program`. For usage, check `xlators/protocol/server/src/server-rpc-fops.c` + +#### Client details + +For details on client structures check `rpc/rpc-lib/src/rpc-clnt.h` for `rpc_clnt_procedure_t` and `rpc_clnt_program_t`. For usage, check `xlators/protocol/client/src/client-rpc-fops.c` + +## Protocol + +A protocol is what is agreed between two parties. In glusterfs, a RPC protocol is defined as .x file, which then gets converted to .c/.h file using `rpcgen`. There are different protocols defined for communication between `xlators/mgmt/glusterd <==> glusterfsd`, `gluster CLI <==> glusterd`, and `client-protocol <==> server-protocol` + +Once a protocol is defined and a release is made with that protocol, make sure no one changes it. Any edits to a given structure there should be a new version of the structure, and also it should get used in new actor, and thus new program version. + +## Server and Client Handshake + +When a client succeeds to establish a connect (it can be any transport, socket, ib-verbs or unix), client sends a dump (GF_DUMP_DUMP) request to server, which will respond back with all the supported versions of the server RPC (the supported programs which are registered with `rpcsvc_program_register()`). + +A client which expects certain programs to be present in server, it should be taking care of looking for it in the handshake methods, and take appropriate action depending on what to do next. In general a compatibility issue should be handled at handshake level itself, thus we can clearly let user/admin know of any 'in-compatibilities'. +As a developer of GlusterFS protocol layer, one just has to make sure *never to make changes to existing program structures*, but they have to add new programs if required. New programs can have the same actors as present in existing, and also little more. Or it can even have same actor behave differently, take different parameter. + +If this is followed properly, there would be smooth upgrade / downgrade of versions. If not, technically, it is 100% guarantee of getting compatibility related issues. diff --git a/doc/developer-guide/syncop.md b/doc/developer-guide/syncop.md new file mode 100644 index 00000000000..bcc8bd08e01 --- /dev/null +++ b/doc/developer-guide/syncop.md @@ -0,0 +1,72 @@ +# syncop framework +A coroutines-based, cooperative multi-tasking framework. + +## Topics + +- Glossary +- Lifecycle of a synctask +- Existing usage + + +## Glossary + +### syncenv + +syncenv is an object that provides access to a pool of worker threads. +synctasks execute in a syncenv. + +### synctask + +synctask can be informally defined as a pair of function pointers, namely _the +call_ and _the callback_ (see syncop.h for more details). + + synctask_fn_t - 'the call' + synctask_cbk_t - 'the callback' + +synctask has two modes of operation, + +1. The calling thread waits for the synctask to complete. +2. The calling thread schedules the synctask and continues. + +synctask guarantees that the callback is called _after_ the call completes. + +### Lifecycle of a synctask + +A synctask could go into the following stages while in execution. + +- CREATED - On calling synctask_create/synctask_new. + +- RUNNABLE - synctask is queued in env->runq. + +- RUNNING - When one of syncenv's worker threads calls synctask_switch_to. + +- WAITING - When a synctask calls synctask_yield. + +- DONE - When a synctask has run to completion. + + + +-------------------------------+ + | CREATED | + +-------------------------------+ + | + | synctask_new/synctask_create + v + +-------------------------------+ + | RUNNABLE (in env->runq) | <+ + +-------------------------------+ | + | | + | synctask_switch_to | + v | + +------+ on task completion +-------------------------------+ | + | DONE | <-------------------- | RUNNING | | synctask_wake/wake + +------+ +-------------------------------+ | + | | + | synctask_yield/yield | + v | + +-------------------------------+ | + | WAITING (in env->waitq) | -+ + +-------------------------------+ + +Note: A synctask is not guaranteed to run on the same thread throughout its +lifetime. Every time a synctask yields, it is possible for it to run on a +different thread. diff --git a/doc/developer-guide/thread-naming.md b/doc/developer-guide/thread-naming.md new file mode 100644 index 00000000000..513140d4437 --- /dev/null +++ b/doc/developer-guide/thread-naming.md @@ -0,0 +1,104 @@ +Thread Naming +================ +Gluster processes spawn many threads; some threads are created by libglusterfs +library, while others are created by xlators. When gfapi library is used in an +application, some threads belong to the application and some are spawned by +gluster libraries. We also have features where n number of threads are spawned +to act as worker threads for same operation. + +In all the above cases, it is useful to be able to determine the list of threads +that exist in runtime. Naming threads when you create them is the easiest way to +provide that information to kernel so that it can then be queried by any means. + +How to name threads +------------------- +We have two wrapper functions in libglusterfs for creating threads. They take +name as an argument and set thread name after its creation. + +```C +gf_thread_create (pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg, const char *name) +``` + +```C +gf_thread_create_detached (pthread_t *thread, + void *(*start_routine)(void *), void *arg, + const char *name) +``` + +As max name length for a thread in POSIX is only 16 characters including the +'\0' character, you have to be a little creative with naming. Also, it is +important that all Gluster threads have common prefix. Considering these +conditions, we have "glfs_" as prefix for all the threads created by these +wrapper functions. It is responsibility of the owner of thread to provide the +suffix part of the name. It does not have to be a descriptive name, as it has +only 10 letters to work with. However, it should be unique enough such that it +can be matched with a table which describes it. + +If n number of threads are spwaned to perform same function, it is must that the +threads are numbered. + +Table of thread names +--------------------- +Thread names don't have to be a descriptive; however, it should be unique enough +such that it can be matched with a table below without ambiguity. + +- bdaio - block device aio +- brfsscan - bit rot fs scanner +- brhevent - bit rot event handler +- brmon - bit rot monitor +- brosign - bit rot one shot signer +- brpobj - bit rot object processor +- brsproc - bit rot scrubber +- brssign - bit rot stub signer +- brswrker - bit rot worker +- clogc - changelog consumer +- clogcbki - changelog callback invoker +- clogd - changelog dispatcher +- clogecon - changelog reverse connection +- clogfsyn - changelog fsync +- cloghcon - changelog history consumer +- clogjan - changelog janitor +- clogpoll - changelog poller +- clogproc - changelog process +- clogro - changelog rollover +- ctrcomp - change time recorder compaction +- dhtdf - dht defrag task +- dhtdg - dht defrag start +- dhtfcnt - dht rebalance file counter +- ecshd - ec heal daemon +- epollN - epoll thread +- fdlwrker - fdl worker +- fusenoti - fuse notify +- fuseproc - fuse main thread +- gdhooks - glusterd hooks +- glfspoll - gfapi poller thread +- idxwrker - index worker +- iosdump - io stats dump +- iotwr - io thread worker +- jbrflush - jbr flush +- leasercl - lease recall +- memsweep - sweeper thread for mem pools +- nfsauth - nfs auth +- nfsnsm - nfs nsm +- nfsudp - nfs udp mount +- nlmmon - nfs nlm/nsm mon +- posixaio - posix aio +- posixfsy - posix fsync +- posixhc - posix heal +- posixjan - posix janitor +- posixrsv - posix reserve +- quiesce - quiesce dequeue +- rdmaAsyn - rdma async event handler +- rdmaehan - rdma completion handler +- rdmarcom - rdma receive completion handler +- rdmascom - rdma send completion handler +- rpcsvcrh - rpcsvc request handler +- scleanup - socket cleanup +- shdheal - self heal daemon +- sigwait - glusterfsd sigwaiter +- spoller - socket poller +- sprocN - syncop worker thread +- tbfclock - token bucket filter token generator thread +- timer - timer thread +- upreaper - upcall reaper diff --git a/doc/developer-guide/translator-development.md b/doc/developer-guide/translator-development.md index 9153c874d0f..f75935519f6 100644 --- a/doc/developer-guide/translator-development.md +++ b/doc/developer-guide/translator-development.md @@ -51,7 +51,7 @@ if (!(xl->fini = dlsym (handle, "fini"))) { In this example, `xl` is a pointer to the in-memory object for the translator we're loading. As you can see, it's looking up various symbols *by name* in the shared object it just loaded, and storing pointers to those symbols. Some of -them (e.g. init are functions, while others e.g. fops are dispatch tables +them (e.g. init) are functions, while others (e.g. fops) are dispatch tables containing pointers to many functions. Together, these make up the translator's public interface. @@ -102,7 +102,7 @@ various structures in logs. I've never used it myself, though I probably should. What's noteworthy here is that we don't even define dumpops. That's because all of the functions that might use these dispatch functions will check for `xl->dumpops` being `NULL` before calling through it. This is in sharp -contrast to the behavior for `fops` and `cbks1`, which *must* be present. If +contrast to the behavior for `fops` and `cbks`, which *must* be present. If they're not, translator loading will fail because these pointers are not checked every time and if they're `NULL` then we'll segfault. That's why we provide an empty definition for cbks; it's OK for the individual function @@ -472,7 +472,7 @@ hello Now let's interrupt the process and see where we are. ``` -^C + Program received signal SIGINT, Interrupt. 0x0000003a0060b3dc in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 @@ -680,4 +680,4 @@ Original author's site: Gluster community site: - * [Translators](http://www.gluster.org/community/documentation/index.php/Translators) + * [Translators](https://docs.gluster.org/en/latest/Quick-Start-Guide/Architecture/#translators) diff --git a/doc/developer-guide/writing-a-cloudsync-plugin.md b/doc/developer-guide/writing-a-cloudsync-plugin.md new file mode 100644 index 00000000000..907860aaed8 --- /dev/null +++ b/doc/developer-guide/writing-a-cloudsync-plugin.md @@ -0,0 +1,164 @@ +## How to write your Cloudsync Plugin + +### Background + +Cloudsync translator is part of the archival feature in Gluster. This translator +does the retrieval/download part. Each cold file will be archived to a remote +storage (public or private cloud). On future access to the file, it will be +retrieved from the remote storage by Cloudsync translator. Each remote storage +would need a unique plugin. Cloudsync translator will load this plugin and +call the necessary plugin functions. + +Upload can be done by a script or program. There are some basic mandatory steps +for uploading the data. There is a sample script for crawl and upload given at +the end of this guide. + +### Necessary changes to create a plugin + +1. Define store_methods: + +* This structure is the container of basic functions that will be called by + cloudsync xlator. + + typedef struct store_methodds { + int (*fop_download) (call_frame_t *frame, void *config); + /* return type should be the store config */ + void *(*fop_init) (xlator_t *this); + int (*fop_reconfigure) (xlator_t *this, dict_t *options); + void (*fop_fini) (void *config); + } store_methods_t; + + + Member details: + fop_download: + This is the download function pointer. + + frame: This will have the fd to write data downloaded from + cloud to GlusterFS.(frame->local->fd) + + config: This is the plugin configuration variable. + + Note: Structure cs_local_t has member dlfd and dloffset which + can be used to manage the writes to Glusterfs. + Include cloudsync-common.h to access these structures. + + fop_init: + This is similar to xlator init. But here the return value is + the plugin configuration pointer. This pointer will be stored + in the cloudsync private object (priv->stores->config). And + the cloudsync private object can be accessed by "this->private" + where "this" is of type xlator_t. + + fop_reconfigure: + This is similar to xlator_reconfigure. + + fop_fini: + Free plugin resources. + + Note: Store_methods_t is part of cs_private_t which in turn part of + xlator_t. Create a store_methods_t object named "store_ops" in + your plugin. For example + + store_methods_t store_ops = { + .fop_download = aws_download_s3, + .fop_init = aws_init, + .fop_reconfigure = aws_reconfigure, + .fop_fini = aws_fini, + }; + + +2 - Making Cloudsync xlator aware of the plugin: + + Add an entry in to the cs_plugin structure. For example + struct cs_plugin plugins[] = { + { + .name = "amazons3", + .library = "libamazons3.so", + .description = "amazon s3 store." + }, + + {.name = NULL}, + }; + + Description about individual members: + name: name of the plugin + library: This is the shared object created. Cloudsync will load + this library during init. + description: Describe about the plugin. + +3- Makefile Changes in Cloudsync: + + Add <plugin.la> to cloudsync_la_LIBADD variable. + +4 - Configure.ac changes: + + In cloudsync section add the necessary dependency checks for + the plugin. + +5 - Export symbols: + + Cloudsync needs "store_ops" to resolve all plugin functions. + Create a file <plugin>.sym and add write "store_ops" to it. + + +### Sample script for upload +This script assumes amazon s3 is the target cloud and bucket name is +gluster-bucket. User can do necessary aws configuration using command +"aws configure". Currently for amazons3 there are four gluster settings +available. +1- features.s3plugin-seckey -> s3 secret key +2- features.s3plugin-keyid -> s3 key id +3- features.s3plugin-bucketid -> bucketid +4- features.s3plugin-hostname -> hostname e.g. s3.amazonaws.com + +Additionally set cloudsync storetype to amazons3. + +gluster v set <VOLNAME> cloudsync-storetype amazons3 + +Now create a mount dedicated for this upload task. + +That covers necessary configurations needed. + +Below is the sample script for upload. The script will crawl directly on the +brick and will upload those files which are not modified for last one month. +It needs two arguments. +1st arguement - Gluster Brick path +2nd arguement - coldness that is how many days since the file was modified. +3rd argument - dedicated gluster mount point created for uploading. + +Once the cloud setup is done, run the following script on individual bricks. +Note: For an AFR volume, pick only the fully synchronized brick among the +replica bricks. + +``` +target_folder=$1 +coldness=$2 +mnt=$3 + +cd $target_folder +for i in `find . -type f | grep -v "glusterfs" | sed 's/..//'` +do + echo "processing $mnt/$i" + + #check whether the file is already archived + getfattr -n trusted.glusterfs.cs.remote $i &> /dev/null + if [ $? -eq 0 ] + then + echo "file $mnt/$i is already archived" + else + #upload to cloud + aws s3 cp $mnt/$i s3://gluster-bucket/ + mtime=`stat -c "%Y" $mnt/$i` + + #post processing of upload + setfattr -n trusted.glusterfs.csou.complete -v $mtime $mnt/$i + if [ $? -ne 0 ] + then + echo "archiving of file $mnt/$i failed" + else + echo "archiving of file $mnt/$i succeeded" + fi + + fi +done +``` diff --git a/doc/developer-guide/xlator-classification.md b/doc/developer-guide/xlator-classification.md new file mode 100644 index 00000000000..6073df9375f --- /dev/null +++ b/doc/developer-guide/xlator-classification.md @@ -0,0 +1,221 @@ +# xlator categories and expectations + +The purpose of the document is to define a category for various xlators +and expectations around what each category means from a perspective of +health and maintenance of a xlator. + +The need to do this is to ensure certain categories are kept in good +health, and helps the community and contributors focus their efforts around the +same. + +This document also provides implementation details for xlator developers to +declare a category for any xlator. + +## Table of contents +1. Audience +2. Categories (and expectations of each category) +3. Implementation and usage details + +## Audience + +This document is intended for the following community participants, +- New xlator contributors +- Existing xlator maintainers +- Packaging and gluster management stack maintainers + +For a more user facing understanding it is recommended to read section (TBD) +in the gluster documentation. + +## Categories +1. Experimental (E) +2. TechPreview (TP) +3. Maintained (M) +4. Deprecated (D) +5. Obsolete (O) + +### Experimental (E) + +Developed in the experimental branch, for exploring new features. These xlators +are NEVER packaged as a part of releases, interested users and contributors can +build and work with these from sources. In the future, these maybe available as +an package based on a weekly build of the same. + +#### Quality expectations +- Compiles or passes smoke tests +- Does not break nightly experimental regressions + - NOTE: If a nightly is broken, then all patches that were merged are reverted + till the errant patch is found and subsequently fixed + +### TechPreview (TP) + +Xlators in master or release branches that are not deemed fit to be in +production deployments, but are feature complete to invite feedback and host +user data. + +These xlators will be worked upon with priority by maintainers/authors who are +involved in making them more stable than xlators in the Experimental/Deprecated/ +Obsolete categories. + +There is no guarantee that these xlators will move to the Maintained state, and +may just get Obsoleted based on feedback, or other project goals or technical +alternatives. + +#### Quality expectations +- Same as Maintained, minus + - Performance, Scale, other(?) + - *TBD* *NOTE* Need inputs, Intention is all quality goals as in Maintained, + other than the list above (which for now has scale and performance) + +### Maintained (M) + +These xltors are part of the core Gluster functionality and are maintained +actively. These are part of master and release branches and are higher in +priority of maintainers and other interested contributors. + +#### Quality expectations + +NOTE: A short note on what each of these mean are added here, details to follow. + +NOTE: Out of the gate all of the following are not mandated, consider the +following a desirable state to reach as we progress on each + +- Bug backlog: Actively address bug backlog +- Enhancement backlog: Actively maintain outstanding enhancement backlog (need + not be acted on, but should be visible to all) +- Review backlog: Actively keep this below desired counts and states +- Static code health: Actively meet near-zero issues in this regard + - Coverity, spellcheck and other checks +- Runtime code health: Actively meet defined coverage levels in this regard + - Coverage, others? + - Per-patch regressions + - Glusto runs + - Performance + - Scalability +- Technical specifications: Implementation details should be documented and + updated at regular cadence (even per patch that change assumptions in + here) +- User documentation: User facing details should be maintained to current + status in the documentation +- Debuggability: Steps, tools, procedures should be documented and maintained + each release/patch as applicable +- Troubleshooting: Steps, tools, procedures should be documented and maintained + each release/patch as applicable + - Steps/guides for self service + - Knowledge base for problems +- Other common criteria that will apply: Required metrics/desired states to be + defined per criteria + - Monitoring, usability, statedump, and other such xlator expectations + +### Deprecated (D) + +Xlators on master or release branches that would be obsoleted and/or replaced +with similar or other functionality in the next major release. + +#### Quality expectations +- Retain status-quo when moved to this state, till it is moved to obsoleted +- Provide migration steps if feature provided by the xlator is replaced with +other xlators + +### Obsolete (O) + +Xlator/code still in tree, but not packaged or shipped or maintained in any +form. This is noted as a category till the code is removed from the tree. + +These xlators and their corresponding code and test health will not be executed. + +#### Quality expectations +- None + +## Implementation and usage details + +### How to specify an xlators category + +While defining 'xlator_api_t' structure for the corresponding xlator, add a +flag like below: + +``` +diff --git a/xlators/performance/nl-cache/src/nl-cache.c b/xlators/performance/nl-cache/src/nl-cache.c +index 0f0e53bac2..8267d6897c 100644 +--- a/xlators/performance/nl-cache/src/nl-cache.c ++++ b/xlators/performance/nl-cache/src/nl-cache.c +@@ -869,4 +869,5 @@ xlator_api_t xlator_api = { + .cbks = &nlc_cbks, + .options = nlc_options, + .identifier = "nl-cache", ++ .category = GF_TECH_PREVIEW, + }; +diff --git a/xlators/performance/quick-read/src/quick-read.c b/xlators/performance/quick-read/src/quick-read.c +index 8d39720e7f..235de27c19 100644 +--- a/xlators/performance/quick-read/src/quick-read.c ++++ b/xlators/performance/quick-read/src/quick-read.c +@@ -1702,4 +1702,5 @@ xlator_api_t xlator_api = { + .cbks = &qr_cbks, + .options = qr_options, + .identifier = "quick-read", ++ .category = GF_MAINTAINED, + }; +``` + +Similarly, if a particular option is in different state other than +the xlator state, one can add the same flag in options structure too. + +``` +diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c +index 0e86e33d03..81996743d1 100644 +--- a/xlators/cluster/afr/src/afr.c ++++ b/xlators/cluster/afr/src/afr.c +@@ -772,6 +772,7 @@ struct volume_options options[] = { + .description = "Maximum latency for shd halo replication in msec." + }, + { .key = {"halo-enabled"}, ++ .category = GF_TECH_PREVIEW, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "False", + +``` + + +### User experience using the categories + +#### Ability to use a category + +This section details which category of xlators can be used when and specifics +around when each category is enabled. + +1. Maintained category xlators can be used by default, this implies, volumes +created with these xlators enabled will throw no warnings, or need no user +intervention to use the xlator. + +2. Tech Preview category xlators needs cluster configuration changes to allow +these xlatorss to be used in volumes, further, logs will contain a message +stating TP xlators are in use. Without the cluster configured to allow TP +xlators, volumes created or edited to use such xlators would result in errors. + - (TBD) Cluster configuration option + - (TBD) Warning message + - (TBD) Code mechanics on how this is achieved + +3. Deprecated category xlators can be used by default, but will throw a warning +in the logs that such are in use and will be deprecated in the future. + - (TBD) Warning message + +4. Obsolete category xlators will not be packaged and hence cannot be used from +release builds. + +5. Experimental category xlators will not be packaged and hence cannot be used +from release builds, if running experimental (weekly or other such) builds, +these will throw a warning in the logs stating experimental xlators are in use. + - (TBD) Warning message + +#### Ability to query xlator category + +(TBD) Need to provide the ability to query xlator categories, or list xlators +and their respective categories. + +#### User facing changes + +User facing changes that are expected due to this change include the following, +- Cluster wide option to enable TP xlators, or more generically a category +level of xlators +- Errors in commands that fail due to invalid categories +- Warning messages in logs to denote certain categories of xlators are in use +- (TBD) Ability to query xlators and their respective categories diff --git a/doc/features/ctime.md b/doc/features/ctime.md new file mode 100644 index 00000000000..74a77abed4b --- /dev/null +++ b/doc/features/ctime.md @@ -0,0 +1,68 @@ +# Consistent time attributes in gluster across replica/distribute + + +#### Problem: +Traditionally gluster has been using time attributes (ctime, atime, mtime) of files/dirs from bricks. The problem with this approach is that, it is not consisteant across replica and distribute bricks. And applications which depend on it breaks as replica might not always return time attributes from same brick. + +Tar especially gives "file changed as we read it" whenever it detects ctime differences when stat is served from different bricks. The way we have been trying to solve it is to serve the stat structures from same brick in afr, max-time in dht. But it doesn't avoid the problem completely. Because there is no way to change ctime at the moment(lutimes() only allows mtime, atime), there is little we can do to make sure ctimes match after self-heals/xattr updates/rebalance. + +#### Solution Proposed: +Store time attribues (ctime, mtime, atime) as an xattr of the file. The xattr is updated based +on the fop. If a filesystem fop changes only mtime and ctime, update only those in xattr for +that file. + +#### Design Overview: +1) As part of each fop, top layer will generate a time stamp and pass it to the down along + with other information + - This will bring a dependency for NTP synced clients along with servers + - There can be a diff in time if the fop stuck in the xlator for various reason, +for ex: because of locks. + + 2) On the server, posix layer stores the value in the memory (inode ctx) and will sync the data periodically to the disk as an extended attr + - Of course sync call also will force it. And fop comes for an inode which is not linked, we do the sync immediately. + + 3) Each time when inodes are created or initialized it read the data from disk and store in inode ctx. + + 4) Before setting to inode_ctx we compare the timestamp stored and the timestamp received, and only store if the stored value is lesser than the current value. + + 5) So in best case data will be stored and retrieved from the memory. We replace the values in iatt with the values in inode_ctx. + + 6) File ops that changes the parent directory attr time need to be consistent across all the distributed directories across the subvolumes. (for eg: a create call will change ctime and mtime of parent dir) + + - This has to handle separately because we only send the fop to the hashed subvolume. + - We can asynchronously send the timeupdate setattr fop to the other subvoumes and change the values for parent directory if the file fops is successful on hashed subvolume. + - This will have a window where the times are inconsistent across dht subvolume (Please provide your suggestions) + +7) Currently we have couple of mount options for time attributes like noatime, relatime , nodiratime etc. But we are not explicitly handled those options even if it is given as mount option when gluster mount. + + +#### Implementation Overview: +This features involves changes in following xlators. + - utime xlator + - posix xlator + +##### utime xlator: +This is a new client side xlator which does following tasks. + +1. It will generate a time stamp and passes it down in frame->root->ctime and over the network. +2. Based on fop, it also decides the time attributes to be updated and this passed using "frame->root->flags" + + Patches: + 1. https://review.gluster.org/#/c/19857/ + +##### posix xlator: +Following tasks are done in posix xlator: + +1. Provides APIs to set and get the xattr from backend. It also caches the xattr in inode context. During get, it updates time attributes stored in xattr into iatt structure. +2. Based on the flags from utime xlator, relevant fops update the time attributes in the xattr. + + Patches: + 1. https://review.gluster.org/#/c/19267/ + 2. https://review.gluster.org/#/c/19795/ + 3. https://review.gluster.org/#/c/19796/ + +#### Pending Work: +1. Handling of time related mount options (noatime, realatime,etc) +2. flag based create (depending on flags in open, create behaviour might change) +3. Changes in dht for direcotory sync acrosss multiple subvolumes +4. readdirp stat need to be worked on. diff --git a/doc/features/ganesha-ha.md b/doc/features/ganesha-ha.md new file mode 100644 index 00000000000..4b226a22ccf --- /dev/null +++ b/doc/features/ganesha-ha.md @@ -0,0 +1,43 @@ +# Overview of Ganesha HA Resource Agents in GlusterFS 3.7 + +The ganesha_mon RA monitors its ganesha.nfsd daemon. While the +daemon is running, it creates two attributes: ganesha-active and +grace-active. When the daemon stops for any reason, the attributes +are deleted. Deleting the ganesha-active attribute triggers the +failover of the virtual IP (the IPaddr RA) to another node — +according to constraint location rules — where ganesha.nfsd is +still running. + +The ganesha_grace RA monitors the grace-active attribute. When +the grace-active attibute is deleted, the ganesha_grace RA stops, +and will not restart. This triggers pacemaker to invoke the notify +action in the ganesha_grace RAs on the other nodes in the cluster; +which send a DBUS message to their respective ganesha.nfsd. + +(N.B. grace-active is a bit of a misnomer. while the grace-active +attribute exists, everything is normal and healthy. Deleting the +attribute triggers putting the surviving ganesha.nfsds into GRACE.) + +To ensure that the remaining/surviving ganesha.nfsds are put into + NFS-GRACE before the IPaddr (virtual IP) fails over there is a +short delay (sleep) between deleting the grace-active attribute +and the ganesha-active attribute. To summarize, e.g. in a four +node cluster: + +1. on node 2 ganesha_mon::monitor notices that ganesha.nfsd has died + +2. on node 2 ganesha_mon::monitor deletes its grace-active attribute + +3. on node 2 ganesha_grace::monitor notices that grace-active is gone +and returns OCF_ERR_GENERIC, a.k.a. new error. When pacemaker tries +to (re)start ganesha_grace, its start action will return +OCF_NOT_RUNNING, a.k.a. known error, don't attempt further restarts. + +4. on nodes 1, 3, and 4, ganesha_grace::notify receives a post-stop +notification indicating that node 2 is gone, and sends a DBUS message +to its ganesha.nfsd, putting it into NFS-GRACE. + +5. on node 2 ganesha_mon::monitor waits a short period, then deletes +its ganesha-active attribute. This triggers the IPaddr (virt IP) +failover according to constraint location rules. + diff --git a/doc/gluster.8 b/doc/gluster.8 index 70ed95a9ae1..ba595edca15 100644 --- a/doc/gluster.8 +++ b/doc/gluster.8 @@ -16,15 +16,14 @@ gluster - Gluster Console Manager (command line utility) .PP To run the program and display gluster prompt: .PP -.B gluster +.B gluster [--remote-host=<gluster_node>] [--mode=script] [--xml] .PP (or) .PP To specify a command directly: .PP .B gluster -.I [commands] [options] - +.I [commands] [options] [--remote-host=<gluster_node>] [--mode=script] [--xml] .SH DESCRIPTION The Gluster Console Manager is a command line utility for elastic volume management. You can run the gluster command on any export server. The command enables administrators to perform cloud operations, such as creating, expanding, shrinking, rebalancing, and migrating volumes without needing to schedule server downtime. .SH COMMANDS @@ -36,7 +35,13 @@ The Gluster Console Manager is a command line utility for elastic volume managem \fB\ volume info [all|<VOLNAME>] \fR Display information about all volumes, or the specified volume. .TP -\fB\ volume create <NEW-VOLNAME> [stripe <COUNT>] [replica <COUNT>] [disperse [<COUNT>]] [redundancy <COUNT>] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ... \fR +\fB\ volume list \fR +List all volumes in cluster +.TP +\fB\ volume status [all | <VOLNAME> [nfs|shd|<BRICK>|quotad]] [detail|clients|mem|inode|fd|callpool|tasks|client-list] \fR +Display status of all or specified volume(s)/brick +.TP +\fB\ volume create <NEW-VOLNAME> [stripe <COUNT>] [[replica <COUNT> [arbiter <COUNT>]]|[replica 2 thin-arbiter 1]] [disperse [<COUNT>]] [disperse-data <COUNT>] [redundancy <COUNT>] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ... <TA-BRICK> \fR Create a new volume of the specified type using the specified bricks and transport type (the default transport type is tcp). To create a volume with both transports (tcp and rdma), give 'transport tcp,rdma' as an option. .TP @@ -52,8 +57,17 @@ Stop the specified volume. \fB\ volume set <VOLNAME> <OPTION> <PARAMETER> [<OPTION> <PARAMETER>] ... \fR Set the volume options. .TP -\fB\ volume get <VOLNAME> <OPTION/all>\fR -Get the volume options. +\fB\ volume get <VOLNAME/all> <OPTION/all> \fR +Get the value of the all options or given option for volume <VOLNAME> or all option. gluster volume get all all is to get all global options +.TP +\fB\ volume reset <VOLNAME> [option] [force] \fR +Reset all the reconfigured options +.TP +\fB\ volume barrier <VOLNAME> {enable|disable} \fR +Barrier/unbarrier file operations on a volume +.TP +\fB\ volume clear-locks <VOLNAME> <path> kind {blocked|granted|all}{inode [range]|entry [basename]|posix [range]} \fR +Clear locks held on path .TP \fB\ volume help \fR Display help for the volume command. @@ -71,6 +85,9 @@ If you remove the brick, the data stored in that brick will not be available. Yo .B replace-brick option. .TP +\fB\ volume reset-brick <VOLNAME> <SOURCE-BRICK> {{start} | {<NEW-BRICK> commit}} \fR +Brings down or replaces the specified source brick with the new brick. +.TP \fB\ volume replace-brick <VOLNAME> <SOURCE-BRICK> <NEW-BRICK> commit force \fR Replace the specified source brick with a new brick. .TP @@ -92,6 +109,18 @@ Locate the log file for corresponding volume/brick. .TP \fB\ volume log rotate <VOLNAME> [BRICK] \fB Rotate the log file for corresponding volume/brick. +.TP +\fB\ volume profile <VOLNAME> {start|info [peek|incremental [peek]|cumulative|clear]|stop} [nfs] \fR +Profile operations on the volume. Once started, volume profile <volname> info provides cumulative statistics of the FOPs performed. +.TP +\fB\ volume top <VOLNAME> {open|read|write|opendir|readdir|clear} [nfs|brick <brick>] [list-cnt <value>] | {read-perf|write-perf} [bs <size> count <count>] [brick <brick>] [list-cnt <value>] \fR +Generates a profile of a volume representing the performance and bottlenecks/hotspots of each brick. +.TP +\fB\ volume statedump <VOLNAME> [[nfs|quotad] [all|mem|iobuf|callpool|priv|fd|inode|history]... | [client <hostname:process-id>]] \fR +Dumps the in memory state of the specified process or the bricks of the volume. +.TP +\fB\ volume sync <HOSTNAME> [all|<VOLNAME>] \fR +Sync the volume information from a peer .SS "Peer Commands" .TP \fB\ peer probe <HOSTNAME> \fR @@ -103,23 +132,111 @@ Detach the specified peer. \fB\ peer status \fR Display the status of peers. .TP +\fB\ pool list \fR +List all the nodes in the pool (including localhost) +.TP \fB\ peer help \fR Display help for the peer command. +.SS "Quota Commands" +.TP +\fB\ volume quota <VOLNAME> enable \fR +Enable quota on the specified volume. This will cause all the directories in the filesystem hierarchy to be accounted and updated thereafter on each operation in the the filesystem. To kick start this accounting, a crawl is done over the hierarchy with an auxiliary client. +.TP +\fB\ volume quota <VOLNAME> disable \fR +Disable quota on the volume. This will disable enforcement and accounting in the filesystem. Any configured limits will be lost. +.TP +\fB\ volume quota <VOLNAME> limit-usage <PATH> <SIZE> [<PERCENT>] \fR +Set a usage limit on the given path. Any previously set limit is overridden to the new value. The soft limit can optionally be specified (as a percentage of hard limit). If soft limit percentage is not provided the default soft limit value for the volume is used to decide the soft limit. +.TP +\fB\ volume quota <VOLNAME> limit-objects <PATH> <SIZE> [<PERCENT>] \fR +Set an inode limit on the given path. Any previously set limit is overridden to the new value. The soft limit can optionally be specified (as a percentage of hard limit). If soft limit percentage is not provided the default soft limit value for the volume is used to decide the soft limit. +.TP +NOTE: valid units of SIZE are : B, KB, MB, GB, TB, PB. If no unit is specified, the unit defaults to bytes. +.TP +\fB\ volume quota <VOLNAME> remove <PATH> \fR +Remove any usage limit configured on the specified directory. Note that if any limit is configured on the ancestors of this directory (previous directories along the path), they will still be honored and enforced. +.TP +\fB\ volume quota <VOLNAME> remove-objects <PATH> \fR +Remove any inode limit configured on the specified directory. Note that if any limit is configured on the ancestors of this directory (previous directories along the path), they will still be honored and enforced. +.TP +\fB\ volume quota <VOLNAME> list <PATH> \fR +Lists the usage and limits configured on directory(s). If a path is given only the limit that has been configured on the directory(if any) is displayed along with the directory's usage. If no path is given, usage and limits are displayed for all directories that has limits configured. +.TP +\fB\ volume quota <VOLNAME> list-objects <PATH> \fR +Lists the inode usage and inode limits configured on directory(s). If a path is given only the limit that has been configured on the directory(if any) is displayed along with the directory's inode usage. If no path is given, usage and limits are displayed for all directories that has limits configured. +.TP +\fB\ volume quota <VOLNAME> default-soft-limit <PERCENT> \fR +Set the percentage value for default soft limit for the volume. +.TP +\fB\ volume quota <VOLNAME> soft-timeout <TIME> \fR +Set the soft timeout for the volume. The interval in which limits are retested before the soft limit is breached. +.TP +\fB\ volume quota <VOLNAME> hard-timeout <TIME> \fR +Set the hard timeout for the volume. The interval in which limits are retested after the soft limit is breached. +.TP +\fB\ volume quota <VOLNAME> alert-time <TIME> \fR +Set the frequency in which warning messages need to be logged (in the brick logs) once soft limit is breached. +.TP +\fB\ volume inode-quota <VOLNAME> enable/disable \fR +Enable/disable inode-quota for <VOLNAME> +.TP +\fB\ volume quota help \fR +Display help for volume quota commands +.TP +NOTE: valid units of time and their symbols are : hours(h/hr), minutes(m/min), seconds(s/sec), weeks(w/wk), Days(d/days). +.SS "Geo-replication Commands" +.TP +\fI\ Note\fR: password-less ssh, from the master node (where these commands are executed) to the slave node <SLAVE_HOST>, is a prerequisite for the geo-replication commands. +.TP +\fB\ system:: execute gsec_create\fR +Generates pem keys which are required for push-pem +.TP +\fB\ volume geo-replication <MASTER_VOL> <SLAVE_HOST>::<SLAVE_VOL> create [[ssh-port n][[no-verify]|[push-pem]]] [force]\fR +Create a new geo-replication session from <MASTER_VOL> to <SLAVE_HOST> host machine having <SLAVE_VOL>. +Use ssh-port n if custom SSH port is configured in slave nodes. +Use no-verify if the rsa-keys of nodes in master volume is distributed to slave nodes through an external agent. +Use push-pem to push the keys automatically. +.TP +\fB\ volume geo-replication <MASTER_VOL> <SLAVE_HOST>::<SLAVE_VOL> {start|stop} [force] \fR +Start/stop the geo-replication session from <MASTER_VOL> to <SLAVE_HOST> host machine having <SLAVE_VOL>. +.TP +\fB\ volume geo-replication [<MASTER_VOL> [<SLAVE_HOST>::<SLAVE_VOL>]] status [detail] \fR +Query status of the geo-replication session from <MASTER_VOL> to <SLAVE_HOST> host machine having <SLAVE_VOL>. +.TP +\fB\ volume geo-replication <MASTER_VOL> <SLAVE_HOST>::<SLAVE_VOL> {pause|resume} [force] \fR +Pause/resume the geo-replication session from <MASTER_VOL> to <SLAVE_HOST> host machine having <SLAVE_VOL>. +.TP +\fB\ volume geo-replication <MASTER_VOL> <SLAVE_HOST>::<SLAVE_VOL> delete [reset-sync-time]\fR +Delete the geo-replication session from <MASTER_VOL> to <SLAVE_HOST> host machine having <SLAVE_VOL>. +Optionally you can also reset the sync time in case you need to resync the entire volume on session recreate. +.TP +\fB\ volume geo-replication <MASTER_VOL> <SLAVE_HOST>::<SLAVE_VOL> config [[!]<options> [<value>]] \fR +View (when no option provided) or set configuration for this geo-replication session. +Use "!<OPTION>" to reset option <OPTION> to default value. .SS "Bitrot Commands" .TP \fB\ volume bitrot <VOLNAME> {enable|disable} \fR Enable/disable bitrot for volume <VOLNAME> .TP +\fB\ volume bitrot <VOLNAME> signing-time <time-in-secs> \fR +Waiting time for an object after last fd is closed to start signing process. +.TP +\fB\ volume bitrot <VOLNAME> signer-threads <count> \fR +Number of signing process threads. Usually set to number of available cores. +.TP \fB\ volume bitrot <VOLNAME> scrub-throttle {lazy|normal|aggressive} \fR Scrub-throttle value is a measure of how fast or slow the scrubber scrubs the filesystem for volume <VOLNAME> .TP -\fB\ volume bitrot <VOLNAME> scrub-frequency {daily|weekly|biweekly|monthly} \fR +\fB\ volume bitrot <VOLNAME> scrub-frequency {hourly|daily|weekly|biweekly|monthly} \fR Scrub frequency for volume <VOLNAME> .TP -\fB\ volume bitrot <VOLNAME> scrub {pause|resume} \fR -Pause/Resume scrub. Upon resume, scrubber continues where it left off. +\fB\ volume bitrot <VOLNAME> scrub {pause|resume|status|ondemand} \fR +Pause/Resume scrub. Upon resume, scrubber continues where it left off. status option shows the statistics of scrubber. ondemand option starts the scrubbing immediately if the scrubber is not paused or already running. +.TP +\fB\ volume bitrot help \fR +Display help for volume bitrot commands +.TP .SS "Snapshot Commands" -.PP .TP \fB\ snapshot create <snapname> <volname> [no-timestamp] [description <description>] [force] \fR Creates a snapshot of a GlusterFS volume. User can provide a snap-name and a description to identify the snap. Snap will be created by appending timestamp in GMT. User can override this behaviour using "no-timestamp" option. The description cannot be more than 1024 characters. To be able to take a snapshot, volume should be present and it should be in started state. @@ -176,8 +293,55 @@ Deactivates the mentioned snapshot. .TP \fB\ snapshot help \fR Display help for the snapshot commands. +.SS "Self-heal Commands" +.TP +\fB\ volume heal <VOLNAME>\fR +Triggers index self heal for the files that need healing. + +.TP +\fB\ volume heal <VOLNAME> [enable | disable]\fR +Enable/disable self-heal-daemon for volume <VOLNAME>. + +.TP +\fB\ volume heal <VOLNAME> full\fR +Triggers self heal on all the files. + +.TP +\fB\ volume heal <VOLNAME> info \fR +Lists the files that need healing. + +.TP +\fB\ volume heal <VOLNAME> info split-brain \fR +Lists the files which are in split-brain state. + +.TP +\fB\ volume heal <VOLNAME> statistics \fR +Lists the crawl statistics. + +.TP +\fB\ volume heal <VOLNAME> statistics heal-count \fR +Displays the count of files to be healed. + +.TP +\fB\ volume heal <VOLNAME> statistics heal-count replica <HOSTNAME:BRICKNAME> \fR +Displays the number of files to be healed from a particular replica subvolume to which the brick <HOSTNAME:BRICKNAME> belongs. + +.TP +\fB\ volume heal <VOLNAME> split-brain bigger-file <FILE> \fR +Performs healing of <FILE> which is in split-brain by choosing the bigger file in the replica as source. + +.TP +\fB\ volume heal <VOLNAME> split-brain source-brick <HOSTNAME:BRICKNAME> \fR +Selects <HOSTNAME:BRICKNAME> as the source for all the files that are in split-brain in that replica and heals them. + +.TP +\fB\ volume heal <VOLNAME> split-brain source-brick <HOSTNAME:BRICKNAME> <FILE> \fR +Selects the split-brained <FILE> present in <HOSTNAME:BRICKNAME> as source and completes heal. .SS "Other Commands" .TP +\fB\ get-state [<daemon>] [[odir </path/to/output/dir/>] [file <filename>]] [detail|volumeoptions] \fR +Get local state representation of mentioned daemon and store data in provided path information +.TP \fB\ help \fR Display the command options. .TP diff --git a/doc/glusterd.8 b/doc/glusterd.8 index 04a43481eec..e3768c78761 100644 --- a/doc/glusterd.8 +++ b/doc/glusterd.8 @@ -30,6 +30,9 @@ File to use for logging. \fB\-L <LOGLEVEL>, \fB\-\-log\-level=<LOGLEVEL>\fR Logging severity. Valid options are TRACE, DEBUG, INFO, WARNING, ERROR and CRITICAL (the default is INFO). .TP +\fB\-\-localtime\-logging\fR +Enable localtime log timestamps. +.TP \fB\-\-debug\fR Run the program in debug mode. This option sets \fB\-\-no\-daemon\fR, \fB\-\-log\-level\fR to DEBUG and \fB\-\-log\-file\fR to console. diff --git a/doc/glusterfs.8 b/doc/glusterfs.8 index fc28ef68be6..3d359ea85e4 100644 --- a/doc/glusterfs.8 +++ b/doc/glusterfs.8 @@ -53,6 +53,9 @@ Maximum number of connect attempts to server. This option should be provided wit \fB\-\-acl\fR Mount the filesystem with POSIX ACL support. .TP +\fB\-\-localtime\-logging\fR +Enable localtime log timestamps. +.TP \fB\-\-debug\fR Run in debug mode. This option sets \fB\-\-no\-daemon\fR, \fB\-\-log\-level\fR to DEBUG, and \fB\-\-log\-file\fR to console. @@ -60,8 +63,8 @@ and \fB\-\-log\-file\fR to console. \fB\-\-enable\-ino32=BOOL\fR Use 32-bit inodes when mounting to workaround application that doesn't support 64-bit inodes. .TP -\fB\-\-fopen\-keep\-cache\fR -Do not purge the cache on file open. +\fB\-\-fopen\-keep\-cache[=BOOL]\fR +Do not purge the cache on file open (default: false). .TP \fB\-\-mac\-compat=BOOL\fR Provide stubs for attributes needed for seamless operation on Macs (the default is off). @@ -98,11 +101,17 @@ Mount the filesystem in 'worm' mode. .TP \fB\-\-xlator\-option=VOLUME\-NAME.OPTION=VALUE\fR Add/Override a translator option for a volume with the specified value. +.TP +\fB\-\-subdir\-mount=SUBDIR\-MOUNT\-PATH\fR +Mount subdirectory instead of the '/' of volume. .SS "Fuse options" .PP .TP +\fB\-\-attr\-times\-granularity=NANOSECONDS\fR +Declare supported granularity of file attribute times (default is 0 which kernel handles as unspecified; valid real values are between 1 and 1000000000). +.TP \fB\-\-attribute\-timeout=SECONDS\fR Set attribute timeout to SECONDS for inodes in fuse kernel module (the default is 1). .TP @@ -112,8 +121,8 @@ Set fuse module's background queue length to N (the default is 64). \fB\-\-congestion\-threshold=N\fR Set fuse module's congestion threshold to N (the default is 48). .TP -\fB\-\-direct\-io\-mode=BOOL\fR -Enable/Disable the direct-I/O mode in fuse module (the default is enable). +\fB\-\-direct\-io\-mode=BOOL|auto\fR +Specify fuse direct I/O strategy (the default is auto). .TP \fB\-\-dump-fuse=PATH\f\R Dump fuse traffic to PATH @@ -124,9 +133,17 @@ Set entry timeout to SECONDS in fuse kernel module (the default is 1). \fB\-\-gid\-timeout=SECONDS\fR Set auxiliary group list timeout to SECONDS for fuse translator (the default is 0). .TP +\fB\-\-kernel-writeback-cache=BOOL\fR +Enable fuse in-kernel writeback cache. +.TP \fB\-\-negative\-timeout=SECONDS\fR Set negative timeout to SECONDS in fuse kernel module (the default is 0). .TP +\fB\-\-auto\-invalidation=BOOL\fR +controls whether fuse-kernel can auto-invalidate attribute, dentry and +page-cache. Disable this only if same files/directories are not +accessed across two different mounts concurrently [default: on]. +.TP \fB\-\-volfile-check\fR Enable strict volume file checking. diff --git a/doc/glusterfsd.8 b/doc/glusterfsd.8 index 88b667cb463..bc1de2a8c80 100644 --- a/doc/glusterfsd.8 +++ b/doc/glusterfsd.8 @@ -51,6 +51,9 @@ Server to get the volume from. This option overrides \fB\-\-volfile option .PP .TP +\fB\-\-localtime\-logging\fR +Enable localtime log timestamps. +.TP \fB\-\-debug\fR Run in debug mode. This option sets \fB\-\-no\-daemon\fR, \fB\-\-log\-level\fR to DEBUG and \fB\-\-log\-file\fR to console @@ -103,7 +106,12 @@ Set entry timeout to SECONDS in fuse kernel module [default: 1] Enable/Disable direct-io mode in fuse module [default: enable] .TP \fB\-\-resolve-gids\fR -Resolve all auxilary groups in fuse translator (max 32 otherwise) +Resolve all auxiliary groups in fuse translator (max 32 otherwise) +.TP +\fB\-\-auto\-invalidation=BOOL\fR +controls whether fuse-kernel can auto-invalidate attribute, dentry and +page-cache. Disable this only if same files/directories are not +accessed across two different mounts concurrently [default: on] .SS "Miscellaneous Options" .PP diff --git a/doc/legacy/Makefile.am b/doc/legacy/Makefile.am deleted file mode 100644 index b2caabaa2f3..00000000000 --- a/doc/legacy/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -info_TEXINFOS = user-guide.texi -CLEANFILES = *~ -DISTCLEANFILES = .deps/*.P *.info *vti diff --git a/doc/legacy/advanced-stripe.odg b/doc/legacy/advanced-stripe.odg Binary files differdeleted file mode 100644 index 7686d7091b2..00000000000 --- a/doc/legacy/advanced-stripe.odg +++ /dev/null diff --git a/doc/legacy/advanced-stripe.pdf b/doc/legacy/advanced-stripe.pdf Binary files differdeleted file mode 100644 index ec8b03dcfbb..00000000000 --- a/doc/legacy/advanced-stripe.pdf +++ /dev/null diff --git a/doc/legacy/authentication.txt b/doc/legacy/authentication.txt deleted file mode 100644 index 036a9df9908..00000000000 --- a/doc/legacy/authentication.txt +++ /dev/null @@ -1,112 +0,0 @@ - -* Authentication is provided by two modules addr and login. Login based authentication uses username/password from client for authentication. Each module returns either ACCEPT, REJCET or DONT_CARE. DONT_CARE is returned if the input authentication information to the module is not concerned to its working. The theory behind authentication is that "none of the auth modules should return REJECT and atleast one of them should return ACCEPT" - -* Currently all the authentication related information is passed un-encrypted over the network from client to server. - ----------------------------------------------------------------------------------------------------- -* options provided in protocol/client: - * for username/password based authentication: - option username <username> - option password <password> - * client can have only one set of username/password - * for addr based authentication: - * no options required in protocol/client. Client has to bind to privileged port (port < 1024 ) which means the process in which protocol/client is loaded has to be run as root. - ----------------------------------------------------------------------------------------------------- -* options provided in protocol/server: - * for username/password based authentication: - option auth.login.<brick>.allow [comma separated list of usernames using which clients can connect to volume <brick>] - option auth.login.<username>.password <password> #specify password <password> for username <username> - * for addr based authentication: - option auth.addr.<brick>.allow [comma separated list of ip-addresses/unix-paths from which clients are allowed to connect to volume <brick>] - option auth.addr.<brick>.reject [comma separated list of ip-addresses/unix-paths from which clients are not allowed to connect to volume <brick>] - * negation operator '!' is used to invert the sense of matching. - Eg., option auth.addr.brick.allow !a.b.c.d #do not allow client from a.b.c.d to connect to volume brick - option auth.addr.brick.reject !w.x.y.z #allow client from w.x.y.z to connect to volume brick - * wildcard '*' can be used to match any ip-address/unix-path - ----------------------------------------------------------------------------------------------------- - -* Usecases: - -* username/password based authentication only - protocol/client: - option username foo - option password foo-password - option remote-subvolume foo-brick - - protocol/server: - option auth.login.foo-brick.allow foo,who #,other users allowed to connect to foo-brick - option auth.login.foo.password foo-password - option auth.login.who.password who-password - - * in protocol/server, dont specify ip from which client is connecting in auth.addr.foo-brick.reject list - -**************************************************************************************************** - -* ip based authentication only - protocol/client: - option remote-subvolume foo-brick - * Client is connecting from a.b.c.d - - protocol/server: - option auth.addr.foo-brick.allow a.b.c.d,e.f.g.h,i.j.k.l #, other ip addresses from which clients are allowed to connect to foo-brick - -**************************************************************************************************** -* ip and username/password based authentication - * allow only "user foo from a.b.c.d" - protocol/client: - option username foo - option password foo-password - option remote-subvolume foo-brick - - protocol/server: - option auth.login.foo-brick.allow foo - option auth.login.foo.password foo-password - option auth.addr.foo-brick.reject !a.b.c.d - - * allow only "user foo" from a.b.c.d i.e., only user foo is allowed from a.b.c.d, but anyone is allowed from ip addresses other than a.b.c.d - protocol/client: - option username foo - option password foo-password - option remote-subvolume foo-brick - - protocol/server: - option auth.login.foo-brick.allow foo - option auth.login.foo.password foo-password - option auth.addr.foo-brick.allow !a.b.c.d - - * reject only "user shoo from a.b.c.d" - protcol/client: - option remote-subvolume shoo-brick - - protocol/server: - # observe that no "option auth.login.shoo-brick.allow shoo" given - # Also other users from a.b.c.d have to be explicitly allowed using auth.login.shoo-brick.allow ... - option auth.addr.shoo-brick.allow !a.b.c.d - - * reject only "user shoo" from a.b.c.d i.e., user shoo from a.b.c.d has to be rejected. - * same as reject only "user shoo from a.b.c.d" above, but rules have to be added whether to allow ip addresses (and users from those ips) other than a.b.c.d - -**************************************************************************************************** - -* ip or username/password based authentication - - * allow user foo or clients from a.b.c.d - protocol/client: - option remote-subvolume foo-brick - - protocol/server: - option auth.login.foo-brick.allow foo - option auth.login.foo.password foo-password - option auth.addr.foo-brick.allow a.b.c.d - - * reject user shoo or clients from a.b.c.d - protocol/client: - option remote-subvolume shoo-brick - - protocol/server: - option auth.login.shoo-brick.allow <usernames other than shoo> - #for each username mentioned in the above <usernames other than shoo> list, specify password as below - option auth.login.<username other than shoo>.password password - option auth.addr.shoo-brick.reject a.b.c.d diff --git a/doc/legacy/booster.txt b/doc/legacy/booster.txt deleted file mode 100644 index 051401a28fc..00000000000 --- a/doc/legacy/booster.txt +++ /dev/null @@ -1,54 +0,0 @@ -Introduction -============ -* booster is a LD_PRELOADable library which boosts read/write performance by bypassing fuse for - read() and write() calls. - -Requirements -============ -* fetch volfile from glusterfs. -* identify whether multiple files are from the same mount point. If so, use only one context. - -Design -====== -* for a getxattr, along with other attributes, fuse returns following attributes. - * contents of client volume-file. - * mount point. - -* LD_PRELOADed booster.so maintains an hash table storing mount-points and libglusterfsclient handles - so that handles are reused for files from same mount point. - -* it also maintains a fdtable. fdtable maps the fd (integer) returned to application to fd (pointer to fd struct) - used by libglusterfsclient. application is returned the same fd as the one returned from libc apis. - -* During fork, these tables are overwritten to enable creation of fresh glusterfs context in child. - -Working -======= -* application willing to use booster LD_PRELOADs booster.so which is a wrapper library implementing - open, read and write. - -* application should specify the path to logfile through the environment variable GLFS_BOOSTER_LOGFILE. If - not specified, logging is done to /dev/stderr. - -* open call does, - * real_open on the file. - * fgetxattr(fd). - * store the volume-file content got in the dictionary to a temporary file. - * look in the hashtable for the mount-point, if already present get the libglusterfsclient handle from the - hashtable. Otherwise get a new handle from libglusterfsclient (be careful about mount point not present in - the hashtable and multiple glusterfs_inits running simultaneously for the same mount-point there by using - multiple handles for the same mount point). - * real_close (fd). - * delete temporary volume-volfile. - * glusterfs_open (handle, path, mode). - * store the fd returned by glusterfs_open in the fdtable at the same index as the fd returned by real_open. - * return the index as fd. - -* read/write calls do, - * get the libglusterfsclient fd from fdtable. - * if found use glusterfs_read/glusterfs_write, else use real_read/real_write. - -* close call does, - * remove the fd from the fdtable. - -* other calls use real_calls. diff --git a/doc/legacy/colonO-icon.jpg b/doc/legacy/colonO-icon.jpg Binary files differdeleted file mode 100644 index 3e66f7a2775..00000000000 --- a/doc/legacy/colonO-icon.jpg +++ /dev/null diff --git a/doc/legacy/errno.list.bsd.txt b/doc/legacy/errno.list.bsd.txt deleted file mode 100644 index 350af25e4ab..00000000000 --- a/doc/legacy/errno.list.bsd.txt +++ /dev/null @@ -1,376 +0,0 @@ -/*- - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)errno.h 8.5 (Berkeley) 1/21/94 - * $FreeBSD: src/sys/sys/errno.h,v 1.28 2005/04/02 12:33:28 das Exp $ - */ - -#ifndef _SYS_ERRNO_H_ -#define _SYS_ERRNO_H_ - -#ifndef _KERNEL -#include <sys/cdefs.h> -__BEGIN_DECLS -int * __error(void); -__END_DECLS -#define errno (* __error()) -#endif - -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* Input/output error */ -#define ENXIO 6 /* Device not configured */ -#define E2BIG 7 /* Argument list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file descriptor */ -#define ECHILD 10 /* No child processes */ -#define EDEADLK 11 /* Resource deadlock avoided */ - /* 11 was EAGAIN */ -#define ENOMEM 12 /* Cannot allocate memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#ifndef _POSIX_SOURCE -#define ENOTBLK 15 /* Block device required */ -#endif -#define EBUSY 16 /* Device busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* Operation not supported by device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* Too many open files in system */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Inappropriate ioctl for device */ -#ifndef _POSIX_SOURCE -#define ETXTBSY 26 /* Text file busy */ -#endif -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only filesystem */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ - -/* math software */ -#define EDOM 33 /* Numerical argument out of domain */ -#define ERANGE 34 /* Result too large */ - -/* non-blocking and interrupt i/o */ -#define EAGAIN 35 /* Resource temporarily unavailable */ -#ifndef _POSIX_SOURCE -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define EINPROGRESS 36 /* Operation now in progress */ -#define EALREADY 37 /* Operation already in progress */ - -/* ipc/network software -- argument errors */ -#define ENOTSOCK 38 /* Socket operation on non-socket */ -#define EDESTADDRREQ 39 /* Destination address required */ -#define EMSGSIZE 40 /* Message too long */ -#define EPROTOTYPE 41 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 42 /* Protocol not available */ -#define EPROTONOSUPPORT 43 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ -#define EOPNOTSUPP 45 /* Operation not supported */ -#define ENOTSUP EOPNOTSUPP /* Operation not supported */ -#define EPFNOSUPPORT 46 /* Protocol family not supported */ -#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ -#define EADDRINUSE 48 /* Address already in use */ -#define EADDRNOTAVAIL 49 /* Can't assign requested address */ - -/* ipc/network software -- operational errors */ -#define ENETDOWN 50 /* Network is down */ -#define ENETUNREACH 51 /* Network is unreachable */ -#define ENETRESET 52 /* Network dropped connection on reset */ -#define ECONNABORTED 53 /* Software caused connection abort */ -#define ECONNRESET 54 /* Connection reset by peer */ -#define ENOBUFS 55 /* No buffer space available */ -#define EISCONN 56 /* Socket is already connected */ -#define ENOTCONN 57 /* Socket is not connected */ -#define ESHUTDOWN 58 /* Can't send after socket shutdown */ -#define ETOOMANYREFS 59 /* Too many references: can't splice */ -#define ETIMEDOUT 60 /* Operation timed out */ -#define ECONNREFUSED 61 /* Connection refused */ - -#define ELOOP 62 /* Too many levels of symbolic links */ -#endif /* _POSIX_SOURCE */ -#define ENAMETOOLONG 63 /* File name too long */ - -/* should be rearranged */ -#ifndef _POSIX_SOURCE -#define EHOSTDOWN 64 /* Host is down */ -#define EHOSTUNREACH 65 /* No route to host */ -#endif /* _POSIX_SOURCE */ -#define ENOTEMPTY 66 /* Directory not empty */ - -/* quotas & mush */ -#ifndef _POSIX_SOURCE -#define EPROCLIM 67 /* Too many processes */ -#define EUSERS 68 /* Too many users */ -#define EDQUOT 69 /* Disc quota exceeded */ - -/* Network File System */ -#define ESTALE 70 /* Stale NFS file handle */ -#define EREMOTE 71 /* Too many levels of remote in path */ -#define EBADRPC 72 /* RPC struct is bad */ -#define ERPCMISMATCH 73 /* RPC version wrong */ -#define EPROGUNAVAIL 74 /* RPC prog. not avail */ -#define EPROGMISMATCH 75 /* Program version wrong */ -#define EPROCUNAVAIL 76 /* Bad procedure for program */ -#endif /* _POSIX_SOURCE */ - -#define ENOLCK 77 /* No locks available */ -#define ENOSYS 78 /* Function not implemented */ - -#ifndef _POSIX_SOURCE -#define EFTYPE 79 /* Inappropriate file type or format */ -#define EAUTH 80 /* Authentication error */ -#define ENEEDAUTH 81 /* Need authenticator */ -#define EIDRM 82 /* Identifier removed */ -#define ENOMSG 83 /* No message of desired type */ -#define EOVERFLOW 84 /* Value too large to be stored in data type */ -#define ECANCELED 85 /* Operation canceled */ -#define EILSEQ 86 /* Illegal byte sequence */ -#define ENOATTR 87 /* Attribute not found */ - -#define EDOOFUS 88 /* Programming error */ -#endif /* _POSIX_SOURCE */ - -#define EBADMSG 89 /* Bad message */ -#define EMULTIHOP 90 /* Multihop attempted */ -#define ENOLINK 91 /* Link has been severed */ -#define EPROTO 92 /* Protocol error */ - -#ifndef _POSIX_SOURCE -#define ELAST 92 /* Must be equal largest errno */ -#endif /* _POSIX_SOURCE */ - -#ifdef _KERNEL -/* pseudo-errors returned inside kernel to modify return to process */ -#define ERESTART (-1) /* restart syscall */ -#define EJUSTRETURN (-2) /* don't modify regs, just return */ -#define ENOIOCTL (-3) /* ioctl not handled by this layer */ -#define EDIRIOCTL (-4) /* do direct ioctl in GEOM */ -#endif - -#endif -/*- - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)errno.h 8.5 (Berkeley) 1/21/94 - * $FreeBSD: src/sys/sys/errno.h,v 1.28 2005/04/02 12:33:28 das Exp $ - */ - -#ifndef _SYS_ERRNO_H_ -#define _SYS_ERRNO_H_ - -#ifndef _KERNEL -#include <sys/cdefs.h> -__BEGIN_DECLS -int * __error(void); -__END_DECLS -#define errno (* __error()) -#endif - -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* Input/output error */ -#define ENXIO 6 /* Device not configured */ -#define E2BIG 7 /* Argument list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file descriptor */ -#define ECHILD 10 /* No child processes */ -#define EDEADLK 11 /* Resource deadlock avoided */ - /* 11 was EAGAIN */ -#define ENOMEM 12 /* Cannot allocate memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#ifndef _POSIX_SOURCE -#define ENOTBLK 15 /* Block device required */ -#endif -#define EBUSY 16 /* Device busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* Operation not supported by device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* Too many open files in system */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Inappropriate ioctl for device */ -#ifndef _POSIX_SOURCE -#define ETXTBSY 26 /* Text file busy */ -#endif -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only filesystem */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ - -/* math software */ -#define EDOM 33 /* Numerical argument out of domain */ -#define ERANGE 34 /* Result too large */ - -/* non-blocking and interrupt i/o */ -#define EAGAIN 35 /* Resource temporarily unavailable */ -#ifndef _POSIX_SOURCE -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define EINPROGRESS 36 /* Operation now in progress */ -#define EALREADY 37 /* Operation already in progress */ - -/* ipc/network software -- argument errors */ -#define ENOTSOCK 38 /* Socket operation on non-socket */ -#define EDESTADDRREQ 39 /* Destination address required */ -#define EMSGSIZE 40 /* Message too long */ -#define EPROTOTYPE 41 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 42 /* Protocol not available */ -#define EPROTONOSUPPORT 43 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ -#define EOPNOTSUPP 45 /* Operation not supported */ -#define ENOTSUP EOPNOTSUPP /* Operation not supported */ -#define EPFNOSUPPORT 46 /* Protocol family not supported */ -#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ -#define EADDRINUSE 48 /* Address already in use */ -#define EADDRNOTAVAIL 49 /* Can't assign requested address */ - -/* ipc/network software -- operational errors */ -#define ENETDOWN 50 /* Network is down */ -#define ENETUNREACH 51 /* Network is unreachable */ -#define ENETRESET 52 /* Network dropped connection on reset */ -#define ECONNABORTED 53 /* Software caused connection abort */ -#define ECONNRESET 54 /* Connection reset by peer */ -#define ENOBUFS 55 /* No buffer space available */ -#define EISCONN 56 /* Socket is already connected */ -#define ENOTCONN 57 /* Socket is not connected */ -#define ESHUTDOWN 58 /* Can't send after socket shutdown */ -#define ETOOMANYREFS 59 /* Too many references: can't splice */ -#define ETIMEDOUT 60 /* Operation timed out */ -#define ECONNREFUSED 61 /* Connection refused */ - -#define ELOOP 62 /* Too many levels of symbolic links */ -#endif /* _POSIX_SOURCE */ -#define ENAMETOOLONG 63 /* File name too long */ - -/* should be rearranged */ -#ifndef _POSIX_SOURCE -#define EHOSTDOWN 64 /* Host is down */ -#define EHOSTUNREACH 65 /* No route to host */ -#endif /* _POSIX_SOURCE */ -#define ENOTEMPTY 66 /* Directory not empty */ - -/* quotas & mush */ -#ifndef _POSIX_SOURCE -#define EPROCLIM 67 /* Too many processes */ -#define EUSERS 68 /* Too many users */ -#define EDQUOT 69 /* Disc quota exceeded */ - -/* Network File System */ -#define ESTALE 70 /* Stale NFS file handle */ -#define EREMOTE 71 /* Too many levels of remote in path */ -#define EBADRPC 72 /* RPC struct is bad */ -#define ERPCMISMATCH 73 /* RPC version wrong */ -#define EPROGUNAVAIL 74 /* RPC prog. not avail */ -#define EPROGMISMATCH 75 /* Program version wrong */ -#define EPROCUNAVAIL 76 /* Bad procedure for program */ -#endif /* _POSIX_SOURCE */ - -#define ENOLCK 77 /* No locks available */ -#define ENOSYS 78 /* Function not implemented */ - -#ifndef _POSIX_SOURCE -#define EFTYPE 79 /* Inappropriate file type or format */ -#define EAUTH 80 /* Authentication error */ -#define ENEEDAUTH 81 /* Need authenticator */ -#define EIDRM 82 /* Identifier removed */ -#define ENOMSG 83 /* No message of desired type */ -#define EOVERFLOW 84 /* Value too large to be stored in data type */ -#define ECANCELED 85 /* Operation canceled */ -#define EILSEQ 86 /* Illegal byte sequence */ -#define ENOATTR 87 /* Attribute not found */ - -#define EDOOFUS 88 /* Programming error */ -#endif /* _POSIX_SOURCE */ - -#define EBADMSG 89 /* Bad message */ -#define EMULTIHOP 90 /* Multihop attempted */ -#define ENOLINK 91 /* Link has been severed */ -#define EPROTO 92 /* Protocol error */ - -#ifndef _POSIX_SOURCE -#define ELAST 92 /* Must be equal largest errno */ -#endif /* _POSIX_SOURCE */ - -#ifdef _KERNEL -/* pseudo-errors returned inside kernel to modify return to process */ -#define ERESTART (-1) /* restart syscall */ -#define EJUSTRETURN (-2) /* don't modify regs, just return */ -#define ENOIOCTL (-3) /* ioctl not handled by this layer */ -#define EDIRIOCTL (-4) /* do direct ioctl in GEOM */ -#endif - -#endif diff --git a/doc/legacy/errno.list.linux.txt b/doc/legacy/errno.list.linux.txt deleted file mode 100644 index 3f3b18c46ec..00000000000 --- a/doc/legacy/errno.list.linux.txt +++ /dev/null @@ -1,1586 +0,0 @@ -#define ICONV_SUPPORTS_ERRNO 1 -#include <errno.h> -/* Error constants. Linux specific version. - Copyright (C) 1996, 1997, 1998, 1999, 2005 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifdef _ERRNO_H - -# undef EDOM -# undef EILSEQ -# undef ERANGE -# include <linux/errno.h> - -/* Linux has no ENOTSUP error code. */ -# define ENOTSUP EOPNOTSUPP - -/* Older Linux versions also had no ECANCELED error code. */ -# ifndef ECANCELED -# define ECANCELED 125 -# endif - -/* Support for error codes to support robust mutexes was added later, too. */ -# ifndef EOWNERDEAD -# define EOWNERDEAD 130 -# define ENOTRECOVERABLE 131 -# endif - -# ifndef __ASSEMBLER__ -/* Function to get address of global `errno' variable. */ -extern int *__errno_location (void) __THROW __attribute__ ((__const__)); - -# if !defined _LIBC || defined _LIBC_REENTRANT -/* When using threads, errno is a per-thread value. */ -# define errno (*__errno_location ()) -# endif -# endif /* !__ASSEMBLER__ */ -#endif /* _ERRNO_H */ - -#if !defined _ERRNO_H && defined __need_Emath -/* This is ugly but the kernel header is not clean enough. We must - define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is - defined. */ -# define EDOM 33 /* Math argument out of domain of function. */ -# define EILSEQ 84 /* Illegal byte sequence. */ -# define ERANGE 34 /* Math result not representable. */ -#endif /* !_ERRNO_H && __need_Emath */ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APR_ERRNO_H -#define APR_ERRNO_H - -/** - * @file apr_errno.h - * @brief APR Error Codes - */ - -#include "apr.h" - -#if APR_HAVE_ERRNO_H -#include <errno.h> -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * @defgroup apr_errno Error Codes - * @ingroup APR - * @{ - */ - -/** - * Type for specifying an error or status code. - */ -typedef int apr_status_t; - -/** - * Return a human readable string describing the specified error. - * @param statcode The error code the get a string for. - * @param buf A buffer to hold the error string. - * @param bufsize Size of the buffer to hold the string. - */ -APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf, - apr_size_t bufsize); - -#if defined(DOXYGEN) -/** - * @def APR_FROM_OS_ERROR(os_err_type syserr) - * Fold a platform specific error into an apr_status_t code. - * @return apr_status_t - * @param e The platform os error code. - * @warning macro implementation; the syserr argument may be evaluated - * multiple times. - */ -#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR) - -/** - * @def APR_TO_OS_ERROR(apr_status_t statcode) - * @return os_err_type - * Fold an apr_status_t code back to the native platform defined error. - * @param e The apr_status_t folded platform os error code. - * @warning macro implementation; the statcode argument may be evaluated - * multiple times. If the statcode was not created by apr_get_os_error - * or APR_FROM_OS_ERROR, the results are undefined. - */ -#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR) - -/** @def apr_get_os_error() - * @return apr_status_t the last platform error, folded into apr_status_t, on most platforms - * @remark This retrieves errno, or calls a GetLastError() style function, and - * folds it with APR_FROM_OS_ERROR. Some platforms (such as OS2) have no - * such mechanism, so this call may be unsupported. Do NOT use this - * call for socket errors from socket, send, recv etc! - */ - -/** @def apr_set_os_error(e) - * Reset the last platform error, unfolded from an apr_status_t, on some platforms - * @param e The OS error folded in a prior call to APR_FROM_OS_ERROR() - * @warning This is a macro implementation; the statcode argument may be evaluated - * multiple times. If the statcode was not created by apr_get_os_error - * or APR_FROM_OS_ERROR, the results are undefined. This macro sets - * errno, or calls a SetLastError() style function, unfolding statcode - * with APR_TO_OS_ERROR. Some platforms (such as OS2) have no such - * mechanism, so this call may be unsupported. - */ - -/** @def apr_get_netos_error() - * Return the last socket error, folded into apr_status_t, on all platforms - * @remark This retrieves errno or calls a GetLastSocketError() style function, - * and folds it with APR_FROM_OS_ERROR. - */ - -/** @def apr_set_netos_error(e) - * Reset the last socket error, unfolded from an apr_status_t - * @param e The socket error folded in a prior call to APR_FROM_OS_ERROR() - * @warning This is a macro implementation; the statcode argument may be evaluated - * multiple times. If the statcode was not created by apr_get_os_error - * or APR_FROM_OS_ERROR, the results are undefined. This macro sets - * errno, or calls a WSASetLastError() style function, unfolding - * socketcode with APR_TO_OS_ERROR. - */ - -#endif /* defined(DOXYGEN) */ - -/** - * APR_OS_START_ERROR is where the APR specific error values start. - */ -#define APR_OS_START_ERROR 20000 -/** - * APR_OS_ERRSPACE_SIZE is the maximum number of errors you can fit - * into one of the error/status ranges below -- except for - * APR_OS_START_USERERR, which see. - */ -#define APR_OS_ERRSPACE_SIZE 50000 -/** - * APR_OS_START_STATUS is where the APR specific status codes start. - */ -#define APR_OS_START_STATUS (APR_OS_START_ERROR + APR_OS_ERRSPACE_SIZE) -/** - * APR_OS_START_USERERR are reserved for applications that use APR that - * layer their own error codes along with APR's. Note that the - * error immediately following this one is set ten times farther - * away than usual, so that users of apr have a lot of room in - * which to declare custom error codes. - */ -#define APR_OS_START_USERERR (APR_OS_START_STATUS + APR_OS_ERRSPACE_SIZE) -/** - * APR_OS_START_USEERR is obsolete, defined for compatibility only. - * Use APR_OS_START_USERERR instead. - */ -#define APR_OS_START_USEERR APR_OS_START_USERERR -/** - * APR_OS_START_CANONERR is where APR versions of errno values are defined - * on systems which don't have the corresponding errno. - */ -#define APR_OS_START_CANONERR (APR_OS_START_USERERR \ - + (APR_OS_ERRSPACE_SIZE * 10)) -/** - * APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into - * apr_status_t values. - */ -#define APR_OS_START_EAIERR (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE) -/** - * APR_OS_START_SYSERR folds platform-specific system error values into - * apr_status_t values. - */ -#define APR_OS_START_SYSERR (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE) - -/** no error. */ -#define APR_SUCCESS 0 - -/** - * @defgroup APR_Error APR Error Values - * <PRE> - * <b>APR ERROR VALUES</b> - * APR_ENOSTAT APR was unable to perform a stat on the file - * APR_ENOPOOL APR was not provided a pool with which to allocate memory - * APR_EBADDATE APR was given an invalid date - * APR_EINVALSOCK APR was given an invalid socket - * APR_ENOPROC APR was not given a process structure - * APR_ENOTIME APR was not given a time structure - * APR_ENODIR APR was not given a directory structure - * APR_ENOLOCK APR was not given a lock structure - * APR_ENOPOLL APR was not given a poll structure - * APR_ENOSOCKET APR was not given a socket - * APR_ENOTHREAD APR was not given a thread structure - * APR_ENOTHDKEY APR was not given a thread key structure - * APR_ENOSHMAVAIL There is no more shared memory available - * APR_EDSOOPEN APR was unable to open the dso object. For more - * information call apr_dso_error(). - * APR_EGENERAL General failure (specific information not available) - * APR_EBADIP The specified IP address is invalid - * APR_EBADMASK The specified netmask is invalid - * APR_ESYMNOTFOUND Could not find the requested symbol - * </PRE> - * - * <PRE> - * <b>APR STATUS VALUES</b> - * APR_INCHILD Program is currently executing in the child - * APR_INPARENT Program is currently executing in the parent - * APR_DETACH The thread is detached - * APR_NOTDETACH The thread is not detached - * APR_CHILD_DONE The child has finished executing - * APR_CHILD_NOTDONE The child has not finished executing - * APR_TIMEUP The operation did not finish before the timeout - * APR_INCOMPLETE The operation was incomplete although some processing - * was performed and the results are partially valid - * APR_BADCH Getopt found an option not in the option string - * APR_BADARG Getopt found an option that is missing an argument - * and an argument was specified in the option string - * APR_EOF APR has encountered the end of the file - * APR_NOTFOUND APR was unable to find the socket in the poll structure - * APR_ANONYMOUS APR is using anonymous shared memory - * APR_FILEBASED APR is using a file name as the key to the shared memory - * APR_KEYBASED APR is using a shared key as the key to the shared memory - * APR_EINIT Ininitalizer value. If no option has been found, but - * the status variable requires a value, this should be used - * APR_ENOTIMPL The APR function has not been implemented on this - * platform, either because nobody has gotten to it yet, - * or the function is impossible on this platform. - * APR_EMISMATCH Two passwords do not match. - * APR_EABSOLUTE The given path was absolute. - * APR_ERELATIVE The given path was relative. - * APR_EINCOMPLETE The given path was neither relative nor absolute. - * APR_EABOVEROOT The given path was above the root path. - * APR_EBUSY The given lock was busy. - * APR_EPROC_UNKNOWN The given process wasn't recognized by APR - * </PRE> - * @{ - */ -/** @see APR_STATUS_IS_ENOSTAT */ -#define APR_ENOSTAT (APR_OS_START_ERROR + 1) -/** @see APR_STATUS_IS_ENOPOOL */ -#define APR_ENOPOOL (APR_OS_START_ERROR + 2) -/* empty slot: +3 */ -/** @see APR_STATUS_IS_EBADDATE */ -#define APR_EBADDATE (APR_OS_START_ERROR + 4) -/** @see APR_STATUS_IS_EINVALSOCK */ -#define APR_EINVALSOCK (APR_OS_START_ERROR + 5) -/** @see APR_STATUS_IS_ENOPROC */ -#define APR_ENOPROC (APR_OS_START_ERROR + 6) -/** @see APR_STATUS_IS_ENOTIME */ -#define APR_ENOTIME (APR_OS_START_ERROR + 7) -/** @see APR_STATUS_IS_ENODIR */ -#define APR_ENODIR (APR_OS_START_ERROR + 8) -/** @see APR_STATUS_IS_ENOLOCK */ -#define APR_ENOLOCK (APR_OS_START_ERROR + 9) -/** @see APR_STATUS_IS_ENOPOLL */ -#define APR_ENOPOLL (APR_OS_START_ERROR + 10) -/** @see APR_STATUS_IS_ENOSOCKET */ -#define APR_ENOSOCKET (APR_OS_START_ERROR + 11) -/** @see APR_STATUS_IS_ENOTHREAD */ -#define APR_ENOTHREAD (APR_OS_START_ERROR + 12) -/** @see APR_STATUS_IS_ENOTHDKEY */ -#define APR_ENOTHDKEY (APR_OS_START_ERROR + 13) -/** @see APR_STATUS_IS_EGENERAL */ -#define APR_EGENERAL (APR_OS_START_ERROR + 14) -/** @see APR_STATUS_IS_ENOSHMAVAIL */ -#define APR_ENOSHMAVAIL (APR_OS_START_ERROR + 15) -/** @see APR_STATUS_IS_EBADIP */ -#define APR_EBADIP (APR_OS_START_ERROR + 16) -/** @see APR_STATUS_IS_EBADMASK */ -#define APR_EBADMASK (APR_OS_START_ERROR + 17) -/* empty slot: +18 */ -/** @see APR_STATUS_IS_EDSOPEN */ -#define APR_EDSOOPEN (APR_OS_START_ERROR + 19) -/** @see APR_STATUS_IS_EABSOLUTE */ -#define APR_EABSOLUTE (APR_OS_START_ERROR + 20) -/** @see APR_STATUS_IS_ERELATIVE */ -#define APR_ERELATIVE (APR_OS_START_ERROR + 21) -/** @see APR_STATUS_IS_EINCOMPLETE */ -#define APR_EINCOMPLETE (APR_OS_START_ERROR + 22) -/** @see APR_STATUS_IS_EABOVEROOT */ -#define APR_EABOVEROOT (APR_OS_START_ERROR + 23) -/** @see APR_STATUS_IS_EBADPATH */ -#define APR_EBADPATH (APR_OS_START_ERROR + 24) -/** @see APR_STATUS_IS_EPATHWILD */ -#define APR_EPATHWILD (APR_OS_START_ERROR + 25) -/** @see APR_STATUS_IS_ESYMNOTFOUND */ -#define APR_ESYMNOTFOUND (APR_OS_START_ERROR + 26) -/** @see APR_STATUS_IS_EPROC_UNKNOWN */ -#define APR_EPROC_UNKNOWN (APR_OS_START_ERROR + 27) -/** @see APR_STATUS_IS_ENOTENOUGHENTROPY */ -#define APR_ENOTENOUGHENTROPY (APR_OS_START_ERROR + 28) -/** @} */ - -/** - * @defgroup APR_STATUS_IS Status Value Tests - * @warning For any particular error condition, more than one of these tests - * may match. This is because platform-specific error codes may not - * always match the semantics of the POSIX codes these tests (and the - * corresponding APR error codes) are named after. A notable example - * are the APR_STATUS_IS_ENOENT and APR_STATUS_IS_ENOTDIR tests on - * Win32 platforms. The programmer should always be aware of this and - * adjust the order of the tests accordingly. - * @{ - */ -/** - * APR was unable to perform a stat on the file - * @warning always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_ENOSTAT(s) ((s) == APR_ENOSTAT) -/** - * APR was not provided a pool with which to allocate memory - * @warning always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_ENOPOOL(s) ((s) == APR_ENOPOOL) -/** APR was given an invalid date */ -#define APR_STATUS_IS_EBADDATE(s) ((s) == APR_EBADDATE) -/** APR was given an invalid socket */ -#define APR_STATUS_IS_EINVALSOCK(s) ((s) == APR_EINVALSOCK) -/** APR was not given a process structure */ -#define APR_STATUS_IS_ENOPROC(s) ((s) == APR_ENOPROC) -/** APR was not given a time structure */ -#define APR_STATUS_IS_ENOTIME(s) ((s) == APR_ENOTIME) -/** APR was not given a directory structure */ -#define APR_STATUS_IS_ENODIR(s) ((s) == APR_ENODIR) -/** APR was not given a lock structure */ -#define APR_STATUS_IS_ENOLOCK(s) ((s) == APR_ENOLOCK) -/** APR was not given a poll structure */ -#define APR_STATUS_IS_ENOPOLL(s) ((s) == APR_ENOPOLL) -/** APR was not given a socket */ -#define APR_STATUS_IS_ENOSOCKET(s) ((s) == APR_ENOSOCKET) -/** APR was not given a thread structure */ -#define APR_STATUS_IS_ENOTHREAD(s) ((s) == APR_ENOTHREAD) -/** APR was not given a thread key structure */ -#define APR_STATUS_IS_ENOTHDKEY(s) ((s) == APR_ENOTHDKEY) -/** Generic Error which can not be put into another spot */ -#define APR_STATUS_IS_EGENERAL(s) ((s) == APR_EGENERAL) -/** There is no more shared memory available */ -#define APR_STATUS_IS_ENOSHMAVAIL(s) ((s) == APR_ENOSHMAVAIL) -/** The specified IP address is invalid */ -#define APR_STATUS_IS_EBADIP(s) ((s) == APR_EBADIP) -/** The specified netmask is invalid */ -#define APR_STATUS_IS_EBADMASK(s) ((s) == APR_EBADMASK) -/* empty slot: +18 */ -/** - * APR was unable to open the dso object. - * For more information call apr_dso_error(). - */ -#if defined(WIN32) -#define APR_STATUS_IS_EDSOOPEN(s) ((s) == APR_EDSOOPEN \ - || APR_TO_OS_ERROR(s) == ERROR_MOD_NOT_FOUND) -#else -#define APR_STATUS_IS_EDSOOPEN(s) ((s) == APR_EDSOOPEN) -#endif -/** The given path was absolute. */ -#define APR_STATUS_IS_EABSOLUTE(s) ((s) == APR_EABSOLUTE) -/** The given path was relative. */ -#define APR_STATUS_IS_ERELATIVE(s) ((s) == APR_ERELATIVE) -/** The given path was neither relative nor absolute. */ -#define APR_STATUS_IS_EINCOMPLETE(s) ((s) == APR_EINCOMPLETE) -/** The given path was above the root path. */ -#define APR_STATUS_IS_EABOVEROOT(s) ((s) == APR_EABOVEROOT) -/** The given path was bad. */ -#define APR_STATUS_IS_EBADPATH(s) ((s) == APR_EBADPATH) -/** The given path contained wildcards. */ -#define APR_STATUS_IS_EPATHWILD(s) ((s) == APR_EPATHWILD) -/** Could not find the requested symbol. - * For more information call apr_dso_error(). - */ -#if defined(WIN32) -#define APR_STATUS_IS_ESYMNOTFOUND(s) ((s) == APR_ESYMNOTFOUND \ - || APR_TO_OS_ERROR(s) == ERROR_PROC_NOT_FOUND) -#else -#define APR_STATUS_IS_ESYMNOTFOUND(s) ((s) == APR_ESYMNOTFOUND) -#endif -/** The given process was not recognized by APR. */ -#define APR_STATUS_IS_EPROC_UNKNOWN(s) ((s) == APR_EPROC_UNKNOWN) - -/** APR could not gather enough entropy to continue. */ -#define APR_STATUS_IS_ENOTENOUGHENTROPY(s) ((s) == APR_ENOTENOUGHENTROPY) - -/** @} */ - -/** - * @addtogroup APR_Error - * @{ - */ -/** @see APR_STATUS_IS_INCHILD */ -#define APR_INCHILD (APR_OS_START_STATUS + 1) -/** @see APR_STATUS_IS_INPARENT */ -#define APR_INPARENT (APR_OS_START_STATUS + 2) -/** @see APR_STATUS_IS_DETACH */ -#define APR_DETACH (APR_OS_START_STATUS + 3) -/** @see APR_STATUS_IS_NOTDETACH */ -#define APR_NOTDETACH (APR_OS_START_STATUS + 4) -/** @see APR_STATUS_IS_CHILD_DONE */ -#define APR_CHILD_DONE (APR_OS_START_STATUS + 5) -/** @see APR_STATUS_IS_CHILD_NOTDONE */ -#define APR_CHILD_NOTDONE (APR_OS_START_STATUS + 6) -/** @see APR_STATUS_IS_TIMEUP */ -#define APR_TIMEUP (APR_OS_START_STATUS + 7) -/** @see APR_STATUS_IS_INCOMPLETE */ -#define APR_INCOMPLETE (APR_OS_START_STATUS + 8) -/* empty slot: +9 */ -/* empty slot: +10 */ -/* empty slot: +11 */ -/** @see APR_STATUS_IS_BADCH */ -#define APR_BADCH (APR_OS_START_STATUS + 12) -/** @see APR_STATUS_IS_BADARG */ -#define APR_BADARG (APR_OS_START_STATUS + 13) -/** @see APR_STATUS_IS_EOF */ -#define APR_EOF (APR_OS_START_STATUS + 14) -/** @see APR_STATUS_IS_NOTFOUND */ -#define APR_NOTFOUND (APR_OS_START_STATUS + 15) -/* empty slot: +16 */ -/* empty slot: +17 */ -/* empty slot: +18 */ -/** @see APR_STATUS_IS_ANONYMOUS */ -#define APR_ANONYMOUS (APR_OS_START_STATUS + 19) -/** @see APR_STATUS_IS_FILEBASED */ -#define APR_FILEBASED (APR_OS_START_STATUS + 20) -/** @see APR_STATUS_IS_KEYBASED */ -#define APR_KEYBASED (APR_OS_START_STATUS + 21) -/** @see APR_STATUS_IS_EINIT */ -#define APR_EINIT (APR_OS_START_STATUS + 22) -/** @see APR_STATUS_IS_ENOTIMPL */ -#define APR_ENOTIMPL (APR_OS_START_STATUS + 23) -/** @see APR_STATUS_IS_EMISMATCH */ -#define APR_EMISMATCH (APR_OS_START_STATUS + 24) -/** @see APR_STATUS_IS_EBUSY */ -#define APR_EBUSY (APR_OS_START_STATUS + 25) -/** @} */ - -/** - * @addtogroup APR_STATUS_IS - * @{ - */ -/** - * Program is currently executing in the child - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code */ -#define APR_STATUS_IS_INCHILD(s) ((s) == APR_INCHILD) -/** - * Program is currently executing in the parent - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_INPARENT(s) ((s) == APR_INPARENT) -/** - * The thread is detached - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_DETACH(s) ((s) == APR_DETACH) -/** - * The thread is not detached - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_NOTDETACH(s) ((s) == APR_NOTDETACH) -/** - * The child has finished executing - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_CHILD_DONE(s) ((s) == APR_CHILD_DONE) -/** - * The child has not finished executing - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_CHILD_NOTDONE(s) ((s) == APR_CHILD_NOTDONE) -/** - * The operation did not finish before the timeout - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP) -/** - * The operation was incomplete although some processing was performed - * and the results are partially valid. - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_INCOMPLETE(s) ((s) == APR_INCOMPLETE) -/* empty slot: +9 */ -/* empty slot: +10 */ -/* empty slot: +11 */ -/** - * Getopt found an option not in the option string - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_BADCH(s) ((s) == APR_BADCH) -/** - * Getopt found an option not in the option string and an argument was - * specified in the option string - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_BADARG(s) ((s) == APR_BADARG) -/** - * APR has encountered the end of the file - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_EOF(s) ((s) == APR_EOF) -/** - * APR was unable to find the socket in the poll structure - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_NOTFOUND(s) ((s) == APR_NOTFOUND) -/* empty slot: +16 */ -/* empty slot: +17 */ -/* empty slot: +18 */ -/** - * APR is using anonymous shared memory - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_ANONYMOUS(s) ((s) == APR_ANONYMOUS) -/** - * APR is using a file name as the key to the shared memory - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_FILEBASED(s) ((s) == APR_FILEBASED) -/** - * APR is using a shared key as the key to the shared memory - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_KEYBASED(s) ((s) == APR_KEYBASED) -/** - * Ininitalizer value. If no option has been found, but - * the status variable requires a value, this should be used - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_EINIT(s) ((s) == APR_EINIT) -/** - * The APR function has not been implemented on this - * platform, either because nobody has gotten to it yet, - * or the function is impossible on this platform. - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_ENOTIMPL(s) ((s) == APR_ENOTIMPL) -/** - * Two passwords do not match. - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_EMISMATCH(s) ((s) == APR_EMISMATCH) -/** - * The given lock was busy - * @warning always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_EBUSY(s) ((s) == APR_EBUSY) - -/** @} */ - -/** - * @addtogroup APR_Error APR Error Values - * @{ - */ -/* APR CANONICAL ERROR VALUES */ -/** @see APR_STATUS_IS_EACCES */ -#ifdef EACCES -#define APR_EACCES EACCES -#else -#define APR_EACCES (APR_OS_START_CANONERR + 1) -#endif - -/** @see APR_STATUS_IS_EXIST */ -#ifdef EEXIST -#define APR_EEXIST EEXIST -#else -#define APR_EEXIST (APR_OS_START_CANONERR + 2) -#endif - -/** @see APR_STATUS_IS_ENAMETOOLONG */ -#ifdef ENAMETOOLONG -#define APR_ENAMETOOLONG ENAMETOOLONG -#else -#define APR_ENAMETOOLONG (APR_OS_START_CANONERR + 3) -#endif - -/** @see APR_STATUS_IS_ENOENT */ -#ifdef ENOENT -#define APR_ENOENT ENOENT -#else -#define APR_ENOENT (APR_OS_START_CANONERR + 4) -#endif - -/** @see APR_STATUS_IS_ENOTDIR */ -#ifdef ENOTDIR -#define APR_ENOTDIR ENOTDIR -#else -#define APR_ENOTDIR (APR_OS_START_CANONERR + 5) -#endif - -/** @see APR_STATUS_IS_ENOSPC */ -#ifdef ENOSPC -#define APR_ENOSPC ENOSPC -#else -#define APR_ENOSPC (APR_OS_START_CANONERR + 6) -#endif - -/** @see APR_STATUS_IS_ENOMEM */ -#ifdef ENOMEM -#define APR_ENOMEM ENOMEM -#else -#define APR_ENOMEM (APR_OS_START_CANONERR + 7) -#endif - -/** @see APR_STATUS_IS_EMFILE */ -#ifdef EMFILE -#define APR_EMFILE EMFILE -#else -#define APR_EMFILE (APR_OS_START_CANONERR + 8) -#endif - -/** @see APR_STATUS_IS_ENFILE */ -#ifdef ENFILE -#define APR_ENFILE ENFILE -#else -#define APR_ENFILE (APR_OS_START_CANONERR + 9) -#endif - -/** @see APR_STATUS_IS_EBADF */ -#ifdef EBADF -#define APR_EBADF EBADF -#else -#define APR_EBADF (APR_OS_START_CANONERR + 10) -#endif - -/** @see APR_STATUS_IS_EINVAL */ -#ifdef EINVAL -#define APR_EINVAL EINVAL -#else -#define APR_EINVAL (APR_OS_START_CANONERR + 11) -#endif - -/** @see APR_STATUS_IS_ESPIPE */ -#ifdef ESPIPE -#define APR_ESPIPE ESPIPE -#else -#define APR_ESPIPE (APR_OS_START_CANONERR + 12) -#endif - -/** - * @see APR_STATUS_IS_EAGAIN - * @warning use APR_STATUS_IS_EAGAIN instead of just testing this value - */ -#ifdef EAGAIN -#define APR_EAGAIN EAGAIN -#elif defined(EWOULDBLOCK) -#define APR_EAGAIN EWOULDBLOCK -#else -#define APR_EAGAIN (APR_OS_START_CANONERR + 13) -#endif - -/** @see APR_STATUS_IS_EINTR */ -#ifdef EINTR -#define APR_EINTR EINTR -#else -#define APR_EINTR (APR_OS_START_CANONERR + 14) -#endif - -/** @see APR_STATUS_IS_ENOTSOCK */ -#ifdef ENOTSOCK -#define APR_ENOTSOCK ENOTSOCK -#else -#define APR_ENOTSOCK (APR_OS_START_CANONERR + 15) -#endif - -/** @see APR_STATUS_IS_ECONNREFUSED */ -#ifdef ECONNREFUSED -#define APR_ECONNREFUSED ECONNREFUSED -#else -#define APR_ECONNREFUSED (APR_OS_START_CANONERR + 16) -#endif - -/** @see APR_STATUS_IS_EINPROGRESS */ -#ifdef EINPROGRESS -#define APR_EINPROGRESS EINPROGRESS -#else -#define APR_EINPROGRESS (APR_OS_START_CANONERR + 17) -#endif - -/** - * @see APR_STATUS_IS_ECONNABORTED - * @warning use APR_STATUS_IS_ECONNABORTED instead of just testing this value - */ - -#ifdef ECONNABORTED -#define APR_ECONNABORTED ECONNABORTED -#else -#define APR_ECONNABORTED (APR_OS_START_CANONERR + 18) -#endif - -/** @see APR_STATUS_IS_ECONNRESET */ -#ifdef ECONNRESET -#define APR_ECONNRESET ECONNRESET -#else -#define APR_ECONNRESET (APR_OS_START_CANONERR + 19) -#endif - -/** @see APR_STATUS_IS_ETIMEDOUT - * @deprecated */ -#ifdef ETIMEDOUT -#define APR_ETIMEDOUT ETIMEDOUT -#else -#define APR_ETIMEDOUT (APR_OS_START_CANONERR + 20) -#endif - -/** @see APR_STATUS_IS_EHOSTUNREACH */ -#ifdef EHOSTUNREACH -#define APR_EHOSTUNREACH EHOSTUNREACH -#else -#define APR_EHOSTUNREACH (APR_OS_START_CANONERR + 21) -#endif - -/** @see APR_STATUS_IS_ENETUNREACH */ -#ifdef ENETUNREACH -#define APR_ENETUNREACH ENETUNREACH -#else -#define APR_ENETUNREACH (APR_OS_START_CANONERR + 22) -#endif - -/** @see APR_STATUS_IS_EFTYPE */ -#ifdef EFTYPE -#define APR_EFTYPE EFTYPE -#else -#define APR_EFTYPE (APR_OS_START_CANONERR + 23) -#endif - -/** @see APR_STATUS_IS_EPIPE */ -#ifdef EPIPE -#define APR_EPIPE EPIPE -#else -#define APR_EPIPE (APR_OS_START_CANONERR + 24) -#endif - -/** @see APR_STATUS_IS_EXDEV */ -#ifdef EXDEV -#define APR_EXDEV EXDEV -#else -#define APR_EXDEV (APR_OS_START_CANONERR + 25) -#endif - -/** @see APR_STATUS_IS_ENOTEMPTY */ -#ifdef ENOTEMPTY -#define APR_ENOTEMPTY ENOTEMPTY -#else -#define APR_ENOTEMPTY (APR_OS_START_CANONERR + 26) -#endif - -/** @} */ - -#if defined(OS2) && !defined(DOXYGEN) - -#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR) -#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR) - -#define INCL_DOSERRORS -#define INCL_DOS - -/* Leave these undefined. - * OS2 doesn't rely on the errno concept. - * The API calls always return a result codes which - * should be filtered through APR_FROM_OS_ERROR(). - * - * #define apr_get_os_error() (APR_FROM_OS_ERROR(GetLastError())) - * #define apr_set_os_error(e) (SetLastError(APR_TO_OS_ERROR(e))) - */ - -/* A special case, only socket calls require this; - */ -#define apr_get_netos_error() (APR_FROM_OS_ERROR(errno)) -#define apr_set_netos_error(e) (errno = APR_TO_OS_ERROR(e)) - -/* And this needs to be greped away for good: - */ -#define APR_OS2_STATUS(e) (APR_FROM_OS_ERROR(e)) - -/* These can't sit in a private header, so in spite of the extra size, - * they need to be made available here. - */ -#define SOCBASEERR 10000 -#define SOCEPERM (SOCBASEERR+1) /* Not owner */ -#define SOCESRCH (SOCBASEERR+3) /* No such process */ -#define SOCEINTR (SOCBASEERR+4) /* Interrupted system call */ -#define SOCENXIO (SOCBASEERR+6) /* No such device or address */ -#define SOCEBADF (SOCBASEERR+9) /* Bad file number */ -#define SOCEACCES (SOCBASEERR+13) /* Permission denied */ -#define SOCEFAULT (SOCBASEERR+14) /* Bad address */ -#define SOCEINVAL (SOCBASEERR+22) /* Invalid argument */ -#define SOCEMFILE (SOCBASEERR+24) /* Too many open files */ -#define SOCEPIPE (SOCBASEERR+32) /* Broken pipe */ -#define SOCEOS2ERR (SOCBASEERR+100) /* OS/2 Error */ -#define SOCEWOULDBLOCK (SOCBASEERR+35) /* Operation would block */ -#define SOCEINPROGRESS (SOCBASEERR+36) /* Operation now in progress */ -#define SOCEALREADY (SOCBASEERR+37) /* Operation already in progress */ -#define SOCENOTSOCK (SOCBASEERR+38) /* Socket operation on non-socket */ -#define SOCEDESTADDRREQ (SOCBASEERR+39) /* Destination address required */ -#define SOCEMSGSIZE (SOCBASEERR+40) /* Message too long */ -#define SOCEPROTOTYPE (SOCBASEERR+41) /* Protocol wrong type for socket */ -#define SOCENOPROTOOPT (SOCBASEERR+42) /* Protocol not available */ -#define SOCEPROTONOSUPPORT (SOCBASEERR+43) /* Protocol not supported */ -#define SOCESOCKTNOSUPPORT (SOCBASEERR+44) /* Socket type not supported */ -#define SOCEOPNOTSUPP (SOCBASEERR+45) /* Operation not supported on socket */ -#define SOCEPFNOSUPPORT (SOCBASEERR+46) /* Protocol family not supported */ -#define SOCEAFNOSUPPORT (SOCBASEERR+47) /* Address family not supported by protocol family */ -#define SOCEADDRINUSE (SOCBASEERR+48) /* Address already in use */ -#define SOCEADDRNOTAVAIL (SOCBASEERR+49) /* Can't assign requested address */ -#define SOCENETDOWN (SOCBASEERR+50) /* Network is down */ -#define SOCENETUNREACH (SOCBASEERR+51) /* Network is unreachable */ -#define SOCENETRESET (SOCBASEERR+52) /* Network dropped connection on reset */ -#define SOCECONNABORTED (SOCBASEERR+53) /* Software caused connection abort */ -#define SOCECONNRESET (SOCBASEERR+54) /* Connection reset by peer */ -#define SOCENOBUFS (SOCBASEERR+55) /* No buffer space available */ -#define SOCEISCONN (SOCBASEERR+56) /* Socket is already connected */ -#define SOCENOTCONN (SOCBASEERR+57) /* Socket is not connected */ -#define SOCESHUTDOWN (SOCBASEERR+58) /* Can't send after socket shutdown */ -#define SOCETOOMANYREFS (SOCBASEERR+59) /* Too many references: can't splice */ -#define SOCETIMEDOUT (SOCBASEERR+60) /* Connection timed out */ -#define SOCECONNREFUSED (SOCBASEERR+61) /* Connection refused */ -#define SOCELOOP (SOCBASEERR+62) /* Too many levels of symbolic links */ -#define SOCENAMETOOLONG (SOCBASEERR+63) /* File name too long */ -#define SOCEHOSTDOWN (SOCBASEERR+64) /* Host is down */ -#define SOCEHOSTUNREACH (SOCBASEERR+65) /* No route to host */ -#define SOCENOTEMPTY (SOCBASEERR+66) /* Directory not empty */ - -/* APR CANONICAL ERROR TESTS */ -#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES \ - || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED \ - || (s) == APR_OS_START_SYSERR + ERROR_SHARING_VIOLATION) -#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST \ - || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED \ - || (s) == APR_OS_START_SYSERR + ERROR_FILE_EXISTS \ - || (s) == APR_OS_START_SYSERR + ERROR_ALREADY_EXISTS \ - || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED) -#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG \ - || (s) == APR_OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \ - || (s) == APR_OS_START_SYSERR + SOCENAMETOOLONG) -#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT \ - || (s) == APR_OS_START_SYSERR + ERROR_FILE_NOT_FOUND \ - || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \ - || (s) == APR_OS_START_SYSERR + ERROR_NO_MORE_FILES \ - || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED) -#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR) -#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC \ - || (s) == APR_OS_START_SYSERR + ERROR_DISK_FULL) -#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM) -#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE \ - || (s) == APR_OS_START_SYSERR + ERROR_TOO_MANY_OPEN_FILES) -#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE) -#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE) -#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_PARAMETER \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_FUNCTION) -#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE \ - || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK) -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \ - || (s) == APR_OS_START_SYSERR + ERROR_NO_DATA \ - || (s) == APR_OS_START_SYSERR + SOCEWOULDBLOCK \ - || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION) -#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR \ - || (s) == APR_OS_START_SYSERR + SOCEINTR) -#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK \ - || (s) == APR_OS_START_SYSERR + SOCENOTSOCK) -#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED \ - || (s) == APR_OS_START_SYSERR + SOCECONNREFUSED) -#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS \ - || (s) == APR_OS_START_SYSERR + SOCEINPROGRESS) -#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \ - || (s) == APR_OS_START_SYSERR + SOCECONNABORTED) -#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET \ - || (s) == APR_OS_START_SYSERR + SOCECONNRESET) -/* XXX deprecated */ -#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT) -#undef APR_STATUS_IS_TIMEUP -#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \ - || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT) -#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \ - || (s) == APR_OS_START_SYSERR + SOCEHOSTUNREACH) -#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \ - || (s) == APR_OS_START_SYSERR + SOCENETUNREACH) -#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE) -#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE \ - || (s) == APR_OS_START_SYSERR + ERROR_BROKEN_PIPE \ - || (s) == APR_OS_START_SYSERR + SOCEPIPE) -#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV \ - || (s) == APR_OS_START_SYSERR + ERROR_NOT_SAME_DEVICE) -#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY \ - || (s) == APR_OS_START_SYSERR + ERROR_DIR_NOT_EMPTY \ - || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED) - -/* - Sorry, too tired to wrap this up for OS2... feel free to - fit the following into their best matches. - - { ERROR_NO_SIGNAL_SENT, ESRCH }, - { SOCEALREADY, EALREADY }, - { SOCEDESTADDRREQ, EDESTADDRREQ }, - { SOCEMSGSIZE, EMSGSIZE }, - { SOCEPROTOTYPE, EPROTOTYPE }, - { SOCENOPROTOOPT, ENOPROTOOPT }, - { SOCEPROTONOSUPPORT, EPROTONOSUPPORT }, - { SOCESOCKTNOSUPPORT, ESOCKTNOSUPPORT }, - { SOCEOPNOTSUPP, EOPNOTSUPP }, - { SOCEPFNOSUPPORT, EPFNOSUPPORT }, - { SOCEAFNOSUPPORT, EAFNOSUPPORT }, - { SOCEADDRINUSE, EADDRINUSE }, - { SOCEADDRNOTAVAIL, EADDRNOTAVAIL }, - { SOCENETDOWN, ENETDOWN }, - { SOCENETRESET, ENETRESET }, - { SOCENOBUFS, ENOBUFS }, - { SOCEISCONN, EISCONN }, - { SOCENOTCONN, ENOTCONN }, - { SOCESHUTDOWN, ESHUTDOWN }, - { SOCETOOMANYREFS, ETOOMANYREFS }, - { SOCELOOP, ELOOP }, - { SOCEHOSTDOWN, EHOSTDOWN }, - { SOCENOTEMPTY, ENOTEMPTY }, - { SOCEPIPE, EPIPE } -*/ - -#elif defined(WIN32) && !defined(DOXYGEN) /* !defined(OS2) */ - -#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR) -#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR) - -#define apr_get_os_error() (APR_FROM_OS_ERROR(GetLastError())) -#define apr_set_os_error(e) (SetLastError(APR_TO_OS_ERROR(e))) - -/* A special case, only socket calls require this: - */ -#define apr_get_netos_error() (APR_FROM_OS_ERROR(WSAGetLastError())) -#define apr_set_netos_error(e) (WSASetLastError(APR_TO_OS_ERROR(e))) - -/* APR CANONICAL ERROR TESTS */ -#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES \ - || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED \ - || (s) == APR_OS_START_SYSERR + ERROR_CANNOT_MAKE \ - || (s) == APR_OS_START_SYSERR + ERROR_CURRENT_DIRECTORY \ - || (s) == APR_OS_START_SYSERR + ERROR_DRIVE_LOCKED \ - || (s) == APR_OS_START_SYSERR + ERROR_FAIL_I24 \ - || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION \ - || (s) == APR_OS_START_SYSERR + ERROR_LOCK_FAILED \ - || (s) == APR_OS_START_SYSERR + ERROR_NOT_LOCKED \ - || (s) == APR_OS_START_SYSERR + ERROR_NETWORK_ACCESS_DENIED \ - || (s) == APR_OS_START_SYSERR + ERROR_SHARING_VIOLATION) -#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST \ - || (s) == APR_OS_START_SYSERR + ERROR_FILE_EXISTS \ - || (s) == APR_OS_START_SYSERR + ERROR_ALREADY_EXISTS) -#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG \ - || (s) == APR_OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \ - || (s) == APR_OS_START_SYSERR + WSAENAMETOOLONG) -#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT \ - || (s) == APR_OS_START_SYSERR + ERROR_FILE_NOT_FOUND \ - || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \ - || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED \ - || (s) == APR_OS_START_SYSERR + ERROR_NO_MORE_FILES) -#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR \ - || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \ - || (s) == APR_OS_START_SYSERR + ERROR_BAD_NETPATH \ - || (s) == APR_OS_START_SYSERR + ERROR_BAD_NET_NAME \ - || (s) == APR_OS_START_SYSERR + ERROR_BAD_PATHNAME \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DRIVE) -#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC \ - || (s) == APR_OS_START_SYSERR + ERROR_DISK_FULL) -#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM \ - || (s) == APR_OS_START_SYSERR + ERROR_ARENA_TRASHED \ - || (s) == APR_OS_START_SYSERR + ERROR_NOT_ENOUGH_MEMORY \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_BLOCK \ - || (s) == APR_OS_START_SYSERR + ERROR_NOT_ENOUGH_QUOTA \ - || (s) == APR_OS_START_SYSERR + ERROR_OUTOFMEMORY) -#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE \ - || (s) == APR_OS_START_SYSERR + ERROR_TOO_MANY_OPEN_FILES) -#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE) -#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_TARGET_HANDLE) -#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_ACCESS \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DATA \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_FUNCTION \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_PARAMETER \ - || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK) -#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE \ - || (s) == APR_OS_START_SYSERR + ERROR_SEEK_ON_DEVICE \ - || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK) -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \ - || (s) == APR_OS_START_SYSERR + ERROR_NO_DATA \ - || (s) == APR_OS_START_SYSERR + ERROR_NO_PROC_SLOTS \ - || (s) == APR_OS_START_SYSERR + ERROR_NESTING_NOT_ALLOWED \ - || (s) == APR_OS_START_SYSERR + ERROR_MAX_THRDS_REACHED \ - || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION \ - || (s) == APR_OS_START_SYSERR + WSAEWOULDBLOCK) -#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR \ - || (s) == APR_OS_START_SYSERR + WSAEINTR) -#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK \ - || (s) == APR_OS_START_SYSERR + WSAENOTSOCK) -#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED \ - || (s) == APR_OS_START_SYSERR + WSAECONNREFUSED) -#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS \ - || (s) == APR_OS_START_SYSERR + WSAEINPROGRESS) -#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \ - || (s) == APR_OS_START_SYSERR + WSAECONNABORTED) -#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET \ - || (s) == APR_OS_START_SYSERR + ERROR_NETNAME_DELETED \ - || (s) == APR_OS_START_SYSERR + WSAECONNRESET) -/* XXX deprecated */ -#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT) -#undef APR_STATUS_IS_TIMEUP -#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \ - || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT) -#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \ - || (s) == APR_OS_START_SYSERR + WSAEHOSTUNREACH) -#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \ - || (s) == APR_OS_START_SYSERR + WSAENETUNREACH) -#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE \ - || (s) == APR_OS_START_SYSERR + ERROR_EXE_MACHINE_TYPE_MISMATCH \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DLL \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_MODULETYPE \ - || (s) == APR_OS_START_SYSERR + ERROR_BAD_EXE_FORMAT \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_EXE_SIGNATURE \ - || (s) == APR_OS_START_SYSERR + ERROR_FILE_CORRUPT \ - || (s) == APR_OS_START_SYSERR + ERROR_BAD_FORMAT) -#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE \ - || (s) == APR_OS_START_SYSERR + ERROR_BROKEN_PIPE) -#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV \ - || (s) == APR_OS_START_SYSERR + ERROR_NOT_SAME_DEVICE) -#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY \ - || (s) == APR_OS_START_SYSERR + ERROR_DIR_NOT_EMPTY) - -#elif defined(NETWARE) && defined(USE_WINSOCK) && !defined(DOXYGEN) /* !defined(OS2) && !defined(WIN32) */ - -#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR) -#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR) - -#define apr_get_os_error() (errno) -#define apr_set_os_error(e) (errno = (e)) - -/* A special case, only socket calls require this: */ -#define apr_get_netos_error() (APR_FROM_OS_ERROR(WSAGetLastError())) -#define apr_set_netos_error(e) (WSASetLastError(APR_TO_OS_ERROR(e))) - -/* APR CANONICAL ERROR TESTS */ -#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES) -#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST) -#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG) -#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT) -#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR) -#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC) -#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM) -#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE) -#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE) -#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF) -#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL) -#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE) - -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \ - || (s) == EWOULDBLOCK \ - || (s) == APR_OS_START_SYSERR + WSAEWOULDBLOCK) -#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR \ - || (s) == APR_OS_START_SYSERR + WSAEINTR) -#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK \ - || (s) == APR_OS_START_SYSERR + WSAENOTSOCK) -#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED \ - || (s) == APR_OS_START_SYSERR + WSAECONNREFUSED) -#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS \ - || (s) == APR_OS_START_SYSERR + WSAEINPROGRESS) -#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \ - || (s) == APR_OS_START_SYSERR + WSAECONNABORTED) -#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET \ - || (s) == APR_OS_START_SYSERR + WSAECONNRESET) -/* XXX deprecated */ -#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT) -#undef APR_STATUS_IS_TIMEUP -#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \ - || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT) -#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \ - || (s) == APR_OS_START_SYSERR + WSAEHOSTUNREACH) -#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \ - || (s) == APR_OS_START_SYSERR + WSAENETUNREACH) -#define APR_STATUS_IS_ENETDOWN(s) ((s) == APR_OS_START_SYSERR + WSAENETDOWN) -#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE) -#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE) -#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV) -#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY) - -#else /* !defined(NETWARE) && !defined(OS2) && !defined(WIN32) */ - -/* - * os error codes are clib error codes - */ -#define APR_FROM_OS_ERROR(e) (e) -#define APR_TO_OS_ERROR(e) (e) - -#define apr_get_os_error() (errno) -#define apr_set_os_error(e) (errno = (e)) - -/* A special case, only socket calls require this: - */ -#define apr_get_netos_error() (errno) -#define apr_set_netos_error(e) (errno = (e)) - -/** - * @addtogroup APR_STATUS_IS - * @{ - */ - -/** permission denied */ -#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES) -/** file exists */ -#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST) -/** path name is too long */ -#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG) -/** - * no such file or directory - * @remark - * EMVSCATLG can be returned by the automounter on z/OS for - * paths which do not exist. - */ -#ifdef EMVSCATLG -#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT \ - || (s) == EMVSCATLG) -#else -#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT) -#endif -/** not a directory */ -#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR) -/** no space left on device */ -#ifdef EDQUOT -#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC \ - || (s) == EDQUOT) -#else -#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC) -#endif -/** not enough memory */ -#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM) -/** too many open files */ -#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE) -/** file table overflow */ -#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE) -/** bad file # */ -#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF) -/** invalid argument */ -#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL) -/** illegal seek */ -#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE) - -/** operation would block */ -#if !defined(EWOULDBLOCK) || !defined(EAGAIN) -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN) -#elif (EWOULDBLOCK == EAGAIN) -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN) -#else -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \ - || (s) == EWOULDBLOCK) -#endif - -/** interrupted system call */ -#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR) -/** socket operation on a non-socket */ -#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK) -/** Connection Refused */ -#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED) -/** operation now in progress */ -#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS) - -/** - * Software caused connection abort - * @remark - * EPROTO on certain older kernels really means ECONNABORTED, so we need to - * ignore it for them. See discussion in new-httpd archives nh.9701 & nh.9603 - * - * There is potentially a bug in Solaris 2.x x<6, and other boxes that - * implement tcp sockets in userland (i.e. on top of STREAMS). On these - * systems, EPROTO can actually result in a fatal loop. See PR#981 for - * example. It's hard to handle both uses of EPROTO. - */ -#ifdef EPROTO -#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \ - || (s) == EPROTO) -#else -#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED) -#endif - -/** Connection Reset by peer */ -#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET) -/** Operation timed out - * @deprecated */ -#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT) -/** no route to host */ -#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH) -/** network is unreachable */ -#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH) -/** inappropriate file type or format */ -#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE) -/** broken pipe */ -#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE) -/** cross device link */ -#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV) -/** Directory Not Empty */ -#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY || \ - (s) == APR_EEXIST) -/** @} */ - -#endif /* !defined(NETWARE) && !defined(OS2) && !defined(WIN32) */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* ! APR_ERRNO_H */ -#ifndef _LINUX_ERRNO_H -#define _LINUX_ERRNO_H - -#include <asm/errno.h> - -#ifdef __KERNEL__ - -/* Should never be seen by user programs */ -#define ERESTARTSYS 512 -#define ERESTARTNOINTR 513 -#define ERESTARTNOHAND 514 /* restart if no handler.. */ -#define ENOIOCTLCMD 515 /* No ioctl command */ -#define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */ - -/* Defined for the NFSv3 protocol */ -#define EBADHANDLE 521 /* Illegal NFS file handle */ -#define ENOTSYNC 522 /* Update synchronization mismatch */ -#define EBADCOOKIE 523 /* Cookie is stale */ -#define ENOTSUPP 524 /* Operation is not supported */ -#define ETOOSMALL 525 /* Buffer or request is too small */ -#define ESERVERFAULT 526 /* An untranslatable error occurred */ -#define EBADTYPE 527 /* Type not supported by server */ -#define EJUKEBOX 528 /* Request initiated, but will not complete before timeout */ -#define EIOCBQUEUED 529 /* iocb queued, will get completion event */ -#define EIOCBRETRY 530 /* iocb queued, will trigger a retry */ - -#endif - -#endif -// Copyright (c) 1994 James Clark -// See the file COPYING for copying permission. - -#ifndef ErrnoMessageArg_INCLUDED -#define ErrnoMessageArg_INCLUDED 1 - -#include "MessageArg.h" -#include "rtti.h" - -#ifdef SP_NAMESPACE -namespace SP_NAMESPACE { -#endif - -class SP_API ErrnoMessageArg : public OtherMessageArg { - RTTI_CLASS -public: - ErrnoMessageArg(int errnum) : errno_(errnum) { } - MessageArg *copy() const; - // errno might be a macro so we must use a different name - int errnum() const; -private: - int errno_; -}; - -inline -int ErrnoMessageArg::errnum() const -{ - return errno_; -} - -#ifdef SP_NAMESPACE -} -#endif - -#endif /* not ErrnoMessageArg_INCLUDED */ -/* Copyright (C) 1991,92,93,94,95,96,97,2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* - * ISO C99 Standard: 7.5 Errors <errno.h> - */ - -#ifndef _ERRNO_H - -/* The includer defined __need_Emath if he wants only the definitions - of EDOM and ERANGE, and not everything else. */ -#ifndef __need_Emath -# define _ERRNO_H 1 -# include <features.h> -#endif - -__BEGIN_DECLS - -/* Get the error number constants from the system-specific file. - This file will test __need_Emath and _ERRNO_H. */ -#include <bits/errno.h> -#undef __need_Emath - -#ifdef _ERRNO_H - -/* Declare the `errno' variable, unless it's defined as a macro by - bits/errno.h. This is the case in GNU, where it is a per-thread - variable. This redeclaration using the macro still works, but it - will be a function declaration without a prototype and may trigger - a -Wstrict-prototypes warning. */ -#ifndef errno -extern int errno; -#endif - -#ifdef __USE_GNU - -/* The full and simple forms of the name with which the program was - invoked. These variables are set up automatically at startup based on - the value of ARGV[0] (this works only if you use GNU ld). */ -extern char *program_invocation_name, *program_invocation_short_name; -#endif /* __USE_GNU */ -#endif /* _ERRNO_H */ - -__END_DECLS - -#endif /* _ERRNO_H */ - -/* The Hurd <bits/errno.h> defines `error_t' as an enumerated type so - that printing `error_t' values in the debugger shows the names. We - might need this definition sometimes even if this file was included - before. */ -#if defined __USE_GNU || defined __need_error_t -# ifndef __error_t_defined -typedef int error_t; -# define __error_t_defined 1 -# endif -# undef __need_error_t -#endif -#ifndef _I386_ERRNO_H -#define _I386_ERRNO_H - -#include <asm-generic/errno.h> - -#endif -#ifndef _ASM_GENERIC_ERRNO_BASE_H -#define _ASM_GENERIC_ERRNO_BASE_H - -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Argument list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* Out of memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math argument out of domain of func */ -#define ERANGE 34 /* Math result not representable */ - -#endif -#ifndef _ASM_GENERIC_ERRNO_H -#define _ASM_GENERIC_ERRNO_H - -#include <asm-generic/errno-base.h> - -#define EDEADLK 35 /* Resource deadlock would occur */ -#define ENAMETOOLONG 36 /* File name too long */ -#define ENOLCK 37 /* No record locks available */ -#define ENOSYS 38 /* Function not implemented */ -#define ENOTEMPTY 39 /* Directory not empty */ -#define ELOOP 40 /* Too many symbolic links encountered */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define ENOMSG 42 /* No message of desired type */ -#define EIDRM 43 /* Identifier removed */ -#define ECHRNG 44 /* Channel number out of range */ -#define EL2NSYNC 45 /* Level 2 not synchronized */ -#define EL3HLT 46 /* Level 3 halted */ -#define EL3RST 47 /* Level 3 reset */ -#define ELNRNG 48 /* Link number out of range */ -#define EUNATCH 49 /* Protocol driver not attached */ -#define ENOCSI 50 /* No CSI structure available */ -#define EL2HLT 51 /* Level 2 halted */ -#define EBADE 52 /* Invalid exchange */ -#define EBADR 53 /* Invalid request descriptor */ -#define EXFULL 54 /* Exchange full */ -#define ENOANO 55 /* No anode */ -#define EBADRQC 56 /* Invalid request code */ -#define EBADSLT 57 /* Invalid slot */ - -#define EDEADLOCK EDEADLK - -#define EBFONT 59 /* Bad font file format */ -#define ENOSTR 60 /* Device not a stream */ -#define ENODATA 61 /* No data available */ -#define ETIME 62 /* Timer expired */ -#define ENOSR 63 /* Out of streams resources */ -#define ENONET 64 /* Machine is not on the network */ -#define ENOPKG 65 /* Package not installed */ -#define EREMOTE 66 /* Object is remote */ -#define ENOLINK 67 /* Link has been severed */ -#define EADV 68 /* Advertise error */ -#define ESRMNT 69 /* Srmount error */ -#define ECOMM 70 /* Communication error on send */ -#define EPROTO 71 /* Protocol error */ -#define EMULTIHOP 72 /* Multihop attempted */ -#define EDOTDOT 73 /* RFS specific error */ -#define EBADMSG 74 /* Not a data message */ -#define EOVERFLOW 75 /* Value too large for defined data type */ -#define ENOTUNIQ 76 /* Name not unique on network */ -#define EBADFD 77 /* File descriptor in bad state */ -#define EREMCHG 78 /* Remote address changed */ -#define ELIBACC 79 /* Can not access a needed shared library */ -#define ELIBBAD 80 /* Accessing a corrupted shared library */ -#define ELIBSCN 81 /* .lib section in a.out corrupted */ -#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ -#define ELIBEXEC 83 /* Cannot exec a shared library directly */ -#define EILSEQ 84 /* Illegal byte sequence */ -#define ERESTART 85 /* Interrupted system call should be restarted */ -#define ESTRPIPE 86 /* Streams pipe error */ -#define EUSERS 87 /* Too many users */ -#define ENOTSOCK 88 /* Socket operation on non-socket */ -#define EDESTADDRREQ 89 /* Destination address required */ -#define EMSGSIZE 90 /* Message too long */ -#define EPROTOTYPE 91 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 92 /* Protocol not available */ -#define EPROTONOSUPPORT 93 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ -#define EPFNOSUPPORT 96 /* Protocol family not supported */ -#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ -#define EADDRINUSE 98 /* Address already in use */ -#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ -#define ENETDOWN 100 /* Network is down */ -#define ENETUNREACH 101 /* Network is unreachable */ -#define ENETRESET 102 /* Network dropped connection because of reset */ -#define ECONNABORTED 103 /* Software caused connection abort */ -#define ECONNRESET 104 /* Connection reset by peer */ -#define ENOBUFS 105 /* No buffer space available */ -#define EISCONN 106 /* Transport endpoint is already connected */ -#define ENOTCONN 107 /* Transport endpoint is not connected */ -#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ -#define ETOOMANYREFS 109 /* Too many references: cannot splice */ -#define ETIMEDOUT 110 /* Connection timed out */ -#define ECONNREFUSED 111 /* Connection refused */ -#define EHOSTDOWN 112 /* Host is down */ -#define EHOSTUNREACH 113 /* No route to host */ -#define EALREADY 114 /* Operation already in progress */ -#define EINPROGRESS 115 /* Operation now in progress */ -#define ESTALE 116 /* Stale NFS file handle */ -#define EUCLEAN 117 /* Structure needs cleaning */ -#define ENOTNAM 118 /* Not a XENIX named type file */ -#define ENAVAIL 119 /* No XENIX semaphores available */ -#define EISNAM 120 /* Is a named type file */ -#define EREMOTEIO 121 /* Remote I/O error */ -#define EDQUOT 122 /* Quota exceeded */ - -#define ENOMEDIUM 123 /* No medium found */ -#define EMEDIUMTYPE 124 /* Wrong medium type */ -#define ECANCELED 125 /* Operation Canceled */ -#define ENOKEY 126 /* Required key not available */ -#define EKEYEXPIRED 127 /* Key has expired */ -#define EKEYREVOKED 128 /* Key has been revoked */ -#define EKEYREJECTED 129 /* Key was rejected by service */ - -/* for robust mutexes */ -#define EOWNERDEAD 130 /* Owner died */ -#define ENOTRECOVERABLE 131 /* State not recoverable */ - -#endif diff --git a/doc/legacy/errno.list.macosx.txt b/doc/legacy/errno.list.macosx.txt deleted file mode 100644 index 2dff28cd379..00000000000 --- a/doc/legacy/errno.list.macosx.txt +++ /dev/null @@ -1,1513 +0,0 @@ -/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as - * applicable. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef APR_ERRNO_H -#define APR_ERRNO_H - -/** - * @file apr_errno.h - * @brief APR Error Codes - */ - -#include "apr.h" - -#if APR_HAVE_ERRNO_H -#include <errno.h> -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * @defgroup apr_errno Error Codes - * @ingroup APR - * @{ - */ - -/** - * Type for specifying an error or status code. - */ -typedef int apr_status_t; - -/** - * Return a human readable string describing the specified error. - * @param statcode The error code the get a string for. - * @param buf A buffer to hold the error string. - * @param bufsize Size of the buffer to hold the string. - */ -APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf, - apr_size_t bufsize); - -#if defined(DOXYGEN) -/** - * @def APR_FROM_OS_ERROR(os_err_type syserr) - * Fold a platform specific error into an apr_status_t code. - * @return apr_status_t - * @param e The platform os error code. - * @warning macro implementation; the syserr argument may be evaluated - * multiple times. - */ -#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR) - -/** - * @def APR_TO_OS_ERROR(apr_status_t statcode) - * @return os_err_type - * Fold an apr_status_t code back to the native platform defined error. - * @param e The apr_status_t folded platform os error code. - * @warning macro implementation; the statcode argument may be evaluated - * multiple times. If the statcode was not created by apr_get_os_error - * or APR_FROM_OS_ERROR, the results are undefined. - */ -#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR) - -/** @def apr_get_os_error() - * @return apr_status_t the last platform error, folded into apr_status_t, on most platforms - * @remark This retrieves errno, or calls a GetLastError() style function, and - * folds it with APR_FROM_OS_ERROR. Some platforms (such as OS2) have no - * such mechanism, so this call may be unsupported. Do NOT use this - * call for socket errors from socket, send, recv etc! - */ - -/** @def apr_set_os_error(e) - * Reset the last platform error, unfolded from an apr_status_t, on some platforms - * @param e The OS error folded in a prior call to APR_FROM_OS_ERROR() - * @warning This is a macro implementation; the statcode argument may be evaluated - * multiple times. If the statcode was not created by apr_get_os_error - * or APR_FROM_OS_ERROR, the results are undefined. This macro sets - * errno, or calls a SetLastError() style function, unfolding statcode - * with APR_TO_OS_ERROR. Some platforms (such as OS2) have no such - * mechanism, so this call may be unsupported. - */ - -/** @def apr_get_netos_error() - * Return the last socket error, folded into apr_status_t, on all platforms - * @remark This retrieves errno or calls a GetLastSocketError() style function, - * and folds it with APR_FROM_OS_ERROR. - */ - -/** @def apr_set_netos_error(e) - * Reset the last socket error, unfolded from an apr_status_t - * @param e The socket error folded in a prior call to APR_FROM_OS_ERROR() - * @warning This is a macro implementation; the statcode argument may be evaluated - * multiple times. If the statcode was not created by apr_get_os_error - * or APR_FROM_OS_ERROR, the results are undefined. This macro sets - * errno, or calls a WSASetLastError() style function, unfolding - * socketcode with APR_TO_OS_ERROR. - */ - -#endif /* defined(DOXYGEN) */ - -/** - * APR_OS_START_ERROR is where the APR specific error values start. - */ -#define APR_OS_START_ERROR 20000 -/** - * APR_OS_ERRSPACE_SIZE is the maximum number of errors you can fit - * into one of the error/status ranges below -- except for - * APR_OS_START_USERERR, which see. - */ -#define APR_OS_ERRSPACE_SIZE 50000 -/** - * APR_OS_START_STATUS is where the APR specific status codes start. - */ -#define APR_OS_START_STATUS (APR_OS_START_ERROR + APR_OS_ERRSPACE_SIZE) -/** - * APR_OS_START_USERERR are reserved for applications that use APR that - * layer their own error codes along with APR's. Note that the - * error immediately following this one is set ten times farther - * away than usual, so that users of apr have a lot of room in - * which to declare custom error codes. - */ -#define APR_OS_START_USERERR (APR_OS_START_STATUS + APR_OS_ERRSPACE_SIZE) -/** - * APR_OS_START_USEERR is obsolete, defined for compatibility only. - * Use APR_OS_START_USERERR instead. - */ -#define APR_OS_START_USEERR APR_OS_START_USERERR -/** - * APR_OS_START_CANONERR is where APR versions of errno values are defined - * on systems which don't have the corresponding errno. - */ -#define APR_OS_START_CANONERR (APR_OS_START_USERERR \ - + (APR_OS_ERRSPACE_SIZE * 10)) -/** - * APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into - * apr_status_t values. - */ -#define APR_OS_START_EAIERR (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE) -/** - * APR_OS_START_SYSERR folds platform-specific system error values into - * apr_status_t values. - */ -#define APR_OS_START_SYSERR (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE) - -/** no error. */ -#define APR_SUCCESS 0 - -/** - * @defgroup APR_Error APR Error Values - * <PRE> - * <b>APR ERROR VALUES</b> - * APR_ENOSTAT APR was unable to perform a stat on the file - * APR_ENOPOOL APR was not provided a pool with which to allocate memory - * APR_EBADDATE APR was given an invalid date - * APR_EINVALSOCK APR was given an invalid socket - * APR_ENOPROC APR was not given a process structure - * APR_ENOTIME APR was not given a time structure - * APR_ENODIR APR was not given a directory structure - * APR_ENOLOCK APR was not given a lock structure - * APR_ENOPOLL APR was not given a poll structure - * APR_ENOSOCKET APR was not given a socket - * APR_ENOTHREAD APR was not given a thread structure - * APR_ENOTHDKEY APR was not given a thread key structure - * APR_ENOSHMAVAIL There is no more shared memory available - * APR_EDSOOPEN APR was unable to open the dso object. For more - * information call apr_dso_error(). - * APR_EGENERAL General failure (specific information not available) - * APR_EBADIP The specified IP address is invalid - * APR_EBADMASK The specified netmask is invalid - * APR_ESYMNOTFOUND Could not find the requested symbol - * </PRE> - * - * <PRE> - * <b>APR STATUS VALUES</b> - * APR_INCHILD Program is currently executing in the child - * APR_INPARENT Program is currently executing in the parent - * APR_DETACH The thread is detached - * APR_NOTDETACH The thread is not detached - * APR_CHILD_DONE The child has finished executing - * APR_CHILD_NOTDONE The child has not finished executing - * APR_TIMEUP The operation did not finish before the timeout - * APR_INCOMPLETE The operation was incomplete although some processing - * was performed and the results are partially valid - * APR_BADCH Getopt found an option not in the option string - * APR_BADARG Getopt found an option that is missing an argument - * and an argument was specified in the option string - * APR_EOF APR has encountered the end of the file - * APR_NOTFOUND APR was unable to find the socket in the poll structure - * APR_ANONYMOUS APR is using anonymous shared memory - * APR_FILEBASED APR is using a file name as the key to the shared memory - * APR_KEYBASED APR is using a shared key as the key to the shared memory - * APR_EINIT Ininitalizer value. If no option has been found, but - * the status variable requires a value, this should be used - * APR_ENOTIMPL The APR function has not been implemented on this - * platform, either because nobody has gotten to it yet, - * or the function is impossible on this platform. - * APR_EMISMATCH Two passwords do not match. - * APR_EABSOLUTE The given path was absolute. - * APR_ERELATIVE The given path was relative. - * APR_EINCOMPLETE The given path was neither relative nor absolute. - * APR_EABOVEROOT The given path was above the root path. - * APR_EBUSY The given lock was busy. - * APR_EPROC_UNKNOWN The given process wasn't recognized by APR - * </PRE> - * @{ - */ -/** @see APR_STATUS_IS_ENOSTAT */ -#define APR_ENOSTAT (APR_OS_START_ERROR + 1) -/** @see APR_STATUS_IS_ENOPOOL */ -#define APR_ENOPOOL (APR_OS_START_ERROR + 2) -/* empty slot: +3 */ -/** @see APR_STATUS_IS_EBADDATE */ -#define APR_EBADDATE (APR_OS_START_ERROR + 4) -/** @see APR_STATUS_IS_EINVALSOCK */ -#define APR_EINVALSOCK (APR_OS_START_ERROR + 5) -/** @see APR_STATUS_IS_ENOPROC */ -#define APR_ENOPROC (APR_OS_START_ERROR + 6) -/** @see APR_STATUS_IS_ENOTIME */ -#define APR_ENOTIME (APR_OS_START_ERROR + 7) -/** @see APR_STATUS_IS_ENODIR */ -#define APR_ENODIR (APR_OS_START_ERROR + 8) -/** @see APR_STATUS_IS_ENOLOCK */ -#define APR_ENOLOCK (APR_OS_START_ERROR + 9) -/** @see APR_STATUS_IS_ENOPOLL */ -#define APR_ENOPOLL (APR_OS_START_ERROR + 10) -/** @see APR_STATUS_IS_ENOSOCKET */ -#define APR_ENOSOCKET (APR_OS_START_ERROR + 11) -/** @see APR_STATUS_IS_ENOTHREAD */ -#define APR_ENOTHREAD (APR_OS_START_ERROR + 12) -/** @see APR_STATUS_IS_ENOTHDKEY */ -#define APR_ENOTHDKEY (APR_OS_START_ERROR + 13) -/** @see APR_STATUS_IS_EGENERAL */ -#define APR_EGENERAL (APR_OS_START_ERROR + 14) -/** @see APR_STATUS_IS_ENOSHMAVAIL */ -#define APR_ENOSHMAVAIL (APR_OS_START_ERROR + 15) -/** @see APR_STATUS_IS_EBADIP */ -#define APR_EBADIP (APR_OS_START_ERROR + 16) -/** @see APR_STATUS_IS_EBADMASK */ -#define APR_EBADMASK (APR_OS_START_ERROR + 17) -/* empty slot: +18 */ -/** @see APR_STATUS_IS_EDSOPEN */ -#define APR_EDSOOPEN (APR_OS_START_ERROR + 19) -/** @see APR_STATUS_IS_EABSOLUTE */ -#define APR_EABSOLUTE (APR_OS_START_ERROR + 20) -/** @see APR_STATUS_IS_ERELATIVE */ -#define APR_ERELATIVE (APR_OS_START_ERROR + 21) -/** @see APR_STATUS_IS_EINCOMPLETE */ -#define APR_EINCOMPLETE (APR_OS_START_ERROR + 22) -/** @see APR_STATUS_IS_EABOVEROOT */ -#define APR_EABOVEROOT (APR_OS_START_ERROR + 23) -/** @see APR_STATUS_IS_EBADPATH */ -#define APR_EBADPATH (APR_OS_START_ERROR + 24) -/** @see APR_STATUS_IS_EPATHWILD */ -#define APR_EPATHWILD (APR_OS_START_ERROR + 25) -/** @see APR_STATUS_IS_ESYMNOTFOUND */ -#define APR_ESYMNOTFOUND (APR_OS_START_ERROR + 26) -/** @see APR_STATUS_IS_EPROC_UNKNOWN */ -#define APR_EPROC_UNKNOWN (APR_OS_START_ERROR + 27) -/** @see APR_STATUS_IS_ENOTENOUGHENTROPY */ -#define APR_ENOTENOUGHENTROPY (APR_OS_START_ERROR + 28) -/** @} */ - -/** - * @defgroup APR_STATUS_IS Status Value Tests - * @warning For any particular error condition, more than one of these tests - * may match. This is because platform-specific error codes may not - * always match the semantics of the POSIX codes these tests (and the - * corresponding APR error codes) are named after. A notable example - * are the APR_STATUS_IS_ENOENT and APR_STATUS_IS_ENOTDIR tests on - * Win32 platforms. The programmer should always be aware of this and - * adjust the order of the tests accordingly. - * @{ - */ -/** - * APR was unable to perform a stat on the file - * @warning always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_ENOSTAT(s) ((s) == APR_ENOSTAT) -/** - * APR was not provided a pool with which to allocate memory - * @warning always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_ENOPOOL(s) ((s) == APR_ENOPOOL) -/** APR was given an invalid date */ -#define APR_STATUS_IS_EBADDATE(s) ((s) == APR_EBADDATE) -/** APR was given an invalid socket */ -#define APR_STATUS_IS_EINVALSOCK(s) ((s) == APR_EINVALSOCK) -/** APR was not given a process structure */ -#define APR_STATUS_IS_ENOPROC(s) ((s) == APR_ENOPROC) -/** APR was not given a time structure */ -#define APR_STATUS_IS_ENOTIME(s) ((s) == APR_ENOTIME) -/** APR was not given a directory structure */ -#define APR_STATUS_IS_ENODIR(s) ((s) == APR_ENODIR) -/** APR was not given a lock structure */ -#define APR_STATUS_IS_ENOLOCK(s) ((s) == APR_ENOLOCK) -/** APR was not given a poll structure */ -#define APR_STATUS_IS_ENOPOLL(s) ((s) == APR_ENOPOLL) -/** APR was not given a socket */ -#define APR_STATUS_IS_ENOSOCKET(s) ((s) == APR_ENOSOCKET) -/** APR was not given a thread structure */ -#define APR_STATUS_IS_ENOTHREAD(s) ((s) == APR_ENOTHREAD) -/** APR was not given a thread key structure */ -#define APR_STATUS_IS_ENOTHDKEY(s) ((s) == APR_ENOTHDKEY) -/** Generic Error which can not be put into another spot */ -#define APR_STATUS_IS_EGENERAL(s) ((s) == APR_EGENERAL) -/** There is no more shared memory available */ -#define APR_STATUS_IS_ENOSHMAVAIL(s) ((s) == APR_ENOSHMAVAIL) -/** The specified IP address is invalid */ -#define APR_STATUS_IS_EBADIP(s) ((s) == APR_EBADIP) -/** The specified netmask is invalid */ -#define APR_STATUS_IS_EBADMASK(s) ((s) == APR_EBADMASK) -/* empty slot: +18 */ -/** - * APR was unable to open the dso object. - * For more information call apr_dso_error(). - */ -#if defined(WIN32) -#define APR_STATUS_IS_EDSOOPEN(s) ((s) == APR_EDSOOPEN \ - || APR_TO_OS_ERROR(s) == ERROR_MOD_NOT_FOUND) -#else -#define APR_STATUS_IS_EDSOOPEN(s) ((s) == APR_EDSOOPEN) -#endif -/** The given path was absolute. */ -#define APR_STATUS_IS_EABSOLUTE(s) ((s) == APR_EABSOLUTE) -/** The given path was relative. */ -#define APR_STATUS_IS_ERELATIVE(s) ((s) == APR_ERELATIVE) -/** The given path was neither relative nor absolute. */ -#define APR_STATUS_IS_EINCOMPLETE(s) ((s) == APR_EINCOMPLETE) -/** The given path was above the root path. */ -#define APR_STATUS_IS_EABOVEROOT(s) ((s) == APR_EABOVEROOT) -/** The given path was bad. */ -#define APR_STATUS_IS_EBADPATH(s) ((s) == APR_EBADPATH) -/** The given path contained wildcards. */ -#define APR_STATUS_IS_EPATHWILD(s) ((s) == APR_EPATHWILD) -/** Could not find the requested symbol. - * For more information call apr_dso_error(). - */ -#if defined(WIN32) -#define APR_STATUS_IS_ESYMNOTFOUND(s) ((s) == APR_ESYMNOTFOUND \ - || APR_TO_OS_ERROR(s) == ERROR_PROC_NOT_FOUND) -#else -#define APR_STATUS_IS_ESYMNOTFOUND(s) ((s) == APR_ESYMNOTFOUND) -#endif -/** The given process was not recognized by APR. */ -#define APR_STATUS_IS_EPROC_UNKNOWN(s) ((s) == APR_EPROC_UNKNOWN) - -/** APR could not gather enough entropy to continue. */ -#define APR_STATUS_IS_ENOTENOUGHENTROPY(s) ((s) == APR_ENOTENOUGHENTROPY) - -/** @} */ - -/** - * @addtogroup APR_Error - * @{ - */ -/** @see APR_STATUS_IS_INCHILD */ -#define APR_INCHILD (APR_OS_START_STATUS + 1) -/** @see APR_STATUS_IS_INPARENT */ -#define APR_INPARENT (APR_OS_START_STATUS + 2) -/** @see APR_STATUS_IS_DETACH */ -#define APR_DETACH (APR_OS_START_STATUS + 3) -/** @see APR_STATUS_IS_NOTDETACH */ -#define APR_NOTDETACH (APR_OS_START_STATUS + 4) -/** @see APR_STATUS_IS_CHILD_DONE */ -#define APR_CHILD_DONE (APR_OS_START_STATUS + 5) -/** @see APR_STATUS_IS_CHILD_NOTDONE */ -#define APR_CHILD_NOTDONE (APR_OS_START_STATUS + 6) -/** @see APR_STATUS_IS_TIMEUP */ -#define APR_TIMEUP (APR_OS_START_STATUS + 7) -/** @see APR_STATUS_IS_INCOMPLETE */ -#define APR_INCOMPLETE (APR_OS_START_STATUS + 8) -/* empty slot: +9 */ -/* empty slot: +10 */ -/* empty slot: +11 */ -/** @see APR_STATUS_IS_BADCH */ -#define APR_BADCH (APR_OS_START_STATUS + 12) -/** @see APR_STATUS_IS_BADARG */ -#define APR_BADARG (APR_OS_START_STATUS + 13) -/** @see APR_STATUS_IS_EOF */ -#define APR_EOF (APR_OS_START_STATUS + 14) -/** @see APR_STATUS_IS_NOTFOUND */ -#define APR_NOTFOUND (APR_OS_START_STATUS + 15) -/* empty slot: +16 */ -/* empty slot: +17 */ -/* empty slot: +18 */ -/** @see APR_STATUS_IS_ANONYMOUS */ -#define APR_ANONYMOUS (APR_OS_START_STATUS + 19) -/** @see APR_STATUS_IS_FILEBASED */ -#define APR_FILEBASED (APR_OS_START_STATUS + 20) -/** @see APR_STATUS_IS_KEYBASED */ -#define APR_KEYBASED (APR_OS_START_STATUS + 21) -/** @see APR_STATUS_IS_EINIT */ -#define APR_EINIT (APR_OS_START_STATUS + 22) -/** @see APR_STATUS_IS_ENOTIMPL */ -#define APR_ENOTIMPL (APR_OS_START_STATUS + 23) -/** @see APR_STATUS_IS_EMISMATCH */ -#define APR_EMISMATCH (APR_OS_START_STATUS + 24) -/** @see APR_STATUS_IS_EBUSY */ -#define APR_EBUSY (APR_OS_START_STATUS + 25) -/** @} */ - -/** - * @addtogroup APR_STATUS_IS - * @{ - */ -/** - * Program is currently executing in the child - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code */ -#define APR_STATUS_IS_INCHILD(s) ((s) == APR_INCHILD) -/** - * Program is currently executing in the parent - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_INPARENT(s) ((s) == APR_INPARENT) -/** - * The thread is detached - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_DETACH(s) ((s) == APR_DETACH) -/** - * The thread is not detached - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_NOTDETACH(s) ((s) == APR_NOTDETACH) -/** - * The child has finished executing - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_CHILD_DONE(s) ((s) == APR_CHILD_DONE) -/** - * The child has not finished executing - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_CHILD_NOTDONE(s) ((s) == APR_CHILD_NOTDONE) -/** - * The operation did not finish before the timeout - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP) -/** - * The operation was incomplete although some processing was performed - * and the results are partially valid. - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_INCOMPLETE(s) ((s) == APR_INCOMPLETE) -/* empty slot: +9 */ -/* empty slot: +10 */ -/* empty slot: +11 */ -/** - * Getopt found an option not in the option string - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_BADCH(s) ((s) == APR_BADCH) -/** - * Getopt found an option not in the option string and an argument was - * specified in the option string - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_BADARG(s) ((s) == APR_BADARG) -/** - * APR has encountered the end of the file - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_EOF(s) ((s) == APR_EOF) -/** - * APR was unable to find the socket in the poll structure - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_NOTFOUND(s) ((s) == APR_NOTFOUND) -/* empty slot: +16 */ -/* empty slot: +17 */ -/* empty slot: +18 */ -/** - * APR is using anonymous shared memory - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_ANONYMOUS(s) ((s) == APR_ANONYMOUS) -/** - * APR is using a file name as the key to the shared memory - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_FILEBASED(s) ((s) == APR_FILEBASED) -/** - * APR is using a shared key as the key to the shared memory - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_KEYBASED(s) ((s) == APR_KEYBASED) -/** - * Ininitalizer value. If no option has been found, but - * the status variable requires a value, this should be used - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_EINIT(s) ((s) == APR_EINIT) -/** - * The APR function has not been implemented on this - * platform, either because nobody has gotten to it yet, - * or the function is impossible on this platform. - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_ENOTIMPL(s) ((s) == APR_ENOTIMPL) -/** - * Two passwords do not match. - * @warning - * always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_EMISMATCH(s) ((s) == APR_EMISMATCH) -/** - * The given lock was busy - * @warning always use this test, as platform-specific variances may meet this - * more than one error code - */ -#define APR_STATUS_IS_EBUSY(s) ((s) == APR_EBUSY) - -/** @} */ - -/** - * @addtogroup APR_Error APR Error Values - * @{ - */ -/* APR CANONICAL ERROR VALUES */ -/** @see APR_STATUS_IS_EACCES */ -#ifdef EACCES -#define APR_EACCES EACCES -#else -#define APR_EACCES (APR_OS_START_CANONERR + 1) -#endif - -/** @see APR_STATUS_IS_EXIST */ -#ifdef EEXIST -#define APR_EEXIST EEXIST -#else -#define APR_EEXIST (APR_OS_START_CANONERR + 2) -#endif - -/** @see APR_STATUS_IS_ENAMETOOLONG */ -#ifdef ENAMETOOLONG -#define APR_ENAMETOOLONG ENAMETOOLONG -#else -#define APR_ENAMETOOLONG (APR_OS_START_CANONERR + 3) -#endif - -/** @see APR_STATUS_IS_ENOENT */ -#ifdef ENOENT -#define APR_ENOENT ENOENT -#else -#define APR_ENOENT (APR_OS_START_CANONERR + 4) -#endif - -/** @see APR_STATUS_IS_ENOTDIR */ -#ifdef ENOTDIR -#define APR_ENOTDIR ENOTDIR -#else -#define APR_ENOTDIR (APR_OS_START_CANONERR + 5) -#endif - -/** @see APR_STATUS_IS_ENOSPC */ -#ifdef ENOSPC -#define APR_ENOSPC ENOSPC -#else -#define APR_ENOSPC (APR_OS_START_CANONERR + 6) -#endif - -/** @see APR_STATUS_IS_ENOMEM */ -#ifdef ENOMEM -#define APR_ENOMEM ENOMEM -#else -#define APR_ENOMEM (APR_OS_START_CANONERR + 7) -#endif - -/** @see APR_STATUS_IS_EMFILE */ -#ifdef EMFILE -#define APR_EMFILE EMFILE -#else -#define APR_EMFILE (APR_OS_START_CANONERR + 8) -#endif - -/** @see APR_STATUS_IS_ENFILE */ -#ifdef ENFILE -#define APR_ENFILE ENFILE -#else -#define APR_ENFILE (APR_OS_START_CANONERR + 9) -#endif - -/** @see APR_STATUS_IS_EBADF */ -#ifdef EBADF -#define APR_EBADF EBADF -#else -#define APR_EBADF (APR_OS_START_CANONERR + 10) -#endif - -/** @see APR_STATUS_IS_EINVAL */ -#ifdef EINVAL -#define APR_EINVAL EINVAL -#else -#define APR_EINVAL (APR_OS_START_CANONERR + 11) -#endif - -/** @see APR_STATUS_IS_ESPIPE */ -#ifdef ESPIPE -#define APR_ESPIPE ESPIPE -#else -#define APR_ESPIPE (APR_OS_START_CANONERR + 12) -#endif - -/** - * @see APR_STATUS_IS_EAGAIN - * @warning use APR_STATUS_IS_EAGAIN instead of just testing this value - */ -#ifdef EAGAIN -#define APR_EAGAIN EAGAIN -#elif defined(EWOULDBLOCK) -#define APR_EAGAIN EWOULDBLOCK -#else -#define APR_EAGAIN (APR_OS_START_CANONERR + 13) -#endif - -/** @see APR_STATUS_IS_EINTR */ -#ifdef EINTR -#define APR_EINTR EINTR -#else -#define APR_EINTR (APR_OS_START_CANONERR + 14) -#endif - -/** @see APR_STATUS_IS_ENOTSOCK */ -#ifdef ENOTSOCK -#define APR_ENOTSOCK ENOTSOCK -#else -#define APR_ENOTSOCK (APR_OS_START_CANONERR + 15) -#endif - -/** @see APR_STATUS_IS_ECONNREFUSED */ -#ifdef ECONNREFUSED -#define APR_ECONNREFUSED ECONNREFUSED -#else -#define APR_ECONNREFUSED (APR_OS_START_CANONERR + 16) -#endif - -/** @see APR_STATUS_IS_EINPROGRESS */ -#ifdef EINPROGRESS -#define APR_EINPROGRESS EINPROGRESS -#else -#define APR_EINPROGRESS (APR_OS_START_CANONERR + 17) -#endif - -/** - * @see APR_STATUS_IS_ECONNABORTED - * @warning use APR_STATUS_IS_ECONNABORTED instead of just testing this value - */ - -#ifdef ECONNABORTED -#define APR_ECONNABORTED ECONNABORTED -#else -#define APR_ECONNABORTED (APR_OS_START_CANONERR + 18) -#endif - -/** @see APR_STATUS_IS_ECONNRESET */ -#ifdef ECONNRESET -#define APR_ECONNRESET ECONNRESET -#else -#define APR_ECONNRESET (APR_OS_START_CANONERR + 19) -#endif - -/** @see APR_STATUS_IS_ETIMEDOUT - * @deprecated */ -#ifdef ETIMEDOUT -#define APR_ETIMEDOUT ETIMEDOUT -#else -#define APR_ETIMEDOUT (APR_OS_START_CANONERR + 20) -#endif - -/** @see APR_STATUS_IS_EHOSTUNREACH */ -#ifdef EHOSTUNREACH -#define APR_EHOSTUNREACH EHOSTUNREACH -#else -#define APR_EHOSTUNREACH (APR_OS_START_CANONERR + 21) -#endif - -/** @see APR_STATUS_IS_ENETUNREACH */ -#ifdef ENETUNREACH -#define APR_ENETUNREACH ENETUNREACH -#else -#define APR_ENETUNREACH (APR_OS_START_CANONERR + 22) -#endif - -/** @see APR_STATUS_IS_EFTYPE */ -#ifdef EFTYPE -#define APR_EFTYPE EFTYPE -#else -#define APR_EFTYPE (APR_OS_START_CANONERR + 23) -#endif - -/** @see APR_STATUS_IS_EPIPE */ -#ifdef EPIPE -#define APR_EPIPE EPIPE -#else -#define APR_EPIPE (APR_OS_START_CANONERR + 24) -#endif - -/** @see APR_STATUS_IS_EXDEV */ -#ifdef EXDEV -#define APR_EXDEV EXDEV -#else -#define APR_EXDEV (APR_OS_START_CANONERR + 25) -#endif - -/** @see APR_STATUS_IS_ENOTEMPTY */ -#ifdef ENOTEMPTY -#define APR_ENOTEMPTY ENOTEMPTY -#else -#define APR_ENOTEMPTY (APR_OS_START_CANONERR + 26) -#endif - -/** @} */ - -#if defined(OS2) && !defined(DOXYGEN) - -#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR) -#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR) - -#define INCL_DOSERRORS -#define INCL_DOS - -/* Leave these undefined. - * OS2 doesn't rely on the errno concept. - * The API calls always return a result codes which - * should be filtered through APR_FROM_OS_ERROR(). - * - * #define apr_get_os_error() (APR_FROM_OS_ERROR(GetLastError())) - * #define apr_set_os_error(e) (SetLastError(APR_TO_OS_ERROR(e))) - */ - -/* A special case, only socket calls require this; - */ -#define apr_get_netos_error() (APR_FROM_OS_ERROR(errno)) -#define apr_set_netos_error(e) (errno = APR_TO_OS_ERROR(e)) - -/* And this needs to be greped away for good: - */ -#define APR_OS2_STATUS(e) (APR_FROM_OS_ERROR(e)) - -/* These can't sit in a private header, so in spite of the extra size, - * they need to be made available here. - */ -#define SOCBASEERR 10000 -#define SOCEPERM (SOCBASEERR+1) /* Not owner */ -#define SOCESRCH (SOCBASEERR+3) /* No such process */ -#define SOCEINTR (SOCBASEERR+4) /* Interrupted system call */ -#define SOCENXIO (SOCBASEERR+6) /* No such device or address */ -#define SOCEBADF (SOCBASEERR+9) /* Bad file number */ -#define SOCEACCES (SOCBASEERR+13) /* Permission denied */ -#define SOCEFAULT (SOCBASEERR+14) /* Bad address */ -#define SOCEINVAL (SOCBASEERR+22) /* Invalid argument */ -#define SOCEMFILE (SOCBASEERR+24) /* Too many open files */ -#define SOCEPIPE (SOCBASEERR+32) /* Broken pipe */ -#define SOCEOS2ERR (SOCBASEERR+100) /* OS/2 Error */ -#define SOCEWOULDBLOCK (SOCBASEERR+35) /* Operation would block */ -#define SOCEINPROGRESS (SOCBASEERR+36) /* Operation now in progress */ -#define SOCEALREADY (SOCBASEERR+37) /* Operation already in progress */ -#define SOCENOTSOCK (SOCBASEERR+38) /* Socket operation on non-socket */ -#define SOCEDESTADDRREQ (SOCBASEERR+39) /* Destination address required */ -#define SOCEMSGSIZE (SOCBASEERR+40) /* Message too long */ -#define SOCEPROTOTYPE (SOCBASEERR+41) /* Protocol wrong type for socket */ -#define SOCENOPROTOOPT (SOCBASEERR+42) /* Protocol not available */ -#define SOCEPROTONOSUPPORT (SOCBASEERR+43) /* Protocol not supported */ -#define SOCESOCKTNOSUPPORT (SOCBASEERR+44) /* Socket type not supported */ -#define SOCEOPNOTSUPP (SOCBASEERR+45) /* Operation not supported on socket */ -#define SOCEPFNOSUPPORT (SOCBASEERR+46) /* Protocol family not supported */ -#define SOCEAFNOSUPPORT (SOCBASEERR+47) /* Address family not supported by protocol family */ -#define SOCEADDRINUSE (SOCBASEERR+48) /* Address already in use */ -#define SOCEADDRNOTAVAIL (SOCBASEERR+49) /* Can't assign requested address */ -#define SOCENETDOWN (SOCBASEERR+50) /* Network is down */ -#define SOCENETUNREACH (SOCBASEERR+51) /* Network is unreachable */ -#define SOCENETRESET (SOCBASEERR+52) /* Network dropped connection on reset */ -#define SOCECONNABORTED (SOCBASEERR+53) /* Software caused connection abort */ -#define SOCECONNRESET (SOCBASEERR+54) /* Connection reset by peer */ -#define SOCENOBUFS (SOCBASEERR+55) /* No buffer space available */ -#define SOCEISCONN (SOCBASEERR+56) /* Socket is already connected */ -#define SOCENOTCONN (SOCBASEERR+57) /* Socket is not connected */ -#define SOCESHUTDOWN (SOCBASEERR+58) /* Can't send after socket shutdown */ -#define SOCETOOMANYREFS (SOCBASEERR+59) /* Too many references: can't splice */ -#define SOCETIMEDOUT (SOCBASEERR+60) /* Connection timed out */ -#define SOCECONNREFUSED (SOCBASEERR+61) /* Connection refused */ -#define SOCELOOP (SOCBASEERR+62) /* Too many levels of symbolic links */ -#define SOCENAMETOOLONG (SOCBASEERR+63) /* File name too long */ -#define SOCEHOSTDOWN (SOCBASEERR+64) /* Host is down */ -#define SOCEHOSTUNREACH (SOCBASEERR+65) /* No route to host */ -#define SOCENOTEMPTY (SOCBASEERR+66) /* Directory not empty */ - -/* APR CANONICAL ERROR TESTS */ -#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES \ - || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED \ - || (s) == APR_OS_START_SYSERR + ERROR_SHARING_VIOLATION) -#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST \ - || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED \ - || (s) == APR_OS_START_SYSERR + ERROR_FILE_EXISTS \ - || (s) == APR_OS_START_SYSERR + ERROR_ALREADY_EXISTS \ - || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED) -#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG \ - || (s) == APR_OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \ - || (s) == APR_OS_START_SYSERR + SOCENAMETOOLONG) -#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT \ - || (s) == APR_OS_START_SYSERR + ERROR_FILE_NOT_FOUND \ - || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \ - || (s) == APR_OS_START_SYSERR + ERROR_NO_MORE_FILES \ - || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED) -#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR) -#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC \ - || (s) == APR_OS_START_SYSERR + ERROR_DISK_FULL) -#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM) -#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE \ - || (s) == APR_OS_START_SYSERR + ERROR_TOO_MANY_OPEN_FILES) -#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE) -#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE) -#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_PARAMETER \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_FUNCTION) -#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE \ - || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK) -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \ - || (s) == APR_OS_START_SYSERR + ERROR_NO_DATA \ - || (s) == APR_OS_START_SYSERR + SOCEWOULDBLOCK \ - || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION) -#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR \ - || (s) == APR_OS_START_SYSERR + SOCEINTR) -#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK \ - || (s) == APR_OS_START_SYSERR + SOCENOTSOCK) -#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED \ - || (s) == APR_OS_START_SYSERR + SOCECONNREFUSED) -#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS \ - || (s) == APR_OS_START_SYSERR + SOCEINPROGRESS) -#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \ - || (s) == APR_OS_START_SYSERR + SOCECONNABORTED) -#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET \ - || (s) == APR_OS_START_SYSERR + SOCECONNRESET) -/* XXX deprecated */ -#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT) -#undef APR_STATUS_IS_TIMEUP -#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \ - || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT) -#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \ - || (s) == APR_OS_START_SYSERR + SOCEHOSTUNREACH) -#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \ - || (s) == APR_OS_START_SYSERR + SOCENETUNREACH) -#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE) -#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE \ - || (s) == APR_OS_START_SYSERR + ERROR_BROKEN_PIPE \ - || (s) == APR_OS_START_SYSERR + SOCEPIPE) -#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV \ - || (s) == APR_OS_START_SYSERR + ERROR_NOT_SAME_DEVICE) -#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY \ - || (s) == APR_OS_START_SYSERR + ERROR_DIR_NOT_EMPTY \ - || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED) - -/* - Sorry, too tired to wrap this up for OS2... feel free to - fit the following into their best matches. - - { ERROR_NO_SIGNAL_SENT, ESRCH }, - { SOCEALREADY, EALREADY }, - { SOCEDESTADDRREQ, EDESTADDRREQ }, - { SOCEMSGSIZE, EMSGSIZE }, - { SOCEPROTOTYPE, EPROTOTYPE }, - { SOCENOPROTOOPT, ENOPROTOOPT }, - { SOCEPROTONOSUPPORT, EPROTONOSUPPORT }, - { SOCESOCKTNOSUPPORT, ESOCKTNOSUPPORT }, - { SOCEOPNOTSUPP, EOPNOTSUPP }, - { SOCEPFNOSUPPORT, EPFNOSUPPORT }, - { SOCEAFNOSUPPORT, EAFNOSUPPORT }, - { SOCEADDRINUSE, EADDRINUSE }, - { SOCEADDRNOTAVAIL, EADDRNOTAVAIL }, - { SOCENETDOWN, ENETDOWN }, - { SOCENETRESET, ENETRESET }, - { SOCENOBUFS, ENOBUFS }, - { SOCEISCONN, EISCONN }, - { SOCENOTCONN, ENOTCONN }, - { SOCESHUTDOWN, ESHUTDOWN }, - { SOCETOOMANYREFS, ETOOMANYREFS }, - { SOCELOOP, ELOOP }, - { SOCEHOSTDOWN, EHOSTDOWN }, - { SOCENOTEMPTY, ENOTEMPTY }, - { SOCEPIPE, EPIPE } -*/ - -#elif defined(WIN32) && !defined(DOXYGEN) /* !defined(OS2) */ - -#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR) -#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR) - -#define apr_get_os_error() (APR_FROM_OS_ERROR(GetLastError())) -#define apr_set_os_error(e) (SetLastError(APR_TO_OS_ERROR(e))) - -/* A special case, only socket calls require this: - */ -#define apr_get_netos_error() (APR_FROM_OS_ERROR(WSAGetLastError())) -#define apr_set_netos_error(e) (WSASetLastError(APR_TO_OS_ERROR(e))) - -/* APR CANONICAL ERROR TESTS */ -#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES \ - || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED \ - || (s) == APR_OS_START_SYSERR + ERROR_CANNOT_MAKE \ - || (s) == APR_OS_START_SYSERR + ERROR_CURRENT_DIRECTORY \ - || (s) == APR_OS_START_SYSERR + ERROR_DRIVE_LOCKED \ - || (s) == APR_OS_START_SYSERR + ERROR_FAIL_I24 \ - || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION \ - || (s) == APR_OS_START_SYSERR + ERROR_LOCK_FAILED \ - || (s) == APR_OS_START_SYSERR + ERROR_NOT_LOCKED \ - || (s) == APR_OS_START_SYSERR + ERROR_NETWORK_ACCESS_DENIED \ - || (s) == APR_OS_START_SYSERR + ERROR_SHARING_VIOLATION) -#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST \ - || (s) == APR_OS_START_SYSERR + ERROR_FILE_EXISTS \ - || (s) == APR_OS_START_SYSERR + ERROR_ALREADY_EXISTS) -#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG \ - || (s) == APR_OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \ - || (s) == APR_OS_START_SYSERR + WSAENAMETOOLONG) -#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT \ - || (s) == APR_OS_START_SYSERR + ERROR_FILE_NOT_FOUND \ - || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \ - || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED \ - || (s) == APR_OS_START_SYSERR + ERROR_NO_MORE_FILES) -#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR \ - || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \ - || (s) == APR_OS_START_SYSERR + ERROR_BAD_NETPATH \ - || (s) == APR_OS_START_SYSERR + ERROR_BAD_NET_NAME \ - || (s) == APR_OS_START_SYSERR + ERROR_BAD_PATHNAME \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DRIVE) -#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC \ - || (s) == APR_OS_START_SYSERR + ERROR_DISK_FULL) -#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM \ - || (s) == APR_OS_START_SYSERR + ERROR_ARENA_TRASHED \ - || (s) == APR_OS_START_SYSERR + ERROR_NOT_ENOUGH_MEMORY \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_BLOCK \ - || (s) == APR_OS_START_SYSERR + ERROR_NOT_ENOUGH_QUOTA \ - || (s) == APR_OS_START_SYSERR + ERROR_OUTOFMEMORY) -#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE \ - || (s) == APR_OS_START_SYSERR + ERROR_TOO_MANY_OPEN_FILES) -#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE) -#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_TARGET_HANDLE) -#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_ACCESS \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DATA \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_FUNCTION \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_PARAMETER \ - || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK) -#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE \ - || (s) == APR_OS_START_SYSERR + ERROR_SEEK_ON_DEVICE \ - || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK) -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \ - || (s) == APR_OS_START_SYSERR + ERROR_NO_DATA \ - || (s) == APR_OS_START_SYSERR + ERROR_NO_PROC_SLOTS \ - || (s) == APR_OS_START_SYSERR + ERROR_NESTING_NOT_ALLOWED \ - || (s) == APR_OS_START_SYSERR + ERROR_MAX_THRDS_REACHED \ - || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION \ - || (s) == APR_OS_START_SYSERR + WSAEWOULDBLOCK) -#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR \ - || (s) == APR_OS_START_SYSERR + WSAEINTR) -#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK \ - || (s) == APR_OS_START_SYSERR + WSAENOTSOCK) -#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED \ - || (s) == APR_OS_START_SYSERR + WSAECONNREFUSED) -#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS \ - || (s) == APR_OS_START_SYSERR + WSAEINPROGRESS) -#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \ - || (s) == APR_OS_START_SYSERR + WSAECONNABORTED) -#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET \ - || (s) == APR_OS_START_SYSERR + ERROR_NETNAME_DELETED \ - || (s) == APR_OS_START_SYSERR + WSAECONNRESET) -/* XXX deprecated */ -#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT) -#undef APR_STATUS_IS_TIMEUP -#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \ - || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT) -#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \ - || (s) == APR_OS_START_SYSERR + WSAEHOSTUNREACH) -#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \ - || (s) == APR_OS_START_SYSERR + WSAENETUNREACH) -#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE \ - || (s) == APR_OS_START_SYSERR + ERROR_EXE_MACHINE_TYPE_MISMATCH \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DLL \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_MODULETYPE \ - || (s) == APR_OS_START_SYSERR + ERROR_BAD_EXE_FORMAT \ - || (s) == APR_OS_START_SYSERR + ERROR_INVALID_EXE_SIGNATURE \ - || (s) == APR_OS_START_SYSERR + ERROR_FILE_CORRUPT \ - || (s) == APR_OS_START_SYSERR + ERROR_BAD_FORMAT) -#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE \ - || (s) == APR_OS_START_SYSERR + ERROR_BROKEN_PIPE) -#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV \ - || (s) == APR_OS_START_SYSERR + ERROR_NOT_SAME_DEVICE) -#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY \ - || (s) == APR_OS_START_SYSERR + ERROR_DIR_NOT_EMPTY) - -#elif defined(NETWARE) && defined(USE_WINSOCK) && !defined(DOXYGEN) /* !defined(OS2) && !defined(WIN32) */ - -#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR) -#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR) - -#define apr_get_os_error() (errno) -#define apr_set_os_error(e) (errno = (e)) - -/* A special case, only socket calls require this: */ -#define apr_get_netos_error() (APR_FROM_OS_ERROR(WSAGetLastError())) -#define apr_set_netos_error(e) (WSASetLastError(APR_TO_OS_ERROR(e))) - -/* APR CANONICAL ERROR TESTS */ -#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES) -#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST) -#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG) -#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT) -#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR) -#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC) -#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM) -#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE) -#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE) -#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF) -#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL) -#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE) - -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \ - || (s) == EWOULDBLOCK \ - || (s) == APR_OS_START_SYSERR + WSAEWOULDBLOCK) -#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR \ - || (s) == APR_OS_START_SYSERR + WSAEINTR) -#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK \ - || (s) == APR_OS_START_SYSERR + WSAENOTSOCK) -#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED \ - || (s) == APR_OS_START_SYSERR + WSAECONNREFUSED) -#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS \ - || (s) == APR_OS_START_SYSERR + WSAEINPROGRESS) -#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \ - || (s) == APR_OS_START_SYSERR + WSAECONNABORTED) -#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET \ - || (s) == APR_OS_START_SYSERR + WSAECONNRESET) -/* XXX deprecated */ -#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT) -#undef APR_STATUS_IS_TIMEUP -#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \ - || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \ - || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT) -#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \ - || (s) == APR_OS_START_SYSERR + WSAEHOSTUNREACH) -#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \ - || (s) == APR_OS_START_SYSERR + WSAENETUNREACH) -#define APR_STATUS_IS_ENETDOWN(s) ((s) == APR_OS_START_SYSERR + WSAENETDOWN) -#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE) -#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE) -#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV) -#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY) - -#else /* !defined(NETWARE) && !defined(OS2) && !defined(WIN32) */ - -/* - * os error codes are clib error codes - */ -#define APR_FROM_OS_ERROR(e) (e) -#define APR_TO_OS_ERROR(e) (e) - -#define apr_get_os_error() (errno) -#define apr_set_os_error(e) (errno = (e)) - -/* A special case, only socket calls require this: - */ -#define apr_get_netos_error() (errno) -#define apr_set_netos_error(e) (errno = (e)) - -/** - * @addtogroup APR_STATUS_IS - * @{ - */ - -/** permission denied */ -#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES) -/** file exists */ -#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST) -/** path name is too long */ -#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG) -/** - * no such file or directory - * @remark - * EMVSCATLG can be returned by the automounter on z/OS for - * paths which do not exist. - */ -#ifdef EMVSCATLG -#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT \ - || (s) == EMVSCATLG) -#else -#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT) -#endif -/** not a directory */ -#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR) -/** no space left on device */ -#ifdef EDQUOT -#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC \ - || (s) == EDQUOT) -#else -#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC) -#endif -/** not enough memory */ -#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM) -/** too many open files */ -#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE) -/** file table overflow */ -#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE) -/** bad file # */ -#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF) -/** invalid argument */ -#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL) -/** illegal seek */ -#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE) - -/** operation would block */ -#if !defined(EWOULDBLOCK) || !defined(EAGAIN) -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN) -#elif (EWOULDBLOCK == EAGAIN) -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN) -#else -#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \ - || (s) == EWOULDBLOCK) -#endif - -/** interrupted system call */ -#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR) -/** socket operation on a non-socket */ -#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK) -/** Connection Refused */ -#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED) -/** operation now in progress */ -#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS) - -/** - * Software caused connection abort - * @remark - * EPROTO on certain older kernels really means ECONNABORTED, so we need to - * ignore it for them. See discussion in new-httpd archives nh.9701 & nh.9603 - * - * There is potentially a bug in Solaris 2.x x<6, and other boxes that - * implement tcp sockets in userland (i.e. on top of STREAMS). On these - * systems, EPROTO can actually result in a fatal loop. See PR#981 for - * example. It's hard to handle both uses of EPROTO. - */ -#ifdef EPROTO -#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \ - || (s) == EPROTO) -#else -#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED) -#endif - -/** Connection Reset by peer */ -#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET) -/** Operation timed out - * @deprecated */ -#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT) -/** no route to host */ -#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH) -/** network is unreachable */ -#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH) -/** inappropriate file type or format */ -#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE) -/** broken pipe */ -#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE) -/** cross device link */ -#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV) -/** Directory Not Empty */ -#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY || \ - (s) == APR_EEXIST) -/** @} */ - -#endif /* !defined(NETWARE) && !defined(OS2) && !defined(WIN32) */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* ! APR_ERRNO_H */ -/* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include <sys/errno.h> - - -/* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)errno.h 8.5 (Berkeley) 1/21/94 - */ - -#ifndef _SYS_ERRNO_H_ -#define _SYS_ERRNO_H_ - -#include <sys/cdefs.h> -__BEGIN_DECLS -extern int * __error(void); -#define errno (*__error()) -__END_DECLS - -/* - * Error codes - */ - -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* Input/output error */ -#define ENXIO 6 /* Device not configured */ -#define E2BIG 7 /* Argument list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file descriptor */ -#define ECHILD 10 /* No child processes */ -#define EDEADLK 11 /* Resource deadlock avoided */ - /* 11 was EAGAIN */ -#define ENOMEM 12 /* Cannot allocate memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define ENOTBLK 15 /* Block device required */ -#endif -#define EBUSY 16 /* Device / Resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* Operation not supported by device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* Too many open files in system */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Inappropriate ioctl for device */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ - -/* math software */ -#define EDOM 33 /* Numerical argument out of domain */ -#define ERANGE 34 /* Result too large */ - -/* non-blocking and interrupt i/o */ -#define EAGAIN 35 /* Resource temporarily unavailable */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define EINPROGRESS 36 /* Operation now in progress */ -#define EALREADY 37 /* Operation already in progress */ - -/* ipc/network software -- argument errors */ -#define ENOTSOCK 38 /* Socket operation on non-socket */ -#define EDESTADDRREQ 39 /* Destination address required */ -#define EMSGSIZE 40 /* Message too long */ -#define EPROTOTYPE 41 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 42 /* Protocol not available */ -#define EPROTONOSUPPORT 43 /* Protocol not supported */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ -#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ -#define ENOTSUP 45 /* Operation not supported */ -#if !__DARWIN_UNIX03 && !defined(KERNEL) -/* - * This is the same for binary and source copmpatability, unless compiling - * the kernel itself, or compiling __DARWIN_UNIX03; if compiling for the - * kernel, the correct value will be returned. If compiling non-POSIX - * source, the kernel return value will be converted by a stub in libc, and - * if compiling source with __DARWIN_UNIX03, the conversion in libc is not - * done, and the caller gets the expected (discrete) value. - */ -#define EOPNOTSUPP ENOTSUP /* Operation not supported on socket */ -#endif /* !__DARWIN_UNIX03 && !KERNEL */ - -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define EPFNOSUPPORT 46 /* Protocol family not supported */ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ -#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ -#define EADDRINUSE 48 /* Address already in use */ -#define EADDRNOTAVAIL 49 /* Can't assign requested address */ - -/* ipc/network software -- operational errors */ -#define ENETDOWN 50 /* Network is down */ -#define ENETUNREACH 51 /* Network is unreachable */ -#define ENETRESET 52 /* Network dropped connection on reset */ -#define ECONNABORTED 53 /* Software caused connection abort */ -#define ECONNRESET 54 /* Connection reset by peer */ -#define ENOBUFS 55 /* No buffer space available */ -#define EISCONN 56 /* Socket is already connected */ -#define ENOTCONN 57 /* Socket is not connected */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define ESHUTDOWN 58 /* Can't send after socket shutdown */ -#define ETOOMANYREFS 59 /* Too many references: can't splice */ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ -#define ETIMEDOUT 60 /* Operation timed out */ -#define ECONNREFUSED 61 /* Connection refused */ - -#define ELOOP 62 /* Too many levels of symbolic links */ -#define ENAMETOOLONG 63 /* File name too long */ - -/* should be rearranged */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define EHOSTDOWN 64 /* Host is down */ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ -#define EHOSTUNREACH 65 /* No route to host */ -#define ENOTEMPTY 66 /* Directory not empty */ - -/* quotas & mush */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define EPROCLIM 67 /* Too many processes */ -#define EUSERS 68 /* Too many users */ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ -#define EDQUOT 69 /* Disc quota exceeded */ - -/* Network File System */ -#define ESTALE 70 /* Stale NFS file handle */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define EREMOTE 71 /* Too many levels of remote in path */ -#define EBADRPC 72 /* RPC struct is bad */ -#define ERPCMISMATCH 73 /* RPC version wrong */ -#define EPROGUNAVAIL 74 /* RPC prog. not avail */ -#define EPROGMISMATCH 75 /* Program version wrong */ -#define EPROCUNAVAIL 76 /* Bad procedure for program */ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ - -#define ENOLCK 77 /* No locks available */ -#define ENOSYS 78 /* Function not implemented */ - -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define EFTYPE 79 /* Inappropriate file type or format */ -#define EAUTH 80 /* Authentication error */ -#define ENEEDAUTH 81 /* Need authenticator */ - -/* Intelligent device errors */ -#define EPWROFF 82 /* Device power is off */ -#define EDEVERR 83 /* Device error, e.g. paper out */ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ - -#define EOVERFLOW 84 /* Value too large to be stored in data type */ - -/* Program loading errors */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define EBADEXEC 85 /* Bad executable */ -#define EBADARCH 86 /* Bad CPU type in executable */ -#define ESHLIBVERS 87 /* Shared library version mismatch */ -#define EBADMACHO 88 /* Malformed Macho file */ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ - -#define ECANCELED 89 /* Operation canceled */ - -#define EIDRM 90 /* Identifier removed */ -#define ENOMSG 91 /* No message of desired type */ -#define EILSEQ 92 /* Illegal byte sequence */ -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define ENOATTR 93 /* Attribute not found */ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ - -#define EBADMSG 94 /* Bad message */ -#define EMULTIHOP 95 /* Reserved */ -#define ENODATA 96 /* No message available on STREAM */ -#define ENOLINK 97 /* Reserved */ -#define ENOSR 98 /* No STREAM resources */ -#define ENOSTR 99 /* Not a STREAM */ -#define EPROTO 100 /* Protocol error */ -#define ETIME 101 /* STREAM ioctl timeout */ - -#if __DARWIN_UNIX03 || defined(KERNEL) -/* This value is only discrete when compiling __DARWIN_UNIX03, or KERNEL */ -#define EOPNOTSUPP 102 /* Operation not supported on socket */ -#endif /* __DARWIN_UNIX03 || KERNEL */ - -#define ENOPOLICY 103 /* No such policy registered */ - -#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#define ELAST 103 /* Must be equal largest errno */ -#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ - -#endif /* _SYS_ERRNO_H_ */ diff --git a/doc/legacy/errno.list.solaris.txt b/doc/legacy/errno.list.solaris.txt deleted file mode 100644 index 23601e9d374..00000000000 --- a/doc/legacy/errno.list.solaris.txt +++ /dev/null @@ -1,206 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2000 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * University Copyright- Copyright (c) 1982, 1986, 1988 - * The Regents of the University of California - * All Rights Reserved - * - * University Acknowledgment- Portions of this document are derived from - * software developed by the University of California, Berkeley, and its - * contributors. - */ - -#ifndef _SYS_ERRNO_H -#define _SYS_ERRNO_H - -#pragma ident "@(#)errno.h 1.22 05/06/08 SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Error codes - */ - -#define EPERM 1 /* Not super-user */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No children */ -#define EAGAIN 11 /* Resource temporarily unavailable */ -#define ENOMEM 12 /* Not enough core */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Mount device busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Inappropriate ioctl for device */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math arg out of domain of func */ -#define ERANGE 34 /* Math result not representable */ -#define ENOMSG 35 /* No message of desired type */ -#define EIDRM 36 /* Identifier removed */ -#define ECHRNG 37 /* Channel number out of range */ -#define EL2NSYNC 38 /* Level 2 not synchronized */ -#define EL3HLT 39 /* Level 3 halted */ -#define EL3RST 40 /* Level 3 reset */ -#define ELNRNG 41 /* Link number out of range */ -#define EUNATCH 42 /* Protocol driver not attached */ -#define ENOCSI 43 /* No CSI structure available */ -#define EL2HLT 44 /* Level 2 halted */ -#define EDEADLK 45 /* Deadlock condition. */ -#define ENOLCK 46 /* No record locks available. */ -#define ECANCELED 47 /* Operation canceled */ -#define ENOTSUP 48 /* Operation not supported */ - -/* Filesystem Quotas */ -#define EDQUOT 49 /* Disc quota exceeded */ - -/* Convergent Error Returns */ -#define EBADE 50 /* invalid exchange */ -#define EBADR 51 /* invalid request descriptor */ -#define EXFULL 52 /* exchange full */ -#define ENOANO 53 /* no anode */ -#define EBADRQC 54 /* invalid request code */ -#define EBADSLT 55 /* invalid slot */ -#define EDEADLOCK 56 /* file locking deadlock error */ - -#define EBFONT 57 /* bad font file fmt */ - -/* Interprocess Robust Locks */ -#define EOWNERDEAD 58 /* process died with the lock */ -#define ENOTRECOVERABLE 59 /* lock is not recoverable */ - -/* stream problems */ -#define ENOSTR 60 /* Device not a stream */ -#define ENODATA 61 /* no data (for no delay io) */ -#define ETIME 62 /* timer expired */ -#define ENOSR 63 /* out of streams resources */ - -#define ENONET 64 /* Machine is not on the network */ -#define ENOPKG 65 /* Package not installed */ -#define EREMOTE 66 /* The object is remote */ -#define ENOLINK 67 /* the link has been severed */ -#define EADV 68 /* advertise error */ -#define ESRMNT 69 /* srmount error */ - -#define ECOMM 70 /* Communication error on send */ -#define EPROTO 71 /* Protocol error */ - -/* Interprocess Robust Locks */ -#define ELOCKUNMAPPED 72 /* locked lock was unmapped */ - -#define ENOTACTIVE 73 /* Facility is not active */ -#define EMULTIHOP 74 /* multihop attempted */ -#define EBADMSG 77 /* trying to read unreadable message */ -#define ENAMETOOLONG 78 /* path name is too long */ -#define EOVERFLOW 79 /* value too large to be stored in data type */ -#define ENOTUNIQ 80 /* given log. name not unique */ -#define EBADFD 81 /* f.d. invalid for this operation */ -#define EREMCHG 82 /* Remote address changed */ - -/* shared library problems */ -#define ELIBACC 83 /* Can't access a needed shared lib. */ -#define ELIBBAD 84 /* Accessing a corrupted shared lib. */ -#define ELIBSCN 85 /* .lib section in a.out corrupted. */ -#define ELIBMAX 86 /* Attempting to link in too many libs. */ -#define ELIBEXEC 87 /* Attempting to exec a shared library. */ -#define EILSEQ 88 /* Illegal byte sequence. */ -#define ENOSYS 89 /* Unsupported file system operation */ -#define ELOOP 90 /* Symbolic link loop */ -#define ERESTART 91 /* Restartable system call */ -#define ESTRPIPE 92 /* if pipe/FIFO, don't sleep in stream head */ -#define ENOTEMPTY 93 /* directory not empty */ -#define EUSERS 94 /* Too many users (for UFS) */ - -/* BSD Networking Software */ - /* argument errors */ -#define ENOTSOCK 95 /* Socket operation on non-socket */ -#define EDESTADDRREQ 96 /* Destination address required */ -#define EMSGSIZE 97 /* Message too long */ -#define EPROTOTYPE 98 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 99 /* Protocol not available */ -#define EPROTONOSUPPORT 120 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 121 /* Socket type not supported */ -#define EOPNOTSUPP 122 /* Operation not supported on socket */ -#define EPFNOSUPPORT 123 /* Protocol family not supported */ -#define EAFNOSUPPORT 124 /* Address family not supported by */ - /* protocol family */ -#define EADDRINUSE 125 /* Address already in use */ -#define EADDRNOTAVAIL 126 /* Can't assign requested address */ - /* operational errors */ -#define ENETDOWN 127 /* Network is down */ -#define ENETUNREACH 128 /* Network is unreachable */ -#define ENETRESET 129 /* Network dropped connection because */ - /* of reset */ -#define ECONNABORTED 130 /* Software caused connection abort */ -#define ECONNRESET 131 /* Connection reset by peer */ -#define ENOBUFS 132 /* No buffer space available */ -#define EISCONN 133 /* Socket is already connected */ -#define ENOTCONN 134 /* Socket is not connected */ -/* XENIX has 135 - 142 */ -#define ESHUTDOWN 143 /* Can't send after socket shutdown */ -#define ETOOMANYREFS 144 /* Too many references: can't splice */ -#define ETIMEDOUT 145 /* Connection timed out */ -#define ECONNREFUSED 146 /* Connection refused */ -#define EHOSTDOWN 147 /* Host is down */ -#define EHOSTUNREACH 148 /* No route to host */ -#define EWOULDBLOCK EAGAIN -#define EALREADY 149 /* operation already in progress */ -#define EINPROGRESS 150 /* operation now in progress */ - -/* SUN Network File System */ -#define ESTALE 151 /* Stale NFS file handle */ - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_ERRNO_H */ diff --git a/doc/legacy/fdl.texi b/doc/legacy/fdl.texi deleted file mode 100644 index e33c687cdfb..00000000000 --- a/doc/legacy/fdl.texi +++ /dev/null @@ -1,454 +0,0 @@ - -@c @node GNU Free Documentation License -@c @appendixsec GNU Free Documentation License - -@cindex FDL, GNU Free Documentation License -@center Version 1.2, November 2002 - -@display -Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307, USA - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@enumerate 0 -@item -PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -functional and useful document @dfn{free} in the sense of freedom: to -assure everyone the effective freedom to copy and redistribute it, -with or without modifying it, either commercially or noncommercially. -Secondarily, this License preserves for the author and publisher a way -to get credit for their work, while not being considered responsible -for modifications made by others. - -This License is a kind of ``copyleft'', which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. - -@item -APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work, in any medium, that -contains a notice placed by the copyright holder saying it can be -distributed under the terms of this License. Such a notice grants a -world-wide, royalty-free license, unlimited in duration, to use that -work under the conditions stated herein. The ``Document'', below, -refers to any such manual or work. Any member of the public is a -licensee, and is addressed as ``you''. You accept the license if you -copy, modify or distribute the work in a way requiring permission -under copyright law. - -A ``Modified Version'' of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A ``Secondary Section'' is a named appendix or a front-matter section -of the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall -subject (or to related matters) and contains nothing that could fall -directly within that overall subject. (Thus, if the Document is in -part a textbook of mathematics, a Secondary Section may not explain -any mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. - -The ``Invariant Sections'' are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. If a -section does not fit the above definition of Secondary then it is not -allowed to be designated as Invariant. The Document may contain zero -Invariant Sections. If the Document does not identify any Invariant -Sections then there are none. - -The ``Cover Texts'' are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. A Front-Cover Text may -be at most 5 words, and a Back-Cover Text may be at most 25 words. - -A ``Transparent'' copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, that is suitable for revising the document -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup, or absence of markup, has been arranged to thwart -or discourage subsequent modification by readers is not Transparent. -An image format is not Transparent if used for any substantial amount -of text. A copy that is not ``Transparent'' is called ``Opaque''. - -Examples of suitable formats for Transparent copies include plain -@sc{ascii} without markup, Texinfo input format, La@TeX{} input -format, @acronym{SGML} or @acronym{XML} using a publicly available -@acronym{DTD}, and standard-conforming simple @acronym{HTML}, -PostScript or @acronym{PDF} designed for human modification. Examples -of transparent image formats include @acronym{PNG}, @acronym{XCF} and -@acronym{JPG}. Opaque formats include proprietary formats that can be -read and edited only by proprietary word processors, @acronym{SGML} or -@acronym{XML} for which the @acronym{DTD} and/or processing tools are -not generally available, and the machine-generated @acronym{HTML}, -PostScript or @acronym{PDF} produced by some word processors for -output purposes only. - -The ``Title Page'' means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, ``Title Page'' means -the text near the most prominent appearance of the work's title, -preceding the beginning of the body of the text. - -A section ``Entitled XYZ'' means a named subunit of the Document whose -title either is precisely XYZ or contains XYZ in parentheses following -text that translates XYZ in another language. (Here XYZ stands for a -specific section name mentioned below, such as ``Acknowledgements'', -``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' -of such a section when you modify the Document means that it remains a -section ``Entitled XYZ'' according to this definition. - -The Document may include Warranty Disclaimers next to the notice which -states that this License applies to the Document. These Warranty -Disclaimers are considered to be included by reference in this -License, but only as regards disclaiming warranties: any other -implication that these Warranty Disclaimers may have is void and has -no effect on the meaning of this License. - -@item -VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. - -You may also lend copies, under the same conditions stated above, and -you may publicly display copies. - -@item -COPYING IN QUANTITY - -If you publish printed copies (or copies in media that commonly have -printed covers) of the Document, numbering more than 100, and the -Document's license notice requires Cover Texts, you must enclose the -copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. - -If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a computer-network location from which the general network-using -public has access to download using public-standard network protocols -a complete Transparent copy of the Document, free of added material. -If you use the latter option, you must take reasonably prudent steps, -when you begin distribution of Opaque copies in quantity, to ensure -that this Transparent copy will remain thus accessible at the stated -location until at least one year after the last time you distribute an -Opaque copy (directly or through your agents or retailers) of that -edition to the public. - -It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to give -them a chance to provide you with an updated version of the Document. - -@item -MODIFICATIONS - -You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: - -@enumerate A -@item -Use in the Title Page (and on the covers, if any) a title distinct -from that of the Document, and from those of previous versions -(which should, if there were any, be listed in the History section -of the Document). You may use the same title as a previous version -if the original publisher of that version gives permission. - -@item -List on the Title Page, as authors, one or more persons or entities -responsible for authorship of the modifications in the Modified -Version, together with at least five of the principal authors of the -Document (all of its principal authors, if it has fewer than five), -unless they release you from this requirement. - -@item -State on the Title page the name of the publisher of the -Modified Version, as the publisher. - -@item -Preserve all the copyright notices of the Document. - -@item -Add an appropriate copyright notice for your modifications -adjacent to the other copyright notices. - -@item -Include, immediately after the copyright notices, a license notice -giving the public permission to use the Modified Version under the -terms of this License, in the form shown in the Addendum below. - -@item -Preserve in that license notice the full lists of Invariant Sections -and required Cover Texts given in the Document's license notice. - -@item -Include an unaltered copy of this License. - -@item -Preserve the section Entitled ``History'', Preserve its Title, and add -to it an item stating at least the title, year, new authors, and -publisher of the Modified Version as given on the Title Page. If -there is no section Entitled ``History'' in the Document, create one -stating the title, year, authors, and publisher of the Document as -given on its Title Page, then add an item describing the Modified -Version as stated in the previous sentence. - -@item -Preserve the network location, if any, given in the Document for -public access to a Transparent copy of the Document, and likewise -the network locations given in the Document for previous versions -it was based on. These may be placed in the ``History'' section. -You may omit a network location for a work that was published at -least four years before the Document itself, or if the original -publisher of the version it refers to gives permission. - -@item -For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve -the Title of the section, and preserve in the section all the -substance and tone of each of the contributor acknowledgements and/or -dedications given therein. - -@item -Preserve all the Invariant Sections of the Document, -unaltered in their text and in their titles. Section numbers -or the equivalent are not considered part of the section titles. - -@item -Delete any section Entitled ``Endorsements''. Such a section -may not be included in the Modified Version. - -@item -Do not retitle any existing section to be Entitled ``Endorsements'' or -to conflict in title with any Invariant Section. - -@item -Preserve any Warranty Disclaimers. -@end enumerate - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section Entitled ``Endorsements'', provided it contains -nothing but endorsements of your Modified Version by various -parties---for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - -@item -COMBINING DOCUMENTS - -You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice, and that you preserve all their Warranty Disclaimers. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. - -In the combination, you must combine any sections Entitled ``History'' -in the various original documents, forming one section Entitled -``History''; likewise combine any sections Entitled ``Acknowledgements'', -and any sections Entitled ``Dedications''. You must delete all -sections Entitled ``Endorsements.'' - -@item -COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this -License in the various documents with a single copy that is included in -the collection, provided that you follow the rules of this License for -verbatim copying of each of the documents in all other respects. - -You may extract a single document from such a collection, and distribute -it individually under this License, provided you insert a copy of this -License into the extracted document, and follow this License in all -other respects regarding verbatim copying of that document. - -@item -AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, is called an ``aggregate'' if the copyright -resulting from the compilation is not used to limit the legal rights -of the compilation's users beyond what the individual works permit. -When the Document is included in an aggregate, this License does not -apply to the other works in the aggregate which are not themselves -derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one half of -the entire aggregate, the Document's Cover Texts may be placed on -covers that bracket the Document within the aggregate, or the -electronic equivalent of covers if the Document is in electronic form. -Otherwise they must appear on printed covers that bracket the whole -aggregate. - -@item -TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License, and all the license notices in the -Document, and any Warranty Disclaimers, provided that you also include -the original English version of this License and the original versions -of those notices and disclaimers. In case of a disagreement between -the translation and the original version of this License or a notice -or disclaimer, the original version will prevail. - -If a section in the Document is Entitled ``Acknowledgements'', -``Dedications'', or ``History'', the requirement (section 4) to Preserve -its Title (section 1) will typically require changing the actual -title. - -@item -TERMINATION - -You may not copy, modify, sublicense, or distribute the Document except -as expressly provided for under this License. Any other attempt to -copy, modify, sublicense or distribute the Document is void, and will -automatically terminate your rights under this License. However, -parties who have received copies, or rights, from you under this -License will not have their licenses terminated so long as such -parties remain in full compliance. - -@item -FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions -of the GNU Free Documentation License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. See -@uref{http://www.gnu.org/copyleft/}. - -Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License ``or any later version'' applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. -@end enumerate - -@page -@c @appendixsubsec ADDENDUM: How to use this License for your -@c documents -@subsection ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - -@smallexample -@group - Copyright (C) @var{year} @var{your name}. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.2 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. A copy of the license is included in the section entitled ``GNU - Free Documentation License''. -@end group -@end smallexample - -If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, -replace the ``with...Texts.'' line with this: - -@smallexample -@group - with the Invariant Sections being @var{list their titles}, with - the Front-Cover Texts being @var{list}, and with the Back-Cover Texts - being @var{list}. -@end group -@end smallexample - -If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. - -@c Local Variables: -@c ispell-local-pdict: "ispell-dict" -@c End: - diff --git a/doc/legacy/fuse.odg b/doc/legacy/fuse.odg Binary files differdeleted file mode 100644 index 61bd103c78b..00000000000 --- a/doc/legacy/fuse.odg +++ /dev/null diff --git a/doc/legacy/fuse.pdf b/doc/legacy/fuse.pdf Binary files differdeleted file mode 100644 index a7d13faff56..00000000000 --- a/doc/legacy/fuse.pdf +++ /dev/null diff --git a/doc/legacy/get_put_api_using_xattr.txt b/doc/legacy/get_put_api_using_xattr.txt deleted file mode 100644 index 243f9f1aec2..00000000000 --- a/doc/legacy/get_put_api_using_xattr.txt +++ /dev/null @@ -1,22 +0,0 @@ -GlusterFS get/put API interface provided through extended attributes: - -API usage: - int put(dirpath/filename, data): setfattr -n glusterfs.file.<filename> -v <data> <dirpath> - void *get(dirpath/filename): getfattr -n glusterfs.file.<filename> <dirpath> - - -internals: -* unify handling setxattr/getxattr - - setxattr - unify's setxattr forwards setxattr call to all the child nodes with XATTR_REPLACE flag, except namespace. setxattr will succeeds only on the child node on which the file already exists. if the setxattr operation fails on all child nodes, it indicates that the file does not already exist on any of the child nodes. unify follows the same rules as it follows for create, but using setxattr call itself with XATTR_CREATE flag. unify sends a setxattr to namespace first, with zero length data. if namespace setxattr succeeds, unify schedules setxattr to one of the child nodes. - - - getxattr - unify's getxattr forwards getxattr call to all the child nodes. wait for completion of operation on all the child nodes, and returns success if getxattr succeeded one child node. - -* posix handling setxattr/getxattr - - setxattr - posix setxattr does a open with O_CREAT|O_TRUNC on the <path>/<name>, writes value of the setxattr as data into the file and closes the file. when data is null, posix setxattr avoids doing write. file is closed after write. - - - getxattr - posix getxattr does open with O_RDONLY on the <path>/<name>, reads the complete content of the file. file is closed after read. - diff --git a/doc/legacy/ha.odg b/doc/legacy/ha.odg Binary files differdeleted file mode 100644 index e4b8b72d08b..00000000000 --- a/doc/legacy/ha.odg +++ /dev/null diff --git a/doc/legacy/ha.pdf b/doc/legacy/ha.pdf Binary files differdeleted file mode 100644 index e372c0ab03e..00000000000 --- a/doc/legacy/ha.pdf +++ /dev/null diff --git a/doc/legacy/hacker-guide/Makefile.am b/doc/legacy/hacker-guide/Makefile.am deleted file mode 100644 index 65c92ac235e..00000000000 --- a/doc/legacy/hacker-guide/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -EXTRA_DIST = replicate.txt bdb.txt posix.txt call-stub.txt write-behind.txt - -#EXTRA_DIST = hacker-guide.tex afr.txt bdb.txt posix.txt call-stub.txt write-behind.txt -#hacker_guidedir = $(docdir) -#hacker_guide_DATA = hacker-guide.pdf - -#hacker-guide.pdf: $(EXTRA_DIST) -# pdflatex $(srcdir)/hacker-guide.tex diff --git a/doc/legacy/hacker-guide/call-stub.txt b/doc/legacy/hacker-guide/call-stub.txt deleted file mode 100644 index cab8e4d552e..00000000000 --- a/doc/legacy/hacker-guide/call-stub.txt +++ /dev/null @@ -1,1033 +0,0 @@ -creating a call stub and pausing a call ---------------------------------------- -libglusterfs provides separate API to pause each of the fop. parameters to each API is -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). - NOTE: @fn should exactly take the same type and number of parameters that - the corresponding regular fop takes. -rest will be the regular parameters to corresponding fop. - -NOTE: @frame can never be NULL. fop_<operation>_stub() fails with errno - set to EINVAL, if @frame is NULL. also wherever @loc is applicable, - @loc cannot be NULL. - -refer to individual stub creation API to know about call-stub creation's behaviour with -specific parameters. - -here is the list of stub creation APIs for xlator fops. - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@need_xattr - flag to specify if xattr should be returned or not. -call_stub_t * -fop_lookup_stub (call_frame_t *frame, - fop_lookup_t fn, - loc_t *loc, - int32_t need_xattr); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -call_stub_t * -fop_stat_stub (call_frame_t *frame, - fop_stat_t fn, - loc_t *loc); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to lk fop. - NOTE: @fd is stored with a fd_ref(). -call_stub_t * -fop_fstat_stub (call_frame_t *frame, - fop_fstat_t fn, - fd_t *fd); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to @loc->inode and - @loc->parent, if not NULL. also @loc->path will be copied to a different location. -@mode - mode parameter to chmod. -call_stub_t * -fop_chmod_stub (call_frame_t *frame, - fop_chmod_t fn, - loc_t *loc, - mode_t mode); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to lk fop. - NOTE: @fd is stored with a fd_ref(). -@mode - mode parameter for fchmod fop. -call_stub_t * -fop_fchmod_stub (call_frame_t *frame, - fop_fchmod_t fn, - fd_t *fd, - mode_t mode); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to @loc->inode and - @loc->parent, if not NULL. also @loc->path will be copied to a different location. -@uid - uid parameter to chown. -@gid - gid parameter to chown. -call_stub_t * -fop_chown_stub (call_frame_t *frame, - fop_chown_t fn, - loc_t *loc, - uid_t uid, - gid_t gid); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to lk fop. - NOTE: @fd is stored with a fd_ref(). -@uid - uid parameter to fchown. -@gid - gid parameter to fchown. -call_stub_t * -fop_fchown_stub (call_frame_t *frame, - fop_fchown_t fn, - fd_t *fd, - uid_t uid, - gid_t gid); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location, if not NULL. -@off - offset parameter to truncate fop. -call_stub_t * -fop_truncate_stub (call_frame_t *frame, - fop_truncate_t fn, - loc_t *loc, - off_t off); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to lk fop. - NOTE: @fd is stored with a fd_ref(). -@off - offset parameter to ftruncate fop. -call_stub_t * -fop_ftruncate_stub (call_frame_t *frame, - fop_ftruncate_t fn, - fd_t *fd, - off_t off); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@tv - tv parameter to utimens fop. -call_stub_t * -fop_utimens_stub (call_frame_t *frame, - fop_utimens_t fn, - loc_t *loc, - struct timespec tv[2]); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@mask - mask parameter for access fop. -call_stub_t * -fop_access_stub (call_frame_t *frame, - fop_access_t fn, - loc_t *loc, - int32_t mask); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@size - size parameter to readlink fop. -call_stub_t * -fop_readlink_stub (call_frame_t *frame, - fop_readlink_t fn, - loc_t *loc, - size_t size); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@mode - mode parameter to mknod fop. -@rdev - rdev parameter to mknod fop. -call_stub_t * -fop_mknod_stub (call_frame_t *frame, - fop_mknod_t fn, - loc_t *loc, - mode_t mode, - dev_t rdev); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@mode - mode parameter to mkdir fop. -call_stub_t * -fop_mkdir_stub (call_frame_t *frame, - fop_mkdir_t fn, - loc_t *loc, - mode_t mode); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -call_stub_t * -fop_unlink_stub (call_frame_t *frame, - fop_unlink_t fn, - loc_t *loc); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -call_stub_t * -fop_rmdir_stub (call_frame_t *frame, - fop_rmdir_t fn, - loc_t *loc); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@linkname - linkname parameter to symlink fop. -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -call_stub_t * -fop_symlink_stub (call_frame_t *frame, - fop_symlink_t fn, - const char *linkname, - loc_t *loc); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@oldloc - pointer to location structure. - NOTE: @oldloc will be copied to a different location, with inode_ref() to - @oldloc->inode and @oldloc->parent, if not NULL. also @oldloc->path will - be copied to a different location, if not NULL. -@newloc - pointer to location structure. - NOTE: @newloc will be copied to a different location, with inode_ref() to - @newloc->inode and @newloc->parent, if not NULL. also @newloc->path will - be copied to a different location, if not NULL. -call_stub_t * -fop_rename_stub (call_frame_t *frame, - fop_rename_t fn, - loc_t *oldloc, - loc_t *newloc); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@newpath - newpath parameter to link fop. -call_stub_t * -fop_link_stub (call_frame_t *frame, - fop_link_t fn, - loc_t *oldloc, - const char *newpath); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@flags - flags parameter to create fop. -@mode - mode parameter to create fop. -@fd - file descriptor parameter to create fop. - NOTE: @fd is stored with a fd_ref(). -call_stub_t * -fop_create_stub (call_frame_t *frame, - fop_create_t fn, - loc_t *loc, - int32_t flags, - mode_t mode, fd_t *fd); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@flags - flags parameter to open fop. -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -call_stub_t * -fop_open_stub (call_frame_t *frame, - fop_open_t fn, - loc_t *loc, - int32_t flags, - fd_t *fd); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to lk fop. - NOTE: @fd is stored with a fd_ref(). -@size - size parameter to readv fop. -@off - offset parameter to readv fop. -call_stub_t * -fop_readv_stub (call_frame_t *frame, - fop_readv_t fn, - fd_t *fd, - size_t size, - off_t off); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to lk fop. - NOTE: @fd is stored with a fd_ref(). -@vector - vector parameter to writev fop. - NOTE: @vector is iov_dup()ed while creating stub. and frame->root->req_refs - dictionary is dict_ref()ed. -@count - count parameter to writev fop. -@off - off parameter to writev fop. -call_stub_t * -fop_writev_stub (call_frame_t *frame, - fop_writev_t fn, - fd_t *fd, - struct iovec *vector, - int32_t count, - off_t off); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to flush fop. - NOTE: @fd is stored with a fd_ref(). -call_stub_t * -fop_flush_stub (call_frame_t *frame, - fop_flush_t fn, - fd_t *fd); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to lk fop. - NOTE: @fd is stored with a fd_ref(). -@datasync - datasync parameter to fsync fop. -call_stub_t * -fop_fsync_stub (call_frame_t *frame, - fop_fsync_t fn, - fd_t *fd, - int32_t datasync); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to @loc->inode and - @loc->parent, if not NULL. also @loc->path will be copied to a different location. -@fd - file descriptor parameter to opendir fop. - NOTE: @fd is stored with a fd_ref(). -call_stub_t * -fop_opendir_stub (call_frame_t *frame, - fop_opendir_t fn, - loc_t *loc, - fd_t *fd); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to getdents fop. - NOTE: @fd is stored with a fd_ref(). -@size - size parameter to getdents fop. -@off - off parameter to getdents fop. -@flags - flags parameter to getdents fop. -call_stub_t * -fop_getdents_stub (call_frame_t *frame, - fop_getdents_t fn, - fd_t *fd, - size_t size, - off_t off, - int32_t flag); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to setdents fop. - NOTE: @fd is stored with a fd_ref(). -@flags - flags parameter to setdents fop. -@entries - entries parameter to setdents fop. -call_stub_t * -fop_setdents_stub (call_frame_t *frame, - fop_setdents_t fn, - fd_t *fd, - int32_t flags, - dir_entry_t *entries, - int32_t count); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to setdents fop. - NOTE: @fd is stored with a fd_ref(). -@datasync - datasync parameter to fsyncdir fop. -call_stub_t * -fop_fsyncdir_stub (call_frame_t *frame, - fop_fsyncdir_t fn, - fd_t *fd, - int32_t datasync); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -call_stub_t * -fop_statfs_stub (call_frame_t *frame, - fop_statfs_t fn, - loc_t *loc); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@dict - dict parameter to setxattr fop. - NOTE: stub creation procedure stores @dict pointer with dict_ref() to it. -call_stub_t * -fop_setxattr_stub (call_frame_t *frame, - fop_setxattr_t fn, - loc_t *loc, - dict_t *dict, - int32_t flags); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@name - name parameter to getxattr fop. -call_stub_t * -fop_getxattr_stub (call_frame_t *frame, - fop_getxattr_t fn, - loc_t *loc, - const char *name); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@name - name parameter to removexattr fop. - NOTE: name string will be copied to a different location while creating stub. -call_stub_t * -fop_removexattr_stub (call_frame_t *frame, - fop_removexattr_t fn, - loc_t *loc, - const char *name); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to lk fop. - NOTE: @fd is stored with a fd_ref(). -@cmd - command parameter to lk fop. -@lock - lock parameter to lk fop. - NOTE: lock will be copied to a different location while creating stub. -call_stub_t * -fop_lk_stub (call_frame_t *frame, - fop_lk_t fn, - fd_t *fd, - int32_t cmd, - struct flock *lock); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - fd parameter to gf_lk fop. - NOTE: @fd is fd_ref()ed while creating stub, if not NULL. -@cmd - cmd parameter to gf_lk fop. -@lock - lock paramater to gf_lk fop. - NOTE: @lock is copied to a different memory location while creating - stub. -call_stub_t * -fop_gf_lk_stub (call_frame_t *frame, - fop_gf_lk_t fn, - fd_t *fd, - int32_t cmd, - struct flock *lock); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@fd - file descriptor parameter to readdir fop. - NOTE: @fd is stored with a fd_ref(). -@size - size parameter to readdir fop. -@off - offset parameter to readdir fop. -call_stub_t * -fop_readdir_stub (call_frame_t *frame, - fop_readdir_t fn, - fd_t *fd, - size_t size, - off_t off); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@loc - pointer to location structure. - NOTE: @loc will be copied to a different location, with inode_ref() to - @loc->inode and @loc->parent, if not NULL. also @loc->path will be - copied to a different location. -@flags - flags parameter to checksum fop. -call_stub_t * -fop_checksum_stub (call_frame_t *frame, - fop_checksum_t fn, - loc_t *loc, - int32_t flags); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@inode - inode parameter to @fn. - NOTE: @inode pointer is stored with a inode_ref(). -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -@dict - dict parameter to @fn. - NOTE: @dict pointer is stored with dict_ref(). -call_stub_t * -fop_lookup_cbk_stub (call_frame_t *frame, - fop_lookup_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - inode_t *inode, - struct stat *buf, - dict_t *dict); -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_stat_cbk_stub (call_frame_t *frame, - fop_stat_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *buf); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_fstat_cbk_stub (call_frame_t *frame, - fop_fstat_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *buf); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_chmod_cbk_stub (call_frame_t *frame, - fop_chmod_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *buf); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_fchmod_cbk_stub (call_frame_t *frame, - fop_fchmod_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *buf); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_chown_cbk_stub (call_frame_t *frame, - fop_chown_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_fchown_cbk_stub (call_frame_t *frame, - fop_fchown_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_truncate_cbk_stub (call_frame_t *frame, - fop_truncate_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_ftruncate_cbk_stub (call_frame_t *frame, - fop_ftruncate_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_utimens_cbk_stub (call_frame_t *frame, - fop_utimens_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -call_stub_t * -fop_access_cbk_stub (call_frame_t *frame, - fop_access_cbk_t fn, - int32_t op_ret, - int32_t op_errno); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@path - path parameter to @fn. - NOTE: @path is copied to a different memory location, if not NULL. -call_stub_t * -fop_readlink_cbk_stub (call_frame_t *frame, - fop_readlink_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - const char *path); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@inode - inode parameter to @fn. - NOTE: @inode pointer is stored with a inode_ref(). -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_mknod_cbk_stub (call_frame_t *frame, - fop_mknod_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - inode_t *inode, - struct stat *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@inode - inode parameter to @fn. - NOTE: @inode pointer is stored with a inode_ref(). -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_mkdir_cbk_stub (call_frame_t *frame, - fop_mkdir_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - inode_t *inode, - struct stat *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -call_stub_t * -fop_unlink_cbk_stub (call_frame_t *frame, - fop_unlink_cbk_t fn, - int32_t op_ret, - int32_t op_errno); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -call_stub_t * -fop_rmdir_cbk_stub (call_frame_t *frame, - fop_rmdir_cbk_t fn, - int32_t op_ret, - int32_t op_errno); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@inode - inode parameter to @fn. - NOTE: @inode pointer is stored with a inode_ref(). -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_symlink_cbk_stub (call_frame_t *frame, - fop_symlink_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - inode_t *inode, - struct stat *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_rename_cbk_stub (call_frame_t *frame, - fop_rename_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@inode - inode parameter to @fn. - NOTE: @inode pointer is stored with a inode_ref(). -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_link_cbk_stub (call_frame_t *frame, - fop_link_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - inode_t *inode, - struct stat *buf); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@fd - fd parameter to @fn. - NOTE: @fd pointer is stored with a fd_ref(). -@inode - inode parameter to @fn. - NOTE: @inode pointer is stored with a inode_ref(). -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_create_cbk_stub (call_frame_t *frame, - fop_create_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - fd_t *fd, - inode_t *inode, - struct stat *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@fd - fd parameter to @fn. - NOTE: @fd pointer is stored with a fd_ref(). -call_stub_t * -fop_open_cbk_stub (call_frame_t *frame, - fop_open_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - fd_t *fd); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@vector - vector parameter to @fn. - NOTE: @vector is copied to a different memory location, if not NULL. also - frame->root->rsp_refs is dict_ref()ed. -@stbuf - stbuf parameter to @fn. - NOTE: @stbuf is copied to a different memory location, if not NULL. -call_stub_t * -fop_readv_cbk_stub (call_frame_t *frame, - fop_readv_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct iovec *vector, - int32_t count, - struct stat *stbuf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@stbuf - stbuf parameter to @fn. - NOTE: @stbuf is copied to a different memory location, if not NULL. -call_stub_t * -fop_writev_cbk_stub (call_frame_t *frame, - fop_writev_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct stat *stbuf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -call_stub_t * -fop_flush_cbk_stub (call_frame_t *frame, - fop_flush_cbk_t fn, - int32_t op_ret, - int32_t op_errno); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -call_stub_t * -fop_fsync_cbk_stub (call_frame_t *frame, - fop_fsync_cbk_t fn, - int32_t op_ret, - int32_t op_errno); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@fd - fd parameter to @fn. - NOTE: @fd pointer is stored with a fd_ref(). -call_stub_t * -fop_opendir_cbk_stub (call_frame_t *frame, - fop_opendir_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - fd_t *fd); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@entries - entries parameter to @fn. -@count - count parameter to @fn. -call_stub_t * -fop_getdents_cbk_stub (call_frame_t *frame, - fop_getdents_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - dir_entry_t *entries, - int32_t count); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -call_stub_t * -fop_setdents_cbk_stub (call_frame_t *frame, - fop_setdents_cbk_t fn, - int32_t op_ret, - int32_t op_errno); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -call_stub_t * -fop_fsyncdir_cbk_stub (call_frame_t *frame, - fop_fsyncdir_cbk_t fn, - int32_t op_ret, - int32_t op_errno); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@buf - buf parameter to @fn. - NOTE: @buf is copied to a different memory location, if not NULL. -call_stub_t * -fop_statfs_cbk_stub (call_frame_t *frame, - fop_statfs_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct statvfs *buf); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -call_stub_t * -fop_setxattr_cbk_stub (call_frame_t *frame, - fop_setxattr_cbk_t fn, - int32_t op_ret, - int32_t op_errno); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@value - value dictionary parameter to @fn. - NOTE: @value pointer is stored with a dict_ref(). -call_stub_t * -fop_getxattr_cbk_stub (call_frame_t *frame, - fop_getxattr_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - dict_t *value); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -call_stub_t * -fop_removexattr_cbk_stub (call_frame_t *frame, - fop_removexattr_cbk_t fn, - int32_t op_ret, - int32_t op_errno); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@lock - lock parameter to @fn. - NOTE: @lock is copied to a different memory location while creating - stub. -call_stub_t * -fop_lk_cbk_stub (call_frame_t *frame, - fop_lk_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct flock *lock); - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@lock - lock parameter to @fn. - NOTE: @lock is copied to a different memory location while creating - stub. -call_stub_t * -fop_gf_lk_cbk_stub (call_frame_t *frame, - fop_gf_lk_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - struct flock *lock); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@entries - entries parameter to @fn. -call_stub_t * -fop_readdir_cbk_stub (call_frame_t *frame, - fop_readdir_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - gf_dirent_t *entries); - - -@frame - call frame which has to be used to resume the call at call_resume(). -@fn - procedure to call during call_resume(). -@op_ret - op_ret parameter to @fn. -@op_errno - op_errno parameter to @fn. -@file_checksum - file_checksum parameter to @fn. - NOTE: file_checksum will be copied to a different memory location - while creating stub. -@dir_checksum - dir_checksum parameter to @fn. - NOTE: file_checksum will be copied to a different memory location - while creating stub. -call_stub_t * -fop_checksum_cbk_stub (call_frame_t *frame, - fop_checksum_cbk_t fn, - int32_t op_ret, - int32_t op_errno, - uint8_t *file_checksum, - uint8_t *dir_checksum); - -resuming a call: ---------------- - call can be resumed using call stub through call_resume API. - - void call_resume (call_stub_t *stub); - - stub - call stub created during pausing a call. - - NOTE: call_resume() will decrease reference count of any fd_t, dict_t and inode_t that it finds - in stub->args.<operation>.<fd_t-or-inode_t-or-dict_t>. so, if any fd_t, dict_t or - inode_t pointers are assigned at stub->args.<operation>.<fd_t-or-inode_t-or-dict_t> after - fop_<operation>_stub() call, they must be <fd_t-or-inode_t-or-dict_t>_ref()ed. - - call_resume does not STACK_DESTROY() for any fop. - - if stub->fn is NULL, call_resume does STACK_WIND() or STACK_UNWIND() using the stub->frame. - - return - call resume fails only if stub is NULL. call resume fails with errno set to EINVAL. diff --git a/doc/legacy/hacker-guide/hacker-guide.tex b/doc/legacy/hacker-guide/hacker-guide.tex deleted file mode 100644 index 11101e7a87a..00000000000 --- a/doc/legacy/hacker-guide/hacker-guide.tex +++ /dev/null @@ -1,309 +0,0 @@ -\documentclass{book}[12pt] -\usepackage{graphicx} -% \usepackage{fancyhdr} - -% \pagestyle{fancy} -\begin{document} - -% \headheight 117pt -% \rhead{\includegraphics{zr-logo.eps}} - -\author{Gluster} -\title{GlusterFS 1.3 Hacker's Guide} -\date{June 1, 2007} - -\maketitle -\frontmatter -\tableofcontents - -\mainmatter -\chapter{Introduction} - -\section{Coding guidelines} -GlusterFS uses Git for version control. To get the latest source do: -\begin{verbatim} - $ git clone git://git.gluster.com/glusterfs.git glusterfs -\end{verbatim} -\noindent -GlusterFS follows the GNU coding -standards\footnote{http://www.gnu.org/prep/standards\_toc.html} for the -most part. - -\chapter{Major components} -\section{libglusterfs} -\texttt{libglusterfs} contains supporting code used by all the other components. -The important files here are: - -\texttt{dict.c}: This is an implementation of a serializable dictionary type. It is -used by the protocol code to send requests and replies. It is also used to pass options -to translators. - -\texttt{logging.c}: This is a thread-safe logging library. The log messages go to a -file (default \texttt{/usr/local/var/log/glusterfs/*}). - -\texttt{protocol.c}: This file implements the GlusterFS on-the-wire -protocol. The protocol itself is a simple ASCII protocol, designed to -be easy to parse and be human readable. - -A sample GlusterFS protocol block looks like this: -\begin{verbatim} - Block Start header - 0000000000000023 callid - 00000001 type - 00000016 op - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx human-readable name - 00000000000000000000000000000ac3 block size - <...> block - Block End -\end{verbatim} - -\texttt{stack.h}: This file defines the \texttt{STACK\_WIND} and -\texttt{STACK\_UNWIND} macros which are used to implement the parallel -stack that is maintained for inter-xlator calls. See the \textsl{Taking control -of the stack} section below for more details. - -\texttt{spec.y}: This contains the Yacc grammar for the GlusterFS -specification file, and the parsing code. - - -Draw diagrams of trees -Two rules: -(1) directory structure is same -(2) file can exist only on one node - -\section{glusterfs-fuse} -\section{glusterfsd} -\section{transport} -\section{scheduler} -\section{xlator} - -\chapter{xlators} -\section{Taking control of the stack} -One can think of STACK\_WIND/UNWIND as a very specific RPC mechanism. - -% \includegraphics{stack.eps} - -\section{Overview of xlators} - -\flushleft{\LARGE\texttt{cluster/}} -\vskip 2ex -\flushleft{\Large\texttt{afr}} -\vskip 2ex -\flushleft{\Large\texttt{stripe}} -\vskip 2ex -\flushleft{\Large\texttt{unify}} - -\vskip 4ex -\flushleft{\LARGE\texttt{debug/}} -\vskip 2ex -\flushleft{\Large\texttt{trace}} -\vskip 2ex -The trace xlator simply logs all fops and mops, and passes them through to its child. - -\vskip 4ex -\flushleft{\LARGE\texttt{features/}} -\flushleft{\Large\texttt{posix-locks}} -\vskip 2ex -This xlator implements \textsc{posix} record locking semantics over -any kind of storage. - -\vskip 4ex -\flushleft{\LARGE\texttt{performance/}} - -\flushleft{\Large\texttt{io-threads}} -\vskip 2ex -\flushleft{\Large\texttt{read-ahead}} -\vskip 2ex -\flushleft{\Large\texttt{stat-prefetch}} -\vskip 2ex -\flushleft{\Large\texttt{write-behind}} -\vskip 2ex - -\vskip 4ex -\flushleft{\LARGE\texttt{protocol/}} -\vskip 2ex - -\flushleft{\Large\texttt{client}} -\vskip 2ex - -\flushleft{\Large\texttt{server}} -\vskip 2ex - -\vskip 4ex -\flushleft{\LARGE\texttt{storage/}} -\flushleft{\Large\texttt{posix}} -\vskip 2ex -The \texttt{posix} xlator is the one which actually makes calls to the -on-disk filesystem. Currently this is the only storage xlator available. However, -plans to develop other storage xlators, such as one for Amazon's S3 service, are -on the roadmap. - -\chapter{Writing a simple xlator} -\noindent -In this section we're going to write a rot13 xlator. ``Rot13'' is a -simple substitution cipher which obscures a text by replacing each -letter with the letter thirteen places down the alphabet. So `a' (0) -would become `n' (12), `b' would be 'm', and so on. Rot13 applied to -a piece of ciphertext yields the plaintext again, because rot13 is its -own inverse, since: - -\[ -x_c = x + 13\; (mod\; 26) -\] -\[ -x_c + 13\; (mod\; 26) = x + 13 + 13\; (mod\; 26) = x -\] - -First we include the requisite headers. - -\begin{verbatim} -#include <ctype.h> -#include <sys/uio.h> - -#include "glusterfs.h" -#include "xlator.h" -#include "logging.h" - -/* - * This is a rot13 ``encryption'' xlator. It rot13's data when - * writing to disk and rot13's it back when reading it. - * This xlator is meant as an example, not for production - * use ;) (hence no error-checking) - */ - -\end{verbatim} - -Then we write the rot13 function itself. For simplicity, we only transform lower case -letters. Any other byte is passed through as it is. - -\begin{verbatim} -/* We only handle lower case letters for simplicity */ -static void -rot13 (char *buf, int len) -{ - int i; - for (i = 0; i < len; i++) { - if (isalpha (buf[i])) - buf[i] = (buf[i] - 'a' + 13) % 26; - else if (buf[i] <= 26) - buf[i] = (buf[i] + 13) % 26 + 'a'; - } -} -\end{verbatim} - -Next comes a utility function whose purpose will be clear after looking at the code -below. - -\begin{verbatim} -static void -rot13_iovec (struct iovec *vector, int count) -{ - int i; - for (i = 0; i < count; i++) { - rot13 (vector[i].iov_base, vector[i].iov_len); - } -} -\end{verbatim} - -\begin{verbatim} -static int32_t -rot13_readv_cbk (call_frame_t *frame, - call_frame_t *prev_frame, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct iovec *vector, - int32_t count) -{ - rot13_iovec (vector, count); - - STACK_UNWIND (frame, op_ret, op_errno, vector, count); - return 0; -} - -static int32_t -rot13_readv (call_frame_t *frame, - xlator_t *this, - dict_t *ctx, - size_t size, - off_t offset) -{ - STACK_WIND (frame, - rot13_readv_cbk, - FIRST_CHILD (this), - FIRST_CHILD (this)->fops->readv, - ctx, size, offset); - return 0; -} - -static int32_t -rot13_writev_cbk (call_frame_t *frame, - call_frame_t *prev_frame, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) -{ - STACK_UNWIND (frame, op_ret, op_errno); - return 0; -} - -static int32_t -rot13_writev (call_frame_t *frame, - xlator_t *this, - dict_t *ctx, - struct iovec *vector, - int32_t count, - off_t offset) -{ - rot13_iovec (vector, count); - - STACK_WIND (frame, - rot13_writev_cbk, - FIRST_CHILD (this), - FIRST_CHILD (this)->fops->writev, - ctx, vector, count, offset); - return 0; -} - -\end{verbatim} - -Every xlator must define two functions and two external symbols. The functions are -\texttt{init} and \texttt{fini}, and the symbols are \texttt{fops} and \texttt{mops}. -The \texttt{init} function is called when the xlator is loaded by GlusterFS, and -contains code for the xlator to initialize itself. Note that if an xlator is present -multiple times in the spec tree, the \texttt{init} function will be called each time -the xlator is loaded. - -\begin{verbatim} -int32_t -init (xlator_t *this) -{ - if (!this->children) { - gf_log ("rot13", GF_LOG_ERROR, - "FATAL: rot13 should have exactly one child"); - return -1; - } - - gf_log ("rot13", GF_LOG_DEBUG, "rot13 xlator loaded"); - return 0; -} -\end{verbatim} - -\begin{verbatim} - -void -fini (xlator_t *this) -{ - return; -} - -struct xlator_fops fops = { - .readv = rot13_readv, - .writev = rot13_writev -}; - - -\end{verbatim} - -\end{document} - diff --git a/doc/legacy/hacker-guide/replicate.txt b/doc/legacy/hacker-guide/replicate.txt deleted file mode 100644 index ad5b352a829..00000000000 --- a/doc/legacy/hacker-guide/replicate.txt +++ /dev/null @@ -1,206 +0,0 @@ ---------------- -* cluster/replicate ---------------- - -Before understanding replicate, one must understand two internal FOPs: - -GF_FILE_LK: - This is exactly like fcntl(2) locking, except the locks are in a - separate domain from locks held by applications. - -GF_DIR_LK (loc_t *loc, char *basename): - This allows one to lock a name under a directory. For example, - to lock /mnt/glusterfs/foo, one would use the call: - - GF_DIR_LK ({loc_t for "/mnt/glusterfs"}, "foo") - - If one wishes to lock *all* the names under a particular directory, - supply the basename argument as NULL. - - The locks can either be read locks or write locks; consult the - function prototype for more details. - -Both these operations are implemented by the features/locks (earlier -known as posix-locks) translator. - --------------- -* Basic design --------------- - -All FOPs can be classified into four major groups: - - - inode-read - Operations that read an inode's data (file contents) or metadata (perms, etc.). - - access, getxattr, fstat, readlink, readv, stat. - - - inode-write - Operations that modify an inode's data or metadata. - - chmod, chown, truncate, writev, utimens. - - - dir-read - Operations that read a directory's contents or metadata. - - readdir, getdents, checksum. - - - dir-write - Operations that modify a directory's contents or metadata. - - create, link, mkdir, mknod, rename, rmdir, symlink, unlink. - - Some of these make a subgroup in that they modify *two* different entries: - link, rename, symlink. - - - Others - Other operations. - - flush, lookup, open, opendir, statfs. - ------------- -* Algorithms ------------- - -Each of the four major groups has its own algorithm: - - ---------------------- - - inode-read, dir-read - ---------------------- - - = Send a request to the first child that is up: - - if it fails: - try the next available child - - if we have exhausted all children: - return failure - - ------------- - - inode-write - ------------- - - All operations are done in parallel unless specified otherwise. - - (1) Send a GF_FILE_LK request on all children for a write lock on - the appropriate region - (for metadata operations: entire file (0, 0) - for writev: (offset, offset+size of buffer)) - - - If a lock request fails on a child: - unlock all children - try to acquire a blocking lock (F_SETLKW) on each child, serially. - - If this fails (due to ENOTCONN or EINVAL): - Consider this child as dead for rest of transaction. - - (2) Mark all children as "pending" on all (alive) children - (see below for meaning of "pending"). - - - If it fails on any child: - mark it as dead (in transaction local state). - - (3) Perform operation on all (alive) children. - - - If it fails on any child: - mark it as dead (in transaction local state). - - (4) Unmark all successful children as not "pending" on all nodes. - - (5) Unlock region on all (alive) children. - - ----------- - - dir-write - ----------- - - The algorithm for dir-write is same as above except instead of holding - GF_FILE_LK locks we hold a GF_DIR_LK lock on the name being operated upon. - In case of link-type calls, we hold locks on both the operand names. - ------------ -* "pending" ------------ - - The "pending" number is like a journal entry. A pending entry is an - array of 32-bit integers stored in network byte-order as the extended - attribute of an inode (which can be a directory as well). - - There are three keys corresponding to three types of pending operations: - - - AFR_METADATA_PENDING - There are some metadata operations pending on this inode (perms, ctime/mtime, - xattr, etc.). - - - AFR_DATA_PENDING - There is some data pending on this inode (writev). - - - AFR_ENTRY_PENDING - There are some directory operations pending on this directory - (create, unlink, etc.). - ------------ -* Self heal ------------ - - - On lookup, gather extended attribute data: - - If entry is a regular file: - - If an entry is present on one child and not on others: - - create entry on others. - - If entries exist but have different metadata (perms, etc.): - - consider the entry with the highest AFR_METADATA_PENDING number as - definitive and replicate its attributes on children. - - - If entry is a directory: - - Consider the entry with the highest AFR_ENTRY_PENDING number as - definitive and replicate its contents on all children. - - - If any two entries have non-matching types (i.e., one is file and - other is directory): - - Announce to the user via log that a split-brain situation has been - detected, and do nothing. - - - On open, gather extended attribute data: - - Consider the file with the highest AFR_DATA_PENDING number as - the definitive one and replicate its contents on all other - children. - - During all self heal operations, appropriate locks must be held on all - regions/entries being affected. - ---------------- -* Inode scaling ---------------- - -Inode scaling is necessary because if a situation arises where: - - An inode number is returned for a directory (by lookup) which was - previously the inode number of a file (as per FUSE's table), then - FUSE gets horribly confused (consult a FUSE expert for more details). - -To avoid such a situation, we distribute the 64-bit inode space equally -among all children of replicate. - -To illustrate: - -If c1, c2, c3 are children of replicate, they each get 1/3 of the available -inode space: - -Child: c1 c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 ... -Inode number: 1 2 3 4 5 6 7 8 9 10 11 ... - -Thus, if lookup on c1 returns an inode number "2", it is scaled to "4" -(which is the second inode number in c1's space). - -This way we ensure that there is never a collision of inode numbers from -two different children. - -This reduction of inode space doesn't really reduce the usability of -replicate since even if we assume replicate has 1024 children (which would be a -highly unusual scenario), each child still has a 54-bit inode space. - -2^54 ~ 1.8 * 10^16 - -which is much larger than any real world requirement. - - -============================================== -$ Last updated: Sun Oct 12 23:17:01 IST 2008 $ -$ Author: Vikas Gorur <vikas@gluster.com> $ -============================================== - diff --git a/doc/legacy/handling-options.txt b/doc/legacy/handling-options.txt deleted file mode 100644 index 9a3b2510acb..00000000000 --- a/doc/legacy/handling-options.txt +++ /dev/null @@ -1,13 +0,0 @@ - -How to add a new option to a given volume ? -=========================================== - -* Add a entry in 'struct volume_options options[]' with your key, what is - the type of the 'key', etc. - -* The 'key' and corresponding 'value' given for the same by user are validated - before calling init() of the translator/transport/scheduler/auth-module. - -* Once the complete init() is successful, user will get a warning if he has - given a 'key' which is not defined in these modules. - diff --git a/doc/legacy/mac-related-xattrs.txt b/doc/legacy/mac-related-xattrs.txt deleted file mode 100644 index 92bb2ceef2d..00000000000 --- a/doc/legacy/mac-related-xattrs.txt +++ /dev/null @@ -1,21 +0,0 @@ - -This document is intended to briefly explain how the Extended Attributes on -Darwin 10.5.x releases works ----- - -On Darwin other than all the normal filesystem operations, 'Finder' (like -Explorer in Windows but a little more) keeps its information in two extended -attributes named 'com.apple.FinderInfo' and 'com.apple.ResourceFork'. If these -xattrs are not implemented the filesystem won't be shown on Finder, and if they -are not implemented properly there may be issues when some of the file operations -are done through GUI of Finder. But when a filesystem is used over mountpoint in a -terminal, everything is fine and these xattrs are not required. - -Currently the way these xattrs are implemented is simple. All the xattr calls -(getxattr, setxattr, listxattr, removexattr) are passed down to underlaying filesystem, -most of the cases when exported FS is on MacOS X itself, these keys are supported, hence -the fops succeed. But in the case of using exports of different OS on Darwin the issue is -extended attribute prefix like 'com.apple.' may not be supported, hence the problem with -Finder. To solve this issue, GlusterFS returns virtual default values to these keys, which -works fine on most of the cases. - diff --git a/doc/legacy/porting_guide.txt b/doc/legacy/porting_guide.txt deleted file mode 100644 index 5705cd96461..00000000000 --- a/doc/legacy/porting_guide.txt +++ /dev/null @@ -1,45 +0,0 @@ - GlusterFS Porting Guide - ----------------------- - -* General setup - -The configure script will detect the target platform for the build. -All platform-specific CFLAGS, macro definitions should be done -in configure.ac - -Platform-specific code can be written like this: - -#ifdef GF_DARWIN_HOST_OS - /* some code specific to Darwin */ -#endif - -* Coding guidelines - -In general, avoid glibc extensions. For example, nested functions don't work -on Mac OS X. It is best to stick to C99. - -When using library calls and system calls, pay attention to the -portability notes. As far as possible stick to POSIX-specified behavior. -Do not use anything expressly permitted by the specification. For example, -some fields in structures may be present only on certain platforms. Avoid -use of such things. - -Do not pass values of constants such as F_*, O_*, errno values, etc. across -platforms. - -Please refer compat-errno.h for more details about errno handling inside -glusterfs for cross platform. - -* Specific issues - -- The argp library is available only on Linux through glibc, but for other - platforms glusterfs has already included argp-standalone library which will - statically linked during the glusterfs build. - -- Extended attribute calls (setxattr, listxattr, etc.) have differing prototypes - on different platforms. See compat.h for macro definitions to resolve this, also - read out the specific extended attribute documentation for your platforms. - ------------------------------------------- -Last revised: Thu Feb 28 13:58:07 IST 2008 ------------------------------------------- diff --git a/doc/legacy/replicate.lyx b/doc/legacy/replicate.lyx deleted file mode 100644 index e3d081191e0..00000000000 --- a/doc/legacy/replicate.lyx +++ /dev/null @@ -1,797 +0,0 @@ -#LyX 1.4.2 created this file. For more info see http://www.lyx.org/ -\lyxformat 245 -\begin_document -\begin_header -\textclass article -\language english -\inputencoding auto -\fontscheme default -\graphics default -\paperfontsize default -\spacing single -\papersize default -\use_geometry false -\use_amsmath 1 -\cite_engine basic -\use_bibtopic false -\paperorientation portrait -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation skip -\defskip medskip -\quotes_language english -\papercolumns 1 -\papersides 1 -\paperpagestyle default -\tracking_changes false -\output_changes false -\end_header - -\begin_body - -\begin_layout Title - -\size larger -Automatic File Replication (replicate) in GlusterFS -\end_layout - -\begin_layout Author -Vikas Gorur -\family typewriter -\size larger -<vikas@gluster.com> -\end_layout - -\begin_layout Standard -\begin_inset ERT -status open - -\begin_layout Standard - - -\backslash -hrule -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Section* -Overview -\end_layout - -\begin_layout Standard -This document describes the design and usage of the replicate translator in GlusterFS. - This document is valid for the 1.4.x releases, and not earlier ones. -\end_layout - -\begin_layout Standard -The replicate translator of GlusterFS aims to keep identical copies of a file - on all its subvolumes, as far as possible. - It tries to do this by performing all filesystem mutation operations (writing - data, creating files, changing ownership, etc.) on all its subvolumes in - such a way that if an operation succeeds on atleast one subvolume, all - other subvolumes can later be brought up to date. -\end_layout - -\begin_layout Standard -In the rest of the document the terms -\begin_inset Quotes eld -\end_inset - -subvolume -\begin_inset Quotes erd -\end_inset - - and -\begin_inset Quotes eld -\end_inset - -server -\begin_inset Quotes erd -\end_inset - - are used interchangeably, trusting that it will cause no confusion to the - reader. -\end_layout - -\begin_layout Section* -Usage -\end_layout - -\begin_layout Standard -A sample volume declaration for replicate looks like this: -\end_layout - -\begin_layout Standard -\begin_inset ERT -status open - -\begin_layout Standard - - -\backslash -begin{verbatim} -\end_layout - -\begin_layout Standard - -volume replicate -\end_layout - -\begin_layout Standard - - type cluster/replicate -\end_layout - -\begin_layout Standard - - # options, see below for description -\end_layout - -\begin_layout Standard - - subvolumes brick1 brick2 -\end_layout - -\begin_layout Standard - -end-volume -\end_layout - -\begin_layout Standard - - -\backslash -end{verbatim} -\end_layout - -\begin_layout Standard - -\end_layout - -\begin_layout Standard - -\end_layout - -\begin_layout Standard - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -This defines an replicate volume with two subvolumes, brick1, and brick2. - For replicate to work properly, it is essential that its subvolumes support -\series bold -extended attributes -\series default -. - This means that you should choose a backend filesystem that supports extended - attributes, like XFS, ReiserFS, or Ext3. -\end_layout - -\begin_layout Standard -The storage volumes used as backend for replicate -\emph on -must -\emph default - have a posix-locks volume loaded above them. -\end_layout - -\begin_layout Standard -\begin_inset ERT -status open - -\begin_layout Standard - - -\backslash -begin{verbatim} -\end_layout - -\begin_layout Standard - -volume brick1 -\end_layout - -\begin_layout Standard - - type features/posix-locks -\end_layout - -\begin_layout Standard - - subvolumes brick1-ds -\end_layout - -\begin_layout Standard - -end-volume -\end_layout - -\begin_layout Standard - - -\backslash -end{verbatim} -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Section* -Design -\end_layout - -\begin_layout Subsection* -Read algorithm -\end_layout - -\begin_layout Standard -All operations that do not modify the file or directory are sent to all - the subvolumes and the first successful reply is returned to the application. -\end_layout - -\begin_layout Standard -The read() system call (reading data from a file) is an exception. - For read() calls, replicate tries to do load balancing by sending all reads from - a particular file to a particular server. -\end_layout - -\begin_layout Standard -The read algorithm is also affected by the option read-subvolume; see below - for details. -\end_layout - -\begin_layout Subsection* -Classes of file operations -\end_layout - -\begin_layout Standard -replicate divides all filesystem write operations into three classes: -\end_layout - -\begin_layout Itemize - -\series bold -data: -\series default -Operations that modify the contents of a file (write, truncate). -\end_layout - -\begin_layout Itemize - -\series bold -metadata: -\series default -Operations that modify attributes of a file or directory (permissions, ownership -, etc.). -\end_layout - -\begin_layout Itemize - -\series bold -entry: -\series default -Operations that create or delete directory entries (mkdir, create, rename, - rmdir, unlink, etc.). -\end_layout - -\begin_layout Subsection* -Locking and Change Log -\end_layout - -\begin_layout Standard -To ensure consistency across subvolumes, replicate holds a lock whenever a modificatio -n is being made to a file or directory. - By default, replicate considers the first subvolume as the sole lock server. - However, the number of lock servers can be increased up to the total number - of subvolumes. -\end_layout - -\begin_layout Standard -The change log is a set of extended attributes associated with files and - directories that replicate maintains. - The change log keeps track of the changes made to files and directories - (data, metadata, entry) so that the self-heal algorithm knows which copy - of a file or directory is the most recent one. -\end_layout - -\begin_layout Subsection* -Write algorithm -\end_layout - -\begin_layout Standard -The algorithm for all write operations (data, metadata, entry) is: -\end_layout - -\begin_layout Enumerate -Lock the file (or directory) on all of the lock servers (see options below). -\end_layout - -\begin_layout Enumerate -Write change log entries on all servers. -\end_layout - -\begin_layout Enumerate -Perform the operation. -\end_layout - -\begin_layout Enumerate -Erase change log entries. -\end_layout - -\begin_layout Enumerate -Unlock the file (or directory) on all of the lock servers. -\end_layout - -\begin_layout Standard -The above algorithm is a simplified version intended for general users. - Please refer to the source code for the full details. -\end_layout - -\begin_layout Subsection* -Self-Heal -\end_layout - -\begin_layout Standard -replicate automatically tries to fix any inconsistencies it detects among different - copies of a file. - It uses information in the change log to determine which copy is the -\begin_inset Quotes eld -\end_inset - -correct -\begin_inset Quotes erd -\end_inset - - version. -\end_layout - -\begin_layout Standard -Self-heal is triggered when a file or directory is first -\begin_inset Quotes eld -\end_inset - -accessed -\begin_inset Quotes erd -\end_inset - -, that is, the first time any operation is attempted on it. - The self-heal algorithm does the following things: -\end_layout - -\begin_layout Standard -If the entry being accessed is a directory: -\end_layout - -\begin_layout Itemize -The contents of the -\begin_inset Quotes eld -\end_inset - -correct -\begin_inset Quotes erd -\end_inset - - version is replicated on all subvolumes, by deleting entries and creating - entries as necessary. -\end_layout - -\begin_layout Standard -If the entry being accessed is a file: -\end_layout - -\begin_layout Itemize -If the file does not exist on some subvolumes, it is created. -\end_layout - -\begin_layout Itemize -If there is a mismatch in the size of the file, or ownership, or permission, - it is fixed. -\end_layout - -\begin_layout Itemize -If the change log indicates that some copies need updating, they are updated. -\end_layout - -\begin_layout Subsection* -Split-brain -\end_layout - -\begin_layout Standard -It may happen that one replicate client can access only some of the servers in - a cluster and another replicate client can access the remaining servers. - Or it may happen that in a cluster of two servers, one server goes down - and comes back up, but the other goes down immediately. - Both these scenarios result in a -\begin_inset Quotes eld -\end_inset - -split-brain -\begin_inset Quotes erd -\end_inset - -. -\end_layout - -\begin_layout Standard -In a split-brain situation, there will be two or more copies of a file, - all of which are -\begin_inset Quotes eld -\end_inset - -correct -\begin_inset Quotes erd -\end_inset - - in some sense. - replicate without manual intervention has no way of knowing what to do, since - it cannot consider any single copy as definitive, nor does it know of any - meaningful way to merge the copies. -\end_layout - -\begin_layout Standard -If replicate detects that a split-brain has happened on a file, it disallows opening - of that file. - You will have to manually resolve the conflict by deleting all but one - copy of the file. - Alternatively you can set an automatic split-brain resolution policy by - using the `favorite-child' option (see below). -\end_layout - -\begin_layout Section* -Translator Options -\end_layout - -\begin_layout Standard -replicate accepts the following options: -\end_layout - -\begin_layout Subsection* -read-subvolume (default: none) -\end_layout - -\begin_layout Standard -The value of this option must be the name of a subvolume. - If given, all read operations are sent to only the specified subvolume, - instead of being balanced across all subvolumes. -\end_layout - -\begin_layout Subsection* -favorite-child (default: none) -\end_layout - -\begin_layout Standard -The value of this option must be the name of a subvolume. - If given, the specified subvolume will be preferentially used in resolving - conflicts ( -\begin_inset Quotes eld -\end_inset - -split-brain -\begin_inset Quotes erd -\end_inset - -). - This means if a discrepancy is noticed in the attributes or content of - a file, the copy on the `favorite-child' will be considered the definitive - version and its contents will -\emph on -overwrite -\emph default -the contents of all other copies. - Use this option with caution! It is possible to -\emph on -lose data -\emph default - with this option. - If you are in doubt, do not specify this option. -\end_layout - -\begin_layout Subsection* -Self-heal options -\end_layout - -\begin_layout Standard -Setting any of these options to -\begin_inset Quotes eld -\end_inset - -off -\begin_inset Quotes erd -\end_inset - - prevents that kind of self-heal from being done on a file or directory. - For example, if metadata self-heal is turned off, permissions and ownership - are no longer fixed automatically. -\end_layout - -\begin_layout Subsubsection* -data-self-heal (default: on) -\end_layout - -\begin_layout Standard -Enable/disable self-healing of file contents. -\end_layout - -\begin_layout Subsubsection* -metadata-self-heal (default: off) -\end_layout - -\begin_layout Standard -Enable/disable self-healing of metadata (permissions, ownership, modification - times). -\end_layout - -\begin_layout Subsubsection* -entry-self-heal (default: on) -\end_layout - -\begin_layout Standard -Enable/disable self-healing of directory entries. -\end_layout - -\begin_layout Subsection* -Change Log options -\end_layout - -\begin_layout Standard -If any of these options is turned off, it disables writing of change log - entries for that class of file operations. - That is, steps 2 and 4 of the write algorithm (see above) are not done. - Note that if the change log is not written, the self-heal algorithm cannot - determine the -\begin_inset Quotes eld -\end_inset - -correct -\begin_inset Quotes erd -\end_inset - - version of a file and hence self-heal will only be able to fix -\begin_inset Quotes eld -\end_inset - -obviously -\begin_inset Quotes erd -\end_inset - - wrong things (such as a file existing on only one node). -\end_layout - -\begin_layout Subsubsection* -data-change-log (default: on) -\end_layout - -\begin_layout Standard -Enable/disable writing of change log for data operations. -\end_layout - -\begin_layout Subsubsection* -metadata-change-log (default: on) -\end_layout - -\begin_layout Standard -Enable/disable writing of change log for metadata operations. -\end_layout - -\begin_layout Subsubsection* -entry-change-log (default: on) -\end_layout - -\begin_layout Standard -Enable/disable writing of change log for entry operations. -\end_layout - -\begin_layout Subsection* -Locking options -\end_layout - -\begin_layout Standard -These options let you specify the number of lock servers to use for each - class of file operations. - The default values are satisfactory in most cases. - If you are extra paranoid, you may want to increase the values. - However, be very cautious if you set the data- or entry- lock server counts - to zero, since this can result in -\emph on -lost data. - -\emph default - For example, if you set the data-lock-server-count to zero, and two application -s write to the same region of a file, there is a possibility that none of - your servers will have all the data. - In other words, the copies will be -\emph on -inconsistent -\emph default -, and -\emph on -incomplete -\emph default -. - Do not set data- and entry- lock server counts to zero unless you absolutely - know what you are doing and agree to not hold GlusterFS responsible for - any lost data. -\end_layout - -\begin_layout Subsubsection* -data-lock-server-count (default: 1) -\end_layout - -\begin_layout Standard -Number of lock servers to use for data operations. -\end_layout - -\begin_layout Subsubsection* -metadata-lock-server-count (default: 0) -\end_layout - -\begin_layout Standard -Number of lock servers to use for metadata operations. -\end_layout - -\begin_layout Subsubsection* -entry-lock-server-count (default: 1) -\end_layout - -\begin_layout Standard -Number of lock servers to use for entry operations. -\end_layout - -\begin_layout Section* -Known Issues -\end_layout - -\begin_layout Subsection* -Self-heal of file with more than one link (hard links): -\end_layout - -\begin_layout Standard -Consider two servers, A and B. - Assume A is down, and the user creates a file `new' as a hard link to a - file `old'. - When A comes back up, replicate will see that the file `new' does not exist on - A, and self-heal will create the file and copy the contents from B. - However, now on server A the file `new' is not a link to the file `old' - but an entirely different file. -\end_layout - -\begin_layout Standard -We know of no easy way to fix this problem, but we will try to fix it in - forthcoming releases. -\end_layout - -\begin_layout Subsection* -File re-opening after a server comes back up: -\end_layout - -\begin_layout Standard -If a server A goes down and comes back up, any files which were opened while - A was down and are still open will not have their writes replicated on - A. - In other words, data replication only happens on those servers which were - alive when the file was opened. -\end_layout - -\begin_layout Standard -This is a rather tricky issue but we hope to fix it very soon. -\end_layout - -\begin_layout Section* -Frequently Asked Questions -\end_layout - -\begin_layout Subsection* -1. - How can I force self-heal to happen? -\end_layout - -\begin_layout Standard -You can force self-heal to happen on your cluster by running a script or - a command that accesses every file. - A simple way to do it would be: -\end_layout - -\begin_layout Standard -\begin_inset ERT -status open - -\begin_layout Standard - -\end_layout - -\begin_layout Standard - - -\backslash -begin{verbatim} -\end_layout - -\begin_layout Standard - -$ ls -lR -\end_layout - -\begin_layout Standard - - -\backslash -end{verbatim} -\end_layout - -\begin_layout Standard - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -Run the command in all directories which you want to forcibly self-heal. -\end_layout - -\begin_layout Subsection* -2. - Which backend filesystem should I use for replicate? -\end_layout - -\begin_layout Standard -You can use any backend filesystem that supports extended attributes. - We know of users successfully using XFR, ReiserFS, and Ext3. -\end_layout - -\begin_layout Subsection* -3. - What can I do to improve replicate performance? -\end_layout - -\begin_layout Standard -Try loading performance translators such as io-threads, write-behind, io-cache, - and read-ahead depending on your workload. - If you are willing to sacrifice correctness in corner cases, you can experiment - with the lock-server-count and the change-log options (see above). - As warned earlier, be very careful! -\end_layout - -\begin_layout Subsection* -4. - How can I selectively replicate files? -\end_layout - -\begin_layout Standard -There is no support for selective replication in replicate itself. - You can achieve selective replication by loading the unify translator over - replicate, and using the switch scheduler. - Configure unify with two subvolumes, one of them being replicate. - Using the switch scheduler, schedule all files for which you need replication - to the replicate subvolume. - Consult unify and switch documentation for more details. -\end_layout - -\begin_layout Section* -Contact -\end_layout - -\begin_layout Standard -If you need more assistance on replicate, contact us on the mailing list <gluster-user -s@gluster.org> (visit gluster.org for details on how to subscribe). -\end_layout - -\begin_layout Standard -Send you comments and suggestions about this document to <vikas@gluster.com>. -\end_layout - -\end_body -\end_document diff --git a/doc/legacy/replicate.pdf b/doc/legacy/replicate.pdf Binary files differdeleted file mode 100644 index b7212af2b4e..00000000000 --- a/doc/legacy/replicate.pdf +++ /dev/null diff --git a/doc/legacy/solaris-related-xattrs.txt b/doc/legacy/solaris-related-xattrs.txt deleted file mode 100644 index fa41e29000b..00000000000 --- a/doc/legacy/solaris-related-xattrs.txt +++ /dev/null @@ -1,44 +0,0 @@ - Solaris Extended Attributes - -In solaris extended attributes are logically supported as files -within the filesystem. The file system is therefore augmented -with an orthogonal namespace of file attributes. Attribute values -are accessed by file descriptors obtained through a special attribute -interface. This type of logical view of "attributes as files" allows -the leveraging of existing file system interface functionality to -support the construction, deletion and manipulation of attributes. - -But as we have tested through this functionality provided by Solaris -we have come across two major issues as written below. - -1. Symlink XATTR_NOFOLLOW not present for creating extended attributes - directly on the symlinks like other platforms Linux,MAC-OSX,BSD etc. - An implementation is present for O_NOFOLLOW for "openat()" call sets - up errno ELOOP whenever encountered with a symlink and also another - implementation AT_SYMLINK_NOFOLLOW which is not present for calls like - "attropen(), openat()" - - a snippet of test code which helped us understand this behaviour - -------------------------------------- - attrfd = attropen (path, key, - flags|AT_SYMLINK_NOFOLLOW|O_CREAT|O_WRONLY|O_NOFOLLOW, 0777); - if (attrfd >= 0) { - ftruncate (attrfd, 0); - ret = write (attrfd, value, size); - close (attrfd); - } else { - fprintf (stderr, "Couldn't set extended attribute for %s (%d)\n", - path, errno); - } - -------------------------------------- - -2. Extended attribute support for special files like device files, fifo files - is not supported under solaris. - -Apart from these glitches almost everything regarding porting functionality -for extended attribute calls has been properly implemented in compat.c -with writing wrapper around functions over -"attropen()", "openat()", "unlinkat()" - - - diff --git a/doc/legacy/stat-prefetch-design.txt b/doc/legacy/stat-prefetch-design.txt deleted file mode 100644 index 68ed423d3dd..00000000000 --- a/doc/legacy/stat-prefetch-design.txt +++ /dev/null @@ -1,154 +0,0 @@ -what is stat-prefetch? -====================== -It is a translator which caches the dentries read in readdir. This dentry -list is stored in the context of fd. Later when lookup happens on -[parent-inode, basename (path)] combination, this list is searched for the -basename. The dentry thus searched is used to fill up the stat corresponding -to path being looked upon, thereby short-cutting lookup calls. This cache is -preserved till closedir is called on the fd. The purpose of this translator -is to optimize operations like 'ls -l', where a readdir is followed by -lookup (stat) calls on each directory entry. - -1. stat-prefetch harnesses the efficiency of short lookup calls - (saves network roundtrip time for lookup calls from being accounted to - the stat call). -2. To maintain the correctness, it does lookup-behind - lookup is winded to - underlying translators after it is unwound to upper translators. - lookup-behind is necessary as inode gets populated in server inode table - only in lookup-cbk and also because various translators store their - contexts in inode contexts during lookup calls. - -fops to be implemented: -======================= -* lookup - 1. check the dentry cache stored in context of fds opened by the same process - on parent inode for basename. If found unwind with cached stat, else wind - the lookup call to underlying translators. - 2. stat is stored in the context of inode if the path being looked upon - happens to be directory. This stat will be used to fill postparent stat - when lookup happens on any of the directory contents. - -* readdir - 1. cache the direntries returned in readdir_cbk in the context of fd. - 2. if the readdir is happening on non-expected offsets (means a seekdir/rewinddir - has happened), cache has to be flushed. - 3. delete the entry corresponding to basename of path on which fd is opened - from cache stored in parent. - -* chmod/fchmod - delete the entry corresponding to basename from cache stored in context of - fds opened on parent inode, since these calls change st_mode and st_ctime of - stat. - -* chown/fchown - delete the entry corresponding to basename from cache stored in context of - fds opened on parent inode, since these calls change st_uid/st_gid and - st_ctime of stat. - -* truncate/ftruncate - delete the entry corresponding to basename from cache stored in context of - fds opened on parent inode, since these calls change st_size/st_mtime of stat. - -* utimens - delete the entry corresponding to basename from cache stored in context of - fds opened on parent inode, since this call changes st_atime/st_mtime of stat. - -* readlink - delete the entry corresponding to basename from cache stored in context of fds - opened on parent inode, since this call changes st_atime of stat. - -* unlink - 1. delete the entry corresponding to basename from cache stored in context of - fds, opened on parent directory containing the file being unlinked. - 2. delete the entry corresponding to basename of parent directory from cache - of grand-parent. - -* rmdir - 1. delete the entry corresponding to basename from cache stored in context of - fds opened on parent inode. - 2. remove the entire cache from all fds opened on inode corresponding to - directory being removed. - 3. delete the entry correspondig to basename of parent from cache stored in - grand-parent. - -* readv - delete the entry corresponding to basename from cache stored in context of fds - opened on parent inode, since readv changes st_atime of file. - -* writev - delete the entry corresponding to basename from cache stored in context of fds - opened on parent inode, since writev can possibly change st_size and definitely - changes st_mtime of file. - -* fsync - there is a confusion here as to whether fsync updates mtime/ctimes. Disk based - filesystems (atleast ext2) just writes the times stored in inode to disk - during fsync and not the time at which fsync is being done. But in glusterfs, - a translator like write-behind actually sends writes during fsync which will - change mtime/ctime. Hence stat-prefetch implements fsync to delete the entry - corresponding to basename from cache stored in context of fds opened on parent - inode. - -* rename - 1. remove entry corresponding to oldname from cache stored in fd contexts of - oldparent. - 2. remove entry corresponding to newname from cache stored in fd contexts of - newparent. - 3. remove entry corresponding to oldparent from cache stored in - old-grand-parent, since removing oldname changes st_mtime and st_ctime - of oldparent stat. - 4. remove entry corresponding to newparent from cache stored in - new-grand-parent, since adding newname changes st_mtime and st_ctime - of newparent stat. - 5. if oldname happens to be a directory, remove entire cache from all fds - opened on it. - -* create/mknod/mkdir/symlink/link - delete entry corresponding to basename of parent directory in which these - operations are happening, from cache stored in context of fds opened on - grand-parent, since adding a new entry to a directory changes st_mtime - and st_ctime of parent directory. - -* setxattr/removexattr - delete the entry corresponding to basename from cache stored in context of - fds opened on parent inode, since setxattr changes st_ctime of file. - -* setdents - 1. remove entry corresponding to basename of path on which fd is opened from - cache stored in context of fds opened on parent. - 2. for each of the entry in the direntry list, delete from cache stored in - context of fd, the entry corresponding to basename of path being passed. - -* getdents - 1. remove entry corresponding to basename of path on which fd is opened from - cache stored in parent, since getdents changes st_atime. - 2. remove entries corresponding to symbolic links from cache, since readlink - would've changed st_atime. - -* checksum - delete the entry corresponding to basename from cache stored in context of - fds opened on parent inode, since st_atime is changed during this call. - -* xattrop/fxattrop - delete the entry corresponding to basename from cache stored in context of fds - opened on parent inode, since these calls modify st_ctime of file. - -callbacks to be implemented: -============================ -* releasedir - free the context stored in fd. - -* forget - dree the stat if the inode corresponds to a directory. - -limitations: -============ -* since a readdir does not return extended attributes of file, if need_xattr is - set, short-cutting of lookup does not happen and lookup is passed to - underlying translators. - -* posix_readdir does not check whether the dentries are spanning across multiple - mount points. Hence it is not transforming inode numbers in stat buffers if - posix is configured to allow export directory spanning on multiple mountpoints. - This is a bug which needs to be fixed. posix_readdir should treat dentries the - same way as if lookup is happening on dentries. diff --git a/doc/legacy/stripe.odg b/doc/legacy/stripe.odg Binary files differdeleted file mode 100644 index 79441bf1452..00000000000 --- a/doc/legacy/stripe.odg +++ /dev/null diff --git a/doc/legacy/stripe.pdf b/doc/legacy/stripe.pdf Binary files differdeleted file mode 100644 index b94446feb56..00000000000 --- a/doc/legacy/stripe.pdf +++ /dev/null diff --git a/doc/legacy/translator-options.txt b/doc/legacy/translator-options.txt deleted file mode 100644 index 3422c058a5d..00000000000 --- a/doc/legacy/translator-options.txt +++ /dev/null @@ -1,224 +0,0 @@ -mount/fuse: - * direct-io-mode GF_OPTION_TYPE_BOOL on|off|yes|no - * mount-point (mountpoint) GF_OPTION_TYPE_PATH <any-posix-valid-path> - * attribute-timeout GF_OPTION_TYPE_DOUBLE 0.0 - * entry-timeout GF_OPTION_TYPE_DOUBLE 0.0 - -protocol/server: - * transport-type GF_OPTION_TYPE_STR tcp|socket|ib-verbs|unix|ib-sdp| - tcp/client|ib-verbs/client - * volume-filename.* GF_OPTION_TYPE_PATH - * inode-lru-limit GF_OPTION_TYPE_INT 0-(1 * GF_UNIT_MB) - * client-volume-filename GF_OPTION_TYPE_PATH - -protocol/client: - * username GF_OPTION_TYPE_ANY - * password GF_OPTION_TYPE_ANY - * transport-type GF_OPTION_TYPE_STR tcp|socket|ib-verbs|unix|ib-sdp| - tcp/client|ib-verbs/client - * remote-host GF_OPTION_TYPE_ANY - * remote-subvolume GF_OPTION_TYPE_ANY - * transport-timeout GF_OPTION_TYPE_TIME 5-1013 - -cluster/replicate: - * read-subvolume GF_OPTION_TYPE_XLATOR - * favorite-child GF_OPTION_TYPE_XLATOR - * data-self-heal GF_OPTION_TYPE_BOOL - * metadata-self-heal GF_OPTION_TYPE_BOOL - * entry-self-heal GF_OPTION_TYPE_BOOL - * data-change-log GF_OPTION_TYPE_BOOL - * metadata-change-log GF_OPTION_TYPE_BOOL - * entry-change-log GF_OPTION_TYPE_BOOL - * data-lock-server-count GF_OPTION_TYPE_INT 0 - * metadata-lock-server-count GF_OPTION_TYPE_INT 0 - * entry-lock-server-count GF_OPTION_TYPE_INT 0 - -cluster/distribute: - * lookup-unhashed GF_OPTION_TYPE_BOOL - -cluster/unify: - * namespace GF_OPTION_TYPE_XLATOR - * scheduler GF_OPTION_TYPE_STR alu|rr|random|nufa|switch - * self-heal GF_OPTION_TYPE_STR foreground|background|off - * optimist GF_OPTION_TYPE_BOOL - -cluster/nufa: - local-volume-name GF_OPTION_TYPE_XLATOR - -cluster/stripe: - * block-size GF_OPTION_TYPE_ANY - * use-xattr GF_OPTION_TYPE_BOOL - -debug/trace: - * include-ops (include) GF_OPTION_TYPE_STR - * exclude-ops (exclude) GF_OPTION_TYPE_STR - -encryption/rot-13: - * encrypt-write GF_OPTION_TYPE_BOOL - * decrypt-read GF_OPTION_TYPE_BOOL - -features/path-convertor: - * start-offset GF_OPTION_TYPE_INT 0-4095 - * end-offset GF_OPTION_TYPE_INT 1-4096 - * replace-with GF_OPTION_TYPE_ANY - -features/trash: - * trash-dir GF_OPTION_TYPE_PATH - -features/locks: - * mandatory-locks (mandatory) GF_OPTION_TYPE_BOOL - -features/filter: - * root-squashing GF_OPTION_TYPE_BOOL - * read-only GF_OPTION_TYPE_BOOL - * fixed-uid GF_OPTION_TYPE_INT - * fixed-gid GF_OPTION_TYPE_INT - * translate-uid GF_OPTION_TYPE_ANY - * translate-gid GF_OPTION_TYPE_ANY - * filter-uid GF_OPTION_TYPE_ANY - * filter-gid GF_OPTION_TYPE_ANY - -features/quota: - * min-free-disk-limit GF_OPTION_TYPE_PERCENT - * refresh-interval GF_OPTION_TYPE_TIME - * disk-usage-limit GF_OPTION_TYPE_SIZET - -storage/posix: - * o-direct GF_OPTION_TYPE_BOOL - * directory GF_OPTION_TYPE_PATH - * export-statfs-size GF_OPTION_TYPE_BOOL - * mandate-attribute GF_OPTION_TYPE_BOOL - -storage/bdb: - * directory GF_OPTION_TYPE_PATH - * logdir GF_OPTION_TYPE_PATH - * errfile GF_OPTION_TYPE_PATH - * dir-mode GF_OPTION_TYPE_ANY - * file-mode GF_OPTION_TYPE_ANY - * page-size GF_OPTION_TYPE_SIZET - * lru-limit GF_OPTION_TYPE_INT - * lock-timeout GF_OPTION_TYPE_TIME - * checkpoint-timeout GF_OPTION_TYPE_TIME - * transaction-timeout GF_OPTION_TYPE_TIME - * mode GF_OPTION_TYPE_BOOL - * access-mode GF_OPTION_TYPE_STR - -performance/read-ahead: - * force-atime-update GF_OPTION_TYPE_BOOL - * page-size GF_OPTION_TYPE_SIZET (64 * GF_UNIT_KB)-(2 * GF_UNIT_MB) - * page-count GF_OPTION_TYPE_INT 1-16 - -performance/write-behind: - * flush-behind GF_OPTION_TYPE_BOOL - * aggregate-size GF_OPTION_TYPE_SIZET (128 * GF_UNIT_KB)-(4 * GF_UNIT_MB) - * window-size GF_OPTION_TYPE_SIZET (512 * GF_UNIT_KB)-(1 * GF_UNIT_GB) - * enable-O_SYNC GF_OPTION_TYPE_BOOL - * disable-for-first-nbytes GF_OPTION_TYPE_SIZET 1 - (1 * GF_UNIT_MB) - -performance/symlink-cache: - -performance/io-threads: - * thread-count GF_OPTION_TYPE_INT 1-32 - -performance/io-cache: - * priority GF_OPTION_TYPE_ANY - * cache-timeout (force-revalidate-timeout) GF_OPTION_TYPE_INT 0-60 - * page-size GF_OPTION_TYPE_SIZET (16 * GF_UNIT_KB)-(4 * GF_UNIT_MB) - * cache-size GF_OPTION_TYPE_SIZET (4 * GF_UNIT_MB)-(6 * GF_UNIT_GB) - -performance/quick-read: - * cache-timeout GF_OPTION_TYPE_INT 1-60 - * max-file-size GF_OPTION_TYPE_SIZET 0-(1000 * GF_UNIT_KB) - -auth: -- addr: - * auth.addr.*.allow GF_OPTION_TYPE_ANY - * auth.addr.*.reject GF_OPTION_TYPE_ANY - -- login: - * auth.login.*.allow GF_OPTION_TYPE_ANY - * auth.login.*.password GF_OPTION_TYPE_ANY - -scheduler/alu: - * scheduler.alu.order (alu.order) - GF_OPTION_TYPE_ANY - * scheduler.alu.disk-usage.entry-threshold (alu.disk-usage.entry-threshold) - GF_OPTION_TYPE_SIZET - * scheduler.alu.disk-usage.exit-threshold (alu.disk-usage.exit-threshold) - GF_OPTION_TYPE_SIZET - * scheduler.alu.write-usage.entry-threshold (alu.write-usage.entry-threshold) - GF_OPTION_TYPE_SIZET - * scheduler.alu.write-usage.exit-threshold (alu.write-usage.exit-threshold) - GF_OPTION_TYPE_SIZET - * scheduler.alu.read-usage.entry-threshold (alu.read-usage.entry-threshold) - GF_OPTION_TYPE_SIZET - * scheduler.alu.read-usage.exit-threshold (alu.read-usage.exit-threshold) - GF_OPTION_TYPE_SIZET - * scheduler.alu.open-files-usage.entry-threshold (alu.open-files-usage.entry-threshold) - GF_OPTION_TYPE_INT - * scheduler.alu.open-files-usage.exit-threshold (alu.open-files-usage.exit-threshold) - GF_OPTION_TYPE_INT - * scheduler.read-only-subvolumes (alu.read-only-subvolumes) - GF_OPTION_TYPE_ANY - * scheduler.refresh-interval (alu.refresh-interval) - GF_OPTION_TYPE_TIME - * scheduler.limits.min-free-disk (alu.limits.min-free-disk) - GF_OPTION_TYPE_PERCENT - * scheduler.alu.stat-refresh.num-file-create (alu.stat-refresh.num-file-create) - GF_OPTION_TYPE_INT - -scheduler/nufa: - * scheduler.refresh-interval (nufa.refresh-interval) - GF_OPTION_TYPE_TIME - * scheduler.limits.min-free-disk (nufa.limits.min-free-disk) - GF_OPTION_TYPE_PERCENT - * scheduler.local-volume-name (nufa.local-volume-name) - GF_OPTION_TYPE_XLATOR - -scheduler/random: - * scheduler.refresh-interval (random.refresh-interval) GF_OPTION_TYPE_TIME - * scheduler.limits.min-free-disk (random.limits.min-free-disk) GF_OPTION_TYPE_PERCENT - -scheduler/rr: - * scheduler.refresh-interval (rr.refresh-interval) GF_OPTION_TYPE_TIME - * scheduler.limits.min-free-disk (rr.limits.min-free-disk) GF_OPTION_TYPE_PERCENT - * scheduler.read-only-subvolumes (rr.read-only-subvolumes) GF_OPTION_TYPE_ANY - -scheduler/switch: - * scheduler.read-only-subvolumes (switch.read-only-subvolumes) GF_OPTION_TYPE_ANY - * scheduler.local-volume-name (switch.nufa.local-volume-name) GF_OPTION_TYPE_XLATOR - * scheduler.switch.case (switch.case) GF_OPTION_TYPE_ANY - -transport/ib-verbs: - * transport.ib-verbs.port (ib-verbs-port) GF_OPTION_TYPE_INT 1-4 - check the option by 'ibv_devinfo' - * transport.ib-verbs.mtu (ib-verbs-mtu) GF_OPTION_TYPE_INT - * transport.ib-verbs.device-name (ib-verbs-device-name) GF_OPTION_TYPE_ANY, - check by 'ibv_devinfo' - * transport.ib-verbs.work-request-send-size (ib-verbs-work-request-send-size) - GF_OPTION_TYPE_INT, - * transport.ib-verbs.work-request-recv-size (ib-verbs-work-request-recv-size) - GF_OPTION_TYPE_INT - * transport.ib-verbs.work-request-send-count (ib-verbs-work-request-send-count) - GF_OPTION_TYPE_INT - * transport.ib-verbs.work-request-recv-count (ib-verbs-work-request-recv-count) - GF_OPTION_TYPE_INT - * remote-port (transport.remote-port,transport.ib-verbs.remote-port) - GF_OPTION_TYPE_INT - * transport.ib-verbs.listen-port GF_OPTION_TYPE_INT - * transport.ib-verbs.connect-path (connect-path) GF_OPTION_TYPE_ANY - * transport.ib-verbs.bind-path (bind-path) GF_OPTION_TYPE_ANY - * transport.ib-verbs.listen-path (listen-path) GF_OPTION_TYPE_ANY - * transport.address-family (address-family) GF_OPTION_TYPE_STR inet|inet6|inet/inet6| - inet6/inet|unix|inet-sdp - -transport/socket: - * transport.remote-port (remote-port,transport.socket.remote-port) GF_OPTION_TYPE_INT - * transport.socket.listen-port (listen-port) GF_OPTION_TYPE_INT - * transport.socket.bind-address (bind-address) GF_OPTION_TYPE_ANY - * transport.socket.connect-path (connect-path) GF_OPTION_TYPE_ANY - * transport.socket.bind-path (bind-path) GF_OPTION_TYPE_ANY - * transport.socket.listen-path (listen-path) GF_OPTION_TYPE_ANY - * transport.address-family (address-family) GF_OPTION_TYPE_STR inet|inet6| - inet/inet6|inet6/inet| - unix|inet-sdp diff --git a/doc/legacy/unify.odg b/doc/legacy/unify.odg Binary files differdeleted file mode 100644 index ccaa9bf16f9..00000000000 --- a/doc/legacy/unify.odg +++ /dev/null diff --git a/doc/legacy/unify.pdf b/doc/legacy/unify.pdf Binary files differdeleted file mode 100644 index c22027f66e7..00000000000 --- a/doc/legacy/unify.pdf +++ /dev/null diff --git a/doc/legacy/user-guide.info b/doc/legacy/user-guide.info deleted file mode 100644 index eae0ef10b58..00000000000 --- a/doc/legacy/user-guide.info +++ /dev/null @@ -1,2697 +0,0 @@ -This is ../../../doc/user-guide/user-guide.info, produced by makeinfo version 4.13 from ../../../doc/user-guide/user-guide.texi. - -START-INFO-DIR-ENTRY -* GlusterFS: (user-guide). GlusterFS distributed filesystem user guide -END-INFO-DIR-ENTRY - - This is the user manual for GlusterFS 2.0. - - Copyright (c) 2007-2011 Gluster, Inc. Permission is granted to -copy, distribute and/or modify this document under the terms of the GNU -Free Documentation License, Version 1.2 or any later version published -by the Free Software Foundation; with no Invariant Sections, no -Front-Cover Texts, and no Back-Cover Texts. A copy of the license is -included in the chapter entitled "GNU Free Documentation License". - - -File: user-guide.info, Node: Top, Next: Acknowledgements, Up: (dir) - -GlusterFS 2.0 User Guide -************************ - -This is the user manual for GlusterFS 2.0. - - Copyright (c) 2007-2011 Gluster, Inc. Permission is granted to -copy, distribute and/or modify this document under the terms of the GNU -Free Documentation License, Version 1.2 or any later version published -by the Free Software Foundation; with no Invariant Sections, no -Front-Cover Texts, and no Back-Cover Texts. A copy of the license is -included in the chapter entitled "GNU Free Documentation License". - -* Menu: - -* Acknowledgements:: -* Introduction:: -* Installation and Invocation:: -* Concepts:: -* Translators:: -* Usage Scenarios:: -* Troubleshooting:: -* GNU Free Documentation Licence:: -* Index:: - - --- The Detailed Node Listing --- - -Installation and Invocation - -* Pre requisites:: -* Getting GlusterFS:: -* Building:: -* Running GlusterFS:: -* A Tutorial Introduction:: - -Running GlusterFS - -* Server:: -* Client:: - -Concepts - -* Filesystems in Userspace:: -* Translator:: -* Volume specification file:: - -Translators - -* Storage Translators:: -* Client and Server Translators:: -* Clustering Translators:: -* Performance Translators:: -* Features Translators:: - -Storage Translators - -* POSIX:: - -Client and Server Translators - -* Transport modules:: -* Client protocol:: -* Server protocol:: - -Clustering Translators - -* Unify:: -* Replicate:: -* Stripe:: - -Performance Translators - -* Read Ahead:: -* Write Behind:: -* IO Threads:: -* IO Cache:: - -Features Translators - -* POSIX Locks:: -* Fixed ID:: - -Miscellaneous Translators - -* ROT-13:: -* Trace:: - - -File: user-guide.info, Node: Acknowledgements, Next: Introduction, Prev: Top, Up: Top - -Acknowledgements -**************** - -GlusterFS continues to be a wonderful and enriching experience for all -of us involved. - - GlusterFS development would not have been possible at this pace if -not for our enthusiastic users. People from around the world have -helped us with bug reports, performance numbers, and feature -suggestions. A huge thanks to them all. - - Matthew Paine - for RPMs & general enthu - - Leonardo Rodrigues de Mello - for DEBs - - Julian Perez & Adam D'Auria - for multi-server tutorial - - Paul England - for HA spec - - Brent Nelson - for many bug reports - - Jacques Mattheij - for Europe mirror. - - Patrick Negri - for TCP non-blocking connect. - http://gluster.org/core-team.php (<list-hacking@gluster.com>) - Gluster - - -File: user-guide.info, Node: Introduction, Next: Installation and Invocation, Prev: Acknowledgements, Up: Top - -1 Introduction -************** - -GlusterFS is a distributed filesystem. It works at the file level, not -block level. - - A network filesystem is one which allows us to access remote files. A -distributed filesystem is one that stores data on multiple machines and -makes them all appear to be a part of the same filesystem. - - Need for distributed filesystems - - * Scalability: A distributed filesystem allows us to store more data - than what can be stored on a single machine. - - * Redundancy: We might want to replicate crucial data on to several - machines. - - * Uniform access: One can mount a remote volume (for example your - home directory) from any machine and access the same data. - -1.1 Contacting us -================= - -You can reach us through the mailing list *gluster-devel* -(<gluster-devel@nongnu.org>). - - You can also find many of the developers on IRC, on the `#gluster' -channel on Freenode (<irc.freenode.net>). - - The GlusterFS documentation wiki is also useful: -<http://gluster.org/docs/index.php/GlusterFS> - - For commercial support, you can contact Gluster at: - - 3194 Winding Vista Common - Fremont, CA 94539 - USA. - - Phone: +1 (510) 354 6801 - Toll free: +1 (888) 813 6309 - Fax: +1 (510) 372 0604 - - You can also email us at <support@gluster.com>. - - -File: user-guide.info, Node: Installation and Invocation, Next: Concepts, Prev: Introduction, Up: Top - -2 Installation and Invocation -***************************** - -* Menu: - -* Pre requisites:: -* Getting GlusterFS:: -* Building:: -* Running GlusterFS:: -* A Tutorial Introduction:: - - -File: user-guide.info, Node: Pre requisites, Next: Getting GlusterFS, Up: Installation and Invocation - -2.1 Pre requisites -================== - -Before installing GlusterFS make sure you have the following components -installed. - -2.1.1 FUSE ----------- - -You'll need FUSE version 2.6.0 or higher to use GlusterFS. You can omit -installing FUSE if you want to build _only_ the server. Note that you -won't be able to mount a GlusterFS filesystem on a machine that does -not have FUSE installed. - - FUSE can be downloaded from: <http://fuse.sourceforge.net/> - - To get the best performance from GlusterFS, however, it is -recommended that you use our patched version of FUSE. See Patched FUSE -for details. - -2.1.2 Patched FUSE ------------------- - -The GlusterFS project maintains a patched version of FUSE meant to be -used with GlusterFS. The patches increase GlusterFS performance. It is -recommended that all users use the patched FUSE. - - The patched FUSE tarball can be downloaded from: - - <ftp://ftp.gluster.com/pub/gluster/glusterfs/fuse/> - - The specific changes made to FUSE are: - - * The communication channel size between FUSE kernel module and - GlusterFS has been increased to 1MB, permitting large reads and - writes to be sent in bigger chunks. - - * The kernel's read-ahead boundary has been extended up to 1MB. - - * Block size returned in the `stat()'/`fstat()' calls tuned to 1MB, - to make cp and similar commands perform I/O using that block size. - - * `flock()' locking support has been added (although some rework in - GlusterFS is needed for perfect compliance). - -2.1.3 libibverbs (optional) ---------------------------- - -This is only needed if you want GlusterFS to use InfiniBand as the -interconnect mechanism between server and client. You can get it from: - - <http://www.openfabrics.org/downloads.htm>. - -2.1.4 Bison and Flex --------------------- - -These should be already installed on most Linux systems. If not, use -your distribution's normal software installation procedures to install -them. Make sure you install the relevant developer packages also. - - -File: user-guide.info, Node: Getting GlusterFS, Next: Building, Prev: Pre requisites, Up: Installation and Invocation - -2.2 Getting GlusterFS -===================== - -There are many ways to get hold of GlusterFS. For a production -deployment, the recommended method is to download the latest release -tarball. Release tarballs are available at: -<http://gluster.org/download.php>. - - If you want the bleeding edge development source, you can get them -from the GNU Arch(1) repository. First you must install GNU Arch -itself. Then register the GlusterFS archive by doing: - - $ tla register-archive http://arch.sv.gnu.org/archives/gluster - - Now you can check out the source itself: - - $ tla get -A gluster@sv.gnu.org glusterfs--mainline--3.0 - - ---------- Footnotes ---------- - - (1) <http://www.gnu.org/software/gnu-arch/> - - -File: user-guide.info, Node: Building, Next: Running GlusterFS, Prev: Getting GlusterFS, Up: Installation and Invocation - -2.3 Building -============ - -You can skip this section if you're installing from RPMs or DEBs. - - GlusterFS uses the Autotools mechanism to build. As such, the -procedure is straight-forward. First, change into the GlusterFS source -directory. - - $ cd glusterfs-<version> - - If you checked out the source from the Arch repository, you'll need -to run `./autogen.sh' first. Note that you'll need to have Autoconf and -Automake installed for this. - - Run `configure'. - - $ ./configure - - The configure script accepts the following options: - -`--disable-ibverbs' - Disable the InfiniBand transport mechanism. - -`--disable-fuse-client' - Disable the FUSE client. - -`--disable-server' - Disable building of the GlusterFS server. - -`--disable-bdb' - Disable building of Berkeley DB based storage translator. - -`--disable-mod_glusterfs' - Disable building of Apache/lighttpd glusterfs plugins. - -`--disable-epoll' - Use poll instead of epoll. - -`--disable-libglusterfsclient' - Disable building of libglusterfsclient - - - Build and install GlusterFS. - - # make install - - The binaries (`glusterfsd' and `glusterfs') will be by default -installed in `/usr/local/sbin/'. Translator, scheduler, and transport -shared libraries will be installed in -`/usr/local/lib/glusterfs/<version>/'. Sample volume specification -files will be in `/usr/local/etc/glusterfs/'. This document itself can -be found in `/usr/local/share/doc/glusterfs/'. If you passed the -`--prefix' argument to the configure script, then replace `/usr/local' -in the preceding paths with the prefix. - - -File: user-guide.info, Node: Running GlusterFS, Next: A Tutorial Introduction, Prev: Building, Up: Installation and Invocation - -2.4 Running GlusterFS -===================== - -* Menu: - -* Server:: -* Client:: - - -File: user-guide.info, Node: Server, Next: Client, Up: Running GlusterFS - -2.4.1 Server ------------- - -The GlusterFS server is necessary to export storage volumes to remote -clients (See *note Server protocol:: for more info). This section -documents the invocation of the GlusterFS server program and all the -command-line options accepted by it. - - Basic Options - -`-f, --volfile=<path>' - Use the volume file as the volume specification. - -`-s, --volfile-server=<hostname>' - Server to get volume file from. This option overrides -volfile - option. - -`-l, --log-file=<path>' - Specify the path for the log file. - -`-L, --log-level=<level>' - Set the log level for the server. Log level should be one of DEBUG, - WARNING, ERROR, CRITICAL, or NONE. - - Advanced Options - -`--debug' - Run in debug mode. This option sets -no-daemon, -log-level to - DEBUG and -log-file to console. - -`-N, --no-daemon' - Run glusterfsd as a foreground process. - -`-p, --pid-file=<path>' - Path for the PID file. - -`--volfile-id=<key>' - 'key' of the volfile to be fetched from server. - -`--volfile-server-port=<port-number>' - Listening port number of volfile server. - -`--volfile-server-transport=[tcp|ib-verbs]' - Transport type to get volfile from server. [default: `tcp'] - -`--xlator-options=<volume-name.option=value>' - Add/override a translator option for a volume with specified value. - - Miscellaneous Options - -`-?, --help' - Show this help text. - -`--usage' - Display a short usage message. - -`-V, --version' - Show version information. - - -File: user-guide.info, Node: Client, Prev: Server, Up: Running GlusterFS - -2.4.2 Client ------------- - -The GlusterFS client process is necessary to access remote storage -volumes and mount them locally using FUSE. This section documents the -invocation of the client process and all its command-line arguments. - - # glusterfs [options] <mountpoint> - - The `mountpoint' is the directory where you want the GlusterFS -filesystem to appear. Example: - - # glusterfs -f /usr/local/etc/glusterfs-client.vol /mnt - - The command-line options are detailed below. - - Basic Options - -`-f, --volfile=<path>' - Use the volume file as the volume specification. - -`-s, --volfile-server=<hostname>' - Server to get volume file from. This option overrides -volfile - option. - -`-l, --log-file=<path>' - Specify the path for the log file. - -`-L, --log-level=<level>' - Set the log level for the server. Log level should be one of DEBUG, - WARNING, ERROR, CRITICAL, or NONE. - - Advanced Options - -`--debug' - Run in debug mode. This option sets -no-daemon, -log-level to - DEBUG and -log-file to console. - -`-N, --no-daemon' - Run `glusterfs' as a foreground process. - -`-p, --pid-file=<path>' - Path for the PID file. - -`--volfile-id=<key>' - 'key' of the volfile to be fetched from server. - -`--volfile-server-port=<port-number>' - Listening port number of volfile server. - -`--volfile-server-transport=[tcp|ib-verbs]' - Transport type to get volfile from server. [default: `tcp'] - -`--xlator-options=<volume-name.option=value>' - Add/override a translator option for a volume with specified value. - -`--volume-name=<volume name>' - Volume name in client spec to use. Defaults to the root volume. - - FUSE Options - -`--attribute-timeout=<n>' - Attribute timeout for inodes in the kernel, in seconds. Defaults - to 1 second. - -`--disable-direct-io-mode' - Disable direct I/O mode in FUSE kernel module. - -`-e, --entry-timeout=<n>' - Entry timeout for directory entries in the kernel, in seconds. - Defaults to 1 second. - - Missellaneous Options - -`-?, --help' - Show this help information. - -`-V, --version' - Show version information. - - -File: user-guide.info, Node: A Tutorial Introduction, Prev: Running GlusterFS, Up: Installation and Invocation - -2.5 A Tutorial Introduction -=========================== - -This section will show you how to quickly get GlusterFS up and running. -We'll configure GlusterFS as a simple network filesystem, with one -server and one client. In this mode of usage, GlusterFS can serve as a -replacement for NFS. - - We'll make use of two machines; call them _server_ and _client_ (If -you don't want to setup two machines, just run everything that follows -on the same machine). In the examples that follow, the shell prompts -will use these names to clarify the machine on which the command is -being run. For example, a command that should be run on the server will -be shown with the prompt: - - [root@server]# - - Our goal is to make a directory on the _server_ (say, `/export') -accessible to the _client_. - - First of all, get GlusterFS installed on both the machines, as -described in the previous sections. Make sure you have the FUSE kernel -module loaded. You can ensure this by running: - - [root@server]# modprobe fuse - - Before we can run the GlusterFS client or server programs, we need -to write two files called _volume specifications_ (equivalently referred -to as _volfiles_). The volfile describes the _translator tree_ on a -node. The next chapter will explain the concepts of `translator' and -`volume specification' in detail. For now, just assume that the volfile -is like an NFS `/etc/export' file. - - On the server, create a text file somewhere (we'll assume the path -`/tmp/glusterfsd.vol') with the following contents. - - volume colon-o - type storage/posix - option directory /export - end-volume - - volume server - type protocol/server - subvolumes colon-o - option transport-type tcp - option auth.addr.colon-o.allow * - end-volume - - A brief explanation of the file's contents. The first section -defines a storage volume, named "colon-o" (the volume names are -arbitrary), which exports the `/export' directory. The second section -defines options for the translator which will make the storage volume -accessible remotely. It specifies `colon-o' as a subvolume. This -defines the _translator tree_, about which more will be said in the -next chapter. The two options specify that the TCP protocol is to be -used (as opposed to InfiniBand, for example), and that access to the -storage volume is to be provided to clients with any IP address at all. -If you wanted to restrict access to this server to only your subnet for -example, you'd specify something like `192.168.1.*' in the second -option line. - - On the client machine, create the following text file (again, we'll -assume the path to be `/tmp/glusterfs-client.vol'). Replace -_server-ip-address_ with the IP address of your server machine. If you -are doing all this on a single machine, use `127.0.0.1'. - - volume client - type protocol/client - option transport-type tcp - option remote-host _server-ip-address_ - option remote-subvolume colon-o - end-volume - - Now we need to start both the server and client programs. To start -the server: - - [root@server]# glusterfsd -f /tmp/glusterfs-server.vol - - To start the client: - - [root@client]# glusterfs -f /tmp/glusterfs-client.vol /mnt/glusterfs - - You should now be able to see the files under the server's `/export' -directory in the `/mnt/glusterfs' directory on the client. That's it; -GlusterFS is now working as a network file system. - - -File: user-guide.info, Node: Concepts, Next: Translators, Prev: Installation and Invocation, Up: Top - -3 Concepts -********** - -* Menu: - -* Filesystems in Userspace:: -* Translator:: -* Volume specification file:: - - -File: user-guide.info, Node: Filesystems in Userspace, Next: Translator, Up: Concepts - -3.1 Filesystems in Userspace -============================ - -A filesystem is usually implemented in kernel space. Kernel space -development is much harder than userspace development. FUSE is a kernel -module/library that allows us to write a filesystem completely in -userspace. - - FUSE consists of a kernel module which interacts with the userspace -implementation using a device file `/dev/fuse'. When a process makes a -syscall on a FUSE filesystem, VFS hands the request to the FUSE module, -which writes the request to `/dev/fuse'. The userspace implementation -polls `/dev/fuse', and when a request arrives, processes it and writes -the result back to `/dev/fuse'. The kernel then reads from the device -file and returns the result to the user process. - - In case of GlusterFS, the userspace program is the GlusterFS client. -The control flow is shown in the diagram below. The GlusterFS client -services the request by sending it to the server, which in turn hands -it to the local POSIX filesystem. - - - Fig 1. Control flow in GlusterFS - - -File: user-guide.info, Node: Translator, Next: Volume specification file, Prev: Filesystems in Userspace, Up: Concepts - -3.2 Translator -============== - -The _translator_ is the most important concept in GlusterFS. In fact, -GlusterFS is nothing but a collection of translators working together, -forming a translator _tree_. - - The idea of a translator is perhaps best understood using an -analogy. Consider the VFS in the Linux kernel. The VFS abstracts the -various filesystem implementations (such as EXT3, ReiserFS, XFS, etc.) -supported by the kernel. When an application calls the kernel to -perform an operation on a file, the kernel passes the request on to the -appropriate filesystem implementation. - - For example, let's say there are two partitions on a Linux machine: -`/', which is an EXT3 partition, and `/usr', which is a ReiserFS -partition. Now if an application wants to open a file called, say, -`/etc/fstab', then the kernel will internally pass the request to the -EXT3 implementation. If on the other hand, an application wants to -read a file called `/usr/src/linux/CREDITS', then the kernel will call -upon the ReiserFS implementation to do the job. - - The "filesystem implementation" objects are analogous to GlusterFS -translators. A GlusterFS translator implements all the filesystem -operations. Whereas in VFS there is a two-level tree (with the kernel -at the root and all the filesystem implementation as its children), in -GlusterFS there exists a more elaborate tree structure. - - We can now define translators more precisely. A GlusterFS translator -is a shared object (`.so') that implements every filesystem call. -GlusterFS translators can be arranged in an arbitrary tree structure -(subject to constraints imposed by the translators). When GlusterFS -receives a filesystem call, it passes it on to the translator at the -root of the translator tree. The root translator may in turn pass it on -to any or all of its children, and so on, until the leaf nodes are -reached. The result of a filesystem call is communicated in the reverse -fashion, from the leaf nodes up to the root node, and then on to the -application. - - So what might a translator tree look like? - - - Fig 2. A sample translator tree - - The diagram depicts three servers and one GlusterFS client. It is -important to note that conceptually, the translator tree spans machine -boundaries. Thus, the client machine in the diagram, `10.0.0.1', can -access the aggregated storage of the filesystems on the server machines -`10.0.0.2', `10.0.0.3', and `10.0.0.4'. The translator diagram will -make more sense once you've read the next chapter and understood the -functions of the various translators. - - -File: user-guide.info, Node: Volume specification file, Prev: Translator, Up: Concepts - -3.3 Volume specification file -============================= - -The volume specification file describes the translator tree for both the -server and client programs. - - A volume specification file is a sequence of volume definitions. -The syntax of a volume definition is explained below: - - *volume* _volume-name_ - *type* _translator-name_ - *option* _option-name_ _option-value_ - ... - *subvolumes* _subvolume1_ _subvolume2_ ... - *end-volume* - - ... - -_volume-name_ - An identifier for the volume. This is just a human-readable name, - and can contain any alphanumeric character. For instance, - "storage-1", "colon-o", or "forty-two". - -_translator-name_ - Name of one of the available translators. Example: - `protocol/client', `cluster/unify'. - -_option-name_ - Name of a valid option for the translator. - -_option-value_ - Value for the option. Everything following the "option" keyword to - the end of the line is considered the value; it is up to the - translator to parse it. - -_subvolume1_, _subvolume2_, ... - Volume names of sub-volumes. The sub-volumes must already have - been defined earlier in the file. - - There are a few rules you must follow when writing a volume -specification file: - - * Everything following a ``#'' is considered a comment and is - ignored. Blank lines are also ignored. - - * All names and keywords are case-sensitive. - - * The order of options inside a volume definition does not matter. - - * An option value may not span multiple lines. - - * If an option is not specified, it will assume its default value. - - * A sub-volume must have already been defined before it can be - referenced. This means you have to write the specification file - "bottom-up", starting from the leaf nodes of the translator tree - and moving up to the root. - - A simple example volume specification file is shown below: - - # This is a comment line - volume client - type protocol/client - option transport-type tcp - option remote-host localhost # Also a comment - option remote-subvolume brick - # The subvolumes line may be absent - end-volume - - volume iot - type performance/io-threads - option thread-count 4 - subvolumes client - end-volume - - volume wb - type performance/write-behind - subvolumes iot - end-volume - - -File: user-guide.info, Node: Translators, Next: Usage Scenarios, Prev: Concepts, Up: Top - -4 Translators -************* - -* Menu: - -* Storage Translators:: -* Client and Server Translators:: -* Clustering Translators:: -* Performance Translators:: -* Features Translators:: -* Miscellaneous Translators:: - - This chapter documents all the available GlusterFS translators in -detail. Each translator section will show its name (for example, -`cluster/unify'), briefly describe its purpose and workings, and list -every option accepted by that translator and their meaning. - - -File: user-guide.info, Node: Storage Translators, Next: Client and Server Translators, Up: Translators - -4.1 Storage Translators -======================= - -The storage translators form the "backend" for GlusterFS. Currently, -the only available storage translator is the POSIX translator, which -stores files on a normal POSIX filesystem. A pleasant consequence of -this is that your data will still be accessible if GlusterFS crashes or -cannot be started. - - Other storage backends are planned for the future. One of the -possibilities is an Amazon S3 translator. Amazon S3 is an unlimited -online storage service accessible through a web services API. The S3 -translator will allow you to access the storage as a normal POSIX -filesystem. (1) - -* Menu: - -* POSIX:: -* BDB:: - - ---------- Footnotes ---------- - - (1) Some more discussion about this can be found at: - -http://developer.amazonwebservices.com/connect/message.jspa?messageID=52873 - - -File: user-guide.info, Node: POSIX, Next: BDB, Up: Storage Translators - -4.1.1 POSIX ------------ - - type storage/posix - - The `posix' translator uses a normal POSIX filesystem as its -"backend" to actually store files and directories. This can be any -filesystem that supports extended attributes (EXT3, ReiserFS, XFS, -...). Extended attributes are used by some translators to store -metadata, for example, by the replicate and stripe translators. See -*note Replicate:: and *note Stripe::, respectively for details. - -`directory <path>' - The directory on the local filesystem which is to be used for - storage. - - -File: user-guide.info, Node: BDB, Prev: POSIX, Up: Storage Translators - -4.1.2 BDB ---------- - - type storage/bdb - - The `BDB' translator uses a Berkeley DB database as its "backend" to -actually store files as key-value pair in the database and directories -as regular POSIX directories. Note that BDB does not provide extended -attribute support for regular files. Do not use BDB as storage -translator while using any translator that demands extended attributes -on "backend". - -`directory <path>' - The directory on the local filesystem which is to be used for - storage. - -`mode [cache|persistent] (cache)' - When BDB is run in `cache' mode, recovery of back-end is not - completely guaranteed. `persistent' guarantees that BDB can - recover back-end from Berkeley DB even if GlusterFS crashes. - -`errfile <path>' - The path of the file to be used as `errfile' for Berkeley DB to - report detailed error messages, if any. Note that all the contents - of this file will be written by Berkeley DB, not GlusterFS. - -`logdir <path>' - - -File: user-guide.info, Node: Client and Server Translators, Next: Clustering Translators, Prev: Storage Translators, Up: Translators - -4.2 Client and Server Translators -================================= - -The client and server translator enable GlusterFS to export a -translator tree over the network or access a remote GlusterFS server. -These two translators implement GlusterFS's network protocol. - -* Menu: - -* Transport modules:: -* Client protocol:: -* Server protocol:: - - -File: user-guide.info, Node: Transport modules, Next: Client protocol, Up: Client and Server Translators - -4.2.1 Transport modules ------------------------ - -The client and server translators are capable of using any of the -pluggable transport modules. Currently available transport modules are -`tcp', which uses a TCP connection between client and server to -communicate; `ib-sdp', which uses a TCP connection over InfiniBand, and -`ibverbs', which uses high-speed InfiniBand connections. - - Each transport module comes in two different versions, one to be -used on the server side and the other on the client side. - -4.2.1.1 TCP -........... - -The TCP transport module uses a TCP/IP connection between the server -and the client. - - option transport-type tcp - - The TCP client module accepts the following options: - -`non-blocking-connect [no|off|on|yes] (on)' - Whether to make the connection attempt asynchronous. - -`remote-port <n> (24007)' - Server port to connect to. - -`remote-host <hostname> *' - Hostname or IP address of the server. If the host name resolves to - multiple IP addresses, all of them will be tried in a round-robin - fashion. This feature can be used to implement fail-over. - - The TCP server module accepts the following options: - -`bind-address <address> (0.0.0.0)' - The local interface on which the server should listen to requests. - Default is to listen on all interfaces. - -`listen-port <n> (24007)' - The local port to listen on. - -4.2.1.2 IB-SDP -.............. - - option transport-type ib-sdp - - kernel implements socket interface for ib hardware. SDP is over -ib-verbs. This module accepts the same options as `tcp' - -4.2.1.3 ibverbs -............... - - option transport-type tcp - - InfiniBand is a scalable switched fabric interconnect mechanism -primarily used in high-performance computing. InfiniBand can deliver -data throughput of the order of 10 Gbit/s, with latencies of 4-5 ms. - - The `ib-verbs' transport accesses the InfiniBand hardware through -the "verbs" API, which is the lowest level of software access possible -and which gives the highest performance. On InfiniBand hardware, it is -always best to use `ib-verbs'. Use `ib-sdp' only if you cannot get -`ib-verbs' working for some reason. - - The `ib-verbs' client module accepts the following options: - -`non-blocking-connect [no|off|on|yes] (on)' - Whether to make the connection attempt asynchronous. - -`remote-port <n> (24007)' - Server port to connect to. - -`remote-host <hostname> *' - Hostname or IP address of the server. If the host name resolves to - multiple IP addresses, all of them will be tried in a round-robin - fashion. This feature can be used to implement fail-over. - - The `ib-verbs' server module accepts the following options: - -`bind-address <address> (0.0.0.0)' - The local interface on which the server should listen to requests. - Default is to listen on all interfaces. - -`listen-port <n> (24007)' - The local port to listen on. - - The following options are common to both the client and server -modules: - - If you are familiar with InfiniBand jargon, the mode is used by -GlusterFS is "reliable connection-oriented channel transfer". - -`ib-verbs-work-request-send-count <n> (64)' - Length of the send queue in datagrams. [Reason to - increase/decrease?] - -`ib-verbs-work-request-recv-count <n> (64)' - Length of the receive queue in datagrams. [Reason to - increase/decrease?] - -`ib-verbs-work-request-send-size <size> (128KB)' - Size of each datagram that is sent. [Reason to increase/decrease?] - -`ib-verbs-work-request-recv-size <size> (128KB)' - Size of each datagram that is received. [Reason to - increase/decrease?] - -`ib-verbs-port <n> (1)' - Port number for ib-verbs. - -`ib-verbs-mtu [256|512|1024|2048|4096] (2048)' - The Maximum Transmission Unit [Reason to increase/decrease?] - -`ib-verbs-device-name <device-name> (first device in the list)' - InfiniBand device to be used. - - For maximum performance, you should ensure that the send/receive -counts on both the client and server are the same. - - ib-verbs is preferred over ib-sdp. - - -File: user-guide.info, Node: Client protocol, Next: Server protocol, Prev: Transport modules, Up: Client and Server Translators - -4.2.2 Client ------------- - - type procotol/client - - The client translator enables the GlusterFS client to access a -remote server's translator tree. - -`transport-type [tcp,ib-sdp,ib-verbs] (tcp)' - The transport type to use. You should use the client versions of - all the transport modules (`tcp', `ib-sdp', `ib-verbs'). - -`remote-subvolume <volume_name> *' - The name of the volume on the remote host to attach to. Note that - this is _not_ the name of the `protocol/server' volume on the - server. It should be any volume under the server. - -`transport-timeout <n> (120- seconds)' - Inactivity timeout. If a reply is expected and no activity takes - place on the connection within this time, the transport connection - will be broken, and a new connection will be attempted. - - -File: user-guide.info, Node: Server protocol, Prev: Client protocol, Up: Client and Server Translators - -4.2.3 Server ------------- - - type protocol/server - - The server translator exports a translator tree and makes it -accessible to remote GlusterFS clients. - -`client-volume-filename <path> (<CONFDIR>/glusterfs-client.vol)' - The volume specification file to use for the client. This is the - file the client will receive when it is invoked with the - `--server' option (*note Client::). - -`transport-type [tcp,ib-verbs,ib-sdp] (tcp)' - The transport to use. You should use the server versions of all - the transport modules (`tcp', `ib-sdp', `ib-verbs'). - -`auth.addr.<volume name>.allow <IP address wildcard pattern>' - IP addresses of the clients that are allowed to attach to the - specified volume. This can be a wildcard. For example, a wildcard - of the form `192.168.*.*' allows any host in the `192.168.x.x' - subnet to connect to the server. - - - -File: user-guide.info, Node: Clustering Translators, Next: Performance Translators, Prev: Client and Server Translators, Up: Translators - -4.3 Clustering Translators -========================== - -The clustering translators are the most important GlusterFS -translators, since it is these that make GlusterFS a cluster -filesystem. These translators together enable GlusterFS to access an -arbitrarily large amount of storage, and provide RAID-like redundancy -and distribution over the entire cluster. - - There are three clustering translators: *unify*, *replicate*, and -*stripe*. The unify translator aggregates storage from many server -nodes. The replicate translator provides file replication. The stripe -translator allows a file to be spread across many server nodes. The -following sections look at each of these translators in detail. - -* Menu: - -* Unify:: -* Replicate:: -* Stripe:: - - -File: user-guide.info, Node: Unify, Next: Replicate, Up: Clustering Translators - -4.3.1 Unify ------------ - - type cluster/unify - - The unify translator presents a `unified' view of all its -sub-volumes. That is, it makes the union of all its sub-volumes appear -as a single volume. It is the unify translator that gives GlusterFS the -ability to access an arbitrarily large amount of storage. - - For unify to work correctly, certain invariants need to be -maintained across the entire network. These are: - - * The directory structure of all the sub-volumes must be identical. - - * A particular file can exist on only one of the sub-volumes. - Phrasing it in another way, a pathname such as - `/home/calvin/homework.txt') is unique across the entire cluster. - - - -Looking at the second requirement, you might wonder how one can -accomplish storing redundant copies of a file, if no file can exist -multiple times. To answer, we must remember that these invariants are -from _unify's perspective_. A translator such as replicate at a lower -level in the translator tree than unify may subvert this picture. - - The first invariant might seem quite tedious to ensure. We shall see -later that this is not so, since unify's _self-heal_ mechanism takes -care of maintaining it. - - The second invariant implies that unify needs some way to decide -which file goes where. Unify makes use of _scheduler_ modules for this -purpose. - - When a file needs to be created, unify's scheduler decides upon the -sub-volume to be used to store the file. There are many schedulers -available, each using a different algorithm and suitable for different -purposes. - - The various schedulers are described in detail in the sections that -follow. - -4.3.1.1 ALU -........... - - option scheduler alu - - ALU stands for "Adaptive Least Usage". It is the most advanced -scheduler available in GlusterFS. It balances the load across volumes -taking several factors in account. It adapts itself to changing I/O -patterns according to its configuration. When properly configured, it -can eliminate the need for regular tuning of the filesystem to keep -volume load nicely balanced. - - The ALU scheduler is composed of multiple least-usage -sub-schedulers. Each sub-scheduler keeps track of a certain type of -load, for each of the sub-volumes, getting statistics from the -sub-volumes themselves. The sub-schedulers are these: - - * disk-usage: The used and free disk space on the volume. - - * read-usage: The amount of reading done from this volume. - - * write-usage: The amount of writing done to this volume. - - * open-files-usage: The number of files currently open from this - volume. - - * disk-speed-usage: The speed at which the disks are spinning. This - is a constant value and therefore not very useful. - - The ALU scheduler needs to know which of these sub-schedulers to use, -and in which order to evaluate them. This is done through the `option -alu.order' configuration directive. - - Each sub-scheduler needs to know two things: when to kick in (the -entry-threshold), and how long to stay in control (the exit-threshold). -For example: when unifying three disks of 100GB, keeping an exact -balance of disk-usage is not necessary. Instead, there could be a 1GB -margin, which can be used to nicely balance other factors, such as -read-usage. The disk-usage scheduler can be told to kick in only when a -certain threshold of discrepancy is passed, such as 1GB. When it -assumes control under this condition, it will write all subsequent data -to the least-used volume. If it is doing so, it is unwise to stop right -after the values are below the entry-threshold again, since that would -make it very likely that the situation will occur again very soon. Such -a situation would cause the ALU to spend most of its time disk-usage -scheduling, which is unfair to the other sub-schedulers. The -exit-threshold therefore defines the amount of data that needs to be -written to the least-used disk, before control is relinquished again. - - In addition to the sub-schedulers, the ALU scheduler also has -"limits" options. These can stop the creation of new files on a volume -once values drop below a certain threshold. For example, setting -`option alu.limits.min-free-disk 5GB' will stop the scheduling of files -to volumes that have less than 5GB of free disk space, leaving the -files on that disk some room to grow. - - The actual values you assign to the thresholds for sub-schedulers and -limits depend on your situation. If you have fast-growing files, you'll -want to stop file-creation on a disk much earlier than when hardly any -of your files are growing. If you care less about disk-usage balance -than about read-usage balance, you'll want a bigger disk-usage -scheduler entry-threshold and a smaller read-usage scheduler -entry-threshold. - - For thresholds defining a size, values specifying "KB", "MB" and "GB" -are allowed. For example: `option alu.limits.min-free-disk 5GB'. - -`alu.order <order> * ("disk-usage:write-usage:read-usage:open-files-usage:disk-speed")' - -`alu.disk-usage.entry-threshold <size> (1GB)' - -`alu.disk-usage.exit-threshold <size> (512MB)' - -`alu.write-usage.entry-threshold <%> (25)' - -`alu.write-usage.exit-threshold <%> (5)' - -`alu.read-usage.entry-threshold <%> (25)' - -`alu.read-usage.exit-threshold <%> (5)' - -`alu.open-files-usage.entry-threshold <n> (1000)' - -`alu.open-files-usage.exit-threshold <n> (100)' - -`alu.limits.min-free-disk <%>' - -`alu.limits.max-open-files <n>' - -4.3.1.2 Round Robin (RR) -........................ - - option scheduler rr - - Round-Robin (RR) scheduler creates files in a round-robin fashion. -Each client will have its own round-robin loop. When your files are -mostly similar in size and I/O access pattern, this scheduler is a good -choice. RR scheduler checks for free disk space on the server before -scheduling, so you can know when to add another server node. The -default value of min-free-disk is 5% and is checked on file creation -calls, with atleast 10 seconds (by default) elapsing between two checks. - - Options: -`rr.limits.min-free-disk <%> (5)' - Minimum free disk space a node must have for RR to schedule a file - to it. - -`rr.refresh-interval <t> (10 seconds)' - Time between two successive free disk space checks. - -4.3.1.3 Random -.............. - - option scheduler random - - The random scheduler schedules file creation randomly among its -child nodes. Like the round-robin scheduler, it also checks for a -minimum amount of free disk space before scheduling a file to a node. - -`random.limits.min-free-disk <%> (5)' - Minimum free disk space a node must have for random to schedule a - file to it. - -`random.refresh-interval <t> (10 seconds)' - Time between two successive free disk space checks. - -4.3.1.4 NUFA -............ - - option scheduler nufa - - It is common in many GlusterFS computing environments for all -deployed machines to act as both servers and clients. For example, a -research lab may have 40 workstations each with its own storage. All of -these workstations might act as servers exporting a volume as well as -clients accessing the entire cluster's storage. In such a situation, -it makes sense to store locally created files on the local workstation -itself (assuming files are accessed most by the workstation that -created them). The Non-Uniform File Allocation (NUFA) scheduler -accomplishes that. - - NUFA gives the local system first priority for file creation over -other nodes. If the local volume does not have more free disk space -than a specified amount (5% by default) then NUFA schedules files among -the other child volumes in a round-robin fashion. - - NUFA is named after the similar strategy used for memory access, -NUMA(1). - -`nufa.limits.min-free-disk <%> (5)' - Minimum disk space that must be free (local or remote) for NUFA to - schedule a file to it. - -`nufa.refresh-interval <t> (10 seconds)' - Time between two successive free disk space checks. - -`nufa.local-volume-name <volume>' - The name of the volume corresponding to the local system. This - volume must be one of the children of the unify volume. This - option is mandatory. - -4.3.1.5 Namespace -................. - -Namespace volume needed because: - persistent inode numbers. - file -exists even when node is down. - - namespace files are simply touched. on every lookup it is checked. - -`namespace <volume> *' - Name of the namespace volume (which should be one of the unify - volume's children). - -`self-heal [on|off] (on)' - Enable/disable self-heal. Unless you know what you are doing, do - not disable self-heal. - -4.3.1.6 Self Heal -................. - -* When a 'lookup()/stat()' call is made on directory for the first -time, a self-heal call is made, which checks for the consistancy of its -child nodes. If an entry is present in storage node, but not in -namespace, that entry is created in namespace, and vica-versa. There is -an writedir() API introduced which is used for the same. It also checks -for permissions, and uid/gid consistencies. - - * This check is also done when an server goes down and comes up. - - * If one starts with an empty namespace export, but has data in -storage nodes, a 'find .>/dev/null' or 'ls -lR >/dev/null' should help -to build namespace in one shot. Even otherwise, namespace is built on -demand when a file is looked up for the first time. - - NOTE: There are some issues (Kernel 'Oops' msgs) seen with -fuse-2.6.3, when someone deletes namespace in backend, when glusterfs is -running. But with fuse-2.6.5, this issue is not there. - - ---------- Footnotes ---------- - - (1) Non-Uniform Memory Access: -<http://en.wikipedia.org/wiki/Non-Uniform_Memory_Access> - - -File: user-guide.info, Node: Replicate, Next: Stripe, Prev: Unify, Up: Clustering Translators - -4.3.2 Replicate (formerly AFR) ------------------------------- - - type cluster/replicate - - Replicate provides RAID-1 like functionality for GlusterFS. -Replicate replicates files and directories across the subvolumes. Hence -if Replicate has four subvolumes, there will be four copies of all -files and directories. Replicate provides high-availability, i.e., in -case one of the subvolumes go down (e. g. server crash, network -disconnection) Replicate will still service the requests using the -redundant copies. - - Replicate also provides self-heal functionality, i.e., in case the -crashed servers come up, the outdated files and directories will be -updated with the latest versions. Replicate uses extended attributes of -the backend file system to track the versioning of files and -directories and provide the self-heal feature. - - volume replicate-example - type cluster/replicate - subvolumes brick1 brick2 brick3 - end-volume - - This sample configuration will replicate all directories and files on -brick1, brick2 and brick3. - - All the read operations happen from the first alive child. If all the -three sub-volumes are up, reads will be done from brick1; if brick1 is -down read will be done from brick2. In case read() was being done on -brick1 and it goes down, replicate transparently falls back to brick2. - - The next release of GlusterFS will add the following features: - * Ability to specify the sub-volume from which read operations are - to be done (this will help users who have one of the sub-volumes - as a local storage volume). - - * Allow scheduling of read operations amongst the sub-volumes in a - round-robin fashion. - - The order of the subvolumes list should be same across all the -'replicate's as they will be used for locking purposes. - -4.3.2.1 Self Heal -................. - -Replicate has self-heal feature, which updates the outdated file and -directory copies by the most recent versions. For example consider the -following config: - - volume replicate-example - type cluster/replicate - subvolumes brick1 brick2 - end-volume - -4.3.2.2 File self-heal -...................... - -Now if we create a file foo.txt on replicate-example, the file will be -created on brick1 and brick2. The file will have two extended -attributes associated with it in the backend filesystem. One is -trusted.afr.createtime and the other is trusted.afr.version. The -trusted.afr.createtime xattr has the create time (in terms of seconds -since epoch) and trusted.afr.version is a number that is incremented -each time a file is modified. This increment happens during close -(incase any write was done before close). - - If brick1 goes down, we edit foo.txt the version gets incremented. -Now the brick1 comes back up, when we open() on foo.txt replicate will -check if their versions are same. If they are not same, the outdated -copy is replaced by the latest copy and its version is updated. After -the sync the open() proceeds in the usual manner and the application -calling open() can continue on its access to the file. - - If brick1 goes down, we delete foo.txt and create a file with the -same name again i.e foo.txt. Now brick1 comes back up, clearly there is -a chance that the version on brick1 being more than the version on -brick2, this is where createtime extended attribute helps in deciding -which the outdated copy is. Hence we need to consider both createtime -and version to decide on the latest copy. - - The version attribute is incremented during the close() call. Version -will not be incremented in case there was no write() done. In case the -fd that the close() gets was got by create() call, we also create the -createtime extended attribute. - -4.3.2.3 Directory self-heal -........................... - -Suppose brick1 goes down, we delete foo.txt, brick1 comes back up, now -we should not create foo.txt on brick2 but we should delete foo.txt on -brick1. We handle this situation by having the createtime and version -attribute on the directory similar to the file. when lookup() is done -on the directory, we compare the createtime/version attributes of the -copies and see which files needs to be deleted and delete those files -and update the extended attributes of the outdated directory copy. -Each time a directory is modified (a file or a subdirectory is created -or deleted inside the directory) and one of the subvols is down, we -increment the directory's version. - - lookup() is a call initiated by the kernel on a file or directory -just before any access to that file or directory. In glusterfs, by -default, lookup() will not be called in case it was called in the past -one second on that particular file or directory. - - The extended attributes can be seen in the backend filesystem using -the `getfattr' command. (`getfattr -n trusted.afr.version <file>') - -`debug [on|off] (off)' - -`self-heal [on|off] (on)' - -`replicate <pattern> (*:1)' - -`lock-node <child_volume> (first child is used by default)' - - -File: user-guide.info, Node: Stripe, Prev: Replicate, Up: Clustering Translators - -4.3.3 Stripe ------------- - - type cluster/stripe - - The stripe translator distributes the contents of a file over its -sub-volumes. It does this by creating a file equal in size to the -total size of the file on each of its sub-volumes. It then writes only -a part of the file to each sub-volume, leaving the rest of it empty. -These empty regions are called `holes' in Unix terminology. The holes -do not consume any disk space. - - The diagram below makes this clear. - - - -You can configure stripe so that only filenames matching a pattern are -striped. You can also configure the size of the data to be stored on -each sub-volume. - -`block-size <pattern>:<size> (*:0 no striping)' - Distribute files matching `<pattern>' over the sub-volumes, - storing at least `<size>' on each sub-volume. For example, - - option block-size *.mpg:1M - - distributes all files ending in `.mpg', storing at least 1 MB on - each sub-volume. - - Any number of `block-size' option lines may be present, specifying - different sizes for different file name patterns. - - -File: user-guide.info, Node: Performance Translators, Next: Features Translators, Prev: Clustering Translators, Up: Translators - -4.4 Performance Translators -=========================== - -* Menu: - -* Read Ahead:: -* Write Behind:: -* IO Threads:: -* IO Cache:: -* Booster:: - - -File: user-guide.info, Node: Read Ahead, Next: Write Behind, Up: Performance Translators - -4.4.1 Read Ahead ----------------- - - type performance/read-ahead - - The read-ahead translator pre-fetches data in advance on every read. -This benefits applications that mostly process files in sequential -order, since the next block of data will already be available by the -time the application is done with the current one. - - Additionally, the read-ahead translator also behaves as a -read-aggregator. Many small read operations are combined and issued as -fewer, larger read requests to the server. - - Read-ahead deals in "pages" as the unit of data fetched. The page -size is configurable, as is the "page count", which is the number of -pages that are pre-fetched. - - Read-ahead is best used with InfiniBand (using the ib-verbs -transport). On FastEthernet and Gigabit Ethernet networks, GlusterFS -can achieve the link-maximum throughput even without read-ahead, making -it quite superflous. - - Note that read-ahead only happens if the reads are perfectly -sequential. If your application accesses data in a random fashion, -using read-ahead might actually lead to a performance loss, since -read-ahead will pointlessly fetch pages which won't be used by the -application. - - Options: -`page-size <n> (256KB)' - The unit of data that is pre-fetched. - -`page-count <n> (2)' - The number of pages that are pre-fetched. - -`force-atime-update [on|off|yes|no] (off|no)' - Whether to force an access time (atime) update on the file on - every read. Without this, the atime will be slightly imprecise, as - it will reflect the time when the read-ahead translator read the - data, not when the application actually read it. - - -File: user-guide.info, Node: Write Behind, Next: IO Threads, Prev: Read Ahead, Up: Performance Translators - -4.4.2 Write Behind ------------------- - - type performance/write-behind - - The write-behind translator improves the latency of a write -operation. It does this by relegating the write operation to the -background and returning to the application even as the write is in -progress. Using the write-behind translator, successive write requests -can be pipelined. This mode of write-behind operation is best used on -the client side, to enable decreased write latency for the application. - - The write-behind translator can also aggregate write requests. If the -`aggregate-size' option is specified, then successive writes up to that -size are accumulated and written in a single operation. This mode of -operation is best used on the server side, as this will decrease the -disk's head movement when multiple files are being written to in -parallel. - - The `aggregate-size' option has a default value of 128KB. Although -this works well for most users, you should always experiment with -different values to determine the one that will deliver maximum -performance. This is because the performance of write-behind depends on -your interconnect, size of RAM, and the work load. - -`aggregate-size <n> (128KB)' - Amount of data to accumulate before doing a write - -`flush-behind [on|yes|off|no] (off|no)' - - -File: user-guide.info, Node: IO Threads, Next: IO Cache, Prev: Write Behind, Up: Performance Translators - -4.4.3 IO Threads ----------------- - - type performance/io-threads - - The IO threads translator is intended to increase the responsiveness -of the server to metadata operations by doing file I/O (read, write) in -a background thread. Since the GlusterFS server is single-threaded, -using the IO threads translator can significantly improve performance. -This translator is best used on the server side, loaded just below the -server protocol translator. - - IO threads operates by handing out read and write requests to a -separate thread. The total number of threads in existence at a time is -constant, and configurable. - -`thread-count <n> (1)' - Number of threads to use. - - -File: user-guide.info, Node: IO Cache, Next: Booster, Prev: IO Threads, Up: Performance Translators - -4.4.4 IO Cache --------------- - - type performance/io-cache - - The IO cache translator caches data that has been read. This is -useful if many applications read the same data multiple times, and if -reads are much more frequent than writes (for example, IO caching may be -useful in a web hosting environment, where most clients will simply -read some files and only a few will write to them). - - The IO cache translator reads data from its child in `page-size' -chunks. It caches data up to `cache-size' bytes. The cache is -maintained as a prioritized least-recently-used (LRU) list, with -priorities determined by user-specified patterns to match filenames. - - When the IO cache translator detects a write operation, the cache -for that file is flushed. - - The IO cache translator periodically verifies the consistency of -cached data, using the modification times on the files. The -verification timeout is configurable. - -`page-size <n> (128KB)' - Size of a page. - -`cache-size (n) (32MB)' - Total amount of data to be cached. - -`force-revalidate-timeout <n> (1)' - Timeout to force a cache consistency verification, in seconds. - -`priority <pattern> (*:0)' - Filename patterns listed in order of priority. - - -File: user-guide.info, Node: Booster, Prev: IO Cache, Up: Performance Translators - -4.4.5 Booster -------------- - - type performance/booster - - The booster translator gives applications a faster path to -communicate read and write requests to GlusterFS. Normally, all -requests to GlusterFS from applications go through FUSE, as indicated -in *note Filesystems in Userspace::. Using the booster translator in -conjunction with the GlusterFS booster shared library, an application -can bypass the FUSE path and send read/write requests directly to the -GlusterFS client process. - - The booster mechanism consists of two parts: the booster translator, -and the booster shared library. The booster translator is meant to be -loaded on the client side, usually at the root of the translator tree. -The booster shared library should be `LD_PRELOAD'ed with the -application. - - The booster translator when loaded opens a Unix domain socket and -listens for read/write requests on it. The booster shared library -intercepts read and write system calls and sends the requests to the -GlusterFS process directly using the Unix domain socket, bypassing FUSE. -This leads to superior performance. - - Once you've loaded the booster translator in your volume -specification file, you can start your application as: - - $ LD_PRELOAD=/usr/local/bin/glusterfs-booster.so your_app - - The booster translator accepts no options. - - -File: user-guide.info, Node: Features Translators, Next: Miscellaneous Translators, Prev: Performance Translators, Up: Translators - -4.5 Features Translators -======================== - -* Menu: - -* POSIX Locks:: -* Fixed ID:: - - -File: user-guide.info, Node: POSIX Locks, Next: Fixed ID, Up: Features Translators - -4.5.1 POSIX Locks ------------------ - - type features/posix-locks - - This translator provides storage independent POSIX record locking -support (`fcntl' locking). Typically you'll want to load this on the -server side, just above the POSIX storage translator. Using this -translator you can get both advisory locking and mandatory locking -support. It also handles `flock()' locks properly. - - Caveat: Consider a file that does not have its mandatory locking bits -(+setgid, -group execution) turned on. Assume that this file is now -opened by a process on a client that has the write-behind xlator -loaded. The write-behind xlator does not cache anything for files which -have mandatory locking enabled, to avoid incoherence. Let's say that -mandatory locking is now enabled on this file through another client. -The former client will not know about this change, and write-behind may -erroneously report a write as being successful when in fact it would -fail due to the region it is writing to being locked. - - There seems to be no easy way to fix this. To work around this -problem, it is recommended that you never enable the mandatory bits on -a file while it is open. - -`mandatory [on|off] (on)' - Turns mandatory locking on. - - -File: user-guide.info, Node: Fixed ID, Prev: POSIX Locks, Up: Features Translators - -4.5.2 Fixed ID --------------- - - type features/fixed-id - - The fixed ID translator makes all filesystem requests from the client -to appear to be coming from a fixed, specified UID/GID, regardless of -which user actually initiated the request. - -`fixed-uid <n> [if not set, not used]' - The UID to send to the server - -`fixed-gid <n> [if not set, not used]' - The GID to send to the server - - -File: user-guide.info, Node: Miscellaneous Translators, Prev: Features Translators, Up: Translators - -4.6 Miscellaneous Translators -============================= - -* Menu: - -* ROT-13:: -* Trace:: - - -File: user-guide.info, Node: ROT-13, Next: Trace, Up: Miscellaneous Translators - -4.6.1 ROT-13 ------------- - - type encryption/rot-13 - - ROT-13 is a toy translator that can "encrypt" and "decrypt" file -contents using the ROT-13 algorithm. ROT-13 is a trivial algorithm that -rotates each alphabet by thirteen places. Thus, 'A' becomes 'N', 'B' -becomes 'O', and 'Z' becomes 'M'. - - It goes without saying that you shouldn't use this translator if you -need _real_ encryption (a future release of GlusterFS will have real -encryption translators). - -`encrypt-write [on|off] (on)' - Whether to encrypt on write - -`decrypt-read [on|off] (on)' - Whether to decrypt on read - - -File: user-guide.info, Node: Trace, Prev: ROT-13, Up: Miscellaneous Translators - -4.6.2 Trace ------------ - - type debug/trace - - The trace translator is intended for debugging purposes. When -loaded, it logs all the system calls received by the server or client -(wherever trace is loaded), their arguments, and the results. You must -use a GlusterFS log level of DEBUG (See *note Running GlusterFS::) for -trace to work. - - Sample trace output (lines have been wrapped for readability): - 2007-10-30 00:08:58 D [trace.c:1579:trace_opendir] trace: callid: 68 - (*this=0x8059e40, loc=0x8091984 {path=/iozone3_283, inode=0x8091f00}, - fd=0x8091d50) - - 2007-10-30 00:08:58 D [trace.c:630:trace_opendir_cbk] trace: - (*this=0x8059e40, op_ret=4, op_errno=1, fd=0x8091d50) - - 2007-10-30 00:08:58 D [trace.c:1602:trace_readdir] trace: callid: 69 - (*this=0x8059e40, size=4096, offset=0 fd=0x8091d50) - - 2007-10-30 00:08:58 D [trace.c:215:trace_readdir_cbk] trace: - (*this=0x8059e40, op_ret=0, op_errno=0, count=4) - - 2007-10-30 00:08:58 D [trace.c:1624:trace_closedir] trace: callid: 71 - (*this=0x8059e40, *fd=0x8091d50) - - 2007-10-30 00:08:58 D [trace.c:809:trace_closedir_cbk] trace: - (*this=0x8059e40, op_ret=0, op_errno=1) - - -File: user-guide.info, Node: Usage Scenarios, Next: Troubleshooting, Prev: Translators, Up: Top - -5 Usage Scenarios -***************** - -5.1 Advanced Striping -===================== - -This section is based on the Advanced Striping tutorial written by -Anand Avati on the GlusterFS wiki (1). - -5.1.1 Mixed Storage Requirements --------------------------------- - -There are two ways of scheduling the I/O. One at file level (using -unify translator) and other at block level (using stripe translator). -Striped I/O is good for files that are potentially large and require -high parallel throughput (for example, a single file of 400GB being -accessed by 100s and 1000s of systems simultaneously and randomly). For -most of the cases, file level scheduling works best. - - In the real world, it is desirable to mix file level and block level -scheduling on a single storage volume. Alternatively users can choose -to have two separate volumes and hence two mount points, but the -applications may demand a single storage system to host both. - - This document explains how to mix file level scheduling with stripe. - -5.1.2 Configuration Brief -------------------------- - -This setup demonstrates how users can configure unify translator with -appropriate I/O scheduler for file level scheduling and strip for only -matching patterns. This way, GlusterFS chooses appropriate I/O profile -and knows how to efficiently handle both the types of data. - - A simple technique to achieve this effect is to create a stripe set -of unify and stripe blocks, where unify is the first sub-volume. Files -that do not match the stripe policy passed on to first unify sub-volume -and inturn scheduled arcoss the cluster using its file level I/O -scheduler. - - 5.1.3 Preparing GlusterFS Envoronment -------------------------------------- - -Create the directories /export/namespace, /export/unify and -/export/stripe on all the storage bricks. - - Place the following server and client volume spec file under -/etc/glusterfs (or appropriate installed path) and replace the IP -addresses / access control fields to match your environment. - - ## file: /etc/glusterfs/glusterfsd.vol - volume posix-unify - type storage/posix - option directory /export/for-unify - end-volume - - volume posix-stripe - type storage/posix - option directory /export/for-stripe - end-volume - - volume posix-namespace - type storage/posix - option directory /export/for-namespace - end-volume - - volume server - type protocol/server - option transport-type tcp - option auth.addr.posix-unify.allow 192.168.1.* - option auth.addr.posix-stripe.allow 192.168.1.* - option auth.addr.posix-namespace.allow 192.168.1.* - subvolumes posix-unify posix-stripe posix-namespace - end-volume - - ## file: /etc/glusterfs/glusterfs.vol - volume client-namespace - type protocol/client - option transport-type tcp - option remote-host 192.168.1.1 - option remote-subvolume posix-namespace - end-volume - - volume client-unify-1 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.1 - option remote-subvolume posix-unify - end-volume - - volume client-unify-2 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.2 - option remote-subvolume posix-unify - end-volume - - volume client-unify-3 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.3 - option remote-subvolume posix-unify - end-volume - - volume client-unify-4 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.4 - option remote-subvolume posix-unify - end-volume - - volume client-stripe-1 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.1 - option remote-subvolume posix-stripe - end-volume - - volume client-stripe-2 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.2 - option remote-subvolume posix-stripe - end-volume - - volume client-stripe-3 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.3 - option remote-subvolume posix-stripe - end-volume - - volume client-stripe-4 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.4 - option remote-subvolume posix-stripe - end-volume - - volume unify - type cluster/unify - option scheduler rr - subvolumes cluster-unify-1 cluster-unify-2 cluster-unify-3 cluster-unify-4 - end-volume - - volume stripe - type cluster/stripe - option block-size *.img:2MB # All files ending with .img are striped with 2MB stripe block size. - subvolumes unify cluster-stripe-1 cluster-stripe-2 cluster-stripe-3 cluster-stripe-4 - end-volume - - Bring up the Storage - - Starting GlusterFS Server: If you have installed through binary -package, you can start the service through init.d startup script. If -not: - - [root@server]# glusterfsd - - Mounting GlusterFS Volumes: - - [root@client]# glusterfs -s [BRICK-IP-ADDRESS] /mnt/cluster - - Improving upon this Setup - - Infiniband Verbs RDMA transport is much faster than TCP/IP GigE -transport. - - Use of performance translators such as read-ahead, write-behind, -io-cache, io-threads, booster is recommended. - - Replace round-robin (rr) scheduler with ALU to handle more dynamic -storage environments. - - ---------- Footnotes ---------- - - (1) -http://gluster.org/docs/index.php/Mixing_Striped_and_Regular_Files - - -File: user-guide.info, Node: Troubleshooting, Next: GNU Free Documentation Licence, Prev: Usage Scenarios, Up: Top - -6 Troubleshooting -***************** - -This chapter is a general troubleshooting guide to GlusterFS. It lists -common GlusterFS server and client error messages, debugging hints, and -concludes with the suggested procedure to report bugs in GlusterFS. - -6.1 GlusterFS error messages -============================ - -6.1.1 Server errors -------------------- - - glusterfsd: FATAL: could not open specfile: - '/etc/glusterfs/glusterfsd.vol' - - The GlusterFS server expects the volume specification file to be at -`/etc/glusterfs/glusterfsd.vol'. The example specification file will be -installed as `/etc/glusterfs/glusterfsd.vol.sample'. You need to edit -it and rename it, or provide a different specification file using the -`--spec-file' command line option (See *note Server::). - - gf_log_init: failed to open logfile "/usr/var/log/glusterfs/glusterfsd.log" - (Permission denied) - - You don't have permission to create files in the -`/usr/var/log/glusterfs' directory. Make sure you are running GlusterFS -as root. Alternatively, specify a different path for the log file using -the `--log-file' option (See *note Server::). - -6.1.2 Client errors -------------------- - - fusermount: failed to access mountpoint /mnt: - Transport endpoint is not connected - - A previous failed (or hung) mount of GlusterFS is preventing it from -being mounted again in the same location. The fix is to do: - - # umount /mnt - - and try mounting again. - - *"Transport endpoint is not connected".* - - If you get this error when you try a command such as `ls' or `cat', -it means the GlusterFS mount did not succeed. Try running GlusterFS in -`DEBUG' logging level and study the log messages to discover the cause. - - *"Connect to server failed", "SERVER-ADDRESS: Connection refused".* - - GluserFS Server is not running or dead. Check your network -connections and firewall settings. To check if the server is reachable, -try: - - telnet IP-ADDRESS 24007 - - If the server is accessible, your `telnet' command should connect and -block. If not you will see an error message such as `telnet: Unable to -connect to remote host: Connection refused'. 24007 is the default -GlusterFS port. If you have changed it, then use the corresponding port -instead. - - gf_log_init: failed to open logfile "/usr/var/log/glusterfs/glusterfs.log" - (Permission denied) - - You don't have permission to create files in the -`/usr/var/log/glusterfs' directory. Make sure you are running GlusterFS -as root. Alternatively, specify a different path for the log file using -the `--log-file' option (See *note Client::). - -6.2 FUSE error messages -======================= - -`modprobe fuse' fails with: "Unknown symbol in module, or unknown -parameter". - - If you are using fuse-2.6.x on Redhat Enterprise Linux Work Station 4 -and Advanced Server 4 with 2.6.9-42.ELlargesmp, 2.6.9-42.ELsmp, -2.6.9-42.EL kernels and get this error while loading FUSE kernel -module, you need to apply the following patch. - - For fuse-2.6.2: - -<http://ftp.gluster.com/pub/gluster/glusterfs/fuse/fuse-2.6.2-rhel-build.patch> - - For fuse-2.6.3: - -<http://ftp.gluster.com/pub/gluster/glusterfs/fuse/fuse-2.6.3-rhel-build.patch> - -6.3 AppArmour and GlusterFS -=========================== - -Under OpenSuSE GNU/Linux, the AppArmour security feature does not allow -GlusterFS to create temporary files or network socket connections even -while running as root. You will see error messages like `Unable to open -log file: Operation not permitted' or `Connection refused'. Disabling -AppArmour using YaST or properly configuring AppArmour to recognize -`glusterfsd' or `glusterfs'/`fusermount' should solve the problem. - -6.4 Reporting a bug -=================== - -If you encounter a bug in GlusterFS, please follow the below guidelines -when you report it to the mailing list. Be sure to report it! User -feedback is crucial to the health of the project and we value it highly. - -6.4.1 General instructions --------------------------- - -When running GlusterFS in a non-production environment, be sure to -build it with the following command: - - $ make CFLAGS='-g -O0 -DDEBUG' - - This includes debugging information which will be helpful in getting -backtraces (see below) and also disable optimization. Enabling -optimization can result in incorrect line numbers being reported to gdb. - -6.4.2 Volume specification files --------------------------------- - -Attach all relevant server and client spec files you were using when -you encountered the bug. Also tell us details of your setup, i.e., how -many clients and how many servers. - -6.4.3 Log files ---------------- - -Set the loglevel of your client and server programs to DEBUG (by -passing the -L DEBUG option) and attach the log files with your bug -report. Obviously, if only the client is failing (for example), you -only need to send us the client log file. - -6.4.4 Backtrace ---------------- - -If GlusterFS has encountered a segmentation fault or has crashed for -some other reason, include the backtrace with the bug report. You can -get the backtrace using the following procedure. - - Run the GlusterFS client or server inside gdb. - - $ gdb ./glusterfs - (gdb) set args -f client.spec -N -l/path/to/log/file -LDEBUG /mnt/point - (gdb) run - - Now when the process segfaults, you can get the backtrace by typing: - - (gdb) bt - - If the GlusterFS process has crashed and dumped a core file (you can -find this in / if running as a daemon and in the current directory -otherwise), you can do: - - $ gdb /path/to/glusterfs /path/to/core.<pid> - - and then get the backtrace. - - If the GlusterFS server or client seems to be hung, then you can get -the backtrace by attaching gdb to the process. First get the `PID' of -the process (using ps), and then do: - - $ gdb ./glusterfs <pid> - - Press Ctrl-C to interrupt the process and then generate the -backtrace. - -6.4.5 Reproducing the bug -------------------------- - -If the bug is reproducible, please include the steps necessary to do -so. If the bug is not reproducible, send us the bug report anyway. - -6.4.6 Other information ------------------------ - -If you think it is relevant, send us also the version of FUSE you're -using, the kernel version, platform. - - -File: user-guide.info, Node: GNU Free Documentation Licence, Next: Index, Prev: Troubleshooting, Up: Top - -Appendix A GNU Free Documentation Licence -***************************************** - - Version 1.2, November 2002 - - Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - 0. PREAMBLE - - The purpose of this License is to make a manual, textbook, or other - functional and useful document "free" in the sense of freedom: to - assure everyone the effective freedom to copy and redistribute it, - with or without modifying it, either commercially or - noncommercially. Secondarily, this License preserves for the - author and publisher a way to get credit for their work, while not - being considered responsible for modifications made by others. - - This License is a kind of "copyleft", which means that derivative - works of the document must themselves be free in the same sense. - It complements the GNU General Public License, which is a copyleft - license designed for free software. - - We have designed this License in order to use it for manuals for - free software, because free software needs free documentation: a - free program should come with manuals providing the same freedoms - that the software does. But this License is not limited to - software manuals; it can be used for any textual work, regardless - of subject matter or whether it is published as a printed book. - We recommend this License principally for works whose purpose is - instruction or reference. - - 1. APPLICABILITY AND DEFINITIONS - - This License applies to any manual or other work, in any medium, - that contains a notice placed by the copyright holder saying it - can be distributed under the terms of this License. Such a notice - grants a world-wide, royalty-free license, unlimited in duration, - to use that work under the conditions stated herein. The - "Document", below, refers to any such manual or work. Any member - of the public is a licensee, and is addressed as "you". You - accept the license if you copy, modify or distribute the work in a - way requiring permission under copyright law. - - A "Modified Version" of the Document means any work containing the - Document or a portion of it, either copied verbatim, or with - modifications and/or translated into another language. - - A "Secondary Section" is a named appendix or a front-matter section - of the Document that deals exclusively with the relationship of the - publishers or authors of the Document to the Document's overall - subject (or to related matters) and contains nothing that could - fall directly within that overall subject. (Thus, if the Document - is in part a textbook of mathematics, a Secondary Section may not - explain any mathematics.) The relationship could be a matter of - historical connection with the subject or with related matters, or - of legal, commercial, philosophical, ethical or political position - regarding them. - - The "Invariant Sections" are certain Secondary Sections whose - titles are designated, as being those of Invariant Sections, in - the notice that says that the Document is released under this - License. If a section does not fit the above definition of - Secondary then it is not allowed to be designated as Invariant. - The Document may contain zero Invariant Sections. If the Document - does not identify any Invariant Sections then there are none. - - The "Cover Texts" are certain short passages of text that are - listed, as Front-Cover Texts or Back-Cover Texts, in the notice - that says that the Document is released under this License. A - Front-Cover Text may be at most 5 words, and a Back-Cover Text may - be at most 25 words. - - A "Transparent" copy of the Document means a machine-readable copy, - represented in a format whose specification is available to the - general public, that is suitable for revising the document - straightforwardly with generic text editors or (for images - composed of pixels) generic paint programs or (for drawings) some - widely available drawing editor, and that is suitable for input to - text formatters or for automatic translation to a variety of - formats suitable for input to text formatters. A copy made in an - otherwise Transparent file format whose markup, or absence of - markup, has been arranged to thwart or discourage subsequent - modification by readers is not Transparent. An image format is - not Transparent if used for any substantial amount of text. A - copy that is not "Transparent" is called "Opaque". - - Examples of suitable formats for Transparent copies include plain - ASCII without markup, Texinfo input format, LaTeX input format, - SGML or XML using a publicly available DTD, and - standard-conforming simple HTML, PostScript or PDF designed for - human modification. Examples of transparent image formats include - PNG, XCF and JPG. Opaque formats include proprietary formats that - can be read and edited only by proprietary word processors, SGML or - XML for which the DTD and/or processing tools are not generally - available, and the machine-generated HTML, PostScript or PDF - produced by some word processors for output purposes only. - - The "Title Page" means, for a printed book, the title page itself, - plus such following pages as are needed to hold, legibly, the - material this License requires to appear in the title page. For - works in formats which do not have any title page as such, "Title - Page" means the text near the most prominent appearance of the - work's title, preceding the beginning of the body of the text. - - A section "Entitled XYZ" means a named subunit of the Document - whose title either is precisely XYZ or contains XYZ in parentheses - following text that translates XYZ in another language. (Here XYZ - stands for a specific section name mentioned below, such as - "Acknowledgements", "Dedications", "Endorsements", or "History".) - To "Preserve the Title" of such a section when you modify the - Document means that it remains a section "Entitled XYZ" according - to this definition. - - The Document may include Warranty Disclaimers next to the notice - which states that this License applies to the Document. These - Warranty Disclaimers are considered to be included by reference in - this License, but only as regards disclaiming warranties: any other - implication that these Warranty Disclaimers may have is void and - has no effect on the meaning of this License. - - 2. VERBATIM COPYING - - You may copy and distribute the Document in any medium, either - commercially or noncommercially, provided that this License, the - copyright notices, and the license notice saying this License - applies to the Document are reproduced in all copies, and that you - add no other conditions whatsoever to those of this License. You - may not use technical measures to obstruct or control the reading - or further copying of the copies you make or distribute. However, - you may accept compensation in exchange for copies. If you - distribute a large enough number of copies you must also follow - the conditions in section 3. - - You may also lend copies, under the same conditions stated above, - and you may publicly display copies. - - 3. COPYING IN QUANTITY - - If you publish printed copies (or copies in media that commonly - have printed covers) of the Document, numbering more than 100, and - the Document's license notice requires Cover Texts, you must - enclose the copies in covers that carry, clearly and legibly, all - these Cover Texts: Front-Cover Texts on the front cover, and - Back-Cover Texts on the back cover. Both covers must also clearly - and legibly identify you as the publisher of these copies. The - front cover must present the full title with all words of the - title equally prominent and visible. You may add other material - on the covers in addition. Copying with changes limited to the - covers, as long as they preserve the title of the Document and - satisfy these conditions, can be treated as verbatim copying in - other respects. - - If the required texts for either cover are too voluminous to fit - legibly, you should put the first ones listed (as many as fit - reasonably) on the actual cover, and continue the rest onto - adjacent pages. - - If you publish or distribute Opaque copies of the Document - numbering more than 100, you must either include a - machine-readable Transparent copy along with each Opaque copy, or - state in or with each Opaque copy a computer-network location from - which the general network-using public has access to download - using public-standard network protocols a complete Transparent - copy of the Document, free of added material. If you use the - latter option, you must take reasonably prudent steps, when you - begin distribution of Opaque copies in quantity, to ensure that - this Transparent copy will remain thus accessible at the stated - location until at least one year after the last time you - distribute an Opaque copy (directly or through your agents or - retailers) of that edition to the public. - - It is requested, but not required, that you contact the authors of - the Document well before redistributing any large number of - copies, to give them a chance to provide you with an updated - version of the Document. - - 4. MODIFICATIONS - - You may copy and distribute a Modified Version of the Document - under the conditions of sections 2 and 3 above, provided that you - release the Modified Version under precisely this License, with - the Modified Version filling the role of the Document, thus - licensing distribution and modification of the Modified Version to - whoever possesses a copy of it. In addition, you must do these - things in the Modified Version: - - A. Use in the Title Page (and on the covers, if any) a title - distinct from that of the Document, and from those of - previous versions (which should, if there were any, be listed - in the History section of the Document). You may use the - same title as a previous version if the original publisher of - that version gives permission. - - B. List on the Title Page, as authors, one or more persons or - entities responsible for authorship of the modifications in - the Modified Version, together with at least five of the - principal authors of the Document (all of its principal - authors, if it has fewer than five), unless they release you - from this requirement. - - C. State on the Title page the name of the publisher of the - Modified Version, as the publisher. - - D. Preserve all the copyright notices of the Document. - - E. Add an appropriate copyright notice for your modifications - adjacent to the other copyright notices. - - F. Include, immediately after the copyright notices, a license - notice giving the public permission to use the Modified - Version under the terms of this License, in the form shown in - the Addendum below. - - G. Preserve in that license notice the full lists of Invariant - Sections and required Cover Texts given in the Document's - license notice. - - H. Include an unaltered copy of this License. - - I. Preserve the section Entitled "History", Preserve its Title, - and add to it an item stating at least the title, year, new - authors, and publisher of the Modified Version as given on - the Title Page. If there is no section Entitled "History" in - the Document, create one stating the title, year, authors, - and publisher of the Document as given on its Title Page, - then add an item describing the Modified Version as stated in - the previous sentence. - - J. Preserve the network location, if any, given in the Document - for public access to a Transparent copy of the Document, and - likewise the network locations given in the Document for - previous versions it was based on. These may be placed in - the "History" section. You may omit a network location for a - work that was published at least four years before the - Document itself, or if the original publisher of the version - it refers to gives permission. - - K. For any section Entitled "Acknowledgements" or "Dedications", - Preserve the Title of the section, and preserve in the - section all the substance and tone of each of the contributor - acknowledgements and/or dedications given therein. - - L. Preserve all the Invariant Sections of the Document, - unaltered in their text and in their titles. Section numbers - or the equivalent are not considered part of the section - titles. - - M. Delete any section Entitled "Endorsements". Such a section - may not be included in the Modified Version. - - N. Do not retitle any existing section to be Entitled - "Endorsements" or to conflict in title with any Invariant - Section. - - O. Preserve any Warranty Disclaimers. - - If the Modified Version includes new front-matter sections or - appendices that qualify as Secondary Sections and contain no - material copied from the Document, you may at your option - designate some or all of these sections as invariant. To do this, - add their titles to the list of Invariant Sections in the Modified - Version's license notice. These titles must be distinct from any - other section titles. - - You may add a section Entitled "Endorsements", provided it contains - nothing but endorsements of your Modified Version by various - parties--for example, statements of peer review or that the text - has been approved by an organization as the authoritative - definition of a standard. - - You may add a passage of up to five words as a Front-Cover Text, - and a passage of up to 25 words as a Back-Cover Text, to the end - of the list of Cover Texts in the Modified Version. Only one - passage of Front-Cover Text and one of Back-Cover Text may be - added by (or through arrangements made by) any one entity. If the - Document already includes a cover text for the same cover, - previously added by you or by arrangement made by the same entity - you are acting on behalf of, you may not add another; but you may - replace the old one, on explicit permission from the previous - publisher that added the old one. - - The author(s) and publisher(s) of the Document do not by this - License give permission to use their names for publicity for or to - assert or imply endorsement of any Modified Version. - - 5. COMBINING DOCUMENTS - - You may combine the Document with other documents released under - this License, under the terms defined in section 4 above for - modified versions, provided that you include in the combination - all of the Invariant Sections of all of the original documents, - unmodified, and list them all as Invariant Sections of your - combined work in its license notice, and that you preserve all - their Warranty Disclaimers. - - The combined work need only contain one copy of this License, and - multiple identical Invariant Sections may be replaced with a single - copy. If there are multiple Invariant Sections with the same name - but different contents, make the title of each such section unique - by adding at the end of it, in parentheses, the name of the - original author or publisher of that section if known, or else a - unique number. Make the same adjustment to the section titles in - the list of Invariant Sections in the license notice of the - combined work. - - In the combination, you must combine any sections Entitled - "History" in the various original documents, forming one section - Entitled "History"; likewise combine any sections Entitled - "Acknowledgements", and any sections Entitled "Dedications". You - must delete all sections Entitled "Endorsements." - - 6. COLLECTIONS OF DOCUMENTS - - You may make a collection consisting of the Document and other - documents released under this License, and replace the individual - copies of this License in the various documents with a single copy - that is included in the collection, provided that you follow the - rules of this License for verbatim copying of each of the - documents in all other respects. - - You may extract a single document from such a collection, and - distribute it individually under this License, provided you insert - a copy of this License into the extracted document, and follow - this License in all other respects regarding verbatim copying of - that document. - - 7. AGGREGATION WITH INDEPENDENT WORKS - - A compilation of the Document or its derivatives with other - separate and independent documents or works, in or on a volume of - a storage or distribution medium, is called an "aggregate" if the - copyright resulting from the compilation is not used to limit the - legal rights of the compilation's users beyond what the individual - works permit. When the Document is included in an aggregate, this - License does not apply to the other works in the aggregate which - are not themselves derivative works of the Document. - - If the Cover Text requirement of section 3 is applicable to these - copies of the Document, then if the Document is less than one half - of the entire aggregate, the Document's Cover Texts may be placed - on covers that bracket the Document within the aggregate, or the - electronic equivalent of covers if the Document is in electronic - form. Otherwise they must appear on printed covers that bracket - the whole aggregate. - - 8. TRANSLATION - - Translation is considered a kind of modification, so you may - distribute translations of the Document under the terms of section - 4. Replacing Invariant Sections with translations requires special - permission from their copyright holders, but you may include - translations of some or all Invariant Sections in addition to the - original versions of these Invariant Sections. You may include a - translation of this License, and all the license notices in the - Document, and any Warranty Disclaimers, provided that you also - include the original English version of this License and the - original versions of those notices and disclaimers. In case of a - disagreement between the translation and the original version of - this License or a notice or disclaimer, the original version will - prevail. - - If a section in the Document is Entitled "Acknowledgements", - "Dedications", or "History", the requirement (section 4) to - Preserve its Title (section 1) will typically require changing the - actual title. - - 9. TERMINATION - - You may not copy, modify, sublicense, or distribute the Document - except as expressly provided for under this License. Any other - attempt to copy, modify, sublicense or distribute the Document is - void, and will automatically terminate your rights under this - License. However, parties who have received copies, or rights, - from you under this License will not have their licenses - terminated so long as such parties remain in full compliance. - - 10. FUTURE REVISIONS OF THIS LICENSE - - The Free Software Foundation may publish new, revised versions of - the GNU Free Documentation License from time to time. Such new - versions will be similar in spirit to the present version, but may - differ in detail to address new problems or concerns. See - `http://www.gnu.org/copyleft/'. - - Each version of the License is given a distinguishing version - number. If the Document specifies that a particular numbered - version of this License "or any later version" applies to it, you - have the option of following the terms and conditions either of - that specified version or of any later version that has been - published (not as a draft) by the Free Software Foundation. If - the Document does not specify a version number of this License, - you may choose any version ever published (not as a draft) by the - Free Software Foundation. - -A.0.1 ADDENDUM: How to use this License for your documents ----------------------------------------------------------- - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and license -notices just after the title page: - - Copyright (C) YEAR YOUR NAME. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.2 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. A copy of the license is included in the section entitled ``GNU - Free Documentation License''. - - If you have Invariant Sections, Front-Cover Texts and Back-Cover -Texts, replace the "with...Texts." line with this: - - with the Invariant Sections being LIST THEIR TITLES, with - the Front-Cover Texts being LIST, and with the Back-Cover Texts - being LIST. - - If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation. - - If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, to -permit their use in free software. - - -File: user-guide.info, Node: Index, Prev: GNU Free Documentation Licence, Up: Top - -Index -***** - - -* Menu: - -* alu (scheduler): Unify. (line 49) -* AppArmour: Troubleshooting. (line 96) -* arch: Getting GlusterFS. (line 6) -* booster: Booster. (line 6) -* commercial support: Introduction. (line 36) -* DNS round robin: Transport modules. (line 29) -* fcntl: POSIX Locks. (line 6) -* FDL, GNU Free Documentation License: GNU Free Documentation Licence. - (line 6) -* fixed-id (translator): Fixed ID. (line 6) -* GlusterFS client: Client. (line 6) -* GlusterFS mailing list: Introduction. (line 28) -* GlusterFS server: Server. (line 6) -* infiniband transport: Transport modules. (line 58) -* InfiniBand, installation: Pre requisites. (line 51) -* io-cache (translator): IO Cache. (line 6) -* io-threads (translator): IO Threads. (line 6) -* IRC channel, #gluster: Introduction. (line 31) -* libibverbs: Pre requisites. (line 51) -* namespace: Unify. (line 207) -* nufa (scheduler): Unify. (line 175) -* OpenSuSE: Troubleshooting. (line 96) -* posix-locks (translator): POSIX Locks. (line 6) -* random (scheduler): Unify. (line 159) -* read-ahead (translator): Read Ahead. (line 6) -* record locking: POSIX Locks. (line 6) -* Redhat Enterprise Linux: Troubleshooting. (line 78) -* Replicate: Replicate. (line 6) -* rot-13 (translator): ROT-13. (line 6) -* rr (scheduler): Unify. (line 138) -* scheduler (unify): Unify. (line 6) -* self heal (replicate): Replicate. (line 46) -* self heal (unify): Unify. (line 223) -* stripe (translator): Stripe. (line 6) -* trace (translator): Trace. (line 6) -* unify (translator): Unify. (line 6) -* unify invariants: Unify. (line 16) -* write-behind (translator): Write Behind. (line 6) -* Gluster, Inc.: Introduction. (line 36) - - - -Tag Table: -Node: Top704 -Node: Acknowledgements2304 -Node: Introduction3214 -Node: Installation and Invocation4649 -Node: Pre requisites4933 -Node: Getting GlusterFS7023 -Ref: Getting GlusterFS-Footnote-17809 -Node: Building7857 -Node: Running GlusterFS9559 -Node: Server9770 -Node: Client11358 -Node: A Tutorial Introduction13564 -Node: Concepts17101 -Node: Filesystems in Userspace17316 -Node: Translator18457 -Node: Volume specification file21160 -Node: Translators23632 -Node: Storage Translators24201 -Ref: Storage Translators-Footnote-125008 -Node: POSIX25142 -Node: BDB25765 -Node: Client and Server Translators26822 -Node: Transport modules27298 -Node: Client protocol31445 -Node: Server protocol32384 -Node: Clustering Translators33373 -Node: Unify34260 -Ref: Unify-Footnote-143859 -Node: Replicate43951 -Node: Stripe49006 -Node: Performance Translators50164 -Node: Read Ahead50438 -Node: Write Behind52170 -Node: IO Threads53579 -Node: IO Cache54367 -Node: Booster55691 -Node: Features Translators57105 -Node: POSIX Locks57333 -Node: Fixed ID58650 -Node: Miscellaneous Translators59136 -Node: ROT-1359334 -Node: Trace60013 -Node: Usage Scenarios61282 -Ref: Usage Scenarios-Footnote-167215 -Node: Troubleshooting67290 -Node: GNU Free Documentation Licence73638 -Node: Index96087 - -End Tag Table diff --git a/doc/legacy/user-guide.pdf b/doc/legacy/user-guide.pdf Binary files differdeleted file mode 100644 index ed7bd2a9907..00000000000 --- a/doc/legacy/user-guide.pdf +++ /dev/null diff --git a/doc/legacy/user-guide.texi b/doc/legacy/user-guide.texi deleted file mode 100644 index 31ff9cf304e..00000000000 --- a/doc/legacy/user-guide.texi +++ /dev/null @@ -1,2246 +0,0 @@ -\input texinfo -@setfilename user-guide.info -@settitle GlusterFS 2.0 User Guide -@afourpaper - -@direntry -* GlusterFS: (user-guide). GlusterFS distributed filesystem user guide -@end direntry - -@copying -This is the user manual for GlusterFS 2.0. - -Copyright @copyright{} 2007-2011 @email{@b{Gluster}} , Inc. Permission is granted to -copy, distribute and/or modify this document under the terms of the -@acronym{GNU} Free Documentation License, Version 1.2 or any later -version published by the Free Software Foundation; with no Invariant -Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the -license is included in the chapter entitled ``@acronym{GNU} Free -Documentation License''. -@end copying - -@titlepage -@title GlusterFS 2.0 User Guide [DRAFT] -@subtitle January 15, 2008 -@author http://gluster.org/core-team.php -@author @email{@b{Gluster}} -@page -@vskip 0pt plus 1filll -@insertcopying -@end titlepage - -@c Info stuff -@ifnottex -@node Top -@top GlusterFS 2.0 User Guide - -@insertcopying -@menu -* Acknowledgements:: -* Introduction:: -* Installation and Invocation:: -* Concepts:: -* Translators:: -* Usage Scenarios:: -* Troubleshooting:: -* GNU Free Documentation Licence:: -* Index:: - -@detailmenu - --- The Detailed Node Listing --- - -Installation and Invocation - -* Pre requisites:: -* Getting GlusterFS:: -* Building:: -* Running GlusterFS:: -* A Tutorial Introduction:: - -Running GlusterFS - -* Server:: -* Client:: - -Concepts - -* Filesystems in Userspace:: -* Translator:: -* Volume specification file:: - -Translators - -* Storage Translators:: -* Client and Server Translators:: -* Clustering Translators:: -* Performance Translators:: -* Features Translators:: - -Storage Translators - -* POSIX:: - -Client and Server Translators - -* Transport modules:: -* Client protocol:: -* Server protocol:: - -Clustering Translators - -* Unify:: -* Replicate:: -* Stripe:: - -Performance Translators - -* Read Ahead:: -* Write Behind:: -* IO Threads:: -* IO Cache:: - -Features Translators - -* POSIX Locks:: -* Fixed ID:: - -Miscellaneous Translators - -* ROT-13:: -* Trace:: - -@end detailmenu -@end menu - -@end ifnottex -@c Info stuff end - -@contents - -@node Acknowledgements -@unnumbered Acknowledgements -GlusterFS continues to be a wonderful and enriching experience for all -of us involved. - -GlusterFS development would not have been possible at this pace if -not for our enthusiastic users. People from around the world have -helped us with bug reports, performance numbers, and feature suggestions. -A huge thanks to them all. - -Matthew Paine - for RPMs & general enthu - -Leonardo Rodrigues de Mello - for DEBs - -Julian Perez & Adam D'Auria - for multi-server tutorial - -Paul England - for HA spec - -Brent Nelson - for many bug reports - -Jacques Mattheij - for Europe mirror. - -Patrick Negri - for TCP non-blocking connect. -@flushright -http://gluster.org/core-team.php (@email{list-hacking@@gluster.com}) -@email{@b{Gluster}} -@end flushright - -@node Introduction -@chapter Introduction - -GlusterFS is a distributed filesystem. It works at the file level, -not block level. - -A network filesystem is one which allows us to access remote files. A -distributed filesystem is one that stores data on multiple machines -and makes them all appear to be a part of the same filesystem. - -Need for distributed filesystems - -@itemize @bullet -@item Scalability: A distributed filesystem allows us to store more data than what can be stored on a single machine. - -@item Redundancy: We might want to replicate crucial data on to several machines. - -@item Uniform access: One can mount a remote volume (for example your home directory) from any machine and access the same data. -@end itemize - -@section Contacting us -You can reach us through the mailing list @strong{gluster-devel} -(@email{gluster-devel@@nongnu.org}). -@cindex GlusterFS mailing list - -You can also find many of the developers on @acronym{IRC}, on the @code{#gluster} -channel on Freenode (@indicateurl{irc.freenode.net}). -@cindex IRC channel, #gluster - -The GlusterFS documentation wiki is also useful: @* -@indicateurl{http://gluster.org/docs/index.php/GlusterFS} - -For commercial support, you can contact @email{@b{Gluster}} at: -@cindex commercial support -@cindex Gluster, Inc. - -@display -3194 Winding Vista Common -Fremont, CA 94539 -USA. - -Phone: +1 (510) 354 6801 -Toll free: +1 (888) 813 6309 -Fax: +1 (510) 372 0604 -@end display - -You can also email us at @email{support@@gluster.com}. - -@node Installation and Invocation -@chapter Installation and Invocation - -@menu -* Pre requisites:: -* Getting GlusterFS:: -* Building:: -* Running GlusterFS:: -* A Tutorial Introduction:: -@end menu - -@node Pre requisites -@section Pre requisites - -Before installing GlusterFS make sure you have the -following components installed. - -@subsection @acronym{FUSE} -GlusterFS has now built-in support for the @acronym{FUSE} protocol. -You need a kernel with @acronym{FUSE} support to mount GlusterFS. -You do not need the @acronym{FUSE} package (library and utilities), -but be aware of the following issues: - -@itemize -@item If you want unprivileged users to be able to mount GlusterFS filesystems, -you need a recent version of the @command{fusermount} utility. You already have -it if you have @acronym{FUSE} version 2.7.0 or higher installed; if that's not -the case, one will be compiled along with GlusterFS if you pass -@command{--enable-fusermount} to the @command{configure} script. @item You -need to ensure @acronym{FUSE} support is configured properly on your system. In -details: -@itemize -@item If your kernel has @acronym{FUSE} as a loadable module, make sure it's -loaded. -@item Create @command{/dev/fuse} (major 10, minor 229) either by means of udev -rules or by hand. -@item Optionally, if you want runtime control over your @acronym{FUSE} mounts, -mount the fusectl auxiliary filesystem: - -@example -# mount -t fusectl none /sys/fs/fuse/connections -@end example -@end itemize - -The @acronym{FUSE} packages shipped by the various distributions usually take care -about these things, so the easiest way to get the above tasks handled is still -installing the @acronym{FUSE} package(s). -@end itemize - -To get the best performance from GlusterFS,it is recommended that you use -our patched version of the @acronym{FUSE} kernel module. See Patched FUSE for details. - -@subsection Patched FUSE - -The GlusterFS project maintains a patched version of @acronym{FUSE} meant to be used -with GlusterFS. The patches increase GlusterFS performance. It is recommended that -all users use the patched @acronym{FUSE}. - -The patched @acronym{FUSE} tarball can be downloaded from: - -@indicateurl{ftp://ftp.gluster.com/pub/gluster/glusterfs/fuse/} - -The specific changes made to @acronym{FUSE} are: - -@itemize -@item The communication channel size between @acronym{FUSE} kernel module and GlusterFS has been increased to 1MB, permitting large reads and writes to be sent in bigger chunks. - -@item The kernel's read-ahead boundary has been extended up to 1MB. - -@item Block size returned in the @command{stat()}/@command{fstat()} calls tuned to 1MB, to make cp and similar commands perform I/O using that block size. - -@item @command{flock()} locking support has been added (although some rework in GlusterFS is needed for perfect compliance). -@end itemize - -@subsection libibverbs (optional) -@cindex InfiniBand, installation -@cindex libibverbs -This is only needed if you want GlusterFS to use InfiniBand as the -interconnect mechanism between server and client. You can get it from: - -@indicateurl{http://www.openfabrics.org/downloads.htm}. - -@subsection Bison and Flex -These should be already installed on most Linux systems. If not, use your distribution's -normal software installation procedures to install them. Make sure you install the -relevant developer packages also. - -@node Getting GlusterFS -@section Getting GlusterFS -@cindex arch -There are many ways to get hold of GlusterFS. For a production deployment, -the recommended method is to download the latest release tarball. -Release tarballs are available at: @indicateurl{http://gluster.org/download.php}. - -If you want the bleeding edge development source, you can get them -from the Git -@footnote{@indicateurl{http://git-scm.com}} -repository. First you must install Git itself. Then -you can check out the source - -@example -$ git clone git://git.sv.gnu.org/gluster.git glusterfs -@end example - -@node Building -@section Building -You can skip this section if you're installing from @acronym{RPM}s -or @acronym{DEB}s. - -GlusterFS uses the Autotools mechanism to build. As such, the procedure -is straight-forward. First, change into the GlusterFS source directory. - -@example -$ cd glusterfs-<version> -@end example - -If you checked out the source from the Arch repository, you'll need -to run @command{./autogen.sh} first. Note that you'll need to have -Autoconf and Automake installed for this. - -Run @command{configure}. - -@example -$ ./configure -@end example - -The configure script accepts the following options: - -@cartouche -@table @code - -@item --disable-ibverbs -Disable the InfiniBand transport mechanism. - -@item --disable-fuse-client -Disable the @acronym{FUSE} client. - -@item --disable-server -Disable building of the GlusterFS server. - -@item --disable-bdb -Disable building of Berkeley DB based storage translator. - -@item --disable-mod_glusterfs -Disable building of Apache/lighttpd glusterfs plugins. - -@item --disable-epoll -Use poll instead of epoll. - -@item --disable-libglusterfsclient -Disable building of libglusterfsclient - -@item --enable-fusermount -Build fusermount - -@end table -@end cartouche - -Build and install GlusterFS. - -@example -# make install -@end example - -The binaries (@command{glusterfsd} and @command{glusterfs}) will be by -default installed in @command{/usr/local/sbin/}. Translator, -scheduler, and transport shared libraries will be installed in -@command{/usr/local/lib/glusterfs/<version>/}. Sample volume -specification files will be in @command{/usr/local/etc/glusterfs/}. -This document itself can be found in -@command{/usr/local/share/doc/glusterfs/}. If you passed the @command{--prefix} -argument to the configure script, then replace @command{/usr/local} in the preceding -paths with the prefix. - -@node Running GlusterFS -@section Running GlusterFS - -@menu -* Server:: -* Client:: -@end menu - -@node Server -@subsection Server -@cindex GlusterFS server - -The GlusterFS server is necessary to export storage volumes to remote clients -(See @ref{Server protocol} for more info). This section documents the invocation -of the GlusterFS server program and all the command-line options accepted by it. - -@cartouche -@table @code -Basic Options -@item -f, --volfile=<path> - Use the volume file as the volume specification. - -@item -s, --volfile-server=<hostname> - Server to get volume file from. This option overrides --volfile option. - -@item -l, --log-file=<path> - Specify the path for the log file. - -@item -L, --log-level=<level> - Set the log level for the server. Log level should be one of @acronym{DEBUG}, -@acronym{WARNING}, @acronym{ERROR}, @acronym{CRITICAL}, or @acronym{NONE}. - -Advanced Options -@item --debug - Run in debug mode. This option sets --no-daemon, --log-level to DEBUG and - --log-file to console. - -@item -N, --no-daemon - Run glusterfsd as a foreground process. - -@item -p, --pid-file=<path> - Path for the @acronym{PID} file. - -@item --volfile-id=<key> - 'key' of the volfile to be fetched from server. - -@item --volfile-server-port=<port-number> - Listening port number of volfile server. - -@item --volfile-server-transport=[tcp|ib-verbs] - Transport type to get volfile from server. [default: @command{tcp}] - -@item --xlator-options=<volume-name.option=value> - Add/override a translator option for a volume with specified value. - -Miscellaneous Options -@item -?, --help - Show this help text. - -@item --usage - Display a short usage message. - -@item -V, --version - Show version information. -@end table -@end cartouche - -@node Client -@subsection Client -@cindex GlusterFS client - -The GlusterFS client process is necessary to access remote storage volumes and -mount them locally using @acronym{FUSE}. This section documents the invocation of the -client process and all its command-line arguments. - -@example - # glusterfs [options] <mountpoint> -@end example - -The @command{mountpoint} is the directory where you want the GlusterFS -filesystem to appear. Example: - -@example - # glusterfs -f /usr/local/etc/glusterfs-client.vol /mnt -@end example - -The command-line options are detailed below. - -@tex -\vfill -@end tex -@page - -@cartouche -@table @code - -Basic Options -@item -f, --volfile=<path> - Use the volume file as the volume specification. - -@item -s, --volfile-server=<hostname> - Server to get volume file from. This option overrides --volfile option. - -@item -l, --log-file=<path> - Specify the path for the log file. - -@item -L, --log-level=<level> - Set the log level for the server. Log level should be one of @acronym{DEBUG}, -@acronym{WARNING}, @acronym{ERROR}, @acronym{CRITICAL}, or @acronym{NONE}. - -Advanced Options -@item --debug - Run in debug mode. This option sets --no-daemon, --log-level to DEBUG and - --log-file to console. - -@item -N, --no-daemon - Run @command{glusterfs} as a foreground process. - -@item -p, --pid-file=<path> - Path for the @acronym{PID} file. - -@item --volfile-id=<key> - 'key' of the volfile to be fetched from server. - -@item --volfile-server-port=<port-number> - Listening port number of volfile server. - -@item --volfile-server-transport=[tcp|ib-verbs] - Transport type to get volfile from server. [default: @command{tcp}] - -@item --xlator-options=<volume-name.option=value> - Add/override a translator option for a volume with specified value. - -@item --volume-name=<volume name> - Volume name in client spec to use. Defaults to the root volume. - -@acronym{FUSE} Options -@item --attribute-timeout=<n> - Attribute timeout for inodes in the kernel, in seconds. Defaults to 1 second. - -@item --disable-direct-io-mode - Disable direct @acronym{I/O} mode in @acronym{FUSE} kernel module. This is set - automatically if kernel supports big writes (>= 2.6.26). - -@item -e, --entry-timeout=<n> - Entry timeout for directory entries in the kernel, in seconds. - Defaults to 1 second. - -Missellaneous Options -@item -?, --help - Show this help information. - -@item -V, --version - Show version information. -@end table -@end cartouche - -@node A Tutorial Introduction -@section A Tutorial Introduction - -This section will show you how to quickly get GlusterFS up and running. We'll -configure GlusterFS as a simple network filesystem, with one server and one client. -In this mode of usage, GlusterFS can serve as a replacement for NFS. - -We'll make use of two machines; call them @emph{server} and -@emph{client} (If you don't want to setup two machines, just run -everything that follows on the same machine). In the examples that -follow, the shell prompts will use these names to clarify the machine -on which the command is being run. For example, a command that should -be run on the server will be shown with the prompt: - -@example -[root@@server]# -@end example - -Our goal is to make a directory on the @emph{server} (say, @command{/export}) -accessible to the @emph{client}. - -First of all, get GlusterFS installed on both the machines, as described in the -previous sections. Make sure you have the @acronym{FUSE} kernel module loaded. You -can ensure this by running: - -@example -[root@@server]# modprobe fuse -@end example - -Before we can run the GlusterFS client or server programs, we need to write -two files called @emph{volume specifications} (equivalently referred to as @emph{volfiles}). -The volfile describes the @emph{translator tree} on a node. The next chapter will -explain the concepts of `translator' and `volume specification' in detail. For now, -just assume that the volfile is like an NFS @command{/etc/export} file. - -On the server, create a text file somewhere (we'll assume the path -@command{/tmp/glusterfsd.vol}) with the following contents. - -@cartouche -@example -volume colon-o - type storage/posix - option directory /export -end-volume - -volume server - type protocol/server - subvolumes colon-o - option transport-type tcp - option auth.addr.colon-o.allow * -end-volume -@end example -@end cartouche - -A brief explanation of the file's contents. The first section defines a storage -volume, named ``colon-o'' (the volume names are arbitrary), which exports the -@command{/export} directory. The second section defines options for the translator -which will make the storage volume accessible remotely. It specifies @command{colon-o} as -a subvolume. This defines the @emph{translator tree}, about which more will be said -in the next chapter. The two options specify that the @acronym{TCP} protocol is to be -used (as opposed to InfiniBand, for example), and that access to the storage volume -is to be provided to clients with any @acronym{IP} address at all. If you wanted to -restrict access to this server to only your subnet for example, you'd specify -something like @command{192.168.1.*} in the second option line. - -On the client machine, create the following text file (again, we'll assume -the path to be @command{/tmp/glusterfs-client.vol}). Replace -@emph{server-ip-address} with the @acronym{IP} address of your server machine. If you -are doing all this on a single machine, use @command{127.0.0.1}. - -@cartouche -@example -volume client - type protocol/client - option transport-type tcp - option remote-host @emph{server-ip-address} - option remote-subvolume colon-o -end-volume -@end example -@end cartouche - -Now we need to start both the server and client programs. To start the server: - -@example -[root@@server]# glusterfsd -f /tmp/glusterfs-server.vol -@end example - -To start the client: - -@example -[root@@client]# glusterfs -f /tmp/glusterfs-client.vol /mnt/glusterfs -@end example - -You should now be able to see the files under the server's @command{/export} directory -in the @command{/mnt/glusterfs} directory on the client. That's it; GlusterFS is now -working as a network file system. - -@node Concepts -@chapter Concepts - -@menu -* Filesystems in Userspace:: -* Translator:: -* Volume specification file:: -@end menu - -@node Filesystems in Userspace -@section Filesystems in Userspace - -A filesystem is usually implemented in kernel space. Kernel space -development is much harder than userspace development. @acronym{FUSE} -is a kernel module/library that allows us to write a filesystem -completely in userspace. - -@acronym{FUSE} consists of a kernel module which interacts with the userspace -implementation using a device file @code{/dev/fuse}. When a process -makes a syscall on a @acronym{FUSE} filesystem, @acronym{VFS} hands the request to the -@acronym{FUSE} module, which writes the request to @code{/dev/fuse}. The -userspace implementation polls @code{/dev/fuse}, and when a request arrives, -processes it and writes the result back to @code{/dev/fuse}. The kernel then -reads from the device file and returns the result to the user process. - -In case of GlusterFS, the userspace program is the GlusterFS client. -The control flow is shown in the diagram below. The GlusterFS client -services the request by sending it to the server, which in turn -hands it to the local @acronym{POSIX} filesystem. - -@center @image{fuse,44pc,,,.pdf} -@center Fig 1. Control flow in GlusterFS - -@node Translator -@section Translator - -The @emph{translator} is the most important concept in GlusterFS. In -fact, GlusterFS is nothing but a collection of translators working -together, forming a translator @emph{tree}. - -The idea of a translator is perhaps best understood using an -analogy. Consider the @acronym{VFS} in the Linux kernel. The -@acronym{VFS} abstracts the various filesystem implementations (such -as @acronym{EXT3}, ReiserFS, @acronym{XFS}, etc.) supported by the -kernel. When an application calls the kernel to perform an operation -on a file, the kernel passes the request on to the appropriate -filesystem implementation. - -For example, let's say there are two partitions on a Linux machine: -@command{/}, which is an @acronym{EXT3} partition, and @command{/usr}, -which is a ReiserFS partition. Now if an application wants to open a -file called, say, @command{/etc/fstab}, then the kernel will -internally pass the request to the @acronym{EXT3} implementation. If -on the other hand, an application wants to read a file called -@command{/usr/src/linux/CREDITS}, then the kernel will call upon the -ReiserFS implementation to do the job. - -The ``filesystem implementation'' objects are analogous to GlusterFS -translators. A GlusterFS translator implements all the filesystem -operations. Whereas in @acronym{VFS} there is a two-level tree (with -the kernel at the root and all the filesystem implementation as its -children), in GlusterFS there exists a more elaborate tree structure. - -We can now define translators more precisely. A GlusterFS translator -is a shared object (@command{.so}) that implements every filesystem -call. GlusterFS translators can be arranged in an arbitrary tree -structure (subject to constraints imposed by the translators). When -GlusterFS receives a filesystem call, it passes it on to the -translator at the root of the translator tree. The root translator may -in turn pass it on to any or all of its children, and so on, until the -leaf nodes are reached. The result of a filesystem call is -communicated in the reverse fashion, from the leaf nodes up to the -root node, and then on to the application. - -So what might a translator tree look like? - -@tex -\vfill -@end tex -@page - -@center @image{xlator,44pc,,,.pdf} -@center Fig 2. A sample translator tree - -The diagram depicts three servers and one GlusterFS client. It is important -to note that conceptually, the translator tree spans machine boundaries. -Thus, the client machine in the diagram, @command{10.0.0.1}, can access -the aggregated storage of the filesystems on the server machines @command{10.0.0.2}, -@command{10.0.0.3}, and @command{10.0.0.4}. The translator diagram will make more -sense once you've read the next chapter and understood the functions of the -various translators. - -@node Volume specification file -@section Volume specification file -The volume specification file describes the translator tree for both the -server and client programs. - -A volume specification file is a sequence of volume definitions. -The syntax of a volume definition is explained below: - -@cartouche -@example -@strong{volume} @emph{volume-name} - @strong{type} @emph{translator-name} - @strong{option} @emph{option-name} @emph{option-value} - @dots{} - @strong{subvolumes} @emph{subvolume1} @emph{subvolume2} @dots{} -@strong{end-volume} -@end example - -@dots{} -@end cartouche - -@table @asis -@item @emph{volume-name} - An identifier for the volume. This is just a human-readable name, -and can contain any alphanumeric character. For instance, ``storage-1'', ``colon-o'', -or ``forty-two''. - -@item @emph{translator-name} - Name of one of the available translators. Example: @command{protocol/client}, -@command{cluster/unify}. - -@item @emph{option-name} - Name of a valid option for the translator. - -@item @emph{option-value} - Value for the option. Everything following the ``option'' keyword to the end of the -line is considered the value; it is up to the translator to parse it. - -@item @emph{subvolume1}, @emph{subvolume2}, @dots{} - Volume names of sub-volumes. The sub-volumes must already have been defined earlier -in the file. -@end table - -There are a few rules you must follow when writing a volume specification file: - -@itemize -@item Everything following a `@command{#}' is considered a comment and is ignored. Blank lines are also ignored. -@item All names and keywords are case-sensitive. -@item The order of options inside a volume definition does not matter. -@item An option value may not span multiple lines. -@item If an option is not specified, it will assume its default value. -@item A sub-volume must have already been defined before it can be referenced. This means you have to write the specification file ``bottom-up'', starting from the leaf nodes of the translator tree and moving up to the root. -@end itemize - -A simple example volume specification file is shown below: - -@cartouche -@example -# This is a comment line -volume client - type protocol/client - option transport-type tcp - option remote-host localhost # Also a comment - option remote-subvolume brick -# The subvolumes line may be absent -end-volume - -volume iot - type performance/io-threads - option thread-count 4 - subvolumes client -end-volume - -volume wb - type performance/write-behind - subvolumes iot -end-volume -@end example -@end cartouche - -@node Translators -@chapter Translators - -@menu -* Storage Translators:: -* Client and Server Translators:: -* Clustering Translators:: -* Performance Translators:: -* Features Translators:: -* Miscellaneous Translators:: -@end menu - -This chapter documents all the available GlusterFS translators in detail. -Each translator section will show its name (for example, @command{cluster/unify}), -briefly describe its purpose and workings, and list every option accepted by -that translator and their meaning. - -@node Storage Translators -@section Storage Translators - -The storage translators form the ``backend'' for GlusterFS. Currently, -the only available storage translator is the @acronym{POSIX} -translator, which stores files on a normal @acronym{POSIX} -filesystem. A pleasant consequence of this is that your data will -still be accessible if GlusterFS crashes or cannot be started. - -Other storage backends are planned for the future. One of the possibilities is an -Amazon S3 translator. Amazon S3 is an unlimited online storage service accessible -through a web services @acronym{API}. The S3 translator will allow you to access -the storage as a normal @acronym{POSIX} filesystem. -@footnote{Some more discussion about this can be found at: - -http://developer.amazonwebservices.com/connect/message.jspa?messageID=52873} - -@menu -* POSIX:: -* BDB:: -@end menu - -@node POSIX -@subsection POSIX -@example -type storage/posix -@end example - -The @command{posix} translator uses a normal @acronym{POSIX} -filesystem as its ``backend'' to actually store files and -directories. This can be any filesystem that supports extended -attributes (@acronym{EXT3}, ReiserFS, @acronym{XFS}, ...). Extended -attributes are used by some translators to store metadata, for -example, by the replicate and stripe translators. See -@ref{Replicate} and @ref{Stripe}, respectively for details. - -@cartouche -@table @code -@item directory <path> -The directory on the local filesystem which is to be used for storage. -@end table -@end cartouche - -@node BDB -@subsection BDB -@example -type storage/bdb -@end example - -The @command{BDB} translator uses a @acronym{Berkeley DB} database as its -``backend'' to actually store files as key-value pair in the database and -directories as regular @acronym{POSIX} directories. Note that @acronym{BDB} -does not provide extended attribute support for regular files. Do not use -@acronym{BDB} as storage translator while using any translator that demands -extended attributes on ``backend''. - -@cartouche -@table @code -@item directory <path> -The directory on the local filesystem which is to be used for storage. -@item mode [cache|persistent] (cache) -When @acronym{BDB} is run in @command{cache} mode, recovery of back-end is not completely -guaranteed. @command{persistent} guarantees that @acronym{BDB} can recover back-end from -@acronym{Berkeley DB} even if GlusterFS crashes. -@item errfile <path> -The path of the file to be used as @command{errfile} for @acronym{Berkeley DB} to report -detailed error messages, if any. Note that all the contents of this file will be written -by @acronym{Berkeley DB}, not GlusterFS. -@item logdir <path> - - -@end table -@end cartouche - -@node Client and Server Translators, Clustering Translators, Storage Translators, Translators -@section Client and Server Translators - -The client and server translator enable GlusterFS to export a -translator tree over the network or access a remote GlusterFS -server. These two translators implement GlusterFS's network protocol. - -@menu -* Transport modules:: -* Client protocol:: -* Server protocol:: -@end menu - -@node Transport modules -@subsection Transport modules -The client and server translators are capable of using any of the -pluggable transport modules. Currently available transport modules are -@command{tcp}, which uses a @acronym{TCP} connection between client -and server to communicate; @command{ib-sdp}, which uses a -@acronym{TCP} connection over InfiniBand, and @command{ibverbs}, which -uses high-speed InfiniBand connections. - -Each transport module comes in two different versions, one to be used on -the server side and the other on the client side. - -@subsubsection TCP - -The @acronym{TCP} transport module uses a @acronym{TCP/IP} connection between -the server and the client. - -@example - option transport-type tcp -@end example - -The @acronym{TCP} client module accepts the following options: - -@cartouche -@table @code -@item non-blocking-connect [no|off|on|yes] (on) -Whether to make the connection attempt asynchronous. -@item remote-port <n> (24007) -Server port to connect to. -@cindex DNS round robin -@item remote-host <hostname> * -Hostname or @acronym{IP} address of the server. If the host name resolves to -multiple IP addresses, all of them will be tried in a round-robin fashion. This -feature can be used to implement fail-over. -@end table -@end cartouche - -The @acronym{TCP} server module accepts the following options: - -@cartouche -@table @code -@item bind-address <address> (0.0.0.0) -The local interface on which the server should listen to requests. Default is to -listen on all interfaces. -@item listen-port <n> (24007) -The local port to listen on. -@end table -@end cartouche - -@subsubsection IB-SDP -@example - option transport-type ib-sdp -@end example - -kernel implements socket interface for ib hardware. SDP is over ib-verbs. -This module accepts the same options as @command{tcp} - -@subsubsection ibverbs - -@example - option transport-type tcp -@end example - -@cindex infiniband transport - -InfiniBand is a scalable switched fabric interconnect mechanism -primarily used in high-performance computing. InfiniBand can deliver -data throughput of the order of 10 Gbit/s, with latencies of 4-5 ms. - -The @command{ib-verbs} transport accesses the InfiniBand hardware through -the ``verbs'' @acronym{API}, which is the lowest level of software access possible -and which gives the highest performance. On InfiniBand hardware, it is always -best to use @command{ib-verbs}. Use @command{ib-sdp} only if you cannot get -@command{ib-verbs} working for some reason. - -The @command{ib-verbs} client module accepts the following options: - -@cartouche -@table @code -@item non-blocking-connect [no|off|on|yes] (on) -Whether to make the connection attempt asynchronous. -@item remote-port <n> (24007) -Server port to connect to. -@cindex DNS round robin -@item remote-host <hostname> * -Hostname or @acronym{IP} address of the server. If the host name resolves to -multiple IP addresses, all of them will be tried in a round-robin fashion. This -feature can be used to implement fail-over. -@end table -@end cartouche - -The @command{ib-verbs} server module accepts the following options: - -@cartouche -@table @code -@item bind-address <address> (0.0.0.0) -The local interface on which the server should listen to requests. Default is to -listen on all interfaces. -@item listen-port <n> (24007) -The local port to listen on. -@end table -@end cartouche - -The following options are common to both the client and server modules: - -If you are familiar with InfiniBand jargon, -the mode is used by GlusterFS is ``reliable connection-oriented channel transfer''. - -@cartouche -@table @code -@item ib-verbs-work-request-send-count <n> (64) -Length of the send queue in datagrams. [Reason to increase/decrease?] - -@item ib-verbs-work-request-recv-count <n> (64) -Length of the receive queue in datagrams. [Reason to increase/decrease?] - -@item ib-verbs-work-request-send-size <size> (128KB) -Size of each datagram that is sent. [Reason to increase/decrease?] - -@item ib-verbs-work-request-recv-size <size> (128KB) -Size of each datagram that is received. [Reason to increase/decrease?] - -@item ib-verbs-port <n> (1) -Port number for ib-verbs. - -@item ib-verbs-mtu [256|512|1024|2048|4096] (2048) -The Maximum Transmission Unit [Reason to increase/decrease?] - -@item ib-verbs-device-name <device-name> (first device in the list) -InfiniBand device to be used. -@end table -@end cartouche - -For maximum performance, you should ensure that the send/receive counts on both -the client and server are the same. - -ib-verbs is preferred over ib-sdp. - -@node Client protocol -@subsection Client -@example -type procotol/client -@end example - -The client translator enables the GlusterFS client to access a remote server's -translator tree. - -@cartouche -@table @code - -@item transport-type [tcp,ib-sdp,ib-verbs] (tcp) -The transport type to use. You should use the client versions of all the -transport modules (@command{tcp}, @command{ib-sdp}, -@command{ib-verbs}). -@item remote-subvolume <volume_name> * -The name of the volume on the remote host to attach to. Note that -this is @emph{not} the name of the @command{protocol/server} volume on the -server. It should be any volume under the server. -@item transport-timeout <n> (120- seconds) -Inactivity timeout. If a reply is expected and no activity takes place -on the connection within this time, the transport connection will be -broken, and a new connection will be attempted. -@end table -@end cartouche - -@node Server protocol -@subsection Server -@example -type protocol/server -@end example - -The server translator exports a translator tree and makes it accessible to -remote GlusterFS clients. - -@cartouche -@table @code -@item client-volume-filename <path> (<CONFDIR>/glusterfs-client.vol) -The volume specification file to use for the client. This is the file the -client will receive when it is invoked with the @command{--server} option -(@ref{Client}). - -@item transport-type [tcp,ib-verbs,ib-sdp] (tcp) -The transport to use. You should use the server versions of all the transport -modules (@command{tcp}, @command{ib-sdp}, @command{ib-verbs}). - -@item auth.addr.<volume name>.allow <IP address wildcard pattern> -IP addresses of the clients that are allowed to attach to the specified volume. -This can be a wildcard. For example, a wildcard of the form @command{192.168.*.*} -allows any host in the @command{192.168.x.x} subnet to connect to the server. - -@end table -@end cartouche - -@node Clustering Translators -@section Clustering Translators - -The clustering translators are the most important GlusterFS -translators, since it is these that make GlusterFS a cluster -filesystem. These translators together enable GlusterFS to access an -arbitrarily large amount of storage, and provide @acronym{RAID}-like -redundancy and distribution over the entire cluster. - -There are three clustering translators: @strong{unify}, @strong{replicate}, -and @strong{stripe}. The unify translator aggregates storage from -many server nodes. The replicate translator provides file replication. The stripe -translator allows a file to be spread across many server nodes. The following sections -look at each of these translators in detail. - -@menu -* Unify:: -* Replicate:: -* Stripe:: -@end menu - -@node Unify -@subsection Unify -@cindex unify (translator) -@cindex scheduler (unify) -@example -type cluster/unify -@end example - -The unify translator presents a `unified' view of all its sub-volumes. That is, -it makes the union of all its sub-volumes appear as a single volume. It is the -unify translator that gives GlusterFS the ability to access an arbitrarily -large amount of storage. - -For unify to work correctly, certain invariants need to be maintained across -the entire network. These are: - -@cindex unify invariants -@itemize -@item The directory structure of all the sub-volumes must be identical. -@item A particular file can exist on only one of the sub-volumes. Phrasing it in another way, a pathname such as @command{/home/calvin/homework.txt}) is unique across the entire cluster. -@end itemize - -@tex -\vfill -@end tex -@page - -@center @image{unify,44pc,,,.pdf} - -Looking at the second requirement, you might wonder how one can -accomplish storing redundant copies of a file, if no file can exist -multiple times. To answer, we must remember that these invariants are -from @emph{unify's perspective}. A translator such as replicate at a lower -level in the translator tree than unify may subvert this picture. - -The first invariant might seem quite tedious to ensure. We shall see -later that this is not so, since unify's @emph{self-heal} mechanism -takes care of maintaining it. - -The second invariant implies that unify needs some way to decide which file goes where. -Unify makes use of @emph{scheduler} modules for this purpose. - -When a file needs to be created, unify's scheduler decides upon the -sub-volume to be used to store the file. There are many schedulers -available, each using a different algorithm and suitable for different -purposes. - -The various schedulers are described in detail in the sections that follow. - -@subsubsection ALU -@cindex alu (scheduler) - -@example - option scheduler alu -@end example - -ALU stands for "Adaptive Least Usage". It is the most advanced -scheduler available in GlusterFS. It balances the load across volumes -taking several factors in account. It adapts itself to changing I/O -patterns according to its configuration. When properly configured, it -can eliminate the need for regular tuning of the filesystem to keep -volume load nicely balanced. - -The ALU scheduler is composed of multiple least-usage -sub-schedulers. Each sub-scheduler keeps track of a certain type of -load, for each of the sub-volumes, getting statistics from -the sub-volumes themselves. The sub-schedulers are these: - -@itemize -@item disk-usage: The used and free disk space on the volume. - -@item read-usage: The amount of reading done from this volume. - -@item write-usage: The amount of writing done to this volume. - -@item open-files-usage: The number of files currently open from this volume. - -@item disk-speed-usage: The speed at which the disks are spinning. This is a constant value and therefore not very useful. -@end itemize - -The ALU scheduler needs to know which of these sub-schedulers to use, -and in which order to evaluate them. This is done through the -@command{option alu.order} configuration directive. - -Each sub-scheduler needs to know two things: when to kick in (the -entry-threshold), and how long to stay in control (the -exit-threshold). For example: when unifying three disks of 100GB, -keeping an exact balance of disk-usage is not necessary. Instead, there -could be a 1GB margin, which can be used to nicely balance other -factors, such as read-usage. The disk-usage scheduler can be told to -kick in only when a certain threshold of discrepancy is passed, such -as 1GB. When it assumes control under this condition, it will write -all subsequent data to the least-used volume. If it is doing so, it is -unwise to stop right after the values are below the entry-threshold -again, since that would make it very likely that the situation will -occur again very soon. Such a situation would cause the ALU to spend -most of its time disk-usage scheduling, which is unfair to the other -sub-schedulers. The exit-threshold therefore defines the amount of -data that needs to be written to the least-used disk, before control -is relinquished again. - -In addition to the sub-schedulers, the ALU scheduler also has "limits" -options. These can stop the creation of new files on a volume once -values drop below a certain threshold. For example, setting -@command{option alu.limits.min-free-disk 5GB} will stop the scheduling -of files to volumes that have less than 5GB of free disk space, -leaving the files on that disk some room to grow. - -The actual values you assign to the thresholds for sub-schedulers and -limits depend on your situation. If you have fast-growing files, -you'll want to stop file-creation on a disk much earlier than when -hardly any of your files are growing. If you care less about -disk-usage balance than about read-usage balance, you'll want a bigger -disk-usage scheduler entry-threshold and a smaller read-usage -scheduler entry-threshold. - -For thresholds defining a size, values specifying "KB", "MB" and "GB" -are allowed. For example: @command{option alu.limits.min-free-disk 5GB}. - -@cartouche -@table @code -@item alu.order <order> * ("disk-usage:write-usage:read-usage:open-files-usage:disk-speed") -@item alu.disk-usage.entry-threshold <size> (1GB) -@item alu.disk-usage.exit-threshold <size> (512MB) -@item alu.write-usage.entry-threshold <%> (25) -@item alu.write-usage.exit-threshold <%> (5) -@item alu.read-usage.entry-threshold <%> (25) -@item alu.read-usage.exit-threshold <%> (5) -@item alu.open-files-usage.entry-threshold <n> (1000) -@item alu.open-files-usage.exit-threshold <n> (100) -@item alu.limits.min-free-disk <%> -@item alu.limits.max-open-files <n> -@end table -@end cartouche - -@subsubsection Round Robin (RR) -@cindex rr (scheduler) - -@example - option scheduler rr -@end example - -Round-Robin (RR) scheduler creates files in a round-robin -fashion. Each client will have its own round-robin loop. When your -files are mostly similar in size and I/O access pattern, this -scheduler is a good choice. RR scheduler checks for free disk space -on the server before scheduling, so you can know when to add -another server node. The default value of min-free-disk is 5% and is -checked on file creation calls, with atleast 10 seconds (by default) -elapsing between two checks. - -Options: -@cartouche -@table @code -@item rr.limits.min-free-disk <%> (5) -Minimum free disk space a node must have for RR to schedule a file to it. -@item rr.refresh-interval <t> (10 seconds) -Time between two successive free disk space checks. -@end table -@end cartouche - -@subsubsection Random -@cindex random (scheduler) - -@example - option scheduler random -@end example - -The random scheduler schedules file creation randomly among its child nodes. -Like the round-robin scheduler, it also checks for a minimum amount of free disk -space before scheduling a file to a node. - -@cartouche -@table @code -@item random.limits.min-free-disk <%> (5) -Minimum free disk space a node must have for random to schedule a file to it. -@item random.refresh-interval <t> (10 seconds) -Time between two successive free disk space checks. -@end table -@end cartouche - -@subsubsection NUFA -@cindex nufa (scheduler) - -@example - option scheduler nufa -@end example - -It is common in many GlusterFS computing environments for all deployed -machines to act as both servers and clients. For example, a -research lab may have 40 workstations each with its own storage. All -of these workstations might act as servers exporting a volume as well -as clients accessing the entire cluster's storage. In such a -situation, it makes sense to store locally created files on the local -workstation itself (assuming files are accessed most by the -workstation that created them). The Non-Uniform File Allocation (@acronym{NUFA}) -scheduler accomplishes that. - -@acronym{NUFA} gives the local system first priority for file creation -over other nodes. If the local volume does not have more free disk space -than a specified amount (5% by default) then @acronym{NUFA} schedules files -among the other child volumes in a round-robin fashion. - -@acronym{NUFA} is named after the similar strategy used for memory access, -@acronym{NUMA}@footnote{Non-Uniform Memory Access: -@indicateurl{http://en.wikipedia.org/wiki/Non-Uniform_Memory_Access}}. - -@cartouche -@table @code -@item nufa.limits.min-free-disk <%> (5) -Minimum disk space that must be free (local or remote) for @acronym{NUFA} to schedule a -file to it. -@item nufa.refresh-interval <t> (10 seconds) -Time between two successive free disk space checks. -@item nufa.local-volume-name <volume> -The name of the volume corresponding to the local system. This volume must be -one of the children of the unify volume. This option is mandatory. -@end table -@end cartouche - -@cindex namespace -@subsubsection Namespace -Namespace volume needed because: - - persistent inode numbers. - - file exists even when node is down. - -namespace files are simply touched. on every lookup it is checked. - -@cartouche -@table @code -@item namespace <volume> * -Name of the namespace volume (which should be one of the unify volume's children). -@item self-heal [on|off] (on) -Enable/disable self-heal. Unless you know what you are doing, do not disable self-heal. -@end table -@end cartouche - -@cindex self heal (unify) -@subsubsection Self Heal - * When a 'lookup()/stat()' call is made on directory for the first -time, a self-heal call is made, which checks for the consistancy of -its child nodes. If an entry is present in storage node, but not in -namespace, that entry is created in namespace, and vica-versa. There -is an writedir() API introduced which is used for the same. It also -checks for permissions, and uid/gid consistencies. - - * This check is also done when an server goes down and comes up. - - * If one starts with an empty namespace export, but has data in -storage nodes, a 'find .>/dev/null' or 'ls -lR >/dev/null' should help -to build namespace in one shot. Even otherwise, namespace is built on -demand when a file is looked up for the first time. - -NOTE: There are some issues (Kernel 'Oops' msgs) seen with fuse-2.6.3, -when someone deletes namespace in backend, when glusterfs is -running. But with fuse-2.6.5, this issue is not there. - -@node Replicate -@subsection Replicate (formerly AFR) -@cindex Replicate -@example -type cluster/replicate -@end example - -Replicate provides @acronym{RAID}-1 like functionality for -GlusterFS. Replicate replicates files and directories across the -subvolumes. Hence if Replicate has four subvolumes, there will be -four copies of all files and directories. Replicate provides -high-availability, i.e., in case one of the subvolumes go down -(e. g. server crash, network disconnection) Replicate will still -service the requests using the redundant copies. - -Replicate also provides self-heal functionality, i.e., in case the -crashed servers come up, the outdated files and directories will be -updated with the latest versions. Replicate uses extended -attributes of the backend file system to track the versioning of files -and directories and provide the self-heal feature. - -@example -volume replicate-example - type cluster/replicate - subvolumes brick1 brick2 brick3 -end-volume -@end example - -This sample configuration will replicate all directories and files on -brick1, brick2 and brick3. - -All the read operations happen from the first alive child. If all the -three sub-volumes are up, reads will be done from brick1; if brick1 is -down read will be done from brick2. In case read() was being done on -brick1 and it goes down, replicate transparently falls back to -brick2. - -The next release of GlusterFS will add the following features: -@itemize -@item Ability to specify the sub-volume from which read operations are to be done (this will help users who have one of the sub-volumes as a local storage volume). -@item Allow scheduling of read operations amongst the sub-volumes in a round-robin fashion. -@end itemize - -The order of the subvolumes list should be same across all the 'replicate's as -they will be used for locking purposes. - -@cindex self heal (replicate) -@subsubsection Self Heal -Replicate has self-heal feature, which updates the outdated file and -directory copies by the most recent versions. For example consider the -following config: - -@example -volume replicate-example - type cluster/replicate - subvolumes brick1 brick2 -end-volume -@end example - -@subsubsection File self-heal - -Now if we create a file foo.txt on replicate-example, the file will be created -on brick1 and brick2. The file will have two extended attributes associated -with it in the backend filesystem. One is trusted.afr.createtime and the -other is trusted.afr.version. The trusted.afr.createtime xattr has the -create time (in terms of seconds since epoch) and trusted.afr.version -is a number that is incremented each time a file is modified. This increment -happens during close (incase any write was done before close). - -If brick1 goes down, we edit foo.txt the version gets incremented. Now -the brick1 comes back up, when we open() on foo.txt replicate will check if -their versions are same. If they are not same, the outdated copy is -replaced by the latest copy and its version is updated. After the sync -the open() proceeds in the usual manner and the application calling open() -can continue on its access to the file. - -If brick1 goes down, we delete foo.txt and create a file with the same -name again i.e foo.txt. Now brick1 comes back up, clearly there is a -chance that the version on brick1 being more than the version on brick2, -this is where createtime extended attribute helps in deciding which -the outdated copy is. Hence we need to consider both createtime and -version to decide on the latest copy. - -The version attribute is incremented during the close() call. Version -will not be incremented in case there was no write() done. In case the -fd that the close() gets was got by create() call, we also create -the createtime extended attribute. - -@subsubsection Directory self-heal - -Suppose brick1 goes down, we delete foo.txt, brick1 comes back up, now -we should not create foo.txt on brick2 but we should delete foo.txt -on brick1. We handle this situation by having the createtime and version -attribute on the directory similar to the file. when lookup() is done -on the directory, we compare the createtime/version attributes of the -copies and see which files needs to be deleted and delete those files -and update the extended attributes of the outdated directory copy. -Each time a directory is modified (a file or a subdirectory is created -or deleted inside the directory) and one of the subvols is down, we -increment the directory's version. - -lookup() is a call initiated by the kernel on a file or directory -just before any access to that file or directory. In glusterfs, by -default, lookup() will not be called in case it was called in the -past one second on that particular file or directory. - -The extended attributes can be seen in the backend filesystem using -the @command{getfattr} command. (@command{getfattr -n trusted.afr.version <file>}) - -@cartouche -@table @code -@item debug [on|off] (off) -@item self-heal [on|off] (on) -@item replicate <pattern> (*:1) -@item lock-node <child_volume> (first child is used by default) -@end table -@end cartouche - -@node Stripe -@subsection Stripe -@cindex stripe (translator) -@example -type cluster/stripe -@end example - -The stripe translator distributes the contents of a file over its -sub-volumes. It does this by creating a file equal in size to the -total size of the file on each of its sub-volumes. It then writes only -a part of the file to each sub-volume, leaving the rest of it empty. -These empty regions are called `holes' in Unix terminology. The holes -do not consume any disk space. - -The diagram below makes this clear. - -@center @image{stripe,44pc,,,.pdf} - -You can configure stripe so that only filenames matching a pattern -are striped. You can also configure the size of the data to be stored -on each sub-volume. - -@cartouche -@table @code -@item block-size <pattern>:<size> (*:0 no striping) -Distribute files matching @command{<pattern>} over the sub-volumes, -storing at least @command{<size>} on each sub-volume. For example, - -@example - option block-size *.mpg:1M -@end example - -distributes all files ending in @command{.mpg}, storing at least 1 MB on -each sub-volume. - -Any number of @command{block-size} option lines may be present, specifying -different sizes for different file name patterns. -@end table -@end cartouche - -@node Performance Translators -@section Performance Translators - -@menu -* Read Ahead:: -* Write Behind:: -* IO Threads:: -* IO Cache:: -* Booster:: -@end menu - -@node Read Ahead -@subsection Read Ahead -@cindex read-ahead (translator) -@example -type performance/read-ahead -@end example - -The read-ahead translator pre-fetches data in advance on every read. -This benefits applications that mostly process files in sequential order, -since the next block of data will already be available by the time the -application is done with the current one. - -Additionally, the read-ahead translator also behaves as a read-aggregator. -Many small read operations are combined and issued as fewer, larger read -requests to the server. - -Read-ahead deals in ``pages'' as the unit of data fetched. The page size -is configurable, as is the ``page count'', which is the number of pages -that are pre-fetched. - -Read-ahead is best used with InfiniBand (using the ib-verbs transport). -On FastEthernet and Gigabit Ethernet networks, -GlusterFS can achieve the link-maximum throughput even without -read-ahead, making it quite superflous. - -Note that read-ahead only happens if the reads are perfectly -sequential. If your application accesses data in a random fashion, -using read-ahead might actually lead to a performance loss, since -read-ahead will pointlessly fetch pages which won't be used by the -application. - -@cartouche -Options: -@table @code -@item page-size <n> (256KB) -The unit of data that is pre-fetched. -@item page-count <n> (2) -The number of pages that are pre-fetched. -@item force-atime-update [on|off|yes|no] (off|no) -Whether to force an access time (atime) update on the file on every read. Without -this, the atime will be slightly imprecise, as it will reflect the time when -the read-ahead translator read the data, not when the application actually read it. -@end table -@end cartouche - -@node Write Behind -@subsection Write Behind -@cindex write-behind (translator) -@example -type performance/write-behind -@end example - -The write-behind translator improves the latency of a write operation. -It does this by relegating the write operation to the background and -returning to the application even as the write is in progress. Using the -write-behind translator, successive write requests can be pipelined. -This mode of write-behind operation is best used on the client side, to -enable decreased write latency for the application. - -The write-behind translator can also aggregate write requests. If the -@command{aggregate-size} option is specified, then successive writes up to that -size are accumulated and written in a single operation. This mode of operation -is best used on the server side, as this will decrease the disk's head movement -when multiple files are being written to in parallel. - -The @command{aggregate-size} option has a default value of 128KB. Although -this works well for most users, you should always experiment with different values -to determine the one that will deliver maximum performance. This is because the -performance of write-behind depends on your interconnect, size of RAM, and the -work load. - -@cartouche -@table @code -@item aggregate-size <n> (128KB) -Amount of data to accumulate before doing a write -@item flush-behind [on|yes|off|no] (off|no) - -@end table -@end cartouche - -@node IO Threads -@subsection IO Threads -@cindex io-threads (translator) -@example -type performance/io-threads -@end example - -The IO threads translator is intended to increase the responsiveness -of the server to metadata operations by doing file I/O (read, write) -in a background thread. Since the GlusterFS server is -single-threaded, using the IO threads translator can significantly -improve performance. This translator is best used on the server side, -loaded just below the server protocol translator. - -IO threads operates by handing out read and write requests to a separate thread. -The total number of threads in existence at a time is constant, and configurable. - -@cartouche -@table @code -@item thread-count <n> (1) -Number of threads to use. -@end table -@end cartouche - -@node IO Cache -@subsection IO Cache -@cindex io-cache (translator) -@example -type performance/io-cache -@end example - -The IO cache translator caches data that has been read. This is useful -if many applications read the same data multiple times, and if reads -are much more frequent than writes (for example, IO caching may be -useful in a web hosting environment, where most clients will simply -read some files and only a few will write to them). - -The IO cache translator reads data from its child in @command{page-size} chunks. -It caches data up to @command{cache-size} bytes. The cache is maintained as -a prioritized least-recently-used (@acronym{LRU}) list, with priorities determined -by user-specified patterns to match filenames. - -When the IO cache translator detects a write operation, the -cache for that file is flushed. - -The IO cache translator periodically verifies the consistency of -cached data, using the modification times on the files. The verification timeout -is configurable. - -@cartouche -@table @code -@item page-size <n> (128KB) -Size of a page. -@item cache-size (n) (32MB) -Total amount of data to be cached. -@item force-revalidate-timeout <n> (1) -Timeout to force a cache consistency verification, in seconds. -@item priority <pattern> (*:0) -Filename patterns listed in order of priority. -@end table -@end cartouche - -@node Booster -@subsection Booster -@cindex booster -@example - type performance/booster -@end example - -The booster translator gives applications a faster path to communicate -read and write requests to GlusterFS. Normally, all requests to GlusterFS from -applications go through FUSE, as indicated in @ref{Filesystems in Userspace}. -Using the booster translator in conjunction with the GlusterFS booster shared -library, an application can bypass the FUSE path and send read/write requests -directly to the GlusterFS client process. - -The booster mechanism consists of two parts: the booster translator, -and the booster shared library. The booster translator is meant to be -loaded on the client side, usually at the root of the translator tree. -The booster shared library should be @command{LD_PRELOAD}ed with the -application. - -The booster translator when loaded opens a Unix domain socket and -listens for read/write requests on it. The booster shared library -intercepts read and write system calls and sends the requests to the -GlusterFS process directly using the Unix domain socket, bypassing FUSE. -This leads to superior performance. - -Once you've loaded the booster translator in your volume specification file, you -can start your application as: - -@example - $ LD_PRELOAD=/usr/local/bin/glusterfs-booster.so your_app -@end example - -The booster translator accepts no options. - -@node Features Translators -@section Features Translators - -@menu -* POSIX Locks:: -* Fixed ID:: -@end menu - -@node POSIX Locks -@subsection POSIX Locks -@cindex record locking -@cindex fcntl -@cindex posix-locks (translator) -@example -type features/posix-locks -@end example - -This translator provides storage independent POSIX record locking -support (@command{fcntl} locking). Typically you'll want to load this on the -server side, just above the @acronym{POSIX} storage translator. Using this -translator you can get both advisory locking and mandatory locking -support. It also handles @command{flock()} locks properly. - -Caveat: Consider a file that does not have its mandatory locking bits -(+setgid, -group execution) turned on. Assume that this file is now -opened by a process on a client that has the write-behind xlator -loaded. The write-behind xlator does not cache anything for files -which have mandatory locking enabled, to avoid incoherence. Let's say -that mandatory locking is now enabled on this file through another -client. The former client will not know about this change, and -write-behind may erroneously report a write as being successful when -in fact it would fail due to the region it is writing to being locked. - -There seems to be no easy way to fix this. To work around this -problem, it is recommended that you never enable the mandatory bits on -a file while it is open. - -@cartouche -@table @code -@item mandatory [on|off] (on) -Turns mandatory locking on. -@end table -@end cartouche - -@node Fixed ID -@subsection Fixed ID -@cindex fixed-id (translator) -@example -type features/fixed-id -@end example - -The fixed ID translator makes all filesystem requests from the client -to appear to be coming from a fixed, specified -@acronym{UID}/@acronym{GID}, regardless of which user actually -initiated the request. - -@cartouche -@table @code -@item fixed-uid <n> [if not set, not used] -The @acronym{UID} to send to the server -@item fixed-gid <n> [if not set, not used] -The @acronym{GID} to send to the server -@end table -@end cartouche - -@node Miscellaneous Translators -@section Miscellaneous Translators - -@menu -* ROT-13:: -* Trace:: -@end menu - -@node ROT-13 -@subsection ROT-13 -@cindex rot-13 (translator) -@example -type encryption/rot-13 -@end example - -@acronym{ROT-13} is a toy translator that can ``encrypt'' and ``decrypt'' file -contents using the @acronym{ROT-13} algorithm. @acronym{ROT-13} is a trivial -algorithm that rotates each alphabet by thirteen places. Thus, 'A' becomes 'N', -'B' becomes 'O', and 'Z' becomes 'M'. - -It goes without saying that you shouldn't use this translator if you need -@emph{real} encryption (a future release of GlusterFS will have real encryption -translators). - -@cartouche -@table @code -@item encrypt-write [on|off] (on) -Whether to encrypt on write -@item decrypt-read [on|off] (on) -Whether to decrypt on read -@end table -@end cartouche - -@node Trace -@subsection Trace -@cindex trace (translator) -@example -type debug/trace -@end example - -The trace translator is intended for debugging purposes. When loaded, it -logs all the system calls received by the server or client (wherever -trace is loaded), their arguments, and the results. You must use a GlusterFS log -level of DEBUG (See @ref{Running GlusterFS}) for trace to work. - -Sample trace output (lines have been wrapped for readability): -@cartouche -@example -2007-10-30 00:08:58 D [trace.c:1579:trace_opendir] trace: callid: 68 -(*this=0x8059e40, loc=0x8091984 @{path=/iozone3_283, inode=0x8091f00@}, - fd=0x8091d50) - -2007-10-30 00:08:58 D [trace.c:630:trace_opendir_cbk] trace: -(*this=0x8059e40, op_ret=4, op_errno=1, fd=0x8091d50) - -2007-10-30 00:08:58 D [trace.c:1602:trace_readdir] trace: callid: 69 -(*this=0x8059e40, size=4096, offset=0 fd=0x8091d50) - -2007-10-30 00:08:58 D [trace.c:215:trace_readdir_cbk] trace: -(*this=0x8059e40, op_ret=0, op_errno=0, count=4) - -2007-10-30 00:08:58 D [trace.c:1624:trace_closedir] trace: callid: 71 -(*this=0x8059e40, *fd=0x8091d50) - -2007-10-30 00:08:58 D [trace.c:809:trace_closedir_cbk] trace: -(*this=0x8059e40, op_ret=0, op_errno=1) -@end example -@end cartouche - -@node Usage Scenarios -@chapter Usage Scenarios - -@section Advanced Striping - -This section is based on the Advanced Striping tutorial written by -Anand Avati on the GlusterFS wiki -@footnote{http://gluster.org/docs/index.php/Mixing_Striped_and_Regular_Files}. - -@subsection Mixed Storage Requirements - -There are two ways of scheduling the I/O. One at file level (using -unify translator) and other at block level (using stripe -translator). Striped I/O is good for files that are potentially large -and require high parallel throughput (for example, a single file of -400GB being accessed by 100s and 1000s of systems simultaneously and -randomly). For most of the cases, file level scheduling works best. - -In the real world, it is desirable to mix file level and block level -scheduling on a single storage volume. Alternatively users can choose -to have two separate volumes and hence two mount points, but the -applications may demand a single storage system to host both. - -This document explains how to mix file level scheduling with stripe. - -@subsection Configuration Brief - -This setup demonstrates how users can configure unify translator with -appropriate I/O scheduler for file level scheduling and strip for only -matching patterns. This way, GlusterFS chooses appropriate I/O profile -and knows how to efficiently handle both the types of data. - -A simple technique to achieve this effect is to create a stripe set of -unify and stripe blocks, where unify is the first sub-volume. Files -that do not match the stripe policy passed on to first unify -sub-volume and inturn scheduled arcoss the cluster using its file -level I/O scheduler. - -@image{advanced-stripe,44pc,,,.pdf} - -@subsection Preparing GlusterFS Envoronment - -Create the directories /export/namespace, /export/unify and -/export/stripe on all the storage bricks. - - Place the following server and client volume spec file under -/etc/glusterfs (or appropriate installed path) and replace the IP -addresses / access control fields to match your environment. - -@cartouche -@example - ## file: /etc/glusterfs/glusterfsd.vol - volume posix-unify - type storage/posix - option directory /export/for-unify - end-volume - - volume posix-stripe - type storage/posix - option directory /export/for-stripe - end-volume - - volume posix-namespace - type storage/posix - option directory /export/for-namespace - end-volume - - volume server - type protocol/server - option transport-type tcp - option auth.addr.posix-unify.allow 192.168.1.* - option auth.addr.posix-stripe.allow 192.168.1.* - option auth.addr.posix-namespace.allow 192.168.1.* - subvolumes posix-unify posix-stripe posix-namespace - end-volume -@end example -@end cartouche - -@cartouche -@example - ## file: /etc/glusterfs/glusterfs.vol - volume client-namespace - type protocol/client - option transport-type tcp - option remote-host 192.168.1.1 - option remote-subvolume posix-namespace - end-volume - - volume client-unify-1 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.1 - option remote-subvolume posix-unify - end-volume - - volume client-unify-2 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.2 - option remote-subvolume posix-unify - end-volume - - volume client-unify-3 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.3 - option remote-subvolume posix-unify - end-volume - - volume client-unify-4 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.4 - option remote-subvolume posix-unify - end-volume - - volume client-stripe-1 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.1 - option remote-subvolume posix-stripe - end-volume - - volume client-stripe-2 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.2 - option remote-subvolume posix-stripe - end-volume - - volume client-stripe-3 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.3 - option remote-subvolume posix-stripe - end-volume - - volume client-stripe-4 - type protocol/client - option transport-type tcp - option remote-host 192.168.1.4 - option remote-subvolume posix-stripe - end-volume - - volume unify - type cluster/unify - option scheduler rr - subvolumes cluster-unify-1 cluster-unify-2 cluster-unify-3 cluster-unify-4 - end-volume - - volume stripe - type cluster/stripe - option block-size *.img:2MB # All files ending with .img are striped with 2MB stripe block size. - subvolumes unify cluster-stripe-1 cluster-stripe-2 cluster-stripe-3 cluster-stripe-4 - end-volume -@end example -@end cartouche - - -Bring up the Storage - -Starting GlusterFS Server: If you have installed through binary -package, you can start the service through init.d startup script. If -not: - -@example -[root@@server]# glusterfsd -@end example - -Mounting GlusterFS Volumes: - -@example -[root@@client]# glusterfs -s [BRICK-IP-ADDRESS] /mnt/cluster -@end example - -Improving upon this Setup - -Infiniband Verbs RDMA transport is much faster than TCP/IP GigE -transport. - -Use of performance translators such as read-ahead, write-behind, -io-cache, io-threads, booster is recommended. - -Replace round-robin (rr) scheduler with ALU to handle more dynamic -storage environments. - -@node Troubleshooting -@chapter Troubleshooting - -This chapter is a general troubleshooting guide to GlusterFS. It lists -common GlusterFS server and client error messages, debugging hints, and -concludes with the suggested procedure to report bugs in GlusterFS. - -@section GlusterFS error messages - -@subsection Server errors - -@example -glusterfsd: FATAL: could not open specfile: -'/etc/glusterfs/glusterfsd.vol' -@end example - -The GlusterFS server expects the volume specification file to be -at @command{/etc/glusterfs/glusterfsd.vol}. The example -specification file will be installed as -@command{/etc/glusterfs/glusterfsd.vol.sample}. You need to edit -it and rename it, or provide a different specification file using -the @command{--spec-file} command line option (See @ref{Server}). - -@vskip 4ex - -@example -gf_log_init: failed to open logfile "/usr/var/log/glusterfs/glusterfsd.log" - (Permission denied) -@end example - -You don't have permission to create files in the -@command{/usr/var/log/glusterfs} directory. Make sure you are running -GlusterFS as root. Alternatively, specify a different path for the log -file using the @command{--log-file} option (See @ref{Server}). - -@subsection Client errors - -@example -fusermount: failed to access mountpoint /mnt: - Transport endpoint is not connected -@end example - -A previous failed (or hung) mount of GlusterFS is preventing it from being -mounted again in the same location. The fix is to do: - -@example -# umount /mnt -@end example - -and try mounting again. - -@vskip 4ex - -@strong{``Transport endpoint is not connected''.} - -If you get this error when you try a command such as @command{ls} or @command{cat}, -it means the GlusterFS mount did not succeed. Try running GlusterFS in @command{DEBUG} -logging level and study the log messages to discover the cause. - -@vskip 4ex - -@strong{``Connect to server failed'', ``SERVER-ADDRESS: Connection refused''.} - -GluserFS Server is not running or dead. Check your network -connections and firewall settings. To check if the server is reachable, -try: - -@example -telnet IP-ADDRESS 24007 -@end example - -If the server is accessible, your `telnet' command should connect and -block. If not you will see an error message such as @command{telnet: Unable to -connect to remote host: Connection refused}. 24007 is the default -GlusterFS port. If you have changed it, then use the corresponding -port instead. - -@vskip 4ex - -@example -gf_log_init: failed to open logfile "/usr/var/log/glusterfs/glusterfs.log" - (Permission denied) -@end example - -You don't have permission to create files in the -@command{/usr/var/log/glusterfs} directory. Make sure you are running -GlusterFS as root. Alternatively, specify a different path for the log -file using the @command{--log-file} option (See @ref{Client}). - -@section FUSE error messages -@command{modprobe fuse} fails with: ``Unknown symbol in module, or unknown parameter''. -@cindex Redhat Enterprise Linux - -If you are using fuse-2.6.x on Redhat Enterprise Linux Work Station 4 -and Advanced Server 4 with 2.6.9-42.ELlargesmp, 2.6.9-42.ELsmp, -2.6.9-42.EL kernels and get this error while loading @acronym{FUSE} kernel -module, you need to apply the following patch. - -For fuse-2.6.2: - -@indicateurl{http://ftp.gluster.com/pub/gluster/glusterfs/fuse/fuse-2.6.2-rhel-build.patch} - -For fuse-2.6.3: - -@indicateurl{http://ftp.gluster.com/pub/gluster/glusterfs/fuse/fuse-2.6.3-rhel-build.patch} - -@section AppArmour and GlusterFS -@cindex AppArmour -@cindex OpenSuSE -Under OpenSuSE GNU/Linux, the AppArmour security feature does not -allow GlusterFS to create temporary files or network socket -connections even while running as root. You will see error messages -like `Unable to open log file: Operation not permitted' or `Connection -refused'. Disabling AppArmour using YaST or properly configuring -AppArmour to recognize @command{glusterfsd} or @command{glusterfs}/@command{fusermount} -should solve the problem. - -@section Reporting a bug - -If you encounter a bug in GlusterFS, please follow the below -guidelines when you report it to the mailing list. Be sure to report -it! User feedback is crucial to the health of the project and we value -it highly. - -@subsection General instructions - -When running GlusterFS in a non-production environment, be sure to -build it with the following command: - -@example - $ make CFLAGS='-g -O0 -DDEBUG' -@end example - -This includes debugging information which will be helpful in getting -backtraces (see below) and also disable optimization. Enabling -optimization can result in incorrect line numbers being reported to -gdb. - -@subsection Volume specification files - -Attach all relevant server and client spec files you were using when -you encountered the bug. Also tell us details of your setup, i.e., how -many clients and how many servers. - -@subsection Log files - -Set the loglevel of your client and server programs to @acronym{DEBUG} (by -passing the -L @acronym{DEBUG} option) and attach the log files with your bug -report. Obviously, if only the client is failing (for example), you -only need to send us the client log file. - -@subsection Backtrace - -If GlusterFS has encountered a segmentation fault or has crashed for -some other reason, include the backtrace with the bug report. You can -get the backtrace using the following procedure. - -Run the GlusterFS client or server inside gdb. - -@example - $ gdb ./glusterfs - (gdb) set args -f client.spec -N -l/path/to/log/file -LDEBUG /mnt/point - (gdb) run -@end example - -Now when the process segfaults, you can get the backtrace by typing: - -@example - (gdb) bt -@end example - -If the GlusterFS process has crashed and dumped a core file (you can -find this in / if running as a daemon and in the current directory -otherwise), you can do: - -@example - $ gdb /path/to/glusterfs /path/to/core.<pid> -@end example - -and then get the backtrace. - -If the GlusterFS server or client seems to be hung, then you can get -the backtrace by attaching gdb to the process. First get the @command{PID} of -the process (using ps), and then do: - -@example - $ gdb ./glusterfs <pid> -@end example - -Press Ctrl-C to interrupt the process and then generate the backtrace. - -@subsection Reproducing the bug - -If the bug is reproducible, please include the steps necessary to do -so. If the bug is not reproducible, send us the bug report anyway. - -@subsection Other information - -If you think it is relevant, send us also the version of @acronym{FUSE} you're -using, the kernel version, platform. - -@node GNU Free Documentation Licence -@appendix GNU Free Documentation Licence -@include fdl.texi - -@node Index -@unnumbered Index -@printindex cp - -@bye diff --git a/doc/legacy/xlator.odg b/doc/legacy/xlator.odg Binary files differdeleted file mode 100644 index 179a65f6e26..00000000000 --- a/doc/legacy/xlator.odg +++ /dev/null diff --git a/doc/legacy/xlator.pdf b/doc/legacy/xlator.pdf Binary files differdeleted file mode 100644 index a07e14d67d2..00000000000 --- a/doc/legacy/xlator.pdf +++ /dev/null diff --git a/doc/mount.glusterfs.8 b/doc/mount.glusterfs.8 index 32260ced04f..ce16e9e40b7 100644 --- a/doc/mount.glusterfs.8 +++ b/doc/mount.glusterfs.8 @@ -12,11 +12,11 @@ .SH NAME .B mount.glusterfs - script to mount native GlusterFS volume .SH SYNOPSIS -.B mount -t glusterfs [-o <options>] <volumeserver>:/<volume> +.B mount -t glusterfs [-o <options>] <volumeserver>:/<volume>[/<subdir>] .B <mountpoint> .TP .B mount -t glusterfs [-o <options>] <server1>,<server2>, -.B <server3>,..<serverN>:/<volname> <mount_point> +.B <server3>,..<serverN>:/<volname>[/<subdir>] <mount_point> .TP .TP .B mount -t glusterfs [-o <options>] <path/to/volumefile> <mountpoint> @@ -44,11 +44,8 @@ INFO and NONE [default: INFO] \fBacl Mount the filesystem with POSIX ACL support .TP -\fBfopen\-keep\-cache -Do not purge the cache on file open -.TP -\fBselinux -Enable SELinux label (extened attributes) support on inodes +\fBfopen\-keep\-cache[=BOOL] +Do not purge the cache on file open (default: false) .TP \fBworm Mount the filesystem in 'worm' mode @@ -65,6 +62,12 @@ support 64-bit inodes .TP \fBmem\-accounting Enable internal memory accounting +.TP +\fBcapability +Enable file capability setting and retrival +.TP +\fBthin-client +Enables thin mount and connects via gfproxyd daemon .PP .SS "Advanced options" @@ -80,7 +83,7 @@ Set entry timeout to SECONDS in fuse kernel module [default: 1] Set fuse module's background queue length to N [default: 64] .TP \fBgid\-timeout=\fRSECONDS -Set auxilary group list timeout to SECONDS for fuse translator [default: 0] +Set auxiliary group list timeout to SECONDS for fuse translator [default: 0] .TP \fBnegative\-timeout=\fRSECONDS Set negative timeout to SECONDS in fuse kernel module [default: 0] @@ -89,17 +92,20 @@ Set negative timeout to SECONDS in fuse kernel module [default: 0] Volume name to be used for MOUNT-POINT [default: top most volume in VOLUME-FILE] .TP -\fBdirect\-io\-mode=\fRdisable -Disable direct I/O mode in fuse kernel module +\fBdirect\-io\-mode=\fRBOOL|auto +Specify fuse direct I/O strategy [default: auto] .TP \fBcongestion\-threshold=\fRN Set fuse module's congestion threshold to N [default: 48] .TP +\fsubdir\-mount=\fRN +Set the subdirectory mount option [default: NULL, ie, no subdirectory mount] +.TP .TP \fBbackup\-volfile\-servers=\fRSERVERLIST Provide list of backup volfile servers in the following format [default: None] -\fB$ mount -t glusterfs -obackup-volfile-servers=<server2>:\fR +\fB$ mount \-t glusterfs \-obackup\-volfile\-servers=<server2>:\fR \fB <server3>:...:<serverN> <server1>:/<volname> <mount_point>\fR .TP @@ -107,7 +113,7 @@ Provide list of backup volfile servers in the following format [default: None] \fBbackupvolfile\-server=\fRSERVER Provide list of backup volfile servers in the following format [default: None] -\fB $ mount -t glusterfs -obackupvolfile-server=<server2> +\fB $ mount \-t glusterfs \-obackupvolfile\-server=<server2> \fB <server1>:/<volname> <mount_point> .TP @@ -116,6 +122,15 @@ Provide list of backup volfile servers in the following format [default: None] \fBDeprecated\fR option - placed here for backward compatibility [default: 1] .TP .TP +\fBlru-limit=\fRN +Set fuse module's limit for number of inodes kept in LRU list to N [default: 65536] +.TP +.TP +\fBinvalidate-limit=\fRN +Suspend fuse invalidations implied by 'lru-limit' if number of outstanding +invalidations reaches N +.TP +.TP \fBbackground-qlen=\fRN Set fuse module's background queue length to N [default: 64] .TP @@ -127,13 +142,27 @@ enable root squashing for the trusted client [default: on] .TP \fBuse\-readdirp=\fRBOOL Use readdirp() mode in fuse kernel module [default: on] +.TP +\fBdump\-fuse=\fRPATH +Dump fuse traffic to PATH +.TP +\fBkernel\-writeback\-cache=\fRBOOL +Enable fuse in-kernel writeback cache [default: off] +.TP +\fBattr\-times\-granularity=\fRNS +Declare supported granularity of file attribute [default: 0] +.TP +\fBauto\-invalidation=\fRBOOL +controls whether fuse-kernel can auto-invalidate attribute, dentry and +page-cache. Disable this only if same files/directories are not +accessed across two different mounts concurrently [default: on] .PP .SH FILES .TP .I /etc/fstab A typical GlusterFS entry in /etc/fstab looks like below -\fBserver1:/mirror /mnt/mirror glusterfs log-file=/var/log/mirror.log,acl,selinux 0 0\fR +\fBserver1:/mirror /mnt/mirror glusterfs log-file=/var/log/mirror.log,acl 0 0\fR .TP .I /proc/mounts diff --git a/doc/tools/gfind_missing_files.md b/doc/tools/gfind_missing_files.md deleted file mode 100644 index 47241be5ac6..00000000000 --- a/doc/tools/gfind_missing_files.md +++ /dev/null @@ -1,67 +0,0 @@ -Introduction -======== -The tool gfind_missing_files.sh can be used to find the missing files in a -GlusterFS geo-replicated slave volume. The tool uses a multi-threaded crawler -operating on the backend .glusterfs of a brickpath which is passed as one of -the parameters to the tool. It does a stat on each entry in the slave volume -mount to check for the presence of a file. The tool uses the aux-gfid-mount -thereby avoiding path conversions and potentially saving time. - -This tool should be run on every node and each brickpath in a geo-replicated -master volume to find the missing files on the slave volume. - -The script gfind_missing_files.sh is a wrapper script that in turn uses the -gcrawler binary to do the backend crawling. The script detects the gfids of -the missing files and runs the gfid-to-path conversion script to list out the -missing files with their full pathnames. - -Usage -===== -```sh -$bash gfind_missing_files.sh <BRICK_PATH> <SLAVE_HOST> <SLAVE_VOL> <OUTFILE> - BRICK_PATH - Full path of the brick - SLAVE_HOST - Hostname of gluster volume - SLAVE_VOL - Gluster volume name - OUTFILE - Output file which contains gfids of the missing files -``` - -The gfid-to-path conversion uses a quicker algorithm for converting gfids to -paths and it is possible that in some cases all missing gfids may not be -converted to their respective paths. - -Example output(126733 missing files) -=================================== -```sh -$ionice -c 2 -n 7 ./gfind_missing_files.sh /bricks/m3 acdc slave-vol ~/test_results/m3-4.txt -Calling crawler... -Crawl Complete. -gfids of skipped files are available in the file /root/test_results/m3-4.txt -Starting gfid to path conversion -Path names of skipped files are available in the file /root/test_results/m3-4.txt_pathnames -WARNING: Unable to convert some GFIDs to Paths, GFIDs logged to /root/test_results/m3-4.txt_gfids -Use bash gfid_to_path.sh <brick-path> /root/test_results/m3-4.txt_gfids to convert those GFIDs to Path -Total Missing File Count : 126733 -``` -In such cases, an additional step is needed to convert those gfids to paths. -This can be used as shown below: -```sh - $bash gfid_to_path.sh <BRICK_PATH> <GFID_FILE> - BRICK_PATH - Full path of the brick. - GFID_FILE - OUTFILE_gfids got from gfind_missing_files.sh -``` -Things to keep in mind when running the tool -============================================ -1. Running this tool can result in a crawl of the backend filesystem at each - brick which can be intensive. To ensure there is no impact on ongoing I/O on - RHS volumes, we recommend that this tool be run at a low I/O scheduling class - (best-effort) and priority. -```sh -$ionice -c 2 -p <pid of gfind_missing_files.sh> -``` - -2. We do not recommend interrupting the tool when it is running - (e.g. by doing CTRL^C). It is better to wait for the tool to finish - execution. In case it is interupted, manually unmount the Slave Volume. -```sh - umount <MOUNT_POINT> -``` diff --git a/doc/tools/glusterfind.md b/doc/tools/glusterfind.md deleted file mode 100644 index b70c229ddf4..00000000000 --- a/doc/tools/glusterfind.md +++ /dev/null @@ -1,148 +0,0 @@ -# glusterfind - A tool to find Modified files/dirs - -A tool which helps to get full/incremental list of files/dirs from GlusterFS Volume using Changelog/Find. In Gluster volumes, detecting the modified files is challenging. Readdir on a directory leads to multiple network calls since files in a directory are distributed accross nodes. - -This tool should be run in one of the node, which will get Volume info and gets the list of nodes and brick paths. For each brick, it spawns the process and runs crawler command in respective node. Crawler will be run in brick FS(xfs, ext4 etc) and not in Gluster Mount. Crawler generates output file with the list of files modified after last run or after the session creation. - -## Session Management - -Create a glusterfind session to remember the time when last sync or processing complete. For example, your backup application runs every day and gets incremental results on each run. The tool maintains session in `$GLUSTERD_WORKDIR/glusterfind/`, for each session it creates and directory and creates a sub directory with Volume name. (Default working directory is /var/lib/glusterd, in some systems this location may change. To find Working dir location run `grep working-directory /etc/glusterfs/glusterd.vol` or `grep working-directory /usr/local/etc/glusterfs/glusterd.vol` if source install) - -For example, if the session name is "backup" and volume name is "datavol", then the tool creates `$GLUSTERD_WORKDIR/glusterfind/backup/datavol`. Now onwards we refer this directory as `$SESSION_DIR`. - - create => pre => post => [delete] - -Once the session is created, we can run the tool with two steps Pre and Post. To collect the list of modified files after the create time or last run time, we need to call pre command. Pre command finds the modified files and generates output file. Consumer can check the exit code of pre command and start processing those files. As a post processing step run the post command to update the session time as per latest run. - -For example, backup utility runs Pre command and gets the list of files/directories changed. Sync those files to backup target and inform to glusterfind by calling Post command. - -At the end of Pre command, `$SESSION_DIR/status.pre` status file will get created. Pre status file stores the time when current crawl is started, and get all the files/dirs modified till that time. Once Post is called, `$SESSION_DIR/status.pre` will be renamed to `$SESSION_DIR/status`. content of this file will be used as start time for the next crawl. - -During Pre, we can force the tool to do full find instead of incremental find. Tool uses `find` command in brick backend to get list of files/dirs. - -When `glusterfind create`, in that node it generates ssh key($GLUSTERD_WORKDIR/glusterfind.secret.pem) and distributes to all Peers via Glusterd. Once ssh key is distributed in Trusted pool, tool can run ssh commands and copy files from other Volume nodes. - -When `glusterfind pre` is run, it internally runs `gluster volume info` to get list of nodes and respective brick paths. For each brick, it calls respective node agents via ssh to find the modified files/dirs which are local them. Once each node agents generates output file, glusterfind collects all the files via scp and merges it into given output file. - -When `glusterfind post` is run, it renames `$SESSION_DIR/status.pre` file to `$SESSION_DIR/status`. - -## Changelog Mode and GFID to Path conversion - -Incremental find uses Changelogs to get the list of GFIDs modified/created. Any application expects file path instead of GFID. Their is no standard/easy way to convert from GFID to Path. - -If we set build-pgfid option in Volume GlusterFS starts recording each files parent directory GFID as xattr in file on any ENTRY fop. - - trusted.pgfid.<GFID>=NUM_LINKS - -To convert from GFID to path, we can mount Volume with aux-gfid-mount option, and get Path information by a getfattr query. - - getfattr -n glusterfs.ancestry.path -e text /mnt/datavol/.gfid/<GFID> - -This approach is slow, for a requested file gets parent GFID via xattr and reads that directory to gets the file which is having same inode number as of GFID file. To improve the performance, glusterfind uses build-pgfid option, but instead of using getfattr on mount it gets the details from brick backend. glusterfind collects all parent GFIDs at once and starts crawling each directory. Instead of processing one GFID to Path conversion, it gets inode numbers of all input GFIDs and filter while reading parent directory. - -Above method is fast compared to `find -samefile` since it crawls only required directories to find files with same inode number as GFID file. But pgfid information only available when a lookup is made or any ENTRY fop to a file after enabling build-pgfid. The files created before build-pgfid enable will not get converted to path from GFID with this approach. - -Tool collects the list of GFIDs failed to convert with above method and does a full crawl to convert it to path. Find command is used to crawl entire namespace. Instead of calling find command for every GFID, glusterfind uses an efficient way to convert all GFID to path with single call to `find` command. - -## Usage - -### Create the session - - glusterfind create SESSION_NAME VOLNAME [--force] - glusterfind create --help - -Where, SESSION_NAME is any name without space to identify when run second time. When a node is added to Volume then the tool expects ssh keys to be copied to new node(s) also. Run Create command with `--force` to distribute keys again. - -Examples, - - glusterfind create --help - glusterfind create backup datavol - glusterfind create antivirus_scanner datavol - glusterfind create backup datavol --force - -### Pre Command - - glusterfind pre SESSION_NAME VOLUME_NAME OUTFILE - glusterfind pre --help - -We need not specify Volume name since session already has the details. List of files will be populated in OUTFILE. - -To trigger the full find, call the pre command with `--full` argument. Multiple crawlers are available for incremental find, we can choose crawl type with `--crawl` argument. - -Examples, - - glusterfind pre backup datavol /root/backup.txt - glusterfind pre backup datavol /root/backup.txt --full - - # Changelog based crawler, works only for incremental - glusterfind pre backup datavol /root/backup.txt --crawler=changelog - - # Find based crawler, works for both full and incremental - glusterfind pre backup datavol /root/backup.txt --crawler=brickfind - -Output file contains list of files/dirs relative to the Volume mount, if we need to prefix with any path to have absolute path then, - - glusterfind pre backup datavol /root/backup.txt --file-prefix=/mnt/datavol/ - -### List Command - -To get the list of sessions and respective session time, - - glusterfind list [--session SESSION_NAME] [--volume VOLUME_NAME] - -Examples, - - glusterfind list - glusterfind list --session backup - -Example output, - - SESSION VOLUME SESSION TIME - --------------------------------------------------------------------------- - backup datavol 2015-03-04 17:35:34 - -### Post Command - - glusterfind post SESSION_NAME VOLUME_NAME - -Examples, - - glusterfind post backup datavol - -### Delete Command - - glusterfind delete SESSION_NAME VOLUME_NAME - -Examples, - - glusterfind delete backup datavol - - -## Adding more Crawlers - -Adding more crawlers is very simple, Add an entry in `$GLUSTERD_WORKDIR/glusterfind.conf`. glusterfind can choose your crawler using `--crawl` argument. - - [crawlers] - changelog=/usr/libexec/glusterfs/glusterfind/changelog.py - brickfind=/usr/libexec/glusterfs/glusterfind/brickfind.py - -For example, if you have a multithreaded brick crawler, say `parallelbrickcrawl` add it to the conf file. - - [crawlers] - changelog=/usr/libexec/glusterfs/glusterfind/changelog.py - brickfind=/usr/libexec/glusterfs/glusterfind/brickfind.py - parallelbrickcrawl=/root/parallelbrickcrawl - -Custom crawler can be executable script/binary which accepts volume name, brick path, output_file and start time(and optional debug flag) - -For example, - - /root/parallelbrickcrawl SESSION_NAME VOLUME BRICK_PATH OUTFILE START_TIME [--debug] - -Where `START_TIME` is in unix epoch format, `START_TIME` will be zero for full find. - -## Known Issues - -1. Deleted files will not get listed, since we can't convert GFID to Path if file/dir is deleted. -2. Only new name will get listed if Renamed. -3. All hardlinks will get listed. |
