From 0a065c45748ec5efe86f4d02f4864a58ed7dae36 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sat, 11 May 2013 13:33:36 +0100 Subject: [PATCH] drives: ceph/gluster/iscsi/sheepdog/ssh: Force the disk name to begin with a '/'. This avoids confusion when using URIs in guestfish, since the path will always start with a '/', and we don't otherwise know if we should remove it or not. By forcing the '/' to always be there, we deal with this problem in the API instead. --- fish/guestfish.pod | 2 +- src/drives.c | 35 +++++++++++++++++++++++++++-------- src/guestfs.pod | 8 ++++---- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/fish/guestfish.pod b/fish/guestfish.pod index c3b43c936..d32e747f6 100644 --- a/fish/guestfish.pod +++ b/fish/guestfish.pod @@ -1133,7 +1133,7 @@ Add a disk located on an iSCSI server. The equivalent API command would be: - > add target-iqn-name/lun protocol:iscsi server:tcp:example.com + > add /target-iqn-name/lun protocol:iscsi server:tcp:example.com =head2 B<-a nbd://example.com[:port]> diff --git a/src/drives.c b/src/drives.c index b52d8df88..5deeb7a2e 100644 --- a/src/drives.c +++ b/src/drives.c @@ -261,6 +261,11 @@ create_drive_rbd (guestfs_h *g, return NULL; } + if (exportname[0] != '/') { + error (g, _("rbd: image name must begin with a '/'")); + return NULL; + } + return create_drive_non_file (g, drive_protocol_rbd, servers, nr_servers, exportname, username, secret, @@ -306,6 +311,11 @@ create_drive_sheepdog (guestfs_h *g, return NULL; } + if (exportname[0] != '/') { + error (g, _("sheepdog: volume parameter must begin with a '/'")); + return NULL; + } + return create_drive_non_file (g, drive_protocol_sheepdog, servers, nr_servers, exportname, username, secret, @@ -344,6 +354,11 @@ create_drive_ssh (guestfs_h *g, return NULL; } + if (exportname[0] != '/') { + error (g, _("sheepdog: pathname must begin with a '/'")); + return NULL; + } + if (username && STREQ (username, "")) { error (g, _("ssh: username should not be an empty string")); return NULL; @@ -387,15 +402,16 @@ create_drive_iscsi (guestfs_h *g, return NULL; } - /* If the exportname begins with a '/', skip it. */ - if (exportname[0] == '/') - exportname++; - if (STREQ (exportname, "")) { error (g, _("iscsi: target name should not be an empty string")); return NULL; } + if (exportname[0] != '/') { + error (g, _("iscsi: target string must begin with a '/'")); + return NULL; + } + return create_drive_non_file (g, drive_protocol_iscsi, servers, nr_servers, exportname, username, secret, @@ -1194,7 +1210,8 @@ guestfs___drive_source_qemu_param (guestfs_h *g, const struct drive_source *src) if (STREQ (src->u.exportname, "")) ret = safe_strdup (g, p); else - ret = safe_asprintf (g, "%s:exportname=%s", p, src->u.exportname); + /* Skip the mandatory leading '/' character. */ + ret = safe_asprintf (g, "%s:exportname=%s", p, &src->u.exportname[1]); return ret; } @@ -1241,8 +1258,9 @@ guestfs___drive_source_qemu_param (guestfs_h *g, const struct drive_source *src) else auth = ":auth_supported=none"; + /* Skip the mandatory leading '/' character on exportname. */ return safe_asprintf (g, "rbd:%s:mon_host=%s%s%s%s", - src->u.exportname, + &src->u.exportname[1], mon_host, username ? username : "", auth, @@ -1250,12 +1268,13 @@ guestfs___drive_source_qemu_param (guestfs_h *g, const struct drive_source *src) } case drive_protocol_sheepdog: + /* Skip the mandatory leading '/' character on exportname. */ if (src->nr_servers == 0) - return safe_asprintf (g, "sheepdog:%s", src->u.exportname); + return safe_asprintf (g, "sheepdog:%s", &src->u.exportname[1]); else /* XXX How to pass multiple hosts? */ return safe_asprintf (g, "sheepdog:%s:%d:%s", src->servers[0].u.hostname, src->servers[0].port, - src->u.exportname); + &src->u.exportname[1]); case drive_protocol_ssh: return make_uri (g, "ssh", src->username, diff --git a/src/guestfs.pod b/src/guestfs.pod index e749a9df0..1477015f9 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -648,7 +648,7 @@ To do this, set the optional C and C parameters of L like this: char **servers = { "ceph1.example.org:3000", /* ... */, NULL }; - guestfs_add_drive_opts (g, "pool/image", + guestfs_add_drive_opts (g, "/pool/image", GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "rbd", GUESTFS_ADD_DRIVE_OPTS_SERVER, servers, @@ -669,7 +669,7 @@ To do this, set the optional C and C parameters of L like this: char **servers = { "gluster.example.org:3000", NULL }; - guestfs_add_drive_opts (g, "volname/image", + guestfs_add_drive_opts (g, "/volname/image", GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "gluster", GUESTFS_ADD_DRIVE_OPTS_SERVER, servers, @@ -688,7 +688,7 @@ To do this, set the optional C and C parameters like this: char **server = { "iscsi.example.org:3000", NULL }; - guestfs_add_drive_opts (g, "target-iqn-name/lun", + guestfs_add_drive_opts (g, "/target-iqn-name/lun", GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "iscsi", GUESTFS_ADD_DRIVE_OPTS_SERVER, server, @@ -768,7 +768,7 @@ To do this, set the optional C and C parameters of L like this: char **servers = { /* optional servers ... */ NULL }; - guestfs_add_drive_opts (g, "volume", + guestfs_add_drive_opts (g, "/volume", GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "sheepdog", GUESTFS_ADD_DRIVE_OPTS_SERVER, servers,