free(o->profile);
free(o->cgroup);
+ free(o->verify_pattern);
+ free(o->buffer_pattern);
+
for (i = 0; i < DDIR_RWDIR_CNT; i++) {
free(o->bssplit[i]);
free(o->zone_split[i]);
thread_options_pack_size(o) > top_sz)
return -EINVAL;
+ o->verify_pattern = realloc(o->verify_pattern,
+ o->verify_pattern_bytes);
+ o->buffer_pattern = realloc(o->buffer_pattern,
+ o->buffer_pattern_bytes);
memcpy(o->verify_pattern, top->patterns, o->verify_pattern_bytes);
memcpy(o->buffer_pattern, &top->patterns[o->verify_pattern_bytes],
o->buffer_pattern_bytes);
int ret;
o1.verify_pattern_bytes = 61;
+ o1.verify_pattern = malloc(o1.verify_pattern_bytes);
memset(o1.verify_pattern, 'V', o1.verify_pattern_bytes);
o1.buffer_pattern_bytes = 15;
+ o1.buffer_pattern = malloc(o1.buffer_pattern_bytes);
memset(o1.buffer_pattern, 'B', o1.buffer_pattern_bytes);
top_sz = thread_options_pack_size(&o1);
free_thread_options_to_cpu(&o2);
free(top2);
free(top1);
+ free(o1.buffer_pattern);
+ free(o1.verify_pattern);
return ret;
}
*
* Returns number of bytes filled or err < 0 in case of failure.
*/
-int parse_and_fill_pattern(const char *in, unsigned int in_len,
- char *out, unsigned int out_len,
- const struct pattern_fmt_desc *fmt_desc,
- struct pattern_fmt *fmt,
- unsigned int *fmt_sz_out)
+static int parse_and_fill_pattern(const char *in, unsigned int in_len,
+ char *out, unsigned int out_len,
+ const struct pattern_fmt_desc *fmt_desc,
+ struct pattern_fmt *fmt,
+ unsigned int *fmt_sz_out)
{
const char *beg, *end, *out_beg = out;
unsigned int total = 0, fmt_rem = 0;
return total;
}
+/**
+ * parse_and_fill_pattern_alloc() - Parses combined input, which consists of
+ * strings, numbers and pattern formats and
+ * allocates a buffer for the result.
+ *
+ * @in - string input
+ * @in_len - size of the input string
+ * @out - pointer to the output buffer pointer, this will be set to the newly
+ * allocated pattern buffer which must be freed by the caller
+ * @fmt_desc - array of pattern format descriptors [input]
+ * @fmt - array of pattern formats [output]
+ * @fmt_sz - pointer where the size of pattern formats array stored [input],
+ * after successful parsing this pointer will contain the number
+ * of parsed formats if any [output].
+ *
+ * See documentation on parse_and_fill_pattern() above for a description
+ * of the functionality.
+ *
+ * Returns number of bytes filled or err < 0 in case of failure.
+ */
+int parse_and_fill_pattern_alloc(const char *in, unsigned int in_len,
+ char **out, const struct pattern_fmt_desc *fmt_desc,
+ struct pattern_fmt *fmt, unsigned int *fmt_sz_out)
+{
+ int count;
+
+ count = parse_and_fill_pattern(in, in_len, NULL, MAX_PATTERN_SIZE,
+ fmt_desc, fmt, fmt_sz_out);
+ if (count < 0)
+ return count;
+
+ *out = malloc(count);
+ count = parse_and_fill_pattern(in, in_len, *out, count, fmt_desc,
+ fmt, fmt_sz_out);
+ if (count < 0) {
+ free(*out);
+ *out = NULL;
+ }
+
+ return count;
+}
+
/**
* dup_pattern() - Duplicates part of the pattern all over the buffer.
*
#ifndef FIO_PARSE_PATTERN_H
#define FIO_PARSE_PATTERN_H
+/*
+ * The pattern is dynamically allocated, but that doesn't mean there
+ * are not limits. The network protocol has a limit of
+ * FIO_SERVER_MAX_CMD_MB and potentially two patterns must fit in there.
+ * There's also a need to verify the incoming data from the network and
+ * this provides a sensible check.
+ *
+ * 128MiB is an arbitrary limit that meets these criteria. The patterns
+ * tend to be truncated at the IO size anyway and IO sizes that large
+ * aren't terribly practical.
+ */
+#define MAX_PATTERN_SIZE (128 << 20)
+
/**
* Pattern format description. The input for 'parse_pattern'.
* Describes format with its name and callback, which should
const struct pattern_fmt_desc *desc;
};
-int parse_and_fill_pattern(const char *in, unsigned int in_len,
- char *out, unsigned int out_len,
- const struct pattern_fmt_desc *fmt_desc,
- struct pattern_fmt *fmt,
- unsigned int *fmt_sz_out);
+int parse_and_fill_pattern_alloc(const char *in, unsigned int in_len,
+ char **out, const struct pattern_fmt_desc *fmt_desc,
+ struct pattern_fmt *fmt, unsigned int *fmt_sz_out);
int paste_format_inplace(char *pattern, unsigned int pattern_len,
struct pattern_fmt *fmt, unsigned int fmt_sz,
int ret;
/* FIXME: for now buffer pattern does not support formats */
- ret = parse_and_fill_pattern(input, strlen(input), td->o.buffer_pattern,
- MAX_PATTERN_SIZE, NULL, NULL, NULL);
+ ret = parse_and_fill_pattern_alloc(input, strlen(input),
+ &td->o.buffer_pattern, NULL, NULL, NULL);
if (ret < 0)
return 1;
int ret;
td->o.verify_fmt_sz = FIO_ARRAY_SIZE(td->o.verify_fmt);
- ret = parse_and_fill_pattern(input, strlen(input), td->o.verify_pattern,
- MAX_PATTERN_SIZE, fmt_desc,
- td->o.verify_fmt, &td->o.verify_fmt_sz);
+ ret = parse_and_fill_pattern_alloc(input, strlen(input),
+ &td->o.verify_pattern, fmt_desc, td->o.verify_fmt,
+ &td->o.verify_fmt_sz);
if (ret < 0)
return 1;
BLOCK_STATE_COUNT,
};
-#define MAX_PATTERN_SIZE 512
#define FIO_JOBNAME_SIZE 128
#define FIO_JOBDESC_SIZE 256
#define FIO_VERROR_SIZE 128
unsigned int do_verify;
unsigned int verify_interval;
unsigned int verify_offset;
- char verify_pattern[MAX_PATTERN_SIZE];
+ char *verify_pattern;
unsigned int verify_pattern_bytes;
struct pattern_fmt verify_fmt[8];
unsigned int verify_fmt_sz;
unsigned int zero_buffers;
unsigned int refill_buffers;
unsigned int scramble_buffers;
- char buffer_pattern[MAX_PATTERN_SIZE];
+ char *buffer_pattern;
unsigned int buffer_pattern_bytes;
unsigned int compress_percentage;
unsigned int compress_chunk;