--- hpn-ssh-hpn-18.4.2/Makefile.in.orig
+++ hpn-ssh-hpn-18.4.2/Makefile.in
@@ -103,6 +103,7 @@
 	monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \
 	ssh-ed25519-sk.o ssh-rsa.o dh.o \
 	msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
+	sftp_provider.o \
 	ssh-pkcs11.o smult_curve25519_ref.o \
 	poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \
 	cipher-chachapoly-libcrypto-mt.o \
@@ -133,7 +134,7 @@
 	srclimit.o sftp-server.o sftp-common.o \
 	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
 	sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \
-	sandbox-solaris.o uidswap.o cipher-switch.o $(SKOBJS)
+	sandbox-solaris.o uidswap.o cipher-switch.o sftp_provider.o $(SKOBJS)
 
 SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o
 
@@ -153,7 +154,8 @@
 
 SSHKEYSCAN_OBJS=ssh-keyscan.o $(SKOBJS)
 
-SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o
+SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o sftp_provider.o
+ROOTDLIBDIR=$(DESTDIR)/usr/lib/dtrace
 
 SFTP_OBJS=	sftp.o sftp-usergroup.o progressmeter.o $(SFTP_CLIENT_OBJS)
 
@@ -266,9 +268,22 @@
 moduli:
 	echo
 
+# dtrace sftp
+sftp_provider.h: $(srcdir)/sftp_provider.d
+	/usr/sbin/dtrace -xnolibs -h -s $(srcdir)/sftp_provider.d \
+	    -o $(srcdir)/sftp_provider.h
+
+sftp_provider.o: sftp_provider.d sftp_provider.h sftp-server.o
+	/usr/sbin/dtrace -G -64 -xnolibs -s $(srcdir)/sftp_provider.d \
+	    sftp-server.o -o sftp_provider.o
+
+# special case for sftp-server.o, it includes sftp_provider.h
+sftp-server.o: sftp_provider.h sftp-server.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $(srcdir)/sftp-server.c
+
 clean:	regressclean
 	rm -f *.o *.lo *.a $(TARGETS) logintest config.cache config.log
-	rm -f *.out core survey
+	rm -f *.out core survey sftp_provider.h
 	rm -f regress/check-perm$(EXEEXT)
 	rm -f regress/mkdtemp$(EXEEXT)
 	rm -f regress/unittests/test_helper/*.a
@@ -470,6 +485,7 @@
 	$(INSTALL) -m 644 hpnssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/hpnssh-keysign.8
 	$(INSTALL) -m 644 hpnssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/hpnssh-pkcs11-helper.8
 	$(INSTALL) -m 644 hpnssh-sk-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/hpnssh-sk-helper.8
+	mkdir -p $(ROOTDLIBDIR) && cp $(srcdir)/hpnsftp.d $(ROOTDLIBDIR)/
 
 install-sysconf:
 	$(MKDIR_P) $(DESTDIR)$(sysconfdir)
--- hpn-ssh-hpn-18.4.2/sftp-server.c.orig
+++ hpn-ssh-hpn-18.4.2/sftp-server.c
@@ -56,6 +56,9 @@
 
 #include "sftp.h"
 #include "sftp-common.h"
+#ifdef DTRACE_SFTP
+#include "sftp_provider_impl.h"
+#endif
 
 char *sftp_realpath(const char *, char *); /* sftp-realpath.c */
 
@@ -803,14 +806,17 @@
 	u_int32_t len;
 	int r, handle, fd, ret, status = SSH2_FX_FAILURE;
 	u_int64_t off;
+	char *fpath;
 
 	if ((r = get_handle(iqueue, &handle)) != 0 ||
 	    (r = sshbuf_get_u64(iqueue, &off)) != 0 ||
 	    (r = sshbuf_get_u32(iqueue, &len)) != 0)
 		fatal_fr(r, "parse");
 
+	fpath = handle_to_name(handle);
+
 	debug("request %u: read \"%s\" (handle %d) off %llu len %u",
-	    id, handle_to_name(handle), handle, (unsigned long long)off, len);
+	    id, fpath, handle, (unsigned long long)off, len);
 	if ((fd = handle_to_fd(handle)) == -1)
 		goto out;
 	if (len > SFTP_MAX_READ_LENGTH) {
@@ -829,6 +835,9 @@
 		    strerror(errno));
 		goto out;
 	}
+#ifdef DTRACE_SFTP
+	SFTP_TRANSFER_START_OP("read", fd, fpath, len);
+#endif
 	if (len == 0) {
 		/* weird, but not strictly disallowed */
 		ret = 0;
@@ -841,11 +850,18 @@
 		status = SSH2_FX_EOF;
 		goto out;
 	}
+#ifdef DTRACE_SFTP
+	SFTP_TRANSFER_DONE_OP("read", fd, fpath, ret);
+#endif
 	send_data(id, buf, ret);
 	handle_update_read(handle, ret);
 	/* success */
 	status = SSH2_FX_OK;
  out:
+#ifdef DTRACE_SFTP
+	if (status != SSH2_FX_OK)
+		SFTP_TRANSFER_DONE_OP("read", fd, fpath, ret);
+#endif
 	if (status != SSH2_FX_OK)
 		send_status(id, status);
 }
@@ -857,14 +873,17 @@
 	size_t len;
 	int r, handle, fd, ret, status;
 	u_char *data;
+	char *fpath;
 
 	if ((r = get_handle(iqueue, &handle)) != 0 ||
 	    (r = sshbuf_get_u64(iqueue, &off)) != 0 ||
 	    (r = sshbuf_get_string(iqueue, &data, &len)) != 0)
 		fatal_fr(r, "parse");
 
+	fpath = handle_to_name(handle);
+
 	debug("request %u: write \"%s\" (handle %d) off %llu len %zu",
-	    id, handle_to_name(handle), handle, (unsigned long long)off, len);
+	    id, fpath, handle, (unsigned long long)off, len);
 	fd = handle_to_fd(handle);
 
 	if (fd < 0)
@@ -877,7 +896,13 @@
 			    strerror(errno));
 		} else {
 /* XXX ATOMICIO ? */
+#ifdef DTRACE_SFTP
+			SFTP_TRANSFER_START_OP("write", fd, fpath, len);
+#endif
 			ret = write(fd, data, len);
+#ifdef DTRACE_SFTP
+			SFTP_TRANSFER_DONE_OP("write", fd, fpath, ret);
+#endif
 			if (ret == -1) {
 				status = errno_to_portable(errno);
 				error_f("write \"%.100s\": %s",
--- /dev/null
+++ hpn-ssh-hpn-18.4.2/hpnsftp.d
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#pragma D depends_on library net.d
+#pragma D depends_on library io.d
+#pragma D depends_on module lofs
+
+typedef struct hpnsftpinfo {
+	string sfi_user;		/* user name */
+	string sfi_operation;		/* SFTP Operation */
+	ssize_t sfi_nbytes;		/* bytes transferred, if any */
+	string sfi_pathname;		/* pathname of transfer */
+	string sfi_fsresource;		/* Dataset(ZFS) or resource name */
+} hpnsftpinfo_t;
+
+/*
+ * This structure must match the definition of same in sftp_provider_impl.h.
+ */
+typedef struct hpnsftpproto {
+	int64_t sftp_nbytes;		/* bytes written or read */
+	uint64_t sftp_user;		/* user name */
+	uint64_t sftp_operation;	/* SFTP operation */
+	uint64_t sftp_raddr;		/* remote address */
+	uint64_t sftp_pathname;		/* path with file name */
+	int32_t sftp_fd;		/* fd for transfer, if any */
+} hpnsftpproto_t;
+
+#pragma D binding "1.6.1" translator
+translator conninfo_t <hpnsftpproto_t *s> {
+	ci_protocol = "tcp";
+	ci_remote = copyinstr((uintptr_t)
+	    *(uint64_t *)copyin((uintptr_t)&s->sftp_raddr, sizeof (uint64_t)));
+	ci_local = "<unknown>";
+};
+
+#pragma D binding "1.6.1" translator
+translator hpnsftpinfo_t <hpnsftpproto_t *s> {
+	sfi_user = copyinstr((uintptr_t)
+	    *(uint64_t *)copyin((uintptr_t)&s->sftp_user, sizeof (uint64_t)));
+	sfi_operation = copyinstr((uintptr_t)
+	    *(uint64_t *)copyin((uintptr_t)&s->sftp_operation,
+	    sizeof (uint64_t)));
+	sfi_nbytes =
+	    *(uint64_t *)copyin((uintptr_t)&s->sftp_nbytes, sizeof (uint64_t));
+	sfi_fsresource = stringof(fds[*(int32_t *)copyin((uintptr_t)&s->sftp_fd,
+	    sizeof (int32_t))].fi_fs) == "lofs" ? stringof(((struct loinfo *)
+	    curthread->t_procp->p_user.u_finfo.fi_list[*(int32_t *)copyin(
+	    (uintptr_t)&s->sftp_fd, sizeof (int32_t))].uf_file->f_vnode->
+	    v_vfsp->vfs_data)->li_realvfs->vfs_resource->rs_string) :
+	    stringof(curthread->t_procp->p_user.u_finfo.fi_list[
+	    *(int32_t *)copyin((uintptr_t)&s->sftp_fd, sizeof (int32_t))].
+	    uf_file->f_vnode->v_vfsp->vfs_resource->rs_string);
+	sfi_pathname = copyinstr((uintptr_t)*(uint64_t *)copyin(
+	    (uintptr_t)&s->sftp_pathname, sizeof (uint64_t)));
+};
--- /dev/null
+++ hpn-ssh-hpn-18.4.2/sftp_provider.d
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * We seem currently unable to depend properly on existing D libraries (like
+ * hpnsftp.d). But the definitions for conninfo_t and sftpinfo_t are stored there
+ * (and have to be, since that's where the real translators live). So we're
+ * forced to define something here to satisfy dtrace(8), but none of the
+ * definitions or translators here are actually used.
+ */
+typedef struct sftpinfo {
+	int dummy;
+} sftpinfo_t;
+
+typedef struct sftpproto {
+	int dummy;
+} sftpproto_t;
+
+typedef struct conninfo {
+	int dummy;
+} conninfo_t;
+
+translator conninfo_t <sftpproto_t *dp> {
+};
+
+translator sftpinfo_t <sftpproto_t *dp> {
+};
+
+provider sftp {
+	probe transfer__start(sftpproto_t *p) :
+	    (conninfo_t *p, sftpinfo_t *p);
+	probe transfer__done(sftpproto_t *p) :
+	    (conninfo_t *p, sftpinfo_t *p);
+};
+
+#pragma D attributes Evolving/Evolving/ISA provider sftp provider
+#pragma D attributes Private/Private/Unknown provider sftp module
+#pragma D attributes Private/Private/Unknown provider sftp function
+#pragma D attributes Private/Private/ISA provider sftp name
+#pragma D attributes Evolving/Evolving/ISA provider sftp args
--- /dev/null
+++ hpn-ssh-hpn-18.4.2/sftp_provider_impl.h
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_SFTP_PROVIDER_IMPL_H
+#define	_SFTP_PROVIDER_IMPL_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * This structure must match the definition of same in hpnsftp.d.
+ */
+typedef struct sftpproto {
+	int64_t sftp_nbytes;		/* bytes writtten or read */
+	const char *sftp_user;		/* user name */
+	const char *sftp_operation;	/* SFTP Operation */
+	const char *sftp_raddr;		/* remote address */
+	const char *sftp_pathname;	/* path with file name */
+	int32_t sftp_fd;		/* fd for transfer, if any */
+} sftpproto_t;
+
+#define	SFTP_TRANSFER_PROTO(proto, op, fd, path, len) \
+	bzero((proto), sizeof (struct sftpproto)); \
+	(proto)->sftp_user = (pw->pw_name ? pw->pw_name : "UNKNOWN"); \
+	(proto)->sftp_operation = (op ? op : "UNKNOWN"); \
+	(proto)->sftp_raddr = (client_addr); \
+	(proto)->sftp_fd = (fd); \
+	(proto)->sftp_pathname = (path ? path : "UNKNOWN"); \
+	(proto)->sftp_nbytes = (len); \
+
+#define	SFTP_TRANSFER_START_OP(op, fd, path, len) \
+	if (SFTP_TRANSFER_START_ENABLED()) { \
+		sftpproto_t proto; \
+		SFTP_TRANSFER_PROTO(&proto, op, fd, path, len); \
+		SFTP_TRANSFER_START(&proto); \
+	} \
+
+#define	SFTP_TRANSFER_DONE_OP(op, fd, path, len) \
+	if (SFTP_TRANSFER_DONE_ENABLED()) { \
+		sftpproto_t proto; \
+		SFTP_TRANSFER_PROTO(&proto, op, fd, path, len); \
+		SFTP_TRANSFER_DONE(&proto); \
+	} \
+
+#include "sftp_provider.h"
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _SFTP_PROVIDER_IMPL_H */
