. DS understands publishing and subscribing where keys are in string
form. Subscriptions are regular expressions. . different types are stored per key; currently u32 and/or string. the same key can be referenced (publish, subscribe, check) as any type. . notify()s are sent when subscriptions are triggered (publishing or updating of matching keys); optionally, a subscribe flag sends updates for all matching keys at subscription time, instead of only after updates after subscribing . all interfacing to ds is in /usr/src/lib/syslib/ds.c. . subscribe is ds_subscribe publish functions are ds_publish_<type> retrieve functions are ds_retrieve_<type> (one-time retrieval of a value) check functions are ds_check_<type> (check for updated key caller subscribes to not yet checked for, or ESRCH for none) . ramdisk driver updated with new ds interface
This commit is contained in:
parent
d40007667c
commit
3512a86b44
@ -17,10 +17,14 @@
|
|||||||
#include "../drivers.h"
|
#include "../drivers.h"
|
||||||
#include "../libdriver/driver.h"
|
#include "../libdriver/driver.h"
|
||||||
#include <sys/ioc_memory.h>
|
#include <sys/ioc_memory.h>
|
||||||
|
#include <minix/ds.h>
|
||||||
#include "../../kernel/const.h"
|
#include "../../kernel/const.h"
|
||||||
#include "../../kernel/config.h"
|
#include "../../kernel/config.h"
|
||||||
#include "../../kernel/type.h"
|
#include "../../kernel/type.h"
|
||||||
|
|
||||||
|
#define MY_DS_NAME_BASE "dev:memory:ramdisk_base"
|
||||||
|
#define MY_DS_NAME_SIZE "dev:memory:ramdisk_size"
|
||||||
|
|
||||||
#include <sys/vm.h>
|
#include <sys/vm.h>
|
||||||
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
@ -291,8 +295,8 @@ message *m_ptr;
|
|||||||
PRIVATE void m_init()
|
PRIVATE void m_init()
|
||||||
{
|
{
|
||||||
/* Initialize this task. All minor devices are initialized one by one. */
|
/* Initialize this task. All minor devices are initialized one by one. */
|
||||||
phys_bytes ramdev_size;
|
u32_t ramdev_size;
|
||||||
phys_bytes ramdev_base;
|
u32_t ramdev_base;
|
||||||
message m;
|
message m;
|
||||||
int i, s;
|
int i, s;
|
||||||
|
|
||||||
@ -319,10 +323,8 @@ PRIVATE void m_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* See if there are already RAM disk details at the Data Store server. */
|
/* See if there are already RAM disk details at the Data Store server. */
|
||||||
m.DS_KEY = MEMORY_MAJOR;
|
if(ds_retrieve_u32(MY_DS_NAME_BASE, &ramdev_base) == OK &&
|
||||||
if (OK == (s = _taskcall(DS_PROC_NR, DS_RETRIEVE, &m))) {
|
ds_retrieve_u32(MY_DS_NAME_SIZE, &ramdev_size) == OK) {
|
||||||
ramdev_size = m.DS_VAL_L1;
|
|
||||||
ramdev_base = m.DS_VAL_L2;
|
|
||||||
printf("MEM retrieved size %u and base %u from DS, status %d\n",
|
printf("MEM retrieved size %u and base %u from DS, status %d\n",
|
||||||
ramdev_size, ramdev_base, s);
|
ramdev_size, ramdev_base, s);
|
||||||
if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s,
|
if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s,
|
||||||
@ -423,15 +425,14 @@ int safe;
|
|||||||
/* Store the values we got in the data store so we can retrieve
|
/* Store the values we got in the data store so we can retrieve
|
||||||
* them later on, in the unfortunate event of a crash.
|
* them later on, in the unfortunate event of a crash.
|
||||||
*/
|
*/
|
||||||
m.DS_KEY = MEMORY_MAJOR;
|
if(ds_publish_u32(MY_DS_NAME_BASE, ramdev_base) != OK ||
|
||||||
m.DS_VAL_L1 = ramdev_size;
|
ds_publish_u32(MY_DS_NAME_SIZE, ramdev_size) != OK) {
|
||||||
m.DS_VAL_L2 = ramdev_base;
|
|
||||||
if (OK != (s = _taskcall(DS_PROC_NR, DS_PUBLISH, &m))) {
|
|
||||||
panic("MEM","Couldn't store RAM disk details at DS.",s);
|
panic("MEM","Couldn't store RAM disk details at DS.",s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
printf("MEM stored size %u and base %u at DS, status %d\n",
|
printf("MEM stored size %u and base %u at DS, names %s and %s\n",
|
||||||
ramdev_size, ramdev_base, s);
|
ramdev_size, ramdev_base, MY_DS_NAME_BASE, MY_DS_NAME_SIZE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s,
|
if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s,
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
# define NEW_KSIG NOTIFY_FROM(HARDWARE) /* new kernel signal */
|
# define NEW_KSIG NOTIFY_FROM(HARDWARE) /* new kernel signal */
|
||||||
# define FKEY_PRESSED NOTIFY_FROM(TTY_PROC_NR)/* function key press */
|
# define FKEY_PRESSED NOTIFY_FROM(TTY_PROC_NR)/* function key press */
|
||||||
# define DEV_PING NOTIFY_FROM(RS_PROC_NR) /* driver liveness ping */
|
# define DEV_PING NOTIFY_FROM(RS_PROC_NR) /* driver liveness ping */
|
||||||
|
# define DS_UPDATE NOTIFY_FROM(DS_PROC_NR) /* subscription update */
|
||||||
|
|
||||||
/* Shorthands for message parameters passed with notifications. */
|
/* Shorthands for message parameters passed with notifications. */
|
||||||
#define NOTIFY_SOURCE m_source
|
#define NOTIFY_SOURCE m_source
|
||||||
@ -548,14 +549,18 @@
|
|||||||
#define DS_RQ_BASE 0x800
|
#define DS_RQ_BASE 0x800
|
||||||
|
|
||||||
#define DS_PUBLISH (DS_RQ_BASE + 0) /* publish information */
|
#define DS_PUBLISH (DS_RQ_BASE + 0) /* publish information */
|
||||||
#define DS_RETRIEVE (DS_RQ_BASE + 1) /* retrieve information */
|
#define DS_SUBSCRIBE (DS_RQ_BASE + 1) /* subscribe to information */
|
||||||
#define DS_SUBSCRIBE (DS_RQ_BASE + 2) /* subscribe to information */
|
#define DS_RETRIEVE (DS_RQ_BASE + 2) /* retrieve information by name */
|
||||||
|
#define DS_CHECK (DS_RQ_BASE + 3) /* retrieve updated information */
|
||||||
|
|
||||||
# define DS_KEY m2_i1 /* key for the information */
|
/* DS field names: DS_SUBSCRIBE, DS_PUBLISH, DS_RETRIEVE */
|
||||||
|
# define DS_KEY_GRANT m2_p1 /* key for the information */
|
||||||
|
# define DS_KEY_LEN m2_i1 /* length of key incl. '\0' */
|
||||||
# define DS_FLAGS m2_i2 /* flags provided by caller */
|
# define DS_FLAGS m2_i2 /* flags provided by caller */
|
||||||
# define DS_AUTH m2_p1 /* authorization of caller */
|
|
||||||
# define DS_VAL_L1 m2_l1 /* first long data value */
|
/* DS_PUBLISH, DS_RETRIEVE */
|
||||||
# define DS_VAL_L2 m2_l2 /* second long data value */
|
# define DS_VAL m2_l1 /* data (u32, char *, etc.) */
|
||||||
|
# define DS_VAL_LEN m2_l2 /* data length */
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* Miscellaneous messages used by TTY *
|
* Miscellaneous messages used by TTY *
|
||||||
|
@ -63,6 +63,7 @@ libsys_FILES=" \
|
|||||||
sys_voutb.c \
|
sys_voutb.c \
|
||||||
sys_voutl.c \
|
sys_voutl.c \
|
||||||
sys_voutw.c \
|
sys_voutw.c \
|
||||||
taskcall.c"
|
taskcall.c \
|
||||||
|
ds.c"
|
||||||
|
|
||||||
TYPE=both
|
TYPE=both
|
||||||
|
259
lib/syslib/ds.c
Normal file
259
lib/syslib/ds.c
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
|
||||||
|
#include <minix/ds.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "syslib.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
ds_subscribe(ds_name_regexp, type, flags)
|
||||||
|
char *ds_name_regexp;
|
||||||
|
int type;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
message m;
|
||||||
|
cp_grant_id_t g;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = strlen(ds_name_regexp)+1;
|
||||||
|
g = cpf_grant_direct(DS_PROC_NR,
|
||||||
|
(vir_bytes) ds_name_regexp, len, CPF_READ);
|
||||||
|
|
||||||
|
if(!GRANT_VALID(g))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
flags &= DS_INITIAL;
|
||||||
|
|
||||||
|
m.DS_KEY_GRANT = (char *) g;
|
||||||
|
m.DS_KEY_LEN = len;
|
||||||
|
m.DS_FLAGS = flags | (type & DS_TYPE_MASK);
|
||||||
|
|
||||||
|
r = _taskcall(DS_PROC_NR, DS_SUBSCRIBE, &m);
|
||||||
|
|
||||||
|
cpf_revoke(g);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds_publish_u32(ds_name, value)
|
||||||
|
char *ds_name;
|
||||||
|
u32_t value;
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
message m;
|
||||||
|
cp_grant_id_t g;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = strlen(ds_name)+1;
|
||||||
|
g = cpf_grant_direct(DS_PROC_NR,
|
||||||
|
(vir_bytes) ds_name, len, CPF_READ);
|
||||||
|
|
||||||
|
if(!GRANT_VALID(g))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
m.DS_KEY_GRANT = (char *) g;
|
||||||
|
m.DS_KEY_LEN = len;
|
||||||
|
m.DS_FLAGS = DS_TYPE_U32;
|
||||||
|
m.DS_VAL = value;
|
||||||
|
m.DS_VAL_LEN = sizeof(value);
|
||||||
|
|
||||||
|
r = _taskcall(DS_PROC_NR, DS_PUBLISH, &m);
|
||||||
|
|
||||||
|
cpf_revoke(g);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds_publish_str(ds_name, value)
|
||||||
|
char *ds_name;
|
||||||
|
char *value;
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
message m;
|
||||||
|
cp_grant_id_t g_key, g_str;
|
||||||
|
size_t len_key, len_str;
|
||||||
|
|
||||||
|
/* Grant for key. */
|
||||||
|
len_key = strlen(ds_name)+1;
|
||||||
|
g_key = cpf_grant_direct(DS_PROC_NR,
|
||||||
|
(vir_bytes) ds_name, len_key, CPF_READ);
|
||||||
|
if(!GRANT_VALID(g_key))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Grant for value. */
|
||||||
|
len_str = strlen(value)+1;
|
||||||
|
g_str = cpf_grant_direct(DS_PROC_NR,
|
||||||
|
(vir_bytes) value, len_str, CPF_READ);
|
||||||
|
|
||||||
|
if(!GRANT_VALID(g_str)) {
|
||||||
|
cpf_revoke(g_key);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m.DS_KEY_GRANT = (char *) g_key;
|
||||||
|
m.DS_KEY_LEN = len_key;
|
||||||
|
m.DS_FLAGS = DS_TYPE_STR;
|
||||||
|
m.DS_VAL = g_str;
|
||||||
|
m.DS_VAL_LEN = len_str;
|
||||||
|
|
||||||
|
r = _taskcall(DS_PROC_NR, DS_PUBLISH, &m);
|
||||||
|
|
||||||
|
cpf_revoke(g_key);
|
||||||
|
cpf_revoke(g_str);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds_retrieve_u32(ds_name, value)
|
||||||
|
char *ds_name;
|
||||||
|
u32_t *value;
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
message m;
|
||||||
|
cp_grant_id_t g_key;
|
||||||
|
size_t len_key;
|
||||||
|
|
||||||
|
/* Grant for key. */
|
||||||
|
len_key = strlen(ds_name)+1;
|
||||||
|
g_key = cpf_grant_direct(DS_PROC_NR,
|
||||||
|
(vir_bytes) ds_name, len_key, CPF_READ);
|
||||||
|
if(!GRANT_VALID(g_key))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Do request. */
|
||||||
|
m.DS_KEY_GRANT = (char *) g_key;
|
||||||
|
m.DS_KEY_LEN = len_key;
|
||||||
|
m.DS_FLAGS = DS_TYPE_U32;
|
||||||
|
|
||||||
|
r = _taskcall(DS_PROC_NR, DS_RETRIEVE, &m);
|
||||||
|
|
||||||
|
cpf_revoke(g_key);
|
||||||
|
|
||||||
|
/* Assign u32 value. */
|
||||||
|
*value = m.DS_VAL;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds_retrieve_str(ds_name, value, len_str)
|
||||||
|
char *ds_name;
|
||||||
|
char *value;
|
||||||
|
size_t len_str;
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
message m;
|
||||||
|
cp_grant_id_t g_key, g_str;
|
||||||
|
size_t len_key;
|
||||||
|
|
||||||
|
/* Grant for key. */
|
||||||
|
len_key = strlen(ds_name)+1;
|
||||||
|
g_key = cpf_grant_direct(DS_PROC_NR,
|
||||||
|
(vir_bytes) ds_name, len_key, CPF_READ);
|
||||||
|
if(!GRANT_VALID(g_key))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Grant for value. */
|
||||||
|
g_str = cpf_grant_direct(DS_PROC_NR,
|
||||||
|
(vir_bytes) value, len_str, CPF_WRITE);
|
||||||
|
|
||||||
|
if(!GRANT_VALID(g_str)) {
|
||||||
|
cpf_revoke(g_key);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do request. */
|
||||||
|
|
||||||
|
m.DS_KEY_GRANT = (char *) g_key;
|
||||||
|
m.DS_KEY_LEN = len_key;
|
||||||
|
m.DS_FLAGS = DS_TYPE_STR;
|
||||||
|
m.DS_VAL = g_str;
|
||||||
|
m.DS_VAL_LEN = len_str;
|
||||||
|
|
||||||
|
r = _taskcall(DS_PROC_NR, DS_RETRIEVE, &m);
|
||||||
|
|
||||||
|
cpf_revoke(g_key);
|
||||||
|
cpf_revoke(g_str);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds_check_str(ds_key, len_key, value, len_str)
|
||||||
|
char *ds_key;
|
||||||
|
size_t len_key;
|
||||||
|
char *value;
|
||||||
|
size_t len_str;
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
message m;
|
||||||
|
cp_grant_id_t g_key, g_str;
|
||||||
|
|
||||||
|
if(len_key < 1 || len_str < 1) return -1;
|
||||||
|
|
||||||
|
/* Grant for key. */
|
||||||
|
g_key = cpf_grant_direct(DS_PROC_NR,
|
||||||
|
(vir_bytes) ds_key, len_key, CPF_WRITE);
|
||||||
|
if(!GRANT_VALID(g_key))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Grant for value. */
|
||||||
|
g_str = cpf_grant_direct(DS_PROC_NR,
|
||||||
|
(vir_bytes) value, len_str, CPF_WRITE);
|
||||||
|
|
||||||
|
if(!GRANT_VALID(g_str)) {
|
||||||
|
cpf_revoke(g_key);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do request. */
|
||||||
|
|
||||||
|
m.DS_KEY_GRANT = (char *) g_key;
|
||||||
|
m.DS_KEY_LEN = len_key;
|
||||||
|
m.DS_FLAGS = DS_TYPE_STR;
|
||||||
|
m.DS_VAL = g_str;
|
||||||
|
m.DS_VAL_LEN = len_str;
|
||||||
|
|
||||||
|
r = _taskcall(DS_PROC_NR, DS_CHECK, &m);
|
||||||
|
|
||||||
|
cpf_revoke(g_key);
|
||||||
|
cpf_revoke(g_str);
|
||||||
|
|
||||||
|
ds_key[len_key-1] = '\0';
|
||||||
|
value[len_str-1] = '\0';
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds_check_u32(ds_key, len_key, value)
|
||||||
|
char *ds_key;
|
||||||
|
size_t len_key;
|
||||||
|
u32_t *value;
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
message m;
|
||||||
|
cp_grant_id_t g_key;
|
||||||
|
|
||||||
|
if(len_key < 1) return -1;
|
||||||
|
|
||||||
|
/* Grant for key. */
|
||||||
|
g_key = cpf_grant_direct(DS_PROC_NR,
|
||||||
|
(vir_bytes) ds_key, len_key, CPF_WRITE);
|
||||||
|
if(!GRANT_VALID(g_key))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Do request. */
|
||||||
|
m.DS_KEY_GRANT = (char *) g_key;
|
||||||
|
m.DS_KEY_LEN = len_key;
|
||||||
|
m.DS_FLAGS = DS_TYPE_U32;
|
||||||
|
|
||||||
|
r = _taskcall(DS_PROC_NR, DS_CHECK, &m);
|
||||||
|
|
||||||
|
cpf_revoke(g_key);
|
||||||
|
|
||||||
|
ds_key[len_key-1] = '\0';
|
||||||
|
|
||||||
|
/* Assign u32 value. */
|
||||||
|
*value = m.DS_VAL;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
@ -310,3 +310,4 @@ cp_grant_id_t gid;
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,6 +59,9 @@ PUBLIC int main(int argc, char **argv)
|
|||||||
case DS_SUBSCRIBE:
|
case DS_SUBSCRIBE:
|
||||||
result = do_subscribe(&m);
|
result = do_subscribe(&m);
|
||||||
break;
|
break;
|
||||||
|
case DS_CHECK:
|
||||||
|
result = do_check(&m);
|
||||||
|
break;
|
||||||
case GETSYSINFO:
|
case GETSYSINFO:
|
||||||
result = do_getsysinfo(&m);
|
result = do_getsysinfo(&m);
|
||||||
break;
|
break;
|
||||||
@ -91,6 +94,9 @@ PRIVATE void init_server(int argc, char **argv)
|
|||||||
sigact.sa_flags = 0; /* default behaviour */
|
sigact.sa_flags = 0; /* default behaviour */
|
||||||
if (sigaction(SIGTERM, &sigact, NULL) < 0)
|
if (sigaction(SIGTERM, &sigact, NULL) < 0)
|
||||||
report("DS","warning, sigaction() failed", errno);
|
report("DS","warning, sigaction() failed", errno);
|
||||||
|
|
||||||
|
/* Initialize DS. */
|
||||||
|
ds_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
@ -7,4 +7,6 @@ _PROTOTYPE(int main, (int argc, char **argv));
|
|||||||
_PROTOTYPE(int do_publish, (message *m_ptr));
|
_PROTOTYPE(int do_publish, (message *m_ptr));
|
||||||
_PROTOTYPE(int do_retrieve, (message *m_ptr));
|
_PROTOTYPE(int do_retrieve, (message *m_ptr));
|
||||||
_PROTOTYPE(int do_subscribe, (message *m_ptr));
|
_PROTOTYPE(int do_subscribe, (message *m_ptr));
|
||||||
|
_PROTOTYPE(int do_check, (message *m_ptr));
|
||||||
_PROTOTYPE(int do_getsysinfo, (message *m_ptr));
|
_PROTOTYPE(int do_getsysinfo, (message *m_ptr));
|
||||||
|
_PROTOTYPE(void ds_init, (void));
|
||||||
|
@ -4,40 +4,66 @@
|
|||||||
|
|
||||||
/* Allocate space for the data store. */
|
/* Allocate space for the data store. */
|
||||||
PRIVATE struct data_store ds_store[NR_DS_KEYS];
|
PRIVATE struct data_store ds_store[NR_DS_KEYS];
|
||||||
|
PRIVATE struct subscription ds_subs[NR_DS_SUBS];
|
||||||
PRIVATE int nr_in_use;
|
PRIVATE int nr_in_use;
|
||||||
|
|
||||||
PRIVATE _PROTOTYPE(int find_key, (int key, struct data_store **dsp));
|
PRIVATE _PROTOTYPE(int find_key, (char *key, struct data_store **dsp, int t));
|
||||||
PRIVATE _PROTOTYPE(int set_owner, (struct data_store *dsp, void *auth_ptr));
|
PRIVATE _PROTOTYPE(int set_owner, (struct data_store *dsp, int auth));
|
||||||
PRIVATE _PROTOTYPE(int is_authorized, (struct data_store *dsp, void *auth_ptr));
|
PRIVATE _PROTOTYPE(int is_authorized, (struct data_store *dsp, int auth));
|
||||||
|
PRIVATE _PROTOTYPE(void check_subscribers, (struct data_store *dsp));
|
||||||
|
|
||||||
|
|
||||||
PRIVATE int set_owner(dsp, ap)
|
/*===========================================================================*
|
||||||
struct data_store *dsp; /* data store structure */
|
* ds_init *
|
||||||
void *ap; /* authorization pointer */
|
*===========================================================================*/
|
||||||
|
PUBLIC void ds_init(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Reset data store: data and subscriptions. */
|
||||||
|
|
||||||
|
for(i = 0; i < NR_DS_KEYS; i++) {
|
||||||
|
int b;
|
||||||
|
ds_store[i].ds_flags = 0;
|
||||||
|
for(b = 0; b < BITMAP_CHUNKS(NR_DS_SUBS); b++) {
|
||||||
|
ds_store[i].ds_old_subs[b] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(i = 0; i < NR_DS_SUBS; i++)
|
||||||
|
ds_subs[i].sub_flags = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRIVATE int set_owner(dsp, auth)
|
||||||
|
struct data_store *dsp; /* data store structure */
|
||||||
|
int auth;
|
||||||
{
|
{
|
||||||
/* Authorize the caller. */
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PRIVATE int is_authorized(dsp, ap)
|
PRIVATE int is_authorized(dsp, ap)
|
||||||
struct data_store *dsp; /* data store structure */
|
struct data_store *dsp; /* data store structure */
|
||||||
void *ap; /* authorization pointer */
|
int ap; /* authorization value */
|
||||||
{
|
{
|
||||||
/* Authorize the caller. */
|
/* Authorize the caller. */
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PRIVATE int find_key(key, dsp)
|
PRIVATE int find_key(key_name, dsp, type)
|
||||||
int key; /* key to look up */
|
char *key_name; /* key to look up */
|
||||||
struct data_store **dsp; /* store pointer here */
|
struct data_store **dsp; /* store pointer here */
|
||||||
|
int type; /* type info */
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
*dsp = NULL;
|
*dsp = NULL;
|
||||||
for (i=0; i<NR_DS_KEYS; i++) {
|
for (i=0; i<NR_DS_KEYS; i++) {
|
||||||
if ((ds_store[i].ds_flags & DS_IN_USE) && ds_store[i].ds_key == key) {
|
if ((ds_store[i].ds_flags & DS_IN_USE) /* valid slot? */
|
||||||
|
&& ((ds_store[i].ds_flags & type) == type) /* right type? */
|
||||||
|
&& !strcmp(ds_store[i].ds_key, key_name)) { /* matching name? */
|
||||||
*dsp = &ds_store[i];
|
*dsp = &ds_store[i];
|
||||||
return(TRUE); /* report success */
|
return(TRUE); /* report success */
|
||||||
}
|
}
|
||||||
@ -50,27 +76,45 @@ PUBLIC int do_publish(m_ptr)
|
|||||||
message *m_ptr; /* request message */
|
message *m_ptr; /* request message */
|
||||||
{
|
{
|
||||||
struct data_store *dsp;
|
struct data_store *dsp;
|
||||||
|
char key_name[DS_MAX_KEYLEN];
|
||||||
|
int r, type;
|
||||||
|
|
||||||
/* Store (key,value)-pair. First see if key already exists. If so,
|
/* Store (key,value)-pair. First see if key already exists. If so,
|
||||||
* check if the caller is allowed to overwrite the value. Otherwise
|
* check if the caller is allowed to overwrite the value. Otherwise
|
||||||
* find a new slot and store the new value.
|
* find a new slot and store the new value.
|
||||||
*/
|
*/
|
||||||
if (find_key(m_ptr->DS_KEY, &dsp)) { /* look up key */
|
if (m_ptr->DS_KEY_LEN > DS_MAX_KEYLEN || m_ptr->DS_KEY_LEN < 2) {
|
||||||
if (! is_authorized(dsp,m_ptr->DS_AUTH)) { /* check if owner */
|
printf("DS: bogus key length (%d) from %d\n", m_ptr->DS_KEY_LEN,
|
||||||
return(EPERM);
|
m_ptr->m_source);
|
||||||
}
|
return EINVAL;
|
||||||
}
|
}
|
||||||
else { /* find a new slot */
|
|
||||||
|
/* Check type info. */
|
||||||
|
type = m_ptr->DS_FLAGS & DS_TYPE_MASK;
|
||||||
|
if(type != DS_TYPE_U32 && type != DS_TYPE_STR) {
|
||||||
|
printf("DS: bogus type code %lx from %d\n", type, m_ptr->m_source);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy name from caller. */
|
||||||
|
if ((r=sys_safecopyfrom(m_ptr->m_source,
|
||||||
|
(cp_grant_id_t) m_ptr->DS_KEY_GRANT, 0,
|
||||||
|
(vir_bytes) key_name, m_ptr->DS_KEY_LEN, D)) != OK) {
|
||||||
|
printf("DS: publish: copy failed from %d: %d\n", m_ptr->m_source, r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure name is 0-terminated. */
|
||||||
|
key_name[DS_MAX_KEYLEN-1] = '\0';
|
||||||
|
|
||||||
|
/* See if it already exists. */
|
||||||
|
if (!find_key(key_name, &dsp, type)) { /* look up key */
|
||||||
if (nr_in_use >= NR_DS_KEYS) {
|
if (nr_in_use >= NR_DS_KEYS) {
|
||||||
return(EAGAIN); /* store is full */
|
return(EAGAIN); /* store is full */
|
||||||
} else {
|
} else {
|
||||||
dsp = &ds_store[nr_in_use]; /* new slot found */
|
dsp = &ds_store[nr_in_use]; /* new slot found */
|
||||||
dsp->ds_key = m_ptr->DS_KEY;
|
strcpy(dsp->ds_key, key_name);
|
||||||
if (! set_owner(dsp,m_ptr->DS_AUTH)) { /* associate owner */
|
dsp->ds_flags = DS_IN_USE | m_ptr->DS_FLAGS; /* initialize slot */
|
||||||
return(EINVAL);
|
|
||||||
}
|
|
||||||
dsp->ds_nr_subs = 0; /* nr of subscribers */
|
|
||||||
dsp->ds_flags = DS_IN_USE; /* initialize slot */
|
|
||||||
nr_in_use ++;
|
nr_in_use ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,59 +122,245 @@ message *m_ptr; /* request message */
|
|||||||
/* At this point we have a data store pointer and know the caller is
|
/* At this point we have a data store pointer and know the caller is
|
||||||
* authorize to write to it. Set all fields as requested.
|
* authorize to write to it. Set all fields as requested.
|
||||||
*/
|
*/
|
||||||
dsp->ds_val_l1 = m_ptr->DS_VAL_L1; /* store all data */
|
switch(type) {
|
||||||
dsp->ds_val_l2 = m_ptr->DS_VAL_L2;
|
case DS_TYPE_U32:
|
||||||
|
dsp->ds_val.ds_val_u32 = (u32_t) m_ptr->DS_VAL; /* store data */
|
||||||
|
break;
|
||||||
|
case DS_TYPE_STR:
|
||||||
|
/* store string data: check size, then do copy */
|
||||||
|
if(m_ptr->DS_VAL_LEN < 1 || m_ptr->DS_VAL_LEN > DS_MAX_VALLEN) {
|
||||||
|
printf("DS: publish: bogus len from %d: %d\n",
|
||||||
|
m_ptr->m_source, m_ptr->DS_VAL_LEN);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the data is public. Check if there are any subscribers to this key.
|
if((r=sys_safecopyfrom(m_ptr->m_source, m_ptr->DS_VAL, 0,
|
||||||
* If so, notify all subscribers so that they can retrieve the data, if
|
(vir_bytes) dsp->ds_val.ds_val_str,
|
||||||
* they're still interested.
|
m_ptr->DS_VAL_LEN, D)) != OK) {
|
||||||
*/
|
printf("DS: publish: str copy failed from %d: %d\n",
|
||||||
if ((dsp->ds_flags & DS_PUBLIC) && dsp->ds_nr_subs > 0) {
|
m_ptr->m_source, r);
|
||||||
|
return r;
|
||||||
/* Subscriptions are not yet implemented. */
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic(__FILE__, "Impossible type.", type);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If anyone has a matching subscription, update them. */
|
||||||
|
check_subscribers(dsp);
|
||||||
|
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* do_retrieve *
|
||||||
|
*===========================================================================*/
|
||||||
PUBLIC int do_retrieve(m_ptr)
|
PUBLIC int do_retrieve(m_ptr)
|
||||||
message *m_ptr; /* request message */
|
message *m_ptr; /* request message */
|
||||||
{
|
{
|
||||||
struct data_store *dsp;
|
struct data_store *dsp;
|
||||||
|
char key_name[DS_MAX_KEYLEN];
|
||||||
|
int r, type;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (m_ptr->DS_KEY_LEN > DS_MAX_KEYLEN || m_ptr->DS_KEY_LEN < 1) {
|
||||||
|
printf("DS: bogus key length (%d) from %d\n", m_ptr->DS_KEY_LEN,
|
||||||
|
m_ptr->m_source);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy name from caller. */
|
||||||
|
if ((r=sys_safecopyfrom(m_ptr->m_source,
|
||||||
|
(cp_grant_id_t) m_ptr->DS_KEY_GRANT, 0,
|
||||||
|
(vir_bytes) key_name, m_ptr->DS_KEY_LEN, D)) != OK) {
|
||||||
|
printf("DS: retrieve: copy failed from %d: %d\n", m_ptr->m_source, r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure name is 0-terminated. */
|
||||||
|
key_name[DS_MAX_KEYLEN-1] = '\0';
|
||||||
|
|
||||||
|
|
||||||
/* Retrieve data. Look up the key in the data store. Return an error if it
|
/* Retrieve data. Look up the key in the data store. Return an error if it
|
||||||
* is not found. If this data is private, only the owner may retrieve it.
|
* is not found. If this data is private, only the owner may retrieve it.
|
||||||
*/
|
*/
|
||||||
if (find_key(m_ptr->DS_KEY, &dsp)) { /* look up key */
|
type = m_ptr->DS_FLAGS & DS_TYPE_MASK;
|
||||||
|
if (find_key(key_name, &dsp, type)) { /* look up key */
|
||||||
/* If the data is not public, the caller must be authorized. */
|
|
||||||
if (! dsp->ds_flags & DS_PUBLIC) { /* check if private */
|
|
||||||
if (! is_authorized(dsp,m_ptr->DS_AUTH)) { /* authorize call */
|
|
||||||
return(EPERM); /* not allowed */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Data is public or the caller is authorized to retrieve it. */
|
/* Data is public or the caller is authorized to retrieve it. */
|
||||||
printf("DS retrieves data: key %d (found %d), l1 %u, l2 %u\n",
|
switch(type) {
|
||||||
m_ptr->DS_KEY, dsp->ds_key, dsp->ds_val_l1, dsp->ds_val_l2);
|
case DS_TYPE_U32:
|
||||||
m_ptr->DS_VAL_L1 = dsp->ds_val_l1; /* return value */
|
m_ptr->DS_VAL = dsp->ds_val.ds_val_u32; /* return value */
|
||||||
m_ptr->DS_VAL_L2 = dsp->ds_val_l2; /* return value */
|
break;
|
||||||
|
case DS_TYPE_STR:
|
||||||
|
len = strlen(dsp->ds_val.ds_val_str) + 1;
|
||||||
|
if(len > m_ptr->DS_VAL_LEN)
|
||||||
|
len = m_ptr->DS_VAL_LEN;
|
||||||
|
if ((r=sys_safecopyto(m_ptr->m_source, m_ptr->DS_VAL,
|
||||||
|
0, (vir_bytes) dsp->ds_val.ds_val_str,len, D)) != OK) {
|
||||||
|
printf("DS: retrieve: copy failed to %d: %d\n",
|
||||||
|
m_ptr->m_source, r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic(__FILE__, "retrieve: impossible type.", type);
|
||||||
|
/* not reached. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
return(OK); /* report success */
|
return(OK); /* report success */
|
||||||
}
|
}
|
||||||
return(ESRCH); /* key not found */
|
return(ESRCH); /* key not found */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* do_check *
|
||||||
|
*===========================================================================*/
|
||||||
|
PUBLIC int do_check(m_ptr)
|
||||||
|
message *m_ptr; /* request message */
|
||||||
|
{
|
||||||
|
/* This routine goes through all subscriptions for a client,
|
||||||
|
* and checks all data items if it has been flagged (i.e.,
|
||||||
|
* created or updated) matching that subscription. Return
|
||||||
|
* a message and copy the key and value for every one.
|
||||||
|
*/
|
||||||
|
struct data_store *dsp;
|
||||||
|
int r, s, d, type = m_ptr->DS_FLAGS & DS_TYPE_MASK;
|
||||||
|
if(!type) return EINVAL;
|
||||||
|
for(s = 0; s < NR_DS_SUBS; s++) {
|
||||||
|
int len;
|
||||||
|
if(!(ds_subs[s].sub_flags & DS_IN_USE))
|
||||||
|
continue;
|
||||||
|
if(m_ptr->m_source != ds_subs[s].sub_owner)
|
||||||
|
continue;
|
||||||
|
for(d = 0; d < NR_DS_KEYS; d++) {
|
||||||
|
|
||||||
|
/* No match if this is no value, it's
|
||||||
|
* not flagged, or the type is wrong.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(!(ds_store[d].ds_flags & DS_IN_USE))
|
||||||
|
continue;
|
||||||
|
if(!GET_BIT(ds_store[d].ds_old_subs, s))
|
||||||
|
continue;
|
||||||
|
if(type != (ds_store[d].ds_flags & DS_TYPE_MASK))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* We have a match. Unflag it for this
|
||||||
|
* subscription.
|
||||||
|
*/
|
||||||
|
UNSET_BIT(ds_store[d].ds_old_subs, s);
|
||||||
|
len = strlen(ds_store[d].ds_key)+1;
|
||||||
|
if(len > m_ptr->DS_KEY_LEN)
|
||||||
|
len = m_ptr->DS_KEY_LEN;
|
||||||
|
|
||||||
|
/* Copy the key into client. */
|
||||||
|
if ((r=sys_safecopyto(m_ptr->m_source,
|
||||||
|
(cp_grant_id_t) m_ptr->DS_KEY_GRANT, 0,
|
||||||
|
(vir_bytes) ds_store[d].ds_key,
|
||||||
|
len, D)) != OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* Now copy the value. */
|
||||||
|
switch(type) {
|
||||||
|
case DS_TYPE_STR:
|
||||||
|
len = strlen(ds_store[d].
|
||||||
|
ds_val.ds_val_str)+1;
|
||||||
|
if(len > m_ptr->DS_VAL_LEN)
|
||||||
|
len = m_ptr->DS_VAL_LEN;
|
||||||
|
if ((r=sys_safecopyto(m_ptr->m_source,
|
||||||
|
m_ptr->DS_VAL, 0,
|
||||||
|
(vir_bytes) ds_store[d].
|
||||||
|
ds_val.ds_val_str,
|
||||||
|
len, D)) != OK)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
|
case DS_TYPE_U32:
|
||||||
|
m_ptr->DS_VAL =
|
||||||
|
ds_store[d].ds_val.ds_val_u32;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic(__FILE__,
|
||||||
|
"Check impossible type.",
|
||||||
|
type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ESRCH); /* key not found */
|
||||||
|
}
|
||||||
|
|
||||||
PUBLIC int do_subscribe(m_ptr)
|
PUBLIC int do_subscribe(m_ptr)
|
||||||
message *m_ptr; /* request message */
|
message *m_ptr; /* request message */
|
||||||
{
|
{
|
||||||
/* Subscribe to a key of interest. Only existing and public keys can be
|
char regex[DS_MAX_KEYLEN+3];
|
||||||
* subscribed to. All updates to the key will cause a notification message
|
int s, type, e, d, n = 0;
|
||||||
|
char errbuf[80];
|
||||||
|
|
||||||
|
/* Subscribe to a key of interest.
|
||||||
|
* All updates to the key will cause a notification message
|
||||||
* to be sent to the subscribed. On success, directly return a copy of the
|
* to be sent to the subscribed. On success, directly return a copy of the
|
||||||
* data for the given key.
|
* data for the given key.
|
||||||
*/
|
*/
|
||||||
return(ENOSYS);
|
if(m_ptr->DS_KEY_LEN < 2 || m_ptr->DS_KEY_LEN > DS_MAX_KEYLEN)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
/* Copy name from caller. Anchor the subscription with "^regexp$" so
|
||||||
|
* substrings don't match. The caller probably will not expect this,
|
||||||
|
* and the usual case is for a complete match.
|
||||||
|
*/
|
||||||
|
regex[0] = '^';
|
||||||
|
if ((s=sys_safecopyfrom(m_ptr->m_source,
|
||||||
|
(cp_grant_id_t) m_ptr->DS_KEY_GRANT, 0,
|
||||||
|
(vir_bytes) regex + 1, m_ptr->DS_KEY_LEN, D)) != OK) {
|
||||||
|
printf("DS: retrieve: copy failed from %d: %d\n", m_ptr->m_source, s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
regex[DS_MAX_KEYLEN-1] = '\0';
|
||||||
|
strcat(regex, "$");
|
||||||
|
|
||||||
|
/* Find subscription slot. */
|
||||||
|
for(s = 0; s < NR_DS_SUBS; s++)
|
||||||
|
if(!(ds_subs[s].sub_flags & DS_IN_USE))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(s >= NR_DS_SUBS) {
|
||||||
|
printf("DS: no space for subscription by %d.\n", m_ptr->m_source);
|
||||||
|
return ENOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compile regular expression. */
|
||||||
|
if((e=regcomp(&ds_subs[s].sub_regex, regex, REG_EXTENDED)) != 0) {
|
||||||
|
regerror(e, &ds_subs[s].sub_regex, errbuf, sizeof(errbuf));
|
||||||
|
printf("DS: subscribe: regerror: %s\n", errbuf);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
type = (m_ptr->DS_FLAGS & DS_TYPE_MASK);
|
||||||
|
ds_subs[s].sub_flags = DS_IN_USE | type;
|
||||||
|
ds_subs[s].sub_owner = m_ptr->m_source;
|
||||||
|
|
||||||
|
/* Caller requested an instant initial list? */
|
||||||
|
if(m_ptr->DS_FLAGS & DS_INITIAL) {
|
||||||
|
for(d = 0; d < NR_DS_KEYS; d++) {
|
||||||
|
if(!(ds_store[d].ds_flags & DS_IN_USE))
|
||||||
|
continue;
|
||||||
|
if(regexec(&ds_subs[s].sub_regex, ds_store[d].ds_key,
|
||||||
|
0, NULL, 0) == 0) {
|
||||||
|
SET_BIT(ds_store[d].ds_old_subs, s);
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Any matches? */
|
||||||
|
if(n) notify(ds_subs[s].sub_owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -156,8 +386,34 @@ message *m_ptr;
|
|||||||
|
|
||||||
dst_proc = m_ptr->m_source;
|
dst_proc = m_ptr->m_source;
|
||||||
dst_addr = (vir_bytes) m_ptr->m1_p1;
|
dst_addr = (vir_bytes) m_ptr->m1_p1;
|
||||||
if (OK != (s=sys_datacopy(SELF, src_addr, dst_proc, dst_addr, len)))
|
if (OK != (s=sys_datacopy(SELF, src_addr, dst_proc, dst_addr, len))) {
|
||||||
|
printf("DS: copy failed: %d\n", s);
|
||||||
return(s);
|
return(s);
|
||||||
|
}
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* check_subscribers *
|
||||||
|
*===========================================================================*/
|
||||||
|
PRIVATE void
|
||||||
|
check_subscribers(struct data_store *dsp)
|
||||||
|
{
|
||||||
|
/* Send subscribers whose subscriptions match this (new
|
||||||
|
* or updated) data item a notify(), and flag the subscriptions
|
||||||
|
* as updated.
|
||||||
|
*/
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < NR_DS_SUBS; i++) {
|
||||||
|
if(ds_subs[i].sub_flags & DS_IN_USE) {
|
||||||
|
if(regexec(&ds_subs[i].sub_regex, dsp->ds_key,
|
||||||
|
0, NULL, 0) == 0) {
|
||||||
|
SET_BIT(dsp->ds_old_subs, i);
|
||||||
|
notify(ds_subs[i].sub_owner);
|
||||||
|
} else {
|
||||||
|
UNSET_BIT(dsp->ds_old_subs, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,33 @@
|
|||||||
/* Type definitions for the Data Store Server. */
|
/* Type definitions for the Data Store Server. */
|
||||||
struct data_store {
|
|
||||||
int ds_flags; /* flags for this store */
|
|
||||||
int ds_key; /* key to lookup information */
|
|
||||||
long ds_val_l1; /* data associated with key */
|
|
||||||
long ds_val_l2; /* data associated with key */
|
|
||||||
long ds_auth; /* secret given by owner of data */
|
|
||||||
int ds_nr_subs; /* number of subscribers for key */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Flag values. */
|
#include <sys/types.h>
|
||||||
#define DS_IN_USE 0x01
|
#include <minix/sys_config.h>
|
||||||
#define DS_PUBLIC 0x02
|
#include <minix/ds.h>
|
||||||
|
#include <minix/bitmap.h>
|
||||||
|
#include <regex.h>
|
||||||
|
|
||||||
/* Constants for the Data Store Server. */
|
/* Constants for the Data Store Server. */
|
||||||
#define NR_DS_KEYS 64 /* reserve space for so many items */
|
#define NR_DS_KEYS 64 /* reserve space for so many items */
|
||||||
|
#define NR_DS_SUBS (4*_NR_SYS_PROCS) /* .. and so many subscriptions */
|
||||||
|
|
||||||
|
/* Types. */
|
||||||
|
|
||||||
|
struct data_store {
|
||||||
|
int ds_flags; /* flags for this store, includes type info */
|
||||||
|
char ds_key[DS_MAX_KEYLEN]; /* key to lookup information */
|
||||||
|
union {
|
||||||
|
u32_t ds_val_u32; /* u32 data (DS_TYPE_U32) */
|
||||||
|
char ds_val_str[DS_MAX_VALLEN]; /* string data (DS_TYPE_STR) */
|
||||||
|
} ds_val;
|
||||||
|
|
||||||
|
/* out of date subscribers. */
|
||||||
|
bitchunk_t ds_old_subs[BITMAP_CHUNKS(NR_DS_SUBS)];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct subscription {
|
||||||
|
int sub_flags; /* flags for this subscription */
|
||||||
|
regex_t sub_regex; /* regular expression agains keys */
|
||||||
|
endpoint_t sub_owner; /* who is subscribed */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
/* Define hooks for the debugging dumps. This table maps function keys
|
/* Define hooks for the debugging dumps. This table maps function keys
|
||||||
* onto a specific dump and provides a description for it.
|
* onto a specific dump and provides a description for it.
|
||||||
*/
|
*/
|
||||||
#define NHOOKS 19
|
#define NHOOKS 18
|
||||||
|
|
||||||
struct hook_entry {
|
struct hook_entry {
|
||||||
int key;
|
int key;
|
||||||
|
@ -20,26 +20,32 @@ FORWARD _PROTOTYPE( char *s_flags_str, (int flags) );
|
|||||||
PUBLIC void data_store_dmp()
|
PUBLIC void data_store_dmp()
|
||||||
{
|
{
|
||||||
struct data_store *dsp;
|
struct data_store *dsp;
|
||||||
int i,j, n=0;
|
int i,j, n=0, s;
|
||||||
static int prev_i=0;
|
static int prev_i=0;
|
||||||
|
|
||||||
|
|
||||||
printf("Data Store (DS) contents dump\n");
|
printf("Data Store (DS) contents dump\n");
|
||||||
|
|
||||||
getsysinfo(DS_PROC_NR, SI_DATA_STORE, store);
|
if((s=getsysinfo(DS_PROC_NR, SI_DATA_STORE, store)) != OK) {
|
||||||
|
printf("Couldn't talk to DS: %d.\n", s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
printf("-slot- -key- -flags- -val_l1- -val_l2-\n");
|
printf("slot key type value\n");
|
||||||
|
|
||||||
for (i=prev_i; i<NR_DS_KEYS; i++) {
|
for (i=prev_i; i<NR_DS_KEYS; i++) {
|
||||||
dsp = &store[i];
|
dsp = &store[i];
|
||||||
if (! dsp->ds_flags & DS_IN_USE) continue;
|
if (! dsp->ds_flags & DS_IN_USE) continue;
|
||||||
if (++n > 22) break;
|
if (++n > 22) break;
|
||||||
printf("%3d %8d %s [%8d] [%8d] \n",
|
printf("%3d %-20s ",
|
||||||
i, dsp->ds_key,
|
i, dsp->ds_key);
|
||||||
s_flags_str(dsp->ds_flags),
|
if(dsp->ds_flags & DS_TYPE_U32) {
|
||||||
dsp->ds_val_l1,
|
printf("u32 %lu\n", dsp->ds_val.ds_val_u32);
|
||||||
dsp->ds_val_l2
|
} else if(dsp->ds_flags & DS_TYPE_STR) {
|
||||||
);
|
printf("str \"%s\"\n", dsp->ds_val.ds_val_str);
|
||||||
|
} else {
|
||||||
|
printf("Bogus type\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (i >= NR_DS_KEYS) i = 0;
|
if (i >= NR_DS_KEYS) i = 0;
|
||||||
else printf("--more--\r");
|
else printf("--more--\r");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user