[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] wating for backend changes (was Re: [PATCH v3 4/4] libxl: add support for vscsi)
How is new code supposed to wait for backend changes? Right now there are two APIs for that: - libxl__wait_for_backend loops for a while until it returns an error. - libxl__ev_devstate_wait registers a watch and a timer. In case of pvscsi there are three variants: - new, can use libxl__wait_device_connection - reconfigure, can use both of the above - remove, may use DEFINE_DEVICE_REMOVE and its libxl__initiate_device_remove The reconfigure case has to wait for various states, depending on the state before the reconfiguration. The pci code in libxl uses just libxl__wait_for_backend. Looking through the history it seems the function was added just for pci. Is it a deprecated function, should callers get converted to libxl__ev_devstate_wait? Olaf On Fri, Mar 06, Olaf Hering wrote: > +void libxl__device_vscsi_add(libxl__egc *egc, uint32_t domid, > + libxl_device_vscsi *vscsi, > + libxl__ao_device *aodev) > +{ > + STATE_AO_GC(aodev->ao); > + libxl_ctx *ctx = libxl__gc_owner(gc); > + flexarray_t *front; > + flexarray_t *back; > + libxl__device *device; > + char *be_path; > + unsigned int be_dirs = 0, rc, i; > + > + if (vscsi->devid == -1) { > + rc = ERROR_FAIL; > + goto out; > + } > + > + /* Prealloc key+value: 4 toplevel + 4 per device */ > + i = 2 * (4 + (4 * vscsi->num_vscsi_devs)); > + back = flexarray_make(gc, i, 1); > + front = flexarray_make(gc, 2 * 2, 1); > + > + GCNEW(device); > + rc = libxl__device_from_vscsi(gc, domid, vscsi, device); > + if ( rc != 0 ) goto out; > + > + /* Check if backend device path is already present */ > + be_path = libxl__device_backend_path(gc, device); > + if (!libxl__xs_directory(gc, XBT_NULL, be_path, &be_dirs) || !be_dirs) { > + /* backend does not exist, create a new one */ > + flexarray_append_pair(back, "frontend-id", GCSPRINTF("%d", domid)); > + flexarray_append_pair(back, "online", "1"); > + flexarray_append_pair(back, "state", "1"); > + flexarray_append_pair(back, "feature-host", GCSPRINTF("%d", > !!vscsi->feature_host)); > + > + flexarray_append_pair(front, "backend-id", GCSPRINTF("%d", > vscsi->backend_domid)); > + flexarray_append_pair(front, "state", "1"); > + } > + > + for (i = 0; i < vscsi->num_vscsi_devs; i++) { > + libxl_vscsi_dev *v = vscsi->vscsi_devs + i; > + /* Trigger removal, otherwise create new device */ > + if (be_dirs) { > + unsigned int nb = 0; > + /* Preserve existing device */ > + if (libxl__xs_directory(gc, XBT_NULL, > GCSPRINTF("%s/vscsi-devs/dev-%u", be_path, v->vscsi_dev_id), &nb) && nb) { > + /* Trigger device removal by forwarding state to > XenbusStateClosing */ > + if (v->remove) > + flexarray_append_pair(back, > GCSPRINTF("vscsi-devs/dev-%u/state", v->vscsi_dev_id), "5"); > + continue; > + } > + } > + flexarray_append_pair(back, GCSPRINTF("vscsi-devs/dev-%u/p-devname", > v->vscsi_dev_id), v->p_devname); > + switch (v->pdev_type) { > + case LIBXL_VSCSI_PDEV_TYPE_WWN: > + flexarray_append_pair(back, > + GCSPRINTF("vscsi-devs/dev-%u/p-dev", > v->vscsi_dev_id), > + v->p_devname); > + break; > + case LIBXL_VSCSI_PDEV_TYPE_DEV: > + case LIBXL_VSCSI_PDEV_TYPE_HCTL: > + flexarray_append_pair(back, > + GCSPRINTF("vscsi-devs/dev-%u/p-dev", > v->vscsi_dev_id), > + GCSPRINTF("%u:%u:%u:%u", v->pdev.hst, > v->pdev.chn, v->pdev.tgt, v->pdev.lun)); > + break; > + case LIBXL_VSCSI_PDEV_TYPE_INVALID: > + default: > + rc = ERROR_FAIL; > + goto out; > + } > + flexarray_append_pair(back, GCSPRINTF("vscsi-devs/dev-%u/v-dev", > v->vscsi_dev_id), > + GCSPRINTF("%u:%u:%u:%u", v->vdev.hst, > v->vdev.chn, v->vdev.tgt, v->vdev.lun)); > + flexarray_append_pair(back, GCSPRINTF("vscsi-devs/dev-%u/state", > v->vscsi_dev_id), "1"); > + } > + > + aodev->dev = device; > + /* Either create new host or reconfigure existing host */ > + if (be_dirs == 0) { > + libxl__device_generic_add(gc, XBT_NULL, device, > + libxl__xs_kvs_of_flexarray(gc, back, > back->count), > + libxl__xs_kvs_of_flexarray(gc, front, > front->count), > + NULL); > + aodev->action = LIBXL__DEVICE_ACTION_ADD; > + libxl__wait_device_connection(egc, aodev); > + rc = 0; > + /* Done with new host */ > + goto out; > + } > + > + /* Only new devices, write them and do vscsi host reconfiguration */ > + xs_transaction_t t; > +retry_transaction: > + t = xs_transaction_start(ctx->xsh); > + libxl__xs_writev(gc, t, be_path, > + libxl__xs_kvs_of_flexarray(gc, back, back->count)); > + xs_write(ctx->xsh, t, GCSPRINTF("%s/state", be_path), "7", 2); > + if (!xs_transaction_end(ctx->xsh, t, 0)) { > + if (errno == EAGAIN) > + goto retry_transaction; > + LOGE(ERROR, "xs transaction failed"); > + rc = ERROR_FAIL; > + goto out; > + } > + libxl__wait_for_backend(gc, be_path, "4"); > + > +retry_transaction2: > + t = xs_transaction_start(ctx->xsh); > + for (i = 0; i < vscsi->num_vscsi_devs; i++) { > + libxl_vscsi_dev *v = vscsi->vscsi_devs + i; > + if (v->remove) { > + char *path, *val; > + path = GCSPRINTF("%s/vscsi-devs/dev-%u/state", be_path, > v->vscsi_dev_id); > + val = libxl__xs_read(gc, t, path); > + if (val && strcmp(val, "6") == 0) { > + path = GCSPRINTF("%s/vscsi-devs/dev-%u/state", be_path, > v->vscsi_dev_id); > + xs_rm(ctx->xsh, t, path); > + path = GCSPRINTF("%s/vscsi-devs/dev-%u/p-devname", be_path, > v->vscsi_dev_id); > + xs_rm(ctx->xsh, t, path); > + path = GCSPRINTF("%s/vscsi-devs/dev-%u/p-dev", be_path, > v->vscsi_dev_id); > + xs_rm(ctx->xsh, t, path); > + path = GCSPRINTF("%s/vscsi-devs/dev-%u/v-dev", be_path, > v->vscsi_dev_id); > + xs_rm(ctx->xsh, t, path); > + path = GCSPRINTF("%s/vscsi-devs/dev-%u", be_path, > v->vscsi_dev_id); > + xs_rm(ctx->xsh, t, path); > + } else { > + LOGE(ERROR, "%s: %s has %s, expected 6", __func__, path, > val); > + } > + } > + } > + > + if (!xs_transaction_end(ctx->xsh, t, 0)) { > + if (errno == EAGAIN) > + goto retry_transaction2; > + LOGE(ERROR, "xs transaction failed"); > + rc = ERROR_FAIL; > + goto out; > + } > + /* As we are not adding new device, skip waiting for it */ > + libxl__ao_complete(egc, aodev->ao, 0); > + > + rc = 0; > +out: > + aodev->rc = rc; > + if(rc) aodev->callback(egc, aodev); > + return; > +} _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |