Skip to content

Commit

Permalink
Introduce libxl_vscsi_pdev
Browse files Browse the repository at this point in the history
Signed-off-by: Olaf Hering <olaf@aepfle.de>
  • Loading branch information
olafhering committed Mar 17, 2015
1 parent a284e2b commit f0de537
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 53 deletions.
15 changes: 11 additions & 4 deletions tools/libxl/libxl.c
Expand Up @@ -1989,6 +1989,7 @@ void libxl__device_vscsi_add(libxl__egc *egc, uint32_t domid,
flexarray_t *front;
flexarray_t *back;
libxl__device *device;
libxl_vscsi_hctl *hctl;
char *be_path;
unsigned int be_dirs = 0, rc, i;

Expand Down Expand Up @@ -2034,18 +2035,24 @@ void libxl__device_vscsi_add(libxl__egc *egc, uint32_t domid,
continue;
}
}
flexarray_append_pair(back, GCSPRINTF("vscsi-devs/dev-%u/p-devname", v->vscsi_dev_id), v->p_devname);
switch (v->pdev_type) {
flexarray_append_pair(back, GCSPRINTF("vscsi-devs/dev-%u/p-devname", v->vscsi_dev_id), v->pdev.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);
v->pdev.u.wwn);
break;
case LIBXL_VSCSI_PDEV_TYPE_DEV:
hctl = &v->pdev.u.dev;
flexarray_append_pair(back,
GCSPRINTF("vscsi-devs/dev-%u/p-dev", v->vscsi_dev_id),
GCSPRINTF("%u:%u:%u:%u", hctl->hst, hctl->chn, hctl->tgt, hctl->lun));
break;
case LIBXL_VSCSI_PDEV_TYPE_HCTL:
hctl = &v->pdev.u.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));
GCSPRINTF("%u:%u:%u:%u", hctl->hst, hctl->chn, hctl->tgt, hctl->lun));
break;
case LIBXL_VSCSI_PDEV_TYPE_INVALID:
default:
Expand Down
18 changes: 13 additions & 5 deletions tools/libxl/libxl_types.idl
Expand Up @@ -556,12 +556,21 @@ libxl_vscsi_hctl = Struct("vscsi_hctl", [
("lun", uint32),
])

libxl_vscsi_pdev = Struct("vscsi_pdev", [
("p_devname", string),
("u", KeyedUnion(None, libxl_vscsi_pdev_type, "type",
[
("invalid", None),
("dev", libxl_vscsi_hctl),
("wwn", string),
("hctl", libxl_vscsi_hctl),
])),
])

libxl_vscsi_dev = Struct("vscsi_dev", [
("vscsi_dev_id", libxl_devid),
("remove", bool),
("p_devname", string),
("pdev_type", libxl_vscsi_pdev_type),
("pdev", libxl_vscsi_hctl),
("pdev", libxl_vscsi_pdev),
("vdev", libxl_vscsi_hctl),
])

Expand Down Expand Up @@ -624,8 +633,7 @@ libxl_vscsiinfo = Struct("vscsiinfo", [
("frontend", string),
("frontend_id", uint32),
("devid", libxl_devid),
("p_devname", string),
("pdev", libxl_vscsi_hctl),
("pdev", libxl_vscsi_pdev),
("vdev", libxl_vscsi_hctl),
("vscsi_dev_id", libxl_devid),
("feature_host", bool),
Expand Down
78 changes: 70 additions & 8 deletions tools/libxl/libxl_vscsi.c
@@ -1,7 +1,7 @@
#include "libxl_osdeps.h" /* must come before any other headers */
#include "libxl_internal.h"

static int vscsi_parse_hctl(libxl__gc *gc, char *str, libxl_vscsi_hctl *hctl)
static int vscsi_parse_hctl(char *str, libxl_vscsi_hctl *hctl)
{
unsigned int hst, chn, tgt, lun;

Expand All @@ -15,6 +15,69 @@ static int vscsi_parse_hctl(libxl__gc *gc, char *str, libxl_vscsi_hctl *hctl)
return 0;
}

static bool vscsi_wwn_valid(const char *p)
{
bool ret = true;
int i = 0;

for (i = 0; i < 16; i++, p++) {
if (*p >= '0' && *p <= '9')
continue;
if (*p >= 'a' && *p <= 'f')
continue;
if (*p >= 'A' && *p <= 'F')
continue;
ret = false;
break;
}
return ret;
}

static bool vscsi_parse_pdev(libxl_ctx *ctx, libxl_vscsi_dev *v_dev,
char *c, char *p, char *v)
{
GC_INIT(ctx);
libxl_vscsi_hctl hctl;
unsigned int lun;
char wwn[16 + 1];
bool parsed_ok = false;

libxl_vscsi_hctl_init(&hctl);

v_dev->pdev.p_devname = libxl__strdup(NOGC, c);

/* Translate p-dev back into pdev.type, expect a valid p-devname */
if (strncmp(c, "/dev/", 5) == 0) {
/* Either xenlinux, or pvops with properly configured alias in sysfs */
if (vscsi_parse_hctl(p, &hctl) == 0) {
libxl_vscsi_pdev_init_type(&v_dev->pdev, LIBXL_VSCSI_PDEV_TYPE_DEV);
libxl_vscsi_hctl_copy(ctx, &v_dev->pdev.u.dev, &hctl);
parsed_ok = true;
}
} else if (strncmp(c, "naa.", 4) == 0) {
/* WWN as understood by pvops */
memset(wwn, 0, sizeof(wwn));
if (sscanf(p, "naa.%16c:%u", wwn, &lun) == 2 && vscsi_wwn_valid(wwn)) {
libxl_vscsi_pdev_init_type(&v_dev->pdev, LIBXL_VSCSI_PDEV_TYPE_WWN);
v_dev->pdev.u.wwn = libxl__strdup(NOGC, c);
parsed_ok = true;
}
} else if (vscsi_parse_hctl(p, &hctl) == 0) {
/* Either xenlinux, or pvops with properly configured alias in sysfs */
libxl_vscsi_pdev_init_type(&v_dev->pdev, LIBXL_VSCSI_PDEV_TYPE_HCTL);
libxl_vscsi_hctl_copy(ctx, &v_dev->pdev.u.hctl, &hctl);
parsed_ok = true;
}

if (parsed_ok && vscsi_parse_hctl(v, &v_dev->vdev) != 0)
parsed_ok = false;

libxl_vscsi_hctl_dispose(&hctl);

GC_FREE;
return parsed_ok;
}

libxl_device_vscsi *libxl_device_vscsi_list(libxl_ctx *ctx, uint32_t domid, int *num)
{
GC_INIT(ctx);
Expand Down Expand Up @@ -78,12 +141,11 @@ libxl_device_vscsi *libxl_device_vscsi_list(libxl_ctx *ctx, uint32_t domid, int
v = libxl__xs_read(gc, XBT_NULL,
GCSPRINTF("%s/vscsi-devs/dev-%u/v-dev",
be_path, vscsi_dev_id));
if (c && p && v) {
v_dev->p_devname = libxl__strdup(NOGC, c);
/* FIXME pdev not always in hctl format with pvops */
if (vscsi_parse_hctl(gc, p, &v_dev->pdev) == 0 &&
vscsi_parse_hctl(gc, v, &v_dev->vdev) == 0)
parsed_ok = true;
if (c && p && v)
parsed_ok = vscsi_parse_pdev(ctx, v_dev, c, p, v);

/* Indication for caller that this v_dev is usable */
if (parsed_ok) {
v_dev->vscsi_dev_id = vscsi_dev_id;
if (vscsi_dev_id > v_hst->next_vscsi_dev_id)
v_hst->next_vscsi_dev_id = vscsi_dev_id + 1;
Expand Down Expand Up @@ -120,7 +182,7 @@ int libxl_device_vscsi_getinfo(libxl_ctx *ctx, uint32_t domid,
libxl_vscsiinfo_init(vscsiinfo);
dompath = libxl__xs_get_dompath(gc, domid);
vscsiinfo->devid = vscsi_host->devid;
libxl_vscsi_hctl_copy(ctx, &vscsiinfo->pdev, &vscsi_dev->pdev);
libxl_vscsi_pdev_copy(ctx, &vscsiinfo->pdev, &vscsi_dev->pdev);
libxl_vscsi_hctl_copy(ctx, &vscsiinfo->vdev, &vscsi_dev->vdev);

vscsipath = GCSPRINTF("%s/device/vscsi/%d", dompath, vscsiinfo->devid);
Expand Down
62 changes: 33 additions & 29 deletions tools/libxl/libxlu_vscsi.c
Expand Up @@ -117,33 +117,48 @@ static bool xlu__vscsi_wwn_valid(const char *p)
return ret;
}

static int xlu__vscsi_parse_pdev(XLU_Config *cfg, char *pdev, libxl_vscsi_dev *new_dev)
static int xlu__vscsi_parse_pdev(XLU_Config *cfg, libxl_ctx *ctx, char *str,
libxl_vscsi_pdev *pdev)
{
int rc = 0;
unsigned int lun;
char wwn[16 + 1];
libxl_vscsi_hctl hctl;

if (strncmp(pdev, "/dev/", 5) == 0) {
libxl_vscsi_hctl_init(&hctl);
if (strncmp(str, "/dev/", 5) == 0) {
/* Either xenlinux, or pvops with properly configured alias in sysfs */
if (xlu__vscsi_parse_dev(cfg, pdev, &new_dev->pdev) == 0)
new_dev->pdev_type = LIBXL_VSCSI_PDEV_TYPE_DEV;
} else if (strncmp(pdev, "naa.", 4) == 0) {
if (xlu__vscsi_parse_dev(cfg, str, &hctl) == 0) {
libxl_vscsi_pdev_init_type(pdev, LIBXL_VSCSI_PDEV_TYPE_DEV);
libxl_vscsi_hctl_copy(ctx, &pdev->u.dev, &hctl);
}
} else if (strncmp(str, "naa.", 4) == 0) {
/* WWN as understood by pvops */
memset(wwn, 0, sizeof(wwn));
if (sscanf(pdev, "naa.%16c:%u", wwn, &lun) == 2 && xlu__vscsi_wwn_valid(wwn)) {
new_dev->pdev_type = LIBXL_VSCSI_PDEV_TYPE_WWN;
new_dev->pdev.lun = lun;
if (sscanf(str, "naa.%16c:%u", wwn, &lun) == 2 && xlu__vscsi_wwn_valid(wwn)) {
libxl_vscsi_pdev_init_type(pdev, LIBXL_VSCSI_PDEV_TYPE_WWN);
pdev->u.wwn = strdup(str);
if (!pdev->u.wwn)
rc = ERROR_NOMEM;
}
} else if (xlu__vscsi_parse_hctl(pdev, &new_dev->pdev) == 0) {
} else if (xlu__vscsi_parse_hctl(str, &hctl) == 0) {
/* Either xenlinux, or pvops with properly configured alias in sysfs */
new_dev->pdev_type = LIBXL_VSCSI_PDEV_TYPE_HCTL;
libxl_vscsi_pdev_init_type(pdev, LIBXL_VSCSI_PDEV_TYPE_HCTL);
libxl_vscsi_hctl_copy(ctx, &pdev->u.dev, &hctl);
} else
rc = ERROR_INVAL;

if (rc == 0) {
pdev->p_devname = strdup(str);
if (!pdev->p_devname)
rc = ERROR_NOMEM;
}

libxl_vscsi_hctl_dispose(&hctl);
return rc;
}

int xlu_vscsi_parse(XLU_Config *cfg, const char *str,
int xlu_vscsi_parse(XLU_Config *cfg, libxl_ctx *ctx, const char *str,
libxl_device_vscsi *new_host,
libxl_vscsi_dev *new_dev)
{
Expand All @@ -168,26 +183,16 @@ int xlu_vscsi_parse(XLU_Config *cfg, const char *str,
pdev = xlu__vscsi_trim_string(pdev);
vdev = xlu__vscsi_trim_string(vdev);

new_dev->pdev_type = LIBXL_VSCSI_PDEV_TYPE_INVALID;
rc = xlu__vscsi_parse_pdev(cfg, pdev, new_dev);
switch (rc) {
case ERROR_NOPARAVIRT:
LOG(cfg, "vscsi: not supported");
goto out;
default:
LOG(cfg, "vscsi: failed to parse %s", pdev);
goto out;
rc = xlu__vscsi_parse_pdev(cfg, ctx, pdev, &new_dev->pdev);
if (rc) {
LOG(cfg, "vscsi: failed to parse %s, rc == %d", pdev, rc);
goto out;
}

switch (new_dev->pdev_type) {
switch (new_dev->pdev.type) {
case LIBXL_VSCSI_PDEV_TYPE_WWN:
case LIBXL_VSCSI_PDEV_TYPE_DEV:
case LIBXL_VSCSI_PDEV_TYPE_HCTL:
new_dev->p_devname = strdup(pdev);
if (!new_dev->p_devname) {
rc = ERROR_NOMEM;
goto out;
}
break;
case LIBXL_VSCSI_PDEV_TYPE_INVALID:
LOG(cfg, "vscsi: invalid pdev '%s'", pdev);
Expand Down Expand Up @@ -260,10 +265,9 @@ int xlu_vscsi_get_host(XLU_Config *cfg, libxl_ctx *ctx, uint32_t domid, const ch
libxl_device_vscsi_init(new_host);
libxl_vscsi_dev_init(new_dev);

if (xlu_vscsi_parse(cfg, str, new_host, new_dev)) {
rc = ERROR_INVAL;
rc = xlu_vscsi_parse(cfg, ctx, str, new_host, new_dev);
if (rc)
goto out;
}

/* Look for existing vscsi_host for given domain */
vscsi_hosts = libxl_device_vscsi_list(ctx, domid, &num_hosts);
Expand Down
2 changes: 1 addition & 1 deletion tools/libxl/libxlutil.h
Expand Up @@ -108,7 +108,7 @@ int xlu_vscsi_get_host(XLU_Config *config,
uint32_t domid,
const char *str,
libxl_device_vscsi *vscsi_host);
int xlu_vscsi_parse(XLU_Config *cfg, const char *str,
int xlu_vscsi_parse(XLU_Config *cfg, libxl_ctx *ctx, const char *str,
libxl_device_vscsi *new_host,
libxl_vscsi_dev *new_dev);
#endif /* LIBXLUTIL_H */
Expand Down
10 changes: 4 additions & 6 deletions tools/libxl/xl_cmdimpl.c
Expand Up @@ -1508,7 +1508,7 @@ static void parse_config_data(const char *config_source,
libxl_device_vscsi_init(&v_hst);
libxl_vscsi_dev_init(&v_dev);

if (xlu_vscsi_parse(config, buf, &v_hst, &v_dev))
if (xlu_vscsi_parse(config, ctx, buf, &v_hst, &v_dev))
exit (-1);

if (d_config->num_vscsis) {
Expand Down Expand Up @@ -6608,9 +6608,7 @@ int main_vscsilist(int argc, char **argv)
for (h = 0; h < num_hosts; ++h) {
for (d = 0; d < vscsi_hosts[h].num_vscsi_devs; d++) {
if (!libxl_device_vscsi_getinfo(ctx, domid, &vscsi_hosts[h], &vscsi_hosts[h].vscsi_devs[d], &vscsiinfo)) {
char pdev[64], vdev[64];
snprintf(pdev, sizeof(pdev), "%u:%u:%u:%u",
vscsiinfo.pdev.hst, vscsiinfo.pdev.chn, vscsiinfo.pdev.tgt, vscsiinfo.pdev.lun);
char vdev[64];
snprintf(vdev, sizeof(vdev), "%u:%u:%u:%u",
vscsiinfo.vdev.hst, vscsiinfo.vdev.chn, vscsiinfo.vdev.tgt, vscsiinfo.vdev.lun);
/* Idx BE state Sta */
Expand All @@ -6619,7 +6617,7 @@ int main_vscsilist(int argc, char **argv)
vscsiinfo.backend_id,
vscsiinfo.vscsi_host_state,
vscsiinfo.backend_id,
pdev, vdev,
vscsiinfo.pdev.p_devname, vdev,
vscsiinfo.vscsi_dev_state);

libxl_vscsiinfo_dispose(&vscsiinfo);
Expand Down Expand Up @@ -6657,7 +6655,7 @@ static int vscsidetach(libxl_device_vscsi *hosts, int num, uint32_t domid,

libxl_vscsi_dev_init(&v_dev);
libxl_device_vscsi_init(&v_hst);
if (xlu_vscsi_parse(config, tmp, &v_hst, &v_dev))
if (xlu_vscsi_parse(config, ctx, tmp, &v_hst, &v_dev))
goto out;

for (h = 0; h < num; ++h) {
Expand Down

0 comments on commit f0de537

Please sign in to comment.