mirage/ocaml-xenstore — pull request #4 by jjd27 (2013-02-22 09:56:45+00:00)
Title: [Do not pull] Starting to make behaviour observationally equivalent with oxenstored

Here is the sdiff of two transcripts from xstest [1] showing oxenstored on the left and this version on the right.

0 S: 0(0) READ "\000". 0 S: 0(0) READ "\000".
0 R: 0(0) ERROR "EINVAL\000". 0 R: 0(0) ERROR "EINVAL\000".
1 S: 0(1) WRITE "\000". 1 S: 0(1) WRITE "\000".
1 R: 0(1) ERROR "EINVAL\000". 1 R: 0(1) ERROR "EINVAL\000".
2 S: 0(2) GET_DOMAIN_PATH "\000". 2 S: 0(2) GET_DOMAIN_PATH "\000".
2 R: 0(2) GET_DOMAIN_PATH "/local/domain/0\000". 2 R: 0(2) GET_DOMAIN_PATH "/local/domain/0\000".
3 S: 0(3) DIRECTORY "\000". 3 S: 0(3) DIRECTORY "\000".
3 R: 0(3) ERROR "EINVAL\000". 3 R: 0(3) ERROR "EINVAL\000".
4 S: 0(4) MKDIR "\000". 4 S: 0(4) MKDIR "\000".
4 R: 0(4) ERROR "EINVAL\000". 4 R: 0(4) ERROR "EINVAL\000".
5 S: 0(5) GET_PERMS "\000". 5 S: 0(5) GET_PERMS "\000".
5 R: 0(5) ERROR "EINVAL\000". 5 R: 0(5) ERROR "EINVAL\000".
6 S: 0(6) SET_PERMS "\000". 6 S: 0(6) SET_PERMS "\000".
6 R: 0(6) ERROR "EINVAL\000". 6 R: 0(6) ERROR "EINVAL\000".
7 S: 0(7) WRITE "/test\000xxx\000yyy\000\000zzz". 7 S: 0(7) WRITE "/test\000xxx\000yyy\000\000zzz".
7 R: 0(7) WRITE "OK\000". 7 R: 0(7) WRITE "OK\000".
8 S: 0(8) READ "/test". 8 S: 0(8) READ "/test".
8 R: 0(8) ERROR "EINVAL\000". | 8 R: 0(8) READ "xxx\000yyy\000\000zzz".
9 S: 0(9) READ "/test\000". 9 S: 0(9) READ "/test\000".
9 R: 0(9) READ "xxx\000yyy\000\000zzz". 9 R: 0(9) READ "xxx\000yyy\000\000zzz".
a S: 0(10) READ "/test\000some\000otherargs". a S: 0(10) READ "/test\000some\000otherargs".
a R: 0(10) ERROR "EINVAL\000". a R: 0(10) ERROR "EINVAL\000".
b S: 0(11) DIRECTORY "/test\000spurious\000abc". b S: 0(11) DIRECTORY "/test\000spurious\000abc".
b R: 0(11) ERROR "EINVAL\000". b R: 0(11) ERROR "EINVAL\000".
c S: 0(12) DIRECTORY "/test\000spurious". c S: 0(12) DIRECTORY "/test\000spurious".
c R: 0(12) ERROR "EINVAL\000". c R: 0(12) ERROR "EINVAL\000".
d S: 0(13) GET_PERMS "/test\000someotherargs". d S: 0(13) GET_PERMS "/test\000someotherargs".
d R: 0(13) ERROR "EINVAL\000". d R: 0(13) ERROR "EINVAL\000".
e S: 0(14) GET_PERMS "/test\000someotherargs\000others". e S: 0(14) GET_PERMS "/test\000someotherargs\000others".
e R: 0(14) ERROR "EINVAL\000". e R: 0(14) ERROR "EINVAL\000".
f S: 0(15) WRITE "/test\000". f S: 0(15) WRITE "/test\000".
f R: 0(15) WRITE "OK\000". f R: 0(15) WRITE "OK\000".
10 S: 0(16) WRITE "/test\000abc". 10 S: 0(16) WRITE "/test\000abc".
10 R: 0(16) WRITE "OK\000". 10 R: 0(16) WRITE "OK\000".
11 S: 0(17) READ "/test". 11 S: 0(17) READ "/test".
11 R: 0(17) ERROR "EINVAL\000". | 11 R: 0(17) READ "abc".
12 S: 0(18) READ "/test\000". 12 S: 0(18) READ "/test\000".
12 R: 0(18) READ "abc". 12 R: 0(18) READ "abc".
13 S: 0(19) READ "/test\000\000". 13 S: 0(19) READ "/test\000\000".
13 R: 0(19) ERROR "EINVAL\000". 13 R: 0(19) ERROR "EINVAL\000".
14 S: 0(20) WRITE "/test". 14 S: 0(20) WRITE "/test".
14 R: 0(20) ERROR "EINVAL\000". | 14 R: 0(20) WRITE "OK\000".
15 S: 0(21) READ "/test". 15 S: 0(21) READ "/test".
15 R: 0(21) ERROR "EINVAL\000". | 15 R: 0(21) READ "".
16 S: 0(22) READ "/test\000". 16 S: 0(22) READ "/test\000".
16 R: 0(22) READ "abc". | 16 R: 0(22) READ "".
17 S: 0(23) READ "/test\000\000". 17 S: 0(23) READ "/test\000\000".
17 R: 0(23) ERROR "EINVAL\000". 17 R: 0(23) ERROR "EINVAL\000".
18 S: 0(24) WRITE "\000/". 18 S: 0(24) WRITE "\000/".
18 R: 0(24) ERROR "EINVAL\000". 18 R: 0(24) ERROR "EINVAL\000".
19 S: 0(25) DIRECTORY "/test". 19 S: 0(25) DIRECTORY "/test".
19 R: 0(25) ERROR "EINVAL\000". | 19 R: 0(25) DIRECTORY "abc\000def\000xyz\000".
1a S: 0(26) DIRECTORY "/test\000". 1a S: 0(26) DIRECTORY "/test\000".
1a R: 0(26) DIRECTORY "". | 1a R: 0(26) DIRECTORY "abc\000def\000xyz\000".
1b S: 0(27) DIRECTORY "/test\000\000". 1b S: 0(27) DIRECTORY "/test\000\000".
1b R: 0(27) ERROR "EINVAL\000". 1b R: 0(27) ERROR "EINVAL\000".
1c S: 0(28) RM "/test". 1c S: 0(28) RM "/test".
1c R: 0(28) ERROR "EINVAL\000". | 1c R: 0(28) RM "OK\000".
1d S: 0(29) DIRECTORY "/test". 1d S: 0(29) DIRECTORY "/test".
1d R: 0(29) ERROR "EINVAL\000". | 1d R: 0(29) ERROR "ENOENT\000".
1e S: 0(30) DIRECTORY "/test\000". 1e S: 0(30) DIRECTORY "/test\000".
1e R: 0(30) DIRECTORY "". | 1e R: 0(30) ERROR "ENOENT\000".
1f S: 0(31) DIRECTORY "/test\000\000". 1f S: 0(31) DIRECTORY "/test\000\000".
1f R: 0(31) ERROR "EINVAL\000". 1f R: 0(31) ERROR "EINVAL\000".
20 S: 0(32) WRITE "/test/abc\000x1". 20 S: 0(32) WRITE "/test/abc\000x1".
20 R: 0(32) WRITE "OK\000". 20 R: 0(32) WRITE "OK\000".
21 S: 0(33) WRITE "/test/def\000x2". 21 S: 0(33) WRITE "/test/def\000x2".
21 R: 0(33) WRITE "OK\000". 21 R: 0(33) WRITE "OK\000".
22 S: 0(34) WRITE "/test/xyz\000x3". 22 S: 0(34) WRITE "/test/xyz\000x3".
22 R: 0(34) WRITE "OK\000". 22 R: 0(34) WRITE "OK\000".
23 S: 0(35) WRITE "/test/xyz\000x4". 23 S: 0(35) WRITE "/test/xyz\000x4".
23 R: 0(35) WRITE "OK\000". 23 R: 0(35) WRITE "OK\000".
24 S: 0(36) DIRECTORY "/test". 24 S: 0(36) DIRECTORY "/test".
24 R: 0(36) ERROR "EINVAL\000". | 24 R: 0(36) DIRECTORY "abc\000def\000xyz\000".
25 S: 0(37) DIRECTORY "/test\000". 25 S: 0(37) DIRECTORY "/test\000".
25 R: 0(37) DIRECTORY "abc\000def\000xyz\000". 25 R: 0(37) DIRECTORY "abc\000def\000xyz\000".
26 S: 0(38) DIRECTORY "/test\000spurious\000". 26 S: 0(38) DIRECTORY "/test\000spurious\000".
26 R: 0(38) ERROR "EINVAL\000". 26 R: 0(38) ERROR "EINVAL\000".
27 S: 0(39) GET_PERMS "/test". 27 S: 0(39) GET_PERMS "/test".
27 R: 0(39) ERROR "EINVAL\000". | 27 R: 0(39) GET_PERMS "n0\000".
28 S: 0(40) GET_PERMS "/test\000". 28 S: 0(40) GET_PERMS "/test\000".
28 R: 0(40) GET_PERMS "n0\000". 28 R: 0(40) GET_PERMS "n0\000".
29 S: 0(41) GET_PERMS "/test\000spurious\000". 29 S: 0(41) GET_PERMS "/test\000spurious\000".
29 R: 0(41) ERROR "EINVAL\000". 29 R: 0(41) ERROR "EINVAL\000".
2a S: 0(42) SET_PERMS "/test". 2a S: 0(42) SET_PERMS "/test".
2a R: 0(42) ERROR "EINVAL\000". 2a R: 0(42) ERROR "EINVAL\000".
2b S: 0(43) GET_PERMS "/test\000". 2b S: 0(43) GET_PERMS "/test\000".
2b R: 0(43) GET_PERMS "n0\000". 2b R: 0(43) GET_PERMS "n0\000".
2c S: 0(44) SET_PERMS "/test\000". 2c S: 0(44) SET_PERMS "/test\000".
2c R: 0(44) ERROR "EINVAL\000". 2c R: 0(44) ERROR "EINVAL\000".
2d S: 0(45) GET_PERMS "/test\000". 2d S: 0(45) GET_PERMS "/test\000".
2d R: 0(45) GET_PERMS "n0\000". 2d R: 0(45) GET_PERMS "n0\000".
2e S: 0(46) SET_PERMS "/test\000\000". 2e S: 0(46) SET_PERMS "/test\000\000".
2e R: 0(46) ERROR "EINVAL\000". 2e R: 0(46) ERROR "EINVAL\000".
2f S: 0(47) GET_PERMS "/test\000". 2f S: 0(47) GET_PERMS "/test\000".
2f R: 0(47) GET_PERMS "n0\000". 2f R: 0(47) GET_PERMS "n0\000".
30 S: 0(48) SET_PERMS "/test\000n0\000". 30 S: 0(48) SET_PERMS "/test\000n0\000".
30 R: 0(48) SET_PERMS "OK\000". 30 R: 0(48) SET_PERMS "OK\000".
31 S: 0(49) GET_PERMS "/test\000". 31 S: 0(49) GET_PERMS "/test\000".
31 R: 0(49) GET_PERMS "n0\000". 31 R: 0(49) GET_PERMS "n0\000".
32 S: 0(50) SET_PERMS "/test\000n0". 32 S: 0(50) SET_PERMS "/test\000n0".
32 R: 0(50) ERROR "EINVAL\000". | 32 R: 0(50) SET_PERMS "OK\000".
33 S: 0(51) GET_PERMS "/test\000". 33 S: 0(51) GET_PERMS "/test\000".
33 R: 0(51) GET_PERMS "n0\000". 33 R: 0(51) GET_PERMS "n0\000".
34 S: 0(52) SET_PERMS "/test\000n0\000r1". 34 S: 0(52) SET_PERMS "/test\000n0\000r1".
34 R: 0(52) SET_PERMS "OK\000". 34 R: 0(52) SET_PERMS "OK\000".
35 S: 0(53) GET_PERMS "/test\000". 35 S: 0(53) GET_PERMS "/test\000".
35 R: 0(53) GET_PERMS "n0\000". | 35 R: 0(53) GET_PERMS "n0\000r1\000".
36 S: 0(54) SET_PERMS "/test\000n0\000r1\000". 36 S: 0(54) SET_PERMS "/test\000n0\000r1\000".
36 R: 0(54) SET_PERMS "OK\000". 36 R: 0(54) SET_PERMS "OK\000".
37 S: 0(55) GET_PERMS "/test\000". 37 S: 0(55) GET_PERMS "/test\000".
37 R: 0(55) GET_PERMS "n0\000r1\000". 37 R: 0(55) GET_PERMS "n0\000r1\000".
38 S: 0(56) SET_PERMS "/test\000n0r2\000spurious". 38 S: 0(56) SET_PERMS "/test\000n0r2\000spurious".
38 R: 0(56) ERROR "EINVAL\000". 38 R: 0(56) ERROR "EINVAL\000".
39 S: 0(57) GET_PERMS "/test\000". 39 S: 0(57) GET_PERMS "/test\000".
39 R: 0(57) GET_PERMS "n0\000r1\000". 39 R: 0(57) GET_PERMS "n0\000r1\000".
3a S: 0(58) GET_DOMAIN_PATH "3\000". 3a S: 0(58) GET_DOMAIN_PATH "3\000".
3a R: 0(58) GET_DOMAIN_PATH "/local/domain/3\000". 3a R: 0(58) GET_DOMAIN_PATH "/local/domain/3\000".
3b S: 0(59) GET_DOMAIN_PATH "10\000". 3b S: 0(59) GET_DOMAIN_PATH "10\000".
3b R: 0(59) GET_DOMAIN_PATH "/local/domain/10\000". 3b R: 0(59) GET_DOMAIN_PATH "/local/domain/10\000".
3c S: 0(60) GET_DOMAIN_PATH "13 \000". 3c S: 0(60) GET_DOMAIN_PATH "13 \000".
3c R: 0(60) GET_DOMAIN_PATH "/local/domain/13\000". 3c R: 0(60) GET_DOMAIN_PATH "/local/domain/13\000".
3d S: 0(61) GET_DOMAIN_PATH " 17\000". 3d S: 0(61) GET_DOMAIN_PATH " 17\000".
3d R: 0(61) GET_DOMAIN_PATH "/local/domain/17\000". 3d R: 0(61) GET_DOMAIN_PATH "/local/domain/17\000".
3e S: 0(62) GET_DOMAIN_PATH "45\000spurious". 3e S: 0(62) GET_DOMAIN_PATH "45\000spurious".
3e R: 0(62) ERROR "EINVAL\000". 3e R: 0(62) ERROR "EINVAL\000".
3f S: 0(63) GET_DOMAIN_PATH "45\000really\000". 3f S: 0(63) GET_DOMAIN_PATH "45\000really\000".
3f R: 0(63) ERROR "EINVAL\000". 3f R: 0(63) ERROR "EINVAL\000".
40 S: 0(64) TRANSACTION_START "\000". 40 S: 0(64) TRANSACTION_START "\000".
40 R: 0(64) TRANSACTION_START "1\000". 40 R: 0(64) TRANSACTION_START "1\000".
41 S: 1(65) TRANSACTION_END "\000". 41 S: 1(65) TRANSACTION_END "\000".
41 R: 1(65) ERROR "EINVAL\000". 41 R: 1(65) ERROR "EINVAL\000".
42 S: 0(66) TRANSACTION_START "\000". 42 S: 0(66) TRANSACTION_START "\000".
42 R: 0(66) TRANSACTION_START "2\000". 42 R: 0(66) TRANSACTION_START "2\000".
43 S: 2(67) TRANSACTION_END "2\000". 43 S: 2(67) TRANSACTION_END "2\000".
43 R: 2(67) ERROR "EINVAL\000". 43 R: 2(67) ERROR "EINVAL\000".
44 S: 0(68) TRANSACTION_START "\000\000". 44 S: 0(68) TRANSACTION_START "\000\000".
44 R: 0(68) TRANSACTION_START "3\000". 44 R: 0(68) TRANSACTION_START "3\000".
45 S: 3(69) TRANSACTION_END "0\000\000". 45 S: 3(69) TRANSACTION_END "0\000\000".
45 R: 3(69) ERROR "EINVAL\000". 45 R: 3(69) ERROR "EINVAL\000".

The differences are all to do with the behaviour when strings in requests are NUL-terminated or not.

This patch makes the behaviour of this xenstore match oxenstored according to xstest, but it is a bunch of hacks and is probably not a reasonable solution nor a complete solution, and it has not been tested in anger.

So this patch is not recommended suitable for pulling as-is; it is just some food for thought about making this xenstore observationally equivalent with oxenstored.

[1] https://github.com/xen-org/xen-api/blob/master/ocaml/xstest/xstest.ml