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