* [Qemu-devel] [RFC 0/2] rbd authentication
@ 2011-11-10 0:20 Josh Durgin
2011-11-10 0:20 ` [Qemu-devel] [RFC 1/2] block: let bdrv_set_key be used for authentication Josh Durgin
2011-11-10 0:20 ` [Qemu-devel] [RFC 2/2] rbd: implement bdrv_set_key Josh Durgin
0 siblings, 2 replies; 3+ messages in thread
From: Josh Durgin @ 2011-11-10 0:20 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, ceph-devel
These patches allow keys to be passed to rbd devices for
authentication via the same interface that qcow uses for encryption -
the monitor block_passwd command.
Since rbd cannot read anything from the cluster before authenticating,
the size of the device is unknown until the key is set. At this point,
the size can be refreshed as if the device were resized. This works
fine with the virtio driver, but other drivers, like ide, don't
implement the resize callback. What do you think is the best way to
solve this?
Josh Durgin (2):
block: let bdrv_set_key be used for authentication
rbd: implement bdrv_set_key
block.c | 27 +++++++---
block.h | 2 +-
block/rbd.c | 160 ++++++++++++++++++++++++++++++++++++++----------------
block_int.h | 3 +-
blockdev.c | 3 +-
hmp-commands.hx | 6 +-
monitor.c | 13 +++--
qapi-schema.json | 7 ++-
qemu-img.c | 4 +-
qerror.c | 16 +++---
qerror.h | 12 ++--
qmp-commands.hx | 6 ++-
12 files changed, 172 insertions(+), 87 deletions(-)
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Qemu-devel] [RFC 1/2] block: let bdrv_set_key be used for authentication
2011-11-10 0:20 [Qemu-devel] [RFC 0/2] rbd authentication Josh Durgin
@ 2011-11-10 0:20 ` Josh Durgin
2011-11-10 0:20 ` [Qemu-devel] [RFC 2/2] rbd: implement bdrv_set_key Josh Durgin
1 sibling, 0 replies; 3+ messages in thread
From: Josh Durgin @ 2011-11-10 0:20 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, ceph-devel
Add a BlockDriverState member 'needs_auth' to distinguish between
drives that require authentication and those that are encrypted.
Update the block_passwd monitor command and error strings to be about
generic passwords instead of encryption.
Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com>
---
block.c | 27 +++++++++++++++++++--------
block.h | 2 +-
block_int.h | 3 ++-
blockdev.c | 3 ++-
hmp-commands.hx | 6 +++---
monitor.c | 13 +++++++------
qapi-schema.json | 7 +++++--
qemu-img.c | 4 ++--
qerror.c | 16 ++++++++--------
qerror.h | 12 ++++++------
qmp-commands.hx | 6 ++++--
11 files changed, 59 insertions(+), 40 deletions(-)
diff --git a/block.c b/block.c
index 49ca0b3..a33ed47 100644
--- a/block.c
+++ b/block.c
@@ -499,7 +499,7 @@ static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
return 0;
/* query actual device if possible, otherwise just trust the hint */
- if (drv->bdrv_getlength) {
+ if (drv->bdrv_getlength && !(bdrv_key_required(bs) && bs->needs_auth)) {
int64_t length = drv->bdrv_getlength(bs);
if (length < 0) {
return length;
@@ -1781,9 +1781,12 @@ int bdrv_key_required(BlockDriverState *bs)
{
BlockDriverState *backing_hd = bs->backing_hd;
- if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
+ if (backing_hd &&
+ (backing_hd->encrypted || backing_hd->needs_auth) &&
+ !backing_hd->valid_key) {
return 1;
- return (bs->encrypted && !bs->valid_key);
+ }
+ return (bs->encrypted || bs->needs_auth) && !bs->valid_key;
}
int bdrv_set_key(BlockDriverState *bs, const char *key)
@@ -1796,7 +1799,7 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
if (!bs->encrypted)
return 0;
}
- if (!bs->encrypted) {
+ if (!bs->encrypted && !bs->needs_auth) {
return -EINVAL;
} else if (!bs->drv || !bs->drv->bdrv_set_key) {
return -ENOMEDIUM;
@@ -1808,6 +1811,11 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
bs->valid_key = 1;
/* call the change callback now, we skipped it on open */
bdrv_dev_change_media_cb(bs, true);
+ /* if we couldn't read the size before, set it now */
+ if (bs->needs_auth) {
+ refresh_total_sectors(bs, bs->total_sectors);
+ bdrv_dev_resize_cb(bs);
+ }
}
return ret;
}
@@ -1974,6 +1982,7 @@ BlockInfoList *qmp_query_block(Error **errp)
info->value->inserted->ro = bs->read_only;
info->value->inserted->drv = g_strdup(bs->drv->format_name);
info->value->inserted->encrypted = bs->encrypted;
+ info->value->inserted->needs_auth = bs->needs_auth;
if (bs->backing_file[0]) {
info->value->inserted->has_backing_file = true;
info->value->inserted->backing_file = g_strdup(bs->backing_file);
@@ -2059,14 +2068,16 @@ BlockStatsList *qmp_query_blockstats(Error **errp)
return head;
}
-const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
+const char *bdrv_get_protected_filename(BlockDriverState *bs)
{
- if (bs->backing_hd && bs->backing_hd->encrypted)
+ if (bs->backing_hd &&
+ (bs->backing_hd->encrypted || bs->backing_hd->needs_auth)) {
return bs->backing_file;
- else if (bs->encrypted)
+ } else if (bs->encrypted || bs->needs_auth) {
return bs->filename;
- else
+ } else {
return NULL;
+ }
}
void bdrv_get_backing_filename(BlockDriverState *bs,
diff --git a/block.h b/block.h
index 9d8909b..126ba11 100644
--- a/block.h
+++ b/block.h
@@ -262,7 +262,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
-const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
+const char *bdrv_get_protected_filename(BlockDriverState *bs);
void bdrv_get_backing_filename(BlockDriverState *bs,
char *filename, int filename_size);
int bdrv_can_snapshot(BlockDriverState *bs);
diff --git a/block_int.h b/block_int.h
index 69418fe..68b91a1 100644
--- a/block_int.h
+++ b/block_int.h
@@ -177,7 +177,8 @@ struct BlockDriverState {
int keep_read_only; /* if true, the media was requested to stay read only */
int open_flags; /* flags used to open the file, re-used for re-open */
int encrypted; /* if true, the media is encrypted */
- int valid_key; /* if true, a valid encryption key has been set */
+ int needs_auth; /* if true, the media requires authentication */
+ int valid_key; /* if true, a valid key has been set */
int sg; /* if true, the device is a /dev/sg* */
BlockDriver *drv; /* NULL means no media */
diff --git a/blockdev.c b/blockdev.c
index 9068c5b..a5fbf42 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -718,7 +718,8 @@ int do_block_set_passwd(Monitor *mon, const QDict *qdict,
err = bdrv_set_key(bs, qdict_get_str(qdict, "password"));
if (err == -EINVAL) {
- qerror_report(QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
+ qerror_report(QERR_DEVICE_PASSWORD_UNNECESSARY,
+ bdrv_get_device_name(bs));
return -1;
} else if (err < 0) {
qerror_report(QERR_INVALID_PASSWORD);
diff --git a/hmp-commands.hx b/hmp-commands.hx
index f8d855e..fd15dba 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1200,8 +1200,8 @@ ETEXI
{
.name = "block_passwd",
.args_type = "device:B,password:s",
- .params = "block_passwd device password",
- .help = "set the password of encrypted block devices",
+ .params = "device password",
+ .help = "set the password for a block device",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_block_set_passwd,
},
@@ -1224,7 +1224,7 @@ ETEXI
STEXI
@item block_passwd @var{device} @var{password}
@findex block_passwd
-Set the encrypted device @var{device} password to @var{password}
+Set the password of @var{device} password to @var{password}
ETEXI
{
diff --git a/monitor.c b/monitor.c
index 5ea35de..6eea007 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1073,7 +1073,7 @@ static void do_singlestep(Monitor *mon, const QDict *qdict)
}
}
-static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs);
+static void protected_bdrv_it(void *opaque, BlockDriverState *bs);
struct bdrv_iterate_context {
Monitor *mon;
@@ -1102,7 +1102,7 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data)
}
bdrv_iterate(iostatus_bdrv_it, NULL);
- bdrv_iterate(encrypted_bdrv_it, &context);
+ bdrv_iterate(protected_bdrv_it, &context);
/* only resume the vm if all keys are set and valid */
if (!context.err) {
vm_start();
@@ -1121,7 +1121,7 @@ static void bdrv_key_cb(void *opaque, int err)
do_cont(mon, NULL, NULL);
}
-static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)
+static void protected_bdrv_it(void *opaque, BlockDriverState *bs)
{
struct bdrv_iterate_context *context = opaque;
@@ -4926,12 +4926,13 @@ int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
}
if (monitor_ctrl_mode(mon)) {
- qerror_report(QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs));
+ qerror_report(QERR_DEVICE_PASSWORD_REQUIRED, bdrv_get_device_name(bs));
return -1;
}
- monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
- bdrv_get_encrypted_filename(bs));
+ monitor_printf(mon, "%s (%s) requires a password.\n",
+ bdrv_get_device_name(bs),
+ bdrv_get_protected_filename(bs));
mon->password_completion_cb = completion_cb;
mon->password_opaque = opaque;
diff --git a/qapi-schema.json b/qapi-schema.json
index fbbdbe0..ab45057 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -370,6 +370,8 @@
#
# @encrypted: true if the backing device is encrypted
#
+# @needs_auth: true if the backing device requires authentication
+#
# @bps: total throughput limit in bytes per second is specified
#
# @bps_rd: read throughput limit in bytes per second is specified
@@ -389,8 +391,9 @@
{ 'type': 'BlockDeviceInfo',
'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str',
'*backing_file': 'str', 'encrypted': 'bool',
- 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
- 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int'} }
+ 'needs_auth': 'bool', 'bps': 'int', 'bps_rd': 'int',
+ 'bps_wr': 'int', 'iops': 'int', 'iops_rd': 'int',
+ 'iops_wr': 'int'} }
##
# @BlockDeviceIoStatus:
diff --git a/qemu-img.c b/qemu-img.c
index 86127f0..77c8165 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -240,8 +240,8 @@ static BlockDriverState *bdrv_new_open(const char *filename,
goto fail;
}
- if (bdrv_is_encrypted(bs)) {
- printf("Disk image '%s' is encrypted.\n", filename);
+ if (bdrv_key_required(bs)) {
+ printf("Disk image '%s' requires a password.\n", filename);
if (read_password(password, sizeof(password)) < 0) {
error_report("No password given");
goto fail;
diff --git a/qerror.c b/qerror.c
index 807fb55..e4d9a9b 100644
--- a/qerror.c
+++ b/qerror.c
@@ -61,10 +61,6 @@ static const QErrorStringTable qerror_table[] = {
.desc = "The command %(name) has not been found",
},
{
- .error_fmt = QERR_DEVICE_ENCRYPTED,
- .desc = "Device '%(device)' is encrypted",
- },
- {
.error_fmt = QERR_DEVICE_INIT_FAILED,
.desc = "Device '%(device)' could not be initialized",
},
@@ -85,10 +81,6 @@ static const QErrorStringTable qerror_table[] = {
.desc = "Device '%(device)' has not been activated",
},
{
- .error_fmt = QERR_DEVICE_NOT_ENCRYPTED,
- .desc = "Device '%(device)' is not encrypted",
- },
- {
.error_fmt = QERR_DEVICE_NOT_FOUND,
.desc = "Device '%(device)' not found",
},
@@ -105,6 +97,14 @@ static const QErrorStringTable qerror_table[] = {
.desc = "Device '%(device)' does not support hotplugging",
},
{
+ .error_fmt = QERR_DEVICE_PASSWORD_REQUIRED,
+ .desc = "Device '%(device)' requires a password",
+ },
+ {
+ .error_fmt = QERR_DEVICE_PASSWORD_UNNECESSARY,
+ .desc = "Device '%(device)' does not require a password",
+ },
+ {
.error_fmt = QERR_DUPLICATE_ID,
.desc = "Duplicate ID '%(id)' for %(object)",
},
diff --git a/qerror.h b/qerror.h
index 777a36a..2e6ecc5 100644
--- a/qerror.h
+++ b/qerror.h
@@ -63,9 +63,6 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_COMMAND_NOT_FOUND \
"{ 'class': 'CommandNotFound', 'data': { 'name': %s } }"
-#define QERR_DEVICE_ENCRYPTED \
- "{ 'class': 'DeviceEncrypted', 'data': { 'device': %s } }"
-
#define QERR_DEVICE_INIT_FAILED \
"{ 'class': 'DeviceInitFailed', 'data': { 'device': %s } }"
@@ -81,9 +78,6 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_DEVICE_NOT_ACTIVE \
"{ 'class': 'DeviceNotActive', 'data': { 'device': %s } }"
-#define QERR_DEVICE_NOT_ENCRYPTED \
- "{ 'class': 'DeviceNotEncrypted', 'data': { 'device': %s } }"
-
#define QERR_DEVICE_NOT_FOUND \
"{ 'class': 'DeviceNotFound', 'data': { 'device': %s } }"
@@ -96,6 +90,12 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_DEVICE_NO_HOTPLUG \
"{ 'class': 'DeviceNoHotplug', 'data': { 'device': %s } }"
+#define QERR_DEVICE_PASSWORD_REQUIRED \
+ "{ 'class': 'DevicePasswordRequired', 'data': { 'device': %s } }"
+
+#define QERR_DEVICE_PASSWORD_UNNECESSARY \
+ "{ 'class': 'DevicePasswordUnnecessary', 'data': { 'device': %s } }"
+
#define QERR_DUPLICATE_ID \
"{ 'class': 'DuplicateId', 'data': { 'id': %s, 'object': %s } }"
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 94da2a8..629af4b 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -826,7 +826,7 @@ EQMP
.name = "block_passwd",
.args_type = "device:B,password:s",
.params = "block_passwd device password",
- .help = "set the password of encrypted block devices",
+ .help = "set the password for a block device",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_block_set_passwd,
},
@@ -835,7 +835,7 @@ SQMP
block_passwd
------------
-Set the password of encrypted block devices.
+Set the password for a block device.
Arguments:
@@ -1190,6 +1190,7 @@ Each json-object contain the following:
"tftp", "vdi", "vmdk", "vpc", "vvfat"
- "backing_file": backing file name (json-string, optional)
- "encrypted": true if encrypted, false otherwise (json-bool)
+ - "needs_auth": true if the device requires authentication, false otherwise (json-bool)
- "bps": limit total bytes per second (json-int)
- "bps_rd": limit read bytes per second (json-int)
- "bps_wr": limit write bytes per second (json-int)
@@ -1216,6 +1217,7 @@ Example:
"ro":false,
"drv":"qcow2",
"encrypted":false,
+ "needs_auth":false,
"file":"disks/test.img",
"bps":1000000,
"bps_rd":0,
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [Qemu-devel] [RFC 2/2] rbd: implement bdrv_set_key
2011-11-10 0:20 [Qemu-devel] [RFC 0/2] rbd authentication Josh Durgin
2011-11-10 0:20 ` [Qemu-devel] [RFC 1/2] block: let bdrv_set_key be used for authentication Josh Durgin
@ 2011-11-10 0:20 ` Josh Durgin
1 sibling, 0 replies; 3+ messages in thread
From: Josh Durgin @ 2011-11-10 0:20 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, ceph-devel
We can't connect to the cluster before the key is set, so this step is
moved to qemu_rbd_open_finish. Each bdrv function will fail before the
key is set.
Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com>
---
block/rbd.c | 160 +++++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 113 insertions(+), 47 deletions(-)
diff --git a/block/rbd.c b/block/rbd.c
index c684e0c..005222a 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -83,6 +83,8 @@ typedef struct BDRVRBDState {
rados_ioctx_t io_ctx;
rbd_image_t image;
char name[RBD_MAX_IMAGE_NAME_SIZE];
+ char pool[RBD_MAX_POOL_NAME_SIZE];
+ char conf[RBD_MAX_CONF_SIZE];
int qemu_aio_count;
char *snap;
int event_reader_pos;
@@ -271,6 +273,17 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
return ret;
}
+static int qemu_rbd_connect(rados_t cluster,
+ const char *pool,
+ rados_ioctx_t *io_ctx)
+{
+ int ret = rados_connect(cluster);
+ if (ret < 0) {
+ return ret;
+ }
+ return rados_ioctx_create(cluster, pool, io_ctx);
+}
+
static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options)
{
int64_t bytes = 0;
@@ -332,16 +345,15 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options)
return -EIO;
}
- if (rados_connect(cluster) < 0) {
- error_report("error connecting");
- rados_shutdown(cluster);
- return -EIO;
- }
-
- if (rados_ioctx_create(cluster, pool, &io_ctx) < 0) {
- error_report("error opening pool %s", pool);
+ ret = qemu_rbd_connect(cluster, pool, &io_ctx);
+ if (ret < 0) {
+ error_report("error connecting: %s", strerror(-ret));
rados_shutdown(cluster);
- return -EIO;
+ if (ret == -EPERM || ret == -ENOTSUP) {
+ return -EPERM;
+ } else {
+ return -EIO;
+ }
}
ret = rbd_create(io_ctx, name, bytes, &obj_order);
@@ -431,57 +443,46 @@ static int qemu_rbd_aio_flush_cb(void *opaque)
return (s->qemu_aio_count > 0);
}
-static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags)
+
+static int qemu_rbd_finish_open(BDRVRBDState *s, const char *key)
{
- BDRVRBDState *s = bs->opaque;
- char pool[RBD_MAX_POOL_NAME_SIZE];
- char snap_buf[RBD_MAX_SNAP_NAME_SIZE];
- char conf[RBD_MAX_CONF_SIZE];
char clientname_buf[RBD_MAX_CONF_SIZE];
char *clientname;
int r;
- if (qemu_rbd_parsename(filename, pool, sizeof(pool),
- snap_buf, sizeof(snap_buf),
- s->name, sizeof(s->name),
- conf, sizeof(conf)) < 0) {
- return -EINVAL;
- }
-
- clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
+ clientname = qemu_rbd_parse_clientname(s->conf, clientname_buf);
r = rados_create(&s->cluster, clientname);
if (r < 0) {
error_report("error initializing");
return r;
}
- s->snap = NULL;
- if (snap_buf[0] != '\0') {
- s->snap = g_strdup(snap_buf);
- }
-
- if (strstr(conf, "conf=") == NULL) {
+ if (strstr(s->conf, "conf=") == NULL) {
/* try default location, but ignore failure */
rados_conf_read_file(s->cluster, NULL);
}
- if (conf[0] != '\0') {
- r = qemu_rbd_set_conf(s->cluster, conf);
+ if (s->conf[0] != '\0') {
+ r = qemu_rbd_set_conf(s->cluster, s->conf);
if (r < 0) {
error_report("error setting config options");
goto failed_shutdown;
}
}
- r = rados_connect(s->cluster);
- if (r < 0) {
- error_report("error connecting");
- goto failed_shutdown;
+ if (key) {
+ r = rados_conf_set(s->cluster, "key", key);
+ if (r < 0) {
+ error_report("error setting key");
+ goto failed_shutdown;
+ }
}
- r = rados_ioctx_create(s->cluster, pool, &s->io_ctx);
- if (r < 0) {
- error_report("error opening pool %s", pool);
+ r = qemu_rbd_connect(s->cluster, s->pool, &s->io_ctx);
+ if (r == -EPERM || r == -ENOTSUP) {
+ return -EPERM;
+ } else if (r < 0) {
+ error_report("error connecting: %s", strerror(-r));
goto failed_shutdown;
}
@@ -491,8 +492,6 @@ static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags)
goto failed_open;
}
- bs->read_only = (s->snap != NULL);
-
s->event_reader_pos = 0;
r = qemu_pipe(s->fds);
if (r < 0) {
@@ -513,23 +512,55 @@ failed_open:
rados_ioctx_destroy(s->io_ctx);
failed_shutdown:
rados_shutdown(s->cluster);
- g_free(s->snap);
return r;
}
+static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags)
+{
+ BDRVRBDState *s = bs->opaque;
+ char snap_buf[RBD_MAX_SNAP_NAME_SIZE];
+ int r;
+
+ if (qemu_rbd_parsename(filename, s->pool, sizeof(s->pool),
+ snap_buf, sizeof(snap_buf),
+ s->name, sizeof(s->name),
+ s->conf, sizeof(s->conf)) < 0) {
+ return -EINVAL;
+ }
+
+ s->snap = NULL;
+ if (snap_buf[0] != '\0') {
+ s->snap = g_strdup(snap_buf);
+ }
+
+ bs->read_only = (s->snap != NULL);
+
+ r = qemu_rbd_finish_open(s, NULL);
+ if (r == -EPERM) {
+ bs->needs_auth = 1;
+ } else if (r < 0) {
+ g_free(s->snap);
+ return r;
+ }
+
+ return 0;
+}
+
static void qemu_rbd_close(BlockDriverState *bs)
{
BDRVRBDState *s = bs->opaque;
- close(s->fds[0]);
- close(s->fds[1]);
- qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], NULL , NULL, NULL, NULL,
- NULL);
+ if (!bdrv_key_required(bs)) {
+ close(s->fds[0]);
+ close(s->fds[1]);
+ qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], NULL , NULL, NULL, NULL,
+ NULL);
- rbd_close(s->image);
- rados_ioctx_destroy(s->io_ctx);
+ rbd_close(s->image);
+ rados_ioctx_destroy(s->io_ctx);
+ rados_shutdown(s->cluster);
+ }
g_free(s->snap);
- rados_shutdown(s->cluster);
}
/*
@@ -692,6 +723,9 @@ static BlockDriverAIOCB *qemu_rbd_aio_readv(BlockDriverState *bs,
BlockDriverCompletionFunc *cb,
void *opaque)
{
+ if (bdrv_key_required(bs)) {
+ return NULL;
+ }
return rbd_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
}
@@ -702,11 +736,18 @@ static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
BlockDriverCompletionFunc *cb,
void *opaque)
{
+ if (bdrv_key_required(bs)) {
+ return NULL;
+ }
return rbd_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
}
static int qemu_rbd_co_flush(BlockDriverState *bs)
{
+ if (bdrv_key_required(bs)) {
+ return -EPERM;
+ }
+
#if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
/* rbd_flush added in 0.1.1 */
BDRVRBDState *s = bs->opaque;
@@ -721,6 +762,9 @@ static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi)
BDRVRBDState *s = bs->opaque;
rbd_image_info_t info;
int r;
+ if (bdrv_key_required(bs)) {
+ return -EPERM;
+ }
r = rbd_stat(s->image, &info, sizeof(info));
if (r < 0) {
@@ -736,6 +780,9 @@ static int64_t qemu_rbd_getlength(BlockDriverState *bs)
BDRVRBDState *s = bs->opaque;
rbd_image_info_t info;
int r;
+ if (bdrv_key_required(bs)) {
+ return -EPERM;
+ }
r = rbd_stat(s->image, &info, sizeof(info));
if (r < 0) {
@@ -749,6 +796,9 @@ static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset)
{
BDRVRBDState *s = bs->opaque;
int r;
+ if (bdrv_key_required(bs)) {
+ return -EPERM;
+ }
r = rbd_resize(s->image, offset);
if (r < 0) {
@@ -758,11 +808,22 @@ static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset)
return 0;
}
+static int qemu_rbd_set_key(BlockDriverState *bs, const char *key)
+{
+ if (bs->valid_key) {
+ return 0;
+ }
+ return qemu_rbd_finish_open(bs->opaque, key);
+}
+
static int qemu_rbd_snap_create(BlockDriverState *bs,
QEMUSnapshotInfo *sn_info)
{
BDRVRBDState *s = bs->opaque;
int r;
+ if (bdrv_key_required(bs)) {
+ return -EPERM;
+ }
if (sn_info->name[0] == '\0') {
return -EINVAL; /* we need a name for rbd snapshots */
@@ -799,6 +860,10 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
rbd_snap_info_t *snaps;
int max_snaps = RBD_MAX_SNAPS;
+ if (bdrv_key_required(bs)) {
+ return -EPERM;
+ }
+
do {
snaps = g_malloc(sizeof(*snaps) * max_snaps);
snap_count = rbd_snap_list(s->image, snaps, &max_snaps);
@@ -856,6 +921,7 @@ static BlockDriver bdrv_rbd = {
.create_options = qemu_rbd_create_options,
.bdrv_getlength = qemu_rbd_getlength,
.bdrv_truncate = qemu_rbd_truncate,
+ .bdrv_set_key = qemu_rbd_set_key,
.protocol_name = "rbd",
.bdrv_aio_readv = qemu_rbd_aio_readv,
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-11-10 0:21 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-10 0:20 [Qemu-devel] [RFC 0/2] rbd authentication Josh Durgin
2011-11-10 0:20 ` [Qemu-devel] [RFC 1/2] block: let bdrv_set_key be used for authentication Josh Durgin
2011-11-10 0:20 ` [Qemu-devel] [RFC 2/2] rbd: implement bdrv_set_key Josh Durgin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).