diff --git a/.gitignore b/.gitignore index da388019..1898a58d 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,7 @@ /src/datapagemap.h /src/logging.h /src/receivelog.c -/src/receivelog.h +/src/receivelog.hщщ /src/streamutil.c /src/streamutil.h /src/xlogreader.c diff --git a/src/backup.c b/src/backup.c index 9ef93fb9..9593e6ab 100644 --- a/src/backup.c +++ b/src/backup.c @@ -943,6 +943,16 @@ do_backup(time_t start_time) //elog(LOG, "Backup completed. Total bytes : " INT64_FORMAT "", // current.data_bytes); + if (is_remote_agent) + fio_transfer(¤t.start_time,current.start_time); + else + complete_backup(); + + return 0; +} + +void complete_backup(void) +{ pgBackupValidate(¤t); elog(INFO, "Backup %s completed", base36enc(current.start_time)); @@ -953,8 +963,6 @@ do_backup(time_t start_time) */ if (delete_expired || delete_wal) do_retention_purge(); - - return 0; } /* @@ -1529,13 +1537,13 @@ wait_wal_lsn(XLogRecPtr lsn, bool is_start_lsn, bool wait_prev_segment) { if (!file_exists) { - file_exists = fileExists(wal_segment_path); + file_exists = fileExists(wal_segment_path, is_start_lsn ? FIO_DB_HOST : FIO_BACKUP_HOST); /* Try to find compressed WAL file */ if (!file_exists) { #ifdef HAVE_LIBZ - file_exists = fileExists(gz_wal_segment_path); + file_exists = fileExists(gz_wal_segment_path, is_start_lsn ? FIO_DB_HOST : FIO_BACKUP_HOST); if (file_exists) elog(LOG, "Found compressed WAL segment: %s", wal_segment_path); #endif @@ -1822,7 +1830,6 @@ pg_stop_backup(pgBackup *backup) PQerrorMessage(conn), stop_backup_query); } elog(INFO, "pg_stop backup() successfully executed"); - sleep(20); } backup_in_progress = false; @@ -2155,7 +2162,7 @@ backup_files(void *arg) skip = true; /* ...skip copying file. */ } if (skip || - !copy_file(arguments->from_root, arguments->to_root, file)) + !copy_file(arguments->from_root, arguments->to_root, file, FIO_BACKUP_HOST)) { file->write_size = BYTES_INVALID; elog(VERBOSE, "File \"%s\" was not copied to backup", diff --git a/src/data.c b/src/data.c index 87db7047..eb2230b6 100644 --- a/src/data.c +++ b/src/data.c @@ -769,13 +769,8 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, */ if (allow_truncate && file->n_blocks != BLOCKNUM_INVALID && !need_truncate) { - size_t file_size = 0; - - /* get file current size */ - fio_fseek(out, 0); - file_size = ftell(out); - - if (file_size > file->n_blocks * BLCKSZ) + struct stat st; + if (fio_ffstat(out, &st) == 0 && st.st_size > file->n_blocks * BLCKSZ) { truncate_from = file->n_blocks; need_truncate = true; @@ -824,7 +819,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, * it is either small control file or already compressed cfs file. */ bool -copy_file(const char *from_root, const char *to_root, pgFile *file) +copy_file(const char *from_root, const char *to_root, pgFile *file, fio_location location) { char to_path[MAXPGPATH]; FILE *in; @@ -858,7 +853,7 @@ copy_file(const char *from_root, const char *to_root, pgFile *file) /* open backup file for write */ join_path_components(to_path, to_root, file->path + strlen(from_root) + 1); - out = fio_fopen(to_path, PG_BINARY_W, FIO_BACKUP_HOST); + out = fio_fopen(to_path, PG_BINARY_W, location); if (out == NULL) { int errno_tmp = errno; @@ -932,7 +927,7 @@ copy_file(const char *from_root, const char *to_root, pgFile *file) file->crc = crc; /* update file permission */ - if (fio_chmod(to_path, st.st_mode, FIO_BACKUP_HOST) == -1) + if (fio_chmod(to_path, st.st_mode, location) == -1) { errno_tmp = errno; fclose(in); @@ -1039,7 +1034,7 @@ push_wal_file(const char *from_path, const char *to_path, bool is_compress, { snprintf(gz_to_path, sizeof(gz_to_path), "%s.gz", to_path); - if (!overwrite && fileExists(gz_to_path)) + if (!overwrite && fileExists(gz_to_path, FIO_BACKUP_HOST)) elog(ERROR, "WAL segment \"%s\" already exists.", gz_to_path); snprintf(to_path_temp, sizeof(to_path_temp), "%s.partial", gz_to_path); @@ -1054,7 +1049,7 @@ push_wal_file(const char *from_path, const char *to_path, bool is_compress, else #endif { - if (!overwrite && fileExists(to_path)) + if (!overwrite && fileExists(to_path, FIO_BACKUP_HOST)) elog(ERROR, "WAL segment \"%s\" already exists.", to_path); snprintf(to_path_temp, sizeof(to_path_temp), "%s.partial", to_path); @@ -1335,9 +1330,8 @@ get_wal_file(const char *from_path, const char *to_path) bool calc_file_checksum(pgFile *file) { - FILE *in; + int in; size_t read_len = 0; - int errno_tmp; char buf[BLCKSZ]; struct stat st; pg_crc32 crc; @@ -1350,8 +1344,8 @@ calc_file_checksum(pgFile *file) file->write_size = 0; /* open backup mode file for read */ - in = fopen(file->path, PG_BINARY_R); - if (in == NULL) + in = fio_open(file->path, O_RDONLY|PG_BINARY, FIO_BACKUP_HOST); + if (in < 0) { FIN_TRADITIONAL_CRC32(crc); file->crc = crc; @@ -1365,16 +1359,16 @@ calc_file_checksum(pgFile *file) } /* stat source file to change mode of destination file */ - if (fstat(fileno(in), &st) == -1) + if (fio_fstat(in, &st) == -1) { - fclose(in); + fio_close(in); elog(ERROR, "cannot stat \"%s\": %s", file->path, strerror(errno)); } for (;;) { - read_len = fread(buf, 1, sizeof(buf), in); + read_len = fio_read(in, buf, sizeof(buf)); if(read_len == 0) break; @@ -1386,19 +1380,11 @@ calc_file_checksum(pgFile *file) file->read_size += read_len; } - errno_tmp = errno; - if (!feof(in)) - { - fclose(in); - elog(ERROR, "cannot read backup mode file \"%s\": %s", - file->path, strerror(errno_tmp)); - } - /* finish CRC calculation and store into pgFile */ FIN_TRADITIONAL_CRC32(crc); file->crc = crc; - fclose(in); + fio_close(in); return true; } diff --git a/src/dir.c b/src/dir.c index ac4d096e..bf5ec27f 100644 --- a/src/dir.c +++ b/src/dir.c @@ -162,8 +162,8 @@ pgFileNew(const char *path, bool omit_symlink) struct stat st; pgFile *file; - /* stat the file */ - if ((omit_symlink ? stat(path, &st) : lstat(path, &st)) == -1) + /* stat the file */ + if (fio_stat(path, &st, omit_symlink, FIO_BACKUP_HOST) < 0) { /* file not found is not an error case */ if (errno == ENOENT) @@ -403,7 +403,7 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink, join_path_components(path, backup_instance_path, PG_BLACK_LIST); /* List files with black list */ - if (root && pgdata && strcmp(root, pgdata) == 0 && fileExists(path)) + if (root && pgdata && strcmp(root, pgdata) == 0 && fileExists(path, FIO_LOCAL_HOST)) { FILE *black_list_file = NULL; char buf[MAXPGPATH * 2]; @@ -935,7 +935,7 @@ create_data_directories(const char *data_dir, const char *backup_dir, size_t i; char backup_database_dir[MAXPGPATH], to_path[MAXPGPATH]; - + sleep(30); dirs = parray_new(); if (extract_tablespaces) { @@ -1088,7 +1088,7 @@ read_tablespace_map(parray *files, const char *backup_dir) join_path_components(map_path, db_path, PG_TABLESPACE_MAP_FILE); /* Exit if database/tablespace_map doesn't exist */ - if (!fileExists(map_path)) + if (!fileExists(map_path, FIO_LOCAL_HOST)) { elog(LOG, "there is no file tablespace_map"); return; @@ -1490,11 +1490,11 @@ dir_is_empty(const char *path) * Return true if the path is a existing regular file. */ bool -fileExists(const char *path) +fileExists(const char *path, fio_location location) { struct stat buf; - if (stat(path, &buf) == -1 && errno == ENOENT) + if (fio_stat(path, &buf, true, location) == -1 && errno == ENOENT) return false; else if (!S_ISREG(buf.st_mode)) return false; diff --git a/src/fetch.c b/src/fetch.c index 56194611..72ab2cbc 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -43,7 +43,7 @@ slurpFile(const char *datadir, const char *path, size_t *filesize, bool safe) fullpath, strerror(errno)); } - if (fio_stat(fd, &statbuf) < 0) + if (fio_fstat(fd, &statbuf) < 0) { if (safe) return NULL; diff --git a/src/merge.c b/src/merge.c index 2873eb5c..8ea5481c 100644 --- a/src/merge.c +++ b/src/merge.c @@ -448,7 +448,7 @@ merge_files(void *arg) /* * We need to decompress target file only if it exists. */ - if (fileExists(to_path_tmp)) + if (fileExists(to_path_tmp, FIO_LOCAL_HOST)) { /* * file->path points to the file in from_root directory. But we diff --git a/src/parsexlog.c b/src/parsexlog.c index 29b98d86..0eb4d1fb 100644 --- a/src/parsexlog.c +++ b/src/parsexlog.c @@ -86,22 +86,22 @@ static bool getRecordTimestamp(XLogReaderState *record, TimestampTz *recordXtime typedef struct XLogPageReadPrivate { - int thread_num; - const char *archivedir; - TimeLineID tli; - uint32 xlog_seg_size; + int thread_num; + const char *archivedir; + TimeLineID tli; + uint32 xlog_seg_size; - bool manual_switch; - bool need_switch; - - int xlogfile; - XLogSegNo xlogsegno; - char xlogpath[MAXPGPATH]; - bool xlogexists; + bool manual_switch; + bool need_switch; + int xlogfile; + XLogSegNo xlogsegno; + char xlogpath[MAXPGPATH]; + bool xlogexists; + fio_location location; #ifdef HAVE_LIBZ - gzFile gz_xlogfile; - char gz_xlogpath[MAXPGPATH]; + gzFile gz_xlogfile; + char gz_xlogpath[MAXPGPATH]; #endif } XLogPageReadPrivate; @@ -853,7 +853,7 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, snprintf(private_data->xlogpath, MAXPGPATH, "%s/%s", private_data->archivedir, xlogfname); - if (fileExists(private_data->xlogpath)) + if (fileExists(private_data->xlogpath, private_data->location)) { elog(LOG, "Thread [%d]: Opening WAL segment \"%s\"", private_data->thread_num, @@ -861,7 +861,7 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, private_data->xlogexists = true; private_data->xlogfile = fio_open(private_data->xlogpath, - O_RDONLY | PG_BINARY, FIO_DB_HOST); + O_RDONLY | PG_BINARY, private_data->location); if (private_data->xlogfile < 0) { @@ -879,7 +879,7 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, snprintf(private_data->gz_xlogpath, sizeof(private_data->gz_xlogpath), "%s.gz", private_data->xlogpath); - if (fileExists(private_data->gz_xlogpath)) + if (fileExists(private_data->gz_xlogpath, private_data->location)) { elog(LOG, "Thread [%d]: Opening compressed WAL segment \"%s\"", private_data->thread_num, private_data->gz_xlogpath); @@ -965,6 +965,7 @@ InitXLogPageRead(XLogPageReadPrivate *private_data, const char *archivedir, private_data->tli = tli; private_data->xlog_seg_size = xlog_seg_size; private_data->xlogfile = -1; + private_data->location = FIO_BACKUP_HOST; if (allocate_reader) { diff --git a/src/pg_probackup.c b/src/pg_probackup.c index 124625c7..e0e1955b 100644 --- a/src/pg_probackup.c +++ b/src/pg_probackup.c @@ -389,7 +389,11 @@ main(int argc, char *argv[]) fio_redirect(STDIN_FILENO, STDOUT_FILENO); } else { /* Execute remote probackup */ - remote_execute(argc, argv, backup_subcmd == BACKUP_CMD); + int status = remote_execute(argc, argv, backup_subcmd == BACKUP_CMD); + if (status != 0) + { + return status; + } } } @@ -537,13 +541,22 @@ main(int argc, char *argv[]) case INIT_CMD: return do_init(); case BACKUP_CMD: + current.stream = stream_wal; + if (ssh_host && !is_remote_agent) + { + current.status = BACKUP_STATUS_DONE; + StrNCpy(current.program_version, PROGRAM_VERSION, + sizeof(current.program_version)); + complete_backup(); + return 0; + } + else { const char *backup_mode; time_t start_time; start_time = time(NULL); backup_mode = deparse_backup_mode(current.backup_mode); - current.stream = stream_wal; elog(INFO, "Backup start, pg_probackup version: %s, backup ID: %s, backup mode: %s, instance: %s, stream: %s, remote: %s", PROGRAM_VERSION, base36enc(start_time), backup_mode, instance_name, diff --git a/src/pg_probackup.h b/src/pg_probackup.h index a3e76b95..b4bd8edf 100644 --- a/src/pg_probackup.h +++ b/src/pg_probackup.h @@ -378,6 +378,7 @@ extern const char *pgdata_exclude_dir[]; /* in backup.c */ extern int do_backup(time_t start_time); +extern void complete_backup(void); extern BackupMode parse_backup_mode(const char *value); extern const char *deparse_backup_mode(BackupMode mode); extern void process_block_change(ForkNumber forknum, RelFileNode rnode, @@ -475,7 +476,7 @@ extern pgBackup* find_parent_full_backup(pgBackup *current_backup); extern int scan_parent_chain(pgBackup *current_backup, pgBackup **result_backup); extern bool is_parent(time_t parent_backup_time, pgBackup *child_backup, bool inclusive); extern int get_backup_index_number(parray *backup_list, pgBackup *backup); -extern void remote_execute(int argc, char *argv[], bool do_backup); +extern int remote_execute(int argc, char *argv[], bool do_backup); #define COMPRESS_ALG_DEFAULT NOT_DEFINED_COMPRESS #define COMPRESS_LEVEL_DEFAULT 1 @@ -501,7 +502,7 @@ extern parray *dir_read_file_list(const char *root, const char *file_txt); extern int dir_create_dir(const char *path, mode_t mode); extern bool dir_is_empty(const char *path); -extern bool fileExists(const char *path); +extern bool fileExists(const char *path, fio_location location); extern size_t pgFileSize(const char *path); extern pgFile *pgFileNew(const char *path, bool omit_symlink); @@ -523,7 +524,7 @@ extern bool backup_data_file(backup_files_arg* arguments, extern void restore_data_file(const char *to_path, pgFile *file, bool allow_truncate, bool write_header); -extern bool copy_file(const char *from_root, const char *to_root, pgFile *file); +extern bool copy_file(const char *from_root, const char *to_root, pgFile *file, fio_location location); extern void move_file(const char *from_root, const char *to_root, pgFile *file); extern void push_wal_file(const char *from_path, const char *to_path, bool is_compress, bool overwrite); diff --git a/src/restore.c b/src/restore.c index f798675b..2cf291d8 100644 --- a/src/restore.c +++ b/src/restore.c @@ -587,14 +587,14 @@ restore_files(void *arg) (arguments->backup->backup_mode == BACKUP_MODE_DIFF_PAGE || arguments->backup->backup_mode == BACKUP_MODE_DIFF_PTRACK)) { - elog(VERBOSE, "The file didn`t change. Skip restore: %s", file->path); + elog(INFO, "The file didn`t change. Skip restore: %s", file->path); continue; } /* Directories were created before */ if (S_ISDIR(file->mode)) { - elog(VERBOSE, "directory, skip"); + elog(INFO, "directory, skip"); continue; } @@ -611,7 +611,7 @@ restore_files(void *arg) * block and have BackupPageHeader meta information, so we cannot just * copy the file from backup. */ - elog(VERBOSE, "Restoring file %s, is_datafile %i, is_cfs %i", + elog(INFO, "Restoring file %s, is_datafile %i, is_cfs %i", file->path, file->is_datafile?1:0, file->is_cfs?1:0); if (file->is_datafile && !file->is_cfs) { @@ -624,7 +624,7 @@ restore_files(void *arg) false); } else - copy_file(from_root, pgdata, file); + copy_file(from_root, pgdata, file, FIO_DB_HOST); /* print size of restored file */ if (file->write_size != BYTES_INVALID) diff --git a/src/utils/file.c b/src/utils/file.c index b562fc13..cbbd0aa3 100644 --- a/src/utils/file.c +++ b/src/utils/file.c @@ -377,13 +377,20 @@ ssize_t fio_read(int fd, void* buf, size_t size) } } -int fio_stat(int fd, struct stat* st) +int fio_ffstat(FILE* f, struct stat* st) +{ + return fio_is_remote_file(f) + ? fio_fstat(fio_fileno(f), st) + : fio_fstat(fileno(f), st); +} + +int fio_fstat(int fd, struct stat* st) { if (fio_is_remote_fd(fd)) { fio_header hdr; - hdr.cop = FIO_STAT; + hdr.cop = FIO_FSTAT; hdr.handle = fd & ~FIO_PIPE_MARKER; hdr.size = 0; @@ -394,6 +401,40 @@ int fio_stat(int fd, struct stat* st) SYS_CHECK(pthread_mutex_unlock(&fio_write_mutex)); + IO_CHECK(fio_read_all(fio_stdin, &hdr, sizeof(hdr)), sizeof(hdr)); + Assert(hdr.cop == FIO_FSTAT); + IO_CHECK(fio_read_all(fio_stdin, st, sizeof(*st)), sizeof(*st)); + + SYS_CHECK(pthread_mutex_unlock(&fio_read_mutex)); + + return hdr.arg; + } + else + { + return fstat(fd, st); + } +} + +int fio_stat(char const* path, struct stat* st, bool follow_symlinks, fio_location location) +{ + if (fio_is_remote(location)) + { + fio_header hdr; + size_t path_len = strlen(path) + 1; + + hdr.cop = FIO_STAT; + hdr.handle = -1; + hdr.arg = follow_symlinks; + hdr.size = path_len; + + SYS_CHECK(pthread_mutex_lock(&fio_read_mutex)); + SYS_CHECK(pthread_mutex_lock(&fio_write_mutex)); + + IO_CHECK(fio_write_all(fio_stdout, &hdr, sizeof(hdr)), sizeof(hdr)); + IO_CHECK(fio_write_all(fio_stdout, path, path_len), path_len); + + SYS_CHECK(pthread_mutex_unlock(&fio_write_mutex)); + IO_CHECK(fio_read_all(fio_stdin, &hdr, sizeof(hdr)), sizeof(hdr)); Assert(hdr.cop == FIO_STAT); IO_CHECK(fio_read_all(fio_stdin, st, sizeof(*st)), sizeof(*st)); @@ -404,7 +445,7 @@ int fio_stat(int fd, struct stat* st) } else { - return fstat(fd, st); + return follow_symlinks ? stat(path, st) : lstat(path, st); } } @@ -566,12 +607,32 @@ static void fio_send_file(int out, char const* path) } } +void fio_transfer(void* addr, size_t value) +{ + struct { + fio_header hdr; + fio_binding bind; + } msg; + + msg.hdr.cop = FIO_TRANSFER; + msg.hdr.size = sizeof(fio_binding); + msg.bind.address = (size_t*)addr; + msg.bind.value = value; + + SYS_CHECK(pthread_mutex_lock(&fio_write_mutex)); + + IO_CHECK(fio_write_all(fio_stdout, &msg, sizeof(msg)), sizeof(msg)); + + SYS_CHECK(pthread_mutex_unlock(&fio_write_mutex)); +} + void fio_communicate(int in, int out) { int fd[FIO_FDMAX]; size_t buf_size = 128*1024; char* buf = (char*)malloc(buf_size); fio_header hdr; + struct stat st; int rc; while ((rc = fio_read_all(in, &hdr, sizeof hdr)) == sizeof(hdr)) { @@ -606,15 +667,18 @@ void fio_communicate(int in, int out) IO_CHECK(fio_write_all(out, &hdr, sizeof(hdr)), sizeof(hdr)); IO_CHECK(fio_write_all(out, buf, rc), rc); break; + case FIO_FSTAT: + hdr.size = sizeof(st); + hdr.arg = fstat(fd[hdr.handle], &st); + IO_CHECK(fio_write_all(out, &hdr, sizeof(hdr)), sizeof(hdr)); + IO_CHECK(fio_write_all(out, &st, sizeof(st)), sizeof(st)); + break; case FIO_STAT: - { - struct stat st; - hdr.size = sizeof(st); - hdr.arg = fstat(fd[hdr.handle], &st); - IO_CHECK(fio_write_all(out, &hdr, sizeof(hdr)), sizeof(hdr)); - IO_CHECK(fio_write_all(out, &st, sizeof(st)), sizeof(st)); - break; - } + hdr.size = sizeof(st); + hdr.arg = hdr.arg ? stat(buf, &st) : lstat(buf, &st); + IO_CHECK(fio_write_all(out, &hdr, sizeof(hdr)), sizeof(hdr)); + IO_CHECK(fio_write_all(out, &st, sizeof(st)), sizeof(st)); + break; case FIO_ACCESS: hdr.size = 0; hdr.arg = access(buf, hdr.arg); @@ -638,6 +702,9 @@ void fio_communicate(int in, int out) case FIO_TRUNCATE: SYS_CHECK(ftruncate(fd[hdr.handle], hdr.arg)); break; + case FIO_TRANSFER: + *((fio_binding*)buf)->address = ((fio_binding*)buf)->value; + break; default: Assert(false); } diff --git a/src/utils/file.h b/src/utils/file.h index 3b7cc112..123167a7 100644 --- a/src/utils/file.h +++ b/src/utils/file.h @@ -17,12 +17,15 @@ typedef enum FIO_READ, FIO_LOAD, FIO_STAT, + FIO_FSTAT, FIO_SEND, - FIO_ACCESS + FIO_ACCESS, + FIO_TRANSFER } fio_operations; typedef enum { + FIO_LOCAL_HOST, FIO_DB_HOST, FIO_BACKUP_HOST } fio_location; @@ -33,13 +36,20 @@ typedef enum #define SYS_CHECK(cmd) do if ((cmd) < 0) { perror(#cmd); exit(EXIT_FAILURE); } while (0) #define IO_CHECK(cmd, size) do { int _rc = (cmd); if (_rc != (size)) { fprintf(stderr, "%s:%d: proceeds %d bytes instead of %d\n", __FILE__, __LINE__, _rc, (int)(size)); exit(EXIT_FAILURE); } } while (0) -typedef struct { +typedef struct +{ unsigned cop : 4; unsigned handle : 8; unsigned size : 20; unsigned arg; } fio_header; +typedef struct +{ + size_t* address; + size_t value; +} fio_binding; + extern void fio_redirect(int in, int out); extern void fio_communicate(int in, int out); @@ -51,13 +61,14 @@ extern int fio_fflush(FILE* f); extern int fio_fseek(FILE* f, off_t offs); extern int fio_ftruncate(FILE* f, off_t size); extern int fio_fclose(FILE* f); +extern int fio_ffstat(FILE* f, struct stat* st); extern int fio_open(char const* name, int mode, fio_location location); extern ssize_t fio_write(int fd, void const* buf, size_t size); extern ssize_t fio_read(int fd, void* buf, size_t size); extern int fio_flush(int fd); extern int fio_seek(int fd, off_t offs); -extern int fio_stat(int fd, struct stat* st); +extern int fio_fstat(int fd, struct stat* st); extern int fio_truncate(int fd, off_t size); extern int fio_close(int fd); @@ -66,9 +77,12 @@ extern int fio_unlink(char const* path, fio_location location); extern int fio_mkdir(char const* path, int mode, fio_location location); extern int fio_chmod(char const* path, int mode, fio_location location); extern int fio_access(char const* path, int mode, fio_location location); +extern int fio_stat(char const* path, struct stat* st, bool follow_symlinks, fio_location location); -extern FILE* fio_open_stream(char const* name, fio_location location); -extern int fio_close_stream(FILE* f); +extern FILE* fio_open_stream(char const* name, fio_location location); +extern int fio_close_stream(FILE* f); + +extern void fio_transfer(void* addr, size_t value); #endif diff --git a/src/utils/remote.c b/src/utils/remote.c index f7b3f4c5..2dd6cfe1 100644 --- a/src/utils/remote.c +++ b/src/utils/remote.c @@ -21,7 +21,7 @@ static int append_option(char* buf, size_t buf_size, size_t dst, char const* src return dst + len + 1; } -void remote_execute(int argc, char* argv[], bool listen) +int remote_execute(int argc, char* argv[], bool listen) { char cmd[MAX_CMDLINE_LENGTH]; size_t dst = 0; @@ -66,6 +66,7 @@ void remote_execute(int argc, char* argv[], bool listen) SYS_CHECK(close(outfd[1])); SYS_CHECK(execvp(ssh_argv[0], ssh_argv)); + return -1; } else { SYS_CHECK(close(outfd[0])); /* These are being used by the child */ SYS_CHECK(close(infd[1])); @@ -74,9 +75,10 @@ void remote_execute(int argc, char* argv[], bool listen) int status; fio_communicate(infd[0], outfd[1]); SYS_CHECK(wait(&status)); - exit(status); + return status; } else { fio_redirect(infd[0], outfd[1]); /* write to stdout */ + return 0; } } } diff --git a/src/walmethods.c b/src/walmethods.c index d384b99f..a179945f 100644 --- a/src/walmethods.c +++ b/src/walmethods.c @@ -305,23 +305,14 @@ dir_get_file_size(const char *pathname) { struct stat statbuf; static char tmppath[MAXPGPATH]; - int fd; snprintf(tmppath, sizeof(tmppath), "%s/%s", dir_data->basedir, pathname); - fd = fio_open(tmppath, O_RDONLY|PG_BINARY, FIO_BACKUP_HOST); - if (fd >= 0) - { - if (fio_stat(fd, &statbuf) != 0) - { - fio_close(fd); - return -1; - } - fio_close(fd); - return statbuf.st_size; - } - return -1; + if (fio_stat(tmppath, &statbuf, true, FIO_BACKUP_HOST) != 0) + return -1; + + return statbuf.st_size; } static bool