From 0b53e7a46e7a7f821fef88a0954403b859e04c39 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Aug 2018 18:24:17 +0200 Subject: [PATCH 01/48] TODO: bin/smbtorture //172.31.9.187/torture -Uadministrator%A1b2C3d4 smb2.durable-v2-open.delaywrite1 https://bugzilla.samba.org/show_bug.cgi?id=13541 --- source4/torture/smb2/durable_v2_open.c | 669 +++++++++++++++++++++++++ 1 file changed, 669 insertions(+) diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c index 0a928ec8c265..df755bbe286b 100644 --- a/source4/torture/smb2/durable_v2_open.c +++ b/source4/torture/smb2/durable_v2_open.c @@ -2011,6 +2011,674 @@ bool test_persistent_open_lease(struct torture_context *tctx, return ret; } +#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ + uint64_t r = 10*1000*1000; \ + NTTIME g = (given).basic_info.out.write_time; \ + NTTIME gr = (g / r) * r; \ + NTTIME _c = (correct).basic_info.out.write_time; \ + NTTIME cr = (_c / r) * r; \ + bool strict = torture_setting_bool(tctx, "strict mode", false); \ + bool err = false; \ + if (strict && (g cmp _c)) { \ + err = true; \ + } else if ((g cmp _c) && (gr cmp cr)) { \ + /* handle filesystem without high resolution timestamps */ \ + err = true; \ + } \ + if (err) { \ + torture_result(tctx, TORTURE_FAIL, __location__": wrong write_time (%s)%s(%llu) %s (%s)%s(%llu)", \ + #given, nt_time_string(tctx, g), (unsigned long long)g, \ + #cmp, #correct, nt_time_string(tctx, _c), (unsigned long long)_c); \ + ret = false; \ + goto done; \ + } \ +} while (0) +#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,!=) +#define COMPARE_WRITE_TIME_GREATER(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,<=) +#define COMPARE_WRITE_TIME_LESS(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,>=) + +#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ + NTTIME g = (given).basic_info.out.access_time; \ + NTTIME c = (correct).basic_info.out.access_time; \ + if (g cmp c) { \ + torture_result(tctx, TORTURE_FAIL, __location__": wrong access_time (%s)%s %s (%s)%s", \ + #given, nt_time_string(tctx, g), \ + #cmp, #correct, nt_time_string(tctx, c)); \ + ret = false; \ + goto done; \ + } \ +} while (0) +#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ + COMPARE_ACCESS_TIME_CMP(given,correct,!=) + +#define COMPARE_BOTH_TIMES_EQUAL(given,correct) do { \ + COMPARE_ACCESS_TIME_EQUAL(given,correct); \ + COMPARE_WRITE_TIME_EQUAL(given,correct); \ +} while (0) + +#define GET_INFO_FILE(finfo) do { \ + NTSTATUS _status; \ + _status = smb2_getinfo_file(tree, tctx, &finfo); \ + if (!NT_STATUS_IS_OK(_status)) { \ + ret = false; \ + torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ + nt_errstr(_status)); \ + goto done; \ + } \ + torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \ + nt_time_string(tctx, finfo.basic_info.out.access_time), \ + nt_time_string(tctx, finfo.basic_info.out.write_time)); \ +} while (0) + +#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ + NTSTATUS _status; \ + union smb_setfileinfo sfinfo; \ + sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ + sfinfo.basic_info.in.file.fnum = tfnum; \ + sfinfo.basic_info.in.create_time = 0; \ + sfinfo.basic_info.in.access_time = 0; \ + unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ + sfinfo.basic_info.in.change_time = 0; \ + sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ + _status = smb_raw_setfileinfo(tree, &sfinfo); \ + if (!NT_STATUS_IS_OK(_status)) { \ + torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ + nt_errstr(_status)); \ + ret = false; \ + goto done; \ + } \ +} while (0) +#define SET_INFO_FILE(finfo, wrtime) \ + SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) + +#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ + NTSTATUS _status; \ + union smb_setfileinfo sfinfo; \ + sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ + sfinfo.basic_info.in.file.fnum = tfnum; \ + sfinfo.basic_info.in.create_time = 0; \ + sfinfo.basic_info.in.access_time = 0; \ + unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ + sfinfo.basic_info.in.write_time += (ns); \ + sfinfo.basic_info.in.change_time = 0; \ + sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ + _status = smb_raw_setfileinfo(tree, &sfinfo); \ + if (!NT_STATUS_IS_OK(_status)) { \ + torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ + nt_errstr(_status)); \ + ret = false; \ + goto done; \ + } \ +} while (0) + +#if 0 +static bool test_delayed_write_update3(struct torture_context *tctx, + struct smbcli_state *cli, + struct smbcli_state *cli2) +{ + union smb_fileinfo finfo0, finfo1, finfo2, finfo3; + union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; + const char *fname = BASEDIR "\\torture_file3.txt"; + int fnum1 = -1; + bool ret = true; + ssize_t written; + struct timeval start; + struct timeval end; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + int normal_delay = 2000000; + double sec = ((double)used_delay) / ((double)normal_delay); + int msec = 1000 * sec; + + torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); + + torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); + + torture_comment(tctx, "Open the file handle\n"); + fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum1 == -1) { + ret = false; + torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); + goto done; + } + + finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; + finfo0.basic_info.in.file.fnum = fnum1; + finfo1 = finfo0; + finfo2 = finfo0; + finfo3 = finfo0; + pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; + pinfo0.basic_info.in.file.path = fname; + pinfo1 = pinfo0; + pinfo2 = pinfo0; + pinfo3 = pinfo0; + pinfo4 = pinfo0; + + /* get the initial times */ + GET_INFO_BOTH(finfo0,pinfo0); + + /* + * make sure the write time is updated 2 seconds later + * calcuated from the first write + * (but expect upto 5 seconds extra time for a busy server) + */ + start = timeval_current(); + end = timeval_add(&start, 7 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_FILE(finfo1); + + if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + if (diff < (used_delay / (double)1000000)) { + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + "(write time update delay == %.2f) (wrong!)\n", + diff, used_delay / (double)1000000); + ret = false; + break; + } + + torture_comment(tctx, "Server updated write_time after %.2f seconds " + "(correct)\n", + diff); + break; + } + smb_msleep(0.5 * msec); + } + + GET_INFO_BOTH(finfo1,pinfo1); + COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); + + /* sure any further write doesn't update the write time */ + start = timeval_current(); + end = timeval_add(&start, 15 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_BOTH(finfo2,pinfo2); + + if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + "(wrong!)\n", + diff); + ret = false; + break; + } + smb_msleep(1 * msec); + } + + GET_INFO_BOTH(finfo2,pinfo2); + COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); + if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { + torture_comment(tctx, "Server did not update write_time (correct)\n"); + } + + /* sleep */ + smb_msleep(5 * msec); + + GET_INFO_BOTH(finfo3,pinfo3); + COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); + + /* + * the close updates the write time to the time of the close + * and not to the time of the last write! + */ + torture_comment(tctx, "Close the file handle\n"); + smbcli_close(cli->tree, fnum1); + fnum1 = -1; + + GET_INFO_PATH(pinfo4); + COMPARE_WRITE_TIME_GREATER(pinfo4, pinfo3); + + if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { + torture_comment(tctx, "Server updated the write_time on close (correct)\n"); + } + + done: + if (fnum1 != -1) + smbcli_close(cli->tree, fnum1); + smbcli_unlink(cli->tree, fname); + smbcli_deltree(cli->tree, BASEDIR); + + return ret; +} + +/* + * Show that a truncate write always updates the write time even + * if an initial write has already updated the write time. + */ + +static bool test_delayed_write_update3a(struct torture_context *tctx, + struct smbcli_state *cli, + struct smbcli_state *cli2) +{ + union smb_fileinfo finfo0, finfo1, finfo2, finfo3; + union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; + const char *fname = BASEDIR "\\torture_file3a.txt"; + int fnum1 = -1; + bool ret = true; + ssize_t written; + int i; + struct timeval start; + struct timeval end; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + int normal_delay = 2000000; + double sec = ((double)used_delay) / ((double)normal_delay); + int msec = 1000 * sec; + + torture_comment(tctx, "\nRunning test_delayed_write_update3a\n"); + + torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); + + torture_comment(tctx, "Open the file handle\n"); + fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum1 == -1) { + ret = false; + torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); + goto done; + } + + finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; + finfo0.basic_info.in.file.fnum = fnum1; + finfo1 = finfo0; + finfo2 = finfo0; + finfo3 = finfo0; + pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; + pinfo0.basic_info.in.file.path = fname; + pinfo1 = pinfo0; + pinfo2 = pinfo0; + pinfo3 = pinfo0; + pinfo4 = pinfo0; + + /* get the initial times */ + GET_INFO_BOTH(finfo0,pinfo0); + + /* + * sleep some time, to demonstrate the handling of write times + * doesn't depend on the time since the open + */ + smb_msleep(5 * msec); + + /* get the initial times */ + GET_INFO_BOTH(finfo1,pinfo1); + COMPARE_WRITE_TIME_EQUAL(finfo1, finfo0); + + /* + * make sure the write time is updated 2 seconds later + * calcuated from the first write + * (but expect upto 5 seconds extra time for a busy server) + */ + start = timeval_current(); + end = timeval_add(&start, 7 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_FILE(finfo1); + + if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + if (diff < (used_delay / (double)1000000)) { + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + "(1sec == %.2f) (wrong!)\n", + diff, sec); + ret = false; + break; + } + + torture_comment(tctx, "Server updated write_time after %.2f seconds " + "(correct)\n", + diff); + break; + } + smb_msleep(0.5 * msec); + } + + GET_INFO_BOTH(finfo1,pinfo1); + COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); + + smb_msleep(3 * msec); + + /* + * demonstrate that a truncate write always + * updates the write time immediately + */ + for (i=0; i < 3; i++) { + smb_msleep(2 * msec); + /* do a write */ + torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); + written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0); + if (written != 0) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_BOTH(finfo2,pinfo2); + COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); + finfo1 = finfo2; + } + + smb_msleep(3 * msec); + + /* sure any further write doesn't update the write time */ + start = timeval_current(); + end = timeval_add(&start, 15 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_BOTH(finfo2,pinfo2); + + if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + "(wrong!)\n", + diff); + ret = false; + break; + } + smb_msleep(1 * msec); + } + + GET_INFO_BOTH(finfo2,pinfo2); + COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); + if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { + torture_comment(tctx, "Server did not update write_time (correct)\n"); + } + + /* sleep */ + smb_msleep(3 * msec); + + /* get the initial times */ + GET_INFO_BOTH(finfo1,pinfo1); + COMPARE_WRITE_TIME_EQUAL(finfo1, finfo2); + + /* + * demonstrate that a truncate write always + * updates the write time immediately + */ + for (i=0; i < 3; i++) { + smb_msleep(2 * msec); + /* do a write */ + torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); + written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); + if (written != 0) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_BOTH(finfo2,pinfo2); + COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); + finfo1 = finfo2; + } + + /* sleep */ + smb_msleep(3 * msec); + + GET_INFO_BOTH(finfo3,pinfo3); + COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); + + /* + * the close doesn't update the write time + */ + torture_comment(tctx, "Close the file handle\n"); + smbcli_close(cli->tree, fnum1); + fnum1 = -1; + + GET_INFO_PATH(pinfo4); + COMPARE_WRITE_TIME_EQUAL(pinfo4, pinfo3); + + if (pinfo4.basic_info.out.write_time == pinfo3.basic_info.out.write_time) { + torture_comment(tctx, "Server did not update the write_time on close (correct)\n"); + } + + done: + if (fnum1 != -1) + smbcli_close(cli->tree, fnum1); + smbcli_unlink(cli->tree, fname); + smbcli_deltree(cli->tree, BASEDIR); + + return ret; +} +#endif + + +static bool test_durable_v2_delaywrite1(struct torture_context *tctx, + struct smb2_tree *tree) +{ + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(tctx); + char fname[256]; + struct smb2_handle _h; + struct smb2_handle *h = NULL; + struct smb2_create io; + struct GUID create_guid = GUID_random(); + union smb_fileinfo finfo0; + union smb_fileinfo finfo1; + union smb_fileinfo finfo2; + union smb_fileinfo finfo3; + struct smb2_close cl; + struct smb2_write wr; + ssize_t written; + struct timeval start; + struct timeval end; + //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; + //int normal_delay = 2000000; + double sec = ((double)used_delay) / ((double)normal_delay); + int msec = 1000 * sec; + bool ret = true; + + /* Choose a random name in case the state is left a little funky. */ + snprintf(fname, 256, "durable_v2_delaywrite1_%s.dat", + generate_random_str(tctx, 8)); + + smb2_util_unlink(tree, fname); + + smb2_oplock_create_share(&io, fname, + smb2_util_share_access(""), + smb2_util_oplock_level("b")); + io.in.durable_open = false; + io.in.durable_open_v2 = true; + io.in.persistent_open = false; + io.in.create_guid = create_guid; + io.in.timeout = UINT32_MAX; + + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + _h = io.out.file.handle; + h = &_h; + CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b")); + CHECK_VAL(io.out.durable_open, false); + CHECK_VAL(io.out.durable_open_v2, true); + CHECK_VAL(io.out.persistent_open, false); + //CHECK_VAL(io.out.timeout, io.in.timeout); + + ZERO_STRUCT(finfo0); + finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + finfo0.basic_info.in.file.handle = *h; + finfo1 = finfo0; + finfo2 = finfo0; + finfo3 = finfo0; + + /* get the initial times */ + GET_INFO_FILE(finfo0); + + /* + * make sure the write time is updated 2 seconds later + * calcuated from the first write + * (but expect upto 5 seconds extra time for a busy server) + */ + start = timeval_current(); + end = timeval_add(&start, 7 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + ZERO_STRUCT(wr); + wr.in.file.handle = *h; + wr.in.offset = 0; + wr.in.data = data_blob_const("x", 1); + status = smb2_write(tree, &wr); + CHECK_STATUS(status, NT_STATUS_OK); + written = wr.out.nwritten; + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_FILE(finfo1); + + if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + if (diff < (used_delay / (double)1000000)) { + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + "(write time update delay == %.2f) (wrong!)\n", + diff, used_delay / (double)1000000); + ret = false; + break; + } + + torture_comment(tctx, "Server updated write_time after %.2f seconds " + "(correct)\n", + diff); + break; + } + smb_msleep(0.5 * msec); + } + + GET_INFO_FILE(finfo1); + COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); + + /* sure any further write doesn't update the write time */ + start = timeval_current(); + end = timeval_add(&start, 15 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + ZERO_STRUCT(wr); + wr.in.file.handle = *h; + wr.in.offset = 0; + wr.in.data = data_blob_const("x", 1); + status = smb2_write(tree, &wr); + CHECK_STATUS(status, NT_STATUS_OK); + written = wr.out.nwritten; + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_FILE(finfo2); + + if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + "(wrong!)\n", + diff); + ret = false; + break; + } + smb_msleep(1 * msec); + } + + GET_INFO_FILE(finfo2); + COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); + if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { + torture_comment(tctx, "Server did not update write_time (correct)\n"); + } + + /* sleep */ + smb_msleep(5 * msec); + + GET_INFO_FILE(finfo3); + COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); + + /* + * the close updates the write time to the time of the close + * and not to the time of the last write! + */ + torture_comment(tctx, "Close the file handle\n"); + + ZERO_STRUCT(cl); + cl.in.file.handle = *h; + cl.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + status = smb2_close(tree, &cl); + CHECK_STATUS(status, NT_STATUS_OK); + h = NULL; + //struct { + // /* static body buffer 60 (0x3C) bytes */ + // /* uint16_t buffer_code; 0x3C */ + // uint16_t flags; + // uint32_t _pad; + // NTTIME create_time; + // NTTIME access_time; + // NTTIME write_time; + // NTTIME change_time; + // uint64_t alloc_size; + // uint64_t size; + // uint32_t file_attr; + //} out; + + //if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { + // torture_comment(tctx, "Server updated the write_time on close (correct)\n"); + //} + ///* try a durable reconnect while the file is still open */ + //ZERO_STRUCT(io); + //io.in.fname = ""; + //io.in.durable_handle_v2 = h; + //io.in.create_guid = create_guid; + //status = smb2_create(tree, mem_ctx, &io); + //CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); + +done: + if (h != NULL) { + smb2_util_close(tree, *h); + } + + smb2_util_unlink(tree, fname); + + talloc_free(tree); + + talloc_free(mem_ctx); + + return ret; +} + struct torture_suite *torture_smb2_durable_v2_open_init(TALLOC_CTX *ctx) { struct torture_suite *suite = @@ -2030,6 +2698,7 @@ struct torture_suite *torture_smb2_durable_v2_open_init(TALLOC_CTX *ctx) torture_suite_add_2smb2_test(suite, "app-instance", test_durable_v2_open_app_instance); torture_suite_add_1smb2_test(suite, "persistent-open-oplock", test_persistent_open_oplock); torture_suite_add_1smb2_test(suite, "persistent-open-lease", test_persistent_open_lease); + torture_suite_add_1smb2_test(suite, "delaywrite1", test_durable_v2_delaywrite1); suite->description = talloc_strdup(suite, "SMB2-DURABLE-V2-OPEN tests"); -- 2.17.1 From 67a374490b3b537fabb02faf25af06a4dfc56eab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Aug 2018 15:15:43 +0200 Subject: [PATCH 02/48] HACK source4/torture/basic/delaywrite.c --- source4/torture/basic/delaywrite.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 347871688729..dd261d86d096 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -30,6 +30,7 @@ #include "libcli/libcli.h" #include "torture/util.h" #include "torture/basic/proto.h" +#include "lib/util/time_basic.h" #define BASEDIR "\\delaywrite" @@ -1308,6 +1309,10 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s } while (0) #define GET_INFO_FILE(finfo) do { \ + struct timeval atv; \ + struct timeval wtv; \ + struct timeval_buf atvb; \ + struct timeval_buf wtvb; \ NTSTATUS _status; \ _status = smb_raw_fileinfo(cli->tree, tctx, &finfo); \ if (!NT_STATUS_IS_OK(_status)) { \ @@ -1316,9 +1321,11 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s nt_errstr(_status)); \ goto done; \ } \ + nttime_to_timeval(&atv, finfo.basic_info.out.access_time); \ + nttime_to_timeval(&wtv, finfo.basic_info.out.write_time); \ torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \ - nt_time_string(tctx, finfo.basic_info.out.access_time), \ - nt_time_string(tctx, finfo.basic_info.out.write_time)); \ + timeval_str_buf(&atv, false, true, &atvb), \ + timeval_str_buf(&wtv, false, true, &wtvb)); \ } while (0) #define GET_INFO_FILE2(finfo) do { \ NTSTATUS _status; \ @@ -1406,6 +1413,8 @@ static bool test_delayed_write_update3(struct torture_context *tctx, struct timeval start; struct timeval end; double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + //int normal_delay = 1000000; int normal_delay = 2000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -1459,7 +1468,7 @@ static bool test_delayed_write_update3(struct torture_context *tctx, if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { double diff = timeval_elapsed(&start); if (diff < (used_delay / (double)1000000)) { - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + torture_result(tctx, TORTURE_FAIL, "111Server updated write_time after %.2f seconds " "(write time update delay == %.2f) (wrong!)\n", diff, used_delay / (double)1000000); ret = false; -- 2.17.1 From c272320ea8996686dd1d9072ceee2c56c8ee2e29 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Aug 2018 15:16:21 +0200 Subject: [PATCH 03/48] TODO source4/torture/smb2/durable_open.c --- source4/torture/smb2/durable_open.c | 1121 +++++++++++++++++++++++++++ 1 file changed, 1121 insertions(+) diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index 17b3b217b56e..092294ff5341 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -27,6 +27,7 @@ #include "torture/torture.h" #include "torture/smb2/proto.h" #include "../libcli/smb/smbXcli_base.h" +#include "lib/util/time_basic.h" #define CHECK_VAL(v, correct) do { \ if ((v) != (correct)) { \ @@ -2752,6 +2753,1124 @@ done: return ret; } +#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \ + const uint64_t _r = 10*1000*1000; \ + NTTIME _g = (given).basic_info.out.gelem; \ + NTTIME _gr = (_g / _r) * _r; \ + NTTIME _c = (correct).basic_info.out.celem; \ + NTTIME _cr = (_c / _r) * _r; \ + bool _strict = torture_setting_bool(tctx, "strict mode", false); \ + const char *_err = NULL; \ + if (_strict && (_g cmp _c)) { \ + _err = "strict"; \ + } else if ((_g cmp _c) && (_gr cmp _cr)) { \ + /* handle filesystem without high resolution timestamps */ \ + _err = "rounded"; \ + } \ + if (_err != NULL) { \ + struct timeval _gtv; \ + struct timeval _ctv; \ + struct timeval_buf _gtvb; \ + struct timeval_buf _ctvb; \ + nttime_to_timeval(&_gtv, _g); \ + nttime_to_timeval(&_ctv, _c); \ + torture_result(tctx, TORTURE_FAIL, \ + __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \ + _err, \ + #given, #gelem, \ + timeval_str_buf(&_gtv, false, true, &_gtvb), \ + #cmp, \ + #correct, #celem, \ + timeval_str_buf(&_ctv, false, true, &_ctvb)); \ + ret = false; \ + goto done; \ + } \ +} while (0) +#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \ +} while (0) +#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,!=) +#define COMPARE_WRITE_TIME_GREATER(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,<=) +#define COMPARE_WRITE_TIME_LESS(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,>=) + +#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ +} while (0) +#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ + COMPARE_ACCESS_TIME_CMP(given,correct,!=) + +#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ +} while (0) +#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ + COMPARE_CHANGE_TIME_CMP(given,correct,!=) + +#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ +} while (0) +#define COMPARE_CREATE_TIME_EQUAL(given,correct) \ + COMPARE_CREATE_TIME_CMP(given,correct,!=) + +#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ + COMPARE_ACCESS_TIME_EQUAL(given,correct); \ + COMPARE_WRITE_TIME_EQUAL(given,correct); \ + COMPARE_CHANGE_TIME_EQUAL(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ +} while (0) + +#define GET_INFO_FILE(tree, finfo) do { \ + struct timeval _atv; \ + struct timeval _wtv; \ + struct timeval_buf _atvb; \ + struct timeval_buf _wtvb; \ + NTSTATUS _status; \ + _status = smb2_getinfo_file(tree, tctx, &finfo); \ + if (!NT_STATUS_IS_OK(_status)) { \ + ret = false; \ + torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ + nt_errstr(_status)); \ + goto done; \ + } \ + nttime_to_timeval(&_atv, finfo.basic_info.out.access_time); \ + nttime_to_timeval(&_wtv, finfo.basic_info.out.write_time); \ + torture_comment(tctx, "fileinfo(%s,%s): Access(%s) Write(%s)\n", \ + #tree, #finfo, \ + timeval_str_buf(&_atv, false, true, &_atvb), \ + timeval_str_buf(&_wtv, false, true, &_wtvb)); \ +} while (0) + +#define GET_INFO_BOTH(finfo1, finfo2) do { \ + GET_INFO_FILE(tree2, finfo2); \ + GET_INFO_FILE(tree1, finfo1); \ + COMPARE_ALL_TIMES_EQUAL(finfo1, finfo2); \ +} while (0) + +#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ + NTSTATUS _status; \ + union smb_setfileinfo sfinfo; \ + sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ + sfinfo.basic_info.in.file.fnum = tfnum; \ + sfinfo.basic_info.in.create_time = 0; \ + sfinfo.basic_info.in.access_time = 0; \ + unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ + sfinfo.basic_info.in.change_time = 0; \ + sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ + _status = smb_raw_setfileinfo(tree, &sfinfo); \ + if (!NT_STATUS_IS_OK(_status)) { \ + torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ + nt_errstr(_status)); \ + ret = false; \ + goto done; \ + } \ +} while (0) +#define SET_INFO_FILE(finfo, wrtime) \ + SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) + +#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ + NTSTATUS _status; \ + union smb_setfileinfo sfinfo; \ + sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ + sfinfo.basic_info.in.file.fnum = tfnum; \ + sfinfo.basic_info.in.create_time = 0; \ + sfinfo.basic_info.in.access_time = 0; \ + unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ + sfinfo.basic_info.in.write_time += (ns); \ + sfinfo.basic_info.in.change_time = 0; \ + sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ + _status = smb_raw_setfileinfo(tree, &sfinfo); \ + if (!NT_STATUS_IS_OK(_status)) { \ + torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ + nt_errstr(_status)); \ + ret = false; \ + goto done; \ + } \ +} while (0) + +#if 0 +static bool test_delayed_write_update3(struct torture_context *tctx, + struct smbcli_state *cli, + struct smbcli_state *cli2) +{ + union smb_fileinfo finfo0, finfo1, finfo2, finfo3; + union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; + const char *fname = BASEDIR "\\torture_file3.txt"; + int fnum1 = -1; + bool ret = true; + ssize_t written; + struct timeval start; + struct timeval end; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + int normal_delay = 2000000; + double sec = ((double)used_delay) / ((double)normal_delay); + int msec = 1000 * sec; + + torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); + + torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); + + torture_comment(tctx, "Open the file handle\n"); + fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum1 == -1) { + ret = false; + torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); + goto done; + } + + finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; + finfo0.basic_info.in.file.fnum = fnum1; + finfo1 = finfo0; + finfo2 = finfo0; + finfo3 = finfo0; + pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; + pinfo0.basic_info.in.file.path = fname; + pinfo1 = pinfo0; + pinfo2 = pinfo0; + pinfo3 = pinfo0; + pinfo4 = pinfo0; + + /* get the initial times */ + GET_INFO_BOTH(finfo0,pinfo0); + + /* + * make sure the write time is updated 2 seconds later + * calcuated from the first write + * (but expect upto 5 seconds extra time for a busy server) + */ + start = timeval_current(); + end = timeval_add(&start, 7 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_FILE(finfo1); + + if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + if (diff < (used_delay / (double)1000000)) { + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + "(write time update delay == %.2f) (wrong!)\n", + diff, used_delay / (double)1000000); + ret = false; + break; + } + + torture_comment(tctx, "Server updated write_time after %.2f seconds " + "(correct)\n", + diff); + break; + } + smb_msleep(0.5 * msec); + } + + GET_INFO_BOTH(finfo1,pinfo1); + COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); + + /* sure any further write doesn't update the write time */ + start = timeval_current(); + end = timeval_add(&start, 15 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_BOTH(finfo2,pinfo2); + + if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + "(wrong!)\n", + diff); + ret = false; + break; + } + smb_msleep(1 * msec); + } + + GET_INFO_BOTH(finfo2,pinfo2); + COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); + if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { + torture_comment(tctx, "Server did not update write_time (correct)\n"); + } + + /* sleep */ + smb_msleep(5 * msec); + + GET_INFO_BOTH(finfo3,pinfo3); + COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); + + /* + * the close updates the write time to the time of the close + * and not to the time of the last write! + */ + torture_comment(tctx, "Close the file handle\n"); + smbcli_close(cli->tree, fnum1); + fnum1 = -1; + + GET_INFO_PATH(pinfo4); + COMPARE_WRITE_TIME_GREATER(pinfo4, pinfo3); + + if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { + torture_comment(tctx, "Server updated the write_time on close (correct)\n"); + } + + done: + if (fnum1 != -1) + smbcli_close(cli->tree, fnum1); + smbcli_unlink(cli->tree, fname); + smbcli_deltree(cli->tree, BASEDIR); + + return ret; +} + +/* + * Show that a truncate write always updates the write time even + * if an initial write has already updated the write time. + */ + +static bool test_delayed_write_update3a(struct torture_context *tctx, + struct smbcli_state *cli, + struct smbcli_state *cli2) +{ + union smb_fileinfo finfo0, finfo1, finfo2, finfo3; + union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; + const char *fname = BASEDIR "\\torture_file3a.txt"; + int fnum1 = -1; + bool ret = true; + ssize_t written; + int i; + struct timeval start; + struct timeval end; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + int normal_delay = 2000000; + double sec = ((double)used_delay) / ((double)normal_delay); + int msec = 1000 * sec; + + torture_comment(tctx, "\nRunning test_delayed_write_update3a\n"); + + torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); + + torture_comment(tctx, "Open the file handle\n"); + fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum1 == -1) { + ret = false; + torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); + goto done; + } + + finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; + finfo0.basic_info.in.file.fnum = fnum1; + finfo1 = finfo0; + finfo2 = finfo0; + finfo3 = finfo0; + pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; + pinfo0.basic_info.in.file.path = fname; + pinfo1 = pinfo0; + pinfo2 = pinfo0; + pinfo3 = pinfo0; + pinfo4 = pinfo0; + + /* get the initial times */ + GET_INFO_BOTH(finfo0,pinfo0); + + /* + * sleep some time, to demonstrate the handling of write times + * doesn't depend on the time since the open + */ + smb_msleep(5 * msec); + + /* get the initial times */ + GET_INFO_BOTH(finfo1,pinfo1); + COMPARE_WRITE_TIME_EQUAL(finfo1, finfo0); + + /* + * make sure the write time is updated 2 seconds later + * calcuated from the first write + * (but expect upto 5 seconds extra time for a busy server) + */ + start = timeval_current(); + end = timeval_add(&start, 7 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_FILE(finfo1); + + if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + if (diff < (used_delay / (double)1000000)) { + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + "(1sec == %.2f) (wrong!)\n", + diff, sec); + ret = false; + break; + } + + torture_comment(tctx, "Server updated write_time after %.2f seconds " + "(correct)\n", + diff); + break; + } + smb_msleep(0.5 * msec); + } + + GET_INFO_BOTH(finfo1,pinfo1); + COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); + + smb_msleep(3 * msec); + + /* + * demonstrate that a truncate write always + * updates the write time immediately + */ + for (i=0; i < 3; i++) { + smb_msleep(2 * msec); + /* do a write */ + torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); + written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0); + if (written != 0) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_BOTH(finfo2,pinfo2); + COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); + finfo1 = finfo2; + } + + smb_msleep(3 * msec); + + /* sure any further write doesn't update the write time */ + start = timeval_current(); + end = timeval_add(&start, 15 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_BOTH(finfo2,pinfo2); + + if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " + "(wrong!)\n", + diff); + ret = false; + break; + } + smb_msleep(1 * msec); + } + + GET_INFO_BOTH(finfo2,pinfo2); + COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); + if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { + torture_comment(tctx, "Server did not update write_time (correct)\n"); + } + + /* sleep */ + smb_msleep(3 * msec); + + /* get the initial times */ + GET_INFO_BOTH(finfo1,pinfo1); + COMPARE_WRITE_TIME_EQUAL(finfo1, finfo2); + + /* + * demonstrate that a truncate write always + * updates the write time immediately + */ + for (i=0; i < 3; i++) { + smb_msleep(2 * msec); + /* do a write */ + torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); + written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); + if (written != 0) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_BOTH(finfo2,pinfo2); + COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); + finfo1 = finfo2; + } + + /* sleep */ + smb_msleep(3 * msec); + + GET_INFO_BOTH(finfo3,pinfo3); + COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); + + /* + * the close doesn't update the write time + */ + torture_comment(tctx, "Close the file handle\n"); + smbcli_close(cli->tree, fnum1); + fnum1 = -1; + + GET_INFO_PATH(pinfo4); + COMPARE_WRITE_TIME_EQUAL(pinfo4, pinfo3); + + if (pinfo4.basic_info.out.write_time == pinfo3.basic_info.out.write_time) { + torture_comment(tctx, "Server did not update the write_time on close (correct)\n"); + } + + done: + if (fnum1 != -1) + smbcli_close(cli->tree, fnum1); + smbcli_unlink(cli->tree, fname); + smbcli_deltree(cli->tree, BASEDIR); + + return ret; +} +#endif + +static bool test_delay_writetime(struct torture_context *tctx, + double used_delay, + double normal_delay, + const char *description, + bool (*get_basic_info_cb)(void *private_data, + union smb_fileinfo *finfo), + bool (*write_data_cb)(void *private_data), + void *private_data) +{ + union smb_fileinfo finfo0, finfo1, finfoT; + struct timeval before_write; + struct timeval after_write; + struct timeval start; + struct timeval end; + double sec = used_delay / normal_delay; + int msec = 1000 * sec; + bool ret = true; + bool ok; + + torture_comment(tctx, "START: %s\n", description); + + /* get the initial times */ + ok = get_basic_info_cb(private_data, &finfo0); + torture_assert(tctx, ok, "get_basic_info_cb: finfo0"); + + /* + * Make sure the time doesn't change during the next 5 seconds + */ + start = timeval_current(); + end = timeval_add(&start, 5 * sec, 0); + while (!timeval_expired(&end)) { + smb_msleep(1 * msec); + torture_comment(tctx, "Check for no change\n"); + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); + } + + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); + + /* + * make sure the write time is updated 2 seconds later + * calcuated from the first write + * (but expect upto 5 seconds extra time for a busy server) + */ + torture_comment(tctx, "Do a write on the file handle\n"); + before_write = timeval_current(); + ok = write_data_cb(private_data); + after_write = timeval_current(); + torture_assert(tctx, ok, "write_data_cb"); + (void)(&before_write == &after_write); + + start = timeval_current(); + end = timeval_add(&start, 7 * sec, 0); + while (!timeval_expired(&end)) { + struct timeval before_get; + struct timeval after_get; + + torture_comment(tctx, "Wait for change\n"); + before_get = timeval_current(); + ok = get_basic_info_cb(private_data, &finfoT); + after_get = timeval_current(); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + (void)(&before_get == &after_get); + + if (finfoT.basic_info.out.write_time > finfo0.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + diff = timeval_elapsed2(&before_write, &after_get); + if (diff < (used_delay / (double)1000000)) { + torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " + "(write time update delay == %.2f) (wrong!)\n", + diff, used_delay / (double)1000000); + ret = false; + break; + } + + torture_comment(tctx, "Server updated write_time after %.2f seconds " + "(correct)\n", + diff); + break; + } + + COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); + smb_msleep(0.5 * msec); + } + + ok = get_basic_info_cb(private_data, &finfo1); + torture_assert(tctx, ok, "get_basic_info_cb: finfo1"); + COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); + + /* + * Make sure the time doesn't change during the next 5 seconds + */ + start = timeval_current(); + end = timeval_add(&start, 5 * sec, 0); + while (!timeval_expired(&end)) { + smb_msleep(1 * msec); + torture_comment(tctx, "Check for no change\n"); + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_WRITE_TIME_EQUAL(finfoT, finfo1); + } + + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_WRITE_TIME_EQUAL(finfoT, finfo1); +#if 0 + start = timeval_current(); + end = timeval_add(&start, 7 * sec, 0); + while (!timeval_expired(&end)) { + union smb_fileinfo finfoT0; + union smb_fileinfo finfoT1; + + ok = get_basic_info_cb(private_data, &finfoT0); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT0"); + + torture_comment(tctx, "Do a write on the file handle\n"); + ok = write_data_cb(private_data); + torture_assert_ntstatus_ok(tctx, status); + + ok = get_basic_info_cb(private_data, &finfoT1); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT1"); + COMPARE_WRITE_TIME_EQUAL(finfoT1, finfoT0); + + if (finfo.basic_info.out.write_time > finfo0.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + if (diff < (used_delay / (double)1000000)) { + torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " + "(write time update delay == %.2f) (wrong!)\n", + diff, used_delay / (double)1000000); + ret = false; + break; + } + + torture_comment(tctx, "Server updated write_time after %.2f seconds " + "(correct)\n", + diff); + changed = true; + break; + } + ok = get_basic_info_cb(private_data, &finfo1); + torture_assert_ntstatus_ok(tctx, status); + + COMPARE_WRITE_TIME_EQUAL(finfo1, finfoT); + smb_msleep(0.5 * msec); + } + changed = false; + GET_INFO_BOTH(finfo1, c2finfo1); + COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); +#endif +done: + return ret; +} + +struct test_durable_open_delaywrite1_state { + struct torture_context *tctx; + struct smb2_tree *tree1; + struct smb2_tree *tree2; + struct smb2_handle *h1; + struct smb2_handle *h2; +}; + +static bool test_durable_open_delaywrite1_get_info(void *private_data, + union smb_fileinfo *finfo) +{ + struct test_durable_open_delaywrite1_state *state = + (struct test_durable_open_delaywrite1_state *)private_data; + struct torture_context *tctx = state->tctx; + union smb_fileinfo t1finfo; + union smb_fileinfo t2finfo; + bool ret = true; + + ZERO_STRUCTP(finfo); + + ZERO_STRUCT(t1finfo); + t1finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + t1finfo.basic_info.in.file.handle = *state->h1; + + ZERO_STRUCT(t2finfo); + t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + t2finfo.basic_info.in.file.handle = *state->h2; + + GET_INFO_FILE(state->tree2, t2finfo); + GET_INFO_FILE(state->tree1, t1finfo); + COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); + + finfo->basic_info.out = t1finfo.basic_info.out; +done: + return ret; +} + +static bool test_durable_open_delaywrite1_write_data(void *private_data) +{ + struct test_durable_open_delaywrite1_state *state = + (struct test_durable_open_delaywrite1_state *)private_data; + struct torture_context *tctx = state->tctx; + struct smb2_write wr; + NTSTATUS status; + bool ret = true; + + ZERO_STRUCT(wr); + wr.in.file.handle = *state->h1; + wr.in.offset = 0; + wr.in.data = data_blob_const("x", 1); + status = smb2_write(state->tree1, &wr); + CHECK_STATUS(status, NT_STATUS_OK); + torture_assert_int_equal_goto(tctx, wr.out.nwritten, 1, + ret, done, "smb2_write"); + +done: + return ret; +} + +static bool test_durable_open_delaywrite1(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) +{ + struct test_durable_open_delaywrite1_state state = { + .tctx = tctx, + .tree1 = tree1, + .tree2 = tree2, + }; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(tctx); + char fname[256]; + struct smb2_handle _h; + struct smb2_handle *h = NULL; + struct smb2_handle _h2; + struct smb2_handle *h2 = NULL; + struct smb2_create cr; + struct smb2_create cr2; + union smb_fileinfo finfoCR, finfo0, finfo1, finfo2, finfo3, finfo4, finfoT, finfoCL; + union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfo4, c2finfoT, c2finfoCL; + struct smb2_close cl; + struct smb2_close cl2; + struct smb2_write wr; + ssize_t written; + struct timeval start; + struct timeval end; + //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + double normal_delay = 1000000; + //int normal_delay = 2000000; + double sec = ((double)used_delay) / ((double)normal_delay); + int msec = 1000 * sec; + bool ret = true; + bool changed = false; + bool ok; + + /* Choose a random name in case the state is left a little funky. */ + snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", + generate_random_str(tctx, 8)); + + smb2_util_unlink(tree1, fname); + + smb2_oplock_create_share(&cr, fname, + smb2_util_share_access(""), + smb2_util_oplock_level("b")); + cr.in.durable_open = true; + + status = smb2_create(tree1, mem_ctx, &cr); + CHECK_STATUS(status, NT_STATUS_OK); + _h = cr.out.file.handle; + h = &_h; + CHECK_CREATED(&cr, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(cr.out.oplock_level, smb2_util_oplock_level("b")); + CHECK_VAL(cr.out.durable_open, true); + CHECK_VAL(cr.out.durable_open_v2, false); + CHECK_VAL(cr.out.persistent_open, false); + //CHECK_VAL(io.out.timeout, io.in.timeout); + + // struct { + // NTTIME create_time; + // NTTIME access_time; + // NTTIME write_time; + // NTTIME change_time; + // uint32_t attrib; + // } out; + //} basic_info; + ZERO_STRUCT(finfoCR); + finfoCR.basic_info.out.create_time = cr.out.create_time; + finfoCR.basic_info.out.access_time = cr.out.access_time; + finfoCR.basic_info.out.write_time = cr.out.write_time; + finfoCR.basic_info.out.change_time = cr.out.change_time; + finfoCR.basic_info.out.attrib = cr.out.file_attr; + + ZERO_STRUCT(finfo0); + finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + finfo0.basic_info.in.file.handle = *h; + finfo1 = finfo0; + finfo2 = finfo0; + finfo3 = finfo0; + finfo4 = finfo0; + finfoT = finfo0; + + /* get the initial times */ + GET_INFO_FILE(tree1, finfo0); + COMPARE_WRITE_TIME_EQUAL(finfoCR, finfo0); + + ///* static body buffer 56 (0x38) bytes */ + //uint8_t security_flags; /* SMB2_SECURITY_* */ + //uint8_t oplock_level; /* SMB2_OPLOCK_LEVEL_* */ + //uint32_t impersonation_level; /* SMB2_IMPERSONATION_* */ + //uint64_t create_flags; + //uint64_t reserved; + //uint32_t desired_access; + //uint32_t file_attributes; + //uint32_t share_access; /* NTCREATEX_SHARE_ACCESS_* */ + //uint32_t create_disposition; /* NTCREATEX_DISP_* */ + //uint32_t create_options; /* NTCREATEX_OPTIONS_* */ + + ///* uint16_t fname_ofs */ + ///* uint16_t fname_size */ + ///* uint32_t blob_ofs; */ + ///* uint32_t blob_size; */ + + ///* dynamic body */ + //const char *fname; + + ///* now some optional parameters - encoded as tagged blobs */ + //struct smb_ea_list eas; + //uint64_t alloc_size; + //struct security_descriptor *sec_desc; + //bool durable_open; + //struct smb2_handle *durable_handle; + + ///* data for durable handle v2 */ + //bool durable_open_v2; + //struct GUID create_guid; + //bool persistent_open; + //uint32_t timeout; + //struct smb2_handle *durable_handle_v2; + + //bool query_maximal_access; + //NTTIME timewarp; + //bool query_on_disk_id; + //struct smb2_lease *lease_request; + //struct smb2_lease *lease_request_v2; + + //struct GUID *app_instance_id; + + ///* and any additional blobs the caller wants */ + //struct smb2_create_blobs blobs; + //} in; + //struct {// + //union smb_handle file; + + ///* static body buffer 88 (0x58) bytes */ + ///* uint16_t buffer_code; 0x59 = 0x58 + 1 */ + //uint8_t oplock_level; + //uint8_t reserved; + //uint32_t create_action; + //NTTIME create_time; + //NTTIME access_time; + //NTTIME write_time; + //NTTIME change_time; + //uint64_t alloc_size; + //uint64_t size; + //uint32_t file_attr; + //uint32_t reserved2; + ///* struct smb2_handle handle;*/ + ///* uint32_t blob_ofs; */ + ///* uint32_t blob_size; */ + + ///* optional return values matching tagged values in the call */ + //uint32_t maximal_access; + //uint8_t on_disk_id[32]; + //struct smb2_lease lease_response; + //struct smb2_lease lease_response_v2; + //bool durable_open; + + ///* durable handle v2 */ + //bool durable_open_v2; + //bool persistent_open; + //uint32_t timeout; + + ///* tagged blobs in the reply */ + //struct smb2_create_blobs blobs; + //} out; + cr2 = cr; + cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE;//FILE_READ_ATTRIBUTES; + cr2.in.durable_open = false; + cr2.in.oplock_level = 0; + cr2.in.create_disposition = NTCREATEX_DISP_OPEN; + status = smb2_create(tree2, mem_ctx, &cr2); + CHECK_STATUS(status, NT_STATUS_OK); + _h2 = cr2.out.file.handle; + h2 = &_h2; + CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(cr2.out.oplock_level, 0); + CHECK_VAL(cr2.out.durable_open, false); + CHECK_VAL(cr2.out.durable_open_v2, false); + CHECK_VAL(cr2.out.persistent_open, false); + + ZERO_STRUCT(c2finfoCR); + c2finfoCR.basic_info.out.create_time = cr2.out.create_time; + c2finfoCR.basic_info.out.access_time = cr2.out.access_time; + c2finfoCR.basic_info.out.write_time = cr2.out.write_time; + c2finfoCR.basic_info.out.change_time = cr2.out.change_time; + c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; + + ZERO_STRUCT(c2finfo0); + c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + c2finfo0.basic_info.in.file.handle = *h2; + c2finfo1 = c2finfo0; + c2finfo2 = c2finfo0; + c2finfo3 = c2finfo0; + c2finfo4 = c2finfo0; + c2finfoT = c2finfo0; + + /* get the initial times */ + GET_INFO_FILE(tree2, c2finfo0); + COMPARE_WRITE_TIME_EQUAL(c2finfoCR, c2finfo0); + + state.h1 = h; + state.h2 = h2; + + ok = test_delay_writetime(tctx, used_delay, normal_delay, + "some description", + test_durable_open_delaywrite1_get_info, + test_durable_open_delaywrite1_write_data, + &state); + torture_assert(tctx, ok, "test_delay_writetime"); +goto done; + /* + * make sure the write time is updated 2 seconds later + * calcuated from the first write + * (but expect upto 5 seconds extra time for a busy server) + */ + start = timeval_current(); + end = timeval_add(&start, 7 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + GET_INFO_BOTH(finfoT, c2finfoT); + ZERO_STRUCT(wr); + wr.in.file.handle = *h; + wr.in.offset = 0; + wr.in.data = data_blob_const("x", 1); + status = smb2_write(tree1, &wr); + CHECK_STATUS(status, NT_STATUS_OK); + written = wr.out.nwritten; + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_BOTH(finfo1, c2finfo1); + if (changed) { + COMPARE_WRITE_TIME_GREATER(finfo1, finfoT); + } + + if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + if (diff < (used_delay / (double)1000000)) { + torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " + "(write time update delay == %.2f) (wrong!)\n", + diff, used_delay / (double)1000000); + ret = false; + break; + } + + torture_comment(tctx, "Server updated write_time after %.2f seconds " + "(correct)\n", + diff); + changed = true; + break; + } + COMPARE_WRITE_TIME_EQUAL(finfo1, finfoT); + smb_msleep(0.5 * msec); + } + + changed = false; + GET_INFO_BOTH(finfo1, c2finfo1); + COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); + + /* sure any further write doesn't update the write time */ + start = timeval_current(); + end = timeval_add(&start, 15 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Do a write on the file handle\n"); + ZERO_STRUCT(wr); + wr.in.file.handle = *h; + wr.in.offset = 0; + wr.in.data = data_blob_const("x", 1); + status = smb2_write(tree1, &wr); + CHECK_STATUS(status, NT_STATUS_OK); + written = wr.out.nwritten; + if (written != 1) { + torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); + ret = false; + goto done; + } + /* get the times after the write */ + GET_INFO_BOTH(finfo2, c2finfo2); + + if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " + "(wrong!)\n", + diff); + ret = false; + //break; + } + smb_msleep(0.1 * msec); + //smb_msleep(1 * msec); + } + + GET_INFO_BOTH(finfo2, c2finfo2); + //COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); + COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); + if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { + torture_comment(tctx, "Server did not update write_time (correct)\n"); + } + + /* sure any further write doesn't update the write time */ + start = timeval_current(); + end = timeval_add(&start, 15 * sec, 0); + while (!timeval_expired(&end)) { + /* do a write */ + torture_comment(tctx, "Check on both file handles\n"); + GET_INFO_BOTH(finfo3, c2finfo3); + + if (finfo3.basic_info.out.write_time > finfo2.basic_info.out.write_time) { + double diff = timeval_elapsed(&start); + torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " + "(wrong!)\n", + diff); + ret = false; + break; + } + smb_msleep(0.1 * msec); + //smb_msleep(1 * msec); + } + GET_INFO_BOTH(finfo3, c2finfo3); + //COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); + + /* sleep */ + torture_comment(tctx, "Sleep ...\n"); + smb_msleep(5 * msec); + torture_comment(tctx, "... continue\n"); + + GET_INFO_BOTH(finfo4, c2finfo4); + COMPARE_WRITE_TIME_EQUAL(finfo4, finfo3); + + /* + * the close updates the write time to the time of the close + * and not to the time of the last write! + */ + torture_comment(tctx, "Close the file handle\n"); + + ZERO_STRUCT(cl); + cl.in.file.handle = *h; + cl.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + status = smb2_close(tree1, &cl); + CHECK_STATUS(status, NT_STATUS_OK); + h = NULL; + ZERO_STRUCT(finfoCL); + finfoCL.basic_info.out.create_time = cl.out.create_time; + finfoCL.basic_info.out.access_time = cl.out.access_time; + finfoCL.basic_info.out.write_time = cl.out.write_time; + finfoCL.basic_info.out.change_time = cl.out.change_time; + finfoCL.basic_info.out.attrib = cl.out.file_attr; + COMPARE_WRITE_TIME_GREATER(finfoCL, finfo3); + + ZERO_STRUCT(cl2); + cl2.in.file.handle = *h2; + cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + status = smb2_close(tree2, &cl2); + CHECK_STATUS(status, NT_STATUS_OK); + h2 = NULL; + ZERO_STRUCT(c2finfoCL); + c2finfoCL.basic_info.out.create_time = cl2.out.create_time; + c2finfoCL.basic_info.out.access_time = cl2.out.access_time; + c2finfoCL.basic_info.out.write_time = cl2.out.write_time; + c2finfoCL.basic_info.out.change_time = cl2.out.change_time; + c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; + COMPARE_WRITE_TIME_EQUAL(c2finfoCL, finfoCL); + //struct { + // /* static body buffer 60 (0x3C) bytes */ + // /* uint16_t buffer_code; 0x3C */ + // uint16_t flags; + // uint32_t _pad; + // NTTIME create_time; + // NTTIME access_time; + // NTTIME write_time; + // NTTIME change_time; + // uint64_t alloc_size; + // uint64_t size; + // uint32_t file_attr; + //} out; + + //if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { + // torture_comment(tctx, "Server updated the write_time on close (correct)\n"); + //} + ///* try a durable reconnect while the file is still open */ + //ZERO_STRUCT(io); + //io.in.fname = ""; + //io.in.durable_handle_v2 = h; + //io.in.create_guid = create_guid; + //status = smb2_create(tree1, mem_ctx, &io); + //CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); + +done: + if (h != NULL) { + smb2_util_close(tree1, *h); + } + + smb2_util_unlink(tree1, fname); + + talloc_free(tree1); + talloc_free(tree2); + + talloc_free(mem_ctx); + + return ret; +} + struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx) { @@ -2787,6 +3906,8 @@ struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx) test_durable_open_alloc_size); torture_suite_add_1smb2_test(suite, "read-only", test_durable_open_read_only); + torture_suite_add_2smb2_test(suite, "delaywrite1", + test_durable_open_delaywrite1); suite->description = talloc_strdup(suite, "SMB2-DURABLE-OPEN tests"); -- 2.17.1 From 18b68abbce9acd359d5ae08f51b9997d5b0209ae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Aug 2018 15:16:21 +0200 Subject: [PATCH 04/48] TODO source4/torture/smb2/durable_open.c --- source4/torture/smb2/durable_open.c | 420 +++------------------------- 1 file changed, 36 insertions(+), 384 deletions(-) diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index 092294ff5341..58bbe3bf648f 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -2821,6 +2821,13 @@ done: COMPARE_CREATE_TIME_EQUAL(given,correct); \ } while (0) +#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ + COMPARE_ACCESS_TIME_GREATER(given,correct); \ + COMPARE_WRITE_TIME_GREATER(given,correct); \ + COMPARE_CHANGE_TIME_GREATER(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ +} while (0) + #define GET_INFO_FILE(tree, finfo) do { \ struct timeval _atv; \ struct timeval _wtv; \ @@ -2889,366 +2896,6 @@ done: } \ } while (0) -#if 0 -static bool test_delayed_write_update3(struct torture_context *tctx, - struct smbcli_state *cli, - struct smbcli_state *cli2) -{ - union smb_fileinfo finfo0, finfo1, finfo2, finfo3; - union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; - const char *fname = BASEDIR "\\torture_file3.txt"; - int fnum1 = -1; - bool ret = true; - ssize_t written; - struct timeval start; - struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; - double sec = ((double)used_delay) / ((double)normal_delay); - int msec = 1000 * sec; - - torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); - - torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); - - torture_comment(tctx, "Open the file handle\n"); - fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); - if (fnum1 == -1) { - ret = false; - torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); - goto done; - } - - finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; - finfo0.basic_info.in.file.fnum = fnum1; - finfo1 = finfo0; - finfo2 = finfo0; - finfo3 = finfo0; - pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; - pinfo0.basic_info.in.file.path = fname; - pinfo1 = pinfo0; - pinfo2 = pinfo0; - pinfo3 = pinfo0; - pinfo4 = pinfo0; - - /* get the initial times */ - GET_INFO_BOTH(finfo0,pinfo0); - - /* - * make sure the write time is updated 2 seconds later - * calcuated from the first write - * (but expect upto 5 seconds extra time for a busy server) - */ - start = timeval_current(); - end = timeval_add(&start, 7 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_FILE(finfo1); - - if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - if (diff < (used_delay / (double)1000000)) { - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " - "(write time update delay == %.2f) (wrong!)\n", - diff, used_delay / (double)1000000); - ret = false; - break; - } - - torture_comment(tctx, "Server updated write_time after %.2f seconds " - "(correct)\n", - diff); - break; - } - smb_msleep(0.5 * msec); - } - - GET_INFO_BOTH(finfo1,pinfo1); - COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); - - /* sure any further write doesn't update the write time */ - start = timeval_current(); - end = timeval_add(&start, 15 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_BOTH(finfo2,pinfo2); - - if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " - "(wrong!)\n", - diff); - ret = false; - break; - } - smb_msleep(1 * msec); - } - - GET_INFO_BOTH(finfo2,pinfo2); - COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); - if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { - torture_comment(tctx, "Server did not update write_time (correct)\n"); - } - - /* sleep */ - smb_msleep(5 * msec); - - GET_INFO_BOTH(finfo3,pinfo3); - COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); - - /* - * the close updates the write time to the time of the close - * and not to the time of the last write! - */ - torture_comment(tctx, "Close the file handle\n"); - smbcli_close(cli->tree, fnum1); - fnum1 = -1; - - GET_INFO_PATH(pinfo4); - COMPARE_WRITE_TIME_GREATER(pinfo4, pinfo3); - - if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { - torture_comment(tctx, "Server updated the write_time on close (correct)\n"); - } - - done: - if (fnum1 != -1) - smbcli_close(cli->tree, fnum1); - smbcli_unlink(cli->tree, fname); - smbcli_deltree(cli->tree, BASEDIR); - - return ret; -} - -/* - * Show that a truncate write always updates the write time even - * if an initial write has already updated the write time. - */ - -static bool test_delayed_write_update3a(struct torture_context *tctx, - struct smbcli_state *cli, - struct smbcli_state *cli2) -{ - union smb_fileinfo finfo0, finfo1, finfo2, finfo3; - union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; - const char *fname = BASEDIR "\\torture_file3a.txt"; - int fnum1 = -1; - bool ret = true; - ssize_t written; - int i; - struct timeval start; - struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; - double sec = ((double)used_delay) / ((double)normal_delay); - int msec = 1000 * sec; - - torture_comment(tctx, "\nRunning test_delayed_write_update3a\n"); - - torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); - - torture_comment(tctx, "Open the file handle\n"); - fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); - if (fnum1 == -1) { - ret = false; - torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); - goto done; - } - - finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; - finfo0.basic_info.in.file.fnum = fnum1; - finfo1 = finfo0; - finfo2 = finfo0; - finfo3 = finfo0; - pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; - pinfo0.basic_info.in.file.path = fname; - pinfo1 = pinfo0; - pinfo2 = pinfo0; - pinfo3 = pinfo0; - pinfo4 = pinfo0; - - /* get the initial times */ - GET_INFO_BOTH(finfo0,pinfo0); - - /* - * sleep some time, to demonstrate the handling of write times - * doesn't depend on the time since the open - */ - smb_msleep(5 * msec); - - /* get the initial times */ - GET_INFO_BOTH(finfo1,pinfo1); - COMPARE_WRITE_TIME_EQUAL(finfo1, finfo0); - - /* - * make sure the write time is updated 2 seconds later - * calcuated from the first write - * (but expect upto 5 seconds extra time for a busy server) - */ - start = timeval_current(); - end = timeval_add(&start, 7 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_FILE(finfo1); - - if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - if (diff < (used_delay / (double)1000000)) { - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " - "(1sec == %.2f) (wrong!)\n", - diff, sec); - ret = false; - break; - } - - torture_comment(tctx, "Server updated write_time after %.2f seconds " - "(correct)\n", - diff); - break; - } - smb_msleep(0.5 * msec); - } - - GET_INFO_BOTH(finfo1,pinfo1); - COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); - - smb_msleep(3 * msec); - - /* - * demonstrate that a truncate write always - * updates the write time immediately - */ - for (i=0; i < 3; i++) { - smb_msleep(2 * msec); - /* do a write */ - torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); - written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0); - if (written != 0) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_BOTH(finfo2,pinfo2); - COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); - finfo1 = finfo2; - } - - smb_msleep(3 * msec); - - /* sure any further write doesn't update the write time */ - start = timeval_current(); - end = timeval_add(&start, 15 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_BOTH(finfo2,pinfo2); - - if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " - "(wrong!)\n", - diff); - ret = false; - break; - } - smb_msleep(1 * msec); - } - - GET_INFO_BOTH(finfo2,pinfo2); - COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); - if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { - torture_comment(tctx, "Server did not update write_time (correct)\n"); - } - - /* sleep */ - smb_msleep(3 * msec); - - /* get the initial times */ - GET_INFO_BOTH(finfo1,pinfo1); - COMPARE_WRITE_TIME_EQUAL(finfo1, finfo2); - - /* - * demonstrate that a truncate write always - * updates the write time immediately - */ - for (i=0; i < 3; i++) { - smb_msleep(2 * msec); - /* do a write */ - torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); - written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); - if (written != 0) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_BOTH(finfo2,pinfo2); - COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); - finfo1 = finfo2; - } - - /* sleep */ - smb_msleep(3 * msec); - - GET_INFO_BOTH(finfo3,pinfo3); - COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); - - /* - * the close doesn't update the write time - */ - torture_comment(tctx, "Close the file handle\n"); - smbcli_close(cli->tree, fnum1); - fnum1 = -1; - - GET_INFO_PATH(pinfo4); - COMPARE_WRITE_TIME_EQUAL(pinfo4, pinfo3); - - if (pinfo4.basic_info.out.write_time == pinfo3.basic_info.out.write_time) { - torture_comment(tctx, "Server did not update the write_time on close (correct)\n"); - } - - done: - if (fnum1 != -1) - smbcli_close(cli->tree, fnum1); - smbcli_unlink(cli->tree, fname); - smbcli_deltree(cli->tree, BASEDIR); - - return ret; -} -#endif - static bool test_delay_writetime(struct torture_context *tctx, double used_delay, double normal_delay, @@ -3264,7 +2911,11 @@ static bool test_delay_writetime(struct torture_context *tctx, struct timeval start; struct timeval end; double sec = used_delay / normal_delay; - int msec = 1000 * sec; + double msec = 1000 * sec; + double nsec = 1000 * msec; + double expected_delay = used_delay / nsec; + double min_delay = expected_delay * 0.1; + double max_delay = 5 * expected_delay; bool ret = true; bool ok; @@ -3278,13 +2929,13 @@ static bool test_delay_writetime(struct torture_context *tctx, * Make sure the time doesn't change during the next 5 seconds */ start = timeval_current(); - end = timeval_add(&start, 5 * sec, 0); + end = timeval_add(&start, max_delay * 1.25, 0); while (!timeval_expired(&end)) { smb_msleep(1 * msec); torture_comment(tctx, "Check for no change\n"); ok = get_basic_info_cb(private_data, &finfoT); torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); } ok = get_basic_info_cb(private_data, &finfoT); @@ -3304,7 +2955,7 @@ static bool test_delay_writetime(struct torture_context *tctx, (void)(&before_write == &after_write); start = timeval_current(); - end = timeval_add(&start, 7 * sec, 0); + end = timeval_add(&start, max_delay * 2, 0); while (!timeval_expired(&end)) { struct timeval before_get; struct timeval after_get; @@ -3317,24 +2968,23 @@ static bool test_delay_writetime(struct torture_context *tctx, (void)(&before_get == &after_get); if (finfoT.basic_info.out.write_time > finfo0.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - diff = timeval_elapsed2(&before_write, &after_get); - if (diff < (used_delay / (double)1000000)) { - torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " - "(write time update delay == %.2f) (wrong!)\n", - diff, used_delay / (double)1000000); - ret = false; - break; - } - - torture_comment(tctx, "Server updated write_time after %.2f seconds " - "(correct)\n", - diff); + double delayS = timeval_elapsed2(&after_write, &before_get); + double delayL = timeval_elapsed2(&before_write, &after_get); + + torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " + "(min delay == %.2f, max delay == %.2f)\n", + delayS, delayL, min_delay, max_delay); + torture_assert(tctx, (delayL >= min_delay), + "Server updated write_time to early!"); + torture_assert(tctx, (delayS <= max_delay), + "Server didn't update write_time!"); + + COMPARE_WRITE_TIME_GREATER(finfoT, finfo0); break; } - COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); - smb_msleep(0.5 * msec); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); + smb_msleep(0.01 * msec); } ok = get_basic_info_cb(private_data, &finfo1); @@ -3345,18 +2995,18 @@ static bool test_delay_writetime(struct torture_context *tctx, * Make sure the time doesn't change during the next 5 seconds */ start = timeval_current(); - end = timeval_add(&start, 5 * sec, 0); + end = timeval_add(&start, max_delay * 1.25, 0); while (!timeval_expired(&end)) { smb_msleep(1 * msec); - torture_comment(tctx, "Check for no change\n"); + torture_comment(tctx, "Check for no additional change\n"); ok = get_basic_info_cb(private_data, &finfoT); torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - COMPARE_WRITE_TIME_EQUAL(finfoT, finfo1); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); } ok = get_basic_info_cb(private_data, &finfoT); torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - COMPARE_WRITE_TIME_EQUAL(finfoT, finfo1); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); #if 0 start = timeval_current(); end = timeval_add(&start, 7 * sec, 0); @@ -3491,8 +3141,10 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, struct timeval start; struct timeval end; //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); double normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); + //double normal_delay = 1000000; //int normal_delay = 2000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; -- 2.17.1 From 1474b4c796ae6a7ae2f00e0142abe40b9670c2a7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Aug 2018 15:16:21 +0200 Subject: [PATCH 05/48] TODO source4/torture/smb2/durable_open.c --- source4/torture/smb2/durable_open.c | 41 +++++++++++++++++++---------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index 58bbe3bf648f..61412558b35c 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -2793,20 +2793,22 @@ done: COMPARE_WRITE_TIME_CMP(given,correct,!=) #define COMPARE_WRITE_TIME_GREATER(given,correct) \ COMPARE_WRITE_TIME_CMP(given,correct,<=) -#define COMPARE_WRITE_TIME_LESS(given,correct) \ - COMPARE_WRITE_TIME_CMP(given,correct,>=) #define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ } while (0) #define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ COMPARE_ACCESS_TIME_CMP(given,correct,!=) +#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ + COMPARE_ACCESS_TIME_CMP(given,correct,<=) #define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ } while (0) #define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ COMPARE_CHANGE_TIME_CMP(given,correct,!=) +#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ + COMPARE_CHANGE_TIME_CMP(given,correct,<=) #define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ @@ -2815,17 +2817,27 @@ done: COMPARE_CREATE_TIME_CMP(given,correct,!=) #define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ - COMPARE_ACCESS_TIME_EQUAL(given,correct); \ COMPARE_WRITE_TIME_EQUAL(given,correct); \ COMPARE_CHANGE_TIME_EQUAL(given,correct); \ + COMPARE_ACCESS_TIME_EQUAL(given,correct); \ COMPARE_CREATE_TIME_EQUAL(given,correct); \ } while (0) #define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ - COMPARE_ACCESS_TIME_GREATER(given,correct); \ COMPARE_WRITE_TIME_GREATER(given,correct); \ COMPARE_CHANGE_TIME_GREATER(given,correct); \ + COMPARE_ACCESS_TIME_EQUAL(given,correct); \ COMPARE_CREATE_TIME_EQUAL(given,correct); \ + COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ +} while (0) + +#define COMPARE_TIMES_AFTER_CLOSE(given,correct) do { \ + COMPARE_WRITE_TIME_GREATER(given,correct); \ + COMPARE_CHANGE_TIME_GREATER(given,correct); \ + COMPARE_ACCESS_TIME_GREATER(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ + COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ + COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ } while (0) #define GET_INFO_FILE(tree, finfo) do { \ @@ -2914,7 +2926,7 @@ static bool test_delay_writetime(struct torture_context *tctx, double msec = 1000 * sec; double nsec = 1000 * msec; double expected_delay = used_delay / nsec; - double min_delay = expected_delay * 0.1; + double min_delay = expected_delay * 0.01; double max_delay = 5 * expected_delay; bool ret = true; bool ok; @@ -2942,11 +2954,6 @@ static bool test_delay_writetime(struct torture_context *tctx, torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); - /* - * make sure the write time is updated 2 seconds later - * calcuated from the first write - * (but expect upto 5 seconds extra time for a busy server) - */ torture_comment(tctx, "Do a write on the file handle\n"); before_write = timeval_current(); ok = write_data_cb(private_data); @@ -2979,7 +2986,7 @@ static bool test_delay_writetime(struct torture_context *tctx, torture_assert(tctx, (delayS <= max_delay), "Server didn't update write_time!"); - COMPARE_WRITE_TIME_GREATER(finfoT, finfo0); + COMPARE_TIMES_AFTER_WRITE(finfoT, finfo0); break; } @@ -2989,7 +2996,7 @@ static bool test_delay_writetime(struct torture_context *tctx, ok = get_basic_info_cb(private_data, &finfo1); torture_assert(tctx, ok, "get_basic_info_cb: finfo1"); - COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); + COMPARE_TIMES_AFTER_WRITE(finfo1, finfo0); /* * Make sure the time doesn't change during the next 5 seconds @@ -3326,6 +3333,7 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, test_durable_open_delaywrite1_write_data, &state); torture_assert(tctx, ok, "test_delay_writetime"); +goto close_handles; goto done; /* * make sure the write time is updated 2 seconds later @@ -3439,6 +3447,7 @@ goto done; smb_msleep(0.1 * msec); //smb_msleep(1 * msec); } +close_handles: GET_INFO_BOTH(finfo3, c2finfo3); //COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); @@ -3468,7 +3477,11 @@ goto done; finfoCL.basic_info.out.write_time = cl.out.write_time; finfoCL.basic_info.out.change_time = cl.out.change_time; finfoCL.basic_info.out.attrib = cl.out.file_attr; - COMPARE_WRITE_TIME_GREATER(finfoCL, finfo3); + //COMPARE_WRITE_TIME_GREATER(finfoCL, finfo3); + //COMPARE_TIMES_AFTER_CLOSE(finfoCL, finfo3); + + GET_INFO_FILE(tree2, c2finfo3); + COMPARE_ALL_TIMES_EQUAL(c2finfo3, finfoCL); ZERO_STRUCT(cl2); cl2.in.file.handle = *h2; @@ -3482,7 +3495,7 @@ goto done; c2finfoCL.basic_info.out.write_time = cl2.out.write_time; c2finfoCL.basic_info.out.change_time = cl2.out.change_time; c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; - COMPARE_WRITE_TIME_EQUAL(c2finfoCL, finfoCL); + COMPARE_ALL_TIMES_EQUAL(c2finfoCL, finfoCL); //struct { // /* static body buffer 60 (0x3C) bytes */ // /* uint16_t buffer_code; 0x3C */ -- 2.17.1 From e1f7c875d0ac0b7e0fd2cd5c13e597df173b8fcd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Aug 2018 15:16:21 +0200 Subject: [PATCH 06/48] TODO source4/torture/smb2/durable_open.c --- source4/torture/smb2/durable_open.c | 482 +++++++++------------------- 1 file changed, 144 insertions(+), 338 deletions(-) diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index 61412558b35c..0704fe4af8fd 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -2917,9 +2917,11 @@ static bool test_delay_writetime(struct torture_context *tctx, bool (*write_data_cb)(void *private_data), void *private_data) { - union smb_fileinfo finfo0, finfo1, finfoT; + union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfoT; struct timeval before_write; struct timeval after_write; + struct timeval before_last_write; + struct timeval after_last_write; struct timeval start; struct timeval end; double sec = used_delay / normal_delay; @@ -2959,7 +2961,6 @@ static bool test_delay_writetime(struct torture_context *tctx, ok = write_data_cb(private_data); after_write = timeval_current(); torture_assert(tctx, ok, "write_data_cb"); - (void)(&before_write == &after_write); start = timeval_current(); end = timeval_add(&start, max_delay * 2, 0); @@ -2972,7 +2973,6 @@ static bool test_delay_writetime(struct torture_context *tctx, ok = get_basic_info_cb(private_data, &finfoT); after_get = timeval_current(); torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - (void)(&before_get == &after_get); if (finfoT.basic_info.out.write_time > finfo0.basic_info.out.write_time) { double delayS = timeval_elapsed2(&after_write, &before_get); @@ -3014,50 +3014,81 @@ static bool test_delay_writetime(struct torture_context *tctx, ok = get_basic_info_cb(private_data, &finfoT); torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); -#if 0 + + torture_comment(tctx, "Do a write on the file handle\n"); + before_write = timeval_current(); + ok = write_data_cb(private_data); + after_write = timeval_current(); + torture_assert(tctx, ok, "write_data_cb"); + + ZERO_STRUCT(finfo2); + before_last_write = before_write; + after_last_write = after_write; start = timeval_current(); - end = timeval_add(&start, 7 * sec, 0); + end = timeval_add(&start, max_delay * 2, 0); while (!timeval_expired(&end)) { - union smb_fileinfo finfoT0; - union smb_fileinfo finfoT1; + struct timeval before_get; + struct timeval after_get; - ok = get_basic_info_cb(private_data, &finfoT0); - torture_assert(tctx, ok, "get_basic_info_cb: finfoT0"); + smb_msleep(0.01 * msec); - torture_comment(tctx, "Do a write on the file handle\n"); - ok = write_data_cb(private_data); - torture_assert_ntstatus_ok(tctx, status); - - ok = get_basic_info_cb(private_data, &finfoT1); - torture_assert(tctx, ok, "get_basic_info_cb: finfoT1"); - COMPARE_WRITE_TIME_EQUAL(finfoT1, finfoT0); - - if (finfo.basic_info.out.write_time > finfo0.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - if (diff < (used_delay / (double)1000000)) { - torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " - "(write time update delay == %.2f) (wrong!)\n", - diff, used_delay / (double)1000000); - ret = false; - break; - } - - torture_comment(tctx, "Server updated write_time after %.2f seconds " - "(correct)\n", - diff); - changed = true; + torture_comment(tctx, "Wait for change\n"); + before_get = timeval_current(); + ok = get_basic_info_cb(private_data, &finfoT); + after_get = timeval_current(); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + + if (finfoT.basic_info.out.write_time > finfo1.basic_info.out.write_time) { + double delayS = timeval_elapsed2(&after_write, &before_get); + double delayL = timeval_elapsed2(&before_write, &after_get); + + torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " + "(min delay == %.2f, max delay == %.2f)\n", + delayS, delayL, min_delay, max_delay); + torture_assert(tctx, (delayL >= min_delay), + "Server updated write_time to early!"); + torture_assert(tctx, (delayS <= max_delay), + "Server didn't update write_time!"); + + COMPARE_TIMES_AFTER_WRITE(finfoT, finfo1); + before_write = before_last_write; + after_write = after_last_write; + finfo2 = finfoT; break; } - ok = get_basic_info_cb(private_data, &finfo1); - torture_assert_ntstatus_ok(tctx, status); - COMPARE_WRITE_TIME_EQUAL(finfo1, finfoT); - smb_msleep(0.5 * msec); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); + + torture_comment(tctx, "Write while waiting\n"); + before_last_write = timeval_current(); + ok = write_data_cb(private_data); + after_last_write = timeval_current(); + torture_assert(tctx, ok, "write_data_cb"); + } + + // We may get one additional change... + + ok = get_basic_info_cb(private_data, &finfo3); + torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); + COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); + + /* + * Make sure the time doesn't change during the next 5 seconds + */ + start = timeval_current(); + end = timeval_add(&start, max_delay * 1.25, 0); + while (!timeval_expired(&end)) { + smb_msleep(1 * msec); + torture_comment(tctx, "Check for no additional change\n"); + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); } - changed = false; - GET_INFO_BOTH(finfo1, c2finfo1); - COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); -#endif + + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); + done: return ret; } @@ -3092,6 +3123,13 @@ static bool test_durable_open_delaywrite1_get_info(void *private_data, GET_INFO_FILE(state->tree2, t2finfo); GET_INFO_FILE(state->tree1, t1finfo); + if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { + /* + * There was a race, get it again on handle 2, + * but then they have to match. + */ + GET_INFO_FILE(state->tree2, t2finfo); + } COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); finfo->basic_info.out = t1finfo.basic_info.out; @@ -3133,20 +3171,16 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); char fname[256]; - struct smb2_handle _h; - struct smb2_handle *h = NULL; + struct smb2_handle _h1; + struct smb2_handle *h1 = NULL; struct smb2_handle _h2; struct smb2_handle *h2 = NULL; - struct smb2_create cr; + struct smb2_create cr1; struct smb2_create cr2; - union smb_fileinfo finfoCR, finfo0, finfo1, finfo2, finfo3, finfo4, finfoT, finfoCL; - union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfo4, c2finfoT, c2finfoCL; - struct smb2_close cl; + union smb_fileinfo c1finfoCR, c1finfo0, c1finfo1, c1finfo2, c1finfoCL; + union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfoCL; + struct smb2_close cl1; struct smb2_close cl2; - struct smb2_write wr; - ssize_t written; - struct timeval start; - struct timeval end; //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); double normal_delay = 1000000; @@ -3156,7 +3190,6 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; bool ret = true; - bool changed = false; bool ok; /* Choose a random name in case the state is left a little funky. */ @@ -3165,132 +3198,23 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, smb2_util_unlink(tree1, fname); - smb2_oplock_create_share(&cr, fname, + smb2_oplock_create_share(&cr1, fname, smb2_util_share_access(""), smb2_util_oplock_level("b")); - cr.in.durable_open = true; + cr1.in.durable_open = true; - status = smb2_create(tree1, mem_ctx, &cr); + status = smb2_create(tree1, mem_ctx, &cr1); CHECK_STATUS(status, NT_STATUS_OK); - _h = cr.out.file.handle; - h = &_h; - CHECK_CREATED(&cr, CREATED, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(cr.out.oplock_level, smb2_util_oplock_level("b")); - CHECK_VAL(cr.out.durable_open, true); - CHECK_VAL(cr.out.durable_open_v2, false); - CHECK_VAL(cr.out.persistent_open, false); - //CHECK_VAL(io.out.timeout, io.in.timeout); - - // struct { - // NTTIME create_time; - // NTTIME access_time; - // NTTIME write_time; - // NTTIME change_time; - // uint32_t attrib; - // } out; - //} basic_info; - ZERO_STRUCT(finfoCR); - finfoCR.basic_info.out.create_time = cr.out.create_time; - finfoCR.basic_info.out.access_time = cr.out.access_time; - finfoCR.basic_info.out.write_time = cr.out.write_time; - finfoCR.basic_info.out.change_time = cr.out.change_time; - finfoCR.basic_info.out.attrib = cr.out.file_attr; - - ZERO_STRUCT(finfo0); - finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - finfo0.basic_info.in.file.handle = *h; - finfo1 = finfo0; - finfo2 = finfo0; - finfo3 = finfo0; - finfo4 = finfo0; - finfoT = finfo0; + _h1 = cr1.out.file.handle; + h1 = &_h1; + CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); + CHECK_VAL(cr1.out.durable_open, true); + CHECK_VAL(cr1.out.durable_open_v2, false); + CHECK_VAL(cr1.out.persistent_open, false); - /* get the initial times */ - GET_INFO_FILE(tree1, finfo0); - COMPARE_WRITE_TIME_EQUAL(finfoCR, finfo0); - - ///* static body buffer 56 (0x38) bytes */ - //uint8_t security_flags; /* SMB2_SECURITY_* */ - //uint8_t oplock_level; /* SMB2_OPLOCK_LEVEL_* */ - //uint32_t impersonation_level; /* SMB2_IMPERSONATION_* */ - //uint64_t create_flags; - //uint64_t reserved; - //uint32_t desired_access; - //uint32_t file_attributes; - //uint32_t share_access; /* NTCREATEX_SHARE_ACCESS_* */ - //uint32_t create_disposition; /* NTCREATEX_DISP_* */ - //uint32_t create_options; /* NTCREATEX_OPTIONS_* */ - - ///* uint16_t fname_ofs */ - ///* uint16_t fname_size */ - ///* uint32_t blob_ofs; */ - ///* uint32_t blob_size; */ - - ///* dynamic body */ - //const char *fname; - - ///* now some optional parameters - encoded as tagged blobs */ - //struct smb_ea_list eas; - //uint64_t alloc_size; - //struct security_descriptor *sec_desc; - //bool durable_open; - //struct smb2_handle *durable_handle; - - ///* data for durable handle v2 */ - //bool durable_open_v2; - //struct GUID create_guid; - //bool persistent_open; - //uint32_t timeout; - //struct smb2_handle *durable_handle_v2; - - //bool query_maximal_access; - //NTTIME timewarp; - //bool query_on_disk_id; - //struct smb2_lease *lease_request; - //struct smb2_lease *lease_request_v2; - - //struct GUID *app_instance_id; - - ///* and any additional blobs the caller wants */ - //struct smb2_create_blobs blobs; - //} in; - //struct {// - //union smb_handle file; - - ///* static body buffer 88 (0x58) bytes */ - ///* uint16_t buffer_code; 0x59 = 0x58 + 1 */ - //uint8_t oplock_level; - //uint8_t reserved; - //uint32_t create_action; - //NTTIME create_time; - //NTTIME access_time; - //NTTIME write_time; - //NTTIME change_time; - //uint64_t alloc_size; - //uint64_t size; - //uint32_t file_attr; - //uint32_t reserved2; - ///* struct smb2_handle handle;*/ - ///* uint32_t blob_ofs; */ - ///* uint32_t blob_size; */ - - ///* optional return values matching tagged values in the call */ - //uint32_t maximal_access; - //uint8_t on_disk_id[32]; - //struct smb2_lease lease_response; - //struct smb2_lease lease_response_v2; - //bool durable_open; - - ///* durable handle v2 */ - //bool durable_open_v2; - //bool persistent_open; - //uint32_t timeout; - - ///* tagged blobs in the reply */ - //struct smb2_create_blobs blobs; - //} out; - cr2 = cr; - cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE;//FILE_READ_ATTRIBUTES; + cr2 = cr1; + cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE; cr2.in.durable_open = false; cr2.in.oplock_level = 0; cr2.in.create_disposition = NTCREATEX_DISP_OPEN; @@ -3304,6 +3228,13 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, CHECK_VAL(cr2.out.durable_open_v2, false); CHECK_VAL(cr2.out.persistent_open, false); + ZERO_STRUCT(c1finfoCR); + c1finfoCR.basic_info.out.create_time = cr1.out.create_time; + c1finfoCR.basic_info.out.access_time = cr1.out.access_time; + c1finfoCR.basic_info.out.write_time = cr1.out.write_time; + c1finfoCR.basic_info.out.change_time = cr1.out.change_time; + c1finfoCR.basic_info.out.attrib = cr1.out.file_attr; + ZERO_STRUCT(c2finfoCR); c2finfoCR.basic_info.out.create_time = cr2.out.create_time; c2finfoCR.basic_info.out.access_time = cr2.out.access_time; @@ -3311,153 +3242,50 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, c2finfoCR.basic_info.out.change_time = cr2.out.change_time; c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; + COMPARE_ALL_TIMES_EQUAL(c1finfoCR, c2finfoCR); + + ZERO_STRUCT(c1finfo0); + c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + c1finfo0.basic_info.in.file.handle = *h1; + c1finfo1 = c1finfo0; + c1finfo2 = c1finfo0; + ZERO_STRUCT(c2finfo0); c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; c2finfo0.basic_info.in.file.handle = *h2; c2finfo1 = c2finfo0; c2finfo2 = c2finfo0; c2finfo3 = c2finfo0; - c2finfo4 = c2finfo0; - c2finfoT = c2finfo0; - /* get the initial times */ - GET_INFO_FILE(tree2, c2finfo0); - COMPARE_WRITE_TIME_EQUAL(c2finfoCR, c2finfo0); + GET_INFO_BOTH(c1finfo0, c2finfo0); + COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); - state.h1 = h; + state.h1 = h1; state.h2 = h2; ok = test_delay_writetime(tctx, used_delay, normal_delay, - "some description", + "run1", test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, &state); - torture_assert(tctx, ok, "test_delay_writetime"); -goto close_handles; -goto done; - /* - * make sure the write time is updated 2 seconds later - * calcuated from the first write - * (but expect upto 5 seconds extra time for a busy server) - */ - start = timeval_current(); - end = timeval_add(&start, 7 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - GET_INFO_BOTH(finfoT, c2finfoT); - ZERO_STRUCT(wr); - wr.in.file.handle = *h; - wr.in.offset = 0; - wr.in.data = data_blob_const("x", 1); - status = smb2_write(tree1, &wr); - CHECK_STATUS(status, NT_STATUS_OK); - written = wr.out.nwritten; - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_BOTH(finfo1, c2finfo1); - if (changed) { - COMPARE_WRITE_TIME_GREATER(finfo1, finfoT); - } - - if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - if (diff < (used_delay / (double)1000000)) { - torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " - "(write time update delay == %.2f) (wrong!)\n", - diff, used_delay / (double)1000000); - ret = false; - break; - } - - torture_comment(tctx, "Server updated write_time after %.2f seconds " - "(correct)\n", - diff); - changed = true; - break; - } - COMPARE_WRITE_TIME_EQUAL(finfo1, finfoT); - smb_msleep(0.5 * msec); - } - - changed = false; - GET_INFO_BOTH(finfo1, c2finfo1); - COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); - - /* sure any further write doesn't update the write time */ - start = timeval_current(); - end = timeval_add(&start, 15 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - ZERO_STRUCT(wr); - wr.in.file.handle = *h; - wr.in.offset = 0; - wr.in.data = data_blob_const("x", 1); - status = smb2_write(tree1, &wr); - CHECK_STATUS(status, NT_STATUS_OK); - written = wr.out.nwritten; - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_BOTH(finfo2, c2finfo2); - - if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " - "(wrong!)\n", - diff); - ret = false; - //break; - } - smb_msleep(0.1 * msec); - //smb_msleep(1 * msec); - } - - GET_INFO_BOTH(finfo2, c2finfo2); - //COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); - COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); - if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { - torture_comment(tctx, "Server did not update write_time (correct)\n"); - } + torture_assert(tctx, ok, "test_delay_writetime(1)"); + ok = test_delay_writetime(tctx, used_delay, normal_delay, + "run2", + test_durable_open_delaywrite1_get_info, + test_durable_open_delaywrite1_write_data, + &state); + torture_assert(tctx, ok, "test_delay_writetime(2)"); - /* sure any further write doesn't update the write time */ - start = timeval_current(); - end = timeval_add(&start, 15 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Check on both file handles\n"); - GET_INFO_BOTH(finfo3, c2finfo3); - - if (finfo3.basic_info.out.write_time > finfo2.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " - "(wrong!)\n", - diff); - ret = false; - break; - } - smb_msleep(0.1 * msec); - //smb_msleep(1 * msec); - } -close_handles: - GET_INFO_BOTH(finfo3, c2finfo3); - //COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); + GET_INFO_BOTH(c1finfo1, c2finfo1); + COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); /* sleep */ torture_comment(tctx, "Sleep ...\n"); smb_msleep(5 * msec); torture_comment(tctx, "... continue\n"); - GET_INFO_BOTH(finfo4, c2finfo4); - COMPARE_WRITE_TIME_EQUAL(finfo4, finfo3); + GET_INFO_BOTH(c1finfo2, c2finfo2); + COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); /* * the close updates the write time to the time of the close @@ -3465,23 +3293,22 @@ close_handles: */ torture_comment(tctx, "Close the file handle\n"); - ZERO_STRUCT(cl); - cl.in.file.handle = *h; - cl.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; - status = smb2_close(tree1, &cl); + ZERO_STRUCT(cl1); + cl1.in.file.handle = *h1; + cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + status = smb2_close(tree1, &cl1); CHECK_STATUS(status, NT_STATUS_OK); - h = NULL; - ZERO_STRUCT(finfoCL); - finfoCL.basic_info.out.create_time = cl.out.create_time; - finfoCL.basic_info.out.access_time = cl.out.access_time; - finfoCL.basic_info.out.write_time = cl.out.write_time; - finfoCL.basic_info.out.change_time = cl.out.change_time; - finfoCL.basic_info.out.attrib = cl.out.file_attr; - //COMPARE_WRITE_TIME_GREATER(finfoCL, finfo3); - //COMPARE_TIMES_AFTER_CLOSE(finfoCL, finfo3); + h1 = NULL; + ZERO_STRUCT(c1finfoCL); + c1finfoCL.basic_info.out.create_time = cl1.out.create_time; + c1finfoCL.basic_info.out.access_time = cl1.out.access_time; + c1finfoCL.basic_info.out.write_time = cl1.out.write_time; + c1finfoCL.basic_info.out.change_time = cl1.out.change_time; + c1finfoCL.basic_info.out.attrib = cl1.out.file_attr; + COMPARE_ALL_TIMES_EQUAL(c1finfoCL, c1finfo2); GET_INFO_FILE(tree2, c2finfo3); - COMPARE_ALL_TIMES_EQUAL(c2finfo3, finfoCL); + COMPARE_ALL_TIMES_EQUAL(c2finfo3, c1finfoCL); ZERO_STRUCT(cl2); cl2.in.file.handle = *h2; @@ -3495,35 +3322,14 @@ close_handles: c2finfoCL.basic_info.out.write_time = cl2.out.write_time; c2finfoCL.basic_info.out.change_time = cl2.out.change_time; c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; - COMPARE_ALL_TIMES_EQUAL(c2finfoCL, finfoCL); - //struct { - // /* static body buffer 60 (0x3C) bytes */ - // /* uint16_t buffer_code; 0x3C */ - // uint16_t flags; - // uint32_t _pad; - // NTTIME create_time; - // NTTIME access_time; - // NTTIME write_time; - // NTTIME change_time; - // uint64_t alloc_size; - // uint64_t size; - // uint32_t file_attr; - //} out; - - //if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { - // torture_comment(tctx, "Server updated the write_time on close (correct)\n"); - //} - ///* try a durable reconnect while the file is still open */ - //ZERO_STRUCT(io); - //io.in.fname = ""; - //io.in.durable_handle_v2 = h; - //io.in.create_guid = create_guid; - //status = smb2_create(tree1, mem_ctx, &io); - //CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); + COMPARE_ALL_TIMES_EQUAL(c2finfoCL, c1finfoCL); done: - if (h != NULL) { - smb2_util_close(tree1, *h); + if (h1 != NULL) { + smb2_util_close(tree1, *h1); + } + if (h2 != NULL) { + smb2_util_close(tree2, *h2); } smb2_util_unlink(tree1, fname); -- 2.17.1 From 1c30035fc20bd918a20f77757e4c2fb7c26367e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Aug 2018 21:45:50 +0200 Subject: [PATCH 07/48] smbd: SMB2 write time mode...??? --- source3/smbd/fileio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 1fe806e058d2..c75b8a4dcef2 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -178,6 +178,10 @@ void fsp_flush_write_time_update(struct files_struct *fsp) /* Remove the timed event handler. */ TALLOC_FREE(fsp->update_write_time_event); + if (fsp->conn->sconn->client->connections->protocol >= PROTOCOL_SMB2_02) { + fsp->update_write_time_triggered = false; + fsp->update_write_time_on_close = false; + } } static void update_write_time_handler(struct tevent_context *ctx, @@ -287,6 +291,7 @@ void mark_file_modified(files_struct *fsp) int dosmode; if (fsp->modified) { + trigger_write_time_update(fsp); return; } -- 2.17.1 From 37efff59337c94cb362185bcf222494148f1b58c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Aug 2018 21:51:08 +0200 Subject: [PATCH 08/48] revert source4/torture/smb2/durable_v2_open.c --- source4/torture/smb2/durable_v2_open.c | 669 ------------------------- 1 file changed, 669 deletions(-) diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c index df755bbe286b..0a928ec8c265 100644 --- a/source4/torture/smb2/durable_v2_open.c +++ b/source4/torture/smb2/durable_v2_open.c @@ -2011,674 +2011,6 @@ bool test_persistent_open_lease(struct torture_context *tctx, return ret; } -#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ - uint64_t r = 10*1000*1000; \ - NTTIME g = (given).basic_info.out.write_time; \ - NTTIME gr = (g / r) * r; \ - NTTIME _c = (correct).basic_info.out.write_time; \ - NTTIME cr = (_c / r) * r; \ - bool strict = torture_setting_bool(tctx, "strict mode", false); \ - bool err = false; \ - if (strict && (g cmp _c)) { \ - err = true; \ - } else if ((g cmp _c) && (gr cmp cr)) { \ - /* handle filesystem without high resolution timestamps */ \ - err = true; \ - } \ - if (err) { \ - torture_result(tctx, TORTURE_FAIL, __location__": wrong write_time (%s)%s(%llu) %s (%s)%s(%llu)", \ - #given, nt_time_string(tctx, g), (unsigned long long)g, \ - #cmp, #correct, nt_time_string(tctx, _c), (unsigned long long)_c); \ - ret = false; \ - goto done; \ - } \ -} while (0) -#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ - COMPARE_WRITE_TIME_CMP(given,correct,!=) -#define COMPARE_WRITE_TIME_GREATER(given,correct) \ - COMPARE_WRITE_TIME_CMP(given,correct,<=) -#define COMPARE_WRITE_TIME_LESS(given,correct) \ - COMPARE_WRITE_TIME_CMP(given,correct,>=) - -#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ - NTTIME g = (given).basic_info.out.access_time; \ - NTTIME c = (correct).basic_info.out.access_time; \ - if (g cmp c) { \ - torture_result(tctx, TORTURE_FAIL, __location__": wrong access_time (%s)%s %s (%s)%s", \ - #given, nt_time_string(tctx, g), \ - #cmp, #correct, nt_time_string(tctx, c)); \ - ret = false; \ - goto done; \ - } \ -} while (0) -#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ - COMPARE_ACCESS_TIME_CMP(given,correct,!=) - -#define COMPARE_BOTH_TIMES_EQUAL(given,correct) do { \ - COMPARE_ACCESS_TIME_EQUAL(given,correct); \ - COMPARE_WRITE_TIME_EQUAL(given,correct); \ -} while (0) - -#define GET_INFO_FILE(finfo) do { \ - NTSTATUS _status; \ - _status = smb2_getinfo_file(tree, tctx, &finfo); \ - if (!NT_STATUS_IS_OK(_status)) { \ - ret = false; \ - torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ - nt_errstr(_status)); \ - goto done; \ - } \ - torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \ - nt_time_string(tctx, finfo.basic_info.out.access_time), \ - nt_time_string(tctx, finfo.basic_info.out.write_time)); \ -} while (0) - -#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ - NTSTATUS _status; \ - union smb_setfileinfo sfinfo; \ - sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ - sfinfo.basic_info.in.file.fnum = tfnum; \ - sfinfo.basic_info.in.create_time = 0; \ - sfinfo.basic_info.in.access_time = 0; \ - unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ - sfinfo.basic_info.in.change_time = 0; \ - sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ - _status = smb_raw_setfileinfo(tree, &sfinfo); \ - if (!NT_STATUS_IS_OK(_status)) { \ - torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ - nt_errstr(_status)); \ - ret = false; \ - goto done; \ - } \ -} while (0) -#define SET_INFO_FILE(finfo, wrtime) \ - SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) - -#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ - NTSTATUS _status; \ - union smb_setfileinfo sfinfo; \ - sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ - sfinfo.basic_info.in.file.fnum = tfnum; \ - sfinfo.basic_info.in.create_time = 0; \ - sfinfo.basic_info.in.access_time = 0; \ - unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ - sfinfo.basic_info.in.write_time += (ns); \ - sfinfo.basic_info.in.change_time = 0; \ - sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ - _status = smb_raw_setfileinfo(tree, &sfinfo); \ - if (!NT_STATUS_IS_OK(_status)) { \ - torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ - nt_errstr(_status)); \ - ret = false; \ - goto done; \ - } \ -} while (0) - -#if 0 -static bool test_delayed_write_update3(struct torture_context *tctx, - struct smbcli_state *cli, - struct smbcli_state *cli2) -{ - union smb_fileinfo finfo0, finfo1, finfo2, finfo3; - union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; - const char *fname = BASEDIR "\\torture_file3.txt"; - int fnum1 = -1; - bool ret = true; - ssize_t written; - struct timeval start; - struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; - double sec = ((double)used_delay) / ((double)normal_delay); - int msec = 1000 * sec; - - torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); - - torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); - - torture_comment(tctx, "Open the file handle\n"); - fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); - if (fnum1 == -1) { - ret = false; - torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); - goto done; - } - - finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; - finfo0.basic_info.in.file.fnum = fnum1; - finfo1 = finfo0; - finfo2 = finfo0; - finfo3 = finfo0; - pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; - pinfo0.basic_info.in.file.path = fname; - pinfo1 = pinfo0; - pinfo2 = pinfo0; - pinfo3 = pinfo0; - pinfo4 = pinfo0; - - /* get the initial times */ - GET_INFO_BOTH(finfo0,pinfo0); - - /* - * make sure the write time is updated 2 seconds later - * calcuated from the first write - * (but expect upto 5 seconds extra time for a busy server) - */ - start = timeval_current(); - end = timeval_add(&start, 7 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_FILE(finfo1); - - if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - if (diff < (used_delay / (double)1000000)) { - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " - "(write time update delay == %.2f) (wrong!)\n", - diff, used_delay / (double)1000000); - ret = false; - break; - } - - torture_comment(tctx, "Server updated write_time after %.2f seconds " - "(correct)\n", - diff); - break; - } - smb_msleep(0.5 * msec); - } - - GET_INFO_BOTH(finfo1,pinfo1); - COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); - - /* sure any further write doesn't update the write time */ - start = timeval_current(); - end = timeval_add(&start, 15 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_BOTH(finfo2,pinfo2); - - if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " - "(wrong!)\n", - diff); - ret = false; - break; - } - smb_msleep(1 * msec); - } - - GET_INFO_BOTH(finfo2,pinfo2); - COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); - if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { - torture_comment(tctx, "Server did not update write_time (correct)\n"); - } - - /* sleep */ - smb_msleep(5 * msec); - - GET_INFO_BOTH(finfo3,pinfo3); - COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); - - /* - * the close updates the write time to the time of the close - * and not to the time of the last write! - */ - torture_comment(tctx, "Close the file handle\n"); - smbcli_close(cli->tree, fnum1); - fnum1 = -1; - - GET_INFO_PATH(pinfo4); - COMPARE_WRITE_TIME_GREATER(pinfo4, pinfo3); - - if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { - torture_comment(tctx, "Server updated the write_time on close (correct)\n"); - } - - done: - if (fnum1 != -1) - smbcli_close(cli->tree, fnum1); - smbcli_unlink(cli->tree, fname); - smbcli_deltree(cli->tree, BASEDIR); - - return ret; -} - -/* - * Show that a truncate write always updates the write time even - * if an initial write has already updated the write time. - */ - -static bool test_delayed_write_update3a(struct torture_context *tctx, - struct smbcli_state *cli, - struct smbcli_state *cli2) -{ - union smb_fileinfo finfo0, finfo1, finfo2, finfo3; - union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; - const char *fname = BASEDIR "\\torture_file3a.txt"; - int fnum1 = -1; - bool ret = true; - ssize_t written; - int i; - struct timeval start; - struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; - double sec = ((double)used_delay) / ((double)normal_delay); - int msec = 1000 * sec; - - torture_comment(tctx, "\nRunning test_delayed_write_update3a\n"); - - torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); - - torture_comment(tctx, "Open the file handle\n"); - fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); - if (fnum1 == -1) { - ret = false; - torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); - goto done; - } - - finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; - finfo0.basic_info.in.file.fnum = fnum1; - finfo1 = finfo0; - finfo2 = finfo0; - finfo3 = finfo0; - pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; - pinfo0.basic_info.in.file.path = fname; - pinfo1 = pinfo0; - pinfo2 = pinfo0; - pinfo3 = pinfo0; - pinfo4 = pinfo0; - - /* get the initial times */ - GET_INFO_BOTH(finfo0,pinfo0); - - /* - * sleep some time, to demonstrate the handling of write times - * doesn't depend on the time since the open - */ - smb_msleep(5 * msec); - - /* get the initial times */ - GET_INFO_BOTH(finfo1,pinfo1); - COMPARE_WRITE_TIME_EQUAL(finfo1, finfo0); - - /* - * make sure the write time is updated 2 seconds later - * calcuated from the first write - * (but expect upto 5 seconds extra time for a busy server) - */ - start = timeval_current(); - end = timeval_add(&start, 7 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_FILE(finfo1); - - if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - if (diff < (used_delay / (double)1000000)) { - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " - "(1sec == %.2f) (wrong!)\n", - diff, sec); - ret = false; - break; - } - - torture_comment(tctx, "Server updated write_time after %.2f seconds " - "(correct)\n", - diff); - break; - } - smb_msleep(0.5 * msec); - } - - GET_INFO_BOTH(finfo1,pinfo1); - COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); - - smb_msleep(3 * msec); - - /* - * demonstrate that a truncate write always - * updates the write time immediately - */ - for (i=0; i < 3; i++) { - smb_msleep(2 * msec); - /* do a write */ - torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); - written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0); - if (written != 0) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_BOTH(finfo2,pinfo2); - COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); - finfo1 = finfo2; - } - - smb_msleep(3 * msec); - - /* sure any further write doesn't update the write time */ - start = timeval_current(); - end = timeval_add(&start, 15 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_BOTH(finfo2,pinfo2); - - if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " - "(wrong!)\n", - diff); - ret = false; - break; - } - smb_msleep(1 * msec); - } - - GET_INFO_BOTH(finfo2,pinfo2); - COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); - if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { - torture_comment(tctx, "Server did not update write_time (correct)\n"); - } - - /* sleep */ - smb_msleep(3 * msec); - - /* get the initial times */ - GET_INFO_BOTH(finfo1,pinfo1); - COMPARE_WRITE_TIME_EQUAL(finfo1, finfo2); - - /* - * demonstrate that a truncate write always - * updates the write time immediately - */ - for (i=0; i < 3; i++) { - smb_msleep(2 * msec); - /* do a write */ - torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); - written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); - if (written != 0) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_BOTH(finfo2,pinfo2); - COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); - finfo1 = finfo2; - } - - /* sleep */ - smb_msleep(3 * msec); - - GET_INFO_BOTH(finfo3,pinfo3); - COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); - - /* - * the close doesn't update the write time - */ - torture_comment(tctx, "Close the file handle\n"); - smbcli_close(cli->tree, fnum1); - fnum1 = -1; - - GET_INFO_PATH(pinfo4); - COMPARE_WRITE_TIME_EQUAL(pinfo4, pinfo3); - - if (pinfo4.basic_info.out.write_time == pinfo3.basic_info.out.write_time) { - torture_comment(tctx, "Server did not update the write_time on close (correct)\n"); - } - - done: - if (fnum1 != -1) - smbcli_close(cli->tree, fnum1); - smbcli_unlink(cli->tree, fname); - smbcli_deltree(cli->tree, BASEDIR); - - return ret; -} -#endif - - -static bool test_durable_v2_delaywrite1(struct torture_context *tctx, - struct smb2_tree *tree) -{ - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(tctx); - char fname[256]; - struct smb2_handle _h; - struct smb2_handle *h = NULL; - struct smb2_create io; - struct GUID create_guid = GUID_random(); - union smb_fileinfo finfo0; - union smb_fileinfo finfo1; - union smb_fileinfo finfo2; - union smb_fileinfo finfo3; - struct smb2_close cl; - struct smb2_write wr; - ssize_t written; - struct timeval start; - struct timeval end; - //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; - //int normal_delay = 2000000; - double sec = ((double)used_delay) / ((double)normal_delay); - int msec = 1000 * sec; - bool ret = true; - - /* Choose a random name in case the state is left a little funky. */ - snprintf(fname, 256, "durable_v2_delaywrite1_%s.dat", - generate_random_str(tctx, 8)); - - smb2_util_unlink(tree, fname); - - smb2_oplock_create_share(&io, fname, - smb2_util_share_access(""), - smb2_util_oplock_level("b")); - io.in.durable_open = false; - io.in.durable_open_v2 = true; - io.in.persistent_open = false; - io.in.create_guid = create_guid; - io.in.timeout = UINT32_MAX; - - status = smb2_create(tree, mem_ctx, &io); - CHECK_STATUS(status, NT_STATUS_OK); - _h = io.out.file.handle; - h = &_h; - CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b")); - CHECK_VAL(io.out.durable_open, false); - CHECK_VAL(io.out.durable_open_v2, true); - CHECK_VAL(io.out.persistent_open, false); - //CHECK_VAL(io.out.timeout, io.in.timeout); - - ZERO_STRUCT(finfo0); - finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - finfo0.basic_info.in.file.handle = *h; - finfo1 = finfo0; - finfo2 = finfo0; - finfo3 = finfo0; - - /* get the initial times */ - GET_INFO_FILE(finfo0); - - /* - * make sure the write time is updated 2 seconds later - * calcuated from the first write - * (but expect upto 5 seconds extra time for a busy server) - */ - start = timeval_current(); - end = timeval_add(&start, 7 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - ZERO_STRUCT(wr); - wr.in.file.handle = *h; - wr.in.offset = 0; - wr.in.data = data_blob_const("x", 1); - status = smb2_write(tree, &wr); - CHECK_STATUS(status, NT_STATUS_OK); - written = wr.out.nwritten; - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_FILE(finfo1); - - if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - if (diff < (used_delay / (double)1000000)) { - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " - "(write time update delay == %.2f) (wrong!)\n", - diff, used_delay / (double)1000000); - ret = false; - break; - } - - torture_comment(tctx, "Server updated write_time after %.2f seconds " - "(correct)\n", - diff); - break; - } - smb_msleep(0.5 * msec); - } - - GET_INFO_FILE(finfo1); - COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); - - /* sure any further write doesn't update the write time */ - start = timeval_current(); - end = timeval_add(&start, 15 * sec, 0); - while (!timeval_expired(&end)) { - /* do a write */ - torture_comment(tctx, "Do a write on the file handle\n"); - ZERO_STRUCT(wr); - wr.in.file.handle = *h; - wr.in.offset = 0; - wr.in.data = data_blob_const("x", 1); - status = smb2_write(tree, &wr); - CHECK_STATUS(status, NT_STATUS_OK); - written = wr.out.nwritten; - if (written != 1) { - torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); - ret = false; - goto done; - } - /* get the times after the write */ - GET_INFO_FILE(finfo2); - - if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { - double diff = timeval_elapsed(&start); - torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " - "(wrong!)\n", - diff); - ret = false; - break; - } - smb_msleep(1 * msec); - } - - GET_INFO_FILE(finfo2); - COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); - if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { - torture_comment(tctx, "Server did not update write_time (correct)\n"); - } - - /* sleep */ - smb_msleep(5 * msec); - - GET_INFO_FILE(finfo3); - COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); - - /* - * the close updates the write time to the time of the close - * and not to the time of the last write! - */ - torture_comment(tctx, "Close the file handle\n"); - - ZERO_STRUCT(cl); - cl.in.file.handle = *h; - cl.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; - status = smb2_close(tree, &cl); - CHECK_STATUS(status, NT_STATUS_OK); - h = NULL; - //struct { - // /* static body buffer 60 (0x3C) bytes */ - // /* uint16_t buffer_code; 0x3C */ - // uint16_t flags; - // uint32_t _pad; - // NTTIME create_time; - // NTTIME access_time; - // NTTIME write_time; - // NTTIME change_time; - // uint64_t alloc_size; - // uint64_t size; - // uint32_t file_attr; - //} out; - - //if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { - // torture_comment(tctx, "Server updated the write_time on close (correct)\n"); - //} - ///* try a durable reconnect while the file is still open */ - //ZERO_STRUCT(io); - //io.in.fname = ""; - //io.in.durable_handle_v2 = h; - //io.in.create_guid = create_guid; - //status = smb2_create(tree, mem_ctx, &io); - //CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); - -done: - if (h != NULL) { - smb2_util_close(tree, *h); - } - - smb2_util_unlink(tree, fname); - - talloc_free(tree); - - talloc_free(mem_ctx); - - return ret; -} - struct torture_suite *torture_smb2_durable_v2_open_init(TALLOC_CTX *ctx) { struct torture_suite *suite = @@ -2698,7 +2030,6 @@ struct torture_suite *torture_smb2_durable_v2_open_init(TALLOC_CTX *ctx) torture_suite_add_2smb2_test(suite, "app-instance", test_durable_v2_open_app_instance); torture_suite_add_1smb2_test(suite, "persistent-open-oplock", test_persistent_open_oplock); torture_suite_add_1smb2_test(suite, "persistent-open-lease", test_persistent_open_lease); - torture_suite_add_1smb2_test(suite, "delaywrite1", test_durable_v2_delaywrite1); suite->description = talloc_strdup(suite, "SMB2-DURABLE-V2-OPEN tests"); -- 2.17.1 From f519ffb5a23974e793817d8ae9e5f2bfa81cc02b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 08:06:55 +0200 Subject: [PATCH 09/48] source4/torture/util_writetime.c --- source4/torture/smb2/durable_open.c | 198 +----------------- source4/torture/util.h | 8 + source4/torture/util_writetime.c | 300 ++++++++++++++++++++++++++++ source4/torture/wscript_build | 2 +- 4 files changed, 315 insertions(+), 193 deletions(-) create mode 100644 source4/torture/util_writetime.c diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index 0704fe4af8fd..814f4944152d 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -25,9 +25,9 @@ #include "libcli/smb2/smb2_calls.h" #include "../libcli/smb/smbXcli_base.h" #include "torture/torture.h" +#include "torture/util.h" #include "torture/smb2/proto.h" -#include "../libcli/smb/smbXcli_base.h" -#include "lib/util/time_basic.h" +#include "../lib/util/time_basic.h" #define CHECK_VAL(v, correct) do { \ if ((v) != (correct)) { \ @@ -2908,191 +2908,6 @@ done: } \ } while (0) -static bool test_delay_writetime(struct torture_context *tctx, - double used_delay, - double normal_delay, - const char *description, - bool (*get_basic_info_cb)(void *private_data, - union smb_fileinfo *finfo), - bool (*write_data_cb)(void *private_data), - void *private_data) -{ - union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfoT; - struct timeval before_write; - struct timeval after_write; - struct timeval before_last_write; - struct timeval after_last_write; - struct timeval start; - struct timeval end; - double sec = used_delay / normal_delay; - double msec = 1000 * sec; - double nsec = 1000 * msec; - double expected_delay = used_delay / nsec; - double min_delay = expected_delay * 0.01; - double max_delay = 5 * expected_delay; - bool ret = true; - bool ok; - - torture_comment(tctx, "START: %s\n", description); - - /* get the initial times */ - ok = get_basic_info_cb(private_data, &finfo0); - torture_assert(tctx, ok, "get_basic_info_cb: finfo0"); - - /* - * Make sure the time doesn't change during the next 5 seconds - */ - start = timeval_current(); - end = timeval_add(&start, max_delay * 1.25, 0); - while (!timeval_expired(&end)) { - smb_msleep(1 * msec); - torture_comment(tctx, "Check for no change\n"); - ok = get_basic_info_cb(private_data, &finfoT); - torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); - } - - ok = get_basic_info_cb(private_data, &finfoT); - torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); - - torture_comment(tctx, "Do a write on the file handle\n"); - before_write = timeval_current(); - ok = write_data_cb(private_data); - after_write = timeval_current(); - torture_assert(tctx, ok, "write_data_cb"); - - start = timeval_current(); - end = timeval_add(&start, max_delay * 2, 0); - while (!timeval_expired(&end)) { - struct timeval before_get; - struct timeval after_get; - - torture_comment(tctx, "Wait for change\n"); - before_get = timeval_current(); - ok = get_basic_info_cb(private_data, &finfoT); - after_get = timeval_current(); - torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - - if (finfoT.basic_info.out.write_time > finfo0.basic_info.out.write_time) { - double delayS = timeval_elapsed2(&after_write, &before_get); - double delayL = timeval_elapsed2(&before_write, &after_get); - - torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " - "(min delay == %.2f, max delay == %.2f)\n", - delayS, delayL, min_delay, max_delay); - torture_assert(tctx, (delayL >= min_delay), - "Server updated write_time to early!"); - torture_assert(tctx, (delayS <= max_delay), - "Server didn't update write_time!"); - - COMPARE_TIMES_AFTER_WRITE(finfoT, finfo0); - break; - } - - COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); - smb_msleep(0.01 * msec); - } - - ok = get_basic_info_cb(private_data, &finfo1); - torture_assert(tctx, ok, "get_basic_info_cb: finfo1"); - COMPARE_TIMES_AFTER_WRITE(finfo1, finfo0); - - /* - * Make sure the time doesn't change during the next 5 seconds - */ - start = timeval_current(); - end = timeval_add(&start, max_delay * 1.25, 0); - while (!timeval_expired(&end)) { - smb_msleep(1 * msec); - torture_comment(tctx, "Check for no additional change\n"); - ok = get_basic_info_cb(private_data, &finfoT); - torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); - } - - ok = get_basic_info_cb(private_data, &finfoT); - torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); - - torture_comment(tctx, "Do a write on the file handle\n"); - before_write = timeval_current(); - ok = write_data_cb(private_data); - after_write = timeval_current(); - torture_assert(tctx, ok, "write_data_cb"); - - ZERO_STRUCT(finfo2); - before_last_write = before_write; - after_last_write = after_write; - start = timeval_current(); - end = timeval_add(&start, max_delay * 2, 0); - while (!timeval_expired(&end)) { - struct timeval before_get; - struct timeval after_get; - - smb_msleep(0.01 * msec); - - torture_comment(tctx, "Wait for change\n"); - before_get = timeval_current(); - ok = get_basic_info_cb(private_data, &finfoT); - after_get = timeval_current(); - torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - - if (finfoT.basic_info.out.write_time > finfo1.basic_info.out.write_time) { - double delayS = timeval_elapsed2(&after_write, &before_get); - double delayL = timeval_elapsed2(&before_write, &after_get); - - torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " - "(min delay == %.2f, max delay == %.2f)\n", - delayS, delayL, min_delay, max_delay); - torture_assert(tctx, (delayL >= min_delay), - "Server updated write_time to early!"); - torture_assert(tctx, (delayS <= max_delay), - "Server didn't update write_time!"); - - COMPARE_TIMES_AFTER_WRITE(finfoT, finfo1); - before_write = before_last_write; - after_write = after_last_write; - finfo2 = finfoT; - break; - } - - COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); - - torture_comment(tctx, "Write while waiting\n"); - before_last_write = timeval_current(); - ok = write_data_cb(private_data); - after_last_write = timeval_current(); - torture_assert(tctx, ok, "write_data_cb"); - } - - // We may get one additional change... - - ok = get_basic_info_cb(private_data, &finfo3); - torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); - COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); - - /* - * Make sure the time doesn't change during the next 5 seconds - */ - start = timeval_current(); - end = timeval_add(&start, max_delay * 1.25, 0); - while (!timeval_expired(&end)) { - smb_msleep(1 * msec); - torture_comment(tctx, "Check for no additional change\n"); - ok = get_basic_info_cb(private_data, &finfoT); - torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); - } - - ok = get_basic_info_cb(private_data, &finfoT); - torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); - COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); - -done: - return ret; -} - struct test_durable_open_delaywrite1_state { struct torture_context *tctx; struct smb2_tree *tree1; @@ -3263,18 +3078,18 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, state.h1 = h1; state.h2 = h2; - ok = test_delay_writetime(tctx, used_delay, normal_delay, + ok = test_delay_writetime1(tctx, used_delay, normal_delay, "run1", test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, &state); - torture_assert(tctx, ok, "test_delay_writetime(1)"); - ok = test_delay_writetime(tctx, used_delay, normal_delay, + torture_assert(tctx, ok, "test_delay_writetime1(1)"); + ok = test_delay_writetime1(tctx, used_delay, normal_delay, "run2", test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, &state); - torture_assert(tctx, ok, "test_delay_writetime(2)"); + torture_assert(tctx, ok, "test_delay_writetime2(2)"); GET_INFO_BOTH(c1finfo1, c2finfo1); COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); @@ -3342,7 +3157,6 @@ done: return ret; } - struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx) { struct torture_suite *suite = diff --git a/source4/torture/util.h b/source4/torture/util.h index 4695710faece..cd0a530be409 100644 --- a/source4/torture/util.h +++ b/source4/torture/util.h @@ -107,5 +107,13 @@ NTSTATUS torture_check_privilege(struct smbcli_state *cli, const char *sid_str, const char *privilege); +bool test_delay_writetime1(struct torture_context *tctx, + double used_delay, + double normal_delay, + const char *description, + bool (*get_basic_info_cb)(void *private_data, + union smb_fileinfo *finfo), + bool (*write_data_cb)(void *private_data), + void *private_data); #endif /* _TORTURE_UTIL_H_ */ diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c new file mode 100644 index 000000000000..7ded582dd894 --- /dev/null +++ b/source4/torture/util_writetime.c @@ -0,0 +1,300 @@ +/* + Unix SMB/CIFS implementation. + + test suite for delayed write time updates + + Copyright (C) Stefan Metzmacher 2018 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "../lib/util/time_basic.h" +#include "../libcli/smb/smb_common.h" +#include "../libcli/smb/smbXcli_base.h" +#include "libcli/raw/libcliraw.h" +#include "torture/torture.h" +#include "torture/util.h" + +#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \ + const uint64_t _r = 10*1000*1000; \ + NTTIME _g = (given).basic_info.out.gelem; \ + NTTIME _gr = (_g / _r) * _r; \ + NTTIME _c = (correct).basic_info.out.celem; \ + NTTIME _cr = (_c / _r) * _r; \ + bool _strict = torture_setting_bool(tctx, "strict mode", false); \ + const char *_err = NULL; \ + if (_strict && (_g cmp _c)) { \ + _err = "strict"; \ + } else if ((_g cmp _c) && (_gr cmp _cr)) { \ + /* handle filesystem without high resolution timestamps */ \ + _err = "rounded"; \ + } \ + if (_err != NULL) { \ + struct timeval _gtv; \ + struct timeval _ctv; \ + struct timeval_buf _gtvb; \ + struct timeval_buf _ctvb; \ + nttime_to_timeval(&_gtv, _g); \ + nttime_to_timeval(&_ctv, _c); \ + torture_result(tctx, TORTURE_FAIL, \ + __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \ + _err, \ + #given, #gelem, \ + timeval_str_buf(&_gtv, false, true, &_gtvb), \ + #cmp, \ + #correct, #celem, \ + timeval_str_buf(&_ctv, false, true, &_ctvb)); \ + ret = false; \ + goto done; \ + } \ +} while (0) +#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \ +} while (0) +#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,!=) +#define COMPARE_WRITE_TIME_GREATER(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,<=) + +#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ +} while (0) +#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ + COMPARE_ACCESS_TIME_CMP(given,correct,!=) +#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ + COMPARE_ACCESS_TIME_CMP(given,correct,<=) + +#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ +} while (0) +#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ + COMPARE_CHANGE_TIME_CMP(given,correct,!=) +#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ + COMPARE_CHANGE_TIME_CMP(given,correct,<=) + +#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ +} while (0) +#define COMPARE_CREATE_TIME_EQUAL(given,correct) \ + COMPARE_CREATE_TIME_CMP(given,correct,!=) + +#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ + COMPARE_WRITE_TIME_EQUAL(given,correct); \ + COMPARE_CHANGE_TIME_EQUAL(given,correct); \ + COMPARE_ACCESS_TIME_EQUAL(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ +} while (0) + +#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ + COMPARE_WRITE_TIME_GREATER(given,correct); \ + COMPARE_CHANGE_TIME_GREATER(given,correct); \ + COMPARE_ACCESS_TIME_EQUAL(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ + COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ +} while (0) + +#define COMPARE_TIMES_AFTER_CLOSE(given,correct) do { \ + COMPARE_WRITE_TIME_GREATER(given,correct); \ + COMPARE_CHANGE_TIME_GREATER(given,correct); \ + COMPARE_ACCESS_TIME_GREATER(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ + COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ + COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ +} while (0) + +bool test_delay_writetime1(struct torture_context *tctx, + double used_delay, + double normal_delay, + const char *description, + bool (*get_basic_info_cb)(void *private_data, + union smb_fileinfo *finfo), + bool (*write_data_cb)(void *private_data), + void *private_data) +{ + union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfoT; + struct timeval before_write; + struct timeval after_write; + struct timeval before_last_write; + struct timeval after_last_write; + struct timeval start; + struct timeval end; + double sec = used_delay / normal_delay; + double msec = 1000 * sec; + double nsec = 1000 * msec; + double expected_delay = used_delay / nsec; + double min_delay = expected_delay * 0.01; + double max_delay = 5 * expected_delay; + bool ret = true; + bool ok; + + torture_comment(tctx, "START: %s\n", description); + + /* get the initial times */ + ok = get_basic_info_cb(private_data, &finfo0); + torture_assert(tctx, ok, "get_basic_info_cb: finfo0"); + + /* + * Make sure the time doesn't change during the next 5 seconds + */ + start = timeval_current(); + end = timeval_add(&start, max_delay * 1.25, 0); + while (!timeval_expired(&end)) { + smb_msleep(1 * msec); + torture_comment(tctx, "Check for no change\n"); + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); + } + + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); + + torture_comment(tctx, "Do a write on the file handle\n"); + before_write = timeval_current(); + ok = write_data_cb(private_data); + after_write = timeval_current(); + torture_assert(tctx, ok, "write_data_cb"); + + start = timeval_current(); + end = timeval_add(&start, max_delay * 2, 0); + while (!timeval_expired(&end)) { + struct timeval before_get; + struct timeval after_get; + + torture_comment(tctx, "Wait for change\n"); + before_get = timeval_current(); + ok = get_basic_info_cb(private_data, &finfoT); + after_get = timeval_current(); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + + if (finfoT.basic_info.out.write_time > finfo0.basic_info.out.write_time) { + double delayS = timeval_elapsed2(&after_write, &before_get); + double delayL = timeval_elapsed2(&before_write, &after_get); + + torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " + "(min delay == %.2f, max delay == %.2f)\n", + delayS, delayL, min_delay, max_delay); + torture_assert(tctx, (delayL >= min_delay), + "Server updated write_time to early!"); + torture_assert(tctx, (delayS <= max_delay), + "Server didn't update write_time!"); + + COMPARE_TIMES_AFTER_WRITE(finfoT, finfo0); + break; + } + + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); + smb_msleep(0.01 * msec); + } + + ok = get_basic_info_cb(private_data, &finfo1); + torture_assert(tctx, ok, "get_basic_info_cb: finfo1"); + COMPARE_TIMES_AFTER_WRITE(finfo1, finfo0); + + /* + * Make sure the time doesn't change during the next 5 seconds + */ + start = timeval_current(); + end = timeval_add(&start, max_delay * 1.25, 0); + while (!timeval_expired(&end)) { + smb_msleep(1 * msec); + torture_comment(tctx, "Check for no additional change\n"); + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); + } + + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); + + torture_comment(tctx, "Do a write on the file handle\n"); + before_write = timeval_current(); + ok = write_data_cb(private_data); + after_write = timeval_current(); + torture_assert(tctx, ok, "write_data_cb"); + + ZERO_STRUCT(finfo2); + before_last_write = before_write; + after_last_write = after_write; + start = timeval_current(); + end = timeval_add(&start, max_delay * 2, 0); + while (!timeval_expired(&end)) { + struct timeval before_get; + struct timeval after_get; + + smb_msleep(0.01 * msec); + + torture_comment(tctx, "Wait for change\n"); + before_get = timeval_current(); + ok = get_basic_info_cb(private_data, &finfoT); + after_get = timeval_current(); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + + if (finfoT.basic_info.out.write_time > finfo1.basic_info.out.write_time) { + double delayS = timeval_elapsed2(&after_write, &before_get); + double delayL = timeval_elapsed2(&before_write, &after_get); + + torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " + "(min delay == %.2f, max delay == %.2f)\n", + delayS, delayL, min_delay, max_delay); + torture_assert(tctx, (delayL >= min_delay), + "Server updated write_time to early!"); + torture_assert(tctx, (delayS <= max_delay), + "Server didn't update write_time!"); + + COMPARE_TIMES_AFTER_WRITE(finfoT, finfo1); + before_write = before_last_write; + after_write = after_last_write; + finfo2 = finfoT; + break; + } + + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); + + torture_comment(tctx, "Write while waiting\n"); + before_last_write = timeval_current(); + ok = write_data_cb(private_data); + after_last_write = timeval_current(); + torture_assert(tctx, ok, "write_data_cb"); + } + + // We may get one additional change... + + ok = get_basic_info_cb(private_data, &finfo3); + torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); + COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); + + /* + * Make sure the time doesn't change during the next 5 seconds + */ + start = timeval_current(); + end = timeval_add(&start, max_delay * 1.25, 0); + while (!timeval_expired(&end)) { + smb_msleep(1 * msec); + torture_comment(tctx, "Check for no additional change\n"); + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); + } + + ok = get_basic_info_cb(private_data, &finfoT); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); + +done: + return ret; +} diff --git a/source4/torture/wscript_build b/source4/torture/wscript_build index aceededc9d83..fb9c324da051 100644 --- a/source4/torture/wscript_build +++ b/source4/torture/wscript_build @@ -2,7 +2,7 @@ bld.SAMBA_SUBSYSTEM('TORTURE_UTIL', - source='util_smb.c', + source='util_smb.c util_writetime.c', public_deps='torture popt POPT_CREDENTIALS', deps='smbclient-raw' ) -- 2.17.1 From 728dcb36ef11adbf915256699002082458ab7e39 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 08:40:54 +0200 Subject: [PATCH 10/48] test_delaywrite_delaywrite1 SMB1 --- source4/torture/basic/delaywrite.c | 438 +++++++++++++++++++++++++++++ 1 file changed, 438 insertions(+) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index dd261d86d096..da69a5a6d126 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -3074,6 +3074,443 @@ static bool test_directory_update8(struct torture_context *tctx, struct smbcli_s return ret; } +#undef COMPARE_WRITE_TIME_CMP +#undef COMPARE_ACCESS_TIME_CMP + +#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \ + const uint64_t _r = 10*1000*1000; \ + NTTIME _g = (given).basic_info.out.gelem; \ + NTTIME _gr = (_g / _r) * _r; \ + NTTIME _c = (correct).basic_info.out.celem; \ + NTTIME _cr = (_c / _r) * _r; \ + bool _strict = torture_setting_bool(tctx, "strict mode", false); \ + const char *_err = NULL; \ + if (_strict && (_g cmp _c)) { \ + _err = "strict"; \ + } else if ((_g cmp _c) && (_gr cmp _cr)) { \ + /* handle filesystem without high resolution timestamps */ \ + _err = "rounded"; \ + } \ + if (_err != NULL) { \ + struct timeval _gtv; \ + struct timeval _ctv; \ + struct timeval_buf _gtvb; \ + struct timeval_buf _ctvb; \ + nttime_to_timeval(&_gtv, _g); \ + nttime_to_timeval(&_ctv, _c); \ + torture_result(tctx, TORTURE_FAIL, \ + __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \ + _err, \ + #given, #gelem, \ + timeval_str_buf(&_gtv, false, true, &_gtvb), \ + #cmp, \ + #correct, #celem, \ + timeval_str_buf(&_ctv, false, true, &_ctvb)); \ + ret = false; \ + goto done; \ + } \ +} while (0) +#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \ +} while (0) +#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,!=) +#define COMPARE_WRITE_TIME_GREATER(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,<=) + +#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ +} while (0) +#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ + COMPARE_ACCESS_TIME_CMP(given,correct,!=) +#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ + COMPARE_ACCESS_TIME_CMP(given,correct,<=) + +#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ +} while (0) +#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ + COMPARE_CHANGE_TIME_CMP(given,correct,!=) +#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ + COMPARE_CHANGE_TIME_CMP(given,correct,<=) + +#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ +} while (0) +#define COMPARE_CREATE_TIME_EQUAL(given,correct) \ + COMPARE_CREATE_TIME_CMP(given,correct,!=) + +#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ + COMPARE_WRITE_TIME_EQUAL(given,correct); \ + COMPARE_CHANGE_TIME_EQUAL(given,correct); \ + COMPARE_ACCESS_TIME_EQUAL(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ +} while (0) + +#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ + COMPARE_WRITE_TIME_GREATER(given,correct); \ + COMPARE_CHANGE_TIME_GREATER(given,correct); \ + COMPARE_ACCESS_TIME_EQUAL(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ + COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ +} while (0) + +struct test_delaywrite_delaywrite1_state { + struct torture_context *tctx; + struct smbcli_state *cli1; + struct smbcli_state *cli2; + int fnum1; + int fnum2; + const char *fname; +}; + +static bool test_delaywrite_delaywrite1_get_info(void *private_data, + union smb_fileinfo *finfo) +{ + struct test_delaywrite_delaywrite1_state *state = + (struct test_delaywrite_delaywrite1_state *)private_data; + struct torture_context *tctx = state->tctx; + struct smbcli_state *cli = state->cli1; + struct smbcli_state *cli2 = state->cli2; + union smb_fileinfo t1finfo; + union smb_fileinfo t2finfo; + union smb_fileinfo t2pinfo; + bool ret = true; + + ZERO_STRUCTP(finfo); + + ZERO_STRUCT(t1finfo); + t1finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + t1finfo.basic_info.in.file.fnum = state->fnum1; + + ZERO_STRUCT(t2finfo); + t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + t2finfo.basic_info.in.file.fnum = state->fnum2; + ZERO_STRUCT(t2pinfo); + t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + t2pinfo.basic_info.in.file.path = state->fname; + + GET_INFO_FILE2(t2finfo); + GET_INFO_PATH(t2pinfo); + GET_INFO_FILE(t1finfo); + if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { + /* + * There was a race, get it again on handle 2, + * but then they have to match. + */ + GET_INFO_FILE2(t2finfo); + GET_INFO_PATH(t2pinfo); + } + COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); + COMPARE_ALL_TIMES_EQUAL(t1finfo, t2pinfo); + + finfo->basic_info.out = t1finfo.basic_info.out; +done: + return ret; +} + +static bool test_delaywrite_delaywrite1_write_data(void *private_data) +{ + struct test_delaywrite_delaywrite1_state *state = + (struct test_delaywrite_delaywrite1_state *)private_data; + struct torture_context *tctx = state->tctx; + bool ret = true; + ssize_t nwritten; + + nwritten = smbcli_write(state->cli1->tree, state->fnum1, 0, "x", 0, 1); + torture_assert_int_equal_goto(tctx, nwritten, 1, + ret, done, "smbcli_write"); + +done: + return ret; +} + +static bool test_delaywrite_delaywrite1(struct torture_context *tctx, + struct smbcli_state *cli, + struct smbcli_state *cli2) +{ + struct test_delaywrite_delaywrite1_state state = { + .tctx = tctx, + .cli1 = cli, + .cli2 = cli2, + }; + union smb_fileinfo c1finfo0, c1finfo1, c1finfo2; + union smb_fileinfo c2pinfo0, c2pinfo1, c2pinfo2, c2pinfo3; + const char *fname = BASEDIR "\\torture_file3.txt"; + int fnum1 = -1; + int fnum2 = -1; + bool ret = true; + //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + double normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); + //double normal_delay = 1000000; + //int normal_delay = 2000000; + double sec = ((double)used_delay) / ((double)normal_delay); + int msec = 1000 * sec; + bool ok; + + torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); + + torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); + + torture_comment(tctx, "Open the file handle\n"); + fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum1 == -1) { + ret = false; + torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); + goto done; + } + fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum2 == -1) { + ret = false; + torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); + goto done; + } + + c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; + c1finfo0.basic_info.in.file.fnum = fnum1; + c1finfo1 = c1finfo0; + c1finfo2 = c1finfo0; + c2pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; + c2pinfo0.basic_info.in.file.path = fname; + c2pinfo1 = c2pinfo0; + c2pinfo2 = c2pinfo0; + c2pinfo3 = c2pinfo0; + + /* get the initial times */ + GET_INFO_BOTH(c1finfo0,c2pinfo0); + + state.fname = fname; + state.fnum1 = fnum1; + state.fnum2 = fnum2; + + ok = test_delay_writetime1(tctx, used_delay, normal_delay, + "run1", + test_delaywrite_delaywrite1_get_info, + test_delaywrite_delaywrite1_write_data, + &state); + torture_assert(tctx, ok, "test_delay_writetime1(1)"); + ok = test_delay_writetime1(tctx, used_delay, normal_delay, + "run2", + test_delaywrite_delaywrite1_get_info, + test_delaywrite_delaywrite1_write_data, + &state); + torture_assert(tctx, ok, "test_delay_writetime2(2)"); + + GET_INFO_BOTH(c1finfo1, c2pinfo1); + COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); + + /* sleep */ + torture_comment(tctx, "Sleep ...\n"); + smb_msleep(5 * msec); + torture_comment(tctx, "... continue\n"); + + GET_INFO_BOTH(c1finfo2, c2pinfo2); + COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); + + /* + * the close updates the write time to the time of the close + * and not to the time of the last write! + */ + torture_comment(tctx, "Close the file handle\n"); + smbcli_close(cli->tree, fnum1); + fnum1 = -1; + + GET_INFO_PATH(c2pinfo3); + COMPARE_WRITE_TIME_GREATER(c2pinfo3, c2pinfo2); + + if (c2pinfo3.basic_info.out.write_time > c2pinfo2.basic_info.out.write_time) { + torture_comment(tctx, "Server updated the write_time on close (correct)\n"); + } + + done: + if (fnum1 != -1) { + smbcli_close(cli->tree, fnum1); + } + if (fnum2 != -1) { + smbcli_close(cli2->tree, fnum2); + } + smbcli_unlink(cli->tree, fname); + smbcli_deltree(cli->tree, BASEDIR); + + return ret; +} +#if 0 + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(tctx); + char fname[256]; + struct smb2_handle _h1; + struct smb2_handle *h1 = NULL; + struct smb2_handle _h2; + struct smb2_handle *h2 = NULL; + struct smb2_create cr1; + struct smb2_create cr2; + union smb_fileinfo c1finfoCR, c1finfo0, c1finfo1, c1finfo2, c1finfoCL; + union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfoCL; + struct smb2_close cl1; + struct smb2_close cl2; + //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + double normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); + //double normal_delay = 1000000; + //int normal_delay = 2000000; + double sec = ((double)used_delay) / ((double)normal_delay); + int msec = 1000 * sec; + bool ret = true; + bool ok; + + /* Choose a random name in case the state is left a little funky. */ + snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", + generate_random_str(tctx, 8)); + + smb2_util_unlink(tree1, fname); + + smb2_oplock_create_share(&cr1, fname, + smb2_util_share_access(""), + smb2_util_oplock_level("b")); + cr1.in.durable_open = true; + + status = smb2_create(tree1, mem_ctx, &cr1); + CHECK_STATUS(status, NT_STATUS_OK); + _h1 = cr1.out.file.handle; + h1 = &_h1; + CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); + CHECK_VAL(cr1.out.durable_open, true); + CHECK_VAL(cr1.out.durable_open_v2, false); + CHECK_VAL(cr1.out.persistent_open, false); + + cr2 = cr1; + cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE; + cr2.in.durable_open = false; + cr2.in.oplock_level = 0; + cr2.in.create_disposition = NTCREATEX_DISP_OPEN; + status = smb2_create(tree2, mem_ctx, &cr2); + CHECK_STATUS(status, NT_STATUS_OK); + _h2 = cr2.out.file.handle; + h2 = &_h2; + CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(cr2.out.oplock_level, 0); + CHECK_VAL(cr2.out.durable_open, false); + CHECK_VAL(cr2.out.durable_open_v2, false); + CHECK_VAL(cr2.out.persistent_open, false); + + ZERO_STRUCT(c1finfoCR); + c1finfoCR.basic_info.out.create_time = cr1.out.create_time; + c1finfoCR.basic_info.out.access_time = cr1.out.access_time; + c1finfoCR.basic_info.out.write_time = cr1.out.write_time; + c1finfoCR.basic_info.out.change_time = cr1.out.change_time; + c1finfoCR.basic_info.out.attrib = cr1.out.file_attr; + + ZERO_STRUCT(c2finfoCR); + c2finfoCR.basic_info.out.create_time = cr2.out.create_time; + c2finfoCR.basic_info.out.access_time = cr2.out.access_time; + c2finfoCR.basic_info.out.write_time = cr2.out.write_time; + c2finfoCR.basic_info.out.change_time = cr2.out.change_time; + c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; + + COMPARE_ALL_TIMES_EQUAL(c1finfoCR, c2finfoCR); + + ZERO_STRUCT(c1finfo0); + c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + c1finfo0.basic_info.in.file.handle = *h1; + c1finfo1 = c1finfo0; + c1finfo2 = c1finfo0; + + ZERO_STRUCT(c2finfo0); + c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + c2finfo0.basic_info.in.file.handle = *h2; + c2finfo1 = c2finfo0; + c2finfo2 = c2finfo0; + c2finfo3 = c2finfo0; + + GET_INFO_BOTH(c1finfo0, c2finfo0); + COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); + + state.h1 = h1; + state.h2 = h2; + + ok = test_delay_writetime1(tctx, used_delay, normal_delay, + "run1", + test_delaywrite_delaywrite1_get_info, + test_delaywrite_delaywrite1_write_data, + &state); + torture_assert(tctx, ok, "test_delay_writetime1(1)"); + ok = test_delay_writetime1(tctx, used_delay, normal_delay, + "run2", + test_delaywrite_delaywrite1_get_info, + test_delaywrite_delaywrite1_write_data, + &state); + torture_assert(tctx, ok, "test_delay_writetime2(2)"); + + GET_INFO_BOTH(c1finfo1, c2finfo1); + COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); + + /* sleep */ + torture_comment(tctx, "Sleep ...\n"); + smb_msleep(5 * msec); + torture_comment(tctx, "... continue\n"); + + GET_INFO_BOTH(c1finfo2, c2finfo2); + COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); + + /* + * the close updates the write time to the time of the close + * and not to the time of the last write! + */ + torture_comment(tctx, "Close the file handle\n"); + + ZERO_STRUCT(cl1); + cl1.in.file.handle = *h1; + cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + status = smb2_close(tree1, &cl1); + CHECK_STATUS(status, NT_STATUS_OK); + h1 = NULL; + ZERO_STRUCT(c1finfoCL); + c1finfoCL.basic_info.out.create_time = cl1.out.create_time; + c1finfoCL.basic_info.out.access_time = cl1.out.access_time; + c1finfoCL.basic_info.out.write_time = cl1.out.write_time; + c1finfoCL.basic_info.out.change_time = cl1.out.change_time; + c1finfoCL.basic_info.out.attrib = cl1.out.file_attr; + COMPARE_ALL_TIMES_EQUAL(c1finfoCL, c1finfo2); + + GET_INFO_FILE(tree2, c2finfo3); + COMPARE_ALL_TIMES_EQUAL(c2finfo3, c1finfoCL); + + ZERO_STRUCT(cl2); + cl2.in.file.handle = *h2; + cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + status = smb2_close(tree2, &cl2); + CHECK_STATUS(status, NT_STATUS_OK); + h2 = NULL; + ZERO_STRUCT(c2finfoCL); + c2finfoCL.basic_info.out.create_time = cl2.out.create_time; + c2finfoCL.basic_info.out.access_time = cl2.out.access_time; + c2finfoCL.basic_info.out.write_time = cl2.out.write_time; + c2finfoCL.basic_info.out.change_time = cl2.out.change_time; + c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; + COMPARE_ALL_TIMES_EQUAL(c2finfoCL, c1finfoCL); + +done: + if (h1 != NULL) { + smb2_util_close(tree1, *h1); + } + if (h2 != NULL) { + smb2_util_close(tree2, *h2); + } + + smb2_util_unlink(tree1, fname); + + talloc_free(tree1); + talloc_free(tree2); + + talloc_free(mem_ctx); + + return ret; +} +#endif /* testing of delayed update of write_time */ @@ -3098,6 +3535,7 @@ struct torture_suite *torture_delay_write(TALLOC_CTX *ctx) torture_suite_add_2smb_test(suite, "delayed update of write time 6", test_delayed_write_update6); torture_suite_add_1smb_test(suite, "timestamp resolution test", test_delayed_write_update7); torture_suite_add_1smb_test(suite, "directory timestamp update test", test_directory_update8); + torture_suite_add_2smb_test(suite, "delaywrite1", test_delaywrite_delaywrite1); return suite; } -- 2.17.1 From aceb3f9c545b5d5a5dfc917e10028f1e5c5346ec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 09:39:36 +0200 Subject: [PATCH 11/48] sq source4/torture/util_writetime.c source4/torture/smb2/durable_open.c --- source4/torture/smb2/durable_open.c | 140 ++++++++++++++-------------- source4/torture/util.h | 2 + source4/torture/util_writetime.c | 16 ++++ 3 files changed, 86 insertions(+), 72 deletions(-) diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index 814f4944152d..f5ace21de8a3 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -2974,6 +2974,62 @@ done: return ret; } +static bool test_durable_open_delaywrite1_close(void *private_data, + union smb_fileinfo *finfo) +{ + struct test_durable_open_delaywrite1_state *state = + (struct test_durable_open_delaywrite1_state *)private_data; + struct torture_context *tctx = state->tctx; + union smb_fileinfo t1finfoCL; + union smb_fileinfo t2finfoCL; + struct smb2_close cl1; + struct smb2_close cl2; + union smb_fileinfo t2finfo; + NTSTATUS status; + bool ret = true; + + ZERO_STRUCTP(finfo); + + ZERO_STRUCT(cl1); + cl1.in.file.handle = *state->h1; + cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + status = smb2_close(state->tree1, &cl1); + CHECK_STATUS(status, NT_STATUS_OK); + state->h1 = NULL; + ZERO_STRUCT(t1finfoCL); + t1finfoCL.basic_info.out.create_time = cl1.out.create_time; + t1finfoCL.basic_info.out.access_time = cl1.out.access_time; + t1finfoCL.basic_info.out.write_time = cl1.out.write_time; + t1finfoCL.basic_info.out.change_time = cl1.out.change_time; + t1finfoCL.basic_info.out.attrib = cl1.out.file_attr; + + ZERO_STRUCT(t2finfo); + t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + t2finfo.basic_info.in.file.handle = *state->h2; + + GET_INFO_FILE(state->tree2, t2finfo); + COMPARE_ALL_TIMES_EQUAL(t2finfo, t1finfoCL); + + ZERO_STRUCT(cl2); + cl2.in.file.handle = *state->h2; + cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + status = smb2_close(state->tree2, &cl2); + CHECK_STATUS(status, NT_STATUS_OK); + state->h2 = NULL; + ZERO_STRUCT(t2finfoCL); + t2finfoCL.basic_info.out.create_time = cl2.out.create_time; + t2finfoCL.basic_info.out.access_time = cl2.out.access_time; + t2finfoCL.basic_info.out.write_time = cl2.out.write_time; + t2finfoCL.basic_info.out.change_time = cl2.out.change_time; + t2finfoCL.basic_info.out.attrib = cl2.out.file_attr; + COMPARE_ALL_TIMES_EQUAL(t2finfoCL, t1finfoCL); + + finfo->basic_info.out = t1finfoCL.basic_info.out; + +done: + return ret; +} + static bool test_durable_open_delaywrite1(struct torture_context *tctx, struct smb2_tree *tree1, struct smb2_tree *tree2) @@ -2987,23 +3043,17 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, TALLOC_CTX *mem_ctx = talloc_new(tctx); char fname[256]; struct smb2_handle _h1; - struct smb2_handle *h1 = NULL; struct smb2_handle _h2; - struct smb2_handle *h2 = NULL; struct smb2_create cr1; struct smb2_create cr2; - union smb_fileinfo c1finfoCR, c1finfo0, c1finfo1, c1finfo2, c1finfoCL; - union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfoCL; - struct smb2_close cl1; - struct smb2_close cl2; + union smb_fileinfo c1finfoCR, c1finfo0; + union smb_fileinfo c2finfoCR, c2finfo0; //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); double normal_delay = 1000000; double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); //double normal_delay = 1000000; //int normal_delay = 2000000; - double sec = ((double)used_delay) / ((double)normal_delay); - int msec = 1000 * sec; bool ret = true; bool ok; @@ -3021,7 +3071,7 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, status = smb2_create(tree1, mem_ctx, &cr1); CHECK_STATUS(status, NT_STATUS_OK); _h1 = cr1.out.file.handle; - h1 = &_h1; + state.h1 = &_h1; CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); CHECK_VAL(cr1.out.durable_open, true); @@ -3036,7 +3086,7 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, status = smb2_create(tree2, mem_ctx, &cr2); CHECK_STATUS(status, NT_STATUS_OK); _h2 = cr2.out.file.handle; - h2 = &_h2; + state.h2 = &_h2; CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); CHECK_VAL(cr2.out.oplock_level, 0); CHECK_VAL(cr2.out.durable_open, false); @@ -3061,90 +3111,36 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, ZERO_STRUCT(c1finfo0); c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - c1finfo0.basic_info.in.file.handle = *h1; - c1finfo1 = c1finfo0; - c1finfo2 = c1finfo0; + c1finfo0.basic_info.in.file.handle = *state.h1; ZERO_STRUCT(c2finfo0); c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - c2finfo0.basic_info.in.file.handle = *h2; - c2finfo1 = c2finfo0; - c2finfo2 = c2finfo0; - c2finfo3 = c2finfo0; + c2finfo0.basic_info.in.file.handle = *state.h2; GET_INFO_BOTH(c1finfo0, c2finfo0); COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); - state.h1 = h1; - state.h2 = h2; - ok = test_delay_writetime1(tctx, used_delay, normal_delay, "run1", test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, + NULL, /* close_cb */ &state); torture_assert(tctx, ok, "test_delay_writetime1(1)"); ok = test_delay_writetime1(tctx, used_delay, normal_delay, "run2", test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, + test_durable_open_delaywrite1_close, &state); torture_assert(tctx, ok, "test_delay_writetime2(2)"); - GET_INFO_BOTH(c1finfo1, c2finfo1); - COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); - - /* sleep */ - torture_comment(tctx, "Sleep ...\n"); - smb_msleep(5 * msec); - torture_comment(tctx, "... continue\n"); - - GET_INFO_BOTH(c1finfo2, c2finfo2); - COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); - - /* - * the close updates the write time to the time of the close - * and not to the time of the last write! - */ - torture_comment(tctx, "Close the file handle\n"); - - ZERO_STRUCT(cl1); - cl1.in.file.handle = *h1; - cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; - status = smb2_close(tree1, &cl1); - CHECK_STATUS(status, NT_STATUS_OK); - h1 = NULL; - ZERO_STRUCT(c1finfoCL); - c1finfoCL.basic_info.out.create_time = cl1.out.create_time; - c1finfoCL.basic_info.out.access_time = cl1.out.access_time; - c1finfoCL.basic_info.out.write_time = cl1.out.write_time; - c1finfoCL.basic_info.out.change_time = cl1.out.change_time; - c1finfoCL.basic_info.out.attrib = cl1.out.file_attr; - COMPARE_ALL_TIMES_EQUAL(c1finfoCL, c1finfo2); - - GET_INFO_FILE(tree2, c2finfo3); - COMPARE_ALL_TIMES_EQUAL(c2finfo3, c1finfoCL); - - ZERO_STRUCT(cl2); - cl2.in.file.handle = *h2; - cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; - status = smb2_close(tree2, &cl2); - CHECK_STATUS(status, NT_STATUS_OK); - h2 = NULL; - ZERO_STRUCT(c2finfoCL); - c2finfoCL.basic_info.out.create_time = cl2.out.create_time; - c2finfoCL.basic_info.out.access_time = cl2.out.access_time; - c2finfoCL.basic_info.out.write_time = cl2.out.write_time; - c2finfoCL.basic_info.out.change_time = cl2.out.change_time; - c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; - COMPARE_ALL_TIMES_EQUAL(c2finfoCL, c1finfoCL); - done: - if (h1 != NULL) { - smb2_util_close(tree1, *h1); + if (state.h1 != NULL) { + smb2_util_close(tree1, *state.h1); } - if (h2 != NULL) { - smb2_util_close(tree2, *h2); + if (state.h2 != NULL) { + smb2_util_close(tree2, *state.h2); } smb2_util_unlink(tree1, fname); diff --git a/source4/torture/util.h b/source4/torture/util.h index cd0a530be409..05e983453d22 100644 --- a/source4/torture/util.h +++ b/source4/torture/util.h @@ -114,6 +114,8 @@ bool test_delay_writetime1(struct torture_context *tctx, bool (*get_basic_info_cb)(void *private_data, union smb_fileinfo *finfo), bool (*write_data_cb)(void *private_data), + bool (*close_cb)(void *private_data, + union smb_fileinfo *finfo), void *private_data); #endif /* _TORTURE_UTIL_H_ */ diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c index 7ded582dd894..c567280eb36b 100644 --- a/source4/torture/util_writetime.c +++ b/source4/torture/util_writetime.c @@ -121,6 +121,8 @@ bool test_delay_writetime1(struct torture_context *tctx, bool (*get_basic_info_cb)(void *private_data, union smb_fileinfo *finfo), bool (*write_data_cb)(void *private_data), + bool (*close_cb)(void *private_data, + union smb_fileinfo *finfo), void *private_data) { union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfoT; @@ -295,6 +297,20 @@ bool test_delay_writetime1(struct torture_context *tctx, torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); + if (close_cb == NULL) { + goto done; + } + + /* + * the close updates the write time to the time of the close + * and not to the time of the last write! + */ + torture_comment(tctx, "Close the file handle\n"); + + ok = close_cb(private_data, &finfoT); + torture_assert(tctx, ok, "close_cb: finfoT"); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); + done: return ret; } -- 2.17.1 From 3dc77fdf7a48009acd706f657116707ac2316b84 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 09:58:38 +0200 Subject: [PATCH 12/48] works for SMB2, fails SMB1 SMB1: no update at all. What's the difference to 'delayed update of write time' test??? --- source4/torture/basic/delaywrite.c | 118 +++++++++++++--------------- source4/torture/smb2/durable_open.c | 8 +- source4/torture/util.h | 1 + source4/torture/util_writetime.c | 14 +++- 4 files changed, 72 insertions(+), 69 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index da69a5a6d126..c95d8ab518d2 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -3225,6 +3225,48 @@ done: return ret; } +static bool test_delaywrite_delaywrite1_close(void *private_data, + union smb_fileinfo *finfo) +{ + struct test_delaywrite_delaywrite1_state *state = + (struct test_delaywrite_delaywrite1_state *)private_data; + struct torture_context *tctx = state->tctx; + struct smbcli_state *cli2 = state->cli2; + union smb_fileinfo t2finfo; + union smb_fileinfo t2pinfo; + bool ret = true; + + ZERO_STRUCTP(finfo); + + /* + * the close updates the write time to the time of the close + * and not to the time of the last write! + */ + torture_comment(tctx, "Close the file handle\n"); + smbcli_close(state->cli1->tree, state->fnum1); + state->fnum1 = -1; + + ZERO_STRUCT(t2finfo); + t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFO; + t2finfo.basic_info.in.file.fnum = state->fnum2; + ZERO_STRUCT(t2pinfo); + t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFO; + t2pinfo.basic_info.in.file.path = state->fname; + + GET_INFO_FILE2(t2finfo); + + smbcli_close(state->cli2->tree, state->fnum2); + state->fnum2 = -1; + + GET_INFO_PATH(t2pinfo); + COMPARE_ALL_TIMES_EQUAL(t2pinfo, t2finfo); + + finfo->basic_info.out = t2finfo.basic_info.out; + +done: + return ret; +} + static bool test_delaywrite_delaywrite1(struct torture_context *tctx, struct smbcli_state *cli, struct smbcli_state *cli2) @@ -3233,12 +3275,10 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, .tctx = tctx, .cli1 = cli, .cli2 = cli2, + .fnum1 = -1, + .fnum2 = -1, }; - union smb_fileinfo c1finfo0, c1finfo1, c1finfo2; - union smb_fileinfo c2pinfo0, c2pinfo1, c2pinfo2, c2pinfo3; const char *fname = BASEDIR "\\torture_file3.txt"; - int fnum1 = -1; - int fnum2 = -1; bool ret = true; //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); @@ -3246,8 +3286,6 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); //double normal_delay = 1000000; //int normal_delay = 2000000; - double sec = ((double)used_delay) / ((double)normal_delay); - int msec = 1000 * sec; bool ok; torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); @@ -3255,81 +3293,35 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); torture_comment(tctx, "Open the file handle\n"); - fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); - if (fnum1 == -1) { + state.fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (state.fnum1 == -1) { ret = false; torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); goto done; } - fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); - if (fnum2 == -1) { + state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (state.fnum2 == -1) { ret = false; torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); goto done; } - c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; - c1finfo0.basic_info.in.file.fnum = fnum1; - c1finfo1 = c1finfo0; - c1finfo2 = c1finfo0; - c2pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; - c2pinfo0.basic_info.in.file.path = fname; - c2pinfo1 = c2pinfo0; - c2pinfo2 = c2pinfo0; - c2pinfo3 = c2pinfo0; - - /* get the initial times */ - GET_INFO_BOTH(c1finfo0,c2pinfo0); - state.fname = fname; - state.fnum1 = fnum1; - state.fnum2 = fnum2; ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run1", + "run", true, /* smb1 */ test_delaywrite_delaywrite1_get_info, test_delaywrite_delaywrite1_write_data, + test_delaywrite_delaywrite1_close, &state); - torture_assert(tctx, ok, "test_delay_writetime1(1)"); - ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run2", - test_delaywrite_delaywrite1_get_info, - test_delaywrite_delaywrite1_write_data, - &state); - torture_assert(tctx, ok, "test_delay_writetime2(2)"); - - GET_INFO_BOTH(c1finfo1, c2pinfo1); - COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); - - /* sleep */ - torture_comment(tctx, "Sleep ...\n"); - smb_msleep(5 * msec); - torture_comment(tctx, "... continue\n"); - - GET_INFO_BOTH(c1finfo2, c2pinfo2); - COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); - - /* - * the close updates the write time to the time of the close - * and not to the time of the last write! - */ - torture_comment(tctx, "Close the file handle\n"); - smbcli_close(cli->tree, fnum1); - fnum1 = -1; - - GET_INFO_PATH(c2pinfo3); - COMPARE_WRITE_TIME_GREATER(c2pinfo3, c2pinfo2); - - if (c2pinfo3.basic_info.out.write_time > c2pinfo2.basic_info.out.write_time) { - torture_comment(tctx, "Server updated the write_time on close (correct)\n"); - } + torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime2(2)"); done: - if (fnum1 != -1) { - smbcli_close(cli->tree, fnum1); + if (state.fnum1 != -1) { + smbcli_close(cli->tree, state.fnum1); } - if (fnum2 != -1) { - smbcli_close(cli2->tree, fnum2); + if (state.fnum2 != -1) { + smbcli_close(cli2->tree, state.fnum2); } smbcli_unlink(cli->tree, fname); smbcli_deltree(cli->tree, BASEDIR); diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index f5ace21de8a3..a21fca2373d1 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -3121,19 +3121,19 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run1", + "run1", false, /* smb1 */ test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, NULL, /* close_cb */ &state); - torture_assert(tctx, ok, "test_delay_writetime1(1)"); + torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run2", + "run2", false, /* smb1 */ test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, test_durable_open_delaywrite1_close, &state); - torture_assert(tctx, ok, "test_delay_writetime2(2)"); + torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime2(2)"); done: if (state.h1 != NULL) { diff --git a/source4/torture/util.h b/source4/torture/util.h index 05e983453d22..f0b3e15c1ecc 100644 --- a/source4/torture/util.h +++ b/source4/torture/util.h @@ -111,6 +111,7 @@ bool test_delay_writetime1(struct torture_context *tctx, double used_delay, double normal_delay, const char *description, + bool smb1, bool (*get_basic_info_cb)(void *private_data, union smb_fileinfo *finfo), bool (*write_data_cb)(void *private_data), diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c index c567280eb36b..a6e42274466c 100644 --- a/source4/torture/util_writetime.c +++ b/source4/torture/util_writetime.c @@ -118,6 +118,7 @@ bool test_delay_writetime1(struct torture_context *tctx, double used_delay, double normal_delay, const char *description, + bool smb1, bool (*get_basic_info_cb)(void *private_data, union smb_fileinfo *finfo), bool (*write_data_cb)(void *private_data), @@ -229,6 +230,11 @@ bool test_delay_writetime1(struct torture_context *tctx, after_write = timeval_current(); torture_assert(tctx, ok, "write_data_cb"); + if (smb1) { + finfo2 = finfo1; + goto no_change; + } + ZERO_STRUCT(finfo2); before_last_write = before_write; after_last_write = after_write; @@ -275,7 +281,7 @@ bool test_delay_writetime1(struct torture_context *tctx, } // We may get one additional change... - +no_change: ok = get_basic_info_cb(private_data, &finfo3); torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); @@ -309,7 +315,11 @@ bool test_delay_writetime1(struct torture_context *tctx, ok = close_cb(private_data, &finfoT); torture_assert(tctx, ok, "close_cb: finfoT"); - COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); + if (smb1) { + COMPARE_TIMES_AFTER_CLOSE(finfoT, finfo1); + } else { + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); + } done: return ret; -- 2.17.1 From be3fa262b08968001c370de62cfe22a418b3f4b9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 10:23:14 +0200 Subject: [PATCH 13/48] works SMB1 --- source4/torture/basic/delaywrite.c | 46 +++++++++++++++++++++--------- source4/torture/util_writetime.c | 15 ++++++---- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index c95d8ab518d2..9e99298af51d 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -3172,6 +3172,7 @@ static bool test_delaywrite_delaywrite1_get_info(void *private_data, struct torture_context *tctx = state->tctx; struct smbcli_state *cli = state->cli1; struct smbcli_state *cli2 = state->cli2; + struct smbcli_state *tmpcli = NULL; union smb_fileinfo t1finfo; union smb_fileinfo t2finfo; union smb_fileinfo t2pinfo; @@ -3190,20 +3191,30 @@ static bool test_delaywrite_delaywrite1_get_info(void *private_data, t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; t2pinfo.basic_info.in.file.path = state->fname; - GET_INFO_FILE2(t2finfo); - GET_INFO_PATH(t2pinfo); + if (state->fnum2 != -1) { + GET_INFO_FILE2(t2finfo); + } + tmpcli = cli2; + cli2 = cli; + if (0) GET_INFO_PATH(t2pinfo); + cli2 = tmpcli; GET_INFO_FILE(t1finfo); +if (0) { if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { /* * There was a race, get it again on handle 2, * but then they have to match. */ + if (state->fnum2 != -1) { GET_INFO_FILE2(t2finfo); - GET_INFO_PATH(t2pinfo); } + if (0) GET_INFO_PATH(t2pinfo); + } + if (state->fnum2 != -1) { COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); + } COMPARE_ALL_TIMES_EQUAL(t1finfo, t2pinfo); - +} finfo->basic_info.out = t1finfo.basic_info.out; done: return ret; @@ -3253,15 +3264,22 @@ static bool test_delaywrite_delaywrite1_close(void *private_data, t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFO; t2pinfo.basic_info.in.file.path = state->fname; - GET_INFO_FILE2(t2finfo); + if (state->fnum2 != -1) { + GET_INFO_FILE2(t2finfo); + } - smbcli_close(state->cli2->tree, state->fnum2); - state->fnum2 = -1; + if (state->fnum2 != -1) { + smbcli_close(state->cli2->tree, state->fnum2); + state->fnum2 = -1; + } GET_INFO_PATH(t2pinfo); + if (state->fnum2 != -1) { COMPARE_ALL_TIMES_EQUAL(t2pinfo, t2finfo); + } finfo->basic_info.out = t2finfo.basic_info.out; + finfo->basic_info.out = t2pinfo.basic_info.out; done: return ret; @@ -3299,12 +3317,12 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); goto done; } - state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); - if (state.fnum2 == -1) { - ret = false; - torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); - goto done; - } + //state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + //if (state.fnum2 == -1) { + // ret = false; + // torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); + // goto done; + //} state.fname = fname; @@ -3314,7 +3332,7 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, test_delaywrite_delaywrite1_write_data, test_delaywrite_delaywrite1_close, &state); - torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime2(2)"); + torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1()"); done: if (state.fnum1 != -1) { diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c index a6e42274466c..c3e2cde75afb 100644 --- a/source4/torture/util_writetime.c +++ b/source4/torture/util_writetime.c @@ -142,12 +142,13 @@ bool test_delay_writetime1(struct torture_context *tctx, bool ret = true; bool ok; + smb1 = false; torture_comment(tctx, "START: %s\n", description); /* get the initial times */ ok = get_basic_info_cb(private_data, &finfo0); torture_assert(tctx, ok, "get_basic_info_cb: finfo0"); - +if (1 || !smb1) { /* * Make sure the time doesn't change during the next 5 seconds */ @@ -164,7 +165,7 @@ bool test_delay_writetime1(struct torture_context *tctx, ok = get_basic_info_cb(private_data, &finfoT); torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); - +} torture_comment(tctx, "Do a write on the file handle\n"); before_write = timeval_current(); ok = write_data_cb(private_data); @@ -200,7 +201,8 @@ bool test_delay_writetime1(struct torture_context *tctx, } COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); - smb_msleep(0.01 * msec); + //smb_msleep(0.01 * msec); + smb_msleep(1 * msec); } ok = get_basic_info_cb(private_data, &finfo1); @@ -231,8 +233,8 @@ bool test_delay_writetime1(struct torture_context *tctx, torture_assert(tctx, ok, "write_data_cb"); if (smb1) { - finfo2 = finfo1; - goto no_change; + //finfo2 = finfo1; + if (0) goto no_change; } ZERO_STRUCT(finfo2); @@ -316,7 +318,8 @@ no_change: ok = close_cb(private_data, &finfoT); torture_assert(tctx, ok, "close_cb: finfoT"); if (smb1) { - COMPARE_TIMES_AFTER_CLOSE(finfoT, finfo1); + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); + //COMPARE_TIMES_AFTER_CLOSE(finfoT, finfo1); } else { COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); } -- 2.17.1 From f8d5b924bd3cb54e1dec2977daa0af1ca5627ca3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 10:29:06 +0200 Subject: [PATCH 14/48] still works SMB1 --- source4/torture/basic/delaywrite.c | 47 +++++++----------------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 9e99298af51d..aca49bc80472 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -3172,10 +3172,8 @@ static bool test_delaywrite_delaywrite1_get_info(void *private_data, struct torture_context *tctx = state->tctx; struct smbcli_state *cli = state->cli1; struct smbcli_state *cli2 = state->cli2; - struct smbcli_state *tmpcli = NULL; union smb_fileinfo t1finfo; union smb_fileinfo t2finfo; - union smb_fileinfo t2pinfo; bool ret = true; ZERO_STRUCTP(finfo); @@ -3187,34 +3185,18 @@ static bool test_delaywrite_delaywrite1_get_info(void *private_data, ZERO_STRUCT(t2finfo); t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; t2finfo.basic_info.in.file.fnum = state->fnum2; - ZERO_STRUCT(t2pinfo); - t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - t2pinfo.basic_info.in.file.path = state->fname; - if (state->fnum2 != -1) { - GET_INFO_FILE2(t2finfo); - } - tmpcli = cli2; - cli2 = cli; - if (0) GET_INFO_PATH(t2pinfo); - cli2 = tmpcli; + GET_INFO_FILE2(t2finfo); GET_INFO_FILE(t1finfo); -if (0) { if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { /* * There was a race, get it again on handle 2, * but then they have to match. */ - if (state->fnum2 != -1) { GET_INFO_FILE2(t2finfo); } - if (0) GET_INFO_PATH(t2pinfo); - } - if (state->fnum2 != -1) { COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); - } - COMPARE_ALL_TIMES_EQUAL(t1finfo, t2pinfo); -} + finfo->basic_info.out = t1finfo.basic_info.out; done: return ret; @@ -3264,21 +3246,14 @@ static bool test_delaywrite_delaywrite1_close(void *private_data, t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFO; t2pinfo.basic_info.in.file.path = state->fname; - if (state->fnum2 != -1) { - GET_INFO_FILE2(t2finfo); - } + GET_INFO_FILE2(t2finfo); - if (state->fnum2 != -1) { - smbcli_close(state->cli2->tree, state->fnum2); - state->fnum2 = -1; - } + smbcli_close(state->cli2->tree, state->fnum2); + state->fnum2 = -1; GET_INFO_PATH(t2pinfo); - if (state->fnum2 != -1) { COMPARE_ALL_TIMES_EQUAL(t2pinfo, t2finfo); - } - finfo->basic_info.out = t2finfo.basic_info.out; finfo->basic_info.out = t2pinfo.basic_info.out; done: @@ -3317,12 +3292,12 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); goto done; } - //state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); - //if (state.fnum2 == -1) { - // ret = false; - // torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); - // goto done; - //} + state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (state.fnum2 == -1) { + ret = false; + torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); + goto done; + } state.fname = fname; -- 2.17.1 From 713123bda5075672afcb211a6742950ad968b146 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 10:43:20 +0200 Subject: [PATCH 15/48] break test_delayed_write_update with a PATHINFO call... --- source4/torture/basic/delaywrite.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index aca49bc80472..a38242b2fe62 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -37,6 +37,7 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcli_state *cli) { union smb_fileinfo finfo1, finfo2; + union smb_fileinfo pinfo1; const char *fname = BASEDIR "\\torture_file.txt"; NTSTATUS status; int fnum1 = -1; @@ -71,6 +72,11 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl torture_assert_int_equal(tctx, written, 1, "unexpected number of bytes written"); + pinfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO; + pinfo1.basic_info.in.file.path = fname; + status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); + torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); + start = timeval_current(); end = timeval_add(&start, (120 * sec), 0); while (!timeval_expired(&end)) { -- 2.17.1 From de084ad41c6455152ad798e70aa3903e79b7ee9c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 10:54:27 +0200 Subject: [PATCH 16/48] works for SMB1 and SMB2 --- source4/torture/basic/delaywrite.c | 11 +++++++++-- source4/torture/smb2/durable_open.c | 6 +++--- source4/torture/util.h | 1 - source4/torture/util_writetime.c | 20 ++++---------------- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index a38242b2fe62..0f9fdfd7e5f1 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -3308,12 +3308,19 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, state.fname = fname; ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run", true, /* smb1 */ + "run1", + test_delaywrite_delaywrite1_get_info, + test_delaywrite_delaywrite1_write_data, + NULL, /* close_cb */ + &state); + torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); + ok = test_delay_writetime1(tctx, used_delay, normal_delay, + "run2", test_delaywrite_delaywrite1_get_info, test_delaywrite_delaywrite1_write_data, test_delaywrite_delaywrite1_close, &state); - torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1()"); + torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); done: if (state.fnum1 != -1) { diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index a21fca2373d1..63eb7e99922a 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -3121,19 +3121,19 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run1", false, /* smb1 */ + "run1", test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, NULL, /* close_cb */ &state); torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run2", false, /* smb1 */ + "run2", test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, test_durable_open_delaywrite1_close, &state); - torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime2(2)"); + torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); done: if (state.h1 != NULL) { diff --git a/source4/torture/util.h b/source4/torture/util.h index f0b3e15c1ecc..05e983453d22 100644 --- a/source4/torture/util.h +++ b/source4/torture/util.h @@ -111,7 +111,6 @@ bool test_delay_writetime1(struct torture_context *tctx, double used_delay, double normal_delay, const char *description, - bool smb1, bool (*get_basic_info_cb)(void *private_data, union smb_fileinfo *finfo), bool (*write_data_cb)(void *private_data), diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c index c3e2cde75afb..98d021b8d7f7 100644 --- a/source4/torture/util_writetime.c +++ b/source4/torture/util_writetime.c @@ -118,7 +118,6 @@ bool test_delay_writetime1(struct torture_context *tctx, double used_delay, double normal_delay, const char *description, - bool smb1, bool (*get_basic_info_cb)(void *private_data, union smb_fileinfo *finfo), bool (*write_data_cb)(void *private_data), @@ -142,13 +141,12 @@ bool test_delay_writetime1(struct torture_context *tctx, bool ret = true; bool ok; - smb1 = false; torture_comment(tctx, "START: %s\n", description); /* get the initial times */ ok = get_basic_info_cb(private_data, &finfo0); torture_assert(tctx, ok, "get_basic_info_cb: finfo0"); -if (1 || !smb1) { + /* * Make sure the time doesn't change during the next 5 seconds */ @@ -165,7 +163,7 @@ if (1 || !smb1) { ok = get_basic_info_cb(private_data, &finfoT); torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); -} + torture_comment(tctx, "Do a write on the file handle\n"); before_write = timeval_current(); ok = write_data_cb(private_data); @@ -232,11 +230,6 @@ if (1 || !smb1) { after_write = timeval_current(); torture_assert(tctx, ok, "write_data_cb"); - if (smb1) { - //finfo2 = finfo1; - if (0) goto no_change; - } - ZERO_STRUCT(finfo2); before_last_write = before_write; after_last_write = after_write; @@ -283,7 +276,7 @@ if (1 || !smb1) { } // We may get one additional change... -no_change: + ok = get_basic_info_cb(private_data, &finfo3); torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); @@ -317,12 +310,7 @@ no_change: ok = close_cb(private_data, &finfoT); torture_assert(tctx, ok, "close_cb: finfoT"); - if (smb1) { - COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); - //COMPARE_TIMES_AFTER_CLOSE(finfoT, finfo1); - } else { - COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); - } + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); done: return ret; -- 2.17.1 From 61e4fc83f45c701508fe3c34289f1c6be4636554 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 19:29:33 +0200 Subject: [PATCH 17/48] source4/torture/smb2/timestamps.c --- source4/torture/smb2/smb2.c | 2 + source4/torture/smb2/timestamps.c | 459 +++++++++++++++++++++++++++++ source4/torture/smb2/wscript_build | 1 + 3 files changed, 462 insertions(+) create mode 100644 source4/torture/smb2/timestamps.c diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c index 344cf5a40a52..1f82a77ec22a 100644 --- a/source4/torture/smb2/smb2.c +++ b/source4/torture/smb2/smb2.c @@ -187,6 +187,8 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx) torture_suite_add_suite(suite, torture_smb2_doc_init(suite)); + torture_suite_add_suite(suite, torture_smb2_timestamps_init(suite)); + suite->description = talloc_strdup(suite, "SMB2-specific tests"); torture_register_suite(ctx, suite); diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c new file mode 100644 index 000000000000..bb8e7325788b --- /dev/null +++ b/source4/torture/smb2/timestamps.c @@ -0,0 +1,459 @@ +/* + Unix SMB/CIFS implementation. + + test suite for SMB2 timestamp handling + + Copyright (C) Stefan Metzmacher 2018 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" +#include "../libcli/smb/smbXcli_base.h" +#include "torture/torture.h" +#include "torture/util.h" +#include "torture/smb2/proto.h" +#include "../lib/util/time_basic.h" + +#define CHECK_VAL(v, correct) do { \ + torture_assert_int_equal_goto(tctx, v, correct, ret, done, __location__); \ +} while (0) + +#define CHECK_STATUS(status, correct) do { \ + torture_assert_ntstatus_equal_goto(tctx, status, correct, ret, done, __location__); \ +} while (0) + +#define CHECK_CREATED(__io, __created, __attribute) \ + do { \ + CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \ + CHECK_VAL((__io)->out.alloc_size, 0); \ + CHECK_VAL((__io)->out.size, 0); \ + CHECK_VAL((__io)->out.file_attr, (__attribute)); \ + CHECK_VAL((__io)->out.reserved2, 0); \ + } while(0) + +#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \ + const uint64_t _r = 10*1000*1000; \ + NTTIME _g = (given).basic_info.out.gelem; \ + NTTIME _gr = (_g / _r) * _r; \ + NTTIME _c = (correct).basic_info.out.celem; \ + NTTIME _cr = (_c / _r) * _r; \ + bool _strict = torture_setting_bool(tctx, "strict mode", false); \ + const char *_err = NULL; \ + if (_strict && (_g cmp _c)) { \ + _err = "strict"; \ + } else if ((_g cmp _c) && (_gr cmp _cr)) { \ + /* handle filesystem without high resolution timestamps */ \ + _err = "rounded"; \ + } \ + if (_err != NULL) { \ + struct timeval _gtv; \ + struct timeval _ctv; \ + struct timeval_buf _gtvb; \ + struct timeval_buf _ctvb; \ + nttime_to_timeval(&_gtv, _g); \ + nttime_to_timeval(&_ctv, _c); \ + torture_result(tctx, TORTURE_FAIL, \ + __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \ + _err, \ + #given, #gelem, \ + timeval_str_buf(&_gtv, false, true, &_gtvb), \ + #cmp, \ + #correct, #celem, \ + timeval_str_buf(&_ctv, false, true, &_ctvb)); \ + ret = false; \ + goto done; \ + } \ +} while (0) +#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \ +} while (0) +#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,!=) +#define COMPARE_WRITE_TIME_GREATER(given,correct) \ + COMPARE_WRITE_TIME_CMP(given,correct,<=) + +#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ +} while (0) +#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ + COMPARE_ACCESS_TIME_CMP(given,correct,!=) +#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ + COMPARE_ACCESS_TIME_CMP(given,correct,<=) + +#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ +} while (0) +#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ + COMPARE_CHANGE_TIME_CMP(given,correct,!=) +#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ + COMPARE_CHANGE_TIME_CMP(given,correct,<=) + +#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ + COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ +} while (0) +#define COMPARE_CREATE_TIME_EQUAL(given,correct) \ + COMPARE_CREATE_TIME_CMP(given,correct,!=) + +#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ + COMPARE_WRITE_TIME_EQUAL(given,correct); \ + COMPARE_CHANGE_TIME_EQUAL(given,correct); \ + COMPARE_ACCESS_TIME_EQUAL(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ +} while (0) + +#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ + COMPARE_WRITE_TIME_GREATER(given,correct); \ + COMPARE_CHANGE_TIME_GREATER(given,correct); \ + COMPARE_ACCESS_TIME_EQUAL(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ + COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ +} while (0) + +#define COMPARE_TIMES_AFTER_CLOSE(given,correct) do { \ + COMPARE_WRITE_TIME_GREATER(given,correct); \ + COMPARE_CHANGE_TIME_GREATER(given,correct); \ + COMPARE_ACCESS_TIME_GREATER(given,correct); \ + COMPARE_CREATE_TIME_EQUAL(given,correct); \ + COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ + COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ +} while (0) + +#define GET_INFO_FILE(tree, finfo) do { \ + struct timeval _atv; \ + struct timeval _wtv; \ + struct timeval_buf _atvb; \ + struct timeval_buf _wtvb; \ + NTSTATUS _status; \ + _status = smb2_getinfo_file(tree, tctx, &finfo); \ + if (!NT_STATUS_IS_OK(_status)) { \ + ret = false; \ + torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ + nt_errstr(_status)); \ + goto done; \ + } \ + nttime_to_timeval(&_atv, finfo.basic_info.out.access_time); \ + nttime_to_timeval(&_wtv, finfo.basic_info.out.write_time); \ + torture_comment(tctx, "fileinfo(%s,%s): Access(%s) Write(%s)\n", \ + #tree, #finfo, \ + timeval_str_buf(&_atv, false, true, &_atvb), \ + timeval_str_buf(&_wtv, false, true, &_wtvb)); \ +} while (0) + +#define GET_INFO_BOTH(finfo1, finfo2) do { \ + GET_INFO_FILE(tree2, finfo2); \ + GET_INFO_FILE(tree1, finfo1); \ + COMPARE_ALL_TIMES_EQUAL(finfo1, finfo2); \ +} while (0) + +#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ + NTSTATUS _status; \ + union smb_setfileinfo sfinfo; \ + sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ + sfinfo.basic_info.in.file.fnum = tfnum; \ + sfinfo.basic_info.in.create_time = 0; \ + sfinfo.basic_info.in.access_time = 0; \ + unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ + sfinfo.basic_info.in.change_time = 0; \ + sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ + _status = smb_raw_setfileinfo(tree, &sfinfo); \ + if (!NT_STATUS_IS_OK(_status)) { \ + torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ + nt_errstr(_status)); \ + ret = false; \ + goto done; \ + } \ +} while (0) +#define SET_INFO_FILE(finfo, wrtime) \ + SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) + +#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ + NTSTATUS _status; \ + union smb_setfileinfo sfinfo; \ + sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ + sfinfo.basic_info.in.file.fnum = tfnum; \ + sfinfo.basic_info.in.create_time = 0; \ + sfinfo.basic_info.in.access_time = 0; \ + unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ + sfinfo.basic_info.in.write_time += (ns); \ + sfinfo.basic_info.in.change_time = 0; \ + sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ + _status = smb_raw_setfileinfo(tree, &sfinfo); \ + if (!NT_STATUS_IS_OK(_status)) { \ + torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ + nt_errstr(_status)); \ + ret = false; \ + goto done; \ + } \ +} while (0) + +struct test_durable_open_delaywrite1_state { + struct torture_context *tctx; + struct smb2_tree *tree1; + struct smb2_tree *tree2; + struct smb2_handle *h1; + struct smb2_handle *h2; +}; + +static bool test_durable_open_delaywrite1_get_info(void *private_data, + union smb_fileinfo *finfo) +{ + struct test_durable_open_delaywrite1_state *state = + (struct test_durable_open_delaywrite1_state *)private_data; + struct torture_context *tctx = state->tctx; + union smb_fileinfo t1finfo; + union smb_fileinfo t2finfo; + bool ret = true; + + ZERO_STRUCTP(finfo); + + ZERO_STRUCT(t1finfo); + t1finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + t1finfo.basic_info.in.file.handle = *state->h1; + + ZERO_STRUCT(t2finfo); + t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + t2finfo.basic_info.in.file.handle = *state->h2; + + GET_INFO_FILE(state->tree2, t2finfo); + GET_INFO_FILE(state->tree1, t1finfo); + if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { + /* + * There was a race, get it again on handle 2, + * but then they have to match. + */ + GET_INFO_FILE(state->tree2, t2finfo); + } + COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); + + finfo->basic_info.out = t1finfo.basic_info.out; +done: + return ret; +} + +static bool test_durable_open_delaywrite1_write_data(void *private_data) +{ + struct test_durable_open_delaywrite1_state *state = + (struct test_durable_open_delaywrite1_state *)private_data; + struct torture_context *tctx = state->tctx; + struct smb2_write wr; + NTSTATUS status; + bool ret = true; + + ZERO_STRUCT(wr); + wr.in.file.handle = *state->h1; + wr.in.offset = 0; + wr.in.data = data_blob_const("x", 1); + status = smb2_write(state->tree1, &wr); + CHECK_STATUS(status, NT_STATUS_OK); + torture_assert_int_equal_goto(tctx, wr.out.nwritten, 1, + ret, done, "smb2_write"); + +done: + return ret; +} + +static bool test_durable_open_delaywrite1_close(void *private_data, + union smb_fileinfo *finfo) +{ + struct test_durable_open_delaywrite1_state *state = + (struct test_durable_open_delaywrite1_state *)private_data; + struct torture_context *tctx = state->tctx; + union smb_fileinfo t1finfoCL; + union smb_fileinfo t2finfoCL; + struct smb2_close cl1; + struct smb2_close cl2; + union smb_fileinfo t2finfo; + NTSTATUS status; + bool ret = true; + + ZERO_STRUCTP(finfo); + + ZERO_STRUCT(cl1); + cl1.in.file.handle = *state->h1; + cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + status = smb2_close(state->tree1, &cl1); + CHECK_STATUS(status, NT_STATUS_OK); + state->h1 = NULL; + ZERO_STRUCT(t1finfoCL); + t1finfoCL.basic_info.out.create_time = cl1.out.create_time; + t1finfoCL.basic_info.out.access_time = cl1.out.access_time; + t1finfoCL.basic_info.out.write_time = cl1.out.write_time; + t1finfoCL.basic_info.out.change_time = cl1.out.change_time; + t1finfoCL.basic_info.out.attrib = cl1.out.file_attr; + + ZERO_STRUCT(t2finfo); + t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + t2finfo.basic_info.in.file.handle = *state->h2; + + GET_INFO_FILE(state->tree2, t2finfo); + COMPARE_ALL_TIMES_EQUAL(t2finfo, t1finfoCL); + + ZERO_STRUCT(cl2); + cl2.in.file.handle = *state->h2; + cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + status = smb2_close(state->tree2, &cl2); + CHECK_STATUS(status, NT_STATUS_OK); + state->h2 = NULL; + ZERO_STRUCT(t2finfoCL); + t2finfoCL.basic_info.out.create_time = cl2.out.create_time; + t2finfoCL.basic_info.out.access_time = cl2.out.access_time; + t2finfoCL.basic_info.out.write_time = cl2.out.write_time; + t2finfoCL.basic_info.out.change_time = cl2.out.change_time; + t2finfoCL.basic_info.out.attrib = cl2.out.file_attr; + COMPARE_ALL_TIMES_EQUAL(t2finfoCL, t1finfoCL); + + finfo->basic_info.out = t1finfoCL.basic_info.out; + +done: + return ret; +} + +static bool test_durable_open_delaywrite1(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) +{ + struct test_durable_open_delaywrite1_state state = { + .tctx = tctx, + .tree1 = tree1, + .tree2 = tree2, + }; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(tctx); + char fname[256]; + struct smb2_handle _h1; + struct smb2_handle _h2; + struct smb2_create cr1; + struct smb2_create cr2; + union smb_fileinfo c1finfoCR, c1finfo0; + union smb_fileinfo c2finfoCR, c2finfo0; + //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + double normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); + //double normal_delay = 1000000; + //int normal_delay = 2000000; + bool ret = true; + bool ok; + + /* Choose a random name in case the state is left a little funky. */ + snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", + generate_random_str(tctx, 8)); + + smb2_util_unlink(tree1, fname); + + smb2_oplock_create_share(&cr1, fname, + smb2_util_share_access(""), + smb2_util_oplock_level("b")); + cr1.in.durable_open = true; + + status = smb2_create(tree1, mem_ctx, &cr1); + CHECK_STATUS(status, NT_STATUS_OK); + _h1 = cr1.out.file.handle; + state.h1 = &_h1; + CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); + CHECK_VAL(cr1.out.durable_open, true); + CHECK_VAL(cr1.out.durable_open_v2, false); + CHECK_VAL(cr1.out.persistent_open, false); + + cr2 = cr1; + cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE; + cr2.in.durable_open = false; + cr2.in.oplock_level = 0; + cr2.in.create_disposition = NTCREATEX_DISP_OPEN; + status = smb2_create(tree2, mem_ctx, &cr2); + CHECK_STATUS(status, NT_STATUS_OK); + _h2 = cr2.out.file.handle; + state.h2 = &_h2; + CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(cr2.out.oplock_level, 0); + CHECK_VAL(cr2.out.durable_open, false); + CHECK_VAL(cr2.out.durable_open_v2, false); + CHECK_VAL(cr2.out.persistent_open, false); + + ZERO_STRUCT(c1finfoCR); + c1finfoCR.basic_info.out.create_time = cr1.out.create_time; + c1finfoCR.basic_info.out.access_time = cr1.out.access_time; + c1finfoCR.basic_info.out.write_time = cr1.out.write_time; + c1finfoCR.basic_info.out.change_time = cr1.out.change_time; + c1finfoCR.basic_info.out.attrib = cr1.out.file_attr; + + ZERO_STRUCT(c2finfoCR); + c2finfoCR.basic_info.out.create_time = cr2.out.create_time; + c2finfoCR.basic_info.out.access_time = cr2.out.access_time; + c2finfoCR.basic_info.out.write_time = cr2.out.write_time; + c2finfoCR.basic_info.out.change_time = cr2.out.change_time; + c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; + + COMPARE_ALL_TIMES_EQUAL(c1finfoCR, c2finfoCR); + + ZERO_STRUCT(c1finfo0); + c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + c1finfo0.basic_info.in.file.handle = *state.h1; + + ZERO_STRUCT(c2finfo0); + c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; + c2finfo0.basic_info.in.file.handle = *state.h2; + + GET_INFO_BOTH(c1finfo0, c2finfo0); + COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); + + ok = test_delay_writetime1(tctx, used_delay, normal_delay, + "run1", + test_durable_open_delaywrite1_get_info, + test_durable_open_delaywrite1_write_data, + NULL, /* close_cb */ + &state); + torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); + ok = test_delay_writetime1(tctx, used_delay, normal_delay, + "run2", + test_durable_open_delaywrite1_get_info, + test_durable_open_delaywrite1_write_data, + test_durable_open_delaywrite1_close, + &state); + torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); + +done: + if (state.h1 != NULL) { + smb2_util_close(tree1, *state.h1); + } + if (state.h2 != NULL) { + smb2_util_close(tree2, *state.h2); + } + + smb2_util_unlink(tree1, fname); + + talloc_free(tree1); + talloc_free(tree2); + + talloc_free(mem_ctx); + + return ret; +} + +struct torture_suite *torture_smb2_timestamps_init(TALLOC_CTX *ctx) +{ + struct torture_suite *suite = + torture_suite_create(ctx, "timestamps"); + + torture_suite_add_2smb2_test(suite, "delaywrite1", + test_durable_open_delaywrite1); + + suite->description = talloc_strdup(suite, "SMB2-TIMESTAMPS tests"); + + return suite; +} diff --git a/source4/torture/smb2/wscript_build b/source4/torture/smb2/wscript_build index 8b0060a2831b..209ea98a004c 100644 --- a/source4/torture/smb2/wscript_build +++ b/source4/torture/smb2/wscript_build @@ -31,6 +31,7 @@ bld.SAMBA_MODULE('TORTURE_SMB2', sharemode.c smb2.c streams.c + timestamps.c util.c ''', subsystem='smbtorture', -- 2.17.1 From fafb38ee97ea0224d5ca6d4de3ffc8fbd8257abf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 19:51:48 +0200 Subject: [PATCH 18/48] source4/torture/util_writetime.c test_delay_writetime1 --- source4/torture/util_writetime.c | 49 ++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c index 98d021b8d7f7..453bcd335c33 100644 --- a/source4/torture/util_writetime.c +++ b/source4/torture/util_writetime.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. - test suite for delayed write time updates + test suite for SMB(1/2/3) timestamp handling Copyright (C) Stefan Metzmacher 2018 @@ -260,13 +260,12 @@ bool test_delay_writetime1(struct torture_context *tctx, "Server didn't update write_time!"); COMPARE_TIMES_AFTER_WRITE(finfoT, finfo1); - before_write = before_last_write; - after_write = after_last_write; finfo2 = finfoT; break; } COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); + finfo2 = finfoT; torture_comment(tctx, "Write while waiting\n"); before_last_write = timeval_current(); @@ -275,17 +274,49 @@ bool test_delay_writetime1(struct torture_context *tctx, torture_assert(tctx, ok, "write_data_cb"); } - // We may get one additional change... + before_write = before_last_write; + after_write = after_last_write; + ZERO_STRUCT(finfo3); + start = after_write; + end = timeval_add(&start, max_delay * 1.25, 0); + while (!timeval_expired(&end)) { + struct timeval before_get; + struct timeval after_get; + + smb_msleep(1 * msec); + + torture_comment(tctx, "Wait for change or no change\n"); + before_get = timeval_current(); + ok = get_basic_info_cb(private_data, &finfoT); + after_get = timeval_current(); + torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); + + if (finfoT.basic_info.out.write_time > finfo2.basic_info.out.write_time) { + double delayS = timeval_elapsed2(&after_write, &before_get); + double delayL = timeval_elapsed2(&before_write, &after_get); - ok = get_basic_info_cb(private_data, &finfo3); - torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); - COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); + torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " + "(min delay == %.2f, max delay == %.2f)\n", + delayS, delayL, min_delay, max_delay); + torture_assert(tctx, (delayL >= min_delay), + "Server updated write_time to early!"); + torture_assert(tctx, (delayS <= max_delay), + "Server didn't update write_time!"); + + COMPARE_TIMES_AFTER_WRITE(finfoT, finfo2); + start = timeval_current(); + end = timeval_add(&start, max_delay * 1.25, 0); + finfo3 = finfoT; + break; + } + + COMPARE_ALL_TIMES_EQUAL(finfoT, finfo2); + finfo3 = finfoT; + } /* * Make sure the time doesn't change during the next 5 seconds */ - start = timeval_current(); - end = timeval_add(&start, max_delay * 1.25, 0); while (!timeval_expired(&end)) { smb_msleep(1 * msec); torture_comment(tctx, "Check for no additional change\n"); -- 2.17.1 From bb18eaaa3870ec4f930a3a0bfe9fd6d85680cba5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 19:52:30 +0200 Subject: [PATCH 19/48] sq source4/torture/smb2/timestamps.c --- source4/torture/smb2/timestamps.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c index bb8e7325788b..44c7e9dab6e1 100644 --- a/source4/torture/smb2/timestamps.c +++ b/source4/torture/smb2/timestamps.c @@ -83,24 +83,18 @@ } while (0) #define COMPARE_WRITE_TIME_EQUAL(given,correct) \ COMPARE_WRITE_TIME_CMP(given,correct,!=) -#define COMPARE_WRITE_TIME_GREATER(given,correct) \ - COMPARE_WRITE_TIME_CMP(given,correct,<=) #define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ } while (0) #define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ COMPARE_ACCESS_TIME_CMP(given,correct,!=) -#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ - COMPARE_ACCESS_TIME_CMP(given,correct,<=) #define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ } while (0) #define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ COMPARE_CHANGE_TIME_CMP(given,correct,!=) -#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ - COMPARE_CHANGE_TIME_CMP(given,correct,<=) #define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ @@ -115,23 +109,6 @@ COMPARE_CREATE_TIME_EQUAL(given,correct); \ } while (0) -#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ - COMPARE_WRITE_TIME_GREATER(given,correct); \ - COMPARE_CHANGE_TIME_GREATER(given,correct); \ - COMPARE_ACCESS_TIME_EQUAL(given,correct); \ - COMPARE_CREATE_TIME_EQUAL(given,correct); \ - COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ -} while (0) - -#define COMPARE_TIMES_AFTER_CLOSE(given,correct) do { \ - COMPARE_WRITE_TIME_GREATER(given,correct); \ - COMPARE_CHANGE_TIME_GREATER(given,correct); \ - COMPARE_ACCESS_TIME_GREATER(given,correct); \ - COMPARE_CREATE_TIME_EQUAL(given,correct); \ - COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ - COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ -} while (0) - #define GET_INFO_FILE(tree, finfo) do { \ struct timeval _atv; \ struct timeval _wtv; \ -- 2.17.1 From 40e2c7e3c94a48b27a79afbda7aad63b874004b9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 19:53:06 +0200 Subject: [PATCH 20/48] sq source4/torture/basic/delaywrite.c --- source4/torture/basic/delaywrite.c | 212 +++-------------------------- 1 file changed, 18 insertions(+), 194 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 0f9fdfd7e5f1..5b4fbc2b6e3b 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -1314,50 +1314,48 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s COMPARE_WRITE_TIME_EQUAL(given,correct); \ } while (0) -#define GET_INFO_FILE(finfo) do { \ +#define _DEBUG_BASIC_INFO(finfo, comment) do { \ struct timeval atv; \ struct timeval wtv; \ struct timeval_buf atvb; \ struct timeval_buf wtvb; \ - NTSTATUS _status; \ - _status = smb_raw_fileinfo(cli->tree, tctx, &finfo); \ - if (!NT_STATUS_IS_OK(_status)) { \ - ret = false; \ - torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ - nt_errstr(_status)); \ - goto done; \ - } \ nttime_to_timeval(&atv, finfo.basic_info.out.access_time); \ nttime_to_timeval(&wtv, finfo.basic_info.out.write_time); \ - torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \ + torture_comment(tctx, "%s: Access(%s) Write(%s)\n", \ + comment, \ timeval_str_buf(&atv, false, true, &atvb), \ timeval_str_buf(&wtv, false, true, &wtvb)); \ } while (0) -#define GET_INFO_FILE2(finfo) do { \ +#define _GET_INFO_FILE(tree, finfo) do { \ NTSTATUS _status; \ - _status = smb_raw_fileinfo(cli2->tree, tctx, &finfo); \ + _status = smb_raw_fileinfo(tree, tctx, &finfo); \ if (!NT_STATUS_IS_OK(_status)) { \ ret = false; \ torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ nt_errstr(_status)); \ goto done; \ } \ - torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \ - nt_time_string(tctx, finfo.basic_info.out.access_time), \ - nt_time_string(tctx, finfo.basic_info.out.write_time)); \ + _DEBUG_BASIC_INFO(finfo, "fileinfo(" #tree ")"); \ } while (0) -#define GET_INFO_PATH(pinfo) do { \ +#define _GET_INFO_PATH(tree, pinfo) do { \ NTSTATUS _status; \ - _status = smb_raw_pathinfo(cli2->tree, tctx, &pinfo); \ + _status = smb_raw_pathinfo(tree, tctx, &pinfo); \ if (!NT_STATUS_IS_OK(_status)) { \ torture_result(tctx, TORTURE_FAIL, __location__": pathinfo failed: %s", \ nt_errstr(_status)); \ ret = false; \ goto done; \ } \ - torture_comment(tctx, "pathinfo: Access(%s) Write(%s)\n", \ - nt_time_string(tctx, pinfo.basic_info.out.access_time), \ - nt_time_string(tctx, pinfo.basic_info.out.write_time)); \ + _DEBUG_BASIC_INFO(pinfo, "pathinfo(" #tree ")"); \ +} while (0) +#define GET_INFO_FILE(finfo) do { \ + _GET_INFO_FILE(cli->tree, finfo); \ +} while (0) +#define GET_INFO_FILE2(finfo) do { \ + _GET_INFO_FILE(cli2->tree, finfo); \ +} while (0) +#define GET_INFO_PATH(pinfo) do { \ + _GET_INFO_PATH(cli2->tree, pinfo); \ } while (0) #define GET_INFO_BOTH(finfo,pinfo) do { \ GET_INFO_FILE(finfo); \ @@ -3334,181 +3332,7 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, return ret; } -#if 0 - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(tctx); - char fname[256]; - struct smb2_handle _h1; - struct smb2_handle *h1 = NULL; - struct smb2_handle _h2; - struct smb2_handle *h2 = NULL; - struct smb2_create cr1; - struct smb2_create cr2; - union smb_fileinfo c1finfoCR, c1finfo0, c1finfo1, c1finfo2, c1finfoCL; - union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfoCL; - struct smb2_close cl1; - struct smb2_close cl2; - //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - double normal_delay = 1000000; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); - //double normal_delay = 1000000; - //int normal_delay = 2000000; - double sec = ((double)used_delay) / ((double)normal_delay); - int msec = 1000 * sec; - bool ret = true; - bool ok; - - /* Choose a random name in case the state is left a little funky. */ - snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", - generate_random_str(tctx, 8)); - - smb2_util_unlink(tree1, fname); - - smb2_oplock_create_share(&cr1, fname, - smb2_util_share_access(""), - smb2_util_oplock_level("b")); - cr1.in.durable_open = true; - - status = smb2_create(tree1, mem_ctx, &cr1); - CHECK_STATUS(status, NT_STATUS_OK); - _h1 = cr1.out.file.handle; - h1 = &_h1; - CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); - CHECK_VAL(cr1.out.durable_open, true); - CHECK_VAL(cr1.out.durable_open_v2, false); - CHECK_VAL(cr1.out.persistent_open, false); - - cr2 = cr1; - cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE; - cr2.in.durable_open = false; - cr2.in.oplock_level = 0; - cr2.in.create_disposition = NTCREATEX_DISP_OPEN; - status = smb2_create(tree2, mem_ctx, &cr2); - CHECK_STATUS(status, NT_STATUS_OK); - _h2 = cr2.out.file.handle; - h2 = &_h2; - CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(cr2.out.oplock_level, 0); - CHECK_VAL(cr2.out.durable_open, false); - CHECK_VAL(cr2.out.durable_open_v2, false); - CHECK_VAL(cr2.out.persistent_open, false); - - ZERO_STRUCT(c1finfoCR); - c1finfoCR.basic_info.out.create_time = cr1.out.create_time; - c1finfoCR.basic_info.out.access_time = cr1.out.access_time; - c1finfoCR.basic_info.out.write_time = cr1.out.write_time; - c1finfoCR.basic_info.out.change_time = cr1.out.change_time; - c1finfoCR.basic_info.out.attrib = cr1.out.file_attr; - - ZERO_STRUCT(c2finfoCR); - c2finfoCR.basic_info.out.create_time = cr2.out.create_time; - c2finfoCR.basic_info.out.access_time = cr2.out.access_time; - c2finfoCR.basic_info.out.write_time = cr2.out.write_time; - c2finfoCR.basic_info.out.change_time = cr2.out.change_time; - c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; - - COMPARE_ALL_TIMES_EQUAL(c1finfoCR, c2finfoCR); - - ZERO_STRUCT(c1finfo0); - c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - c1finfo0.basic_info.in.file.handle = *h1; - c1finfo1 = c1finfo0; - c1finfo2 = c1finfo0; - - ZERO_STRUCT(c2finfo0); - c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - c2finfo0.basic_info.in.file.handle = *h2; - c2finfo1 = c2finfo0; - c2finfo2 = c2finfo0; - c2finfo3 = c2finfo0; - - GET_INFO_BOTH(c1finfo0, c2finfo0); - COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); - - state.h1 = h1; - state.h2 = h2; - - ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run1", - test_delaywrite_delaywrite1_get_info, - test_delaywrite_delaywrite1_write_data, - &state); - torture_assert(tctx, ok, "test_delay_writetime1(1)"); - ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run2", - test_delaywrite_delaywrite1_get_info, - test_delaywrite_delaywrite1_write_data, - &state); - torture_assert(tctx, ok, "test_delay_writetime2(2)"); - GET_INFO_BOTH(c1finfo1, c2finfo1); - COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); - - /* sleep */ - torture_comment(tctx, "Sleep ...\n"); - smb_msleep(5 * msec); - torture_comment(tctx, "... continue\n"); - - GET_INFO_BOTH(c1finfo2, c2finfo2); - COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); - - /* - * the close updates the write time to the time of the close - * and not to the time of the last write! - */ - torture_comment(tctx, "Close the file handle\n"); - - ZERO_STRUCT(cl1); - cl1.in.file.handle = *h1; - cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; - status = smb2_close(tree1, &cl1); - CHECK_STATUS(status, NT_STATUS_OK); - h1 = NULL; - ZERO_STRUCT(c1finfoCL); - c1finfoCL.basic_info.out.create_time = cl1.out.create_time; - c1finfoCL.basic_info.out.access_time = cl1.out.access_time; - c1finfoCL.basic_info.out.write_time = cl1.out.write_time; - c1finfoCL.basic_info.out.change_time = cl1.out.change_time; - c1finfoCL.basic_info.out.attrib = cl1.out.file_attr; - COMPARE_ALL_TIMES_EQUAL(c1finfoCL, c1finfo2); - - GET_INFO_FILE(tree2, c2finfo3); - COMPARE_ALL_TIMES_EQUAL(c2finfo3, c1finfoCL); - - ZERO_STRUCT(cl2); - cl2.in.file.handle = *h2; - cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; - status = smb2_close(tree2, &cl2); - CHECK_STATUS(status, NT_STATUS_OK); - h2 = NULL; - ZERO_STRUCT(c2finfoCL); - c2finfoCL.basic_info.out.create_time = cl2.out.create_time; - c2finfoCL.basic_info.out.access_time = cl2.out.access_time; - c2finfoCL.basic_info.out.write_time = cl2.out.write_time; - c2finfoCL.basic_info.out.change_time = cl2.out.change_time; - c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; - COMPARE_ALL_TIMES_EQUAL(c2finfoCL, c1finfoCL); - -done: - if (h1 != NULL) { - smb2_util_close(tree1, *h1); - } - if (h2 != NULL) { - smb2_util_close(tree2, *h2); - } - - smb2_util_unlink(tree1, fname); - - talloc_free(tree1); - talloc_free(tree2); - - talloc_free(mem_ctx); - - return ret; -} -#endif /* testing of delayed update of write_time */ -- 2.17.1 From c666c2a9f1cd123ef4ba2c4d60ff63eb1bfaec2f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 19:53:17 +0200 Subject: [PATCH 21/48] test_delayed_write_update TODO: research PATHINFO => DEFER_CHANGE_ON_CLOSE --- source4/torture/basic/delaywrite.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 5b4fbc2b6e3b..b53ec0ada35e 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -72,13 +72,19 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl torture_assert_int_equal(tctx, written, 1, "unexpected number of bytes written"); + start = timeval_current(); + //smb_msleep(5 * msec); pinfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO; + pinfo1.basic_info.level = RAW_FILEINFO_MODE_INFORMATION; pinfo1.basic_info.in.file.path = fname; status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); - start = timeval_current(); - end = timeval_add(&start, (120 * sec), 0); + //written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); + //torture_assert_int_equal(tctx, written, 1, + // "unexpected number of bytes written"); + + end = timeval_add(&start, (30 * sec), 0); while (!timeval_expired(&end)) { status = smb_raw_fileinfo(cli->tree, tctx, &finfo2); @@ -107,14 +113,16 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl smb_msleep(1 * msec); } - torture_assert_u64_not_equal(tctx, - finfo2.basic_info.out.write_time, - finfo1.basic_info.out.write_time, - "Server did not update write time within " - "120 seconds"); + //torture_assert_u64_not_equal(tctx, + // finfo2.basic_info.out.write_time, + // finfo1.basic_info.out.write_time, + // "Server did not update write time within " + // "120 seconds"); if (fnum1 != -1) smbcli_close(cli->tree, fnum1); + status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); + torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); smbcli_unlink(cli->tree, fname); smbcli_deltree(cli->tree, BASEDIR); -- 2.17.1 From ea4b58768d15880e1dac512d78073a96aa98c870 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 19:54:03 +0200 Subject: [PATCH 22/48] Revert "test_delayed_write_update TODO: research PATHINFO => DEFER_CHANGE_ON_CLOSE" This reverts commit c666c2a9f1cd123ef4ba2c4d60ff63eb1bfaec2f. --- source4/torture/basic/delaywrite.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index b53ec0ada35e..5b4fbc2b6e3b 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -72,19 +72,13 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl torture_assert_int_equal(tctx, written, 1, "unexpected number of bytes written"); - start = timeval_current(); - //smb_msleep(5 * msec); pinfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO; - pinfo1.basic_info.level = RAW_FILEINFO_MODE_INFORMATION; pinfo1.basic_info.in.file.path = fname; status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); - //written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); - //torture_assert_int_equal(tctx, written, 1, - // "unexpected number of bytes written"); - - end = timeval_add(&start, (30 * sec), 0); + start = timeval_current(); + end = timeval_add(&start, (120 * sec), 0); while (!timeval_expired(&end)) { status = smb_raw_fileinfo(cli->tree, tctx, &finfo2); @@ -113,16 +107,14 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl smb_msleep(1 * msec); } - //torture_assert_u64_not_equal(tctx, - // finfo2.basic_info.out.write_time, - // finfo1.basic_info.out.write_time, - // "Server did not update write time within " - // "120 seconds"); + torture_assert_u64_not_equal(tctx, + finfo2.basic_info.out.write_time, + finfo1.basic_info.out.write_time, + "Server did not update write time within " + "120 seconds"); if (fnum1 != -1) smbcli_close(cli->tree, fnum1); - status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); - torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); smbcli_unlink(cli->tree, fname); smbcli_deltree(cli->tree, BASEDIR); -- 2.17.1 From fa2eeff50187202d8dd7d934c932829aec10166e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 19:57:53 +0200 Subject: [PATCH 23/48] test_smb_timestamp_writetime1 source4/torture/util_smb_timestamps.c --- source4/torture/util.h | 20 +++++++++---------- ...util_writetime.c => util_smb_timestamps.c} | 20 +++++++++---------- source4/torture/wscript_build | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) rename source4/torture/{util_writetime.c => util_smb_timestamps.c} (96%) diff --git a/source4/torture/util.h b/source4/torture/util.h index 05e983453d22..f3264f86fd8b 100644 --- a/source4/torture/util.h +++ b/source4/torture/util.h @@ -107,15 +107,15 @@ NTSTATUS torture_check_privilege(struct smbcli_state *cli, const char *sid_str, const char *privilege); -bool test_delay_writetime1(struct torture_context *tctx, - double used_delay, - double normal_delay, - const char *description, - bool (*get_basic_info_cb)(void *private_data, - union smb_fileinfo *finfo), - bool (*write_data_cb)(void *private_data), - bool (*close_cb)(void *private_data, - union smb_fileinfo *finfo), - void *private_data); +bool test_smb_timestamp_writetime1(struct torture_context *tctx, + double used_delay, + double normal_delay, + const char *description, + bool (*get_basic_info_cb)(void *private_data, + union smb_fileinfo *finfo), + bool (*write_data_cb)(void *private_data), + bool (*close_cb)(void *private_data, + union smb_fileinfo *finfo), + void *private_data); #endif /* _TORTURE_UTIL_H_ */ diff --git a/source4/torture/util_writetime.c b/source4/torture/util_smb_timestamps.c similarity index 96% rename from source4/torture/util_writetime.c rename to source4/torture/util_smb_timestamps.c index 453bcd335c33..7d1c0c6c64c0 100644 --- a/source4/torture/util_writetime.c +++ b/source4/torture/util_smb_timestamps.c @@ -114,16 +114,16 @@ COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ } while (0) -bool test_delay_writetime1(struct torture_context *tctx, - double used_delay, - double normal_delay, - const char *description, - bool (*get_basic_info_cb)(void *private_data, - union smb_fileinfo *finfo), - bool (*write_data_cb)(void *private_data), - bool (*close_cb)(void *private_data, - union smb_fileinfo *finfo), - void *private_data) +bool test_smb_timestamp_writetime1(struct torture_context *tctx, + double used_delay, + double normal_delay, + const char *description, + bool (*get_basic_info_cb)(void *private_data, + union smb_fileinfo *finfo), + bool (*write_data_cb)(void *private_data), + bool (*close_cb)(void *private_data, + union smb_fileinfo *finfo), + void *private_data) { union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfoT; struct timeval before_write; diff --git a/source4/torture/wscript_build b/source4/torture/wscript_build index fb9c324da051..01f6caaec609 100644 --- a/source4/torture/wscript_build +++ b/source4/torture/wscript_build @@ -2,7 +2,7 @@ bld.SAMBA_SUBSYSTEM('TORTURE_UTIL', - source='util_smb.c util_writetime.c', + source='util_smb.c util_smb_timestamps.c', public_deps='torture popt POPT_CREDENTIALS', deps='smbclient-raw' ) -- 2.17.1 From cdd42744698edea532de52db34f6b418688a739a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 20:04:02 +0200 Subject: [PATCH 24/48] revert source4/torture/smb2/durable_open.c --- source4/torture/smb2/durable_open.c | 404 +--------------------------- 1 file changed, 1 insertion(+), 403 deletions(-) diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index 63eb7e99922a..17b3b217b56e 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -25,9 +25,8 @@ #include "libcli/smb2/smb2_calls.h" #include "../libcli/smb/smbXcli_base.h" #include "torture/torture.h" -#include "torture/util.h" #include "torture/smb2/proto.h" -#include "../lib/util/time_basic.h" +#include "../libcli/smb/smbXcli_base.h" #define CHECK_VAL(v, correct) do { \ if ((v) != (correct)) { \ @@ -2753,405 +2752,6 @@ done: return ret; } -#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \ - const uint64_t _r = 10*1000*1000; \ - NTTIME _g = (given).basic_info.out.gelem; \ - NTTIME _gr = (_g / _r) * _r; \ - NTTIME _c = (correct).basic_info.out.celem; \ - NTTIME _cr = (_c / _r) * _r; \ - bool _strict = torture_setting_bool(tctx, "strict mode", false); \ - const char *_err = NULL; \ - if (_strict && (_g cmp _c)) { \ - _err = "strict"; \ - } else if ((_g cmp _c) && (_gr cmp _cr)) { \ - /* handle filesystem without high resolution timestamps */ \ - _err = "rounded"; \ - } \ - if (_err != NULL) { \ - struct timeval _gtv; \ - struct timeval _ctv; \ - struct timeval_buf _gtvb; \ - struct timeval_buf _ctvb; \ - nttime_to_timeval(&_gtv, _g); \ - nttime_to_timeval(&_ctv, _c); \ - torture_result(tctx, TORTURE_FAIL, \ - __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \ - _err, \ - #given, #gelem, \ - timeval_str_buf(&_gtv, false, true, &_gtvb), \ - #cmp, \ - #correct, #celem, \ - timeval_str_buf(&_ctv, false, true, &_ctvb)); \ - ret = false; \ - goto done; \ - } \ -} while (0) -#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ - COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \ -} while (0) -#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ - COMPARE_WRITE_TIME_CMP(given,correct,!=) -#define COMPARE_WRITE_TIME_GREATER(given,correct) \ - COMPARE_WRITE_TIME_CMP(given,correct,<=) - -#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ - COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ -} while (0) -#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ - COMPARE_ACCESS_TIME_CMP(given,correct,!=) -#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ - COMPARE_ACCESS_TIME_CMP(given,correct,<=) - -#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ - COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ -} while (0) -#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ - COMPARE_CHANGE_TIME_CMP(given,correct,!=) -#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ - COMPARE_CHANGE_TIME_CMP(given,correct,<=) - -#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ - COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ -} while (0) -#define COMPARE_CREATE_TIME_EQUAL(given,correct) \ - COMPARE_CREATE_TIME_CMP(given,correct,!=) - -#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ - COMPARE_WRITE_TIME_EQUAL(given,correct); \ - COMPARE_CHANGE_TIME_EQUAL(given,correct); \ - COMPARE_ACCESS_TIME_EQUAL(given,correct); \ - COMPARE_CREATE_TIME_EQUAL(given,correct); \ -} while (0) - -#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ - COMPARE_WRITE_TIME_GREATER(given,correct); \ - COMPARE_CHANGE_TIME_GREATER(given,correct); \ - COMPARE_ACCESS_TIME_EQUAL(given,correct); \ - COMPARE_CREATE_TIME_EQUAL(given,correct); \ - COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ -} while (0) - -#define COMPARE_TIMES_AFTER_CLOSE(given,correct) do { \ - COMPARE_WRITE_TIME_GREATER(given,correct); \ - COMPARE_CHANGE_TIME_GREATER(given,correct); \ - COMPARE_ACCESS_TIME_GREATER(given,correct); \ - COMPARE_CREATE_TIME_EQUAL(given,correct); \ - COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ - COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ -} while (0) - -#define GET_INFO_FILE(tree, finfo) do { \ - struct timeval _atv; \ - struct timeval _wtv; \ - struct timeval_buf _atvb; \ - struct timeval_buf _wtvb; \ - NTSTATUS _status; \ - _status = smb2_getinfo_file(tree, tctx, &finfo); \ - if (!NT_STATUS_IS_OK(_status)) { \ - ret = false; \ - torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ - nt_errstr(_status)); \ - goto done; \ - } \ - nttime_to_timeval(&_atv, finfo.basic_info.out.access_time); \ - nttime_to_timeval(&_wtv, finfo.basic_info.out.write_time); \ - torture_comment(tctx, "fileinfo(%s,%s): Access(%s) Write(%s)\n", \ - #tree, #finfo, \ - timeval_str_buf(&_atv, false, true, &_atvb), \ - timeval_str_buf(&_wtv, false, true, &_wtvb)); \ -} while (0) - -#define GET_INFO_BOTH(finfo1, finfo2) do { \ - GET_INFO_FILE(tree2, finfo2); \ - GET_INFO_FILE(tree1, finfo1); \ - COMPARE_ALL_TIMES_EQUAL(finfo1, finfo2); \ -} while (0) - -#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ - NTSTATUS _status; \ - union smb_setfileinfo sfinfo; \ - sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ - sfinfo.basic_info.in.file.fnum = tfnum; \ - sfinfo.basic_info.in.create_time = 0; \ - sfinfo.basic_info.in.access_time = 0; \ - unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ - sfinfo.basic_info.in.change_time = 0; \ - sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ - _status = smb_raw_setfileinfo(tree, &sfinfo); \ - if (!NT_STATUS_IS_OK(_status)) { \ - torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ - nt_errstr(_status)); \ - ret = false; \ - goto done; \ - } \ -} while (0) -#define SET_INFO_FILE(finfo, wrtime) \ - SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) - -#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ - NTSTATUS _status; \ - union smb_setfileinfo sfinfo; \ - sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ - sfinfo.basic_info.in.file.fnum = tfnum; \ - sfinfo.basic_info.in.create_time = 0; \ - sfinfo.basic_info.in.access_time = 0; \ - unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ - sfinfo.basic_info.in.write_time += (ns); \ - sfinfo.basic_info.in.change_time = 0; \ - sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ - _status = smb_raw_setfileinfo(tree, &sfinfo); \ - if (!NT_STATUS_IS_OK(_status)) { \ - torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ - nt_errstr(_status)); \ - ret = false; \ - goto done; \ - } \ -} while (0) - -struct test_durable_open_delaywrite1_state { - struct torture_context *tctx; - struct smb2_tree *tree1; - struct smb2_tree *tree2; - struct smb2_handle *h1; - struct smb2_handle *h2; -}; - -static bool test_durable_open_delaywrite1_get_info(void *private_data, - union smb_fileinfo *finfo) -{ - struct test_durable_open_delaywrite1_state *state = - (struct test_durable_open_delaywrite1_state *)private_data; - struct torture_context *tctx = state->tctx; - union smb_fileinfo t1finfo; - union smb_fileinfo t2finfo; - bool ret = true; - - ZERO_STRUCTP(finfo); - - ZERO_STRUCT(t1finfo); - t1finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - t1finfo.basic_info.in.file.handle = *state->h1; - - ZERO_STRUCT(t2finfo); - t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - t2finfo.basic_info.in.file.handle = *state->h2; - - GET_INFO_FILE(state->tree2, t2finfo); - GET_INFO_FILE(state->tree1, t1finfo); - if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { - /* - * There was a race, get it again on handle 2, - * but then they have to match. - */ - GET_INFO_FILE(state->tree2, t2finfo); - } - COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); - - finfo->basic_info.out = t1finfo.basic_info.out; -done: - return ret; -} - -static bool test_durable_open_delaywrite1_write_data(void *private_data) -{ - struct test_durable_open_delaywrite1_state *state = - (struct test_durable_open_delaywrite1_state *)private_data; - struct torture_context *tctx = state->tctx; - struct smb2_write wr; - NTSTATUS status; - bool ret = true; - - ZERO_STRUCT(wr); - wr.in.file.handle = *state->h1; - wr.in.offset = 0; - wr.in.data = data_blob_const("x", 1); - status = smb2_write(state->tree1, &wr); - CHECK_STATUS(status, NT_STATUS_OK); - torture_assert_int_equal_goto(tctx, wr.out.nwritten, 1, - ret, done, "smb2_write"); - -done: - return ret; -} - -static bool test_durable_open_delaywrite1_close(void *private_data, - union smb_fileinfo *finfo) -{ - struct test_durable_open_delaywrite1_state *state = - (struct test_durable_open_delaywrite1_state *)private_data; - struct torture_context *tctx = state->tctx; - union smb_fileinfo t1finfoCL; - union smb_fileinfo t2finfoCL; - struct smb2_close cl1; - struct smb2_close cl2; - union smb_fileinfo t2finfo; - NTSTATUS status; - bool ret = true; - - ZERO_STRUCTP(finfo); - - ZERO_STRUCT(cl1); - cl1.in.file.handle = *state->h1; - cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; - status = smb2_close(state->tree1, &cl1); - CHECK_STATUS(status, NT_STATUS_OK); - state->h1 = NULL; - ZERO_STRUCT(t1finfoCL); - t1finfoCL.basic_info.out.create_time = cl1.out.create_time; - t1finfoCL.basic_info.out.access_time = cl1.out.access_time; - t1finfoCL.basic_info.out.write_time = cl1.out.write_time; - t1finfoCL.basic_info.out.change_time = cl1.out.change_time; - t1finfoCL.basic_info.out.attrib = cl1.out.file_attr; - - ZERO_STRUCT(t2finfo); - t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - t2finfo.basic_info.in.file.handle = *state->h2; - - GET_INFO_FILE(state->tree2, t2finfo); - COMPARE_ALL_TIMES_EQUAL(t2finfo, t1finfoCL); - - ZERO_STRUCT(cl2); - cl2.in.file.handle = *state->h2; - cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; - status = smb2_close(state->tree2, &cl2); - CHECK_STATUS(status, NT_STATUS_OK); - state->h2 = NULL; - ZERO_STRUCT(t2finfoCL); - t2finfoCL.basic_info.out.create_time = cl2.out.create_time; - t2finfoCL.basic_info.out.access_time = cl2.out.access_time; - t2finfoCL.basic_info.out.write_time = cl2.out.write_time; - t2finfoCL.basic_info.out.change_time = cl2.out.change_time; - t2finfoCL.basic_info.out.attrib = cl2.out.file_attr; - COMPARE_ALL_TIMES_EQUAL(t2finfoCL, t1finfoCL); - - finfo->basic_info.out = t1finfoCL.basic_info.out; - -done: - return ret; -} - -static bool test_durable_open_delaywrite1(struct torture_context *tctx, - struct smb2_tree *tree1, - struct smb2_tree *tree2) -{ - struct test_durable_open_delaywrite1_state state = { - .tctx = tctx, - .tree1 = tree1, - .tree2 = tree2, - }; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(tctx); - char fname[256]; - struct smb2_handle _h1; - struct smb2_handle _h2; - struct smb2_create cr1; - struct smb2_create cr2; - union smb_fileinfo c1finfoCR, c1finfo0; - union smb_fileinfo c2finfoCR, c2finfo0; - //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - double normal_delay = 1000000; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); - //double normal_delay = 1000000; - //int normal_delay = 2000000; - bool ret = true; - bool ok; - - /* Choose a random name in case the state is left a little funky. */ - snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", - generate_random_str(tctx, 8)); - - smb2_util_unlink(tree1, fname); - - smb2_oplock_create_share(&cr1, fname, - smb2_util_share_access(""), - smb2_util_oplock_level("b")); - cr1.in.durable_open = true; - - status = smb2_create(tree1, mem_ctx, &cr1); - CHECK_STATUS(status, NT_STATUS_OK); - _h1 = cr1.out.file.handle; - state.h1 = &_h1; - CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); - CHECK_VAL(cr1.out.durable_open, true); - CHECK_VAL(cr1.out.durable_open_v2, false); - CHECK_VAL(cr1.out.persistent_open, false); - - cr2 = cr1; - cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE; - cr2.in.durable_open = false; - cr2.in.oplock_level = 0; - cr2.in.create_disposition = NTCREATEX_DISP_OPEN; - status = smb2_create(tree2, mem_ctx, &cr2); - CHECK_STATUS(status, NT_STATUS_OK); - _h2 = cr2.out.file.handle; - state.h2 = &_h2; - CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); - CHECK_VAL(cr2.out.oplock_level, 0); - CHECK_VAL(cr2.out.durable_open, false); - CHECK_VAL(cr2.out.durable_open_v2, false); - CHECK_VAL(cr2.out.persistent_open, false); - - ZERO_STRUCT(c1finfoCR); - c1finfoCR.basic_info.out.create_time = cr1.out.create_time; - c1finfoCR.basic_info.out.access_time = cr1.out.access_time; - c1finfoCR.basic_info.out.write_time = cr1.out.write_time; - c1finfoCR.basic_info.out.change_time = cr1.out.change_time; - c1finfoCR.basic_info.out.attrib = cr1.out.file_attr; - - ZERO_STRUCT(c2finfoCR); - c2finfoCR.basic_info.out.create_time = cr2.out.create_time; - c2finfoCR.basic_info.out.access_time = cr2.out.access_time; - c2finfoCR.basic_info.out.write_time = cr2.out.write_time; - c2finfoCR.basic_info.out.change_time = cr2.out.change_time; - c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; - - COMPARE_ALL_TIMES_EQUAL(c1finfoCR, c2finfoCR); - - ZERO_STRUCT(c1finfo0); - c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - c1finfo0.basic_info.in.file.handle = *state.h1; - - ZERO_STRUCT(c2finfo0); - c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; - c2finfo0.basic_info.in.file.handle = *state.h2; - - GET_INFO_BOTH(c1finfo0, c2finfo0); - COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); - - ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run1", - test_durable_open_delaywrite1_get_info, - test_durable_open_delaywrite1_write_data, - NULL, /* close_cb */ - &state); - torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); - ok = test_delay_writetime1(tctx, used_delay, normal_delay, - "run2", - test_durable_open_delaywrite1_get_info, - test_durable_open_delaywrite1_write_data, - test_durable_open_delaywrite1_close, - &state); - torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); - -done: - if (state.h1 != NULL) { - smb2_util_close(tree1, *state.h1); - } - if (state.h2 != NULL) { - smb2_util_close(tree2, *state.h2); - } - - smb2_util_unlink(tree1, fname); - - talloc_free(tree1); - talloc_free(tree2); - - talloc_free(mem_ctx); - - return ret; -} struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx) { @@ -3187,8 +2787,6 @@ struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx) test_durable_open_alloc_size); torture_suite_add_1smb2_test(suite, "read-only", test_durable_open_read_only); - torture_suite_add_2smb2_test(suite, "delaywrite1", - test_durable_open_delaywrite1); suite->description = talloc_strdup(suite, "SMB2-DURABLE-OPEN tests"); -- 2.17.1 From 9c7d557e449d94e950d0b60ad2f52a0dd33bc7e8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 20:07:18 +0200 Subject: [PATCH 25/48] sq test_delaywrite_delaywrite1 source4/torture/basic/delaywrite.c --- source4/torture/basic/delaywrite.c | 38 ++++++++++++++---------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 5b4fbc2b6e3b..1c11c9e26f89 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -3277,48 +3277,46 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, }; const char *fname = BASEDIR "\\torture_file3.txt"; bool ret = true; - //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); double normal_delay = 1000000; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); - //double normal_delay = 1000000; - //int normal_delay = 2000000; + double used_delay; bool ok; + used_delay = torture_setting_int(tctx, "writetimeupdatedelay", + normal_delay); + torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); - torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); + torture_assert(tctx, torture_setup_dir(cli, BASEDIR), + "Failed to setup up test directory: " BASEDIR); torture_comment(tctx, "Open the file handle\n"); state.fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); - if (state.fnum1 == -1) { - ret = false; - torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); - goto done; - } + torture_assert_int_not_equal_goto(tctx, state.fnum1, -1, + ret, done, + "unable to open fnum1"); state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); - if (state.fnum2 == -1) { - ret = false; - torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); - goto done; - } + torture_assert_int_not_equal_goto(tctx, state.fnum2, -1, + ret, done, + "unable to open fnum2"); state.fname = fname; - ok = test_delay_writetime1(tctx, used_delay, normal_delay, + ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, "run1", test_delaywrite_delaywrite1_get_info, test_delaywrite_delaywrite1_write_data, NULL, /* close_cb */ &state); - torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); - ok = test_delay_writetime1(tctx, used_delay, normal_delay, + torture_assert_goto(tctx, ok, ret, done, + "test_smb_timestamp_writetime1(1)"); + ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, "run2", test_delaywrite_delaywrite1_get_info, test_delaywrite_delaywrite1_write_data, test_delaywrite_delaywrite1_close, &state); - torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); + torture_assert_goto(tctx, ok, ret, done, + "test_smb_timestamp_writetime1(2)"); done: if (state.fnum1 != -1) { -- 2.17.1 From 67f9b259996c887158637dff8f5dc7e1d2f3e58d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 20:07:43 +0200 Subject: [PATCH 26/48] sq test_durable_open_delaywrite1 source4/torture/smb2/timestamps.c --- source4/torture/smb2/timestamps.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c index 44c7e9dab6e1..4cafec889a8d 100644 --- a/source4/torture/smb2/timestamps.c +++ b/source4/torture/smb2/timestamps.c @@ -389,20 +389,22 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, GET_INFO_BOTH(c1finfo0, c2finfo0); COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); - ok = test_delay_writetime1(tctx, used_delay, normal_delay, + ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, "run1", test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, NULL, /* close_cb */ &state); - torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); - ok = test_delay_writetime1(tctx, used_delay, normal_delay, + torture_assert_goto(tctx, ok, ret, done, + "test_smb_timestamp_writetime1(1)"); + ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, "run2", test_durable_open_delaywrite1_get_info, test_durable_open_delaywrite1_write_data, test_durable_open_delaywrite1_close, &state); - torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); + torture_assert_goto(tctx, ok, ret, done, + "test_smb_timestamp_writetime1(2)"); done: if (state.h1 != NULL) { -- 2.17.1 From ed114c60c63f8ae3ec6af3338a49a6c7e010a9a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 20:08:25 +0200 Subject: [PATCH 27/48] Revert "break test_delayed_write_update with a PATHINFO call..." This reverts commit 713123bda5075672afcb211a6742950ad968b146. --- source4/torture/basic/delaywrite.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 1c11c9e26f89..4008df680eaa 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -37,7 +37,6 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcli_state *cli) { union smb_fileinfo finfo1, finfo2; - union smb_fileinfo pinfo1; const char *fname = BASEDIR "\\torture_file.txt"; NTSTATUS status; int fnum1 = -1; @@ -72,11 +71,6 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl torture_assert_int_equal(tctx, written, 1, "unexpected number of bytes written"); - pinfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO; - pinfo1.basic_info.in.file.path = fname; - status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); - torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); - start = timeval_current(); end = timeval_add(&start, (120 * sec), 0); while (!timeval_expired(&end)) { -- 2.17.1 From 65d9404157c0d17cc8ca188c9ec26ce6d9750f36 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 20:09:31 +0200 Subject: [PATCH 28/48] revert test_delayed_write_update3 --- source4/torture/basic/delaywrite.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 4008df680eaa..6f5bd2a8b6a9 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -1411,8 +1411,6 @@ static bool test_delayed_write_update3(struct torture_context *tctx, struct timeval start; struct timeval end; double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - //int normal_delay = 1000000; int normal_delay = 2000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -1466,7 +1464,7 @@ static bool test_delayed_write_update3(struct torture_context *tctx, if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { double diff = timeval_elapsed(&start); if (diff < (used_delay / (double)1000000)) { - torture_result(tctx, TORTURE_FAIL, "111Server updated write_time after %.2f seconds " + torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " "(write time update delay == %.2f) (wrong!)\n", diff, used_delay / (double)1000000); ret = false; -- 2.17.1 From 52063482e2a5ad1fd7a8abccbf7aff8d8fa631f3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 20:11:42 +0200 Subject: [PATCH 29/48] sq source4/torture/smb2/timestamps.c --- source4/torture/smb2/timestamps.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c index 4cafec889a8d..55c6b1694226 100644 --- a/source4/torture/smb2/timestamps.c +++ b/source4/torture/smb2/timestamps.c @@ -317,15 +317,14 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, struct smb2_create cr2; union smb_fileinfo c1finfoCR, c1finfo0; union smb_fileinfo c2finfoCR, c2finfo0; - //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); double normal_delay = 1000000; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); - //double normal_delay = 1000000; - //int normal_delay = 2000000; + double used_delay; bool ret = true; bool ok; + used_delay = torture_setting_int(tctx, "writetimeupdatedelay", + normal_delay); + /* Choose a random name in case the state is left a little funky. */ snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", generate_random_str(tctx, 8)); -- 2.17.1 From b48f60349c5552c415db18ab4ffccc52c2822f49 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 20:22:07 +0200 Subject: [PATCH 30/48] sq test_smb_timestamp_writetime1 source4/torture/util_smb_timestamps.c --- source4/torture/util_smb_timestamps.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source4/torture/util_smb_timestamps.c b/source4/torture/util_smb_timestamps.c index 7d1c0c6c64c0..9d007a542ac7 100644 --- a/source4/torture/util_smb_timestamps.c +++ b/source4/torture/util_smb_timestamps.c @@ -199,7 +199,6 @@ bool test_smb_timestamp_writetime1(struct torture_context *tctx, } COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); - //smb_msleep(0.01 * msec); smb_msleep(1 * msec); } @@ -239,8 +238,6 @@ bool test_smb_timestamp_writetime1(struct torture_context *tctx, struct timeval before_get; struct timeval after_get; - smb_msleep(0.01 * msec); - torture_comment(tctx, "Wait for change\n"); before_get = timeval_current(); ok = get_basic_info_cb(private_data, &finfoT); @@ -272,6 +269,8 @@ bool test_smb_timestamp_writetime1(struct torture_context *tctx, ok = write_data_cb(private_data); after_last_write = timeval_current(); torture_assert(tctx, ok, "write_data_cb"); + + smb_msleep(0.01 * msec); } before_write = before_last_write; -- 2.17.1 From 682c0b0d335caa44a7e2202083dfa4e2f087c422 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 21:11:39 +0200 Subject: [PATCH 31/48] sq source4/torture/smb2/timestamps.c --- source4/torture/smb2/timestamps.c | 118 ++++++++++-------------------- 1 file changed, 40 insertions(+), 78 deletions(-) diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c index 55c6b1694226..259075ebc00a 100644 --- a/source4/torture/smb2/timestamps.c +++ b/source4/torture/smb2/timestamps.c @@ -39,8 +39,6 @@ #define CHECK_CREATED(__io, __created, __attribute) \ do { \ CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \ - CHECK_VAL((__io)->out.alloc_size, 0); \ - CHECK_VAL((__io)->out.size, 0); \ CHECK_VAL((__io)->out.file_attr, (__attribute)); \ CHECK_VAL((__io)->out.reserved2, 0); \ } while(0) @@ -109,11 +107,19 @@ COMPARE_CREATE_TIME_EQUAL(given,correct); \ } while (0) +#define DEBUG_BASIC_INFO(finfo, comment) do { \ + struct timeval atv; \ + struct timeval wtv; \ + struct timeval_buf atvb; \ + struct timeval_buf wtvb; \ + nttime_to_timeval(&atv, finfo.basic_info.out.access_time); \ + nttime_to_timeval(&wtv, finfo.basic_info.out.write_time); \ + torture_comment(tctx, "%s: Access(%s) Write(%s)\n", \ + comment, \ + timeval_str_buf(&atv, false, true, &atvb), \ + timeval_str_buf(&wtv, false, true, &wtvb)); \ +} while (0) #define GET_INFO_FILE(tree, finfo) do { \ - struct timeval _atv; \ - struct timeval _wtv; \ - struct timeval_buf _atvb; \ - struct timeval_buf _wtvb; \ NTSTATUS _status; \ _status = smb2_getinfo_file(tree, tctx, &finfo); \ if (!NT_STATUS_IS_OK(_status)) { \ @@ -122,12 +128,7 @@ nt_errstr(_status)); \ goto done; \ } \ - nttime_to_timeval(&_atv, finfo.basic_info.out.access_time); \ - nttime_to_timeval(&_wtv, finfo.basic_info.out.write_time); \ - torture_comment(tctx, "fileinfo(%s,%s): Access(%s) Write(%s)\n", \ - #tree, #finfo, \ - timeval_str_buf(&_atv, false, true, &_atvb), \ - timeval_str_buf(&_wtv, false, true, &_wtvb)); \ + DEBUG_BASIC_INFO(finfo, "fileinfo(" #tree ")"); \ } while (0) #define GET_INFO_BOTH(finfo1, finfo2) do { \ @@ -136,48 +137,7 @@ COMPARE_ALL_TIMES_EQUAL(finfo1, finfo2); \ } while (0) -#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ - NTSTATUS _status; \ - union smb_setfileinfo sfinfo; \ - sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ - sfinfo.basic_info.in.file.fnum = tfnum; \ - sfinfo.basic_info.in.create_time = 0; \ - sfinfo.basic_info.in.access_time = 0; \ - unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ - sfinfo.basic_info.in.change_time = 0; \ - sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ - _status = smb_raw_setfileinfo(tree, &sfinfo); \ - if (!NT_STATUS_IS_OK(_status)) { \ - torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ - nt_errstr(_status)); \ - ret = false; \ - goto done; \ - } \ -} while (0) -#define SET_INFO_FILE(finfo, wrtime) \ - SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) - -#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ - NTSTATUS _status; \ - union smb_setfileinfo sfinfo; \ - sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ - sfinfo.basic_info.in.file.fnum = tfnum; \ - sfinfo.basic_info.in.create_time = 0; \ - sfinfo.basic_info.in.access_time = 0; \ - unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ - sfinfo.basic_info.in.write_time += (ns); \ - sfinfo.basic_info.in.change_time = 0; \ - sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ - _status = smb_raw_setfileinfo(tree, &sfinfo); \ - if (!NT_STATUS_IS_OK(_status)) { \ - torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ - nt_errstr(_status)); \ - ret = false; \ - goto done; \ - } \ -} while (0) - -struct test_durable_open_delaywrite1_state { +struct test_timestamp_delaywrite1_state { struct torture_context *tctx; struct smb2_tree *tree1; struct smb2_tree *tree2; @@ -185,11 +145,11 @@ struct test_durable_open_delaywrite1_state { struct smb2_handle *h2; }; -static bool test_durable_open_delaywrite1_get_info(void *private_data, +static bool test_timestamp_delaywrite1_get_info(void *private_data, union smb_fileinfo *finfo) { - struct test_durable_open_delaywrite1_state *state = - (struct test_durable_open_delaywrite1_state *)private_data; + struct test_timestamp_delaywrite1_state *state = + (struct test_timestamp_delaywrite1_state *)private_data; struct torture_context *tctx = state->tctx; union smb_fileinfo t1finfo; union smb_fileinfo t2finfo; @@ -221,10 +181,10 @@ done: return ret; } -static bool test_durable_open_delaywrite1_write_data(void *private_data) +static bool test_timestamp_delaywrite1_write_data(void *private_data) { - struct test_durable_open_delaywrite1_state *state = - (struct test_durable_open_delaywrite1_state *)private_data; + struct test_timestamp_delaywrite1_state *state = + (struct test_timestamp_delaywrite1_state *)private_data; struct torture_context *tctx = state->tctx; struct smb2_write wr; NTSTATUS status; @@ -243,11 +203,11 @@ done: return ret; } -static bool test_durable_open_delaywrite1_close(void *private_data, +static bool test_timestamp_delaywrite1_close(void *private_data, union smb_fileinfo *finfo) { - struct test_durable_open_delaywrite1_state *state = - (struct test_durable_open_delaywrite1_state *)private_data; + struct test_timestamp_delaywrite1_state *state = + (struct test_timestamp_delaywrite1_state *)private_data; struct torture_context *tctx = state->tctx; union smb_fileinfo t1finfoCL; union smb_fileinfo t2finfoCL; @@ -299,11 +259,13 @@ done: return ret; } -static bool test_durable_open_delaywrite1(struct torture_context *tctx, - struct smb2_tree *tree1, - struct smb2_tree *tree2) +static bool test_timestamp_delaywrite1x(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2, + const char *description, + bool reconnect) { - struct test_durable_open_delaywrite1_state state = { + struct test_timestamp_delaywrite1_state state = { .tctx = tctx, .tree1 = tree1, .tree2 = tree2, @@ -326,7 +288,7 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, normal_delay); /* Choose a random name in case the state is left a little funky. */ - snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", + snprintf(fname, 256, "%s_%s.dat", description, generate_random_str(tctx, 8)); smb2_util_unlink(tree1, fname); @@ -351,7 +313,7 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, cr2.in.durable_open = false; cr2.in.oplock_level = 0; cr2.in.create_disposition = NTCREATEX_DISP_OPEN; - status = smb2_create(tree2, mem_ctx, &cr2); + status = smb2_create(state.tree2, mem_ctx, &cr2); CHECK_STATUS(status, NT_STATUS_OK); _h2 = cr2.out.file.handle; state.h2 = &_h2; @@ -390,17 +352,17 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, "run1", - test_durable_open_delaywrite1_get_info, - test_durable_open_delaywrite1_write_data, + test_timestamp_delaywrite1_get_info, + test_timestamp_delaywrite1_write_data, NULL, /* close_cb */ &state); torture_assert_goto(tctx, ok, ret, done, "test_smb_timestamp_writetime1(1)"); ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, "run2", - test_durable_open_delaywrite1_get_info, - test_durable_open_delaywrite1_write_data, - test_durable_open_delaywrite1_close, + test_timestamp_delaywrite1_get_info, + test_timestamp_delaywrite1_write_data, + test_timestamp_delaywrite1_close, &state); torture_assert_goto(tctx, ok, ret, done, "test_smb_timestamp_writetime1(2)"); @@ -413,10 +375,10 @@ done: smb2_util_close(tree2, *state.h2); } - smb2_util_unlink(tree1, fname); + smb2_util_unlink(tree2, fname); - talloc_free(tree1); - talloc_free(tree2); + TALLOC_FREE(tree1); + TALLOC_FREE(tree2); talloc_free(mem_ctx); @@ -429,7 +391,7 @@ struct torture_suite *torture_smb2_timestamps_init(TALLOC_CTX *ctx) torture_suite_create(ctx, "timestamps"); torture_suite_add_2smb2_test(suite, "delaywrite1", - test_durable_open_delaywrite1); + test_timestamp_delaywrite1); suite->description = talloc_strdup(suite, "SMB2-TIMESTAMPS tests"); -- 2.17.1 From 846d07c8c510bcebd6547e2e5b57ffcd6c7cf0a2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 21:15:16 +0200 Subject: [PATCH 32/48] test_timestamp_delaywrite1a/b durable-reconnect --- source4/torture/smb2/timestamps.c | 84 +++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c index 259075ebc00a..2ecc203394f1 100644 --- a/source4/torture/smb2/timestamps.c +++ b/source4/torture/smb2/timestamps.c @@ -140,9 +140,12 @@ struct test_timestamp_delaywrite1_state { struct torture_context *tctx; struct smb2_tree *tree1; + struct smb2_tree **tree1ptr; struct smb2_tree *tree2; struct smb2_handle *h1; struct smb2_handle *h2; + const char *fname; + bool reconnect; }; static bool test_timestamp_delaywrite1_get_info(void *private_data, @@ -166,7 +169,56 @@ static bool test_timestamp_delaywrite1_get_info(void *private_data, t2finfo.basic_info.in.file.handle = *state->h2; GET_INFO_FILE(state->tree2, t2finfo); - GET_INFO_FILE(state->tree1, t1finfo); + if (state->reconnect) { + struct smb2_create cr; + union smb_fileinfo finfoCR; + NTSTATUS status; + struct smb2_session *session = state->tree1->session; + uint64_t previous_session_id; + struct smbcli_options options; + struct smb2_handle *h = state->h1; + bool ok; + + previous_session_id = + smb2cli_session_current_id(session->smbXcli); + options = state->tree1->session->transport->options; + + state->h1 = NULL; + *state->tree1ptr = NULL; + TALLOC_FREE(state->tree1); + + ok = torture_smb2_connection_ext(tctx, previous_session_id, + &options, &state->tree1); + torture_assert_goto(tctx, ok, ret, done, "could not reconnect"); + *state->tree1ptr = state->tree1; + + ZERO_STRUCT(cr); + cr.in.fname = state->fname; + cr.in.durable_handle = h; + + status = smb2_create(state->tree1, tctx, &cr); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_CREATED(&cr, EXISTED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(cr.out.oplock_level, smb2_util_oplock_level("b")); + CHECK_VAL(cr.out.durable_open, false); + CHECK_VAL(cr.out.durable_open_v2, false); + CHECK_VAL(cr.out.persistent_open, false); + *h = cr.out.file.handle; + state->h1 = h; + + ZERO_STRUCT(finfoCR); + finfoCR.basic_info.out.create_time = cr.out.create_time; + finfoCR.basic_info.out.access_time = cr.out.access_time; + finfoCR.basic_info.out.write_time = cr.out.write_time; + finfoCR.basic_info.out.change_time = cr.out.change_time; + finfoCR.basic_info.out.attrib = cr.out.file_attr; + DEBUG_BASIC_INFO(finfoCR, "durable-reconnect"); \ + + t1finfo = finfoCR; + } else { + GET_INFO_FILE(state->tree1, t1finfo); + } + if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { /* * There was a race, get it again on handle 2, @@ -268,7 +320,9 @@ static bool test_timestamp_delaywrite1x(struct torture_context *tctx, struct test_timestamp_delaywrite1_state state = { .tctx = tctx, .tree1 = tree1, + .tree1ptr = &tree1, .tree2 = tree2, + .reconnect = reconnect, }; NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); @@ -291,6 +345,8 @@ static bool test_timestamp_delaywrite1x(struct torture_context *tctx, snprintf(fname, 256, "%s_%s.dat", description, generate_random_str(tctx, 8)); + torture_comment(tctx, "START: %s on %s", description, fname); + smb2_util_unlink(tree1, fname); smb2_oplock_create_share(&cr1, fname, @@ -350,6 +406,8 @@ static bool test_timestamp_delaywrite1x(struct torture_context *tctx, GET_INFO_BOTH(c1finfo0, c2finfo0); COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); + state.fname = fname; + ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, "run1", test_timestamp_delaywrite1_get_info, @@ -385,13 +443,33 @@ done: return ret; } +static bool test_timestamp_delaywrite1a(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) +{ + return test_timestamp_delaywrite1x(tctx, tree1, tree2, + __func__, + false); /* reconnect */ +} + +static bool test_timestamp_delaywrite1b(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) +{ + return test_timestamp_delaywrite1x(tctx, tree1, tree2, + __func__, + true); /* reconnect */ +} + struct torture_suite *torture_smb2_timestamps_init(TALLOC_CTX *ctx) { struct torture_suite *suite = torture_suite_create(ctx, "timestamps"); - torture_suite_add_2smb2_test(suite, "delaywrite1", - test_timestamp_delaywrite1); + torture_suite_add_2smb2_test(suite, "delaywrite1a", + test_timestamp_delaywrite1a); + torture_suite_add_2smb2_test(suite, "delaywrite1b", + test_timestamp_delaywrite1b); suite->description = talloc_strdup(suite, "SMB2-TIMESTAMPS tests"); -- 2.17.1 From 5923ad11c0c7eabf0b19b9073ccad62a89c5cddc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Aug 2018 21:22:03 +0200 Subject: [PATCH 33/48] fix mark_file_modified for new Windows >= 2008R2 behaviour --- source3/smbd/fileio.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index c75b8a4dcef2..833b50012e2c 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -178,10 +178,8 @@ void fsp_flush_write_time_update(struct files_struct *fsp) /* Remove the timed event handler. */ TALLOC_FREE(fsp->update_write_time_event); - if (fsp->conn->sconn->client->connections->protocol >= PROTOCOL_SMB2_02) { - fsp->update_write_time_triggered = false; - fsp->update_write_time_on_close = false; - } + fsp->update_write_time_triggered = false; + fsp->update_write_time_on_close = false; } static void update_write_time_handler(struct tevent_context *ctx, @@ -291,7 +289,7 @@ void mark_file_modified(files_struct *fsp) int dosmode; if (fsp->modified) { - trigger_write_time_update(fsp); + trigger_write_time_update(fsp); return; } -- 2.17.1 From dc156af622aaaa8b04456b18e05bd076a7193b00 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Aug 2018 10:14:20 +0200 Subject: [PATCH 34/48] TODO smbd: allow durable opens together with stat opens TODO: explicit tests --- source3/locking/locking.c | 27 +++++++++++++++++++++++---- source3/locking/proto.h | 2 ++ source3/smbd/durable.c | 29 +++-------------------------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 208f7e2081d0..833734cd37fa 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -876,6 +876,29 @@ struct share_mode_entry *find_share_mode_entry( return NULL; } +struct share_mode_entry *find_share_mode_entry_durable( + struct share_mode_lock *lck, uint64_t persistent_fid) +{ + struct share_mode_data *d = lck->data; + uint32_t i; + + for (i=0; inum_share_modes; i++) { + struct share_mode_entry *e = &d->share_modes[i]; + + if (!server_id_is_disconnected(&e->pid)) { + continue; + } + if (!is_valid_share_mode_entry(e)) { + continue; + } + if (persistent_fid != e->share_file_id) { + continue; + } + return e; + } + return NULL; +} + /******************************************************************* Del the share mode of a file for this process. Return the number of entries left. @@ -901,10 +924,6 @@ bool mark_share_mode_disconnected(struct share_mode_lock *lck, { struct share_mode_entry *e; - if (lck->data->num_share_modes != 1) { - return false; - } - if (fsp->op == NULL) { return false; } diff --git a/source3/locking/proto.h b/source3/locking/proto.h index b615a4ae6d0b..1e8ae049704e 100644 --- a/source3/locking/proto.h +++ b/source3/locking/proto.h @@ -178,6 +178,8 @@ bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp, uint32_t lease_idx); struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck, files_struct *fsp); +struct share_mode_entry *find_share_mode_entry_durable( + struct share_mode_lock *lck, uint64_t persistent_fid); void remove_stale_share_mode_entries(struct share_mode_data *d); bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp); bool mark_share_mode_disconnected(struct share_mode_lock *lck, diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c index 80392e2c6dbb..2a309a2aedd2 100644 --- a/source3/smbd/durable.c +++ b/source3/smbd/durable.c @@ -617,33 +617,10 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, return NT_STATUS_INTERNAL_DB_ERROR; } - if (lck->data->num_share_modes > 1) { - /* - * It can't be durable if there is more than one handle - * on the file. - */ - DEBUG(5, ("vfs_default_durable_reconnect: more than one " - "share-mode entry - can not be durable\n")); - TALLOC_FREE(lck); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - e = &lck->data->share_modes[0]; - - if (!server_id_is_disconnected(&e->pid)) { - DEBUG(5, ("vfs_default_durable_reconnect: denying durable " - "reconnect for handle that was not marked " - "disconnected (e.g. smbd or cluster node died)\n")); - TALLOC_FREE(lck); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - if (e->share_file_id != op->global->open_persistent_id) { + e = find_share_mode_entry_durable(lck, op->global->open_persistent_id); + if (e == NULL) { DEBUG(5, ("vfs_default_durable_reconnect: denying durable " - "share_file_id changed %llu != %llu" - "(e.g. another client had opened the file)\n", - (unsigned long long)e->share_file_id, - (unsigned long long)op->global->open_persistent_id)); + "reconnect for handle - share mode not found\n")); TALLOC_FREE(lck); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } -- 2.17.1 From 9247020e0569322eeefd71ea18d7083da290bc46 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Aug 2018 10:16:46 +0200 Subject: [PATCH 35/48] s4:libcli: cleanup smbcli_deltree() We already have the 'status' of smbcli_unlink(), so we can check that directly. Signed-off-by: Stefan Metzmacher --- source4/libcli/clideltree.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index 7bce95c2a179..866b8c551388 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -99,13 +99,13 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname) /* it might be a file */ status = smbcli_unlink(tree, dname); - if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) { + if (NT_STATUS_IS_OK(status)) { return 1; } - if (NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_NAME_NOT_FOUND) || - NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_PATH_NOT_FOUND) || - NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE) || - NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_DOS(ERRDOS, ERRbadfile))) { + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) || + NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) || + NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_FILE) || + NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRbadfile))) { return 0; } if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) { -- 2.17.1 From c739ee3c7c1f61aa1fe2a7dea5123da304ac12e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Aug 2018 10:18:25 +0200 Subject: [PATCH 36/48] sq smb2.timestamps --- selftest/skip | 1 + source3/selftest/tests.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/selftest/skip b/selftest/skip index dd60ab5a1fbe..be99bae40041 100644 --- a/selftest/skip +++ b/selftest/skip @@ -92,6 +92,7 @@ ^samba4.smb2.dir ^samba4.smb2.session ^samba4.smb2.compound +^samba4.smb2.timestamps # this is tested as 'samba3.smb2.timestamps already ^samba4.smb2.oplock.levelii501 # No test yet # SMB2 in s4 does not seem to support rename correctly ^samba4.smb2.rename.*\(ad_dc_ntvfs\)$ diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index d3c548703774..c0aa816eec28 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -435,8 +435,8 @@ vfs = ["vfs.fruit", "vfs.acl_xattr", "vfs.fruit_netatalk", "vfs.fruit_file_id", tests= base + raw + smb2 + rpc + unix + local + rap + nbt + libsmbclient + idmap + vfs for t in tests: - if t == "base.delaywrite" or t == "base.deny1" or t == "base.deny2": - plansmbtorture4testsuite(t, "fileserver", '//$SERVER/tmp -U$USERNAME%$PASSWORD --maximum-runtime=900') + if t == "base.delaywrite" or t == "base.deny1" or t == "base.deny2" or t == "smb2.timestamps": + plansmbtorture4testsuite(t, "fileserver", '//$SERVER/durable -U$USERNAME%$PASSWORD --maximum-runtime=900') elif t == "base.createx_access": plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD -k yes --maximum-runtime=900') elif t == "rap.sam": -- 2.17.1 From 0c1861a74155df13b9ac579d7ccf7e4d26fe856b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 01:50:08 +0200 Subject: [PATCH 37/48] MSG_SMB_FILE_PATHINFO --- librpc/idl/messaging.idl | 6 ++++ source3/locking/locking.c | 61 ++++++++++++++++++++++++++++++++++++--- source3/locking/proto.h | 5 ++++ source3/smbd/fileio.c | 58 ++++++++++++++++++++++++++++++++++++- source3/smbd/process.c | 2 ++ source3/smbd/proto.h | 5 ++++ source3/smbd/trans2.c | 6 +++- 7 files changed, 137 insertions(+), 6 deletions(-) diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl index c916768ccec7..2a2f67187d2f 100644 --- a/librpc/idl/messaging.idl +++ b/librpc/idl/messaging.idl @@ -110,6 +110,12 @@ interface messaging MSG_SMB_NOTIFY_REC_CHANGES = 0x031E, MSG_SMB_NOTIFY_STARTED = 0x031F, + /* + * Send to all open handles, if a + * SMB1 QUERY PATH INFO happened. + */ + MSG_SMB_FILE_PATHINFO = 0x0320, + /* winbind messages */ MSG_WINBIND_FINISHED = 0x0401, MSG_WINBIND_FORGET_STATE = 0x0402, diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 833734cd37fa..a5dec6c254d5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -600,12 +600,15 @@ bool rename_share_filename(struct messaging_context *msg_ctx, return True; } -void get_file_infos(struct file_id id, - uint32_t name_hash, - bool *delete_on_close, - struct timespec *write_time) +static void get_filepath_infos(struct file_id id, + struct messaging_context *pathinfo_msg_ctx, + uint32_t name_hash, + bool *delete_on_close, + struct timespec *write_time) { struct share_mode_lock *lck; + uint8_t msg[24] = {0, }; + uint32_t i; if (delete_on_close) { *delete_on_close = false; @@ -627,9 +630,59 @@ void get_file_infos(struct file_id id, *write_time = get_share_mode_write_time(lck); } + if (pathinfo_msg_ctx == NULL) { + TALLOC_FREE(lck); + return; + } + + push_file_id_24((char *)msg, &id); + + for (i = 0; i < lck->data->num_share_modes; i++) { + struct share_mode_entry *e = &lck->data->share_modes[i]; + + if (!is_valid_share_mode_entry(e)) { + continue; + } + + if (!serverid_exists(&e->pid)) { + continue; + } + + messaging_send_buf(pathinfo_msg_ctx, + e->pid, + MSG_SMB_FILE_PATHINFO, + msg, + sizeof(msg)); + } + TALLOC_FREE(lck); } +void get_file_infos(struct file_id id, + uint32_t name_hash, + bool *delete_on_close, + struct timespec *write_time) +{ + get_filepath_infos(id, + NULL, /* pathinfo_msg_ctx */ + name_hash, + delete_on_close, + write_time); +} + +void get_path_infos(struct file_id id, + struct messaging_context *msg_ctx, + uint32_t name_hash, + bool *delete_on_close, + struct timespec *write_time) +{ + get_filepath_infos(id, + msg_ctx, + name_hash, + delete_on_close, + write_time); +} + bool is_valid_share_mode_entry(const struct share_mode_entry *e) { int num_props = 0; diff --git a/source3/locking/proto.h b/source3/locking/proto.h index 1e8ae049704e..d06144f9f0bf 100644 --- a/source3/locking/proto.h +++ b/source3/locking/proto.h @@ -171,6 +171,11 @@ void get_file_infos(struct file_id id, uint32_t name_hash, bool *delete_on_close, struct timespec *write_time); +void get_path_infos(struct file_id id, + struct messaging_context *msg_ctx, + uint32_t name_hash, + bool *delete_on_close, + struct timespec *write_time); bool is_valid_share_mode_entry(const struct share_mode_entry *e); bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx); bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp, diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 833b50012e2c..d83efde6abb0 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -271,7 +271,7 @@ void trigger_write_time_update_immediate(struct files_struct *fsp) fsp_str_dbg(fsp))); /* After an immediate update, reset the trigger. */ - fsp->update_write_time_triggered = true; + fsp->update_write_time_triggered = true; // TODO: false??? fsp->update_write_time_on_close = false; ZERO_STRUCT(ft); @@ -316,6 +316,62 @@ void mark_file_modified(files_struct *fsp) dosmode | FILE_ATTRIBUTE_ARCHIVE, NULL, false); } +/**************************************************************************** + Receive notification that someone did a SMB1 QueryPathInfo on the file. + This changes the write time update behaviour on open handles. +****************************************************************************/ + +void msg_file_got_pathinfo(struct messaging_context *msg, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) +{ + struct smbd_server_connection *sconn = + talloc_get_type_abort(private_data, + struct smbd_server_connection); + struct files_struct *fsp = NULL; + struct file_id id; + + if (data->data == NULL || data->length != 24) { + DBG_ERR("Got invalid msg len %zu\n", data->length); + return; + } + + /* Unpack the message. */ + pull_file_id_24((char *)data->data, &id); + + DBG_DEBUG("Got PATHINFO notification file_id %s\n", + file_id_string_tos(&id)); + + for(fsp = file_find_di_first(sconn, id); fsp; + fsp = file_find_di_next(fsp)) { + + if (fsp->write_time_forced) { + /* + * No point - "sticky" write times + * in effect. + */ + continue; + } + + if (!fsp->update_write_time_triggered) { + /* + * No write time update pending. + */ + continue; + } + + /* + * We cancel the timer, which means the write time update + * will happen on close. + */ + DBG_INFO("Defer write time updates to close on %s\n", + fsp_str_dbg(fsp)); + TALLOC_FREE(fsp->update_write_time_event); + } +} + /**************************************************************************** Write to a file. ****************************************************************************/ diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 35b5f4df385d..c67d7eef7d5e 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -4092,6 +4092,8 @@ void smbd_process(struct tevent_context *ev_ctx, MSG_SMB_CLOSE_FILE, msg_close_file); messaging_register(sconn->msg_ctx, sconn, MSG_SMB_FILE_RENAME, msg_file_was_renamed); + messaging_register(sconn->msg_ctx, sconn, + MSG_SMB_FILE_PATHINFO, msg_file_got_pathinfo); id_cache_register_msgs(sconn->msg_ctx); messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL); diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 2a41d9d251dd..45e39e9df37c 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -332,6 +332,11 @@ ssize_t read_file(files_struct *fsp,char *data,off_t pos,size_t n); void fsp_flush_write_time_update(struct files_struct *fsp); void trigger_write_time_update(struct files_struct *fsp); void trigger_write_time_update_immediate(struct files_struct *fsp); +void msg_file_got_pathinfo(struct messaging_context *msg, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data); void mark_file_modified(files_struct *fsp); ssize_t write_file(struct smb_request *req, files_struct *fsp, diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 0ec20fe6337f..a9d413bf3c3b 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -5982,7 +5982,11 @@ static void call_trans2qfilepathinfo(connection_struct *conn, } fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); - get_file_infos(fileid, name_hash, &delete_pending, &write_time_ts); + get_path_infos(fileid, + req->sconn->msg_ctx, + name_hash, + &delete_pending, + &write_time_ts); if (delete_pending) { reply_nterror(req, NT_STATUS_DELETE_PENDING); return; -- 2.17.1 From 8d751a927ea95c7b9d1ae013237cdb1a049b7d1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 01:50:41 +0200 Subject: [PATCH 38/48] HACK w2k behaviour --- source3/include/vfs.h | 2 ++ source3/smbd/fileio.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 4f3db6948964..efc9a99cdaf3 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -334,6 +334,8 @@ typedef struct files_struct { bool kernel_share_modes_taken; bool update_write_time_triggered; + uint64_t num_write_time_updates; + bool got_query_path_info; struct tevent_timer *update_write_time_event; bool update_write_time_on_close; struct timespec close_write_time; diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index d83efde6abb0..9448ebe5d08c 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -178,8 +178,10 @@ void fsp_flush_write_time_update(struct files_struct *fsp) /* Remove the timed event handler. */ TALLOC_FREE(fsp->update_write_time_event); + if (!fsp->got_query_path_info) { fsp->update_write_time_triggered = false; fsp->update_write_time_on_close = false; + } } static void update_write_time_handler(struct tevent_context *ctx, @@ -226,6 +228,7 @@ void trigger_write_time_update(struct files_struct *fsp) return; } fsp->update_write_time_triggered = true; + fsp->num_write_time_updates++; delay = lp_parm_int(SNUM(fsp->conn), "smbd", "writetimeupdatedelay", @@ -362,6 +365,12 @@ void msg_file_got_pathinfo(struct messaging_context *msg, continue; } + fsp->got_query_path_info = true; + + if (fsp->num_write_time_updates == 1) { + continue; + } + /* * We cancel the timer, which means the write time update * will happen on close. -- 2.17.1 From 17c5d23284509ee2e70fc1bc642cbcbd75b8da49 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 01:50:54 +0200 Subject: [PATCH 39/48] Revert "HACK w2k behaviour" This reverts commit 8d751a927ea95c7b9d1ae013237cdb1a049b7d1a. --- source3/include/vfs.h | 2 -- source3/smbd/fileio.c | 9 --------- 2 files changed, 11 deletions(-) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index efc9a99cdaf3..4f3db6948964 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -334,8 +334,6 @@ typedef struct files_struct { bool kernel_share_modes_taken; bool update_write_time_triggered; - uint64_t num_write_time_updates; - bool got_query_path_info; struct tevent_timer *update_write_time_event; bool update_write_time_on_close; struct timespec close_write_time; diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 9448ebe5d08c..d83efde6abb0 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -178,10 +178,8 @@ void fsp_flush_write_time_update(struct files_struct *fsp) /* Remove the timed event handler. */ TALLOC_FREE(fsp->update_write_time_event); - if (!fsp->got_query_path_info) { fsp->update_write_time_triggered = false; fsp->update_write_time_on_close = false; - } } static void update_write_time_handler(struct tevent_context *ctx, @@ -228,7 +226,6 @@ void trigger_write_time_update(struct files_struct *fsp) return; } fsp->update_write_time_triggered = true; - fsp->num_write_time_updates++; delay = lp_parm_int(SNUM(fsp->conn), "smbd", "writetimeupdatedelay", @@ -365,12 +362,6 @@ void msg_file_got_pathinfo(struct messaging_context *msg, continue; } - fsp->got_query_path_info = true; - - if (fsp->num_write_time_updates == 1) { - continue; - } - /* * We cancel the timer, which means the write time update * will happen on close. -- 2.17.1 From 092f769e1c75012a51949694da06e3c31f33198e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 01:51:28 +0200 Subject: [PATCH 40/48] test_delayed_write_update4 HACKS ... --- source4/torture/basic/delaywrite.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 6f5bd2a8b6a9..7b981b06e5ef 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -2143,8 +2143,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -2187,7 +2187,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, goto done; } - GET_INFO_BOTH(finfo1,pinfo1); + //GET_INFO_BOTH(finfo1,pinfo1); + GET_INFO_FILE(finfo1); COMPARE_WRITE_TIME_EQUAL(finfo1,finfo0); /* @@ -2219,8 +2220,9 @@ static bool test_delayed_write_update4(struct torture_context *tctx, smb_msleep(0.5 * msec); } - GET_INFO_BOTH(finfo1,pinfo1); - COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); + //GET_INFO_BOTH(finfo1,pinfo1); + GET_INFO_FILE(finfo1); + COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); /* sure any further write doesn't update the write time */ start = timeval_current(); @@ -2248,7 +2250,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, smb_msleep(1 * msec); } - GET_INFO_BOTH(finfo2,pinfo2); + //GET_INFO_BOTH(finfo2,pinfo2); + GET_INFO_FILE(finfo2); COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { torture_comment(tctx, "Server did not updatewrite_time (correct)\n"); @@ -2257,7 +2260,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, /* sleep */ smb_msleep(5 * msec); - GET_INFO_BOTH(finfo3,pinfo3); + //GET_INFO_BOTH(finfo3,pinfo3); + GET_INFO_FILE(finfo3); COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); /* -- 2.17.1 From 9995e9e6023c70d5fb9b5789cb70b5621978d238 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 01:51:46 +0200 Subject: [PATCH 41/48] Revert "test_delayed_write_update4 HACKS ..." This reverts commit 092f769e1c75012a51949694da06e3c31f33198e. --- source4/torture/basic/delaywrite.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 7b981b06e5ef..6f5bd2a8b6a9 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -2143,8 +2143,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + int normal_delay = 2000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -2187,8 +2187,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx, goto done; } - //GET_INFO_BOTH(finfo1,pinfo1); - GET_INFO_FILE(finfo1); + GET_INFO_BOTH(finfo1,pinfo1); COMPARE_WRITE_TIME_EQUAL(finfo1,finfo0); /* @@ -2220,9 +2219,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, smb_msleep(0.5 * msec); } - //GET_INFO_BOTH(finfo1,pinfo1); - GET_INFO_FILE(finfo1); - COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); + GET_INFO_BOTH(finfo1,pinfo1); + COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); /* sure any further write doesn't update the write time */ start = timeval_current(); @@ -2250,8 +2248,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx, smb_msleep(1 * msec); } - //GET_INFO_BOTH(finfo2,pinfo2); - GET_INFO_FILE(finfo2); + GET_INFO_BOTH(finfo2,pinfo2); COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { torture_comment(tctx, "Server did not updatewrite_time (correct)\n"); @@ -2260,8 +2257,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx, /* sleep */ smb_msleep(5 * msec); - //GET_INFO_BOTH(finfo3,pinfo3); - GET_INFO_FILE(finfo3); + GET_INFO_BOTH(finfo3,pinfo3); COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); /* -- 2.17.1 From 09f914311f1597068a06c248d4ba335c2ecdc10e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 02:24:52 +0200 Subject: [PATCH 42/48] modern and legacy delaywrite => legacy works against w2k legacy lower time to 1 sec? --- source4/torture/basic/base.c | 3 ++- source4/torture/basic/delaywrite.c | 32 ++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c index 314e8f2d131f..43b46d89a22a 100644 --- a/source4/torture/basic/base.c +++ b/source4/torture/basic/base.c @@ -1972,7 +1972,8 @@ NTSTATUS torture_base_init(TALLOC_CTX *ctx) torture_suite_add_1smb_test(suite, "chkpath", torture_chkpath_test); torture_suite_add_1smb_test(suite, "secleak", torture_sec_leak); torture_suite_add_simple_test(suite, "disconnect", torture_disconnect); - torture_suite_add_suite(suite, torture_delay_write(suite)); + torture_suite_add_suite(suite, torture_delay_write_modern(suite)); + torture_suite_add_suite(suite, torture_delay_write_legacy(suite)); torture_suite_add_simple_test(suite, "samba3error", torture_samba3_errorpaths); torture_suite_add_1smb_test(suite, "casetable", torture_casetable); torture_suite_add_1smb_test(suite, "utable", torture_utable); diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 6f5bd2a8b6a9..be75533243d1 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -3326,9 +3326,9 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, /* testing of delayed update of write_time */ -struct torture_suite *torture_delay_write(TALLOC_CTX *ctx) +struct torture_suite *torture_delay_write_modern(TALLOC_CTX *ctx) { - struct torture_suite *suite = torture_suite_create(ctx, "delaywrite"); + struct torture_suite *suite = torture_suite_create(ctx, "delaywrite-modern"); torture_suite_add_2smb_test(suite, "finfo update on close", test_finfo_after_write); torture_suite_add_1smb_test(suite, "delayed update of write time", test_delayed_write_update); @@ -3349,5 +3349,33 @@ struct torture_suite *torture_delay_write(TALLOC_CTX *ctx) torture_suite_add_1smb_test(suite, "directory timestamp update test", test_directory_update8); torture_suite_add_2smb_test(suite, "delaywrite1", test_delaywrite_delaywrite1); + suite->description = talloc_strdup(suite, "SMB1-DELAYWRITE tests modern >= w2k8r2 behaviour"); + + return suite; +} +struct torture_suite *torture_delay_write_legacy(TALLOC_CTX *ctx) +{ + struct torture_suite *suite = torture_suite_create(ctx, "delaywrite-legacy"); + + torture_suite_add_2smb_test(suite, "finfo update on close", test_finfo_after_write); + torture_suite_add_1smb_test(suite, "delayed update of write time", test_delayed_write_update); + torture_suite_add_1smb_test(suite, "update of write time and SMBwrite truncate", test_delayed_write_update1); + torture_suite_add_1smb_test(suite, "update of write time and SMBwrite truncate expand", test_delayed_write_update1a); + torture_suite_add_1smb_test(suite, "update of write time using SET_END_OF_FILE", test_delayed_write_update1b); + torture_suite_add_1smb_test(suite, "update of write time using SET_ALLOCATION_SIZE", test_delayed_write_update1c); + torture_suite_add_2smb_test(suite, "delayed update of write time using 2 connections", test_delayed_write_update2); + torture_suite_add_2smb_test(suite, "delayed update of write time 3", test_delayed_write_update3); + torture_suite_add_2smb_test(suite, "delayed update of write time 3a", test_delayed_write_update3a); + torture_suite_add_2smb_test(suite, "delayed update of write time 3b", test_delayed_write_update3b); + torture_suite_add_2smb_test(suite, "delayed update of write time 3c", test_delayed_write_update3c); + torture_suite_add_2smb_test(suite, "delayed update of write time 4", test_delayed_write_update4); + torture_suite_add_2smb_test(suite, "delayed update of write time 5", test_delayed_write_update5); + torture_suite_add_2smb_test(suite, "delayed update of write time 5b", test_delayed_write_update5b); + torture_suite_add_2smb_test(suite, "delayed update of write time 6", test_delayed_write_update6); + torture_suite_add_1smb_test(suite, "timestamp resolution test", test_delayed_write_update7); + torture_suite_add_1smb_test(suite, "directory timestamp update test", test_directory_update8); + + suite->description = talloc_strdup(suite, "SMB1-DELAYWRITE tests legacy w2k behaviour"); + return suite; } -- 2.17.1 From 55c8fbc733e9a1beef630e7cc3f7a300e2d1a850 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 02:24:52 +0200 Subject: [PATCH 43/48] modern and legacy delaywrite --- source4/torture/basic/delaywrite.c | 65 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index be75533243d1..42a00e30596d 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -44,8 +44,8 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -125,8 +125,8 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; char buf[2048]; @@ -291,8 +291,8 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; char buf[2048]; @@ -452,8 +452,8 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; char buf[2048]; @@ -612,8 +612,8 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; char buf[2048]; @@ -776,8 +776,8 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; union smb_flush flsh; @@ -1134,8 +1134,8 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s int fnum2; bool ret = true; ssize_t written; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -1410,8 +1410,8 @@ static bool test_delayed_write_update3(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -1562,8 +1562,8 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, int i; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -1773,8 +1773,8 @@ static bool test_delayed_write_update3b(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -1937,8 +1937,8 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, int i; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -2143,8 +2143,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -2300,8 +2300,8 @@ static bool test_delayed_write_update5(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -2460,8 +2460,8 @@ static bool test_delayed_write_update5b(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -2625,8 +2625,8 @@ static bool test_delayed_write_update6(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; bool first = true; @@ -2989,8 +2989,8 @@ static bool test_directory_update8(struct torture_context *tctx, struct smbcli_s int fnum1 = -1; int fnum2 = -1; bool ret = true; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); - int normal_delay = 2000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); + int normal_delay = 1000000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; TALLOC_CTX *mem_ctx = talloc_init("test_delayed_write_update8"); @@ -3341,7 +3341,6 @@ struct torture_suite *torture_delay_write_modern(TALLOC_CTX *ctx) torture_suite_add_2smb_test(suite, "delayed update of write time 3a", test_delayed_write_update3a); torture_suite_add_2smb_test(suite, "delayed update of write time 3b", test_delayed_write_update3b); torture_suite_add_2smb_test(suite, "delayed update of write time 3c", test_delayed_write_update3c); - torture_suite_add_2smb_test(suite, "delayed update of write time 4", test_delayed_write_update4); torture_suite_add_2smb_test(suite, "delayed update of write time 5", test_delayed_write_update5); torture_suite_add_2smb_test(suite, "delayed update of write time 5b", test_delayed_write_update5b); torture_suite_add_2smb_test(suite, "delayed update of write time 6", test_delayed_write_update6); -- 2.17.1 From 8ac8972497967262b73030b1e740996c132f34d3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 02:48:30 +0200 Subject: [PATCH 44/48] sq test_delaywrite_delaywrite1 --- source4/torture/basic/delaywrite.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 42a00e30596d..bd34dc8e2618 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -3267,7 +3267,7 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, .fnum1 = -1, .fnum2 = -1, }; - const char *fname = BASEDIR "\\torture_file3.txt"; + const char *fname = BASEDIR "\\torture_file_delaywrite1.txt"; bool ret = true; double normal_delay = 1000000; double used_delay; @@ -3276,7 +3276,7 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); - torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); + torture_comment(tctx, "\nRunning test_delaywrite_delaywrite1\n"); torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); -- 2.17.1 From b831cf95b7a42935b4d164806220e90282a05ab4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 02:57:40 +0200 Subject: [PATCH 45/48] sq modern and legacy delaywrite selftest --- source3/selftest/tests.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index c0aa816eec28..5fe962ad36e1 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -381,13 +381,15 @@ plantestsuite("samba3.async_req", "nt4_dc", #smbtorture4 tests -base = ["base.attr", "base.charset", "base.chkpath", "base.createx_access", "base.defer_open", "base.delaywrite", "base.delete", +base = ["base.attr", "base.charset", "base.chkpath", "base.createx_access", "base.defer_open", "base.delete", "base.deny1", "base.deny2", "base.deny3", "base.denydos", "base.dir1", "base.dir2", "base.disconnect", "base.fdpass", "base.lock", "base.mangle", "base.negnowait", "base.ntdeny1", "base.ntdeny2", "base.open", "base.openattr", "base.properties", "base.rename", "base.rw1", "base.secleak", "base.tcon", "base.tcondev", "base.trans2", "base.unlink", "base.vuid", - "base.xcopy", "base.samba3error"] + "base.xcopy", "base.samba3error", + "base.delaywrite-modern", + ] raw = ["raw.acls", "raw.chkpath", "raw.close", "raw.composite", "raw.context", "raw.eas", "raw.ioctl", "raw.lock", "raw.mkdir", "raw.mux", "raw.notify", "raw.open", "raw.oplock", @@ -435,7 +437,7 @@ vfs = ["vfs.fruit", "vfs.acl_xattr", "vfs.fruit_netatalk", "vfs.fruit_file_id", tests= base + raw + smb2 + rpc + unix + local + rap + nbt + libsmbclient + idmap + vfs for t in tests: - if t == "base.delaywrite" or t == "base.deny1" or t == "base.deny2" or t == "smb2.timestamps": + if t == "base.delaywrite-modern" or t == "base.deny1" or t == "base.deny2" or t == "smb2.timestamps": plansmbtorture4testsuite(t, "fileserver", '//$SERVER/durable -U$USERNAME%$PASSWORD --maximum-runtime=900') elif t == "base.createx_access": plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD -k yes --maximum-runtime=900') -- 2.17.1 From 3be8e1f8fe502ee056d505f1c8ad43c262fab07c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 11:35:41 +0200 Subject: [PATCH 46/48] TODO: smb2_server: set req->do_encryption = true earlier TODO: tests https://blogs.msdn.microsoft.com/openspecification/2012/10/05/encryption-in-smb-3-0-a-protocol-perspective/ The sender encrypts the message if any of the following conditions is satisfied: If the sender is sending a response to an encrypted request. If Session.EncryptData is TRUE and the request or response being sent is not NEGOTIATE. If Session.EncryptData is FALSE, the request or response being sent is not NEGOTIATE or SESSION_SETUP or TREE_CONNECT, and .EncryptData is TRUE. [MS-SMB2] 3.3.4.1.4 Encrypting the Message If Connection.Dialect belongs to the SMB 3.x dialect family and Connection.ClientCapabilities includes the SMB2_GLOBAL_CAP_ENCRYPTION bit, the server MUST encrypt the message before sending, if any of the following conditions are satisfied: - If the message being sent is any response to a client request for which Request.IsEncrypted is TRUE. - If Session.EncryptData is TRUE and the response being sent is not SMB2_NEGOTIATE or SMB2 SESSION_SETUP. - If Session.EncryptData is FALSE, the response being sent is not SMB2_NEGOTIATE or SMB2 SESSION_SETUP or SMB2 TREE_CONNECT, and Share.EncryptData for the share associated with the TreeId in the SMB2 header of the response is TRUE. The server MUST encrypt the message as specified in section 3.1.4.3, before sending it to the client. --- source3/smbd/smb2_server.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 229f8ab0e856..e36db1e55f5e 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -2359,7 +2359,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) req->async_internal = false; req->do_signing = false; - req->do_encryption = false; + if (opcode != SMB2_OP_SESSSETUP) { + req->do_encryption = encryption_desired; + } else { + req->do_encryption = false; + } req->was_encrypted = false; if (intf_v->iov_len == SMB2_TF_HDR_SIZE) { const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req); @@ -2383,9 +2387,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) } req->was_encrypted = true; + req->do_encryption = true; } if (encryption_required && !req->was_encrypted) { + req->do_encryption = true; return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED); } @@ -2523,8 +2529,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) encryption_required = true; } if (encryption_required && !req->was_encrypted) { + req->do_encryption = true; return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED); + } else if (encryption_desired) { + req->do_encryption = true; } } else if (call->need_session) { struct auth_session_info *session_info = NULL; @@ -2544,10 +2553,6 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) session_info->info->domain_name); } - if (req->was_encrypted || encryption_desired) { - req->do_encryption = true; - } - if (req->session) { bool update_session_global = false; bool update_tcon_global = false; -- 2.17.1 From 329ac5e104bdee2010451fa3a0455812556e9158 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 12:25:17 +0200 Subject: [PATCH 47/48] modern and legacy delaywrite => 0.5 sec delay --- source4/torture/basic/delaywrite.c | 64 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index bd34dc8e2618..b66ff09b7583 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -44,8 +44,8 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -125,8 +125,8 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; char buf[2048]; @@ -291,8 +291,8 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; char buf[2048]; @@ -452,8 +452,8 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; char buf[2048]; @@ -612,8 +612,8 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; char buf[2048]; @@ -776,8 +776,8 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; union smb_flush flsh; @@ -1134,8 +1134,8 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s int fnum2; bool ret = true; ssize_t written; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -1410,8 +1410,8 @@ static bool test_delayed_write_update3(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -1562,8 +1562,8 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, int i; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -1773,8 +1773,8 @@ static bool test_delayed_write_update3b(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -1937,8 +1937,8 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, int i; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -2143,8 +2143,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -2300,8 +2300,8 @@ static bool test_delayed_write_update5(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -2460,8 +2460,8 @@ static bool test_delayed_write_update5b(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; @@ -2625,8 +2625,8 @@ static bool test_delayed_write_update6(struct torture_context *tctx, ssize_t written; struct timeval start; struct timeval end; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; bool first = true; @@ -2989,8 +2989,8 @@ static bool test_directory_update8(struct torture_context *tctx, struct smbcli_s int fnum1 = -1; int fnum2 = -1; bool ret = true; - double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); - int normal_delay = 1000000; + double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); + int normal_delay = 500000; double sec = ((double)used_delay) / ((double)normal_delay); int msec = 1000 * sec; TALLOC_CTX *mem_ctx = talloc_init("test_delayed_write_update8"); -- 2.17.1 From 58ce7c981b96c7f84685d1e3064a535353e4eac7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Aug 2018 15:19:25 +0200 Subject: [PATCH 48/48] Output examples bin/smbtorture //172.31.9.192/torture -Uadministrator%geheim 'base.delaywrite-legacy' 2>&1 | tee out.legacy-192 bin/smbtorture //172.31.9.219/torture -Uadministrator%A1b2C3d4 'base.delaywrite-modern' 2>&1 | tee out.modern-219 bin/smbtorture //172.31.9.187/torture -Uadministrator%A1b2C3d4 'base.delaywrite-modern' 2>&1 | tee out.modern-187 172.31.9.192 is Windows 2000 SP4 172.31.9.219 is Windows 2008 R2 172.31.9.187 is Windows 2016 --- out.legacy-192 | 1086 +++++++++++++++++++++++ out.modern-187 | 2297 ++++++++++++++++++++++++++++++++++++++++++++++++ out.modern-219 | 1787 +++++++++++++++++++++++++++++++++++++ 3 files changed, 5170 insertions(+) create mode 100644 out.legacy-192 create mode 100644 out.modern-187 create mode 100644 out.modern-219 diff --git a/out.legacy-192 b/out.legacy-192 new file mode 100644 index 000000000000..b57ecf6ced32 --- /dev/null +++ b/out.legacy-192 @@ -0,0 +1,1086 @@ +smbtorture 4.10.0pre1-DEVELOPERBUILD +Using seed 1534511438 +time: 2018-08-17 13:10:38.915952 +progress: 17 +test: finfo update on close +time: 2018-08-17 13:10:38.916111 + +Running test_finfo_after_write +time: 2018-08-17 13:10:39.932646 +success: finfo update on close +test: delayed update of write time +time: 2018-08-17 13:10:39.932686 + +Running test_delayed_write_update +Initial write time Fri Aug 17 15:10:40 2018 CEST +write time Fri Aug 17 15:10:40 2018 CEST +write time Fri Aug 17 15:10:40 2018 CEST +write time Fri Aug 17 15:10:40 2018 CEST +write time Fri Aug 17 15:10:42 2018 CEST +Server updated write_time after 3.00 seconds (correct) +time: 2018-08-17 13:10:42.950208 +success: delayed update of write time +test: update of write time and SMBwrite truncate +time: 2018-08-17 13:10:42.950251 + +Running test_delayed_write_update1 +Initial write time Fri Aug 17 15:10:43 2018 CEST +write time Fri Aug 17 15:10:49 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 15:10:49 2018 CEST +write time Fri Aug 17 15:10:49 2018 CEST +write time Fri Aug 17 15:10:49 2018 CEST +write time Fri Aug 17 15:10:49 2018 CEST +write time Fri Aug 17 15:10:49 2018 CEST +write time Fri Aug 17 15:10:49 2018 CEST +write time Fri Aug 17 15:10:49 2018 CEST +write time Fri Aug 17 15:10:49 2018 CEST +write time Fri Aug 17 15:10:49 2018 CEST +write time Fri Aug 17 15:10:49 2018 CEST +Server did not update write time within 10 seconds. Good! +Server updated write time on close (correct) +time: 2018-08-17 13:11:02.988284 +success: update of write time and SMBwrite truncate +test: update of write time and SMBwrite truncate expand +time: 2018-08-17 13:11:02.988328 + +Running test_delayed_write_update1a +Initial write time Fri Aug 17 15:11:03 2018 CEST +write time Fri Aug 17 15:11:06 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 15:11:06 2018 CEST +write time Fri Aug 17 15:11:06 2018 CEST +write time Fri Aug 17 15:11:06 2018 CEST +write time Fri Aug 17 15:11:06 2018 CEST +write time Fri Aug 17 15:11:06 2018 CEST +write time Fri Aug 17 15:11:06 2018 CEST +write time Fri Aug 17 15:11:06 2018 CEST +write time Fri Aug 17 15:11:06 2018 CEST +write time Fri Aug 17 15:11:06 2018 CEST +write time Fri Aug 17 15:11:06 2018 CEST +Server did not update write time within 10 seconds. Good! +Server updated write time on close (correct) +time: 2018-08-17 13:11:18.021734 +success: update of write time and SMBwrite truncate expand +test: update of write time using SET_END_OF_FILE +time: 2018-08-17 13:11:18.021753 + +Running test_delayed_write_update1b +Initial write time Fri Aug 17 15:11:18 2018 CEST +write time Fri Aug 17 15:11:21 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 15:11:21 2018 CEST +write time Fri Aug 17 15:11:21 2018 CEST +write time Fri Aug 17 15:11:21 2018 CEST +write time Fri Aug 17 15:11:21 2018 CEST +write time Fri Aug 17 15:11:21 2018 CEST +write time Fri Aug 17 15:11:21 2018 CEST +write time Fri Aug 17 15:11:21 2018 CEST +write time Fri Aug 17 15:11:21 2018 CEST +write time Fri Aug 17 15:11:21 2018 CEST +write time Fri Aug 17 15:11:21 2018 CEST +Server did not update write time within 10 seconds. Good! +Server updated write time on close (correct) +time: 2018-08-17 13:11:33.054125 +success: update of write time using SET_END_OF_FILE +test: update of write time using SET_ALLOCATION_SIZE +time: 2018-08-17 13:11:33.054165 + +Running test_delayed_write_update1c +Initial write time Fri Aug 17 15:11:33 2018 CEST +write time Fri Aug 17 15:11:36 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 15:11:36 2018 CEST +write time Fri Aug 17 15:11:36 2018 CEST +write time Fri Aug 17 15:11:36 2018 CEST +write time Fri Aug 17 15:11:36 2018 CEST +write time Fri Aug 17 15:11:36 2018 CEST +write time Fri Aug 17 15:11:36 2018 CEST +write time Fri Aug 17 15:11:36 2018 CEST +write time Fri Aug 17 15:11:36 2018 CEST +write time Fri Aug 17 15:11:36 2018 CEST +write time Fri Aug 17 15:11:36 2018 CEST +Server did not update write time within 10 seconds. Good! +time: 2018-08-17 13:11:48.090610 +success: update of write time using SET_ALLOCATION_SIZE +test: delayed update of write time using 2 connections +time: 2018-08-17 13:11:48.090656 + +Running test_delayed_write_update2 +Initial write time Fri Aug 17 15:11:48 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +Server updated write_time (correct) +Modified write time Fri Aug 17 06:51:51 2018 CEST +Doing a 10 byte write to extend the file and see if this changes the last write time. +Doing flush after write +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +Server did not update write time (correct) +Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. +write time Fri Aug 17 06:51:51 2018 CEST +Closing the first fd to see if write time updated. +Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +write time Fri Aug 17 06:51:51 2018 CEST +Server did not update write time (correct) +Closing second fd to see if write time updated. +Second open initial write time Fri Aug 17 15:12:23 2018 CEST +Doing a 10 byte write to extend the file to see if this changes the last write time. +write time Fri Aug 17 15:12:23 2018 CEST +write time Fri Aug 17 15:12:23 2018 CEST +write time Fri Aug 17 15:12:23 2018 CEST +write time Fri Aug 17 15:12:34 2018 CEST +Server updated write_time after 2.00 seconds(correct) +time: 2018-08-17 13:12:35.189016 +success: delayed update of write time using 2 connections +test: delayed update of write time 3 +time: 2018-08-17 13:12:35.189044 + +Running test_delayed_write_update3 +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:35.102404) Write(2018/08/17 15:12:35.102404) +pathinfo(cli2->tree): Access(2018/08/17 15:12:35.102404) Write(2018/08/17 15:12:35.102404) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:35.102404) Write(2018/08/17 15:12:35.102404) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:35.102404) Write(2018/08/17 15:12:35.102404) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:35.102404) Write(2018/08/17 15:12:35.102404) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Server updated write_time after 1.51 seconds (correct) +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 15:12:56.663407) Write(2018/08/17 15:12:56.663407) +Server updated the write_time on close (correct) +time: 2018-08-17 13:12:56.760420 +success: delayed update of write time 3 +test: delayed update of write time 3a +time: 2018-08-17 13:12:56.760456 + +Running test_delayed_write_update3a +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) +pathinfo(cli2->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) +fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) +pathinfo(cli2->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:03.322983) Write(2018/08/17 15:13:03.322983) +Server updated write_time after 2.01 seconds (correct) +fileinfo(cli->tree): Access(2018/08/17 15:13:03.322983) Write(2018/08/17 15:13:03.322983) +pathinfo(cli2->tree): Access(2018/08/17 15:13:03.322983) Write(2018/08/17 15:13:03.322983) +Do a truncate SMBwrite [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:08.700716) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:08.700716) +Do a truncate SMBwrite [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:10.703596) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:10.703596) +Do a truncate SMBwrite [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) +Do a truncate SMBwrite [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:35.769639) +pathinfo(cli2->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:35.769639) +Do a truncate SMBwrite [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:37.772519) +pathinfo(cli2->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:37.772519) +Do a truncate SMBwrite [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:39.775399) +pathinfo(cli2->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:39.775399) +fileinfo(cli->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:39.775399) +pathinfo(cli2->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:39.775399) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:39.775399) +Server did not update the write_time on close (correct) +time: 2018-08-17 13:13:42.871875 +success: delayed update of write time 3a +test: delayed update of write time 3b +time: 2018-08-17 13:13:42.871895 + +Running test_delayed_write_update3b +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) +pathinfo(cli2->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) +fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) +pathinfo(cli2->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Server updated write_time after 2.01 seconds (write time update delay == 0.50) (correct) +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 15:14:09.848643) Write(2018/08/17 15:14:09.848643) +Server updated the write_time on close (correct) +time: 2018-08-17 13:14:09.951853 +success: delayed update of write time 3b +test: delayed update of write time 3c +time: 2018-08-17 13:14:09.951883 + +Running test_delayed_write_update3c +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:09.868671) +pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:09.868671) +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:09.868671) +pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:09.868671) +Do a truncate SMBwrite [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:16.878751) +pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:16.878751) +Do a truncate SMBwrite [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:18.881631) +pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:18.881631) +Do a truncate SMBwrite [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) +Do a truncate write [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:34.914686) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:34.914686) +Do a truncate write [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:36.907551) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:36.907551) +Do a truncate write [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 15:15:03.976475) Write(2018/08/17 15:15:03.976475) +Server updated the write_time on close (correct) +time: 2018-08-17 13:15:04.075559 +success: delayed update of write time 3c +test: delayed update of write time 4 +time: 2018-08-17 13:15:04.075597 + +Running test_delayed_write_update4 +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) +pathinfo(cli2->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) +pathinfo(cli2->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) +fileinfo(cli->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) +fileinfo(cli->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) +fileinfo(cli->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Server updated write_time after 1.51 seconds (write time update delay == 0.50) (correct) +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Server did not updatewrite_time (correct) +fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.554692) Write(2018/08/17 15:15:30.554692) +Server updated the write_time on close (correct) +time: 2018-08-17 13:15:30.655585 +success: delayed update of write time 4 +test: delayed update of write time 5 +time: 2018-08-17 13:15:30.655608 + +Running test_delayed_write_update5 +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/17 15:15:30.574721) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/17 15:15:30.574721) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/17 15:15:30.574721) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/17 15:15:30.574721) +Set write time in the future on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/18 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/18 15:15:30.000000) +Set write time in the past on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Server did not update write_time (correct) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.665179) Write(2018/08/16 15:15:30.000000) +Server did not update the write_time on close (correct) +time: 2018-08-17 13:16:05.765388 +success: delayed update of write time 5 +test: delayed update of write time 5b +time: 2018-08-17 13:16:05.765418 + +Running test_delayed_write_update5b +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/17 15:16:05.685207) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/17 15:16:05.685207) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/17 15:16:05.685207) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/17 15:16:05.685207) +Set write time in the future on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/18 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/18 15:16:05.000000) +Set write time in the past on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Server did not update write_time (correct) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) +Server did not update the write_time on close (correct) +time: 2018-08-17 13:16:40.866349 +success: delayed update of write time 5b +test: delayed update of write time 6 +time: 2018-08-17 13:16:40.866374 + +Running test_delayed_write_update6 +Open the file handle +Open the 2nd file handle on 2nd connection +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/17 15:16:40.785679) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/17 15:16:40.785679) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/17 15:16:40.785679) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/17 15:16:40.785679) +Set write time in the future on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/18 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/18 15:16:40.000000) +Set write time in the past on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Server did not update write_time (correct) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Server updated the write_time on close (correct) +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Have we lost the sticky write time ? +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) +Set write time in the future on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/18 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/18 15:17:28.000000) +Set write time in the past on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Server did not update write_time (correct) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Server updated the write_time on close (correct) +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Have we lost the sticky write time ? +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) +Close the 2nd file handle +pathinfo(cli2->tree): Access(2018/08/17 15:18:17.014049) Write(2018/08/17 15:17:53.960900) +Server did not update the write_time on close (correct) +time: 2018-08-17 13:18:17.112115 +success: delayed update of write time 6 +test: timestamp resolution test +time: 2018-08-17 13:18:17.112135 + +Running test_delayed_write_update7 (timestamp resolution test) +time: 2018-08-17 13:18:17.121007 +success: timestamp resolution test +test: directory timestamp update test +time: 2018-08-17 13:18:17.121025 + +Running test directory write update +Initial write time Fri Aug 17 15:18:17 2018 CEST +Updated write time Fri Aug 17 15:18:20 2018 CEST +time: 2018-08-17 13:18:20.134425 +success: directory timestamp update test diff --git a/out.modern-187 b/out.modern-187 new file mode 100644 index 000000000000..bdac1a55b6ef --- /dev/null +++ b/out.modern-187 @@ -0,0 +1,2297 @@ +smbtorture 4.10.0pre1-DEVELOPERBUILD +Using seed 1534501266 +time: 2018-08-17 10:21:06.655675 +progress: 17 +test: finfo update on close +time: 2018-08-17 10:21:06.655833 + +Running test_finfo_after_write +time: 2018-08-17 10:21:07.676713 +success: finfo update on close +test: delayed update of write time +time: 2018-08-17 10:21:07.676756 + +Running test_delayed_write_update +Initial write time Fri Aug 17 12:21:08 2018 CEST +write time Fri Aug 17 12:21:08 2018 CEST +write time Fri Aug 17 12:21:08 2018 CEST +write time Fri Aug 17 12:21:10 2018 CEST +Server updated write_time after 2.00 seconds (correct) +time: 2018-08-17 10:21:09.692169 +success: delayed update of write time +test: update of write time and SMBwrite truncate +time: 2018-08-17 10:21:09.692208 + +Running test_delayed_write_update1 +Initial write time Fri Aug 17 12:21:10 2018 CEST +write time Fri Aug 17 12:21:16 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 12:21:16 2018 CEST +write time Fri Aug 17 12:21:16 2018 CEST +write time Fri Aug 17 12:21:16 2018 CEST +write time Fri Aug 17 12:21:16 2018 CEST +write time Fri Aug 17 12:21:16 2018 CEST +write time Fri Aug 17 12:21:16 2018 CEST +write time Fri Aug 17 12:21:16 2018 CEST +write time Fri Aug 17 12:21:16 2018 CEST +write time Fri Aug 17 12:21:16 2018 CEST +write time Fri Aug 17 12:21:16 2018 CEST +Server did not update write time within 10 seconds. Good! +Server updated write time on close (correct) +time: 2018-08-17 10:21:29.741022 +success: update of write time and SMBwrite truncate +test: update of write time and SMBwrite truncate expand +time: 2018-08-17 10:21:29.741063 + +Running test_delayed_write_update1a +Initial write time Fri Aug 17 12:21:30 2018 CEST +write time Fri Aug 17 12:21:33 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 12:21:33 2018 CEST +write time Fri Aug 17 12:21:33 2018 CEST +write time Fri Aug 17 12:21:33 2018 CEST +write time Fri Aug 17 12:21:33 2018 CEST +write time Fri Aug 17 12:21:33 2018 CEST +write time Fri Aug 17 12:21:33 2018 CEST +write time Fri Aug 17 12:21:33 2018 CEST +write time Fri Aug 17 12:21:33 2018 CEST +write time Fri Aug 17 12:21:33 2018 CEST +write time Fri Aug 17 12:21:33 2018 CEST +Server did not update write time within 10 seconds. Good! +Server updated write time on close (correct) +time: 2018-08-17 10:21:44.794855 +success: update of write time and SMBwrite truncate expand +test: update of write time using SET_END_OF_FILE +time: 2018-08-17 10:21:44.794884 + +Running test_delayed_write_update1b +Initial write time Fri Aug 17 12:21:45 2018 CEST +write time Fri Aug 17 12:21:48 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 12:21:48 2018 CEST +write time Fri Aug 17 12:21:48 2018 CEST +write time Fri Aug 17 12:21:48 2018 CEST +write time Fri Aug 17 12:21:48 2018 CEST +write time Fri Aug 17 12:21:48 2018 CEST +write time Fri Aug 17 12:21:48 2018 CEST +write time Fri Aug 17 12:21:48 2018 CEST +write time Fri Aug 17 12:21:48 2018 CEST +write time Fri Aug 17 12:21:48 2018 CEST +write time Fri Aug 17 12:21:48 2018 CEST +Server did not update write time within 10 seconds. Good! +Server updated write time on close (correct) +time: 2018-08-17 10:21:59.848678 +success: update of write time using SET_END_OF_FILE +test: update of write time using SET_ALLOCATION_SIZE +time: 2018-08-17 10:21:59.848707 + +Running test_delayed_write_update1c +Initial write time Fri Aug 17 12:22:00 2018 CEST +write time Fri Aug 17 12:22:03 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 12:22:03 2018 CEST +write time Fri Aug 17 12:22:03 2018 CEST +write time Fri Aug 17 12:22:03 2018 CEST +write time Fri Aug 17 12:22:03 2018 CEST +write time Fri Aug 17 12:22:03 2018 CEST +write time Fri Aug 17 12:22:03 2018 CEST +write time Fri Aug 17 12:22:03 2018 CEST +write time Fri Aug 17 12:22:03 2018 CEST +write time Fri Aug 17 12:22:03 2018 CEST +write time Fri Aug 17 12:22:03 2018 CEST +Server did not update write time within 10 seconds. Good! +time: 2018-08-17 10:22:14.889942 +success: update of write time using SET_ALLOCATION_SIZE +test: delayed update of write time using 2 connections +time: 2018-08-17 10:22:14.889983 + +Running test_delayed_write_update2 +Initial write time Fri Aug 17 12:22:15 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +Server updated write_time (correct) +Modified write time Fri Aug 17 04:02:17 2018 CEST +Doing a 10 byte write to extend the file and see if this changes the last write time. +Doing flush after write +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +Server did not update write time (correct) +Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. +write time Fri Aug 17 04:02:17 2018 CEST +Closing the first fd to see if write time updated. +Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +write time Fri Aug 17 04:02:17 2018 CEST +Server did not update write time (correct) +Closing second fd to see if write time updated. +Second open initial write time Fri Aug 17 12:22:50 2018 CEST +Doing a 10 byte write to extend the file to see if this changes the last write time. +write time Fri Aug 17 12:22:50 2018 CEST +write time Fri Aug 17 12:22:50 2018 CEST +write time Fri Aug 17 12:22:50 2018 CEST +write time Fri Aug 17 12:22:50 2018 CEST +write time Fri Aug 17 12:23:03 2018 CEST +Server updated write_time after 3.01 seconds(correct) +time: 2018-08-17 10:23:03.004249 +success: delayed update of write time using 2 connections +test: delayed update of write time 3 +time: 2018-08-17 10:23:03.004310 + +Running test_delayed_write_update3 +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Server updated write_time after 2.01 seconds (correct) +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:25.030595) +Server updated the write_time on close (correct) +time: 2018-08-17 10:23:25.085565 +success: delayed update of write time 3 +test: delayed update of write time 3a +time: 2018-08-17 10:23:25.085579 + +Running test_delayed_write_update3a +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:25.046529) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:25.046529) +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:25.046529) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:25.046529) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:25.046529) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:30.498815) +Server updated write_time after 0.50 seconds (correct) +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:30.498815) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:30.498815) +Do a truncate SMBwrite [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:35.561499) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:35.561499) +Do a truncate SMBwrite [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:37.577115) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:37.577115) +Do a truncate SMBwrite [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) +Do a truncate SMBwrite [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:02.810789) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:02.810789) +Do a truncate SMBwrite [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:04.810696) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:04.810696) +Do a truncate SMBwrite [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:06.826559) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:06.826559) +fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:06.826559) +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:06.826559) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:06.826559) +Server did not update the write_time on close (correct) +time: 2018-08-17 10:24:09.882712 +success: delayed update of write time 3a +test: delayed update of write time 3b +time: 2018-08-17 10:24:09.882744 + +Running test_delayed_write_update3b +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:09.842148) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:09.842148) +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:09.842148) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:09.842148) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:09.842148) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Server updated write_time after 0.50 seconds (write time update delay == 0.50) (correct) +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:35.419315) +Server updated the write_time on close (correct) +time: 2018-08-17 10:24:35.467659 +success: delayed update of write time 3b +test: delayed update of write time 3c +time: 2018-08-17 10:24:35.467721 + +Running test_delayed_write_update3c +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:35.434994) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:35.434994) +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:35.434994) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:35.434994) +Do a truncate SMBwrite [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:42.435487) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:42.435487) +Do a truncate SMBwrite [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:44.450742) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:44.450742) +Do a truncate SMBwrite [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) +Do a truncate write [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:00.481998) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:00.481998) +Do a truncate write [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:02.497410) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:02.497410) +Do a truncate write [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:29.590701) +Server updated the write_time on close (correct) +time: 2018-08-17 10:25:29.657002 +success: delayed update of write time 3c +test: delayed update of write time 5 +time: 2018-08-17 10:25:29.657021 + +Running test_delayed_write_update5 +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/17 12:25:29.621994) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/17 12:25:29.621994) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/17 12:25:29.621994) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/17 12:25:29.621994) +Set write time in the future on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/18 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/18 12:25:29.000000) +Set write time in the past on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Server did not update write_time (correct) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) +Server did not update the write_time on close (correct) +time: 2018-08-17 10:26:04.774051 +success: delayed update of write time 5 +test: delayed update of write time 5b +time: 2018-08-17 10:26:04.774088 + +Running test_delayed_write_update5b +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/17 12:26:04.731354) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/17 12:26:04.731354) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/17 12:26:04.731354) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/17 12:26:04.731354) +Set write time in the future on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/18 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/18 12:26:04.000000) +Set write time in the past on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Server did not update write_time (correct) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) +Server did not update the write_time on close (correct) +time: 2018-08-17 10:26:39.928555 +success: delayed update of write time 5b +test: delayed update of write time 6 +time: 2018-08-17 10:26:39.928575 + +Running test_delayed_write_update6 +Open the file handle +Open the 2nd file handle on 2nd connection +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:26:39.887346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:26:39.887346) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:26:39.887346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:26:39.887346) +Set write time in the future on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/18 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/18 12:26:39.000000) +Set write time in the past on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Server did not update write_time (correct) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Server updated the write_time on close (correct) +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Have we lost the sticky write time ? +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) +Set write time in the future on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/18 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/18 12:27:28.000000) +Set write time in the past on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Server did not update write_time (correct) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Server updated the write_time on close (correct) +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Have we lost the sticky write time ? +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Close the 2nd file handle +pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) +Server did not update the write_time on close (correct) +time: 2018-08-17 10:28:16.218644 +success: delayed update of write time 6 +test: timestamp resolution test +time: 2018-08-17 10:28:16.218678 + +Running test_delayed_write_update7 (timestamp resolution test) +time: 2018-08-17 10:28:16.233498 +success: timestamp resolution test +test: directory timestamp update test +time: 2018-08-17 10:28:16.233519 + +Running test directory write update +Initial write time Fri Aug 17 12:28:16 2018 CEST +Updated write time Fri Aug 17 12:28:19 2018 CEST +time: 2018-08-17 10:28:19.248341 +success: directory timestamp update test +test: delaywrite1 +time: 2018-08-17 10:28:19.248394 + +Running test_delaywrite_delaywrite1 +Open the file handle +START: run1 +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +Do a write on the file handle +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Server updated write_time after 1.00/1.01 seconds (min delay == 0.01, max delay == 5.00) +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Do a write on the file handle +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Server updated write_time after 0.38/0.38 seconds (min delay == 0.01, max delay == 5.00) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +START: run2 +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Do a write on the file handle +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Server updated write_time after 3.01/3.01 seconds (min delay == 0.01, max delay == 5.00) +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Do a write on the file handle +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +Server updated write_time after 3.00/3.00 seconds (min delay == 0.01, max delay == 5.00) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +Close the file handle +Close the file handle +fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +pathinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) +time: 2018-08-17 10:29:02.779445 +success: delaywrite1 diff --git a/out.modern-219 b/out.modern-219 new file mode 100644 index 000000000000..6445e89c07ae --- /dev/null +++ b/out.modern-219 @@ -0,0 +1,1787 @@ +smbtorture 4.10.0pre1-DEVELOPERBUILD +Using seed 1534500791 +time: 2018-08-17 10:13:11.988198 +progress: 17 +test: finfo update on close +time: 2018-08-17 10:13:11.988352 + +Running test_finfo_after_write +time: 2018-08-17 10:13:13.005181 +success: finfo update on close +test: delayed update of write time +time: 2018-08-17 10:13:13.005212 + +Running test_delayed_write_update +Initial write time Fri Aug 17 12:13:13 2018 CEST +write time Fri Aug 17 12:13:13 2018 CEST +write time Fri Aug 17 12:13:13 2018 CEST +write time Fri Aug 17 12:13:15 2018 CEST +Server updated write_time after 2.00 seconds (correct) +time: 2018-08-17 10:13:15.020529 +success: delayed update of write time +test: update of write time and SMBwrite truncate +time: 2018-08-17 10:13:15.020563 + +Running test_delayed_write_update1 +Initial write time Fri Aug 17 12:13:15 2018 CEST +write time Fri Aug 17 12:13:21 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 12:13:21 2018 CEST +write time Fri Aug 17 12:13:21 2018 CEST +write time Fri Aug 17 12:13:21 2018 CEST +write time Fri Aug 17 12:13:21 2018 CEST +write time Fri Aug 17 12:13:21 2018 CEST +write time Fri Aug 17 12:13:21 2018 CEST +write time Fri Aug 17 12:13:21 2018 CEST +write time Fri Aug 17 12:13:21 2018 CEST +write time Fri Aug 17 12:13:21 2018 CEST +write time Fri Aug 17 12:13:21 2018 CEST +Server did not update write time within 10 seconds. Good! +Server updated write time on close (correct) +time: 2018-08-17 10:13:35.065108 +success: update of write time and SMBwrite truncate +test: update of write time and SMBwrite truncate expand +time: 2018-08-17 10:13:35.065151 + +Running test_delayed_write_update1a +Initial write time Fri Aug 17 12:13:35 2018 CEST +write time Fri Aug 17 12:13:38 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 12:13:38 2018 CEST +write time Fri Aug 17 12:13:38 2018 CEST +write time Fri Aug 17 12:13:38 2018 CEST +write time Fri Aug 17 12:13:38 2018 CEST +write time Fri Aug 17 12:13:38 2018 CEST +write time Fri Aug 17 12:13:38 2018 CEST +write time Fri Aug 17 12:13:38 2018 CEST +write time Fri Aug 17 12:13:38 2018 CEST +write time Fri Aug 17 12:13:38 2018 CEST +write time Fri Aug 17 12:13:38 2018 CEST +Server did not update write time within 10 seconds. Good! +Server updated write time on close (correct) +time: 2018-08-17 10:13:50.102264 +success: update of write time and SMBwrite truncate expand +test: update of write time using SET_END_OF_FILE +time: 2018-08-17 10:13:50.102291 + +Running test_delayed_write_update1b +Initial write time Fri Aug 17 12:13:50 2018 CEST +write time Fri Aug 17 12:13:53 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 12:13:53 2018 CEST +write time Fri Aug 17 12:13:53 2018 CEST +write time Fri Aug 17 12:13:53 2018 CEST +write time Fri Aug 17 12:13:53 2018 CEST +write time Fri Aug 17 12:13:53 2018 CEST +write time Fri Aug 17 12:13:53 2018 CEST +write time Fri Aug 17 12:13:53 2018 CEST +write time Fri Aug 17 12:13:53 2018 CEST +write time Fri Aug 17 12:13:53 2018 CEST +write time Fri Aug 17 12:13:53 2018 CEST +Server did not update write time within 10 seconds. Good! +Server updated write time on close (correct) +time: 2018-08-17 10:14:05.142073 +success: update of write time using SET_END_OF_FILE +test: update of write time using SET_ALLOCATION_SIZE +time: 2018-08-17 10:14:05.142110 + +Running test_delayed_write_update1c +Initial write time Fri Aug 17 12:14:05 2018 CEST +write time Fri Aug 17 12:14:08 2018 CEST +Server updated write time immediately. Good! +write time Fri Aug 17 12:14:08 2018 CEST +write time Fri Aug 17 12:14:08 2018 CEST +write time Fri Aug 17 12:14:08 2018 CEST +write time Fri Aug 17 12:14:08 2018 CEST +write time Fri Aug 17 12:14:08 2018 CEST +write time Fri Aug 17 12:14:08 2018 CEST +write time Fri Aug 17 12:14:08 2018 CEST +write time Fri Aug 17 12:14:08 2018 CEST +write time Fri Aug 17 12:14:08 2018 CEST +write time Fri Aug 17 12:14:08 2018 CEST +Server did not update write time within 10 seconds. Good! +time: 2018-08-17 10:14:20.178262 +success: update of write time using SET_ALLOCATION_SIZE +test: delayed update of write time using 2 connections +time: 2018-08-17 10:14:20.178301 + +Running test_delayed_write_update2 +Initial write time Fri Aug 17 12:14:20 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +Server updated write_time (correct) +Modified write time Fri Aug 17 03:54:23 2018 CEST +Doing a 10 byte write to extend the file and see if this changes the last write time. +Doing flush after write +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +Server did not update write time (correct) +Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. +write time Fri Aug 17 03:54:23 2018 CEST +Closing the first fd to see if write time updated. +Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +write time Fri Aug 17 03:54:23 2018 CEST +Server did not update write time (correct) +Closing second fd to see if write time updated. +Second open initial write time Fri Aug 17 12:14:55 2018 CEST +Doing a 10 byte write to extend the file to see if this changes the last write time. +write time Fri Aug 17 12:14:55 2018 CEST +write time Fri Aug 17 12:14:55 2018 CEST +write time Fri Aug 17 12:14:55 2018 CEST +write time Fri Aug 17 12:14:55 2018 CEST +write time Fri Aug 17 12:15:08 2018 CEST +Server updated write_time after 3.01 seconds(correct) +time: 2018-08-17 10:15:08.271634 +success: delayed update of write time using 2 connections +test: delayed update of write time 3 +time: 2018-08-17 10:15:08.271665 + +Running test_delayed_write_update3 +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:08.178131) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:08.178131) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:08.178131) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:08.178131) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:08.178131) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Server updated write_time after 1.51 seconds (correct) +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:29.740631) +Server updated the write_time on close (correct) +time: 2018-08-17 10:15:29.846089 +success: delayed update of write time 3 +test: delayed update of write time 3a +time: 2018-08-17 10:15:29.846124 + +Running test_delayed_write_update3a +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:35.475006) +Server updated write_time after 1.01 seconds (correct) +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:35.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:35.475006) +Do a truncate SMBwrite [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:40.771881) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:40.771881) +Do a truncate SMBwrite [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:42.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:42.787506) +Do a truncate SMBwrite [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) +Do a truncate SMBwrite [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:07.850006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:07.850006) +Do a truncate SMBwrite [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:09.850006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:09.850006) +Do a truncate SMBwrite [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:11.850006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:11.850006) +fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:11.850006) +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:11.850006) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:11.850006) +Server did not update the write_time on close (correct) +time: 2018-08-17 10:16:14.960060 +success: delayed update of write time 3a +test: delayed update of write time 3b +time: 2018-08-17 10:16:14.960105 + +Running test_delayed_write_update3b +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Server updated write_time after 1.01 seconds (write time update delay == 0.50) (correct) +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:40.943756) +Server updated the write_time on close (correct) +time: 2018-08-17 10:16:41.040859 +success: delayed update of write time 3b +test: delayed update of write time 3c +time: 2018-08-17 10:16:41.040895 + +Running test_delayed_write_update3c +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:40.959381) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:40.959381) +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:40.959381) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:40.959381) +Do a truncate SMBwrite [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:47.959381) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:47.959381) +Do a truncate SMBwrite [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:49.959381) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:49.959381) +Do a truncate SMBwrite [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) +Do a truncate write [0] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:05.990631) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:05.990631) +Do a truncate write [1] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:07.990631) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:07.990631) +Do a truncate write [2] on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:35.053131) +Server updated the write_time on close (correct) +time: 2018-08-17 10:17:35.154560 +success: delayed update of write time 3c +test: delayed update of write time 5 +time: 2018-08-17 10:17:35.154582 + +Running test_delayed_write_update5 +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/17 12:17:35.068756) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/17 12:17:35.068756) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/17 12:17:35.068756) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/17 12:17:35.068756) +Set write time in the future on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/18 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/18 12:17:35.000000) +Set write time in the past on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Server did not update write_time (correct) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) +Server did not update the write_time on close (correct) +time: 2018-08-17 10:18:10.267297 +success: delayed update of write time 5 +test: delayed update of write time 5b +time: 2018-08-17 10:18:10.267338 + +Running test_delayed_write_update5b +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/17 12:18:10.178131) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/17 12:18:10.178131) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/17 12:18:10.178131) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/17 12:18:10.178131) +Set write time in the future on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/18 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/18 12:18:10.000000) +Set write time in the past on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Server did not update write_time (correct) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Do a truncate write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) +Server did not update the write_time on close (correct) +time: 2018-08-17 10:18:45.375869 +success: delayed update of write time 5b +test: delayed update of write time 6 +time: 2018-08-17 10:18:45.375909 + +Running test_delayed_write_update6 +Open the file handle +Open the 2nd file handle on 2nd connection +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:18:45.287506) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:18:45.287506) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:18:45.287506) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:18:45.287506) +Set write time in the future on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/18 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/18 12:18:45.000000) +Set write time in the past on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Server did not update write_time (correct) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Server updated the write_time on close (correct) +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Have we lost the sticky write time ? +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Open the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) +Set write time in the future on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/18 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/18 12:19:33.000000) +Set write time in the past on the 2nd file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Server did not update write_time (correct) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Do a write on the file handle +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Server did not update write_time (correct) +fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) +Close the file handle +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Server updated the write_time on close (correct) +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Have we lost the sticky write time ? +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Do a truncate write on the second file handle +fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Close the 2nd file handle +pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) +Server did not update the write_time on close (correct) +time: 2018-08-17 10:20:21.632961 +success: delayed update of write time 6 +test: timestamp resolution test +time: 2018-08-17 10:20:21.632986 + +Running test_delayed_write_update7 (timestamp resolution test) +time: 2018-08-17 10:20:21.646111 +success: timestamp resolution test +test: directory timestamp update test +time: 2018-08-17 10:20:21.646136 + +Running test directory write update +Initial write time Fri Aug 17 12:20:22 2018 CEST +Updated write time Fri Aug 17 12:20:25 2018 CEST +time: 2018-08-17 10:20:24.658805 +success: directory timestamp update test +test: delaywrite1 +time: 2018-08-17 10:20:24.658851 + +Running test_delaywrite_delaywrite1 +Open the file handle +START: run1 +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +Do a write on the file handle +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Server updated write_time after 1.00/1.00 seconds (min delay == 0.01, max delay == 5.00) +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Do a write on the file handle +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Server updated write_time after 0.86/0.86 seconds (min delay == 0.01, max delay == 5.00) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +START: run2 +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Check for no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Do a write on the file handle +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Server updated write_time after 3.01/3.01 seconds (min delay == 0.01, max delay == 5.00) +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Check for no additional change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Do a write on the file handle +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) +Write while waiting +Wait for change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +Server updated write_time after 0.94/0.94 seconds (min delay == 0.01, max delay == 5.00) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +Wait for change or no change +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +Close the file handle +Close the file handle +fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +pathinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) +time: 2018-08-17 10:21:06.592228 +success: delaywrite1 -- 2.17.1