Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

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

Sign up
Appearance settings

Commit970a186

Browse files
committed
Use GUC lexer for recovery.conf parsing.
This eliminates some crufty, special-purpose code and, as a non-trivialside benefit, allows recovery.conf parameters to be unquoted.Dimitri Fontaine, with review and cleanup by Alvaro Herrera, ItagakiTakahiro, and me.
1 parent9cea52a commit970a186

File tree

4 files changed

+135
-209
lines changed

4 files changed

+135
-209
lines changed

‎src/backend/access/transam/xlog.c

Lines changed: 39 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -5023,116 +5023,21 @@ str_time(pg_time_t tnow)
50235023
returnbuf;
50245024
}
50255025

5026-
/*
5027-
* Parse one line from recovery.conf. 'cmdline' is the raw line from the
5028-
* file. If the line is parsed successfully, returns true, false indicates
5029-
* syntax error. On success, *key_p and *value_p are set to the parameter
5030-
* name and value on the line, respectively. If the line is an empty line,
5031-
* consisting entirely of whitespace and comments, function returns true
5032-
* and *keyp_p and *value_p are set to NULL.
5033-
*
5034-
* The pointers returned in *key_p and *value_p point to an internal buffer
5035-
* that is valid only until the next call of parseRecoveryCommandFile().
5036-
*/
5037-
staticbool
5038-
parseRecoveryCommandFileLine(char*cmdline,char**key_p,char**value_p)
5039-
{
5040-
char*ptr;
5041-
char*bufp;
5042-
char*key;
5043-
char*value;
5044-
staticchar*buf=NULL;
5045-
5046-
*key_p=*value_p=NULL;
5047-
5048-
/*
5049-
* Allocate the buffer on first use. It's used to hold both the parameter
5050-
* name and value.
5051-
*/
5052-
if (buf==NULL)
5053-
buf=malloc(MAXPGPATH+1);
5054-
bufp=buf;
5055-
5056-
/* Skip any whitespace at the beginning of line */
5057-
for (ptr=cmdline;*ptr;ptr++)
5058-
{
5059-
if (!isspace((unsignedchar)*ptr))
5060-
break;
5061-
}
5062-
/* Ignore empty lines */
5063-
if (*ptr=='\0'||*ptr=='#')
5064-
return true;
5065-
5066-
/* Read the parameter name */
5067-
key=bufp;
5068-
while (*ptr&& !isspace((unsignedchar)*ptr)&&
5069-
*ptr!='='&&*ptr!='\'')
5070-
*(bufp++)=*(ptr++);
5071-
*(bufp++)='\0';
5072-
5073-
/* Skip to the beginning quote of the parameter value */
5074-
ptr=strchr(ptr,'\'');
5075-
if (!ptr)
5076-
return false;
5077-
ptr++;
5078-
5079-
/* Read the parameter value to *bufp. Collapse any '' escapes as we go. */
5080-
value=bufp;
5081-
for (;;)
5082-
{
5083-
if (*ptr=='\'')
5084-
{
5085-
ptr++;
5086-
if (*ptr=='\'')
5087-
*(bufp++)='\'';
5088-
else
5089-
{
5090-
/* end of parameter */
5091-
*bufp='\0';
5092-
break;
5093-
}
5094-
}
5095-
elseif (*ptr=='\0')
5096-
return false;/* unterminated quoted string */
5097-
else
5098-
*(bufp++)=*ptr;
5099-
5100-
ptr++;
5101-
}
5102-
*(bufp++)='\0';
5103-
5104-
/* Check that there's no garbage after the value */
5105-
while (*ptr)
5106-
{
5107-
if (*ptr=='#')
5108-
break;
5109-
if (!isspace((unsignedchar)*ptr))
5110-
return false;
5111-
ptr++;
5112-
}
5113-
5114-
/* Success! */
5115-
*key_p=key;
5116-
*value_p=value;
5117-
return true;
5118-
}
5119-
51205026
/*
51215027
* See if there is a recovery command file (recovery.conf), and if so
51225028
* read in parameters for archive recovery and XLOG streaming.
51235029
*
5124-
* XXX longer term intention is to expand this to
5125-
* cater for additional parameters and controls
5126-
* possibly use a flex lexer similar to the GUC one
5030+
* The file is parsed using the main configuration parser.
51275031
*/
51285032
staticvoid
51295033
readRecoveryCommandFile(void)
51305034
{
51315035
FILE*fd;
5132-
charcmdline[MAXPGPATH];
51335036
TimeLineIDrtli=0;
51345037
boolrtliGiven= false;
5135-
boolsyntaxError= false;
5038+
ConfigVariable*item,
5039+
*head=NULL,
5040+
*tail=NULL;
51365041

51375042
fd=AllocateFile(RECOVERY_COMMAND_FILE,"r");
51385043
if (fd==NULL)
@@ -5146,55 +5051,47 @@ readRecoveryCommandFile(void)
51465051
}
51475052

51485053
/*
5149-
* Parse the file...
5150-
*/
5151-
while (fgets(cmdline,sizeof(cmdline),fd)!=NULL)
5152-
{
5153-
char*tok1;
5154-
char*tok2;
5054+
* Since we're asking ParseConfigFp() to error out at FATAL, there's no
5055+
* need to check the return value.
5056+
*/
5057+
ParseConfigFp(fd,RECOVERY_COMMAND_FILE,0,FATAL,&head,&tail);
51555058

5156-
if (!parseRecoveryCommandFileLine(cmdline,&tok1,&tok2))
5157-
{
5158-
syntaxError= true;
5159-
break;
5160-
}
5161-
if (tok1==NULL)
5162-
continue;
5163-
5164-
if (strcmp(tok1,"restore_command")==0)
5059+
for (item=head;item;item=item->next)
5060+
{
5061+
if (strcmp(item->name,"restore_command")==0)
51655062
{
5166-
recoveryRestoreCommand=pstrdup(tok2);
5063+
recoveryRestoreCommand=pstrdup(item->value);
51675064
ereport(DEBUG2,
51685065
(errmsg("restore_command = '%s'",
51695066
recoveryRestoreCommand)));
51705067
}
5171-
elseif (strcmp(tok1,"recovery_end_command")==0)
5068+
elseif (strcmp(item->name,"recovery_end_command")==0)
51725069
{
5173-
recoveryEndCommand=pstrdup(tok2);
5070+
recoveryEndCommand=pstrdup(item->value);
51745071
ereport(DEBUG2,
51755072
(errmsg("recovery_end_command = '%s'",
51765073
recoveryEndCommand)));
51775074
}
5178-
elseif (strcmp(tok1,"archive_cleanup_command")==0)
5075+
elseif (strcmp(item->name,"archive_cleanup_command")==0)
51795076
{
5180-
archiveCleanupCommand=pstrdup(tok2);
5077+
archiveCleanupCommand=pstrdup(item->value);
51815078
ereport(DEBUG2,
51825079
(errmsg("archive_cleanup_command = '%s'",
51835080
archiveCleanupCommand)));
51845081
}
5185-
elseif (strcmp(tok1,"recovery_target_timeline")==0)
5082+
elseif (strcmp(item->name,"recovery_target_timeline")==0)
51865083
{
51875084
rtliGiven= true;
5188-
if (strcmp(tok2,"latest")==0)
5085+
if (strcmp(item->value,"latest")==0)
51895086
rtli=0;
51905087
else
51915088
{
51925089
errno=0;
5193-
rtli= (TimeLineID)strtoul(tok2,NULL,0);
5090+
rtli= (TimeLineID)strtoul(item->value,NULL,0);
51945091
if (errno==EINVAL||errno==ERANGE)
51955092
ereport(FATAL,
51965093
(errmsg("recovery_target_timeline is not a valid number: \"%s\"",
5197-
tok2)));
5094+
item->value)));
51985095
}
51995096
if (rtli)
52005097
ereport(DEBUG2,
@@ -5203,20 +5100,20 @@ readRecoveryCommandFile(void)
52035100
ereport(DEBUG2,
52045101
(errmsg("recovery_target_timeline = latest")));
52055102
}
5206-
elseif (strcmp(tok1,"recovery_target_xid")==0)
5103+
elseif (strcmp(item->name,"recovery_target_xid")==0)
52075104
{
52085105
errno=0;
5209-
recoveryTargetXid= (TransactionId)strtoul(tok2,NULL,0);
5106+
recoveryTargetXid= (TransactionId)strtoul(item->value,NULL,0);
52105107
if (errno==EINVAL||errno==ERANGE)
52115108
ereport(FATAL,
52125109
(errmsg("recovery_target_xid is not a valid number: \"%s\"",
5213-
tok2)));
5110+
item->value)));
52145111
ereport(DEBUG2,
52155112
(errmsg("recovery_target_xid = %u",
52165113
recoveryTargetXid)));
52175114
recoveryTarget=RECOVERY_TARGET_XID;
52185115
}
5219-
elseif (strcmp(tok1,"recovery_target_time")==0)
5116+
elseif (strcmp(item->name,"recovery_target_time")==0)
52205117
{
52215118
/*
52225119
* if recovery_target_xid specified, then this overrides
@@ -5231,62 +5128,54 @@ readRecoveryCommandFile(void)
52315128
*/
52325129
recoveryTargetTime=
52335130
DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in,
5234-
CStringGetDatum(tok2),
5131+
CStringGetDatum(item->value),
52355132
ObjectIdGetDatum(InvalidOid),
52365133
Int32GetDatum(-1)));
52375134
ereport(DEBUG2,
52385135
(errmsg("recovery_target_time = '%s'",
52395136
timestamptz_to_str(recoveryTargetTime))));
52405137
}
5241-
elseif (strcmp(tok1,"recovery_target_inclusive")==0)
5138+
elseif (strcmp(item->name,"recovery_target_inclusive")==0)
52425139
{
52435140
/*
52445141
* does nothing if a recovery_target is not also set
52455142
*/
5246-
if (!parse_bool(tok2,&recoveryTargetInclusive))
5143+
if (!parse_bool(item->value,&recoveryTargetInclusive))
52475144
ereport(ERROR,
52485145
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
52495146
errmsg("parameter \"%s\" requires a Boolean value","recovery_target_inclusive")));
52505147
ereport(DEBUG2,
5251-
(errmsg("recovery_target_inclusive = %s",tok2)));
5148+
(errmsg("recovery_target_inclusive = %s",item->value)));
52525149
}
5253-
elseif (strcmp(tok1,"standby_mode")==0)
5150+
elseif (strcmp(item->name,"standby_mode")==0)
52545151
{
5255-
if (!parse_bool(tok2,&StandbyMode))
5152+
if (!parse_bool(item->value,&StandbyMode))
52565153
ereport(ERROR,
52575154
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
52585155
errmsg("parameter \"%s\" requires a Boolean value","standby_mode")));
52595156
ereport(DEBUG2,
5260-
(errmsg("standby_mode = '%s'",tok2)));
5157+
(errmsg("standby_mode = '%s'",item->value)));
52615158
}
5262-
elseif (strcmp(tok1,"primary_conninfo")==0)
5159+
elseif (strcmp(item->name,"primary_conninfo")==0)
52635160
{
5264-
PrimaryConnInfo=pstrdup(tok2);
5161+
PrimaryConnInfo=pstrdup(item->value);
52655162
ereport(DEBUG2,
52665163
(errmsg("primary_conninfo = '%s'",
52675164
PrimaryConnInfo)));
52685165
}
5269-
elseif (strcmp(tok1,"trigger_file")==0)
5166+
elseif (strcmp(item->name,"trigger_file")==0)
52705167
{
5271-
TriggerFile=pstrdup(tok2);
5168+
TriggerFile=pstrdup(item->value);
52725169
ereport(DEBUG2,
52735170
(errmsg("trigger_file = '%s'",
52745171
TriggerFile)));
52755172
}
52765173
else
52775174
ereport(FATAL,
52785175
(errmsg("unrecognized recovery parameter \"%s\"",
5279-
tok1)));
5176+
item->name)));
52805177
}
52815178

5282-
FreeFile(fd);
5283-
5284-
if (syntaxError)
5285-
ereport(FATAL,
5286-
(errmsg("syntax error in recovery command file: %s",
5287-
cmdline),
5288-
errhint("Lines should have the format parameter = 'value'.")));
5289-
52905179
/*
52915180
* Check for compulsory parameters
52925181
*/
@@ -5332,6 +5221,9 @@ readRecoveryCommandFile(void)
53325221
recoveryTargetTLI=findNewestTimeLine(recoveryTargetTLI);
53335222
}
53345223
}
5224+
5225+
FreeConfigVariables(head);
5226+
FreeFile(fd);
53355227
}
53365228

53375229
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp