/* * Contact the hypervisor metadata agent and request the value for the provided * key name. Returns a C string if a value is found, NULL if no value is * found, or aborts the program on any other condition. The caller is expected * to call free(3C) on the returned string. */ char * mdataGet(const char *keyname) { char *errmsg = NULL; string_t *mdata = NULL; mdata_response_t mdr; char *out; if (initialized_proto == 0) { if (proto_init(&mdp, &errmsg) != 0) { fatal(ERR_MDATA_INIT, "could not initialize metadata: %s\n", errmsg); } initialized_proto = 1; } if (proto_execute(mdp, "GET", keyname, &mdr, &mdata) != 0) { fatal(ERR_UNEXPECTED, "failed to get metadata for '%s': unknown " "error\n", keyname); } switch (mdr) { case MDR_SUCCESS: if ((out = strdup(dynstr_cstr(mdata))) == NULL) { fatal(ERR_STRDUP, "strdup failure\n"); } dynstr_free(mdata); dlog("MDATA %s=%s\n", keyname, out); return (out); case MDR_NOTFOUND: dlog("INFO no metadata for '%s'\n", keyname); dynstr_free(mdata); return (NULL); case MDR_UNKNOWN: fatal(ERR_MDATA_FAIL, "failed to get metadata for '%s': %s\n", keyname, dynstr_cstr(mdata)); break; case MDR_INVALID_COMMAND: fatal(ERR_MDATA_FAIL, "failed to get metadata for '%s': %s\n", keyname, "host does not support GET"); break; default: fatal(ERR_UNEXPECTED, "GET[%s]: unknown response\n", keyname); break; } /* NOTREACHED */ abort(); return (NULL); }
void mdataPut(const char *keyname, const char *value) { string_t *data; char *errmsg = NULL; mdata_response_t mdr; string_t *req = dynstr_new(); if (initialized_proto == 0) { if (proto_init(&mdp, &errmsg) != 0) { fatal(ERR_MDATA_INIT, "could not initialize metadata: %s\n", errmsg); } initialized_proto = 1; } base64_encode(keyname, strlen(keyname), req); dynstr_appendc(req, ' '); base64_encode(value, strlen(value), req); if (proto_version(mdp) < 2) { fatal(ERR_MDATA_TOO_OLD, "mdata protocol must be >= 2 for PUT"); } if (proto_execute(mdp, "PUT", dynstr_cstr(req), &mdr, &data) != 0) { fatal(ERR_MDATA_FAIL, "failed to PUT"); } dynstr_free(req); dlog("MDATA PUT %s=%s\n", keyname, value); }
void read_response(mdata_get_t *mdg) { int retries = 3; string_t *resp = dynstr_new(); for (;;) { char buf[2]; ssize_t sz = fread(&buf, 1, 1, mdg->mdg_fp); if (sz == 1) { if (buf[0] == '\n') { process_input(mdg, dynstr_cstr(resp)); dynstr_reset(resp); } else { buf[1] = '\0'; dynstr_append(resp, buf); } } else if ((sz == 0) || (sz == -1 && errno == EAGAIN)) { if (--retries == 0) errx(1, "timed out while reading metadata " "response"); sleep(1); } else { errx(1, "could not read metadata response"); } if (mdg->mdg_state == MDGS_DONE) break; } }
static int print_response(mdata_response_t mdr, string_t *data) { const char *cstr = dynstr_cstr(data); size_t len = dynstr_len(data); switch (mdr) { case MDR_SUCCESS: fprintf(stdout, "%s", cstr); if (len >= 1 && cstr[len - 1] != '\n') fprintf(stdout, "\n"); return (MDEC_SUCCESS); case MDR_NOTFOUND: fprintf(stderr, "No metadata\n"); return (MDEC_NOTFOUND); case MDR_UNKNOWN: fprintf(stderr, "Error getting metadata: %s\n", cstr); return (MDEC_ERROR); case MDR_INVALID_COMMAND: fprintf(stderr, "ERROR: host does not support KEYS\n"); return (MDEC_ERROR); default: ABORT("print_response: UNKNOWN RESPONSE\n"); return (MDEC_ERROR); } }
void print_response(mdata_get_t *mdg) { switch (mdg->mdg_response) { case MDGR_SUCCESS: fprintf(stdout, "%s\n", dynstr_cstr(mdg->mdg_data)); break; case MDGR_NOTFOUND: fprintf(stderr, "No metadata for '%s'\n", mdg->mdg_keyname); break; case MDGR_UNKNOWN: fprintf(stderr, "Error getting metadata for key '%s': %s\n", mdg->mdg_keyname, dynstr_cstr(mdg->mdg_data)); break; default: abort(); } }
int plat_send(mdata_plat_t *mpl, string_t *data) { int len = dynstr_len(data); if (write(mpl->mpl_conn, dynstr_cstr(data), len) != len) return (-1); return (0); }
static int print_response(mdata_response_t mdr, string_t *data) { switch (mdr) { case MDR_SUCCESS: return (MDEC_SUCCESS); case MDR_NOTFOUND: fprintf(stderr, "No metadata for '%s'\n", keyname); return (MDEC_NOTFOUND); case MDR_UNKNOWN: fprintf(stderr, "Error deleting metadata key '%s': %s\n", keyname, dynstr_cstr(data)); return (MDEC_ERROR); case MDR_INVALID_COMMAND: fprintf(stderr, "ERROR: host does not support DELETE\n"); return (MDEC_ERROR); default: ABORT("print_response: UNKNOWN RESPONSE\n"); return (MDEC_ERROR); } }
static int plat_send_reset(mdata_plat_t *mpl) { int ret = -1; string_t *str = dynstr_new(); dynstr_append(str, "\n"); if (plat_send(mpl, str) != 0) goto bail; dynstr_reset(str); if (plat_recv(mpl, str, 2000) != 0) goto bail; if (strcmp(dynstr_cstr(str), "invalid command") != 0) goto bail; ret = 0; bail: dynstr_free(str); return (ret); }