diff options
-rw-r--r-- | usr.sbin/ldomctl/ldomctl.c | 20 | ||||
-rw-r--r-- | usr.sbin/ldomctl/mdstore.c | 77 | ||||
-rw-r--r-- | usr.sbin/ldomctl/mdstore.h | 4 |
3 files changed, 88 insertions, 13 deletions
diff --git a/usr.sbin/ldomctl/ldomctl.c b/usr.sbin/ldomctl/ldomctl.c index 73ab89a32b9..a4c7b23f1c8 100644 --- a/usr.sbin/ldomctl/ldomctl.c +++ b/usr.sbin/ldomctl/ldomctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ldomctl.c,v 1.12 2012/11/04 20:09:02 kettenis Exp $ */ +/* $OpenBSD: ldomctl.c,v 1.13 2012/11/04 21:44:20 kettenis Exp $ */ /* * Copyright (c) 2012 Mark Kettenis @@ -59,6 +59,7 @@ void fetch_pri(void); void dump(int argc, char **argv); void list(int argc, char **argv); +void xselect(int argc, char **argv); void guest_start(int argc, char **argv); void guest_stop(int argc, char **argv); void guest_status(int argc, char **argv); @@ -66,6 +67,7 @@ void guest_status(int argc, char **argv); struct command commands[] = { { "dump", dump }, { "list", list }, + { "select", xselect }, { "start", guest_start }, { "stop", guest_stop }, { "status", guest_status }, @@ -284,6 +286,22 @@ list(int argc, char **argv) } void +xselect(int argc, char **argv) +{ + struct ds_conn *dc; + + if (argc < 2) + usage(); + + dc = ds_conn_open("/dev/spds", NULL); + ds_conn_register_service(dc, &mdstore_service); + while (TAILQ_EMPTY(&mdstore_sets)) + ds_conn_handle(dc); + + mdstore_select(dc, argv[1]); +} + +void guest_start(int argc, char **argv) { struct hvctl_msg msg; diff --git a/usr.sbin/ldomctl/mdstore.c b/usr.sbin/ldomctl/mdstore.c index fbc036e09a3..877665b7e40 100644 --- a/usr.sbin/ldomctl/mdstore.c +++ b/usr.sbin/ldomctl/mdstore.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdstore.c,v 1.1 2012/11/04 20:09:02 kettenis Exp $ */ +/* $OpenBSD: mdstore.c,v 1.2 2012/11/04 21:44:20 kettenis Exp $ */ /* * Copyright (c) 2012 Mark Kettenis @@ -16,7 +16,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <assert.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include "ds.h" @@ -31,6 +33,9 @@ struct ds_service mdstore_service = { }; #define MDSET_LIST_REQUEST 0x0004 +#define MDSET_SELECT_REQUEST 0x0005 +#define MDSET_DELETE_REQUEST 0x0006 +#define MDSET_RETREIVE_REQUEST 0x0007 struct mdstore_msg { uint32_t msg_type; @@ -40,6 +45,17 @@ struct mdstore_msg { uint16_t command; } __packed; +struct mdstore_sel_del_req { + uint32_t msg_type; + uint32_t payload_len; + uint64_t svc_handle; + uint64_t reqnum; + uint16_t command; + uint16_t reserved; + uint32_t namelen; + char name[1]; +} __packed; + #define MDSET_LIST_REPLY 0x0104 struct mdstore_list_resp { @@ -67,6 +83,8 @@ struct mdstore_list_resp { #define MDST_NOT_EXIST_ERR 0xb struct mdstore_set_head mdstore_sets = TAILQ_HEAD_INITIALIZER(mdstore_sets); +uint64_t mdstore_reqnum; +uint64_t mdstore_command; void mdstore_start(struct ldc_conn *lc, uint64_t svc_handle) @@ -77,8 +95,8 @@ mdstore_start(struct ldc_conn *lc, uint64_t svc_handle) mm.msg_type = DS_DATA; mm.payload_len = sizeof(mm) - 8; mm.svc_handle = svc_handle; - mm.reqnum = 0; - mm.command = MDSET_LIST_REQUEST; + mm.reqnum = mdstore_reqnum++; + mm.command = mdstore_command = MDSET_LIST_REQUEST; ds_send_msg(lc, &mm, sizeof(mm)); } @@ -95,13 +113,50 @@ mdstore_rx_data(struct ldc_conn *lc, uint64_t svc_handle, void *data, return; } - len = 0; - for (idx = 0; len < mr->payload_len - 24; idx++) { - set = xmalloc(sizeof(*set)); - set->name = xstrdup(&mr->sets[len]); - set->booted_set = (idx == mr->booted_set); - set->boot_set = (idx == mr->boot_set); - TAILQ_INSERT_TAIL(&mdstore_sets, set, link); - len += strlen(&mr->sets[len]) + 1; + switch (mdstore_command) { + case MDSET_LIST_REQUEST: + for (idx = 0, len = 0; len < mr->payload_len - 24; idx++) { + set = xmalloc(sizeof(*set)); + set->name = xstrdup(&mr->sets[len]); + set->booted_set = (idx == mr->booted_set); + set->boot_set = (idx == mr->boot_set); + TAILQ_INSERT_TAIL(&mdstore_sets, set, link); + len += strlen(&mr->sets[len]) + 1; + } + break; + case MDSET_SELECT_REQUEST: + mdstore_command = 0; + break; } } + +void +mdstore_select(struct ds_conn *dc, const char *name) +{ + struct ds_conn_svc *dcs; + struct mdstore_sel_del_req *mr; + struct mdstore_set *set; + size_t len; + + TAILQ_FOREACH(dcs, &dc->services, link) + if (strcmp(dcs->service->ds_svc_id, "mdstore") == 0) + break; + assert(dcs != TAILQ_END(&dc->services)); + + len = sizeof(*set) + strlen(name); + mr = xzalloc(len); + + mr->msg_type = DS_DATA; + mr->payload_len = len - 8; + mr->svc_handle = dcs->svc_handle; + mr->reqnum = mdstore_reqnum++; + mr->command = mdstore_command = MDSET_SELECT_REQUEST; + mr->namelen = strlen(name); + memcpy(mr->name, name, strlen(name)); + + ds_send_msg(&dc->lc, mr, len); + free(mr); + + while (mdstore_command == MDSET_SELECT_REQUEST) + ds_conn_handle(dc); +} diff --git a/usr.sbin/ldomctl/mdstore.h b/usr.sbin/ldomctl/mdstore.h index 665ef8f95f1..8edccd62624 100644 --- a/usr.sbin/ldomctl/mdstore.h +++ b/usr.sbin/ldomctl/mdstore.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mdstore.h,v 1.1 2012/11/04 20:09:02 kettenis Exp $ */ +/* $OpenBSD: mdstore.h,v 1.2 2012/11/04 21:44:20 kettenis Exp $ */ /* * Copyright (c) 2012 Mark Kettenis @@ -30,3 +30,5 @@ struct mdstore_set { }; extern TAILQ_HEAD(mdstore_set_head, mdstore_set) mdstore_sets; + +void mdstore_select(struct ds_conn *, const char *); |