proto: change mkfs to use libdisk to process proto files, inst: use -U option in mkfs so uid is set and automatic reboot, realemu: cleanup

This commit is contained in:
cinap_lenrek 2011-04-29 09:15:28 +00:00
parent 7e0519a5e4
commit 0fb128b622
5 changed files with 77 additions and 492 deletions

View file

@ -17,7 +17,7 @@ case checkready
} }
case go case go
rm -f /tmp/copydone rm -f /tmp/copydone
disk/mkfs -z 16384 -p -s /n/dist -d /n/newfs /sys/lib/sysconfig/proto/allproto disk/mkfs -z 16372 -U -s /n/dist -d /n/newfs /sys/lib/sysconfig/proto/allproto
touch /tmp/copydone touch /tmp/copydone
case checkdone case checkdone

View file

@ -1,8 +1,3 @@
#!/bin/rc #!/bin/rc
fshalt -r
echo -n 'Halting file systems...' while(){}
fshalt
echo
echo Remember to take the install disk out of the drive.
echo Feel free to turn off your computer.

View file

@ -1063,11 +1063,11 @@ opstos(Cpu *cpu, Inst *i)
} }
static int static int
repcond(Cpu *cpu, int rep) repcond(ulong *f, int rep)
{ {
if(rep == OREPNE) if(rep == OREPNE)
return (cpu->reg[RFL] & ZF) == 0; return (*f & ZF) == 0;
return !rep || (cpu->reg[RFL] & ZF) != 0; return !rep || (*f & ZF) != 0;
} }
static void static void
@ -1098,7 +1098,7 @@ opscas(Cpu *cpu, Inst *i)
d->off += n; d->off += n;
d->off &= m; d->off &= m;
c--; c--;
if(repcond(cpu, i->rep)) if(repcond(f, i->rep))
break; break;
} }
aw(areg(cpu, i->alen, RDI), d->off); aw(areg(cpu, i->alen, RDI), d->off);
@ -1135,7 +1135,7 @@ opcmps(Cpu *cpu, Inst *i)
d->off += n; d->off += n;
d->off &= m; d->off &= m;
c--; c--;
if(repcond(cpu, i->rep)) if(repcond(f, i->rep))
break; break;
} }
aw(areg(cpu, i->alen, RDI), d->off); aw(areg(cpu, i->alen, RDI), d->off);

View file

@ -1,11 +1,11 @@
#include <u.h> #include <u.h>
#include <libc.h> #include <libc.h>
#include <disk.h>
#include <auth.h> #include <auth.h>
#include <bio.h> #include <bio.h>
enum{ enum{
LEN = 8*1024, LEN = 4096,
HUNKS = 128,
/* /*
* types of destination file sytems * types of destination file sytems
@ -15,44 +15,19 @@ enum{
Archive, Archive,
}; };
typedef struct File File; void protowarn(char *msg, void *);
void protoenum(char *new, char *old, Dir *d, void *);
struct File{
char *new;
char *elem;
char *old;
char *uid;
char *gid;
ulong mode;
};
void arch(Dir*); void arch(Dir*);
void copy(Dir*); void copy(Dir*);
int copyfile(File*, Dir*, int);
void* emalloc(ulong);
void error(char *, ...); void error(char *, ...);
void freefile(File*);
File* getfile(File*);
char* getmode(char*, ulong*);
char* getname(char*, char**);
char* getpath(char*);
void kfscmd(char *); void kfscmd(char *);
void mkdir(Dir*); void mkdir(Dir*);
int mkfile(File*);
void mkfs(File*, int);
char* mkpath(char*, char*);
void mktree(File*, int);
void mountkfs(char*); void mountkfs(char*);
void printfile(File*);
void setnames(File*);
void setusers(void);
void skipdir(void);
char* strdup(char*);
int uptodate(Dir*, char*); int uptodate(Dir*, char*);
void usage(void); void usage(void);
void warn(char *, ...); void warn(char *, ...);
Biobuf *b;
Biobufhdr bout; /* stdout when writing archive */ Biobufhdr bout; /* stdout when writing archive */
uchar boutbuf[2*LEN]; uchar boutbuf[2*LEN];
char newfile[LEN]; char newfile[LEN];
@ -63,11 +38,9 @@ char *users;
char *oldroot; char *oldroot;
char *newroot; char *newroot;
char *prog = "mkfs"; char *prog = "mkfs";
int lineno;
char *buf; char *buf;
char *zbuf; char *zbuf;
int buflen = 1024-8; int buflen = 1024-8;
int indent;
int verb; int verb;
int modes; int modes;
int ream; int ream;
@ -81,16 +54,12 @@ char *user;
void void
main(int argc, char **argv) main(int argc, char **argv)
{ {
File file;
char *name; char *name;
int i, errs; int i, errs;
quotefmtinstall(); quotefmtinstall();
user = getuser(); user = getuser();
name = ""; name = "";
memset(&file, 0, sizeof file);
file.new = "";
file.old = 0;
oldroot = ""; oldroot = "";
newroot = "/n/kfs"; newroot = "/n/kfs";
users = 0; users = 0;
@ -150,34 +119,25 @@ main(int argc, char **argv)
if(!argc) if(!argc)
usage(); usage();
buf = emalloc(buflen); buf = malloc(buflen);
zbuf = emalloc(buflen); zbuf = malloc(buflen);
memset(zbuf, 0, buflen); memset(zbuf, 0, buflen);
mountkfs(name); mountkfs(name);
kfscmd("allow"); kfscmd("allow");
proto = "users";
setusers();
cputype = getenv("cputype"); cputype = getenv("cputype");
if(cputype == 0) if(cputype == 0)
cputype = "68020"; cputype = "386";
errs = 0; errs = 0;
for(i = 0; i < argc; i++){ for(i = 0; i < argc; i++){
proto = argv[i]; proto = argv[i];
fprint(2, "processing %q\n", proto); fprint(2, "processing %q\n", proto);
if(rdproto(proto, oldroot, protoenum, protowarn, nil) < 0){
b = Bopen(proto, OREAD);
if(!b){
fprint(2, "%q: can't open %q: skipping\n", prog, proto); fprint(2, "%q: can't open %q: skipping\n", prog, proto);
errs++; errs++;
continue; continue;
} }
lineno = 0;
indent = 0;
mkfs(&file, -1);
Bterm(b);
} }
fprint(2, "file system made\n"); fprint(2, "file system made\n");
kfscmd("disallow"); kfscmd("disallow");
@ -191,139 +151,6 @@ main(int argc, char **argv)
exits(0); exits(0);
} }
void
mkfs(File *me, int level)
{
File *child;
int rec;
child = getfile(me);
if(!child)
return;
if((child->elem[0] == '+' || child->elem[0] == '*') && child->elem[1] == '\0'){
rec = child->elem[0] == '+';
free(child->new);
child->new = strdup(me->new);
setnames(child);
mktree(child, rec);
freefile(child);
child = getfile(me);
}
while(child && indent > level){
if(mkfile(child))
mkfs(child, indent);
freefile(child);
child = getfile(me);
}
if(child){
freefile(child);
Bseek(b, -Blinelen(b), 1);
lineno--;
}
}
void
mktree(File *me, int rec)
{
File child;
Dir *d;
int i, n, fd;
fd = open(oldfile, OREAD);
if(fd < 0){
warn("can't open %q: %r", oldfile);
return;
}
child = *me;
while((n = dirread(fd, &d)) > 0){
for(i = 0; i < n; i++){
child.new = mkpath(me->new, d[i].name);
if(me->old)
child.old = mkpath(me->old, d[i].name);
child.elem = d[i].name;
setnames(&child);
if(copyfile(&child, &d[i], 1) && rec)
mktree(&child, rec);
free(child.new);
if(child.old)
free(child.old);
}
}
close(fd);
}
int
mkfile(File *f)
{
Dir *dir;
if((dir = dirstat(oldfile)) == nil){
warn("can't stat file %q: %r", oldfile);
skipdir();
return 0;
}
return copyfile(f, dir, 0);
}
int
copyfile(File *f, Dir *d, int permonly)
{
ulong mode;
Dir nd;
if(xflag){
Bprint(&bout, "%q\t%ld\t%lld\n", f->new, d->mtime, d->length);
return (d->mode & DMDIR) != 0;
}
if(verb && (fskind == Archive || ream))
fprint(2, "%q\n", f->new);
d->name = f->elem;
if(d->type != 'M'){
d->uid = "sys";
d->gid = "sys";
mode = (d->mode >> 6) & 7;
d->mode |= mode | (mode << 3);
}
if(strcmp(f->uid, "-") != 0)
d->uid = f->uid;
if(strcmp(f->gid, "-") != 0)
d->gid = f->gid;
if(fskind == Fs && !setuid){
d->uid = "";
d->gid = "";
}
if(f->mode != ~0){
if(permonly)
d->mode = (d->mode & ~0666) | (f->mode & 0666);
else if((d->mode&DMDIR) != (f->mode&DMDIR))
warn("inconsistent mode for %q", f->new);
else
d->mode = f->mode;
}
if(!uptodate(d, newfile)){
if(verb && (fskind != Archive && ream == 0))
fprint(2, "%q\n", f->new);
if(d->mode & DMDIR)
mkdir(d);
else
copy(d);
}else if(modes){
nulldir(&nd);
nd.mode = d->mode;
nd.gid = d->gid;
nd.mtime = d->mtime;
if(verb && (fskind != Archive && ream == 0))
fprint(2, "%q\n", f->new);
if(dirwstat(newfile, &nd) < 0)
warn("can't set modes for %q: %r", f->new);
nulldir(&nd);
nd.uid = d->uid;
dirwstat(newfile, &nd);
}
return (d->mode & DMDIR) != 0;
}
/* /*
* check if file to is up to date with * check if file to is up to date with
* respect to the file represented by df * respect to the file represented by df
@ -478,273 +305,50 @@ arch(Dir *d)
newfile, d->mode, d->uid, d->gid, d->mtime, d->length); newfile, d->mode, d->uid, d->gid, d->mtime, d->length);
} }
char * void
mkpath(char *prefix, char *elem) protowarn(char *msg, void *)
{ {
char *p; warn("%s", msg);
int n;
n = strlen(prefix) + strlen(elem) + 2;
p = emalloc(n);
sprint(p, "%s/%s", prefix, elem);
return p;
}
char *
strdup(char *s)
{
char *t;
t = emalloc(strlen(s) + 1);
return strcpy(t, s);
} }
void void
setnames(File *f) protoenum(char *new, char *old, Dir *d, void *)
{ {
sprint(newfile, "%s%s", newroot, f->new); Dir nd;
if(f->old){
if(f->old[0] == '/')
sprint(oldfile, "%s%s", oldroot, f->old);
else
strcpy(oldfile, f->old);
}else
sprint(oldfile, "%s%s", oldroot, f->new);
if(strlen(newfile) >= sizeof newfile
|| strlen(oldfile) >= sizeof oldfile)
error("name overfile");
}
void sprint(newfile, "%s%s", newroot, new);
freefile(File *f) sprint(oldfile, "%s", old);
{
if(f->old)
free(f->old);
if(f->new)
free(f->new);
free(f);
}
/* if(xflag){
* skip all files in the proto that Bprint(&bout, "%q\t%ld\t%lld\n", new, d->mtime, d->length);
* could be in the current dir
*/
void
skipdir(void)
{
char *p, c;
int level;
if(indent < 0 || b == nil) /* b is nil when copying adm/users */
return; return;
level = indent;
for(;;){
indent = 0;
p = Brdline(b, '\n');
lineno++;
if(!p){
indent = -1;
return;
}
while((c = *p++) != '\n')
if(c == ' ')
indent++;
else if(c == '\t')
indent += 8;
else
break;
if(indent <= level){
Bseek(b, -Blinelen(b), 1);
lineno--;
return;
}
} }
} if(verb && (fskind == Archive || ream))
fprint(2, "%q\n", new);
File* if(fskind == Fs && !setuid){
getfile(File *old) d->uid = "";
{ d->gid = "";
File *f;
char *elem;
char *p;
int c;
if(indent < 0)
return 0;
loop:
indent = 0;
p = Brdline(b, '\n');
lineno++;
if(!p){
indent = -1;
return 0;
} }
while((c = *p++) != '\n') if(!uptodate(d, newfile)){
if(c == ' ') if(verb && (fskind != Archive && ream == 0))
indent++; fprint(2, "%q\n", new);
else if(c == '\t') if(d->mode & DMDIR)
indent += 8; mkdir(d);
else else
break; copy(d);
if(c == '\n' || c == '#') }else if(modes){
goto loop; nulldir(&nd);
p--; nd.mode = d->mode;
f = emalloc(sizeof *f); nd.gid = d->gid;
p = getname(p, &elem); nd.mtime = d->mtime;
if(debug) if(verb && (fskind != Archive && ream == 0))
fprint(2, "getfile: %q root %q\n", elem, old->new); fprint(2, "%q\n", new);
f->new = mkpath(old->new, elem); if(dirwstat(newfile, &nd) < 0)
f->elem = utfrrune(f->new, L'/') + 1; warn("can't set modes for %q: %r", new);
p = getmode(p, &f->mode); nulldir(&nd);
p = getname(p, &f->uid); nd.uid = d->uid;
if(!*f->uid) dirwstat(newfile, &nd);
f->uid = "-";
p = getname(p, &f->gid);
if(!*f->gid)
f->gid = "-";
f->old = getpath(p);
if(f->old && strcmp(f->old, "-") == 0){
free(f->old);
f->old = 0;
} }
setnames(f);
if(debug)
printfile(f);
return f;
}
char*
getpath(char *p)
{
char *q, *new;
int c, n;
while((c = *p) == ' ' || c == '\t')
p++;
q = p;
while((c = *q) != '\n' && c != ' ' && c != '\t')
q++;
if(q == p)
return 0;
n = q - p;
new = emalloc(n + 1);
memcpy(new, p, n);
new[n] = 0;
return new;
}
char*
getname(char *p, char **buf)
{
char *s, *start;
int c;
while((c = *p) == ' ' || c == '\t')
p++;
start = p;
while((c = *p) != '\n' && c != ' ' && c != '\t' && c != '\0')
p++;
*buf = malloc(p+1-start);
if(*buf == nil)
return nil;
memmove(*buf, start, p-start);
(*buf)[p-start] = '\0';
if(**buf == '$'){
s = getenv(*buf+1);
if(s == 0){
warn("can't read environment variable %q", *buf+1);
skipdir();
free(*buf);
return nil;
}
free(*buf);
*buf = s;
}
return p;
}
char*
getmode(char *p, ulong *xmode)
{
char *buf, *s;
ulong m;
*xmode = ~0;
p = getname(p, &buf);
if(p == nil)
return nil;
s = buf;
if(!*s || strcmp(s, "-") == 0)
return p;
m = 0;
if(*s == 'd'){
m |= DMDIR;
s++;
}
if(*s == 'a'){
m |= DMAPPEND;
s++;
}
if(*s == 'l'){
m |= DMEXCL;
s++;
}
if(s[0] < '0' || s[0] > '7'
|| s[1] < '0' || s[1] > '7'
|| s[2] < '0' || s[2] > '7'
|| s[3]){
warn("bad mode specification %q", buf);
free(buf);
return p;
}
*xmode = m | strtoul(s, 0, 8);
free(buf);
return p;
}
void
setusers(void)
{
File file;
int m;
if(fskind != Kfs)
return;
m = modes;
modes = 1;
file.uid = "adm";
file.gid = "adm";
file.mode = DMDIR|0775;
file.new = "/adm";
file.elem = "adm";
file.old = 0;
setnames(&file);
strcpy(oldfile, file.new); /* Don't use root for /adm */
mkfile(&file);
file.new = "/adm/users";
file.old = users;
file.elem = "users";
file.mode = 0664;
setnames(&file);
if (file.old)
strcpy(oldfile, file.old); /* Don't use root for /adm/users */
mkfile(&file);
kfscmd("user");
mkfile(&file);
file.mode = DMDIR|0775;
file.new = "/adm";
file.old = "/adm";
file.elem = "adm";
setnames(&file);
strcpy(oldfile, file.old); /* Don't use root for /adm */
mkfile(&file);
modes = m;
} }
void void
@ -802,23 +406,13 @@ kfscmd(char *cmd)
} }
} }
void *
emalloc(ulong n)
{
void *p;
if((p = malloc(n)) == 0)
error("out of memory");
return p;
}
void void
error(char *fmt, ...) error(char *fmt, ...)
{ {
char buf[1024]; char buf[1024];
va_list arg; va_list arg;
sprint(buf, "%q: %q:%d: ", prog, proto, lineno); sprint(buf, "%q: %q: ", prog, proto);
va_start(arg, fmt); va_start(arg, fmt);
vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg); vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg);
va_end(arg); va_end(arg);
@ -834,25 +428,16 @@ warn(char *fmt, ...)
char buf[1024]; char buf[1024];
va_list arg; va_list arg;
sprint(buf, "%q: %q:%d: ", prog, proto, lineno); sprint(buf, "%q: %q: ", prog, proto);
va_start(arg, fmt); va_start(arg, fmt);
vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg); vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg);
va_end(arg); va_end(arg);
fprint(2, "%s\n", buf); fprint(2, "%s\n", buf);
} }
void
printfile(File *f)
{
if(f->old)
fprint(2, "%q from %q %q %q %lo\n", f->new, f->old, f->uid, f->gid, f->mode);
else
fprint(2, "%q %q %q %lo\n", f->new, f->uid, f->gid, f->mode);
}
void void
usage(void) usage(void)
{ {
fprint(2, "usage: %q [-aprvx] [-d root] [-n name] [-s source] [-u users] [-z n] proto ...\n", prog); fprint(2, "usage: %q [-adprvxUD] [-d root] [-n name] [-s source] [-u users] [-z n] proto ...\n", prog);
exits("usage"); exits("usage");
} }

View file

@ -68,7 +68,7 @@ static char* getpath(Mkaux*, char*);
static int mkfile(Mkaux*, File*); static int mkfile(Mkaux*, File*);
static char* mkpath(Mkaux*, char*, char*); static char* mkpath(Mkaux*, char*, char*);
static void mktree(Mkaux*, File*, int); static void mktree(Mkaux*, File*, int);
static void setnames(Mkaux*, File*); static void setname(Mkaux*, Name*, File*);
static void skipdir(Mkaux*); static void skipdir(Mkaux*);
static void warn(Mkaux*, char *, ...); static void warn(Mkaux*, char *, ...);
static void popopt(Mkaux *mkaux); static void popopt(Mkaux *mkaux);
@ -154,7 +154,7 @@ domkfs(Mkaux *mkaux, File *me, int level)
rec = child->elem[0] == '+'; rec = child->elem[0] == '+';
free(child->new); free(child->new);
child->new = estrdup(mkaux, me->new); child->new = estrdup(mkaux, me->new);
setnames(mkaux, child); setname(mkaux, &mkaux->oldfile, child);
mktree(mkaux, child, rec); mktree(mkaux, child, rec);
freefile(child); freefile(child);
child = getfile(mkaux, me); child = getfile(mkaux, me);
@ -194,7 +194,7 @@ mktree(Mkaux *mkaux, File *me, int rec)
if(me->old) if(me->old)
child.old = mkpath(mkaux, me->old, d[i].name); child.old = mkpath(mkaux, me->old, d[i].name);
child.elem = d[i].name; child.elem = d[i].name;
setnames(mkaux, &child); setname(mkaux, &mkaux->oldfile, &child);
if((!(d[i].mode&DMDIR) || rec) && copyfile(mkaux, &child, &d[i], 1) && rec) if((!(d[i].mode&DMDIR) || rec) && copyfile(mkaux, &child, &d[i], 1) && rec)
mktree(mkaux, &child, rec); mktree(mkaux, &child, rec);
free(child.new); free(child.new);
@ -223,19 +223,36 @@ enum {
}; };
static void static void
setname(Mkaux *mkaux, Name *name, char *s1, char *s2) setname(Mkaux *mkaux, Name *name, File *f)
{ {
char *s1, *s2, *ss;
int l; int l;
s1 = mkaux->root;
s2 = "";
if(f->old){
/* if old is not a absolute path, dont append root to it */
if(f->old[0] != '/')
s1 = f->old;
else
s2 = f->old;
}else
s2 = f->new;
l = strlen(s1)+strlen(s2)+1; l = strlen(s1);
ss = (*s1 && *s2 && *s2 != '/' && s1[l-1] != '/') ? "/" : "";
l += strlen(ss);
l += strlen(s2);
l++;
if(name->n < l+SLOP/2) { if(name->n < l+SLOP/2) {
free(name->s); free(name->s);
name->s = emalloc(mkaux, l+SLOP); name->s = emalloc(mkaux, l+SLOP);
name->n = l+SLOP; name->n = l+SLOP;
} }
snprint(name->s, name->n, "%s%s%s", s1, *s1==0 || s1[strlen(s1)-1]!='/' ? "/" : "", s2); snprint(name->s, name->n, "%s%s%s", s1, ss, s2);
} }
static int static int
copyfile(Mkaux *mkaux, File *f, Dir *d, int permonly) copyfile(Mkaux *mkaux, File *f, Dir *d, int permonly)
{ {
@ -244,7 +261,8 @@ copyfile(Mkaux *mkaux, File *f, Dir *d, int permonly)
ulong xmode; ulong xmode;
char *p; char *p;
setname(mkaux, &mkaux->fullname, mkaux->root, f->old ? f->old : f->new); setname(mkaux, &mkaux->fullname, f);
/* /*
* Extra stat here is inefficient but accounts for binds. * Extra stat here is inefficient but accounts for binds.
*/ */
@ -300,19 +318,6 @@ mkpath(Mkaux *mkaux, char *prefix, char *elem)
return p; return p;
} }
static void
setnames(Mkaux *mkaux, File *f)
{
if(f->old){
if(f->old[0] == '/')
setname(mkaux, &mkaux->oldfile, f->old, "");
else
setname(mkaux, &mkaux->oldfile, mkaux->root, f->old);
} else
setname(mkaux, &mkaux->oldfile, mkaux->root, f->new);
}
static void static void
setopt(Mkaux *mkaux, char *key, char *val) setopt(Mkaux *mkaux, char *key, char *val)
{ {
@ -475,7 +480,7 @@ loop:
free(f->old); free(f->old);
f->old = 0; f->old = 0;
} }
setnames(mkaux, f); setname(mkaux, &mkaux->oldfile, f);
return f; return f;
} }