return received;
}
+/*
+ * nbd_list_meta_contexts:
+ * Request the server to list all meta contexts for export @info->name.
+ * return 0 if list is complete (even if empty),
+ * -1 with errp set for any error
+ */
+static int nbd_list_meta_contexts(QIOChannel *ioc,
+ NBDExportInfo *info,
+ Error **errp)
+{
+ int ret;
+
+ if (nbd_send_meta_query(ioc, NBD_OPT_LIST_META_CONTEXT,
+ info->name, NULL, errp) < 0) {
+ return -1;
+ }
+
+ while (1) {
+ char *context;
+
+ ret = nbd_receive_one_meta_context(ioc, NBD_OPT_LIST_META_CONTEXT,
+ &context, NULL, errp);
+ if (ret <= 0) {
+ return ret;
+ }
+ info->contexts = g_renew(char *, info->contexts, ++info->n_contexts);
+ info->contexts[info->n_contexts - 1] = context;
+ }
+}
+
/*
* nbd_start_negotiate:
* Start the handshake to the server. After a positive return, the server
/* Clean up result of nbd_receive_export_list */
void nbd_free_export_list(NBDExportInfo *info, int count)
{
- int i;
+ int i, j;
if (!info) {
return;
for (i = 0; i < count; i++) {
g_free(info[i].name);
g_free(info[i].description);
+ for (j = 0; j < info[i].n_contexts; j++) {
+ g_free(info[i].contexts[j]);
+ }
+ g_free(info[i].contexts);
}
g_free(info);
}
break;
}
- /* TODO: Grab meta contexts */
+ if (result == 3 &&
+ nbd_list_meta_contexts(ioc, &array[i], errp) < 0) {
+ goto out;
+ }
}
/* Send NBD_OPT_ABORT as a courtesy before hanging up */