diff --git a/include/proto/server.h b/include/proto/server.h index 0e2aabfe4..634aa2a93 100644 --- a/include/proto/server.h +++ b/include/proto/server.h @@ -136,6 +136,16 @@ void srv_append_status(struct chunk *msg, struct server *s, const char *reason, */ void srv_set_stopped(struct server *s, const char *reason); +/* Marks server up regardless of its checks' statuses and provided it isn't + * in maintenance. Notifies by all available means, recounts the remaining + * servers on the proxy and tries to grab requests from the proxy. It + * automatically recomputes the number of servers, but not the map. Maintenance + * servers are ignored. It reports if non-null as the reason for going + * up. Note that it makes use of the trash to build the log strings, so + * must not be placed there. + */ +void srv_set_running(struct server *s, const char *reason); + /* Puts server into maintenance mode, and propagate that status down to all * tracking servers. This does the same action as the CLI's "disable server x". * A log is emitted for all servers that were not yet in maintenance mode. diff --git a/src/server.c b/src/server.c index e62e3406d..42a80f1ca 100644 --- a/src/server.c +++ b/src/server.c @@ -268,6 +268,71 @@ void srv_set_stopped(struct server *s, const char *reason) srv_set_stopped(srv, NULL); } +/* Marks server up regardless of its checks' statuses and provided it isn't + * in maintenance. Notifies by all available means, recounts the remaining + * servers on the proxy and tries to grab requests from the proxy. It + * automatically recomputes the number of servers, but not the map. Maintenance + * servers are ignored. It reports if non-null as the reason for going + * up. Note that it makes use of the trash to build the log strings, so + * must not be placed there. + */ +void srv_set_running(struct server *s, const char *reason) +{ + struct server *srv; + int xferred; + + if (s->admin & SRV_ADMF_MAINT) + return; + + if (s->state == SRV_ST_STARTING || s->state == SRV_ST_RUNNING) + return; + + if (s->proxy->srv_bck == 0 && s->proxy->srv_act == 0) { + if (s->proxy->last_change < now.tv_sec) // ignore negative times + s->proxy->down_time += now.tv_sec - s->proxy->last_change; + s->proxy->last_change = now.tv_sec; + } + + if (s->state == SRV_ST_STOPPED && s->last_change < now.tv_sec) // ignore negative times + s->down_time += now.tv_sec - s->last_change; + + s->last_change = now.tv_sec; + + s->state = SRV_ST_STARTING; + if (s->slowstart > 0) + task_schedule(s->warmup, tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20)))); + else + s->state = SRV_ST_RUNNING; + + server_recalc_eweight(s); + + /* If the server is set with "on-marked-up shutdown-backup-sessions", + * and it's not a backup server and its effective weight is > 0, + * then it can accept new connections, so we shut down all sessions + * on all backup servers. + */ + if ((s->onmarkedup & HANA_ONMARKEDUP_SHUTDOWNBACKUPSESSIONS) && + !(s->flags & SRV_F_BACKUP) && s->eweight) + srv_shutdown_backup_sessions(s->proxy, SN_ERR_UP); + + /* check if we can handle some connections queued at the proxy. We + * will take as many as we can handle. + */ + xferred = pendconn_grab_from_px(s); + + chunk_printf(&trash, + "%sServer %s/%s is UP", s->flags & SRV_F_BACKUP ? "Backup " : "", + s->proxy->id, s->id); + + srv_append_status(&trash, s, reason, xferred, 0); + Warning("%s.\n", trash.str); + send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str); + + for (srv = s->trackers; srv; srv = srv->tracknext) + srv_set_running(srv, NULL); +} + + /* Puts server into maintenance mode, and propagate that status down to all * tracking servers. This does the same action as the CLI's "disable server x". * A log is emitted for all servers that were not yet in maintenance mode.