[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC V8 11/13] quorum: Add quorum_snapshot_img_create.
From: |
Benoît Canet |
Subject: |
[Qemu-devel] [RFC V8 11/13] quorum: Add quorum_snapshot_img_create. |
Date: |
Mon, 28 Jan 2013 18:07:23 +0100 |
Signed-off-by: Benoit Canet <address@hidden>
---
block/quorum.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 188 insertions(+)
diff --git a/block/quorum.c b/block/quorum.c
index 306a2df..cc02c5f 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -609,6 +609,192 @@ static coroutine_fn int quorum_co_flush(BlockDriverState
*bs)
return result;
}
+static int quorum_parse_uint_step_next(const char *start,
+ const char *name,
+ const char separator,
+ unsigned long long *value,
+ char **next,
+ Error **errp)
+{
+ int ret;
+ if (start[0] == '\0') {
+ error_set(errp, QERR_MISSING_PARAMETER, name);
+ return -EINVAL;
+ }
+ ret = parse_uint(start, value, next, 10);
+ if (ret < 0) {
+ error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
+ return ret;
+ }
+ if (**next != separator) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "%c separator required after %s",
+ separator, name);
+ return -EINVAL;
+ }
+ *next += 1;
+ return 0;
+}
+
+static int quorum_parse_url(BDRVQuorumState *s, const char *url, Error **errp)
+{
+ int i, j, k, len, ret = 0;
+ char *a, *b, *names;
+ const char *start;
+ bool escape;
+
+ /* Parse the quorum: prefix */
+ if (!strstart(url, "quorum:", &start)) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "Invalid quorum url");
+ return -EINVAL;
+ }
+
+ /* Get threshold */
+ ret = quorum_parse_uint_step_next(start, "threshold", '/',
+ &s->threshold, &a, errp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* Get total */
+ ret = quorum_parse_uint_step_next(a, "total", ':',
+ &s->total, &b, errp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (s->threshold < 1) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+ "threshold", "value >= 1");
+ return -ERANGE;
+ }
+
+ if (s->total < 2) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, "total", "value >= 2");
+ return -ERANGE;
+ }
+
+ if (s->threshold > s->total) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "threshold <= total must be true");
+ return -ERANGE;
+ }
+
+ s->bs = g_malloc0(sizeof(BlockDriverState *) * s->total);
+ /* Two allocations for all filenames: simpler to free */
+ s->filenames = g_malloc0(sizeof(char *) * s->total);
+ names = g_strdup(b);
+
+ /* Get the filenames pointers */
+ escape = false;
+ s->filenames[0] = names;
+ len = strlen(names);
+ for (i = j = k = 0; i < len && j < s->total; i++) {
+ /* separation between two files */
+ if (!escape && names[i] == ':') {
+ char *prev = s->filenames[j];
+ prev[k] = '\0';
+ s->filenames[++j] = prev + k + 1;
+ k = 0;
+ continue;
+ }
+
+ escape = !escape && names[i] == '\\';
+
+ /* if we are not escaping copy */
+ if (!escape) {
+ s->filenames[j][k++] = names[i];
+ }
+ }
+ /* terminate last string */
+ s->filenames[j][k] = '\0';
+
+ return j + 1;
+}
+
+static int quorum_validate_url(BDRVQuorumState *s, int ret, Error **errp)
+{
+ if (ret == s->total) {
+ return 0;
+ }
+
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "Number of provided file must be equal to total");
+ return -EINVAL;
+}
+
+static void quorum_free(BDRVQuorumState *s)
+{
+ g_free(s->filenames[0]);
+ g_free(s->filenames);
+ s->filenames = NULL;
+ g_free(s->bs);
+}
+
+static bool quorum_are_states_compatibles(BDRVQuorumState *a,
+ BDRVQuorumState *b,
+ Error **errp)
+{
+ if (a->threshold != b->threshold) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "Theshold must be the same as previously");
+ return false;
+ }
+
+ if (a->total != b->total) {
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+ "Total must be the same as previously");
+ return false;
+ }
+
+ return true;
+
+}
+
+static void quorum_snapshot_img_create(BlockDriverState *bs,
+ const char *filename, const char *fmt,
+ const char *base_filename,
+ const char *base_fmt,
+ char *options, uint64_t img_size,
+ int flags, Error **errp)
+{
+ BDRVQuorumState *s = bs->file->opaque;
+ int i;
+ int ret = 0;
+ bool compatible;
+ BDRVQuorumState new_s;
+
+ memset(&new_s, 0, sizeof(BDRVQuorumState));
+
+ ret = quorum_parse_url(&new_s, filename, errp);
+ if (ret < 0) {
+ return;
+ }
+
+ ret = quorum_validate_url(&new_s, ret, errp);
+ if (ret < 0) {
+ goto free_new_s_exit;
+ }
+
+ compatible = quorum_are_states_compatibles(s, &new_s, errp);
+ if (!compatible) {
+ goto free_new_s_exit;
+ }
+
+ for (i = 0; i < new_s.total; i++) {
+ bdrv_img_create(new_s.filenames[i], fmt,
+ s->filenames[i], s->bs[i]->drv->format_name,
+ options, img_size, flags, errp);
+ if (error_is_set(errp)) {
+ break;
+ }
+ }
+
+free_new_s_exit:
+ quorum_free(&new_s);
+}
+
static BlockDriver bdrv_quorum = {
.format_name = "quorum",
.protocol_name = "quorum",
@@ -623,6 +809,8 @@ static BlockDriver bdrv_quorum = {
.bdrv_aio_writev = quorum_aio_writev,
.bdrv_invalidate_cache = quorum_invalidate_cache,
.bdrv_co_is_allocated = quorum_co_is_allocated,
+
+ .bdrv_ext_snapshot_img_create = quorum_snapshot_img_create,
};
static void bdrv_quorum_init(void)
--
1.7.10.4
- [Qemu-devel] [RFC V8 00/13] Quorum block filter., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 02/13] quorum: Create BDRVQuorumState and BlkDriver and do init., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 01/13] quorum: Create quorum .c, add QuorumSingleAIOCB and QuorumAIOCB., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 03/13] quorum: Add quorum_aio_writev and its dependencies., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 05/13] quorum: Add quorum_aio_readv., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 04/13] blkverify: Extract qemu_iovec_clone() and qemu_iovec_compare() from blkverify., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 06/13] quorum: Add quorum mechanism., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 09/13] quorum: Add quorum_co_is_allocated., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 08/13] quorum: Add quorum_invalidate_cache()., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 10/13] quorum: Add quorum_co_flush()., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 11/13] quorum: Add quorum_snapshot_img_create.,
Benoît Canet <=
- [Qemu-devel] [RFC V8 07/13] quorum: Add quorum_getlength()., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 12/13] quorum: Add quorum_snapshot_reopen., Benoît Canet, 2013/01/28
- [Qemu-devel] [RFC V8 13/13] quorum: Add quorum_open() and quorum_close()., Benoît Canet, 2013/01/28