summaryrefslogtreecommitdiffstats
path: root/extra/mariabackup/xbstream.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--extra/mariabackup/xbstream.cc64
1 files changed, 59 insertions, 5 deletions
diff --git a/extra/mariabackup/xbstream.cc b/extra/mariabackup/xbstream.cc
index 6306806b..d69a0029 100644
--- a/extra/mariabackup/xbstream.cc
+++ b/extra/mariabackup/xbstream.cc
@@ -262,7 +262,7 @@ mode_create(int argc, char **argv)
return 1;
}
- stream = xb_stream_write_new();
+ stream = xb_stream_write_new(nullptr, nullptr);
if (stream == NULL) {
msg("%s: xb_stream_write_new() failed.", my_progname);
return 1;
@@ -287,7 +287,7 @@ mode_create(int argc, char **argv)
goto err;
}
- file = xb_stream_write_open(stream, filepath, &mystat, NULL, NULL);
+ file = xb_stream_write_open(stream, filepath, &mystat, false);
if (file == NULL) {
goto err;
}
@@ -314,7 +314,8 @@ err:
static
file_entry_t *
-file_entry_new(extract_ctxt_t *ctxt, const char *path, uint pathlen)
+file_entry_new(extract_ctxt_t *ctxt, const char *path, uint pathlen,
+ uchar chunk_flags)
{
file_entry_t *entry;
ds_file_t *file;
@@ -331,7 +332,8 @@ file_entry_new(extract_ctxt_t *ctxt, const char *path, uint pathlen)
}
entry->pathlen = pathlen;
- file = ds_open(ctxt->ds_ctxt, path, NULL);
+ file = ds_open(ctxt->ds_ctxt, path, NULL,
+ chunk_flags == XB_STREAM_FLAG_REWRITE);
if (file == NULL) {
msg("%s: failed to create file.", my_progname);
@@ -412,10 +414,50 @@ extract_worker_thread_func(void *arg)
(uchar *) chunk.path,
chunk.pathlen);
+ if (entry && (chunk.type == XB_CHUNK_TYPE_REMOVE ||
+ chunk.type == XB_CHUNK_TYPE_RENAME)) {
+ msg("%s: rename and remove chunks can not be applied to opened file: %s",
+ my_progname, chunk.path);
+ pthread_mutex_unlock(ctxt->mutex);
+ break;
+ }
+
+ if (chunk.type == XB_CHUNK_TYPE_REMOVE) {
+ if (ds_remove(ctxt->ds_ctxt, chunk.path)) {
+ msg("%s: error on file removing: %s", my_progname, chunk.path);
+ pthread_mutex_unlock(ctxt->mutex);
+ res = XB_STREAM_READ_ERROR;
+ break;
+ }
+ pthread_mutex_unlock(ctxt->mutex);
+ continue;
+ }
+
+ if (chunk.type == XB_CHUNK_TYPE_RENAME) {
+ if (my_hash_search(ctxt->filehash,
+ reinterpret_cast<const uchar *>(chunk.data), chunk.length)) {
+ msg("%s: rename chunks can not be applied to opened file: %s",
+ my_progname, reinterpret_cast<const uchar *>(chunk.data));
+ pthread_mutex_unlock(ctxt->mutex);
+ break;
+ }
+ if (ds_rename(ctxt->ds_ctxt, chunk.path,
+ reinterpret_cast<const char *>(chunk.data))) {
+ msg("%s: error on file renaming: %s to %s", my_progname,
+ reinterpret_cast<const char *>(chunk.data), chunk.path);
+ pthread_mutex_unlock(ctxt->mutex);
+ res = XB_STREAM_READ_ERROR;
+ break;
+ }
+ pthread_mutex_unlock(ctxt->mutex);
+ continue;
+ }
+
if (entry == NULL) {
entry = file_entry_new(ctxt,
chunk.path,
- chunk.pathlen);
+ chunk.pathlen,
+ chunk.flags);
if (entry == NULL) {
pthread_mutex_unlock(ctxt->mutex);
break;
@@ -432,6 +474,18 @@ extract_worker_thread_func(void *arg)
pthread_mutex_unlock(ctxt->mutex);
+ if (chunk.type == XB_CHUNK_TYPE_SEEK) {
+ if (ds_seek_set(entry->file, chunk.offset)) {
+ msg("%s: my_seek() failed.", my_progname);
+ pthread_mutex_unlock(&entry->mutex);
+ res = XB_STREAM_READ_ERROR;
+ break;
+ }
+ entry->offset = chunk.offset;
+ pthread_mutex_unlock(&entry->mutex);
+ continue;
+ }
+
res = xb_stream_validate_checksum(&chunk);
if (res != XB_STREAM_READ_CHUNK) {