summaryrefslogtreecommitdiff
path: root/source4/torture/util_smb.c
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2014-08-21 10:32:00 +0200
committerMichael Adam <obnox@samba.org>2014-09-10 13:15:17 +0200
commit868e8f42a08f9cb75cb9ab728169faf368a3e7f5 (patch)
tree0027a50712940dba8c8a05a4f8557f366d47507a /source4/torture/util_smb.c
parent589344802df9916bbfcd12317e703d3b6cbbba8e (diff)
downloadsamba-868e8f42a08f9cb75cb9ab728169faf368a3e7f5.tar.gz
s4:torture: fix multi_smb_test child status tracking.
The original code in torture_start_procs() lost status of child status. So the affected test caseses (defer_open, ntdeny1, bench-torture, and also direct torture_start_proxy-user bench-nbench) were not always able to correctly detect and treat errors in the worker children. With this patch, torture_create_procs() correctly puts child result and reason into top level torture_result(), thereby in particular fixing remaining unexpected errors in the flapping deferopen test. Signed-off-by: Michael Adam <obnox@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org> Autobuild-User(master): Michael Adam <obnox@samba.org> Autobuild-Date(master): Wed Sep 10 13:15:17 CEST 2014 on sn-devel-104
Diffstat (limited to 'source4/torture/util_smb.c')
-rw-r--r--source4/torture/util_smb.c87
1 files changed, 62 insertions, 25 deletions
diff --git a/source4/torture/util_smb.c b/source4/torture/util_smb.c
index 588ac055c7e..0520f275a4c 100644
--- a/source4/torture/util_smb.c
+++ b/source4/torture/util_smb.c
@@ -582,12 +582,19 @@ static void sigcont(int sig)
{
}
-double torture_create_procs(struct torture_context *tctx,
- bool (*fn)(struct torture_context *, struct smbcli_state *, int), bool *result)
+struct child_status {
+ pid_t pid;
+ bool start;
+ enum torture_result result;
+ char reason[1024];
+};
+
+double torture_create_procs(struct torture_context *tctx,
+ bool (*fn)(struct torture_context *, struct smbcli_state *, int),
+ bool *result)
{
int i, status;
- volatile pid_t *child_status;
- volatile bool *child_status_out;
+ struct child_status *child_status;
int synccount;
int tries = 8;
int torture_nprocs = torture_setting_int(tctx, "nprocs", 4);
@@ -600,21 +607,15 @@ double torture_create_procs(struct torture_context *tctx,
signal(SIGCONT, sigcont);
- child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
- if (!child_status) {
+ child_status = (struct child_status *)anonymous_shared_allocate(
+ sizeof(struct child_status)*torture_nprocs);
+ if (child_status == NULL) {
printf("Failed to setup shared memory\n");
return -1;
}
- child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
- if (!child_status_out) {
- printf("Failed to setup result status shared memory\n");
- return -1;
- }
-
for (i = 0; i < torture_nprocs; i++) {
- child_status[i] = 0;
- child_status_out[i] = true;
+ ZERO_STRUCT(child_status[i]);
}
tv = timeval_current();
@@ -623,6 +624,7 @@ double torture_create_procs(struct torture_context *tctx,
procnum = i;
if (fork() == 0) {
char *myname;
+ bool ok;
pid_t mypid = getpid();
srandom(((int)mypid) ^ ((int)time(NULL)));
@@ -646,17 +648,45 @@ double torture_create_procs(struct torture_context *tctx,
smb_msleep(100);
}
- child_status[i] = getpid();
+ child_status[i].pid = getpid();
pause();
- if (child_status[i]) {
+ if (!child_status[i].start) {
+ child_status[i].result = TORTURE_ERROR;
printf("Child %d failed to start!\n", i);
- child_status_out[i] = 1;
_exit(1);
}
- child_status_out[i] = fn(tctx, current_cli, i);
+ ok = fn(tctx, current_cli, i);
+ if (!ok) {
+ if (tctx->last_result == TORTURE_OK) {
+ torture_result(tctx, TORTURE_ERROR,
+ "unknown error: missing "
+ "torture_result call?\n");
+ }
+
+ child_status[i].result = tctx->last_result;
+
+ if (strlen(tctx->last_reason) > 1023) {
+ /* note: reason already contains \n */
+ torture_comment(tctx,
+ "child %d (pid %u) failed: %s",
+ i,
+ (unsigned)child_status[i].pid,
+ tctx->last_reason);
+ }
+
+ snprintf(child_status[i].reason,
+ 1024, "child %d (pid %u) failed: %s",
+ i, (unsigned)child_status[i].pid,
+ tctx->last_reason);
+ /* ensure proper "\n\0" termination: */
+ if (child_status[i].reason[1022] != '\0') {
+ child_status[i].reason[1022] = '\n';
+ child_status[i].reason[1023] = '\0';
+ }
+ }
_exit(0);
}
}
@@ -664,9 +694,13 @@ double torture_create_procs(struct torture_context *tctx,
do {
synccount = 0;
for (i=0;i<torture_nprocs;i++) {
- if (child_status[i]) synccount++;
+ if (child_status[i].pid != 0) {
+ synccount++;
+ }
+ }
+ if (synccount == torture_nprocs) {
+ break;
}
- if (synccount == torture_nprocs) break;
smb_msleep(100);
} while (timeval_elapsed(&tv) < start_time_limit);
@@ -675,8 +709,8 @@ double torture_create_procs(struct torture_context *tctx,
/* cleanup child processes */
for (i = 0; i < torture_nprocs; i++) {
- if (child_status[i]) {
- kill(child_status[i], SIGTERM);
+ if (child_status[i].pid != 0) {
+ kill(child_status[i].pid, SIGTERM);
}
}
@@ -689,7 +723,7 @@ double torture_create_procs(struct torture_context *tctx,
/* start the client load */
tv = timeval_current();
for (i=0;i<torture_nprocs;i++) {
- child_status[i] = 0;
+ child_status[i].start = true;
}
printf("%d clients started\n", torture_nprocs);
@@ -705,12 +739,15 @@ double torture_create_procs(struct torture_context *tctx,
}
printf("\n");
-
+
for (i=0;i<torture_nprocs;i++) {
- if (!child_status_out[i]) {
+ if (child_status[i].result != TORTURE_OK) {
*result = false;
+ torture_result(tctx, child_status[i].result,
+ "%s", child_status[i].reason);
}
}
+
return timeval_elapsed(&tv);
}