示例#1
0
文件: lutil.c 项目: LLNL/lustre
int liblustre_init_current(char *comm)
{
    current = malloc(sizeof(*current));
    if (!current) {
        CERROR("Not enough memory\n");
        return -ENOMEM;
    }

    strncpy(current->comm, comm, sizeof(current->comm));
    current->pid = getpid();
    current->gid = getgid();
    current->fsuid = geteuid();
    current->fsgid = getegid();
    memset(&current->pending, 0, sizeof(current->pending));

    current->max_groups = sysconf(_SC_NGROUPS_MAX);
    current->groups = malloc(sizeof(gid_t) * current->max_groups);
    if (!current->groups) {
        CERROR("Not enough memory\n");
        return -ENOMEM;
    }
    current->ngroups = getgroups(current->max_groups, current->groups);
    if (current->ngroups < 0) {
        perror("Error getgroups");
        return -EINVAL;
    }

    init_capability(&current->cap_effective);

    return 0;
}
示例#2
0
struct amf_cluster *amf_config_read (char **error_string)
{
	char buf[1024];
	char *line;
	FILE *fp;
	const char *filename;
	amf_object_type_t current_parse = AMF_NONE;
	int line_number = 0;
	char *loc;
	int i;
	struct amf_cluster       *cluster;
	struct amf_application   *app = 0;
	struct amf_node          *node = 0;
	struct amf_sg            *sg = 0;
	struct amf_su            *su = 0;
	struct amf_comp          *comp = 0;
	struct amf_si            *si = 0;
	struct amf_si_ranked_su  *si_ranked_su = 0;
	struct amf_si_dependency *si_dependency = 0;
	struct amf_healthcheck   *healthcheck = 0;
	struct amf_csi           *csi = 0;
	struct amf_csi_attribute *attribute = 0;
	SaStringT                 env_var;
	int                       su_cnt = 0;
	int                       sg_cnt = 0;
	int                       comp_env_var_cnt = 0;
	int                       comp_cs_type_cnt = 0;
	int                       csi_attr_cnt = 0;
	int                       csi_dependencies_cnt = 0;
	const char                *error_reason = NULL;
	char                     *value;
	filename = getenv ("COROSYNC_AMF_CONFIG_FILE");
	if (!filename) {
		filename = COROSYSCONFDIR "/amf.conf";
	}

	fp = fopen (filename, "r");
	if (fp == 0) {
		sprintf (buf, "Can't read %s file reason = (%s).\n",
			filename, strerror (errno));
		*error_string = buf;
		return NULL;
	}

	cluster = amf_cluster_new ();
	assert (cluster != NULL);

	while (fgets (buf, 255, fp)) {
		line_number += 1;
		line = buf;
		if (strlen(line) > 0) {
			line[strlen(line) - 1] = '\0';
		}
		/*
		 * Clear out comments and empty lines
		 */
		if (line[0] == '#' || line[0] == '\0' || line[0] == '\n') {
			continue;
		}

		/*
		 * Clear out white space and tabs
		 */
		for (i = strlen (line) - 1; i > -1; i--) {
			if (line[i] == '\t' || line[i] == ' ') {
				line[i] = '\0';
			} else {
				break;
			}
		}

		/* Trim whitespace from beginning of string */
		line = rm_beginning_ws(line);
		error_reason = line;
		error_reason = NULL;
		switch (current_parse) {
		case AMF_NONE:
			if ((loc = strstr_rs (line, "safAmfCluster=")) != 0) {
				setSaNameT (&cluster->name, trim_str (loc));
				current_parse = AMF_CLUSTER;
			} else {
				goto parse_error;
			}
			break;

		case AMF_CLUSTER:
			if ((loc = strstr_rs (line, "saAmfClusterClmCluster=")) != 0) {
				setSaNameT (&cluster->saAmfClusterClmCluster, loc);
			} else if ((loc = strstr_rs (line, "saAmfClusterStartupTimeout=")) != 0) {
				cluster->saAmfClusterStartupTimeout = atol(loc);
			} else if ((loc = strstr_rs (line, "safAmfNode=")) != 0) {
				node = amf_node_new (cluster, trim_str (loc));
				cluster->node_head = node;
				current_parse = AMF_NODE;
			} else if ((loc = strstr_rs (line, "safApp=")) != 0) {
				app = amf_application_new (cluster);
				setSaNameT (&app->name, trim_str (loc));
				current_parse = AMF_APPLICATION;
				sg_cnt = 0;
			} else if (strstr_rs (line, "}")) {
				if (cluster->saAmfClusterStartupTimeout == -1) {
					error_reason = "saAmfClusterStartupTimeout missing";
					goto parse_error;
				}
				/* spec: set to default value if zero */
				if (cluster->saAmfClusterStartupTimeout == 0) {
					cluster->saAmfClusterStartupTimeout = COROSYNC_CLUSTER_STARTUP_TIMEOUT;
				}
				current_parse = AMF_NONE;
			} else {
				goto parse_error;
			}
			break;

		case AMF_NODE:
			if ((loc = strstr_rs (line, "saAmfNodeSuFailOverProb=")) != 0) {
				node->saAmfNodeSuFailOverProb = atol(loc);
			} else if ((loc = strstr_rs (line, "saAmfNodeSuFailoverMax=")) != 0) {
				node->saAmfNodeSuFailoverMax = atol(loc);
			} else if ((loc = strstr_rs (line, "saAmfNodeClmNode=")) != 0) {
				setSaNameT (&node->saAmfNodeClmNode, trim_str (loc));
			} else if ((loc = strstr_rs (line, "saAmfNodeAutoRepair=")) != 0) {
				if (strcmp (loc, "true") == 0) {
					node->saAmfNodeAutoRepair = SA_TRUE;
				} else if (strcmp (loc, "false") == 0) {
					node->saAmfNodeAutoRepair = SA_FALSE;
				} else {
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfNodeRebootOnTerminationFailure=")) != 0) {
				if (strcmp (loc, "true") == 0) {
					node->saAmfNodeRebootOnTerminationFailure = SA_TRUE;
				} else if (strcmp (loc, "false") == 0) {
					node->saAmfNodeRebootOnTerminationFailure = SA_FALSE;
				} else {
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfNodeRebootOnInstantiationFailure=")) != 0) {
				if (strcmp (loc, "true") == 0) {
					node->saAmfNodeRebootOnInstantiationFailure = SA_TRUE;
				} else if (strcmp (loc, "false") == 0) {
					node->saAmfNodeRebootOnInstantiationFailure = SA_FALSE;
				} else {
					goto parse_error;
				}
			} else if (strstr_rs (line, "}")) {
				if (node->saAmfNodeSuFailOverProb == -1) {
					error_reason = "saAmfNodeSuFailOverProb missing";
					goto parse_error;
				}
				if (node->saAmfNodeSuFailoverMax == ~0) {
					error_reason = "saAmfNodeSuFailoverMax missing";
					goto parse_error;
				}
				if (node->saAmfNodeClmNode.length == 0) {
					error_reason = "saAmfNodeClmNode missing";
					goto parse_error;
				}
				current_parse = AMF_CLUSTER;
			} else {
				goto parse_error;
			}
			break;

		case AMF_APPLICATION:
			if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
				app->clccli_path = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "safSg=")) != 0) {
				sg = amf_sg_new (app, trim_str (loc));
				sg_cnt++;
				sg->recovery_scope.comp = NULL;
				sg->recovery_scope.event_type = 0;
				sg->recovery_scope.node = NULL;
				sg->recovery_scope.sis = NULL;
				sg->recovery_scope.sus = NULL;
				current_parse = AMF_SG;
				su_cnt = 0;
			} else if ((loc = strstr_rs (line, "safSi=")) != 0) {
				si = amf_si_new (app, trim_str (loc));
				current_parse = AMF_SI;
			} else if ((loc = strstr_rs (line, "safCSType=")) != 0) {
				current_parse = AMF_CS_TYPE;
			} else if (strstr_rs (line, "}")) {
				if (sg_cnt == 1) {
					for (si = app->si_head; si != NULL; si = si->next) {
						memcpy (&si->saAmfSIProtectedbySG, &sg->name,
							sizeof (SaNameT));
					}
				} else {
					for (si = app->si_head; si != NULL; si = si->next) {
						if (si->saAmfSIProtectedbySG.length == 0) {
							error_reason = "saAmfSIProtectedbySG not set in SI"
								", needed when several SGs are specified.";
							goto parse_error;
						}
					}
				}
				current_parse = AMF_CLUSTER;
			} else {
				goto parse_error;
			}
			break;

		case AMF_SG:
			if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
				sg->clccli_path = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "saAmfSGRedundancyModel=")) != 0) {
				if (strcmp (loc, "2n") == 0) {
					sg->saAmfSGRedundancyModel = SA_AMF_2N_REDUNDANCY_MODEL;
				} else if (strcmp (loc, "nplusm") == 0) {
					sg->saAmfSGRedundancyModel = SA_AMF_NPM_REDUNDANCY_MODEL;
				} else if (strcmp (loc, "nway") == 0) {
					error_reason = "nway redundancy model not supported";
					goto parse_error;
				} else if (strcmp (loc, "nwayactive") == 0) {
					error_reason = "nway active redundancy model not supported";
					goto parse_error;
				} else if (strcmp (loc, "noredundancy") == 0) {
					sg->saAmfSGRedundancyModel = SA_AMF_NO_REDUNDANCY_MODEL;
				} else {
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfSGNumPrefActiveSUs=")) != 0) {
				sg->saAmfSGNumPrefActiveSUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGNumPrefStandbySUs=")) != 0) {
				sg->saAmfSGNumPrefStandbySUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGNumPrefInserviceSUs=")) != 0) {
				sg->saAmfSGNumPrefInserviceSUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGNumPrefAssignedSUs=")) != 0) {
				sg->saAmfSGNumPrefAssignedSUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGMaxActiveSIsperSUs=")) != 0) {
				sg->saAmfSGMaxActiveSIsperSUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGMaxStandbySIsperSUs=")) != 0) {
				sg->saAmfSGMaxStandbySIsperSUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGCompRestartProb=")) != 0) {
				sg->saAmfSGCompRestartProb = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGCompRestartMax=")) != 0) {
				sg->saAmfSGCompRestartMax = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGSuRestartProb=")) != 0) {
				sg->saAmfSGSuRestartProb = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGSuRestartMax=")) != 0) {
				sg->saAmfSGSuRestartMax = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGAutoAdjustProb=")) != 0) {
				sg->saAmfSGAutoAdjustProb = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGAutoRepair=")) != 0) {
				sg->saAmfSGAutoRepair = atoi (loc);
			} else if ((loc = strstr_rs (line, "safSu=")) != 0) {
				su = amf_su_new (sg, trim_str (loc));
				su_cnt++;
				current_parse = AMF_SU;
			} else if (strstr_rs (line, "}")) {
				if (sg->saAmfSGRedundancyModel == 0) {
					error_reason = "saAmfSGRedundancyModel missing";
					goto parse_error;
				}
				if (sg->saAmfSGCompRestartProb == -1) {
					error_reason = "saAmfSGCompRestartProb missing";
					goto parse_error;
				}
				if (sg->saAmfSGCompRestartMax == ~0) {
					error_reason = "saAmfSGCompRestartMax missing";
					goto parse_error;
				}
				if (sg->saAmfSGSuRestartProb == -1) {
					error_reason = "saAmfSGSuRestartProb missing";
					goto parse_error;
				}
				if (sg->saAmfSGSuRestartMax == ~0) {
					error_reason = "saAmfSGSuRestartMax missing";
					goto parse_error;
				}
				if (sg->saAmfSGAutoAdjustProb == -1) {
					error_reason = "saAmfSGAutoAdjustProb missing";
					goto parse_error;
				}
				if (sg->saAmfSGAutoRepair > 1) {
					error_reason = "saAmfSGAutoRepair erroneous";
					goto parse_error;
				}
				if (sg->saAmfSGNumPrefInserviceSUs == ~0) {
					sg->saAmfSGNumPrefInserviceSUs = su_cnt;
				}
				if (sg->saAmfSGNumPrefAssignedSUs == ~0) {
					sg->saAmfSGNumPrefAssignedSUs =
						sg->saAmfSGNumPrefInserviceSUs;
				}
				current_parse = AMF_APPLICATION;
			} else {
				goto parse_error;
			}
			break;

		case AMF_SU:
			if ((loc = strstr_rs (line, "saAmfSUNumComponents=")) != 0) {
				su->saAmfSUNumComponents = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSUIsExternal=")) != 0) {
				su->saAmfSUIsExternal = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSUFailover=")) != 0) {
				su->saAmfSUFailover = atoi (loc);
			} else if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
				su->clccli_path = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "saAmfSUHostedByNode=")) != 0) {
				setSaNameT (&su->saAmfSUHostedByNode, loc);
			} else if ((loc = strstr_rs (line, "safComp=")) != 0) {
				comp = amf_comp_new (su, trim_str (loc));
				comp_env_var_cnt = 0;
				comp_cs_type_cnt = 0;
				current_parse = AMF_COMP;
			} else if (strstr_rs (line, "}")) {
				if (su->saAmfSUNumComponents == 0) {
					error_reason = "saAmfSUNumComponents missing";
					goto parse_error;
				}
				if (su->saAmfSUIsExternal > 1) {
					error_reason = "saAmfSUIsExternal erroneous";
					goto parse_error;
				}
				if (su->saAmfSUFailover > 1) {
					error_reason = "saAmfSUFailover erroneous";
					goto parse_error;
				}
				if (strcmp ((char*)su->saAmfSUHostedByNode.value, "") == 0) {
					error_reason = "saAmfSUHostedByNode missing";
					goto parse_error;
				}
				current_parse = AMF_SG;
			} else {
				goto parse_error;
			}
			break;

		case AMF_COMP:
			if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
				comp->clccli_path = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "saAmfCompCsTypes{")) != 0) {
				current_parse = AMF_COMP_CS_TYPE;
			} else if ((loc = strstr_rs(line, "saAmfCompCategory=")) != 0) {
				if (init_category(comp, loc) != 0) {
					error_reason = "unknown category";
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfCompCapability=")) != 0) {
				if (init_capability(comp, loc) != 0) {
					error_reason = "unknown capability model";
					goto parse_error;
				}
			} else if ((loc = strstr_rs(line, "saAmfCompNumMaxActiveCsi=")) != 0) {
				comp->saAmfCompNumMaxActiveCsi = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompNumMaxStandbyCsi=")) != 0) {
				comp->saAmfCompNumMaxStandbyCsi = atol (loc);
			} else if ((loc = strstr_rs (line, "saAmfCompCmdEnv{")) != 0) {
				current_parse = AMF_COMP_ENV_VAR;
			} else if ((loc = strstr_rs(line, "saAmfCompDefaultClcCliTimeout=")) != 0) {
				comp->saAmfCompDefaultClcCliTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompDefaultCallbackTimeOut=")) != 0) {
				comp->saAmfCompDefaultCallbackTimeOut = atol (loc);
			} else if ((loc = strstr_rs (line, "saAmfCompInstantiateCmdArgv=")) != 0) {
				comp->saAmfCompInstantiateCmdArgv = amf_strdup(loc);
			} else if ((loc = strstr_rs ( line, "saAmfCompInstantiateCmd=")) != 0) {
				comp->saAmfCompInstantiateCmd = amf_strdup(loc);
			} else if ((loc = strstr_rs(line, "saAmfCompInstantiateTimeout=")) != 0) {
				comp->saAmfCompInstantiateTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompInstantiationLevel=")) != 0) {
				comp->saAmfCompInstantiationLevel = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompNumMaxInstantiateWithoutDelay=")) != 0) {
				comp->saAmfCompNumMaxInstantiateWithoutDelay = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompNumMaxInstantiateWithDelay=")) != 0) {
				comp->saAmfCompNumMaxInstantiateWithDelay = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompDelayBetweenInstantiateAttempts=")) != 0) {
				comp->saAmfCompDelayBetweenInstantiateAttempts = atol (loc);
			} else if ((loc = strstr_rs (line, "saAmfCompTerminateCmdArgv=")) != 0) {
				comp->saAmfCompTerminateCmdArgv = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "saAmfCompTerminateCmd=")) != 0) {
				comp->saAmfCompTerminateCmd = amf_strdup(loc);
			} else if ((loc = strstr_rs(line, "saAmfCompTerminateTimeout=")) != 0) {
				comp->saAmfCompTerminateTimeout = atol (loc);
			} else if ((loc = strstr_rs (line, "saAmfCompCleanupCmdArgv=")) != 0) {
				comp->saAmfCompCleanupCmdArgv = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "saAmfCompCleanupCmd=")) != 0) {
				comp->saAmfCompCleanupCmd = amf_strdup(loc);
			} else if ((loc = strstr_rs(line, "saAmfCompCleanupTimeout=")) != 0) {
				comp->saAmfCompCleanupTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompTerminateCallbackTimeout=")) != 0) {
				comp->saAmfCompTerminateCallbackTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompCSISetCallbackTimeout=")) != 0) {
				comp->saAmfCompCSISetCallbackTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompQuiescingCompleteTimeout=")) != 0) {
				comp->saAmfCompQuiescingCompleteTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompCSIRmvCallbackTimeout=")) != 0) {
				comp->saAmfCompCSIRmvCallbackTimeout = atol (loc);
			} else if ((loc = strstr_rs (line, "saAmfCompRecoveryOnError=")) != 0) {
				if (init_recovery_on_error (comp, loc) != 0) {
					error_reason = "bad value";
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfCompDisableRestart=")) != 0) {
				if (strcmp (loc, "false") == 0) {
					comp->saAmfCompDisableRestart = SA_FALSE;
				} else if (strcmp (loc, "true") == 0) {
					comp->saAmfCompDisableRestart = SA_TRUE;
				} else {
					error_reason = "bad value";
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfCompProxyCsi=")) != 0) {
				setSaNameT (&comp->saAmfCompProxyCsi, loc);
			} else if ((loc = strstr_rs (line, "safHealthcheckKey=")) != 0) {
				healthcheck = calloc (1, sizeof (struct amf_healthcheck));
				healthcheck->next = comp->healthcheck_head;
				comp->healthcheck_head = healthcheck;
				healthcheck->comp = comp;
				strcpy ((char *)healthcheck->safHealthcheckKey.key, trim_str (loc));
				healthcheck->safHealthcheckKey.keyLen = strlen (loc);
				current_parse = AMF_HEALTHCHECK;
			} else if (strstr_rs (line, "}")) {
				if (comp->saAmfCompCategory == 0) {
					error_reason = "category missing";
					goto parse_error;
				}
				if (comp->saAmfCompCapability == 0) {
					error_reason = "capability model missing";
					goto parse_error;
				}
				if (comp->saAmfCompCategory == SA_AMF_COMP_SA_AWARE) {
					comp->comptype = clc_component_sa_aware;
				} else if (comp->saAmfCompCategory == SA_AMF_COMP_PROXY) {
					if (comp->saAmfCompCapability == SA_AMF_COMP_NON_PRE_INSTANTIABLE) {
						comp->comptype = clc_component_proxied_non_pre;
					} else {
						comp->comptype = clc_component_proxied_pre;
					}
				} else if (comp->saAmfCompCategory == SA_AMF_COMP_LOCAL) {
					comp->comptype = clc_component_non_proxied_non_sa_aware;
				}
				if (comp->saAmfCompNumMaxActiveCsi == 0) {
					error_reason = "saAmfCompNumMaxActiveCsi missing";
					goto parse_error;
				}
				if (comp->saAmfCompNumMaxStandbyCsi == 0) {
					error_reason = "saAmfCompNumMaxStandbyCsi missing";
					goto parse_error;
				}
				if (comp->saAmfCompDefaultClcCliTimeout == 0) {
					error_reason = "saAmfCompDefaultClcCliTimeout missing or erroneous";
					goto parse_error;
				}
				if (comp->saAmfCompDefaultCallbackTimeOut == 0) {
					error_reason = "saAmfCompDefaultCallbackTimeOut missing or erroneous";
					goto parse_error;
				}
				if (comp->saAmfCompRecoveryOnError == 0) {
					error_reason = "saAmfCompRecoveryOnError missing";
					goto parse_error;
				}
				post_init_comp (comp);
				current_parse = AMF_SU;
			} else {
				error_reason = line;
				goto parse_error;
			}
			break;

		case AMF_COMP_CS_TYPE:
			if (strstr_rs (line, "}")) {
				current_parse = AMF_COMP;
			} else {
				comp_cs_type_cnt++;
				comp->saAmfCompCsTypes = realloc (comp->saAmfCompCsTypes,
					(comp_cs_type_cnt + 1) * sizeof(SaNameT));
				comp->saAmfCompCsTypes[comp_cs_type_cnt] = NULL;
				comp->saAmfCompCsTypes[comp_cs_type_cnt - 1] = amf_malloc (sizeof(SaNameT));
				setSaNameT (comp->saAmfCompCsTypes[comp_cs_type_cnt - 1], line);
			}
			break;

		case AMF_COMP_ENV_VAR:
			if (strstr_rs (line, "}")) {
				current_parse = AMF_COMP;
			} else if ((loc = strchr (line, '=')) != 0) {
				comp_env_var_cnt++;
				comp->saAmfCompCmdEnv = realloc (comp->saAmfCompCmdEnv,
					(comp_env_var_cnt + 1) * sizeof(SaStringT));
				comp->saAmfCompCmdEnv[comp_env_var_cnt] = NULL;
				env_var = comp->saAmfCompCmdEnv[comp_env_var_cnt - 1] = amf_strdup(line);
			} else {
				goto parse_error;
			}
			break;

		case AMF_HEALTHCHECK:
			if ((loc = strstr_rs (line, "saAmfHealthcheckPeriod=")) != 0) {
				healthcheck->saAmfHealthcheckPeriod = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfHealthcheckMaxDuration=")) != 0) {
				healthcheck->saAmfHealthcheckMaxDuration = atoi (loc);
			} else if (strstr_rs (line, "}")) {
				current_parse = AMF_COMP;
			} else {
				goto parse_error;
			}
			break;

		case AMF_SI:
			if ((loc = strstr_rs (line, "safRankedSu=")) != 0) {
				si_ranked_su = calloc (1, sizeof(struct amf_si_ranked_su));
				si_ranked_su->si_next = si->ranked_sus;
				si->ranked_sus = si_ranked_su;
				si_ranked_su->si = si;
				setSaNameT (&si_ranked_su->name, trim_str (loc));
				current_parse = AMF_SI_RANKED_SU;
			} else if ((loc = strstr_rs (line, "safDepend=")) != 0) {
				si_dependency = calloc (1, sizeof(struct amf_si_dependency));
				si_dependency->next = si->depends_on;
				si->depends_on = si_dependency;
				setSaNameT (&si_dependency->name, trim_str (loc));
				current_parse = AMF_SI_DEPENDENCY;
			} else if ((loc = strstr_rs (line, "safCsi=")) != 0) {
				csi = calloc (1, sizeof(struct amf_csi));
				csi->next = si->csi_head;
				si->csi_head = csi;
				csi->si = si;
				setSaNameT (&csi->name, trim_str (loc));
				current_parse = AMF_CSI;
			} else if ((loc = strstr_rs (line, "saAmfSIProtectedbySG=")) != 0) {
				setSaNameT (&si->saAmfSIProtectedbySG, loc);
			} else if ((loc = strstr_rs (line, "saAmfSIRank=")) != 0) {
				si->saAmfSIRank = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSINumCSIs=")) != 0) {
				si->saAmfSINumCSIs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSIPrefActiveAssignments=")) != 0) {
				si->saAmfSIPrefActiveAssignments = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSIPrefActiveAssignments=")) != 0) {
				si->saAmfSIPrefStandbyAssignments = atoi (loc);
			} else if (strstr_rs (line, "}")) {
				if (si->saAmfSINumCSIs == 0) {
					error_reason = "saAmfSINumCSIs missing";
					goto parse_error;
				}
				current_parse = AMF_APPLICATION;
			} else {
				goto parse_error;
			}
			break;

		case AMF_SI_RANKED_SU:
			if ((loc = strstr_rs (line, "saAmfRank=")) != 0) {
				si_ranked_su->saAmfRank = atoi (loc);
			} else if (strstr_rs (line, "}")) {
				current_parse = AMF_SI;
			} else {
				goto parse_error;
			}
			break;

		case AMF_SI_DEPENDENCY:
			if ((loc = strstr_rs (line, "saAmfToleranceTime=")) != 0) {
				si_dependency->saAmfToleranceTime = atoi (loc);
			} else if (strstr_rs (line, "}")) {
				current_parse = AMF_SI;
			} else {
				goto parse_error;
			}
			break;

		case AMF_CSI:
			if ((loc = strstr_rs (line, "saAmfCSTypeName=")) != 0) {
				setSaNameT (&csi->saAmfCSTypeName, loc);
			} else if ((loc = strstr_rs (line, "safCSIAttr=")) != 0) {
				attribute = calloc (1, sizeof(struct amf_csi_attribute));
				attribute->next = csi->attributes_head;
				csi->attributes_head = attribute;
				attribute->name = amf_strdup(loc);
				csi_attr_cnt = 1;
				current_parse = AMF_CSI_ATTRIBUTE;
			} else if ((loc = strstr_rs (line, "saAmfCsiDependencies{")) != 0) {
				csi_dependencies_cnt = 0;
				current_parse = AMF_CSI_DEPENDENCIES;
			} else if (strstr_rs (line, "}")) {
				if (strcmp(getSaNameT(&csi->saAmfCSTypeName), "") == 0) {
					error_reason = "saAmfCSTypeName missing";
					goto parse_error;
				}
				current_parse = AMF_SI;
			} else {
				goto parse_error;
			}
			break;

		case AMF_CSI_DEPENDENCIES:
			if (strstr_rs (line, "}")) {
				current_parse = AMF_CSI;
			} else if ((loc = strstr_rs (line, "saAmfCSIDependency=")) != 0) {
				csi_dependencies_cnt++;
				csi->saAmfCSIDependencies = realloc (csi->saAmfCSIDependencies,
					(csi_dependencies_cnt + 1) * sizeof(SaNameT));
				csi->saAmfCSIDependencies[csi_dependencies_cnt] = NULL;
				csi->saAmfCSIDependencies[csi_dependencies_cnt - 1] =
					amf_malloc (sizeof(SaNameT));
				setSaNameT (
					csi->saAmfCSIDependencies[csi_dependencies_cnt - 1], loc);
			} else {
				goto parse_error;
			}
			break;

		case AMF_CSI_ATTRIBUTE:
			if ((loc = strstr_rs (line, "}")) != 0) {
				current_parse = AMF_CSI;
			} else {
				value = rm_beginning_ws (line);
				attribute->value = realloc (attribute->value,
					sizeof (SaStringT) * (csi_attr_cnt + 1));
				attribute->value[csi_attr_cnt - 1] = amf_strdup(value);
				attribute->value[csi_attr_cnt] = NULL;
				csi_attr_cnt++;
			}
			break;

		case AMF_CS_TYPE:
			if ((loc = strstr_rs (line, "}")) != 0) {
				current_parse = AMF_APPLICATION;
			}
			break;

		default:
			error_reason = "Invalid state\n";
			goto parse_error;
			break;
		}
	}

	fclose (fp);

	sprintf (buf, "Successfully read AMF configuration file '%s'.\n", filename);
	*error_string = buf;

	return cluster;

parse_error:
	sprintf (buf, "parse error at %s: %d: %s\n",
		filename, line_number, error_reason);
	*error_string = buf;
	fclose (fp);
	return NULL;
}