/* * This thread sit's in a loop and ensures that it keeps checking for * connection to isns_server. Once the connection works it registers * with the isns and bails out. * We expect the isns server to be fault taulerant and has persistence * for the registered entries. */ static void * isns_server_connection_thr(void *arg) { Boolean_t registered_targets = False; char server[MAXHOSTNAMELEN + 1] = {0}; while (isns_shutdown == False && connection_thr_bail_out == False) { /* current server */ (void) strcpy(server, isns_args.server); if (is_isns_server_up(server) == 0) { if (registered_targets == False) { /* * register all targets, what happens if * no targets are created yet? this should * not be a failure, when new target gets * created, update gets call. what if SCN * register fails? */ if (isns_reg_all() == 0) { /* scn register all targets */ if (isns_op_all(ISNS_SCN_REG) != 0) { syslog(LOG_ERR, "SCN registrations" " failed\n"); (void) isns_op_all( ISNS_DEV_DEREG); registered_targets = False; } else { registered_targets = True; break; } } } } else { syslog(LOG_INFO, "isns server %s is not reachable", server); registered_targets = False; } (void) sleep(ISNS_SLEEP_SECS); /* If isns was disabled, deregister and close the thread */ if (isns_enabled() == False) { syslog(LOG_INFO, "isns server is disabled, dergister target"); isns_fini(); break; } } queue_message_set(mgmtq, 0, msg_pthread_join, (void *)(uintptr_t)pthread_self()); return (NULL); }
static int isns_populate_and_update_server_info(Boolean_t update) { char *isns_srv, *isns_port; int retcode = 0; /* get isns server info */ (void) tgt_find_value_str(main_config, XML_ELEMENT_ISNS_SERV, &isns_srv); if (isns_srv == NULL) { syslog(LOG_INFO, "The server has not been setup, " "but enabling the isns access"); retcode = -1; return (retcode); } isns_port = strchr(isns_srv, ':'); if (isns_port == NULL) { isns_args.isns_port = ISNS_DEFAULT_SERVER_PORT; } else { isns_args.isns_port = strtoul(isns_port + 1, NULL, 0); if (isns_args.isns_port == 0) { isns_args.isns_port = ISNS_DEFAULT_SERVER_PORT; } *isns_port = '\0'; } if (update == True) { /* isns_server changed */ if (strcmp(isns_srv, isns_args.server) != 0) { /* de-reg from old iSNS server if it is setup */ syslog(LOG_INFO, "Detected a new isns server, deregistering" " %s", isns_args.server); (void) isns_dereg_all(); (void) strcpy(isns_args.server, isns_srv); /* Register with the new server */ if (isns_reg_all() == 0) { /* scn register all targets */ if (isns_op_all(ISNS_SCN_REG) != 0) { syslog(LOG_ERR, "SCN registrations failed\n"); (void) isns_op_all(ISNS_DEV_DEREG); retcode = -1; } } } } else { (void) strcpy(isns_args.server, isns_srv); } free(isns_srv); return (retcode); }
static char * remove_tpgt(tgt_node_t *x) { char *msg = NULL; char *prop = NULL; tgt_node_t *node = NULL; tgt_node_t *c = NULL; Boolean_t change_made = False; if (tgt_find_value_str(x, XML_ELEMENT_NAME, &prop) == False) { xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_NAME); return (msg); } while ((node = tgt_node_next(main_config, XML_ELEMENT_TPGT, node)) != NULL) { if (strcmp(node->x_value, prop) == 0) break; } free(prop); if (node == NULL) { xml_rtn_msg(&msg, ERR_TPGT_NOT_FOUND); return (msg); } if (tgt_find_value_str(x, XML_ELEMENT_IPADDR, &prop) == True) { if (prop == NULL) { xml_rtn_msg(&msg, ERR_SYNTAX_EMPTY_IPADDR); return (msg); } c = tgt_node_alloc(XML_ELEMENT_IPADDR, String, prop); if (tgt_node_remove(node, c, MatchBoth) == False) { xml_rtn_msg(&msg, ERR_INVALID_IP); goto error; } tgt_node_free(c); free(prop); change_made = True; } if ((change_made != True) && (tgt_find_value_str(x, XML_ELEMENT_ALL, &prop) == True)) { tgt_node_remove(main_config, node, MatchBoth); change_made = True; } if (change_made == True) { /* Isns re-register all target */ if (isns_enabled() == True) isns_reg_all(); if (mgmt_config_save2scf() == True) xml_rtn_msg(&msg, ERR_SUCCESS); } else { xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_OPERAND); } return (msg); error: if (c != NULL) tgt_node_free(c); if (prop != NULL) free(prop); return (msg); }
/* * []---- * | modify_tpgt -- add an IP-address to a target portal group * []---- */ static char * modify_tpgt(tgt_node_t *x) { struct addrinfo *res = NULL; char *msg = NULL; char *name = NULL; char *ip_str = NULL; tgt_node_t *tnode = NULL; tgt_node_t *list = NULL; (void) pthread_rwlock_wrlock(&targ_config_mutex); if (tgt_find_value_str(x, XML_ELEMENT_NAME, &name) == False) { xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_NAME); goto error; } if (tgt_find_value_str(x, XML_ELEMENT_IPADDR, &ip_str) == False) { xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_IPADDR); goto error; } if ((getaddrinfo(ip_str, NULL, NULL, &res) != 0) || (res == NULL)) { xml_rtn_msg(&msg, ERR_INVALID_IP); goto error; } while ((tnode = tgt_node_next_child(main_config, XML_ELEMENT_TPGT, tnode)) != NULL) { if (strcmp(tnode->x_value, name) == 0) break; } if (tnode == NULL) { xml_rtn_msg(&msg, ERR_TPGT_NOT_FOUND); goto error; } if ((list = tgt_node_next(tnode, XML_ELEMENT_IPADDRLIST, NULL)) == NULL) { list = tgt_node_alloc(XML_ELEMENT_IPADDRLIST, String, ""); if (list == NULL) { xml_rtn_msg(&msg, ERR_NO_MEM); goto error; } tgt_node_add(tnode, list); } if (modify_element(XML_ELEMENT_IPADDR, ip_str, list, MatchBoth) == False) { xml_rtn_msg(&msg, ERR_NO_MEM); goto error; } if (mgmt_config_save2scf() == True) { xml_rtn_msg(&msg, ERR_SUCCESS); } else { /* tpgt change should be updated to smf */ xml_rtn_msg(&msg, ERR_INTERNAL_ERROR); } /* * Re-register all targets, currently there's no method to * update TPGT for individual target */ if (isns_enabled() == True) { (void) isns_reg_all(); } error: if (name) free(name); if (ip_str) free(ip_str); if (res) freeaddrinfo(res); (void) pthread_rwlock_unlock(&targ_config_mutex); return (msg); }
/* * Update an existing iscsi target property */ int isns_dev_update(char *targ, uint32_t mods) { int so; int flags = 0; /* update only */ char *iname = NULL; char *dummy = NULL; char alias[MAXNAMELEN]; tgt_node_t *tgt = NULL; isns_pdu_t *cmd; isns_rsp_t *rsp; int ret = -1; if (mods == 0) return (0); if (isns_server_connection_thr_running == False) { syslog(LOG_ERR, "isns_dev_update: iSNS discovery is not running." " Check the previous iSNS initialization error."); return (-1); } if ((tgt = find_tgt_by_name(targ, &iname)) != NULL) { if (tgt_find_value_str(tgt, XML_ELEMENT_ALIAS, &dummy) == True) { (void) strcpy(alias, dummy); free(dummy); } else (void) strcpy(alias, tgt->x_value); if ((so = isns_open(isns_args.server)) < 0) { goto error; } if (isns_create_pdu(ISNS_DEV_ATTR_REG, flags, &cmd)) { goto error; } /* source attr, msg key, delimiter */ if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID, STRLEN(iname), iname, 0) != 0) { goto error; } if (isns_append_attr(cmd, ISNS_EID_ATTR_ID, STRLEN(isns_args.entity), isns_args.entity, 0) != 0) { goto error; } if (isns_append_attr(cmd, ISNS_DELIMITER_ATTR_ID, 0, NULL, 0) != 0) { goto error; } /* * get current operating attributes, alias & portal group * objects, these should be the only things that get change */ (void) isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID, STRLEN(iname), iname, 0); (void) isns_append_attr(cmd, ISNS_ISCSI_NODE_TYPE_ATTR_ID, ISNS_NODE_TYP_SZ, NULL, ISNS_TARGET_NODE_TYPE); if (mods & ISNS_MOD_ALIAS) if (isns_append_attr(cmd, ISNS_ISCSI_ALIAS_ATTR_ID, STRLEN(alias), alias, 0) != 0) { goto error; } if (mods & ISNS_MOD_TPGT) if (append_tpgt(tgt, cmd) != 0) { goto error; } if (isns_send(so, (isns_pdu_t *)cmd) < 0) { goto error; } if (isns_recv(so, &rsp) == -1) { goto error; } /* process response, if failed do a isns_reg_all */ if ((ret = process_rsp(cmd, rsp)) == -1) { if (isns_reg_all() != 0 || isns_scn_reg_all() != 0) { syslog(LOG_ALERT, "ISNS register failed\n"); goto error; } ret = 0; } else { if (isns_scn_reg(so, iname) == -1) { syslog(LOG_ERR, "ISNS SCN register failed\n"); goto error; } ret = 0; } } else { syslog(LOG_ERR, "ISNS: fails to update target %s\n", alias); } error: if (cmd) isns_free_pdu(cmd); if (rsp) isns_free_pdu(rsp); if (iname) free(iname); isns_close(so); return (ret); }