xref: /openbsd/usr.sbin/ldomctl/mdstore.c (revision 6aace0ce)
1*6aace0ceSkettenis /*	$OpenBSD: mdstore.c,v 1.2 2012/11/04 21:44:20 kettenis Exp $	*/
2cceaa36bSkettenis 
3cceaa36bSkettenis /*
4cceaa36bSkettenis  * Copyright (c) 2012 Mark Kettenis
5cceaa36bSkettenis  *
6cceaa36bSkettenis  * Permission to use, copy, modify, and distribute this software for any
7cceaa36bSkettenis  * purpose with or without fee is hereby granted, provided that the above
8cceaa36bSkettenis  * copyright notice and this permission notice appear in all copies.
9cceaa36bSkettenis  *
10cceaa36bSkettenis  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11cceaa36bSkettenis  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12cceaa36bSkettenis  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13cceaa36bSkettenis  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14cceaa36bSkettenis  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15cceaa36bSkettenis  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16cceaa36bSkettenis  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17cceaa36bSkettenis  */
18cceaa36bSkettenis 
19*6aace0ceSkettenis #include <assert.h>
20cceaa36bSkettenis #include <stdio.h>
21*6aace0ceSkettenis #include <stdlib.h>
22cceaa36bSkettenis #include <string.h>
23cceaa36bSkettenis 
24cceaa36bSkettenis #include "ds.h"
25cceaa36bSkettenis #include "mdstore.h"
26cceaa36bSkettenis #include "util.h"
27cceaa36bSkettenis 
28cceaa36bSkettenis void	mdstore_start(struct ldc_conn *, uint64_t);
29cceaa36bSkettenis void	mdstore_rx_data(struct ldc_conn *, uint64_t, void *, size_t);
30cceaa36bSkettenis 
31cceaa36bSkettenis struct ds_service mdstore_service = {
32cceaa36bSkettenis 	"mdstore", 1, 0, mdstore_start, mdstore_rx_data
33cceaa36bSkettenis };
34cceaa36bSkettenis 
35cceaa36bSkettenis #define MDSET_LIST_REQUEST	0x0004
36*6aace0ceSkettenis #define MDSET_SELECT_REQUEST	0x0005
37*6aace0ceSkettenis #define MDSET_DELETE_REQUEST	0x0006
38*6aace0ceSkettenis #define MDSET_RETREIVE_REQUEST	0x0007
39cceaa36bSkettenis 
40cceaa36bSkettenis struct mdstore_msg {
41cceaa36bSkettenis 	uint32_t	msg_type;
42cceaa36bSkettenis 	uint32_t	payload_len;
43cceaa36bSkettenis 	uint64_t	svc_handle;
44cceaa36bSkettenis 	uint64_t	reqnum;
45cceaa36bSkettenis 	uint16_t	command;
46cceaa36bSkettenis } __packed;
47cceaa36bSkettenis 
48*6aace0ceSkettenis struct mdstore_sel_del_req {
49*6aace0ceSkettenis 	uint32_t	msg_type;
50*6aace0ceSkettenis 	uint32_t	payload_len;
51*6aace0ceSkettenis 	uint64_t	svc_handle;
52*6aace0ceSkettenis 	uint64_t	reqnum;
53*6aace0ceSkettenis 	uint16_t	command;
54*6aace0ceSkettenis 	uint16_t	reserved;
55*6aace0ceSkettenis 	uint32_t	namelen;
56*6aace0ceSkettenis 	char		name[1];
57*6aace0ceSkettenis } __packed;
58*6aace0ceSkettenis 
59cceaa36bSkettenis #define MDSET_LIST_REPLY	0x0104
60cceaa36bSkettenis 
61cceaa36bSkettenis struct mdstore_list_resp {
62cceaa36bSkettenis 	uint32_t	msg_type;
63cceaa36bSkettenis 	uint32_t	payload_len;
64cceaa36bSkettenis 	uint64_t	svc_handle;
65cceaa36bSkettenis 	uint64_t	reqnum;
66cceaa36bSkettenis 	uint32_t	result;
67cceaa36bSkettenis 	uint16_t	booted_set;
68cceaa36bSkettenis 	uint16_t	boot_set;
69cceaa36bSkettenis 	char		sets[1];
70cceaa36bSkettenis } __packed;
71cceaa36bSkettenis 
72cceaa36bSkettenis #define MDST_SUCCESS		0x0
73cceaa36bSkettenis #define MDST_FAILURE		0x1
74cceaa36bSkettenis #define MDST_INVALID_MSG	0x2
75cceaa36bSkettenis #define MDST_MAX_MDS_ERR	0x3
76cceaa36bSkettenis #define MDST_BAD_NAME_ERR	0x4
77cceaa36bSkettenis #define MDST_SET_EXISTS_ERR	0x5
78cceaa36bSkettenis #define MDST_ALLOC_SET_ERR	0x6
79cceaa36bSkettenis #define MDST_ALLOC_MD_ERR	0x7
80cceaa36bSkettenis #define MDST_MD_COUNT_ERR	0x8
81cceaa36bSkettenis #define MDST_MD_SIZE_ERR	0x9
82cceaa36bSkettenis #define MDST_MD_TYPE_ERR	0xa
83cceaa36bSkettenis #define MDST_NOT_EXIST_ERR	0xb
84cceaa36bSkettenis 
85cceaa36bSkettenis struct mdstore_set_head mdstore_sets = TAILQ_HEAD_INITIALIZER(mdstore_sets);
86*6aace0ceSkettenis uint64_t mdstore_reqnum;
87*6aace0ceSkettenis uint64_t mdstore_command;
88cceaa36bSkettenis 
89cceaa36bSkettenis void
90cceaa36bSkettenis mdstore_start(struct ldc_conn *lc, uint64_t svc_handle)
91cceaa36bSkettenis {
92cceaa36bSkettenis 	struct mdstore_msg mm;
93cceaa36bSkettenis 
94cceaa36bSkettenis 	bzero(&mm, sizeof(mm));
95cceaa36bSkettenis 	mm.msg_type = DS_DATA;
96cceaa36bSkettenis 	mm.payload_len = sizeof(mm) - 8;
97cceaa36bSkettenis 	mm.svc_handle = svc_handle;
98*6aace0ceSkettenis 	mm.reqnum = mdstore_reqnum++;
99*6aace0ceSkettenis 	mm.command = mdstore_command = MDSET_LIST_REQUEST;
100cceaa36bSkettenis 	ds_send_msg(lc, &mm, sizeof(mm));
101cceaa36bSkettenis }
102cceaa36bSkettenis 
103cceaa36bSkettenis void
104cceaa36bSkettenis mdstore_rx_data(struct ldc_conn *lc, uint64_t svc_handle, void *data,
105cceaa36bSkettenis     size_t len)
106cceaa36bSkettenis {
107cceaa36bSkettenis 	struct mdstore_list_resp *mr = data;
108cceaa36bSkettenis 	struct mdstore_set *set;
109cceaa36bSkettenis 	int idx;
110cceaa36bSkettenis 
111cceaa36bSkettenis 	if (mr->result != MDST_SUCCESS) {
112cceaa36bSkettenis 		DPRINTF(("Unexpected result 0x%x\n", mr->result));
113cceaa36bSkettenis 		return;
114cceaa36bSkettenis 	}
115cceaa36bSkettenis 
116*6aace0ceSkettenis 	switch (mdstore_command) {
117*6aace0ceSkettenis 	case MDSET_LIST_REQUEST:
118*6aace0ceSkettenis 		for (idx = 0, len = 0; len < mr->payload_len - 24; idx++) {
119cceaa36bSkettenis 			set = xmalloc(sizeof(*set));
120cceaa36bSkettenis 			set->name = xstrdup(&mr->sets[len]);
121cceaa36bSkettenis 			set->booted_set = (idx == mr->booted_set);
122cceaa36bSkettenis 			set->boot_set = (idx == mr->boot_set);
123cceaa36bSkettenis 			TAILQ_INSERT_TAIL(&mdstore_sets, set, link);
124cceaa36bSkettenis 			len += strlen(&mr->sets[len]) + 1;
125cceaa36bSkettenis 		}
126*6aace0ceSkettenis 		break;
127*6aace0ceSkettenis 	case MDSET_SELECT_REQUEST:
128*6aace0ceSkettenis 		mdstore_command = 0;
129*6aace0ceSkettenis 		break;
130*6aace0ceSkettenis 	}
131*6aace0ceSkettenis }
132*6aace0ceSkettenis 
133*6aace0ceSkettenis void
134*6aace0ceSkettenis mdstore_select(struct ds_conn *dc, const char *name)
135*6aace0ceSkettenis {
136*6aace0ceSkettenis 	struct ds_conn_svc *dcs;
137*6aace0ceSkettenis 	struct mdstore_sel_del_req *mr;
138*6aace0ceSkettenis 	struct mdstore_set *set;
139*6aace0ceSkettenis 	size_t len;
140*6aace0ceSkettenis 
141*6aace0ceSkettenis 	TAILQ_FOREACH(dcs, &dc->services, link)
142*6aace0ceSkettenis 		if (strcmp(dcs->service->ds_svc_id, "mdstore") == 0)
143*6aace0ceSkettenis 			break;
144*6aace0ceSkettenis 	assert(dcs != TAILQ_END(&dc->services));
145*6aace0ceSkettenis 
146*6aace0ceSkettenis 	len = sizeof(*set) + strlen(name);
147*6aace0ceSkettenis 	mr = xzalloc(len);
148*6aace0ceSkettenis 
149*6aace0ceSkettenis 	mr->msg_type = DS_DATA;
150*6aace0ceSkettenis 	mr->payload_len = len - 8;
151*6aace0ceSkettenis 	mr->svc_handle = dcs->svc_handle;
152*6aace0ceSkettenis 	mr->reqnum = mdstore_reqnum++;
153*6aace0ceSkettenis 	mr->command = mdstore_command = MDSET_SELECT_REQUEST;
154*6aace0ceSkettenis 	mr->namelen = strlen(name);
155*6aace0ceSkettenis 	memcpy(mr->name, name, strlen(name));
156*6aace0ceSkettenis 
157*6aace0ceSkettenis 	ds_send_msg(&dc->lc, mr, len);
158*6aace0ceSkettenis 	free(mr);
159*6aace0ceSkettenis 
160*6aace0ceSkettenis 	while (mdstore_command == MDSET_SELECT_REQUEST)
161*6aace0ceSkettenis 		ds_conn_handle(dc);
162cceaa36bSkettenis }
163