Understand *_S variants: DIAGNOSTICS_S, DEV_{READ,WRITE,IOCTL}_S,
include grant id in DEV_REVIVE messages
This commit is contained in:
parent
3ca26c812d
commit
60bbcab13f
@ -9,6 +9,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <minix/type.h>
|
||||
#include <minix/safecopies.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "../../kernel/const.h"
|
||||
@ -83,33 +85,33 @@ message *m; /* notification message */
|
||||
/*===========================================================================*
|
||||
* do_diagnostics *
|
||||
*===========================================================================*/
|
||||
PUBLIC int do_diagnostics(message *m)
|
||||
PUBLIC int do_diagnostics(message *m, int safe)
|
||||
{
|
||||
/* The LOG server handles all diagnostic messages from servers and device
|
||||
* drivers. It forwards the message to the TTY driver to display it to the
|
||||
* user. It also saves a copy in a local buffer so that messages can be
|
||||
* reviewed at a later time.
|
||||
*/
|
||||
int proc_nr_e;
|
||||
vir_bytes src;
|
||||
int count;
|
||||
char c;
|
||||
int i = 0;
|
||||
int i = 0, offset = 0;
|
||||
static char diagbuf[10240];
|
||||
|
||||
/* Change SELF to actual process number. */
|
||||
if ((proc_nr_e = m->DIAG_ENDPT) == SELF)
|
||||
m->DIAG_ENDPT = proc_nr_e = m->m_source;
|
||||
|
||||
/* Now also make a copy for the private buffer at the LOG server, so
|
||||
/* Also make a copy for the private buffer at the LOG server, so
|
||||
* that the messages can be reviewed at a later time.
|
||||
*/
|
||||
src = (vir_bytes) m->DIAG_PRINT_BUF;
|
||||
src = (vir_bytes) m->DIAG_PRINT_BUF_G;
|
||||
count = m->DIAG_BUF_COUNT;
|
||||
while (count > 0 && i < sizeof(diagbuf)-1) {
|
||||
if (sys_datacopy(proc_nr_e, src, SELF, (vir_bytes) &c, 1) != OK)
|
||||
break; /* stop copying on error */
|
||||
src ++;
|
||||
int r;
|
||||
if(safe) {
|
||||
r = sys_safecopyfrom(m->m_source, src, offset, (vir_bytes) &c, 1, D);
|
||||
} else {
|
||||
r = sys_datacopy(m->m_source, src+offset, SELF, (vir_bytes) &c, 1);
|
||||
}
|
||||
if(r != OK) break;
|
||||
offset ++;
|
||||
count --;
|
||||
diagbuf[i++] = c;
|
||||
}
|
||||
|
@ -22,8 +22,7 @@ int c;
|
||||
|
||||
if ((c == 0 && buf_count > 0) || buf_count == sizeof(print_buf)) {
|
||||
m.DIAG_BUF_COUNT = buf_count;
|
||||
m.DIAG_PRINT_BUF = print_buf;
|
||||
m.DIAG_ENDPT = SELF;
|
||||
m.DIAG_PRINT_BUF_G = print_buf;
|
||||
m.m_type = DIAGNOSTICS; /* request TTY to output this buffer */
|
||||
_sendrec(TTY_PROC_NR, &m); /* if it fails, we give up */
|
||||
buf_count = 0; /* clear buffer for next batch */
|
||||
|
@ -26,21 +26,21 @@ PRIVATE int log_device = -1; /* current device */
|
||||
FORWARD _PROTOTYPE( char *log_name, (void) );
|
||||
FORWARD _PROTOTYPE( struct device *log_prepare, (int device) );
|
||||
FORWARD _PROTOTYPE( int log_transfer, (int proc_nr, int opcode, off_t position,
|
||||
iovec_t *iov, unsigned nr_req) );
|
||||
iovec_t *iov, unsigned nr_req, int safe) );
|
||||
FORWARD _PROTOTYPE( int log_do_open, (struct driver *dp, message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( int log_cancel, (struct driver *dp, message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( int log_select, (struct driver *dp, message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( void log_signal, (struct driver *dp, message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( int log_other, (struct driver *dp, message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( int log_other, (struct driver *dp, message *m_ptr, int) );
|
||||
FORWARD _PROTOTYPE( void log_geometry, (struct partition *entry) );
|
||||
FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count, int proc_nr, vir_bytes user_vir) );
|
||||
FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count, int proc_nr, vir_bytes user_vir, size_t, int safe) );
|
||||
|
||||
/* Entry points to this driver. */
|
||||
PRIVATE struct driver log_dtab = {
|
||||
log_name, /* current device's name */
|
||||
log_do_open, /* open or mount */
|
||||
do_nop, /* nothing on a close */
|
||||
do_nop, /* ioctl nop */
|
||||
nop_ioctl, /* ioctl nop */
|
||||
log_prepare, /* prepare for I/O on a given minor device */
|
||||
log_transfer, /* do the I/O */
|
||||
nop_cleanup, /* no need to clean up */
|
||||
@ -104,7 +104,8 @@ int device;
|
||||
* subwrite *
|
||||
*===========================================================================*/
|
||||
PRIVATE int
|
||||
subwrite(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
|
||||
subwrite(struct logdevice *log, int count, int proc_nr,
|
||||
vir_bytes user_vir, size_t offset, int safe)
|
||||
{
|
||||
char *buf;
|
||||
int r;
|
||||
@ -116,8 +117,15 @@ subwrite(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
|
||||
memcpy(buf, (char *) user_vir, count);
|
||||
}
|
||||
else {
|
||||
if((r=sys_vircopy(proc_nr,D,user_vir, SELF,D,(int)buf, count)) != OK)
|
||||
if(safe) {
|
||||
if((r=sys_safecopyfrom(proc_nr, user_vir, offset,
|
||||
(vir_bytes)buf, count, D)) != OK)
|
||||
return r;
|
||||
} else {
|
||||
if((r=sys_vircopy(proc_nr, D,
|
||||
user_vir + offset, SELF,D,(int)buf, count)) != OK)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
LOGINC(log->log_write, count);
|
||||
@ -135,7 +143,8 @@ subwrite(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
|
||||
* be revived.
|
||||
*/
|
||||
log->log_status = subread(log, log->log_iosize,
|
||||
log->log_proc_nr, log->log_user_vir);
|
||||
log->log_proc_nr, log->log_user_vir_g,
|
||||
log->log_user_vir_offset, log->log_safe);
|
||||
notify(log->log_source);
|
||||
log->log_revive_alerted = 1;
|
||||
}
|
||||
@ -174,10 +183,10 @@ log_append(char *buf, int count)
|
||||
if(count > LOG_SIZE) skip = count - LOG_SIZE;
|
||||
count -= skip;
|
||||
buf += skip;
|
||||
w = subwrite(&logdevices[0], count, SELF, (vir_bytes) buf);
|
||||
w = subwrite(&logdevices[0], count, SELF, (vir_bytes) buf,0,0);
|
||||
|
||||
if(w > 0 && w < count)
|
||||
subwrite(&logdevices[0], count-w, SELF, (vir_bytes) buf+w);
|
||||
subwrite(&logdevices[0], count-w, SELF, (vir_bytes) buf+w,0,0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -185,7 +194,8 @@ log_append(char *buf, int count)
|
||||
* subread *
|
||||
*===========================================================================*/
|
||||
PRIVATE int
|
||||
subread(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
|
||||
subread(struct logdevice *log, int count, int proc_nr,
|
||||
vir_bytes user_vir, size_t offset, int safe)
|
||||
{
|
||||
char *buf;
|
||||
int r;
|
||||
@ -195,8 +205,15 @@ subread(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
|
||||
count = LOG_SIZE - log->log_read;
|
||||
|
||||
buf = log->log_buffer + log->log_read;
|
||||
if((r=sys_vircopy(SELF,D,(int)buf,proc_nr,D,user_vir, count)) != OK)
|
||||
if(safe) {
|
||||
if((r=sys_safecopyto(proc_nr, user_vir, offset,
|
||||
(vir_bytes)buf, count, D)) != OK)
|
||||
return r;
|
||||
} else {
|
||||
if((r=sys_vircopy(SELF,D,(int)buf,
|
||||
proc_nr, safe ? GRANT_SEG : D, user_vir + offset, count)) != OK)
|
||||
return r;
|
||||
}
|
||||
|
||||
LOGINC(log->log_read, count);
|
||||
log->log_size -= count;
|
||||
@ -207,12 +224,13 @@ subread(struct logdevice *log, int count, int proc_nr, vir_bytes user_vir)
|
||||
/*===========================================================================*
|
||||
* log_transfer *
|
||||
*===========================================================================*/
|
||||
PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req)
|
||||
PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req, safe)
|
||||
int proc_nr; /* process doing the request */
|
||||
int opcode; /* DEV_GATHER or DEV_SCATTER */
|
||||
off_t position; /* offset on device to read or write */
|
||||
iovec_t *iov; /* pointer to read or write request vector */
|
||||
unsigned nr_req; /* length of request vector */
|
||||
int safe; /* safe copies? */
|
||||
{
|
||||
/* Read or write one the driver's minor devices. */
|
||||
unsigned count;
|
||||
@ -222,6 +240,7 @@ unsigned nr_req; /* length of request vector */
|
||||
int accumulated_read = 0;
|
||||
struct logdevice *log;
|
||||
static int f;
|
||||
size_t vir_offset = 0;
|
||||
|
||||
if(log_device < 0 || log_device >= NR_DEVS)
|
||||
return EIO;
|
||||
@ -253,8 +272,10 @@ unsigned nr_req; /* length of request vector */
|
||||
/* No data available; let caller block. */
|
||||
log->log_proc_nr = proc_nr;
|
||||
log->log_iosize = count;
|
||||
log->log_user_vir = user_vir;
|
||||
log->log_user_vir_g = user_vir;
|
||||
log->log_user_vir_offset = 0;
|
||||
log->log_revive_alerted = 0;
|
||||
log->log_safe = safe;
|
||||
|
||||
/* Device_caller is a global in drivers library. */
|
||||
log->log_source = device_caller;
|
||||
@ -264,13 +285,13 @@ unsigned nr_req; /* length of request vector */
|
||||
#endif
|
||||
return(SUSPEND);
|
||||
}
|
||||
count = subread(log, count, proc_nr, user_vir);
|
||||
count = subread(log, count, proc_nr, user_vir, vir_offset, safe);
|
||||
if(count < 0) {
|
||||
return count;
|
||||
}
|
||||
accumulated_read += count;
|
||||
} else {
|
||||
count = subwrite(log, count, proc_nr, user_vir);
|
||||
count = subwrite(log, count, proc_nr, user_vir, vir_offset, safe);
|
||||
if(count < 0)
|
||||
return count;
|
||||
}
|
||||
@ -281,8 +302,8 @@ unsigned nr_req; /* length of request vector */
|
||||
}
|
||||
|
||||
/* Book the number of bytes transferred. */
|
||||
iov->iov_addr += count;
|
||||
if ((iov->iov_size -= count) == 0) { iov++; nr_req--; }
|
||||
vir_offset += count;
|
||||
if ((iov->iov_size -= count) == 0) { iov++; nr_req--; vir_offset = 0; }
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
@ -401,9 +422,10 @@ message *m_ptr;
|
||||
/*============================================================================*
|
||||
* log_other *
|
||||
*============================================================================*/
|
||||
PRIVATE int log_other(dp, m_ptr)
|
||||
PRIVATE int log_other(dp, m_ptr, safe)
|
||||
struct driver *dp;
|
||||
message *m_ptr;
|
||||
int safe;
|
||||
{
|
||||
int r;
|
||||
|
||||
@ -412,7 +434,11 @@ message *m_ptr;
|
||||
*/
|
||||
switch(m_ptr->m_type) {
|
||||
case DIAGNOSTICS: {
|
||||
r = do_diagnostics(m_ptr);
|
||||
r = do_diagnostics(m_ptr, 0);
|
||||
break;
|
||||
}
|
||||
case DIAGNOSTICS_S: {
|
||||
r = do_diagnostics(m_ptr, 1);
|
||||
break;
|
||||
}
|
||||
case DEV_STATUS: {
|
||||
|
@ -23,7 +23,8 @@ struct logdevice {
|
||||
log_iosize,
|
||||
log_revive_alerted,
|
||||
log_status; /* proc that is blocking on read */
|
||||
vir_bytes log_user_vir;
|
||||
vir_bytes log_user_vir_g, log_user_vir_offset;
|
||||
int log_safe;
|
||||
#endif
|
||||
int log_selected, log_select_proc,
|
||||
log_select_alerted, log_select_ready_ops;
|
||||
@ -32,6 +33,6 @@ struct logdevice {
|
||||
/* Function prototypes. */
|
||||
_PROTOTYPE( void kputc, (int c) );
|
||||
_PROTOTYPE( int do_new_kmess, (message *m) );
|
||||
_PROTOTYPE( int do_diagnostics, (message *m) );
|
||||
_PROTOTYPE( int do_diagnostics, (message *m, int safe) );
|
||||
_PROTOTYPE( void log_append, (char *buf, int len) );
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user