Boolean_t mgmt_param_save2scf(tgt_node_t *node, char *target_name, int lun) { targ_scf_t *h = NULL; char *pgname = NULL; ssize_t max_name_len; tgt_node_t *n = NULL; Boolean_t status = False; h = mgmt_handle_init(); if (h == NULL) return (status); if (alloc_scf_name(&max_name_len, (void *)&pgname) == False) { goto error; } (void) snprintf(pgname, max_name_len, "param_%s_%d", target_name, lun); (void) pthread_mutex_lock(&scf_param_mutex); if (mgmt_transaction_start(h, pgname, "parameter") == True) { (void) scf_pg_delete(h->t_pg); (void) mgmt_transaction_end(h); } if (mgmt_transaction_start(h, pgname, "parameter") == True) { for (n = node->x_child; n; n = n->x_sibling) { if (n->x_child == NULL) { /* now n is node of basic property */ new_property(h, n); } } new_property(h, node->x_attr); n = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, n); tgt_node_free(n); n = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, n); tgt_node_free(n); (void) mgmt_transaction_end(h); } status = True; error: (void) pthread_mutex_unlock(&scf_param_mutex); free(pgname); mgmt_handle_fini(h); return (status); }
Boolean_t mgmt_param_save2scf(tgt_node_t *node, char *target_name, int lun) { targ_scf_t *h = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *iter = NULL; char pgname[64]; tgt_node_t *n = NULL; h = mgmt_handle_init(); if (h == NULL) return (False); snprintf(pgname, sizeof (pgname), "param_%s_%d", target_name, lun); (void) pthread_mutex_lock(&scf_param_mutex); if (mgmt_transaction_start(h, pgname, "parameter") == True) { scf_pg_delete(h->t_pg); mgmt_transaction_end(h); } if (mgmt_transaction_start(h, pgname, "parameter") == True) { for (n = node->x_child; n; n = n->x_sibling) { if (n->x_child == NULL) { /* now n is node of basic property */ new_property(h, n); } } new_property(h, node->x_attr); n = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, n); tgt_node_free(n); n = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, n); tgt_node_free(n); mgmt_transaction_end(h); } (void) pthread_mutex_unlock(&scf_param_mutex); return (True); error: (void) pthread_mutex_unlock(&scf_param_mutex); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); mgmt_handle_fini(h); return (False); }
Boolean_t mgmt_param_remove(char *target_name, int lun) { targ_scf_t *h = NULL; char *pgname = NULL; ssize_t max_name_len; Boolean_t status = False; h = mgmt_handle_init(); if (h == NULL) return (status); if (alloc_scf_name(&max_name_len, (void *)&pgname) == NULL) { goto error; } (void) snprintf(pgname, max_name_len, "param_%s_%d", target_name, lun); if (mgmt_transaction_start(h, pgname, "parameter") == True) { (void) scf_pg_delete(h->t_pg); (void) mgmt_transaction_end(h); status = True; } error: free(pgname); mgmt_handle_fini(h); return (status); }
Boolean_t mgmt_param_remove(char *target_name, int lun) { targ_scf_t *h = NULL; char pgname[64]; h = mgmt_handle_init(); if (h == NULL) return (False); snprintf(pgname, sizeof (pgname), "param_%s_%d", target_name, lun); if (mgmt_transaction_start(h, pgname, "parameter") == True) { scf_pg_delete(h->t_pg); mgmt_transaction_end(h); mgmt_handle_fini(h); return (True); } else { mgmt_handle_fini(h); return (False); } }
/* * this function tries to convert configuration in files into scf * it loads xml conf into node tree then dump them to scf with * mgmt_config_save2scf() * this function has 3 return values: * CONVERT_OK: successfully converted * CONVERT_INIT_NEW: configuration files dont exist, created a new scf entry * CONVERT_FAIL: some error occurred in conversion and no scf entry created. * In this case, user have to check files manually and try * conversion again. */ convert_ret_t mgmt_convert_conf() { targ_scf_t *h = NULL; xmlTextReaderPtr r; convert_ret_t ret = CONVERT_FAIL; int xml_fd = -1; int n; tgt_node_t *node = NULL; tgt_node_t *next = NULL; char path[MAXPATHLEN]; char *target = NULL; h = mgmt_handle_init(); if (h == NULL) return (CONVERT_FAIL); /* check main config in pgroup iscsitgt */ if (scf_service_get_pg(h->t_service, "iscsitgt", h->t_pg) == 0) { ret = CONVERT_OK; goto done; } /* check the conf files */ if (access(config_file, R_OK) != 0) { /* * if there is no configuration file, initialize * an empty scf entry */ if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) { ret = CONVERT_INIT_NEW; node = tgt_node_alloc(XML_ELEMENT_VERS, String, "1.0"); new_property(h, node); tgt_node_free(node); /* "daemonize" is set to true by default */ node = tgt_node_alloc(XML_ELEMENT_DBGDAEMON, String, "true"); new_property(h, node); tgt_node_free(node); node = NULL; node = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, node); tgt_node_free(node); node = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, node); tgt_node_free(node); mgmt_transaction_end(h); } else { syslog(LOG_ERR, "Creating empty entry failed"); ret = CONVERT_FAIL; goto done; } if (mgmt_transaction_start(h, "passwords", "application") == True) { node = tgt_node_alloc(ISCSI_READ_AUTHNAME, String, ISCSI_AUTH_READ); new_property(h, node); tgt_node_free(node); node = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, node); tgt_node_free(node); node = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, node); tgt_node_free(node); mgmt_transaction_end(h); } else { syslog(LOG_ERR, "Creating empty entry failed"); ret = CONVERT_FAIL; } goto done; } if ((xml_fd = open(config_file, O_RDONLY)) >= 0) r = (xmlTextReaderPtr)xmlReaderForFd(xml_fd, NULL, NULL, 0); if (r != NULL) { n = xmlTextReaderRead(r); while (n == 1) { if (tgt_node_process(r, &node) == False) { break; } n = xmlTextReaderRead(r); } if (n < 0) { syslog(LOG_ERR, "Parsing main config failed"); ret = CONVERT_FAIL; goto done; } main_config = node; (void) tgt_find_value_str(node, XML_ELEMENT_BASEDIR, &target_basedir); if (target_basedir == NULL) target_basedir = strdup(DEFAULT_TARGET_BASEDIR); /* Now convert targets' config if possible */ if (xml_fd != -1) (void) close(xml_fd); xmlTextReaderClose(r); xmlFreeTextReader(r); xmlCleanupParser(); r = NULL; xml_fd = -1; node = NULL; (void) snprintf(path, MAXPATHLEN, "%s/%s", target_basedir, "config.xml"); if ((xml_fd = open(path, O_RDONLY)) >= 0) r = (xmlTextReaderPtr)xmlReaderForFd(xml_fd, NULL, NULL, 0); if (r != NULL) { n = xmlTextReaderRead(r); while (n == 1) { if (tgt_node_process(r, &node) == False) { break; } n = xmlTextReaderRead(r); } if (n < 0) { syslog(LOG_ERR, "Parsing target conf failed"); ret = CONVERT_FAIL; goto done; } /* now combine main_config and node */ if (node) { next = NULL; while ((next = tgt_node_next(node, XML_ELEMENT_TARG, next)) != NULL) { tgt_node_add(main_config, tgt_node_dup(next)); } tgt_node_free(node); } if (mgmt_config_save2scf() != True) { syslog(LOG_ERR, "Converting config failed"); if (xml_fd != -1) (void) close(xml_fd); xmlTextReaderClose(r); xmlFreeTextReader(r); xmlCleanupParser(); ret = CONVERT_FAIL; goto done; } /* Copy files into backup dir */ (void) snprintf(path, sizeof (path), "%s/backup", target_basedir); if ((mkdir(path, 0755) == -1) && (errno != EEXIST)) { syslog(LOG_ERR, "Creating backup dir failed"); ret = CONVERT_FAIL; goto done; } backup(config_file, NULL); (void) snprintf(path, MAXPATHLEN, "%s/%s", target_basedir, "config.xml"); backup(path, NULL); while ((next = tgt_node_next(main_config, XML_ELEMENT_TARG, next)) != NULL) { if (tgt_find_value_str(next, XML_ELEMENT_INAME, &target) == False) { continue; } (void) snprintf(path, MAXPATHLEN, "%s/%s", target_basedir, target); if (mgmt_convert_param(path, next) != True) { ret = CONVERT_FAIL; goto done; } free(target); } ret = CONVERT_OK; syslog(LOG_NOTICE, "Conversion succeeded"); xmlTextReaderClose(r); xmlFreeTextReader(r); xmlCleanupParser(); } else { syslog(LOG_ERR, "Reading targets config failed"); ret = CONVERT_FAIL; goto done; } } else { syslog(LOG_ERR, "Reading main config failed"); ret = CONVERT_FAIL; goto done; } done: if (xml_fd != -1) (void) close(xml_fd); mgmt_handle_fini(h); return (ret); }
/* * mgmt_config_save2scf() saves main configuration to scf * See also : mgmt_get_main_config() */ Boolean_t mgmt_config_save2scf() { targ_scf_t *h = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *iter = NULL; char pgname[64]; char passcode[32]; unsigned int outlen; tgt_node_t *n = NULL; tgt_node_t *pn = NULL; tgt_node_t *tn = NULL; scf_transaction_t *tx = NULL; secret_list_t *sl_head; secret_list_t *sl_tail; h = mgmt_handle_init(); if (h == NULL) return (False); prop = scf_property_create(h->t_handle); value = scf_value_create(h->t_handle); iter = scf_iter_create(h->t_handle); (void) pthread_mutex_lock(&scf_conf_mutex); if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) { scf_pg_delete(h->t_pg); mgmt_transaction_end(h); } if (mgmt_transaction_start(h, "passwords", "application") == True) { scf_pg_delete(h->t_pg); mgmt_transaction_end(h); } if (scf_iter_service_pgs_typed(iter, h->t_service, "configuration") == -1) { goto error; } tx = scf_transaction_create(h->t_handle); while (scf_iter_next_pg(iter, h->t_pg) > 0) { scf_transaction_start(tx, h->t_pg); scf_pg_delete(h->t_pg); scf_transaction_commit(tx); } scf_transaction_reset(tx); scf_transaction_destroy(tx); sl_head = (secret_list_t *)calloc(1, sizeof (secret_list_t)); sl_tail = sl_head; if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) { for (n = main_config->x_child; n; n = n->x_sibling) { if (strcmp(n->x_name, XML_ELEMENT_CHAPSECRET) == 0) { sl_tail->next = (secret_list_t *) calloc(1, sizeof (secret_list_t)); sl_tail = sl_tail->next; sl_tail->name = strdup("main"); sl_tail->secret = strdup(n->x_value); continue; } /* so does the radius server secret */ if (strcmp(n->x_name, XML_ELEMENT_RAD_SECRET) == 0) { sl_tail->next = (secret_list_t *) calloc(1, sizeof (secret_list_t)); sl_tail = sl_tail->next; sl_tail->name = strdup("radius"); sl_tail->secret = strdup(n->x_value); continue; } if (n->x_child == NULL) { new_property(h, n); } } new_property(h, main_config->x_attr); n = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, n); tgt_node_free(n); n = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, n); tgt_node_free(n); mgmt_transaction_end(h); } /* now update target/initiator/tpgt information */ for (n = main_config->x_child; n; n = n->x_sibling) { if (n->x_child == NULL) continue; snprintf(pgname, sizeof (pgname), "%s_%s", n->x_name, n->x_value); if (mgmt_transaction_start(h, pgname, "configuration") == True) { for (pn = n->x_child; pn; pn = pn->x_sibling) { if (strcmp(pn->x_name, XML_ELEMENT_CHAPSECRET) == 0) { sl_tail->next = (secret_list_t *) calloc(1, sizeof (secret_list_t)); sl_tail = sl_tail->next; sl_tail->name = (char *) calloc(1, strlen(n->x_value) + 3); snprintf(sl_tail->name, strlen(n->x_value) + 3, "I_%s", n->x_value); sl_tail->secret = strdup(pn->x_value); continue; } if (pn->x_child == NULL) { /* normal property */ new_property(h, pn); } else { /* pn -> xxx-list */ new_value_list(h, pn); } tn = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, tn); tgt_node_free(tn); tn = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, tn); tgt_node_free(tn); } mgmt_transaction_end(h); } } if (mgmt_transaction_start(h, "passwords", "application") == True) { while (sl_head != NULL) { /* Here we use sl_tail as a temporari var */ sl_tail = sl_head->next; if (sl_head->name) { /* max length of encoded passwd is 24B */ sasl_encode64(sl_head->secret, strlen(sl_head->secret), passcode, sizeof (passcode), &outlen); n = tgt_node_alloc(sl_head->name, String, passcode); new_property(h, n); tgt_node_free(n); } if (sl_head->name) free(sl_head->name); if (sl_head->secret) free(sl_head->secret); free(sl_head); sl_head = sl_tail; } n = tgt_node_alloc(ISCSI_READ_AUTHNAME, String, ISCSI_AUTH_READ); new_property(h, n); tgt_node_free(n); n = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, n); tgt_node_free(n); n = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, n); tgt_node_free(n); mgmt_transaction_end(h); } if (smf_refresh_instance(SA_TARGET_SVC_INSTANCE_FMRI) != 0) goto error; (void) pthread_mutex_unlock(&scf_conf_mutex); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); return (True); error: (void) pthread_mutex_unlock(&scf_conf_mutex); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); mgmt_handle_fini(h); return (False); }
/* * check_auth_modify() checks if a given cred has * the authorization to add/change/remove configuration values. * cred is from the door call. */ Boolean_t check_auth_modify(ucred_t *cred) { targ_scf_t *h = NULL; Boolean_t ret = False; int exit_code = -1; uid_t uid; gid_t gid; pid_t pid; tgt_node_t *n = NULL; scf_transaction_entry_t *ent = NULL; const priv_set_t *eset; pid = fork(); switch (pid) { case 0: /* Child process to check authorization */ uid = ucred_geteuid(cred); if (seteuid(uid) != 0) { syslog(LOG_ERR, "not priviliged\n"); exit(-1); } gid = ucred_getegid(cred); if (setegid(gid) != 0) { syslog(LOG_ERR, "not priviliged\n"); exit(-1); } eset = ucred_getprivset(cred, PRIV_EFFECTIVE); setppriv(PRIV_ON, PRIV_EFFECTIVE, eset); h = mgmt_handle_init(); if (h == NULL) { exit(-1); } if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) { n = tgt_node_alloc("dummy", String, "dummy"); new_property(h, n); tgt_node_free(n); if (mgmt_transaction_end(h) == True) { exit_code = 0; } else { exit_code = -1; } } else { exit_code = -1; } if (exit_code != 0) { mgmt_handle_fini(h); exit(exit_code); } if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) { ent = scf_entry_create(h->t_handle); if (ent) { scf_transaction_property_delete(h->t_trans, ent, "dummy"); } } mgmt_transaction_end(h); mgmt_handle_fini(h); exit(exit_code); break; case -1: /* Fail to fork */ exit(SMF_EXIT_ERR_CONFIG); default: wait(&exit_code); exit_code = exit_code >> 8; if (exit_code == 0) ret = True; else ret = False; break; } return (ret); }
/* * check_auth() checks if a given cred has * the authorization to create/remove targets/initiators/tpgt * cred is from the door call. */ Boolean_t check_auth_addremove(ucred_t *cred) { targ_scf_t *h = NULL; Boolean_t ret = False; int exit_code = 1; uid_t uid; gid_t gid; pid_t pid; const priv_set_t *eset; pid = fork(); switch (pid) { case 0: /* Child process to check authorization */ uid = ucred_geteuid(cred); if (seteuid(uid) != 0) { syslog(LOG_ERR, "not priviliged\n"); exit(-1); } gid = ucred_getegid(cred); if (setegid(gid) != 0) { syslog(LOG_ERR, "not priviliged\n"); exit(-1); } eset = ucred_getprivset(cred, PRIV_EFFECTIVE); setppriv(PRIV_ON, PRIV_EFFECTIVE, eset); h = mgmt_handle_init(); if (h == NULL) { exit(1); } if (mgmt_transaction_start(h, "dummy", "dummy") == True) { scf_pg_delete(h->t_pg); mgmt_transaction_end(h); exit_code = 0; } else { exit_code = 1; } mgmt_handle_fini(h); exit(exit_code); break; case -1: /* Fail to fork */ exit(SMF_EXIT_ERR_CONFIG); default: wait(&exit_code); exit_code = exit_code >> 8; if (exit_code == 0) ret = True; else ret = False; break; } return (ret); }
/* * Convert legacy (XML) configuration files into an equivalent SCF * representation. * * Read the XML from disk, translate the XML into a tree of nodes of * type tgt_node_t, and write the in-memory tree to SCF's persistent * data-store using mgmt_config_save2scf(). * * Return Values: * CONVERT_OK: successfully converted * CONVERT_INIT_NEW: configuration files don't exist; created an SCF entry * CONVERT_FAIL: some conversion error occurred; no SCF entry created. * In this case, user has to manually check files and try * conversion again. */ convert_ret_t mgmt_convert_conf() { targ_scf_t *h = NULL; xmlTextReaderPtr r; convert_ret_t ret = CONVERT_FAIL; int xml_fd = -1; int n; tgt_node_t *node = NULL; tgt_node_t *next = NULL; char path[MAXPATHLEN]; char *target = NULL; h = mgmt_handle_init(); if (h == NULL) return (CONVERT_FAIL); /* * Check if the "iscsitgt" PropertyGroup has already been added * to the "iscsitgt" SMF Service. If so, then we have already * converted the legacy configuration files (and there is no work * to do). */ if (scf_service_get_pg(h->t_service, "iscsitgt", h->t_pg) == 0) { ret = CONVERT_OK; goto done; } if (access(config_file, R_OK) != 0) { /* * then the Main Config file is not present; initialize * SCF Properties to default values. */ if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) { ret = CONVERT_INIT_NEW; node = tgt_node_alloc(XML_ELEMENT_VERS, String, "1.0"); new_property(h, node); tgt_node_free(node); /* "daemonize" is set to true by default */ node = tgt_node_alloc(XML_ELEMENT_DBGDAEMON, String, "true"); new_property(h, node); tgt_node_free(node); node = NULL; node = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, node); tgt_node_free(node); node = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, node); tgt_node_free(node); (void) mgmt_transaction_end(h); } else { syslog(LOG_ERR, "Creating empty entry failed"); ret = CONVERT_FAIL; goto done; } if (mgmt_transaction_start(h, "passwords", "application") == True) { node = tgt_node_alloc(ISCSI_READ_AUTHNAME, String, ISCSI_AUTH_READ); new_property(h, node); tgt_node_free(node); node = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, node); tgt_node_free(node); node = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, node); tgt_node_free(node); (void) mgmt_transaction_end(h); } else { syslog(LOG_ERR, "Creating empty entry failed"); ret = CONVERT_FAIL; } goto done; } if ((xml_fd = open(config_file, O_RDONLY)) >= 0) r = (xmlTextReaderPtr)xmlReaderForFd(xml_fd, NULL, NULL, 0); if (r != NULL) { int is_target_config; n = xmlTextReaderRead(r); while (n == 1) { if (tgt_node_process(r, &node) == False) { break; } n = xmlTextReaderRead(r); } if (n < 0) { syslog(LOG_ERR, "Parsing main config failed"); ret = CONVERT_FAIL; goto done; } main_config = node; /* * Initialize the Base Directory (global) variable by * using the value specified in the XML_ELEMENT_BASEDIR * XML tag. If a tag is not specified, use a default. */ (void) tgt_find_value_str(node, XML_ELEMENT_BASEDIR, &target_basedir); if (target_basedir == NULL) target_basedir = strdup(DEFAULT_TARGET_BASEDIR); if (xml_fd != -1) { (void) close(xml_fd); xml_fd = -1; } (void) xmlTextReaderClose(r); xmlFreeTextReader(r); xmlCleanupParser(); /* * If a Target Config file is present, read and translate * its XML representation into a tree of tgt_node_t. * Merge that tree with the tree of tgt_node_t rooted at * 'main_config'. The merged tree will then be archived * using an SCF representation. */ (void) snprintf(path, MAXPATHLEN, "%s/%s", target_basedir, "config.xml"); if ((xml_fd = open(path, O_RDONLY)) >= 0) { is_target_config = 1; r = (xmlTextReaderPtr)xmlReaderForFd(xml_fd, NULL, NULL, 0); } else { is_target_config = 0; r = NULL; } if (r != NULL) { /* then the Target Config file is available. */ node = NULL; /* * Create a tree of tgt_node_t rooted at 'node' by * processing each XML Tag in the file. */ n = xmlTextReaderRead(r); while (n == 1) { if (tgt_node_process(r, &node) == False) { break; } n = xmlTextReaderRead(r); } if (n < 0) { syslog(LOG_ERR, "Parsing target conf failed"); ret = CONVERT_FAIL; goto done; } /* * Merge the tree at 'node' into the tree rooted at * 'main_config'. */ if (node != NULL) { next = NULL; while ((next = tgt_node_next(node, XML_ELEMENT_TARG, next)) != NULL) { tgt_node_add(main_config, tgt_node_dup(next)); } tgt_node_free(node); } } /* * Iterate over the in-memory tree rooted at 'main_config' * and write a representation of the appropriate nodes to * SCF's persistent data-store. */ if (mgmt_config_save2scf() != True) { syslog(LOG_ERR, "Converting config failed"); if (xml_fd != -1) { (void) close(xml_fd); xml_fd = -1; } (void) xmlTextReaderClose(r); xmlFreeTextReader(r); xmlCleanupParser(); ret = CONVERT_FAIL; goto done; } /* * Move the configuration files into a well-known backup * directory. This allows a user to restore their * configuration, if they choose. */ (void) snprintf(path, sizeof (path), "%s/backup", target_basedir); if ((mkdir(path, 0755) == -1) && (errno != EEXIST)) { syslog(LOG_ERR, "Creating backup dir failed"); ret = CONVERT_FAIL; goto done; } /* Save the Main Config file. */ backup(config_file, NULL); /* Save the Target Config file, if it was present. */ if (is_target_config != 0) { (void) snprintf(path, MAXPATHLEN, "%s/%s", target_basedir, "config.xml"); backup(path, NULL); } /* * For each tgt_node_t node in 'main_config' whose value is * an iSCSI Name as defined in the RFC (3720) standard (eg, * "iqn.1986..."), read its XML-encoded attributes from a * flat-file and write an equivalent representation to SCF's * data-store. */ while ((next = tgt_node_next(main_config, XML_ELEMENT_TARG, next)) != NULL) { if (tgt_find_value_str(next, XML_ELEMENT_INAME, &target) == False) { continue; } (void) snprintf(path, MAXPATHLEN, "%s/%s", target_basedir, target); if (mgmt_convert_param(path, next) != True) { ret = CONVERT_FAIL; goto done; } free(target); } ret = CONVERT_OK; syslog(LOG_NOTICE, "Conversion succeeded"); (void) xmlTextReaderClose(r); xmlFreeTextReader(r); xmlCleanupParser(); } else { syslog(LOG_ERR, "Reading main config failed"); ret = CONVERT_FAIL; goto done; } done: if (xml_fd != -1) (void) close(xml_fd); mgmt_handle_fini(h); return (ret); }