Changeset 989 for vendor/current/ctdb/server
- Timestamp:
- Nov 25, 2016, 8:04:54 PM (9 years ago)
- Location:
- vendor/current/ctdb/server
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/ctdb/server/ctdb_control.c
r988 r989 716 716 return ctdb_control_db_transaction_cancel(ctdb, indata); 717 717 718 case CTDB_CONTROL_DB_PULL: 719 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_pulldb_ext)); 720 return ctdb_control_db_pull(ctdb, c, indata, outdata); 721 722 case CTDB_CONTROL_DB_PUSH_START: 723 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_pulldb_ext)); 724 return ctdb_control_db_push_start(ctdb, indata); 725 726 case CTDB_CONTROL_DB_PUSH_CONFIRM: 727 CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t)); 728 return ctdb_control_db_push_confirm(ctdb, indata, outdata); 729 718 730 default: 719 731 DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode)); -
vendor/current/ctdb/server/ctdb_daemon.c
r988 r989 44 44 #include "common/common.h" 45 45 #include "common/logging.h" 46 #include "common/pidfile.h" 46 47 47 48 struct ctdb_client_pid_list { … … 53 54 54 55 const char *ctdbd_pidfile = NULL; 56 static struct pidfile_context *ctdbd_pidfile_ctx = NULL; 55 57 56 58 static void daemon_incoming_packet(void *, struct ctdb_req_header *); … … 984 986 { 985 987 struct sockaddr_un addr; 988 int ret; 986 989 987 990 ctdb->daemon.sd = socket(AF_UNIX, SOCK_STREAM, 0); … … 994 997 strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path)-1); 995 998 996 /* First check if an old ctdbd might be running */997 if (connect(ctdb->daemon.sd,998 (struct sockaddr *)&addr, sizeof(addr)) == 0) {999 DEBUG(DEBUG_CRIT,1000 ("Something is already listening on ctdb socket '%s'\n",1001 ctdb->daemon.name));1002 goto failed;1003 }1004 1005 999 /* Remove any old socket */ 1006 unlink(ctdb->daemon.name); 1000 ret = unlink(ctdb->daemon.name); 1001 if (ret == 0) { 1002 DEBUG(DEBUG_WARNING, 1003 ("Removed stale socket %s\n", ctdb->daemon.name)); 1004 } else if (errno != ENOENT) { 1005 DEBUG(DEBUG_ERR, 1006 ("Failed to remove stale socket %s\n", ctdb->daemon.name)); 1007 return -1; 1008 } 1007 1009 1008 1010 set_close_on_exec(ctdb->daemon.sd); … … 1128 1130 static void ctdb_remove_pidfile(void) 1129 1131 { 1130 /* Only the main ctdbd's PID matches the SID */ 1131 if (ctdbd_pidfile != NULL && getsid(0) == getpid()) { 1132 if (unlink(ctdbd_pidfile) == 0) { 1133 DEBUG(DEBUG_NOTICE, ("Removed PID file %s\n", 1134 ctdbd_pidfile)); 1135 } else { 1136 DEBUG(DEBUG_WARNING, ("Failed to Remove PID file %s\n", 1137 ctdbd_pidfile)); 1138 } 1139 } 1140 } 1141 1142 static void ctdb_create_pidfile(pid_t pid) 1132 TALLOC_FREE(ctdbd_pidfile_ctx); 1133 } 1134 1135 static void ctdb_create_pidfile(TALLOC_CTX *mem_ctx) 1143 1136 { 1144 1137 if (ctdbd_pidfile != NULL) { 1145 FILE *fp;1146 1147 fp = fopen(ctdbd_pidfile, "w");1148 if (fp == NULL) {1149 DEBUG(DEBUG_ALERT,1150 ("Failed to open PID file %s\n",ctdbd_pidfile));1138 int ret = pidfile_create(mem_ctx, ctdbd_pidfile, 1139 &ctdbd_pidfile_ctx); 1140 if (ret != 0) { 1141 DEBUG(DEBUG_ERR, 1142 ("Failed to create PID file %s\n", 1143 ctdbd_pidfile)); 1151 1144 exit(11); 1152 1145 } 1153 1146 1154 fprintf(fp, "%d\n", pid);1155 fclose(fp);1156 1147 DEBUG(DEBUG_NOTICE, ("Created PID file %s\n", ctdbd_pidfile)); 1157 1148 atexit(ctdb_remove_pidfile); … … 1214 1205 int res, ret = -1; 1215 1206 struct tevent_fd *fde; 1207 1208 if (do_fork && fork()) { 1209 return 0; 1210 } 1211 1212 if (do_fork) { 1213 if (setsid() == -1) { 1214 ctdb_die(ctdb, "Failed to setsid()\n"); 1215 } 1216 close(0); 1217 if (open("/dev/null", O_RDONLY) != 0) { 1218 DEBUG(DEBUG_ALERT,(__location__ " Failed to setup stdin on /dev/null\n")); 1219 exit(11); 1220 } 1221 } 1222 ignore_signal(SIGPIPE); 1223 ignore_signal(SIGUSR1); 1224 1225 ctdb->ctdbd_pid = getpid(); 1226 DEBUG(DEBUG_ERR, ("Starting CTDBD (Version %s) as PID: %u\n", 1227 CTDB_VERSION_STRING, ctdb->ctdbd_pid)); 1228 ctdb_create_pidfile(ctdb); 1216 1229 1217 1230 /* create a unix domain stream socket to listen to */ … … 1222 1235 } 1223 1236 1224 if (do_fork && fork()) {1225 return 0;1226 }1227 1228 tdb_reopen_all(false);1229 1230 if (do_fork) {1231 if (setsid() == -1) {1232 ctdb_die(ctdb, "Failed to setsid()\n");1233 }1234 close(0);1235 if (open("/dev/null", O_RDONLY) != 0) {1236 DEBUG(DEBUG_ALERT,(__location__ " Failed to setup stdin on /dev/null\n"));1237 exit(11);1238 }1239 }1240 ignore_signal(SIGPIPE);1241 ignore_signal(SIGUSR1);1242 1243 ctdb->ctdbd_pid = getpid();1244 DEBUG(DEBUG_ERR, ("Starting CTDBD (Version %s) as PID: %u\n",1245 CTDB_VERSION_STRING, ctdb->ctdbd_pid));1246 ctdb_create_pidfile(ctdb->ctdbd_pid);1247 1248 1237 /* Make sure we log something when the daemon terminates. 1249 1238 * This must be the first exit handler to run (so the last to … … 1261 1250 1262 1251 ctdb->ev = tevent_context_init(NULL); 1252 if (ctdb->ev == NULL) { 1253 DEBUG(DEBUG_ALERT,("tevent_context_init() failed\n")); 1254 exit(1); 1255 } 1263 1256 tevent_loop_allow_nesting(ctdb->ev); 1264 1257 tevent_set_trace_callback(ctdb->ev, ctdb_tevent_trace, ctdb); … … 1846 1839 /* get a new event context */ 1847 1840 ctdb->ev = tevent_context_init(ctdb); 1841 if (ctdb->ev == NULL) { 1842 DEBUG(DEBUG_ALERT,("tevent_context_init() failed\n")); 1843 exit(1); 1844 } 1848 1845 tevent_loop_allow_nesting(ctdb->ev); 1849 1846 -
vendor/current/ctdb/server/ctdb_logging.c
r988 r989 282 282 /* We'll fail if stderr/stdout not already open; it's simpler. */ 283 283 old_stdout = dup(STDOUT_FILENO); 284 if (old_stdout < 0) { 285 DEBUG(DEBUG_ERR, ("Failed to dup stdout for child logging\n")); 286 return -1; 287 } 284 288 old_stderr = dup(STDERR_FILENO); 285 if (old_stdout < 0 || old_stderr < 0) { 286 DEBUG(DEBUG_ERR, ("Failed to dup stdout/stderr for child logging\n")); 289 if (old_stderr < 0) { 290 DEBUG(DEBUG_ERR, ("Failed to dup stderr for child logging\n")); 291 close(old_stdout); 287 292 return -1; 288 293 } -
vendor/current/ctdb/server/ctdb_recover.c
r988 r989 314 314 } 315 315 316 struct db_pull_state { 317 struct ctdb_context *ctdb; 318 struct ctdb_db_context *ctdb_db; 319 struct ctdb_marshall_buffer *recs; 320 uint32_t pnn; 321 uint64_t srvid; 322 uint32_t num_records; 323 }; 324 325 static int traverse_db_pull(struct tdb_context *tdb, TDB_DATA key, 326 TDB_DATA data, void *private_data) 327 { 328 struct db_pull_state *state = (struct db_pull_state *)private_data; 329 struct ctdb_marshall_buffer *recs; 330 331 recs = ctdb_marshall_add(state->ctdb, state->recs, 332 state->ctdb_db->db_id, 0, key, NULL, data); 333 if (recs == NULL) { 334 TALLOC_FREE(state->recs); 335 return -1; 336 } 337 state->recs = recs; 338 339 if (talloc_get_size(state->recs) >= 340 state->ctdb->tunable.rec_buffer_size_limit) { 341 TDB_DATA buffer; 342 int ret; 343 344 buffer = ctdb_marshall_finish(state->recs); 345 ret = ctdb_daemon_send_message(state->ctdb, state->pnn, 346 state->srvid, buffer); 347 if (ret != 0) { 348 TALLOC_FREE(state->recs); 349 return -1; 350 } 351 352 state->num_records += state->recs->count; 353 TALLOC_FREE(state->recs); 354 } 355 356 return 0; 357 } 358 359 int32_t ctdb_control_db_pull(struct ctdb_context *ctdb, 360 struct ctdb_req_control_old *c, 361 TDB_DATA indata, TDB_DATA *outdata) 362 { 363 struct ctdb_pulldb_ext *pulldb_ext; 364 struct ctdb_db_context *ctdb_db; 365 struct db_pull_state state; 366 int ret; 367 368 pulldb_ext = (struct ctdb_pulldb_ext *)indata.dptr; 369 370 ctdb_db = find_ctdb_db(ctdb, pulldb_ext->db_id); 371 if (ctdb_db == NULL) { 372 DEBUG(DEBUG_ERR,(__location__ " Unknown db 0x%08x\n", 373 pulldb_ext->db_id)); 374 return -1; 375 } 376 377 if (!ctdb_db_frozen(ctdb_db)) { 378 DEBUG(DEBUG_ERR, 379 ("rejecting ctdb_control_pull_db when not frozen\n")); 380 return -1; 381 } 382 383 if (ctdb_db->unhealthy_reason) { 384 /* this is just a warning, as the tdb should be empty anyway */ 385 DEBUG(DEBUG_WARNING, 386 ("db(%s) unhealty in ctdb_control_db_pull: %s\n", 387 ctdb_db->db_name, ctdb_db->unhealthy_reason)); 388 } 389 390 state.ctdb = ctdb; 391 state.ctdb_db = ctdb_db; 392 state.recs = NULL; 393 state.pnn = c->hdr.srcnode; 394 state.srvid = pulldb_ext->srvid; 395 state.num_records = 0; 396 397 if (ctdb_lockdb_mark(ctdb_db) != 0) { 398 DEBUG(DEBUG_ERR, 399 (__location__ " Failed to get lock on entire db - failing\n")); 400 return -1; 401 } 402 403 ret = tdb_traverse_read(ctdb_db->ltdb->tdb, traverse_db_pull, &state); 404 if (ret == -1) { 405 DEBUG(DEBUG_ERR, 406 (__location__ " Failed to get traverse db '%s'\n", 407 ctdb_db->db_name)); 408 ctdb_lockdb_unmark(ctdb_db); 409 return -1; 410 } 411 412 /* Last few records */ 413 if (state.recs != NULL) { 414 TDB_DATA buffer; 415 416 buffer = ctdb_marshall_finish(state.recs); 417 ret = ctdb_daemon_send_message(state.ctdb, state.pnn, 418 state.srvid, buffer); 419 if (ret != 0) { 420 TALLOC_FREE(state.recs); 421 ctdb_lockdb_unmark(ctdb_db); 422 return -1; 423 } 424 425 state.num_records += state.recs->count; 426 TALLOC_FREE(state.recs); 427 } 428 429 ctdb_lockdb_unmark(ctdb_db); 430 431 outdata->dptr = talloc_size(outdata, sizeof(uint32_t)); 432 if (outdata->dptr == NULL) { 433 DEBUG(DEBUG_ERR, (__location__ " Memory allocation error\n")); 434 return -1; 435 } 436 437 memcpy(outdata->dptr, (uint8_t *)&state.num_records, sizeof(uint32_t)); 438 outdata->dsize = sizeof(uint32_t); 439 440 return 0; 441 } 442 316 443 /* 317 444 push a bunch of records into a ltdb, filtering by rsn … … 406 533 ctdb_lockdb_unmark(ctdb_db); 407 534 return -1; 535 } 536 537 struct db_push_state { 538 struct ctdb_context *ctdb; 539 struct ctdb_db_context *ctdb_db; 540 uint64_t srvid; 541 uint32_t num_records; 542 bool failed; 543 }; 544 545 static void db_push_msg_handler(uint64_t srvid, TDB_DATA indata, 546 void *private_data) 547 { 548 struct db_push_state *state = talloc_get_type( 549 private_data, struct db_push_state); 550 struct ctdb_marshall_buffer *recs; 551 struct ctdb_rec_data_old *rec; 552 int i, ret; 553 554 if (state->failed) { 555 return; 556 } 557 558 recs = (struct ctdb_marshall_buffer *)indata.dptr; 559 rec = (struct ctdb_rec_data_old *)&recs->data[0]; 560 561 DEBUG(DEBUG_INFO, ("starting push of %u records for dbid 0x%x\n", 562 recs->count, recs->db_id)); 563 564 for (i=0; i<recs->count; i++) { 565 TDB_DATA key, data; 566 struct ctdb_ltdb_header *hdr; 567 568 key.dptr = &rec->data[0]; 569 key.dsize = rec->keylen; 570 data.dptr = &rec->data[key.dsize]; 571 data.dsize = rec->datalen; 572 573 if (data.dsize < sizeof(struct ctdb_ltdb_header)) { 574 DEBUG(DEBUG_CRIT,(__location__ " bad ltdb record\n")); 575 goto failed; 576 } 577 578 hdr = (struct ctdb_ltdb_header *)data.dptr; 579 /* Strip off any read only record flags. 580 * All readonly records are revoked implicitely by a recovery. 581 */ 582 hdr->flags &= ~CTDB_REC_RO_FLAGS; 583 584 data.dptr += sizeof(*hdr); 585 data.dsize -= sizeof(*hdr); 586 587 ret = ctdb_ltdb_store(state->ctdb_db, key, hdr, data); 588 if (ret != 0) { 589 DEBUG(DEBUG_ERR, 590 (__location__ " Unable to store record\n")); 591 goto failed; 592 } 593 594 rec = (struct ctdb_rec_data_old *)(rec->length + (uint8_t *)rec); 595 } 596 597 DEBUG(DEBUG_DEBUG, ("finished push of %u records for dbid 0x%x\n", 598 recs->count, recs->db_id)); 599 600 state->num_records += recs->count; 601 return; 602 603 failed: 604 state->failed = true; 605 } 606 607 int32_t ctdb_control_db_push_start(struct ctdb_context *ctdb, TDB_DATA indata) 608 { 609 struct ctdb_pulldb_ext *pulldb_ext; 610 struct ctdb_db_context *ctdb_db; 611 struct db_push_state *state; 612 int ret; 613 614 pulldb_ext = (struct ctdb_pulldb_ext *)indata.dptr; 615 616 ctdb_db = find_ctdb_db(ctdb, pulldb_ext->db_id); 617 if (ctdb_db == NULL) { 618 DEBUG(DEBUG_ERR, 619 (__location__ " Unknown db 0x%08x\n", pulldb_ext->db_id)); 620 return -1; 621 } 622 623 if (!ctdb_db_frozen(ctdb_db)) { 624 DEBUG(DEBUG_ERR, 625 ("rejecting ctdb_control_db_push_start when not frozen\n")); 626 return -1; 627 } 628 629 if (ctdb_db->push_started) { 630 DEBUG(DEBUG_WARNING, 631 (__location__ " DB push already started for %s\n", 632 ctdb_db->db_name)); 633 634 /* De-register old state */ 635 state = (struct db_push_state *)ctdb_db->push_state; 636 if (state != NULL) { 637 srvid_deregister(ctdb->srv, state->srvid, state); 638 talloc_free(state); 639 ctdb_db->push_state = NULL; 640 } 641 } 642 643 state = talloc_zero(ctdb_db, struct db_push_state); 644 if (state == NULL) { 645 DEBUG(DEBUG_ERR, (__location__ " Memory allocation error\n")); 646 return -1; 647 } 648 649 state->ctdb = ctdb; 650 state->ctdb_db = ctdb_db; 651 state->srvid = pulldb_ext->srvid; 652 state->failed = false; 653 654 ret = srvid_register(ctdb->srv, state, state->srvid, 655 db_push_msg_handler, state); 656 if (ret != 0) { 657 DEBUG(DEBUG_ERR, 658 (__location__ " Failed to register srvid for db push\n")); 659 talloc_free(state); 660 return -1; 661 } 662 663 if (ctdb_lockdb_mark(ctdb_db) != 0) { 664 DEBUG(DEBUG_ERR, 665 (__location__ " Failed to get lock on entire db - failing\n")); 666 srvid_deregister(ctdb->srv, state->srvid, state); 667 talloc_free(state); 668 return -1; 669 } 670 671 ctdb_db->push_started = true; 672 ctdb_db->push_state = state; 673 674 return 0; 675 } 676 677 int32_t ctdb_control_db_push_confirm(struct ctdb_context *ctdb, 678 TDB_DATA indata, TDB_DATA *outdata) 679 { 680 uint32_t db_id; 681 struct ctdb_db_context *ctdb_db; 682 struct db_push_state *state; 683 684 db_id = *(uint32_t *)indata.dptr; 685 686 ctdb_db = find_ctdb_db(ctdb, db_id); 687 if (ctdb_db == NULL) { 688 DEBUG(DEBUG_ERR,(__location__ " Unknown db 0x%08x\n", db_id)); 689 return -1; 690 } 691 692 if (!ctdb_db_frozen(ctdb_db)) { 693 DEBUG(DEBUG_ERR, 694 ("rejecting ctdb_control_db_push_confirm when not frozen\n")); 695 return -1; 696 } 697 698 if (!ctdb_db->push_started) { 699 DEBUG(DEBUG_ERR, (__location__ " DB push not started\n")); 700 return -1; 701 } 702 703 if (ctdb_db->readonly) { 704 DEBUG(DEBUG_ERR, 705 ("Clearing the tracking database for dbid 0x%x\n", 706 ctdb_db->db_id)); 707 if (tdb_wipe_all(ctdb_db->rottdb) != 0) { 708 DEBUG(DEBUG_ERR, 709 ("Failed to wipe tracking database for 0x%x." 710 " Dropping read-only delegation support\n", 711 ctdb_db->db_id)); 712 ctdb_db->readonly = false; 713 tdb_close(ctdb_db->rottdb); 714 ctdb_db->rottdb = NULL; 715 ctdb_db->readonly = false; 716 } 717 718 while (ctdb_db->revokechild_active != NULL) { 719 talloc_free(ctdb_db->revokechild_active); 720 } 721 } 722 723 ctdb_lockdb_unmark(ctdb_db); 724 725 state = (struct db_push_state *)ctdb_db->push_state; 726 if (state == NULL) { 727 DEBUG(DEBUG_ERR, (__location__ " Missing push db state\n")); 728 return -1; 729 } 730 731 srvid_deregister(ctdb->srv, state->srvid, state); 732 733 outdata->dptr = talloc_size(outdata, sizeof(uint32_t)); 734 if (outdata->dptr == NULL) { 735 DEBUG(DEBUG_ERR, (__location__ " Memory allocation error\n")); 736 talloc_free(state); 737 ctdb_db->push_state = NULL; 738 return -1; 739 } 740 741 memcpy(outdata->dptr, (uint8_t *)&state->num_records, sizeof(uint32_t)); 742 outdata->dsize = sizeof(uint32_t); 743 744 talloc_free(state); 745 ctdb_db->push_started = false; 746 ctdb_db->push_state = NULL; 747 748 return 0; 408 749 } 409 750 … … 1033 1374 if (data.dsize < sizeof(struct ctdb_ltdb_header)) { 1034 1375 DEBUG(DEBUG_CRIT,(__location__ " bad ltdb record in indata\n")); 1376 talloc_free(records); 1035 1377 return -1; 1036 1378 } … … 1225 1567 DEBUG(DEBUG_CRIT, (__location__ " bad ltdb record " 1226 1568 "in indata\n")); 1569 talloc_free(records); 1227 1570 return -1; 1228 1571 } -
vendor/current/ctdb/server/ctdb_recoverd.c
r988 r989 253 253 uint32_t *force_rebalance_nodes; 254 254 struct ctdb_node_capabilities *caps; 255 bool frozen_on_inactive; 255 256 }; 256 257 … … 1782 1783 } 1783 1784 1785 setenv("CTDB_DBDIR_STATE", rec->ctdb->db_directory_state, 1); 1786 1784 1787 if (!ctdb_vfork_with_logging(state, rec->ctdb, "recovery", prog, nargs, 1785 1788 args, NULL, NULL, &state->pid)) { … … 1981 1984 1982 1985 DEBUG(DEBUG_NOTICE, (__location__ " Recovery - disabled recovery mode\n")); 1986 1987 /* execute the "recovered" event script on all nodes */ 1988 ret = run_recovered_eventscript(rec, nodemap, "do_recovery"); 1989 if (ret!=0) { 1990 DEBUG(DEBUG_ERR, (__location__ " Unable to run the 'recovered' event on cluster. Recovery process failed.\n")); 1991 return -1; 1992 } 1993 1994 DEBUG(DEBUG_NOTICE, (__location__ " Recovery - finished the recovered event\n")); 1983 1995 1984 1996 return 0; … … 2157 2169 do_takeover_run(rec, nodemap, false); 2158 2170 2159 /* execute the "recovered" event script on all nodes */2160 ret = run_recovered_eventscript(rec, nodemap, "do_recovery");2161 if (ret!=0) {2162 DEBUG(DEBUG_ERR, (__location__ " Unable to run the 'recovered' event on cluster. Recovery process failed.\n"));2163 goto fail;2164 }2165 2166 DEBUG(DEBUG_NOTICE, (__location__ " Recovery - finished the recovered event\n"));2167 2168 2171 /* send a message to all clients telling them that the cluster 2169 2172 has been reconfigured */ … … 2659 2662 } 2660 2663 2664 /* 2665 * handler for assigning banning credits 2666 */ 2667 static void banning_handler(uint64_t srvid, TDB_DATA data, void *private_data) 2668 { 2669 struct ctdb_recoverd *rec = talloc_get_type( 2670 private_data, struct ctdb_recoverd); 2671 uint32_t ban_pnn; 2672 2673 /* Ignore if we are not recmaster */ 2674 if (rec->ctdb->pnn != rec->recmaster) { 2675 return; 2676 } 2677 2678 if (data.dsize != sizeof(uint32_t)) { 2679 DEBUG(DEBUG_ERR, (__location__ "invalid data size %zu\n", 2680 data.dsize)); 2681 return; 2682 } 2683 2684 ban_pnn = *(uint32_t *)data.dptr; 2685 2686 ctdb_set_culprit_count(rec, ban_pnn, rec->nodemap->num); 2687 } 2661 2688 2662 2689 /* … … 3490 3517 return; 3491 3518 } 3492 ret = ctdb_ctrl_freeze(ctdb, CONTROL_TIMEOUT(), CTDB_CURRENT_NODE); 3519 } 3520 if (! rec->frozen_on_inactive) { 3521 ret = ctdb_ctrl_freeze(ctdb, CONTROL_TIMEOUT(), 3522 CTDB_CURRENT_NODE); 3493 3523 if (ret != 0) { 3494 DEBUG(DEBUG_ERR,(__location__ " Failed to freeze node in STOPPED or BANNED state\n")); 3524 DEBUG(DEBUG_ERR, 3525 (__location__ " Failed to freeze node " 3526 "in STOPPED or BANNED state\n")); 3495 3527 return; 3496 3528 } 3529 3530 rec->frozen_on_inactive = true; 3497 3531 } 3498 3532 … … 3503 3537 return; 3504 3538 } 3539 3540 rec->frozen_on_inactive = false; 3505 3541 3506 3542 /* If we are not the recmaster then do some housekeeping */ … … 3883 3919 3884 3920 rec->priority_time = timeval_current(); 3921 rec->frozen_on_inactive = false; 3885 3922 3886 3923 /* register a message port for sending memory dumps */ 3887 3924 ctdb_client_set_message_handler(ctdb, CTDB_SRVID_MEM_DUMP, mem_dump_handler, rec); 3925 3926 /* when a node is assigned banning credits */ 3927 ctdb_client_set_message_handler(ctdb, CTDB_SRVID_BANNING, 3928 banning_handler, rec); 3888 3929 3889 3930 /* register a message port for recovery elections */ -
vendor/current/ctdb/server/ctdb_recovery_helper.c
r988 r989 35 35 #include "client/client.h" 36 36 37 #define TIMEOUT() timeval_current_ofs(10, 0) 37 static int recover_timeout = 30; 38 39 #define NUM_RETRIES 3 40 41 #define TIMEOUT() timeval_current_ofs(recover_timeout, 0) 38 42 39 43 static void LOG(const char *fmt, ...) … … 64 68 } 65 69 70 static bool generic_recv(struct tevent_req *req, int *perr) 71 { 72 int err; 73 74 if (tevent_req_is_unix_error(req, &err)) { 75 if (perr != NULL) { 76 *perr = err; 77 } 78 return false; 79 } 80 81 return true; 82 } 83 84 static uint64_t rec_srvid = CTDB_SRVID_RECOVERY; 85 86 static uint64_t srvid_next(void) 87 { 88 rec_srvid += 1; 89 return rec_srvid; 90 } 91 66 92 /* 67 93 * Recovery database functions … … 81 107 uint32_t hash_size, bool persistent) 82 108 { 109 static char *db_dir_state = NULL; 83 110 struct recdb_context *recdb; 84 111 unsigned int tdb_flags; … … 89 116 } 90 117 118 if (db_dir_state == NULL) { 119 db_dir_state = getenv("CTDB_DBDIR_STATE"); 120 } 121 91 122 recdb->db_name = db_name; 92 123 recdb->db_id = db_id; 93 124 recdb->db_path = talloc_asprintf(recdb, "%s/recdb.%s", 94 dirname(discard_const(db_path)), 125 db_dir_state != NULL ? 126 db_dir_state : 127 dirname(discard_const(db_path)), 95 128 db_name); 96 129 if (recdb->db_path == NULL) { … … 113 146 } 114 147 148 static uint32_t recdb_id(struct recdb_context *recdb) 149 { 150 return recdb->db_id; 151 } 152 115 153 static const char *recdb_name(struct recdb_context *recdb) 116 154 { 117 155 return recdb->db_name; 156 } 157 158 static const char *recdb_path(struct recdb_context *recdb) 159 { 160 return recdb->db_path; 161 } 162 163 static struct tdb_context *recdb_tdb(struct recdb_context *recdb) 164 { 165 return recdb->db->tdb; 166 } 167 168 static bool recdb_persistent(struct recdb_context *recdb) 169 { 170 return recdb->persistent; 118 171 } 119 172 … … 141 194 142 195 /* fetch the existing record, if any */ 143 prev_data = tdb_fetch( state->recdb->db->tdb, key);196 prev_data = tdb_fetch(recdb_tdb(state->recdb), key); 144 197 145 198 if (prev_data.dptr != NULL) { … … 155 208 } 156 209 157 ret = tdb_store( state->recdb->db->tdb, key, data, TDB_REPLACE);210 ret = tdb_store(recdb_tdb(state->recdb), key, data, TDB_REPLACE); 158 211 if (ret != 0) { 159 212 return -1; … … 179 232 } 180 233 181 struct recdb_traverse_state { 182 struct ctdb_rec_buffer *recbuf; 183 uint32_t pnn; 184 uint32_t reqid; 185 bool persistent; 186 bool failed; 187 }; 188 189 static int recdb_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, 190 void *private_data) 191 { 192 struct recdb_traverse_state *state = 193 (struct recdb_traverse_state *)private_data; 234 /* This function decides which records from recdb are retained */ 235 static int recbuf_filter_add(struct ctdb_rec_buffer *recbuf, bool persistent, 236 uint32_t reqid, uint32_t dmaster, 237 TDB_DATA key, TDB_DATA data) 238 { 194 239 struct ctdb_ltdb_header *header; 195 240 int ret; … … 225 270 * data structures built from the various tdb-level records. 226 271 */ 227 if (!state->persistent && 228 data.dsize <= sizeof(struct ctdb_ltdb_header)) { 272 if (!persistent && data.dsize <= sizeof(struct ctdb_ltdb_header)) { 229 273 return 0; 230 274 } … … 232 276 /* update the dmaster field to point to us */ 233 277 header = (struct ctdb_ltdb_header *)data.dptr; 234 if (! state->persistent) {235 header->dmaster = state->pnn;278 if (!persistent) { 279 header->dmaster = dmaster; 236 280 header->flags |= CTDB_REC_FLAG_MIGRATED_WITH_DATA; 237 281 } 238 282 239 ret = ctdb_rec_buffer_add(state->recbuf, state->recbuf, state->reqid, 240 NULL, key, data); 283 ret = ctdb_rec_buffer_add(recbuf, recbuf, reqid, NULL, key, data); 284 if (ret != 0) { 285 return ret; 286 } 287 288 return 0; 289 } 290 291 struct recdb_records_traverse_state { 292 struct ctdb_rec_buffer *recbuf; 293 uint32_t dmaster; 294 uint32_t reqid; 295 bool persistent; 296 bool failed; 297 }; 298 299 static int recdb_records_traverse(struct tdb_context *tdb, 300 TDB_DATA key, TDB_DATA data, 301 void *private_data) 302 { 303 struct recdb_records_traverse_state *state = 304 (struct recdb_records_traverse_state *)private_data; 305 int ret; 306 307 ret = recbuf_filter_add(state->recbuf, state->persistent, 308 state->reqid, state->dmaster, key, data); 241 309 if (ret != 0) { 242 310 state->failed = true; … … 248 316 249 317 static struct ctdb_rec_buffer *recdb_records(struct recdb_context *recdb, 250 TALLOC_CTX *mem_ctx, uint32_t pnn) 251 { 252 struct recdb_traverse_state state; 253 int ret; 254 255 state.recbuf = ctdb_rec_buffer_init(mem_ctx, recdb->db_id); 318 TALLOC_CTX *mem_ctx, 319 uint32_t dmaster) 320 { 321 struct recdb_records_traverse_state state; 322 int ret; 323 324 state.recbuf = ctdb_rec_buffer_init(mem_ctx, recdb_id(recdb)); 256 325 if (state.recbuf == NULL) { 257 326 return NULL; 258 327 } 259 state. pnn = pnn;328 state.dmaster = dmaster; 260 329 state.reqid = 0; 261 state.persistent = recdb ->persistent;330 state.persistent = recdb_persistent(recdb); 262 331 state.failed = false; 263 332 264 ret = tdb_traverse_read(recdb->db->tdb, recdb_traverse, &state); 333 ret = tdb_traverse_read(recdb_tdb(recdb), recdb_records_traverse, 334 &state); 335 if (ret == -1 || state.failed) { 336 LOG("Failed to marshall recovery records for %s\n", 337 recdb_name(recdb)); 338 TALLOC_FREE(state.recbuf); 339 return NULL; 340 } 341 342 return state.recbuf; 343 } 344 345 struct recdb_file_traverse_state { 346 struct ctdb_rec_buffer *recbuf; 347 struct recdb_context *recdb; 348 TALLOC_CTX *mem_ctx; 349 uint32_t dmaster; 350 uint32_t reqid; 351 bool persistent; 352 bool failed; 353 int fd; 354 int max_size; 355 int num_buffers; 356 }; 357 358 static int recdb_file_traverse(struct tdb_context *tdb, 359 TDB_DATA key, TDB_DATA data, 360 void *private_data) 361 { 362 struct recdb_file_traverse_state *state = 363 (struct recdb_file_traverse_state *)private_data; 364 int ret; 365 366 ret = recbuf_filter_add(state->recbuf, state->persistent, 367 state->reqid, state->dmaster, key, data); 368 if (ret != 0) { 369 state->failed = true; 370 return ret; 371 } 372 373 if (ctdb_rec_buffer_len(state->recbuf) > state->max_size) { 374 ret = ctdb_rec_buffer_write(state->recbuf, state->fd); 375 if (ret != 0) { 376 LOG("Failed to collect recovery records for %s\n", 377 recdb_name(state->recdb)); 378 state->failed = true; 379 return ret; 380 } 381 382 state->num_buffers += 1; 383 384 TALLOC_FREE(state->recbuf); 385 state->recbuf = ctdb_rec_buffer_init(state->mem_ctx, 386 recdb_id(state->recdb)); 387 if (state->recbuf == NULL) { 388 state->failed = true; 389 return ENOMEM; 390 } 391 } 392 393 return 0; 394 } 395 396 static int recdb_file(struct recdb_context *recdb, TALLOC_CTX *mem_ctx, 397 uint32_t dmaster, int fd, int max_size) 398 { 399 struct recdb_file_traverse_state state; 400 int ret; 401 402 state.recbuf = ctdb_rec_buffer_init(mem_ctx, recdb_id(recdb)); 403 if (state.recbuf == NULL) { 404 return -1; 405 } 406 state.recdb = recdb; 407 state.mem_ctx = mem_ctx; 408 state.dmaster = dmaster; 409 state.reqid = 0; 410 state.persistent = recdb_persistent(recdb); 411 state.failed = false; 412 state.fd = fd; 413 state.max_size = max_size; 414 state.num_buffers = 0; 415 416 ret = tdb_traverse_read(recdb_tdb(recdb), recdb_file_traverse, &state); 265 417 if (ret == -1 || state.failed) { 266 418 TALLOC_FREE(state.recbuf); 419 return -1; 420 } 421 422 ret = ctdb_rec_buffer_write(state.recbuf, fd); 423 if (ret != 0) { 424 LOG("Failed to collect recovery records for %s\n", 425 recdb_name(recdb)); 426 TALLOC_FREE(state.recbuf); 427 return -1; 428 } 429 state.num_buffers += 1; 430 431 LOG("Wrote %d buffers of recovery records for %s\n", 432 state.num_buffers, recdb_name(recdb)); 433 434 return state.num_buffers; 435 } 436 437 /* 438 * Pull database from a single node 439 */ 440 441 struct pull_database_state { 442 struct tevent_context *ev; 443 struct ctdb_client_context *client; 444 struct recdb_context *recdb; 445 uint32_t pnn; 446 uint64_t srvid; 447 int num_records; 448 }; 449 450 static void pull_database_handler(uint64_t srvid, TDB_DATA data, 451 void *private_data); 452 static void pull_database_register_done(struct tevent_req *subreq); 453 static void pull_database_old_done(struct tevent_req *subreq); 454 static void pull_database_unregister_done(struct tevent_req *subreq); 455 static void pull_database_new_done(struct tevent_req *subreq); 456 457 static struct tevent_req *pull_database_send( 458 TALLOC_CTX *mem_ctx, 459 struct tevent_context *ev, 460 struct ctdb_client_context *client, 461 uint32_t pnn, uint32_t caps, 462 struct recdb_context *recdb) 463 { 464 struct tevent_req *req, *subreq; 465 struct pull_database_state *state; 466 struct ctdb_req_control request; 467 468 req = tevent_req_create(mem_ctx, &state, struct pull_database_state); 469 if (req == NULL) { 267 470 return NULL; 268 471 } 269 472 270 return state.recbuf; 473 state->ev = ev; 474 state->client = client; 475 state->recdb = recdb; 476 state->pnn = pnn; 477 state->srvid = srvid_next(); 478 479 if (caps & CTDB_CAP_FRAGMENTED_CONTROLS) { 480 subreq = ctdb_client_set_message_handler_send( 481 state, state->ev, state->client, 482 state->srvid, pull_database_handler, 483 req); 484 if (tevent_req_nomem(subreq, req)) { 485 return tevent_req_post(req, ev); 486 } 487 488 tevent_req_set_callback(subreq, pull_database_register_done, 489 req); 490 491 } else { 492 struct ctdb_pulldb pulldb; 493 494 pulldb.db_id = recdb_id(recdb); 495 pulldb.lmaster = CTDB_LMASTER_ANY; 496 497 ctdb_req_control_pull_db(&request, &pulldb); 498 subreq = ctdb_client_control_send(state, state->ev, 499 state->client, 500 pnn, TIMEOUT(), 501 &request); 502 if (tevent_req_nomem(subreq, req)) { 503 return tevent_req_post(req, ev); 504 } 505 tevent_req_set_callback(subreq, pull_database_old_done, req); 506 } 507 508 return req; 509 } 510 511 static void pull_database_handler(uint64_t srvid, TDB_DATA data, 512 void *private_data) 513 { 514 struct tevent_req *req = talloc_get_type_abort( 515 private_data, struct tevent_req); 516 struct pull_database_state *state = tevent_req_data( 517 req, struct pull_database_state); 518 struct ctdb_rec_buffer *recbuf; 519 int ret; 520 bool status; 521 522 if (srvid != state->srvid) { 523 return; 524 } 525 526 ret = ctdb_rec_buffer_pull(data.dptr, data.dsize, state, &recbuf); 527 if (ret != 0) { 528 LOG("Invalid data received for DB_PULL messages\n"); 529 return; 530 } 531 532 if (recbuf->db_id != recdb_id(state->recdb)) { 533 talloc_free(recbuf); 534 LOG("Invalid dbid:%08x for DB_PULL messages for %s\n", 535 recbuf->db_id, recdb_name(state->recdb)); 536 return; 537 } 538 539 status = recdb_add(state->recdb, ctdb_client_pnn(state->client), 540 recbuf); 541 if (! status) { 542 talloc_free(recbuf); 543 LOG("Failed to add records to recdb for %s\n", 544 recdb_name(state->recdb)); 545 return; 546 } 547 548 state->num_records += recbuf->count; 549 talloc_free(recbuf); 550 } 551 552 static void pull_database_register_done(struct tevent_req *subreq) 553 { 554 struct tevent_req *req = tevent_req_callback_data( 555 subreq, struct tevent_req); 556 struct pull_database_state *state = tevent_req_data( 557 req, struct pull_database_state); 558 struct ctdb_req_control request; 559 struct ctdb_pulldb_ext pulldb_ext; 560 int ret; 561 bool status; 562 563 status = ctdb_client_set_message_handler_recv(subreq, &ret); 564 TALLOC_FREE(subreq); 565 if (! status) { 566 LOG("failed to set message handler for DB_PULL for %s\n", 567 recdb_name(state->recdb)); 568 tevent_req_error(req, ret); 569 return; 570 } 571 572 pulldb_ext.db_id = recdb_id(state->recdb); 573 pulldb_ext.lmaster = CTDB_LMASTER_ANY; 574 pulldb_ext.srvid = state->srvid; 575 576 ctdb_req_control_db_pull(&request, &pulldb_ext); 577 subreq = ctdb_client_control_send(state, state->ev, state->client, 578 state->pnn, TIMEOUT(), &request); 579 if (tevent_req_nomem(subreq, req)) { 580 return; 581 } 582 tevent_req_set_callback(subreq, pull_database_new_done, req); 583 } 584 585 static void pull_database_old_done(struct tevent_req *subreq) 586 { 587 struct tevent_req *req = tevent_req_callback_data( 588 subreq, struct tevent_req); 589 struct pull_database_state *state = tevent_req_data( 590 req, struct pull_database_state); 591 struct ctdb_reply_control *reply; 592 struct ctdb_rec_buffer *recbuf; 593 int ret; 594 bool status; 595 596 status = ctdb_client_control_recv(subreq, &ret, state, &reply); 597 TALLOC_FREE(subreq); 598 if (! status) { 599 LOG("control PULL_DB failed for %s on node %u, ret=%d\n", 600 recdb_name(state->recdb), state->pnn, ret); 601 tevent_req_error(req, ret); 602 return; 603 } 604 605 ret = ctdb_reply_control_pull_db(reply, state, &recbuf); 606 talloc_free(reply); 607 if (ret != 0) { 608 tevent_req_error(req, ret); 609 return; 610 } 611 612 status = recdb_add(state->recdb, ctdb_client_pnn(state->client), 613 recbuf); 614 if (! status) { 615 talloc_free(recbuf); 616 tevent_req_error(req, EIO); 617 return; 618 } 619 620 state->num_records = recbuf->count; 621 talloc_free(recbuf); 622 623 LOG("Pulled %d records for db %s from node %d\n", 624 state->num_records, recdb_name(state->recdb), state->pnn); 625 626 tevent_req_done(req); 627 } 628 629 static void pull_database_new_done(struct tevent_req *subreq) 630 { 631 struct tevent_req *req = tevent_req_callback_data( 632 subreq, struct tevent_req); 633 struct pull_database_state *state = tevent_req_data( 634 req, struct pull_database_state); 635 struct ctdb_reply_control *reply; 636 uint32_t num_records; 637 int ret; 638 bool status; 639 640 status = ctdb_client_control_recv(subreq, &ret, state, &reply); 641 TALLOC_FREE(subreq); 642 if (! status) { 643 LOG("control DB_PULL failed for %s on node %u, ret=%d\n", 644 recdb_name(state->recdb), state->pnn, ret); 645 tevent_req_error(req, ret); 646 return; 647 } 648 649 ret = ctdb_reply_control_db_pull(reply, &num_records); 650 talloc_free(reply); 651 if (num_records != state->num_records) { 652 LOG("mismatch (%u != %u) in DB_PULL records for %s\n", 653 num_records, state->num_records, recdb_name(state->recdb)); 654 tevent_req_error(req, EIO); 655 return; 656 } 657 658 LOG("Pulled %d records for db %s from node %d\n", 659 state->num_records, recdb_name(state->recdb), state->pnn); 660 661 subreq = ctdb_client_remove_message_handler_send( 662 state, state->ev, state->client, 663 state->srvid, req); 664 if (tevent_req_nomem(subreq, req)) { 665 return; 666 } 667 tevent_req_set_callback(subreq, pull_database_unregister_done, req); 668 } 669 670 static void pull_database_unregister_done(struct tevent_req *subreq) 671 { 672 struct tevent_req *req = tevent_req_callback_data( 673 subreq, struct tevent_req); 674 struct pull_database_state *state = tevent_req_data( 675 req, struct pull_database_state); 676 int ret; 677 bool status; 678 679 status = ctdb_client_remove_message_handler_recv(subreq, &ret); 680 TALLOC_FREE(subreq); 681 if (! status) { 682 LOG("failed to remove message handler for DB_PULL for %s\n", 683 recdb_name(state->recdb)); 684 tevent_req_error(req, ret); 685 return; 686 } 687 688 tevent_req_done(req); 689 } 690 691 static bool pull_database_recv(struct tevent_req *req, int *perr) 692 { 693 return generic_recv(req, perr); 694 } 695 696 /* 697 * Push database to specified nodes (old style) 698 */ 699 700 struct push_database_old_state { 701 struct tevent_context *ev; 702 struct ctdb_client_context *client; 703 struct recdb_context *recdb; 704 uint32_t *pnn_list; 705 int count; 706 struct ctdb_rec_buffer *recbuf; 707 int index; 708 }; 709 710 static void push_database_old_push_done(struct tevent_req *subreq); 711 712 static struct tevent_req *push_database_old_send( 713 TALLOC_CTX *mem_ctx, 714 struct tevent_context *ev, 715 struct ctdb_client_context *client, 716 uint32_t *pnn_list, int count, 717 struct recdb_context *recdb) 718 { 719 struct tevent_req *req, *subreq; 720 struct push_database_old_state *state; 721 struct ctdb_req_control request; 722 uint32_t pnn; 723 724 req = tevent_req_create(mem_ctx, &state, 725 struct push_database_old_state); 726 if (req == NULL) { 727 return NULL; 728 } 729 730 state->ev = ev; 731 state->client = client; 732 state->recdb = recdb; 733 state->pnn_list = pnn_list; 734 state->count = count; 735 state->index = 0; 736 737 state->recbuf = recdb_records(recdb, state, 738 ctdb_client_pnn(client)); 739 if (tevent_req_nomem(state->recbuf, req)) { 740 return tevent_req_post(req, ev); 741 } 742 743 pnn = state->pnn_list[state->index]; 744 745 ctdb_req_control_push_db(&request, state->recbuf); 746 subreq = ctdb_client_control_send(state, ev, client, pnn, 747 TIMEOUT(), &request); 748 if (tevent_req_nomem(subreq, req)) { 749 return tevent_req_post(req, ev); 750 } 751 tevent_req_set_callback(subreq, push_database_old_push_done, req); 752 753 return req; 754 } 755 756 static void push_database_old_push_done(struct tevent_req *subreq) 757 { 758 struct tevent_req *req = tevent_req_callback_data( 759 subreq, struct tevent_req); 760 struct push_database_old_state *state = tevent_req_data( 761 req, struct push_database_old_state); 762 struct ctdb_req_control request; 763 uint32_t pnn; 764 int ret; 765 bool status; 766 767 status = ctdb_client_control_recv(subreq, &ret, NULL, NULL); 768 TALLOC_FREE(subreq); 769 if (! status) { 770 LOG("control PUSH_DB failed for db %s on node %u, ret=%d\n", 771 recdb_name(state->recdb), state->pnn_list[state->index], 772 ret); 773 tevent_req_error(req, ret); 774 return; 775 } 776 777 state->index += 1; 778 if (state->index == state->count) { 779 TALLOC_FREE(state->recbuf); 780 tevent_req_done(req); 781 return; 782 } 783 784 pnn = state->pnn_list[state->index]; 785 786 ctdb_req_control_push_db(&request, state->recbuf); 787 subreq = ctdb_client_control_send(state, state->ev, state->client, 788 pnn, TIMEOUT(), &request); 789 if (tevent_req_nomem(subreq, req)) { 790 return; 791 } 792 tevent_req_set_callback(subreq, push_database_old_push_done, req); 793 } 794 795 static bool push_database_old_recv(struct tevent_req *req, int *perr) 796 { 797 return generic_recv(req, perr); 798 } 799 800 /* 801 * Push database to specified nodes (new style) 802 */ 803 804 struct push_database_new_state { 805 struct tevent_context *ev; 806 struct ctdb_client_context *client; 807 struct recdb_context *recdb; 808 uint32_t *pnn_list; 809 int count; 810 uint64_t srvid; 811 uint32_t dmaster; 812 int fd; 813 int num_buffers; 814 int num_buffers_sent; 815 int num_records; 816 }; 817 818 static void push_database_new_started(struct tevent_req *subreq); 819 static void push_database_new_send_msg(struct tevent_req *req); 820 static void push_database_new_send_done(struct tevent_req *subreq); 821 static void push_database_new_confirmed(struct tevent_req *subreq); 822 823 static struct tevent_req *push_database_new_send( 824 TALLOC_CTX *mem_ctx, 825 struct tevent_context *ev, 826 struct ctdb_client_context *client, 827 uint32_t *pnn_list, int count, 828 struct recdb_context *recdb, 829 int max_size) 830 { 831 struct tevent_req *req, *subreq; 832 struct push_database_new_state *state; 833 struct ctdb_req_control request; 834 struct ctdb_pulldb_ext pulldb_ext; 835 char *filename; 836 off_t offset; 837 838 req = tevent_req_create(mem_ctx, &state, 839 struct push_database_new_state); 840 if (req == NULL) { 841 return NULL; 842 } 843 844 state->ev = ev; 845 state->client = client; 846 state->recdb = recdb; 847 state->pnn_list = pnn_list; 848 state->count = count; 849 850 state->srvid = srvid_next(); 851 state->dmaster = ctdb_client_pnn(client); 852 state->num_buffers_sent = 0; 853 state->num_records = 0; 854 855 filename = talloc_asprintf(state, "%s.dat", recdb_path(recdb)); 856 if (tevent_req_nomem(filename, req)) { 857 return tevent_req_post(req, ev); 858 } 859 860 state->fd = open(filename, O_RDWR|O_CREAT, 0644); 861 if (state->fd == -1) { 862 tevent_req_error(req, errno); 863 return tevent_req_post(req, ev); 864 } 865 unlink(filename); 866 talloc_free(filename); 867 868 state->num_buffers = recdb_file(recdb, state, state->dmaster, 869 state->fd, max_size); 870 if (state->num_buffers == -1) { 871 tevent_req_error(req, ENOMEM); 872 return tevent_req_post(req, ev); 873 } 874 875 offset = lseek(state->fd, 0, SEEK_SET); 876 if (offset != 0) { 877 tevent_req_error(req, EIO); 878 return tevent_req_post(req, ev); 879 } 880 881 pulldb_ext.db_id = recdb_id(recdb); 882 pulldb_ext.srvid = state->srvid; 883 884 ctdb_req_control_db_push_start(&request, &pulldb_ext); 885 subreq = ctdb_client_control_multi_send(state, ev, client, 886 pnn_list, count, 887 TIMEOUT(), &request); 888 if (tevent_req_nomem(subreq, req)) { 889 return tevent_req_post(req, ev); 890 } 891 tevent_req_set_callback(subreq, push_database_new_started, req); 892 893 return req; 894 } 895 896 static void push_database_new_started(struct tevent_req *subreq) 897 { 898 struct tevent_req *req = tevent_req_callback_data( 899 subreq, struct tevent_req); 900 struct push_database_new_state *state = tevent_req_data( 901 req, struct push_database_new_state); 902 int *err_list; 903 int ret; 904 bool status; 905 906 status = ctdb_client_control_multi_recv(subreq, &ret, state, 907 &err_list, NULL); 908 TALLOC_FREE(subreq); 909 if (! status) { 910 int ret2; 911 uint32_t pnn; 912 913 ret2 = ctdb_client_control_multi_error(state->pnn_list, 914 state->count, 915 err_list, &pnn); 916 if (ret2 != 0) { 917 LOG("control DB_PUSH_START failed for db %s " 918 "on node %u, ret=%d\n", 919 recdb_name(state->recdb), pnn, ret2); 920 } else { 921 LOG("control DB_PUSH_START failed for db %s, ret=%d\n", 922 recdb_name(state->recdb), ret); 923 } 924 talloc_free(err_list); 925 926 tevent_req_error(req, ret); 927 return; 928 } 929 930 push_database_new_send_msg(req); 931 } 932 933 static void push_database_new_send_msg(struct tevent_req *req) 934 { 935 struct push_database_new_state *state = tevent_req_data( 936 req, struct push_database_new_state); 937 struct tevent_req *subreq; 938 struct ctdb_rec_buffer *recbuf; 939 struct ctdb_req_message message; 940 TDB_DATA data; 941 int ret; 942 943 if (state->num_buffers_sent == state->num_buffers) { 944 struct ctdb_req_control request; 945 946 ctdb_req_control_db_push_confirm(&request, 947 recdb_id(state->recdb)); 948 subreq = ctdb_client_control_multi_send(state, state->ev, 949 state->client, 950 state->pnn_list, 951 state->count, 952 TIMEOUT(), &request); 953 if (tevent_req_nomem(subreq, req)) { 954 return; 955 } 956 tevent_req_set_callback(subreq, push_database_new_confirmed, 957 req); 958 return; 959 } 960 961 ret = ctdb_rec_buffer_read(state->fd, state, &recbuf); 962 if (ret != 0) { 963 tevent_req_error(req, ret); 964 return; 965 } 966 967 data.dsize = ctdb_rec_buffer_len(recbuf); 968 data.dptr = talloc_size(state, data.dsize); 969 if (tevent_req_nomem(data.dptr, req)) { 970 return; 971 } 972 973 ctdb_rec_buffer_push(recbuf, data.dptr); 974 975 message.srvid = state->srvid; 976 message.data.data = data; 977 978 LOG("Pushing buffer %d with %d records for %s\n", 979 state->num_buffers_sent, recbuf->count, recdb_name(state->recdb)); 980 981 subreq = ctdb_client_message_multi_send(state, state->ev, 982 state->client, 983 state->pnn_list, state->count, 984 &message); 985 if (tevent_req_nomem(subreq, req)) { 986 return; 987 } 988 tevent_req_set_callback(subreq, push_database_new_send_done, req); 989 990 state->num_records += recbuf->count; 991 992 talloc_free(data.dptr); 993 talloc_free(recbuf); 994 } 995 996 static void push_database_new_send_done(struct tevent_req *subreq) 997 { 998 struct tevent_req *req = tevent_req_callback_data( 999 subreq, struct tevent_req); 1000 struct push_database_new_state *state = tevent_req_data( 1001 req, struct push_database_new_state); 1002 bool status; 1003 int ret; 1004 1005 status = ctdb_client_message_multi_recv(subreq, &ret, NULL, NULL); 1006 TALLOC_FREE(subreq); 1007 if (! status) { 1008 LOG("Sending recovery records failed for %s\n", 1009 recdb_name(state->recdb)); 1010 tevent_req_error(req, ret); 1011 return; 1012 } 1013 1014 state->num_buffers_sent += 1; 1015 1016 push_database_new_send_msg(req); 1017 } 1018 1019 static void push_database_new_confirmed(struct tevent_req *subreq) 1020 { 1021 struct tevent_req *req = tevent_req_callback_data( 1022 subreq, struct tevent_req); 1023 struct push_database_new_state *state = tevent_req_data( 1024 req, struct push_database_new_state); 1025 struct ctdb_reply_control **reply; 1026 int *err_list; 1027 bool status; 1028 int ret, i; 1029 uint32_t num_records; 1030 1031 status = ctdb_client_control_multi_recv(subreq, &ret, state, 1032 &err_list, &reply); 1033 TALLOC_FREE(subreq); 1034 if (! status) { 1035 int ret2; 1036 uint32_t pnn; 1037 1038 ret2 = ctdb_client_control_multi_error(state->pnn_list, 1039 state->count, err_list, 1040 &pnn); 1041 if (ret2 != 0) { 1042 LOG("control DB_PUSH_CONFIRM failed for %s on node %u," 1043 " ret=%d\n", recdb_name(state->recdb), pnn, ret2); 1044 } else { 1045 LOG("control DB_PUSH_CONFIRM failed for %s, ret=%d\n", 1046 recdb_name(state->recdb), ret); 1047 } 1048 tevent_req_error(req, ret); 1049 return; 1050 } 1051 1052 for (i=0; i<state->count; i++) { 1053 ret = ctdb_reply_control_db_push_confirm(reply[i], 1054 &num_records); 1055 if (ret != 0) { 1056 tevent_req_error(req, EPROTO); 1057 return; 1058 } 1059 1060 if (num_records != state->num_records) { 1061 LOG("Node %u received %d of %d records for %s\n", 1062 state->pnn_list[i], num_records, 1063 state->num_records, recdb_name(state->recdb)); 1064 tevent_req_error(req, EPROTO); 1065 return; 1066 } 1067 } 1068 1069 talloc_free(reply); 1070 1071 LOG("Pushed %d records for db %s\n", 1072 state->num_records, recdb_name(state->recdb)); 1073 1074 tevent_req_done(req); 1075 } 1076 1077 static bool push_database_new_recv(struct tevent_req *req, int *perr) 1078 { 1079 return generic_recv(req, perr); 1080 } 1081 1082 /* 1083 * wrapper for push_database_old and push_database_new 1084 */ 1085 1086 struct push_database_state { 1087 bool old_done, new_done; 1088 }; 1089 1090 static void push_database_old_done(struct tevent_req *subreq); 1091 static void push_database_new_done(struct tevent_req *subreq); 1092 1093 static struct tevent_req *push_database_send( 1094 TALLOC_CTX *mem_ctx, 1095 struct tevent_context *ev, 1096 struct ctdb_client_context *client, 1097 uint32_t *pnn_list, int count, uint32_t *caps, 1098 struct ctdb_tunable_list *tun_list, 1099 struct recdb_context *recdb) 1100 { 1101 struct tevent_req *req, *subreq; 1102 struct push_database_state *state; 1103 uint32_t *old_list, *new_list; 1104 int old_count, new_count; 1105 int i; 1106 1107 req = tevent_req_create(mem_ctx, &state, struct push_database_state); 1108 if (req == NULL) { 1109 return NULL; 1110 } 1111 1112 state->old_done = false; 1113 state->new_done = false; 1114 1115 old_count = 0; 1116 new_count = 0; 1117 old_list = talloc_array(state, uint32_t, count); 1118 new_list = talloc_array(state, uint32_t, count); 1119 if (tevent_req_nomem(old_list, req) || 1120 tevent_req_nomem(new_list,req)) { 1121 return tevent_req_post(req, ev); 1122 } 1123 1124 for (i=0; i<count; i++) { 1125 uint32_t pnn = pnn_list[i]; 1126 1127 if (caps[pnn] & CTDB_CAP_FRAGMENTED_CONTROLS) { 1128 new_list[new_count] = pnn; 1129 new_count += 1; 1130 } else { 1131 old_list[old_count] = pnn; 1132 old_count += 1; 1133 } 1134 } 1135 1136 if (old_count > 0) { 1137 subreq = push_database_old_send(state, ev, client, 1138 old_list, old_count, recdb); 1139 if (tevent_req_nomem(subreq, req)) { 1140 return tevent_req_post(req, ev); 1141 } 1142 tevent_req_set_callback(subreq, push_database_old_done, req); 1143 } else { 1144 state->old_done = true; 1145 } 1146 1147 if (new_count > 0) { 1148 subreq = push_database_new_send(state, ev, client, 1149 new_list, new_count, recdb, 1150 tun_list->rec_buffer_size_limit); 1151 if (tevent_req_nomem(subreq, req)) { 1152 return tevent_req_post(req, ev); 1153 } 1154 tevent_req_set_callback(subreq, push_database_new_done, req); 1155 } else { 1156 state->new_done = true; 1157 } 1158 1159 return req; 1160 } 1161 1162 static void push_database_old_done(struct tevent_req *subreq) 1163 { 1164 struct tevent_req *req = tevent_req_callback_data( 1165 subreq, struct tevent_req); 1166 struct push_database_state *state = tevent_req_data( 1167 req, struct push_database_state); 1168 bool status; 1169 int ret; 1170 1171 status = push_database_old_recv(subreq, &ret); 1172 if (! status) { 1173 tevent_req_error(req, ret); 1174 return; 1175 } 1176 1177 state->old_done = true; 1178 1179 if (state->old_done && state->new_done) { 1180 tevent_req_done(req); 1181 } 1182 } 1183 1184 static void push_database_new_done(struct tevent_req *subreq) 1185 { 1186 struct tevent_req *req = tevent_req_callback_data( 1187 subreq, struct tevent_req); 1188 struct push_database_state *state = tevent_req_data( 1189 req, struct push_database_state); 1190 bool status; 1191 int ret; 1192 1193 status = push_database_new_recv(subreq, &ret); 1194 if (! status) { 1195 tevent_req_error(req, ret); 1196 return; 1197 } 1198 1199 state->new_done = true; 1200 1201 if (state->old_done && state->new_done) { 1202 tevent_req_done(req); 1203 } 1204 } 1205 1206 static bool push_database_recv(struct tevent_req *req, int *perr) 1207 { 1208 return generic_recv(req, perr); 271 1209 } 272 1210 … … 280 1218 uint32_t *pnn_list; 281 1219 int count; 1220 uint32_t *caps; 1221 uint32_t *ban_credits; 282 1222 uint32_t db_id; 283 1223 struct recdb_context *recdb; … … 292 1232 struct tevent_context *ev, 293 1233 struct ctdb_client_context *client, 294 uint32_t *pnn_list, int count, 295 uint32_t db_id, struct recdb_context *recdb) 1234 uint32_t *pnn_list, int count, uint32_t *caps, 1235 uint32_t *ban_credits, uint32_t db_id, 1236 struct recdb_context *recdb) 296 1237 { 297 1238 struct tevent_req *req, *subreq; … … 309 1250 state->pnn_list = pnn_list; 310 1251 state->count = count; 1252 state->caps = caps; 1253 state->ban_credits = ban_credits; 311 1254 state->db_id = db_id; 312 1255 state->recdb = recdb; … … 332 1275 req, struct collect_highseqnum_db_state); 333 1276 struct ctdb_reply_control **reply; 334 struct ctdb_req_control request;335 struct ctdb_pulldb pulldb;336 1277 int *err_list; 337 1278 bool status; … … 380 1321 recdb_name(state->recdb), state->max_pnn, max_seqnum); 381 1322 382 pulldb.db_id = state->db_id; 383 pulldb.lmaster = CTDB_LMASTER_ANY; 384 385 ctdb_req_control_pull_db(&request, &pulldb); 386 subreq = ctdb_client_control_send(state, state->ev, state->client, 387 state->max_pnn, TIMEOUT(), &request); 1323 subreq = pull_database_send(state, state->ev, state->client, 1324 state->max_pnn, 1325 state->caps[state->max_pnn], 1326 state->recdb); 388 1327 if (tevent_req_nomem(subreq, req)) { 389 1328 return; … … 399 1338 struct collect_highseqnum_db_state *state = tevent_req_data( 400 1339 req, struct collect_highseqnum_db_state); 401 struct ctdb_reply_control *reply; 402 struct ctdb_rec_buffer *recbuf; 403 int ret; 404 bool status; 405 406 status = ctdb_client_control_recv(subreq, &ret, state, &reply); 407 TALLOC_FREE(subreq); 408 if (! status) { 409 LOG("control PULL_DB failed for %s on node %u, ret=%d\n", 410 recdb_name(state->recdb), state->max_pnn, ret); 411 tevent_req_error(req, ret); 412 return; 413 } 414 415 ret = ctdb_reply_control_pull_db(reply, state, &recbuf); 416 if (ret != 0) { 417 tevent_req_error(req, EPROTO); 418 return; 419 } 420 421 talloc_free(reply); 422 423 ret = recdb_add(state->recdb, ctdb_client_pnn(state->client), recbuf); 424 talloc_free(recbuf); 425 if (! ret) { 426 tevent_req_error(req, EIO); 1340 int ret; 1341 bool status; 1342 1343 status = pull_database_recv(subreq, &ret); 1344 TALLOC_FREE(subreq); 1345 if (! status) { 1346 state->ban_credits[state->max_pnn] += 1; 1347 tevent_req_error(req, ret); 427 1348 return; 428 1349 } … … 433 1354 static bool collect_highseqnum_db_recv(struct tevent_req *req, int *perr) 434 1355 { 435 int err; 436 437 if (tevent_req_is_unix_error(req, &err)) { 438 if (perr != NULL) { 439 *perr = err; 440 } 441 return false; 442 } 443 444 return true; 1356 return generic_recv(req, perr); 445 1357 } 446 1358 … … 454 1366 uint32_t *pnn_list; 455 1367 int count; 1368 uint32_t *caps; 1369 uint32_t *ban_credits; 456 1370 uint32_t db_id; 457 1371 struct recdb_context *recdb; … … 466 1380 struct tevent_context *ev, 467 1381 struct ctdb_client_context *client, 468 uint32_t *pnn_list, int count, 469 uint32_t db_id, struct recdb_context *recdb) 1382 uint32_t *pnn_list, int count, uint32_t *caps, 1383 uint32_t *ban_credits, uint32_t db_id, 1384 struct recdb_context *recdb) 470 1385 { 471 1386 struct tevent_req *req, *subreq; 472 1387 struct collect_all_db_state *state; 473 struct ctdb_req_control request;1388 uint32_t pnn; 474 1389 475 1390 req = tevent_req_create(mem_ctx, &state, … … 483 1398 state->pnn_list = pnn_list; 484 1399 state->count = count; 1400 state->caps = caps; 1401 state->ban_credits = ban_credits; 485 1402 state->db_id = db_id; 486 1403 state->recdb = recdb; 487 488 state->pulldb.db_id = db_id;489 state->pulldb.lmaster = CTDB_LMASTER_ANY;490 491 1404 state->index = 0; 492 1405 493 ctdb_req_control_pull_db(&request, &state->pulldb); 494 subreq = ctdb_client_control_send(state, ev, client, 495 state->pnn_list[state->index], 496 TIMEOUT(), &request); 1406 pnn = state->pnn_list[state->index]; 1407 1408 subreq = pull_database_send(state, ev, client, pnn, caps[pnn], recdb); 497 1409 if (tevent_req_nomem(subreq, req)) { 498 1410 return tevent_req_post(req, ev); … … 509 1421 struct collect_all_db_state *state = tevent_req_data( 510 1422 req, struct collect_all_db_state); 511 struct ctdb_reply_control *reply; 512 struct ctdb_req_control request; 513 struct ctdb_rec_buffer *recbuf; 514 int ret; 515 bool status; 516 517 status = ctdb_client_control_recv(subreq, &ret, state, &reply); 518 TALLOC_FREE(subreq); 519 if (! status) { 520 LOG("control PULL_DB failed for %s from node %u, ret=%d\n", 521 recdb_name(state->recdb), state->pnn_list[state->index], 522 ret); 523 tevent_req_error(req, ret); 524 return; 525 } 526 527 ret = ctdb_reply_control_pull_db(reply, state, &recbuf); 528 if (ret != 0) { 529 LOG("control PULL_DB failed for %s, ret=%d\n", 530 recdb_name(state->recdb), ret); 531 tevent_req_error(req, EPROTO); 532 return; 533 } 534 535 talloc_free(reply); 536 537 status = recdb_add(state->recdb, ctdb_client_pnn(state->client), recbuf); 538 talloc_free(recbuf); 539 if (! status) { 540 tevent_req_error(req, EIO); 1423 uint32_t pnn; 1424 int ret; 1425 bool status; 1426 1427 status = pull_database_recv(subreq, &ret); 1428 TALLOC_FREE(subreq); 1429 if (! status) { 1430 pnn = state->pnn_list[state->index]; 1431 state->ban_credits[pnn] += 1; 1432 tevent_req_error(req, ret); 541 1433 return; 542 1434 } … … 548 1440 } 549 1441 550 ctdb_req_control_pull_db(&request, &state->pulldb); 551 subreq = ctdb_client_control_send(state, state->ev, state->client, 552 state->pnn_list[state->index], 553 TIMEOUT(), &request); 1442 pnn = state->pnn_list[state->index]; 1443 subreq = pull_database_send(state, state->ev, state->client, 1444 pnn, state->caps[pnn], state->recdb); 554 1445 if (tevent_req_nomem(subreq, req)) { 555 1446 return; … … 560 1451 static bool collect_all_db_recv(struct tevent_req *req, int *perr) 561 1452 { 562 int err; 563 564 if (tevent_req_is_unix_error(req, &err)) { 565 if (perr != NULL) { 566 *perr = err; 567 } 568 return false; 569 } 570 571 return true; 1453 return generic_recv(req, perr); 572 1454 } 573 1455 … … 592 1474 uint32_t *pnn_list; 593 1475 int count; 1476 uint32_t *caps; 1477 uint32_t *ban_credits; 594 1478 uint32_t db_id; 595 1479 bool persistent; … … 600 1484 const char *db_name, *db_path; 601 1485 struct recdb_context *recdb; 602 struct ctdb_rec_buffer *recbuf;603 604 1486 }; 605 1487 … … 619 1501 struct ctdb_tunable_list *tun_list, 620 1502 uint32_t *pnn_list, int count, 1503 uint32_t *caps, 1504 uint32_t *ban_credits, 621 1505 uint32_t generation, 622 1506 uint32_t db_id, bool persistent) … … 636 1520 state->pnn_list = pnn_list; 637 1521 state->count = count; 1522 state->caps = caps; 1523 state->ban_credits = ban_credits; 638 1524 state->db_id = db_id; 639 1525 state->persistent = persistent; … … 820 1706 subreq = collect_highseqnum_db_send( 821 1707 state, state->ev, state->client, 822 state->pnn_list, state->count, 823 state->db_id, state->recdb); 1708 state->pnn_list, state->count, state->caps, 1709 state->ban_credits, state->db_id, 1710 state->recdb); 824 1711 } else { 825 1712 subreq = collect_all_db_send( 826 1713 state, state->ev, state->client, 827 state->pnn_list, state->count, 828 state->db_id, state->recdb); 1714 state->pnn_list, state->count, state->caps, 1715 state->ban_credits, state->db_id, 1716 state->recdb); 829 1717 } 830 1718 if (tevent_req_nomem(subreq, req)) { … … 872 1760 struct recover_db_state *state = tevent_req_data( 873 1761 req, struct recover_db_state); 874 struct ctdb_req_control request;875 1762 int *err_list; 876 1763 int ret; … … 898 1785 } 899 1786 900 state->recbuf = recdb_records(state->recdb, state, state->destnode); 901 if (tevent_req_nomem(state->recbuf, req)) { 902 return; 903 } 904 905 TALLOC_FREE(state->recdb); 906 907 ctdb_req_control_push_db(&request, state->recbuf); 908 subreq = ctdb_client_control_multi_send(state, state->ev, 909 state->client, 910 state->pnn_list, state->count, 911 TIMEOUT(), &request); 1787 subreq = push_database_send(state, state->ev, state->client, 1788 state->pnn_list, state->count, 1789 state->caps, state->tun_list, 1790 state->recdb); 912 1791 if (tevent_req_nomem(subreq, req)) { 913 1792 return; … … 923 1802 req, struct recover_db_state); 924 1803 struct ctdb_req_control request; 925 int *err_list; 926 int ret; 927 bool status; 928 929 status = ctdb_client_control_multi_recv(subreq, &ret, NULL, &err_list, 930 NULL); 931 TALLOC_FREE(subreq); 932 if (! status) { 933 int ret2; 934 uint32_t pnn; 935 936 ret2 = ctdb_client_control_multi_error(state->pnn_list, 937 state->count, 938 err_list, &pnn); 939 if (ret2 != 0) { 940 LOG("control PUSHDB failed for db %s on node %u," 941 " ret=%d\n", state->db_name, pnn, ret2); 942 } else { 943 LOG("control PUSHDB failed for db %s, ret=%d\n", 944 state->db_name, ret); 945 } 946 tevent_req_error(req, ret); 947 return; 948 } 949 950 TALLOC_FREE(state->recbuf); 1804 int ret; 1805 bool status; 1806 1807 status = push_database_recv(subreq, &ret); 1808 TALLOC_FREE(subreq); 1809 if (! status) { 1810 tevent_req_error(req, ret); 1811 return; 1812 } 1813 1814 TALLOC_FREE(state->recdb); 951 1815 952 1816 ctdb_req_control_db_transaction_commit(&request, &state->transdb); … … 1040 1904 static bool recover_db_recv(struct tevent_req *req) 1041 1905 { 1042 int err; 1043 1044 if (tevent_req_is_unix_error(req, &err)) { 1045 return false; 1046 } 1047 1048 return true; 1906 return generic_recv(req, NULL); 1049 1907 } 1050 1908 … … 1070 1928 uint32_t *pnn_list; 1071 1929 int count; 1930 uint32_t *caps; 1931 uint32_t *ban_credits; 1072 1932 uint32_t generation; 1073 1933 uint32_t db_id; … … 1084 1944 struct ctdb_tunable_list *tun_list, 1085 1945 uint32_t *pnn_list, int count, 1946 uint32_t *caps, 1947 uint32_t *ban_credits, 1086 1948 uint32_t generation) 1087 1949 { … … 1119 1981 substate->pnn_list = pnn_list; 1120 1982 substate->count = count; 1983 substate->caps = caps; 1984 substate->ban_credits = ban_credits; 1121 1985 substate->generation = generation; 1122 1986 substate->db_id = dbmap->dbs[i].db_id; … … 1125 1989 1126 1990 subreq = recover_db_send(state, ev, client, tun_list, 1127 pnn_list, count, generation,1128 substate->db_id,1991 pnn_list, count, caps, ban_credits, 1992 generation, substate->db_id, 1129 1993 substate->persistent); 1130 1994 if (tevent_req_nomem(subreq, req)) { … … 1157 2021 1158 2022 substate->num_fails += 1; 1159 if (substate->num_fails < 5) {2023 if (substate->num_fails < NUM_RETRIES) { 1160 2024 subreq = recover_db_send(state, state->ev, substate->client, 1161 2025 substate->tun_list, 1162 2026 substate->pnn_list, substate->count, 2027 substate->caps, substate->ban_credits, 1163 2028 substate->generation, substate->db_id, 1164 2029 substate->persistent); … … 1207 2072 * Run the parallel database recovery 1208 2073 * 2074 * - Get tunables 1209 2075 * - Get nodemap 1210 2076 * - Get vnnmap 1211 2077 * - Get capabilities from all nodes 1212 * - Get tunables from all nodes1213 2078 * - Get dbmap 1214 2079 * - Set RECOVERY_ACTIVE … … 1229 2094 struct ctdb_node_map *nodemap; 1230 2095 uint32_t *caps; 2096 uint32_t *ban_credits; 1231 2097 struct ctdb_tunable_list *tun_list; 1232 2098 struct ctdb_vnn_map *vnnmap; … … 1234 2100 }; 1235 2101 2102 static void recovery_tunables_done(struct tevent_req *subreq); 1236 2103 static void recovery_nodemap_done(struct tevent_req *subreq); 1237 2104 static void recovery_vnnmap_done(struct tevent_req *subreq); 1238 2105 static void recovery_capabilities_done(struct tevent_req *subreq); 1239 static void recovery_tunables_done(struct tevent_req *subreq);1240 2106 static void recovery_dbmap_done(struct tevent_req *subreq); 1241 2107 static void recovery_active_done(struct tevent_req *subreq); … … 1243 2109 static void recovery_vnnmap_update_done(struct tevent_req *subreq); 1244 2110 static void recovery_db_recovery_done(struct tevent_req *subreq); 2111 static void recovery_failed_done(struct tevent_req *subreq); 1245 2112 static void recovery_normal_done(struct tevent_req *subreq); 1246 2113 static void recovery_end_recovery_done(struct tevent_req *subreq); … … 1265 2132 state->destnode = ctdb_client_pnn(client); 1266 2133 1267 ctdb_req_control_get_nodemap(&request); 1268 subreq = ctdb_client_control_send(mem_ctx, ev, client, state->destnode, 1269 TIMEOUT(), &request); 2134 ctdb_req_control_get_all_tunables(&request); 2135 subreq = ctdb_client_control_send(state, state->ev, state->client, 2136 state->destnode, TIMEOUT(), 2137 &request); 1270 2138 if (tevent_req_nomem(subreq, req)) { 1271 2139 return tevent_req_post(req, ev); 1272 2140 } 1273 tevent_req_set_callback(subreq, recovery_ nodemap_done, req);2141 tevent_req_set_callback(subreq, recovery_tunables_done, req); 1274 2142 1275 2143 return req; 1276 2144 } 1277 2145 1278 static void recovery_ nodemap_done(struct tevent_req *subreq)2146 static void recovery_tunables_done(struct tevent_req *subreq) 1279 2147 { 1280 2148 struct tevent_req *req = tevent_req_callback_data( … … 1284 2152 struct ctdb_reply_control *reply; 1285 2153 struct ctdb_req_control request; 2154 int ret; 2155 bool status; 2156 2157 status = ctdb_client_control_recv(subreq, &ret, state, &reply); 2158 TALLOC_FREE(subreq); 2159 if (! status) { 2160 LOG("control GET_ALL_TUNABLES failed, ret=%d\n", ret); 2161 tevent_req_error(req, ret); 2162 return; 2163 } 2164 2165 ret = ctdb_reply_control_get_all_tunables(reply, state, 2166 &state->tun_list); 2167 if (ret != 0) { 2168 LOG("control GET_ALL_TUNABLES failed, ret=%d\n", ret); 2169 tevent_req_error(req, EPROTO); 2170 return; 2171 } 2172 2173 talloc_free(reply); 2174 2175 recover_timeout = state->tun_list->recover_timeout; 2176 2177 ctdb_req_control_get_nodemap(&request); 2178 subreq = ctdb_client_control_send(state, state->ev, state->client, 2179 state->destnode, TIMEOUT(), 2180 &request); 2181 if (tevent_req_nomem(subreq, req)) { 2182 return; 2183 } 2184 tevent_req_set_callback(subreq, recovery_nodemap_done, req); 2185 } 2186 2187 static void recovery_nodemap_done(struct tevent_req *subreq) 2188 { 2189 struct tevent_req *req = tevent_req_callback_data( 2190 subreq, struct tevent_req); 2191 struct recovery_state *state = tevent_req_data( 2192 req, struct recovery_state); 2193 struct ctdb_reply_control *reply; 2194 struct ctdb_req_control request; 1286 2195 bool status; 1287 2196 int ret; … … 1307 2216 if (state->count <= 0) { 1308 2217 tevent_req_error(req, ENOMEM); 2218 return; 2219 } 2220 2221 state->ban_credits = talloc_zero_array(state, uint32_t, 2222 state->nodemap->num); 2223 if (tevent_req_nomem(state->ban_credits, req)) { 1309 2224 return; 1310 2225 } … … 1408 2323 return; 1409 2324 } 1410 }1411 1412 talloc_free(reply);1413 1414 ctdb_req_control_get_all_tunables(&request);1415 subreq = ctdb_client_control_send(state, state->ev, state->client,1416 state->destnode, TIMEOUT(),1417 &request);1418 if (tevent_req_nomem(subreq, req)) {1419 return;1420 }1421 tevent_req_set_callback(subreq, recovery_tunables_done, req);1422 }1423 1424 static void recovery_tunables_done(struct tevent_req *subreq)1425 {1426 struct tevent_req *req = tevent_req_callback_data(1427 subreq, struct tevent_req);1428 struct recovery_state *state = tevent_req_data(1429 req, struct recovery_state);1430 struct ctdb_reply_control *reply;1431 struct ctdb_req_control request;1432 int ret;1433 bool status;1434 1435 status = ctdb_client_control_recv(subreq, &ret, state, &reply);1436 TALLOC_FREE(subreq);1437 if (! status) {1438 LOG("control GET_ALL_TUNABLES failed, ret=%d\n", ret);1439 tevent_req_error(req, ret);1440 return;1441 }1442 1443 ret = ctdb_reply_control_get_all_tunables(reply, state,1444 &state->tun_list);1445 if (ret != 0) {1446 LOG("control GET_ALL_TUNABLES failed, ret=%d\n", ret);1447 tevent_req_error(req, EPROTO);1448 return;1449 2325 } 1450 2326 … … 1675 2551 state->dbmap, state->tun_list, 1676 2552 state->pnn_list, state->count, 2553 state->caps, state->ban_credits, 1677 2554 state->vnnmap->generation); 1678 2555 if (tevent_req_nomem(subreq, req)) { … … 1695 2572 TALLOC_FREE(subreq); 1696 2573 1697 LOG("%d databases recovered\n", count); 1698 1699 if (! status) { 1700 tevent_req_error(req, EIO); 2574 LOG("%d of %d databases recovered\n", count, state->dbmap->num); 2575 2576 if (! status) { 2577 uint32_t max_pnn = CTDB_UNKNOWN_PNN, max_credits = 0; 2578 int i; 2579 2580 /* Bans are not enabled */ 2581 if (state->tun_list->enable_bans == 0) { 2582 tevent_req_error(req, EIO); 2583 return; 2584 } 2585 2586 for (i=0; i<state->count; i++) { 2587 uint32_t pnn; 2588 pnn = state->pnn_list[i]; 2589 if (state->ban_credits[pnn] > max_credits) { 2590 max_pnn = pnn; 2591 max_credits = state->ban_credits[pnn]; 2592 } 2593 } 2594 2595 /* If pulling database fails multiple times */ 2596 if (max_credits >= NUM_RETRIES) { 2597 struct ctdb_req_message message; 2598 2599 LOG("Assigning banning credits to node %u\n", max_pnn); 2600 2601 message.srvid = CTDB_SRVID_BANNING; 2602 message.data.pnn = max_pnn; 2603 2604 subreq = ctdb_client_message_send( 2605 state, state->ev, state->client, 2606 ctdb_client_pnn(state->client), 2607 &message); 2608 if (tevent_req_nomem(subreq, req)) { 2609 return; 2610 } 2611 tevent_req_set_callback(subreq, recovery_failed_done, 2612 req); 2613 } else { 2614 tevent_req_error(req, EIO); 2615 } 1701 2616 return; 1702 2617 } … … 1711 2626 } 1712 2627 tevent_req_set_callback(subreq, recovery_normal_done, req); 2628 } 2629 2630 static void recovery_failed_done(struct tevent_req *subreq) 2631 { 2632 struct tevent_req *req = tevent_req_callback_data( 2633 subreq, struct tevent_req); 2634 int ret; 2635 bool status; 2636 2637 status = ctdb_client_message_recv(subreq, &ret); 2638 TALLOC_FREE(subreq); 2639 if (! status) { 2640 LOG("failed to assign banning credits, ret=%d\n", ret); 2641 } 2642 2643 tevent_req_error(req, EIO); 1713 2644 } 1714 2645 … … 1795 2726 static void recovery_recv(struct tevent_req *req, int *perr) 1796 2727 { 1797 int err; 1798 1799 if (tevent_req_is_unix_error(req, &err)) { 1800 if (perr != NULL) { 1801 *perr = err; 1802 } 1803 return; 1804 } 2728 generic_recv(req, perr); 1805 2729 } 1806 2730 -
vendor/current/ctdb/server/ctdb_takeover.c
r988 r989 404 404 } 405 405 406 struct takeover_callback_state {407 struct ctdb_req_control_old *c;408 ctdb_sock_addr *addr;409 struct ctdb_vnn *vnn;410 };411 412 406 struct ctdb_do_takeip_state { 413 407 struct ctdb_req_control_old *c; … … 502 496 CTDB_NO_MEMORY(ctdb, state); 503 497 504 state->c = talloc_steal(ctdb, c);498 state->c = NULL; 505 499 state->vnn = vnn; 506 500 … … 531 525 } 532 526 527 state->c = talloc_steal(ctdb, c); 533 528 return 0; 534 529 } … … 639 634 CTDB_NO_MEMORY(ctdb, state); 640 635 641 state->c = talloc_steal(ctdb, c);636 state->c = NULL; 642 637 state->old = old; 643 638 state->vnn = vnn; … … 671 666 } 672 667 668 state->c = talloc_steal(ctdb, c); 673 669 return 0; 674 670 } … … 816 812 } 817 813 818 /*819 kill any clients that are registered with a IP that is being released820 */821 static void release_kill_clients(struct ctdb_context *ctdb, ctdb_sock_addr *addr)822 {823 struct ctdb_client_ip *ip;824 825 DEBUG(DEBUG_INFO,("release_kill_clients for ip %s\n",826 ctdb_addr_to_str(addr)));827 828 for (ip=ctdb->client_ip_list; ip; ip=ip->next) {829 ctdb_sock_addr tmp_addr;830 831 tmp_addr = ip->addr;832 DEBUG(DEBUG_INFO,("checking for client %u with IP %s\n",833 ip->client_id,834 ctdb_addr_to_str(&ip->addr)));835 836 if (ctdb_same_ip(&tmp_addr, addr)) {837 struct ctdb_client *client = reqid_find(ctdb->idr,838 ip->client_id,839 struct ctdb_client);840 DEBUG(DEBUG_INFO,("matched client %u with IP %s and pid %u\n",841 ip->client_id,842 ctdb_addr_to_str(&ip->addr),843 client->pid));844 845 if (client->pid != 0) {846 DEBUG(DEBUG_INFO,(__location__ " Killing client pid %u for IP %s on client_id %u\n",847 (unsigned)client->pid,848 ctdb_addr_to_str(addr),849 ip->client_id));850 kill(client->pid, SIGKILL);851 }852 }853 }854 }855 856 814 static void do_delete_ip(struct ctdb_context *ctdb, struct ctdb_vnn *vnn) 857 815 { … … 862 820 } 863 821 822 static struct ctdb_vnn *release_ip_post(struct ctdb_context *ctdb, 823 struct ctdb_vnn *vnn, 824 ctdb_sock_addr *addr) 825 { 826 TDB_DATA data; 827 828 /* Send a message to all clients of this node telling them 829 * that the cluster has been reconfigured and they should 830 * close any connections on this IP address 831 */ 832 data.dptr = (uint8_t *)ctdb_addr_to_str(addr); 833 data.dsize = strlen((char *)data.dptr)+1; 834 DEBUG(DEBUG_INFO, ("Sending RELEASE_IP message for %s\n", data.dptr)); 835 ctdb_daemon_send_message(ctdb, ctdb->pnn, CTDB_SRVID_RELEASE_IP, data); 836 837 ctdb_vnn_unassign_iface(ctdb, vnn); 838 839 /* Process the IP if it has been marked for deletion */ 840 if (vnn->delete_pending) { 841 do_delete_ip(ctdb, vnn); 842 return NULL; 843 } 844 845 return vnn; 846 } 847 848 struct release_ip_callback_state { 849 struct ctdb_req_control_old *c; 850 ctdb_sock_addr *addr; 851 struct ctdb_vnn *vnn; 852 uint32_t target_pnn; 853 }; 854 864 855 /* 865 856 called when releaseip event finishes 866 857 */ 867 static void release_ip_callback(struct ctdb_context *ctdb, int status, 858 static void release_ip_callback(struct ctdb_context *ctdb, int status, 868 859 void *private_data) 869 860 { 870 struct takeover_callback_state *state = 871 talloc_get_type(private_data, struct takeover_callback_state); 872 TDB_DATA data; 861 struct release_ip_callback_state *state = 862 talloc_get_type(private_data, struct release_ip_callback_state); 873 863 874 864 if (status == -ETIME) { … … 888 878 } 889 879 890 /* send a message to all clients of this node telling them 891 that the cluster has been reconfigured and they should 892 release any sockets on this IP */ 893 data.dptr = (uint8_t *)talloc_strdup(state, ctdb_addr_to_str(state->addr)); 894 CTDB_NO_MEMORY_VOID(ctdb, data.dptr); 895 data.dsize = strlen((char *)data.dptr)+1; 896 897 DEBUG(DEBUG_INFO,(__location__ " sending RELEASE_IP for '%s'\n", data.dptr)); 898 899 ctdb_daemon_send_message(ctdb, ctdb->pnn, CTDB_SRVID_RELEASE_IP, data); 900 901 /* kill clients that have registered with this IP */ 902 release_kill_clients(ctdb, state->addr); 903 904 ctdb_vnn_unassign_iface(ctdb, state->vnn); 905 906 /* Process the IP if it has been marked for deletion */ 907 if (state->vnn->delete_pending) { 908 do_delete_ip(ctdb, state->vnn); 909 state->vnn = NULL; 910 } 880 state->vnn->pnn = state->target_pnn; 881 state->vnn = release_ip_post(ctdb, state->vnn, state->addr); 911 882 912 883 /* the control succeeded */ … … 915 886 } 916 887 917 static int ctdb_releaseip_destructor(struct takeover_callback_state *state)888 static int ctdb_releaseip_destructor(struct release_ip_callback_state *state) 918 889 { 919 890 if (state->vnn != NULL) { … … 932 903 { 933 904 int ret; 934 struct takeover_callback_state *state;905 struct release_ip_callback_state *state; 935 906 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr; 936 907 struct ctdb_vnn *vnn; … … 944 915 return 0; 945 916 } 946 vnn->pnn = pip->pnn;947 917 948 918 /* stop any previous arps */ … … 950 920 vnn->takeover_ctx = NULL; 951 921 952 /* Some ctdb tool commands (e.g. moveip, rebalanceip) send 953 * lazy multicast to drop an IP from any node that isn't the 954 * intended new node. The following causes makes ctdbd ignore 955 * a release for any address it doesn't host. 922 /* RELEASE_IP controls are sent to all nodes that should not 923 * be hosting a particular IP. This serves 2 purposes. The 924 * first is to help resolve any inconsistencies. If a node 925 * does unexpectly host an IP then it will be released. The 926 * 2nd is to use a "redundant release" to tell non-takeover 927 * nodes where an IP is moving to. This is how "ctdb ip" can 928 * report the (likely) location of an IP by only asking the 929 * local node. Redundant releases need to update the PNN but 930 * are otherwise ignored. 956 931 */ 957 932 if (ctdb->tunable.disable_ip_failover == 0 && ctdb->do_checkpublicip) { … … 961 936 vnn->public_netmask_bits, 962 937 ctdb_vnn_iface_string(vnn))); 938 vnn->pnn = pip->pnn; 963 939 ctdb_vnn_unassign_iface(ctdb, vnn); 964 940 return 0; … … 969 945 ctdb_addr_to_str(&pip->addr), 970 946 vnn->public_netmask_bits)); 947 vnn->pnn = pip->pnn; 971 948 return 0; 972 949 } … … 994 971 pip->pnn)); 995 972 996 state = talloc(ctdb, struct takeover_callback_state);973 state = talloc(ctdb, struct release_ip_callback_state); 997 974 if (state == NULL) { 998 975 ctdb_set_error(ctdb, "Out of memory at %s:%d", … … 1002 979 } 1003 980 1004 state->c = talloc_steal(state, c);1005 state->addr = talloc(state, ctdb_sock_addr); 981 state->c = NULL; 982 state->addr = talloc(state, ctdb_sock_addr); 1006 983 if (state->addr == NULL) { 1007 984 ctdb_set_error(ctdb, "Out of memory at %s:%d", … … 1012 989 } 1013 990 *state->addr = pip->addr; 991 state->target_pnn = pip->pnn; 1014 992 state->vnn = vnn; 1015 993 … … 1035 1013 /* tell the control that we will be reply asynchronously */ 1036 1014 *async_reply = true; 1015 state->c = talloc_steal(state, c); 1037 1016 return 0; 1038 1017 } … … 1776 1755 bool can_host_ips; 1777 1756 1757 /* Default timeout for early jump to IPREALLOCATED. See below 1758 * for explanation of 3 times... */ 1759 timeout = timeval_current_ofs(3 * ctdb->tunable.takeover_timeout, 0); 1760 1778 1761 /* 1779 1762 * ip failover is completely disabled, just send out the … … 1852 1835 1853 1836 ZERO_STRUCT(ip); /* Avoid valgrind warnings for union */ 1837 1838 /* Each of the following stages (RELEASE_IP, TAKEOVER_IP, 1839 * IPREALLOCATED) notionally has a timeout of TakeoverTimeout 1840 * seconds. However, RELEASE_IP can take longer due to TCP 1841 * connection killing, so sometimes needs more time. 1842 * Therefore, use a cumulative timeout of TakeoverTimeout * 3 1843 * seconds across all 3 stages. No explicit expiry checks are 1844 * needed before each stage because tevent is smart enough to 1845 * fire the timeouts even if they are in the past. Initialise 1846 * this here so it explicitly covers the stages we're 1847 * interested in but, in particular, not the time taken by the 1848 * ipalloc(). 1849 */ 1850 timeout = timeval_current_ofs(3 * ctdb->tunable.takeover_timeout, 0); 1854 1851 1855 1852 /* Send a RELEASE_IP to all nodes that should not be hosting … … 1875 1872 ip.addr = tmp_ip->addr; 1876 1873 1877 timeout = TAKEOVER_TIMEOUT();1878 1874 data.dsize = sizeof(ip); 1879 1875 data.dptr = (uint8_t *)&ip; … … 1918 1914 ip.addr = tmp_ip->addr; 1919 1915 1920 timeout = TAKEOVER_TIMEOUT();1921 1916 data.dsize = sizeof(ip); 1922 1917 data.dptr = (uint8_t *)&ip; … … 1956 1951 nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true); 1957 1952 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_IPREALLOCATED, 1958 nodes, 0, TAKEOVER_TIMEOUT(),1953 nodes, 0, timeout, 1959 1954 false, tdb_null, 1960 1955 NULL, iprealloc_fail_callback, … … 2377 2372 void ctdb_release_all_ips(struct ctdb_context *ctdb) 2378 2373 { 2379 struct ctdb_vnn *vnn ;2374 struct ctdb_vnn *vnn, *next; 2380 2375 int count = 0; 2381 2376 … … 2384 2379 } 2385 2380 2386 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) { 2381 for (vnn = ctdb->vnn; vnn != NULL; vnn = next) { 2382 /* vnn can be freed below in release_ip_post() */ 2383 next = vnn->next; 2384 2387 2385 if (!ctdb_sys_have_ip(&vnn->public_address)) { 2388 2386 ctdb_vnn_unassign_iface(ctdb, vnn); 2389 continue;2390 }2391 if (!vnn->iface) {2392 2387 continue; 2393 2388 } … … 2413 2408 2414 2409 ctdb_event_script_args(ctdb, CTDB_EVENT_RELEASE_IP, "%s %s %u", 2415 ctdb_vnn_iface_string(vnn), 2416 ctdb_addr_to_str(&vnn->public_address), 2417 vnn->public_netmask_bits); 2418 release_kill_clients(ctdb, &vnn->public_address); 2419 ctdb_vnn_unassign_iface(ctdb, vnn); 2420 vnn->update_in_flight = false; 2410 ctdb_vnn_iface_string(vnn), 2411 ctdb_addr_to_str(&vnn->public_address), 2412 vnn->public_netmask_bits); 2413 /* releaseip timeouts are converted to success, so to 2414 * detect failures just check if the IP address is 2415 * still there... 2416 */ 2417 if (ctdb_sys_have_ip(&vnn->public_address)) { 2418 DEBUG(DEBUG_ERR, 2419 (__location__ 2420 " IP address %s not released\n", 2421 ctdb_addr_to_str(&vnn->public_address))); 2422 vnn->update_in_flight = false; 2423 continue; 2424 } 2425 2426 vnn = release_ip_post(ctdb, vnn, &vnn->public_address); 2427 if (vnn != NULL) { 2428 vnn->update_in_flight = false; 2429 } 2421 2430 count++; 2422 2431 } -
vendor/current/ctdb/server/ctdb_tunables.c
r988 r989 42 42 { "KeepaliveInterval", 5, offsetof(struct ctdb_tunable_list, keepalive_interval), false }, 43 43 { "KeepaliveLimit", 5, offsetof(struct ctdb_tunable_list, keepalive_limit), false }, 44 { "RecoverTimeout", 120, offsetof(struct ctdb_tunable_list, recover_timeout), false },44 { "RecoverTimeout", 30, offsetof(struct ctdb_tunable_list, recover_timeout), false }, 45 45 { "RecoverInterval", 1, offsetof(struct ctdb_tunable_list, recover_interval), false }, 46 46 { "ElectionTimeout", 3, offsetof(struct ctdb_tunable_list, election_timeout), false }, … … 94 94 { "TDBMutexEnabled", 0, offsetof(struct ctdb_tunable_list, mutex_enabled), false }, 95 95 { "LockProcessesPerDB", 200, offsetof(struct ctdb_tunable_list, lock_processes_per_db), false }, 96 { "RecBufferSizeLimit", 1000000, offsetof(struct ctdb_tunable_list, rec_buffer_size_limit), false }, 96 97 }; 97 98 -
vendor/current/ctdb/server/ctdbd.c
r988 r989 179 179 180 180 ev = tevent_context_init(NULL); 181 if (ev == NULL) { 182 DEBUG(DEBUG_ALERT,("tevent_context_init() failed\n")); 183 exit(1); 184 } 181 185 tevent_loop_allow_nesting(ev); 182 186 -
vendor/current/ctdb/server/eventscript.c
r988 r989 697 697 { 698 698 DLIST_REMOVE(callback->ctdb->script_callbacks, callback); 699 return 0; 700 } 701 702 struct schedule_callback_state { 703 struct ctdb_context *ctdb; 704 void (*callback)(struct ctdb_context *, int, void *); 705 void *private_data; 706 int status; 707 struct tevent_immediate *im; 708 }; 709 710 static void schedule_callback_handler(struct tevent_context *ctx, 711 struct tevent_immediate *im, 712 void *private_data) 713 { 714 struct schedule_callback_state *state = 715 talloc_get_type_abort(private_data, 716 struct schedule_callback_state); 717 718 if (state->callback != NULL) { 719 state->callback(state->ctdb, state->status, 720 state->private_data); 721 } 722 talloc_free(state); 723 } 724 725 static int 726 schedule_callback_immediate(struct ctdb_context *ctdb, 727 void (*callback)(struct ctdb_context *, 728 int, void *), 729 void *private_data, 730 int status) 731 { 732 struct schedule_callback_state *state; 733 struct tevent_immediate *im; 734 735 state = talloc_zero(ctdb, struct schedule_callback_state); 736 if (state == NULL) { 737 DEBUG(DEBUG_ERR, (__location__ " out of memory\n")); 738 return -1; 739 } 740 im = tevent_create_immediate(state); 741 if (im == NULL) { 742 DEBUG(DEBUG_ERR, (__location__ " out of memory\n")); 743 talloc_free(state); 744 return -1; 745 } 746 747 state->ctdb = ctdb; 748 state->callback = callback; 749 state->private_data = private_data; 750 state->status = status; 751 state->im = im; 752 753 tevent_schedule_immediate(im, ctdb->ev, 754 schedule_callback_handler, state); 699 755 return 0; 700 756 } … … 808 864 state->child = 0; 809 865 866 /* Nothing to do? */ 867 if (state->scripts->num_scripts == 0) { 868 int ret = schedule_callback_immediate(ctdb, callback, 869 private_data, 0); 870 talloc_free(state); 871 if (ret != 0) { 872 DEBUG(DEBUG_ERR, 873 ("Unable to schedule callback for 0 scripts\n")); 874 return 1; 875 } 876 return 0; 877 } 878 879 state->scripts->scripts[0].status = fork_child_for_script(ctdb, state); 880 if (state->scripts->scripts[0].status != 0) { 881 talloc_free(state); 882 return -1; 883 } 884 810 885 if (call == CTDB_EVENT_MONITOR) { 811 886 ctdb->current_monitor = state; 812 887 } 813 888 889 ctdb->active_events++; 890 814 891 talloc_set_destructor(state, event_script_destructor); 815 816 ctdb->active_events++;817 818 /* Nothing to do? */819 if (state->scripts->num_scripts == 0) {820 callback(ctdb, 0, private_data);821 talloc_free(state);822 return 0;823 }824 825 state->scripts->scripts[0].status = fork_child_for_script(ctdb, state);826 if (state->scripts->scripts[0].status != 0) {827 /* Callback is called from destructor, with fail result. */828 talloc_free(state);829 return 0;830 }831 892 832 893 if (!timeval_is_zero(&state->timeout)) { … … 1008 1069 CTDB_NO_MEMORY(ctdb, state); 1009 1070 1010 state->c = talloc_steal(state, c);1071 state->c = NULL; 1011 1072 1012 1073 DEBUG(DEBUG_NOTICE,("Running eventscripts with arguments %s\n", indata.dptr)); … … 1024 1085 /* tell ctdb_control.c that we will be replying asynchronously */ 1025 1086 *async_reply = true; 1026 1087 state->c = talloc_steal(state, c); 1027 1088 return 0; 1028 1089 }
Note:
See TracChangeset
for help on using the changeset viewer.