From 2251d98cd7ecb7dd4b2f58fe9b97f5799eb39edc Mon Sep 17 00:00:00 2001 From: dormando Date: Tue, 10 Nov 2020 22:20:10 -0800 Subject: extstore: use fcntl locking on disk file if you accidentally start memcached with the same options twice, extstore is initiated before the listener sockets and will happily truncate its own file. So this avoids that. Keep in mind any other process can still wipe the file clean! --- extstore.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'extstore.c') diff --git a/extstore.c b/extstore.c index 9e2a981..8f32f51 100644 --- a/extstore.c +++ b/extstore.c @@ -253,15 +253,32 @@ void *extstore_init(struct extstore_conf_file *fh, struct extstore_conf *cf, e->page_size = cf->page_size; uint64_t temp_page_count = 0; for (f = fh; f != NULL; f = f->next) { - f->fd = open(f->file, O_RDWR | O_CREAT | O_TRUNC, 0644); + f->fd = open(f->file, O_RDWR | O_CREAT, 0644); if (f->fd < 0) { *res = EXTSTORE_INIT_OPEN_FAIL; #ifdef EXTSTORE_DEBUG - perror("open"); + perror("extstore open"); #endif free(e); return NULL; } + // use an fcntl lock to help avoid double starting. + struct flock lock; + lock.l_type = F_WRLCK; + lock.l_start = 0; + lock.l_whence = SEEK_SET; + lock.l_len = 0; + if (fcntl(f->fd, F_SETLK, &lock) < 0) { + *res = EXTSTORE_INIT_OPEN_FAIL; + free(e); + return NULL; + } + if (ftruncate(f->fd, 0) < 0) { + *res = EXTSTORE_INIT_OPEN_FAIL; + free(e); + return NULL; + } + temp_page_count += f->page_count; f->offset = 0; } -- cgit v1.2.1