MCPcopy Create free account
hub / github.com/F-Stack/f-stack / clusterLockConfig

Function clusterLockConfig

app/redis-6.2.6/src/cluster.c:395–441  ·  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

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

Callers 1

clusterInitFunction · 0.85

Calls 2

closeFunction · 0.70
flockClass · 0.50

Tested by

no test coverage detected