Deleted Added
sdiff udiff text old ( 217732 ) new ( 225787 )
full compact
1/*-
2 * Copyright (c) 2009-2010 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Pawel Jakub Dawidek under sponsorship from
6 * the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sbin/hastd/nv.c 225787 2011-09-27 08:50:37Z pjd $");
32
33#include <sys/param.h>
34#include <sys/endian.h>
35
36#include <bitstring.h>
37#include <errno.h>
38#include <stdarg.h>
39#include <stdbool.h>
40#include <stdint.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44
45#include <ebuf.h>
46#include <pjdlog.h>
47
48#include "nv.h"
49
50#ifndef PJDLOG_ASSERT
51#include <assert.h>
52#define PJDLOG_ASSERT(...) assert(__VA_ARGS__)
53#endif
54#ifndef PJDLOG_ABORT
55#define PJDLOG_ABORT(...) abort()
56#endif
57
58#define NV_TYPE_NONE 0
59
60#define NV_TYPE_INT8 1
61#define NV_TYPE_UINT8 2
62#define NV_TYPE_INT16 3
63#define NV_TYPE_UINT16 4
64#define NV_TYPE_INT32 5
65#define NV_TYPE_UINT32 6

--- 36 unchanged lines hidden (view full) ---

102 (sizeof(struct nvhdr) + roundup2((nvh)->nvh_namesize, 8))
103#define NVH_DSIZE(nvh) \
104 (((nvh)->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST ? \
105 (nvh)->nvh_dsize : \
106 le32toh((nvh)->nvh_dsize))
107#define NVH_SIZE(nvh) (NVH_HSIZE(nvh) + roundup2(NVH_DSIZE(nvh), 8))
108
109#define NV_CHECK(nv) do { \
110 PJDLOG_ASSERT((nv) != NULL); \
111 PJDLOG_ASSERT((nv)->nv_magic == NV_MAGIC); \
112} while (0)
113
114static void nv_add(struct nv *nv, const unsigned char *value, size_t vsize,
115 int type, const char *name);
116static void nv_addv(struct nv *nv, const unsigned char *value, size_t vsize,
117 int type, const char *namefmt, va_list nameap);
118static struct nvhdr *nv_find(struct nv *nv, int type, const char *namefmt,
119 va_list nameap);

--- 84 unchanged lines hidden (view full) ---

204 int error;
205
206 if (nv == NULL) {
207 errno = ENOMEM;
208 return (-1);
209 }
210
211 NV_CHECK(nv);
212 PJDLOG_ASSERT(nv->nv_error == 0);
213
214 /* TODO: Check that names are unique? */
215
216 error = 0;
217 ptr = ebuf_data(nv->nv_ebuf, &size);
218 while (size > 0) {
219 /*
220 * Zeros at the end of the buffer are acceptable.

--- 91 unchanged lines hidden (view full) ---

312 break;
313 }
314 if (strlen((char *)data) != dsize - 1) {
315 error = EINVAL;
316 break;
317 }
318 break;
319 default:
320 PJDLOG_ABORT("invalid condition");
321 }
322 if (error != 0)
323 break;
324 ptr += NVH_SIZE(nvh);
325 size -= NVH_SIZE(nvh);
326 }
327 if (error != 0) {
328 errno = error;

--- 13 unchanged lines hidden (view full) ---

342struct ebuf *
343nv_hton(struct nv *nv)
344{
345 struct nvhdr *nvh;
346 unsigned char *ptr;
347 size_t size;
348
349 NV_CHECK(nv);
350 PJDLOG_ASSERT(nv->nv_error == 0);
351
352 ptr = ebuf_data(nv->nv_ebuf, &size);
353 while (size > 0) {
354 /*
355 * Minimum size at this point is size of nvhdr structure,
356 * one character long name plus terminating '\0'.
357 */
358 PJDLOG_ASSERT(size >= sizeof(*nvh) + 2);
359 nvh = (struct nvhdr *)ptr;
360 PJDLOG_ASSERT(NVH_SIZE(nvh) <= size);
361 nv_swap(nvh, false);
362 ptr += NVH_SIZE(nvh);
363 size -= NVH_SIZE(nvh);
364 }
365
366 return (nv->nv_ebuf);
367}
368
369/*
370 * Create nv structure based on ebuf received from the network.
371 */
372struct nv *
373nv_ntoh(struct ebuf *eb)
374{
375 struct nv *nv;
376 size_t extra;
377 int rerrno;
378
379 PJDLOG_ASSERT(eb != NULL);
380
381 nv = malloc(sizeof(*nv));
382 if (nv == NULL)
383 return (NULL);
384 nv->nv_error = 0;
385 nv->nv_ebuf = eb;
386 nv->nv_magic = NV_MAGIC;
387

--- 110 unchanged lines hidden (view full) ---

498 va_list nameap; \
499 type##_t value; \
500 \
501 va_start(nameap, namefmt); \
502 nvh = nv_find(nv, NV_TYPE_##TYPE, namefmt, nameap); \
503 va_end(nameap); \
504 if (nvh == NULL) \
505 return (0); \
506 PJDLOG_ASSERT((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST);\
507 PJDLOG_ASSERT(sizeof(value) == nvh->nvh_dsize); \
508 bcopy(NVH_DATA(nvh), &value, sizeof(value)); \
509 \
510 return (value); \
511}
512
513NV_DEFINE_GET(int8, INT8)
514NV_DEFINE_GET(uint8, UINT8)
515NV_DEFINE_GET(int16, INT16)

--- 13 unchanged lines hidden (view full) ---

529 struct nvhdr *nvh; \
530 va_list nameap; \
531 \
532 va_start(nameap, namefmt); \
533 nvh = nv_find(nv, NV_TYPE_##TYPE##_ARRAY, namefmt, nameap); \
534 va_end(nameap); \
535 if (nvh == NULL) \
536 return (NULL); \
537 PJDLOG_ASSERT((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST);\
538 PJDLOG_ASSERT((nvh->nvh_dsize % sizeof(type##_t)) == 0); \
539 if (sizep != NULL) \
540 *sizep = nvh->nvh_dsize / sizeof(type##_t); \
541 return ((type##_t *)(void *)NVH_DATA(nvh)); \
542}
543
544NV_DEFINE_GET_ARRAY(int8, INT8)
545NV_DEFINE_GET_ARRAY(uint8, UINT8)
546NV_DEFINE_GET_ARRAY(int16, INT16)

--- 12 unchanged lines hidden (view full) ---

559 va_list nameap;
560 char *str;
561
562 va_start(nameap, namefmt);
563 nvh = nv_find(nv, NV_TYPE_STRING, namefmt, nameap);
564 va_end(nameap);
565 if (nvh == NULL)
566 return (NULL);
567 PJDLOG_ASSERT((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST);
568 PJDLOG_ASSERT(nvh->nvh_dsize >= 1);
569 str = NVH_DATA(nvh);
570 PJDLOG_ASSERT(str[nvh->nvh_dsize - 1] == '\0');
571 PJDLOG_ASSERT(strlen(str) == nvh->nvh_dsize - 1);
572 return (str);
573}
574
575static bool
576nv_vexists(struct nv *nv, const char *namefmt, va_list nameap)
577{
578 struct nvhdr *nvh;
579 int snverror, serrno;

--- 26 unchanged lines hidden (view full) ---

606}
607
608void
609nv_assert(struct nv *nv, const char *namefmt, ...)
610{
611 va_list nameap;
612
613 va_start(nameap, namefmt);
614 PJDLOG_ASSERT(nv_vexists(nv, namefmt, nameap));
615 va_end(nameap);
616}
617
618/*
619 * Dump content of the nv structure.
620 */
621void
622nv_dump(struct nv *nv)

--- 5 unchanged lines hidden (view full) ---

628 bool swap;
629
630 if (nv_validate(nv, NULL) < 0) {
631 printf("error: %d\n", errno);
632 return;
633 }
634
635 NV_CHECK(nv);
636 PJDLOG_ASSERT(nv->nv_error == 0);
637
638 ptr = ebuf_data(nv->nv_ebuf, &size);
639 while (size > 0) {
640 PJDLOG_ASSERT(size >= sizeof(*nvh) + 2);
641 nvh = (struct nvhdr *)ptr;
642 PJDLOG_ASSERT(size >= NVH_SIZE(nvh));
643 swap = ((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_NETWORK);
644 dsize = NVH_DSIZE(nvh);
645 data = NVH_DATA(nvh);
646 printf(" %s", nvh->nvh_name);
647 switch (nvh->nvh_type & NV_TYPE_MASK) {
648 case NV_TYPE_INT8:
649 printf("(int8): %jd", (intmax_t)(*(int8_t *)data));
650 break;

--- 87 unchanged lines hidden (view full) ---

738 (uintmax_t)le64toh(((uint64_t *)(void *)data)[ii]) :
739 (uintmax_t)((uint64_t *)(void *)data)[ii]);
740 }
741 break;
742 case NV_TYPE_STRING:
743 printf("(string): %s", (char *)data);
744 break;
745 default:
746 PJDLOG_ABORT("invalid condition");
747 }
748 printf("\n");
749 ptr += NVH_SIZE(nvh);
750 size -= NVH_SIZE(nvh);
751 }
752}
753
754/*

--- 25 unchanged lines hidden (view full) ---

780 }
781 nvh->nvh_type = NV_ORDER_HOST | type;
782 nvh->nvh_namesize = (uint8_t)namesize;
783 nvh->nvh_dsize = (uint32_t)vsize;
784 bcopy(name, nvh->nvh_name, namesize);
785
786 /* Add header first. */
787 if (ebuf_add_tail(nv->nv_ebuf, nvh, NVH_HSIZE(nvh)) < 0) {
788 PJDLOG_ASSERT(errno != 0);
789 if (nv->nv_error == 0)
790 nv->nv_error = errno;
791 free(nvh);
792 return;
793 }
794 free(nvh);
795 /* Add the actual data. */
796 if (ebuf_add_tail(nv->nv_ebuf, value, vsize) < 0) {
797 PJDLOG_ASSERT(errno != 0);
798 if (nv->nv_error == 0)
799 nv->nv_error = errno;
800 return;
801 }
802 /* Align the data (if needed). */
803 vsize = roundup2(vsize, 8) - vsize;
804 if (vsize == 0)
805 return;
806 PJDLOG_ASSERT(vsize > 0 && vsize <= sizeof(align));
807 if (ebuf_add_tail(nv->nv_ebuf, align, vsize) < 0) {
808 PJDLOG_ASSERT(errno != 0);
809 if (nv->nv_error == 0)
810 nv->nv_error = errno;
811 return;
812 }
813}
814
815static void
816nv_addv(struct nv *nv, const unsigned char *value, size_t vsize, int type,
817 const char *namefmt, va_list nameap)
818{
819 char name[255];
820 size_t namesize;
821
822 namesize = vsnprintf(name, sizeof(name), namefmt, nameap);
823 PJDLOG_ASSERT(namesize > 0 && namesize < sizeof(name));
824
825 nv_add(nv, value, vsize, type, name);
826}
827
828static struct nvhdr *
829nv_find(struct nv *nv, int type, const char *namefmt, va_list nameap)
830{
831 char name[255];

--- 4 unchanged lines hidden (view full) ---

836 if (nv == NULL) {
837 errno = ENOMEM;
838 return (NULL);
839 }
840
841 NV_CHECK(nv);
842
843 namesize = vsnprintf(name, sizeof(name), namefmt, nameap);
844 PJDLOG_ASSERT(namesize > 0 && namesize < sizeof(name));
845 namesize++;
846
847 ptr = ebuf_data(nv->nv_ebuf, &size);
848 while (size > 0) {
849 PJDLOG_ASSERT(size >= sizeof(*nvh) + 2);
850 nvh = (struct nvhdr *)ptr;
851 PJDLOG_ASSERT(size >= NVH_SIZE(nvh));
852 nv_swap(nvh, true);
853 if (strcmp(nvh->nvh_name, name) == 0) {
854 if (type != NV_TYPE_NONE &&
855 (nvh->nvh_type & NV_TYPE_MASK) != type) {
856 errno = EINVAL;
857 if (nv->nv_error == 0)
858 nv->nv_error = EINVAL;
859 return (NULL);

--- 71 unchanged lines hidden (view full) ---

931 *(uint32_t *)(void *)p =
932 le32toh(*(uint32_t *)(void *)p);
933 break;
934 case 8:
935 *(uint64_t *)(void *)p =
936 le64toh(*(uint64_t *)(void *)p);
937 break;
938 default:
939 PJDLOG_ABORT("invalid condition");
940 }
941 } else {
942 switch (vsize) {
943 case 2:
944 *(uint16_t *)(void *)p =
945 htole16(*(uint16_t *)(void *)p);
946 break;
947 case 4:
948 *(uint32_t *)(void *)p =
949 htole32(*(uint32_t *)(void *)p);
950 break;
951 case 8:
952 *(uint64_t *)(void *)p =
953 htole64(*(uint64_t *)(void *)p);
954 break;
955 default:
956 PJDLOG_ABORT("invalid condition");
957 }
958 }
959 }
960 break;
961 case NV_TYPE_STRING:
962 break;
963 default:
964 PJDLOG_ABORT("unrecognized type");
965 }
966}