static int discover_from_conf_file(const char *desc, char *argstr, const struct argconfig_commandline_options *opts, bool connect) { FILE *f; char line[256], *ptr, *args, **argv; int argc, err, ret = 0; f = fopen(PATH_NVMF_DISC, "r"); if (f == NULL) { fprintf(stderr, "No discover params given and no %s conf\n", PATH_NVMF_DISC); return -EINVAL; } while (fgets(line, sizeof(line), f) != NULL) { if (line[0] == '#' || line[0] == '\n') continue; args = strdup(line); if (!args) { fprintf(stderr, "failed to strdup args\n"); ret = -ENOMEM; goto out; } argv = calloc(MAX_DISC_ARGS, BUF_SIZE); if (!argv) { fprintf(stderr, "failed to allocate argv vector\n"); free(args); ret = -ENOMEM; goto out; } argc = 0; argv[argc++] = "discover"; while ((ptr = strsep(&args, " =\n")) != NULL) argv[argc++] = ptr; argconfig_parse(argc, argv, desc, opts, &cfg, sizeof(cfg)); err = build_options(argstr, BUF_SIZE); if (err) { ret = err; continue; } err = do_discover(argstr, connect); if (err) { ret = err; continue; } free(args); free(argv); } out: fclose(f); return ret; }
int discover(const char *desc, int argc, char **argv, bool connect) { char argstr[BUF_SIZE]; int ret; const struct argconfig_commandline_options command_line_options[] = { {"transport", 't', "LIST", CFG_STRING, &cfg.transport, required_argument, "transport type" }, {"traddr", 'a', "LIST", CFG_STRING, &cfg.traddr, required_argument, "transport address" }, {"trsvcid", 's', "LIST", CFG_STRING, &cfg.trsvcid, required_argument, "transport service id (e.g. IP port)" }, {"host-traddr", 'w', "LIST", CFG_STRING, &cfg.host_traddr, required_argument, "host traddr (e.g. FC WWN's)" }, {"hostnqn", 'q', "LIST", CFG_STRING, &cfg.hostnqn, required_argument, "user-defined hostnqn (if default not used)" }, {"raw", 'r', "LIST", CFG_STRING, &cfg.raw, required_argument, "raw output file" }, {NULL}, }; argconfig_parse(argc, argv, desc, command_line_options, &cfg, sizeof(cfg)); cfg.nqn = NVME_DISC_SUBSYS_NAME; if (!cfg.transport && !cfg.traddr) { return discover_from_conf_file(desc, argstr, command_line_options, connect); } else { ret = build_options(argstr, BUF_SIZE); if (ret) return ret; return do_discover(argstr, connect); } }
int add_domain(Domain_t *domain) { SaErrorT rv; GSList *ptr; rv = do_discover(domain); if (rv != SA_OK) return(-1); ptr = g_slist_find(domainlist, domain); if (ptr == (GSList *)NULL) domainlist = g_slist_append(domainlist, domain); return(0); }
static int connect_ctrl(struct nvmf_disc_rsp_page_entry *e) { char argstr[BUF_SIZE], *p = argstr; bool discover = false; int len; switch (e->subtype) { case NVME_NQN_DISC: discover = true; case NVME_NQN_NVME: break; default: fprintf(stderr, "skipping unsupported subtype %d\n", e->subtype); return -EINVAL; } len = sprintf(p, "nqn=%s", e->subnqn); if (len < 0) return -EINVAL; p += len; if (cfg.hostnqn) { len = sprintf(p, ",hostnqn=%s", cfg.hostnqn); if (len < 0) return -EINVAL; p += len; } switch (e->trtype) { case NVMF_TRTYPE_LOOP: /* loop */ len = sprintf(p, ",transport=loop"); if (len < 0) return -EINVAL; p += len; /* we can safely ignore the rest of the entries */ break; case NVMF_TRTYPE_RDMA: switch (e->adrfam) { case NVMF_ADDR_FAMILY_IP4: case NVMF_ADDR_FAMILY_IP6: /* FALLTHRU */ len = sprintf(p, ",transport=rdma"); if (len < 0) return -EINVAL; p += len; len = sprintf(p, ",traddr=%s", e->traddr); if (len < 0) return -EINVAL; p += len; len = sprintf(p, ",trsvcid=%s", e->trsvcid); if (len < 0) return -EINVAL; p += len; break; default: fprintf(stderr, "skipping unsupported adrfam\n"); return -EINVAL; } break; case NVMF_TRTYPE_FC: switch (e->adrfam) { case NVMF_ADDR_FAMILY_FC: len = sprintf(p, ",transport=fc"); if (len < 0) return -EINVAL; p += len; len = sprintf(p, ",traddr=%s", e->traddr); if (len < 0) return -EINVAL; p += len; break; default: fprintf(stderr, "skipping unsupported adrfam\n"); return -EINVAL; } break; default: fprintf(stderr, "skipping unsupported transport %d\n", e->trtype); return -EINVAL; } if (discover) return do_discover(argstr, true); else return add_ctrl(argstr); }