summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ldomctl/ldomctl.c20
-rw-r--r--usr.sbin/ldomctl/mdstore.c77
-rw-r--r--usr.sbin/ldomctl/mdstore.h4
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 *);