| # Some more complex uses of mount tables and mounts |
| # |
| # TODO - list the examples and any issues. |
| |
| cache off |
| |
| root |
| eval $_ |
| set root=$MT_NAME |
| |
| set NAMESPACE_ROOT=$root |
| mt tl/a |
| set m=$_ |
| eval $m |
| eval $m |
| set mt_a_name=$MT_NAME |
| set mt_a_addr=$MT_ADDR |
| |
| mt tl/b |
| set m=$_ |
| eval $m |
| eval $m |
| set mt_b_name=$MT_NAME |
| set mt_b_addr=$MT_ADDR |
| |
| setRoots $root |
| |
| # |
| # Using glob 'correctly' takes some care. There are (at least?) three |
| # forms that you need to consider... |
| # |
| |
| # ls ... finds all of the mount points, as relative names |
| ls ... |
| set l=$_ |
| eval $l |
| assert $RN 3 |
| wait $l |
| |
| # ls /... does not.. - it just finds itself... seems a little weird. |
| ls /... |
| set l=$_ |
| eval $l |
| assert $RN 1 |
| wait $l |
| |
| # a rooted glob finds all of the mount points, include an entry for the root |
| # itself. It returns rooted names. |
| ls $root/... |
| set l=$_ |
| eval $l |
| assert $RN 4 |
| wait $l |
| |
| resolve tl/a |
| set r=$_ |
| eval $r |
| assert $RN 1 |
| eval $r |
| assert $R0 $mt_a_name |
| wait $r |
| |
| # |
| # Now, let's run some echo servers, invoke rpc's on them, see what |
| # glob and resolve do. |
| # |
| |
| # run an echo server on tl. |
| echoServer "E1" tl |
| set es_E1=$_ |
| read $es_E1 |
| eval $es_E1 |
| set es_E1_addr=$ADDR |
| |
| # the echo server above, obscures the mount tables below it. |
| # each of the ls (i.e. glob) calls below will lead to 'ipc:unknown method' |
| # errors generated by the echo server. |
| ls ... |
| set l=$_ |
| eval $l |
| assert $RN 1 |
| |
| ls $root/... |
| set l=$_ |
| eval $l |
| assert $RN 2 |
| |
| echoClient tl test |
| read $_ o |
| assert $o "E1: test" |
| |
| # resolve will find the address of the echo server. |
| resolve tl |
| set r=$_ |
| eval $r |
| assert $RN 1 |
| eval $r |
| assert $R0 /$es_E1_addr// |
| |
| # let's have the echo server shut down |
| wait $es_E1 |
| |
| # and now, we can see the mount tables again. |
| ls ... |
| set l=$_ |
| eval $l |
| assert $RN 3 |
| wait $l |
| |
| resolve tl/a |
| set r=$_ |
| eval $r |
| assert $RN 1 |
| eval $r |
| assert $R0 $mt_a_name |
| |
| # run an echo server on tl/a |
| echoServer "E2" tl/a |
| set es_E2=$_ |
| read $es_E2 |
| eval $es_E2 |
| read $es_E2 |
| set es_E2_addr=$ADDR |
| |
| # we can invoke the echo server 'E2' just fine, probably because |
| # we just get lucky and get the most recently mounted address back first. |
| echoClient "tl/a" bar |
| read $_ o |
| assert $o "E2: bar" |
| |
| # but, when we resolve it's name, we get back two servers, one for the |
| # mount table and another for the server! |
| resolve tl/a |
| set r=$_ |
| eval $r |
| assert $RN 2 |
| eval $r |
| assert $R0 /$es_E2_addr// |
| eval $r |
| assert $R1 $mt_a_name |
| |
| # resolveMT correctly returns the root's address. |
| resolveMT tl/a |
| set r=$_ |
| eval $r |
| assert $RN 1 |
| eval $r |
| assert $R0 $root//tl/a |
| |
| # |
| # NOTE: I propose to fix the above ambiguity by having resolve only |
| # ever return non-mountpoint servers. To do so, requires that the mount table |
| # can tell them apart, which requires the separate Mount and MountMT calls. |
| # |
| |
| # Mount the same server somewhere else |
| mount tl/a/c /$es_E2_addr// 1h |
| wait $_ |
| |
| ls ... |
| wait $_ |
| |
| # this leads to 1 call of ResolveStep for //c on the echo server. |
| resolve tl/a/c |
| wait $_ |
| |
| # this leads to 2 calls of ResolveStep for //c on the echo server. |
| echoClient tl/a/c baz |
| read $_ o |
| assert $o "E2: baz" |
| |
| # |
| # Can the spurious calls to ResolveStep above be avoided?? |
| # |
| |
| # Mount the same server with a really long name. |
| set long_name=tl/b/x/y/z/really/long |
| mount $long_name /$es_E2_addr// 1h |
| wait $_ |
| |
| echoClient $long_name "long baz" |
| read $_ o |
| assert $o "E2: long baz" |
| |
| # This example just creates a 'pointer' into the Echo servers name space. |
| # NOTE: do we really need this functionality? |
| # |
| # ResolveStep is again called on the server for //tl/b/x/y/z/really/long |
| mount tl/b/short1 /$es_E2_addr/$long_name 1h |
| wait $_ |
| |
| echoClient tl/b/short1 "short baz" |
| read $_ o |
| assert $o E2.${long_name}": short baz" |
| |
| # Create a mount table with a 'long' name |
| set long_name=tl/b/some/deep/name/that/is/a/mount/table |
| mt $long_name |
| set m=$_ |
| eval $m |
| eval $m |
| set mt_l_name=$MT_NAME |
| set mt_l_addr=$MT_ADDR |
| |
| |
| # Create a second mount table with a 'long' name |
| set second_long_name=tl/a/some/deep/name/that/is/a/mount/table |
| mt $second_long_name |
| set m=$_ |
| eval $m |
| eval $m |
| set mt_l2_name=$MT_NAME |
| set mt_l2_addr=$MT_ADDR |
| |
| # Run an echo server that uses that mount table |
| echoServer "E3" $long_name/echo |
| set es_E3=$_ |
| read $es_E3 |
| eval $es_E3 |
| set es_E3_addr=$ADDR |
| |
| echoClient $long_name/echo "long E3" |
| read $_ o |
| assert $o "E3: long E3" |
| |
| # make sure that the mount table is the one we expect. |
| resolveMT $long_name/echo |
| set r=$_ |
| eval $r |
| assert $RN 1 |
| eval $r |
| assert $R0 /$mt_l_addr//echo |
| |
| # Now, use mount directly to create a 'symlink' |
| set symlink_target=some/deep/name/that/is/a/mount |
| mount tl/b/symlink /$mt_b_addr/$symlink_target 1h |
| wait $_ |
| |
| ls -l tl/b/symlink |
| wait $_ |
| |
| resolve tl/b/symlink |
| set r=$_ |
| eval $r |
| # returns nothing since symlink is an 'interior' node. |
| assert $RN 0 |
| |
| # resolveMT will return the original mount point |
| resolveMT tl/b/symlink |
| set r=$_ |
| eval $r |
| assert $RN 1 |
| eval $r |
| assert $R0 /$mt_b_addr//$symlink_target |
| |