Update to reflect major changes in vinum kernel module
This commit is contained in:
parent
0834a1f2db
commit
52e80fad69
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=42947
@ -35,7 +35,7 @@
|
||||
* otherwise) arising in any way out of the use of this software, even if
|
||||
* advised of the possibility of such damage.
|
||||
*
|
||||
* $Id: list.c,v 1.6 1998/12/28 16:32:39 peter Exp $
|
||||
* $Id: list.c,v 1.17 1999/01/17 02:58:44 grog Exp grog $
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
@ -350,56 +350,6 @@ vinum_lpi(int plexno, int recurse)
|
||||
get_volume_info(&vol, plex.volno);
|
||||
printf("\t\tPart of volume %s\n", vol.name);
|
||||
}
|
||||
if (plex.state == plex_reviving) {
|
||||
printf("\t\tRevive pointer:\t\t%s (%d%%)\n",
|
||||
roughlength(plex.revived << DEV_BSHIFT, 0),
|
||||
(int) (((u_int64_t) (plex.revived * 100)) / plex.length));
|
||||
printf("\t\tRevive blocksize:\t%s\n"
|
||||
"\t\tRevive interval:\t%10d seconds\n",
|
||||
roughlength(plex.revive_blocksize, 0),
|
||||
plex.revive_interval);
|
||||
}
|
||||
if (Verbose) { /* show the unmapped and defective parts */
|
||||
int re; /* freelist entry */
|
||||
struct plexregion region;
|
||||
struct rerq { /* request to pass to ioctl */
|
||||
int plexno; /* plex for the request */
|
||||
int re; /* region */
|
||||
} *rerq = (struct rerq *) ®ion;
|
||||
|
||||
if (plex.unmapped_regions) {
|
||||
printf("\t\tPlex contains %d unmapped regions:\n\t\t Offset\t Size\n",
|
||||
plex.unmapped_regions);
|
||||
for (re = 0; re < plex.unmapped_regions; re++) {
|
||||
rerq->plexno = plex.plexno;
|
||||
rerq->re = re;
|
||||
if (ioctl(superdev, VINUM_GETUNMAPPED, ®ion) < 0) {
|
||||
fprintf(stderr,
|
||||
"Can't get unmapped region %d: %s\n",
|
||||
re,
|
||||
strerror(errno));
|
||||
longjmp(command_fail, -1);
|
||||
}
|
||||
printf("\t\t%9qd\t%9qd\n", region.offset, region.length);
|
||||
}
|
||||
}
|
||||
if (plex.defective_regions) {
|
||||
printf("\t\tPlex contains %d defective regions:\n\t\t Offset\t Size\n",
|
||||
plex.defective_regions);
|
||||
for (re = 0; re < plex.defective_regions; re++) {
|
||||
rerq->plexno = plex.plexno;
|
||||
rerq->re = re;
|
||||
if (ioctl(superdev, VINUM_GETDEFECTIVE, ®ion) < 0) {
|
||||
fprintf(stderr,
|
||||
"Can't get defective region %d: %s\n",
|
||||
re,
|
||||
strerror(errno));
|
||||
longjmp(command_fail, -1);
|
||||
}
|
||||
printf("\t\t%9qd\t%9qd\n", region.offset, region.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char *org = ""; /* organization */
|
||||
|
||||
@ -438,12 +388,15 @@ vinum_lpi(int plexno, int recurse)
|
||||
if (plex.writes != 0)
|
||||
printf("\t\tAverage write:\t%16qd bytes\n",
|
||||
plex.bytes_written / plex.writes);
|
||||
if ((plex.organization == plex_striped)
|
||||
|| (plex.organization == plex_raid5))
|
||||
printf("\t\tMultiblock:\t%16qd\n"
|
||||
"\t\tMultistripe:\t%16qd\n",
|
||||
if (((plex.reads + plex.writes) > 0)
|
||||
&& ((plex.organization == plex_striped)
|
||||
|| (plex.organization == plex_raid5)))
|
||||
printf("\t\tMultiblock:\t%16qd (%d%%)\n"
|
||||
"\t\tMultistripe:\t%16qd (%d%%)\n",
|
||||
plex.multiblock,
|
||||
plex.multistripe);
|
||||
(int) (plex.multiblock * 100 / (plex.reads + plex.writes)),
|
||||
plex.multistripe,
|
||||
(int) (plex.multistripe * 100 / (plex.reads + plex.writes)));
|
||||
}
|
||||
if (plex.subdisks > 0) {
|
||||
int sdno;
|
||||
@ -512,10 +465,16 @@ vinum_lsi(int sdno, int recurse)
|
||||
if (sd.plexno >= 0) {
|
||||
get_plex_info(&plex, sd.plexno);
|
||||
printf("\t\tPlex %s", plex.name);
|
||||
if (plex.organization == plex_concat)
|
||||
printf(" at offset %qd\n", (long long) sd.plexoffset * DEV_BSIZE);
|
||||
else
|
||||
printf("\n");
|
||||
printf(" at offset %qd\n", (long long) sd.plexoffset * DEV_BSIZE);
|
||||
}
|
||||
if (sd.state == sd_reviving) {
|
||||
printf("\t\tRevive pointer:\t\t%s (%d%%)\n",
|
||||
roughlength(sd.revived << DEV_BSHIFT, 0),
|
||||
(int) (((u_int64_t) (sd.revived * 100)) / sd.sectors));
|
||||
printf("\t\tRevive blocksize:\t%s\n"
|
||||
"\t\tRevive interval:\t%10d seconds\n",
|
||||
roughlength(sd.revive_blocksize, 0),
|
||||
sd.revive_interval);
|
||||
}
|
||||
} else {
|
||||
printf("S %-21s State: %s\tPO: %s ",
|
||||
@ -633,7 +592,7 @@ vinum_info(int argc, char *argv[], char *argv0[])
|
||||
#if VINUMDEBUG
|
||||
struct rqinfo rq;
|
||||
#endif
|
||||
|
||||
|
||||
if (ioctl(superdev, VINUM_GETCONFIG, &vinum_conf) < 0) {
|
||||
perror("Can't get vinum config");
|
||||
return;
|
||||
@ -668,7 +627,7 @@ vinum_info(int argc, char *argv[], char *argv0[])
|
||||
}
|
||||
#if VINUMDEBUG
|
||||
if (Verbose) {
|
||||
printf("\nTime\t\t Event\t Buf\tSD\tDev\tOffset\tBytes\tDoffset\tGoffset\n\n");
|
||||
printf("\nTime\t\t Event\t Buf\tDev\tOffset\t\tBytes\tSD\tSDoff\tDoffset\tGoffset\n\n");
|
||||
for (i = RQINFO_SIZE - 1; i >= 0; i--) { /* go through the request list in order */
|
||||
*((int *) &rq) = i;
|
||||
if (ioctl(superdev, VINUM_RQINFO, &rq) < 0) {
|
||||
@ -680,75 +639,77 @@ vinum_info(int argc, char *argv[], char *argv0[])
|
||||
break;
|
||||
|
||||
case loginfo_user_bp: /* this is the bp when strategy is called */
|
||||
printf("%s 1VS %s %p\t\t0x%x\t0x%x\t%ld\n",
|
||||
printf("%s 1VS %s %p\t0x%x\t0x%-9x\t%ld\n",
|
||||
timetext(&rq.timestamp),
|
||||
rq.info.b.b_flags & B_READ ? "Read " : "Write",
|
||||
rq.bp,
|
||||
/* no subdisk */
|
||||
rq.info.b.b_dev,
|
||||
rq.info.b.b_blkno,
|
||||
rq.info.b.b_bcount);
|
||||
break;
|
||||
|
||||
case loginfo_user_bpl: /* and this is the bp at launch time */
|
||||
printf("%s 2LR %s %p\t\t0x%x\t0x%x\t%ld\n",
|
||||
printf("%s 2LR %s %p\t0x%x\t0x%-9x\t%ld\n",
|
||||
timetext(&rq.timestamp),
|
||||
rq.info.b.b_flags & B_READ ? "Read " : "Write",
|
||||
rq.bp,
|
||||
/* no subdisk */
|
||||
rq.info.b.b_dev,
|
||||
rq.info.b.b_blkno,
|
||||
rq.info.b.b_bcount);
|
||||
break;
|
||||
|
||||
case loginfo_rqe: /* user RQE */
|
||||
printf("%s 3RQ %s %p\t%d\t0x%x\t0x%x\t%ld\t%x\t%x\n",
|
||||
printf("%s 3RQ %s %p\t0x%x\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n",
|
||||
timetext(&rq.timestamp),
|
||||
rq.info.rqe.b.b_flags & B_READ ? "Read " : "Write",
|
||||
rq.bp,
|
||||
rq.info.rqe.sdno,
|
||||
rq.info.rqe.b.b_dev,
|
||||
rq.info.rqe.b.b_blkno,
|
||||
rq.info.rqe.b.b_bcount,
|
||||
rq.info.rqe.sdno,
|
||||
rq.info.rqe.sdoffset,
|
||||
rq.info.rqe.dataoffset,
|
||||
rq.info.rqe.groupoffset);
|
||||
break;
|
||||
|
||||
case loginfo_iodone: /* iodone called */
|
||||
printf("%s 4DN %s %p\t%d\t0x%x\t0x%x\t%ld\t%x\t%x\n",
|
||||
printf("%s 4DN %s %p\t0x%x\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n",
|
||||
timetext(&rq.timestamp),
|
||||
rq.info.rqe.b.b_flags & B_READ ? "Read " : "Write",
|
||||
rq.bp,
|
||||
rq.info.rqe.sdno,
|
||||
rq.info.rqe.b.b_dev,
|
||||
rq.info.rqe.b.b_blkno,
|
||||
rq.info.rqe.b.b_bcount,
|
||||
rq.info.rqe.sdno,
|
||||
rq.info.rqe.sdoffset,
|
||||
rq.info.rqe.dataoffset,
|
||||
rq.info.rqe.groupoffset);
|
||||
break;
|
||||
|
||||
case loginfo_raid5_data: /* RAID-5 write data block */
|
||||
printf("%s 5RD %s %p\t%d\t0x%x\t0x%x\t%ld\t%x\t%x\n",
|
||||
printf("%s 5RD %s %p\t0x%x\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n",
|
||||
timetext(&rq.timestamp),
|
||||
rq.info.rqe.b.b_flags & B_READ ? "Read " : "Write",
|
||||
rq.bp,
|
||||
rq.info.rqe.sdno,
|
||||
rq.info.rqe.b.b_dev,
|
||||
rq.info.rqe.b.b_blkno,
|
||||
rq.info.rqe.b.b_bcount,
|
||||
rq.info.rqe.sdno,
|
||||
rq.info.rqe.sdoffset,
|
||||
rq.info.rqe.dataoffset,
|
||||
rq.info.rqe.groupoffset);
|
||||
break;
|
||||
|
||||
case loginfo_raid5_parity: /* RAID-5 write parity block */
|
||||
printf("%s 6RP %s %p\t%d\t0x%x\t0x%x\t%ld\t%x\t%x\n",
|
||||
printf("%s 6RP %s %p\t0x%x\t0x%-9x\t%ld\t%d\t%x\t%x\t%x\n",
|
||||
timetext(&rq.timestamp),
|
||||
rq.info.rqe.b.b_flags & B_READ ? "Read " : "Write",
|
||||
rq.bp,
|
||||
rq.info.rqe.sdno,
|
||||
rq.info.rqe.b.b_dev,
|
||||
rq.info.rqe.b.b_blkno,
|
||||
rq.info.rqe.b.b_bcount,
|
||||
rq.info.rqe.sdno,
|
||||
rq.info.rqe.sdoffset,
|
||||
rq.info.rqe.dataoffset,
|
||||
rq.info.rqe.groupoffset);
|
||||
}
|
||||
@ -820,7 +781,7 @@ vinum_printconfig(int argc, char *argv[], char *argv0[])
|
||||
plex_state(plex.state),
|
||||
plex_org(plex.organization));
|
||||
if ((plex.organization == plex_striped)
|
||||
) {
|
||||
|| (plex.organization == plex_raid5)) {
|
||||
fprintf(of, "%db ", (int) plex.stripesize);
|
||||
}
|
||||
if (plex.volno >= 0) { /* we have a volume */
|
||||
|
110
sbin/vinum/v.c
110
sbin/vinum/v.c
@ -36,7 +36,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* $Id: v.c,v 1.2 1998/12/28 16:32:39 peter Exp $ */
|
||||
/* $Id: v.c,v 1.24 1999/01/17 02:53:38 grog Exp grog $ */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -57,6 +57,9 @@
|
||||
#include <sys/wait.h>
|
||||
#include <readline/history.h>
|
||||
#include <readline/readline.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
FILE *cf; /* config file handle */
|
||||
|
||||
@ -88,6 +91,8 @@ struct drive drive;
|
||||
jmp_buf command_fail; /* return on a failed command */
|
||||
int superdev; /* vinum super device */
|
||||
|
||||
void start_daemon(void);
|
||||
|
||||
#define ofs(x) ((void *) (& ((struct confdata *) 0)->x)) /* offset of x in struct confdata */
|
||||
|
||||
/* create description-file
|
||||
@ -112,6 +117,20 @@ int tokens; /* number of tokens */
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
#if RAID5
|
||||
#define VINUMMOD "Vinum"
|
||||
#else
|
||||
#define VINUMMOD "vinum"
|
||||
#endif
|
||||
|
||||
if (modfind(VINUMMOD) < 0) {
|
||||
/* need to load the vinum module */
|
||||
if (kldload(VINUMMOD) < 0 || modfind(VINUMMOD) < 0) {
|
||||
perror("vinum kernel module not available");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
superdev = open(VINUM_SUPERDEV_NAME, O_RDWR); /* open it */
|
||||
|
||||
if (superdev < 0) { /* no go */
|
||||
@ -122,6 +141,10 @@ main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* Check if the dæmon is running. If not, start it in the
|
||||
* background */
|
||||
start_daemon();
|
||||
|
||||
if (argc > 1) { /* we have a command on the line */
|
||||
if (setjmp(command_fail) != 0) /* long jumped out */
|
||||
return -1;
|
||||
@ -156,6 +179,13 @@ main(int argc, char *argv[])
|
||||
return 0; /* normal completion */
|
||||
}
|
||||
|
||||
/* stop the hard way */
|
||||
void
|
||||
vinum_quit(int argc, char *argv[], char *argv0[])
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#define FUNKEY(x) { kw_##x, &vinum_##x } /* create pair "kw_foo", vinum_foo */
|
||||
|
||||
struct funkey {
|
||||
@ -191,6 +221,10 @@ struct funkey {
|
||||
FUNKEY(printconfig),
|
||||
FUNKEY(start),
|
||||
FUNKEY(stop),
|
||||
FUNKEY(makedev),
|
||||
FUNKEY(help),
|
||||
FUNKEY(quit),
|
||||
FUNKEY(setdaemon),
|
||||
FUNKEY(resetstats)
|
||||
};
|
||||
|
||||
@ -348,6 +382,7 @@ make_devices(void)
|
||||
system("mkdir -p " VINUM_DIR "/drive " /* and make them again */
|
||||
VINUM_DIR "/plex "
|
||||
VINUM_DIR "/sd "
|
||||
VINUM_DIR "/rsd "
|
||||
VINUM_DIR "/vol "
|
||||
VINUM_DIR "/rvol "
|
||||
VINUM_RDIR);
|
||||
@ -440,9 +475,15 @@ make_devices(void)
|
||||
if (mknod(filename, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IFBLK, sddev) < 0)
|
||||
fprintf(stderr, "Can't create %s: %s\n", filename, strerror(errno));
|
||||
|
||||
/* And /dev/vinum/sd/<sd> */
|
||||
/* /dev/vinum/sd/<sd> */
|
||||
sprintf(filename, VINUM_DIR "/sd/%s", sd.name);
|
||||
if (mknod(filename, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IFBLK, sddev) < 0)
|
||||
fprintf(stderr, "Can't create %s: %s\n", filename, strerror(errno));
|
||||
|
||||
/* And /dev/vinum/rsd/<sd> */
|
||||
sprintf(filename, VINUM_DIR "/rsd/%s", sd.name);
|
||||
sddev = VINUMCDEV(volno, plexno, sdno, VINUM_SD_TYPE);
|
||||
if (mknod(filename, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IFCHR, sddev) < 0)
|
||||
fprintf(stderr, "Can't create %s: %s\n", filename, strerror(errno));
|
||||
}
|
||||
}
|
||||
@ -461,6 +502,13 @@ make_devices(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* command line interface for the 'makedev' command */
|
||||
void
|
||||
vinum_makedev(int argc, char *argv[], char *arg0[])
|
||||
{
|
||||
make_devices();
|
||||
}
|
||||
|
||||
/* Find the object "name". Return object type at type,
|
||||
* and the index as the return value.
|
||||
* If not found, return -1 and invalid_object.
|
||||
@ -516,13 +564,13 @@ find_object(const char *name, enum objecttype *type)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Continue reviving a plex in the background */
|
||||
/* Continue reviving a subdisk in the background */
|
||||
void
|
||||
continue_revive(int plexno)
|
||||
continue_revive(int sdno)
|
||||
{
|
||||
struct plex plex;
|
||||
struct sd sd;
|
||||
pid_t pid;
|
||||
get_plex_info(&plex, plexno);
|
||||
get_sd_info(&sd, sdno);
|
||||
|
||||
#if VINUMDEBUG
|
||||
if (debug)
|
||||
@ -537,27 +585,59 @@ continue_revive(int plexno)
|
||||
struct vinum_ioctl_msg *message = (struct vinum_ioctl_msg *) &reply;
|
||||
|
||||
openlog("vinum", LOG_CONS | LOG_PERROR | LOG_PID, LOG_KERN);
|
||||
syslog(LOG_INFO | LOG_KERN, "reviving plex %s", plex.name);
|
||||
syslog(LOG_INFO | LOG_KERN, "reviving %s", sd.name);
|
||||
|
||||
for (reply.error = EAGAIN; reply.error == EAGAIN;) {
|
||||
message->index = plexno; /* pass plex number */
|
||||
message->type = plex_object; /* and type of object */
|
||||
message->index = sdno; /* pass sd number */
|
||||
message->type = sd_object; /* and type of object */
|
||||
message->state = object_up;
|
||||
ioctl(superdev, VINUM_SETSTATE, message);
|
||||
}
|
||||
if (reply.error) {
|
||||
syslog(LOG_ERR | LOG_KERN,
|
||||
"can't revive plex %s: %s",
|
||||
plex.name,
|
||||
"can't revive %s: %s",
|
||||
sd.name,
|
||||
reply.msg[0] ? reply.msg : strerror(reply.error));
|
||||
exit(1);
|
||||
} else {
|
||||
get_plex_info(&plex, plexno); /* update the info */
|
||||
syslog(LOG_INFO | LOG_KERN, "plex %s is %s", plex.name, plex_state(plex.state));
|
||||
get_sd_info(&sd, sdno); /* update the info */
|
||||
syslog(LOG_INFO | LOG_KERN, "%s is %s", sd.name, sd_state(sd.state));
|
||||
exit(0);
|
||||
}
|
||||
} else if (pid < 0) /* couldn't fork? */
|
||||
fprintf(stderr, "Can't continue reviving %s: %s\n", plex.name, strerror(errno));
|
||||
fprintf(stderr, "Can't continue reviving %s: %s\n", sd.name, strerror(errno));
|
||||
else
|
||||
printf("Reviving %s in the background\n", plex.name);
|
||||
printf("Reviving %s in the background\n", sd.name);
|
||||
}
|
||||
|
||||
/* Check if the daemon is running,
|
||||
* start it if it isn't. The check itself
|
||||
* could take a while, so we do it as a separate
|
||||
* process, which will become the daemon if one isn't
|
||||
* running already */
|
||||
void
|
||||
start_daemon(void)
|
||||
{
|
||||
int pid;
|
||||
int status;
|
||||
int error;
|
||||
|
||||
pid = (int) fork();
|
||||
|
||||
if (pid == 0) { /* We're the child, do the work */
|
||||
error = daemon(0, 0); /* this will fork again, but who's counting? */
|
||||
if (error != 0) {
|
||||
fprintf(stderr, "Can't start daemon: %s (%d)\n", strerror(errno), errno);
|
||||
exit(1);
|
||||
}
|
||||
setproctitle("Vinum daemon"); /* show what we're doing */
|
||||
status = ioctl(superdev, VINUM_FINDDAEMON, NULL);
|
||||
if (status != 0) { /* no daemon, */
|
||||
ioctl(superdev, VINUM_DAEMON, &verbose); /* we should hang here */
|
||||
syslog(LOG_ERR | LOG_KERN, "%s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
exit(0); /* when told to die */
|
||||
} else if (pid < 0) /* couldn't fork */
|
||||
printf("Can't fork to check daemon\n");
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Nan Yang Computer Services Limited
|
||||
* All rights reserved.
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998
|
||||
* Nan Yang Computer Services Limited. All rights reserved.
|
||||
*
|
||||
* This software is distributed under the so-called ``Berkeley
|
||||
* License'':
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -12,28 +15,30 @@
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed for the NetBSD Project
|
||||
* by Jason R. Thorpe.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
* This product includes software developed by Nan Yang Computer
|
||||
* Services Limited.
|
||||
* 4. Neither the name of the Company nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* This software is provided ``as is'', and any express or implied
|
||||
* warranties, including, but not limited to, the implied warranties of
|
||||
* merchantability and fitness for a particular purpose are disclaimed.
|
||||
* In no event shall the company or contributors be liable for any
|
||||
* direct, indirect, incidental, special, exemplary, or consequential
|
||||
* damages (including, but not limited to, procurement of substitute
|
||||
* goods or services; loss of use, data, or profits; or business
|
||||
* interruption) however caused and on any theory of liability, whether
|
||||
* in contract, strict liability, or tort (including negligence or
|
||||
* otherwise) arising in any way out of the use of this software, even if
|
||||
* advised of the possibility of such damage.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id: vext.h,v 1.1.1.1 1998/09/16 05:57:36 grog Exp $ */
|
||||
/* $Id: vext.h,v 1.10 1999/01/12 04:31:45 grog Exp grog $ */
|
||||
|
||||
#define MAXARGS 64 /* maximum number of args on a line */
|
||||
#define PLEXINITSIZE MAXPHYS /* block size to write when initializing */
|
||||
#define PLEXINITSIZE 61440 /* this is what the system does somewhere */
|
||||
|
||||
enum {
|
||||
KILOBYTE = 1024,
|
||||
@ -61,6 +66,10 @@ void vinum_resetconfig(int argc, char *argv[], char *arg0[]);
|
||||
void vinum_start(int argc, char *argv[], char *arg0[]);
|
||||
void continue_revive(int plexno);
|
||||
void vinum_stop(int argc, char *argv[], char *arg0[]);
|
||||
void vinum_makedev(int argc, char *argv[], char *arg0[]);
|
||||
void vinum_help(int argc, char *argv[], char *arg0[]);
|
||||
void vinum_quit(int argc, char *argv[], char *arg0[]);
|
||||
void vinum_setdaemon(int argc, char *argv[], char *arg0[]);
|
||||
void reset_volume_stats(int volno, int recurse);
|
||||
void reset_plex_stats(int plexno, int recurse);
|
||||
void reset_sd_stats(int sdno, int recurse);
|
||||
@ -77,6 +86,7 @@ void vinum_ld(int argc, char *argv[], char *arg0[]);
|
||||
void vinum_ls(int argc, char *argv[], char *arg0[]);
|
||||
void vinum_lp(int argc, char *argv[], char *arg0[]);
|
||||
void vinum_lv(int argc, char *argv[], char *arg0[]);
|
||||
void start_daemon(void);
|
||||
#ifdef VINUMDEBUG
|
||||
void vinum_debug(int argc, char *argv[], char *arg0[]);
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" Hey, Emacs, edit this file in -*- nroff-fill -*- mode
|
||||
.\"
|
||||
.Dd 11 July 1998
|
||||
.Dd 15 January 1999
|
||||
.Dt vinum 8
|
||||
.Os FreeBSD
|
||||
.Sh NAME
|
||||
@ -30,9 +30,14 @@ Attach a plex to a volume, or a subdisk to a plex.
|
||||
.in +1i
|
||||
Cause the volume manager to enter the kernel debugger.
|
||||
.in
|
||||
.Cd debug
|
||||
.Ar flags
|
||||
.in +1i
|
||||
Set debugging flags.
|
||||
.in
|
||||
.Cd detach
|
||||
.Op Ar plex | subdisk
|
||||
.in +1
|
||||
.in +1i
|
||||
Detach a plex or subdisk from the volume or plex to which it is attached.
|
||||
.in
|
||||
.Cd info
|
||||
@ -112,12 +117,21 @@ List information about volumes
|
||||
Remake the device nodes in
|
||||
.Ar /dev/vinum .
|
||||
.in
|
||||
.Cd quit
|
||||
.in +1i
|
||||
Exit the
|
||||
.Nm
|
||||
program when running in interactive mode. Normally this would be done by
|
||||
entering the
|
||||
.Ar EOF
|
||||
character.
|
||||
.in
|
||||
.Cd read
|
||||
.Ar disk-partition
|
||||
.Ar disk Op disk...
|
||||
.in +1i
|
||||
Read the
|
||||
.Nm
|
||||
configuration from the specified disk partition.
|
||||
configuration from the specified disks.
|
||||
.in
|
||||
.Cd rename Op Fl r
|
||||
.Ar [ drive | subdisk | plex | volume ]
|
||||
@ -164,6 +178,11 @@ XXX
|
||||
Set the state of the object to \fIstate\fP\|
|
||||
.in
|
||||
..
|
||||
.Cd setdaemon
|
||||
.Op value
|
||||
.in +1i
|
||||
Set dæmon configuration.
|
||||
.in
|
||||
.Cd start
|
||||
.Op volume | plex | subdisk
|
||||
.in +1i
|
||||
@ -184,7 +203,10 @@ for more information about the volume manager.
|
||||
.Xr vinum 8
|
||||
is designed either for interactive use, when started without a command, or to
|
||||
execute a single command if the command is supplied as arguments to
|
||||
.Nm vinum.
|
||||
.Nm vinum .
|
||||
In interactive mode,
|
||||
.Nm
|
||||
maintains a command line history.
|
||||
.Ss OPTIONS
|
||||
.Nm
|
||||
commands may optionally be followed by an option. Any of the following options
|
||||
@ -245,7 +267,8 @@ commands perform the following functions:
|
||||
.Bl -hang
|
||||
.It Nm attach Ar plex Ar volume
|
||||
.Op Nm rename
|
||||
.sp -1v
|
||||
.if n .sp -1v
|
||||
.if t .sp -.6v
|
||||
.It Nm attach Ar subdisk Ar plex Ar [offset]
|
||||
.Op Nm rename
|
||||
.sp
|
||||
@ -300,13 +323,49 @@ CONFIGURATION FILE below for more information.
|
||||
.Ar debug
|
||||
is used to enter the remote kernel debugger. It is only activated if
|
||||
.Nm
|
||||
is built with the DEBUG option. This option will stop the execution of the
|
||||
operating system until the kernel debugger is exited. If there is no remote
|
||||
is built with the
|
||||
.Ar VINUMDEBUG
|
||||
option. This option will stop the execution of the operating system until the
|
||||
kernel debugger is exited. If remote debugging is set and there is no remote
|
||||
connection for a kernel debugger, it will be necessary to reset the system and
|
||||
reboot in order to leave the debugger.
|
||||
.It Nm debug
|
||||
.Ar flags
|
||||
.Pp
|
||||
Set a bit mask of internal debugging flags. These will change without warning
|
||||
as the product matures; to be certain, read the header file
|
||||
.Pa sys/dev/vinumvar.h .
|
||||
The bit mask is composed of the following values:
|
||||
.Bl -hang
|
||||
.It DEBUG_ADDRESSES (1)
|
||||
.br
|
||||
Show buffer information during requests
|
||||
.It DEBUG_NUMOUTPUT (2)
|
||||
.br
|
||||
Show the value of
|
||||
.Dv vp->v_numoutput.
|
||||
.It DEBUG_RESID (4)
|
||||
.br
|
||||
Go into debugger in
|
||||
.Fd complete_rqe.
|
||||
.It DEBUG_LASTREQS (8)
|
||||
.br
|
||||
Keep a circular buffer of last requests.
|
||||
.It DEBUG_REVIVECONFLICT (16)
|
||||
.br
|
||||
Print info about revive conflicts.
|
||||
.It DEBUG_REMOTEGDB (256)
|
||||
.br
|
||||
Go into remote
|
||||
.Ic gdb
|
||||
when the
|
||||
.Nm debug
|
||||
command is issued.
|
||||
.El
|
||||
.It Nm detach Op Fl f
|
||||
.Ar plex
|
||||
.sp -1v
|
||||
.if n .sp -1v
|
||||
.if t .sp -.6v
|
||||
.It Nm detach Op Fl f
|
||||
.Ar subdisk
|
||||
.sp
|
||||
@ -327,7 +386,7 @@ the subdisk is marked absent, and can later be replaced with the
|
||||
.Nm attach
|
||||
command.
|
||||
.It Nm info
|
||||
.Pp
|
||||
.br
|
||||
.Nm
|
||||
.Ar info
|
||||
displays information about
|
||||
@ -335,6 +394,117 @@ displays information about
|
||||
memory usage. This is intended primarily for debugging. With the
|
||||
.Fl v
|
||||
option, it will give detailed information about the memory areas in use.
|
||||
.Pp
|
||||
With the
|
||||
.Fl V
|
||||
option,
|
||||
.Ar info
|
||||
displays information about the last up to 64 I/O requests handled by the
|
||||
.Nm
|
||||
driver. This information is only collected if debug flag 8 is set. The format
|
||||
looks like:
|
||||
.Pp
|
||||
.Bd -literal
|
||||
vinum -> info -V
|
||||
Flags: 0x200 1 opens
|
||||
Total of 38 blocks malloced, total memory: 16460
|
||||
Maximum allocs: 56, malloc table at 0xf0f72dbc
|
||||
|
||||
Time Event Buf Dev Offset Bytes SD SDoff Doffset Goffset
|
||||
|
||||
14:40:00.637758 1VS Write 0xf2361f40 0x5b03 0x10 16384
|
||||
14:40:00.639280 2LR Write 0xf2361f40 0x5b03 0x10 16384
|
||||
14:40:00.639294 3RQ Read 0xf2361f40 0x427 0x104109 8192 19 0 0 0
|
||||
14:40:00.639455 3RQ Read 0xf2361f40 0x417 0xd2109 8192 17 0 0 0
|
||||
14:40:00.639529 3RQ Read 0xf2361f40 0x40f 0x6e109 8192 16 0 0 0
|
||||
14:40:00.652978 4DN Read 0xf2361f40 0x427 0x104109 8192 19 0 0 0
|
||||
14:40:00.667040 4DN Read 0xf2361f40 0x40f 0x6e109 8192 16 0 0 0
|
||||
14:40:00.668556 4DN Read 0xf2361f40 0x417 0xd2109 8192 17 0 0 0
|
||||
14:40:00.669777 6RP Write 0xf2361f40 0x427 0x104109 8192 19 0 0 0
|
||||
14:40:00.685547 4DN Write 0xf2361f40 0x427 0x104109 8192 19 0 0 0
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Ar Buf
|
||||
field always contains the address of the user buffer header. This can be used
|
||||
to identify the requests associated with a user request, though this is not 100%
|
||||
reliable: theoretically two requests in sequence could use the same buffer
|
||||
header, though this is not common. The beginning of a request can be identified
|
||||
by the event
|
||||
.Ar 1VS .
|
||||
The example above shows the requests involved in a single user request.
|
||||
.Pp
|
||||
The
|
||||
.Ar Event
|
||||
field contains information related to the sequence of events in the request
|
||||
chain. The digit
|
||||
.Ar 1
|
||||
to
|
||||
.Ar 6
|
||||
indicates the approximate sequence of events, and the two-letter abbreviation is
|
||||
a mnemonic for the location
|
||||
.Bl -hang
|
||||
.It 1VS
|
||||
(vinumstrategy) shows information about the user request on entry to
|
||||
.Fd vinumstrategy .
|
||||
The device number is the
|
||||
.Nm
|
||||
device, and offset and length are the user parameters. This is always the
|
||||
beginning of a request sequence.
|
||||
.It 2LR
|
||||
(launch_requests) shows the user request just prior to launching the low-level
|
||||
.Nm
|
||||
requests in the function
|
||||
.Fd launch_requests.
|
||||
The parameters should be the same as in the
|
||||
.Ar 1VS
|
||||
information.
|
||||
.Pp
|
||||
In the following requests,
|
||||
.Ar Dev
|
||||
is the device number of the associated disk partition,
|
||||
.Ar Offset
|
||||
is the offset from the beginning of the partition,
|
||||
.Ar SD
|
||||
is the subdisk index in
|
||||
.Dv vinum_conf ,
|
||||
.Ar SDoff
|
||||
is the offset from the beginning of the subdisk,
|
||||
.Ar Doffset
|
||||
is the offset of the associated data request, and
|
||||
.Ar Goffset
|
||||
is the offset of the associated group request, where applicable.
|
||||
.It 3RQ
|
||||
(request) shows one of possibly several low-level
|
||||
.Nm
|
||||
requests which are launched to satisfy the high-level request. This information
|
||||
is also logged in
|
||||
.Fd launch_requests.
|
||||
.It 4DN
|
||||
(done) is called from
|
||||
.Fd complete_rqe,
|
||||
showing the completion of a request. This completion should match a request
|
||||
launched either at stage
|
||||
.Ar 4DN
|
||||
from
|
||||
.Fd launch_requests,
|
||||
or from
|
||||
.Fd complete_raid5_write
|
||||
at stage
|
||||
.Ar 5RD
|
||||
or
|
||||
.Ar 6RP .
|
||||
.It 5RD
|
||||
(RAID-5 data) is called from
|
||||
.Fd complete_raid5_write
|
||||
and represents the data written to a RAID-5 data stripe after calculating
|
||||
parity.
|
||||
.It 6RP
|
||||
(RAID-5 parity) is called from
|
||||
.Fd complete_raid5_write
|
||||
and represents the data written to a RAID-5 parity stripe after calculating
|
||||
parity.
|
||||
.El
|
||||
.\" XXX
|
||||
.It Nm init Ar plex
|
||||
.Pp
|
||||
@ -374,33 +544,38 @@ This command is deprecated.
|
||||
.Op Fl r
|
||||
.Op Fl V
|
||||
.Op volume | plex | subdisk
|
||||
.sp -1
|
||||
.if n .sp -1v
|
||||
.if t .sp -.6v
|
||||
.It Nm l
|
||||
.Op Fl r
|
||||
.Op Fl V
|
||||
.Op volume | plex | subdisk
|
||||
.sp -1
|
||||
.if n .sp -1v
|
||||
.if t .sp -.6v
|
||||
.It Nm ld
|
||||
.Op Fl r
|
||||
.Op Fl s
|
||||
.Op Fl v
|
||||
.Op Fl V
|
||||
.Op volume
|
||||
.sp -1
|
||||
.if n .sp -1v
|
||||
.if t .sp -.6v
|
||||
.It Nm ls
|
||||
.Op Fl r
|
||||
.Op Fl s
|
||||
.Op Fl v
|
||||
.Op Fl V
|
||||
.Op subdisk
|
||||
.sp -1
|
||||
.if n .sp -1v
|
||||
.if t .sp -.6v
|
||||
.It Nm lp
|
||||
.Op Fl r
|
||||
.Op Fl s
|
||||
.Op Fl v
|
||||
.Op Fl V
|
||||
.Op plex
|
||||
.sp -1
|
||||
.if n .sp -1v
|
||||
.if t .sp -.6v
|
||||
.It Nm lv
|
||||
.Op Fl r
|
||||
.Op Fl s
|
||||
@ -447,18 +622,34 @@ command removes the directory /dev/vinum and recreates it with device nodes
|
||||
which reflect the current configuration. This command is not intended for
|
||||
general use, and is provided for emergency use only.
|
||||
.Pp
|
||||
.It Nm quit
|
||||
Exit the
|
||||
.Nm
|
||||
program when running in interactive mode. Normally this would be done by
|
||||
entering the
|
||||
.Ar EOF
|
||||
character.
|
||||
.It Nm read
|
||||
.Ar disk-partition
|
||||
.Ar disk Op disk...
|
||||
.Pp
|
||||
The
|
||||
.Nm read
|
||||
command reads a previously created
|
||||
.Nm
|
||||
configuration from the specified disk partition.
|
||||
command scans the specified disks for
|
||||
.Nm
|
||||
partitions containing previously created configuration information. It reads
|
||||
the configuration in order from the most recently updated to least recently
|
||||
updated configuration. This is the normal method used to start
|
||||
.Nm vinum .
|
||||
.Nm
|
||||
maintains an up-to-date copy of all configuration information on each disk
|
||||
partition. You can specify any of the partitions in a configuration as the
|
||||
partition. You must specify all of the partitions in a configuration as the
|
||||
parameter to this command.
|
||||
.Nm
|
||||
.Nm read
|
||||
will accept the names of non-Vinum partitions, so you can specify all partitions
|
||||
upon which a
|
||||
.Nm
|
||||
partition might be resident to this command.
|
||||
.It Nm rename
|
||||
.Op Fl r
|
||||
.Ar [ drive | subdisk | plex | volume ]
|
||||
@ -568,6 +759,15 @@ care: it can result in total loss of data on a volume.
|
||||
.\"XXX
|
||||
.Nm This command has not yet been implemented.
|
||||
..
|
||||
.It Nm setdaemon
|
||||
.Op value
|
||||
.Pp
|
||||
.Nm setdaemon
|
||||
sets a variable bitmask for the
|
||||
.Nm
|
||||
dæmon. This command is temporary and will be replaced. Currently, the bit mask
|
||||
may contain the bits 1 (log every action to syslog) and 4 (don't update
|
||||
configuration). Option bit 4 can be useful for error recovery.
|
||||
.It Nm start
|
||||
.Op volume | plex | subdisk
|
||||
.Pp
|
||||
@ -1019,14 +1219,62 @@ commands, though especially
|
||||
.Nm resetconfig
|
||||
outputs all sort of dire warnings. Don't use these commands unless you have a
|
||||
good reason to do so.
|
||||
.It
|
||||
Some state transitions are not very intuitive. In fact, it's not clear whether
|
||||
this is a bug or a feature. If you find that you can't start an object in some
|
||||
strange state, such as a
|
||||
.Ar reborn
|
||||
subdisk, try first to get it into
|
||||
.Ar stopped
|
||||
state, with the
|
||||
.Nm stop
|
||||
or
|
||||
.Nm stop Ar -f
|
||||
commands. If that works, you should then be able to start it. If you find
|
||||
that this is the only way to get out of a position where easier methods fail,
|
||||
please report the situation.
|
||||
.It
|
||||
If you build the kernel module with the
|
||||
.Ar -DVINUMDEBUG
|
||||
option, you must also build
|
||||
.Nm vinum(8)
|
||||
with the
|
||||
.Ar -DVINUMDEBUG
|
||||
option, since the size of some data objects used by both components depends on
|
||||
this option. If you don't do so, commands will fail with the message
|
||||
.Ar Invalid argument ,
|
||||
and a console message will be logged such as
|
||||
.Pp
|
||||
.Bd -literal
|
||||
vinumioctl: invalid ioctl from process 247 (vinum): c0e44642
|
||||
.Ed
|
||||
.Pp
|
||||
This error may also occur if you use old versions of kld or userland program.
|
||||
.El
|
||||
.Sh BUGS
|
||||
.Bl -enum
|
||||
.It
|
||||
.Nm
|
||||
is currently in beta test. Many bugs can be expected. The configuration
|
||||
mechanism is not yet fully functional. If you have difficulties, please look at
|
||||
http://www.lemis.com/vinum_beta.html and
|
||||
http://www.lemis.com/vinum_debugging.html before reporting problems.
|
||||
.Pp
|
||||
.It
|
||||
It is possible to unload
|
||||
.Nm
|
||||
with the
|
||||
.Nm kldunload
|
||||
command. This is buggy, and the only reason it is present at all is to make it
|
||||
easier for people testing the system: the alternative is a reboot. It works
|
||||
about 80% of the time: expect about one panic every five unloads.
|
||||
.It
|
||||
It is possible to configure
|
||||
.Nm
|
||||
statically, but it has never been tested in this form. Don't even bother to
|
||||
report the problem if you have trouble with a static
|
||||
.Nm
|
||||
pseudo-device.
|
||||
.It
|
||||
This man page tickles a bug in the
|
||||
.Ar doc
|
||||
man page macros: depending on your screen size, you may get the error message
|
||||
@ -1037,6 +1285,7 @@ warning: page 6: table text block will not fit on one page
|
||||
This will be fixed in a later rewrite of the page, when the
|
||||
.Nm tbl
|
||||
macros will be removed.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Ar /dev/vinum
|
||||
- directory with device nodes for
|
||||
|
Loading…
Reference in New Issue
Block a user