@@ -2050,22 +2050,18 @@ void MtmUpdateNodeConnectionInfo(MtmConnectionInfo* conn, char const* connStr)
2050
2050
2051
2051
port = strstr (connStr , "raftport=" );
2052
2052
if (port != NULL ) {
2053
- int n ;
2054
- if (sscanf (port + 9 , "%d%n" , & conn -> raftablePort , & n ) != 1 ) {
2053
+ if (sscanf (port + 9 , "%d" , & conn -> raftablePort ) != 1 ) {
2055
2054
elog (ERROR , "Invalid raftable port: %s" , port + 9 );
2056
2055
}
2057
- n += 9 ;
2058
2056
} else {
2059
2057
conn -> raftablePort = 0 ;
2060
2058
}
2061
2059
2062
2060
port = strstr (connStr , "arbiterport=" );
2063
2061
if (port != NULL ) {
2064
- int n ;
2065
- if (sscanf (port + 12 , "%d%n" , & conn -> arbiterPort , & n ) != 1 ) {
2062
+ if (sscanf (port + 12 , "%d" , & conn -> arbiterPort ) != 1 ) {
2066
2063
elog (ERROR , "Invalid arbiter port: %s" , port + 12 );
2067
2064
}
2068
- n += 12 ;
2069
2065
} else {
2070
2066
conn -> arbiterPort = 0 ;
2071
2067
}
@@ -2074,23 +2070,29 @@ void MtmUpdateNodeConnectionInfo(MtmConnectionInfo* conn, char const* connStr)
2074
2070
static void MtmSplitConnStrs (void )
2075
2071
{
2076
2072
int i ;
2077
- char * copy = pstrdup (MtmConnStrs );
2078
- char * connStr = copy ;
2079
- char * connStrEnd = connStr + strlen (connStr );
2080
-
2081
- for (i = 0 ; connStr < connStrEnd ; i ++ ) {
2082
- char * p = strchr (connStr , ',' );
2083
- if (p == NULL ) {
2084
- p = connStrEnd ;
2085
- }
2086
- connStr = p + 1 ;
2073
+ FILE * f = NULL ;
2074
+ char buf [MULTIMASTER_MAX_CTL_STR_SIZE ];
2075
+
2076
+ if (* MtmConnStrs == '@' ) {
2077
+ f = fopen (MtmConnStrs + 1 , "r" );
2078
+ for (i = 0 ; fgets (buf , sizeof buf , f ) != NULL ; i ++ ) {
2079
+ if (strlen (buf ) <= 1 ) {
2080
+ elog (ERROR , "Empty lines are not allowed in %s file" , MtmConnStrs + 1 );
2081
+ }
2082
+ }
2083
+ } else {
2084
+ char * p = MtmConnStrs ;
2085
+ for (i = 0 ; * p != '\0' ; i ++ ) {
2086
+ if ((p = strchr (p , ',' )) == NULL ) {
2087
+ i += 1 ;
2088
+ break ;
2089
+ }
2090
+ }
2087
2091
}
2092
+
2088
2093
if (i > MAX_NODES ) {
2089
2094
elog (ERROR , "Multimaster with more than %d nodes is not currently supported" , MAX_NODES );
2090
2095
}
2091
- if (MtmNodeId > i ) {
2092
- elog (ERROR , "Multimaster node id %d is out of range [%d..%d]" , MtmNodeId , 1 , i );
2093
- }
2094
2096
if (i < 2 ) {
2095
2097
elog (ERROR , "Multimaster should have at least two nodes" );
2096
2098
}
@@ -2101,56 +2103,89 @@ static void MtmSplitConnStrs(void)
2101
2103
}
2102
2104
MtmNodes = i ;
2103
2105
MtmConnections = (MtmConnectionInfo * )palloc (MtmMaxNodes * sizeof (MtmConnectionInfo ));
2104
- connStr = copy ;
2105
2106
2106
- for (i = 0 ; connStr < connStrEnd ; i ++ ) {
2107
- char * p = strchr (connStr , ',' );
2108
- if (p == NULL ) {
2109
- p = connStrEnd ;
2110
- }
2111
- * p = '\0' ;
2112
-
2113
- MtmUpdateNodeConnectionInfo (& MtmConnections [i ], connStr );
2114
-
2115
- if (i + 1 == MtmNodeId ) {
2116
- char * dbName = strstr (connStr , "dbname=" ); // XXX: shoud we care about string 'itisnotdbname=xxx'?
2117
- char * dbUser = strstr (connStr , "user=" );
2118
- char * end ;
2119
- size_t len ;
2120
-
2121
- if (dbName == NULL )
2122
- elog (ERROR , "Database is not specified in connection string: '%s'" , connStr );
2123
-
2124
- if (dbUser == NULL )
2125
- {
2126
- char * errstr ;
2127
- const char * username = get_user_name (& errstr );
2128
- if (!username )
2129
- elog (FATAL , "Database user is not specified in connection string '%s', fallback failed: %s" , connStr , errstr );
2130
- else
2131
- elog (WARNING , "Database user is not specified in connection string '%s', fallback to '%s'" , connStr , username );
2132
- MtmDatabaseUser = pstrdup (username );
2107
+ if (f != NULL ) {
2108
+ fseek (f , SEEK_SET , 0 );
2109
+ for (i = 0 ; fgets (buf , sizeof buf , f ) != NULL ; i ++ ) {
2110
+ size_t len = strlen (buf );
2111
+ if (buf [len - 1 ] == '\n' ) {
2112
+ buf [len - 1 ] = '\0' ;
2113
+ }
2114
+ MtmUpdateNodeConnectionInfo (& MtmConnections [i ], buf );
2115
+ }
2116
+ fclose (f );
2117
+ } else {
2118
+ char * copy = pstrdup (MtmConnStrs );
2119
+ char * connStr = copy ;
2120
+ char * connStrEnd = connStr + strlen (connStr );
2121
+
2122
+ for (i = 0 ; connStr != connStrEnd ; i ++ ) {
2123
+ char * p = strchr (connStr , ',' );
2124
+ if (p == NULL ) {
2125
+ p = connStrEnd ;
2133
2126
}
2134
- else
2135
- {
2136
- dbUser += 5 ;
2137
- end = strchr (dbUser , ' ' );
2138
- if (!end ) end = strchr (dbUser , '\0' );
2139
- Assert (end != NULL );
2140
- len = end - dbUser ;
2141
- MtmDatabaseUser = pnstrdup (dbUser , len );
2127
+ * p = '\0' ;
2128
+ MtmUpdateNodeConnectionInfo (& MtmConnections [i ], connStr );
2129
+ connStr = p + 1 ;
2130
+ }
2131
+ pfree (copy );
2132
+ }
2133
+ if (MtmNodeId == INT_MAX ) {
2134
+ if (gethostname (buf , sizeof buf ) != 0 ) {
2135
+ elog (ERROR , "Failed to get host name: %m" );
2136
+ }
2137
+ for (i = 0 ; i < MtmNodes ; i ++ ) {
2138
+ if (strcmp (MtmConnections [i ].hostName , buf ) == 0 ) {
2139
+ if (MtmNodeId == INT_MAX ) {
2140
+ MtmNodeId = i + 1 ;
2141
+ } else {
2142
+ elog (ERROR , "multimaster.node_id is not explicitly specified and more than one nodes are configured for host %s" , buf );
2143
+ }
2142
2144
}
2143
-
2144
- dbName += 7 ;
2145
- end = strchr (dbName , ' ' );
2146
- if (!end ) end = strchr (dbName , '\0' );
2145
+ }
2146
+ if (MtmNodeId == INT_MAX ) {
2147
+ elog (ERROR , "multimaster.node_id and host name %s can not be located in connection strings list" , buf );
2148
+ }
2149
+ } else if (MtmNodeId > i ) {
2150
+ elog (ERROR , "Multimaster node id %d is out of range [%d..%d]" , MtmNodeId , 1 , MtmNodes );
2151
+ }
2152
+ {
2153
+ char * connStr = MtmConnections [MtmNodeId - 1 ].connStr ;
2154
+ char * dbName = strstr (connStr , "dbname=" ); // XXX: shoud we care about string 'itisnotdbname=xxx'?
2155
+ char * dbUser = strstr (connStr , "user=" );
2156
+ char * end ;
2157
+ size_t len ;
2158
+
2159
+ if (dbName == NULL )
2160
+ elog (ERROR , "Database is not specified in connection string: '%s'" , connStr );
2161
+
2162
+ if (dbUser == NULL )
2163
+ {
2164
+ char * errstr ;
2165
+ const char * username = get_user_name (& errstr );
2166
+ if (!username )
2167
+ elog (FATAL , "Database user is not specified in connection string '%s', fallback failed: %s" , connStr , errstr );
2168
+ else
2169
+ elog (WARNING , "Database user is not specified in connection string '%s', fallback to '%s'" , connStr , username );
2170
+ MtmDatabaseUser = pstrdup (username );
2171
+ }
2172
+ else
2173
+ {
2174
+ dbUser += 5 ;
2175
+ end = strchr (dbUser , ' ' );
2176
+ if (!end ) end = strchr (dbUser , '\0' );
2147
2177
Assert (end != NULL );
2148
- len = end - dbName ;
2149
- MtmDatabaseName = pnstrdup (dbName , len );
2178
+ len = end - dbUser ;
2179
+ MtmDatabaseUser = pnstrdup (dbUser , len );
2150
2180
}
2151
- connStr = p + 1 ;
2181
+
2182
+ dbName += 7 ;
2183
+ end = strchr (dbName , ' ' );
2184
+ if (!end ) end = strchr (dbName , '\0' );
2185
+ Assert (end != NULL );
2186
+ len = end - dbName ;
2187
+ MtmDatabaseName = pnstrdup (dbName , len );
2152
2188
}
2153
- pfree (copy );
2154
2189
}
2155
2190
2156
2191
static bool ConfigIsSane (void )
@@ -2994,7 +3029,15 @@ mtm_add_node(PG_FUNCTION_ARGS)
2994
3029
MtmLock (LW_EXCLUSIVE );
2995
3030
nodeId = Mtm -> nAllNodes ;
2996
3031
elog (NOTICE , "Add node %d: '%s'" , nodeId + 1 , connStr );
3032
+
2997
3033
MtmUpdateNodeConnectionInfo (& Mtm -> nodes [nodeId ].con , connStr );
3034
+
3035
+ if (* MtmConnStrs == '@' ) {
3036
+ FILE * f = fopen (MtmConnStrs + 1 , "a" );
3037
+ fprintf (f , "%s\n" , connStr );
3038
+ fclose (f );
3039
+ }
3040
+
2998
3041
Mtm -> nodes [nodeId ].transDelay = 0 ;
2999
3042
Mtm -> nodes [nodeId ].lastStatusChangeTime = MtmGetSystemTime ();
3000
3043
Mtm -> nodes [nodeId ].flushPos = 0 ;
0 commit comments