netbsd fsck driver import

. fsck driver parses /etc/fstab and invokes sub-fscks
	. further simplifies fs handling in rc
This commit is contained in:
Ben Gras 2011-12-22 22:51:26 +01:00
parent 6b6d114a21
commit 4d4057d8a2
46 changed files with 5470 additions and 66 deletions

View file

@ -60,6 +60,7 @@ elf-libraries: includes
commands: includes libraries
$(MAKE) -C commands all
$(MAKE) -C bin all
$(MAKE) -C sbin all
$(MAKE) -C usr.bin all
$(MAKE) -C libexec all
$(MAKE) -C usr.sbin all
@ -68,6 +69,7 @@ dep-all:
$(MAKE) CC=cc -C boot dependall
$(MAKE) -C commands dependall
$(MAKE) -C bin dependall
$(MAKE) -C sbin dependall
$(MAKE) -C usr.bin dependall
$(MAKE) -C libexec dependall
$(MAKE) -C usr.sbin dependall
@ -85,6 +87,7 @@ all:
$(MAKE) CC=cc -C boot all
$(MAKE) -C commands all
$(MAKE) -C bin all
$(MAKE) -C sbin all
$(MAKE) -C usr.bin all
$(MAKE) -C libexec all
$(MAKE) -C usr.sbin all
@ -96,6 +99,7 @@ install:
$(MAKE) -C man install makedb
$(MAKE) -C commands install
$(MAKE) -C bin install
$(MAKE) -C sbin install
$(MAKE) -C usr.bin install
$(MAKE) -C usr.sbin install
$(MAKE) -C servers install
@ -106,6 +110,7 @@ clean: mkfiles
$(MAKE) -C boot clean
$(MAKE) -C commands clean
$(MAKE) -C bin clean
$(MAKE) -C sbin clean
$(MAKE) -C usr.bin clean
$(MAKE) -C libexec clean
$(MAKE) -C usr.sbin clean
@ -118,6 +123,7 @@ cleandepend: mkfiles
$(MAKE) -C boot cleandepend
$(MAKE) -C commands cleandepend
$(MAKE) -C bin cleandepend
$(MAKE) -C sbin cleandepend
$(MAKE) -C usr.bin cleandepend
$(MAKE) -C libexec cleandepend
$(MAKE) -C usr.sbin cleandepend

View file

@ -1,6 +1,7 @@
FSCK= ${NETBSDSRCDIR}/sbin/fsck
PROG= fsck.mfs
SRCS= fsck.c
CPPFLAGS+= -I${MINIXSRCDIR}/servers
CPPFLAGS+= -I${MINIXSRCDIR}/servers -I${FSCK}
BINDIR= /sbin
MAN=

View file

@ -58,6 +58,8 @@
#include <tools.h>
#include <dirent.h>
#include "exitvalues.h"
#undef N_DATA
unsigned int fs_version = 2, block_size = 0;
@ -238,7 +240,7 @@ void fatal(s)
char *s;
{
printf("%s\nfatal\n", s);
exit(-1);
exit(FSCK_EXIT_CHECK_FAILED);
}
/* Test for end of line. */
@ -267,7 +269,7 @@ char *question;
return(1);
}
fflush(stdout);
if ((c = answerchar = getchar()) == 'q' || c == 'Q') exit(1);
if ((c = answerchar = getchar()) == 'q' || c == 'Q') exit(FSCK_EXIT_CHECK_FAILED);
if(c == 'A') { automatic = 1; c = 'y'; }
while (!eoln(c)) c = getchar();
yes = !(answerchar == 'n' || answerchar == 'N');
@ -551,7 +553,7 @@ void lsuper()
if(sb.s_flags & MFSFLAG_CLEAN) printf("CLEAN "); else printf("DIRTY ");
printf("\n");
} while (yes("Do you want to try again"));
if (repair) exit(0);
if (repair) exit(FSCK_EXIT_OK);
}
/* Get the super block from either disk or user. Do some initial checks. */
@ -1589,6 +1591,7 @@ char *f, **clist, **ilist, **zlist;
/* If we were told to repair the FS, and the user never stopped us from
* doing it, and the FS wasn't marked clean, we can mark the FS as clean.
* If we were stopped from repairing, tell user about it.
*/
if(repair && !(sb.s_flags & MFSFLAG_CLEAN)) {
if(notrepaired) {
@ -1609,13 +1612,14 @@ int argc;
char **argv;
{
register char **clist = 0, **ilist = 0, **zlist = 0;
int badflag = 0;
register devgiven = 0;
register char *arg;
if ((1 << BITSHIFT) != 8 * sizeof(bitchunk_t)) {
printf("Fsck was compiled with the wrong BITSHIFT!\n");
exit(1);
exit(FSCK_EXIT_CHECK_FAILED);
}
sync();
@ -1641,6 +1645,7 @@ char **argv;
case 'f': break;
default:
printf("%s: unknown flag '%s'\n", prog, arg);
badflag = 1;
}
else {
chkdev(arg, clist, ilist, zlist);
@ -1649,9 +1654,9 @@ char **argv;
zlist = 0;
devgiven = 1;
}
if (!devgiven) {
if (!devgiven || badflag) {
printf("Usage: fsck [-dyfpacilrsz] file\n");
exit(1);
exit(FSCK_EXIT_USAGE);
}
return(0);
}

View file

@ -381,36 +381,20 @@ printf("testb = 0x%x 0x%x 0x%x\n", testb[0], testb[1], testb[block_size-1]);
block_t sizeup(device)
char *device;
{
int fd;
struct partition entry;
u64_t bytes, resize;
block_t d;
struct stat st;
unsigned int rem;
u64_t resize;
u32_t rem;
if ((fd = open(device, O_RDONLY)) == -1) {
if (errno != ENOENT)
perror("sizeup open");
if(minix_sizeup(device, &bytes) < 0) {
perror("sizeup");
return 0;
}
if (ioctl(fd, DIOCGETP, &entry) == -1) {
perror("sizeup ioctl");
if(fstat(fd, &st) < 0) {
perror("fstat");
entry.size = cvu64(0);
} else {
fprintf(stderr, "used fstat instead\n");
entry.size = cvu64(st.st_size);
}
}
close(fd);
d = div64u(entry.size, block_size);
rem = rem64u(entry.size, block_size);
d = div64u(bytes, block_size);
rem = rem64u(bytes, block_size);
resize = add64u(mul64u(d, block_size), rem);
if(cmp64(resize, entry.size) != 0) {
if(cmp64(resize, bytes) != 0) {
d = ULONG_MAX;
fprintf(stderr, "mkfs: truncating FS at %lu blocks\n", d);
}

View file

@ -4,5 +4,6 @@
INCS+= archtypes.h bios.h cmos.h cpu.h diskparm.h fpu.h int86.h \
interrupt.h memory.h multiboot.h partition.h \
pci.h pci_amd.h pci_intel.h pci_sis.h pci_via.h \
ports.h stackframe.h vm.h elf.h elf_machdep.h
ports.h stackframe.h vm.h elf.h elf_machdep.h mutex.h \
disklabel.h

View file

@ -0,0 +1,75 @@
/* $NetBSD: disklabel.h,v 1.16 2011/08/30 12:39:55 bouyer Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 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 by Christopher G. Demetriou.
* 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 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.
*/
#ifndef _I386_DISKLABEL_H_
#define _I386_DISKLABEL_H_
#define LABELUSESMBR 1 /* use MBR partitionning */
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
#define OLDMAXPARTITIONS 8 /* number of partitions before 1.6 */
#define RAW_PART 3 /* raw partition: XX?d (XXX) */
/*
* We use the highest bit of the minor number for the partition number.
* This maintains backward compatibility with device nodes created before
* MAXPARTITIONS was increased.
*/
#define __I386_MAXDISKS ((1 << 20) / MAXPARTITIONS)
#define DISKUNIT(dev) ((minor(dev) / OLDMAXPARTITIONS) % __I386_MAXDISKS)
#define DISKPART(dev) ((minor(dev) % OLDMAXPARTITIONS) + \
((minor(dev) / (__I386_MAXDISKS * OLDMAXPARTITIONS)) * OLDMAXPARTITIONS))
#define DISKMINOR(unit, part) \
(((unit) * OLDMAXPARTITIONS) + ((part) % OLDMAXPARTITIONS) + \
((part) / OLDMAXPARTITIONS) * (__I386_MAXDISKS * OLDMAXPARTITIONS))
/* Pull in MBR partition definitions. */
#if HAVE_NBTOOL_CONFIG_H
#include <nbinclude/sys/bootblock.h>
#else
#include <sys/bootblock.h>
#endif /* HAVE_NBTOOL_CONFIG_H */
#ifndef __ASSEMBLER__
#if HAVE_NBTOOL_CONFIG_H
#include <nbinclude/sys/dkbad.h>
#else
#include <sys/dkbad.h>
#endif /* HAVE_NBTOOL_CONFIG_H */
struct cpu_disklabel {
#define __HAVE_DISKLABEL_DKBAD
struct dkbad bad;
};
#endif
#endif /* _I386_DISKLABEL_H_ */

View file

@ -0,0 +1,3 @@
/* $NetBSD: mutex.h,v 1.2 2007/02/09 21:55:05 ad Exp $ */
#include <x86/mutex.h>

View file

@ -5,5 +5,7 @@
INCS+= elf32.h elf64.h elf_common.h elf_generic.h \
ioc_block.h ioc_fbd.h ioc_file.h ioc_tape.h ioc_disk.h \
ioc_memory.h ioc_sound.h ioc_tty.h \
kbdio.h mtio.h svrctl.h video.h vm.h procfs.h elf_core.h exec_elf.h
kbdio.h mtio.h svrctl.h video.h vm.h procfs.h elf_core.h exec_elf.h \
disk.h dkio.h ioccom.h mutex.h iostat.h disklabel.h bootblock.h \
dkbad.h

File diff suppressed because it is too large Load diff

538
common/include/sys/disk.h Normal file
View file

@ -0,0 +1,538 @@
/* $NetBSD: disk.h,v 1.55 2011/11/13 22:07:00 christos Exp $ */
/*-
* Copyright (c) 1996, 1997, 2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION 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.
*/
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratories.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University 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 BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
*
* from: Header: disk.h,v 1.5 92/11/19 04:33:03 torek Exp (LBL)
*
* @(#)disk.h 8.2 (Berkeley) 1/9/95
*/
#ifndef _SYS_DISK_H_
#define _SYS_DISK_H_
/*
* Disk device structures.
*/
#ifdef _KERNEL
#include <sys/device.h>
#endif
#include <sys/dkio.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <sys/mutex.h>
#include <sys/iostat.h>
#include <prop/proplib.h>
struct buf;
struct disk;
struct disklabel;
struct cpu_disklabel;
struct lwp;
struct vnode;
/*
* Disk information dictionary.
*
* This contains general infomation for disk devices.
*
* <dict>
* <key>type</key>
* <string>...</string>
* <key>geometry</key>
* <dict>
* <!-- See below for disk geometry dictionary
* contents. -->
* </dict>
*
* <!-- optional information -->
* <key>rpm</key>
* <integer>...</integer>
* <key>sector-interleave</key>
* <integer>...</integer>
* <key>track-skew</key>
* <integer>...</integer>
* <key>cylinder-skew</key>
* <integer>...</integer>
* <key>head-switch-usecs</key>
* <integer>...</integer>
* <key>track-seek-usecs</key>
* <integer>...</integer>
* <key>removable</key>
* <false/>
* <key>ecc</key>
* <false/>
* <key>bad-sector-forwarding</key>
* <true/>
* <key>ramdisk</key>
* <false/>
* <key>back-to-back-transfers</key>
* <true/>
*
* <!-- additional information for SMD drives -->
* <key>smd-skip-sectoring</key>
* <false/>
* <!-- XXX better names for these properties -->
* <key>smd-mindist</key>
* <integer>...</integer>
* <key>smd-maxdist</key>
* <integer>...</integer>
* <key>smd-sdist</key>
* <integer>...</integer>
*
* <!-- additional information for ST506 drives -->
* <!-- XXX better names for these properties -->
* <key>st506-precompcyl</key>
* <integer>...</integer>
* <key>st506-gap3</key>
* <integer>...</integer>
*
* <!-- additional information for ATA drives -->
* <!-- XXX -->
*
* <!-- additional information for SCSI drives -->
* <!-- XXX -->
* </dict>
*/
/*
* dkwedge_info:
*
* Information needed to configure (or query configuration of) a
* disk wedge.
*/
struct dkwedge_info {
char dkw_devname[16];/* device-style name (e.g. "dk0") */
uint8_t dkw_wname[128]; /* wedge name (Unicode, UTF-8) */
char dkw_parent[16]; /* parent disk device name */
daddr_t dkw_offset; /* LBA offset of wedge in parent */
uint64_t dkw_size; /* size of wedge in blocks */
char dkw_ptype[32]; /* partition type string */
};
/*
* dkwedge_list:
*
* Structure used to query a list of wedges.
*/
struct dkwedge_list {
void *dkwl_buf; /* storage for dkwedge_info array */
size_t dkwl_bufsize; /* size of that buffer */
u_int dkwl_nwedges; /* total number of wedges */
u_int dkwl_ncopied; /* number actually copied */
};
#ifdef _KERNEL
/*
* dkwedge_discovery_method:
*
* Structure used to describe partition map parsing schemes
* used for wedge autodiscovery.
*/
struct dkwedge_discovery_method {
/* link in wedge driver's list */
LIST_ENTRY(dkwedge_discovery_method) ddm_list;
const char *ddm_name; /* name of this method */
int ddm_priority; /* search priority */
int (*ddm_discover)(struct disk *, struct vnode *);
};
#define DKWEDGE_DISCOVERY_METHOD_DECL(name, prio, discover) \
static struct dkwedge_discovery_method name ## _ddm = { \
{ NULL, NULL }, \
#name, \
prio, \
discover \
}; \
__link_set_add_data(dkwedge_methods, name ## _ddm)
#endif /* _KERNEL */
/* Some common partition types */
#define DKW_PTYPE_UNKNOWN ""
#define DKW_PTYPE_UNUSED "unused"
#define DKW_PTYPE_SWAP "swap"
#define DKW_PTYPE_V6 "v6"
#define DKW_PTYPE_V7 "v7"
#define DKW_PTYPE_SYSV "sysv"
#define DKW_PTYPE_V71K "v71k"
#define DKW_PTYPE_V8 "v8"
#define DKW_PTYPE_FFS "ffs"
#define DKW_PTYPE_FAT "msdos"
#define DKW_PTYPE_LFS "lfs"
#define DKW_PTYPE_OTHER "other"
#define DKW_PTYPE_HPFS "hpfs"
#define DKW_PTYPE_ISO9660 "cd9660"
#define DKW_PTYPE_BOOT "boot"
#define DKW_PTYPE_AMIGADOS "ados"
#define DKW_PTYPE_HFS "hfs"
#define DKW_PTYPE_FILECORE "filecore"
#define DKW_PTYPE_EXT2FS "ext2fs"
#define DKW_PTYPE_NTFS "ntfs"
#define DKW_PTYPE_RAIDFRAME "raidframe"
#define DKW_PTYPE_CCD "ccd"
#define DKW_PTYPE_JFS2 "jfs2"
#define DKW_PTYPE_APPLEUFS "appleufs"
#define DKW_PTYPE_VINUM "vinum"
#define DKW_PTYPE_UDF "udf"
#define DKW_PTYPE_APPLEHFS "hfs"
#define DKW_PTYPE_SYSVBFS "sysvbfs"
#define DKW_PTYPE_EFS "efs"
#define DKW_PTYPE_NILFS "nilfs"
#define DKW_PTYPE_CGD "cgd"
/*
* Disk geometry dictionary.
*
* NOTE: Not all geometry information is relevant for every kind of disk.
*
* <dict>
* <key>sectors-per-unit</key>
* <integer>...</integer>
* <key>sector-size</key>
* <integer>...</integer>
* <key>sectors-per-track</key>
* <integer>...</integer>
* <key>tracks-per-cylinder</key>
* <integer>...</integer>
* <key>cylinders-per-unit</key>
* <integer>...</integer>
* <key>physical-cylinders-per-unit</key>
* <integer>...</integer>
* <key>spare-sectors-per-track</key>
* <integer>...</integer>
* <key>spare-sectors-per-cylinder</key>
* <integer>...</integer>
* <key>alternative-cylinders</key>
* <integer>...</integer>
* </dict>
* NOTE: Not all geometry information is relevant for every kind of disk.
*/
struct disk_geom {
int64_t dg_secperunit; /* # of data sectors per unit */
uint32_t dg_secsize; /* # of bytes per sector */
uint32_t dg_nsectors; /* # of data sectors per track */
uint32_t dg_ntracks; /* # of tracks per cylinder */
uint32_t dg_ncylinders; /* # of data cylinders per unit */
uint32_t dg_secpercyl; /* # of data sectors per cylinder */
uint32_t dg_pcylinders; /* # of physical cylinders per unit */
/*
* Spares (bad sector replacements) below are not counted in
* dg_nsectors or dg_secpercyl. Spare sectors are assumed to
* be physical sectors which occupy space at the end of each
* track and/or cylinder.
*/
uint32_t dg_sparespertrack;
uint32_t dg_sparespercyl;
/*
* Alternative cylinders include maintenance, replacement,
* configuration description areas, etc.
*/
uint32_t dg_acylinders;
};
/*
* Disk partition dictionary.
*
* A partition is represented as a dictionary containing generic partition
* properties (such as starting block and block count), as well as information
* that is specific to individual partition map formats.
*
* <dict>
* <key>start-block</key>
* <integer>...</integer>
* <key>block-count</key>
* <integer>...</integer>
* <!-- DKW_PTYPE strings ("" or missing if unknown) -->
* <key>type</type>
* <string>...</string>
* <!-- optional -->
* <key>name</key>
* <string>...</string>
*
* <!-- these are valid for GPT partition maps -->
* <key>gpt-type-guid</key>
* <string>...</string>
* <key>gpt-partition-guid</key>
* <string>...</string>
* <key>gpt-platform-required</key>
* <false/>
*
* <!-- these are valid for 4.4BSD partition maps -->
* <key>bsd44-partition-type</key>
* <integer>...</integer>
* <key>bsd44-fs-fragment-size</key>
* <integer>...</integer>
* <key>bsd44-iso9660-session-offset</key>
* <integer>...</integer>
* <key>bsd44-ffs-cylinders-per-group</key>
* <integer>...</integer>
* <key>bsd44-lfs-segment-shift</key>
* <integer>...</integer>
*
* <!-- these are valid for NeXT partition maps -->
* <key>next-block-size</key>
* <integer>...</integer>
* <key>next-fs-fragment-size</key>
* <integer>...</integer>
* <key>next-fs-optimization</key>
* <string>...</string> <!-- "space" or "time" -->
* <key>next-fs-cylinders-per-group</key>
* <integer>...</integer>
* <key>next-bytes-per-inode-density</key>
* <integer>...</integer>
* <key>next-minfree-percentage</key>
* <integer>...</integer>
* <key>next-run-newfs-during-init</key>
* <false/>
* <key>next-mount-point</key>
* <string>...</string>
* <key>next-automount</key>
* <true/>
* <key>next-partition-type</key>
* <string>...</string>
*
* <!-- these are valid for MBR partition maps -->
* <key>mbr-start-head</key>
* <integer>...</integer>
* <key>mbr-start-sector</key>
* <integer>...</integer>
* <key>mbr-start-cylinder</key>
* <integer>...</integer>
* <key>mbr-partition-type</key>
* <integer>...</integer>
* <key>mbr-end-head</key>
* <integer>...</integer>
* <key>mbr-end-sector</key>
* <integer>...</integer>
* <key>mbr-end-cylinder</key>
* <integer>...</integer>
* <key>mbr-active-partition</key>
* <false/>
*
* <!-- these are valid for Apple partition maps -->
* <key>apple-partition-type</key>
* <string>...</string>
* <!-- XXX What else do we need? wrstuden? -->
*
* <!-- these are valid for RISCiX partition maps -->
* <key>riscix-partition-type</key>
* <integer>...</integer>
*
* <!-- these are valid for MIPS/SGI partition maps -->
* <key>mips-partition-type</key>
* <integer>...</integer>
*
* <!-- SunOS 4 partition maps have no specific
* additional information. Note, however,
* that SunOS 4 partitions must begin on
* cylinder boundaries. -->
*
* <!-- XXX Need Amiga partition map info -->
*
* <!-- these are valid for VTOC partition maps -->
* <key>vtoc-tag</key>
* <integer>...</integer>
* <key>vtoc-unmount</key>
* <false/>
* <key>vtoc-read-only</key>
* <false/>
* <!-- XXX is this really part of the partition info? -->
* <key>vtoc-timestamp</key>
* <integer>...</integer>
*
* <!-- mvme68k partition maps use 4.4BSD partition
* info stuffed into two different areas of the
* disk information label recognized by BUG. -->
*
* <!-- XXX What else? -->
* </dict>
*/
struct disk {
TAILQ_ENTRY(disk) dk_link; /* link in global disklist */
const char *dk_name; /* disk name */
prop_dictionary_t dk_info; /* reference to disk-info dictionary */
int dk_bopenmask; /* block devices open */
int dk_copenmask; /* character devices open */
int dk_openmask; /* composite (bopen|copen) */
int dk_state; /* label state ### */
int dk_blkshift; /* shift to convert DEV_BSIZE to blks */
int dk_byteshift; /* shift to convert bytes to blks */
/*
* Metrics data; note that some metrics may have no meaning
* on certain types of disks.
*/
struct io_stats *dk_stats;
const struct dkdriver *dk_driver; /* pointer to driver */
/*
* Information required to be the parent of a disk wedge.
*/
kmutex_t dk_rawlock; /* lock on these fields */
u_int dk_rawopens; /* # of openes of rawvp */
struct vnode *dk_rawvp; /* vnode for the RAW_PART bdev */
kmutex_t dk_openlock; /* lock on these and openmask */
u_int dk_nwedges; /* # of configured wedges */
/* all wedges on this disk */
LIST_HEAD(, dkwedge_softc) dk_wedges;
/*
* Disk label information. Storage for the in-core disk label
* must be dynamically allocated, otherwise the size of this
* structure becomes machine-dependent.
*/
daddr_t dk_labelsector; /* sector containing label */
struct disklabel *dk_label; /* label */
struct cpu_disklabel *dk_cpulabel;
};
struct dkdriver {
void (*d_strategy)(struct buf *);
void (*d_minphys)(struct buf *);
#ifdef notyet
int (*d_open)(dev_t, int, int, struct proc *);
int (*d_close)(dev_t, int, int, struct proc *);
int (*d_ioctl)(dev_t, u_long, void *, int, struct proc *);
int (*d_dump)(dev_t);
void (*d_start)(struct buf *, daddr_t);
int (*d_mklabel)(struct disk *);
#endif
};
/* states */
#define DK_CLOSED 0 /* drive is closed */
#define DK_WANTOPEN 1 /* drive being opened */
#define DK_WANTOPENRAW 2 /* drive being opened */
#define DK_RDLABEL 3 /* label being read */
#define DK_OPEN 4 /* label read, drive open */
#define DK_OPENRAW 5 /* open without label */
/*
* Bad sector lists per fixed disk
*/
struct disk_badsectors {
SLIST_ENTRY(disk_badsectors) dbs_next;
daddr_t dbs_min; /* min. sector number */
daddr_t dbs_max; /* max. sector number */
struct timeval dbs_failedat; /* first failure at */
};
struct disk_badsecinfo {
uint32_t dbsi_bufsize; /* size of region pointed to */
uint32_t dbsi_skip; /* how many to skip past */
uint32_t dbsi_copied; /* how many got copied back */
uint32_t dbsi_left; /* remaining to copy */
void * dbsi_buffer; /* region to copy disk_badsectors to */
};
#define DK_STRATEGYNAMELEN 32
struct disk_strategy {
char dks_name[DK_STRATEGYNAMELEN]; /* name of strategy */
char *dks_param; /* notyet; should be NULL */
size_t dks_paramlen; /* notyet; should be 0 */
};
#define DK_BSIZE2BLKSHIFT(b) ((ffs((b) / DEV_BSIZE)) - 1)
#define DK_BSIZE2BYTESHIFT(b) (ffs((b)) - 1)
#ifdef _KERNEL
extern int disk_count; /* number of disks in global disklist */
struct proc;
void disk_attach(struct disk *);
int disk_begindetach(struct disk *, int (*)(device_t), device_t, int);
void disk_detach(struct disk *);
void disk_init(struct disk *, const char *, const struct dkdriver *);
void disk_destroy(struct disk *);
void disk_busy(struct disk *);
void disk_unbusy(struct disk *, long, int);
bool disk_isbusy(struct disk *);
void disk_blocksize(struct disk *, int);
struct disk *disk_find(const char *);
int disk_ioctl(struct disk *, u_long, void *, int, struct lwp *);
void dkwedge_init(void);
int dkwedge_add(struct dkwedge_info *);
int dkwedge_del(struct dkwedge_info *);
void dkwedge_delall(struct disk *);
int dkwedge_list(struct disk *, struct dkwedge_list *, struct lwp *);
void dkwedge_discover(struct disk *);
void dkwedge_set_bootwedge(device_t, daddr_t, uint64_t);
int dkwedge_read(struct disk *, struct vnode *, daddr_t, void *, size_t);
device_t dkwedge_find_by_wname(const char *);
void dkwedge_print_wnames(void);
#endif
#endif /* _SYS_DISK_H_ */

View file

@ -0,0 +1,475 @@
/* $NetBSD: disklabel.h,v 1.111 2011/11/13 22:19:09 christos Exp $ */
/*
* Copyright (c) 1987, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University 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 BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
*
* @(#)disklabel.h 8.2 (Berkeley) 7/10/94
*/
#ifndef _SYS_DISKLABEL_H_
#define _SYS_DISKLABEL_H_
/*
* We need <machine/types.h> for __HAVE_OLD_DISKLABEL
*/
#ifndef _LOCORE
#include <sys/types.h>
#endif
/*
* Each disk has a label which includes information about the hardware
* disk geometry, filesystem partitions, and drive specific information.
* The location of the label, as well as the number of partitions the
* label can describe and the number of the "whole disk" (raw)
* paritition are machine dependent.
*/
#if HAVE_NBTOOL_CONFIG_H
#include <nbinclude/machine/disklabel.h>
#else
#include <machine/disklabel.h>
#endif /* HAVE_NBTOOL_CONFIG_H */
/*
* The absolute maximum number of disk partitions allowed.
* This is the maximum value of MAXPARTITIONS for which 'struct disklabel'
* is <= DEV_BSIZE bytes long. If MAXPARTITIONS is greater than this, beware.
*/
#define MAXMAXPARTITIONS 22
#if MAXPARTITIONS > MAXMAXPARTITIONS
#warning beware: MAXPARTITIONS bigger than MAXMAXPARTITIONS
#endif
/*
* Ports can switch their MAXPARTITIONS once, as follows:
*
* - define OLDMAXPARTITIONS in <machine/disklabel.h> as the old number
* - define MAXPARTITIONS as the new number
* - define DISKUNIT, DISKPART and DISKMINOR macros in <machine/disklabel.h>
* as appropriate for the port (see the i386 one for an example).
* - define __HAVE_OLD_DISKLABEL in <machine/types.h>
*/
#if defined(_KERNEL) && defined(__HAVE_OLD_DISKLABEL) && \
(MAXPARTITIONS < OLDMAXPARTITIONS)
#error "can only grow disklabel size"
#endif
/*
* Translate between device numbers and major/disk unit/disk partition.
*/
#ifndef __HAVE_OLD_DISKLABEL
#if !HAVE_NBTOOL_CONFIG_H
#define DISKUNIT(dev) (minor(dev) / MAXPARTITIONS)
#define DISKPART(dev) (minor(dev) % MAXPARTITIONS)
#define DISKMINOR(unit, part) \
(((unit) * MAXPARTITIONS) + (part))
#endif /* !HAVE_NBTOOL_CONFIG_H */
#endif
#define MAKEDISKDEV(maj, unit, part) \
(makedev((maj), DISKMINOR((unit), (part))))
#define DISKMAGIC ((uint32_t)0x82564557) /* The disk magic number */
#ifndef _LOCORE
struct disklabel {
uint32_t d_magic; /* the magic number */
uint16_t d_type; /* drive type */
uint16_t d_subtype; /* controller/d_type specific */
char d_typename[16]; /* type name, e.g. "eagle" */
/*
* d_packname contains the pack identifier and is returned when
* the disklabel is read off the disk or in-core copy.
* d_boot0 and d_boot1 are the (optional) names of the
* primary (block 0) and secondary (block 1-15) bootstraps
* as found in /usr/mdec. These are returned when using
* getdiskbyname(3) to retrieve the values from /etc/disktab.
*/
union {
char un_d_packname[16]; /* pack identifier */
struct {
char *un_d_boot0; /* primary bootstrap name */
char *un_d_boot1; /* secondary bootstrap name */
} un_b;
uint64_t un_d_pad; /* force 8 byte alignment */
} d_un;
#define d_packname d_un.un_d_packname
#define d_boot0 d_un.un_b.un_d_boot0
#define d_boot1 d_un.un_b.un_d_boot1
/* disk geometry: */
uint32_t d_secsize; /* # of bytes per sector */
uint32_t d_nsectors; /* # of data sectors per track */
uint32_t d_ntracks; /* # of tracks per cylinder */
uint32_t d_ncylinders; /* # of data cylinders per unit */
uint32_t d_secpercyl; /* # of data sectors per cylinder */
uint32_t d_secperunit; /* # of data sectors per unit */
/*
* Spares (bad sector replacements) below are not counted in
* d_nsectors or d_secpercyl. Spare sectors are assumed to
* be physical sectors which occupy space at the end of each
* track and/or cylinder.
*/
uint16_t d_sparespertrack; /* # of spare sectors per track */
uint16_t d_sparespercyl; /* # of spare sectors per cylinder */
/*
* Alternative cylinders include maintenance, replacement,
* configuration description areas, etc.
*/
uint32_t d_acylinders; /* # of alt. cylinders per unit */
/* hardware characteristics: */
/*
* d_interleave, d_trackskew and d_cylskew describe perturbations
* in the media format used to compensate for a slow controller.
* Interleave is physical sector interleave, set up by the
* formatter or controller when formatting. When interleaving is
* in use, logically adjacent sectors are not physically
* contiguous, but instead are separated by some number of
* sectors. It is specified as the ratio of physical sectors
* traversed per logical sector. Thus an interleave of 1:1
* implies contiguous layout, while 2:1 implies that logical
* sector 0 is separated by one sector from logical sector 1.
* d_trackskew is the offset of sector 0 on track N relative to
* sector 0 on track N-1 on the same cylinder. Finally, d_cylskew
* is the offset of sector 0 on cylinder N relative to sector 0
* on cylinder N-1.
*/
uint16_t d_rpm; /* rotational speed */
uint16_t d_interleave; /* hardware sector interleave */
uint16_t d_trackskew; /* sector 0 skew, per track */
uint16_t d_cylskew; /* sector 0 skew, per cylinder */
uint32_t d_headswitch; /* head switch time, usec */
uint32_t d_trkseek; /* track-to-track seek, usec */
uint32_t d_flags; /* generic flags */
#define NDDATA 5
uint32_t d_drivedata[NDDATA]; /* drive-type specific information */
#define NSPARE 5
uint32_t d_spare[NSPARE]; /* reserved for future use */
uint32_t d_magic2; /* the magic number (again) */
uint16_t d_checksum; /* xor of data incl. partitions */
/* filesystem and partition information: */
uint16_t d_npartitions; /* number of partitions in following */
uint32_t d_bbsize; /* size of boot area at sn0, bytes */
uint32_t d_sbsize; /* max size of fs superblock, bytes */
struct partition { /* the partition table */
uint32_t p_size; /* number of sectors in partition */
uint32_t p_offset; /* starting sector */
union {
uint32_t fsize; /* FFS, ADOS:
filesystem basic fragment size */
uint32_t cdsession; /* ISO9660: session offset */
} __partition_u2;
#define p_fsize __partition_u2.fsize
#define p_cdsession __partition_u2.cdsession
uint8_t p_fstype; /* filesystem type, see below */
uint8_t p_frag; /* filesystem fragments per block */
union {
uint16_t cpg; /* UFS: FS cylinders per group */
uint16_t sgs; /* LFS: FS segment shift */
} __partition_u1;
#define p_cpg __partition_u1.cpg
#define p_sgs __partition_u1.sgs
} d_partitions[MAXPARTITIONS]; /* actually may be more */
};
#if defined(__HAVE_OLD_DISKLABEL) && !HAVE_NBTOOL_CONFIG_H
/*
* Same as above, but with OLDMAXPARTITIONS partitions. For use in
* the old DIOC* ioctl calls.
*/
struct olddisklabel {
uint32_t d_magic;
uint16_t d_type;
uint16_t d_subtype;
char d_typename[16];
union {
char un_d_packname[16];
struct {
char *un_d_boot0;
char *un_d_boot1;
} un_b;
} d_un;
uint32_t d_secsize;
uint32_t d_nsectors;
uint32_t d_ntracks;
uint32_t d_ncylinders;
uint32_t d_secpercyl;
uint32_t d_secperunit;
uint16_t d_sparespertrack;
uint16_t d_sparespercyl;
uint32_t d_acylinders;
uint16_t d_rpm;
uint16_t d_interleave;
uint16_t d_trackskew;
uint16_t d_cylskew;
uint32_t d_headswitch;
uint32_t d_trkseek;
uint32_t d_flags;
uint32_t d_drivedata[NDDATA];
uint32_t d_spare[NSPARE];
uint32_t d_magic2;
uint16_t d_checksum;
uint16_t d_npartitions;
uint32_t d_bbsize;
uint32_t d_sbsize;
struct opartition {
uint32_t p_size;
uint32_t p_offset;
union {
uint32_t fsize;
uint32_t cdsession;
} __partition_u2;
uint8_t p_fstype;
uint8_t p_frag;
union {
uint16_t cpg;
uint16_t sgs;
} __partition_u1;
} d_partitions[OLDMAXPARTITIONS];
};
#endif /* __HAVE_OLD_DISKLABEL */
#else /* _LOCORE */
/*
* offsets for asm boot files.
*/
.set d_secsize,40
.set d_nsectors,44
.set d_ntracks,48
.set d_ncylinders,52
.set d_secpercyl,56
.set d_secperunit,60
.set d_end_,276 /* size of disk label */
#endif /* _LOCORE */
/*
* We normally use C99 initialisers (just in case the lists below are out
* of sequence, or have gaps), but lint doesn't grok them.
* Maybe some host compilers don't either, but many have for quite some time.
*/
#ifndef lint
#define ARRAY_INIT(element,value) [element]=value
#else
#define ARRAY_INIT(element,value) value
#endif
/* Use pre-processor magic to get all the parameters one one line... */
/* d_type values: */
#define DKTYPE_DEFN(x) \
x(UNKNOWN, 0, "unknown") \
x(SMD, 1, "SMD") /* SMD, XSMD; VAX hp/up */ \
x(MSCP, 2, "MSCP") /* MSCP */ \
x(DEC, 3, "old DEC") /* other DEC (rk, rl) */ \
x(SCSI, 4, "SCSI") /* SCSI */ \
x(ESDI, 5, "ESDI") /* ESDI interface */ \
x(ST506, 6, "ST506") /* ST506 etc. */ \
x(HPIB, 7, "HP-IB") /* CS/80 on HP-IB */ \
x(HPFL, 8, "HP-FL") /* HP Fiber-link */ \
x(TYPE_9, 9, "type 9") \
x(FLOPPY, 10, "floppy") /* floppy */ \
x(CCD, 11, "ccd") /* concatenated disk device */ \
x(VND, 12, "vnd") /* uvnode pseudo-disk */ \
x(ATAPI, 13, "ATAPI") /* ATAPI */ \
x(RAID, 14, "RAID") /* RAIDframe */ \
x(LD, 15, "ld") /* logical disk */ \
x(JFS2, 16, "jfs") /* IBM JFS2 */ \
x(CGD, 17, "cgd") /* cryptographic pseudo-disk */ \
x(VINUM, 18, "vinum") /* vinum volume */ \
x(FLASH, 19, "flash") /* flash memory devices */ \
x(DM, 20, "dm") /* device-mapper pseudo-disk devices */\
x(RUMPD, 21, "rumpd") /* rump virtual disk */ \
#ifndef _LOCORE
#define DKTYPE_NUMS(tag, number, name) __CONCAT(DTYPE_,tag=number),
#ifndef DKTYPE_ENUMNAME
#define DKTYPE_ENUMNAME
#endif
enum DKTYPE_ENUMNAME { DKTYPE_DEFN(DKTYPE_NUMS) DKMAXTYPES };
#undef DKTYPE_NUMS
#endif
#ifdef DKTYPENAMES
#define DKTYPE_NAMES(tag, number, name) ARRAY_INIT(number,name),
static const char *const dktypenames[] = { DKTYPE_DEFN(DKTYPE_NAMES) NULL };
#undef DKTYPE_NAMES
#endif
/*
* Partition type names, numbers, label-names, fsck prog, and mount prog
*/
#define FSTYPE_DEFN(x) \
x(UNUSED, 0, "unused", NULL, NULL) /* unused */ \
x(SWAP, 1, "swap", NULL, NULL) /* swap */ \
x(V6, 2, "Version 6", NULL, NULL) /* Sixth Edition */ \
x(V7, 3, "Version 7", "v7fs", "v7fs") /* Seventh Edition */ \
x(SYSV, 4, "System V", NULL, NULL) /* System V */ \
x(V71K, 5, "4.1BSD", NULL, NULL) /* V7, 1K blocks (4.1, 2.9) */ \
x(V8, 6, "Eighth Edition",NULL, NULL) /* Eighth Edition, 4K blocks */ \
x(BSDFFS, 7, "4.2BSD", "ffs", "ffs") /* 4.2BSD fast file system */ \
x(MSDOS, 8, "MSDOS", "msdos", "msdos") /* MSDOS file system */ \
x(BSDLFS, 9, "4.4LFS", "lfs", "lfs") /* 4.4BSD log-structured FS */ \
x(OTHER, 10, "unknown", NULL, NULL) /* in use, unknown/unsupported */\
x(HPFS, 11, "HPFS", NULL, NULL) /* OS/2 high-performance FS */ \
x(ISO9660, 12, "ISO9660", NULL, "cd9660")/* ISO 9660, normally CD-ROM */ \
x(BOOT, 13, "boot", NULL, NULL) /* bootstrap code in partition */\
x(ADOS, 14, "ADOS", NULL, "ados") /* AmigaDOS fast file system */ \
x(HFS, 15, "HFS", NULL, NULL) /* Macintosh HFS */ \
x(FILECORE,16, "FILECORE", NULL, "filecore")/* Acorn Filecore FS */ \
x(EX2FS, 17, "Linux Ext2","ext2fs","ext2fs")/* Linux Extended 2 FS */ \
x(NTFS, 18, "NTFS", NULL, "ntfs") /* Windows/NT file system */ \
x(RAID, 19, "RAID", NULL, NULL) /* RAIDframe component */ \
x(CCD, 20, "ccd", NULL, NULL) /* concatenated disk component */\
x(JFS2, 21, "jfs", NULL, NULL) /* IBM JFS2 */ \
x(APPLEUFS,22, "Apple UFS", "ffs", "ffs") /* Apple UFS */ \
/* XXX this is not the same as FreeBSD. How to solve? */ \
x(VINUM, 23, "vinum", NULL, NULL) /* Vinum */ \
x(UDF, 24, "UDF", NULL, "udf") /* UDF */ \
x(SYSVBFS, 25, "SysVBFS", NULL, "sysvbfs")/* System V boot file system */ \
x(EFS, 26, "EFS", NULL, "efs") /* SGI's Extent Filesystem */ \
x(NILFS, 27, "NiLFS", NULL, "nilfs") /* NTT's NiLFS(2) */ \
x(CGD, 28, "cgd", NULL, NULL) /* Cryptographic disk */
#ifndef _LOCORE
#define FS_TYPENUMS(tag, number, name, fsck, mount) __CONCAT(FS_,tag=number),
#ifndef FSTYPE_ENUMNAME
#define FSTYPE_ENUMNAME
#endif
enum FSTYPE_ENUMNAME { FSTYPE_DEFN(FS_TYPENUMS) FSMAXTYPES };
#undef FS_TYPENUMS
#endif
#ifdef FSTYPENAMES
#define FS_TYPENAMES(tag, number, name, fsck, mount) ARRAY_INIT(number,name),
static const char *const fstypenames[] = { FSTYPE_DEFN(FS_TYPENAMES) NULL };
#undef FS_TYPENAMES
#endif
#ifdef FSCKNAMES
/* These are the names MOUNT_XXX from <sys/mount.h> */
#define FS_FSCKNAMES(tag, number, name, fsck, mount) ARRAY_INIT(number,fsck),
static const char *const fscknames[] = { FSTYPE_DEFN(FS_FSCKNAMES) NULL };
#undef FS_FSCKNAMES
#define FSMAXNAMES FSMAXTYPES
#endif
#ifdef MOUNTNAMES
/* These are the names MOUNT_XXX from <sys/mount.h> */
#define FS_MOUNTNAMES(tag, number, name, fsck, mount) ARRAY_INIT(number,mount),
static const char *const mountnames[] = { FSTYPE_DEFN(FS_MOUNTNAMES) NULL };
#undef FS_MOUNTNAMES
#define FSMAXMOUNTNAMES FSMAXTYPES
#endif
/*
* flags shared by various drives:
*/
#define D_REMOVABLE 0x01 /* removable media */
#define D_ECC 0x02 /* supports ECC */
#define D_BADSECT 0x04 /* supports bad sector forw. */
#define D_RAMDISK 0x08 /* disk emulator */
#define D_CHAIN 0x10 /* can do back-back transfers */
#define D_SCSI_MMC 0x20 /* SCSI MMC sessioned media */
/*
* Drive data for SMD.
*/
#define d_smdflags d_drivedata[0]
#define D_SSE 0x1 /* supports skip sectoring */
#define d_mindist d_drivedata[1]
#define d_maxdist d_drivedata[2]
#define d_sdist d_drivedata[3]
/*
* Drive data for ST506.
*/
#define d_precompcyl d_drivedata[0]
#define d_gap3 d_drivedata[1] /* used only when formatting */
/*
* Drive data for SCSI.
*/
#define d_blind d_drivedata[0]
#ifndef _LOCORE
/*
* Structure used to perform a format or other raw operation,
* returning data and/or register values. Register identification
* and format are device- and driver-dependent. Currently unused.
*/
struct format_op {
char *df_buf;
int df_count; /* value-result */
daddr_t df_startblk;
int df_reg[8]; /* result */
};
#ifdef _KERNEL
/*
* Structure used internally to retrieve information about a partition
* on a disk.
*/
struct partinfo {
struct disklabel *disklab;
struct partition *part;
};
struct disk;
int disk_read_sectors(void (*)(struct buf *), const struct disklabel *,
struct buf *, unsigned int, int);
void diskerr(const struct buf *, const char *, const char *, int,
int, const struct disklabel *);
u_int dkcksum(struct disklabel *);
u_int dkcksum_sized(struct disklabel *, size_t);
int setdisklabel(struct disklabel *, struct disklabel *, u_long,
struct cpu_disklabel *);
const char *readdisklabel(dev_t, void (*)(struct buf *),
struct disklabel *, struct cpu_disklabel *);
int writedisklabel(dev_t, void (*)(struct buf *), struct disklabel *,
struct cpu_disklabel *);
const char *convertdisklabel(struct disklabel *, void (*)(struct buf *),
struct buf *, uint32_t);
int bounds_check_with_label(struct disk *, struct buf *, int);
int bounds_check_with_mediasize(struct buf *, int, uint64_t);
const char *getfstypename(int);
#endif
#endif /* _LOCORE */
#if !defined(_KERNEL) && !defined(_LOCORE)
#include <sys/cdefs.h>
#endif
#endif /* !_SYS_DISKLABEL_H_ */

View file

@ -0,0 +1,82 @@
/* $NetBSD: dkbad.h,v 1.15 2005/12/26 18:41:36 perry Exp $ */
/*-
* Copyright (c) 1982, 1986, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University 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 BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
*
* @(#)dkbad.h 8.2 (Berkeley) 7/10/94
*/
#ifndef _SYS_DKBAD_H_
#define _SYS_DKBAD_H_
/*
* Definitions needed to perform bad sector revectoring ala DEC STD 144.
*
* The bad sector information is located in the first 5 even numbered
* sectors of the last track of the disk pack. There are five identical
* copies of the information, described by the dkbad structure.
*
* Replacement sectors are allocated starting with the first sector before
* the bad sector information and working backwards towards the beginning of
* the disk. A maximum of 126 bad sectors are supported. The position of
* the bad sector in the bad sector table determines which replacement sector
* it corresponds to.
*
* The bad sector information and replacement sectors are conventionally
* only accessible through the 'c' file system partition of the disk. If
* that partition is used for a file system, the user is responsible for
* making sure that it does not overlap the bad sector information or any
* replacement sectors.
*/
#define NBT_BAD 126
struct dkbad {
int32_t bt_csn; /* cartridge serial number */
uint16_t bt_mbz; /* unused; should be 0 */
uint16_t bt_flag; /* -1 => alignment cartridge */
struct bt_bad {
uint16_t bt_cyl; /* cylinder number of bad sector */
uint16_t bt_trksec; /* track and sector number */
} bt_bad[NBT_BAD];
};
/*
* An indicator that the bad block handling is available. This is used
* to conditionally enable code that performs badblock re-mapping.
*/
#define HAS_BAD144_HANDLING
#define ECC 0
#define SSE 1
#define BSE 2
#define CONT 3
#ifdef _KERNEL
int isbad(struct dkbad *, int, int, int);
#endif
#endif /* _SYS_DKBAD_H_ */

112
common/include/sys/dkio.h Normal file
View file

@ -0,0 +1,112 @@
/* $NetBSD: dkio.h,v 1.17 2011/01/18 19:52:24 matt Exp $ */
/*
* Copyright (c) 1987, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University 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 BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
*/
#ifndef _SYS_DKIO_H_
#define _SYS_DKIO_H_
#include <sys/ioccom.h>
#include <prop/plistref.h>
/*
* Disk-specific ioctls.
*/
/* get and set disklabel; DIOCGPART used internally */
#define DIOCGDINFO _IOR('d', 101, struct disklabel)/* get */
#define DIOCSDINFO _IOW('d', 102, struct disklabel)/* set */
#define DIOCWDINFO _IOW('d', 103, struct disklabel)/* set, update disk */
#ifdef _KERNEL
#define DIOCGDINFO32 (DIOCGDINFO - (sizeof(uint32_t) << IOCPARM_SHIFT))
#define DIOCGPART _IOW('d', 104, struct partinfo) /* get partition */
#endif
#if defined(__HAVE_OLD_DISKLABEL) && defined(_KERNEL)
#define ODIOCGDINFO _IOR('d', 101, struct olddisklabel)/* get */
#define ODIOCSDINFO _IOW('d', 102, struct olddisklabel)/* set */
#define ODIOCWDINFO _IOW('d', 103, struct olddisklabel)/* set, update dk */
#endif
/* do format operation, read or write */
#define DIOCRFORMAT _IOWR('d', 105, struct format_op)
#define DIOCWFORMAT _IOWR('d', 106, struct format_op)
#define DIOCSSTEP _IOW('d', 107, int) /* set step rate */
#define DIOCSRETRIES _IOW('d', 108, int) /* set # of retries */
#define DIOCKLABEL _IOW('d', 119, int) /* keep/drop label on close? */
#define DIOCWLABEL _IOW('d', 109, int) /* write en/disable label */
#define DIOCSBAD _IOW('d', 110, struct dkbad) /* set kernel dkbad */
#define DIOCEJECT _IOW('d', 112, int) /* eject removable disk */
#define ODIOCEJECT _IO('d', 112) /* eject removable disk */
#define DIOCLOCK _IOW('d', 113, int) /* lock/unlock pack */
/* get default label, clear label */
#define DIOCGDEFLABEL _IOR('d', 114, struct disklabel)
#define DIOCCLRLABEL _IO('d', 115)
#if defined(__HAVE_OLD_DISKLABEL) && defined(_KERNEL)
#define ODIOCGDEFLABEL _IOR('d', 114, struct olddisklabel)
#endif
/* disk cache enable/disable */
#define DIOCGCACHE _IOR('d', 116, int) /* get cache enables */
#define DIOCSCACHE _IOW('d', 117, int) /* set cache enables */
#define DKCACHE_READ 0x000001 /* read cache enabled */
#define DKCACHE_WRITE 0x000002 /* write(back) cache enabled */
#define DKCACHE_RCHANGE 0x000100 /* read enable is changeable */
#define DKCACHE_WCHANGE 0x000200 /* write enable is changeable */
#define DKCACHE_SAVE 0x010000 /* cache parameters are savable/save them */
/* sync disk cache */
#define DIOCCACHESYNC _IOW('d', 118, int) /* sync cache (force?) */
/* bad sector list */
#define DIOCBSLIST _IOWR('d', 119, struct disk_badsecinfo) /* get list */
#define DIOCBSFLUSH _IO('d', 120) /* flush list */
/* wedges */
#define DIOCAWEDGE _IOWR('d', 121, struct dkwedge_info) /* add wedge */
#define DIOCGWEDGEINFO _IOR('d', 122, struct dkwedge_info) /* get wedge inf */
#define DIOCDWEDGE _IOW('d', 123, struct dkwedge_info) /* del wedge */
#define DIOCLWEDGES _IOWR('d', 124, struct dkwedge_list) /* list wedges */
/* disk buffer queue strategy */
#define DIOCGSTRATEGY _IOR('d', 125, struct disk_strategy)
#define DIOCSSTRATEGY _IOW('d', 126, struct disk_strategy)
/* get disk-info dictionary */
#define DIOCGDISKINFO _IOR('d', 127, struct plistref)
#define DIOCTUR _IOR('d', 128, int) /* test unit ready */
#endif /* _SYS_DKIO_H_ */

View file

@ -0,0 +1,75 @@
/* $NetBSD: ioccom.h,v 1.11 2011/10/19 10:53:12 yamt Exp $ */
/*-
* Copyright (c) 1982, 1986, 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University 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 BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
*
* @(#)ioccom.h 8.3 (Berkeley) 1/9/95
*/
#ifndef _SYS_IOCCOM_H_
#define _SYS_IOCCOM_H_
/*
* Ioctl's have the command encoded in the lower word, and the size of
* any in or out parameters in the upper word. The high 3 bits of the
* upper word are used to encode the in/out status of the parameter.
*
* 31 29 28 16 15 8 7 0
* +---------------------------------------------------------------+
* | I/O | Parameter Length | Command Group | Command |
* +---------------------------------------------------------------+
*/
#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */
#define IOCPARM_SHIFT 16
#define IOCGROUP_SHIFT 8
#define IOCPARM_LEN(x) (((x) >> IOCPARM_SHIFT) & IOCPARM_MASK)
#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << IOCPARM_SHIFT))
#define IOCGROUP(x) (((x) >> IOCGROUP_SHIFT) & 0xff)
#define IOCPARM_MAX NBPG /* max size of ioctl args, mult. of NBPG */
/* no parameters */
#define IOC_VOID (unsigned long)0x20000000
/* copy parameters out */
#define IOC_OUT (unsigned long)0x40000000
/* copy parameters in */
#define IOC_IN (unsigned long)0x80000000
/* copy parameters in and out */
#define IOC_INOUT (IOC_IN|IOC_OUT)
/* mask for IN/OUT/VOID */
#define IOC_DIRMASK (unsigned long)0xe0000000
#define _IOC(inout, group, num, len) \
((inout) | (((len) & IOCPARM_MASK) << IOCPARM_SHIFT) | \
((group) << IOCGROUP_SHIFT) | (num))
#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0)
#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t))
#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t))
/* this should be _IORW, but stdio got there first */
#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t))
#endif /* !_SYS_IOCCOM_H_ */

108
common/include/sys/iostat.h Normal file
View file

@ -0,0 +1,108 @@
/* $NetBSD: iostat.h,v 1.10 2009/04/04 07:30:09 ad Exp $ */
/*-
* Copyright (c) 1996, 1997, 2004, 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION 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.
*/
#ifndef _SYS_IOSTAT_H_
#define _SYS_IOSTAT_H_
/*
* Disk device structures.
*/
#include <sys/time.h>
#include <sys/queue.h>
#define IOSTATNAMELEN 16
/* types of drives we can have */
#define IOSTAT_DISK 0
#define IOSTAT_TAPE 1
#define IOSTAT_NFS 2
/* The following structure is 64-bit alignment safe */
struct io_sysctl {
char name[IOSTATNAMELEN];
int32_t busy;
int32_t type;
u_int64_t xfer;
u_int64_t seek;
u_int64_t bytes;
u_int32_t attachtime_sec;
u_int32_t attachtime_usec;
u_int32_t timestamp_sec;
u_int32_t timestamp_usec;
u_int32_t time_sec;
u_int32_t time_usec;
/* New separate read/write stats */
u_int64_t rxfer;
u_int64_t rbytes;
u_int64_t wxfer;
u_int64_t wbytes;
};
/*
* Structure for keeping the in-kernel drive stats - these are linked
* together in drivelist.
*/
struct io_stats {
char io_name[IOSTATNAMELEN]; /* device name */
void *io_parent; /* pointer to what we are attached to */
int io_type; /* type of device the state belong to */
int io_busy; /* busy counter */
u_int64_t io_rxfer; /* total number of read transfers */
u_int64_t io_wxfer; /* total number of write transfers */
u_int64_t io_seek; /* total independent seek operations */
u_int64_t io_rbytes; /* total bytes read */
u_int64_t io_wbytes; /* total bytes written */
struct timeval io_attachtime; /* time disk was attached */
struct timeval io_timestamp; /* timestamp of last unbusy */
struct timeval io_time; /* total time spent busy */
TAILQ_ENTRY(io_stats) io_link;
};
/*
* drivelist_head is defined here so that user-land has access to it.
*/
TAILQ_HEAD(iostatlist_head, io_stats); /* the iostatlist is a TAILQ */
#ifdef _KERNEL
void iostat_init(void);
void iostat_busy(struct io_stats *);
void iostat_unbusy(struct io_stats *, long, int);
bool iostat_isbusy(struct io_stats *);
struct io_stats *iostat_find(const char *);
struct io_stats *iostat_alloc(int32_t, void *, const char *);
void iostat_free(struct io_stats *);
void iostat_seek(struct io_stats *);
#endif
#endif /* _SYS_IOSTAT_H_ */

216
common/include/sys/mutex.h Normal file
View file

@ -0,0 +1,216 @@
/* $NetBSD: mutex.h,v 1.20 2010/02/08 09:54:27 skrll Exp $ */
/*-
* Copyright (c) 2002, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe and Andrew Doran.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION 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.
*/
#ifndef _SYS_MUTEX_H_
#define _SYS_MUTEX_H_
/*
* There are 2 types of mutexes:
*
* * Adaptive -- If the lock is already held, the thread attempting
* to acquire the lock determines if the thread that holds it is
* currently running. If so, it spins, else it sleeps.
*
* * Spin -- If the lock is already held, the thread attempting to
* acquire the lock spins. The IPL will be raised on entry.
*
* Machine dependent code must provide the following:
*
* struct mutex
* The actual mutex structure. This structure is mostly
* opaque to machine-independent code; most access are done
* through macros. However, machine-independent code must
* be able to access the following members:
*
* uintptr_t mtx_owner
* ipl_cookie_t mtx_ipl
* __cpu_simple_lock_t mtx_lock
*
* If an architecture can be considered 'simple' (no interlock required in
* the MP case, or no MP) it need only define __HAVE_SIMPLE_MUTEXES and
* provide the following:
*
* struct mutex
*
* [additionally:]
* volatile integer mtx_id
*
* MUTEX_RECEIVE(mtx)
* Post a load fence after acquiring the mutex, if necessary.
*
* MUTEX_GIVE(mtx)
* Post a load/store fence after releasing the mutex, if
* necessary.
*
* MUTEX_CAS(ptr, old, new)
* Perform an atomic "compare and swap" operation and
* evaluate to true or false according to the success
*
* Otherwise, the following must be defined:
*
* MUTEX_INITIALIZE_SPIN(mtx, dodebug, minipl)
* Initialize a spin mutex.
*
* MUTEX_INITIALIZE_ADAPTIVE(mtx, dodebug)
* Initialize an adaptive mutex.
*
* MUTEX_DESTROY(mtx)
* Tear down a mutex.
*
* MUTEX_ADAPTIVE_P(mtx)
* Evaluates to true if the mutex is an adaptive mutex.
*
* MUTEX_SPIN_P(mtx)
* Evaluates to true if the mutex is a spin mutex.
*
* MUTEX_OWNER(owner)
* Returns the owner of the adaptive mutex (LWP address).
*
* MUTEX_OWNED(owner)
* Returns non-zero if an adaptive mutex is currently
* held by an LWP.
*
* MUTEX_HAS_WAITERS(mtx)
* Returns true if the mutex has waiters.
*
* MUTEX_SET_WAITERS(mtx)
* Mark the mutex has having waiters.
*
* MUTEX_ACQUIRE(mtx, owner)
* Try to acquire an adaptive mutex such that:
* if (lock held OR waiters)
* return 0;
* else
* return 1;
* Must be MP/interrupt atomic.
*
* MUTEX_RELEASE(mtx)
* Release the lock and clear the "has waiters" indication.
* Must be interrupt atomic, need not be MP safe.
*
* MUTEX_DEBUG_P(mtx)
* Evaluates to true if the mutex is initialized with
* dodebug==true. Only used in the LOCKDEBUG case.
*
* Machine dependent code may optionally provide stubs for the following
* functions to implement the easy (unlocked / no waiters) cases. If
* these stubs are provided, __HAVE_MUTEX_STUBS should be defined.
*
* mutex_enter()
* mutex_exit()
*
* Two additional stubs may be implemented that handle only the spinlock
* case, primarily for the scheduler. __HAVE_SPIN_MUTEX_STUBS should be
* defined if these are provided:
*
* mutex_spin_enter()
* mutex_spin_exit()
*/
#if defined(_KERNEL_OPT)
#include "opt_lockdebug.h"
#endif
#if !defined(_KERNEL)
#include <sys/types.h>
#include <sys/inttypes.h>
#endif
typedef enum kmutex_type_t {
MUTEX_SPIN = 0, /* To get a spin mutex at IPL_NONE */
MUTEX_ADAPTIVE = 1, /* For porting code written for Solaris */
MUTEX_DEFAULT = 2, /* The only native, endorsed type */
MUTEX_DRIVER = 3, /* For porting code written for Solaris */
MUTEX_NODEBUG = 4 /* Disables LOCKDEBUG; use with care */
} kmutex_type_t;
typedef struct kmutex kmutex_t;
#if defined(__MUTEX_PRIVATE)
#define MUTEX_THREAD ((uintptr_t)-16L)
#define MUTEX_BIT_SPIN 0x01
#define MUTEX_BIT_WAITERS 0x02
#if defined(LOCKDEBUG)
#define MUTEX_BIT_NODEBUG 0x04 /* LOCKDEBUG disabled */
#else
#define MUTEX_BIT_NODEBUG 0x00 /* do nothing */
#endif /* LOCKDEBUG */
#define MUTEX_SPIN_IPL(mtx) ((mtx)->mtx_ipl)
#define MUTEX_SPIN_OLDSPL(ci) ((ci)->ci_mtx_oldspl)
void mutex_vector_enter(kmutex_t *);
void mutex_vector_exit(kmutex_t *);
void mutex_spin_retry(kmutex_t *);
void mutex_wakeup(kmutex_t *);
#endif /* __MUTEX_PRIVATE */
#ifdef _KERNEL
#include <sys/intr.h>
#endif
#include <machine/mutex.h>
/*
* Return true if no spin mutexes are held by the current CPU.
*/
#ifndef MUTEX_NO_SPIN_ACTIVE_P
#define MUTEX_NO_SPIN_ACTIVE_P(ci) ((ci)->ci_mtx_count == 0)
#endif
#ifdef _KERNEL
void mutex_init(kmutex_t *, kmutex_type_t, int);
void mutex_destroy(kmutex_t *);
void mutex_enter(kmutex_t *);
void mutex_exit(kmutex_t *);
void mutex_spin_enter(kmutex_t *);
void mutex_spin_exit(kmutex_t *);
int mutex_tryenter(kmutex_t *);
int mutex_owned(kmutex_t *);
lwp_t *mutex_owner(kmutex_t *);
void mutex_obj_init(void);
kmutex_t *mutex_obj_alloc(kmutex_type_t, int);
void mutex_obj_hold(kmutex_t *);
bool mutex_obj_free(kmutex_t *);
#endif /* _KERNEL */
#endif /* _SYS_MUTEX_H_ */

View file

@ -71,6 +71,13 @@
755 root operator /usr/include/rpcsvc
755 root operator /usr/include/ssp
755 root operator /usr/include/sys
755 root operator /usr/include/ufs
755 root operator /usr/include/ufs/chfs
755 root operator /usr/include/ufs/ext2fs
755 root operator /usr/include/ufs/ffs
755 root operator /usr/include/ufs/lfs
755 root operator /usr/include/ufs/mfs
755 root operator /usr/include/ufs/ufs
700 root operator /usr/preserve
755 root operator /usr/run
755 root operator /usr/share

9
etc/rc
View file

@ -114,8 +114,10 @@ start)
# options for fsck. default is -r, which prompts the user for repairs.
fsckopts="`sysenv fsckopts`"
if [ ! "$fsckopts" ]
then fsckopts=-r
optname=fsckopts
fsckopts=-p
if sysenv $optname >/dev/null
then fsckopts="`sysenv $optname`"
fi
if [ "`sysenv debug_fkeys`" != 0 ]
@ -160,7 +162,8 @@ start)
read <$FSTAB fstabline
if [ "$fstabline" = "# Poor man's File System Table." ]
then mountfstab_poorman # Old minix /etc/fstab
else mountfstab $fflag -o"$fsckopts" $FSTAB
else fsck -x / $fflag $fsckopts
mountfstab $FSTAB
fi
fi

View file

@ -1,21 +1,6 @@
mountfstab()
{
fsck_opts=""
fflag="-p"
while getopts "fo:" opt
do case $opt
in f) fflag="-f"
;;
o) fsck_opts="$OPTARG"
;;
*) echo "mountfstab: odd"
return 1
;;
esac
done
shift `expr $OPTIND - 1`
fstabfile="$1"
@ -37,23 +22,13 @@ mountfstab()
# This line's parameters
dev="$1"; mp="$2"; fstype="$3"
# Don't fsck / as it's already mounted
# Don't mount / as it's already mounted
if [ "$mp" = "/" ]; then continue; fi
# Sanity checks
if [ ! -b $dev ]; then echo "$dev missing"; continue; fi
if [ ! -d $mp ]; then echo "$mp missing"; continue; fi
# Do fsck if necessary or requested
if [ -n "$fflag" ]
then fsck.$fstype $fflag $fsck_opts $dev
fi
# Skip the actual mount for /, it's already mounted
if [ "$mp" = / ]
then continue
fi
# Do actual mount command
mount -t $fstype $dev $mp
done

View file

@ -94,6 +94,7 @@ SRCS+= \
setmode.c \
settimeofday.c \
shquote.c \
sizeup.c \
stderr.c \
strcasestr.c \
strdup.c \

52
lib/libc/other/sizeup.c Normal file
View file

@ -0,0 +1,52 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <minix/u64.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <minix/config.h>
#include <minix/const.h>
#include <minix/type.h>
#include <minix/minlib.h>
#include <minix/partition.h>
#include <sys/ioc_disk.h>
#include <unistd.h>
/*================================================================
* minix_sizeup - determine device size
*===============================================================*/
int minix_sizeup(device, bytes)
char *device;
u64_t *bytes;
{
int fd;
struct partition entry;
struct stat st;
if ((fd = open(device, O_RDONLY)) == -1) {
if (errno != ENOENT)
perror("sizeup open");
return -1;
}
if (ioctl(fd, DIOCGETP, &entry) == -1) {
perror("sizeup ioctl");
if(fstat(fd, &st) < 0) {
perror("fstat");
entry.size = cvu64(0);
} else {
entry.size = cvu64(st.st_size);
}
}
close(fd);
*bytes = entry.size;
return 0;
}

View file

@ -61,14 +61,17 @@ __opendisk(const char *path, int flags, char *buf, size_t buflen, int iscooked,
return (-1);
}
#ifndef __minix
rawpart = getrawpartition();
if (rawpart < 0)
return (-1); /* sysctl(3) in getrawpartition sets errno */
#endif
f = ofn(buf, flags, 0);
if (f != -1 || errno != ENOENT)
return (f);
#ifndef __minix
snprintf(buf, buflen, "%s%c", path, 'a' + rawpart);
f = ofn(buf, flags, 0);
if (f != -1 || errno != ENOENT)
@ -85,6 +88,7 @@ __opendisk(const char *path, int flags, char *buf, size_t buflen, int iscooked,
snprintf(buf, buflen, "%s%s%s%c", _PATH_DEV, iscooked ? "" : "r", path,
'a' + rawpart);
f = ofn(buf, flags, 0);
#endif
return (f);
}

View file

@ -16,7 +16,7 @@ SRCS+= accept.c access.c bind.c brk.c sbrk.c m_closefrom.c getsid.c \
vectorio.c shutdown.c sigaction.c sigpending.c sigreturn.c sigsuspend.c\
sigprocmask.c socket.c socketpair.c stat.c statvfs.c symlink.c \
sync.c syscall.c sysuname.c truncate.c umask.c unlink.c write.c \
_exit.c _ucontext.c environ.c __getcwd.c vfork.c
_exit.c _ucontext.c environ.c __getcwd.c vfork.c sizeup.c
# Minix specific syscalls.
SRCS+= cprofile.c lseek64.c sprofile.c _mcontext.c

View file

@ -0,0 +1,52 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <minix/u64.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <minix/config.h>
#include <minix/const.h>
#include <minix/type.h>
#include <minix/minlib.h>
#include <minix/partition.h>
#include <sys/ioc_disk.h>
#include <unistd.h>
/*================================================================
* minix_sizeup - determine device size
*===============================================================*/
int minix_sizeup(device, bytes)
char *device;
u64_t *bytes;
{
int fd;
struct partition entry;
struct stat st;
if ((fd = open(device, O_RDONLY)) == -1) {
if (errno != ENOENT)
perror("sizeup open");
return -1;
}
if (ioctl(fd, DIOCGETP, &entry) == -1) {
perror("sizeup ioctl");
if(fstat(fd, &st) < 0) {
perror("fstat");
entry.size = cvu64(0);
} else {
entry.size = cvu64(st.st_size);
}
}
close(fd);
*bytes = entry.size;
return 0;
}

View file

@ -7,7 +7,7 @@ MAN= acd.1 anm.1 ar.1 ash.1 asize.1 at.1 banner.1 basename.1 \
dumpcore.1 echo.1 ed.1 eject.1 elvis.1 elvrec.1 \
env.1 expand.1 expr.1 factor.1 file.1 \
finger.1 flexdoc.1 fmt.1 fold.1 format.1 fortune.1 \
fsck.1 head.1 host.1 hostaddr.1 ifdef.1 \
fsck.mfs.1 head.1 host.1 hostaddr.1 ifdef.1 \
install.1 isodir.1 isoinfo.1 isoread.1 join.1 kill.1 \
last.1 leave.1 loadfont.1 loadkeys.1 logger.1 login.1 \
look.1 lp.1 ls.1 lspci.1 M.1 mail.1 \

View file

@ -66,6 +66,9 @@
#define MAXPHYS (64 * 1024) /* max raw I/O transfer size */
#endif
#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
#define DEV_BSIZE (1 << DEV_BSHIFT)
/*
* Mach derived conversion macros
*/

View file

@ -5,6 +5,7 @@ INCSDIR=/usr/include/x86
INCS= float.h \
ieee.h \
ieeefp.h \
math.h
math.h \
mutex.h
.include <bsd.kinc.mk>

View file

@ -0,0 +1,80 @@
/* $NetBSD: mutex.h,v 1.6 2009/04/24 17:49:51 ad Exp $ */
/*-
* Copyright (c) 2002, 2006, 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe and Andrew Doran.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION 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.
*/
#ifndef _X86_MUTEX_H_
#define _X86_MUTEX_H_
struct kmutex {
union {
volatile uintptr_t mtxa_owner;
#ifdef __MUTEX_PRIVATE
struct {
volatile uint8_t mtxs_dummy;
ipl_cookie_t mtxs_ipl;
__cpu_simple_lock_t mtxs_lock;
volatile uint8_t mtxs_unused;
} s;
#endif
} u;
};
#ifdef __MUTEX_PRIVATE
#define mtx_owner u.mtxa_owner
#define mtx_ipl u.s.mtxs_ipl
#define mtx_lock u.s.mtxs_lock
#define __HAVE_MUTEX_STUBS 1
#define __HAVE_SPIN_MUTEX_STUBS 1
#define __HAVE_SIMPLE_MUTEXES 1
/*
* MUTEX_RECEIVE: technically, no memory barrier is required
* as 'ret' implies a load fence. However we need this to
* handle a bug with some Opteron revisions. See patch.c,
* lock_stubs.S.
*/
#define MUTEX_RECEIVE(mtx) membar_consumer()
/*
* MUTEX_GIVE: no memory barrier required, as _lock_cas() will take care of it.
*/
#define MUTEX_GIVE(mtx) /* nothing */
#define MUTEX_CAS(p, o, n) \
(_atomic_cas_ulong((volatile unsigned long *)(p), (o), (n)) == (o))
unsigned long _atomic_cas_ulong(volatile unsigned long *,
unsigned long, unsigned long);
#endif /* __MUTEX_PRIVATE */
#endif /* _X86_MUTEX_H_ */

View file

@ -1,6 +1,43 @@
#ifndef _SYS_MOUNT_H
#define _SYS_MOUNT_H_
/*
* File system types.
*/
#define MOUNT_FFS "ffs" /* UNIX "Fast" Filesystem */
#define MOUNT_UFS MOUNT_FFS /* for compatibility */
#define MOUNT_NFS "nfs" /* Network Filesystem */
#define MOUNT_MFS "mfs" /* Memory Filesystem */
#define MOUNT_MSDOS "msdos" /* MSDOS Filesystem */
#define MOUNT_LFS "lfs" /* Log-based Filesystem */
#define MOUNT_FDESC "fdesc" /* File Descriptor Filesystem */
#define MOUNT_NULL "null" /* Minimal Filesystem Layer */
#define MOUNT_OVERLAY "overlay" /* Minimal Overlay Filesystem Layer */
#define MOUNT_UMAP "umap" /* User/Group Identifier Remapping Filesystem */
#define MOUNT_KERNFS "kernfs" /* Kernel Information Filesystem */
#define MOUNT_PROCFS "procfs" /* /proc Filesystem */
#define MOUNT_AFS "afs" /* Andrew Filesystem */
#define MOUNT_CD9660 "cd9660" /* ISO9660 (aka CDROM) Filesystem */
#define MOUNT_UNION "union" /* Union (translucent) Filesystem */
#define MOUNT_ADOSFS "adosfs" /* AmigaDOS Filesystem */
#define MOUNT_EXT2FS "ext2fs" /* Second Extended Filesystem */
#define MOUNT_CFS "coda" /* Coda Filesystem */
#define MOUNT_CODA MOUNT_CFS /* Coda Filesystem */
#define MOUNT_FILECORE "filecore" /* Acorn Filecore Filesystem */
#define MOUNT_NTFS "ntfs" /* Windows/NT Filesystem */
#define MOUNT_SMBFS "smbfs" /* CIFS (SMB) */
#define MOUNT_PTYFS "ptyfs" /* Pseudo tty filesystem */
#define MOUNT_TMPFS "tmpfs" /* Efficient memory file-system */
#define MOUNT_UDF "udf" /* UDF CD/DVD filesystem */
#define MOUNT_SYSVBFS "sysvbfs" /* System V Boot Filesystem */
#define MOUNT_PUFFS "puffs" /* Pass-to-Userspace filesystem */
#define MOUNT_HFS "hfs" /* Apple HFS+ Filesystem */
#define MOUNT_EFS "efs" /* SGI's Extent Filesystem */
#define MOUNT_ZFS "zfs" /* Sun ZFS */
#define MOUNT_NILFS "nilfs" /* NTT's NiLFS(2) logging file system */
#define MOUNT_RUMPFS "rumpfs" /* rump virtual file system */
#define MOUNT_V7FS "v7fs" /* 7th Edition of Unix Filesystem */
#include <sys/statvfs.h>
#include <minix/mount.h>

7
sbin/Makefile Normal file
View file

@ -0,0 +1,7 @@
# Makefile for bin
.include <bsd.own.mk>
SUBDIR= fsck
.include <bsd.subdir.mk>

6
sbin/Makefile.inc Normal file
View file

@ -0,0 +1,6 @@
.include <minix.newlibc.mk>
CPPFLAGS+= -D_NETBSD_SOURCE
BINDIR?=/sbin

13
sbin/fsck/Makefile Normal file
View file

@ -0,0 +1,13 @@
# $NetBSD: Makefile,v 1.18 2009/06/05 21:52:31 haad Exp $
PROG= fsck
SRCS= fsck.c fsutil.c preen.c
MAN= fsck.8
LDADD+=-lutil
DPADD+=${LIBUTIL}
LDADD+=-lprop
DPADD+=${LIBPROP}
.include <bsd.prog.mk>

34
sbin/fsck/exitvalues.h Normal file
View file

@ -0,0 +1,34 @@
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION 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.
*/
#define FSCK_EXIT_OK 0
#define FSCK_EXIT_USAGE 1
#define FSCK_EXIT_UNRESOLVED 2
#define FSCK_EXIT_ROOT_CHANGED 4
#define FSCK_EXIT_CHECK_FAILED 8
#define FSCK_EXIT_SIGNALLED 12

176
sbin/fsck/fsck.8 Normal file
View file

@ -0,0 +1,176 @@
.\" $NetBSD: fsck.8,v 1.38 2011/04/28 12:16:10 wiz Exp $
.\"
.\" Copyright (c) 1996 Christos Zoulas. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" 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.
.\"
.Dd February 17, 2010
.Dt FSCK 8
.Os
.Sh NAME
.Nm fsck
.Nd file system consistency check and interactive repair
.Sh SYNOPSIS
.Nm
.Op Fl dfnPpqvy
.Op Fl l Ar maxparallel
.Op Fl T Ar fstype:fsoptions
.Op Fl t Ar fstype
.Op Fl x Ar mountpoint
.Op special | node ...
.Sh DESCRIPTION
The
.Nm
command invokes file system-specific programs to check
the special devices listed in the
.Xr fstab 5
file or in the command line for consistency.
.Pp
It is normally used in the script
.Pa /etc/rc
during automatic reboot.
If no file systems are specified, and
.Dq preen
mode is enabled (
.Fl p
option)
.Nm
reads the table
.Pa /etc/fstab
to determine which file systems to check, in what order.
Only partitions in fstab that are mounted ``rw,'' ``rq'' or ``ro''
and that have non-zero pass number are checked.
File systems with pass number 1 (normally just the root file system)
are checked one at a time.
When pass 1 completes, all remaining file systems are checked,
running one process per disk drive.
By default, file systems which are already mounted read-write are not checked.
The disk drive containing each file system is inferred from the longest prefix
of the device name that ends in a digit; the remaining characters are assumed
to be the partition designator.
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl d
Debugging mode.
Just print the commands without executing them.
.It Fl f
Force checking of file systems, even when they are marked clean (for file
systems that support this), or when they are mounted read-write.
.It Fl l Ar maxparallel
Limit the number of parallel checks to the number specified in
the following argument.
By default, the limit is the number of disks, running one process per disk.
If a smaller limit is given, the disks are checked round-robin,
one file system at a time.
.It Fl n
Causes
.Nm
to assume no as the answer to all operator questions, except "CONTINUE?".
.It Fl P
Display a progress meter for each file system check.
This option also disables parallel checking.
Note that progress meters are not supported by all file system types.
.It Fl p
Enter preen mode.
In preen mode,
.Nm
will check all file systems listed in
.Pa /etc/fstab
according to their pass number, and will make minor repairs without
human intervention.
.It Fl q
Quiet mode, do not output any messages for clean filesystems.
.It Fl T Ar fstype:fsoptions
List of comma separated file system specific options for the specified
file system type, in the same format as
.Xr mount 8 .
.It Fl t Ar fstype
Invoke
.Nm
only for the comma separated list of file system types.
If the list starts with
.Dq no
then invoke
.Nm
for the file system types that are not specified in the list.
.It Fl v
Print the commands before executing them.
.It Fl x Ar mountpoint
Exclude the filesystem which has a
.Ar mountpoint
the same as in
.Pa /etc/fstab .
Used only in
.Dq preen
mode.
.It Fl y
Causes
.Nm
to assume yes
as the answer to all operator questions.
.El
.Sh FILES
.Bl -tag -width /etc/fstab -compact
.It Pa /etc/fstab
file system table
.El
.Sh EXIT STATUS
.Nm
exits with
.Dv 0
on success.
Any major problems will cause
.Nm
to exit with the following non-zero
.Xr exit 3
codes, so as to alert any invoking program or script that human
intervention is required.
.Bl -tag -width XXXX
.It Dv 1
Usage problem.
.It Dv 2
Unresolved errors while checking the filesystem.
Re-running
.Nm
on the filesystem(s) is required.
.It Dv 4
The root filesystem was changed in the process of checking, and updating the
mount was unsuccessful.
A reboot (without sync) is required.
.It Dv 8
The filesystem check has failed, and a subsequent check is required
that will require human intervention.
.It Dv 12
.Nm
exited because of the result of a signal (usually
.Dv SIGINT
or
.Dv SIGQUIT
from the terminal).
.El
.Sh SEE ALSO
.Xr fstab 5 ,
.Xr fsck_ext2fs 8 ,
.Xr fsck_ffs 8 ,
.Xr fsck_lfs 8 ,
.Xr fsck_msdos 8 ,
.Xr mount 8

604
sbin/fsck/fsck.c Normal file
View file

@ -0,0 +1,604 @@
/* $NetBSD: fsck.c,v 1.49 2010/02/24 13:56:07 hannken Exp $ */
/*
* Copyright (c) 1996 Christos Zoulas. All rights reserved.
* Copyright (c) 1980, 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University 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 BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
*
* From: @(#)mount.c 8.19 (Berkeley) 4/19/94
* From: NetBSD: mount.c,v 1.24 1995/11/18 03:34:29 cgd Exp
*
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fsck.c,v 1.49 2010/02/24 13:56:07 hannken Exp $");
#endif /* not lint */
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/queue.h>
#include <sys/wait.h>
#define FSTYPENAMES
#define FSCKNAMES
#include <sys/disk.h>
#include <sys/disklabel.h>
#include <sys/ioctl.h>
#include <err.h>
#include <errno.h>
#include <fstab.h>
#include <fcntl.h>
#include <paths.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <util.h>
#include "pathnames.h"
#include "fsutil.h"
#include "exitvalues.h"
static enum { IN_LIST, NOT_IN_LIST } which = NOT_IN_LIST;
TAILQ_HEAD(fstypelist, entry) opthead, selhead, omhead;
struct entry {
char *type;
char *options;
TAILQ_ENTRY(entry) entries;
};
static int maxrun = 0;
static char *options = NULL;
static int flags = 0;
static int checkfs(const char *, const char *, const char *, void *, pid_t *);
static int selected(const char *);
static int omitted(const char *);
static void addoption(char *);
static const char *getoptions(const char *);
static void addentry(struct fstypelist *, const char *, const char *);
static void maketypelist(char *);
static void catopt(char **, const char *);
static void mangle(char *, int *, const char ** volatile *, int *);
static const char *getfslab(const char *);
static void usage(void);
static void *isok(struct fstab *);
int
main(int argc, char *argv[])
{
struct fstab *fs;
int i, rval;
const char *vfstype = NULL;
char globopt[3];
int ret = FSCK_EXIT_OK;
globopt[0] = '-';
globopt[2] = '\0';
TAILQ_INIT(&selhead);
TAILQ_INIT(&opthead);
TAILQ_INIT(&omhead);
while ((i = getopt(argc, argv, "dfl:nPpqT:t:vx:y")) != -1) {
switch (i) {
case 'd':
flags |= CHECK_DEBUG;
continue;
case 'f':
flags |= CHECK_FORCE;
break;
case 'n':
flags |= CHECK_NOFIX;
break;
case 'p':
flags |= CHECK_PREEN;
break;
case 'P':
flags |= CHECK_PROGRESS;
break;
case 'q':
break;
case 'l':
maxrun = atoi(optarg);
continue;
case 'T':
if (*optarg)
addoption(optarg);
continue;
case 't':
if (TAILQ_FIRST(&selhead) != NULL)
errx(1, "only one -t option may be specified.");
maketypelist(optarg);
vfstype = optarg;
continue;
case 'v':
flags |= CHECK_VERBOSE;
continue;
case 'x':
addentry(&omhead, optarg, "");
continue;
case 'y':
break;
case '?':
default:
usage();
/* NOTREACHED */
}
/* Pass option to fsck_xxxfs */
globopt[1] = i;
catopt(&options, globopt);
}
/* Don't do progress meters if we're debugging. */
if (flags & CHECK_DEBUG)
flags &= ~CHECK_PROGRESS;
/*
* If progress meters are being used, force max parallel to 1
* so the progress meter outputs don't interfere with one another.
*/
if (flags & CHECK_PROGRESS)
maxrun = 1;
argc -= optind;
argv += optind;
if (argc == 0)
return checkfstab(flags, maxrun, isok, checkfs);
#define BADTYPE(type) \
(strcmp(type, FSTAB_RO) && \
strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ))
for (; argc--; argv++) {
const char *spec, *type, *cp;
char device[MAXPATHLEN];
spec = *argv;
cp = strrchr(spec, '/');
if (cp == 0) {
(void)snprintf(device, sizeof(device), "%s%s",
_PATH_DEV, spec);
spec = device;
}
if ((fs = getfsfile(spec)) == NULL &&
(fs = getfsspec(spec)) == NULL) {
if (vfstype == NULL)
vfstype = getfslab(spec);
type = vfstype;
}
else {
spec = fs->fs_spec;
type = fs->fs_vfstype;
if (BADTYPE(fs->fs_type))
errx(FSCK_EXIT_CHECK_FAILED,
"%s has unknown file system type.",
spec);
}
rval = checkfs(type, blockcheck(spec), *argv, NULL, NULL);
if (rval > ret)
ret = rval;
}
return ret;
}
static void *
isok(struct fstab *fs)
{
if (fs->fs_passno == 0)
return NULL;
if (BADTYPE(fs->fs_type))
return NULL;
if (!selected(fs->fs_vfstype))
return NULL;
if (omitted(fs->fs_file))
return NULL;
return fs;
}
static int
checkfs(const char *vfst, const char *spec, const char *mntpt, void *auxarg,
pid_t *pidp)
{
/* List of directories containing fsck_xxx subcommands. */
static const char *edirs[] = {
#ifdef RESCUEDIR
RESCUEDIR,
#endif
_PATH_SBIN,
_PATH_USRSBIN,
#ifdef __minix
"/usr/pkg/sbin/",
#endif
NULL
};
const char ** volatile argv, **edir;
const char * volatile vfstype = vfst;
pid_t pid;
int argc, i, status, maxargc;
char *optb;
char *volatile optbuf;
char execname[MAXPATHLEN + 1], execbase1[MAXPATHLEN], execbase2[MAXPATHLEN];
const char *extra = getoptions(vfstype);
if (!strcmp(vfstype, "ufs"))
vfstype = MOUNT_UFS;
optb = NULL;
if (options)
catopt(&optb, options);
if (extra)
catopt(&optb, extra);
optbuf = optb;
maxargc = 64;
argv = emalloc(sizeof(char *) * maxargc);
(void) snprintf(execbase1, sizeof(execbase1), "fsck_%s", vfstype);
(void) snprintf(execbase2, sizeof(execbase2), "fsck.%s", vfstype);
argc = 0;
argv[argc++] = execbase1;
if (optbuf)
mangle(optbuf, &argc, &argv, &maxargc);
argv[argc++] = spec;
argv[argc] = NULL;
if (flags & (CHECK_DEBUG|CHECK_VERBOSE)) {
(void)printf("start %s %swait", mntpt,
pidp ? "no" : "");
for (i = 0; i < argc; i++)
(void)printf(" %s", argv[i]);
(void)printf("\n");
}
switch (pid = vfork()) {
case -1: /* Error. */
warn("vfork");
if (optbuf)
free(optbuf);
free(argv);
return FSCK_EXIT_CHECK_FAILED;
case 0: /* Child. */
#ifndef __minix
if ((flags & CHECK_FORCE) == 0) {
struct statvfs sfs;
/*
* if mntpt is a mountpoint of a mounted file
* system and it's mounted read-write, skip it
* unless -f is given.
*/
if ((statvfs(mntpt, &sfs) == 0) &&
(strcmp(mntpt, sfs.f_mntonname) == 0) &&
((sfs.f_flag & MNT_RDONLY) == 0)) {
printf(
"%s: file system is mounted read-write on %s; not checking\n",
spec, mntpt);
if ((flags & CHECK_PREEN) && auxarg != NULL)
_exit(FSCK_EXIT_OK); /* fsck -p */
else
_exit(FSCK_EXIT_CHECK_FAILED); /* fsck [[-p] ...] */
}
}
#endif
if (flags & CHECK_DEBUG)
_exit(FSCK_EXIT_OK);
/* Go find an executable. */
edir = edirs;
do {
(void)snprintf(execname,
sizeof(execname), "%s/%s", *edir, execbase1);
execv(execname, (char * const *)__UNCONST(argv));
if (errno != ENOENT) {
if (spec)
warn("exec %s for %s", execname, spec);
else
warn("exec %s", execname);
}
(void)snprintf(execname,
sizeof(execname), "%s/%s", *edir, execbase2);
execv(execname, (char * const *)__UNCONST(argv));
if (errno != ENOENT) {
if (spec)
warn("exec %s for %s", execname, spec);
else
warn("exec %s", execname);
}
} while (*++edir != NULL);
if (errno == ENOENT) {
if (spec)
warn("exec %s for %s", execname, spec);
else
warn("exec %s", execname);
}
_exit(FSCK_EXIT_CHECK_FAILED);
/* NOTREACHED */
default: /* Parent. */
if (optbuf)
free(optbuf);
free(argv);
if (pidp) {
*pidp = pid;
return FSCK_EXIT_OK;
}
if (waitpid(pid, &status, 0) < 0) {
warn("waitpid");
return FSCK_EXIT_CHECK_FAILED;
}
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0)
return WEXITSTATUS(status);
}
else if (WIFSIGNALED(status)) {
warnx("%s: %s", spec, strsignal(WTERMSIG(status)));
return FSCK_EXIT_CHECK_FAILED;
}
break;
}
return FSCK_EXIT_OK;
}
static int
selected(const char *type)
{
struct entry *e;
/* If no type specified, it's always selected. */
TAILQ_FOREACH(e, &selhead, entries)
if (!strcmp(e->type, type))
return which == IN_LIST ? 1 : 0;
return which == IN_LIST ? 0 : 1;
}
static int
omitted(const char *mountedon)
{
struct entry *e;
/* If no type specified, it's always selected. */
TAILQ_FOREACH(e, &omhead, entries)
if (!strcmp(e->type, mountedon))
return 1;
return 0;
}
static const char *
getoptions(const char *type)
{
struct entry *e;
TAILQ_FOREACH(e, &opthead, entries)
if (!strcmp(e->type, type))
return e->options;
return "";
}
static void
addoption(char *optstr)
{
char *newoptions;
struct entry *e;
if ((newoptions = strchr(optstr, ':')) == NULL)
errx(1, "Invalid option string");
*newoptions++ = '\0';
TAILQ_FOREACH(e, &opthead, entries)
if (!strcmp(e->type, optstr)) {
catopt(&e->options, newoptions);
return;
}
addentry(&opthead, optstr, newoptions);
}
static void
addentry(struct fstypelist *list, const char *type, const char *opts)
{
struct entry *e;
e = emalloc(sizeof(struct entry));
e->type = estrdup(type);
e->options = estrdup(opts);
TAILQ_INSERT_TAIL(list, e, entries);
}
static void
maketypelist(char *fslist)
{
char *ptr;
if ((fslist == NULL) || (fslist[0] == '\0'))
errx(1, "empty type list");
if (fslist[0] == 'n' && fslist[1] == 'o') {
fslist += 2;
which = NOT_IN_LIST;
}
else
which = IN_LIST;
while ((ptr = strsep(&fslist, ",")) != NULL)
addentry(&selhead, ptr, "");
}
static void
catopt(char **sp, const char *o)
{
char *s;
size_t i, j;
s = *sp;
if (s) {
i = strlen(s);
j = i + 1 + strlen(o) + 1;
s = erealloc(s, j);
(void)snprintf(s + i, j, ",%s", o);
} else
s = estrdup(o);
*sp = s;
}
static void
mangle(char *opts, int *argcp, const char ** volatile *argvp, int *maxargcp)
{
char *p, *s;
int argc, maxargc;
const char **argv;
argc = *argcp;
argv = *argvp;
maxargc = *maxargcp;
for (s = opts; (p = strsep(&s, ",")) != NULL;) {
/* Always leave space for one more argument and the NULL. */
if (argc >= maxargc - 3) {
maxargc <<= 1;
argv = erealloc(argv, maxargc * sizeof(char *));
}
if (*p != '\0') {
if (*p == '-') {
argv[argc++] = p;
p = strchr(p, '=');
if (p) {
*p = '\0';
argv[argc++] = p+1;
}
} else {
argv[argc++] = "-o";
argv[argc++] = p;
}
}
}
*argcp = argc;
*argvp = argv;
*maxargcp = maxargc;
}
static const char *
getfslab(const char *str)
{
static struct dkwedge_info dkw;
struct disklabel dl;
int fd;
char p;
const char *vfstype;
u_char t;
/* deduce the file system type from the disk label */
if ((fd = open(str, O_RDONLY)) == -1)
err(1, "cannot open `%s'", str);
/* First check to see if it's a wedge. */
if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == 0) {
/* Yup, this is easy. */
(void) close(fd);
return (dkw.dkw_ptype);
}
if (ioctl(fd, DIOCGDINFO, &dl) == -1)
err(1, "cannot get disklabel for `%s'", str);
(void) close(fd);
p = str[strlen(str) - 1];
if ((p - 'a') >= dl.d_npartitions)
errx(1, "partition `%s' is not defined on disk", str);
if ((t = dl.d_partitions[p - 'a'].p_fstype) >= FSMAXTYPES)
errx(1, "partition `%s' is not of a legal vfstype",
str);
if ((vfstype = fscknames[t]) == NULL)
errx(1, "vfstype `%s' on partition `%s' is not supported",
fstypenames[t], str);
return vfstype;
}
static void
usage(void)
{
static const char common[] =
"[-dfnPpqvy] [-x excludemount] [-l maxparallel] [-T fstype:fsoptions]\n\t\t[-t fstype]";
(void)fprintf(stderr, "usage: %s %s [special|node]...\n",
getprogname(), common);
exit(FSCK_EXIT_USAGE);
}

306
sbin/fsck/fsutil.c Normal file
View file

@ -0,0 +1,306 @@
/* $NetBSD: fsutil.c,v 1.20 2011/06/09 19:57:50 christos Exp $ */
/*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University 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 BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fsutil.c,v 1.20 2011/06/09 19:57:50 christos Exp $");
#endif /* not lint */
#include <sys/param.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <fstab.h>
#include <fcntl.h>
#include <unistd.h>
#include <err.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "fsutil.h"
#include "exitvalues.h"
static const char *dev = NULL;
static int hot = 0;
static int preen = 0;
int quiet;
#define F_ERROR 0x80000000
void
setcdevname(const char *cd, int pr)
{
dev = cd;
preen = pr;
}
const char *
cdevname(void)
{
return dev;
}
int
hotroot(void)
{
return hot;
}
/*VARARGS*/
void
errexit(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
(void) vfprintf(stderr, fmt, ap);
va_end(ap);
(void)fprintf(stderr, "\n");
exit(FSCK_EXIT_CHECK_FAILED);
}
void
vmsg(int fatal, const char *fmt, va_list ap)
{
int serr = fatal & F_ERROR;
int serrno = errno;
fatal &= ~F_ERROR;
if (!fatal && preen)
(void)printf("%s: ", dev);
if (quiet && !preen) {
(void)printf("** %s (vmsg)\n", dev);
quiet = 0;
}
(void) vprintf(fmt, ap);
if (serr)
printf(" (%s)", strerror(serrno));
if (fatal && preen)
(void) printf("\n");
if (fatal && preen) {
(void) printf(
"%s: UNEXPECTED INCONSISTENCY; RUN %s MANUALLY.\n",
dev, getprogname());
exit(FSCK_EXIT_CHECK_FAILED);
}
}
/*VARARGS*/
void
pfatal(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vmsg(1, fmt, ap);
va_end(ap);
}
/*VARARGS*/
void
pwarn(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vmsg(0, fmt, ap);
va_end(ap);
}
void
perr(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vmsg(1 | F_ERROR, fmt, ap);
va_end(ap);
}
void
panic(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vmsg(1, fmt, ap);
va_end(ap);
exit(FSCK_EXIT_CHECK_FAILED);
}
const char *
unrawname(const char *name)
{
static char unrawbuf[MAXPATHLEN];
const char *dp;
struct stat stb;
if ((dp = strrchr(name, '/')) == 0)
return (name);
if (stat(name, &stb) < 0)
return (name);
if (!S_ISCHR(stb.st_mode))
return (name);
if (dp[1] != 'r')
return (name);
(void)snprintf(unrawbuf, sizeof(unrawbuf), "%.*s/%s",
(int)(dp - name), name, dp + 2);
return (unrawbuf);
}
const char *
rawname(const char *name)
{
static char rawbuf[MAXPATHLEN];
const char *dp;
if ((dp = strrchr(name, '/')) == 0)
return (0);
(void)snprintf(rawbuf, sizeof(rawbuf), "%.*s/r%s",
(int)(dp - name), name, dp + 1);
return (rawbuf);
}
const char *
blockcheck(const char *origname)
{
#ifdef __minix
return origname;
#else
struct stat stslash, stblock, stchar;
const char *newname, *raw;
struct fstab *fsp;
int retried = 0;
hot = 0;
if (stat("/", &stslash) < 0) {
perr("Can't stat `/'");
return (origname);
}
newname = origname;
retry:
if (stat(newname, &stblock) < 0) {
perr("Can't stat `%s'", newname);
return (origname);
}
if (S_ISBLK(stblock.st_mode)) {
if (stslash.st_dev == stblock.st_rdev)
hot++;
raw = strdup(newname);
raw = rawname(newname);
if (stat(raw, &stchar) < 0) {
perr("Can't stat `%s'", raw);
return (origname);
}
if (S_ISCHR(stchar.st_mode)) {
return (raw);
} else {
printf("%s is not a character device\n", raw);
return (origname);
}
} else if (S_ISCHR(stblock.st_mode) && !retried) {
newname = unrawname(newname);
retried++;
goto retry;
} else if ((fsp = getfsfile(newname)) != 0 && !retried) {
newname = fsp->fs_spec;
retried++;
goto retry;
}
/*
* Not a block or character device, just return name and
* let the user decide whether to use it.
*/
return (origname);
#endif
}
const char *
print_mtime(time_t t)
{
static char b[128];
char *p = ctime(&t);
if (p != NULL)
(void)snprintf(b, sizeof(b), "%12.12s %4.4s ", &p[4], &p[20]);
else
(void)snprintf(b, sizeof(b), "%lld ", (long long)t);
return b;
}
void
catch(int n)
{
if (ckfinish) (*ckfinish)(0);
_exit(FSCK_EXIT_SIGNALLED);
}
/*
* When preening, allow a single quit to signal
* a special exit after filesystem checks complete
* so that reboot sequence may be interrupted.
*/
void
catchquit(int n)
{
static const char msg[] =
"returning to single-user after filesystem check\n";
int serrno = errno;
(void)write(STDOUT_FILENO, msg, sizeof(msg) - 1);
returntosingle = 1;
(void)signal(SIGQUIT, SIG_DFL);
errno = serrno;
}
/*
* Ignore a single quit signal; wait and flush just in case.
* Used by child processes in preen.
*/
void
voidquit(int n)
{
int serrno = errno;
sleep(1);
(void)signal(SIGQUIT, SIG_IGN);
(void)signal(SIGQUIT, SIG_DFL);
errno = serrno;
}

65
sbin/fsck/fsutil.h Normal file
View file

@ -0,0 +1,65 @@
/* $NetBSD: fsutil.h,v 1.17 2011/06/09 21:23:29 christos Exp $ */
/*
* Copyright (c) 1996 Christos Zoulas. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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.
*/
#include <stdarg.h>
#include <signal.h>
void errexit(const char *, ...)
__attribute__((__noreturn__,__format__(__printf__,1,2)));
void pfatal(const char *, ...)
__attribute__((__format__(__printf__,1,2)));
void pwarn(const char *, ...)
__attribute__((__format__(__printf__,1,2)));
void perr(const char *, ...)
__attribute__((__format__(__printf__,1,2)));
void panic(const char *, ...)
__attribute__((__noreturn__,__format__(__printf__,1,2)));
void vmsg(int, const char *, va_list)
__attribute__((__format__(__printf__,2,0)));
const char *rawname(const char *);
const char *unrawname(const char *);
const char *blockcheck(const char *);
const char *cdevname(void);
void setcdevname(const char *, int);
int hotroot(void);
const char *print_mtime(time_t);
#define CHECK_PREEN 1
#define CHECK_VERBOSE 2
#define CHECK_DEBUG 4
#define CHECK_FORCE 8
#define CHECK_PROGRESS 16
#define CHECK_NOFIX 32
struct fstab;
int checkfstab(int, int, void *(*)(struct fstab *),
int (*) (const char *, const char *, const char *, void *, pid_t *));
void (*ckfinish)(int);
volatile sig_atomic_t returntosingle;
void catch(int);
void catchquit(int);
void voidquit(int);

205
sbin/fsck/partutil.c Normal file
View file

@ -0,0 +1,205 @@
/* $NetBSD: partutil.c,v 1.10 2010/03/06 00:30:54 christos Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: partutil.c,v 1.10 2010/03/06 00:30:54 christos Exp $");
#include <sys/types.h>
#include <sys/disklabel.h>
#include <sys/disk.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <disktab.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <util.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <prop/proplib.h>
#include "partutil.h"
/*
* Convert disklabel geometry info to disk_geom.
*/
static void
label2geom(struct disk_geom *geo, const struct disklabel *lp)
{
geo->dg_secperunit = lp->d_secperunit;
geo->dg_secsize = lp->d_secsize;
geo->dg_nsectors = lp->d_nsectors;
geo->dg_ntracks = lp->d_ntracks;
geo->dg_ncylinders = lp->d_ncylinders;
geo->dg_secpercyl = lp->d_secpercyl;
geo->dg_pcylinders = lp->d_ncylinders;
geo->dg_sparespertrack = lp->d_sparespertrack;
geo->dg_sparespercyl = lp->d_sparespercyl;
geo->dg_acylinders = lp->d_acylinders;
}
/*
* Set what we need to know about disk geometry.
*/
static void
dict2geom(struct disk_geom *geo, prop_dictionary_t dict)
{
(void)memset(geo, 0, sizeof(struct disk_geom));
prop_dictionary_get_int64(dict, "sectors-per-unit",
&geo->dg_secperunit);
prop_dictionary_get_uint32(dict, "sector-size", &geo->dg_secsize);
prop_dictionary_get_uint32(dict, "sectors-per-track",
&geo->dg_nsectors);
prop_dictionary_get_uint32(dict, "tracks-per-cylinder",
&geo->dg_ntracks);
prop_dictionary_get_uint32(dict, "cylinders-per-unit",
&geo->dg_ncylinders);
}
static void
part2wedge(struct dkwedge_info *dkw, const struct disklabel *lp, const char *s)
{
struct stat sb;
const struct partition *pp;
int ptn;
(void)memset(dkw, 0, sizeof(*dkw));
if (stat(s, &sb) == -1)
return;
ptn = strchr(s, '\0')[-1] - 'a';
if ((unsigned)ptn >= lp->d_npartitions ||
(devminor_t)ptn != DISKPART(sb.st_rdev))
return;
pp = &lp->d_partitions[ptn];
dkw->dkw_offset = pp->p_offset;
dkw->dkw_size = pp->p_size;
dkw->dkw_parent[0] = '*';
switch (pp->p_fstype) {
default:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_UNKNOWN);
break;
case FS_UNUSED:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_UNUSED);
break;
case FS_SWAP:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_SWAP);
break;
case FS_BSDFFS:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_FFS);
break;
case FS_BSDLFS:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_LFS);
break;
case FS_EX2FS:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_EXT2FS);
break;
case FS_ISO9660:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_ISO9660);
break;
case FS_ADOS:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_AMIGADOS);
break;
case FS_HFS:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_APPLEHFS);
break;
case FS_MSDOS:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_FAT);
break;
case FS_FILECORE:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_FILECORE);
break;
case FS_APPLEUFS:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_APPLEUFS);
break;
case FS_NTFS:
(void)strcpy(dkw->dkw_ptype, DKW_PTYPE_NTFS);
break;
}
}
int
getdiskinfo(const char *s, int fd, const char *dt, struct disk_geom *geo,
struct dkwedge_info *dkw)
{
struct disklabel lab;
struct disklabel *lp = &lab;
prop_dictionary_t disk_dict, geom_dict;
if (dt) {
#ifdef __minix
errx(1, "minix doesn't know about disk types (%s)", dt);
#else
lp = getdiskbyname(dt);
if (lp == NULL)
errx(1, "unknown disk type `%s'", dt);
#endif
}
/* Get disk description dictionary */
#ifndef __minix
if (prop_dictionary_recv_ioctl(fd, DIOCGDISKINFO, &disk_dict)) {
#else
if (-1) {
#endif
/*
* Ask for disklabel if DIOCGDISKINFO failed. This is
* compatibility call and can be removed when all devices
* will support DIOCGDISKINFO.
* cgd, ccd pseudo disk drives doesn't support DIOCGDDISKINFO
*/
if (ioctl(fd, DIOCGDINFO, lp) == -1) {
warn("DIOCGDINFO on %s failed", s);
return -1;
}
label2geom(geo, lp);
} else {
geom_dict = prop_dictionary_get(disk_dict, "geometry");
dict2geom(geo, geom_dict);
}
/* Get info about partition/wedge */
if (ioctl(fd, DIOCGWEDGEINFO, dkw) == -1) {
if (ioctl(fd, DIOCGDINFO, lp) == -1)
err(1, "Please implement DIOCGWEDGEINFO or "
"DIOCGDINFO for disk device %s", s);
part2wedge(dkw, lp, s);
}
return 0;
}

39
sbin/fsck/partutil.h Normal file
View file

@ -0,0 +1,39 @@
/* $NetBSD: partutil.h,v 1.2 2008/04/28 20:23:08 martin Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION 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.
*/
#ifndef _PARTUTIL_H_
#define _PARTUTIL_H_
__BEGIN_DECLS
int getdiskinfo(const char *, int, const char *,
struct disk_geom *, struct dkwedge_info *);
__END_DECLS
#endif /* _PARTUTIL_H_ */

28
sbin/fsck/pathnames.h Normal file
View file

@ -0,0 +1,28 @@
/* $NetBSD: pathnames.h,v 1.2 2009/10/21 01:07:46 snj Exp $ */
/*
* Copyright (c) 1996 Christos Zoulas. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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.
*/
#define _PATH_SBIN "/sbin"
#define _PATH_USRSBIN "/usr/sbin"

363
sbin/fsck/preen.c Normal file
View file

@ -0,0 +1,363 @@
/* $NetBSD: preen.c,v 1.30 2008/02/23 21:41:47 christos Exp $ */
/*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University 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 BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: preen.c,v 1.30 2008/02/23 21:41:47 christos Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/queue.h>
#include <sys/disk.h>
#include <sys/ioctl.h>
#include <err.h>
#include <ctype.h>
#include <fstab.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <util.h>
#include "fsutil.h"
#include "exitvalues.h"
struct partentry {
TAILQ_ENTRY(partentry) p_entries;
char *p_devname; /* device name */
char *p_mntpt; /* mount point */
char *p_type; /* file system type */
void *p_auxarg; /* auxiliary argument */
};
TAILQ_HEAD(part, partentry) badh;
struct diskentry {
TAILQ_ENTRY(diskentry) d_entries;
char *d_name; /* disk base name */
TAILQ_HEAD(prt, partentry) d_part; /* list of partitions on disk */
int d_pid; /* 0 or pid of fsck proc */
};
TAILQ_HEAD(diskinfo, diskentry) diskh;
static int nrun = 0, ndisks = 0;
static struct diskentry *finddisk(const char *);
static void addpart(const char *, const char *, const char *, void *);
static int startdisk(struct diskentry *,
int (*)(const char *, const char *, const char *, void *, pid_t *));
static void printpart(void);
int
checkfstab(int flags, int maxrun, void *(*docheck)(struct fstab *),
int (*checkit)(const char *, const char *, const char *, void *, pid_t *))
{
struct fstab *fs;
struct diskentry *d, *nextdisk;
struct partentry *p;
int ret, pid, retcode, passno, sumstatus, status;
void *auxarg;
const char *name;
int error = FSCK_EXIT_OK;
TAILQ_INIT(&badh);
TAILQ_INIT(&diskh);
sumstatus = FSCK_EXIT_OK;
for (passno = 1; passno <= 2; passno++) {
if (setfsent() == 0) {
warnx("Can't open checklist file: %s", _PATH_FSTAB);
return FSCK_EXIT_CHECK_FAILED;
}
while ((fs = getfsent()) != 0) {
if ((auxarg = (*docheck)(fs)) == NULL)
continue;
name = blockcheck(fs->fs_spec);
if (flags & CHECK_DEBUG)
printf("pass %d, name %s\n", passno, name);
if ((flags & CHECK_PREEN) == 0 ||
(passno == 1 && fs->fs_passno == 1)) {
if (name == NULL) {
if (flags & CHECK_PREEN)
return FSCK_EXIT_CHECK_FAILED;
else
continue;
}
sumstatus = (*checkit)(fs->fs_vfstype,
name, fs->fs_file, auxarg, NULL);
if (sumstatus) {
if ((flags & CHECK_NOFIX) == 0)
return sumstatus;
else if (error < sumstatus)
error = sumstatus;
}
} else if (passno == 2 && fs->fs_passno > 1) {
if (name == NULL) {
(void) fprintf(stderr,
"BAD DISK NAME %s\n", fs->fs_spec);
sumstatus = FSCK_EXIT_CHECK_FAILED;
continue;
}
addpart(fs->fs_vfstype, name, fs->fs_file,
auxarg);
}
}
if ((flags & CHECK_PREEN) == 0)
return error;
}
if (flags & CHECK_DEBUG)
printpart();
if (flags & CHECK_PREEN) {
if (maxrun == 0)
maxrun = ndisks;
if (maxrun > ndisks)
maxrun = ndisks;
nextdisk = TAILQ_FIRST(&diskh);
for (passno = 0; passno < maxrun; ++passno) {
if ((ret = startdisk(nextdisk, checkit)) != 0) {
if ((flags & CHECK_NOFIX) == 0)
return ret;
else if (error < ret)
error = ret;
}
nextdisk = TAILQ_NEXT(nextdisk, d_entries);
}
while ((pid = wait(&status)) != -1) {
TAILQ_FOREACH(d, &diskh, d_entries)
if (d->d_pid == pid)
break;
if (d == NULL) {
warnx("Unknown pid %d", pid);
continue;
}
if (WIFEXITED(status))
retcode = WEXITSTATUS(status);
else
retcode = 0;
p = TAILQ_FIRST(&d->d_part);
if (flags & (CHECK_DEBUG|CHECK_VERBOSE))
(void) printf("done %s: %s (%s) = 0x%x\n",
p->p_type, p->p_devname, p->p_mntpt,
status);
if (WIFSIGNALED(status)) {
(void) fprintf(stderr,
"%s: %s (%s): EXITED WITH SIGNAL %d\n",
p->p_type, p->p_devname, p->p_mntpt,
WTERMSIG(status));
retcode = FSCK_EXIT_SIGNALLED;
}
TAILQ_REMOVE(&d->d_part, p, p_entries);
if (retcode != 0) {
TAILQ_INSERT_TAIL(&badh, p, p_entries);
sumstatus |= retcode;
} else {
free(p->p_type);
free(p->p_devname);
free(p);
}
d->d_pid = 0;
nrun--;
if (TAILQ_FIRST(&d->d_part) == NULL)
ndisks--;
if (nextdisk == NULL) {
if (TAILQ_FIRST(&d->d_part) != NULL) {
if ((ret = startdisk(d, checkit)) != 0)
{
if ((flags & CHECK_NOFIX) == 0)
return ret;
else if (error < ret)
error = ret;
}
}
} else if (nrun < maxrun && nrun < ndisks) {
for ( ;; ) {
nextdisk = TAILQ_NEXT(nextdisk,
d_entries);
if (nextdisk == NULL)
nextdisk = TAILQ_FIRST(&diskh);
if (TAILQ_FIRST(&nextdisk->d_part)
!= NULL && nextdisk->d_pid == 0)
break;
}
if ((ret = startdisk(nextdisk, checkit)) != 0)
{
if ((flags & CHECK_NOFIX) == 0)
return ret;
else if (error < ret)
error = ret;
}
}
}
}
if (sumstatus) {
p = TAILQ_FIRST(&badh);
if (p == NULL)
return sumstatus;
(void) fprintf(stderr,
"THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t",
TAILQ_NEXT(p, p_entries) ? "S" : "",
"UNEXPECTED INCONSISTENCY:");
TAILQ_FOREACH(p, &badh, p_entries)
(void) fprintf(stderr,
"%s: %s (%s)%s", p->p_type, p->p_devname,
p->p_mntpt, TAILQ_NEXT(p, p_entries) ? ", " : "\n");
return sumstatus;
}
(void) endfsent();
return error;
}
static struct diskentry *
finddisk(const char *name)
{
const char *p;
size_t len, dlen;
struct diskentry *d;
char buf[MAXPATHLEN];
struct dkwedge_info dkw;
int fd;
#ifndef __minix
if ((fd = opendisk(name, O_RDONLY, buf, sizeof(buf), 0)) != -1) {
if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1)
name = dkw.dkw_parent;
(void)close(fd);
}
#endif
for (dlen = len = strlen(name), p = name + len - 1; p >= name; --p)
if (isdigit((unsigned char)*p)) {
len = p - name + 1;
break;
}
if (p < name)
len = dlen;
TAILQ_FOREACH(d, &diskh, d_entries)
if (strncmp(d->d_name, name, len) == 0 && d->d_name[len] == 0)
return d;
d = emalloc(sizeof(*d));
d->d_name = estrdup(name);
d->d_name[len] = '\0';
TAILQ_INIT(&d->d_part);
d->d_pid = 0;
TAILQ_INSERT_TAIL(&diskh, d, d_entries);
ndisks++;
return d;
}
static void
printpart(void)
{
struct diskentry *d;
struct partentry *p;
TAILQ_FOREACH(d, &diskh, d_entries) {
(void) printf("disk %s:", d->d_name);
TAILQ_FOREACH(p, &d->d_part, p_entries)
(void) printf(" %s", p->p_devname);
(void) printf("\n");
}
}
static void
addpart(const char *type, const char *dev, const char *mntpt, void *auxarg)
{
struct diskentry *d = finddisk(dev);
struct partentry *p;
TAILQ_FOREACH(p, &d->d_part, p_entries)
if (strcmp(p->p_devname, dev) == 0) {
warnx("%s in fstab more than once!", dev);
return;
}
p = emalloc(sizeof(*p));
p->p_devname = estrdup(dev);
p->p_mntpt = estrdup(mntpt);
p->p_type = estrdup(type);
p->p_auxarg = auxarg;
TAILQ_INSERT_TAIL(&d->d_part, p, p_entries);
}
static int
startdisk(struct diskentry *d,
int (*checkit)(const char *, const char *, const char *, void *, pid_t *))
{
struct partentry *p = TAILQ_FIRST(&d->d_part);
int rv;
while ((rv = (*checkit)(p->p_type, p->p_devname, p->p_mntpt,
p->p_auxarg, &d->d_pid)) != 0 && nrun > 0)
sleep(10);
if (rv == 0)
nrun++;
return rv;
}

168
sbin/fsck/progress.c Normal file
View file

@ -0,0 +1,168 @@
/* $NetBSD: progress.c,v 1.5 2009/04/11 06:48:36 lukem Exp $ */
/*-
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn; by Chris Gilbert; and by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION 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.
*/
#ifndef SMALL
#include <sys/cdefs.h>
__RCSID("$NetBSD: progress.c,v 1.5 2009/04/11 06:48:36 lukem Exp $");
/*
* File system independent fsck progress bar routines.
*/
#include <sys/param.h>
#include <sys/tty.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "progress.h"
static size_t ttywidth = 80;
static int progress_onoff;
static int progress_lowlim;
static int progress_highlim;
#define BUFLEFT (sizeof(buf) - len)
void
progress_switch(int onoff)
{
progress_onoff = onoff;
}
void
progress_init(void)
{
progress_setrange(0, 100);
}
/* Set both low and high limit. */
void
progress_setrange(int lowlim, int highlim)
{
progress_lowlim = lowlim;
progress_highlim = highlim;
}
/* Previous high limit becomes new low limit; set new high limit. */
void
progress_sethighlim(int highlim)
{
progress_setrange(progress_highlim, highlim);
}
/*
* Display a progress bar, assuming that current/total represents a
* percentage in the range [progress_lowlim .. progress_highlim].
*/
void
progress_bar(const char *dev, const char *label, off_t current, off_t total)
{
static int lastpercentage = -1;
char buf[256];
int len, percentage;
int barlength;
int i;
int lengthextras;
#define BAROVERHEAD 10 /* non-* portion of progress bar */
/*
* stars should contain at least sizeof(buf) - BAROVERHEAD
* entries.
*/
static const char stars[] =
"*****************************************************************************"
"*****************************************************************************"
"*****************************************************************************";
if (progress_onoff == 0)
return;
len = 0;
lengthextras = strlen(dev) + (label != NULL ? strlen(label) : 0);
percentage = progress_lowlim +
(current * (progress_highlim - progress_lowlim)) / total;
percentage = MAX(percentage, 0);
percentage = MIN(percentage, 100);
if (percentage == lastpercentage)
return;
lastpercentage = percentage;
len += snprintf(buf + len, BUFLEFT, "%s: ", dev);
if (label != NULL)
len += snprintf(buf + len, BUFLEFT, "%s ", label);
barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD - lengthextras;
if (barlength > 0) {
i = barlength * percentage / 100;
len += snprintf(buf + len, BUFLEFT,
"|%.*s%*s| ", i, stars, barlength - i, "");
}
len += snprintf(buf + len, BUFLEFT, "%3d%%\r", percentage);
write(fileno(stdout), buf, len);
}
void
progress_done(void)
{
char buf[256];
int len;
if (progress_onoff == 0)
return;
len = MIN(sizeof(buf) - 2, ttywidth);
memset(buf, ' ', len);
buf[len] = '\r';
buf[len + 1] = '\0';
write(fileno(stdout), buf, len + 1);
}
void
progress_ttywidth(int a)
{
struct winsize winsize;
int oerrno = errno;
if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1 &&
winsize.ws_col != 0)
ttywidth = winsize.ws_col;
else
ttywidth = 80;
errno = oerrno;
}
#endif /* ! SMALL */

42
sbin/fsck/progress.h Normal file
View file

@ -0,0 +1,42 @@
/* $NetBSD: progress.h,v 1.3 2008/04/28 20:23:08 martin Exp $ */
/*-
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn; by Chris Gilbert; and by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION 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.
*/
/*
* File system independent fsck progress bar routines.
*/
void progress_init(void);
void progress_setrange(int, int);
void progress_sethighlim(int);
void progress_switch(int);
void progress_ttywidth(int);
void progress_bar(const char *, const char *, off_t, off_t);
void progress_done(void);

View file

@ -1,4 +1,11 @@
common/lib/libprop src/common/lib/libprop
nbsd_include/ufs src/sys/ufs
sbin/newfs_ext2fs src/sbin/newfs_ext2fs
sbin/fsck_ext2fs src/sbin/fsck_ext2fs
lib/libprop src/lib/libprop
common/include/arch/x86 src/sys/arch/x86/include
common/include/arch/i386 src/sys/arch/i386/include
common/include src/common/include
common/lib/libc src/common/lib/libc
lib/nbsd_libc src/lib/libc
lib/nbsd_libm src/lib/libm
@ -10,6 +17,7 @@ common/lib/libutil src/common/lib/libutil
lib/libbz2 src/lib/libbz2
nbsd_include src/include
bin/mkdir src/bin/mkdir
usr.sbin/fsck src/usr.sbin/fsck
usr.bin/chpass src/usr.bin/chpass
usr.bin/m4 src/usr.bin/m4
usr.bin/indent src/usr.bin/indent