Mercurial > hvf > hvf
changeset 591:d953d7d4d89d
cp: revamp directory handling
The directory is now read from the IPL filesystem. re2c & yacc are used to
generate the parser & lexer (although there is still a bit too much code
duplication between the config file lexer and the directory file lexer).
The CMakeLists.txt file could use some cleanup as well, but that's a
different story.
This commit also changes the way auth classes are done. Now, they resemble
something much like what VM/370 and similar does.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Sat, 26 Nov 2011 22:46:47 -0500 |
parents | ffe037678d57 |
children | 732345b0925c |
files | cp/.gitignore cp/CMakeLists.txt cp/config/hvf.directory cp/config/system.config cp/guest/init.c cp/include/config.h cp/include/directory.h cp/include/nucleus.h cp/include/shell.h cp/include/slab.h cp/include/util.h cp/mm/slab.c cp/nucleus/.gitignore cp/nucleus/config.c cp/nucleus/config.l cp/nucleus/config.y cp/nucleus/direct.c cp/nucleus/direct.l cp/nucleus/direct.y cp/nucleus/init.c cp/nucleus/objs.cmake cp/nucleus/util.c cp/shell/cmd_beginstop.c cp/shell/cmd_display.c cp/shell/cmd_enable.c cp/shell/cmd_logon.c cp/shell/cmd_query.c cp/shell/cmd_set.c cp/shell/cmd_store.c cp/shell/cmd_system.c cp/shell/directory.c cp/shell/objs.cmake |
diffstat | 32 files changed, 653 insertions(+), 87 deletions(-) [+] |
line wrap: on
line diff
--- a/cp/.gitignore Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/.gitignore Sat Nov 26 22:46:47 2011 -0500 @@ -1,7 +1,6 @@ *.rto ipl/ipl_rdr_ccws.s ipl/ipl_tape.s -shell/directory_structs.c hvf loader_rdr.bin loader_tape.bin
--- a/cp/CMakeLists.txt Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/CMakeLists.txt Sat Nov 26 22:46:47 2011 -0500 @@ -20,6 +20,22 @@ DEPENDS nucleus/config.l nucleus/config.tab.h ) +add_custom_command( + OUTPUT nucleus/direct.tab.h + nucleus/direct.tab.c + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../build/byacc/yacc + -b direct -d -P -p direct_ direct.y + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/nucleus + DEPENDS nucleus/direct.y +) +add_custom_command( + OUTPUT nucleus/direct.lex.c + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../build/re2c/re2c + -o direct.lex.c direct.l + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/nucleus + DEPENDS nucleus/direct.l nucleus/direct.tab.h +) + set(SUBDIRS nucleus mm fs drivers shell guest) set(SRCFILES "")
--- a/cp/config/hvf.directory Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/config/hvf.directory Sat Nov 26 22:46:47 2011 -0500 @@ -1,4 +1,4 @@ -USER OPERATOR A +USER OPERATOR ABCDEG MACHINE ESA 1 STORAGE 17M CONSOLE 0009 3215 @@ -7,7 +7,7 @@ SPOOL 000E 1403 PRINT MDISK 0191 3390 15 100 0192 -USER JEFFPC A +USER JEFFPC ABCDEG MACHINE ESA 1 STORAGE 64M CONSOLE 0009 3215
--- a/cp/config/system.config Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/config/system.config Sat Nov 26 22:46:47 2011 -0500 @@ -1,3 +1,6 @@ +* SPECIFY THE FILE WITH THE USER DIRECTORY +DIRECTORY HVF DIRECT + * DEFINE OPERATOR ENVIRONMENT OPERATOR CONSOLE 0009 OPERATOR USERID OPERATOR
--- a/cp/guest/init.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/guest/init.c Sat Nov 26 22:46:47 2011 -0500 @@ -24,18 +24,20 @@ void alloc_guest_devices(struct virt_sys *sys) { + struct directory_vdev *cur; int ret; int i; INIT_LIST_HEAD(&sys->virt_devs); - for(i=0; sys->directory->devices[i].type != VDEV_INVAL; i++) { - ret = alloc_virt_dev(sys, &sys->directory->devices[i], - 0x10000 + i); + i = 0; + list_for_each_entry(cur, &sys->directory->devices, list) { + ret = alloc_virt_dev(sys, cur, 0x10000 + i); if (ret) - con_printf(sys->con, "Failed to allocate vdev %04X, SCH = %05X (%s)\n", - sys->directory->devices[i].vdev, - 0x10000 + i, errstrings[-ret]); + con_printf(sys->con, "Failed to allocate vdev %04X, " + "SCH = %05X (%s)\n", cur->vdev, 0x10000 + i, + errstrings[-ret]); + i++; } }
--- a/cp/include/config.h Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/include/config.h Sat Nov 26 22:46:47 2011 -0500 @@ -31,6 +31,9 @@ char oper_userid[9]; struct list_head rdevs; struct list_head logos; + + char direct_fn[8]; + char direct_ft[8]; }; enum {
--- a/cp/include/directory.h Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/include/directory.h Sat Nov 26 22:46:47 2011 -0500 @@ -10,6 +10,20 @@ #include <console.h> +#define AUTH_A 0x80 /* operations (shutdown, force, ...) */ +#define AUTH_B 0x40 /* device op (attach, detach) */ +#define AUTH_C 0x20 /* sys prog (alter real storage) */ +#define AUTH_D 0x10 /* spool op (start/drain UR, access all spools) */ +#define AUTH_E 0x08 /* system analyst (examine real storage) */ +#define AUTH_F 0x04 /* CE (I/O device error analysis) */ +#define AUTH_G 0x02 /* general user */ + +/* only useful during directory load */ +struct directory_prop { + int got_storage; + u64 storage; +}; + enum directory_vdevtype { VDEV_INVAL = 0, /* invalid */ VDEV_CONS, /* a console */ @@ -20,6 +34,8 @@ }; struct directory_vdev { + struct list_head list; + enum directory_vdevtype type; /* device type */ u16 vdev; /* virtual dev # */ @@ -53,17 +69,25 @@ }; struct user { + struct list_head list; /* list of users */ + char *userid; struct task *task; /* VM configuration */ u64 storage_size; - struct directory_vdev *devices; + struct list_head devices; u8 auth; }; extern struct user *find_user_by_id(char *userid); +extern void directory_alloc_user(char *name, int auth, + struct directory_prop *prop, + struct list_head *vdevs); +extern int load_directory(struct fs *fs); +extern int direct_lex(void *data, void *yyval); +extern int direct_parse(struct parser *parser); #endif
--- a/cp/include/nucleus.h Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/include/nucleus.h Sat Nov 26 22:46:47 2011 -0500 @@ -64,8 +64,4 @@ extern int con_printf(struct console *con, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); -/* - * stdarg.h equivalents - */ - #endif
--- a/cp/include/shell.h Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/include/shell.h Sat Nov 26 22:46:47 2011 -0500 @@ -31,7 +31,7 @@ extern int spool_exec(struct virt_sys *sys, struct virt_device *vdev); #define SHELL_CMD_AUTH(s,a) do { \ - if ((s)->directory->auth > (a)) \ + if (!((s)->directory->auth & AUTH_##a)) \ return -EPERM; \ } while(0)
--- a/cp/include/slab.h Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/include/slab.h Sat Nov 26 22:46:47 2011 -0500 @@ -31,5 +31,6 @@ extern void *malloc(int size, int type); extern void free(void *ptr); +extern int allocsize(void *ptr); #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cp/include/util.h Sat Nov 26 22:46:47 2011 -0500 @@ -0,0 +1,8 @@ +#ifndef __UTIL_H +#define __UTIL_H + +extern char *strdup(char *s, int flags); +extern int hex(char *a, char *b, u64 *out); +extern int bcd2dec(u64 val, u64 *out); + +#endif
--- a/cp/mm/slab.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/mm/slab.c Sat Nov 26 22:46:47 2011 -0500 @@ -258,6 +258,16 @@ spin_unlock_intrestore(&slab->first->lock, int_mask); } +int allocsize(void *ptr) +{ + struct slab *slab; + + /* get the slab object ptr */ + slab = (struct slab *) (((u64) ptr) & ~0xfff); + + return slab->objsize; +} + void *malloc(int size, int type) { if (!size)
--- a/cp/nucleus/.gitignore Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/nucleus/.gitignore Sat Nov 26 22:46:47 2011 -0500 @@ -3,3 +3,7 @@ config.tab.c config.tab.h config.lex.c + +direct.tab.c +direct.tab.h +direct.lex.c
--- a/cp/nucleus/config.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/nucleus/config.c Sat Nov 26 22:46:47 2011 -0500 @@ -9,6 +9,7 @@ #include <bdev.h> #include <edf.h> #include <slab.h> +#include <directory.h> #include <ebcdic.h> #include <sclp.h> #include <parser.h> @@ -80,6 +81,9 @@ struct device *dev; struct fs *fs; + sclp_msg("LOADING CONFIG FROM '%*.*s' '%*.*s'\n", + 8, 8, CONFIG_FILE_NAME, 8, 8, CONFIG_FILE_TYPE); + memset(&sysconf, 0, sizeof(struct sysconf)); INIT_LIST_HEAD(&sysconf.rdevs); INIT_LIST_HEAD(&sysconf.logos); @@ -111,6 +115,7 @@ if (config_parse(&p)) return ERR_PTR(-ECORRUPT); + load_directory(fs); __load_logos(fs); return fs;
--- a/cp/nucleus/config.l Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/nucleus/config.l Sat Nov 26 22:46:47 2011 -0500 @@ -5,41 +5,13 @@ * details. */ +#include <util.h> #include <ebcdic.h> #include <lexer.h> +#include <sclp.h> #include "config.tab.h" -int hex(char *a, char *b, u64 *out) -{ - u64 val; - char c; - - if (a>=b) - return 1; - - val = 0; - - while(a<b) { - c = *a; - - if ((c >= '0') && (c <= '9')) - val = (val << 4) | (*a - '0'); - else if ((c >= 'A') && (c <= 'F')) - val = (val << 4) | (*a - 'A' + 10); - else if ((c >= 'a') && (c <= 'f')) - val = (val << 4) | (*a - 'a' + 10); - else - return 1; - - a++; - } - - *out = val; - - return 0; -} - static int __fill(struct lexer *lexer, int n) { char buf[CONFIG_LRECL]; @@ -123,6 +95,7 @@ re2c:define:YYLIMIT = &lexer->buf[lexer->filllen]; "\n" { YYRETURN(NLINE); } "*" [^\n]* { YYRETURN(COMMENT); } + "DIRECTORY" { YYRETURN(DIRECTORY); } "OPERATOR" { YYRETURN(OPERATOR); } "RDEV" { YYRETURN(RDEV); } "LOGO" { YYRETURN(LOGO); } @@ -136,7 +109,7 @@ len = cur-&lexer->buf[lexer->recoff]; memcpy(lexer->retbuf, &lexer->buf[lexer->recoff], len); lexer->retbuf[len] = '\0'; - val->ptr = lexer->retbuf; + val->ptr = strdup(lexer->retbuf, ZONE_NORMAL); YYRETURN(WORD); } [ \t]+ { YYSKIP(); }
--- a/cp/nucleus/config.y Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/nucleus/config.y Sat Nov 26 22:46:47 2011 -0500 @@ -76,6 +76,12 @@ sysconf.oper_userid[8] = '\0'; } +static void __direct(char *fn, char *ft) +{ + copy_fn(sysconf.direct_fn, fn); + copy_fn(sysconf.direct_ft, ft); +} + %} %union { @@ -85,7 +91,7 @@ %token <ptr> WORD %token <num> NUM -%token OPERATOR RDEV LOGO CONSOLE USERID LOCAL +%token OPERATOR RDEV LOGO CONSOLE USERID LOCAL DIRECTORY %token NLINE COMMENT %% @@ -95,11 +101,22 @@ ; stmt : OPERATOR CONSOLE NUM NLINE { __oper_con($3); } - | OPERATOR USERID WORD NLINE { __oper_userid($3); } + | OPERATOR USERID WORD NLINE { __oper_userid($3); + free($3); + } | OPERATOR USERID OPERATOR NLINE { __oper_userid("OPERATOR"); } | RDEV NUM NUM NLINE { __rdev($2, $3); } - | LOGO LOCAL NUM WORD WORD NLINE { __logo(1, $3, $4, $5); } - | LOGO LOCAL NUM WORD LOGO NLINE { __logo(1, $3, $4, "LOGO"); } + | LOGO LOCAL NUM WORD WORD NLINE { __logo(1, $3, $4, $5); + free($4); + free($5); + } + | LOGO LOCAL NUM WORD LOGO NLINE { __logo(1, $3, $4, "LOGO"); + free($4); + } + | DIRECTORY WORD WORD NLINE { __direct($2, $3); + free($2); + free($3); + } | COMMENT NLINE | NLINE ;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cp/nucleus/direct.c Sat Nov 26 22:46:47 2011 -0500 @@ -0,0 +1,104 @@ +/* + * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * + * This file is released under the GPLv2. See the COPYING file for more + * details. + */ + +#include <errno.h> +#include <ebcdic.h> +#include <directory.h> +#include <shell.h> +#include <slab.h> +#include <parser.h> +#include <lexer.h> +#include <edf.h> +#include <sclp.h> + +#include "direct.tab.h" + +static LIST_HEAD(directory); + +int direct_parse(struct parser *); + +struct user *find_user_by_id(char *userid) +{ + struct user *u; + + if (!userid) + return ERR_PTR(-ENOENT); + + list_for_each_entry(u, &directory, list) + if (!strcasecmp(u->userid, userid)) + return u; + + return ERR_PTR(-ENOENT); +} + +static void *_realloc(void *p, size_t s) +{ + if (!p) + return malloc(s, ZONE_NORMAL); + + if (s <= allocsize(p)) + return p; + + BUG(); + return NULL; +} + +static void _error(struct parser *p, char *msg) +{ + sclp_msg("directory parse error: %s\n", msg); + BUG(); +} + +int load_directory(struct fs *fs) +{ + struct parser p; + struct lexer l; + + sclp_msg("LOADING DIRECTORY FROM '%*.*s' '%*.*s'\n", + 8, 8, sysconf.direct_fn, 8, 8, sysconf.direct_ft); + + /* set up the parser */ + memset(&p, 0, sizeof(p)); + p.lex = direct_lex; + p.lex_data = &l; + p.realloc = _realloc; + p.free = free; + p.error = _error; + + /* set up the lexer */ + memset(&l, 0, sizeof(l)); + l.fs = fs; + l.init = 0; + + /* parse! */ + return direct_parse(&p) ? -ECORRUPT : 0; +} + +void directory_alloc_user(char *name, int auth, struct directory_prop *prop, + struct list_head *vdevs) +{ + struct user *user; + + assert(name); + assert(prop->got_storage); + + user = malloc(sizeof(struct user), ZONE_NORMAL); + assert(user); + + memset(user, 0, sizeof(struct user)); + + INIT_LIST_HEAD(&user->list); + INIT_LIST_HEAD(&user->devices); + list_splice(vdevs, &user->devices); + + user->userid = name; + user->storage_size = prop->storage; + user->auth = auth; + + // FIXME: locking? + list_add_tail(&user->list, &directory); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cp/nucleus/direct.l Sat Nov 26 22:46:47 2011 -0500 @@ -0,0 +1,131 @@ +/* + * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * + * This file is released under the GPLv2. See the COPYING file for more + * details. + */ + +#include <util.h> +#include <ebcdic.h> +#include <lexer.h> +#include <directory.h> +#include <sclp.h> + +#include "direct.tab.h" + +static int __fill(struct lexer *lexer, int n) +{ + char buf[CONFIG_LRECL]; + int end, i; + int ret; + + if (unlikely(!lexer->init)) { + /* look up the directory file */ + lexer->file = edf_lookup(lexer->fs, sysconf.direct_fn, sysconf.direct_ft); + if (IS_ERR(lexer->file)) + return PTR_ERR(lexer->file); + + if ((lexer->file->FST.LRECL != CONFIG_LRECL) || + (lexer->file->FST.RECFM != FSTDFIX)) + return -EINVAL; + + lexer->recoff = 0; + lexer->buflen = sizeof(lexer->buf); + lexer->filllen = 0; + + lexer->init = 1; + } + + if (lexer->recoff) { + lexer->filllen -= lexer->recoff; + memmove(lexer->buf, &lexer->buf[lexer->recoff], lexer->filllen); + lexer->recoff = 0; + } + + assert(lexer->filllen < CONFIG_LRECL); + + ret = edf_read_rec(lexer->file, buf, lexer->recno++); + if (ret) + return ret; + + ebcdic2ascii((u8*) buf, CONFIG_LRECL); + ascii2upper((u8*) buf, CONFIG_LRECL); + + /* find the last non-blank */ + for(end=CONFIG_LRECL-1; end>=0; end--) + if (buf[end] != ' ') + break; + + for(i=0; (i<CONFIG_LRECL) && (i<end+1); i++) + lexer->buf[lexer->filllen+i] = buf[i]; + + lexer->buf[lexer->filllen+i] = '\n'; + lexer->filllen += i+1; + + return 0; +} +#define YYFILL(n) do { \ + int ret; \ + int off = cur - &lexer->buf[lexer->recoff]; \ + ret = __fill(lexer, (n)); \ + if (ret && !(lexer->filllen - lexer->recoff)) \ + return ret; \ + cur = &lexer->buf[off]; \ + } while(0) +#define YYRETURN(x) do { \ + lexer->recoff = cur - lexer->buf; \ + return (x); \ + } while(0) +#define YYSKIP() do { \ + lexer->recoff = cur - lexer->buf; \ + goto next; \ + } while(0) +int direct_lex(void *data, void *yyval) +{ + struct lexer *lexer = data; + YYSTYPE *val = yyval; + char *cur; + +next: + cur = &lexer->buf[lexer->recoff]; + + /*!re2c + re2c:define:YYCTYPE = "char"; + re2c:define:YYCURSOR = cur; + re2c:define:YYLIMIT = &lexer->buf[lexer->filllen]; + "\n" { YYRETURN(NLINE); } + "*" [^\n]* { YYRETURN(COMMENT); } + "USER" { YYRETURN(USER); } + "MACHINE" { YYRETURN(MACHINE); } + "STORAGE" { YYRETURN(STORAGE); } + "CONSOLE" { YYRETURN(CONSOLE); } + "SPOOL" { YYRETURN(SPOOL); } + "READER" { YYRETURN(READER); } + "PUNCH" { YYRETURN(PUNCH); } + "PRINT" { YYRETURN(PRINT); } + "MDISK" { YYRETURN(MDISK); } + [0-9]+[KMGTP] { hex(&lexer->buf[lexer->recoff], cur-1, &val->num); + bcd2dec(val->num, &val->num); + switch(*(cur-1)) { + case 'P': val->num *= 1024; + case 'T': val->num *= 1024; + case 'G': val->num *= 1024; + case 'M': val->num *= 1024; + case 'K': val->num *= 1024; + } + + YYRETURN(STORSPEC); + } + [0-9A-F]+ { hex(&lexer->buf[lexer->recoff], cur, &val->num); + YYRETURN(NUM); + } + [A-Z]+ { int len; + len = cur-&lexer->buf[lexer->recoff]; + memcpy(lexer->retbuf, &lexer->buf[lexer->recoff], len); + lexer->retbuf[len] = '\0'; + val->ptr = strdup(lexer->retbuf, ZONE_NORMAL); + YYRETURN(WORD); + } + [ \t]+ { YYSKIP(); } + */ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cp/nucleus/direct.y Sat Nov 26 22:46:47 2011 -0500 @@ -0,0 +1,156 @@ +%{ + +#include <util.h> +#include <slab.h> +#include <directory.h> + +static void merge_props(struct directory_prop *out, struct directory_prop *a, + struct directory_prop *b) +{ + out->got_storage = a->got_storage || b->got_storage; + + if (a->got_storage && !b->got_storage) + out->storage = a->storage; + else if (!a->got_storage && b->got_storage) + out->storage = b->storage; + else if (a->got_storage && b->got_storage) + BUG(); +} + +static struct directory_vdev *__alloc_spool_vdev(enum directory_vdevtype type, + u64 devnum, u64 typenum) +{ + struct directory_vdev *vdev; + + assert(devnum <= 0xffff); + assert(typenum <= 0xffff); + assert((type == VDEV_CONS) || (type == VDEV_SPOOL)); + + vdev = malloc(sizeof(struct directory_vdev), ZONE_NORMAL); + assert(vdev); + + vdev->type = type; + vdev->vdev = devnum; + + if (type == VDEV_SPOOL) { + vdev->u.spool.type = typenum; + vdev->u.spool.model = 0; + } + + return vdev; +} + +static struct directory_vdev *__alloc_mdisk_vdev(u64 devnum, u64 typenum, + u64 start, u64 len, u64 rdev) +{ + struct directory_vdev *vdev; + + assert(devnum <= 0xffff); + assert(typenum <= 0xffff); + assert(start <= 0xffff); + assert(len <= 0xffff); + assert(rdev <= 0xffff); + + vdev = malloc(sizeof(struct directory_vdev), ZONE_NORMAL); + assert(vdev); + + vdev->type = VDEV_MDISK; + vdev->vdev = devnum; + vdev->u.mdisk.cyloff = start; + vdev->u.mdisk.cylcnt = len; + vdev->u.mdisk.rdev = rdev; + + return vdev; +} + +static int __auth_str(char *in) +{ + int a = 0; + + for(; *in; in++) { + if (*in == 'A') + a |= AUTH_A; + else if (*in == 'B') + a |= AUTH_B; + else if (*in == 'C') + a |= AUTH_C; + else if (*in == 'D') + a |= AUTH_D; + else if (*in == 'E') + a |= AUTH_E; + else if (*in == 'F') + a |= AUTH_F; + else if (*in == 'G') + a |= AUTH_G; + else + return -1; + } + + return a; +} + +static int __auth_int(u64 in) +{ + // FIXME + return AUTH_G; +} + +%} + +%union { + struct directory_vdev *vdev; + struct list_head list; + struct directory_prop prop; + char *ptr; + u64 num; +}; + +%token <ptr> WORD +%token <num> STORSPEC NUM +%token USER MACHINE STORAGE CONSOLE SPOOL READER PUNCH PRINT MDISK +%token NLINE COMMENT + +%type <prop> props prop +%type <list> vdevs +%type <vdev> vdev + +%% + +users : users NLINE user + | user + | NLINE /* an empty line */ + ; + +user : USER WORD WORD NLINE props vdevs { directory_alloc_user($2, __auth_str($3), &$5, &$6); } + | USER WORD NUM NLINE props vdevs { directory_alloc_user($2, __auth_int($3), &$5, &$6); } + ; + +props : props prop { merge_props(&$$, &$1, &$2); } + | prop { memcpy(&$$, &$1, sizeof($$)); } + ; + +vdevs : vdevs vdev { INIT_LIST_HEAD(&$$); + list_splice(&$1, &$$); + list_add(&$2->list, &$$); + } + | vdev { INIT_LIST_HEAD(&$$); + list_add(&$1->list, &$$); + } + ; + +prop : MACHINE WORD NUM NLINE { memset(&$$, 0, sizeof($$)); + free($2); + } + | STORAGE STORSPEC NLINE { $$.got_storage = 1; + $$.storage = $2; } + | STORAGE NUM NLINE { $$.got_storage = 1; + assert(!bcd2dec($2, &$$.storage)); + } + ; + +vdev : CONSOLE NUM NUM NLINE { $$ = __alloc_spool_vdev(VDEV_CONS, $2, $3); } + | SPOOL NUM NUM READER NLINE { $$ = __alloc_spool_vdev(VDEV_SPOOL, $2, $3); } + | SPOOL NUM NUM PUNCH NLINE { $$ = __alloc_spool_vdev(VDEV_SPOOL, $2, $3); } + | SPOOL NUM NUM PRINT NLINE { $$ = __alloc_spool_vdev(VDEV_SPOOL, $2, $3); } + | MDISK NUM NUM NUM NUM NUM NLINE { $$ = __alloc_mdisk_vdev($2, $3, $4, $5, $6); } + ;
--- a/cp/nucleus/init.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/nucleus/init.c Sat Nov 26 22:46:47 2011 -0500 @@ -17,6 +17,7 @@ #include <interrupt.h> #include <magic.h> #include <shell.h> +#include <sclp.h> static struct psw new_io_psw = { .ea = 1, @@ -101,6 +102,10 @@ */ get_parsed_tod(&ipltime); + sclp_msg("IPL AT %02d:%02d:%02d UTC %04d-%02d-%02d\n\n", + ipltime.th, ipltime.tm, ipltime.ts, ipltime.dy, + ipltime.dm, ipltime.dd); + opcon = start_oper_console(); con_printf(opcon, "NOW %02d:%02d:%02d UTC %04d-%02d-%02d\n\n",
--- a/cp/nucleus/objs.cmake Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/nucleus/objs.cmake Sat Nov 26 22:46:47 2011 -0500 @@ -1,2 +1,3 @@ set(FILES init.c io.c printf.c int.s ext.c svc.c pgm.c spinlock.c mutex.c - sched.c sclp.c ldep.c config.c config.tab.c config.lex.c) + sched.c sclp.c ldep.c util.c config.c config.tab.c config.lex.c + direct.c direct.tab.c direct.lex.c)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cp/nucleus/util.c Sat Nov 26 22:46:47 2011 -0500 @@ -0,0 +1,77 @@ +/* + * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * + * This file is released under the GPLv2. See the COPYING file for more + * details. + */ + +#include <slab.h> +#include <util.h> + +char *strdup(char *s, int flags) +{ + char *d; + int len; + + for(d=s; *d; d++) + ; + + len = d - s; + + d = malloc(sizeof(char)*len, flags); + if (!d) + return NULL; + + memcpy(d, s, len*sizeof(char)); + + return d; +} + +int hex(char *a, char *b, u64 *out) +{ + u64 val; + char c; + + if (a>=b) + return 1; + + val = 0; + + while(a<b) { + c = *a; + + if ((c >= '0') && (c <= '9')) + val = (val << 4) | (*a - '0'); + else if ((c >= 'A') && (c <= 'F')) + val = (val << 4) | (*a - 'A' + 10); + else if ((c >= 'a') && (c <= 'f')) + val = (val << 4) | (*a - 'a' + 10); + else + return 1; + + a++; + } + + *out = val; + + return 0; +} + +int bcd2dec(u64 val, u64 *out) +{ + u64 v; + u64 scale; + + for(v=0,scale=1; val; scale*=10, val>>=4) { + u64 x = val & 0xf; + + if (x>=10) + return 1; + + v += (x*scale); + } + + *out = v; + + return 0; +}
--- a/cp/shell/cmd_beginstop.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/shell/cmd_beginstop.c Sat Nov 26 22:46:47 2011 -0500 @@ -16,6 +16,8 @@ */ static int cmd_begin(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + sys->task->cpu->state = GUEST_OPERATING; return 0; } @@ -31,6 +33,8 @@ */ static int cmd_stop(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + sys->task->cpu->state = GUEST_STOPPED; return 0; }
--- a/cp/shell/cmd_display.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/shell/cmd_display.c Sat Nov 26 22:46:47 2011 -0500 @@ -1,5 +1,5 @@ /* - * (C) Copyright 2007-2010 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * This file is released under the GPLv2. See the COPYING file for more * details. @@ -201,6 +201,8 @@ u64 mlen = 0; enum display_fmt fmt; + SHELL_CMD_AUTH(sys, G); + switch (cmd[0]) { case 'N': case 'n': /* numeric */ @@ -246,7 +248,7 @@ u32 *val; int i; - SHELL_CMD_AUTH(sys, 'E'); + SHELL_CMD_AUTH(sys, E); val = (u32*) &sys->task->cpu->sie_cb; @@ -271,6 +273,8 @@ */ static int cmd_display_gpr(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + con_printf(sys->con, "GR 0 = %016llX %016llX\n", sys->task->cpu->regs.gpr[0], sys->task->cpu->regs.gpr[1]); @@ -309,6 +313,8 @@ */ static int cmd_display_fpcr(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + con_printf(sys->con, "FPCR = %08X\n", sys->task->cpu->regs.fpcr); return 0; } @@ -324,6 +330,8 @@ */ static int cmd_display_fpr(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + con_printf(sys->con, "FR 0 = %016llX %016llX\n", sys->task->cpu->regs.fpr[0], sys->task->cpu->regs.fpr[1]); @@ -362,6 +370,8 @@ */ static int cmd_display_cr(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + con_printf(sys->con, "CR 0 = %016llX %016llX\n", sys->task->cpu->sie_cb.gcr[0], sys->task->cpu->sie_cb.gcr[1]); @@ -400,6 +410,8 @@ */ static int cmd_display_ar(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + con_printf(sys->con, "AR 0 = %08X %08X\n", sys->task->cpu->regs.ar[0], sys->task->cpu->regs.ar[1]); @@ -485,6 +497,8 @@ int disp = 0; int zarch; + SHELL_CMD_AUTH(sys, G); + if (!strcasecmp(cmd, "ALL")) disp = D_PSW_ALL; else if (!strcasecmp(cmd, "RST")) @@ -586,6 +600,8 @@ u64 sch; int all; + SHELL_CMD_AUTH(sys, G); + if (strcasecmp(cmd, "ALL")) { cmd = __extract_hex(cmd, &sch); if (IS_ERR(cmd))
--- a/cp/shell/cmd_enable.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/shell/cmd_enable.c Sat Nov 26 22:46:47 2011 -0500 @@ -21,6 +21,8 @@ struct device *dev; struct console *con; + SHELL_CMD_AUTH(sys, A); + if (!strcasecmp(cmd, "ALL")) { con_printf(sys->con, "ENABLE ALL not yet implemented!\n"); return 0;
--- a/cp/shell/cmd_logon.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/shell/cmd_logon.c Sat Nov 26 22:46:47 2011 -0500 @@ -10,7 +10,7 @@ *!! SYNTAX *! \tok{\sc LOGON} <userid> *!! XATNYS - *!! AUTH G + *!! AUTH none *!! PURPOSE *! Log on to a virtual machine. */
--- a/cp/shell/cmd_query.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/shell/cmd_query.c Sat Nov 26 22:46:47 2011 -0500 @@ -111,6 +111,8 @@ */ static int cmd_query_cplevel(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + con_printf(sys->con, "HVF version " VERSION "\n"); con_printf(sys->con, "IPL at %02d:%02d:%02d UTC %04d-%02d-%02d\n", ipltime.th, ipltime.tm, ipltime.ts, ipltime.dy, @@ -132,6 +134,8 @@ { struct datetime dt; + SHELL_CMD_AUTH(sys, G); + get_parsed_tod(&dt); con_printf(sys->con, "TIME IS %02d:%02d:%02d UTC %04d-%02d-%02d\n", @@ -151,7 +155,11 @@ */ static int cmd_query_archmode(struct virt_sys *sys, char *cmd, int len) { - char *mode = (VCPU_ZARCH(sys->task->cpu)) ? "z/Arch" : "ESA390"; + char *mode; + + SHELL_CMD_AUTH(sys, G); + + mode = (VCPU_ZARCH(sys->task->cpu)) ? "z/Arch" : "ESA390"; con_printf(sys->con, "ARCHMODE = %s\n", mode); @@ -171,6 +179,8 @@ { struct virt_device *vdev; + SHELL_CMD_AUTH(sys, G); + con_printf(sys->con, "CPU 00 ID %016llX %s\n", sys->task->cpu->cpuid, __guest_state_to_str(sys->task->cpu->state)); @@ -213,7 +223,7 @@ *! <rdev> *! \end{stack} *!! XATNYS - *!! AUTH A + *!! AUTH B *!! PURPOSE *! \cbstart *! Lists the host's real devices, CPUs, and storage @@ -231,7 +241,7 @@ int what = 0; u64 devnum; - SHELL_CMD_AUTH(sys, 'A'); + SHELL_CMD_AUTH(sys, B); if (strnlen(cmd, len) == 0) { what = QUERY_CPUS | QUERY_STOR | QUERY_DEVS; @@ -275,14 +285,14 @@ *!! SYNTAX *! \tok{\sc Query} \tok{\sc Task} *!! XATNYS - *!! AUTH A + *!! AUTH E *!! PURPOSE *! Lists all of the tasks running on the host. This includes guest virtual *! cpu tasks, as well as system helper tasks. */ static int cmd_query_task(struct virt_sys *sys, char *cmd, int len) { - SHELL_CMD_AUTH(sys, 'A'); + SHELL_CMD_AUTH(sys, E); list_tasks(display_task, sys->con); @@ -306,6 +316,8 @@ */ static int cmd_query_names(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + list_users(sys->con, display_names); return 0; @@ -322,6 +334,8 @@ */ static int cmd_query_userid(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + con_printf(sys->con, "%s\n", sys->directory->userid); return 0; }
--- a/cp/shell/cmd_set.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/shell/cmd_set.c Sat Nov 26 22:46:47 2011 -0500 @@ -16,6 +16,8 @@ */ static int cmd_set_nots(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + sys->print_ts = 0; return 0; } @@ -31,6 +33,8 @@ */ static int cmd_set_ts(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + sys->print_ts = 1; return 0; }
--- a/cp/shell/cmd_store.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/shell/cmd_store.c Sat Nov 26 22:46:47 2011 -0500 @@ -22,6 +22,8 @@ u64 guest_addr, host_addr; u64 val = 0; + SHELL_CMD_AUTH(sys, G); + cmd = parse_addrspec(&guest_addr, NULL, cmd); if (IS_ERR(cmd)) { con_printf(sys->con, "STORE: Invalid addr-spec\n"); @@ -70,6 +72,8 @@ u64 *ptr = (u64*) &sys->task->cpu->regs.gpr; u64 val, gpr; + SHELL_CMD_AUTH(sys, G); + cmd = __extract_dec(cmd, &gpr); if (IS_ERR(cmd)) return PTR_ERR(cmd); @@ -103,6 +107,8 @@ u64 *ptr = (u64*) &sys->task->cpu->regs.fpr; u64 val, fpr; + SHELL_CMD_AUTH(sys, G); + cmd = __extract_dec(cmd, &fpr); if (IS_ERR(cmd)) return PTR_ERR(cmd); @@ -135,6 +141,8 @@ { u64 val; + SHELL_CMD_AUTH(sys, G); + cmd = __extract_hex(cmd, &val); if (IS_ERR(cmd)) return PTR_ERR(cmd); @@ -162,6 +170,8 @@ u64 *ptr = (u64*) &sys->task->cpu->sie_cb.gcr; u64 val, cr; + SHELL_CMD_AUTH(sys, G); + cmd = __extract_dec(cmd, &cr); if (IS_ERR(cmd)) return PTR_ERR(cmd); @@ -195,6 +205,8 @@ u32 *ptr = (u32*) &sys->task->cpu->regs.ar; u64 val, ar; + SHELL_CMD_AUTH(sys, G); + cmd = __extract_dec(cmd, &ar); if (IS_ERR(cmd)) return PTR_ERR(cmd); @@ -272,6 +284,8 @@ u64 new_words[4] = {0, 0, 0, 0}; int cnt; + SHELL_CMD_AUTH(sys, G); + for (cnt=0; cnt<4; cnt++) { cmd = __extract_hex(cmd, &new_words[cnt]); if (IS_ERR(cmd))
--- a/cp/shell/cmd_system.c Sat Nov 26 17:27:19 2011 -0500 +++ b/cp/shell/cmd_system.c Sat Nov 26 22:46:47 2011 -0500 @@ -273,6 +273,8 @@ u64 vdevnum = 0; char *c; + SHELL_CMD_AUTH(sys, G); + /* get IPL vdev # */ c = __extract_hex(cmd, &vdevnum); if (IS_ERR(c)) @@ -334,6 +336,8 @@ */ static int cmd_system(struct virt_sys *sys, char *cmd, int len) { + SHELL_CMD_AUTH(sys, G); + if (!strcasecmp(cmd, "CLEAR")) { guest_system_reset_clear(sys); con_printf(sys->con, "STORAGE CLEARED - SYSTEM RESET\n");
--- a/cp/shell/directory.c Sat Nov 26 17:27:19 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * (C) Copyright 2007-2010 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> - * - * This file is released under the GPLv2. See the COPYING file for more - * details. - */ - -#include <errno.h> -#include <directory.h> - -#include "directory_structs.c" - -struct user *find_user_by_id(char *userid) -{ - struct user *u; - - if (!userid) - return ERR_PTR(-ENOENT); - - u = directory; - - for (; u->userid; u++) - if (!strcasecmp(u->userid, userid)) - return u; - - return ERR_PTR(-ENOENT); -}