Ejemplo n.º 1
0
/* Sets server options.
 * Returns:
 * 0 if it worked
 * 2 if the option didn't exist
 * 3 on logical errors.
 *
 * On logical errors, the error_message will be populated with the reason. */
int mongo_store_option(mongo_con_manager *manager, mongo_servers *servers, char *option_name, char *option_value, char **error_message)
{
	int i;

	if (strcasecmp(option_name, "authMechanism") == 0) {
		int mechanism;

		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'authMechanism': '%s'", option_value);
		if (strcasecmp(option_value, "MONGODB-CR") == 0) {
			mechanism = MONGO_AUTH_MECHANISM_MONGODB_CR;
		} else if (strcasecmp(option_value, "MONGODB-X509") == 0) {
			mechanism = MONGO_AUTH_MECHANISM_MONGODB_X509;
		} else if (strcasecmp(option_value, "GSSAPI") == 0) {
			mechanism = MONGO_AUTH_MECHANISM_GSSAPI;
		} else if (strcasecmp(option_value, "PLAIN") == 0) {
			mechanism = MONGO_AUTH_MECHANISM_PLAIN;
		} else {
			int len = strlen(option_value) + sizeof("The authMechanism '' does not exist.");

			*error_message = malloc(len + 1);
			snprintf(*error_message, len, "The authMechanism '%s' does not exist.", option_value);
			return 3;
		}
		for (i = 0; i < servers->count; i++) {
			servers->server[i]->mechanism = mechanism;
		}
		return 0;
	}

	if (strcasecmp(option_name, "authSource") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'authSource': '%s'", option_value);
		for (i = 0; i < servers->count; i++) {
			if (servers->server[i]->authdb) {
				free(servers->server[i]->authdb);
			}
			servers->server[i]->authdb = strdup(option_value);
		}
		return 0;
	}

	if (strcasecmp(option_name, "connectTimeoutMS") == 0) {
		int value = atoi(option_value);

		if (servers->options.connectTimeoutMS) {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Replacing previously set value for 'connectTimeoutMS' (%d)", servers->options.connectTimeoutMS);
		}
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'connectTimeoutMS': %d", value);
		servers->options.connectTimeoutMS = value;
		return 0;
	}

	if (strcasecmp(option_name, "db") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'db': '%s'", option_value);
		for (i = 0; i < servers->count; i++) {
			if (servers->server[i]->db) {
				free(servers->server[i]->db);
				/* Free the authdb too as it defaulted to 'admin' when no db was passed as the connection string */
				free(servers->server[i]->authdb);
				servers->server[i]->authdb = NULL;
			}
			servers->server[i]->db = strdup(option_value);
		}
		return 0;
	}

	if (strcasecmp(option_name, "fsync") == 0) {
		if (strcasecmp(option_value, "true") == 0 || strcmp(option_value, "1") == 0) {
			servers->options.default_fsync = 1;
		} else {
			servers->options.default_fsync = 0;
		}
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'fsync': %d", servers->options.default_fsync);
		return 0;
	}

	if (strcasecmp(option_name, "journal") == 0) {
		if (strcasecmp(option_value, "true") == 0 || strcmp(option_value, "1") == 0) {
			servers->options.default_journal = 1;
		} else {
			servers->options.default_journal = 0;
		}
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'journal': %d", servers->options.default_journal);
		return 0;
	}

	if (strcasecmp(option_name, "password") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'password': '******'", option_value);
		for (i = 0; i < servers->count; i++) {
			if (servers->server[i]->password) {
				free(servers->server[i]->password);
			}
			servers->server[i]->password = strdup(option_value);
		}
		return 0;
	}

	if (strcasecmp(option_name, "readPreference") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'readPreference': '%s'", option_value);
		if (strcasecmp(option_value, "primary") == 0) {
			servers->read_pref.type = MONGO_RP_PRIMARY;
		} else if (strcasecmp(option_value, "primaryPreferred") == 0) {
			servers->read_pref.type = MONGO_RP_PRIMARY_PREFERRED;
		} else if (strcasecmp(option_value, "secondary") == 0) {
			servers->read_pref.type = MONGO_RP_SECONDARY;
		} else if (strcasecmp(option_value, "secondaryPreferred") == 0) {
			servers->read_pref.type = MONGO_RP_SECONDARY_PREFERRED;
		} else if (strcasecmp(option_value, "nearest") == 0) {
			servers->read_pref.type = MONGO_RP_NEAREST;
		} else {
			int len = strlen(option_value) + sizeof("The readPreference value '' is not supported.");

			*error_message = malloc(len + 1);
			snprintf(*error_message, len, "The readPreference value '%s' is not supported.", option_value);
			return 3;
		}
		return 0;
	}

	if (strcasecmp(option_name, "readPreferenceTags") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'readPreferenceTags': '%s'", option_value);
		return parse_read_preference_tags(manager, servers, option_value, error_message);
	}

	if (strcasecmp(option_name, "replicaSet") == 0) {
		if (servers->options.repl_set_name) {
			/* Free the already existing one */
			free(servers->options.repl_set_name);
			servers->options.repl_set_name = NULL; /* We reset it as not all options set a string as replset name */
		}

		if (option_value && *option_value) {
			/* We explicitly check for the stringified version of "true" here,
			 * as "true" has a special meaning. It does not mean that the
			 * replicaSet name is "1". */
			if (strcmp(option_value, "1") != 0) {
				servers->options.repl_set_name = strdup(option_value);
				mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'replicaSet': '%s'", option_value);

				/* Associate the given replica set name with all the server
				 * definitions from the seed */
				for (i = 0; i < servers->count; i++) {
					if (servers->server[i]->repl_set_name) {
						free(servers->server[i]->repl_set_name);
					}
					servers->server[i]->repl_set_name = strdup(option_value);
				}
			} else {
				mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Found option 'replicaSet': true - Expected the name of the replica set");
			}
			servers->options.con_type = MONGO_CON_TYPE_REPLSET;
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Switching connection type: REPLSET");
		}
		return 0;
	}

	if (strcasecmp(option_name, "gssapiServiceName") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'gssapiServiceName': '%s'", option_value);
		free(servers->options.gssapiServiceName);
		servers->options.gssapiServiceName = strdup(option_value);
		return 0;
	}

	if (strcasecmp(option_name, "secondaryAcceptableLatencyMS") == 0) {
		int value = atoi(option_value);

		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'secondaryAcceptableLatencyMS': '%s'", option_value);
		servers->options.secondaryAcceptableLatencyMS = value;
		return 0;
	}

	if (strcasecmp(option_name, "slaveOkay") == 0) {
		if (strcasecmp(option_value, "true") == 0 || strcmp(option_value, "1") == 0) {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'slaveOkay': true");
			if (servers->read_pref.type != MONGO_RP_PRIMARY || servers->read_pref.tagset_count) {
				/* The server already has read preferences configured, but
				 * we're still trying to set slave okay. The spec says that's
				 * an error */
				*error_message = strdup("You can not use both slaveOkay and read-preferences. Please switch to read-preferences.");
				return 3;
			} else {
				/* Old style option, that needs to be removed. For now, spec
				 * dictates it needs to be ReadPreference=SECONDARY_PREFERRED */
				servers->read_pref.type = MONGO_RP_SECONDARY_PREFERRED;
			}
			return -1;
		}

		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'slaveOkay': false");
		return -1;
	}

	if (strcasecmp(option_name, "socketTimeoutMS") == 0) {
		int value = atoi(option_value);

		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'socketTimeoutMS': %d", value);
		servers->options.socketTimeoutMS = value;
		return 0;
	}

	if (strcasecmp(option_name, "ssl") == 0) {
		int value = 0;
		if (strcasecmp(option_value, "true") == 0 || strcmp(option_value, "1") == 0) {
			value = MONGO_SSL_ENABLE;
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'ssl': true");
		} else if (strcasecmp(option_value, "false") == 0 || strcmp(option_value, "0") == 0) {
			value = MONGO_SSL_DISABLE;
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'ssl': false");
		} else if (strcasecmp(option_value, "prefer") == 0 || atoi(option_value) == MONGO_SSL_PREFER) {
			/* FIXME: MongoDB doesn't support "connection promotion" to SSL at
			 * the moment, so we can't support this option properly */
			value = MONGO_SSL_PREFER;
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'ssl': prefer");
			*error_message = strdup("SSL=prefer is currently not supported by mongod");
			return 3;
		} else {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'ssl': '%s'", option_name);
			*error_message = strdup("SSL can only be 'true' or 'false'");
			return 3;
		}

		servers->options.ssl = value;
		return 0;
	}

	if (strcasecmp(option_name, "timeout") == 0) {
		int value = atoi(option_value);

		if (servers->options.connectTimeoutMS) {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Replacing previously set value for 'connectTimeoutMS' (%d)", servers->options.connectTimeoutMS);
		}
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'timeout' ('connectTimeoutMS'): %d", value);
		servers->options.connectTimeoutMS = value;
		return -1;
	}

	if (strcasecmp(option_name, "username") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'username': '******'", option_value);
		for (i = 0; i < servers->count; i++) {
			if (servers->server[i]->username) {
				free(servers->server[i]->username);
			}
			servers->server[i]->username = strdup(option_value);
			/* Use "admin" as the default db if none selected yet. It is okay
			 * if it is set in a later option, as we first always free the
			 * value before setting it anyway. */
			if (!servers->server[i]->db) {
				servers->server[i]->db = strdup("admin");
				if (!servers->server[i]->authdb) {
					/* Admin users always authenticate on the admin db, even when
					 * using other databases */
					servers->server[i]->authdb = strdup("admin");
				}
			}
		}
		return 0;
	}

	if (strcasecmp(option_name, "w") == 0) {
		/* Rough check to see whether this is a numeric string or not */
		char *endptr;
		long tmp_value;

		if (servers->options.default_wstring != NULL) {
			free(servers->options.default_wstring);
		}

		/* Reassign defaults before we set default_w or default_wstring */
		servers->options.default_w = -1;
		servers->options.default_wstring = NULL;

		tmp_value = strtol(option_value, &endptr, 10);
		/* If no invalid character is found (endptr == 0), we consider the
		 * option value as a number */
		if (!*endptr) {
			servers->options.default_w = tmp_value;
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'w': %d", servers->options.default_w);
			if (servers->options.default_w < 0) {
				*error_message = strdup("The value of 'w' needs to be 0 or higher (or a string).");
				return 3;
			}
		} else {
			servers->options.default_wstring = strdup(option_value);
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'w': '%s'", servers->options.default_wstring);
		}
		return 0;
	}

	if (strcasecmp(option_name, "wTimeout") == 0) {
		int value = atoi(option_value);

		if (servers->options.default_wtimeout != -1) {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Replacing previously set value for 'wTimeoutMS' (%d)", servers->options.default_wtimeout);
		}
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'wTimeout' ('wTimeoutMS'): %d", value);
		servers->options.default_wtimeout = value;
		return 0;
	}

	if (strcasecmp(option_name, "wTimeoutMS") == 0) {
		int value = atoi(option_value);

		if (servers->options.default_wtimeout != -1) {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Replacing previously set value for 'wTimeoutMS' (%d)", servers->options.default_wtimeout);
		}
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'wTimeoutMS': %d", value);
		servers->options.default_wtimeout = value;
		return 0;
	}

	*error_message = malloc(256);
	snprintf(*error_message, 256, "- Found unknown connection string option '%s' with value '%s'", option_name, option_value);
	mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Found unknown connection string option '%s' with value '%s'", option_name, option_value);
	return 2;
}
Ejemplo n.º 2
0
/* Sets server options.
 * Returns 0 if it worked, 2 if the option didn't exist, 3 on logical errors.
 * On logical errors, the error_message will be populated with the reason.
 */
int mongo_store_option(mongo_con_manager *manager, mongo_servers *servers, char *option_name, char *option_value, char **error_message)
{
	int i;

	if (strcasecmp(option_name, "replicaSet") == 0) {
		if (servers->options.repl_set_name) {
			/* Free the already existing one */
			free(servers->options.repl_set_name);
			servers->options.repl_set_name = NULL; /* We reset it as not all options set a string as replset name */
		}

		if (option_value && *option_value) {
			/* We explicitly check for the stringified version of "true" here,
			 * as "true" has a special meaning. It does not mean that the
			 * replicaSet name is "1". */
			if (strcmp(option_value, "1") != 0) {
				servers->options.repl_set_name = strdup(option_value);
				mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'replicaSet': '%s'", option_value);

				/* Associate the given replica set name with all the server definitions from the seed */
				for (i = 0; i < servers->count; i++) {
					if (servers->server[i]->repl_set_name) {
						free(servers->server[i]->repl_set_name);
					}
					servers->server[i]->repl_set_name = strdup(option_value);
				}
			} else {
				mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Found option 'replicaSet': true - Expected the name of the replica set");
			}
			servers->options.con_type = MONGO_CON_TYPE_REPLSET;
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Switching connection type: REPLSET");
		}
		return 0;
	}
	if (strcasecmp(option_name, "username") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'username': '******'", option_value);
		for (i = 0; i < servers->count; i++) {
			if (servers->server[i]->username) {
				free(servers->server[i]->username);
			}
			servers->server[i]->username = strdup(option_value);
			/* Use "admin" as the default db if none selected yet. It is okay
			 * if it is set in a later option, as we first always free the
			 * value before setting it anyway. */
			if (!servers->server[i]->db) {
				servers->server[i]->db = strdup("admin");
				/* Admin users always authenticate on the admin db, even when using other databases */
				servers->server[i]->authdb = strdup("admin");
			}
		}
		return 0;
	}
	if (strcasecmp(option_name, "password") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'password': '******'", option_value);
		for (i = 0; i < servers->count; i++) {
			if (servers->server[i]->password) {
				free(servers->server[i]->password);
			}
			servers->server[i]->password = strdup(option_value);
		}
		return 0;
	}
	if (strcasecmp(option_name, "db") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'db': '%s'", option_value);
		for (i = 0; i < servers->count; i++) {
			if (servers->server[i]->db) {
				free(servers->server[i]->db);
				/* Free the authdb too as it defaulted to 'admin' when no db was passed as the connection string */
				free(servers->server[i]->authdb);
				servers->server[i]->authdb = NULL;
			}
			servers->server[i]->db = strdup(option_value);
		}
		return 0;
	}
	if (strcasecmp(option_name, "authSource") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'authSource': '%s'", option_value);
		for (i = 0; i < servers->count; i++) {
			if (servers->server[i]->authdb) {
				free(servers->server[i]->authdb);
			}
			servers->server[i]->authdb = strdup(option_value);
		}
		return 0;
	}
	if (strcasecmp(option_name, "authMechanism") == 0) {
		int mechanism;

		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'authMechanism': '%s'", option_value);
		if (strcasecmp(option_value, "MONGODB-CR") == 0) {
			mechanism = MONGO_AUTH_MECHANISM_MONGODB_CR;
		} else if (strcasecmp(option_value, "GSSAPI") == 0) {
			/* FIXME: GSSAPI isn't implemented yet */
			mechanism = MONGO_AUTH_MECHANISM_GSSAPI;
			*error_message = strdup("The authMechanism 'GSSAPI' is currently not supported. Only MONGODB-CR is available.");
			return 3;
		} else {
			int len = strlen(option_value) + sizeof("The authMechanism '' does not exist.");

			*error_message = malloc(len + 1);
			snprintf(*error_message, len, "The authMechanism '%s' does not exist.", option_value);
			return 3;
		}
		for (i = 0; i < servers->count; i++) {
			servers->server[i]->mechanism = mechanism;
		}
		return 0;
	}

	if (strcasecmp(option_name, "slaveOkay") == 0) {
		if (strcasecmp(option_value, "true") == 0 || *option_value == '1') {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'slaveOkay': true");
			if (servers->read_pref.type != MONGO_RP_PRIMARY || servers->read_pref.tagset_count) {
				/* the server already has read preferences configured, but we're still
				 * trying to set slave okay. The spec says that's an error */
				*error_message = strdup("You can not use both slaveOkay and read-preferences. Please switch to read-preferences.");
				return 3;
			} else {
				/* Old style option, that needs to be removed. For now, spec dictates
				 * it needs to be ReadPreference=SECONDARY_PREFERRED */
				servers->read_pref.type = MONGO_RP_SECONDARY_PREFERRED;
			}
			return 0;
		}

		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'slaveOkay': false");
		return 0;
	}
	if (strcasecmp(option_name, "readPreference") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'readPreference': '%s'", option_value);
		if (strcasecmp(option_value, "primary") == 0) {
			servers->read_pref.type = MONGO_RP_PRIMARY;
		} else if (strcasecmp(option_value, "primaryPreferred") == 0) {
			servers->read_pref.type = MONGO_RP_PRIMARY_PREFERRED;
		} else if (strcasecmp(option_value, "secondary") == 0) {
			servers->read_pref.type = MONGO_RP_SECONDARY;
		} else if (strcasecmp(option_value, "secondaryPreferred") == 0) {
			servers->read_pref.type = MONGO_RP_SECONDARY_PREFERRED;
		} else if (strcasecmp(option_value, "nearest") == 0) {
			servers->read_pref.type = MONGO_RP_NEAREST;
		} else {
			int len = strlen(option_value) + sizeof("The readPreference value '' is not supported.");

			*error_message = malloc(len + 1);
			snprintf(*error_message, len, "The readPreference value '%s' is not supported.", option_value);
			return 3;
		}
		return 0;
	}
	if (strcasecmp(option_name, "readPreferenceTags") == 0) {
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'readPreferenceTags': '%s'", option_value);
		return parse_read_preference_tags(manager, servers, option_value, error_message);
	}

	if (strcasecmp(option_name, "timeout") == 0) {
		int value = atoi(option_value);

		if (servers->options.connectTimeoutMS) {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Replacing previously set value for 'connectTimeoutMS' (%d)", servers->options.connectTimeoutMS);
		}
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'timeout' ('connectTimeoutMS'): %d", value);
		servers->options.connectTimeoutMS = value;
		return 0;
	}

	if (strcasecmp(option_name, "connectTimeoutMS") == 0) {
		int value = atoi(option_value);

		if (servers->options.connectTimeoutMS) {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Replacing previously set value for 'connectTimeoutMS' (%d)", servers->options.connectTimeoutMS);
		}
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'connectTimeoutMS': %d", value);
		servers->options.connectTimeoutMS = value;
		return 0;
	}

	if (strcasecmp(option_name, "socketTimeoutMS") == 0) {
		int value = atoi(option_value);

		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'socketTimeoutMS': %d", value);
		servers->options.socketTimeoutMS = value;
		return 0;
	}

	if (strcasecmp(option_name, "w") == 0) {
		/* Rough check to see whether this is a numeric string or not */
		if ((option_value[0] >= '0' && option_value[0] <= '9') || option_value[0] == '-') {
			servers->options.default_w = atoi(option_value);
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'w': %d", servers->options.default_w);
			if (servers->options.default_w < 0) {
				*error_message = strdup("The value of 'w' needs to be 0 or higher (or a string).");
				return 3;
			}
		} else {
			servers->options.default_w = 1;
			servers->options.default_wstring = strdup(option_value);
			mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'w': '%s'", servers->options.default_wstring);
		}
		return 0;
	}

	if (strcasecmp(option_name, "wTimeout") == 0) {
		int value = atoi(option_value);

		if (servers->options.default_wtimeout != -1) {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Replacing previously set value for 'wTimeoutMS' (%d)", servers->options.default_wtimeout);
		}
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'wTimeout' ('wTimeoutMS'): %d", value);
		servers->options.default_wtimeout = value;
		return 0;
	}

	if (strcasecmp(option_name, "wTimeoutMS") == 0) {
		int value = atoi(option_value);

		if (servers->options.default_wtimeout != -1) {
			mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Replacing previously set value for 'wTimeoutMS' (%d)", servers->options.default_wtimeout);
		}
		mongo_manager_log(manager, MLOG_PARSE, MLOG_INFO, "- Found option 'wTimeoutMS': %d", value);
		servers->options.default_wtimeout = value;
		return 0;
	}

	*error_message = malloc(256);
	snprintf(*error_message, 256, "- Found unknown connection string option '%s' with value '%s'", option_name, option_value);
	mongo_manager_log(manager, MLOG_PARSE, MLOG_WARN, "- Found unknown connection string option '%s' with value '%s'", option_name, option_value);
	return 2;
}