Skip to content

Commit

Permalink
unix: Don't fail on FreeBSD running ZFS (#461)
Browse files Browse the repository at this point in the history
* unix: Don't fail on FreeBSD running ZFS

ZFS doesn't support posix_fallocate() so libqb IPC or RB would
always fail with EINVAL.

As there seems to be no prospect of a more useful return code,
trap it in a QB_BSD #ifdef. That way if we do have actual errors
in the posix_fallocate() call the Linux tests should still find them.

Also, stick a small sleep in the test_ipc_disconnect_after_created
test to allow the server to shutdown before killing it with SIGTERM
and causing a test failure. all the other uses of it seem to have this
sleep!
  • Loading branch information
chrissie-c authored Mar 17, 2022
1 parent f510634 commit 2d03793
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 23 deletions.
71 changes: 49 additions & 22 deletions lib/unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,44 @@ open_mmap_file(char *path, uint32_t file_flags)
return open(path, file_flags, 0600);
}

#if defined(QB_BSD) || !defined(HAVE_POSIX_FALLOCATE)
static int local_fallocate(int fd, size_t bytes)
{
long page_size = sysconf(_SC_PAGESIZE);
long write_size = QB_MIN(page_size, bytes);
char *buffer = NULL;
int i;
size_t written;

if (page_size < 0) {
goto error_exit;
}
buffer = calloc(1, write_size);
if (buffer == NULL) {
goto error_exit;
}

for (i = 0; i < (bytes / write_size); i++) {
retry_write:
written = write(fd, buffer, write_size);
if (written == -1 && errno == EINTR) {
goto retry_write;
}
if (written != write_size) {
free(buffer);
errno = ENOSPC;
goto error_exit;
}
}
free(buffer);

return 0;

error_exit:
return -1;
}
#endif

int32_t
qb_sys_mmap_file_open(char *path, const char *file, size_t bytes,
uint32_t file_flags)
Expand Down Expand Up @@ -132,6 +170,16 @@ qb_sys_mmap_file_open(char *path, const char *file, size_t bytes,
if (res == EINTR) {
qb_util_log(LOG_DEBUG, "got EINTR trying to allocate file %s, retrying...", path);
continue;
#ifdef QB_BSD
} else if (res == EINVAL) { /* posix_fallocate() fails on ZFS
https://lists.freebsd.org/pipermail/freebsd-current/2018-February/068448.html */
qb_util_log(LOG_DEBUG, "posix_fallocate returned EINVAL - running on ZFS?");
if (file_flags & O_CREAT) {
if (local_fallocate(fd, bytes)) {
goto unlink_exit;
}
}
#endif
} else if (res != 0) {
errno = res;
res = -1 * res;
Expand All @@ -142,30 +190,9 @@ qb_sys_mmap_file_open(char *path, const char *file, size_t bytes,
} while (fallocate_retry > 0);
#else
if (file_flags & O_CREAT) {
long page_size = sysconf(_SC_PAGESIZE);
long write_size = QB_MIN(page_size, bytes);
if (page_size < 0) {
res = -errno;
if (local_fallocate(fd, bytes)) {
goto unlink_exit;
}
buffer = calloc(1, write_size);
if (buffer == NULL) {
res = -ENOMEM;
goto unlink_exit;
}
for (i = 0; i < (bytes / write_size); i++) {
retry_write:
written = write(fd, buffer, write_size);
if (written == -1 && errno == EINTR) {
goto retry_write;
}
if (written != write_size) {
res = -ENOSPC;
free(buffer);
goto unlink_exit;
}
}
free(buffer);
}
#endif /* HAVE_POSIX_FALLOCATE */

Expand Down
2 changes: 1 addition & 1 deletion tests/check_ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1959,8 +1959,8 @@ test_ipc_disconnect_after_created(void)
ck_assert_int_eq(res, -ENOTCONN);
}
ck_assert_int_eq(QB_FALSE, qb_ipcc_is_connected(conn));

qb_ipcc_disconnect(conn);
sleep(1); /* Give it time to stop */
kill_server(pid);
}

Expand Down

0 comments on commit 2d03793

Please sign in to comment.