[stgt] [PATCH] bs_rbd.c: accept and parse bsopts
Dan Mick
dan.mick at inktank.com
Tue Oct 29 01:19:34 CET 2013
Options are supplied as one string, "key1=val1;key2=val2;" etc.
Legal options:
conf=<conffile>
id=<clientid>
For example, --bsopts "conf=/usr/local/ceph/ceph.conf;id=stgt"
(quoting is necessary to protect ; from the shell)
Unknown options are skipped.
Signed-off-by: Dan Mick <dan.mick at inktank.com>
---
usr/bs_rbd.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 80 insertions(+), 6 deletions(-)
diff --git a/usr/bs_rbd.c b/usr/bs_rbd.c
index 77b27f7..3ea9d36 100644
--- a/usr/bs_rbd.c
+++ b/usr/bs_rbd.c
@@ -466,26 +466,96 @@ static void bs_rbd_close(struct scsi_lu *lu)
}
}
+// Slurp up and return a copy of everything to the next ';', and update p
+static char *slurp_to_semi(char **p)
+{
+ char *end = index(*p, ';');
+ char *ret;
+ int len;
+
+ if (end == NULL)
+ end = *p + strlen(*p);
+ len = end - *p;
+ ret = malloc(len + 1);
+ strncpy(ret, *p, len);
+ ret[len] = '\0';
+ *p = end;
+ return ret;
+}
+
+static char *slurp_value(char **p)
+{
+ char *equal = index(*p, '=');
+ if (equal) {
+ *p = equal + 1;
+ return slurp_to_semi(p);
+ } else {
+ // uh...no?
+ return NULL;
+ }
+}
+
+static int is_opt(const char *opt, char *p)
+{
+ int ret = 0;
+ if ((strncmp(p, opt, strlen(opt)) == 0) &&
+ (p[strlen(opt)] == '=')) {
+ ret = 1;
+ }
+ return ret;
+}
+
+
static tgtadm_err bs_rbd_init(struct scsi_lu *lu, char *bsopts)
{
+ struct bs_thread_info *info = BS_THREAD_I(lu);
tgtadm_err ret = TGTADM_UNKNOWN_ERR;
int rados_ret;
- struct bs_thread_info *info = BS_THREAD_I(lu);
struct active_rbd *rbd = RBDP(lu);
+ char *confname = NULL;
+ char *clientid = NULL;
+ char *ignore = NULL;
+
+ dprintf("bs_rbd_init bsopts: \"%s\"\n", bsopts);
+
+ // look for conf= or id=
+
+ while (bsopts && strlen(bsopts)) {
+ if (is_opt("conf", bsopts))
+ confname = slurp_value(&bsopts);
+ else if (is_opt("id", bsopts))
+ clientid = slurp_value(&bsopts);
+ else {
+ ignore = slurp_to_semi(&bsopts);
+ eprintf("bs_rbd: ignoring unknown option \"%s\"\n",
+ ignore);
+ free(ignore);
+ break;
+ }
+ }
+
+ if (clientid)
+ eprintf("bs_rbd_init: clientid %s\n", clientid);
+ if (confname)
+ eprintf("bs_rbd_init: confname %s\n", confname);
- rados_ret = rados_create(&rbd->cluster, NULL);
eprintf("bs_rbd_init bsopts=%s\n", bsopts);
+ /* clientid may be set by -i/--id */
+ rados_ret = rados_create(&rbd->cluster, clientid);
if (rados_ret < 0) {
eprintf("bs_rbd_init: rados_create: %d\n", rados_ret);
return ret;
}
- /* read config from environment and then default files */
+ /*
+ * Read config from environment, then conf file(s) which may
+ * be set by conf=
+ */
rados_ret = rados_conf_parse_env(rbd->cluster, NULL);
if (rados_ret < 0) {
eprintf("bs_rbd_init: rados_conf_parse_env: %d\n", rados_ret);
goto fail;
}
- rados_ret = rados_conf_read_file(rbd->cluster, NULL);
+ rados_ret = rados_conf_read_file(rbd->cluster, confname);
if (rados_ret < 0) {
eprintf("bs_rbd_init: rados_conf_read_file: %d\n", rados_ret);
goto fail;
@@ -496,9 +566,12 @@ static tgtadm_err bs_rbd_init(struct scsi_lu *lu, char *bsopts)
goto fail;
}
ret = bs_thread_open(info, bs_rbd_request, nr_iothreads);
- if (ret == TGTADM_SUCCESS)
- return ret;
fail:
+ if (confname)
+ free(confname);
+ if (clientid)
+ free(clientid);
+
return ret;
}
@@ -507,6 +580,7 @@ static void bs_rbd_exit(struct scsi_lu *lu)
struct bs_thread_info *info = BS_THREAD_I(lu);
struct active_rbd *rbd = RBDP(lu);
+ /* do this first to try to be sure there's no outstanding I/O */
bs_thread_close(info);
rados_shutdown(rbd->cluster);
}
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list