Module Name: src
Committed By: pooka
Date: Mon Nov 22 21:04:28 UTC 2010
Modified Files:
src/bin/dd: Makefile args.c dd.c dd.h extern.h position.c
Log Message:
Add two new operands: "rif" and "rof". They operate exactly like
"if" and "of" with the exception that the communicate with a rump
kernel instead of the host kernel.
For example, to write stdout to /tmp/file.txt in a rump kernel namespace:
dd rof=/tmp/file.txt
copy /file1 to /file2 inside a rump kernel:
dd rif=/file1 rof=/file2
copy a snippet from /dev/rmd0d on the rump kernel to the host fs:
dd rif=/dev/rmd0d of=save seek=1000 count=3
Eat that, usermode OS.
(I'll document the operands one I have some manpage to refer to
for rump client use).
To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/bin/dd/Makefile src/bin/dd/dd.h
cvs rdiff -u -r1.26 -r1.27 src/bin/dd/args.c
cvs rdiff -u -r1.43 -r1.44 src/bin/dd/dd.c
cvs rdiff -u -r1.17 -r1.18 src/bin/dd/extern.h src/bin/dd/position.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/bin/dd/Makefile
diff -u src/bin/dd/Makefile:1.12 src/bin/dd/Makefile:1.13
--- src/bin/dd/Makefile:1.12 Fri Oct 5 07:23:09 2007
+++ src/bin/dd/Makefile Mon Nov 22 21:04:27 2010
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.12 2007/10/05 07:23:09 lukem Exp $
+# $NetBSD: Makefile,v 1.13 2010/11/22 21:04:27 pooka Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= dd
@@ -8,9 +8,11 @@
LDADD+= -lutil
.ifdef SMALLPROG
-CPPFLAGS+= -DNO_CONV
+CPPFLAGS+= -DNO_CONV -DSMALL
.else
SRCS+= conv_tab.c
+DPADD+= ${LIBRUMPCLIENT}
+LDADD+= -lrumpclient
.endif
.include <bsd.prog.mk>
Index: src/bin/dd/dd.h
diff -u src/bin/dd/dd.h:1.12 src/bin/dd/dd.h:1.13
--- src/bin/dd/dd.h:1.12 Sat Jan 17 20:48:57 2004
+++ src/bin/dd/dd.h Mon Nov 22 21:04:27 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: dd.h,v 1.12 2004/01/17 20:48:57 dbj Exp $ */
+/* $NetBSD: dd.h,v 1.13 2010/11/22 21:04:27 pooka Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -35,6 +35,35 @@
* @(#)dd.h 8.3 (Berkeley) 4/2/94
*/
+#include <sys/stat.h>
+
+struct ddfops {
+ int (*op_open)(const char *, int, ...);
+ int (*op_close)(int);
+
+ int (*op_fcntl)(int, int, ...);
+ int (*op_ioctl)(int, unsigned long, ...);
+
+ int (*op_fstat)(int, struct stat *);
+ int (*op_fsync)(int);
+ int (*op_ftruncate)(int, off_t);
+
+ off_t (*op_lseek)(int, off_t, int);
+
+ ssize_t (*op_read)(int, void *, size_t);
+ ssize_t (*op_write)(int, const void *, size_t);
+};
+
+#define ddop_open(dir, a1, a2, ...) dir.ops->op_open(a1, a2, __VA_ARGS__)
+#define ddop_close(dir, a1) dir.ops->op_close(a1)
+#define ddop_fcntl(dir, a1, a2, ...) dir.ops->op_fcntl(a1, a2, __VA_ARGS__)
+#define ddop_ioctl(dir, a1, a2, ...) dir.ops->op_ioctl(a1, a2, __VA_ARGS__)
+#define ddop_fsync(dir, a1) dir.ops->op_fsync(a1)
+#define ddop_ftruncate(dir, a1, a2) dir.ops->op_ftruncate(a1, 2)
+#define ddop_lseek(dir, a1, a2, a3) dir.ops->op_lseek(a1, a2, a3)
+#define ddop_read(dir, a1, a2, a3) dir.ops->op_read(a1, a2, a3)
+#define ddop_write(dir, a1, a2, a3) dir.ops->op_write(a1, a2, a3)
+
/* Input/output stream state. */
typedef struct {
u_char *db; /* buffer address */
@@ -52,6 +81,7 @@
const char *name; /* name */
int fd; /* file descriptor */
uint64_t offset; /* # of blocks to skip */
+ struct ddfops const *ops; /* ops to use with fd */
} IO;
typedef struct {
@@ -89,3 +119,6 @@
#define C_UNBLOCK 0x80000
#define C_OSYNC 0x100000
#define C_SPARSE 0x200000
+#define C_RIF 0x400000
+#define C_ROF 0x800000
+#define C_RUMP 0x1000000
Index: src/bin/dd/args.c
diff -u src/bin/dd/args.c:1.26 src/bin/dd/args.c:1.27
--- src/bin/dd/args.c:1.26 Mon Jan 9 10:17:05 2006
+++ src/bin/dd/args.c Mon Nov 22 21:04:27 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: args.c,v 1.26 2006/01/09 10:17:05 apb Exp $ */
+/* $NetBSD: args.c,v 1.27 2010/11/22 21:04:27 pooka Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94";
#else
-__RCSID("$NetBSD: args.c,v 1.26 2006/01/09 10:17:05 apb Exp $");
+__RCSID("$NetBSD: args.c,v 1.27 2010/11/22 21:04:27 pooka Exp $");
#endif
#endif /* not lint */
@@ -55,6 +55,10 @@
#include "dd.h"
#include "extern.h"
+#ifndef SMALL
+#include <rump/rumpclient.h>
+#endif
+
static int c_arg(const void *, const void *);
#ifndef NO_CONV
static int c_conv(const void *, const void *);
@@ -72,6 +76,11 @@
static void f_skip(char *);
static void f_progress(char *);
+#ifndef SMALL
+static void f_rif(char *);
+static void f_rof(char *);
+#endif
+
static const struct arg {
const char *name;
void (*f)(char *);
@@ -85,10 +94,14 @@
{ "count", f_count, C_COUNT, C_COUNT },
{ "files", f_files, C_FILES, C_FILES },
{ "ibs", f_ibs, C_IBS, C_BS|C_IBS },
- { "if", f_if, C_IF, C_IF },
+ { "if", f_if, C_IF, C_IF|C_RIF },
{ "obs", f_obs, C_OBS, C_BS|C_OBS },
- { "of", f_of, C_OF, C_OF },
+ { "of", f_of, C_OF, C_OF|C_ROF },
{ "progress", f_progress, 0, 0 },
+#ifndef SMALL
+ { "rif", f_rif, C_RIF|C_RUMP, C_RIF|C_IF },
+ { "rof", f_rof, C_ROF|C_RUMP, C_ROF|C_ROF },
+#endif
{ "seek", f_seek, C_SEEK, C_SEEK },
{ "skip", f_skip, C_SKIP, C_SKIP },
};
@@ -185,6 +198,12 @@
* if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)
* errx(1, "seek offsets cannot be larger than %d", INT_MAX);
*/
+
+#ifndef SMALL
+ if (ddflags & C_RUMP)
+ if (rumpclient_init() == -1)
+ err(1, "rumpclient init failed");
+#endif
}
static int
@@ -257,6 +276,40 @@
out.name = arg;
}
+#ifndef SMALL
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+static const struct ddfops ddfops_rump = {
+ .op_open = rump_sys_open,
+ .op_close = rump_sys_close,
+ .op_fcntl = rump_sys_fcntl,
+ .op_ioctl = rump_sys_ioctl,
+ .op_fstat = rump_sys_fstat,
+ .op_fsync = rump_sys_fsync,
+ .op_ftruncate = rump_sys_ftruncate,
+ .op_lseek = rump_sys_lseek,
+ .op_read = rump_sys_read,
+ .op_write = rump_sys_write,
+};
+
+static void
+f_rif(char *arg)
+{
+
+ in.name = arg;
+ in.ops = &ddfops_rump;
+}
+
+static void
+f_rof(char *arg)
+{
+
+ out.name = arg;
+ out.ops = &ddfops_rump;
+}
+#endif
+
static void
f_seek(char *arg)
{
Index: src/bin/dd/dd.c
diff -u src/bin/dd/dd.c:1.43 src/bin/dd/dd.c:1.44
--- src/bin/dd/dd.c:1.43 Sat Feb 14 07:13:40 2009
+++ src/bin/dd/dd.c Mon Nov 22 21:04:27 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: dd.c,v 1.43 2009/02/14 07:13:40 lukem Exp $ */
+/* $NetBSD: dd.c,v 1.44 2010/11/22 21:04:27 pooka Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -43,7 +43,7 @@
#if 0
static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94";
#else
-__RCSID("$NetBSD: dd.c,v 1.43 2009/02/14 07:13:40 lukem Exp $");
+__RCSID("$NetBSD: dd.c,v 1.44 2010/11/22 21:04:27 pooka Exp $");
#endif
#endif /* not lint */
@@ -70,7 +70,7 @@
static void dd_close(void);
static void dd_in(void);
static void getfdtype(IO *);
-static int redup_clean_fd(int);
+static void redup_clean_fd(IO *);
static void setup(void);
int main(int, char *[]);
@@ -87,6 +87,21 @@
const u_char *ctab; /* conversion table */
sigset_t infoset; /* a set blocking SIGINFO */
+static const struct ddfops ddfops_host = {
+ .op_open = open,
+ .op_close = close,
+ .op_fcntl = fcntl,
+ .op_ioctl = ioctl,
+ .op_fstat = fstat,
+ .op_fsync = fsync,
+ .op_ftruncate = ftruncate,
+ .op_lseek = lseek,
+ .op_read = read,
+ .op_write = write,
+};
+
+#include <rump/rumpclient.h>
+
int
main(int argc, char *argv[])
{
@@ -127,17 +142,21 @@
setup(void)
{
+ if (in.ops == NULL)
+ in.ops = &ddfops_host;
+ if (out.ops == NULL)
+ out.ops = &ddfops_host;
if (in.name == NULL) {
in.name = "stdin";
in.fd = STDIN_FILENO;
} else {
- in.fd = open(in.name, O_RDONLY, 0);
+ in.fd = ddop_open(in, in.name, O_RDONLY, 0);
if (in.fd < 0)
err(EXIT_FAILURE, "%s", in.name);
/* NOTREACHED */
/* Ensure in.fd is outside the stdio descriptor range */
- in.fd = redup_clean_fd(in.fd);
+ redup_clean_fd(&in);
}
getfdtype(&in);
@@ -154,14 +173,15 @@
} else {
#define OFLAGS \
(O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
- out.fd = open(out.name, O_RDWR | OFLAGS, DEFFILEMODE);
+ out.fd = ddop_open(out, out.name, O_RDWR | OFLAGS, DEFFILEMODE);
/*
* May not have read access, so try again with write only.
* Without read we may have a problem if output also does
* not support seeks.
*/
if (out.fd < 0) {
- out.fd = open(out.name, O_WRONLY | OFLAGS, DEFFILEMODE);
+ out.fd = ddop_open(out, out.name, O_WRONLY | OFLAGS,
+ DEFFILEMODE);
out.flags |= NOREAD;
}
if (out.fd < 0) {
@@ -170,7 +190,7 @@
}
/* Ensure out.fd is outside the stdio descriptor range */
- out.fd = redup_clean_fd(out.fd);
+ redup_clean_fd(&out);
}
getfdtype(&out);
@@ -205,7 +225,7 @@
* kinds of output files, tapes, for example.
*/
if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK))
- (void)ftruncate(out.fd, (off_t)out.offset * out.dbsz);
+ (void)ddop_ftruncate(out, out.fd, (off_t)out.offset * out.dbsz);
/*
* If converting case at the same time as another conversion, build a
@@ -251,13 +271,15 @@
struct mtget mt;
struct stat sb;
- if (fstat(io->fd, &sb)) {
+ if (io->ops->op_fstat(io->fd, &sb)) {
err(EXIT_FAILURE, "%s", io->name);
/* NOTREACHED */
}
if (S_ISCHR(sb.st_mode))
- io->flags |= ioctl(io->fd, MTIOCGET, &mt) ? ISCHR : ISTAPE;
- else if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
+ io->flags |= io->ops->op_ioctl(io->fd, MTIOCGET, &mt)
+ ? ISCHR : ISTAPE;
+ else if (io->ops->op_lseek(io->fd, (off_t)0, SEEK_CUR) == -1
+ && errno == ESPIPE)
io->flags |= ISPIPE; /* XXX fixed in 4.4BSD */
}
@@ -267,29 +289,29 @@
* accidentally outputting completion or error messages into the
* output file that were intended for the tty.
*/
-static int
-redup_clean_fd(int fd)
+static void
+redup_clean_fd(IO *io)
{
+ int fd = io->fd;
int newfd;
if (fd != STDIN_FILENO && fd != STDOUT_FILENO &&
fd != STDERR_FILENO)
/* File descriptor is ok, return immediately. */
- return fd;
+ return;
/*
* 3 is the first descriptor greater than STD*_FILENO. Any
* free descriptor valued 3 or above is acceptable...
*/
- newfd = fcntl(fd, F_DUPFD, 3);
+ newfd = io->ops->op_fcntl(fd, F_DUPFD, 3);
if (newfd < 0) {
err(EXIT_FAILURE, "dupfd IO");
/* NOTREACHED */
}
- close(fd);
-
- return newfd;
+ io->ops->op_close(fd);
+ io->fd = newfd;
}
static void
@@ -316,7 +338,7 @@
(void)memset(in.dbp, 0, in.dbsz);
}
- n = read(in.fd, in.dbp, in.dbsz);
+ n = ddop_read(in, in.fd, in.dbp, in.dbsz);
if (n == 0) {
in.dbrcnt = 0;
return;
@@ -343,7 +365,7 @@
* in sector size chunks.
*/
if (!(in.flags & (ISPIPE|ISTAPE)) &&
- lseek(in.fd, (off_t)in.dbsz, SEEK_CUR))
+ ddop_lseek(in, in.fd, (off_t)in.dbsz, SEEK_CUR))
warn("%s", in.name);
/* If sync not specified, omit block and continue. */
@@ -431,11 +453,12 @@
* may be shared among with other processes and close(2) just
* decreases the reference count.
*/
- if (out.fd == STDOUT_FILENO && fsync(out.fd) == -1 && errno != EINVAL) {
+ if (out.fd == STDOUT_FILENO && ddop_fsync(out, out.fd) == -1
+ && errno != EINVAL) {
err(EXIT_FAILURE, "fsync stdout");
/* NOTREACHED */
}
- if (close(out.fd) == -1) {
+ if (ddop_close(out, out.fd) == -1) {
err(EXIT_FAILURE, "close");
/* NOTREACHED */
}
@@ -484,12 +507,12 @@
}
}
if (pending != 0) {
- if (lseek(out.fd, pending, SEEK_CUR) ==
- -1)
+ if (ddop_lseek(out,
+ out.fd, pending, SEEK_CUR) == -1)
err(EXIT_FAILURE, "%s: seek error creating sparse file",
out.name);
}
- nw = bwrite(out.fd, outp, cnt);
+ nw = bwrite(&out, outp, cnt);
if (nw <= 0) {
if (nw == 0)
errx(EXIT_FAILURE,
@@ -545,14 +568,14 @@
* A protected against SIGINFO write
*/
ssize_t
-bwrite(int fd, const void *buf, size_t len)
+bwrite(IO *io, const void *buf, size_t len)
{
sigset_t oset;
ssize_t rv;
int oerrno;
(void)sigprocmask(SIG_BLOCK, &infoset, &oset);
- rv = write(fd, buf, len);
+ rv = io->ops->op_write(io->fd, buf, len);
oerrno = errno;
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
errno = oerrno;
Index: src/bin/dd/extern.h
diff -u src/bin/dd/extern.h:1.17 src/bin/dd/extern.h:1.18
--- src/bin/dd/extern.h:1.17 Mon Jan 9 10:17:05 2006
+++ src/bin/dd/extern.h Mon Nov 22 21:04:28 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: extern.h,v 1.17 2006/01/09 10:17:05 apb Exp $ */
+/* $NetBSD: extern.h,v 1.18 2010/11/22 21:04:28 pooka Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -50,7 +50,7 @@
void terminate(int);
void unblock(void);
void unblock_close(void);
-ssize_t bwrite(int, const void *, size_t);
+ssize_t bwrite(IO *, const void *, size_t);
extern IO in, out;
extern STAT st;
Index: src/bin/dd/position.c
diff -u src/bin/dd/position.c:1.17 src/bin/dd/position.c:1.18
--- src/bin/dd/position.c:1.17 Sat Feb 14 07:13:40 2009
+++ src/bin/dd/position.c Mon Nov 22 21:04:28 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: position.c,v 1.17 2009/02/14 07:13:40 lukem Exp $ */
+/* $NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)position.c 8.3 (Berkeley) 4/2/94";
#else
-__RCSID("$NetBSD: position.c,v 1.17 2009/02/14 07:13:40 lukem Exp $");
+__RCSID("$NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka Exp $");
#endif
#endif /* not lint */
@@ -70,7 +70,7 @@
/* If not a pipe or tape device, try to seek on it. */
if (!(in.flags & (ISPIPE|ISTAPE))) {
- if (lseek(in.fd,
+ if (ddop_lseek(in, in.fd,
(off_t)in.offset * (off_t)in.dbsz, SEEK_CUR) == -1) {
err(EXIT_FAILURE, "%s", in.name);
/* NOTREACHED */
@@ -85,7 +85,7 @@
* blocks for other devices.
*/
for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
- if ((nr = read(in.fd, in.db, bcnt)) > 0) {
+ if ((nr = ddop_read(in, in.fd, in.db, bcnt)) > 0) {
if (in.flags & ISPIPE) {
if (!(bcnt -= nr)) {
bcnt = in.dbsz;
@@ -137,7 +137,7 @@
* have specified the seek operand.
*/
if (!(out.flags & ISTAPE)) {
- if (lseek(out.fd,
+ if (ddop_lseek(out, out.fd,
(off_t)out.offset * (off_t)out.dbsz, SEEK_SET) == -1)
err(EXIT_FAILURE, "%s", out.name);
/* NOTREACHED */
@@ -149,7 +149,7 @@
t_op.mt_op = MTFSR;
t_op.mt_count = out.offset;
- if (ioctl(out.fd, MTIOCTOP, &t_op) < 0)
+ if (ddop_ioctl(out, out.fd, MTIOCTOP, &t_op) < 0)
err(EXIT_FAILURE, "%s", out.name);
/* NOTREACHED */
return;
@@ -157,7 +157,7 @@
/* Read it. */
for (cnt = 0; cnt < out.offset; ++cnt) {
- if ((n = read(out.fd, out.db, out.dbsz)) > 0)
+ if ((n = ddop_read(out, out.fd, out.db, out.dbsz)) > 0)
continue;
if (n < 0)
@@ -171,12 +171,13 @@
*/
t_op.mt_op = MTBSR;
t_op.mt_count = 1;
- if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
+ if (ddop_ioctl(out, out.fd, MTIOCTOP, &t_op) == -1)
err(EXIT_FAILURE, "%s", out.name);
/* NOTREACHED */
while (cnt++ < out.offset)
- if ((uint64_t)(n = bwrite(out.fd, out.db, out.dbsz)) != out.dbsz)
+ if ((uint64_t)(n = bwrite(&out,
+ out.db, out.dbsz)) != out.dbsz)
err(EXIT_FAILURE, "%s", out.name);
/* NOTREACHED */
break;