I agree. It would be nice if we could export variables from the same
file they are declared in rather than spreading them across multiple
files.

On Tue, Nov 24, 2015 at 2:15 PM, 'Davide Libenzi' via Akaros
<[email protected]> wrote:
> This would have been a bit nicer IMO, if modules wanting to export
> variables, won't need to hack into another file.
> The macro, used locally in the module source files, would populate a given
> section with structs like:
>
> struct var_export_entry {
>     const char *name;
>     void *addr;
>     unsigned long flags;
> };
>
> Then the init code of the var file would just read those entries and
> populate the var namespace.
>
>
>
>
> On Tue, Nov 24, 2015 at 2:10 PM, Kevin Klues <[email protected]> wrote:
>>
>> I'm curious if we don't want to expose the topology in the same way
>> linux does in /proc so libraries like libnuma can compile and just
>> work. I see the usefulness of this for variables in general, but I'm
>> not sure num_cores should be here (or maybe it's also here in addition
>> to /proc).
>>
>> On Tue, Nov 24, 2015 at 2:02 PM, Barret Rhoden <[email protected]>
>> wrote:
>> > With #vars, you can specify certain global variables, such as num_cores,
>> > to
>> > be exposed to userspace.  If you want, you can:
>> >
>> > $ bind -a \#vars /dev
>> > $ cat /dev/num_cores
>> >
>> > For debugging, you can add entries to vars_dir[] to temporarily track
>> > certain variables.  In the future, we could try adding support for
>> > dynamically adding entries.
>> >
>> > Signed-off-by: Barret Rhoden <[email protected]>
>> > ---
>> >  kern/drivers/dev/Kbuild  |   1 +
>> >  kern/drivers/dev/Kconfig |   7 ++
>> >  kern/drivers/dev/vars.c  | 183
>> > +++++++++++++++++++++++++++++++++++++++++++++++
>> >  3 files changed, 191 insertions(+)
>> >  create mode 100644 kern/drivers/dev/vars.c
>> >
>> > diff --git a/kern/drivers/dev/Kbuild b/kern/drivers/dev/Kbuild
>> > index 57fd9368fb60..ee5e7a74fe21 100644
>> > --- a/kern/drivers/dev/Kbuild
>> > +++ b/kern/drivers/dev/Kbuild
>> > @@ -12,5 +12,6 @@ obj-y                                         +=
>> > proc.o
>> >  obj-$(CONFIG_REGRESS)                          += regress.o
>> >  obj-y                                          += root.o
>> >  obj-y                                          += srv.o
>> > +obj-$(CONFIG_VARS)                     += vars.o
>> >
>> >  obj-$(CONFIG_NIX)                              += nix.o
>> > diff --git a/kern/drivers/dev/Kconfig b/kern/drivers/dev/Kconfig
>> > index eb737b8b11cb..85aac58f1a3f 100644
>> > --- a/kern/drivers/dev/Kconfig
>> > +++ b/kern/drivers/dev/Kconfig
>> > @@ -4,3 +4,10 @@ config REGRESS
>> >          help
>> >                  The regression test device allows you to push commands
>> > to monitor()
>> >                 for testing. Defaults to 'y' for now.
>> > +
>> > +config VARS
>> > +       bool "#vars kernel variable exporter"
>> > +       default y
>> > +       help
>> > +               The #vars device exports read access to select kernel
>> > variables.  The
>> > +               list of variables is statically declared in vars.c
>> > diff --git a/kern/drivers/dev/vars.c b/kern/drivers/dev/vars.c
>> > new file mode 100644
>> > index 000000000000..573e3ac1c1d9
>> > --- /dev/null
>> > +++ b/kern/drivers/dev/vars.c
>> > @@ -0,0 +1,183 @@
>> > +/* Copyright (c) 2015 Google Inc
>> > + * Barret Rhoden <[email protected]>
>> > + * See LICENSE for details.
>> > + *
>> > + * #vars device, exports read access to select kernel global variables.
>> > These
>> > + * variables are statically determined (i.e. set in the code below).
>> > + *
>> > + * To add a variable, add a VARS_ENTRY to vars_dir.  If the variable is
>> > a number
>> > + * and you want it in hex, "or" VARS_HEX into the type.  e.g:
>> > + *
>> > + *     VARS_ENTRY(foobar, type_int | VARS_HEX),
>> > + *
>> > + * If we add write support to vars, those will also be flags for
>> > 'type.'
>> > + *
>> > + * Another thing we can consider doing is implementing create() to add
>> > variables
>> > + * on the fly.  We can easily get the address (symbol table), but not
>> > the type,
>> > + * unless we get debugging info.  We could consider a CTL command to
>> > allow the
>> > + * user to change the type, though that might overload write() if we
>> > also allow
>> > + * setting variables. */
>> > +
>> > +#include <ns.h>
>> > +#include <kmalloc.h>
>> > +#include <kref.h>
>> > +#include <atomic.h>
>> > +#include <string.h>
>> > +#include <stdio.h>
>> > +#include <assert.h>
>> > +#include <error.h>
>> > +#include <sys/queue.h>
>> > +#include <fdtap.h>
>> > +#include <syscall.h>
>> > +
>> > +struct dev vars_devtab;
>> > +
>> > +static char *devname(void)
>> > +{
>> > +       return vars_devtab.name;
>> > +}
>> > +
>> > +enum {
>> > +       type_s8 = 1,
>> > +       type_s16,
>> > +       type_s32,
>> > +       type_s64,
>> > +       type_u8,
>> > +       type_u16,
>> > +       type_u32,
>> > +       type_u64,
>> > +
>> > +       type_bool,
>> > +       type_char,
>> > +       type_short,
>> > +       type_int,
>> > +       type_long,
>> > +       type_ushort,
>> > +       type_uint,
>> > +       type_ulong,
>> > +       type_ntstr,             /* null-terminated string */
>> > +
>> > +       VARS_HEX = (1 << 31),
>> > +};
>> > +
>> > +/* The qid.path is the addr of the variable.  The qid.vers is the type.
>> > Or-in
>> > + * any VARS_* flags you want to the type.  "." has no type or addr. */
>> > +#define VARS_ENTRY(name, type) {#name,
>> > \
>> > +                                {(uint64_t)&(name), (type), QTFILE},
>> > \
>> > +                                sizeof((name)),
>> > \
>> > +                                0444}
>> > +
>> > +static struct dirtab vars_dir[] = {
>> > +       {".", {0, 0, QTDIR}, 0, DMDIR | 0555},
>> > +       VARS_ENTRY(num_cores, type_int),
>> > +};
>> > +
>> > +static struct chan *vars_attach(char *spec)
>> > +{
>> > +       struct chan *c;
>> > +
>> > +       c = devattach(devname(), spec);
>> > +       mkqid(&c->qid, 0, 0, QTDIR);
>> > +       return c;
>> > +}
>> > +
>> > +static struct walkqid *vars_walk(struct chan *c, struct chan *nc, char
>> > **name,
>> > +                                                                int
>> > nname)
>> > +{
>> > +       return devwalk(c, nc, name, nname, vars_dir,
>> > ARRAY_SIZE(vars_dir), devgen);
>> > +}
>> > +
>> > +static int vars_stat(struct chan *c, uint8_t *db, int n)
>> > +{
>> > +       return devstat(c, db, n, vars_dir, ARRAY_SIZE(vars_dir),
>> > devgen);
>> > +}
>> > +
>> > +static struct chan *vars_open(struct chan *c, int omode)
>> > +{
>> > +       return devopen(c, omode, vars_dir, ARRAY_SIZE(vars_dir),
>> > devgen);
>> > +}
>> > +
>> > +static void vars_close(struct chan *c)
>> > +{
>> > +}
>> > +
>> > +static long vars_read(struct chan *c, void *ubuf, long n, int64_t
>> > offset)
>> > +{
>> > +       char tmp[128];  /* big enough for any number and most strings */
>> > +       size_t size = sizeof(tmp);
>> > +       char *fmt_str_s32 = c->qid.vers & VARS_HEX ? "0x%x" : "%d";
>> > +       char *fmt_str_s64 = c->qid.vers & VARS_HEX ? "0x%lx" : "%ld";
>> > +       char *fmt_str_u32 = c->qid.vers & VARS_HEX ? "0x%x" : "%u";
>> > +       char *fmt_str_u64 = c->qid.vers & VARS_HEX ? "0x%lx" : "%lu";
>> > +       int type = c->qid.vers & ~VARS_HEX;
>> > +
>> > +       switch (type) {
>> > +       case 0:
>> > +               return devdirread(c, ubuf, n, vars_dir,
>> > ARRAY_SIZE(vars_dir), devgen);
>> > +       case type_bool:
>> > +       case type_u8:
>> > +               size = snprintf(tmp, size, fmt_str_u32,
>> > *(uint8_t*)c->qid.path);
>> > +               break;
>> > +       case type_u16:
>> > +               size = snprintf(tmp, size, fmt_str_u32,
>> > *(uint16_t*)c->qid.path);
>> > +               break;
>> > +       case type_uint:
>> > +       case type_u32:
>> > +               size = snprintf(tmp, size, fmt_str_u32,
>> > *(uint32_t*)c->qid.path);
>> > +               break;
>> > +       case type_ulong:
>> > +       case type_u64:
>> > +               size = snprintf(tmp, size, fmt_str_u64,
>> > *(uint64_t*)c->qid.path);
>> > +               break;
>> > +       case type_s8:
>> > +               size = snprintf(tmp, size, fmt_str_s32,
>> > *(int8_t*)c->qid.path);
>> > +               break;
>> > +       case type_s16:
>> > +               size = snprintf(tmp, size, fmt_str_s32,
>> > *(int16_t*)c->qid.path);
>> > +               break;
>> > +       case type_int:
>> > +       case type_s32:
>> > +               size = snprintf(tmp, size, fmt_str_s32,
>> > *(int32_t*)c->qid.path);
>> > +               break;
>> > +       case type_long:
>> > +       case type_s64:
>> > +               size = snprintf(tmp, size, fmt_str_s64,
>> > *(int64_t*)c->qid.path);
>> > +               break;
>> > +       case type_char:
>> > +               size = snprintf(tmp, size, "%c", *(char*)c->qid.path);
>> > +               break;
>> > +       case type_ntstr:
>> > +               size = snprintf(tmp, size, "%s", *(char**)c->qid.path);
>> > +               break;
>> > +       default:
>> > +               panic("Unknown #%s type %d", devname(), type);
>> > +       }
>> > +       return readmem(offset, ubuf, n, tmp, size + 1);
>> > +}
>> > +
>> > +static long vars_write(struct chan *c, void *ubuf, long n, int64_t
>> > offset)
>> > +{
>> > +       error(EFAIL, "Can't write to a #%s file", devname());
>> > +}
>> > +
>> > +struct dev vars_devtab __devtab = {
>> > +       .name = "vars",
>> > +       .reset = devreset,
>> > +       .init = devinit,
>> > +       .shutdown = devshutdown,
>> > +       .attach = vars_attach,
>> > +       .walk = vars_walk,
>> > +       .stat = vars_stat,
>> > +       .open = vars_open,
>> > +       .create = devcreate,
>> > +       .close = vars_close,
>> > +       .read = vars_read,
>> > +       .bread = devbread,
>> > +       .write = vars_write,
>> > +       .bwrite = devbwrite,
>> > +       .remove = devremove,
>> > +       .wstat = devwstat,
>> > +       .power = devpower,
>> > +       .chaninfo = devchaninfo,
>> > +       .tapfd = 0,
>> > +};
>> > --
>> > 2.6.0.rc2.230.g3dd15c0
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups "Akaros" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> > an email to [email protected].
>> > To post to this group, send email to [email protected].
>> > For more options, visit https://groups.google.com/d/optout.
>>
>>
>>
>> --
>> ~Kevin
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Akaros" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> To post to this group, send email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Akaros" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> For more options, visit https://groups.google.com/d/optout.



-- 
~Kevin

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to