Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Sep 2019 21:56:42 +0000 (UTC)
From:      Matt Macy <mmacy@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r352922 - head/bin/dd
Message-ID:  <201909302156.x8ULugWF032095@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mmacy
Date: Mon Sep 30 21:56:42 2019
New Revision: 352922
URL: https://svnweb.freebsd.org/changeset/base/352922

Log:
  Add oflag=fsync and oflag=sync capability to dd
  
  Sets the O_FSYNC flag on the output file. oflag=fsync and oflag=sync are
  synonyms just as O_FSYNC and O_SYNC are synonyms. This functionality is
  intended to improve portability of dd commands in the ZFS test suite.
  
  Submitted by:	Ryan Moeller
  Reviewed by:	manpages, mmacy@
  MFC after:	1 week
  Sponsored by:	 iXsytems, Inc.
  Differential Revision:	https://reviews.freebsd.org/D21422

Modified:
  head/bin/dd/args.c
  head/bin/dd/dd.1
  head/bin/dd/dd.c
  head/bin/dd/dd.h

Modified: head/bin/dd/args.c
==============================================================================
--- head/bin/dd/args.c	Mon Sep 30 21:53:26 2019	(r352921)
+++ head/bin/dd/args.c	Mon Sep 30 21:56:42 2019	(r352922)
@@ -41,7 +41,7 @@ static char sccsid[] = "@(#)args.c	8.3 (Berkeley) 4/2/
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/types.h>
+#include <sys/param.h>
 
 #include <ctype.h>
 #include <err.h>
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
 
 static int	c_arg(const void *, const void *);
 static int	c_conv(const void *, const void *);
+static int	c_oflag(const void *, const void *);
 static void	f_bs(char *);
 static void	f_cbs(char *);
 static void	f_conv(char *);
@@ -67,6 +68,7 @@ static void	f_ibs(char *);
 static void	f_if(char *);
 static void	f_obs(char *);
 static void	f_of(char *);
+static void	f_oflag(char *);
 static void	f_seek(char *);
 static void	f_skip(char *);
 static void	f_speed(char *);
@@ -90,6 +92,7 @@ static const struct arg {
 	{ "iseek",	f_skip,		C_SKIP,	 C_SKIP },
 	{ "obs",	f_obs,		C_OBS,	 C_BS|C_OBS },
 	{ "of",		f_of,		C_OF,	 C_OF },
+	{ "oflag",	f_oflag,	0,	 0 },
 	{ "oseek",	f_seek,		C_SEEK,	 C_SEEK },
 	{ "seek",	f_seek,		C_SEEK,	 C_SEEK },
 	{ "skip",	f_skip,		C_SKIP,	 C_SKIP },
@@ -348,8 +351,8 @@ f_conv(char *arg)
 
 	while (arg != NULL) {
 		tmp.name = strsep(&arg, ",");
-		cp = bsearch(&tmp, clist, sizeof(clist) / sizeof(struct conv),
-		    sizeof(struct conv), c_conv);
+		cp = bsearch(&tmp, clist, nitems(clist), sizeof(struct conv),
+		    c_conv);
 		if (cp == NULL)
 			errx(1, "unknown conversion %s", tmp.name);
 		if (ddflags & cp->noset)
@@ -366,6 +369,37 @@ c_conv(const void *a, const void *b)
 
 	return (strcmp(((const struct conv *)a)->name,
 	    ((const struct conv *)b)->name));
+}
+
+static const struct oflag {
+	const char *name;
+	uint64_t set;
+} olist[] = {
+	{ "fsync",	C_OFSYNC },
+	{ "sync",	C_OFSYNC },
+};
+
+static void
+f_oflag(char *arg)
+{
+	struct oflag *op, tmp;
+
+	while (arg != NULL) {
+		tmp.name = strsep(&arg, ",");
+		op = bsearch(&tmp, olist, nitems(olist), sizeof(struct oflag),
+		    c_oflag);
+		if (op == NULL)
+			errx(1, "unknown open flag %s", tmp.name);
+		ddflags |= op->set;
+	}
+}
+
+static int
+c_oflag(const void *a, const void *b)
+{
+
+	return (strcmp(((const struct oflag *)a)->name,
+	    ((const struct oflag *)b)->name));
 }
 
 static intmax_t

Modified: head/bin/dd/dd.1
==============================================================================
--- head/bin/dd/dd.1	Mon Sep 30 21:53:26 2019	(r352921)
+++ head/bin/dd/dd.1	Mon Sep 30 21:56:42 2019	(r352922)
@@ -123,6 +123,19 @@ If an initial portion of the output file is seeked pas
 .Cm oseek
 operand),
 the output file is truncated at that point.
+.It Cm oflag Ns = Ns Ar value Ns Op , Ns Ar value ...
+Where
+.Cm value
+is one of the symbols from the following list.
+.Bl -tag -width "fsync"
+.It Cm fsync
+Set the O_FSYNC flag on the output file to make writes synchronous.
+.It Cm sync
+Set the O_SYNC flag on the output file to make writes synchronous.
+This is synonymous with the
+.Cm fsync
+value.
+.El
 .It Cm oseek Ns = Ns Ar n
 Seek on the output file
 .Ar n

Modified: head/bin/dd/dd.c
==============================================================================
--- head/bin/dd/dd.c	Mon Sep 30 21:53:26 2019	(r352921)
+++ head/bin/dd/dd.c	Mon Sep 30 21:56:42 2019	(r352922)
@@ -143,6 +143,7 @@ static void
 setup(void)
 {
 	u_int cnt;
+	int oflags;
 	cap_rights_t rights;
 	unsigned long cmds[] = { FIODTYPE, MTIOCTOP };
 
@@ -171,17 +172,28 @@ setup(void)
 		/* No way to check for read access here. */
 		out.fd = STDOUT_FILENO;
 		out.name = "stdout";
+		if (ddflags & C_OFSYNC) {
+			oflags = fcntl(out.fd, F_GETFL);
+			if (oflags == -1)
+				err(1, "unable to get fd flags for stdout");
+			oflags |= O_FSYNC;
+			if (fcntl(out.fd, F_SETFL, oflags) == -1)
+				err(1, "unable to set fd flags for stdout");
+		}
 	} else {
-#define	OFLAGS \
-    (O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
-		out.fd = open(out.name, O_RDWR | OFLAGS, DEFFILEMODE);
+		oflags = O_CREAT;
+		if (!(ddflags & (C_SEEK | C_NOTRUNC)))
+			oflags |= O_TRUNC;
+		if (ddflags & C_OFSYNC)
+			oflags |= O_FSYNC;
+		out.fd = open(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 == -1) {
-			out.fd = open(out.name, O_WRONLY | OFLAGS, DEFFILEMODE);
+			out.fd = open(out.name, O_WRONLY | oflags, DEFFILEMODE);
 			out.flags |= NOREAD;
 			cap_rights_clear(&rights, CAP_READ);
 		}

Modified: head/bin/dd/dd.h
==============================================================================
--- head/bin/dd/dd.h	Mon Sep 30 21:53:26 2019	(r352921)
+++ head/bin/dd/dd.h	Mon Sep 30 21:56:42 2019	(r352922)
@@ -103,6 +103,7 @@ typedef struct {
 #define	C_PROGRESS	0x0000000040000000ULL
 #define	C_FSYNC		0x0000000080000000ULL
 #define	C_FDATASYNC	0x0000000100000000ULL
+#define	C_OFSYNC	0x0000000200000000ULL
 
 #define	C_PARITY	(C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET)
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909302156.x8ULugWF032095>