Add support for version 2.0 of the mdstore protocol.
authorkettenis <kettenis@openbsd.org>
Sat, 15 Sep 2018 13:20:16 +0000 (13:20 +0000)
committerkettenis <kettenis@openbsd.org>
Sat, 15 Sep 2018 13:20:16 +0000 (13:20 +0000)
usr.sbin/ldomctl/ldomctl.c
usr.sbin/ldomctl/mdstore.c
usr.sbin/ldomctl/mdstore.h

index 7e6dcb7..1193b86 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ldomctl.c,v 1.20 2014/10/09 02:44:55 deraadt Exp $    */
+/*     $OpenBSD: ldomctl.c,v 1.21 2018/09/15 13:20:16 kettenis Exp $   */
 
 /*
  * Copyright (c) 2012 Mark Kettenis
@@ -283,7 +283,7 @@ list(int argc, char **argv)
        struct mdstore_set *set;
 
        dc = ds_conn_open("/dev/spds", NULL);
-       ds_conn_register_service(dc, &mdstore_service);
+       mdstore_register(dc);
        while (TAILQ_EMPTY(&mdstore_sets))
                ds_conn_handle(dc);
 
@@ -306,7 +306,7 @@ xselect(int argc, char **argv)
                usage();
 
        dc = ds_conn_open("/dev/spds", NULL);
-       ds_conn_register_service(dc, &mdstore_service);
+       mdstore_register(dc);
        while (TAILQ_EMPTY(&mdstore_sets))
                ds_conn_handle(dc);
 
@@ -325,7 +325,7 @@ delete(int argc, char **argv)
                errx(1, "\"%s\" should not be deleted", argv[1]);
 
        dc = ds_conn_open("/dev/spds", NULL);
-       ds_conn_register_service(dc, &mdstore_service);
+       mdstore_register(dc);
        while (TAILQ_EMPTY(&mdstore_sets))
                ds_conn_handle(dc);
 
@@ -341,7 +341,7 @@ download(int argc, char **argv)
                usage();
 
        dc = ds_conn_open("/dev/spds", NULL);
-       ds_conn_register_service(dc, &mdstore_service);
+       mdstore_register(dc);
        while (TAILQ_EMPTY(&mdstore_sets))
                ds_conn_handle(dc);
 
index 80607d6..8a8ee47 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mdstore.c,v 1.7 2014/09/13 16:06:37 doug Exp $        */
+/*     $OpenBSD: mdstore.c,v 1.8 2018/09/15 13:20:16 kettenis Exp $    */
 
 /*
  * Copyright (c) 2012 Mark Kettenis
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 
 #include "ds.h"
 #include "mdesc.h"
 #include "ldomctl.h"
 
 void   mdstore_start(struct ldc_conn *, uint64_t);
+void   mdstore_start_v2(struct ldc_conn *, uint64_t);
 void   mdstore_rx_data(struct ldc_conn *, uint64_t, void *, size_t);
 
 struct ds_service mdstore_service = {
        "mdstore", 1, 0, mdstore_start, mdstore_rx_data
 };
 
+struct ds_service mdstore_service_v2 = {
+       "mdstore", 2, 0, mdstore_start_v2, mdstore_rx_data
+};
+
 #define MDSET_BEGIN_REQUEST    0x0001
 #define MDSET_END_REQUEST      0x0002
 #define MD_TRANSFER_REQUEST    0x0003
@@ -62,6 +68,19 @@ struct mdstore_begin_end_req {
        char            name[1];
 } __packed;
 
+struct mdstore_begin_req_v2 {
+       uint32_t        msg_type;
+       uint32_t        payload_len;
+       uint64_t        svc_handle;
+       uint64_t        reqnum;
+       uint16_t        command;
+       uint16_t        nmds;
+       uint32_t        config_size;
+       uint64_t        timestamp;
+       uint32_t        namelen;
+       char            name[1];
+} __packed;
+
 struct mdstore_transfer_req {
        uint32_t        msg_type;
        uint32_t        payload_len;
@@ -119,6 +138,14 @@ struct mdstore_list_resp {
 struct mdstore_set_head mdstore_sets = TAILQ_HEAD_INITIALIZER(mdstore_sets);
 uint64_t mdstore_reqnum;
 uint64_t mdstore_command;
+uint16_t mdstore_major;
+
+void
+mdstore_register(struct ds_conn *dc)
+{
+       ds_conn_register_service(dc, &mdstore_service);
+       ds_conn_register_service(dc, &mdstore_service_v2);
+}
 
 void
 mdstore_start(struct ldc_conn *lc, uint64_t svc_handle)
@@ -134,6 +161,13 @@ mdstore_start(struct ldc_conn *lc, uint64_t svc_handle)
        ds_send_msg(lc, &mm, sizeof(mm));
 }
 
+void
+mdstore_start_v2(struct ldc_conn *lc, uint64_t svc_handle)
+{
+       mdstore_major = 2;
+       mdstore_start(lc, svc_handle);
+}
+
 void
 mdstore_rx_data(struct ldc_conn *lc, uint64_t svc_handle, void *data,
     size_t len)
@@ -165,6 +199,8 @@ mdstore_rx_data(struct ldc_conn *lc, uint64_t svc_handle, void *data,
                        set->boot_set = (idx == mr->boot_set);
                        TAILQ_INSERT_TAIL(&mdstore_sets, set, link);
                        len += strlen(&mr->sets[len]) + 1;
+                       if (mdstore_major == 2)
+                               len += sizeof(uint64_t); /* skip timestamp */
                }
                break;
        }
@@ -173,7 +209,7 @@ mdstore_rx_data(struct ldc_conn *lc, uint64_t svc_handle, void *data,
 }
 
 void
-mdstore_begin(struct ds_conn *dc, uint64_t svc_handle, const char *name,
+mdstore_begin_v1(struct ds_conn *dc, uint64_t svc_handle, const char *name,
     int nmds)
 {
        struct mdstore_begin_end_req *mr;
@@ -196,6 +232,42 @@ mdstore_begin(struct ds_conn *dc, uint64_t svc_handle, const char *name,
                ds_conn_handle(dc);
 }
 
+void
+mdstore_begin_v2(struct ds_conn *dc, uint64_t svc_handle, const char *name,
+    int nmds, uint32_t config_size)
+{
+       struct mdstore_begin_req_v2 *mr;
+       size_t len = sizeof(*mr) + strlen(name);
+
+       mr = xzalloc(len);
+       mr->msg_type = DS_DATA;
+       mr->payload_len = len - 8;
+       mr->svc_handle = svc_handle;
+       mr->reqnum = mdstore_reqnum++;
+       mr->command = mdstore_command = MDSET_BEGIN_REQUEST;
+       mr->config_size = config_size;
+       mr->timestamp = time(NULL);
+       mr->nmds = nmds;
+       mr->namelen = strlen(name);
+       memcpy(mr->name, name, strlen(name));
+
+       ds_send_msg(&dc->lc, mr, len);
+       free(mr);
+
+       while (mdstore_command == MDSET_BEGIN_REQUEST)
+               ds_conn_handle(dc);
+}
+
+void
+mdstore_begin(struct ds_conn *dc, uint64_t svc_handle, const char *name,
+    int nmds, uint32_t config_size)
+{
+       if (mdstore_major == 2)
+         mdstore_begin_v2(dc, svc_handle, name, nmds, config_size);
+       else
+         mdstore_begin_v1(dc, svc_handle, name, nmds);
+}
+
 void
 mdstore_transfer(struct ds_conn *dc, uint64_t svc_handle, const char *path,
     uint16_t type, uint64_t offset)
@@ -330,6 +402,7 @@ mdstore_download(struct ds_conn *dc, const char *name)
        struct guest *guest;
        int nmds = 2;
        char *path;
+       uint32_t total_size = 0;
        uint16_t type;
 
        TAILQ_FOREACH(dcs, &dc->services, link)
@@ -358,7 +431,19 @@ mdstore_download(struct ds_conn *dc, const char *name)
        frag_init();
        hv_mdpa = alloc_frag();
 
-       mdstore_begin(dc, dcs->svc_handle, name, nmds);
+       TAILQ_FOREACH(guest, &guest_list, link) {
+               if (asprintf(&path, "%s/%s.md", name, guest->name) == -1)
+                       err(1, "asprintf");
+               total_size += md_size(path);
+       }
+       if (asprintf(&path, "%s/hv.md", name) == -1)
+               err(1, "asprintf");
+       total_size += md_size(path);
+       if (asprintf(&path, "%s/pri", name) == -1)
+               err(1, "asprintf");
+       total_size += md_size(path);
+
+       mdstore_begin(dc, dcs->svc_handle, name, nmds, total_size);
        TAILQ_FOREACH(guest, &guest_list, link) {
                if (asprintf(&path, "%s/%s.md", name, guest->name) == -1)
                        err(1, "asprintf");
index db8916d..ec4e702 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mdstore.h,v 1.3 2012/11/04 23:30:38 kettenis Exp $    */
+/*     $OpenBSD: mdstore.h,v 1.4 2018/09/15 13:20:16 kettenis Exp $    */
 
 /*
  * Copyright (c) 2012 Mark Kettenis
@@ -31,6 +31,8 @@ struct mdstore_set {
 
 extern TAILQ_HEAD(mdstore_set_head, mdstore_set) mdstore_sets;
 
+void mdstore_register(struct ds_conn *);
+
 void mdstore_download(struct ds_conn *, const char *);
 void mdstore_select(struct ds_conn *, const char *);
 void mdstore_delete(struct ds_conn *, const char *);