@@ -1824,9 +1824,14 @@ int libxl_device_nic_destroy(libxl_ctx *ctx, uint32_t domid,
const libxl_asyncop_how *ao_how)
LIBXL_EXTERNAL_CALLERS_ONLY;
-libxl_device_nic *libxl_device_nic_list(libxl_ctx *ctx, uint32_t domid, int *num);
+libxl_device_nic *libxl_device_nic_list(libxl_ctx *ctx,
+ uint32_t domid, int *num)
+ LIBXL_EXTERNAL_CALLERS_ONLY;
+void libxl_device_nic_list_free(libxl_device_nic* list, int num)
+ LIBXL_EXTERNAL_CALLERS_ONLY;
int libxl_device_nic_getinfo(libxl_ctx *ctx, uint32_t domid,
- libxl_device_nic *nic, libxl_nicinfo *nicinfo);
+ libxl_device_nic *nic, libxl_nicinfo *nicinfo)
+ LIBXL_EXTERNAL_CALLERS_ONLY;
/*
* Virtual Channels
@@ -63,7 +63,8 @@ void libxl__checkpoint_devices_setup(libxl__egc *egc,
cds->num_disks = 0;
if (cds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VIF))
- cds->nics = libxl_device_nic_list(CTX, cds->domid, &cds->num_nics);
+ cds->nics = libxl__device_list(gc, &libxl__nic_devtype, cds->domid,
+ "vif", &cds->num_nics);
if (cds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VBD))
cds->disks = libxl__device_list(gc, &libxl__disk_devtype, cds->domid,
@@ -206,8 +207,6 @@ static void devices_teardown_cb(libxl__egc *egc,
libxl__multidev *multidev,
int rc)
{
- int i;
-
STATE_AO_GC(multidev->ao);
/* Convenience aliases */
@@ -215,9 +214,7 @@ static void devices_teardown_cb(libxl__egc *egc,
CONTAINER_OF(multidev, *cds, multidev);
/* clean nic */
- for (i = 0; i < cds->num_nics; i++)
- libxl_device_nic_dispose(&cds->nics[i]);
- free(cds->nics);
+ libxl__device_list_free(&libxl__nic_devtype, cds->nics, cds->num_nics);
cds->nics = NULL;
cds->num_nics = 0;
@@ -87,6 +87,7 @@ void libxl__colo_save_setup(libxl__egc *egc, libxl__colo_save_state *css)
libxl__srm_save_autogen_callbacks *const callbacks =
&dss->sws.shs.callbacks.save.a;
libxl_device_nic *nics;
+ int nb;
STATE_AO_GC(dss->ao);
@@ -122,9 +123,10 @@ void libxl__colo_save_setup(libxl__egc *egc, libxl__colo_save_state *css)
cds->device_kind_flags = (1 << LIBXL__DEVICE_KIND_VBD);
/* Use this args we can connect to qemu colo-compare */
- nics = libxl_device_nic_list(CTX, cds->domid, &cds->num_nics);
+ nics = libxl_device_nic_list(CTX, cds->domid, &nb);
css->cps.checkpoint_host = nics->colo_checkpoint_host;
css->cps.checkpoint_port = nics->colo_checkpoint_port;
+ libxl_device_nic_list_free(nics, nb);
} else {
cds->device_kind_flags = (1 << LIBXL__DEVICE_KIND_VIF) |
(1 << LIBXL__DEVICE_KIND_VBD);
@@ -1970,8 +1970,8 @@ static void spawn_stub_launch_dm(libxl__egc *egc,
* called libxl_device_nic_add at this point, but qemu needs
* the nic information to be complete.
*/
- ret = libxl__device_nic_setdefault(gc, &dm_config->nics[i], dm_domid,
- false);
+ ret = libxl__nic_devtype.set_default(gc, dm_domid, &dm_config->nics[i],
+ false);
if (ret)
goto out;
}
@@ -1242,8 +1242,6 @@ _hidden int libxl__domain_create_info_setdefault(libxl__gc *gc,
libxl_domain_create_info *c_info);
_hidden int libxl__domain_build_info_setdefault(libxl__gc *gc,
libxl_domain_build_info *b_info);
-_hidden int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
- uint32_t domid, bool hotplug);
_hidden int libxl__device_pci_setdefault(libxl__gc *gc, libxl_device_pci *pci);
_hidden void libxl__rdm_setdefault(libxl__gc *gc,
libxl_domain_build_info *b_info);
@@ -20,15 +20,18 @@
int libxl_mac_to_device_nic(libxl_ctx *ctx, uint32_t domid,
const char *mac, libxl_device_nic *nic)
{
+ GC_INIT(ctx);
libxl_device_nic *nics;
int nb, rc, i;
libxl_mac mac_n;
+ libxl_device_nic_init(nic);
+
rc = libxl__parse_mac(mac, mac_n);
if (rc)
return rc;
- nics = libxl_device_nic_list(ctx, domid, &nb);
+ nics = libxl__device_list(gc, &libxl__nic_devtype, domid, "vif", &nb);
if (!nics)
return ERROR_FAIL;
@@ -37,23 +40,18 @@ int libxl_mac_to_device_nic(libxl_ctx *ctx, uint32_t domid,
rc = ERROR_INVAL;
for (i = 0; i < nb; ++i) {
if (!libxl__compare_macs(&mac_n, &nics[i].mac)) {
- *nic = nics[i];
+ libxl_device_nic_copy(ctx, nic, &nics[i]);
rc = 0;
- i++; /* Do not dispose this NIC on exit path */
break;
}
- libxl_device_nic_dispose(&nics[i]);
}
-
- for (; i<nb; i++)
- libxl_device_nic_dispose(&nics[i]);
-
- free(nics);
+ libxl__device_list_free(&libxl__nic_devtype, nics, nb);
+ GC_FREE;
return rc;
}
-int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
- uint32_t domid, bool hotplug)
+static int libxl__device_nic_setdefault(libxl__gc *gc, uint32_t domid,
+ libxl_device_nic *nic, bool hotplug)
{
int rc;
@@ -138,49 +136,13 @@ static void libxl__update_config_nic(libxl__gc *gc, libxl_device_nic *dst,
libxl_mac_copy(CTX, &dst->mac, &src->mac);
}
-static void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
- libxl_device_nic *nic,
- libxl__ao_device *aodev)
+static int libxl__set_xenstore_nic(libxl__gc *gc, uint32_t domid,
+ libxl_device_nic *nic,
+ flexarray_t *back, flexarray_t *front,
+ flexarray_t *ro_front)
{
- STATE_AO_GC(aodev->ao);
- flexarray_t *front;
- flexarray_t *back;
- libxl__device *device;
- int rc;
- xs_transaction_t t = XBT_NULL;
- libxl_domain_config d_config;
- libxl_device_nic nic_saved;
- libxl__domain_userdata_lock *lock = NULL;
-
- libxl_domain_config_init(&d_config);
- libxl_device_nic_init(&nic_saved);
- libxl_device_nic_copy(CTX, &nic_saved, nic);
-
- rc = libxl__device_nic_setdefault(gc, nic, domid, aodev->update_json);
- if (rc) goto out;
+ flexarray_grow(back, 2);
- front = flexarray_make(gc, 16, 1);
- back = flexarray_make(gc, 18, 1);
-
- if (nic->devid == -1) {
- if ((nic->devid = libxl__device_nextid(gc, domid, "vif")) < 0) {
- rc = ERROR_FAIL;
- goto out;
- }
- }
-
- libxl__update_config_nic(gc, &nic_saved, nic);
-
- GCNEW(device);
- rc = libxl__device_from_nic(gc, domid, nic, device);
- if ( rc != 0 ) goto out;
-
- flexarray_append(back, "frontend-id");
- flexarray_append(back, GCSPRINTF("%d", domid));
- flexarray_append(back, "online");
- flexarray_append(back, "1");
- flexarray_append(back, "state");
- flexarray_append(back, GCSPRINTF("%d", XenbusStateInitialising));
if (nic->script)
flexarray_append_pair(back, "script",
libxl__abs_path(gc, nic->script,
@@ -281,78 +243,24 @@ static void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
flexarray_append(back, libxl__strdup(gc,
libxl_nic_type_to_string(nic->nictype)));
- flexarray_append(front, "backend-id");
- flexarray_append(front, GCSPRINTF("%d", nic->backend_domid));
- flexarray_append(front, "state");
- flexarray_append(front, GCSPRINTF("%d", XenbusStateInitialising));
flexarray_append(front, "handle");
flexarray_append(front, GCSPRINTF("%d", nic->devid));
flexarray_append(front, "mac");
flexarray_append(front, GCSPRINTF(
LIBXL_MAC_FMT, LIBXL_MAC_BYTES(nic->mac)));
- if (aodev->update_json) {
- lock = libxl__lock_domain_userdata(gc, domid);
- if (!lock) {
- rc = ERROR_LOCK_FAIL;
- goto out;
- }
-
- rc = libxl__get_domain_configuration(gc, domid, &d_config);
- if (rc) goto out;
-
- DEVICE_ADD(nic, nics, domid, &nic_saved, COMPARE_DEVID, &d_config);
-
- rc = libxl__dm_check_start(gc, &d_config, domid);
- if (rc) goto out;
- }
-
- for (;;) {
- rc = libxl__xs_transaction_start(gc, &t);
- if (rc) goto out;
-
- rc = libxl__device_exists(gc, t, device);
- if (rc < 0) goto out;
- if (rc == 1) { /* already exists in xenstore */
- LOGD(ERROR, domid, "device already exists in xenstore");
- aodev->action = LIBXL__DEVICE_ACTION_ADD; /* for error message */
- rc = ERROR_DEVICE_EXISTS;
- goto out;
- }
-
- if (aodev->update_json) {
- rc = libxl__set_domain_configuration(gc, domid, &d_config);
- if (rc) goto out;
- }
-
- libxl__device_generic_add(gc, t, device,
- libxl__xs_kvs_of_flexarray(gc, back),
- libxl__xs_kvs_of_flexarray(gc, front),
- NULL);
-
- rc = libxl__xs_transaction_commit(gc, &t);
- if (!rc) break;
- if (rc < 0) goto out;
- }
-
- aodev->dev = device;
- aodev->action = LIBXL__DEVICE_ACTION_ADD;
- libxl__wait_device_connection(egc, aodev);
+ return 0;
+}
- rc = 0;
-out:
- libxl__xs_transaction_abort(gc, &t);
- if (lock) libxl__unlock_domain_userdata(lock);
- libxl_device_nic_dispose(&nic_saved);
- libxl_domain_config_dispose(&d_config);
- aodev->rc = rc;
- if (rc) aodev->callback(egc, aodev);
- return;
+static void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
+ libxl_device_nic *nic,
+ libxl__ao_device *aodev)
+{
+ libxl__device_add_async(egc, domid, &libxl__nic_devtype, nic, aodev);
}
-static int libxl__device_nic_from_xenstore(libxl__gc *gc,
- const char *libxl_path,
- libxl_device_nic *nic)
+static int libxl__nic_from_xenstore(libxl__gc *gc, const char *libxl_path,
+ libxl_devid devid, libxl_device_nic *nic)
{
const char *tmp;
int rc;
@@ -498,7 +406,7 @@ int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid,
libxl_path = GCSPRINTF("%s/device/vif/%d", libxl_dom_path, devid);
- rc = libxl__device_nic_from_xenstore(gc, libxl_path, nic);
+ rc = libxl__nic_from_xenstore(gc, libxl_path, devid, nic);
if (rc) goto out;
rc = 0;
@@ -507,64 +415,22 @@ out:
return rc;
}
-static int libxl__append_nic_list(libxl__gc *gc,
- uint32_t domid,
- libxl_device_nic **nics,
- int *nnics)
-{
- char *libxl_dir_path = NULL;
- char **dir = NULL;
- unsigned int n = 0;
- libxl_device_nic *pnic = NULL, *pnic_end = NULL;
- int rc;
-
- libxl_dir_path = GCSPRINTF("%s/device/vif",
- libxl__xs_libxl_path(gc, domid));
- dir = libxl__xs_directory(gc, XBT_NULL, libxl_dir_path, &n);
- if (dir && n) {
- libxl_device_nic *tmp;
- tmp = realloc(*nics, sizeof (libxl_device_nic) * (*nnics + n));
- if (tmp == NULL)
- return ERROR_NOMEM;
- *nics = tmp;
- pnic = *nics + *nnics;
- pnic_end = *nics + *nnics + n;
- for (; pnic < pnic_end; pnic++, dir++) {
- const char *p;
- p = GCSPRINTF("%s/%s", libxl_dir_path, *dir);
- rc = libxl__device_nic_from_xenstore(gc, p, pnic);
- if (rc) goto out;
- }
- *nnics += n;
- }
- return 0;
-
- out:
- return rc;
-}
-
libxl_device_nic *libxl_device_nic_list(libxl_ctx *ctx, uint32_t domid, int *num)
{
- GC_INIT(ctx);
- libxl_device_nic *nics = NULL;
- int rc;
+ libxl_device_nic *r;
- *num = 0;
+ GC_INIT(ctx);
- rc = libxl__append_nic_list(gc, domid, &nics, num);
- if (rc) goto out_err;
+ r = libxl__device_list(gc, &libxl__nic_devtype, domid, "vif", num);
GC_FREE;
- return nics;
-out_err:
- LOGD(ERROR, domid, "Unable to list nics");
- while (*num) {
- (*num)--;
- libxl_device_nic_dispose(&nics[*num]);
- }
- free(nics);
- return NULL;
+ return r;
+}
+
+void libxl_device_nic_list_free(libxl_device_nic* list, int num)
+{
+ libxl__device_list_free(&libxl__nic_devtype, list, num);
}
int libxl_device_nic_getinfo(libxl_ctx *ctx, uint32_t domid,
@@ -646,7 +512,7 @@ int libxl__device_nic_set_devids(libxl__gc *gc, libxl_domain_config *d_config,
* called libxl_device_nic_add when domcreate_launch_dm gets called,
* but qemu needs the nic information to be complete.
*/
- ret = libxl__device_nic_setdefault(gc, &d_config->nics[i], domid,
+ ret = libxl__device_nic_setdefault(gc, domid, &d_config->nics[i],
false);
if (ret) {
LOGD(ERROR, domid, "Unable to set nic defaults for nic %d", i);
@@ -669,10 +535,16 @@ LIBXL_DEFINE_DEVICE_ADD(nic)
LIBXL_DEFINE_DEVICES_ADD(nic)
LIBXL_DEFINE_DEVICE_REMOVE(nic)
-#define libxl__device_nic_update_devid NULL
+static LIBXL_DEFINE_UPDATE_DEVID(nic, "vif")
DEFINE_DEVICE_TYPE_STRUCT(nic,
- .update_config = libxl_device_nic_update_config
+ .update_config = libxl_device_nic_update_config,
+ .from_xenstore = (int (*)(libxl__gc *, const char *, libxl_devid, void *))
+ libxl__nic_from_xenstore,
+ .set_xenstore_config = (int (*)(libxl__gc *, uint32_t, void *,
+ flexarray_t *back, flexarray_t *front,
+ flexarray_t *ro_front))
+ libxl__set_xenstore_nic
);
/*
@@ -734,9 +734,8 @@ value stub_xl_device_nic_list(value ctx, value domid)
Field(list, 1) = temp;
temp = list;
Store_field(list, 0, Val_device_nic(&c_list[i]));
- libxl_device_nic_dispose(&c_list[i]);
}
- free(c_list);
+ libxl_device_nic_list_free(c_list, nb)
CAMLreturn(list);
}
@@ -124,9 +124,8 @@ int main_networklist(int argc, char **argv)
nicinfo.rref_tx, nicinfo.rref_rx, nicinfo.backend);
libxl_nicinfo_dispose(&nicinfo);
}
- libxl_device_nic_dispose(&nics[i]);
}
- free(nics);
+ libxl_device_nic_list_free(nics, nb);
}
return 0;
}