1/*- 2 * Copyright (c) 2012 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Edward Tomasz Napierala under sponsorship 6 * from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 15 unchanged lines hidden (view full) --- 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: stable/10/usr.sbin/ctld/ctld.c 279006 2015-02-19 14:52:01Z mav $"); |
33 34#include <sys/types.h> 35#include <sys/time.h> 36#include <sys/socket.h> 37#include <sys/wait.h> 38#include <netinet/in.h> 39#include <arpa/inet.h> 40#include <assert.h> --- 45 unchanged lines hidden (view full) --- 86 struct conf *conf; 87 88 conf = calloc(1, sizeof(*conf)); 89 if (conf == NULL) 90 log_err(1, "calloc"); 91 TAILQ_INIT(&conf->conf_luns); 92 TAILQ_INIT(&conf->conf_targets); 93 TAILQ_INIT(&conf->conf_auth_groups); |
94 TAILQ_INIT(&conf->conf_ports); |
95 TAILQ_INIT(&conf->conf_portal_groups); 96 TAILQ_INIT(&conf->conf_isns); 97 98 conf->conf_isns_period = 900; 99 conf->conf_isns_timeout = 5; 100 conf->conf_debug = 0; 101 conf->conf_timeout = 60; 102 conf->conf_maxproc = 30; --- 17 unchanged lines hidden (view full) --- 120 TAILQ_FOREACH_SAFE(targ, &conf->conf_targets, t_next, tmp) 121 target_delete(targ); 122 TAILQ_FOREACH_SAFE(ag, &conf->conf_auth_groups, ag_next, cagtmp) 123 auth_group_delete(ag); 124 TAILQ_FOREACH_SAFE(pg, &conf->conf_portal_groups, pg_next, cpgtmp) 125 portal_group_delete(pg); 126 TAILQ_FOREACH_SAFE(is, &conf->conf_isns, i_next, istmp) 127 isns_delete(is); |
128 assert(TAILQ_EMPTY(&conf->conf_ports)); |
129 free(conf->conf_pidfile_path); 130 free(conf); 131} 132 133static struct auth * 134auth_new(struct auth_group *ag) 135{ 136 struct auth *auth; --- 469 unchanged lines hidden (view full) --- 606 return (NULL); 607 } 608 609 pg = calloc(1, sizeof(*pg)); 610 if (pg == NULL) 611 log_err(1, "calloc"); 612 pg->pg_name = checked_strdup(name); 613 TAILQ_INIT(&pg->pg_portals); |
614 TAILQ_INIT(&pg->pg_ports); |
615 pg->pg_conf = conf; 616 pg->pg_tag = 0; /* Assigned later in conf_apply(). */ 617 TAILQ_INSERT_TAIL(&conf->conf_portal_groups, pg, pg_next); 618 619 return (pg); 620} 621 622void 623portal_group_delete(struct portal_group *pg) 624{ 625 struct portal *portal, *tmp; |
626 struct port *port, *tport; |
627 |
628 TAILQ_FOREACH_SAFE(port, &pg->pg_ports, p_pgs, tport) 629 port_delete(port); |
630 TAILQ_REMOVE(&pg->pg_conf->conf_portal_groups, pg, pg_next); 631 632 TAILQ_FOREACH_SAFE(portal, &pg->pg_portals, p_next, tmp) 633 portal_delete(portal); 634 free(pg->pg_name); 635 free(pg->pg_redirection); 636 free(pg); 637} --- 147 unchanged lines hidden (view full) --- 785 786static int 787isns_do_register(struct isns *isns, int s, const char *hostname) 788{ 789 struct conf *conf = isns->i_conf; 790 struct target *target; 791 struct portal *portal; 792 struct portal_group *pg; |
793 struct port *port; |
794 struct isns_req *req; 795 int res = 0; 796 uint32_t error; 797 798 req = isns_req_create(ISNS_FUNC_DEVATTRREG, ISNS_FLAG_CLIENT); 799 isns_req_add_str(req, 32, TAILQ_FIRST(&conf->conf_targets)->t_name); 800 isns_req_add_delim(req); 801 isns_req_add_str(req, 1, hostname); --- 7 unchanged lines hidden (view full) --- 809 isns_req_add_port(req, 17, portal->p_ai); 810 } 811 } 812 TAILQ_FOREACH(target, &conf->conf_targets, t_next) { 813 isns_req_add_str(req, 32, target->t_name); 814 isns_req_add_32(req, 33, 1); /* 1 -- Target*/ 815 if (target->t_alias != NULL) 816 isns_req_add_str(req, 34, target->t_alias); |
817 TAILQ_FOREACH(port, &target->t_ports, p_ts) { 818 if ((pg = port->p_portal_group) == NULL) 819 continue; 820 isns_req_add_32(req, 51, pg->pg_tag); 821 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 822 isns_req_add_addr(req, 49, portal->p_ai); 823 isns_req_add_port(req, 50, portal->p_ai); 824 } |
825 } 826 } 827 res = isns_req_send(s, req); 828 if (res < 0) { 829 log_warn("send(2) failed for %s", isns->i_addr); 830 goto quit; 831 } 832 res = isns_req_receive(s, req); --- 295 unchanged lines hidden (view full) --- 1128 } else { 1129 log_warnx("invalid target name \"%s\"; should start with " 1130 "either \".iqn\", \"eui.\", or \"naa.\"", 1131 name); 1132 } 1133 return (true); 1134} 1135 |
1136struct port * 1137port_new(struct conf *conf, struct target *target, struct portal_group *pg) 1138{ 1139 struct port *port; 1140 1141 port = calloc(1, sizeof(*port)); 1142 if (port == NULL) 1143 log_err(1, "calloc"); 1144 asprintf(&port->p_name, "%s-%s", pg->pg_name, target->t_name); 1145 if (port_find(conf, port->p_name) != NULL) { 1146 log_warnx("duplicate port \"%s\"", port->p_name); 1147 free(port); 1148 return (NULL); 1149 } 1150 port->p_conf = conf; 1151 TAILQ_INSERT_TAIL(&conf->conf_ports, port, p_next); 1152 TAILQ_INSERT_TAIL(&target->t_ports, port, p_ts); 1153 port->p_target = target; 1154 TAILQ_INSERT_TAIL(&pg->pg_ports, port, p_pgs); 1155 port->p_portal_group = pg; 1156 return (port); 1157} 1158 1159struct port * 1160port_find(const struct conf *conf, const char *name) 1161{ 1162 struct port *port; 1163 1164 TAILQ_FOREACH(port, &conf->conf_ports, p_next) { 1165 if (strcasecmp(port->p_name, name) == 0) 1166 return (port); 1167 } 1168 1169 return (NULL); 1170} 1171 1172struct port * 1173port_find_in_pg(const struct portal_group *pg, const char *target) 1174{ 1175 struct port *port; 1176 1177 TAILQ_FOREACH(port, &pg->pg_ports, p_pgs) { 1178 if (strcasecmp(port->p_target->t_name, target) == 0) 1179 return (port); 1180 } 1181 1182 return (NULL); 1183} 1184 1185void 1186port_delete(struct port *port) 1187{ 1188 1189 if (port->p_portal_group) 1190 TAILQ_REMOVE(&port->p_portal_group->pg_ports, port, p_pgs); 1191 if (port->p_target) 1192 TAILQ_REMOVE(&port->p_target->t_ports, port, p_ts); 1193 TAILQ_REMOVE(&port->p_conf->conf_ports, port, p_next); 1194 free(port->p_name); 1195 free(port); 1196} 1197 |
1198struct target * 1199target_new(struct conf *conf, const char *name) 1200{ 1201 struct target *targ; 1202 int i, len; 1203 1204 targ = target_find(conf, name); 1205 if (targ != NULL) { --- 12 unchanged lines hidden (view full) --- 1218 /* 1219 * RFC 3722 requires us to normalize the name to lowercase. 1220 */ 1221 len = strlen(name); 1222 for (i = 0; i < len; i++) 1223 targ->t_name[i] = tolower(targ->t_name[i]); 1224 1225 targ->t_conf = conf; |
1226 TAILQ_INIT(&targ->t_ports); |
1227 TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next); 1228 1229 return (targ); 1230} 1231 1232void 1233target_delete(struct target *targ) 1234{ |
1235 struct port *port, *tport; |
1236 |
1237 TAILQ_FOREACH_SAFE(port, &targ->t_ports, p_ts, tport) 1238 port_delete(port); |
1239 TAILQ_REMOVE(&targ->t_conf->conf_targets, targ, t_next); 1240 1241 free(targ->t_name); 1242 free(targ->t_redirection); 1243 free(targ); 1244} 1245 1246struct target * --- 20 unchanged lines hidden (view full) --- 1267 return (1); 1268 } 1269 1270 target->t_redirection = checked_strdup(addr); 1271 1272 return (0); 1273} 1274 |
1275struct lun * 1276lun_new(struct conf *conf, const char *name) 1277{ 1278 struct lun *lun; 1279 1280 lun = lun_find(conf, name); 1281 if (lun != NULL) { 1282 log_warnx("duplicated lun \"%s\"", name); --- 289 unchanged lines hidden (view full) --- 1572 return (0); 1573} 1574 1575int 1576conf_verify(struct conf *conf) 1577{ 1578 struct auth_group *ag; 1579 struct portal_group *pg; |
1580 struct port *port; |
1581 struct target *targ; 1582 struct lun *lun; 1583 bool found; 1584 int error, i; 1585 1586 if (conf->conf_pidfile_path == NULL) 1587 conf->conf_pidfile_path = checked_strdup(DEFAULT_PIDFILE); 1588 1589 TAILQ_FOREACH(lun, &conf->conf_luns, l_next) { 1590 error = conf_verify_lun(lun); 1591 if (error != 0) 1592 return (error); 1593 } 1594 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1595 if (targ->t_auth_group == NULL) { 1596 targ->t_auth_group = auth_group_find(conf, 1597 "default"); 1598 assert(targ->t_auth_group != NULL); 1599 } |
1600 if (TAILQ_EMPTY(&targ->t_ports)) { 1601 pg = portal_group_find(conf, "default"); 1602 assert(pg != NULL); 1603 port_new(conf, targ, pg); |
1604 } 1605 found = false; 1606 for (i = 0; i < MAX_LUNS; i++) { 1607 if (targ->t_luns[i] != NULL) 1608 found = true; 1609 } 1610 if (!found && targ->t_redirection == NULL) { 1611 log_warnx("no LUNs defined for target \"%s\"", --- 11 unchanged lines hidden (view full) --- 1623 pg->pg_discovery_auth_group = 1624 auth_group_find(conf, "default"); 1625 assert(pg->pg_discovery_auth_group != NULL); 1626 } 1627 1628 if (pg->pg_discovery_filter == PG_FILTER_UNKNOWN) 1629 pg->pg_discovery_filter = PG_FILTER_NONE; 1630 |
1631 if (!TAILQ_EMPTY(&pg->pg_ports)) { 1632 if (pg->pg_redirection != NULL) { |
1633 log_debugx("portal-group \"%s\" assigned " |
1634 "to target, but configured " |
1635 "for redirection", |
1636 pg->pg_name); |
1637 } 1638 pg->pg_unassigned = false; |
1639 } else { 1640 if (strcmp(pg->pg_name, "default") != 0) 1641 log_warnx("portal-group \"%s\" not assigned " 1642 "to any target", pg->pg_name); 1643 pg->pg_unassigned = true; 1644 } 1645 } 1646 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { --- 4 unchanged lines hidden (view full) --- 1651 1652 found = false; 1653 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1654 if (targ->t_auth_group == ag) { 1655 found = true; 1656 break; 1657 } 1658 } |
1659 TAILQ_FOREACH(port, &conf->conf_ports, p_next) { 1660 if (port->p_auth_group == ag) { 1661 found = true; 1662 break; 1663 } 1664 } |
1665 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1666 if (pg->pg_discovery_auth_group == ag) { 1667 found = true; 1668 break; 1669 } 1670 } 1671 if (!found && ag->ag_name != NULL && 1672 strcmp(ag->ag_name, "default") != 0 && --- 5 unchanged lines hidden (view full) --- 1678 } 1679 1680 return (0); 1681} 1682 1683static int 1684conf_apply(struct conf *oldconf, struct conf *newconf) 1685{ |
1686 struct lun *oldlun, *newlun, *tmplun; 1687 struct portal_group *oldpg, *newpg; 1688 struct portal *oldp, *newp; |
1689 struct port *oldport, *newport, *tmpport; |
1690 struct isns *oldns, *newns; 1691 pid_t otherpid; 1692 int changed, cumulated_error = 0, error, sockbuf; 1693 int one = 1; 1694 1695 if (oldconf->conf_debug != newconf->conf_debug) { 1696 log_debugx("changing debug level to %d", newconf->conf_debug); 1697 log_init(newconf->conf_debug); --- 51 unchanged lines hidden (view full) --- 1749 /* 1750 * XXX: If target or lun removal fails, we should somehow "move" 1751 * the old lun or target into newconf, so that subsequent 1752 * conf_apply() would try to remove them again. That would 1753 * be somewhat hairy, though, and lun deletion failures don't 1754 * really happen, so leave it as it is for now. 1755 */ 1756 /* |
1757 * First, remove any ports present in the old configuration |
1758 * and missing in the new one. 1759 */ |
1760 TAILQ_FOREACH_SAFE(oldport, &oldconf->conf_ports, p_next, tmpport) { 1761 newport = port_find(newconf, oldport->p_name); 1762 if (newport != NULL) |
1763 continue; |
1764 error = kernel_port_remove(oldport); |
1765 if (error != 0) { |
1766 log_warnx("failed to remove port %s", 1767 oldport->p_name); |
1768 /* 1769 * XXX: Uncomment after fixing the root cause. 1770 * 1771 * cumulated_error++; 1772 */ 1773 } 1774 } 1775 --- 98 unchanged lines hidden (view full) --- 1874 if (error != 0) { 1875 log_warnx("failed to add lun \"%s\"", newlun->l_name); 1876 lun_delete(newlun); 1877 cumulated_error++; 1878 } 1879 } 1880 1881 /* |
1882 * Now add new ports or modify existing ones. |
1883 */ |
1884 TAILQ_FOREACH(newport, &newconf->conf_ports, p_next) { 1885 oldport = port_find(oldconf, newport->p_name); |
1886 |
1887 if (oldport == NULL) { 1888 error = kernel_port_add(newport); 1889 } else { 1890 newport->p_ctl_port = oldport->p_ctl_port; 1891 error = kernel_port_update(newport); |
1892 } 1893 if (error != 0) { |
1894 log_warnx("failed to %s port %s", 1895 (oldport == NULL) ? "add" : "update", 1896 newport->p_name); |
1897 /* 1898 * XXX: Uncomment after fixing the root cause. 1899 * 1900 * cumulated_error++; 1901 */ 1902 } 1903 } 1904 --- 584 unchanged lines hidden --- |