diff options
author | dormando <dormando@rydia.net> | 2020-11-10 22:20:10 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2020-11-11 21:23:35 -0800 |
commit | 2251d98cd7ecb7dd4b2f58fe9b97f5799eb39edc (patch) | |
tree | 089383cc7b09fdf7b98e778b354ce612200cf8bd /extstore.c | |
parent | 19aac5aeca5aaf588dc58d5c04264c6be14ff7c0 (diff) | |
download | memcached-2251d98cd7ecb7dd4b2f58fe9b97f5799eb39edc.tar.gz |
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!
Diffstat (limited to 'extstore.c')
-rw-r--r-- | extstore.c | 21 |
1 files changed, 19 insertions, 2 deletions
@@ -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; } |