src/usr.sbin/ldomd/var-config.c

151 lines
3.7 KiB
C

/* $OpenBSD: var-config.c,v 1.3 2019/11/28 18:40:42 kn Exp $ */
/*
* Copyright (c) 2012 Mark Kettenis
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/poll.h>
#include <sys/queue.h>
#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "ds.h"
#include "mdesc.h"
#include "ldom_util.h"
#include "ldomd.h"
void var_config_start(struct ldc_conn *, uint64_t);
void var_config_rx_data(struct ldc_conn *, uint64_t, void *, size_t);
struct ds_service var_config_service = {
"var-config", 1, 0, var_config_start, var_config_rx_data
};
#define VAR_CONFIG_SET_REQ 0x00
#define VAR_CONFIG_DELETE_REQ 0x01
struct var_config_set_req {
uint32_t msg_type;
uint32_t payload_len;
uint64_t svc_handle;
uint32_t cmd;
char name[1];
} __packed;
#define VAR_CONFIG_SET_RESP 0x02
#define VAR_CONFIG_DELETE_RESP 0x03
struct var_config_resp {
uint32_t msg_type;
uint32_t payload_len;
uint64_t svc_handle;
uint32_t cmd;
uint32_t result;
} __packed;
#define VAR_CONFIG_SUCCESS 0x00
#define VAR_CONFIG_NO_SPACE 0x01
#define VAR_CONFIG_INVALID_VAR 0x02
#define VAR_CONFIG_INVALID_VAL 0x03
#define VAR_CONFIG_VAR_NOT_PRESENT 0x04
uint32_t
set_variable(struct guest *guest, const char *name, const char *value)
{
struct md *md = guest->md;
struct md_node *node;
struct md_prop *prop;
node = md_find_node(md, "variables");
if (node == NULL) {
struct md_node *root = md_find_node(md, "root");
assert(root);
node = md_add_node(md, "variables");
md_link_node(md, root, node);
}
prop = md_add_prop_str(md, node, name, value);
if (prop == NULL)
return VAR_CONFIG_NO_SPACE;
hv_update_md(guest);
return VAR_CONFIG_SUCCESS;
}
uint32_t
delete_variable(struct guest *guest, const char *name)
{
struct md *md = guest->md;
struct md_node *node;
struct md_prop *prop;
node = md_find_node(md, "variables");
if (node == NULL)
return VAR_CONFIG_VAR_NOT_PRESENT;
prop = md_find_prop(md, node, name);
if (prop == NULL)
return VAR_CONFIG_VAR_NOT_PRESENT;
md_delete_prop(md, node, prop);
hv_update_md(guest);
return VAR_CONFIG_SUCCESS;
}
void
var_config_start(struct ldc_conn *lc, uint64_t svc_handle)
{
}
void
var_config_rx_data(struct ldc_conn *lc, uint64_t svc_handle, void *data,
size_t len)
{
struct ds_conn *dc = lc->lc_cookie;
struct var_config_set_req *vr = data;
struct var_config_resp vx;
switch (vr->cmd) {
case VAR_CONFIG_SET_REQ:
vx.msg_type = DS_DATA;
vx.payload_len = sizeof(vx) - 8;
vx.svc_handle = svc_handle;
vx.cmd = VAR_CONFIG_SET_RESP;
vx.result = set_variable(dc->cookie, vr->name,
vr->name + strlen(vr->name) + 1);
ds_send_msg(lc, &vx, sizeof(vx));
break;
case VAR_CONFIG_DELETE_REQ:
vx.msg_type = DS_DATA;
vx.payload_len = sizeof(vx) - 8;
vx.svc_handle = svc_handle;
vx.result = delete_variable(dc->cookie, vr->name);
vx.cmd = VAR_CONFIG_DELETE_RESP;
ds_send_msg(lc, &vx, sizeof(vx));
break;
default:
printf("Unknown request 0x%02x\n", vr->cmd);
break;
}
}