ia64/xen-unstable

view tools/xenstore/xs_stress.c @ 8740:3d7ea7972b39

Update patches for linux 2.6.15.

Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Thu Feb 02 17:16:00 2006 +0000 (2006-02-02)
parents 61b3b357d827
children
line source
1 /* Stress test for Xen Store: multiple people hammering transactions */
2 #include "xs.h"
3 #include "utils.h"
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include <errno.h>
13 #define NUM_HANDLES 2
14 #define DIR_FANOUT 3
15 #define DIR_DEPTH 3
17 /* How often to print progress */
18 static int print;
20 /* Layout looks like /<num>/<num>/count. */
21 static void work(unsigned int cycles, unsigned int childnum)
22 {
23 unsigned int i;
24 struct xs_handle *handles[NUM_HANDLES];
25 char id;
27 if (childnum < 10)
28 id = '0' + childnum;
29 else
30 id = 'A' + childnum - 10;
32 for (i = 0; i < NUM_HANDLES; i++) {
33 handles[i] = xs_daemon_open();
34 if (!handles[i])
35 barf_perror("Opening handle %i", i);
36 }
38 srandom(childnum);
39 for (i = 0; i < cycles; i++) {
40 unsigned int j, len;
41 char file[100] = "";
42 char *contents, tmp[100];
43 struct xs_handle *h = handles[random() % NUM_HANDLES];
45 for (j = 0; j < DIR_DEPTH; j++)
46 sprintf(file + strlen(file), "/%li",
47 random()%DIR_FANOUT);
49 if (!xs_transaction_start(h))
50 barf_perror("%i: starting transaction %i",
51 childnum, i);
53 sprintf(file + strlen(file), "/count");
54 contents = xs_read(h, file, &len);
55 if (!contents)
56 barf_perror("%i: can't read %s iter %i",
57 childnum, file, i);
58 sprintf(tmp, "%i", atoi(contents) + 1);
59 if (!xs_write(h, file, tmp, strlen(tmp)+1))
60 barf_perror("%i: can't write %s iter %i",
61 childnum, file, i);
63 /* Abandon 1 in 10 */
64 if (random() % 10 == 0) {
65 if (!xs_transaction_end(h, true))
66 barf_perror("%i: can't abort transact",
67 childnum);
68 i--;
69 } else {
70 if (!xs_transaction_end(h, false)) {
71 if (errno == EAGAIN) {
72 write(STDOUT_FILENO, "!", 1);
73 i--;
74 } else
75 barf_perror("%i: can't commit trans",
76 childnum);
77 } else {
78 /* Offset when we print . so kids don't all
79 * print at once. */
80 if ((i + print/(childnum+1)) % print == 0)
81 write(STDOUT_FILENO, &id, 1);
82 }
83 }
84 }
85 }
87 static void create_dirs(struct xs_handle *h, const char *base, int togo)
88 {
89 unsigned int i;
90 char filename[100];
92 if (togo == 0) {
93 sprintf(filename, "%s/count", base);
94 if (!xs_write(h, filename, "0", 1))
95 barf_perror("Writing to %s", filename);
96 return;
97 }
99 for (i = 0; i < DIR_FANOUT; i++) {
100 sprintf(filename, "%s/%i", base, i);
101 if (!xs_mkdir(h, filename))
102 barf_perror("xs_mkdir %s", filename);
103 create_dirs(h, filename, togo-1);
104 }
105 }
107 static unsigned int add_count(struct xs_handle *h, const char *base, int togo)
108 {
109 unsigned int i, count;
110 char filename[100];
112 if (togo == 0) {
113 char *answer;
114 unsigned int len;
116 sprintf(filename, "%s/count", base);
117 answer = xs_read(h, filename, &len);
118 if (!answer)
119 barf_perror("Reading %s", filename);
120 count = atoi(answer);
121 free(answer);
122 return count;
123 }
125 count = 0;
126 for (i = 0; i < DIR_FANOUT; i++) {
127 sprintf(filename, "%s/%i", base, i);
128 count += add_count(h, filename, togo-1);
129 }
130 return count;
131 }
133 static void setup(void)
134 {
135 struct xs_handle *h;
137 /* Do setup. */
138 h = xs_daemon_open();
139 if (!h)
140 barf_perror("Contacting daemon");
141 create_dirs(h, "", DIR_DEPTH);
142 xs_daemon_close(h);
143 }
145 static unsigned int tally_counts(void)
146 {
147 struct xs_handle *h;
148 unsigned int ret;
150 h = xs_daemon_open();
151 if (!h)
152 barf_perror("Contacting daemon");
154 ret = add_count(h, "", DIR_DEPTH);
155 xs_daemon_close(h);
156 return ret;
157 }
159 int main(int argc, char *argv[])
160 {
161 unsigned int i;
162 bool failed = false;
163 int kids[10];
165 if (argc != 2)
166 barf("Usage: xs_stress <iterations>");
168 printf("Setting up directories...\n");
169 setup();
171 print = atoi(argv[1]) / 76;
172 if (!print)
173 print = 1;
175 printf("Running %i children...\n", ARRAY_SIZE(kids));
176 for (i = 0; i < ARRAY_SIZE(kids); i++) {
177 kids[i] = fork();
178 if (kids[i] == -1)
179 barf_perror("fork");
180 if (kids[i] == 0) {
181 work(atoi(argv[1]) / ARRAY_SIZE(kids), i);
182 exit(0);
183 }
184 }
186 for (i = 0; i < ARRAY_SIZE(kids); i++) {
187 int status;
188 if (waitpid(kids[i], &status, 0) == -1)
189 barf_perror("waitpid");
190 if (!WIFEXITED(status))
191 barf("Kid %i died via signal %i\n",
192 i, WTERMSIG(status));
193 if (WEXITSTATUS(status) != 0) {
194 printf("Child %i exited %i\n", i, WEXITSTATUS(status));
195 failed = true;
196 }
197 }
198 if (failed)
199 exit(1);
201 printf("\nCounting results...\n");
202 i = tally_counts();
203 if (i != (unsigned)atoi(argv[1]))
204 barf("Total counts %i not %s", i, argv[1]);
205 printf("Success!\n");
206 exit(0);
207 }