Two Writers One Offset

Two independent processes append audit lines to the same file. Each runs this, once per line:

int fd = open("audit.log", O_WRONLY | O_CREAT, 0644);
off_t end = lseek(fd, 0, SEEK_END);
pwrite(fd, line, len, end);
close(fd);

Under load the log ends up with fewer lines than were written, and some lines are half-overwritten by others. What is the defect and the fix?

A

Both processes create the file, so each gets its own inode and the second open() replaces the first. Add O_EXCL so only one writer owns the file.

B

Reading the end offset and writing at it are two separate steps, so both processes can observe the same end and then write over each other. Open with O_APPEND and use write(): the kernel repositions to end-of-file and writes as one atomic step.

C

The writes are only in the page cache, so one process's data is evicted before the other's lseek can see it. Add O_SYNC to the open() so each line is on disk before the next offset is computed.

D

pwrite() ignores the file offset the process just established, so it always writes at offset 0. Use write() after the lseek() instead.