1*6aace0ceSkettenis /* $OpenBSD: mdstore.c,v 1.2 2012/11/04 21:44:20 kettenis Exp $ */ 2cceaa36bSkettenis 3cceaa36bSkettenis /* 4cceaa36bSkettenis * Copyright (c) 2012 Mark Kettenis 5cceaa36bSkettenis * 6cceaa36bSkettenis * Permission to use, copy, modify, and distribute this software for any 7cceaa36bSkettenis * purpose with or without fee is hereby granted, provided that the above 8cceaa36bSkettenis * copyright notice and this permission notice appear in all copies. 9cceaa36bSkettenis * 10cceaa36bSkettenis * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11cceaa36bSkettenis * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12cceaa36bSkettenis * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13cceaa36bSkettenis * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14cceaa36bSkettenis * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15cceaa36bSkettenis * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16cceaa36bSkettenis * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17cceaa36bSkettenis */ 18cceaa36bSkettenis 19*6aace0ceSkettenis #include <assert.h> 20cceaa36bSkettenis #include <stdio.h> 21*6aace0ceSkettenis #include <stdlib.h> 22cceaa36bSkettenis #include <string.h> 23cceaa36bSkettenis 24cceaa36bSkettenis #include "ds.h" 25cceaa36bSkettenis #include "mdstore.h" 26cceaa36bSkettenis #include "util.h" 27cceaa36bSkettenis 28cceaa36bSkettenis void mdstore_start(struct ldc_conn *, uint64_t); 29cceaa36bSkettenis void mdstore_rx_data(struct ldc_conn *, uint64_t, void *, size_t); 30cceaa36bSkettenis 31cceaa36bSkettenis struct ds_service mdstore_service = { 32cceaa36bSkettenis "mdstore", 1, 0, mdstore_start, mdstore_rx_data 33cceaa36bSkettenis }; 34cceaa36bSkettenis 35cceaa36bSkettenis #define MDSET_LIST_REQUEST 0x0004 36*6aace0ceSkettenis #define MDSET_SELECT_REQUEST 0x0005 37*6aace0ceSkettenis #define MDSET_DELETE_REQUEST 0x0006 38*6aace0ceSkettenis #define MDSET_RETREIVE_REQUEST 0x0007 39cceaa36bSkettenis 40cceaa36bSkettenis struct mdstore_msg { 41cceaa36bSkettenis uint32_t msg_type; 42cceaa36bSkettenis uint32_t payload_len; 43cceaa36bSkettenis uint64_t svc_handle; 44cceaa36bSkettenis uint64_t reqnum; 45cceaa36bSkettenis uint16_t command; 46cceaa36bSkettenis } __packed; 47cceaa36bSkettenis 48*6aace0ceSkettenis struct mdstore_sel_del_req { 49*6aace0ceSkettenis uint32_t msg_type; 50*6aace0ceSkettenis uint32_t payload_len; 51*6aace0ceSkettenis uint64_t svc_handle; 52*6aace0ceSkettenis uint64_t reqnum; 53*6aace0ceSkettenis uint16_t command; 54*6aace0ceSkettenis uint16_t reserved; 55*6aace0ceSkettenis uint32_t namelen; 56*6aace0ceSkettenis char name[1]; 57*6aace0ceSkettenis } __packed; 58*6aace0ceSkettenis 59cceaa36bSkettenis #define MDSET_LIST_REPLY 0x0104 60cceaa36bSkettenis 61cceaa36bSkettenis struct mdstore_list_resp { 62cceaa36bSkettenis uint32_t msg_type; 63cceaa36bSkettenis uint32_t payload_len; 64cceaa36bSkettenis uint64_t svc_handle; 65cceaa36bSkettenis uint64_t reqnum; 66cceaa36bSkettenis uint32_t result; 67cceaa36bSkettenis uint16_t booted_set; 68cceaa36bSkettenis uint16_t boot_set; 69cceaa36bSkettenis char sets[1]; 70cceaa36bSkettenis } __packed; 71cceaa36bSkettenis 72cceaa36bSkettenis #define MDST_SUCCESS 0x0 73cceaa36bSkettenis #define MDST_FAILURE 0x1 74cceaa36bSkettenis #define MDST_INVALID_MSG 0x2 75cceaa36bSkettenis #define MDST_MAX_MDS_ERR 0x3 76cceaa36bSkettenis #define MDST_BAD_NAME_ERR 0x4 77cceaa36bSkettenis #define MDST_SET_EXISTS_ERR 0x5 78cceaa36bSkettenis #define MDST_ALLOC_SET_ERR 0x6 79cceaa36bSkettenis #define MDST_ALLOC_MD_ERR 0x7 80cceaa36bSkettenis #define MDST_MD_COUNT_ERR 0x8 81cceaa36bSkettenis #define MDST_MD_SIZE_ERR 0x9 82cceaa36bSkettenis #define MDST_MD_TYPE_ERR 0xa 83cceaa36bSkettenis #define MDST_NOT_EXIST_ERR 0xb 84cceaa36bSkettenis 85cceaa36bSkettenis struct mdstore_set_head mdstore_sets = TAILQ_HEAD_INITIALIZER(mdstore_sets); 86*6aace0ceSkettenis uint64_t mdstore_reqnum; 87*6aace0ceSkettenis uint64_t mdstore_command; 88cceaa36bSkettenis 89cceaa36bSkettenis void 90cceaa36bSkettenis mdstore_start(struct ldc_conn *lc, uint64_t svc_handle) 91cceaa36bSkettenis { 92cceaa36bSkettenis struct mdstore_msg mm; 93cceaa36bSkettenis 94cceaa36bSkettenis bzero(&mm, sizeof(mm)); 95cceaa36bSkettenis mm.msg_type = DS_DATA; 96cceaa36bSkettenis mm.payload_len = sizeof(mm) - 8; 97cceaa36bSkettenis mm.svc_handle = svc_handle; 98*6aace0ceSkettenis mm.reqnum = mdstore_reqnum++; 99*6aace0ceSkettenis mm.command = mdstore_command = MDSET_LIST_REQUEST; 100cceaa36bSkettenis ds_send_msg(lc, &mm, sizeof(mm)); 101cceaa36bSkettenis } 102cceaa36bSkettenis 103cceaa36bSkettenis void 104cceaa36bSkettenis mdstore_rx_data(struct ldc_conn *lc, uint64_t svc_handle, void *data, 105cceaa36bSkettenis size_t len) 106cceaa36bSkettenis { 107cceaa36bSkettenis struct mdstore_list_resp *mr = data; 108cceaa36bSkettenis struct mdstore_set *set; 109cceaa36bSkettenis int idx; 110cceaa36bSkettenis 111cceaa36bSkettenis if (mr->result != MDST_SUCCESS) { 112cceaa36bSkettenis DPRINTF(("Unexpected result 0x%x\n", mr->result)); 113cceaa36bSkettenis return; 114cceaa36bSkettenis } 115cceaa36bSkettenis 116*6aace0ceSkettenis switch (mdstore_command) { 117*6aace0ceSkettenis case MDSET_LIST_REQUEST: 118*6aace0ceSkettenis for (idx = 0, len = 0; len < mr->payload_len - 24; idx++) { 119cceaa36bSkettenis set = xmalloc(sizeof(*set)); 120cceaa36bSkettenis set->name = xstrdup(&mr->sets[len]); 121cceaa36bSkettenis set->booted_set = (idx == mr->booted_set); 122cceaa36bSkettenis set->boot_set = (idx == mr->boot_set); 123cceaa36bSkettenis TAILQ_INSERT_TAIL(&mdstore_sets, set, link); 124cceaa36bSkettenis len += strlen(&mr->sets[len]) + 1; 125cceaa36bSkettenis } 126*6aace0ceSkettenis break; 127*6aace0ceSkettenis case MDSET_SELECT_REQUEST: 128*6aace0ceSkettenis mdstore_command = 0; 129*6aace0ceSkettenis break; 130*6aace0ceSkettenis } 131*6aace0ceSkettenis } 132*6aace0ceSkettenis 133*6aace0ceSkettenis void 134*6aace0ceSkettenis mdstore_select(struct ds_conn *dc, const char *name) 135*6aace0ceSkettenis { 136*6aace0ceSkettenis struct ds_conn_svc *dcs; 137*6aace0ceSkettenis struct mdstore_sel_del_req *mr; 138*6aace0ceSkettenis struct mdstore_set *set; 139*6aace0ceSkettenis size_t len; 140*6aace0ceSkettenis 141*6aace0ceSkettenis TAILQ_FOREACH(dcs, &dc->services, link) 142*6aace0ceSkettenis if (strcmp(dcs->service->ds_svc_id, "mdstore") == 0) 143*6aace0ceSkettenis break; 144*6aace0ceSkettenis assert(dcs != TAILQ_END(&dc->services)); 145*6aace0ceSkettenis 146*6aace0ceSkettenis len = sizeof(*set) + strlen(name); 147*6aace0ceSkettenis mr = xzalloc(len); 148*6aace0ceSkettenis 149*6aace0ceSkettenis mr->msg_type = DS_DATA; 150*6aace0ceSkettenis mr->payload_len = len - 8; 151*6aace0ceSkettenis mr->svc_handle = dcs->svc_handle; 152*6aace0ceSkettenis mr->reqnum = mdstore_reqnum++; 153*6aace0ceSkettenis mr->command = mdstore_command = MDSET_SELECT_REQUEST; 154*6aace0ceSkettenis mr->namelen = strlen(name); 155*6aace0ceSkettenis memcpy(mr->name, name, strlen(name)); 156*6aace0ceSkettenis 157*6aace0ceSkettenis ds_send_msg(&dc->lc, mr, len); 158*6aace0ceSkettenis free(mr); 159*6aace0ceSkettenis 160*6aace0ceSkettenis while (mdstore_command == MDSET_SELECT_REQUEST) 161*6aace0ceSkettenis ds_conn_handle(dc); 162cceaa36bSkettenis } 163