s3: Add a test for proper brlock cleanup
authorVolker Lendecke <vl@samba.org>
Thu, 5 Jan 2012 16:44:44 +0000 (17:44 +0100)
committerVolker Lendecke <vlendec@samba.org>
Thu, 5 Jan 2012 19:29:59 +0000 (20:29 +0100)
We need to improve the server here.

Maybe we should validate the brlock entry whenever we detect a read/write being
blocked from locking? This is not our hot code path anyway, and it would gain
us significant robustness. The code might become quite a bit simpler as well.

source3/torture/proto.h
source3/torture/test_cleanup.c
source3/torture/torture.c

index 19e7a72a7066d00f8f1c5c3eeb5ac7ffa66c0ce8..8d661aada91094ceb8040944c687e6713b08c7de 100644 (file)
@@ -102,5 +102,6 @@ bool run_smb2_session_reauth(int dummy);
 bool run_local_conv_auth_info(int dummy);
 bool run_local_sprintf_append(int dummy);
 bool run_cleanup1(int dummy);
+bool run_cleanup2(int dummy);
 
 #endif /* __TORTURE_H__ */
index 4e89893bcd1cd211e563967d39a1ed54b306e5c6..2b4989e48b00ece2498a0f1b37ee14e470a63003 100644 (file)
@@ -22,6 +22,7 @@
 #include "system/filesys.h"
 #include "libsmb/libsmb.h"
 #include "libcli/smb/smbXcli_base.h"
+#include "libcli/security/security.h"
 
 bool run_cleanup1(int dummy)
 {
@@ -68,3 +69,89 @@ done:
        torture_close_connection(cli);
        return NT_STATUS_IS_OK(status);
 }
+
+bool run_cleanup2(int dummy)
+{
+       struct cli_state *cli1, *cli2;
+       const char *fname = "\\cleanup2";
+       uint16_t fnum1, fnum2;
+       NTSTATUS status;
+       char buf;
+
+       printf("CLEANUP2: Checking that a conflicting brlock is cleaned up\n");
+
+       if (!torture_open_connection(&cli1, 0)) {
+               return false;
+       }
+       status = cli_ntcreate(
+               cli1, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
+               FILE_ATTRIBUTE_NORMAL,
+               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+               FILE_OVERWRITE_IF, 0, 0, &fnum1);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("open of %s failed (%s)\n", fname, nt_errstr(status));
+               return false;
+       }
+       status = cli_lock32(cli1, fnum1, 0, 1, 0, WRITE_LOCK);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("lock failed (%s)\n", nt_errstr(status));
+               return false;
+       }
+
+       /*
+        * Check the file is indeed locked
+        */
+       if (!torture_open_connection(&cli2, 0)) {
+               return false;
+       }
+       status = cli_ntcreate(
+               cli2, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
+               FILE_ATTRIBUTE_NORMAL,
+               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+               FILE_OPEN, 0, 0, &fnum2);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("open of %s failed (%s)\n", fname, nt_errstr(status));
+               return false;
+       }
+       buf = 'x';
+       status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
+               printf("write succeeded\n");
+               return false;
+       }
+
+       /*
+        * Kill the lock holder
+        */
+       status = smbXcli_conn_samba_suicide(cli1->conn, 1);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("smbXcli_conn_samba_suicide failed: %s\n",
+                      nt_errstr(status));
+               return false;
+       }
+
+       /*
+        * Right now we don't clean up immediately. Re-open the 2nd connection.
+        */
+#if 1
+       cli_shutdown(cli2);
+       if (!torture_open_connection(&cli2, 0)) {
+               return false;
+       }
+       status = cli_ntcreate(
+               cli2, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
+               FILE_ATTRIBUTE_NORMAL,
+               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+               FILE_OPEN, 0, 0, &fnum2);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("open of %s failed (%s)\n", fname, nt_errstr(status));
+               return false;
+       }
+#endif
+       status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("write failed: %s\n", nt_errstr(status));
+               return false;
+       }
+       return true;
+}
index 9d18f72271a6d0ccca647b77e009740311e7b68c..8535333a284635ed7bd339f3ae777c11907bf1a1 100644 (file)
@@ -8880,6 +8880,7 @@ static struct {
        { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
        { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
        { "CLEANUP1", run_cleanup1 },
+       { "CLEANUP2", run_cleanup2 },
        { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
        { "LOCAL-GENCACHE", run_local_gencache, 0},
        { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},