kernel: introduce devswap #¶ to serve /dev/swap and handle swapfile encryption
This commit is contained in:
parent
93117262c2
commit
f3f9392517
44 changed files with 273 additions and 142 deletions
|
@ -10,6 +10,7 @@ bind #p /proc
|
||||||
bind -c #s /srv
|
bind -c #s /srv
|
||||||
bind -q #σ /shr
|
bind -q #σ /shr
|
||||||
bind -a #¤ /dev
|
bind -a #¤ /dev
|
||||||
|
bind -qa #¶ /dev
|
||||||
|
|
||||||
# authentication
|
# authentication
|
||||||
mount -b /srv/factotum /mnt
|
mount -b /srv/factotum /mnt
|
||||||
|
|
|
@ -22,7 +22,6 @@ cons \- console, clocks, process/process group ids, user, null, reboot, etc.
|
||||||
.B /dev/ppid
|
.B /dev/ppid
|
||||||
.B /dev/random
|
.B /dev/random
|
||||||
.B /dev/reboot
|
.B /dev/reboot
|
||||||
.B /dev/swap
|
|
||||||
.B /dev/sysname
|
.B /dev/sysname
|
||||||
.B /dev/sysstat
|
.B /dev/sysstat
|
||||||
.B /dev/time
|
.B /dev/time
|
||||||
|
@ -240,41 +239,6 @@ Writing anything to
|
||||||
.B sysstat
|
.B sysstat
|
||||||
resets all of the counts on all processors.
|
resets all of the counts on all processors.
|
||||||
.PP
|
.PP
|
||||||
The
|
|
||||||
.B swap
|
|
||||||
device holds a text block giving memory usage statistics:
|
|
||||||
.IP
|
|
||||||
.EX
|
|
||||||
\fIn\fP memory
|
|
||||||
\fIn\fP pagesize
|
|
||||||
\fIn\fP kernel
|
|
||||||
\fIn\fP/\fIm\fP user
|
|
||||||
\fIn\fP/\fIm\fP swap
|
|
||||||
\fIa\fP/\fIn\fP/\fIm\fP kernel malloc
|
|
||||||
\fIa\fP/\fIn\fP/\fIm\fP kernel draw
|
|
||||||
.EE
|
|
||||||
.PP
|
|
||||||
These are total memory (bytes), system page size (bytes),
|
|
||||||
kernel memory (pages), user memory (pages), swap space (pages),
|
|
||||||
kernel malloced data (bytes), and kernel graphics data (bytes).
|
|
||||||
The expression
|
|
||||||
.IR n / m
|
|
||||||
indicates
|
|
||||||
.I n
|
|
||||||
used out of
|
|
||||||
.I m
|
|
||||||
available.
|
|
||||||
For kernel malloc and kernel draw,
|
|
||||||
.IR a
|
|
||||||
indicates the current allocation in bytes.
|
|
||||||
These numbers are not blank padded.
|
|
||||||
.PP
|
|
||||||
To turn on swapping, write to
|
|
||||||
.B swap
|
|
||||||
the textual file descriptor number of a file or device on which to swap.
|
|
||||||
See
|
|
||||||
.IR swap (8).
|
|
||||||
.PP
|
|
||||||
Reads and writes to
|
Reads and writes to
|
||||||
.IR mordor
|
.IR mordor
|
||||||
will inevitably cause the front to fall off.
|
will inevitably cause the front to fall off.
|
||||||
|
|
46
sys/man/3/swap
Normal file
46
sys/man/3/swap
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
.TH SWAP 3
|
||||||
|
.SH NAME
|
||||||
|
swap \- memory usage statistics and pagefile control
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.nf
|
||||||
|
.B bind -a #¶ /dev
|
||||||
|
|
||||||
|
.B /dev/swap
|
||||||
|
.fi
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.B swap
|
||||||
|
device holds a text block giving memory usage statistics:
|
||||||
|
.IP
|
||||||
|
.EX
|
||||||
|
\fIn\fP memory
|
||||||
|
\fIn\fP pagesize
|
||||||
|
\fIn\fP kernel
|
||||||
|
\fIn\fP/\fIm\fP user
|
||||||
|
\fIn\fP/\fIm\fP swap
|
||||||
|
\fIa\fP/\fIn\fP/\fIm\fP kernel malloc
|
||||||
|
\fIa\fP/\fIn\fP/\fIm\fP kernel draw
|
||||||
|
.EE
|
||||||
|
.PP
|
||||||
|
These are total memory (bytes), system page size (bytes),
|
||||||
|
kernel memory (pages), user memory (pages), swap space (pages),
|
||||||
|
kernel malloced data (bytes), and kernel graphics data (bytes).
|
||||||
|
The expression
|
||||||
|
.IR n / m
|
||||||
|
indicates
|
||||||
|
.I n
|
||||||
|
used out of
|
||||||
|
.I m
|
||||||
|
available.
|
||||||
|
For kernel malloc and kernel draw,
|
||||||
|
.IR a
|
||||||
|
indicates the current allocation in bytes.
|
||||||
|
These numbers are not blank padded.
|
||||||
|
.PP
|
||||||
|
To turn on swapping, write to
|
||||||
|
.B swap
|
||||||
|
the textual file descriptor number of a file or device on which to swap.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.IR swap (8).
|
||||||
|
.SH SOURCE
|
||||||
|
.B /sys/src/9/port/devswap.c
|
|
@ -35,4 +35,5 @@ will lead to deadlock if the process isn't made non-swappable
|
||||||
ctl-message in
|
ctl-message in
|
||||||
.IR proc (3)).
|
.IR proc (3)).
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
|
.IR swap (3),
|
||||||
.IR proc (3)
|
.IR proc (3)
|
||||||
|
|
|
@ -270,7 +270,6 @@ main(void)
|
||||||
links();
|
links();
|
||||||
chandevreset(); /* most devices are discovered here */
|
chandevreset(); /* most devices are discovered here */
|
||||||
pageinit();
|
pageinit();
|
||||||
swapinit();
|
|
||||||
userinit();
|
userinit();
|
||||||
gpiomeminit();
|
gpiomeminit();
|
||||||
schedinit();
|
schedinit();
|
||||||
|
|
|
@ -33,7 +33,6 @@ PORT=\
|
||||||
rdb.$O\
|
rdb.$O\
|
||||||
rebootcmd.$O\
|
rebootcmd.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
syscallfmt.$O\
|
syscallfmt.$O\
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
env
|
env
|
||||||
pipe
|
pipe
|
||||||
proc
|
proc
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
env
|
env
|
||||||
pipe
|
pipe
|
||||||
proc
|
proc
|
||||||
|
|
|
@ -10,7 +10,7 @@ unmount /root
|
||||||
|
|
||||||
bind -q '#d' /fd
|
bind -q '#d' /fd
|
||||||
bind -q '#p' /proc
|
bind -q '#p' /proc
|
||||||
for(i in S f k æ t b m)
|
for(i in ¶ P S f k æ t b m)
|
||||||
bind -qa '#'^$i /dev
|
bind -qa '#'^$i /dev
|
||||||
|
|
||||||
# bind in an ip interface
|
# bind in an ip interface
|
||||||
|
|
|
@ -322,7 +322,6 @@ wave(' ');
|
||||||
chandevreset(); /* most devices are discovered here */
|
chandevreset(); /* most devices are discovered here */
|
||||||
|
|
||||||
pageinit();
|
pageinit();
|
||||||
swapinit();
|
|
||||||
userinit();
|
userinit();
|
||||||
schedinit();
|
schedinit();
|
||||||
panic("schedinit returned");
|
panic("schedinit returned");
|
||||||
|
|
|
@ -32,7 +32,6 @@ PORT=\
|
||||||
qio.$O\
|
qio.$O\
|
||||||
qlock.$O\
|
qlock.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
syscallfmt.$O\
|
syscallfmt.$O\
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
env
|
env
|
||||||
pipe
|
pipe
|
||||||
proc
|
proc
|
||||||
|
|
|
@ -35,7 +35,6 @@ main(void)
|
||||||
links();
|
links();
|
||||||
chandevreset();
|
chandevreset();
|
||||||
pageinit();
|
pageinit();
|
||||||
swapinit();
|
|
||||||
fpsave(&initfp);
|
fpsave(&initfp);
|
||||||
initfp.fpscr = 0;
|
initfp.fpscr = 0;
|
||||||
userinit();
|
userinit();
|
||||||
|
|
|
@ -30,7 +30,6 @@ PORT=\
|
||||||
qlock.$O\
|
qlock.$O\
|
||||||
rdb.$O\
|
rdb.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
taslock.$O\
|
taslock.$O\
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
arch
|
arch
|
||||||
pnp pci
|
pnp pci
|
||||||
env
|
env
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
arch
|
arch
|
||||||
pnp pci
|
pnp pci
|
||||||
env
|
env
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
env
|
env
|
||||||
pipe
|
pipe
|
||||||
proc
|
proc
|
||||||
|
|
|
@ -276,7 +276,6 @@ wave('l');
|
||||||
// i8250console(); /* too early; see init0 */
|
// i8250console(); /* too early; see init0 */
|
||||||
|
|
||||||
pageinit();
|
pageinit();
|
||||||
swapinit();
|
|
||||||
userinit();
|
userinit();
|
||||||
schedinit();
|
schedinit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ PORT=\
|
||||||
qio.$O\
|
qio.$O\
|
||||||
qlock.$O\
|
qlock.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
taslock.$O\
|
taslock.$O\
|
||||||
|
|
|
@ -62,7 +62,6 @@ main(void)
|
||||||
chandevreset();
|
chandevreset();
|
||||||
netconsole();
|
netconsole();
|
||||||
pageinit();
|
pageinit();
|
||||||
swapinit();
|
|
||||||
userinit();
|
userinit();
|
||||||
schedinit();
|
schedinit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ PORT=\
|
||||||
rdb.$O\
|
rdb.$O\
|
||||||
rebootcmd.$O\
|
rebootcmd.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
syscallfmt.$O\
|
syscallfmt.$O\
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
arch
|
arch
|
||||||
pnp pci
|
pnp pci
|
||||||
env
|
env
|
||||||
|
|
|
@ -332,7 +332,6 @@ main()
|
||||||
netconsole();
|
netconsole();
|
||||||
preallocpages();
|
preallocpages();
|
||||||
pageinit();
|
pageinit();
|
||||||
swapinit();
|
|
||||||
userinit();
|
userinit();
|
||||||
schedinit();
|
schedinit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ PORT=\
|
||||||
rdb.$O\
|
rdb.$O\
|
||||||
rebootcmd.$O\
|
rebootcmd.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
syscallfmt.$O\
|
syscallfmt.$O\
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
arch
|
arch
|
||||||
pnp pci
|
pnp pci
|
||||||
env
|
env
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "fns.h"
|
#include "fns.h"
|
||||||
#include "../port/error.h"
|
#include "../port/error.h"
|
||||||
|
|
||||||
#include <pool.h>
|
|
||||||
#include <authsrv.h>
|
#include <authsrv.h>
|
||||||
|
|
||||||
void (*consdebug)(void) = nil;
|
void (*consdebug)(void) = nil;
|
||||||
|
@ -324,7 +323,6 @@ enum{
|
||||||
Qppid,
|
Qppid,
|
||||||
Qrandom,
|
Qrandom,
|
||||||
Qreboot,
|
Qreboot,
|
||||||
Qswap,
|
|
||||||
Qsysname,
|
Qsysname,
|
||||||
Qsysstat,
|
Qsysstat,
|
||||||
Qtime,
|
Qtime,
|
||||||
|
@ -357,7 +355,6 @@ static Dirtab consdir[]={
|
||||||
"ppid", {Qppid}, NUMSIZE, 0444,
|
"ppid", {Qppid}, NUMSIZE, 0444,
|
||||||
"random", {Qrandom}, 0, 0444,
|
"random", {Qrandom}, 0, 0444,
|
||||||
"reboot", {Qreboot}, 0, 0664,
|
"reboot", {Qreboot}, 0, 0664,
|
||||||
"swap", {Qswap}, 0, 0664,
|
|
||||||
"sysname", {Qsysname}, 0, 0664,
|
"sysname", {Qsysname}, 0, 0664,
|
||||||
"sysstat", {Qsysstat}, 0, 0666,
|
"sysstat", {Qsysstat}, 0, 0666,
|
||||||
"time", {Qtime}, NUMSIZE+3*VLNUMSIZE, 0664,
|
"time", {Qtime}, NUMSIZE+3*VLNUMSIZE, 0664,
|
||||||
|
@ -471,8 +468,6 @@ consread(Chan *c, void *buf, long n, vlong off)
|
||||||
int i, k, id;
|
int i, k, id;
|
||||||
vlong offset = off;
|
vlong offset = off;
|
||||||
extern char configfile[];
|
extern char configfile[];
|
||||||
extern Image fscache;
|
|
||||||
extern Image swapimage;
|
|
||||||
|
|
||||||
if(n <= 0)
|
if(n <= 0)
|
||||||
return n;
|
return n;
|
||||||
|
@ -592,33 +587,6 @@ consread(Chan *c, void *buf, long n, vlong off)
|
||||||
poperror();
|
poperror();
|
||||||
return n;
|
return n;
|
||||||
|
|
||||||
case Qswap:
|
|
||||||
snprint(tmp, sizeof tmp,
|
|
||||||
"%llud memory\n"
|
|
||||||
"%llud pagesize\n"
|
|
||||||
"%lud kernel\n"
|
|
||||||
"%lud/%lud user\n"
|
|
||||||
"%lud/%lud swap\n"
|
|
||||||
"%llud/%llud/%llud kernel malloc\n"
|
|
||||||
"%llud/%llud/%llud kernel draw\n"
|
|
||||||
"%llud/%llud/%llud kernel secret\n",
|
|
||||||
(uvlong)conf.npage*BY2PG,
|
|
||||||
(uvlong)BY2PG,
|
|
||||||
conf.npage-conf.upages,
|
|
||||||
palloc.user-palloc.freecount-fscache.pgref-swapimage.pgref, palloc.user,
|
|
||||||
conf.nswap-swapalloc.free, conf.nswap,
|
|
||||||
(uvlong)mainmem->curalloc,
|
|
||||||
(uvlong)mainmem->cursize,
|
|
||||||
(uvlong)mainmem->maxsize,
|
|
||||||
(uvlong)imagmem->curalloc,
|
|
||||||
(uvlong)imagmem->cursize,
|
|
||||||
(uvlong)imagmem->maxsize,
|
|
||||||
(uvlong)secrmem->curalloc,
|
|
||||||
(uvlong)secrmem->cursize,
|
|
||||||
(uvlong)secrmem->maxsize);
|
|
||||||
|
|
||||||
return readstr((ulong)offset, buf, n, tmp);
|
|
||||||
|
|
||||||
case Qsysname:
|
case Qsysname:
|
||||||
if(sysname == nil)
|
if(sysname == nil)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -669,8 +637,7 @@ conswrite(Chan *c, void *va, long n, vlong off)
|
||||||
long l, bp;
|
long l, bp;
|
||||||
char *a;
|
char *a;
|
||||||
Mach *mp;
|
Mach *mp;
|
||||||
int id, fd;
|
int id;
|
||||||
Chan *swc;
|
|
||||||
ulong offset;
|
ulong offset;
|
||||||
Cmdbuf *cb;
|
Cmdbuf *cb;
|
||||||
Cmdtab *ct;
|
Cmdtab *ct;
|
||||||
|
@ -765,25 +732,6 @@ conswrite(Chan *c, void *va, long n, vlong off)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qswap:
|
|
||||||
if(n >= sizeof buf)
|
|
||||||
error(Egreg);
|
|
||||||
memmove(buf, va, n); /* so we can NUL-terminate */
|
|
||||||
buf[n] = 0;
|
|
||||||
/* start a pager if not already started */
|
|
||||||
if(strncmp(buf, "start", 5) == 0){
|
|
||||||
kickpager();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!iseve())
|
|
||||||
error(Eperm);
|
|
||||||
if(buf[0]<'0' || '9'<buf[0])
|
|
||||||
error(Ebadarg);
|
|
||||||
fd = strtoul(buf, 0, 0);
|
|
||||||
swc = fdtochan(fd, ORDWR, 1, 1);
|
|
||||||
setswapchan(swc);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qsysname:
|
case Qsysname:
|
||||||
if(offset != 0)
|
if(offset != 0)
|
||||||
error(Ebadarg);
|
error(Ebadarg);
|
||||||
|
|
|
@ -5,21 +5,29 @@
|
||||||
#include "fns.h"
|
#include "fns.h"
|
||||||
#include "../port/error.h"
|
#include "../port/error.h"
|
||||||
|
|
||||||
|
#include <libsec.h>
|
||||||
|
#include <pool.h>
|
||||||
|
|
||||||
static int canflush(Proc*, Segment*);
|
static int canflush(Proc*, Segment*);
|
||||||
static void executeio(void);
|
static void executeio(void);
|
||||||
static void pageout(Proc*, Segment*);
|
static void pageout(Proc*, Segment*);
|
||||||
static void pagepte(int, Page**);
|
static void pagepte(int, Page**);
|
||||||
static void pager(void*);
|
static void pager(void*);
|
||||||
|
|
||||||
Image swapimage;
|
Image swapimage = {
|
||||||
|
.notext = 1,
|
||||||
|
};
|
||||||
|
|
||||||
static int swopen;
|
static Chan *swapchan;
|
||||||
static Page **iolist;
|
static uchar *swapbuf;
|
||||||
static int ioptr;
|
static AESstate *swapkey;
|
||||||
|
|
||||||
static ushort ageclock;
|
static Page **iolist;
|
||||||
|
static int ioptr;
|
||||||
|
|
||||||
void
|
static ushort ageclock;
|
||||||
|
|
||||||
|
static void
|
||||||
swapinit(void)
|
swapinit(void)
|
||||||
{
|
{
|
||||||
swapalloc.swmap = xalloc(conf.nswap);
|
swapalloc.swmap = xalloc(conf.nswap);
|
||||||
|
@ -30,10 +38,8 @@ swapinit(void)
|
||||||
swapalloc.xref = 0;
|
swapalloc.xref = 0;
|
||||||
|
|
||||||
iolist = xalloc(conf.nswppo*sizeof(Page*));
|
iolist = xalloc(conf.nswppo*sizeof(Page*));
|
||||||
if(swapalloc.swmap == 0 || iolist == 0)
|
if(swapalloc.swmap == nil || iolist == nil)
|
||||||
panic("swapinit: not enough memory");
|
panic("swapinit: not enough memory");
|
||||||
|
|
||||||
swapimage.notext = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr
|
static uintptr
|
||||||
|
@ -216,13 +222,8 @@ pageout(Proc *p, Segment *s)
|
||||||
if(!canqlock(s)) /* We cannot afford to wait, we will surely deadlock */
|
if(!canqlock(s)) /* We cannot afford to wait, we will surely deadlock */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!canflush(p, s)) { /* Able to invalidate all tlbs with references */
|
if(!canflush(p, s) /* Able to invalidate all tlbs with references */
|
||||||
qunlock(s);
|
|| waserror()) {
|
||||||
putseg(s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(waserror()) {
|
|
||||||
qunlock(s);
|
qunlock(s);
|
||||||
putseg(s);
|
putseg(s);
|
||||||
return;
|
return;
|
||||||
|
@ -389,10 +390,10 @@ needpages(void*)
|
||||||
return palloc.freecount < swapalloc.headroom;
|
return palloc.freecount < swapalloc.headroom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
setswapchan(Chan *c)
|
setswapchan(Chan *c)
|
||||||
{
|
{
|
||||||
uchar dirbuf[sizeof(Dir)+100];
|
uchar buf[sizeof(Dir)+100];
|
||||||
Dir d;
|
Dir d;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
@ -412,8 +413,8 @@ setswapchan(Chan *c)
|
||||||
* to be at most the size of the partition
|
* to be at most the size of the partition
|
||||||
*/
|
*/
|
||||||
if(devtab[c->type]->dc != L'M'){
|
if(devtab[c->type]->dc != L'M'){
|
||||||
n = devtab[c->type]->stat(c, dirbuf, sizeof dirbuf);
|
n = devtab[c->type]->stat(c, buf, sizeof buf);
|
||||||
if(n <= 0 || convM2D(dirbuf, n, &d, nil) == 0)
|
if(n <= 0 || convM2D(buf, n, &d, nil) == 0)
|
||||||
error("stat failed in setswapchan");
|
error("stat failed in setswapchan");
|
||||||
if(d.length < conf.nswppo*BY2PG)
|
if(d.length < conf.nswppo*BY2PG)
|
||||||
error("swap device too small");
|
error("swap device too small");
|
||||||
|
@ -425,6 +426,187 @@ setswapchan(Chan *c)
|
||||||
}
|
}
|
||||||
c->flag &= ~CCACHE;
|
c->flag &= ~CCACHE;
|
||||||
cclunk(c);
|
cclunk(c);
|
||||||
swapimage.c = c;
|
|
||||||
poperror();
|
poperror();
|
||||||
|
|
||||||
|
swapchan = c;
|
||||||
|
swapimage.c = namec("#¶/swapfile", Aopen, ORDWR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Qdir,
|
||||||
|
Qswap,
|
||||||
|
Qswapfile,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Dirtab swapdir[]={
|
||||||
|
".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
|
||||||
|
"swap", {Qswap}, 0, 0664,
|
||||||
|
"swapfile", {Qswapfile}, 0, 0600,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Chan*
|
||||||
|
swapattach(char *spec)
|
||||||
|
{
|
||||||
|
return devattach(L'¶', spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Walkqid*
|
||||||
|
swapwalk(Chan *c, Chan *nc, char **name, int nname)
|
||||||
|
{
|
||||||
|
return devwalk(c, nc, name, nname, swapdir, nelem(swapdir), devgen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
swapstat(Chan *c, uchar *dp, int n)
|
||||||
|
{
|
||||||
|
return devstat(c, dp, n, swapdir, nelem(swapdir), devgen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Chan*
|
||||||
|
swapopen(Chan *c, int omode)
|
||||||
|
{
|
||||||
|
uchar key[128/8];
|
||||||
|
|
||||||
|
switch((ulong)c->qid.path){
|
||||||
|
case Qswapfile:
|
||||||
|
if(!iseve() || omode != ORDWR)
|
||||||
|
error(Eperm);
|
||||||
|
if(swapimage.c != nil)
|
||||||
|
error(Einuse);
|
||||||
|
if(swapchan == nil)
|
||||||
|
error(Egreg);
|
||||||
|
|
||||||
|
c->mode = openmode(omode);
|
||||||
|
c->flag |= COPEN;
|
||||||
|
c->offset = 0;
|
||||||
|
|
||||||
|
swapbuf = mallocalign(BY2PG, BY2PG, 0, 0);
|
||||||
|
swapkey = secalloc(sizeof(AESstate)*2);
|
||||||
|
if(swapbuf == nil || swapkey == nil)
|
||||||
|
error(Enomem);
|
||||||
|
|
||||||
|
genrandom(key, sizeof(key));
|
||||||
|
setupAESstate(&swapkey[0], key, sizeof(key), nil);
|
||||||
|
genrandom(key, sizeof(key));
|
||||||
|
setupAESstate(&swapkey[1], key, sizeof(key), nil);
|
||||||
|
memset(key, 0, sizeof(key));
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return devopen(c, omode, swapdir, nelem(swapdir), devgen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swapclose(Chan *c)
|
||||||
|
{
|
||||||
|
if((c->flag & COPEN) == 0)
|
||||||
|
return;
|
||||||
|
switch((ulong)c->qid.path){
|
||||||
|
case Qswapfile:
|
||||||
|
cclose(swapchan);
|
||||||
|
swapchan = nil;
|
||||||
|
secfree(swapkey);
|
||||||
|
swapkey = nil;
|
||||||
|
free(swapbuf);
|
||||||
|
swapbuf = nil;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
swapread(Chan *c, void *va, long n, vlong off)
|
||||||
|
{
|
||||||
|
char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */
|
||||||
|
|
||||||
|
switch((ulong)c->qid.path){
|
||||||
|
case Qdir:
|
||||||
|
return devdirread(c, va, n, swapdir, nelem(swapdir), devgen);
|
||||||
|
case Qswap:
|
||||||
|
snprint(tmp, sizeof tmp,
|
||||||
|
"%llud memory\n"
|
||||||
|
"%llud pagesize\n"
|
||||||
|
"%lud kernel\n"
|
||||||
|
"%lud/%lud user\n"
|
||||||
|
"%lud/%lud swap\n"
|
||||||
|
"%llud/%llud/%llud kernel malloc\n"
|
||||||
|
"%llud/%llud/%llud kernel draw\n"
|
||||||
|
"%llud/%llud/%llud kernel secret\n",
|
||||||
|
(uvlong)conf.npage*BY2PG,
|
||||||
|
(uvlong)BY2PG,
|
||||||
|
conf.npage-conf.upages,
|
||||||
|
palloc.user-palloc.freecount-fscache.pgref-swapimage.pgref, palloc.user,
|
||||||
|
conf.nswap-swapalloc.free, conf.nswap,
|
||||||
|
(uvlong)mainmem->curalloc,
|
||||||
|
(uvlong)mainmem->cursize,
|
||||||
|
(uvlong)mainmem->maxsize,
|
||||||
|
(uvlong)imagmem->curalloc,
|
||||||
|
(uvlong)imagmem->cursize,
|
||||||
|
(uvlong)imagmem->maxsize,
|
||||||
|
(uvlong)secrmem->curalloc,
|
||||||
|
(uvlong)secrmem->cursize,
|
||||||
|
(uvlong)secrmem->maxsize);
|
||||||
|
return readstr((ulong)off, va, n, tmp);
|
||||||
|
case Qswapfile:
|
||||||
|
if(n != BY2PG)
|
||||||
|
error(Ebadarg);
|
||||||
|
if(devtab[swapchan->type]->read(swapchan, va, n, off) != n)
|
||||||
|
error(Eio);
|
||||||
|
aes_xts_decrypt(&swapkey[0], &swapkey[1], off, va, va, n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
error(Egreg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
swapwrite(Chan *c, void *va, long n, vlong off)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
switch((ulong)c->qid.path){
|
||||||
|
case Qswap:
|
||||||
|
if(!iseve())
|
||||||
|
error(Eperm);
|
||||||
|
if(n >= sizeof buf)
|
||||||
|
error(Egreg);
|
||||||
|
memmove(buf, va, n); /* so we can NUL-terminate */
|
||||||
|
buf[n] = 0;
|
||||||
|
/* start a pager if not already started */
|
||||||
|
if(strncmp(buf, "start", 5) == 0)
|
||||||
|
kickpager();
|
||||||
|
else if(buf[0]>='0' && '9'<=buf[0])
|
||||||
|
setswapchan(fdtochan(strtoul(buf, nil, 0), ORDWR, 1, 1));
|
||||||
|
else
|
||||||
|
error(Ebadctl);
|
||||||
|
return n;
|
||||||
|
case Qswapfile:
|
||||||
|
if(n != BY2PG)
|
||||||
|
error(Ebadarg);
|
||||||
|
aes_xts_encrypt(&swapkey[0], &swapkey[1], off, va, swapbuf, n);
|
||||||
|
if(devtab[swapchan->type]->write(swapchan, swapbuf, n, off) != n)
|
||||||
|
error(Eio);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
error(Egreg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dev swapdevtab = {
|
||||||
|
L'¶',
|
||||||
|
"swap",
|
||||||
|
devreset,
|
||||||
|
swapinit,
|
||||||
|
devshutdown,
|
||||||
|
swapattach,
|
||||||
|
swapwalk,
|
||||||
|
swapstat,
|
||||||
|
swapopen,
|
||||||
|
devcreate,
|
||||||
|
swapclose,
|
||||||
|
swapread,
|
||||||
|
devbread,
|
||||||
|
swapwrite,
|
||||||
|
devbwrite,
|
||||||
|
devremove,
|
||||||
|
devwstat,
|
||||||
|
};
|
|
@ -318,7 +318,6 @@ int setlabel(Label*);
|
||||||
void setmalloctag(void*, uintptr);
|
void setmalloctag(void*, uintptr);
|
||||||
void setrealloctag(void*, uintptr);
|
void setrealloctag(void*, uintptr);
|
||||||
void setregisters(Ureg*, char*, char*, int);
|
void setregisters(Ureg*, char*, char*, int);
|
||||||
void setswapchan(Chan*);
|
|
||||||
void setupwatchpts(Proc*, Watchpt*, int);
|
void setupwatchpts(Proc*, Watchpt*, int);
|
||||||
char* skipslash(char*);
|
char* skipslash(char*);
|
||||||
void sleep(Rendez*, int(*)(void*), void*);
|
void sleep(Rendez*, int(*)(void*), void*);
|
||||||
|
@ -332,7 +331,6 @@ void srvrenameuser(char*, char*);
|
||||||
void shrrenameuser(char*, char*);
|
void shrrenameuser(char*, char*);
|
||||||
int swapcount(uintptr);
|
int swapcount(uintptr);
|
||||||
int swapfull(void);
|
int swapfull(void);
|
||||||
void swapinit(void);
|
|
||||||
void syscallfmt(ulong syscallno, uintptr pc, va_list list);
|
void syscallfmt(ulong syscallno, uintptr pc, va_list list);
|
||||||
void sysretfmt(ulong syscallno, va_list list, uintptr ret, uvlong start, uvlong stop);
|
void sysretfmt(ulong syscallno, va_list list, uintptr ret, uvlong start, uvlong stop);
|
||||||
void timeradd(Timer*);
|
void timeradd(Timer*);
|
||||||
|
|
|
@ -62,15 +62,15 @@ errstr.h: ../port/mkerrstr ../port/error.h
|
||||||
%.db: main.$O
|
%.db: main.$O
|
||||||
$CC -s$stem main.c | dbfmt > $stem.db
|
$CC -s$stem main.c | dbfmt > $stem.db
|
||||||
|
|
||||||
alloc.$O: /sys/include/pool.h
|
alloc.$O devswap.$O: /sys/include/pool.h
|
||||||
devmnt.$O: /sys/include/fcall.h
|
devmnt.$O: /sys/include/fcall.h
|
||||||
proc.$O proc.acid: errstr.h
|
proc.$O proc.acid: errstr.h
|
||||||
devroot.$O: errstr.h
|
devroot.$O: errstr.h
|
||||||
devaudio.$O: ../port/audioif.h
|
devaudio.$O: ../port/audioif.h
|
||||||
devaoe.$O: /$objtype/include/ureg.h
|
devaoe.$O: ../port/sd.h /$objtype/include/ureg.h
|
||||||
devfs.$O: /$objtype/include/ureg.h
|
devfs.$O: ../port/sd.h /$objtype/include/ureg.h
|
||||||
devsd.$O: /$objtype/include/ureg.h
|
devsd.$O: ../port/sd.h /$objtype/include/ureg.h
|
||||||
sdscsi.$O: /$objtype/include/ureg.h
|
sdscsi.$O: ../port/sd.h /$objtype/include/ureg.h
|
||||||
trap.$O: /$objtype/include/ureg.h
|
trap.$O: /$objtype/include/ureg.h
|
||||||
devproc.$O: /$objtype/include/ureg.h
|
devproc.$O: /$objtype/include/ureg.h
|
||||||
main.$O: init.h
|
main.$O: init.h
|
||||||
|
@ -87,3 +87,5 @@ unthwack.$O: ../port/thwack.h
|
||||||
devsdp.$O: ../port/thwack.h
|
devsdp.$O: ../port/thwack.h
|
||||||
devproc.$O sysproc.$O: /sys/include/tos.h
|
devproc.$O sysproc.$O: /sys/include/tos.h
|
||||||
devproc.$O edf.$O proc.$O: /sys/include/trace.h
|
devproc.$O edf.$O proc.$O: /sys/include/trace.h
|
||||||
|
devcons.$O: /sys/include/authsrv.h
|
||||||
|
devcap.$O devfs.$O devsdp.$O devssl.$O devtls.$O devswap.$O random.$O: /sys/include/libsec.h
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
env
|
env
|
||||||
flash
|
flash
|
||||||
pipe
|
pipe
|
||||||
|
|
|
@ -84,7 +84,6 @@ main(void)
|
||||||
links();
|
links();
|
||||||
chandevreset();
|
chandevreset();
|
||||||
pageinit();
|
pageinit();
|
||||||
swapinit();
|
|
||||||
sharedseginit();
|
sharedseginit();
|
||||||
fpsave(&initfp);
|
fpsave(&initfp);
|
||||||
initfp.fpscr = 0;
|
initfp.fpscr = 0;
|
||||||
|
|
|
@ -31,7 +31,6 @@ PORT=\
|
||||||
qlock.$O\
|
qlock.$O\
|
||||||
rdb.$O\
|
rdb.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
taslock.$O\
|
taslock.$O\
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
uart
|
uart
|
||||||
mnt
|
mnt
|
||||||
srv
|
srv
|
||||||
|
|
|
@ -192,8 +192,6 @@ main(void)
|
||||||
initseg();
|
initseg();
|
||||||
links();
|
links();
|
||||||
chandevreset();
|
chandevreset();
|
||||||
|
|
||||||
swapinit();
|
|
||||||
userinit();
|
userinit();
|
||||||
schedinit();
|
schedinit();
|
||||||
panic("schedinit returned");
|
panic("schedinit returned");
|
||||||
|
|
|
@ -38,7 +38,6 @@ PORT=\
|
||||||
rdb.$O\
|
rdb.$O\
|
||||||
rebootcmd.$O\
|
rebootcmd.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
syscallfmt.$O\
|
syscallfmt.$O\
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
|
|
|
@ -455,7 +455,6 @@ main(void)
|
||||||
// i8250console(); /* too early; see init0 */
|
// i8250console(); /* too early; see init0 */
|
||||||
|
|
||||||
pageinit(); /* prints "1020M memory: ⋯ */
|
pageinit(); /* prints "1020M memory: ⋯ */
|
||||||
swapinit();
|
|
||||||
userinit();
|
userinit();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -34,7 +34,6 @@ PORT=\
|
||||||
qio.$O\
|
qio.$O\
|
||||||
qlock.$O\
|
qlock.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
syscallfmt.$O\
|
syscallfmt.$O\
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
env
|
env
|
||||||
pipe
|
pipe
|
||||||
proc
|
proc
|
||||||
|
|
|
@ -103,8 +103,6 @@ main(void)
|
||||||
// conf.monitor = 1;
|
// conf.monitor = 1;
|
||||||
chandevreset();
|
chandevreset();
|
||||||
pageinit();
|
pageinit();
|
||||||
|
|
||||||
swapinit();
|
|
||||||
userinit();
|
userinit();
|
||||||
schedinit();
|
schedinit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ PORT=\
|
||||||
qlock.$O\
|
qlock.$O\
|
||||||
rebootcmd.$O\
|
rebootcmd.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
taslock.$O\
|
taslock.$O\
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
dev
|
dev
|
||||||
root netif
|
root netif
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
uart
|
uart
|
||||||
arch
|
arch
|
||||||
env
|
env
|
||||||
|
|
|
@ -393,7 +393,6 @@ main(void)
|
||||||
archinit();
|
archinit();
|
||||||
chandevreset();
|
chandevreset();
|
||||||
pageinit();
|
pageinit();
|
||||||
swapinit();
|
|
||||||
screeninit();
|
screeninit();
|
||||||
userinit();
|
userinit();
|
||||||
schedinit();
|
schedinit();
|
||||||
|
|
|
@ -31,7 +31,6 @@ PORT=\
|
||||||
qio.$O\
|
qio.$O\
|
||||||
qlock.$O\
|
qlock.$O\
|
||||||
segment.$O\
|
segment.$O\
|
||||||
swap.$O\
|
|
||||||
sysfile.$O\
|
sysfile.$O\
|
||||||
sysproc.$O\
|
sysproc.$O\
|
||||||
taslock.$O\
|
taslock.$O\
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
dev
|
dev
|
||||||
root
|
root
|
||||||
cons
|
cons
|
||||||
|
swap
|
||||||
arch
|
arch
|
||||||
uart
|
uart
|
||||||
mnt
|
mnt
|
||||||
|
|
Loading…
Reference in a new issue