2. Development

2.1. Can I use relative paths instead of absolute paths when opening journaled files and journals with functions jf_file_open and jf_journal_open?
2.2. How can I guess which options was selected at configure/compile time?
2.3. My project is using libjf, how can I register it?
2.4. I would like to port libjf to some different operating system, will you merge my fixes & patches?
2.5. Can I use libjf in a multi-threaded program?
2.6. How can I recover journaled files after a crash?
2.7. How can I recover a damaged journal and its journaled files after a crash?
2.8. Are text files supported?
2.9. What's the difference between fsync and jf_journal_commit?

2.1. Can I use relative paths instead of absolute paths when opening journaled files and journals with functions jf_file_open and jf_journal_open?

Yes, you may, but some precautions must be taken: when you re-use a journaled file created using a relative path you must start your program from the same current dir of creation time because journal file keeps original relative path. Some issues may happen if you have symbolic link in your path. As a general rule, it's strongly suggested to use absolute paths if journal file and related journaled files are not stored in the same directory.

2.2. How can I guess which options was selected at configure/compile time?

Commands:

strings /opt/libjf/lib/libjf | grep 'feature/'
	
retrieve which features are active in compiled library.

2.3. My project is using libjf, how can I register it?

Compile a linked_proj_record.xml record and send to

2.4. I would like to port libjf to some different operating system, will you merge my fixes & patches?

After revision, your porting fixes and patches will be merged in main distribution and you will be cited as a contributor. A specific forum has been created on SourceForge.net for porting related discussions.

2.5. Can I use libjf in a multi-threaded program?

Yes, you may, but libjf objects are not multi-thread self protected: it's your responsibility avoid the same set of objects (a journal and its related journaled files) is accessed at the same time by two or more threads. At this time the support is guaranteed only by reentrant code: there is no static variable with a little exception can be ignored in most cases (it's a trivial counter used only when --enable-crash-simul build option is active).

2.6. How can I recover journaled files after a crash?

Your application must set recovery_enabled = TRUE in jf_journal_opts_s struct passed to jf_journal_open function. This type of recovery is called "automatic recovery" and is not enabled by default (you must set it).

2.7. How can I recover a damaged journal and its journaled files after a crash?

Sometimes, the crash may damage the journal itself, but some errors can be fixed with a "forced recovery". Your application must set recovery_enabled = TRUE and recovery_damaged_journal = TRUE in jf_journal_opts_s struct passed to jf_journal_open function. This type of recovery is called "automatic forced recovery" and is not enabled by default (you must set it).

2.8. Are text files supported?

Yes, libjf supports binary files as well as text files, but there are some differences between standard ANSI C streams and libjf journaled text files:

  • UNIX text files, with records delimited by NL ("\n") must be opened like binary files, for example: "r", "w".

  • DOS text files, with records delimited by CRLF ("\r\n") must be opened with a special ("DOS mode") flag, for example: "rD", "wD".

Please pay attention: libjf will translate CRLF ("\r\n") to NL ("\n") when reading and NL ("\n") to CRLF ("\r\n") when writing a file opened appending flag "D" to "open mode" string. If the journaled file is not opened specifying "DOS mode", the application has to deal with "\r\n" sequences. The semantic of libjf is slightly different from standard ANSI C streams: your application can deal with a file encoded for a different architecture without convert if before usage. For example, the configuration journaled file of your application might be encoded using "DOS mode" while running on DOS-like operating system or UNIX-like operating system. Additional encodings may be added in the future (MAC OS?) if someone will ask for them.

2.9. What's the difference between fsync and jf_journal_commit?

fsync synchronize the content of ONE file at a time, jf_journal_commit synchronize ALL the files at the same time preserving consistency in the event of an application or system crash.

2.1. Testing

2.1.1. Is there a case test procedure?
2.1.2. Where do case test scripts write journals, journaled files and standard files?
2.1.3. Is there a stress test procedure?
2.1.4. Stress test procedure is very slow, can I speed it up?

2.1.1. Is there a case test procedure?

Yes, sure: I'm spending half of the time in developing case tests! Use make check command to start case test procedure.

2.1.2. Where do case test scripts write journals, journaled files and standard files?

Default path is /tmp/libjf, but you can change it setting environment var TEST_TMP_PATH before configure operation; this is an example:

> export TEST_TMP_PATH=/tmp/foo/bar
> ./configure
	  

2.1.3. Is there a stress test procedure?

Yes, it runs case test trying all the available configurations. These are the commands to start it:

> ./configure
> cd tests
> ./stress_test.sh
	  

2.1.4. Stress test procedure is very slow, can I speed it up?

Stress test procedure may be very slow, especially if you set environment variable JF_JOURNAL_SYNC_TYPE to "1" and use safe synchronization. If your operating system (and kernel) supports it, you can reduce elapsed time, using a "TMPFS" filesystem. If you are riding GNU/linux 2.4+ with "TMPFS" feature active, you can create a "TMPFS" filesystem for your /tmp mount point inserting something like this in your /etc/fstab:

none   /tmp   tmpfs   defaults   0 0
	  
"TMPFS" is available on some flavor of UNIX systems.