151 lines
3.7 KiB
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;
|
||
|
}
|
||
|
}
|