xref: /openbsd-src/usr.sbin/ldomd/var-config.c (revision d73a4c4fb3962df1e72dd6910861075eabc6a1c3)
1 /*	$OpenBSD: var-config.c,v 1.3 2019/11/28 18:40:42 kn Exp $	*/
2 
3 /*
4  * Copyright (c) 2012 Mark Kettenis
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/poll.h>
21 #include <sys/queue.h>
22 #include <assert.h>
23 #include <err.h>
24 #include <fcntl.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 
30 #include "ds.h"
31 #include "mdesc.h"
32 #include "ldom_util.h"
33 #include "ldomd.h"
34 
35 void	var_config_start(struct ldc_conn *, uint64_t);
36 void	var_config_rx_data(struct ldc_conn *, uint64_t, void *, size_t);
37 
38 struct ds_service var_config_service = {
39 	"var-config", 1, 0, var_config_start, var_config_rx_data
40 };
41 
42 #define VAR_CONFIG_SET_REQ	0x00
43 #define VAR_CONFIG_DELETE_REQ	0x01
44 
45 struct var_config_set_req {
46 	uint32_t	msg_type;
47 	uint32_t	payload_len;
48 	uint64_t	svc_handle;
49 	uint32_t	cmd;
50 	char		name[1];
51 } __packed;
52 
53 #define VAR_CONFIG_SET_RESP	0x02
54 #define VAR_CONFIG_DELETE_RESP	0x03
55 
56 struct var_config_resp {
57 	uint32_t	msg_type;
58 	uint32_t	payload_len;
59 	uint64_t	svc_handle;
60 	uint32_t	cmd;
61 	uint32_t	result;
62 } __packed;
63 
64 #define VAR_CONFIG_SUCCESS		0x00
65 #define VAR_CONFIG_NO_SPACE		0x01
66 #define VAR_CONFIG_INVALID_VAR		0x02
67 #define VAR_CONFIG_INVALID_VAL		0x03
68 #define VAR_CONFIG_VAR_NOT_PRESENT	0x04
69 
70 uint32_t
set_variable(struct guest * guest,const char * name,const char * value)71 set_variable(struct guest *guest, const char *name, const char *value)
72 {
73 	struct md *md = guest->md;
74 	struct md_node *node;
75 	struct md_prop *prop;
76 
77 	node = md_find_node(md, "variables");
78 	if (node == NULL) {
79 		struct md_node *root = md_find_node(md, "root");
80 
81 		assert(root);
82 		node = md_add_node(md, "variables");
83 		md_link_node(md, root, node);
84 	}
85 
86 	prop = md_add_prop_str(md, node, name, value);
87 	if (prop == NULL)
88 		return VAR_CONFIG_NO_SPACE;
89 
90 	hv_update_md(guest);
91 	return VAR_CONFIG_SUCCESS;
92 }
93 
94 uint32_t
delete_variable(struct guest * guest,const char * name)95 delete_variable(struct guest *guest, const char *name)
96 {
97 	struct md *md = guest->md;
98 	struct md_node *node;
99 	struct md_prop *prop;
100 
101 	node = md_find_node(md, "variables");
102 	if (node == NULL)
103 		return VAR_CONFIG_VAR_NOT_PRESENT;
104 
105 	prop = md_find_prop(md, node, name);
106 	if (prop == NULL)
107 		return VAR_CONFIG_VAR_NOT_PRESENT;
108 
109 	md_delete_prop(md, node, prop);
110 
111 	hv_update_md(guest);
112 	return VAR_CONFIG_SUCCESS;
113 }
114 
115 void
var_config_start(struct ldc_conn * lc,uint64_t svc_handle)116 var_config_start(struct ldc_conn *lc, uint64_t svc_handle)
117 {
118 }
119 
120 void
var_config_rx_data(struct ldc_conn * lc,uint64_t svc_handle,void * data,size_t len)121 var_config_rx_data(struct ldc_conn *lc, uint64_t svc_handle, void *data,
122     size_t len)
123 {
124 	struct ds_conn *dc = lc->lc_cookie;
125 	struct var_config_set_req *vr = data;
126 	struct var_config_resp vx;
127 
128 	switch (vr->cmd) {
129 	case VAR_CONFIG_SET_REQ:
130 		vx.msg_type = DS_DATA;
131 		vx.payload_len = sizeof(vx) - 8;
132 		vx.svc_handle = svc_handle;
133 		vx.cmd = VAR_CONFIG_SET_RESP;
134 		vx.result = set_variable(dc->cookie, vr->name,
135 		    vr->name + strlen(vr->name) + 1);
136 		ds_send_msg(lc, &vx, sizeof(vx));
137 		break;
138 	case VAR_CONFIG_DELETE_REQ:
139 		vx.msg_type = DS_DATA;
140 		vx.payload_len = sizeof(vx) - 8;
141 		vx.svc_handle = svc_handle;
142 		vx.result = delete_variable(dc->cookie, vr->name);
143 		vx.cmd = VAR_CONFIG_DELETE_RESP;
144 		ds_send_msg(lc, &vx, sizeof(vx));
145 		break;
146 	default:
147 		printf("Unknown request 0x%02x\n", vr->cmd);
148 		break;
149 	}
150 }
151