secondary.c (229744) | secondary.c (229945) |
---|---|
1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> 4 * All rights reserved. 5 * 6 * This software was developed by Pawel Jakub Dawidek under sponsorship from 7 * the FreeBSD Foundation. 8 * --- 15 unchanged lines hidden (view full) --- 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> 4 * All rights reserved. 5 * 6 * This software was developed by Pawel Jakub Dawidek under sponsorship from 7 * the FreeBSD Foundation. 8 * --- 15 unchanged lines hidden (view full) --- 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/sbin/hastd/secondary.c 229744 2012-01-06 23:44:26Z pjd $"); | 32__FBSDID("$FreeBSD: head/sbin/hastd/secondary.c 229945 2012-01-10 22:39:07Z pjd $"); |
33 34#include <sys/param.h> 35#include <sys/time.h> 36#include <sys/bio.h> 37#include <sys/disk.h> 38#include <sys/stat.h> 39 40#include <err.h> --- 135 unchanged lines hidden (view full) --- 176 TAILQ_INSERT_HEAD(&hio_free_list, hio, hio_next); 177 } 178} 179 180static void 181init_local(struct hast_resource *res) 182{ 183 | 33 34#include <sys/param.h> 35#include <sys/time.h> 36#include <sys/bio.h> 37#include <sys/disk.h> 38#include <sys/stat.h> 39 40#include <err.h> --- 135 unchanged lines hidden (view full) --- 176 TAILQ_INSERT_HEAD(&hio_free_list, hio, hio_next); 177 } 178} 179 180static void 181init_local(struct hast_resource *res) 182{ 183 |
184 if (metadata_read(res, true) < 0) | 184 if (metadata_read(res, true) == -1) |
185 exit(EX_NOINPUT); 186} 187 188static void 189init_remote(struct hast_resource *res, struct nv *nvin) 190{ 191 uint64_t resuid; 192 struct nv *nvout; --- 64 unchanged lines hidden (view full) --- 257 /* 258 * Provider is used for the first time. If primary node done no 259 * writes yet as well (we will find "virgin" argument) then 260 * there is no need to synchronize anything. If primary node 261 * done any writes already we have to synchronize everything. 262 */ 263 PJDLOG_ASSERT(res->hr_secondary_localcnt == 0); 264 res->hr_resuid = resuid; | 185 exit(EX_NOINPUT); 186} 187 188static void 189init_remote(struct hast_resource *res, struct nv *nvin) 190{ 191 uint64_t resuid; 192 struct nv *nvout; --- 64 unchanged lines hidden (view full) --- 257 /* 258 * Provider is used for the first time. If primary node done no 259 * writes yet as well (we will find "virgin" argument) then 260 * there is no need to synchronize anything. If primary node 261 * done any writes already we have to synchronize everything. 262 */ 263 PJDLOG_ASSERT(res->hr_secondary_localcnt == 0); 264 res->hr_resuid = resuid; |
265 if (metadata_write(res) < 0) | 265 if (metadata_write(res) == -1) |
266 exit(EX_NOINPUT); 267 if (nv_exists(nvin, "virgin")) { 268 free(map); 269 map = NULL; 270 mapsize = 0; 271 } else { 272 memset(map, 0xff, mapsize); 273 } 274 nv_add_int8(nvout, 1, "virgin"); 275 nv_add_uint8(nvout, HAST_SYNCSRC_PRIMARY, "syncsrc"); 276 } else if (res->hr_resuid != resuid) { 277 char errmsg[256]; 278 279 free(map); 280 (void)snprintf(errmsg, sizeof(errmsg), 281 "Resource unique ID mismatch (primary=%ju, secondary=%ju).", 282 (uintmax_t)resuid, (uintmax_t)res->hr_resuid); 283 pjdlog_error("%s", errmsg); 284 nv_add_string(nvout, errmsg, "errmsg"); | 266 exit(EX_NOINPUT); 267 if (nv_exists(nvin, "virgin")) { 268 free(map); 269 map = NULL; 270 mapsize = 0; 271 } else { 272 memset(map, 0xff, mapsize); 273 } 274 nv_add_int8(nvout, 1, "virgin"); 275 nv_add_uint8(nvout, HAST_SYNCSRC_PRIMARY, "syncsrc"); 276 } else if (res->hr_resuid != resuid) { 277 char errmsg[256]; 278 279 free(map); 280 (void)snprintf(errmsg, sizeof(errmsg), 281 "Resource unique ID mismatch (primary=%ju, secondary=%ju).", 282 (uintmax_t)resuid, (uintmax_t)res->hr_resuid); 283 pjdlog_error("%s", errmsg); 284 nv_add_string(nvout, errmsg, "errmsg"); |
285 if (hast_proto_send(res, res->hr_remotein, nvout, NULL, 0) < 0) { | 285 if (hast_proto_send(res, res->hr_remotein, nvout, NULL, 0) == -1) { |
286 pjdlog_exit(EX_TEMPFAIL, "Unable to send response to %s", 287 res->hr_remoteaddr); 288 } 289 nv_free(nvout); 290 exit(EX_CONFIG); 291 } else if ( 292 /* Is primary out-of-date? */ 293 (res->hr_secondary_localcnt > res->hr_primary_remotecnt && --- 28 unchanged lines hidden (view full) --- 322 } else if (res->hr_secondary_localcnt > res->hr_primary_remotecnt && 323 res->hr_primary_localcnt > res->hr_secondary_remotecnt) { 324 /* 325 * Not good, we have split-brain condition. 326 */ 327 free(map); 328 pjdlog_error("Split-brain detected, exiting."); 329 nv_add_string(nvout, "Split-brain condition!", "errmsg"); | 286 pjdlog_exit(EX_TEMPFAIL, "Unable to send response to %s", 287 res->hr_remoteaddr); 288 } 289 nv_free(nvout); 290 exit(EX_CONFIG); 291 } else if ( 292 /* Is primary out-of-date? */ 293 (res->hr_secondary_localcnt > res->hr_primary_remotecnt && --- 28 unchanged lines hidden (view full) --- 322 } else if (res->hr_secondary_localcnt > res->hr_primary_remotecnt && 323 res->hr_primary_localcnt > res->hr_secondary_remotecnt) { 324 /* 325 * Not good, we have split-brain condition. 326 */ 327 free(map); 328 pjdlog_error("Split-brain detected, exiting."); 329 nv_add_string(nvout, "Split-brain condition!", "errmsg"); |
330 if (hast_proto_send(res, res->hr_remotein, nvout, NULL, 0) < 0) { | 330 if (hast_proto_send(res, res->hr_remotein, nvout, NULL, 0) == -1) { |
331 pjdlog_exit(EX_TEMPFAIL, "Unable to send response to %s", 332 res->hr_remoteaddr); 333 } 334 nv_free(nvout); 335 /* Exit on split-brain. */ 336 event_send(res, EVENT_SPLITBRAIN); 337 exit(EX_CONFIG); 338 } else /* if (res->hr_secondary_localcnt < res->hr_primary_remotecnt || --- 17 unchanged lines hidden (view full) --- 356 } 357 pjdlog_warning("This should never happen, asking for full synchronization (primary(local=%ju, remote=%ju), secondary(local=%ju, remote=%ju)).", 358 (uintmax_t)res->hr_primary_localcnt, 359 (uintmax_t)res->hr_primary_remotecnt, 360 (uintmax_t)res->hr_secondary_localcnt, 361 (uintmax_t)res->hr_secondary_remotecnt); 362 } 363 nv_add_uint32(nvout, (uint32_t)mapsize, "mapsize"); | 331 pjdlog_exit(EX_TEMPFAIL, "Unable to send response to %s", 332 res->hr_remoteaddr); 333 } 334 nv_free(nvout); 335 /* Exit on split-brain. */ 336 event_send(res, EVENT_SPLITBRAIN); 337 exit(EX_CONFIG); 338 } else /* if (res->hr_secondary_localcnt < res->hr_primary_remotecnt || --- 17 unchanged lines hidden (view full) --- 356 } 357 pjdlog_warning("This should never happen, asking for full synchronization (primary(local=%ju, remote=%ju), secondary(local=%ju, remote=%ju)).", 358 (uintmax_t)res->hr_primary_localcnt, 359 (uintmax_t)res->hr_primary_remotecnt, 360 (uintmax_t)res->hr_secondary_localcnt, 361 (uintmax_t)res->hr_secondary_remotecnt); 362 } 363 nv_add_uint32(nvout, (uint32_t)mapsize, "mapsize"); |
364 if (hast_proto_send(res, res->hr_remotein, nvout, map, mapsize) < 0) { | 364 if (hast_proto_send(res, res->hr_remotein, nvout, map, mapsize) == -1) { |
365 pjdlog_exit(EX_TEMPFAIL, "Unable to send activemap to %s", 366 res->hr_remoteaddr); 367 } 368 if (map != NULL) 369 free(map); 370 nv_free(nvout); 371#ifdef notyet 372 /* Setup direction. */ --- 8 unchanged lines hidden (view full) --- 381 sigset_t mask; 382 pthread_t td; 383 pid_t pid; 384 int error, mode, debuglevel; 385 386 /* 387 * Create communication channel between parent and child. 388 */ | 365 pjdlog_exit(EX_TEMPFAIL, "Unable to send activemap to %s", 366 res->hr_remoteaddr); 367 } 368 if (map != NULL) 369 free(map); 370 nv_free(nvout); 371#ifdef notyet 372 /* Setup direction. */ --- 8 unchanged lines hidden (view full) --- 381 sigset_t mask; 382 pthread_t td; 383 pid_t pid; 384 int error, mode, debuglevel; 385 386 /* 387 * Create communication channel between parent and child. 388 */ |
389 if (proto_client(NULL, "socketpair://", &res->hr_ctrl) < 0) { | 389 if (proto_client(NULL, "socketpair://", &res->hr_ctrl) == -1) { |
390 KEEP_ERRNO((void)pidfile_remove(pfh)); 391 pjdlog_exit(EX_OSERR, 392 "Unable to create control sockets between parent and child"); 393 } 394 /* 395 * Create communication channel between child and parent. 396 */ | 390 KEEP_ERRNO((void)pidfile_remove(pfh)); 391 pjdlog_exit(EX_OSERR, 392 "Unable to create control sockets between parent and child"); 393 } 394 /* 395 * Create communication channel between child and parent. 396 */ |
397 if (proto_client(NULL, "socketpair://", &res->hr_event) < 0) { | 397 if (proto_client(NULL, "socketpair://", &res->hr_event) == -1) { |
398 KEEP_ERRNO((void)pidfile_remove(pfh)); 399 pjdlog_exit(EX_OSERR, 400 "Unable to create event sockets between child and parent"); 401 } 402 403 pid = fork(); 404 if (pid == -1) { 405 KEEP_ERRNO((void)pidfile_remove(pfh)); --- 30 unchanged lines hidden (view full) --- 436 pjdlog_debug_set(debuglevel); 437 pjdlog_prefix_set("[%s] (%s) ", res->hr_name, role2str(res->hr_role)); 438 setproctitle("%s (%s)", res->hr_name, role2str(res->hr_role)); 439 440 PJDLOG_VERIFY(sigemptyset(&mask) == 0); 441 PJDLOG_VERIFY(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); 442 443 /* Error in setting timeout is not critical, but why should it fail? */ | 398 KEEP_ERRNO((void)pidfile_remove(pfh)); 399 pjdlog_exit(EX_OSERR, 400 "Unable to create event sockets between child and parent"); 401 } 402 403 pid = fork(); 404 if (pid == -1) { 405 KEEP_ERRNO((void)pidfile_remove(pfh)); --- 30 unchanged lines hidden (view full) --- 436 pjdlog_debug_set(debuglevel); 437 pjdlog_prefix_set("[%s] (%s) ", res->hr_name, role2str(res->hr_role)); 438 setproctitle("%s (%s)", res->hr_name, role2str(res->hr_role)); 439 440 PJDLOG_VERIFY(sigemptyset(&mask) == 0); 441 PJDLOG_VERIFY(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); 442 443 /* Error in setting timeout is not critical, but why should it fail? */ |
444 if (proto_timeout(res->hr_remotein, 2 * HAST_KEEPALIVE) < 0) | 444 if (proto_timeout(res->hr_remotein, 2 * HAST_KEEPALIVE) == -1) |
445 pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); | 445 pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); |
446 if (proto_timeout(res->hr_remoteout, res->hr_timeout) < 0) | 446 if (proto_timeout(res->hr_remoteout, res->hr_timeout) == -1) |
447 pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); 448 449 init_local(res); 450 init_environment(); 451 452 if (drop_privs(res) != 0) 453 exit(EX_CONFIG); 454 pjdlog_info("Privileges successfully dropped."); --- 163 unchanged lines hidden (view full) --- 618 struct hast_resource *res = arg; 619 struct hio *hio; 620 struct nv *nv; 621 622 for (;;) { 623 pjdlog_debug(2, "recv: Taking free request."); 624 QUEUE_TAKE(free, hio); 625 pjdlog_debug(2, "recv: (%p) Got request.", hio); | 447 pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); 448 449 init_local(res); 450 init_environment(); 451 452 if (drop_privs(res) != 0) 453 exit(EX_CONFIG); 454 pjdlog_info("Privileges successfully dropped."); --- 163 unchanged lines hidden (view full) --- 618 struct hast_resource *res = arg; 619 struct hio *hio; 620 struct nv *nv; 621 622 for (;;) { 623 pjdlog_debug(2, "recv: Taking free request."); 624 QUEUE_TAKE(free, hio); 625 pjdlog_debug(2, "recv: (%p) Got request.", hio); |
626 if (hast_proto_recv_hdr(res->hr_remotein, &nv) < 0) { | 626 if (hast_proto_recv_hdr(res->hr_remotein, &nv) == -1) { |
627 secondary_exit(EX_TEMPFAIL, 628 "Unable to receive request header"); 629 } 630 if (requnpack(res, hio, nv) != 0) { 631 nv_free(nv); 632 pjdlog_debug(2, 633 "recv: (%p) Moving request to the send queue.", 634 hio); --- 26 unchanged lines hidden (view full) --- 661 pjdlog_debug(2, 662 "recv: (%p) Moving request to the free queue.", 663 hio); 664 hio_clear(hio); 665 QUEUE_INSERT(free, hio); 666 continue; 667 } else if (hio->hio_cmd == HIO_WRITE) { 668 if (hast_proto_recv_data(res, res->hr_remotein, nv, | 627 secondary_exit(EX_TEMPFAIL, 628 "Unable to receive request header"); 629 } 630 if (requnpack(res, hio, nv) != 0) { 631 nv_free(nv); 632 pjdlog_debug(2, 633 "recv: (%p) Moving request to the send queue.", 634 hio); --- 26 unchanged lines hidden (view full) --- 661 pjdlog_debug(2, 662 "recv: (%p) Moving request to the free queue.", 663 hio); 664 hio_clear(hio); 665 QUEUE_INSERT(free, hio); 666 continue; 667 } else if (hio->hio_cmd == HIO_WRITE) { 668 if (hast_proto_recv_data(res, res->hr_remotein, nv, |
669 hio->hio_data, MAXPHYS) < 0) { | 669 hio->hio_data, MAXPHYS) == -1) { |
670 secondary_exit(EX_TEMPFAIL, 671 "Unable to receive request data"); 672 } 673 } 674 nv_free(nv); 675 pjdlog_debug(2, "recv: (%p) Moving request to the disk queue.", 676 hio); 677 QUEUE_INSERT(disk, hio); --- 52 unchanged lines hidden (view full) --- 730 reqlog(LOG_DEBUG, 2, -1, hio, "disk: (%p) Got request: ", hio); 731 logerror = true; 732 /* Handle the actual request. */ 733 switch (hio->hio_cmd) { 734 case HIO_READ: 735 ret = pread(res->hr_localfd, hio->hio_data, 736 hio->hio_length, 737 hio->hio_offset + res->hr_localoff); | 670 secondary_exit(EX_TEMPFAIL, 671 "Unable to receive request data"); 672 } 673 } 674 nv_free(nv); 675 pjdlog_debug(2, "recv: (%p) Moving request to the disk queue.", 676 hio); 677 QUEUE_INSERT(disk, hio); --- 52 unchanged lines hidden (view full) --- 730 reqlog(LOG_DEBUG, 2, -1, hio, "disk: (%p) Got request: ", hio); 731 logerror = true; 732 /* Handle the actual request. */ 733 switch (hio->hio_cmd) { 734 case HIO_READ: 735 ret = pread(res->hr_localfd, hio->hio_data, 736 hio->hio_length, 737 hio->hio_offset + res->hr_localoff); |
738 if (ret < 0) | 738 if (ret == -1) |
739 hio->hio_error = errno; 740 else if (ret != (int64_t)hio->hio_length) 741 hio->hio_error = EIO; 742 else 743 hio->hio_error = 0; 744 break; 745 case HIO_WRITE: 746 ret = pwrite(res->hr_localfd, hio->hio_data, 747 hio->hio_length, 748 hio->hio_offset + res->hr_localoff); | 739 hio->hio_error = errno; 740 else if (ret != (int64_t)hio->hio_length) 741 hio->hio_error = EIO; 742 else 743 hio->hio_error = 0; 744 break; 745 case HIO_WRITE: 746 ret = pwrite(res->hr_localfd, hio->hio_data, 747 hio->hio_length, 748 hio->hio_offset + res->hr_localoff); |
749 if (ret < 0) | 749 if (ret == -1) |
750 hio->hio_error = errno; 751 else if (ret != (int64_t)hio->hio_length) 752 hio->hio_error = EIO; 753 else 754 hio->hio_error = 0; 755 break; 756 case HIO_DELETE: 757 ret = g_delete(res->hr_localfd, 758 hio->hio_offset + res->hr_localoff, 759 hio->hio_length); | 750 hio->hio_error = errno; 751 else if (ret != (int64_t)hio->hio_length) 752 hio->hio_error = EIO; 753 else 754 hio->hio_error = 0; 755 break; 756 case HIO_DELETE: 757 ret = g_delete(res->hr_localfd, 758 hio->hio_offset + res->hr_localoff, 759 hio->hio_length); |
760 if (ret < 0) | 760 if (ret == -1) |
761 hio->hio_error = errno; 762 else 763 hio->hio_error = 0; 764 break; 765 case HIO_FLUSH: 766 if (!res->hr_localflush) { 767 ret = -1; 768 hio->hio_error = EOPNOTSUPP; 769 logerror = false; 770 break; 771 } 772 ret = g_flush(res->hr_localfd); | 761 hio->hio_error = errno; 762 else 763 hio->hio_error = 0; 764 break; 765 case HIO_FLUSH: 766 if (!res->hr_localflush) { 767 ret = -1; 768 hio->hio_error = EOPNOTSUPP; 769 logerror = false; 770 break; 771 } 772 ret = g_flush(res->hr_localfd); |
773 if (ret < 0) { | 773 if (ret == -1) { |
774 if (errno == EOPNOTSUPP) 775 res->hr_localflush = false; 776 hio->hio_error = errno; 777 } else { 778 hio->hio_error = 0; 779 } 780 break; 781 default: --- 50 unchanged lines hidden (view full) --- 832 break; 833 default: 834 PJDLOG_ABORT("Unexpected command (cmd=%hhu).", 835 hio->hio_cmd); 836 } 837 if (hio->hio_error != 0) 838 nv_add_int16(nvout, hio->hio_error, "error"); 839 if (hast_proto_send(res, res->hr_remoteout, nvout, data, | 774 if (errno == EOPNOTSUPP) 775 res->hr_localflush = false; 776 hio->hio_error = errno; 777 } else { 778 hio->hio_error = 0; 779 } 780 break; 781 default: --- 50 unchanged lines hidden (view full) --- 832 break; 833 default: 834 PJDLOG_ABORT("Unexpected command (cmd=%hhu).", 835 hio->hio_cmd); 836 } 837 if (hio->hio_error != 0) 838 nv_add_int16(nvout, hio->hio_error, "error"); 839 if (hast_proto_send(res, res->hr_remoteout, nvout, data, |
840 length) < 0) { | 840 length) == -1) { |
841 secondary_exit(EX_TEMPFAIL, "Unable to send reply."); 842 } 843 nv_free(nvout); 844 pjdlog_debug(2, "send: (%p) Moving request to the free queue.", 845 hio); 846 hio_clear(hio); 847 QUEUE_INSERT(free, hio); 848 } 849 /* NOTREACHED */ 850 return (NULL); 851} | 841 secondary_exit(EX_TEMPFAIL, "Unable to send reply."); 842 } 843 nv_free(nvout); 844 pjdlog_debug(2, "send: (%p) Moving request to the free queue.", 845 hio); 846 hio_clear(hio); 847 QUEUE_INSERT(free, hio); 848 } 849 /* NOTREACHED */ 850 return (NULL); 851} |