START
|
- check D, F
- |
- <--------------------------------------'|
- Nothing F, D both ENOENT |
- F: ENOENT |
- D: ENOENT |
- duct: not not reading anything |
- | |
- |`---------------------. |
- | | duct times out waiting for F |
- V innd creates F | duct exits |
- | V |
- Noduct GO TO Dropped |
- F: innd writing |
- D: ENOENT |
- duct: not running or not reading anything |
- | |
- | |
- ,-->--+ <---------------------------------'|
- | | duct opens F F exists |
- | | D ENOENT |
+ ,-->--. check F, D
+ | | |
+ | | |
+ | | <----------------<---------------------------------'|
+ | | F exists |
+ | | D ENOENT |
+ | | duct opens F |
| V |
| Normal |
| F: innd writing, duct reading |
| F == D: innd writing, duct reading both exist |
^ | |
| | duct unlinks F |
- | V |
- | Moved <----+------------<--'|
- | F: ENOENT | F ENOENT |
- | D: innd writing, duct reading | D exists |
- | | | |
- | | duct requests flush of feed | |
- | | (others can too, harmlessly) | |
- | V | |
- | Flushing | |
- | F: ENOENT | |
- | D: innd flushing, duct reading | |
- | | | |
- | | inndcomm flush fails | |
- | |`-------------------------->---------' |
- | | |
+ | | <-----------<-------------<--'|
+ | | open D F ENOENT |
+ | | if exists |
+ | | |
+ | V <---------------------. |
+ | Moved | |
+ | F: ENOENT | |
+ | D: innd writing, duct reading; or ENOENT | |
+ | | | |
+ | | duct requests flush of feed | |
+ | | (others can too, harmlessly) | |
+ | V | |
+ | Flushing | |
+ | F: ENOENT | |
+ | D: innd flushing, duct; or ENOENT | |
+ | | | |
+ | | inndcomm flush fails | |
+ | |`-------------------------->------------------' |
+ | | |
| | inndcomm reports no such site |
| |`---------------------------------------------------- | -.
- | | | |
+ | | | |
| | innd finishes writing D, creates F | |
| | inndcomm reports flush successful | |
| | | |
| V | |
| Separated <----------------' |
| F: innd writing F!=D /
- | D: duct reading both exist /
+ | D: duct reading; or ENOENT both exist /
| | /
| | duct gets to the end of D /
| | duct opens F too /
return status;
}
+static void xunlink(const char *path, const char *what) {
+ int r= unlink(path);
+ if (r) sysdie("can't unlink %s %s", path, what);
+}
+
static void check_isreg(const struct stat *stab, const char *path,
const char *what) {
if (!S_ISREG(stab->st_mode))
if (r) sysdie("link feedfile %s to flushing file %s", feedfile, dut_path);
/* => Hardlinked */
- r= unlink(feedfile);
- if (r) sysdie("unlink old feedfile link %s", feedfile);
+ xunlink(feedfile, "old feedfile link");
/* => Moved */
spawn_inndcomm_flush(); /* => Flushing, sets sms to sm_FLUSHING */
/* See official state diagram at top of file. We implement
* this as follows:
- ================
- WAITING
- [Nothing/Noduct]
- poll for F
- ================
- |
- | TIMEOUT and no defer, no backlog
- |`--------------------------.
- | |
- | OPEN F SUCCEEDS | exit
- ,--------->| V
- | V =========
- | ======== (ESRCH)
- | NORMAL [Dropped]
- | [Normal] =========
- | main F tail
- | ========
- | |
- | | F IS SO BIG WE SHOULD FLUSH
- ^ | hardlink F to D
- | [Hardlinked]
- | | unlink F
- | | our handle onto F is now onto D
- | [Moved]
- | |
- | |<---------------------------------------------------.
+ .=======.
+ ||START||
+ `======='
+ |
+ | open F
+ |
+ | F ENOENT
+ |`---------------------------------------------------.
+ F OPEN OK | |
+ |`---------------- - - - |
+ D ENOENT | D EXISTS see OVERALL STATES diagram |
+ | for full startup logic |
+ ,--------->| |
+ | V |
+ | ============ try to |
+ | NORMAL open D |
+ | [Normal] |
+ | main F tail |
+ | ============ V
+ | | |
+ | | F IS SO BIG WE SHOULD FLUSH, OR TIMEOUT |
+ ^ | hardlink F to D |
+ | [Hardlinked] |
+ | | unlink F |
+ | | our handle onto F is now onto D |
+ | [Moved] |
+ | | |
+ | |<-------------------<---------------------<---------+
| | |
| | spawn inndcomm flush |
| V |
- | ========== |
+ | ================ |
| FLUSHING |
| [Flushing] |
- | main D tail |
- | ========== |
+ | main D tail/none |
+ | ================ |
| | |
| | INNDCOMM FLUSH FAILS ^
| |`----------------------->----------. |
| | | |
| | NO SUCH SITE V |
- ^ |`--------------->----. =========== |
- | | \ FLUSHFAIL |
- | | \ [Moved] |
- | | \ main D tail |
- | | \ =========== |
+ ^ |`--------------->----. ================ |
+ | | \ FLUSHFAIL |
+ | | \ [Moved] |
+ | | FLUSH OK \ main D tail/none |
+ | | open F \ ================ |
| | \ | |
| | \ | TIME TO RETRY |
- | | \ `----------------'
- | | FLUSH OK \
- | | open F \
- | V V
- | ============= ============
- | SEPARATED/ DROPPING/
- | flsh->fd>=0 flsh->fd>=0
- | [Separated] [Dropping]
- | main F idle main none
- | old D tail old D tail
- | ============= ============
- | | |
- ^ | EOF ON D | EOF ON D
- | V V
- | =============== ===============
- | SEPARATED/ DROPPING/
- | flsh->fd==-1 flsh->fd==-1
- | [Finishing] [Dropping]
- | main F tail main none
- | old D closed old D closed
- | =============== ===============
- | | |
- | | ALL D PROCESSED | ALL D PROCESSED
- | V install defer as backlog V install defer as backlog
- ^ | close D | close D
+ |<--------'| ,---<---'\ `----------------'
+ | D NONE | | D NONE \
+ | | | \
+ | | | |
+ | | V |
+ | V | V
+ | ============= | ============
+ | SEPARATED/ | DROPPING/
+ | flsh->fd>=0 | flsh->fd>=0
+ | [Separated] | [Dropping]
+ | main F idle | main none
+ | old D tail | old D tail
+ | ============= | ============
+ | | | |
+ ^ | EOF ON D | | EOF ON D
+ | V | V
+ | =============== | ===============
+ | SEPARATED/ | DROPPING/
+ | flsh->fd==-1 V flsh->fd==-1
+ | [Finishing] | [Dropping]
+ | main F tail `. main none
+ | old D closed `. old D closed
+ | =============== `. ===============
+ | | `. |
+ | | ALL D PROCESSED `. | ALL D PROCESSED
+ | V install defer as backlog `. V install defer as backlog
+ ^ | close D \| close D
| | unlink D | unlink D
+ | | | unlink lock
| | | exit
`----------' V
==========
open_defer(); /* so that we will later close it and rename it */
break;
case 2:
- if (unlink(path_defer))
- sysdie("could not unlink stale defer file link %s (presumably"
- " hardlink to backlog file)", path_defer);
+ xunlink(path_defer, "stale defer file link"
+ " (presumably hardlink to backlog file)");
break;
default:
die("defer file %s has unexpected link count %d",
if (samefile(&stab_d, &stab_f)) {
debug("startup: F==D => Hardlinked");
- r= unlink(path_flushing);
- if (r) sysdie("unlink feed file %s during startup", feedfile);
+ xunlink(path_flushing, "feed file (during startup)");
found_moved:
debug(" => Moved");
startup_set_input_file(file_d);
close_defer();
- if (unlink(path_flushing))
- sysdie("could not unlink old flushing file %s", path_flushing);
+ xunlink(path_flushing, "old flushing file");
if (sms==sm_DROPPING) {
if (search_backlog_file()) {
return;
}
notice("feed dropped and our work is complete");
- r= unlink(path_lock);
- if (r) sysdie("unlink lockfile for old feed %s", path_lock);
+ xunlink(path_lock, "lockfile for old feed");
exit(0);
}
if (main_input_file && main_input_file->readable_callback)
filemon_callback(main_input_file);
});
-
+
#define DEBUGF_IPF(wh) " " #wh "=%p/%s:ip=%ld,off=%ld,fd=%d%s" \
#define DEBUG_IPF(sh) \
wh##_input_file, debug_ipf_path(wh##_input_file), \