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