911 * ddp->dd_linkid is not set. Following this, the link
912 * must still be in the DD_INITIALIZING state because
913 * that flag is removed IFF dd_linkid is set. This is
914 * why we can ASSERT the DD_INITIALIZING flag below if
915 * the call to i_dls_devnet_setzid() fails.
916 */
917 if (linkid == DATALINK_INVALID_LINKID ||
918 class != DATALINK_CLASS_PHYS) {
919 err = EINVAL;
920 goto done;
921 }
922
923 ASSERT(ddp->dd_flags & DD_INITIALIZING);
924
925 } else {
926 ddp = kmem_cache_alloc(i_dls_devnet_cachep, KM_SLEEP);
927 ddp->dd_flags = DD_INITIALIZING;
928 ddp->dd_tref = 0;
929 ddp->dd_ref++;
930 ddp->dd_owner_zid = zoneid;
931 (void) strlcpy(ddp->dd_mac, macname, sizeof (ddp->dd_mac));
932 VERIFY(mod_hash_insert(i_dls_devnet_hash,
933 (mod_hash_key_t)ddp->dd_mac, (mod_hash_val_t)ddp) == 0);
934 }
935
936 if (linkid != DATALINK_INVALID_LINKID) {
937 ddp->dd_linkid = linkid;
938 (void) strlcpy(ddp->dd_linkname, linkname,
939 sizeof (ddp->dd_linkname));
940 VERIFY(mod_hash_insert(i_dls_devnet_id_hash,
941 (mod_hash_key_t)(uintptr_t)linkid,
942 (mod_hash_val_t)ddp) == 0);
943 devnet_need_rebuild = B_TRUE;
944 stat_create = B_TRUE;
945 mutex_enter(&ddp->dd_mutex);
946 if (!ddp->dd_prop_loaded && (ddp->dd_prop_taskid == 0)) {
947 ddp->dd_prop_taskid = taskq_dispatch(system_taskq,
948 dls_devnet_prop_task, ddp, TQ_SLEEP);
949 }
950 mutex_exit(&ddp->dd_mutex);
951 }
952 err = 0;
953 done:
954 /*
955 * It is safe to drop the i_dls_devnet_lock at this point. In the case
956 * of physical devices, the softmac framework will fail the device
957 * detach based on the smac_state or smac_hold_cnt. Other cases like
958 * vnic and aggr use their own scheme to serialize creates and deletes
959 * and ensure that *ddp is valid.
960 */
961 rw_exit(&i_dls_devnet_lock);
962 if (err == 0) {
963 if (zoneid != GLOBAL_ZONEID &&
964 (err = i_dls_devnet_setzid(ddp, zoneid, B_FALSE,
965 B_FALSE)) != 0) {
966 /*
967 * At this point the link is marked as
968 * DD_INITIALIZING -- there can be no
969 * outstanding temp refs and therefore no need
970 * to wait for them.
971 */
972 ASSERT(ddp->dd_flags & DD_INITIALIZING);
973 (void) dls_devnet_unset(mh, &linkid, B_FALSE);
974 return (err);
975 }
976
977 /*
978 * The kstat subsystem holds its own locks (rather perimeter)
979 * before calling the ks_update (dls_devnet_stat_update) entry
980 * point which in turn grabs the i_dls_devnet_lock. So the
981 * lock hierarchy is kstat locks -> i_dls_devnet_lock.
982 */
983 if (stat_create)
984 dls_devnet_stat_create(ddp, zoneid, zoneid);
985 if (ddpp != NULL)
986 *ddpp = ddp;
987
988 mutex_enter(&ddp->dd_mutex);
989 if (linkid != DATALINK_INVALID_LINKID && !ddp->dd_prop_loaded &&
990 ddp->dd_prop_taskid == TASKQID_INVALID) {
991 ddp->dd_prop_taskid = taskq_dispatch(system_taskq,
992 dls_devnet_prop_task, ddp, TQ_SLEEP);
993 }
994 mutex_exit(&ddp->dd_mutex);
995
996 }
997 return (err);
998 }
999
1000 /*
1001 * Disassociate the linkid from the link identified by macname. If
1002 * wait is B_TRUE, wait until all temporary refs are released and the
1003 * prop task is finished.
1004 *
1005 * If waiting then you SHOULD NOT call this from inside the MAC perim
1006 * as deadlock will ensue. Otherwise, this function is safe to call
1007 * from inside or outside the MAC perim.
1008 */
1009 static int
1010 dls_devnet_unset(mac_handle_t mh, datalink_id_t *id, boolean_t wait)
1031 * property loading as part of the post attach hasn't yet completed.
1032 */
1033 VERIFY(ddp->dd_ref != 0);
1034 if ((ddp->dd_ref != 1) || (!wait &&
1035 (ddp->dd_tref != 0 || ddp->dd_prop_taskid != 0))) {
1036 int zstatus = 0;
1037
1038 /*
1039 * There are a couple of alternatives that might be going on
1040 * here; a) the zone is shutting down and it has a transient
1041 * link assigned, in which case we want to clean it up instead
1042 * of moving it back to the global zone, or b) its possible
1043 * that we're trying to clean up an orphaned vnic that was
1044 * delegated to a zone and which wasn't cleaned up properly
1045 * when the zone went away. Check for either of these cases
1046 * before we simply return EBUSY.
1047 *
1048 * zstatus indicates which situation we are dealing with:
1049 * 0 - means return EBUSY
1050 * 1 - means case (a), cleanup transient link
1051 * -1 - means case (b), orphained VNIC
1052 */
1053 if (ddp->dd_ref > 1 && ddp->dd_zid != GLOBAL_ZONEID) {
1054 zone_t *zp;
1055
1056 if ((zp = zone_find_by_id(ddp->dd_zid)) == NULL) {
1057 zstatus = -1;
1058 } else {
1059 if (ddp->dd_transient) {
1060 zone_status_t s = zone_status_get(zp);
1061
1062 if (s >= ZONE_IS_SHUTTING_DOWN)
1063 zstatus = 1;
1064 }
1065 zone_rele(zp);
1066 }
1067 }
1068
1069 if (zstatus == 0) {
1070 mutex_exit(&ddp->dd_mutex);
1071 rw_exit(&i_dls_devnet_lock);
1072 return (EBUSY);
1073 }
1074
1075 /*
1076 * We want to delete the link, reset ref to 1;
1077 */
1078 if (zstatus == -1)
1079 /* Log a warning, but continue in this case */
1080 cmn_err(CE_WARN, "clear orphaned datalink: %s\n",
1081 ddp->dd_linkname);
1082 ddp->dd_ref = 1;
1083 }
1084
1085 ddp->dd_flags |= DD_CONDEMNED;
1086 ddp->dd_ref--;
1087 *id = ddp->dd_linkid;
1088
1089 /*
1090 * Remove this dls_devnet_t from the hash table.
1091 */
1092 VERIFY(mod_hash_remove(i_dls_devnet_hash,
1093 (mod_hash_key_t)ddp->dd_mac, &val) == 0);
1094
1095 if (ddp->dd_linkid != DATALINK_INVALID_LINKID) {
1096 VERIFY(mod_hash_remove(i_dls_devnet_id_hash,
1097 (mod_hash_key_t)(uintptr_t)ddp->dd_linkid, &val) == 0);
1098
1099 devnet_need_rebuild = B_TRUE;
1100 }
1101 rw_exit(&i_dls_devnet_lock);
1102
1103 /*
1104 * It is important to call i_dls_devnet_setzid() WITHOUT the
1105 * i_dls_devnet_lock held. The setzid call grabs the MAC
1106 * perim; thus causing DLS -> MAC lock ordering if performed
1107 * with the i_dls_devnet_lock held. This forces consumers to
1108 * grab the MAC perim before calling dls_devnet_unset() (the
1109 * locking rules state MAC -> DLS order). By performing the
1110 * setzid outside of the i_dls_devnet_lock consumers can
1111 * safely call dls_devnet_unset() outside the MAC perim.
1112 */
1113 if (ddp->dd_zid != GLOBAL_ZONEID) {
1114 dls_devnet_stat_destroy(ddp, ddp->dd_zid);
1115 (void) i_dls_devnet_setzid(ddp, GLOBAL_ZONEID, B_FALSE,
1116 B_FALSE);
1117 }
1118
1119 if (wait) {
1120 /*
1121 * Wait until all temporary references are released.
1122 * The holders of the tref need the MAC perim to
1123 * perform their work and release the tref. To avoid
1124 * deadlock, assert that the perim is never held here.
1125 */
1126 ASSERT0(MAC_PERIM_HELD(mh));
1127 while ((ddp->dd_tref != 0) || (ddp->dd_prop_taskid != 0))
1128 cv_wait(&ddp->dd_cv, &ddp->dd_mutex);
1129 } else {
1130 VERIFY(ddp->dd_tref == 0);
1131 VERIFY(ddp->dd_prop_taskid == (taskqid_t)NULL);
1132 }
1133
1134 if (ddp->dd_linkid != DATALINK_INVALID_LINKID) {
1135 dls_devnet_stat_destroy(ddp, ddp->dd_owner_zid);
1136 }
1137
1138 ddp->dd_prop_loaded = B_FALSE;
1139 ddp->dd_linkid = DATALINK_INVALID_LINKID;
1140 ddp->dd_flags = 0;
1141 mutex_exit(&ddp->dd_mutex);
1142 kmem_cache_free(i_dls_devnet_cachep, ddp);
1143
1144 return (0);
1145 }
1146
1147 /*
1148 * This is a private hold routine used when we already have the dls_link_t, thus
1149 * we know that it cannot go away.
1150 */
1151 int
1152 dls_devnet_hold_tmp_by_link(dls_link_t *dlp, dls_dl_handle_t *ddhp)
1153 {
1154 int err;
1155 dls_devnet_t *ddp = NULL;
1156
1157 rw_enter(&i_dls_devnet_lock, RW_WRITER);
1158 if ((err = mod_hash_find(i_dls_devnet_hash,
1159 (mod_hash_key_t)dlp->dl_name, (mod_hash_val_t *)&ddp)) != 0) {
1160 ASSERT(err == MH_ERR_NOTFOUND);
1161 rw_exit(&i_dls_devnet_lock);
1162 return (ENOENT);
1163 }
1164
1165 mutex_enter(&ddp->dd_mutex);
1166 ASSERT(ddp->dd_ref > 0);
1167 if (ddp->dd_flags & DD_CONDEMNED) {
1168 mutex_exit(&ddp->dd_mutex);
1169 rw_exit(&i_dls_devnet_lock);
1170 return (ENOENT);
1171 }
1172 ddp->dd_tref++;
1173 mutex_exit(&ddp->dd_mutex);
1174 rw_exit(&i_dls_devnet_lock);
1175
1176 *ddhp = ddp;
1177 return (0);
1178 }
1179
1180 static int
1181 dls_devnet_hold_common(datalink_id_t linkid, dls_devnet_t **ddpp,
1182 boolean_t tmp_hold)
1183 {
1184 dls_devnet_t *ddp;
1185 int err;
1186
1187 rw_enter(&i_dls_devnet_lock, RW_READER);
1918 * i_dls_devnet_hash.
1919 *
1920 * Even if #3 wasn't true the dls_devnet_set() may fail for
1921 * different reasons in the future; the point is that it _can_
1922 * fail as part of its contract. We can't rely on it working
1923 * so we must assume that these two pieces of state (devnet
1924 * and link hashes), which should always be in sync, can get
1925 * out of sync and thus even if we get ENOENT from the devnet
1926 * hash we should still try to delete from the link hash just
1927 * in case.
1928 *
1929 * We could prevent the ENOTEMPTY from dls_link_rele_by_name()
1930 * by calling mac_disable() before calling
1931 * dls_devnet_destroy() but that's not currently possible due
1932 * to a long-standing bug. OpenSolaris 6791335: The semantics
1933 * of mac_disable() were modified by Crossbow such that
1934 * dls_devnet_destroy() needs to be called before
1935 * mac_disable() can succeed. This is because of the implicit
1936 * reference that dls has on the mac_impl_t.
1937 */
1938 if (err != 0 && err != ENOENT) {
1939 return (err);
1940 }
1941
1942 mac_perim_enter_by_mh(mh, &mph);
1943 err = dls_link_rele_by_name(mac_name(mh));
1944 if (err != 0) {
1945 dls_devnet_t *ddp;
1946
1947 /*
1948 * XXX It is a general GLDv3 bug that dls_devnet_set() has to
1949 * be called to re-set the link when destroy fails. The
1950 * zoneid below will be incorrect if this function is ever
1951 * called from kernel context or from a zone other than that
1952 * which initially created the link.
1953 */
1954 (void) dls_devnet_set(mh, *idp, crgetzoneid(CRED()), &ddp);
1955
1956 /*
1957 * You might think dd_linkid should always be set
1958 * here, but in the case where dls_devnet_unset()
1959 * returns ENOENT it will be DATALINK_INVALID_LINKID.
1960 * Stay consistent with the rest of DLS and only
|
911 * ddp->dd_linkid is not set. Following this, the link
912 * must still be in the DD_INITIALIZING state because
913 * that flag is removed IFF dd_linkid is set. This is
914 * why we can ASSERT the DD_INITIALIZING flag below if
915 * the call to i_dls_devnet_setzid() fails.
916 */
917 if (linkid == DATALINK_INVALID_LINKID ||
918 class != DATALINK_CLASS_PHYS) {
919 err = EINVAL;
920 goto done;
921 }
922
923 ASSERT(ddp->dd_flags & DD_INITIALIZING);
924
925 } else {
926 ddp = kmem_cache_alloc(i_dls_devnet_cachep, KM_SLEEP);
927 ddp->dd_flags = DD_INITIALIZING;
928 ddp->dd_tref = 0;
929 ddp->dd_ref++;
930 ddp->dd_owner_zid = zoneid;
931 /*
932 * If we are creating a new devnet which will be owned by a NGZ
933 * then mark it as transient. This link has never been in the
934 * GZ, the GZ will not have a hold on its reference, and we do
935 * not want to return it to the GZ when the zone halts.
936 */
937 if (zoneid != GLOBAL_ZONEID)
938 ddp->dd_transient = B_TRUE;
939 (void) strlcpy(ddp->dd_mac, macname, sizeof (ddp->dd_mac));
940 VERIFY(mod_hash_insert(i_dls_devnet_hash,
941 (mod_hash_key_t)ddp->dd_mac, (mod_hash_val_t)ddp) == 0);
942 }
943
944 if (linkid != DATALINK_INVALID_LINKID) {
945 ddp->dd_linkid = linkid;
946 (void) strlcpy(ddp->dd_linkname, linkname,
947 sizeof (ddp->dd_linkname));
948 VERIFY(mod_hash_insert(i_dls_devnet_id_hash,
949 (mod_hash_key_t)(uintptr_t)linkid,
950 (mod_hash_val_t)ddp) == 0);
951 devnet_need_rebuild = B_TRUE;
952 stat_create = B_TRUE;
953 }
954 err = 0;
955 done:
956 /*
957 * It is safe to drop the i_dls_devnet_lock at this point. In the case
958 * of physical devices, the softmac framework will fail the device
959 * detach based on the smac_state or smac_hold_cnt. Other cases like
960 * vnic and aggr use their own scheme to serialize creates and deletes
961 * and ensure that *ddp is valid.
962 */
963 rw_exit(&i_dls_devnet_lock);
964
965 if (err == 0 && zoneid != GLOBAL_ZONEID) {
966 /*
967 * If this link is being created directly within a non-global
968 * zone, then flag it as transient so that it will be cleaned
969 * up when the zone is shut down.
970 */
971 err = i_dls_devnet_setzid(ddp, zoneid, B_FALSE, B_TRUE);
972 if (err != 0) {
973 /*
974 * At this point the link is marked as
975 * DD_INITIALIZING -- there can be no
976 * outstanding temp refs and therefore no need
977 * to wait for them.
978 */
979 ASSERT(ddp->dd_flags & DD_INITIALIZING);
980 (void) dls_devnet_unset(mh, &linkid, B_FALSE);
981 return (err);
982 }
983 }
984
985 if (err == 0) {
986 if (zoneid != GLOBAL_ZONEID &&
987 (err = i_dls_devnet_setzid(ddp, zoneid, B_FALSE,
988 B_FALSE)) != 0) {
989 /*
990 * At this point the link is marked as
991 * DD_INITIALIZING -- there can be no
992 * outstanding temp refs and therefore no need
993 * to wait for them.
994 */
995 ASSERT(ddp->dd_flags & DD_INITIALIZING);
996 (void) dls_devnet_unset(mh, &linkid, B_FALSE);
997 return (err);
998 }
999
1000 /*
1001 * The kstat subsystem holds its own locks (rather perimeter)
1002 * before calling the ks_update (dls_devnet_stat_update) entry
1003 * point which in turn grabs the i_dls_devnet_lock. So the
1004 * lock hierarchy is kstat locks -> i_dls_devnet_lock.
1005 */
1006 if (stat_create)
1007 dls_devnet_stat_create(ddp, zoneid, zoneid);
1008 if (ddpp != NULL)
1009 *ddpp = ddp;
1010
1011 mutex_enter(&ddp->dd_mutex);
1012 if (linkid != DATALINK_INVALID_LINKID &&
1013 !ddp->dd_prop_loaded && ddp->dd_prop_taskid == 0) {
1014 ddp->dd_prop_taskid = taskq_dispatch(system_taskq,
1015 dls_devnet_prop_task, ddp, TQ_SLEEP);
1016 }
1017 mutex_exit(&ddp->dd_mutex);
1018
1019 }
1020 return (err);
1021 }
1022
1023 /*
1024 * Disassociate the linkid from the link identified by macname. If
1025 * wait is B_TRUE, wait until all temporary refs are released and the
1026 * prop task is finished.
1027 *
1028 * If waiting then you SHOULD NOT call this from inside the MAC perim
1029 * as deadlock will ensue. Otherwise, this function is safe to call
1030 * from inside or outside the MAC perim.
1031 */
1032 static int
1033 dls_devnet_unset(mac_handle_t mh, datalink_id_t *id, boolean_t wait)
1054 * property loading as part of the post attach hasn't yet completed.
1055 */
1056 VERIFY(ddp->dd_ref != 0);
1057 if ((ddp->dd_ref != 1) || (!wait &&
1058 (ddp->dd_tref != 0 || ddp->dd_prop_taskid != 0))) {
1059 int zstatus = 0;
1060
1061 /*
1062 * There are a couple of alternatives that might be going on
1063 * here; a) the zone is shutting down and it has a transient
1064 * link assigned, in which case we want to clean it up instead
1065 * of moving it back to the global zone, or b) its possible
1066 * that we're trying to clean up an orphaned vnic that was
1067 * delegated to a zone and which wasn't cleaned up properly
1068 * when the zone went away. Check for either of these cases
1069 * before we simply return EBUSY.
1070 *
1071 * zstatus indicates which situation we are dealing with:
1072 * 0 - means return EBUSY
1073 * 1 - means case (a), cleanup transient link
1074 * -1 - means case (b), orphaned VNIC
1075 */
1076 if (ddp->dd_ref > 1 && ddp->dd_zid != GLOBAL_ZONEID) {
1077 zone_t *zp;
1078
1079 if ((zp = zone_find_by_id(ddp->dd_zid)) == NULL) {
1080 zstatus = -1;
1081 } else {
1082 if (ddp->dd_transient) {
1083 zone_status_t s = zone_status_get(zp);
1084
1085 if (s >= ZONE_IS_SHUTTING_DOWN)
1086 zstatus = 1;
1087 }
1088 zone_rele(zp);
1089 }
1090 }
1091
1092 if (zstatus == 0) {
1093 mutex_exit(&ddp->dd_mutex);
1094 rw_exit(&i_dls_devnet_lock);
1095 return (EBUSY);
1096 }
1097
1098 /*
1099 * We want to delete the link, reset ref to 1;
1100 */
1101 if (zstatus == -1) {
1102 /* Log a warning, but continue in this case */
1103 cmn_err(CE_WARN, "clear orphaned datalink: %s\n",
1104 ddp->dd_linkname);
1105 }
1106 ddp->dd_ref = 1;
1107 }
1108
1109 ddp->dd_flags |= DD_CONDEMNED;
1110 ddp->dd_ref--;
1111 *id = ddp->dd_linkid;
1112
1113 /*
1114 * Remove this dls_devnet_t from the hash table.
1115 */
1116 VERIFY(mod_hash_remove(i_dls_devnet_hash,
1117 (mod_hash_key_t)ddp->dd_mac, &val) == 0);
1118
1119 if (ddp->dd_linkid != DATALINK_INVALID_LINKID) {
1120 VERIFY(mod_hash_remove(i_dls_devnet_id_hash,
1121 (mod_hash_key_t)(uintptr_t)ddp->dd_linkid, &val) == 0);
1122
1123 devnet_need_rebuild = B_TRUE;
1124 }
1125 rw_exit(&i_dls_devnet_lock);
1126
1127 /*
1128 * It is important to call i_dls_devnet_setzid() WITHOUT the
1129 * i_dls_devnet_lock held. The setzid call grabs the MAC
1130 * perim; thus causing DLS -> MAC lock ordering if performed
1131 * with the i_dls_devnet_lock held. This forces consumers to
1132 * grab the MAC perim before calling dls_devnet_unset() (the
1133 * locking rules state MAC -> DLS order). By performing the
1134 * setzid outside of the i_dls_devnet_lock consumers can
1135 * safely call dls_devnet_unset() outside the MAC perim.
1136 */
1137 if (ddp->dd_zid != GLOBAL_ZONEID) {
1138 /*
1139 * We need to release the dd_mutex before we try and destroy the
1140 * stat. When we destroy it, we'll need to grab the lock for the
1141 * kstat but if there's a concurrent reader of the kstat, we'll
1142 * be blocked on it. This will lead to deadlock because these
1143 * kstats employ a ks_update function (dls_devnet_stat_update)
1144 * which needs the dd_mutex that we currently hold.
1145 *
1146 * Because we've already flagged the dls_devnet_t as
1147 * DD_CONDEMNED and we still have a write lock on
1148 * i_dls_devnet_lock, we should be able to release the dd_mutex.
1149 */
1150 mutex_exit(&ddp->dd_mutex);
1151 dls_devnet_stat_destroy(ddp, ddp->dd_zid);
1152 mutex_enter(&ddp->dd_mutex);
1153 (void) i_dls_devnet_setzid(ddp, GLOBAL_ZONEID, B_FALSE,
1154 B_FALSE);
1155 }
1156
1157 if (wait) {
1158 /*
1159 * Wait until all temporary references are released.
1160 * The holders of the tref need the MAC perim to
1161 * perform their work and release the tref. To avoid
1162 * deadlock, assert that the perim is never held here.
1163 */
1164 ASSERT0(MAC_PERIM_HELD(mh));
1165 while ((ddp->dd_tref != 0) || (ddp->dd_prop_taskid != 0))
1166 cv_wait(&ddp->dd_cv, &ddp->dd_mutex);
1167 } else {
1168 VERIFY(ddp->dd_tref == 0);
1169 VERIFY(ddp->dd_prop_taskid == 0);
1170 }
1171
1172 if (ddp->dd_linkid != DATALINK_INVALID_LINKID) {
1173 dls_devnet_stat_destroy(ddp, ddp->dd_owner_zid);
1174 }
1175
1176 ddp->dd_prop_loaded = B_FALSE;
1177 ddp->dd_linkid = DATALINK_INVALID_LINKID;
1178 ddp->dd_flags = 0;
1179 mutex_exit(&ddp->dd_mutex);
1180 kmem_cache_free(i_dls_devnet_cachep, ddp);
1181
1182 return (0);
1183 }
1184
1185 /*
1186 * This is a private hold routine used when we already have the dls_link_t, thus
1187 * we know that it cannot go away.
1188 */
1189 int
1190 dls_devnet_hold_tmp_by_link(dls_link_t *dlp, dls_dl_handle_t *ddhp)
1191 {
1192 int err;
1193 dls_devnet_t *ddp = NULL;
1194
1195 rw_enter(&i_dls_devnet_lock, RW_WRITER);
1196 if ((err = mod_hash_find(i_dls_devnet_hash,
1197 (mod_hash_key_t)dlp->dl_name, (mod_hash_val_t *)&ddp)) != 0) {
1198 ASSERT(err == MH_ERR_NOTFOUND);
1199 rw_exit(&i_dls_devnet_lock);
1200 return (ENOENT);
1201 }
1202
1203 mutex_enter(&ddp->dd_mutex);
1204 VERIFY(ddp->dd_ref > 0);
1205 if (DD_NOT_VISIBLE(ddp->dd_flags)) {
1206 mutex_exit(&ddp->dd_mutex);
1207 rw_exit(&i_dls_devnet_lock);
1208 return (ENOENT);
1209 }
1210 ddp->dd_tref++;
1211 mutex_exit(&ddp->dd_mutex);
1212 rw_exit(&i_dls_devnet_lock);
1213
1214 *ddhp = ddp;
1215 return (0);
1216 }
1217
1218 static int
1219 dls_devnet_hold_common(datalink_id_t linkid, dls_devnet_t **ddpp,
1220 boolean_t tmp_hold)
1221 {
1222 dls_devnet_t *ddp;
1223 int err;
1224
1225 rw_enter(&i_dls_devnet_lock, RW_READER);
1956 * i_dls_devnet_hash.
1957 *
1958 * Even if #3 wasn't true the dls_devnet_set() may fail for
1959 * different reasons in the future; the point is that it _can_
1960 * fail as part of its contract. We can't rely on it working
1961 * so we must assume that these two pieces of state (devnet
1962 * and link hashes), which should always be in sync, can get
1963 * out of sync and thus even if we get ENOENT from the devnet
1964 * hash we should still try to delete from the link hash just
1965 * in case.
1966 *
1967 * We could prevent the ENOTEMPTY from dls_link_rele_by_name()
1968 * by calling mac_disable() before calling
1969 * dls_devnet_destroy() but that's not currently possible due
1970 * to a long-standing bug. OpenSolaris 6791335: The semantics
1971 * of mac_disable() were modified by Crossbow such that
1972 * dls_devnet_destroy() needs to be called before
1973 * mac_disable() can succeed. This is because of the implicit
1974 * reference that dls has on the mac_impl_t.
1975 */
1976 if (err != 0 && err != ENOENT)
1977 return (err);
1978
1979 mac_perim_enter_by_mh(mh, &mph);
1980 err = dls_link_rele_by_name(mac_name(mh));
1981 if (err != 0) {
1982 dls_devnet_t *ddp;
1983
1984 /*
1985 * XXX It is a general GLDv3 bug that dls_devnet_set() has to
1986 * be called to re-set the link when destroy fails. The
1987 * zoneid below will be incorrect if this function is ever
1988 * called from kernel context or from a zone other than that
1989 * which initially created the link.
1990 */
1991 (void) dls_devnet_set(mh, *idp, crgetzoneid(CRED()), &ddp);
1992
1993 /*
1994 * You might think dd_linkid should always be set
1995 * here, but in the case where dls_devnet_unset()
1996 * returns ENOENT it will be DATALINK_INVALID_LINKID.
1997 * Stay consistent with the rest of DLS and only
|