/** * @name fab_host_delete_inactive - * @brief Delete an inactive fabric host * @param [in] fab_ctx : fab context pointer * @param [in] lkup_host : host instance * @param [in] locked : flag to specify whether fab_ctx is already held or not * * @retval int zero if no error else non-zero */ int fab_host_delete_inactive(fab_struct_t *fab_ctx, fab_host_t *lkup_host, bool locked) { fab_host_t *host; int err = 0; char *host_pstr; if (!locked) c_wr_lock(&fab_ctx->lock); if (!(host = g_hash_table_lookup(fab_ctx->inact_host_htbl, lkup_host))) { app_rlog_debug("%s: No such inactive host", FN); err = -1; goto done; } host_pstr = fab_dump_single_host(host); app_log_debug("%s: Inactive Host deleted %s", FN, host_pstr); free(host_pstr); if (host->tenant_nw) { host->tenant_nw->host_list = g_slist_remove(host->tenant_nw->host_list, host); fab_tenant_nw_put(host->tenant_nw); host->tenant_nw = NULL; } g_hash_table_remove(fab_ctx->inact_host_htbl, host); done: if (!locked) c_wr_unlock(&fab_ctx->lock); return err; }
/** * @name fab_host_put_locked * @brief Version of fab_host_put() with locks taken * @param [in] host: fabric host pointer * * @retval void Nothing */ void fab_host_put_locked(fab_host_t *host) { c_wr_lock(&fab_ctx->lock); fab_host_unref(host); c_wr_unlock(&fab_ctx->lock); }
void c_service_send(mul_service_t *service, struct cbuf *b) { if (service->is_client) { c_service_clr_rcv_buf(service); c_socket_write_block_loop(&service->conn, b); if (service->conn.dead && !service->reconn_timer_event) c_service_reconnect(service); } else { c_wr_lock(&service->conn.conn_lock); if (cbuf_list_queue_len(&service->conn.tx_q) > 1024) { c_wr_unlock(&service->conn.conn_lock); free_cbuf(b); return; } cbuf_list_queue_tail(&service->conn.tx_q, b); c_socket_write_nonblock_loop(&service->conn, c_service_write_event_sched); c_wr_unlock(&service->conn.conn_lock); } }
int prism_app_service_send(void *service, struct cbuf *b, bool wait, uint8_t resp) { int ret = 0; if (!service || !b) { if (b) free_cbuf(b); return -1; } c_wr_lock(&prism_ctx->serv_lock); c_service_send(service, b); if(wait) { b = c_service_wait_response(service); } else { b = NULL; } c_wr_unlock(&prism_ctx->serv_lock); if (b) { if (wait && !check_reply_type(b, resp)) { ret = -1; } free_cbuf(b); } return ret; }
/** * @name c_app_write_event * @brief processes a write event */ static void c_app_write_event(evutil_socket_t fd UNUSED, short events UNUSED, void *arg) { c_conn_t *conn = arg; c_wr_lock(&conn->conn_lock); c_socket_write_nonblock_loop(conn, c_app_write_event_sched); c_wr_unlock(&conn->conn_lock); }
/** * @name fab_loop_all_hosts_wr * @brief Loop through all known hosts and call iter_fn for each for writing * any global list manipulations eg host add/del etc * @param [in] fab_ctx fabric context pointer * @param [in] iter_fn iteration function for each host * @param [in] arg argument to be passed to iter_fn * * @retval void Nothing */ void fab_loop_all_hosts_wr(fab_struct_t *fab_ctx, GHFunc iter_fn, void *arg) { c_wr_lock(&fab_ctx->lock); if (fab_ctx->host_htbl) { g_hash_table_foreach(fab_ctx->host_htbl, (GHFunc)iter_fn, arg); } c_wr_unlock(&fab_ctx->lock); }
/** * lldp_port_find - * * Find and return a port in a switch * Note it is assumed that a reference to switch is held prior to call */ lldp_port_t * lldp_port_find(lldp_switch_t *lldp_sw, uint16_t port_id) { lldp_port_t *this_port = NULL; c_wr_lock(&lldp_sw->lock); if (!(this_port = g_hash_table_lookup(lldp_sw->ports, &port_id))){ c_wr_unlock(&lldp_sw->lock); return NULL; } c_wr_unlock(&lldp_sw->lock); return this_port; }
/** * @name fab_host_delete - * @brief Delete a fabric host * @parama [in] fab_ctx: fab context pointer * @param [in] dpid: switch dpid to the connected host * @param [in] sw_alias: switch alias id to the connected host * @param [un] fl: struct flow defining a host * @param [in] locked: flag to specify whether fab_ctx is already held or not * @param [in] deactivate: flag to specify whether to only deactivate not delete * * @retval int zero if no error else non-zero */ int fab_host_delete(fab_struct_t *fab_ctx, struct flow *fl, uint8_t *tenant_id, uint8_t *network_id, bool locked, bool deactivate, bool sync_ha) { fab_host_t *lkup_host, *host; char *host_pstr; int err = 0; bool dont_free = false; fab_port_t *port; fab_switch_t *sw; struct fab_host_service_arg iter_arg = { false, NULL, (send_cb_t)mul_app_ha_proc }; lkup_host = fab_host_create(0, 0, fl, tenant_id, network_id); if (sync_ha && mul_app_is_master()) { fabric_service_send_host_info(lkup_host, NULL, &iter_arg); } if (!locked) c_wr_lock(&fab_ctx->lock); if (!(host = g_hash_table_lookup(fab_ctx->host_htbl, lkup_host))) { if (!deactivate) { err = fab_host_delete_inactive(fab_ctx, lkup_host, true); } else { app_log_debug("%s: No active host", FN); err = -1; } goto done; } host->dead = true; __fab_host_route_delete(host, NULL, fab_ctx); __fab_del_pending_routes_tofro_host(fab_ctx, host); if (host->tenant_nw) { host->tenant_nw->host_list = g_slist_remove(host->tenant_nw->host_list, host); fab_tenant_nw_put(host->tenant_nw); host->tenant_nw = NULL; } if (deactivate) { fab_host_clone_prop(lkup_host, host); host_pstr = fab_dump_single_host(lkup_host); app_log_debug("%s: Host Active->Inactive %s", FN, host_pstr); free(host_pstr); fab_host_add_inactive(fab_ctx, lkup_host, true); dont_free = true; } else { /* Force port off the host and hence its host ref */ if ((sw = __fab_switch_get(fab_ctx, host->sw.swid))) { c_rd_lock(&sw->lock); if ((port = __fab_port_find(fab_ctx, sw, host->sw.port)) && port->host == host) { fab_host_put(port->host); port->host = NULL; } fab_switch_put_locked(sw); c_rd_unlock(&sw->lock); } host_pstr = fab_dump_single_host(lkup_host); app_log_debug("%s: Host Deleted %s", FN, host_pstr); free(host_pstr); } g_hash_table_remove(fab_ctx->host_htbl, host); done: if (!locked) c_wr_unlock(&fab_ctx->lock); if (!dont_free) fab_free(lkup_host); return err; }