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;

Reply via email to