278 lines
4.6 KiB
C
278 lines
4.6 KiB
C
|
|
/* Streams queue monitoring module */
|
|
|
|
#include "f_module.h"
|
|
#include "primitives.h"
|
|
#include <sys/time.h>
|
|
#include "f_signal.h"
|
|
#include "f_malloc.h"
|
|
#include <sys/sysmacros.h>
|
|
#include "streams.h"
|
|
#include <sys/stropts.h>
|
|
#include "f_user.h"
|
|
#include <sys/errno.h>
|
|
#include "streamlib.h"
|
|
#include "isdn_proto.h"
|
|
#ifndef KERNEL
|
|
#include "kernel.h"
|
|
#endif
|
|
|
|
#define MAXB 10
|
|
|
|
static struct module_info qinfo_minfo =
|
|
{
|
|
0, "qinfo", 0, INFPSZ, 0, 0
|
|
};
|
|
|
|
static qf_open qinfo_open;
|
|
static qf_close qinfo_close;
|
|
static qf_put qinfo_put;
|
|
|
|
static struct qinit qinfo_rinit =
|
|
{
|
|
qinfo_put, NULL, qinfo_open, qinfo_close, NULL, &qinfo_minfo, NULL
|
|
};
|
|
|
|
static struct qinit qinfo_winit =
|
|
{
|
|
qinfo_put, NULL, NULL, NULL, NULL, &qinfo_minfo, NULL
|
|
};
|
|
|
|
struct streamtab qinfoinfo =
|
|
{&qinfo_rinit, &qinfo_winit, NULL, NULL};
|
|
|
|
#include "qinfo.h"
|
|
#ifndef linux
|
|
#include <sys/var.h>
|
|
#endif
|
|
|
|
#define NQINFO 4
|
|
struct _qinfo {
|
|
queue_t *qptr;
|
|
int nr;
|
|
#ifdef NEW_TIMEOUT
|
|
int timer;
|
|
#endif
|
|
int timeout;
|
|
};
|
|
|
|
static void
|
|
qinf (queue_t * q)
|
|
{
|
|
struct msgb *m = q->q_first;
|
|
long sum = 0;
|
|
unsigned short fl = q->q_flag;
|
|
char x[30];
|
|
char *p = x;
|
|
|
|
if (fl & QENAB)
|
|
*p++ = 'e';
|
|
if (fl & QWANTR)
|
|
*p++ = 'r';
|
|
if (fl & QWANTW)
|
|
*p++ = 'w';
|
|
if (fl & QFULL)
|
|
*p++ = 'f';
|
|
if (fl & QREADR)
|
|
*p++ = 'R';
|
|
#ifdef QUSE
|
|
if (fl & QUSE)
|
|
*p++ = 'u';
|
|
#endif
|
|
if (fl & QNOENB)
|
|
*p++ = 'n';
|
|
*p = '\0';
|
|
printf ("%s ", x);
|
|
|
|
while (m != NULL) {
|
|
int siz = dsize (m);
|
|
|
|
sum += siz + 1;
|
|
printf ("%d", siz);
|
|
m = m->b_next;
|
|
if (m != NULL)
|
|
printf (",");
|
|
}
|
|
if (sum)
|
|
printf (": %ld", sum);
|
|
if (q->q_count > 0) {
|
|
if ((sum == 0) && (q->q_count > 0)) {
|
|
printf (" * %d * ", q->q_count);
|
|
q->q_count = 0;
|
|
q->q_flag &= ~QFULL;
|
|
qenable (q);
|
|
}
|
|
printf (" %d/%d/%d", q->q_lowat, q->q_count, q->q_hiwat);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
qinfo_log (struct _qinfo *qinfo)
|
|
{
|
|
queue_t *q = qinfo->qptr;
|
|
|
|
while (q->q_next != NULL)
|
|
q = q->q_next;
|
|
|
|
printf ("*** QInfo %d\n", qinfo->nr);
|
|
|
|
while (q != NULL) {
|
|
printf ("%s: ", q->q_qinfo->qi_minfo->mi_idname);
|
|
qinf (q);
|
|
printf (" // ");
|
|
q = WR (q);
|
|
qinf (q);
|
|
printf ("\n");
|
|
|
|
q = q->q_next;
|
|
if (q != NULL)
|
|
q = RD (q);
|
|
}
|
|
|
|
printf ("\n");
|
|
#ifdef NEW_TIMEOUT
|
|
qinfo->timer =
|
|
#endif
|
|
timeout ((void *)qinfo_log, qinfo, qinfo->timeout);
|
|
return;
|
|
}
|
|
|
|
|
|
static int
|
|
qinfo_open (queue_t * q, dev_t dev, int flag, int sflag ERR_DECL)
|
|
{
|
|
struct _qinfo *qinfo;
|
|
static int nr = 1;
|
|
|
|
if (q->q_ptr)
|
|
return 0;
|
|
qinfo = malloc(sizeof(*qinfo));
|
|
if (qinfo == NULL)
|
|
ERR_RETURN(-ENOMEM);
|
|
memset(qinfo,0,sizeof(*qinfo));
|
|
WR (q)->q_ptr = (char *) qinfo;
|
|
q->q_ptr = (char *) qinfo;
|
|
|
|
qinfo->qptr = q;
|
|
qinfo->nr = nr++;
|
|
printf ("QInfo driver %d opened.\n", qinfo->nr);
|
|
qinfo->timeout = 10*HZ;
|
|
#ifdef NEW_TIMEOUT
|
|
qinfo->timer =
|
|
#endif
|
|
timeout ((void *)qinfo_log, qinfo, qinfo->timeout);
|
|
|
|
MORE_USE;
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
qinfo_prot (queue_t * q, mblk_t * mp)
|
|
{
|
|
struct _qinfo *qinfo = (struct _qinfo *) q->q_ptr;
|
|
ushort_t id;
|
|
streamchar *origmp = mp->b_rptr;
|
|
int error = 0;
|
|
|
|
if (m_getid (mp, &id) != 0) {
|
|
mp->b_rptr = origmp;
|
|
m_reply(q,mp,ENXIO);
|
|
return;
|
|
}
|
|
switch (id) {
|
|
default:
|
|
mp->b_rptr = origmp;
|
|
break;
|
|
case PROTO_MODULE:
|
|
if (strnamecmp (q, mp)) { /* Config information for me. */
|
|
long z;
|
|
|
|
while ((mp != NULL) && ((error = m_getsx (mp, &id)) == 0)) {
|
|
switch (id) {
|
|
case PROTO_MODULE:
|
|
break;
|
|
default:
|
|
goto err;
|
|
case QINFO_TIMER:
|
|
if ((error = m_geti (mp, &z)) != 0)
|
|
goto err;
|
|
if (z < 1 || z >= 3600) {
|
|
goto err;
|
|
}
|
|
qinfo->timeout = z;
|
|
break;
|
|
}
|
|
}
|
|
mp->b_rptr = origmp;
|
|
m_reply (q,mp,0);
|
|
mp = NULL;
|
|
/* printf("\n"); */
|
|
} else {
|
|
mp->b_rptr = origmp;
|
|
putnext(q,mp);
|
|
mp = NULL;
|
|
}
|
|
break;
|
|
}
|
|
if (mp != NULL) {
|
|
if(origmp != NULL)
|
|
mp->b_rptr = origmp;
|
|
putnext(q,mp);
|
|
}
|
|
return;
|
|
err:
|
|
mp->b_rptr = origmp;
|
|
m_reply(q,mp,error ? error : -EINVAL);
|
|
}
|
|
static void
|
|
qinfo_put (queue_t * q, mblk_t * mp)
|
|
{
|
|
#if 0 /* def CONFIG_DEBUG_STREAMS */
|
|
qcheck (q->q_next, 1);
|
|
#endif
|
|
if(DATA_TYPE(mp) == MSG_PROTO)
|
|
qinfo_prot(q,mp);
|
|
else
|
|
putnext (q, mp);
|
|
#if 0 /* def CONFIG_DEBUG_STREAMS */
|
|
qcheck (q->q_next, 2);
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
qinfo_close (queue_t * q, int dummy)
|
|
{
|
|
struct _qinfo *qinfo = (struct _qinfo *) q->q_ptr;
|
|
|
|
#ifdef NEW_TIMEOUT
|
|
untimeout (qinfo->timer);
|
|
#else
|
|
untimeout ((void *)qinfo_log, qinfo);
|
|
#endif
|
|
|
|
flushq (q, FLUSHALL);
|
|
flushq (WR (q), FLUSHALL);
|
|
printf ("QInfo driver %d closed.\n", qinfo->nr);
|
|
free(qinfo);
|
|
LESS_USE;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef MODULE
|
|
static int do_init_module(void)
|
|
{
|
|
return register_strmod(&qinfoinfo);
|
|
}
|
|
|
|
static int do_exit_module(void)
|
|
{
|
|
return unregister_strmod(&qinfoinfo);
|
|
}
|
|
#endif
|