0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <stdio.h>
0035 #include <stdlib.h>
0036 #include <string.h>
0037 #include <errno.h>
0038 #include <regex.h>
0039 #include <utlist.h>
0040 #include <unistd.h>
0041 #include <signal.h>
0042
0043 #include <ndebug.h>
0044 #include <atmi.h>
0045 #include <atmi_int.h>
0046 #include <typed_buf.h>
0047 #include <ndrstandard.h>
0048 #include <ubf.h>
0049 #include <ubfutil.h>
0050 #include <cconfig.h>
0051 #include "exsinglesv.h"
0052 #include <fcntl.h>
0053 #include <singlegrp.h>
0054 #include <Exfields.h>
0055 #include <nstdutil.h>
0056
0057
0058 #define MAX_LOCKS 2
0059 #define DATA_SIZE 24
0060 #define DATA_FOR_CRC 16
0061 #define PING_READ_CRC_ERR -2
0062 #define PING_NO_FILE -3
0063
0064
0065
0066
0067
0068
0069 typedef struct
0070 {
0071 int fd;
0072 char lockfile[PATH_MAX+1];
0073 } ndrx_exsinglesv_filelock_t;
0074
0075
0076
0077
0078
0079
0080 exprivate ndrx_exsinglesv_filelock_t M_locks[MAX_LOCKS] = {
0081 {.fd=EXFAIL, .lockfile=""},
0082 {.fd=EXFAIL, .lockfile=""}
0083 };
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 expublic int ndrx_exsinglesv_file_chkpid(int lock_no, char *lockfile)
0094 {
0095 int ret = EXSUCCEED;
0096 struct flock lck;
0097
0098 memset(&lck, 0, sizeof(lck));
0099
0100 lck.l_whence = SEEK_SET;
0101 lck.l_start = 0;
0102 lck.l_len = 1;
0103 lck.l_type = F_WRLCK;
0104
0105 TP_LOG(log_debug, "Checking (%d) [%s] lock status...", lock_no, lockfile);
0106
0107 if ( EXSUCCEED!=fcntl(M_locks[lock_no].fd, F_GETLK, &lck))
0108 {
0109 TP_LOG(log_info, "Failed to fcntl F_GETLK on [%s]: %s",
0110 lockfile, strerror(errno));
0111 EXFAIL_OUT(ret);
0112 }
0113
0114
0115
0116
0117 if (lck.l_type!=F_UNLCK)
0118 {
0119 TP_LOG(log_error, "ERROR ! Lock file [%s] locked by other process (pid=%d)",
0120 lockfile, (int)lck.l_pid);
0121 EXFAIL_OUT(ret);
0122 }
0123
0124 out:
0125 return ret;
0126 }
0127
0128
0129
0130
0131
0132
0133
0134 expublic int ndrx_exsinglesv_file_lock(int lock_no, char *lockfile)
0135 {
0136 int ret = EXSUCCEED;
0137 struct flock lck;
0138
0139 memset(&lck, 0, sizeof(lck));
0140
0141 lck.l_whence = SEEK_SET;
0142 lck.l_start = 0;
0143 lck.l_len = 1;
0144 lck.l_type = F_WRLCK;
0145
0146 TP_LOG(log_debug, "Trying to lock file (%d) [%s]", lock_no, lockfile);
0147
0148
0149 if (EXFAIL==(M_locks[lock_no].fd = open(lockfile, O_RDWR|O_CREAT, 0666)))
0150 {
0151 TP_LOG(log_error, "Failed to open lock file [%s]: %s",
0152 lockfile, strerror(errno));
0153 ret=NDRX_LOCKE_FILE;
0154 goto out;
0155 }
0156
0157
0158 if (EXFAIL==fcntl(M_locks[lock_no].fd, F_SETLK, &lck))
0159 {
0160 if (EACCES==errno || EAGAIN==errno)
0161 {
0162
0163 fcntl(M_locks[lock_no].fd, F_GETLK, &lck);
0164
0165 TP_LOG(log_info, "Failed to lock file [%s]: %s (pid=%d)",
0166 lockfile, strerror(errno), (int)lck.l_pid);
0167 ret=NDRX_LOCKE_BUSY;
0168 goto out;
0169 }
0170 else
0171 {
0172 TP_LOG(log_error, "Failed to lock file [%s]: %s",
0173 lockfile, strerror(errno));
0174 ret=NDRX_LOCKE_LOCK;
0175 goto out;
0176 }
0177 }
0178
0179 NDRX_STRCPY_SAFE(M_locks[lock_no].lockfile, lockfile);
0180
0181 out:
0182
0183
0184 if (EXSUCCEED!=ret && M_locks[lock_no].fd!=EXFAIL)
0185 {
0186 close(M_locks[lock_no].fd);
0187 M_locks[lock_no].fd = EXFAIL;
0188 }
0189 return ret;
0190 }
0191
0192
0193
0194
0195
0196
0197 expublic int ndrx_exsinglesv_file_unlock(int lock_no)
0198 {
0199 int ret = EXSUCCEED;
0200 struct flock lock;
0201
0202 if (EXFAIL==M_locks[lock_no].fd)
0203 {
0204 TP_LOG(log_error, "Lock file [%s] is not locked",
0205 M_locks[lock_no].lockfile);
0206 ret=NDRX_LOCKE_NOLOCK;
0207 goto out;
0208 }
0209
0210 lock.l_type = F_UNLCK;
0211 lock.l_whence = SEEK_SET;
0212 lock.l_start = 0;
0213 lock.l_len = 1;
0214
0215 if (fcntl(M_locks[lock_no].fd, F_SETLK, &lock) == -1) {
0216 TP_LOG(log_error, "Failed to unlock [%s]: %s",
0217 M_locks[lock_no].lockfile, strerror(errno));
0218 ret=NDRX_LOCKE_LOCK;
0219 goto out;
0220 }
0221
0222 out:
0223
0224
0225 close(M_locks[lock_no].fd);
0226 M_locks[lock_no].fd = EXFAIL;
0227
0228 return ret;
0229 }
0230
0231
0232
0233
0234
0235
0236
0237 expublic int ndrx_exsinglesv_sg_is_locked(ndrx_locksm_ctx_t *lock_ctx, int force_chk)
0238 {
0239 int ret=EXFALSE;
0240 UBFH *p_ub = NULL;
0241 long tmp, rsplen;
0242 char svcnm[MAXTIDENT+1]={EXEOS};
0243 int locked_by_stat;
0244 char lckstatus;
0245 long last_refresh;
0246 long their_sequence;
0247 int is_net_rply;
0248 int i;
0249 ndrx_exsinglesv_lockent_t ent;
0250
0251
0252 lock_ctx->pshm=ndrx_sg_get(ndrx_G_exsinglesv_conf.procgrp_lp_no);
0253 if (NULL==lock_ctx->pshm)
0254 {
0255 TP_LOG(log_error, "Failed to get singleton process group: %d",
0256 ndrx_G_exsinglesv_conf.procgrp_lp_no);
0257 EXFAIL_OUT(ret);
0258 }
0259
0260
0261 ndrx_sg_load(&lock_ctx->local, lock_ctx->pshm);
0262
0263 ret = ndrx_sg_is_locked(ndrx_G_exsinglesv_conf.procgrp_lp_no, NULL, 0);
0264
0265
0266 if (EXTRUE!=ret)
0267 {
0268 TP_LOG(log_info, "Group %d is not locked by shm",
0269 ndrx_G_exsinglesv_conf.procgrp_lp_no);
0270 goto out;
0271 }
0272
0273 if (!(lock_ctx->local.flags & NDRX_SG_VERIFY) && !force_chk)
0274 {
0275 TP_LOG(log_info, "Group %d verification is not required",
0276 ndrx_G_exsinglesv_conf.procgrp_lp_no);
0277 goto out;
0278 }
0279
0280
0281 for (i=0; i<CONF_NDRX_NODEID_COUNT; i++)
0282 {
0283 int locked_by_stat=EXFALSE;
0284 last_refresh = 0;
0285
0286 if (lock_ctx->local.sg_nodes[i])
0287 {
0288 if (lock_ctx->local.sg_nodes[i]==G_atmi_env.our_nodeid)
0289 {
0290 continue;
0291 }
0292 TP_LOG(log_debug, "Checking node [%d]...",
0293 lock_ctx->local.sg_nodes[i]);
0294
0295 if (NULL!=p_ub)
0296 {
0297 tpfree((char *)p_ub);
0298 p_ub = NULL;
0299 }
0300
0301
0302 ret=EXSUCCEED;
0303 if (!ndrx_G_exsinglesv_conf.noremote)
0304 {
0305 p_ub = (UBFH *)tpalloc("UBF", NULL, 1024);
0306
0307 if (NULL==p_ub)
0308 {
0309 TP_LOG(log_error, "Failed to allocate UBF");
0310 EXFAIL_OUT(ret);
0311 }
0312
0313
0314
0315 tmp = ndrx_G_exsinglesv_conf.procgrp_lp_no;
0316 if (EXSUCCEED!=Bchg(p_ub, EX_COMMAND, 0, NDRX_SGCMD_QUERY, 0L)
0317 || EXSUCCEED!=Bchg(p_ub, EX_PROCGRP_NO, 0, (char *)&tmp, 0L))
0318 {
0319 TP_LOG(log_error, "Failed to setup request buffer: %s",
0320 Bstrerror(Berror));
0321 EXFAIL_OUT(ret);
0322 }
0323
0324 tpsblktime(ndrx_G_exsinglesv_conf.svc_timeout, TPBLK_NEXT);
0325
0326
0327 snprintf(svcnm, sizeof(svcnm), NDRX_SVC_SGREM, (long)lock_ctx->local.sg_nodes[i],
0328 ndrx_G_exsinglesv_conf.procgrp_lp_no);
0329 TP_LOG(log_debug, "Checking with [%s] group %d lock status", svcnm,
0330 ndrx_G_exsinglesv_conf.procgrp_lp_no);
0331
0332 ret = tpcall(svcnm, (char*)p_ub, 0L, (char **)&p_ub, &rsplen, TPNOTRAN);
0333 }
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348 if (EXSUCCEED!=ret || ndrx_G_exsinglesv_conf.noremote)
0349 {
0350 int log_lev = log_error;
0351
0352
0353 if (EXSUCCEED!=ret)
0354 {
0355 if (TPESVCFAIL==tperrno)
0356 {
0357
0358 ndrx_tplogprintubf(log_error, "svc error response", p_ub);
0359 }
0360 else if (TPENOENT==tperrno)
0361 {
0362 log_lev = log_debug;
0363 }
0364
0365 TP_LOG(log_lev, "Failed to call [%s]: %s - falling back to disk check",
0366 svcnm, tpstrerror(tperrno));
0367
0368
0369 ret=EXSUCCEED;
0370 }
0371
0372
0373 if (EXSUCCEED!=ndrx_exsinglesv_ping_read(lock_ctx->local.sg_nodes[i], &ent))
0374 {
0375 TP_LOG(log_error, "Failed to ping lock file [%s] for node %d"
0376 , ndrx_G_exsinglesv_conf.lockfile_2, (int)lock_ctx->local.sg_nodes[i]);
0377 userlog("Failed to ping lock file [%s] for node %d"
0378 , ndrx_G_exsinglesv_conf.lockfile_2, (int)lock_ctx->local.sg_nodes[i]);
0379 EXFAIL_OUT(ret);
0380 }
0381
0382
0383 last_refresh = ent.lock_time;
0384 their_sequence = ent.sequence;
0385 is_net_rply=EXFALSE;
0386 }
0387 else
0388 {
0389 ndrx_tplogprintubf(log_debug, "svc response", p_ub);
0390
0391 if (EXSUCCEED!=Bget(p_ub, EX_LCKSTATUS, 0, &lckstatus, 0L)
0392 || EXSUCCEED!=Bget(p_ub, EX_TSTAMP, 0, (char *)&last_refresh, 0L)
0393 || EXSUCCEED!=Bget(p_ub, EX_SEQUENCE, 0, (char *)&their_sequence, 0L))
0394 {
0395
0396 TP_LOG(log_error, "Failed to get EX_LCKSTATUS/EX_TSTAMP/EX_SEQUENCE from node %d: %s",
0397 (int)lock_ctx->local.sg_nodes[i], Bstrerror(Berror));
0398 EXFAIL_OUT(ret);
0399 }
0400
0401 if (EXTRUE==lckstatus)
0402 {
0403 locked_by_stat=EXTRUE;
0404 }
0405
0406 is_net_rply=EXTRUE;
0407 }
0408
0409
0410 if (locked_by_stat)
0411 {
0412 TP_LOG(log_error, "Node %d is locked according to network status. "
0413 "Their refresh time: %ld, our time: %ld - UNLOCKING local group %d",
0414 (int)lock_ctx->local.sg_nodes[i], last_refresh, lock_ctx->local.last_refresh,
0415 ndrx_G_exsinglesv_conf.procgrp_lp_no);
0416 userlog("Node %d is locked according to network status. "
0417 "Their refresh time: %ld, our time: %ld - UNLOCKING local group %d",
0418 (int)lock_ctx->local.sg_nodes[i], last_refresh, lock_ctx->local.last_refresh,
0419 ndrx_G_exsinglesv_conf.procgrp_lp_no);
0420
0421 ndrx_sg_unlock(lock_ctx->pshm, NDRX_SG_RSN_NETLOCK);
0422 EXFAIL_OUT(ret);
0423 }
0424
0425 if (their_sequence>=lock_ctx->local.sequence)
0426 {
0427 TP_LOG(log_error, "Node %d has higher sequence than us. "
0428 "their seq: %ld, our seq: %ld, their refresh time: %ld, our time: %ld - UNLOCKING local group %d. Source: %s",
0429 (int)lock_ctx->local.sg_nodes[i], their_sequence, lock_ctx->local.sequence, last_refresh, lock_ctx->local.last_refresh,
0430 ndrx_G_exsinglesv_conf.procgrp_lp_no, is_net_rply?"network":"disk");
0431 userlog("Node %d has higher sequence than us. "
0432 "their seq: %ld, our seq: %ld, their refresh time: %ld, our time: %ld - UNLOCKING local group %d. Source: %s",
0433 (int)lock_ctx->local.sg_nodes[i], their_sequence, lock_ctx->local.sequence, last_refresh, lock_ctx->local.last_refresh,
0434 ndrx_G_exsinglesv_conf.procgrp_lp_no, is_net_rply?"network":"disk");
0435
0436 if (is_net_rply)
0437 {
0438 ndrx_sg_unlock(lock_ctx->pshm, NDRX_SG_RSN_NETSEQ);
0439 }
0440 else
0441 {
0442 ndrx_sg_unlock(lock_ctx->pshm, NDRX_SG_RSN_FSEQ);
0443 }
0444
0445 EXFAIL_OUT(ret);
0446 }
0447 }
0448 else
0449 {
0450
0451 break;
0452 }
0453 }
0454
0455
0456 ret=EXTRUE;
0457
0458
0459 out:
0460
0461 if (NULL!=p_ub)
0462 {
0463 tpfree((char *)p_ub);
0464 }
0465
0466 return ret;
0467 }
0468
0469
0470
0471
0472
0473
0474
0475 expublic int ndrx_exsinglesv_ping_do(ndrx_locksm_ctx_t *lock_ctx)
0476 {
0477 int fd=EXFAIL;
0478 struct stat st;
0479 int ret=EXSUCCEED;
0480 ssize_t bytes_written;
0481 struct flock lock;
0482 size_t fsize = DATA_SIZE*CONF_NDRX_NODEID_COUNT*2;
0483 ndrx_exsinglesv_lockent_t ent;
0484 int i, copy;
0485 char data_block[DATA_SIZE];
0486
0487
0488
0489
0490
0491
0492 for (copy=0; copy<2; copy++)
0493 {
0494 size_t offset= DATA_SIZE * CONF_NDRX_NODEID_COUNT * copy
0495 + DATA_SIZE*(G_atmi_env.our_nodeid-1);
0496
0497 fd = open(ndrx_G_exsinglesv_conf.lockfile_2, O_RDWR | O_CREAT, 0660);
0498
0499 if (EXFAIL==fd)
0500 {
0501 TP_LOG(log_error, "copy %d: Failed to open [%s]: %s",
0502 copy, ndrx_G_exsinglesv_conf.lockfile_2, strerror(errno));
0503 EXFAIL_OUT(ret);
0504 }
0505
0506
0507 lock.l_type = F_WRLCK;
0508 lock.l_whence = SEEK_SET;
0509 lock.l_start = 0;
0510
0511
0512 lock.l_len = 0;
0513
0514 if (fcntl(fd, F_SETLKW, &lock) == -1)
0515 {
0516 TP_LOG(log_error, "copy %d: Failed to write-lock [%s] (fd=%d) file: %s",
0517 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, strerror(errno));
0518 EXFAIL_OUT(ret);
0519 }
0520
0521 if (fstat(fd, &st) == -1)
0522 {
0523 TP_LOG(log_error, "copy %d: Failed to stat [%s] (fd=%d) file: %s",
0524 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, strerror(errno));
0525 EXFAIL_OUT(ret);
0526 }
0527
0528
0529 if (st.st_size == 0)
0530 {
0531 if (ftruncate(fd, fsize) == -1)
0532 {
0533 TP_LOG(log_error, "copy %d: Truncate [%s] (fd=%d) to %d bytes failed: %s",
0534 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, fsize, strerror(errno));
0535 EXFAIL_OUT(ret);
0536 }
0537
0538
0539 memset(data_block, 0, DATA_FOR_CRC);
0540 ent.crc32=ndrx_Crc32_ComputeBuf(0, (unsigned char *)data_block, DATA_FOR_CRC);
0541 ent.crc32 = htonll(ent.crc32);
0542 memcpy(data_block+DATA_FOR_CRC, &ent.crc32, sizeof(ent.crc32));
0543
0544
0545 for (i=0; i<CONF_NDRX_NODEID_COUNT*2; i++)
0546 {
0547 size_t init_offset=DATA_SIZE * i;
0548
0549 if (lseek(fd, init_offset, SEEK_SET) == -1)
0550 {
0551 TP_LOG(log_error, "copy %d: lseek [%s] (fd=%d) to offset %d bytes failed: %s",
0552 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, init_offset, strerror(errno));
0553 EXFAIL_OUT(ret);
0554 }
0555
0556 bytes_written = write(fd, data_block, DATA_SIZE);
0557
0558
0559 if (DATA_SIZE!=bytes_written)
0560 {
0561 TP_LOG(log_error, "copy %d, write [%s] (fd=%d) of %d bytes (wrote %zd) failed: %s",
0562 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, DATA_SIZE,
0563 bytes_written, strerror(errno));
0564 EXFAIL_OUT(ret);
0565 }
0566 else
0567 {
0568 TP_LOG(log_debug, "copy %d: Wrote %zd bytes at offset %d", copy, bytes_written, offset);
0569 }
0570 }
0571 }
0572
0573 if (lseek(fd, offset, SEEK_SET) == -1)
0574 {
0575 TP_LOG(log_error, "copy %d: lseek [%s] (fd=%d) to offset %d bytes failed: %s",
0576 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, offset, strerror(errno));
0577 EXFAIL_OUT(ret);
0578 }
0579
0580
0581
0582 ent.lock_time = htonll(lock_ctx->new_refresh);
0583 ent.sequence = htonll(lock_ctx->new_sequence);
0584
0585
0586 memcpy(data_block, &ent.lock_time, sizeof(ent.lock_time));
0587 memcpy(data_block+sizeof(ent.lock_time), &ent.sequence, sizeof(ent.sequence));
0588 ent.crc32=ndrx_Crc32_ComputeBuf(0, (unsigned char *)data_block, DATA_FOR_CRC);
0589
0590
0591 TP_LOG(log_info, "copy %d: writting nodeid=%d group=%d "
0592 "refresh=%ld sequence=%ld crc32=%lx",
0593 copy, G_atmi_env.our_nodeid, ndrx_G_exsinglesv_conf.procgrp_lp_no,
0594 (long)lock_ctx->new_refresh, (long)lock_ctx->new_sequence, (long)ent.crc32);
0595
0596 ent.crc32 = htonll(ent.crc32);
0597 memcpy(data_block+DATA_FOR_CRC, &ent.crc32, sizeof(ent.crc32));
0598
0599 bytes_written = write(fd, data_block, DATA_SIZE);
0600
0601
0602 if (DATA_SIZE!=bytes_written)
0603 {
0604 TP_LOG(log_error, "copy %d: write [%s] (fd=%d) of %d bytes (wrote %zd) failed: %s",
0605 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, DATA_SIZE,
0606 bytes_written, strerror(errno));
0607 EXFAIL_OUT(ret);
0608 }
0609 else
0610 {
0611 TP_LOG(log_debug, "copy %d: Wrote %zd bytes at offset %d",
0612 copy, bytes_written, offset);
0613 }
0614
0615
0616 if (EXSUCCEED!=fsync(fd))
0617 {
0618 TP_LOG(log_error, "copy %d: fsync [%s] (fd=%d) failed: %s",
0619 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, strerror(errno));
0620 EXFAIL_OUT(ret);
0621 }
0622
0623
0624 lock.l_type = F_UNLCK;
0625 if (fcntl(fd, F_SETLK, &lock) == -1)
0626 {
0627 TP_LOG(log_error, "copy %d: fcntl unlock [%s] (fd=%d) failed: %s",
0628 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, strerror(errno));
0629 EXFAIL_OUT(ret);
0630 }
0631
0632 if (EXFAIL!=fd)
0633 {
0634 close(fd);
0635 fd=EXFAIL;
0636 }
0637 }
0638
0639 out:
0640
0641 if (EXFAIL!=fd)
0642 {
0643 close(fd);
0644 }
0645
0646 return ret;
0647 }
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660 exprivate int ndrx_exsinglesv_ping_read_int(int copy, int nodeid, ndrx_exsinglesv_lockent_t *p_ent)
0661 {
0662 int ret = EXSUCCEED;
0663 int fd;
0664 struct flock lock;
0665 ssize_t bytes_read;
0666 size_t offset=DATA_SIZE * CONF_NDRX_NODEID_COUNT * copy + DATA_SIZE*(nodeid-1);
0667 char data_block[DATA_SIZE];
0668 uint64_t crc32_calc;
0669
0670
0671 fd = open(ndrx_G_exsinglesv_conf.lockfile_2, O_RDONLY);
0672 if (EXFAIL==fd)
0673 {
0674 TP_LOG(log_error, "Failed to open [%s]: %s",
0675 ndrx_G_exsinglesv_conf.lockfile_2, strerror(errno));
0676
0677
0678 if (ENOENT==errno)
0679 {
0680 ret=PING_NO_FILE;
0681 goto out;
0682 }
0683
0684 EXFAIL_OUT(ret);
0685 }
0686
0687 lock.l_type = F_RDLCK;
0688 lock.l_whence = SEEK_SET;
0689 lock.l_start = 0;
0690 lock.l_len = 0;
0691
0692 TP_LOG(log_debug, "Acquring read lock on fd %d", fd);
0693
0694 if (fcntl(fd, F_SETLKW, &lock) == EXFAIL)
0695 {
0696 TP_LOG(log_error, "copy %d: Failed to read lock [%s] (fd=%d) file: %s",
0697 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, strerror(errno));
0698 EXFAIL_OUT(ret);
0699 }
0700
0701 TP_LOG(log_debug, "Read locked on fd %d", fd);
0702
0703 if (lseek(fd, offset, SEEK_SET) == -1)
0704 {
0705 TP_LOG(log_error, "copy %d: lseek [%s] (fd=%d) to offset %d bytes failed: %s",
0706 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, offset, strerror(errno));
0707 EXFAIL_OUT(ret);
0708 }
0709
0710 bytes_read = read(fd, data_block, DATA_SIZE);
0711 if (bytes_read != DATA_SIZE)
0712 {
0713 TP_LOG(log_error, "copy %d: read [%s] (fd=%d) of %d bytes (wrote %zd) failed: %s",
0714 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, DATA_SIZE,
0715 bytes_read, strerror(errno));
0716 EXFAIL_OUT(ret);
0717 }
0718 else
0719 {
0720 TP_LOG(log_debug, "copy %d: Read %zd bytes at offset %d: for node: %d (fd=%d)",
0721 copy, bytes_read, offset, nodeid, fd);
0722 }
0723
0724
0725 lock.l_type = F_UNLCK;
0726 if (fcntl(fd, F_SETLK, &lock) == -1)
0727 {
0728 TP_LOG(log_error, "copy %d: fcntl unlock [%s] (fd=%d) failed: %s",
0729 copy, ndrx_G_exsinglesv_conf.lockfile_2, fd, strerror(errno));
0730 EXFAIL_OUT(ret);
0731 }
0732
0733
0734 memcpy(&p_ent->lock_time, data_block, sizeof(p_ent->lock_time));
0735 memcpy(&p_ent->sequence, data_block+sizeof(p_ent->lock_time), sizeof(p_ent->sequence));
0736 memcpy(&p_ent->crc32, data_block+DATA_FOR_CRC, sizeof(p_ent->crc32));
0737
0738
0739 p_ent->lock_time = ntohll(p_ent->lock_time);
0740 p_ent->crc32 = ntohll(p_ent->crc32);
0741 p_ent->sequence = ntohll(p_ent->sequence);
0742
0743 TP_LOG(log_info, "copy %d: got nodeid=%d group=%d "
0744 "refresh=%lu sequence=%lu crc32=%lx",
0745 copy, nodeid, ndrx_G_exsinglesv_conf.procgrp_lp_no,
0746 (long)p_ent->lock_time, (long)p_ent->sequence, (long)p_ent->crc32);
0747
0748 crc32_calc = ndrx_Crc32_ComputeBuf(0, (unsigned char *)data_block, DATA_FOR_CRC);
0749
0750 if (p_ent->crc32!=crc32_calc)
0751 {
0752 TP_LOG(log_warn, "copy %d: CRC32 mismatch (disk: %lx calc: %lx) file [%s] offset: %d", copy,
0753 (long)p_ent->crc32, (long)crc32_calc, ndrx_G_exsinglesv_conf.lockfile_2, (int)offset);
0754 ret=PING_READ_CRC_ERR;
0755 }
0756
0757 out:
0758 if (EXFAIL!=fd)
0759 {
0760 close(fd);
0761 }
0762
0763 return ret;
0764 }
0765
0766
0767
0768
0769
0770
0771
0772 expublic int ndrx_exsinglesv_ping_read(int nodeid, ndrx_exsinglesv_lockent_t *p_ent)
0773 {
0774 int i, ret;
0775
0776 for (i=0; i<3; i++)
0777 {
0778 ret=ndrx_exsinglesv_ping_read_int(i<2?i:0, nodeid, p_ent);
0779
0780 if (ret==PING_READ_CRC_ERR)
0781 {
0782 continue;
0783 }
0784 else
0785 {
0786
0787 break;
0788 }
0789 }
0790
0791
0792 if (PING_READ_CRC_ERR==ret)
0793 {
0794 TP_LOG(log_error, "Failed to read ping lock file for node %d - corrupted file. "
0795 "Shutdown the cluster, remove lock file [%s] and boot again.",
0796 nodeid, ndrx_G_exsinglesv_conf.lockfile_2);
0797
0798 userlog("Failed to read ping lock file for node %d - corrupted file. "
0799 "Shutdown the cluster, remove lock file [%s] and boot again.",
0800 nodeid, ndrx_G_exsinglesv_conf.lockfile_2);
0801 EXFAIL_OUT(ret);
0802 }
0803
0804 out:
0805
0806 TP_LOG(log_info, "%s returns %d", __FUNCTION__, ret);
0807 return ret;
0808 }
0809
0810
0811
0812
0813
0814
0815
0816 expublic long ndrx_exsinglesv_sg_max_seq(ndrx_locksm_ctx_t *lock_ctx)
0817 {
0818 int ret=EXSUCCEED;
0819 long seq_max=0;
0820 int i;
0821 ndrx_exsinglesv_lockent_t ent;
0822
0823 for (i=0; i<CONF_NDRX_NODEID_COUNT; i++)
0824 {
0825 if (lock_ctx->local.sg_nodes[i])
0826 {
0827 TP_LOG(log_debug, "Checking node [%d]...",
0828 lock_ctx->local.sg_nodes[i]);
0829
0830 ret = ndrx_exsinglesv_ping_read(lock_ctx->local.sg_nodes[i], &ent);
0831
0832
0833 if (ret==PING_NO_FILE)
0834 {
0835
0836 ret=0;
0837 break;
0838 }
0839 else if (EXSUCCEED!=ret)
0840 {
0841 TP_LOG(log_error, "Failed to distinguish current max sequence number for node %d",
0842 (int)lock_ctx->local.sg_nodes[i]);
0843 EXFAIL_OUT(ret);
0844 }
0845
0846 if (ent.sequence > seq_max)
0847 {
0848 seq_max = ent.sequence;
0849 }
0850 }
0851 }
0852
0853 out:
0854 TP_LOG(log_info, "returns %d, max sequence %ld", ret, seq_max);
0855
0856 if (EXSUCCEED==ret)
0857 {
0858 return seq_max;
0859 }
0860 else
0861 {
0862 return ret;
0863 }
0864 }
0865
0866