8000 [PBCKP-236] draft, solution without couple of unapplied shortenings · postgrespro/pg_probackup@eefd887 · GitHub
[go: up one dir, main page]

Skip to content

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit eefd887

Browse files
author
Ivan Lazarev
committed
[PBCKP-236] draft, solution without couple of unapplied shortenings
1 parent 497751c commit eefd887

File tree

3 files changed

+99
-25
lines changed

3 files changed

+99
-25
lines changed

src/pg_probackup.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -882,8 +882,9 @@ extern DestDirIncrCompatibility check_incremental_compatibility(const char *pgda
882882
IncrRestoreMode incremental_mode);
883883

884884
/* in remote.c */
885-
extern void check_remote_agent_compatibility(int agent_version, char *compatibility_str);
8000 886-
extern size_t prepare_remote_agent_compatibility_str(char* compatibility_buf, size_t buf_size);
885+
extern void check_remote_agent_compatibility(int agent_version,
886+
char *compatibility_str, size_t compatibility_str_max_size);
887+
extern size_t prepare_compatibility_str(char* compatibility_buf, size_t compatibility_buf_size);
887888

888889
/* in merge.c */
889890
extern void do_merge(InstanceState *instanceState, time_t backup_id, bool no_validate, bool no_sync);

src/utils/file.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ fio_get_agent_version(int* protocol, char* payload_buf, size_t payload_buf_size)
281281
IO_CHECK(fio_read_all(fio_stdin, &hdr, sizeof(hdr)), sizeof(hdr));
282282
if (hdr.size > payload_buf_size)
283283
{
284-
elog(ERROR, "Bad protocol, insufficient payload_buf_size=%zu", payload_buf_size);
284+
//TODO REVIEW XXX %zu is C99 but not ANSI S standard, should we cast to unsigned long?
285+
elog(ERROR, "Corrupted remote compatibility protocol: insufficient payload_buf_size=%zu", payload_buf_size);
285286
}
286287

287288
*protocol = hdr.arg;
@@ -3321,17 +3322,18 @@ fio_communicate(int in, int out)
33213322
IO_CHECK(fio_write_all(out, buf, hdr.size), hdr.size);
33223323
break;
33233324
case FIO_AGENT_VERSION:
3324-
hdr.arg = AGENT_PROTOCOL_VERSION;
3325-
IO_CHECK(fio_write_all(out, &hdr, sizeof(hdr)), sizeof(hdr));
3326-
//TODO REVIEW XXX is it allowed by ANSI C to declare new scope inside???
33273325
{
3328-
size_t payload_size = prepare_remote_agent_compatibility_str(buf, buf_size);
3326+
size_t payload_size = prepare_compatibility_str(buf, buf_size);
3327+
3328+
hdr.arg = AGENT_PROTOCOL_VERSION;
3329+
hdr.size = payload_size;
3330+
3331+
IO_CHECK(fio_write_all(out, &hdr, sizeof(hdr)), sizeof(hdr));
33293332
IO_CHECK(fio_write_all(out, buf, payload_size), payload_size);
33303333
//TODO REVIEW XXX make INFO to LOG or VERBOSE
33313334
elog(INFO, "TODO REVIEW XXX sent agent compatibility\n %s", buf);
3335+
break;
33323336
}
3333-
assert(false);
3334-
break;
33353337
case FIO_STAT: /* Get information about file with specified path */
33363338
hdr.size = sizeof(st);
33373339
rc = hdr.arg ? stat(buf, &st) : lstat(buf, &st);

src/utils/remote.c

Lines changed: 87 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ bool launch_agent(void)
118118
int errfd[2];
119119
int agent_version;
120120
//TODO REVIEW XXX review buf_size
121-
size_t payload_buf_size = 1024 * 8;
121+
int payload_buf_size = 1024 * 8;
122122
char payload_buf[payload_buf_size];
123123

124124
ssh_argc = 0;
@@ -244,29 +244,83 @@ bool launch_agent(void)
244244
/* Make sure that remote agent has the same version, fork and other features to be binary compatible
245245
*/
246246
fio_get_agent_version(&agent_version, payload_buf, payload_buf_size);
247-
check_remote_agent_compatibility(0, payload_buf);
247+
check_remote_agent_compatibility(agent_version, payload_buf, payload_buf_size);
248248

249249
return true;
250250
}
251251

252-
//TODO REVIEW XXX review macro
253-
#define STR(macro) #macro
254-
size_t prepare_remote_agent_compatibility_str(char* compatibility_buf, size_t buf_size)
252+
#define COMPATIBILITY_VAL(macro) #macro, macro
253+
#define COMPATIBILITY_STR(macro) #macro
254+
#define COMPATIBILITY_VAL_STR(macro) #macro, COMPATIBILITY_STR(macro)
255+
256+
#define COMPATIBILITY_VAL_SEPARATOR "="
257+
#define COMPATIBILITY_LINE_SEPARATOR "\n"
258+
259+
static char* compatibility_params[] = {
260+
COMPATIBILITY_VAL(PG_MAJORVERSION),
261+
//TODO remove?
262+
//TODO doesn't work macro name check for ints!!!!
263+
COMPATIBILITY_VAL_STR(SIZEOF_VOID_P),
264+
//TODO REVIEW XXX can use edition.h/extract_pgpro_edition()
265+
#ifdef PGPRO_EDN
266+
//TODO add vanilla
267+
//TODO make "1c" -> "vanilla"
268+
COMPATIBILITY_VAL(PGPRO_EDN),
269+
#endif
270+
};
271+
272+
/*
273+
* Compose compatibility string to be sent by pg_probackup agent
274+
* through ssh and to be verified by pg_probackup peer.
275+
* Compatibility string contains postgres essential vars as strings
276+
* in format "var_name" + COMPATIBILITY_VAL_SEPARATOR + "var_value" + COMPATIBILITY_LINE_SEPARATOR
277+
*/
278+
size_t prepare_compatibility_str(char* compatibility_buf, size_t compatibility_buf_size)
255279
{
256-
size_t payload_size = snprintf(compatibility_buf, buf_size,
257-
// "%s\n%s\n%s\n%s\n",
258-
"%s\n%s\n",
259-
STR(PG_MAJORVERSION), PG_MAJORVERSION);
260-
// STR(PGPRO_EDN), PGPRO_EDN);
261-
if (payload_size >= buf_size)
280+
char tmp_buf[1024];
281+
int size_inc = 0;
282+
size_t result_size = 1;
283+
size_t compatibility_params_array_size = sizeof compatibility_params / sizeof compatibility_params[0];;
284+
285+
*compatibility_buf = '\0';
286+
Assert(compatibility_params_array_size % 2 == 0);
287+
288+
//TODO !!!!
289+
for (int i = 0; i < compatibility_params_array_size; i+=2)
262290
{
263-
elog(ERROR, "TODO REVIEW XXX too bad message buffer exhaust");
291+
size_inc = snprintf(compatibility_buf + size_inc, compatibility_buf_size,
292+
"%s" COMPATIBILITY_VAL_SEPARATOR "%s" COMPATIBILITY_LINE_SEPARATOR,
293+
compatibility_params[i], compatibility_params[i+1]);
294+
295+
// size_inc = snprintf(tmp_buf, sizeof tmp_buf,
296+
// "%s" COMPATIBILITY_VAL_SEPARATOR "%s" COMPATIBILITY_LINE_SEPARATOR,
297+
// compatibility_params[i], compatibility_params[i+1]);
298+
if (size_inc >= sizeof tmp_buf)
299+
{
300+
//TODO make Assert
301+
elog(ERROR, "Compatibility params from agent doesn't fit to %zu chars, %s=%s",
302+
sizeof tmp_buf - 1, compatibility_params[i], compatibility_params[i+1] );
303+
}
304+
305+
result_size += size_inc;
306+
if (result_size > compatibility_buf_size)
307+
{
308+
//TODO make Assert
309+
elog(ERROR, "Can't fit compatibility string size %zu to buffer size %zu:\n%s\n%s",
310+
result_size, compatibility_buf_size, compatibility_buf, tmp_buf);
311+
}
312+
strcat(compatibility_buf, tmp_buf);
264313
}
265-
return payload_size + 1;
314+
return result_size;
266315
}
267316

268-
void check_remote_agent_compatibility(int agent_version, char *compatibility_str)
317+
/*
318+
* Check incoming remote agent's compatibility params for equality to local ones.
319+
*/
320+
void check_remote_agent_compatibility(int agent_version, char *compatibility_str, size_t compatibility_str_max_size)
269321
{
322+
elog(LOG, "Agent version=%d", agent_version);
323+
270324
if (agent_version != AGENT_PROTOCOL_VERSION)
271325
{
272326
char agent_version_str[1024];
@@ -279,6 +333,23 @@ void check_remote_agent_compatibility(int agent_version, char *compatibility_str
279333
"consider to upgrade pg_probackup binary",
280334
agent_version_str, AGENT_PROTOCOL_VERSION_STR);
281335
}
282-
assert(false);
283-
elog(ERROR, " check_remote_agent_compatibility() not implemented");
336+
337+
if (strnlen(compatibility_str, compatibility_str_max_size) == compatibility_str_max_size)
338+
{
339+
elog(ERROR, "Corrupted remote compatibility protocol: compatibility string has no terminating \\0");
340+
}
341+
342+
elog(LOG, "Agent compatibility params: '%s'", compatibility_str);
343+
344+
/* checking compatibility params */
345+
{
346+
char *buf[compatibility_str_max_size];
347+
348+
prepare_compatibility_str(buf, sizeof buf);
349+
if(!strcmp(compatibility_str, buf))
350+
{
351+
elog(ERROR, "Incompatible agent params, expected %s", buf);
352+
}
353+
}
354+
284355
}

0 commit comments

Comments
 (0)
0