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.
