/* global options */
static struct gentest_options {
- bool showall;
- bool analyze;
- bool analyze_always;
- bool analyze_continuous;
+ int showall;
+ int analyze;
+ int analyze_always;
+ int analyze_continuous;
uint_t max_open_handles;
uint_t seed;
uint_t numops;
- bool use_oplocks;
+ int use_oplocks;
char **ignore_patterns;
const char *seeds_file;
- bool use_preset_seeds;
- bool fast_reconnect;
+ int use_preset_seeds;
+ int fast_reconnect;
} options;
/* mapping between open handles on the server and local handles */
*/
static uint16_t gen_fnum_close(int instance)
{
- if (num_open_handles < 3) {
- if (gen_chance(80)) return BAD_HANDLE;
+ if (num_open_handles < 5) {
+ if (gen_chance(90)) return BAD_HANDLE;
}
return gen_fnum(instance);
/*
generate an integer in a specified range
*/
-static int gen_int_range(uint_t min, uint_t max)
+static int gen_int_range(uint64_t min, uint64_t max)
{
uint_t r = random();
return min + (r % (1+max-min));
static int gen_offset(void)
{
if (gen_chance(20)) return 0;
+// if (gen_chance(5)) return gen_int_range(0, 0xFFFFFFFF);
return gen_int_range(0, 1024*1024);
}
static int gen_io_count(void)
{
if (gen_chance(20)) return 0;
+// if (gen_chance(5)) return gen_int_range(0, 0xFFFFFFFF);
return gen_int_range(0, 4096);
}
/*
- return a lockingx lock mode
+ return a set of lock flags
*/
-static uint16_t gen_lock_mode(void)
+static uint16_t gen_lock_flags(void)
{
if (gen_chance(5)) return gen_bits_mask(0xFFFF);
if (gen_chance(20)) return gen_bits_mask(0x1F);
- return gen_bits_mask(LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES);
+ if (gen_chance(50)) return SMB2_LOCK_FLAG_UNLOCK;
+ return gen_bits_mask(SMB2_LOCK_FLAG_SHARED |
+ SMB2_LOCK_FLAG_EXCLUSIVE |
+ SMB2_LOCK_FLAG_FAIL_IMMEDIATELY);
}
/*
*/
static uint32_t gen_access_mask(void)
{
- if (gen_chance(50)) return SEC_FLAG_MAXIMUM_ALLOWED;
- if (gen_chance(20)) return SEC_FILE_ALL;
+ if (gen_chance(70)) return SEC_FLAG_MAXIMUM_ALLOWED;
+ if (gen_chance(70)) return SEC_FILE_ALL;
return gen_bits_mask(0xFFFFFFFF);
}
*/
static uint32_t gen_open_disp(void)
{
+ if (gen_chance(50)) return NTCREATEX_DISP_OPEN_IF;
if (gen_chance(10)) return gen_bits_mask(0xFFFFFFFF);
return gen_int_range(0, 5);
}
/*
generate ntcreatex operations
*/
-static bool handler_ntcreatex(int instance)
+static bool handler_create(int instance)
{
struct smb2_create parm[NSERVERS];
NTSTATUS status[NSERVERS];
ZERO_STRUCT(parm[0]);
- parm[0].in.security_flags = gen_bits_levels(3, 70, 0x0, 70, 0x3, 100, 0xFF);
- parm[0].in.oplock_level = gen_bits_levels(3, 70, 0x0, 70, 0x9, 100, 0xFF);
- parm[0].in.impersonation_level = gen_bits_levels(3, 70, 0x0, 70, 0x3, 100, 0xFFFFFFFF);
- parm[0].in.create_flags = gen_bits_levels(2, 80, 0x0, 100, 0xFFFFFFFF);
+ parm[0].in.security_flags = gen_bits_levels(3, 90, 0x0, 70, 0x3, 100, 0xFF);
+ parm[0].in.oplock_level = gen_bits_levels(3, 90, 0x0, 70, 0x9, 100, 0xFF);
+ parm[0].in.impersonation_level = gen_bits_levels(3, 90, 0x0, 70, 0x3, 100, 0xFFFFFFFF);
+ parm[0].in.create_flags = gen_bits_levels(2, 90, 0x0, 100, 0xFFFFFFFF);
if (gen_chance(2)) {
parm[0].in.create_flags |= gen_bits_mask(0xFFFFFFFF);
}
- parm[0].in.reserved = gen_bits_levels(2, 80, 0x0, 100, 0xFFFFFFFF);
+ parm[0].in.reserved = gen_bits_levels(2, 95, 0x0, 100, 0xFFFFFFFF);
if (gen_chance(2)) {
parm[0].in.reserved |= gen_bits_mask(0xFFFFFFFF);
}
return true;
}
-#if 0
/*
generate read operations
*/
static bool handler_read(int instance)
{
- union smb_read parm[NSERVERS];
+ struct smb2_read parm[NSERVERS];
NTSTATUS status[NSERVERS];
- parm[0].readx.level = RAW_READ_READX;
- parm[0].readx.in.file.fnum = gen_fnum(instance);
- parm[0].readx.in.offset = gen_offset();
- parm[0].readx.in.mincnt = gen_io_count();
- parm[0].readx.in.maxcnt = gen_io_count();
- parm[0].readx.in.remaining = gen_io_count();
- parm[0].readx.in.read_for_execute = gen_bool();
- parm[0].readx.out.data = talloc_array(current_op.mem_ctx, uint8_t,
- MAX(parm[0].readx.in.mincnt, parm[0].readx.in.maxcnt));
+ parm[0].in.file.handle.data[0] = gen_fnum(instance);
+ parm[0].in.reserved = gen_bits_mask2(0x0, 0xFF);
+ parm[0].in.length = gen_io_count();
+ parm[0].in.offset = gen_offset();
+ parm[0].in.min_count = gen_io_count();
+ parm[0].in.channel = gen_bits_mask2(0x0, 0xFFFFFFFF);
+ parm[0].in.remaining = gen_bits_mask2(0x0, 0xFFFFFFFF);
+ parm[0].in.channel_offset = gen_bits_mask2(0x0, 0xFFFF);
+ parm[0].in.channel_length = gen_bits_mask2(0x0, 0xFFFF);
GEN_COPY_PARM;
- GEN_SET_FNUM(readx.in.file.fnum);
- GEN_CALL(smb_raw_read(tree, &parm[i]));
+ GEN_SET_FNUM(in.file.handle);
+ GEN_CALL(smb2_read(tree, current_op.mem_ctx, &parm[i]));
- CHECK_EQUAL(readx.out.remaining);
- CHECK_EQUAL(readx.out.compaction_mode);
- CHECK_EQUAL(readx.out.nread);
+ CHECK_EQUAL(out.remaining);
+ CHECK_EQUAL(out.reserved);
+ CHECK_EQUAL(out.data.length);
return true;
}
*/
static bool handler_write(int instance)
{
- union smb_write parm[NSERVERS];
+ struct smb2_write parm[NSERVERS];
NTSTATUS status[NSERVERS];
- parm[0].writex.level = RAW_WRITE_WRITEX;
- parm[0].writex.in.file.fnum = gen_fnum(instance);
- parm[0].writex.in.offset = gen_offset();
- parm[0].writex.in.wmode = gen_bits_mask(0xFFFF);
- parm[0].writex.in.remaining = gen_io_count();
- parm[0].writex.in.count = gen_io_count();
- parm[0].writex.in.data = talloc_zero_array(current_op.mem_ctx, uint8_t, parm[0].writex.in.count);
+ parm[0].in.file.handle.data[0] = gen_fnum(instance);
+ parm[0].in.offset = gen_offset();
+ parm[0].in.unknown1 = gen_bits_mask2(0, 0xFFFFFFFF);
+ parm[0].in.unknown2 = gen_bits_mask2(0, 0xFFFFFFFF);
+ parm[0].in.data = data_blob_talloc(current_op.mem_ctx, NULL,
+ gen_io_count());
GEN_COPY_PARM;
- GEN_SET_FNUM(writex.in.file.fnum);
- GEN_CALL(smb_raw_write(tree, &parm[i]));
+ GEN_SET_FNUM(in.file.handle);
+ GEN_CALL(smb2_write(tree, &parm[i]));
- CHECK_EQUAL(writex.out.nwritten);
- CHECK_EQUAL(writex.out.remaining);
+ CHECK_EQUAL(out._pad);
+ CHECK_EQUAL(out.nwritten);
+ CHECK_EQUAL(out.unknown1);
return true;
}
*/
static bool handler_lock(int instance)
{
- union smb_lock parm[NSERVERS];
+ struct smb2_lock parm[NSERVERS];
NTSTATUS status[NSERVERS];
- int n, nlocks;
+ int n;
- parm[0].lockx.level = RAW_LOCK_LOCKX;
- parm[0].lockx.in.file.fnum = gen_fnum(instance);
- parm[0].lockx.in.mode = gen_lock_mode();
- parm[0].lockx.in.timeout = gen_timeout();
- do {
- /* make sure we don't accidentially generate an oplock
- break ack - otherwise the server can just block forever */
- parm[0].lockx.in.ulock_cnt = gen_lock_count();
- parm[0].lockx.in.lock_cnt = gen_lock_count();
- nlocks = parm[0].lockx.in.ulock_cnt + parm[0].lockx.in.lock_cnt;
- } while (nlocks == 0);
-
- if (nlocks > 0) {
- parm[0].lockx.in.locks = talloc_array(current_op.mem_ctx,
- struct smb_lock_entry,
- nlocks);
- for (n=0;n<nlocks;n++) {
- parm[0].lockx.in.locks[n].pid = gen_pid();
- parm[0].lockx.in.locks[n].offset = gen_offset();
- parm[0].lockx.in.locks[n].count = gen_io_count();
- }
+ parm[0].level = RAW_LOCK_LOCKX;
+ parm[0].in.file.handle.data[0] = gen_fnum(instance);
+ parm[0].in.lock_count = gen_lock_count();
+ parm[0].in.reserved = gen_bits_mask2(0, 0xFFFFFFFF);
+
+ parm[0].in.locks = talloc_array(current_op.mem_ctx,
+ struct smb2_lock_element,
+ parm[0].in.lock_count);
+ for (n=0;n<parm[0].in.lock_count;n++) {
+ parm[0].in.locks[n].offset = gen_offset();
+ parm[0].in.locks[n].length = gen_io_count();
+ /* don't yet cope with async replies */
+ parm[0].in.locks[n].flags = gen_lock_flags() |
+ SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
+ parm[0].in.locks[n].reserved = gen_bits_mask2(0x0, 0xFFFFFFFF);
}
GEN_COPY_PARM;
- GEN_SET_FNUM(lockx.in.file.fnum);
- GEN_CALL(smb_raw_lock(tree, &parm[i]));
+ GEN_SET_FNUM(in.file.handle);
+ GEN_CALL(smb2_lock(tree, &parm[i]));
+
+ return true;
+}
+
+/*
+ generate flush operations
+*/
+static bool handler_flush(int instance)
+{
+ struct smb2_flush parm[NSERVERS];
+ NTSTATUS status[NSERVERS];
+
+ ZERO_STRUCT(parm[0]);
+ parm[0].in.file.handle.data[0] = gen_fnum(instance);
+ parm[0].in.reserved1 = gen_bits_mask2(0x0, 0xFFFF);
+ parm[0].in.reserved2 = gen_bits_mask2(0x0, 0xFFFFFFFF);
+
+ GEN_COPY_PARM;
+ GEN_SET_FNUM(in.file.handle);
+ GEN_CALL(smb2_flush(tree, &parm[i]));
+
+ CHECK_EQUAL(out.reserved);
return true;
}
+#if 0
+
/*
generate a fileinfo query structure
*/
return true;
}
-/*
- generate qpathinfo operations
-*/
-static bool handler_qpathinfo(int instance)
-{
- union smb_fileinfo parm[NSERVERS];
- NTSTATUS status[NSERVERS];
-
- parm[0].generic.in.file.path = gen_fname_open(instance);
-
- gen_fileinfo(instance, &parm[0]);
-
- GEN_COPY_PARM;
- GEN_CALL(smb_raw_pathinfo(tree, current_op.mem_ctx, &parm[i]));
-
- return cmp_fileinfo(instance, parm, status);
-}
-
/*
generate qfileinfo operations
*/
}
status = smb2_util_mkdir(servers[i].tree[0], "gentest");
if (NT_STATUS_IS_ERR(status)) {
- printf("Failed to create gentest - %s\n", nt_errstr(status));
+ printf("Failed to create gentest on server %d - %s\n", i, nt_errstr(status));
exit(1);
}
if (n > 0) {
bool (*handler)(int instance);
int count, success_count;
} gen_ops[] = {
- {"NTCREATEX", handler_ntcreatex},
+ {"CREATE", handler_create},
{"CLOSE", handler_close},
+ {"READ", handler_read},
+ {"WRITE", handler_write},
+ {"LOCK", handler_lock},
+ {"FLUSH", handler_flush},
};