MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / clusterLockConfig

Function clusterLockConfig

src/cluster.cpp:412–456  ·  view source on GitHub ↗

Lock the cluster config using flock(), and leaks the file descriptor used to * acquire the lock so that the file will be locked forever. * * This works because we always update nodes.conf with a new version * in-place, reopening the file, and writing to it in place (later adjusting * the length with ftruncate()). * * On success C_OK is returned, otherwise an error is logged and * the funct

Source from the content-addressed store, hash-verified

410 * On success C_OK is returned, otherwise an error is logged and
411 * the function returns C_ERR to signal a lock was not acquired. */
412int clusterLockConfig(char *filename) {
413/* flock() does not exist on Solaris
414 * and a fcntl-based solution won't help, as we constantly re-open that file,
415 * which will release _all_ locks anyway
416 */
417#if !defined(__sun)
418 /* To lock it, we need to open the file in a way it is created if
419 * it does not exist, otherwise there is a race condition with other
420 * processes. */
421 int fd = open(filename,O_WRONLY|O_CREAT|O_CLOEXEC,0644);
422 if (fd == -1) {
423 serverLog(LL_WARNING,
424 "Can't open %s in order to acquire a lock: %s",
425 filename, strerror(errno));
426 return C_ERR;
427 }
428
429 if (flock(fd,LOCK_EX|LOCK_NB) == -1) {
430 if (errno == EWOULDBLOCK) {
431 serverLog(LL_WARNING,
432 "Sorry, the cluster configuration file %s is already used "
433 "by a different KeyDB Cluster node. Please make sure that "
434 "different nodes use different cluster configuration "
435 "files.", filename);
436 } else {
437 serverLog(LL_WARNING,
438 "Impossible to lock %s: %s", filename, strerror(errno));
439 }
440 close(fd);
441 return C_ERR;
442 }
443 /* Lock acquired: leak the 'fd' by not closing it, so that we'll retain the
444 * lock to the file as long as the process exists.
445 *
446 * After fork, the child process will get the fd opened by the parent process,
447 * we need save `fd` to `cluster_config_file_lock_fd`, so that in redisFork(),
448 * it will be closed in the child process.
449 * If it is not closed, when the main process is killed -9, but the child process
450 * (redis-aof-rewrite) is still alive, the fd(lock) will still be held by the
451 * child process, and the main process will fail to get lock, means fail to start. */
452 g_pserver->cluster_config_file_lock_fd = fd;
453#endif /* __sun */
454
455 return C_OK;
456}
457
458/* Derives our ports to be announced in the cluster bus. */
459void deriveAnnouncedPorts(int *announced_port, int *announced_pport,

Callers 1

clusterInitFunction · 0.85

Calls 1

serverLogFunction · 0.85

Tested by

no test coverage detected