summaryrefslogtreecommitdiffstats
path: root/disk-utils
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:41 +0100
committerKarel Zak2006-12-07 00:25:41 +0100
commiteb63b9b8f4cecb34c2478282567862bc48ef256d (patch)
tree99243f8eecb44c2bb6a559982b99c680fcb649e7 /disk-utils
parentImported from util-linux-2.9v tarball. (diff)
downloadkernel-qcow2-util-linux-eb63b9b8f4cecb34c2478282567862bc48ef256d.tar.gz
kernel-qcow2-util-linux-eb63b9b8f4cecb34c2478282567862bc48ef256d.tar.xz
kernel-qcow2-util-linux-eb63b9b8f4cecb34c2478282567862bc48ef256d.zip
Imported from util-linux-2.10f tarball.
Diffstat (limited to 'disk-utils')
-rw-r--r--disk-utils/Makefile36
-rw-r--r--disk-utils/blockdev.c220
-rw-r--r--disk-utils/fdformat.c20
-rw-r--r--disk-utils/fsck.minix.c88
-rw-r--r--disk-utils/mkfs.bfs.848
-rw-r--r--disk-utils/mkfs.bfs.c284
-rw-r--r--disk-utils/mkfs.c14
-rw-r--r--disk-utils/mkfs.minix.844
-rw-r--r--disk-utils/mkfs.minix.c26
-rw-r--r--disk-utils/mkswap.831
-rw-r--r--disk-utils/mkswap.c166
-rw-r--r--disk-utils/raw.887
-rw-r--r--disk-utils/raw.c217
-rw-r--r--disk-utils/setfdprm.c23
14 files changed, 1138 insertions, 166 deletions
diff --git a/disk-utils/Makefile b/disk-utils/Makefile
index b170e81ee..36f5e616f 100644
--- a/disk-utils/Makefile
+++ b/disk-utils/Makefile
@@ -1,49 +1,53 @@
# Makefile -- Makefile for util-linux Linux utilities
# Created: Sat Dec 26 20:09:40 1992
-# Revised: Fri Oct 6 21:02:21 1995 by r.faith@ieee.org
# Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
-#
+
include ../make_include
include ../MCONFIG
# Where to put man pages?
-MAN8= fdformat.8 mkswap.8 setfdprm.8
+MAN8= fdformat.8 mkfs.8 mkswap.8
# Where to put binaries?
# See the "install" rule for the links. . .
-SBIN= mkfs mkswap
+SBIN= mkfs mkswap blockdev
-USRBIN= fdformat setfdprm
+USRBIN= fdformat
ETC= fdprm
ifneq "$(CPU)" "sparc"
# fsck and mkfs will compile, but there is no kernel support on sparc
-MAN8:=$(MAN8) fsck.minix.8 mkfs.8 mkfs.minix.8
-SBIN:=$(SBIN) fsck.minix mkfs.minix
+MAN8:=$(MAN8) fsck.minix.8 mkfs.minix.8 mkfs.bfs.8
+SBIN:=$(SBIN) fsck.minix mkfs.minix mkfs.bfs
endif
-# Where to put datebase files?
+ifneq "$(HAVE_FDUTILS)" "yes"
+USRBIN:=$(USRBIN) setfdprm
+MAN8:=$(MAN8) setfdprm.8
+endif
+
+# raw.c does not compile on 2.2.*.
+# find out later where it does and add tests to config
+ifeq "$(ADD_RAW)" "yes"
+USRBIN:=$(USRBIN) raw
+MAN8:=$(MAN8) raw.8
+endif
all: $(SBIN) $(USRBIN)
-fdformat: fdformat.o
-fsck.minix: fsck.minix.o
-fsck.minix.o: fsck.minix.c bitops.h
-mkfs: mkfs.o
-mkfs.minix: mkfs.minix.o
-mkfs.minix.o: mkfs.minix.c bitops.h
-mkswap: mkswap.o
-setfdprm: setfdprm.o
+fsck.minix.o mkfs.minix.o: bitops.h
install: all
$(INSTALLDIR) $(SBINDIR) $(USRBINDIR) $(ETCDIR)
$(INSTALLBIN) $(SBIN) $(SBINDIR)
$(INSTALLBIN) $(USRBIN) $(USRBINDIR)
+ifneq "$(HAVE_FDUTILS)" "yes"
$(INSTALLDAT) $(ETC) $(ETCDIR)
+endif
$(INSTALLDIR) $(MAN8DIR)
$(INSTALLMAN) $(MAN8) $(MAN8DIR)
diff --git a/disk-utils/blockdev.c b/disk-utils/blockdev.c
new file mode 100644
index 000000000..7f1fd7bb8
--- /dev/null
+++ b/disk-utils/blockdev.c
@@ -0,0 +1,220 @@
+/*
+ * blockdev.c --- Do various simple block device ioctls from the command line
+ * aeb, 991028
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#include <linux/fs.h>
+#include "nls.h"
+
+const char *progname;
+
+struct bdc {
+ char *name;
+ char *iocname;
+ long ioc;
+ int argtype;
+#define ARGNONE 0
+#define ARGINTA 1
+#define ARGINTP 2
+#define ARGINTG 3
+#define ARGLINTG 4
+ long argval;
+ char *argname;
+ char *help;
+} bdcms[] = {
+#ifdef BLKROSET
+ { "--setro", "BLKROSET", BLKROSET, ARGINTP, 1, NULL, N_("set read-only") },
+ { "--setrw", "BLKROSET", BLKROSET, ARGINTP, 0, NULL, N_("set read-write") },
+#endif
+#ifdef BLKROGET
+ { "--getro", "BLKROGET", BLKROGET, ARGINTG, -1, NULL, N_("get read-only") },
+#endif
+#ifdef BLKSSZGET
+ { "--getss", "BLKSSZGET", BLKSSZGET, ARGINTG, -1, NULL, N_("get sectorsize") },
+#endif
+#ifdef BLKGETSIZE
+ { "--getsize", "BLKGETSIZE", BLKGETSIZE, ARGLINTG, -1, NULL, N_("get size") },
+#endif
+#ifdef BLKRASET
+ { "--setra", "BLKRASET", BLKRASET, ARGINTA, 0, "READAHEAD", N_("set readahead") },
+#endif
+#ifdef BLKRAGET
+ { "--getra", "BLKRAGET", BLKRAGET, ARGLINTG, -1, NULL, N_("get readahead") },
+#endif
+#ifdef BLKFLSBUF
+ { "--flushbufs", "BLKFLSBUF", BLKFLSBUF, ARGNONE, 0, NULL, N_("flush buffers") },
+#endif
+#ifdef BLKRRPART
+ { "--rereadpt", "BLKRRPART", BLKRRPART, ARGNONE, 0, NULL,
+ N_("reread partition table") },
+#endif
+};
+
+#define SIZE(a) (sizeof(a)/sizeof((a)[0]))
+
+static void
+usage(void) {
+ int i;
+ fprintf(stderr, _("Usage: %s [-V] [-v|-q] commands devices\n"), progname);
+ fprintf(stderr, _("Available commands:\n"));
+ for (i = 0; i < SIZE(bdcms); i++) {
+ fprintf(stderr, "\t%s", bdcms[i].name);
+ if (bdcms[i].argname)
+ fprintf(stderr, " %s", bdcms[i].argname);
+ if (bdcms[i].help)
+ fprintf(stderr, "\t(%s)", _(bdcms[i].help));
+ fprintf(stderr, "\n");
+ }
+ exit(1);
+}
+
+int
+find_cmd(char *s) {
+ int j;
+
+ for (j = 0; j < SIZE(bdcms); j++)
+ if (!strcmp(s, bdcms[j].name))
+ return j;
+ return -1;
+}
+
+void do_commands(int fd, char **argv, int d);
+
+int
+main(int argc, char **argv) {
+ int fd, d, j, k;
+ char *p;
+
+ /* egcs-2.91.66 is buggy and says:
+ blockdev.c:93: warning: `d' might be used uninitialized */
+ d = 0;
+
+ progname = argv[0];
+ if ((p = strrchr(progname, '/')) != NULL)
+ progname = p+1;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (argc < 2)
+ usage();
+
+ /* -V not together with commands */
+ if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) {
+ printf("%s from %s\n", progname, util_linux_version);
+ exit(0);
+ }
+
+ /* do each of the commands on each of the devices */
+ /* devices start after last command */
+ for (d = 1; d < argc; d++) {
+ j = find_cmd(argv[d]);
+ if (j >= 0) {
+ if (bdcms[j].argtype == ARGINTA)
+ d++;
+ continue;
+ }
+ if (!strcmp(argv[d], "--")) {
+ d++;
+ break;
+ }
+ if (argv[d][0] != '-')
+ break;
+ }
+
+ if (d >= argc)
+ usage();
+
+ for (k = d; k < argc; k++) {
+ fd = open(argv[k], O_RDONLY, 0);
+ if (fd < 0) {
+ perror(argv[k]);
+ exit(1);
+ }
+ do_commands(fd, argv, d);
+ }
+ return 0;
+}
+
+void
+do_commands(int fd, char **argv, int d) {
+ int res, i, j;
+ int iarg;
+ long larg;
+ int verbose = 0;
+
+ for (i = 1; i < d; i++) {
+ if (!strcmp(argv[i], "-v")) {
+ verbose = 1;
+ continue;
+ }
+ if (!strcmp(argv[i], "-q")) {
+ verbose = 0;
+ continue;
+ }
+
+ j = find_cmd(argv[i]);
+ if (j == -1) {
+ fprintf(stderr, _("%s: Unknown command: %s\n"), progname, argv[i]);
+ usage();
+ }
+
+ switch(bdcms[j].argtype) {
+ default:
+ case ARGNONE:
+ res = ioctl(fd, bdcms[j].ioc, 0);
+ break;
+ case ARGINTA:
+ if (i == d-1) {
+ fprintf(stderr, _("%s requires an argument\n"),
+ bdcms[j].name);
+ usage();
+ }
+ iarg = atoi(argv[++i]);
+ res = ioctl(fd, bdcms[j].ioc, iarg);
+ break;
+ case ARGINTP:
+ case ARGINTG:
+ iarg = bdcms[j].argval;
+ res = ioctl(fd, bdcms[j].ioc, &iarg);
+ break;
+ case ARGLINTG:
+ larg = bdcms[j].argval;
+ res = ioctl(fd, bdcms[j].ioc, &larg);
+ break;
+ }
+ if (res == -1) {
+ perror(bdcms[j].iocname);
+ if (verbose)
+ printf("%s failed.\n", _(bdcms[j].help));
+ exit(1);
+ }
+ switch(bdcms[j].argtype) {
+ case ARGINTG:
+ if (verbose)
+ printf("%s: %d\n", _(bdcms[j].help), iarg);
+ else
+ printf("%d\n", iarg);
+ break;
+ case ARGLINTG:
+ if (verbose)
+ printf("%s: %ld\n", _(bdcms[j].help), larg);
+ else
+ printf("%ld\n", larg);
+ break;
+ default:
+ if (verbose)
+ printf("%s succeeded.\n", _(bdcms[j].help));
+ break;
+ }
+ }
+}
diff --git a/disk-utils/fdformat.c b/disk-utils/fdformat.c
index bb4f0a1f5..6c3ef5c91 100644
--- a/disk-utils/fdformat.c
+++ b/disk-utils/fdformat.c
@@ -101,22 +101,31 @@ static void usage(char *name)
int main(int argc,char **argv)
{
int verify;
- char *name;
struct stat st;
+ char *progname, *p;
+
+ progname = argv[0];
+ if ((p = strrchr(progname, '/')) != NULL)
+ progname = p+1;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- name = argv[0];
+ if (argc == 2 &&
+ (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
+ printf(_("%s from %s\n"), progname, util_linux_version);
+ exit(0);
+ }
+
verify = 1;
if (argc > 1 && argv[1][0] == '-') {
- if (argv[1][1] != 'n') usage(name);
+ if (argv[1][1] != 'n') usage(progname);
verify = 0;
argc--;
argv++;
}
- if (argc != 2) usage(name);
+ if (argc != 2) usage(progname);
if (stat(argv[1],&st) < 0) PERROR(argv[1]);
if (!S_ISBLK(st.st_mode) || MAJOR(st.st_rdev) != FLOPPY_MAJOR) {
fprintf(stderr,_("%s: not a floppy device\n"),argv[1]);
@@ -127,7 +136,8 @@ int main(int argc,char **argv)
if (ioctl(ctrl,FDGETPRM,(long) &param) < 0)
PERROR(_("Could not determine current format type"));
printf(_("%s-sided, %d tracks, %d sec/track. Total capacity %d kB.\n"),
- param.head ? _("Double") : _("Single"),param.track,param.sect,param.size >> 1);
+ param.head ? _("Double") : _("Single"),
+ param.track, param.sect,param.size >> 1);
format_disk(argv[1]);
if (verify) verify_disk(argv[1]);
return 0;
diff --git a/disk-utils/fsck.minix.c b/disk-utils/fsck.minix.c
index 416c178cb..99a8ca853 100644
--- a/disk-utils/fsck.minix.c
+++ b/disk-utils/fsck.minix.c
@@ -98,7 +98,6 @@
#include <linux/fs.h>
#include <linux/minix_fs.h>
-#include "../version.h"
#include "nls.h"
#ifdef MINIX2_SUPER_MAGIC2
@@ -125,7 +124,6 @@
#define BITS_PER_BLOCK (BLOCK_SIZE<<3)
static char * program_name = "fsck.minix";
-static char * program_version = "1.2 - 11/11/96";
static char * device_name = NULL;
static int IN;
static int repair=0, automatic=0, verbose=0, list=0, show=0, warn_mode=0,
@@ -185,17 +183,25 @@ void recursive_check2(unsigned int ino);
#define mark_zone(x) (setbit(zone_map,(x)-FIRSTZONE+1),changed=1)
#define unmark_zone(x) (clrbit(zone_map,(x)-FIRSTZONE+1),changed=1)
-void fatal_error(const char *, int) __attribute__ ((noreturn));
-void fatal_error(const char * fmt_string, int status)
+void leave(int) __attribute__ ((noreturn));
+void leave(int status)
{
- fprintf(stderr,fmt_string,program_name,device_name);
if (termios_set)
tcsetattr(0, TCSANOW, &termios);
exit(status);
}
-#define usage() fatal_error(_("Usage: %s [-larvsmf] /dev/name\n"),16)
-#define die(str) fatal_error(_("%s: " str "\n"),8)
+void usage(void) {
+ fprintf(stderr,
+ _("Usage: %s [-larvsmf] /dev/name\n"),
+ program_name);
+ leave(16);
+}
+
+void die(const char *str) {
+ fprintf(stderr, "%s: %s\n", program_name, str);
+ leave(8);
+}
/*
* This simply goes through the file-name data and prints out the
@@ -381,7 +387,7 @@ void write_block(unsigned int nr, char * addr)
return;
}
if (BLOCK_SIZE*nr != lseek(IN, BLOCK_SIZE*nr, SEEK_SET))
- die("seek failed in write_block");
+ die(_("seek failed in write_block"));
if (BLOCK_SIZE != write(IN, addr, BLOCK_SIZE)) {
printf(_("Write error: bad block in file '"));
print_current_name();
@@ -502,9 +508,9 @@ void write_super_block(void)
Super.s_state &= ~MINIX_ERROR_FS;
if (BLOCK_SIZE != lseek(IN, BLOCK_SIZE, SEEK_SET))
- die("seek failed in write_super_block");
+ die(_("seek failed in write_super_block"));
if (BLOCK_SIZE != write(IN, super_block_buffer, BLOCK_SIZE))
- die("unable to write super-block");
+ die(_("unable to write super-block"));
return;
}
@@ -514,11 +520,11 @@ void write_tables(void)
write_super_block();
if (IMAPS*BLOCK_SIZE != write(IN,inode_map,IMAPS*BLOCK_SIZE))
- die("Unable to write inode map");
+ die(_("Unable to write inode map"));
if (ZMAPS*BLOCK_SIZE != write(IN,zone_map,ZMAPS*BLOCK_SIZE))
- die("Unable to write zone map");
+ die(_("Unable to write zone map"));
if (INODE_BUFFER_SIZE != write(IN,inode_buffer,INODE_BUFFER_SIZE))
- die("Unable to write inodes");
+ die(_("Unable to write inodes"));
}
void get_dirsize (void)
@@ -547,9 +553,9 @@ void get_dirsize (void)
void read_superblock(void)
{
if (BLOCK_SIZE != lseek(IN, BLOCK_SIZE, SEEK_SET))
- die("seek failed");
+ die(_("seek failed"));
if (BLOCK_SIZE != read(IN, super_block_buffer, BLOCK_SIZE))
- die("unable to read super block");
+ die(_("unable to read super block"));
if (MAGIC == MINIX_SUPER_MAGIC) {
namelen = 14;
dirsize = 16;
@@ -569,20 +575,20 @@ void read_superblock(void)
version2 = 1;
#endif
} else
- die("bad magic number in super-block");
+ die(_("bad magic number in super-block"));
if (ZONESIZE != 0 || BLOCK_SIZE != 1024)
- die("Only 1k blocks/zones supported");
+ die(_("Only 1k blocks/zones supported"));
if (IMAPS * BLOCK_SIZE * 8 < INODES + 1)
- die("bad s_imap_blocks field in super-block");
+ die(_("bad s_imap_blocks field in super-block"));
if (ZMAPS * BLOCK_SIZE * 8 < ZONES - FIRSTZONE + 1)
- die("bad s_zmap_blocks field in super-block");
+ die(_("bad s_zmap_blocks field in super-block"));
}
void read_tables(void)
{
inode_map = malloc(IMAPS * BLOCK_SIZE);
if (!inode_map)
- die("Unable to allocate buffer for inode map");
+ die(_("Unable to allocate buffer for inode map"));
zone_map = malloc(ZMAPS * BLOCK_SIZE);
if (!inode_map)
die("Unable to allocate buffer for zone map");
@@ -590,19 +596,19 @@ void read_tables(void)
memset(zone_map,0,sizeof(zone_map));
inode_buffer = malloc(INODE_BUFFER_SIZE);
if (!inode_buffer)
- die("Unable to allocate buffer for inodes");
+ die(_("Unable to allocate buffer for inodes"));
inode_count = malloc(INODES + 1);
if (!inode_count)
- die("Unable to allocate buffer for inode count");
+ die(_("Unable to allocate buffer for inode count"));
zone_count = malloc(ZONES);
if (!zone_count)
- die("Unable to allocate buffer for zone count");
+ die(_("Unable to allocate buffer for zone count"));
if (IMAPS*BLOCK_SIZE != read(IN,inode_map,IMAPS*BLOCK_SIZE))
- die("Unable to read inode map");
+ die(_("Unable to read inode map"));
if (ZMAPS*BLOCK_SIZE != read(IN,zone_map,ZMAPS*BLOCK_SIZE))
- die("Unable to read zone map");
+ die(_("Unable to read zone map"));
if (INODE_BUFFER_SIZE != read(IN,inode_buffer,INODE_BUFFER_SIZE))
- die("Unable to read inodes");
+ die(_("Unable to read inodes"));
if (NORM_FIRSTZONE != FIRSTZONE) {
printf(_("Warning: Firstzone != Norm_firstzone\n"));
errors_uncorrected = 1;
@@ -723,7 +729,7 @@ void check_root(void)
struct minix_inode * inode = Inode + ROOT_INO;
if (!inode || !S_ISDIR(inode->i_mode))
- die("root inode isn't a directory");
+ die(_("root inode isn't a directory"));
}
#ifdef HAVE_MINIX2
@@ -1065,7 +1071,7 @@ void recursive_check(unsigned int ino)
dir = Inode + ino;
if (!S_ISDIR(dir->i_mode))
- die("internal error");
+ die(_("internal error"));
if (dir->i_size < 2 * dirsize) {
print_current_name();
printf(_(": bad directory: size<32"));
@@ -1100,7 +1106,7 @@ int bad_zone(int i)
char buffer[1024];
if (BLOCK_SIZE*i != lseek(IN, BLOCK_SIZE*i, SEEK_SET))
- die("seek failed in bad_zone");
+ die(_("seek failed in bad_zone"));
return (BLOCK_SIZE != read(IN, buffer, BLOCK_SIZE));
}
@@ -1234,19 +1240,27 @@ int main(int argc, char ** argv)
struct termios tmp;
int count;
int retcode = 0;
+ char *p;
+
+ program_name = (argc && *argv) ? argv[0] : "fsck.minix";
+ if ((p = strrchr(program_name, '/')) != NULL)
+ program_name = p+1;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
-
- if (argc && *argv)
- program_name = *argv;
+ if (argc == 2 &&
+ (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
+ printf(_("%s from %s\n"), program_name, util_linux_version);
+ exit(0);
+ }
+
if (INODE_SIZE * MINIX_INODES_PER_BLOCK != BLOCK_SIZE)
- die("bad inode size");
+ die(_("bad inode size"));
#ifdef HAVE_MINIX2
if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE)
- die("bad v2 inode size");
+ die(_("bad v2 inode size"));
#endif
while (argc-- > 1) {
argv++;
@@ -1272,11 +1286,11 @@ int main(int argc, char ** argv)
check_mount(); /* trying to check a mounted filesystem? */
if (repair && !automatic) {
if (!isatty(0) || !isatty(1))
- die("need terminal for interactive repairs");
+ die(_("need terminal for interactive repairs"));
}
IN = open(device_name,repair?O_RDWR:O_RDONLY);
if (IN < 0)
- die("unable to open '%s'");
+ die(_("unable to open '%s'"));
for (count=0 ; count<3 ; count++)
sync();
read_superblock();
@@ -1287,8 +1301,6 @@ int main(int argc, char ** argv)
* flags and whether or not the -f switch was specified on the
* command line.
*/
- printf("%s, %s / %s\n", program_name, program_version,
- util_linux_version);
if ( !(Super.s_state & MINIX_ERROR_FS) &&
(Super.s_state & MINIX_VALID_FS) &&
!force ) {
diff --git a/disk-utils/mkfs.bfs.8 b/disk-utils/mkfs.bfs.8
new file mode 100644
index 000000000..4da40e206
--- /dev/null
+++ b/disk-utils/mkfs.bfs.8
@@ -0,0 +1,48 @@
+.\" Copyright 1999 Andries E. Brouwer (aeb@cwi.nl)
+.\" May be freely distributed.
+.TH MKFS.BFS 8 "12 Sept 1999" "Util-linux 2.9x" "Linux System Administrator's Manual"
+.SH NAME
+mkfs.bfs \- make an SCO bfs filesystem
+.SH SYNOPSIS
+.BR "mkfs.bfs [ \-N"
+nr-of-inodes
+.B ] [ \-V
+volume-name
+.B ] [ \-F
+fsname
+.B ]
+device
+.B [
+size-in-blocks
+.B ]
+.SH DESCRIPTION
+.B mkfs.bfs
+creates an SCO bfs file-system on a block device
+(usually a disk partition or a file accessed via the loop device).
+
+The
+.I size-in-blocks
+parameter is the desired size of the file system, in blocks.
+If nothing is specified, the entire partition will be used.
+
+.SH OPTIONS
+.TP
+.B \-N
+Specify the desired number of inodes (at most 512).
+If nothing is specified some default number in the range 48-512 is picked
+depending on the size of the partition.
+.TP
+.BI \-V " volume-label"
+Specify the volume label. I have no idea if/where this is used.
+.TP
+.BI \-F " fsname"
+Specify the fsname. I have no idea if/where this is used.
+.TP
+.B \-v
+Be verbose.
+.SH "EXIT CODES"
+The exit code returned by
+.B mkfs.bfs
+is 0 when all went well, and 1 when something went wrong.
+.SH "SEE ALSO"
+.BR mkfs (8).
diff --git a/disk-utils/mkfs.bfs.c b/disk-utils/mkfs.bfs.c
new file mode 100644
index 000000000..93cf1e60a
--- /dev/null
+++ b/disk-utils/mkfs.bfs.c
@@ -0,0 +1,284 @@
+/*
+ * mkfs.bfs - Create SCO BFS filesystem - aeb, 1999-09-07
+ *
+ * Usage: mkfs.bfs [-N nr-of-inodes] [-V volume-name] [-F fsname] device
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+
+#include <linux/fs.h> /* for BLKGETSIZE */
+
+#include "../defines.h" /* for util_linux_version */
+
+#define BFS_ROOT_INO 2
+#define BFS_NAMELEN 14
+#define BFS_BLOCKSIZE 512
+#define BFS_SUPER_MAGIC 0x1badface
+
+/* superblock - 512 bytes */
+struct bfssb {
+ unsigned int s_magic;
+ unsigned int s_start; /* byte offset of start of data */
+ unsigned int s_end; /* sizeof(slice)-1 */
+
+ /* for recovery during compaction */
+ int s_from, s_to; /* src and dest block of current transfer */
+ int s_backup_from, s_backup_to;
+
+ /* labels - may well contain garbage */
+ char s_fsname[6];
+ char s_volume[6];
+ char s_pad[472];
+};
+
+/* inode - 64 bytes */
+struct bfsi {
+ unsigned short i_ino;
+ unsigned char i_pad1[2];
+ unsigned long i_first_block;
+ unsigned long i_last_block;
+ unsigned long i_bytes_to_end;
+ unsigned long i_type; /* 1: file, 2: the unique dir */
+ unsigned long i_mode;
+ unsigned long i_uid, i_gid;
+ unsigned long i_nlinks;
+ unsigned long i_atime, i_mtime, i_ctime;
+ unsigned char i_pad2[16];
+};
+
+#define BFS_DIR_TYPE 2
+
+/* directory entry - 16 bytes */
+struct bfsde {
+ unsigned short d_ino;
+ char d_name[BFS_NAMELEN];
+};
+
+
+static char *progname;
+
+static void
+fatal(char *s, ...) {
+ va_list p;
+
+ va_start(p, s);
+ fflush(stdout);
+ fprintf(stderr, "\n%s: ", progname);
+ vfprintf(stderr, s, p);
+ va_end(p);
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+static void
+usage(void) {
+ fprintf(stderr,
+ "Usage: %s [-v] [-N nr-of-inodes] [-V volume-name]\n"
+ " [-F fsname] device [block-count]\n",
+ progname);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[]) {
+ char *device, *volume, *fsname;
+ int inodes;
+ unsigned long total_blocks, ino_bytes, ino_blocks, data_blocks;
+ unsigned long user_specified_total_blocks = 0;
+ int verbose = 0;
+ int fd;
+ struct bfssb sb;
+ struct bfsi ri;
+ struct bfsde de;
+ struct stat statbuf;
+ time_t now;
+ int c, i, len;
+ char *p;
+
+ progname = argv[0];
+ if ((p = strrchr(progname, '/')) != NULL)
+ progname = p+1;
+
+ if (argc < 2)
+ usage();
+
+ if (argc == 2 &&
+ (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
+ printf("%s from %s\n", progname, util_linux_version);
+ exit(0);
+ }
+
+ volume = fsname = " "; /* is there a default? */
+ inodes = 0;
+
+ while (EOF != (c = getopt(argc, argv, "vF:N:V:cl:"))) {
+ switch (c) {
+ case 'N':
+ inodes = atol(optarg);
+ break;
+
+ case 'V':
+ len = strlen(optarg);
+ if (len <= 0 || len > 6)
+ fatal("volume name too long");
+ volume = strdup(optarg);
+ break;
+
+ case 'F':
+ len = strlen(optarg);
+ if (len <= 0 || len > 6)
+ fatal("fsname name too long");
+ fsname = strdup(optarg);
+ break;
+
+ case 'v':
+ verbose = 1;
+ break;
+
+ /* when called via mkfs we may get options c,l,v */
+ case 'c':
+ case 'l':
+ break;
+
+ default:
+ usage();
+ }
+ }
+
+ if (optind == argc)
+ usage();
+
+ device = argv[optind++];
+
+ if (stat(device, &statbuf) == -1) {
+ perror(device);
+ fatal("cannot stat device %s", device);
+ }
+
+ if (!S_ISBLK(statbuf.st_mode))
+ fatal("%s is not a block special device", device);
+
+ fd = open(device, O_RDWR);
+ if (fd == -1) {
+ perror(device);
+ fatal("cannot open %s", device);
+ }
+
+ if (optind == argc-1)
+ user_specified_total_blocks = atoi(argv[optind]);
+ else if (optind != argc)
+ usage();
+
+ if (ioctl(fd, BLKGETSIZE, &total_blocks) == -1) {
+ if (!user_specified_total_blocks) {
+ perror("BLKGETSIZE");
+ fatal("cannot get size of %s", device);
+ }
+ total_blocks = user_specified_total_blocks;
+ } else if (user_specified_total_blocks) {
+ if (user_specified_total_blocks > total_blocks)
+ fatal("blocks argument too large, max is %d",
+ total_blocks);
+ total_blocks = user_specified_total_blocks;
+ }
+
+ if (!inodes) {
+ /* pick some reasonable default */
+ inodes = 8*(total_blocks/800);
+ if (inodes < 48)
+ inodes = 48;
+ if (inodes > 512)
+ inodes = 512;
+ } else {
+ /* believe the user */
+ if (inodes > 512)
+ fatal("too many inodes - max is 512");
+ }
+
+ ino_bytes = inodes * sizeof(struct bfsi);
+ ino_blocks = (ino_bytes + BFS_BLOCKSIZE - 1) / BFS_BLOCKSIZE;
+ data_blocks = total_blocks - ino_blocks - 1;
+
+ /* mimic the behaviour of SCO's mkfs - maybe this limit is needed */
+ if (data_blocks < 32)
+ fatal("not enough space, need at least %d blocks",
+ ino_blocks + 33);
+
+ memset(&sb, 0, sizeof(sb));
+ sb.s_magic = BFS_SUPER_MAGIC;
+ sb.s_start = ino_bytes + sizeof(struct bfssb);
+ sb.s_end = total_blocks * BFS_BLOCKSIZE - 1;
+ sb.s_from = sb.s_to = sb.s_backup_from = sb.s_backup_to = -1;
+ memcpy(sb.s_fsname, fsname, 6);
+ memcpy(sb.s_volume, volume, 6);
+
+ if (verbose) {
+ fprintf(stderr, "Device: %s\n", device);
+ fprintf(stderr, "Volume: <%-6s>\n", volume);
+ fprintf(stderr, "FSname: <%-6s>\n", fsname);
+ fprintf(stderr, "BlockSize: %d\n", BFS_BLOCKSIZE);
+ fprintf(stderr, "Inodes: %d (in %ld block%s)\n",
+ inodes, ino_blocks, (ino_blocks==1) ? "" : "s");
+ fprintf(stderr, "Blocks: %ld\n", total_blocks);
+ fprintf(stderr, "Inode end: %d, Data end: %d\n",
+ sb.s_start-1, sb.s_end);
+ }
+
+ if (write(fd, &sb, sizeof(sb)) != sizeof(sb))
+ fatal("error writing superblock");
+
+ memset(&ri, 0, sizeof(ri));
+ ri.i_ino = BFS_ROOT_INO;
+ ri.i_first_block = 1 + ino_blocks;
+ ri.i_last_block = ri.i_first_block +
+ (inodes * sizeof(de) - 1) / BFS_BLOCKSIZE;
+ ri.i_bytes_to_end = ri.i_first_block * BFS_BLOCKSIZE
+ + 2 * sizeof(struct bfsde) - 1;
+ ri.i_type = BFS_DIR_TYPE;
+ ri.i_mode = S_IFDIR | 0755; /* or just 0755 */
+ ri.i_uid = 0;
+ ri.i_gid = 1; /* random */
+ ri.i_nlinks = 2;
+ time(&now);
+ ri.i_atime = now;
+ ri.i_mtime = now;
+ ri.i_ctime = now;
+
+ if (write(fd, &ri, sizeof(ri)) != sizeof(ri))
+ fatal("error writing root inode");
+
+ memset(&ri, 0, sizeof(ri));
+ for (i=1; i<inodes; i++)
+ if (write(fd, &ri, sizeof(ri)) != sizeof(ri))
+ fatal("error writing inode");
+
+ if (lseek(fd, (1 + ino_blocks)*BFS_BLOCKSIZE, SEEK_SET) == -1)
+ fatal("seek error");
+
+ memset(&de, 0, sizeof(de));
+ de.d_ino = BFS_ROOT_INO;
+ memcpy(de.d_name, ".", 1);
+ if (write(fd, &de, sizeof(de)) != sizeof(de))
+ fatal("error writing . entry");
+
+ memcpy(de.d_name, "..", 2);
+ if (write(fd, &de, sizeof(de)) != sizeof(de))
+ fatal("error writing .. entry");
+
+ if (close(fd) == -1) {
+ perror(device);
+ fatal("error closing %s", device);
+ }
+
+ return 0;
+}
diff --git a/disk-utils/mkfs.c b/disk-utils/mkfs.c
index 9ea27a504..5ca2704c5 100644
--- a/disk-utils/mkfs.c
+++ b/disk-utils/mkfs.c
@@ -24,7 +24,6 @@
#include <limits.h>
#include "nls.h"
-#include "../version.h"
#define VERSION UTIL_LINUX_VERSION
#ifndef DEFAULT_FSTYPE
@@ -41,11 +40,22 @@ int main(int argc, char *argv[])
char *fstype = NULL;
int i, more = 0, verbose = 0;
char *oldpath, *newpath;
+ char *program_name, *p;
+
+ program_name = argv[0];
+ if ((p = strrchr(program_name, '/')) != NULL)
+ program_name = p+1;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
+ if (argc == 2 &&
+ (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
+ printf(_("%s from %s\n"), program_name, util_linux_version);
+ exit(0);
+ }
+
/* Check commandline options. */
opterr = 0;
while ((more == 0) && ((i = getopt(argc, argv, "Vt:")) != EOF))
@@ -86,7 +96,7 @@ int main(int argc, char *argv[])
argv[--optind] = progname;
if (verbose) {
- puts(_("mkfs version " VERSION " (" __DATE__ ")"));
+ printf(_("mkfs version %s (%s)\n"), VERSION, __DATE__);
i = optind;
while (argv[i])
printf("%s ", argv[i++]);
diff --git a/disk-utils/mkfs.minix.8 b/disk-utils/mkfs.minix.8
index 6a9c7931c..2325805a2 100644
--- a/disk-utils/mkfs.minix.8
+++ b/disk-utils/mkfs.minix.8
@@ -1,11 +1,10 @@
.\" Copyright 1992, 1993, 1994 Rickard E. Faith (faith@cs.unc.edu)
.\" May be freely distributed.
-.\" " for emacs hilit19 mode
-.TH MKFS 8 "2 July 1996" "Util-linux 2.6" "Linux System Administrator's Manual"
+.TH MKFS.MINIX 8 "2 July 1996" "Util-linux 2.6" "Linux System Administrator's Manual"
.SH NAME
-mkfs \- make a Linux MINIX filesystem
+mkfs.minix \- make a Linux MINIX filesystem
.SH SYNOPSIS
-.BR "mkfs [ \-c | \-l filename ] [ \-n"
+.BR "mkfs.minix [ \-c | \-l filename ] [ \-n"
namelength
.B ] [ \-i
inodecount
@@ -15,7 +14,7 @@ device
size-in-blocks
.B ]
.SH DESCRIPTION
-.B mkfs
+.B mkfs.minix
creates a Linux MINIX file-system on a device (usually a disk partition).
The
@@ -33,14 +32,11 @@ is usually of the following form:
The
.I size-in-blocks
-parameter is the desired size of the file system, in blocks. This
-information can be determined from the
-.BR fdisk (8)
-or
-.BR cfdisk (8)
-program. If omitted it will be determined automaticaly. Only block
-counts strictly greater than 10 and strictly less than 65536 are
-allowed.
+parameter is the desired size of the file system, in blocks.
+It is present only for backwards compatibility.
+If omitted the size will be determined automatically.
+Only block counts strictly greater than 10 and strictly less than
+65536 are allowed.
.SH OPTIONS
.TP
.B \-c
@@ -50,7 +46,7 @@ are found, the count is printed.
.BI \-n " namelength"
Specify the maximum length of filenames.
Currently, the only allowable values are 14 and 30.
-.B 30 is the default.
+The default is 30.
.TP
.BI \-i " inodecount"
Specify the number of inodes for the filesystem.
@@ -76,24 +72,4 @@ Usage or syntax error
.SH "SEE ALSO"
.BR mkfs (8),
.BR fsck (8),
-.BR mke2fs (8),
-.BR e2fsck (8),
.BR reboot (8)
-.\" .SH AUTHORS
-.\" Linus Torvalds (torvalds@cs.helsinki.fi).
-.\" .br
-.\" Error code values by Rik Faith (faith@cs.unc.edu)
-.\" .br
-.\" Inode request feature by Scott Heavner (sdh@po.cwru.edu)
-.\" .br
-.\" Support for the file system valid flag by Dr. Wettstein
-.\" (greg%wind.uucp@plains.nodak.edu)
-.\" .br
-.\" Check to prevent mkfs of mounted filesystem and boot sector clearing
-.\" by Daniel Quinlan (quinlan@yggdrasil.com)
-.\" .br
-.\" Minix v2 support by Andreas Schwab
-.\" (schwab@issan.informatik.uni-dortmund.de), updated by Nicolai
-.\" Langfeldt (janl@math.uio.no)
-.\" .br
-.\" Portability patch by Russell King.
diff --git a/disk-utils/mkfs.minix.c b/disk-utils/mkfs.minix.c
index b05960b23..4887f05d1 100644
--- a/disk-utils/mkfs.minix.c
+++ b/disk-utils/mkfs.minix.c
@@ -76,7 +76,6 @@
#include <linux/minix_fs.h>
#include "nls.h"
-#include "../version.h"
#ifdef MINIX2_SUPER_MAGIC2
#define HAVE_MINIX2 1
@@ -489,6 +488,7 @@ void setup_tables(void)
ZONESIZE = 0;
MAXSIZE = version2 ? 0x7fffffff : (7+512+512*512)*1024;
ZONES = BLOCKS;
+
/* some magic nrs: 1 inode / 3 blocks */
if ( req_nr_inodes == 0 )
inodes = BLOCKS/3;
@@ -507,9 +507,13 @@ void setup_tables(void)
inodes = 65535;
INODES = inodes;
IMAPS = UPPER(INODES + 1,BITS_PER_BLOCK);
- ZMAPS = 0;
- while (ZMAPS != UPPER(BLOCKS - NORM_FIRSTZONE + 1,BITS_PER_BLOCK))
- ZMAPS = UPPER(BLOCKS - NORM_FIRSTZONE + 1,BITS_PER_BLOCK);
+ ZMAPS = UPPER(BLOCKS - (1+IMAPS+INODE_BLOCKS), BITS_PER_BLOCK+1);
+ /* The old code here
+ * ZMAPS = 0;
+ * while (ZMAPS != UPPER(BLOCKS - NORM_FIRSTZONE + 1,BITS_PER_BLOCK))
+ * ZMAPS = UPPER(BLOCKS - NORM_FIRSTZONE + 1,BITS_PER_BLOCK);
+ * was no good, since it may loop. - aeb
+ */
FIRSTZONE = NORM_FIRSTZONE;
inode_map = malloc(IMAPS * BLOCK_SIZE);
zone_map = malloc(ZMAPS * BLOCK_SIZE);
@@ -630,9 +634,23 @@ int main(int argc, char ** argv)
char * tmp;
struct stat statbuf;
char * listfile = NULL;
+ char * p;
if (argc && *argv)
program_name = *argv;
+ if ((p = strrchr(program_name, '/')) != NULL)
+ program_name = p+1;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (argc == 2 &&
+ (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
+ printf(_("%s from %s\n"), program_name, util_linux_version);
+ exit(0);
+ }
+
if (INODE_SIZE * MINIX_INODES_PER_BLOCK != BLOCK_SIZE)
die(_("bad inode size"));
#ifdef HAVE_MINIX2
diff --git a/disk-utils/mkswap.8 b/disk-utils/mkswap.8
index c16a89380..368ef3b5c 100644
--- a/disk-utils/mkswap.8
+++ b/disk-utils/mkswap.8
@@ -7,7 +7,7 @@
.SH NAME
mkswap \- set up a Linux swap area
.SH SYNOPSIS
-.BI "mkswap [\-c] [\-v" N "] [\-f] " device " [" size "]"
+.BI "mkswap [\-c] [\-v" N "] [\-f] [\-p " PSZ "] "device " [" size "]"
.SH DESCRIPTION
.B mkswap
sets up a Linux swap area on a device or in a file.
@@ -30,6 +30,8 @@ but can also be a file.
The Linux kernel does not look at partition Id's, but
many installation scripts will assume that partitions
of hex type 82 (LINUX_SWAP) are meant to be swap partitions.
+(Warning: Solaris also uses this type. Be careful not to kill
+your Solaris partitions.)
The
.I size
@@ -39,6 +41,18 @@ parameter is superfluous but retained for backwards compatibility.
will use the entire partition or file if it is omitted.
Specifying it is unwise - a typo may destroy your disk.)
+The
+.I PSZ
+parameter specifies the page size to use. It is almost always
+unnecessary (even unwise) to specify it, but certain old libc
+versions lie about the page size, so it is possible that
+.B mkswap
+gets it wrong. The symptom is that a subsequent
+.B swapon
+fails because no swap signature is found. Typical values for
+.I PSZ
+are 4096 or 8192.
+
Linux knows about two styles of swap areas, old style and new style.
The last 10 bytes of the first page of the swap area distinguishes
them: old style has `SWAP_SPACE', new style has `SWAPSPACE2' as
@@ -51,9 +65,9 @@ Also, the last 10 bytes hold the signature. So, if the page
size is S, an old style swap area can describe at most
8*(S-10)-1 pages used for swapping.
With S=4096 (as on i386), the useful area is at most 133890048 bytes
-(almost 128 MB if you believe in 1 MB=2^20 bytes), and the rest is wasted.
+(almost 128 MiB), and the rest is wasted.
On an alpha and sparc64, with S=8192, the useful area is at most
-535560992 bytes (almost 512 MB with the same proviso).
+535560992 bytes (almost 512 MiB).
The old setup wastes most of this bitmap page, because zero bits
denote bad blocks or blocks past the end of the swap space,
@@ -63,12 +77,12 @@ to use a swap space with hundreds of bad blocks. (I would not even
use a swap space with 1 bad block.)
In the new style swap area this is precisely what is done.
The maximum useful size of a swap area now depends on the architecture.
-It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
-128GB on alpha and 3TB on sparc64.
+It is roughly 2GiB on i386, PPC, m68k, ARM, 1GiB on sparc, 512MiB on mips,
+128GiB on alpha and 3TiB on sparc64.
Note that before 2.1.117 the kernel allocated one byte for each page,
-while it now allocates two bytes, so that taking a swap area of 2 GB
-in use might require 2 MB of kernel memory.
+while it now allocates two bytes, so that taking a swap area of 2 GiB
+in use might require 2 MiB of kernel memory.
Presently, Linux allows 8 swap areas. The areas in use can be seen
in the file
@@ -114,6 +128,9 @@ Without this option
will refuse to create a v0 swap on a device with a valid SPARC superblock,
as that probably means one is going to erase the partition table.
.TP
+.BI "\-p " PSZ
+Specify the page size to use.
+.TP
.B \-v0
Create an old style swap area.
.TP
diff --git a/disk-utils/mkswap.c b/disk-utils/mkswap.c
index ef5f58c11..2803587b7 100644
--- a/disk-utils/mkswap.c
+++ b/disk-utils/mkswap.c
@@ -77,9 +77,20 @@ linux_version_code(void) {
/*
* The definition of the union swap_header uses the constant PAGE_SIZE.
* Unfortunately, on some architectures this depends on the hardware model,
- * and can only be found at run time -- we use getpagesize().
+ * and can only be found at run time -- we use getpagesize(), so that
+ * we do not need separate binaries e.g. for sun4, sun4c/d/m and sun4u.
+ *
+ * Even more unfortunately, getpagesize() does not always return
+ * the right information. For example, libc4 and libc5 do not use
+ * the system call but invent a value themselves
+ * (EXEC_PAGESIZE or NBPG * CLSIZE or NBPC), and thus it may happen
+ * that e.g. on a sparc PAGE_SIZE=4096 and getpagesize() returns 8192.
+ * What to do? Let us allow the user to specify the pagesize explicitly.
*/
+static int user_pagesize = 0;
+static int kernel_pagesize; /* obtained via getpagesize(); */
+static int defined_pagesize = 0; /* PAGE_SIZE, when that exists */
static int pagesize;
static int *signature_page;
@@ -94,12 +105,31 @@ struct swap_header_v1 {
static void
init_signature_page() {
- pagesize = getpagesize();
-
#ifdef PAGE_SIZE
- if (pagesize != PAGE_SIZE)
- fprintf(stderr, _("Assuming pages of size %d\n"), pagesize);
+ defined_pagesize = PAGE_SIZE;
#endif
+ kernel_pagesize = getpagesize();
+ pagesize = kernel_pagesize;
+
+ if (user_pagesize) {
+ if ((user_pagesize & (user_pagesize-1)) ||
+ user_pagesize < 1024) {
+ fprintf(stderr, _("Bad user-specified page size %d\n"),
+ user_pagesize);
+ exit(1);
+ }
+ pagesize = user_pagesize;
+ }
+
+ if (user_pagesize && user_pagesize != kernel_pagesize &&
+ user_pagesize != defined_pagesize)
+ fprintf(stderr, _("Using user-specified page size %d, "
+ "instead of the system values %d/%d\n"),
+ pagesize, kernel_pagesize, defined_pagesize);
+ else if (defined_pagesize && pagesize != defined_pagesize)
+ fprintf(stderr, _("Assuming pages of size %d (not %d)\n"),
+ pagesize, defined_pagesize);
+
signature_page = (int *) malloc(pagesize);
memset(signature_page,0,pagesize);
p = (struct swap_header_v1 *) signature_page;
@@ -158,8 +188,8 @@ It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
#define MAX_BADPAGES ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
-static void bit_set (unsigned int *addr, unsigned int nr)
-{
+static void
+bit_set (unsigned int *addr, unsigned int nr) {
unsigned int r, m;
addr += nr / (8 * sizeof(int));
@@ -168,8 +198,8 @@ static void bit_set (unsigned int *addr, unsigned int nr)
*addr = r | m;
}
-static int bit_test_and_clear (unsigned int *addr, unsigned int nr)
-{
+static int
+bit_test_and_clear (unsigned int *addr, unsigned int nr) {
unsigned int r, m;
addr += nr / (8 * sizeof(int));
@@ -179,14 +209,19 @@ static int bit_test_and_clear (unsigned int *addr, unsigned int nr)
return (r & m) != 0;
}
-void fatal_error(const char * fmt_string)
-{
- fprintf(stderr,fmt_string,program_name,device_name);
+void
+usage(void) {
+ fprintf(stderr,
+ _("Usage: %s [-c] [-v0|-v1] [-pPAGESZ] /dev/name [blocks]\n"),
+ program_name);
exit(1);
}
-#define usage() fatal_error(_("Usage: %s [-c] [-v0|-v1] /dev/name [blocks]\n"))
-#define die(str) fatal_error(_("%s: " str "\n"))
+void
+die(const char *str) {
+ fprintf(stderr, "%s: %s\n", program_name, str);
+ exit(1);
+}
void
page_ok(int page) {
@@ -200,7 +235,7 @@ page_bad(int page) {
bit_test_and_clear(signature_page, page);
else {
if (badpages == MAX_BADPAGES)
- die("too many bad pages");
+ die(_("too many bad pages"));
p->badpages[badpages] = page;
}
badpages++;
@@ -214,7 +249,7 @@ check_blocks(void) {
buffer = malloc(pagesize);
if (!buffer)
- die("Out of memory");
+ die(_("Out of memory"));
current_page = 0;
while (current_page < PAGES) {
if (!check) {
@@ -223,7 +258,7 @@ check_blocks(void) {
}
if (do_seek && lseek(DEV,current_page*pagesize,SEEK_SET) !=
current_page*pagesize)
- die("seek failed in check_blocks");
+ die(_("seek failed in check_blocks"));
if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) {
page_bad(current_page++);
continue;
@@ -236,8 +271,8 @@ check_blocks(void) {
printf(_("%d bad pages\n"), badpages);
}
-static long valid_offset (int fd, int offset)
-{
+static long
+valid_offset (int fd, int offset) {
char ch;
if (lseek (fd, offset, 0) < 0)
@@ -248,8 +283,7 @@ static long valid_offset (int fd, int offset)
}
static int
-find_size (int fd)
-{
+find_size (int fd) {
unsigned int high, low;
low = 0;
@@ -269,8 +303,7 @@ find_size (int fd)
/* return size in pages, to avoid integer overflow */
static long
-get_size(const char *file)
-{
+get_size(const char *file) {
int fd;
long size;
@@ -289,58 +322,85 @@ get_size(const char *file)
return size;
}
-int main(int argc, char ** argv)
-{
- char * tmp;
+int
+isnzdigit(char c) {
+ return (c >= '1' && c <= '9');
+}
+
+int
+main(int argc, char ** argv) {
struct stat statbuf;
- int sz;
+ int i, sz;
int maxpages;
int goodpages;
int offset;
int force = 0;
+ char *block_count = 0;
+ char *pp;
+
+ program_name = (argc && *argv) ? argv[0] : "fsck.minix";
+ if ((pp = strrchr(program_name, '/')) != NULL)
+ program_name = pp+1;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
-
-
- if (argc && *argv)
- program_name = *argv;
- init_signature_page(); /* get pagesize */
+ if (argc == 2 &&
+ (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
+ printf(_("%s from %s\n"), program_name, util_linux_version);
+ exit(0);
+ }
- while (argc-- > 1) {
- argv++;
- if (argv[0][0] != '-') {
- if (device_name) {
- int blocks_per_page = pagesize/1024;
- PAGES = strtol(argv[0],&tmp,0)/blocks_per_page;
- if (*tmp)
- usage();
- } else
- device_name = argv[0];
- } else {
- switch (argv[0][1]) {
+ for (i=1; i<argc; i++) {
+ if (argv[i][0] == '-') {
+ switch (argv[i][1]) {
case 'c':
check=1;
break;
case 'f':
force=1;
break;
+ case 'p':
+ pp = argv[i]+2;
+ if (!*pp && i+1 < argc)
+ pp = argv[++i];
+ if (isnzdigit(*pp))
+ user_pagesize=atoi(pp);
+ else
+ usage();
+ break;
case 'v':
- version=atoi(argv[0]+2);
+ version = atoi(argv[0]+2);
break;
default:
usage();
}
- }
+ } else if (!device_name) {
+ device_name = argv[i];
+ } else if (!block_count) {
+ block_count = argv[i];
+ } else
+ usage();
}
+
+ init_signature_page(); /* get pagesize */
+
if (!device_name) {
fprintf(stderr,
_("%s: error: Nowhere to set up swap on?\n"),
program_name);
usage();
}
+ if (block_count) {
+ /* this silly user specified the number of blocks
+ explicitly */
+ char *tmp;
+ int blocks_per_page = pagesize/1024;
+ PAGES = strtol(block_count,&tmp,0)/blocks_per_page;
+ if (*tmp)
+ usage();
+ }
sz = get_size(device_name);
if (!PAGES) {
PAGES = sz;
@@ -401,7 +461,7 @@ int main(int argc, char ** argv)
if (!S_ISBLK(statbuf.st_mode))
check=0;
else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
- die("Will not try to make swapdevice on '%s'");
+ die(_("Will not try to make swapdevice on '%s'"));
#ifdef __sparc__
if (!force && version == 0) {
@@ -410,7 +470,7 @@ int main(int argc, char ** argv)
unsigned short *q, sum;
if (read(DEV, buffer, 512) != 512)
- die("fatal: first page unreadable");
+ die(_("fatal: first page unreadable"));
if (buffer[508] == 0xDA && buffer[509] == 0xBE) {
q = (unsigned short *)(buffer + 510);
for (sum = 0; q >= (unsigned short *) buffer;)
@@ -431,7 +491,7 @@ the -f option to force it.\n"),
if (version == 0 || check)
check_blocks();
if (version == 0 && !bit_test_and_clear(signature_page,0))
- die("fatal: first page unreadable");
+ die(_("fatal: first page unreadable"));
if (version == 1) {
p->version = version;
p->last_page = PAGES-1;
@@ -440,23 +500,23 @@ the -f option to force it.\n"),
goodpages = PAGES - badpages - 1;
if (goodpages <= 0)
- die("Unable to set up swap-space: unreadable");
+ die(_("Unable to set up swap-space: unreadable"));
printf(_("Setting up swapspace version %d, size = %ld bytes\n"),
version, (long)(goodpages*pagesize));
write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2");
offset = ((version == 0) ? 0 : 1024);
if (lseek(DEV, offset, SEEK_SET) != offset)
- die("unable to rewind swap-device");
+ die(_("unable to rewind swap-device"));
if (write(DEV,(char*)signature_page+offset, pagesize-offset)
!= pagesize-offset)
- die("unable to write signature page");
+ die(_("unable to write signature page"));
/*
* A subsequent swapon() will fail if the signature
* is not actually on disk. (This is a kernel bug.)
*/
if (fsync(DEV))
- die("fsync failed");
+ die(_("fsync failed"));
return 0;
}
diff --git a/disk-utils/raw.8 b/disk-utils/raw.8
new file mode 100644
index 000000000..cb8021668
--- /dev/null
+++ b/disk-utils/raw.8
@@ -0,0 +1,87 @@
+.\" -*- nroff -*-
+.TH RAW 8 "Aug 1999" "Version 0.1"
+.SH NAME
+raw \- bind a Linux raw character device
+.SH SYNOPSIS
+.B raw
+.I /dev/raw<N> <major> <minor>
+.PP
+.B raw
+.I /dev/raw<N> /dev/<blockdev>
+.PP
+.B raw
+.B \-q
+.I /dev/raw<N>
+.PP
+.B raw
+.B \-qa
+.SH DESCRIPTION
+.B raw
+is used to bind a Linux raw character device to a block device. Any
+block device may be used: at the time of binding, the device driver does
+not even have to be accessible (it may be loaded on demand as a kernel
+module later).
+.PP
+.B raw
+is used in two modes: it either sets raw device bindings, or it queries
+existing bindings. When setting a raw device,
+.I /dev/raw<N>
+is the device name of an existing raw device node in the filesystem.
+The block device to which it is to be bound can be specified either in
+terms of its
+.I major
+and
+.I minor
+device numbers, or as a path name
+.I /dev/<blockdev>
+to an existing block device file.
+.PP
+The bindings already in existence can be queried with the
+.I \-q
+option, with is used either with a raw device filename to query that one
+device, or with the
+.I \-a
+option to query all bound raw devices.
+.PP
+Once bound to a block device, a raw device can be opened, read and
+written, just like the block device it is bound to. However, the raw
+device does not behave exactly like the block device. In particular,
+access to the raw device bypasses the kernel's block buffer cache
+entirely: all I/O is done directly to and from the address space of the
+process performing the I/O. If the underlying block device driver can
+support DMA, then no data copying at all is required to complete the
+I/O.
+.PP
+Because raw I/O involves direct hardware access to a process's memory, a
+few extra restrictions must be observed. All I/Os must be correctly
+aligned in memory and on disk: they must start at a sector offset on
+disk, they must be an exact number of sectors long, and the data buffer
+in virtual memory must also be aligned to a multiple of the sector
+size. The sector size is 512 bytes for most devices.
+.SH OPTIONS
+.TP
+.B -q
+Set query mode.
+.B raw
+will query an existing binding instead of setting a new one.
+.TP
+.B -a
+With
+.B -q
+, specifies that all bound raw devices should be queried.
+.TP
+.B -h
+provides a usage summary.
+.SH BUGS
+The Linux
+.B dd
+(1) command does not currently align its buffers correctly, and so
+cannot be used on raw devices.
+.PP
+Raw I/O devices do not maintain cache coherency with the Linux block
+device buffer cache. If you use raw I/O to overwrite data already in
+the buffer cache, the buffer cache will no longer correspond to the
+contents of the actual storage device underneath. This is deliberate,
+but is regarded either a bug or a feature depending on who you ask!
+.SH AUTHOR
+Stephen Tweedie (sct@redhat.com)
diff --git a/disk-utils/raw.c b/disk-utils/raw.c
new file mode 100644
index 000000000..5fb95348a
--- /dev/null
+++ b/disk-utils/raw.c
@@ -0,0 +1,217 @@
+/*
+ * raw.c: User mode tool to bind and query raw character devices.
+ *
+ * Stephen Tweedie, 1999
+ *
+ * This file may be redistributed under the terms of the GNU General
+ * Public License, version 2.
+ *
+ * Copyright Red Hat Software, 1999
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/sysmacros.h>
+#include <sys/raw.h>
+
+
+
+char * progname;
+int do_query = 0;
+int do_query_all = 0;
+
+int master_fd;
+int raw_minor;
+
+void open_raw_ctl(void);
+int query(int minor, int quiet);
+int bind (int minor, int block_major, int block_minor);
+
+
+static void usage(int err)
+{
+ fprintf(stderr,
+ "Usage:\n"
+ " %s /dev/rawN <major> <minor>\n"
+ " %s /dev/rawN /dev/<blockdev>\n"
+ " %s -q /dev/rawN\n"
+ " %s -qa\n",
+ progname, progname, progname, progname);
+ exit(err);
+}
+
+
+int main(int argc, char *argv[])
+{
+ char c;
+ char * raw_name;
+ char * block_name;
+ int err;
+ int block_major, block_minor;
+ int i;
+
+ struct stat statbuf;
+
+ progname = argv[0];
+
+ while ((c = getopt(argc, argv, "ahq")) != EOF) {
+ switch (c) {
+ case 'a':
+ do_query_all = 1;
+ break;
+ case 'h':
+ usage(0);
+ case 'q':
+ do_query = 1;
+ break;
+ default:
+ usage(1);
+ }
+ }
+
+ /*
+ * Check for, and open, the master raw device, /dev/raw
+ */
+
+ open_raw_ctl();
+
+ if (do_query_all) {
+ if (optind < argc)
+ usage(1);
+ for (i=1; i<255; i++)
+ query(i, 1);
+ exit(0);
+ }
+
+ /*
+ * It's a bind or a single query. Either way we need a raw device.
+ */
+
+ if (optind >= argc)
+ usage(1);
+ raw_name = argv[optind++];
+
+ err = stat(raw_name, &statbuf);
+ if (err) {
+ fprintf (stderr, "Cannot locate raw device '%s' (%s)\n",
+ raw_name, strerror(errno));
+ exit(2);
+ }
+
+ if (!S_ISCHR(statbuf.st_mode)) {
+ fprintf (stderr, "raw device '%s' is not a character dev\n",
+ raw_name);
+ exit(2);
+ }
+ if (major(statbuf.st_rdev) != RAW_MAJOR) {
+ fprintf (stderr, "Device '%s' is not a raw dev\n",
+ raw_name);
+ exit(2);
+ }
+
+ raw_minor = minor(statbuf.st_rdev);
+
+ if (do_query)
+ return query(raw_minor, 0);
+
+ /*
+ * It's not a query, so we still have some parsing to do. Have
+ * we been given a block device filename or a major/minor pair?
+ */
+
+ switch (argc - optind) {
+ case 1:
+ block_name = argv[optind];
+ err = stat(block_name, &statbuf);
+ if (err) {
+ fprintf (stderr,
+ "Cannot locate block device '%s' (%s)\n",
+ block_name, strerror(errno));
+ exit(2);
+ }
+
+ if (!S_ISBLK(statbuf.st_mode)) {
+ fprintf (stderr, "Device '%s' is not a block dev\n",
+ block_name);
+ exit(2);
+ }
+
+ block_major = major(statbuf.st_rdev);
+ block_minor = minor(statbuf.st_rdev);
+ break;
+
+ case 2:
+ block_major = strtol(argv[optind], 0, 0);
+ block_minor = strtol(argv[optind+1], 0, 0);
+ break;
+
+ default:
+ usage(1);
+ }
+
+ return bind(raw_minor, block_major, block_minor);
+ return 0;
+
+}
+
+
+void open_raw_ctl(void)
+{
+ master_fd = open("/dev/raw", O_RDWR, 0);
+ if (master_fd < 0) {
+ fprintf (stderr,
+ "Cannot open master raw device '/dev/raw' (%s)\n",
+ strerror(errno));
+ exit(2);
+ }
+}
+
+int query(int minor, int quiet)
+{
+ struct raw_config_request rq;
+ int err;
+
+ rq.raw_minor = minor;
+ err = ioctl(master_fd, RAW_GETBIND, &rq);
+ if (err < 0) {
+ if (quiet && errno == ENODEV)
+ return 3;
+ fprintf (stderr,
+ "Error querying raw device (%s)\n",
+ strerror(errno));
+ exit(3);
+ }
+ if (quiet && !rq.block_major && !rq.block_minor)
+ return 0;
+ printf ("/dev/raw%d: bound to major %d, minor %d\n",
+ minor, (int) rq.block_major, (int) rq.block_minor);
+ return 0;
+}
+
+int bind(int minor, int block_major, int block_minor)
+{
+ struct raw_config_request rq;
+ int err;
+
+ rq.raw_minor = minor;
+ rq.block_major = block_major;
+ rq.block_minor = block_minor;
+ err = ioctl(master_fd, RAW_SETBIND, &rq);
+ if (err < 0) {
+ fprintf (stderr,
+ "Error setting raw device (%s)\n",
+ strerror(errno));
+ exit(3);
+ }
+ printf ("/dev/raw%d: bound to major %d, minor %d\n",
+ raw_minor, (int) rq.block_major, (int) rq.block_minor);
+ return 0;
+}
+
diff --git a/disk-utils/setfdprm.c b/disk-utils/setfdprm.c
index 7c2b0dc36..73b3b7174 100644
--- a/disk-utils/setfdprm.c
+++ b/disk-utils/setfdprm.c
@@ -109,18 +109,27 @@ gap rate spec1 fmt_gap\n"),name);
}
int
-main(int argc,char **argv)
+main(int argc, char **argv)
{
int fd;
unsigned int cmd;
- char *name;
+ char *progname, *p;
+
+ progname = argv[0];
+ if ((p = strrchr(progname, '/')) != NULL)
+ progname = p+1;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- name = argv[0];
- if (argc < 3) usage(name);
+ if (argc == 2 &&
+ (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
+ printf(_("%s from %s\n"), progname, util_linux_version);
+ exit(0);
+ }
+
+ if (argc < 3) usage(progname);
cmd = FDSETPRM;
if (*argv[1] == '-') {
switch (argv[1][1]) {
@@ -142,7 +151,7 @@ main(int argc,char **argv)
break;
#endif
default:
- usage(name);
+ usage(progname);
}
argc--;
argv++;
@@ -152,11 +161,11 @@ main(int argc,char **argv)
exit(1);
}
if (cmd != FDSETPRM && cmd != FDDEFPRM) {
- if (argc != 2) usage(name);
+ if (argc != 2) usage(progname);
cmd_without_param(cmd,fd);
}
if (argc != 11 && argc != 3)
- usage(name);
+ usage(progname);
else if (argc == 11)
set_params(cmd,fd,&argv[2]);
else