The branch, master has been updated via 5147ff5 s3: tests: Add blackbox test for scopy. via eeddeba docs: Document new scopy command. via cebcf0e s3:client: Add "scopy" cmd to perform Server Side copy using smbclient. from 1023db2 ctdb-daemon: Return correct sequence number for CONTROL_GET_DB_SEQNUM
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 5147ff54e3c5f9e35ae32bf880b01b1e9cc8e08d Author: Jeremy Allison <j...@samba.org> Date: Mon Jul 13 14:15:45 2015 -0700 s3: tests: Add blackbox test for scopy. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> Autobuild-User(master): Ralph Böhme <s...@samba.org> Autobuild-Date(master): Tue Jul 14 16:10:44 CEST 2015 on sn-devel-104 commit eeddeba8b5201b837ddf5005f693cd7f9fb962f2 Author: Jeremy Allison <j...@samba.org> Date: Fri Jul 10 10:29:01 2015 -0700 docs: Document new scopy command. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit cebcf0e4dad42b5ede11681f57c19e2384655218 Author: Anubhav Rakshit <anubhav.raks...@gmail.com> Date: Thu Jun 25 11:37:18 2015 +0530 s3:client: Add "scopy" cmd to perform Server Side copy using smbclient. Signed-off-by: Anubhav Rakshit <anubhav.raks...@gmail.com> Reviewed-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> ----------------------------------------------------------------------- Summary of changes: docs-xml/manpages/smbclient.1.xml | 8 ++ source3/client/client.c | 134 ++++++++++++++++++++++++++++++ source3/script/tests/test_smbclient_s3.sh | 79 ++++++++++++++++++ 3 files changed, 221 insertions(+) Changeset truncated at 500 lines: diff --git a/docs-xml/manpages/smbclient.1.xml b/docs-xml/manpages/smbclient.1.xml index 8b166d1..e1d805a 100644 --- a/docs-xml/manpages/smbclient.1.xml +++ b/docs-xml/manpages/smbclient.1.xml @@ -1011,6 +1011,14 @@ </varlistentry> <varlistentry> + <term>scopy <source filename> <destination filename></term> + <listitem><para>Attempt to copy a file on the server using the + most efficient server-side copy calls. Falls back to using + read then write if server doesn't support server-side copy. + </para></listitem> + </varlistentry> + + <varlistentry> <term>setmode <filename> <perm=[+|\-]rsha></term> <listitem><para>A version of the DOS attrib command to set file permissions. For example: </para> diff --git a/source3/client/client.c b/source3/client/client.c index fde5b49..f49f3ff 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -3806,6 +3806,139 @@ static int cmd_rename(void) return 0; } +struct scopy_timing { + struct timespec tp_start; +}; + +static int scopy_status(off_t written, void *priv) +{ + struct timespec tp_end; + unsigned int scopy_total_time_ms; + struct scopy_timing *st = priv; + + clock_gettime_mono(&tp_end); + scopy_total_time_ms = nsec_time_diff(&tp_end,&st->tp_start)/1000000; + + DEBUG(5,("Copied %jd bytes at an average %3.1f kb/s\n", + (intmax_t)written, written / (1.024*scopy_total_time_ms))); + + return true; +} + +/**************************************************************************** + Server-Side copy some file. +****************************************************************************/ + +static int cmd_scopy(void) +{ + TALLOC_CTX *ctx = talloc_tos(); + char *src, *dest; + char *buf, *buf2; + struct cli_state *targetcli; + char *targetsrc; + char *targetdest; + uint32_t DesiredAccess, ShareAccess, CreateDisposition, CreateOptions; + struct smb_create_returns cr; + uint16_t destfnum = (uint16_t)-1; + uint16_t srcfnum = (uint16_t)-1; + off_t written = 0; + struct scopy_timing st; + int rc = 0; + NTSTATUS status; + + if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || + !next_token_talloc(ctx, &cmd_ptr,&buf2,NULL)) { + d_printf("scopy <src> <dest>\n"); + return 1; + } + + src = talloc_asprintf(ctx, + "%s%s", + client_get_cur_dir(), + buf); + if (!src) { + return 1; + } + + dest = talloc_asprintf(ctx, + "%s%s", + client_get_cur_dir(), + buf2); + if (!dest) { + return 1; + } + + status = cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, + &targetsrc); + if (!NT_STATUS_IS_OK(status)) { + d_printf("scopy %s: %s\n", src, nt_errstr(status)); + return 1; + } + + status = cli_resolve_path(ctx, "", auth_info, cli, dest, &targetcli, + &targetdest); + if (!NT_STATUS_IS_OK(status)) { + d_printf("scopy %s: %s\n", dest, nt_errstr(status)); + return 1; + } + + + DesiredAccess = (FILE_READ_DATA|FILE_READ_EA|FILE_READ_ATTRIBUTES| + READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS); + ShareAccess = FILE_SHARE_READ|FILE_SHARE_DELETE; + CreateDisposition = FILE_OPEN; + CreateOptions = (FILE_SEQUENTIAL_ONLY|FILE_NON_DIRECTORY_FILE| + FILE_OPEN_REPARSE_POINT); + status = cli_ntcreate(targetcli, targetsrc, 0, DesiredAccess, 0, + ShareAccess, CreateDisposition, CreateOptions, 0x0, + &srcfnum, &cr); + if (!NT_STATUS_IS_OK(status)) { + d_printf("Failed to open file %s. %s\n", + targetsrc, nt_errstr(status)); + return 1; + } + + DesiredAccess = (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_READ_EA| + FILE_WRITE_EA|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES| + DELETE_ACCESS|READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|SYNCHRONIZE_ACCESS); + ShareAccess = FILE_SHARE_NONE; + CreateDisposition = FILE_CREATE; + CreateOptions = FILE_SEQUENTIAL_ONLY|FILE_NON_DIRECTORY_FILE; + status = cli_ntcreate(targetcli, targetdest, 0, DesiredAccess, + FILE_ATTRIBUTE_ARCHIVE, ShareAccess, CreateDisposition, + CreateOptions, 0x0, &destfnum, NULL); + if (!NT_STATUS_IS_OK(status)) { + d_printf("Failed to create file %s. %s\n", + targetdest, nt_errstr(status)); + cli_close(targetcli, srcfnum); + return 1; + } + + clock_gettime_mono(&st.tp_start); + status = cli_splice(targetcli, targetcli, srcfnum, destfnum, + cr.end_of_file, 0, 0, &written, scopy_status, &st); + if (!NT_STATUS_IS_OK(status)) { + d_printf("%s copying file %s -> %s \n", + nt_errstr(status), + targetsrc, + targetdest); + rc = 1; + } + + status = cli_close(targetcli, srcfnum); + if (!NT_STATUS_IS_OK(status)) { + d_printf("Error %s closing remote source file\n", nt_errstr(status)); + rc = 1; + } + status = cli_close(targetcli, destfnum); + if (!NT_STATUS_IS_OK(status)) { + d_printf("Error %s closing remote dest file\n", nt_errstr(status)); + rc = 1; + } + + return rc; +} + /**************************************************************************** Print the volume name. ****************************************************************************/ @@ -4699,6 +4832,7 @@ static struct { {"setea", cmd_setea, "<file name> <eaname> <eaval> Set an EA of a file", {COMPL_REMOTE, COMPL_LOCAL}}, {"setmode",cmd_setmode,"<file name> <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}}, + {"scopy",cmd_scopy,"<src> <dest> server-side copy file",{COMPL_REMOTE,COMPL_REMOTE}}, {"stat",cmd_stat,"<file name> Do a UNIX extensions stat call on a file",{COMPL_REMOTE,COMPL_NONE}}, {"symlink",cmd_symlink,"<oldname> <newname> create a UNIX symlink",{COMPL_REMOTE,COMPL_REMOTE}}, {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}}, diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh index faf8d98..69c7452 100755 --- a/source3/script/tests/test_smbclient_s3.sh +++ b/source3/script/tests/test_smbclient_s3.sh @@ -896,6 +896,81 @@ EOF fi } +# Test using scopy to copy a file on the server. +test_scopy() +{ + tmpfile=$PREFIX/smbclient_interactive_prompt_commands + scopy_file=$PREFIX/scopy_file + + rm -f $scopy_file + cat > $tmpfile <<EOF +put ${SMBCLIENT} +scopy smbclient scopy_file +lcd ${PREFIX} +get scopy_file +del smbclient +del scopy_file +quit +EOF + cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -mSMB3 -U$USERNAME%$PASSWORD //$SERVER/tmp -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' + eval echo "$cmd" + out=`eval $cmd` + ret=$? + out1=`md5sum ${SMBCLIENT} | sed -e 's/ .*//'` + out2=`md5sum ${scopy_file} | sed -e 's/ .*//'` + rm -f $tmpfile + rm -f $scopy_file + + if [ $ret != 0 ] ; then + echo "$out" + echo "failed scopy test (1) with output $ret" + false + return + fi + + if [ $out1 != $out2 ] ; then + echo "$out1 $out2" + echo "failed md5sum (1)" + false + fi + +# +# Now do again using SMB1 +# to force client-side fallback. +# + + cat > $tmpfile <<EOF +put ${SMBCLIENT} +scopy smbclient scopy_file +lcd ${PREFIX} +get scopy_file +del smbclient +del scopy_file +quit +EOF + cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -mNT1 -U$USERNAME%$PASSWORD //$SERVER/tmp -I $SERVER_IP $ADDARGS < $tmpfile 2>&1' + eval echo "$cmd" + out=`eval $cmd` + ret=$? + out1=`md5sum ${SMBCLIENT} | sed -e 's/ .*//'` + out2=`md5sum ${scopy_file} | sed -e 's/ .*//'` + rm -f $tmpfile + rm -f $scopy_file + + if [ $ret != 0 ] ; then + echo "$out" + echo "failed scopy test (2) with output $ret" + false + return + fi + + if [ $out1 != $out2 ] ; then + echo "$out1 $out2" + echo "failed md5sum (2)" + false + fi +} + LOGDIR_PREFIX=test_smbclient_s3 @@ -980,6 +1055,10 @@ testit "list a share with a mangled name + acl_xattr object" \ test_mangled_names || \ failed=`expr $failed + 1` +testit "server-side file copy" \ + test_scopy || \ + failed=`expr $failed + 1` + testit "rm -rf $LOGDIR" \ rm -rf $LOGDIR || \ failed=`expr $failed + 1` -- Samba Shared Repository