/*
**  CM_CLEANUP -- cleanup after interrupt or error.
**
**	This routine does things like call the interrupt cleanup
**	function, reset the input, etc.
**
**	Parameters:
**		typ -- the type of cleanup:
**			1 -- fatal error (from error [error.c]).
**			2 -- keyboard interrupt.
**
**	Returns:
**		never (uses non-local jump to ctlmod/main.c).
**
**	Side Effects:
**		Proc_name & Cm.cm_input are reset.
**
**	Trace Flags:
**		0
*/
void
cm_cleanup(int typ)
{
	register int		i;
	register func_t	*f;
	extern jmp_buf		CmReset;
	register ctx_t		*ctx;

#ifdef xCTR2
	if (tTf(0, 13))
		printf("cm_cleanup: %d\n", typ);
#endif

	/*
	**  Call all interrupt cleanup functions for active
	**	modules.
	*/

	for (i = 0; i < NumFunc; i++) {
		f = FuncVect[i];
		if (f->fn_active > 0) {
			setprocname(Ctx.ctx_name = f->fn_name);
			(*f->fn_cleanup)(typ);
		}
	}

	/* clean up memory */
	for (ctx = &Ctx; ctx != NULL; ctx = ctx->ctx_link) {
		if (ctx->ctx_qt != NULL) {
			xfree(ctx->ctx_qt);
		}
		if (ctx->ctx_glob != NULL) {
			bmove(ctx->ctx_glob, ctx->ctx_fn->fn_gptr, ctx->ctx_fn->fn_gsize);
			xfree(ctx->ctx_glob);
		}
	}

	/* return to top of loop */
	longjmp(CmReset, typ);
}
Example #2
0
int
probes_init(struct glougloud *ggd) {
	_ggd = ggd;
	_probes = xcalloc(1, sizeof(struct glougloud_probes));
	_probes->pid = fork();
	if (_probes->pid > 0)
		return 0;
	setprocname("probes");
	droppriv(GLOUGLOUD_USER_PROBES, 1, NULL);

	_probes->evb = event_base_new();

	if (_modules_load() < 0)
	    goto err;

	_probes->rc = redis_connect(_probes->evb, cb_connect, cb_disconnect);
	if (_probes->rc->err)
		return -1;

	_probes->server = gg_server_start(_probes->evb,
		&ggd->probes.serv_ip, ggd->probes.serv_port,
		prb_handle_conn, prb_handle_packet, NULL);
	if (!_probes->server) {
		log_warn("probes: gg_server_start failed");
		return -1;
	}

	event_base_dispatch(_probes->evb);

	gg_server_stop(_probes->server);

	return 0;

err:
    probes_shutdown();
    return -1;
}
int
proc_err(pb_t *ppb, int pc, paramv_t *pv)
{
	register func_t	*f;
	register int		i;
	register ctx_t		*ctx;

#ifdef xCTR2
	if (tTf(6, 8))
		lprintf("proc_err: new = %d\n", Ctx.ctx_new);
#endif
	pb_prime(ppb, PB_ERR);

	/*
	**  Scan back on the list of context dependencies.
	**	If we come to someone who can process this message,
	**	we go ahead and do it.  We also take this
	**	opportunity to unwind the context list & call the
	**	cleanup functions.
	*/

	for (ctx = &Ctx; ctx != NULL; ctx = ctx->ctx_link) {
		setprocname(ctx->ctx_name);
		f = ctx->ctx_fn;
#ifdef xCTR2
		if (tTf(6, 9))
			lprintf("proc_err: unwinding %s: errfn=%x, ppb=%x, link=%x, resp=%d, fn=%x\n",
			    getprocname(), ctx->ctx_errfn, ctx->ctx_ppb,
			    ctx->ctx_link, ctx->ctx_resp, f);
#endif

		/*  Do the actual error processing. */
		ppb->pb_proc = ctx->ctx_resp;
		if (ctx->ctx_errfn != NULL)
			i = (*ctx->ctx_errfn)(pc, pv);
		else
			i = -1;

#ifdef xCTR2
		if (tTf(6, 11))
			lprintf("proc_err: errcode %d\n", i);
#endif
		if (i == 0)
			break;
		else if (i > 0) {
			/* turn into nonfatal error */
			ppb->pb_stat |= PB_INFO;
			ppb->pb_proc = PB_FRONT;
		} else {
			/* call the cleanup function */
			if (f != NULL && f->fn_active > 0) {
				(*f->fn_cleanup)(1);
			}
		}

		/* arrange to leave if parent not in this process */
		if (ppb->pb_proc != Cm.cm_myproc) {
			send_off(ppb, pc, pv);
			pb_flush(ppb);

			/* throw away dead contexts and exit */
			break;
		}
	}
	if (ctx == NULL) {
		syserr("proc_err: no parent");
	}

#ifdef xCTR3
	MonPpb = getmonppb();
	if (tTf(6, 12)) {
		lprintf("proc_err: cleanup: ctx=%x, ->_link=%x, MonPpb = ", ctx, ctx->ctx_link);
		pb_dump(MonPpb, TRUE);
	}
#endif
	/* pop contexts down to ctx and exit */
	ctx = ctx->ctx_link;
	while (Ctx.ctx_link != ctx) {
		if (Ctx.ctx_link == NULL)
			syserr("proc_err: underflow");
		Ctx.ctx_new = TRUE;
		resetp();
	}

	/*
	**  Flush input pipe.
	**	THIS CODE IS ONLY NEEDED TO MAKE READMON WORK, AND
	**	SHOULD BE REMOVED WHEN READMON GOES AWAY!!
	*/

	if (ctx == NULL) {
		Cm.cm_input = Cm.cm_rinput;
		MonPpb = getmonppb();
		while (!BITISSET(PB_EOF, MonPpb->pb_stat)) {
			pb_read(MonPpb);
		}
		MonPpb->pb_st = PB_UNKNOWN;
	}

	longjmp(Ctx.ctx_jbuf, 1);
}