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 246922 2013-02-17 21:12:34Z 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>
--- 25 unchanged lines hidden (view full) ---
66
67struct hio {
68 uint64_t hio_seq;
69 int hio_error;
70 void *hio_data;
71 uint8_t hio_cmd;
72 uint64_t hio_offset;
73 uint64_t hio_length;
74 bool hio_memsync;
75 TAILQ_ENTRY(hio) hio_next;
76};
77
78static struct hast_resource *gres;
79
80/*
81 * Free list holds unused structures. When free list is empty, we have to wait
82 * until some in-progress requests are freed.
--- 48 unchanged lines hidden (view full) ---
131hio_clear(struct hio *hio)
132{
133
134 hio->hio_seq = 0;
135 hio->hio_error = 0;
136 hio->hio_cmd = HIO_UNDEF;
137 hio->hio_offset = 0;
138 hio->hio_length = 0;
139 hio->hio_memsync = false;
140}
141
142static void
143hio_copy(const struct hio *srchio, struct hio *dsthio)
144{
145
146 /*
147 * We don't copy hio_error, hio_data and hio_next fields.
148 */
149
150 dsthio->hio_seq = srchio->hio_seq;
151 dsthio->hio_cmd = srchio->hio_cmd;
152 dsthio->hio_offset = srchio->hio_offset;
153 dsthio->hio_length = srchio->hio_length;
154 dsthio->hio_memsync = srchio->hio_memsync;
155}
156
157static void
158init_environment(void)
159{
160 struct hio *hio;
161 unsigned int ii;
162
163 /*
164 * Initialize lists, their locks and theirs condition variables.
165 */
--- 389 unchanged lines hidden (view full) ---
555 hio->hio_error = EINVAL;
556 goto end;
557 }
558 }
559 switch (hio->hio_cmd) {
560 case HIO_FLUSH:
561 case HIO_KEEPALIVE:
562 break;
563 case HIO_WRITE:
564 hio->hio_memsync = nv_exists(nv, "memsync");
565 /* FALLTHROUGH */
566 case HIO_READ:
567 case HIO_DELETE:
568 hio->hio_offset = nv_get_uint64(nv, "offset");
569 if (nv_error(nv) != 0) {
570 pjdlog_error("Header is missing 'offset' field.");
571 hio->hio_error = EINVAL;
572 goto end;
573 }
574 hio->hio_length = nv_get_uint64(nv, "length");
--- 60 unchanged lines hidden (view full) ---
635
636/*
637 * Thread receives requests from the primary node.
638 */
639static void *
640recv_thread(void *arg)
641{
642 struct hast_resource *res = arg;
643 struct hio *hio, *mshio;
644 struct nv *nv;
645
646 for (;;) {
647 pjdlog_debug(2, "recv: Taking free request.");
648 QUEUE_TAKE(free, hio);
649 pjdlog_debug(2, "recv: (%p) Got request.", hio);
650 if (hast_proto_recv_hdr(res->hr_remotein, &nv) == -1) {
651 secondary_exit(EX_TEMPFAIL,
--- 37 unchanged lines hidden (view full) ---
689 QUEUE_INSERT(free, hio);
690 continue;
691 } else if (hio->hio_cmd == HIO_WRITE) {
692 if (hast_proto_recv_data(res, res->hr_remotein, nv,
693 hio->hio_data, MAXPHYS) == -1) {
694 secondary_exit(EX_TEMPFAIL,
695 "Unable to receive request data");
696 }
697 if (hio->hio_memsync) {
698 /*
699 * For memsync requests we expect two replies.
700 * Clone the hio so we can handle both of them.
701 */
702 pjdlog_debug(2, "recv: Taking free request.");
703 QUEUE_TAKE(free, mshio);
704 pjdlog_debug(2, "recv: (%p) Got request.",
705 mshio);
706 hio_copy(hio, mshio);
707 mshio->hio_error = 0;
708 /*
709 * We want to keep 'memsync' tag only on the
710 * request going onto send queue (mshio).
711 */
712 hio->hio_memsync = false;
713 pjdlog_debug(2,
714 "recv: (%p) Moving memsync request to the send queue.",
715 mshio);
716 QUEUE_INSERT(send, mshio);
717 }
718 }
719 nv_free(nv);
720 pjdlog_debug(2, "recv: (%p) Moving request to the disk queue.",
721 hio);
722 QUEUE_INSERT(disk, hio);
723 }
724 /* NOTREACHED */
725 return (NULL);
--- 127 unchanged lines hidden (view full) ---
853
854 for (;;) {
855 pjdlog_debug(2, "send: Taking request.");
856 QUEUE_TAKE(send, hio);
857 reqlog(LOG_DEBUG, 2, -1, hio, "send: (%p) Got request: ", hio);
858 nvout = nv_alloc();
859 /* Copy sequence number. */
860 nv_add_uint64(nvout, hio->hio_seq, "seq");
861 if (hio->hio_memsync) {
862 PJDLOG_ASSERT(hio->hio_cmd == HIO_WRITE);
863 nv_add_int8(nvout, 1, "received");
864 }
865 switch (hio->hio_cmd) {
866 case HIO_READ:
867 if (hio->hio_error == 0) {
868 data = hio->hio_data;
869 length = hio->hio_length;
870 break;
871 }
872 /*
--- 28 unchanged lines hidden ---
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 246922 2013-02-17 21:12:34Z 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>
--- 25 unchanged lines hidden (view full) ---
66
67struct hio {
68 uint64_t hio_seq;
69 int hio_error;
70 void *hio_data;
71 uint8_t hio_cmd;
72 uint64_t hio_offset;
73 uint64_t hio_length;
74 bool hio_memsync;
75 TAILQ_ENTRY(hio) hio_next;
76};
77
78static struct hast_resource *gres;
79
80/*
81 * Free list holds unused structures. When free list is empty, we have to wait
82 * until some in-progress requests are freed.
--- 48 unchanged lines hidden (view full) ---
131hio_clear(struct hio *hio)
132{
133
134 hio->hio_seq = 0;
135 hio->hio_error = 0;
136 hio->hio_cmd = HIO_UNDEF;
137 hio->hio_offset = 0;
138 hio->hio_length = 0;
139 hio->hio_memsync = false;
140}
141
142static void
143hio_copy(const struct hio *srchio, struct hio *dsthio)
144{
145
146 /*
147 * We don't copy hio_error, hio_data and hio_next fields.
148 */
149
150 dsthio->hio_seq = srchio->hio_seq;
151 dsthio->hio_cmd = srchio->hio_cmd;
152 dsthio->hio_offset = srchio->hio_offset;
153 dsthio->hio_length = srchio->hio_length;
154 dsthio->hio_memsync = srchio->hio_memsync;
155}
156
157static void
158init_environment(void)
159{
160 struct hio *hio;
161 unsigned int ii;
162
163 /*
164 * Initialize lists, their locks and theirs condition variables.
165 */
--- 389 unchanged lines hidden (view full) ---
555 hio->hio_error = EINVAL;
556 goto end;
557 }
558 }
559 switch (hio->hio_cmd) {
560 case HIO_FLUSH:
561 case HIO_KEEPALIVE:
562 break;
563 case HIO_WRITE:
564 hio->hio_memsync = nv_exists(nv, "memsync");
565 /* FALLTHROUGH */
566 case HIO_READ:
567 case HIO_DELETE:
568 hio->hio_offset = nv_get_uint64(nv, "offset");
569 if (nv_error(nv) != 0) {
570 pjdlog_error("Header is missing 'offset' field.");
571 hio->hio_error = EINVAL;
572 goto end;
573 }
574 hio->hio_length = nv_get_uint64(nv, "length");
--- 60 unchanged lines hidden (view full) ---
635
636/*
637 * Thread receives requests from the primary node.
638 */
639static void *
640recv_thread(void *arg)
641{
642 struct hast_resource *res = arg;
643 struct hio *hio, *mshio;
644 struct nv *nv;
645
646 for (;;) {
647 pjdlog_debug(2, "recv: Taking free request.");
648 QUEUE_TAKE(free, hio);
649 pjdlog_debug(2, "recv: (%p) Got request.", hio);
650 if (hast_proto_recv_hdr(res->hr_remotein, &nv) == -1) {
651 secondary_exit(EX_TEMPFAIL,
--- 37 unchanged lines hidden (view full) ---
689 QUEUE_INSERT(free, hio);
690 continue;
691 } else if (hio->hio_cmd == HIO_WRITE) {
692 if (hast_proto_recv_data(res, res->hr_remotein, nv,
693 hio->hio_data, MAXPHYS) == -1) {
694 secondary_exit(EX_TEMPFAIL,
695 "Unable to receive request data");
696 }
697 if (hio->hio_memsync) {
698 /*
699 * For memsync requests we expect two replies.
700 * Clone the hio so we can handle both of them.
701 */
702 pjdlog_debug(2, "recv: Taking free request.");
703 QUEUE_TAKE(free, mshio);
704 pjdlog_debug(2, "recv: (%p) Got request.",
705 mshio);
706 hio_copy(hio, mshio);
707 mshio->hio_error = 0;
708 /*
709 * We want to keep 'memsync' tag only on the
710 * request going onto send queue (mshio).
711 */
712 hio->hio_memsync = false;
713 pjdlog_debug(2,
714 "recv: (%p) Moving memsync request to the send queue.",
715 mshio);
716 QUEUE_INSERT(send, mshio);
717 }
718 }
719 nv_free(nv);
720 pjdlog_debug(2, "recv: (%p) Moving request to the disk queue.",
721 hio);
722 QUEUE_INSERT(disk, hio);
723 }
724 /* NOTREACHED */
725 return (NULL);
--- 127 unchanged lines hidden (view full) ---
853
854 for (;;) {
855 pjdlog_debug(2, "send: Taking request.");
856 QUEUE_TAKE(send, hio);
857 reqlog(LOG_DEBUG, 2, -1, hio, "send: (%p) Got request: ", hio);
858 nvout = nv_alloc();
859 /* Copy sequence number. */
860 nv_add_uint64(nvout, hio->hio_seq, "seq");
861 if (hio->hio_memsync) {
862 PJDLOG_ASSERT(hio->hio_cmd == HIO_WRITE);
863 nv_add_int8(nvout, 1, "received");
864 }
865 switch (hio->hio_cmd) {
866 case HIO_READ:
867 if (hio->hio_error == 0) {
868 data = hio->hio_data;
869 length = hio->hio_length;
870 break;
871 }
872 /*
--- 28 unchanged lines hidden ---