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