~kris/9p

krisyotam.net

krisyotam.net/reference/pmikkelsen/pmikkelsen.com/plan9/mounting-9p-over-drawterm.html -rw-r--r-- 9.4 KiB
8bfa4b74 — Kris Yotam ci: declare SourceHut source for push builds a month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
<!DOCTYPE HTML>
<html>
<head>

    <title>plan9 - mounting-9p over drawterm</title>
    <style media="screen, handheld">
body { display: flex; flex-wrap: wrap; font-family: sans;}
header { flex-basis: 100%; flex-shrink: 0; }
article { flex-basis: 60%; padding-left: 1em; }
footer { flex-basis: 100%; flex-shrink: 0; }
header nav { display: flex; justify-content: space-between; }
nav a, header a { text-decoration: none ; color: inherit; }
header h1 span { margin-left: 1em; font-size: 50%; font-style: italic; }
.mainContent > nav { flex-basis: content; padding-right: 1vw; min-width: 16em; }
nav ul { display: flex; flex-direction: column; list-style-type: none; list-style-position: outside; padding-left: 0;  }
nav li ul { padding-left: 0.6em }
footer { display: flex; justify-content: space-between; }

/* cut here to leave vanity behind */

body { margin:0; padding: 0; font-size: 84%; font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif; }
a { text-decoration: none; color: }
a:hover { text-decoration: underline; }
.thisPage { color: black; }

/* header and top bar */
header nav { background-color: rgb(100,135,220); color: white; padding: 0.3em; border-bottom: 2px solid black; font-size: 91%; }
header h1 { background-color: #ff6d06; color: black; margin: 0; border-bottom: 2px solid black; font-weight: normal; padding: 0.25ex; font-size: 233%; }
header a:hover { text-decoration: none; }

/* sidebar */
.mainContent > nav { border-right: 1px solid #ddd; padding: 0;  } 
.mainContent > nav > div { border-bottom: 1px solid #ddd; } 
.mainContent > nav > div a { color: rgb(0, 102, 204); display: block; text-transform: capitalize; font-weight: bold; padding: 0.25em 1ex 0.25em 2mm; font-size: 102%} 
.mainContent > nav > div a:hover { color: white; background-color: rgb(100,135,220); border-left: black solid 0.2em; text-decoration: none; }
.mainContent > nav > div p { font-weight: bold; margin: 0 0 0.5em 2mm; padding: 1em 0 0 0; }

/* main copy */
article { padding: 0.5ex 0 5vh 1vw;  }
article h1, article h2 { color: rgb(0,102,204); font-weight: bold; margin: 2em 0 0 0; border-bottom: 2px solid rgb(0,102,204); }
article h3, article h4, article h5 { color: rgb(0,102,204); font-weight: bold; margin: 2em 0 0 0; }
article h6, article h7, article h8 { color: rgb(0,102,204); font-weight: bold; margin: 2em 0 0 0; }
article a { color: rgb(0,102,204); }
article a:hover { color:  rgb(100,135,220); }
article pre { font-size: 1.2em; }

/* footer */
footer { color: white; background-color: rgb(100,135,220); }
footer a { color: inherit; }
footer div { padding: 1em; }

/* tables */
table { border: 1px solid rgba(128,128,128,0.5); padding: 0; }
th { color: white; background-color: rgb(100,135,220); }
tr:nth-child(odd) { background-color: rgba(128,128,128,0.1)  }

/* modifications */
img {
	max-width: 100%;
	border: 1px solid black;
}

body {
	
}

header h1 {
	background-color: #c2d2c6;
}

html {
	font-size: 1.2em;
}

header nav, footer {
	background-color: #442a13;
}

code > pre {
	border: 2px solid #442a13;
	background-color: #c2d2c6;
	width: max-content;
	padding: 0 0.5em;
}

.mainContent > nav > div a, article a:hover {
	color: #442a13;
}

.mainContent > nav > div a:hover {
	color: #442a13;
	background-color: #c2d2c6;
}

article h1, article h2 {
	color: #c48f3b;
	border-bottom: 2px solid #442a13;
}

article a, .thisPage, footer, header nav {
	color: #c48f3b;
}

footer {
	padding: 0.5em;
	flex-shrink: 1;
	flex-basis: unset;
}

header {
	flex-basis: unset;
}

html {
	display: flex;
	min-height: 100%;
}

body {
	flex-direction: column;
	flex: 1;
	background-color: #e3dfd7;
}

.mainContent {
	display: flex;
	flex-grow: 1;
}    </style>
    <link rel="shortcut icon" href="https://images.pmikkelsen.com/favicon.ico" type="image/vnd.microsoft.icon">
    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 



    

</head>
<body>

<header>
    <nav>
    <div class="left">
		<a href="https://pmikkelsen.com">notes</a> |
		<a href="https://git.pmikkelsen.com">git</a> |
		<a href="https://images.pmikkelsen.com">images</a> |
		<a href="https://files.pmikkelsen.com">files</a> |
		<a href="https://prolog.pmikkelsen.com">PProlog</a> |
		<a href="https://apl.pmikkelsen.com">APL9</a> |
		<a href="https://aplwc.org">aplwc</a>
    </div>

    <div class="right">
		<a href="https://git.sr.ht/~pmikkelsen">sourcehut</a> |
		<a href="https://9front.org">9front</a> |
		<a href="https://openbsd.org">OpenBSD</a> |
		<a href="https://dyalog.com">Dyalog</a>
    </div>

    </nav>
    <h1><a href="../index.html">Peter&#39;s website <span id="headerSubTitle">- random notes</span></a></h1>
</header>

<div class=mainContent>
    <nav id="side-bar">
        <div>
<ul>
<li><a href="../APL-and-J/index.html">&rsaquo; APL and J/</a></li>
<li><a href="../OpenBSD/index.html">&rsaquo; OpenBSD/</a></li>
<li><a href="../contact.html">&rsaquo; contact</a></li>
<li><a href="../facts/index.html">&rsaquo; facts/</a></li>
<li><a href="../haskell/index.html">&rsaquo; haskell/</a></li>
<li><a href="../linux/index.html">&rsaquo; linux/</a></li>
<li><a href="../mainframe/index.html">&rsaquo; mainframe/</a></li>
<li><a href="../me/index.html">&rsaquo; me/</a></li>
<li><a href="../opinions/index.html">&rsaquo; opinions/</a></li>
<li><a href="index.html" class="thisPage">&raquo;<i> plan9/</i></a></li>
<li><ul>
<li><a href="basic_9p_server.html">&rsaquo; basic 9p server</a></li>
<li><a href="discord.html">&rsaquo; discord</a></li>
<li><a href="dns.html">&rsaquo; dns</a></li>
<li><a href="fonts.html">&rsaquo; fonts</a></li>
<li><a href="lets_encrypt.html">&rsaquo; lets encrypt</a></li>
<li><a href="mounting-9p-over-drawterm.html" class="thisPage">&raquo;<i> mounting 9p over drawterm</i></a></li>
<li><a href="network_booting.html">&rsaquo; network booting</a></li>
<li><a href="trellofs.html">&rsaquo; trellofs</a></li>
<li><a href="using_irc.html">&rsaquo; using irc</a></li>
<li><a href="webfs-websocket.html">&rsaquo; webfs websocket</a></li>
</ul></li>
<li><a href="../prolog/index.html">&rsaquo; prolog/</a></li>
<li><a href="../web/index.html">&rsaquo; web/</a></li>
</ul>
        </div>
    </nav>

<article>
<h1>Mounting a 9P connection over drawterm</h1>
<p>I sometimes use drawterm on linux to connect to my 9front server. While it is possible to access the host system's files under <code>/mnt/term</code>, there is no builtin way to access the remote system's file under linux. Now, why would anybody want to do this? In my case, I often want to write some code under 9front, but for languages which aren't supported such as prolog in this case, so there are three options as I see it:</p>
<ul>
<li>
Store the files on the host machine, and access them under <code>/mnt/term</code>.
</li><li>
Store the files on the server and somehow mount the server's filesystem on the host.
</li><li>
Store the files on a third machine that both the host and server can access.
</li>
</ul>
<p>Option number two seems best for me, so I asked around and it seems like the best tool to mount a 9P connection on linux is <a href="https://github.com/bunny351/9pfs">9pfs</a>.</p>
<h2>How it works</h2>
<p>Before I could mount the connection, I had to serve it somehow. Normally I already serve 9P directly from my server's filesystem, but that requires some authentication that 9pfs does not support, so I had to serve it without authentication. Serving directly to the internet without authentication is of course pretty dumb since everyone can then access my files, so thanks to a hint from hiro, I figured out that it is actually possible to use the host's network stack on the server by binding <code>/mnt/term/net</code> over <code>/net</code>.</p>
<p>I'll just show the final script below and explain it afterwards:</p>
<code><pre>
#!/bin/rc

rfork n
bind /mnt/term/net /net
aux/listen1 -t tcp!*!12335 /bin/exportfs -r / &amp;
os mkdir -p /tmp/drawterm
os 9pfs localhost -p 12335 /tmp/drawterm
</pre></code>
<p>So the first thing that happens is that I bind the host's network in, and from that point on, every network connection in this namespace actually goes out from the host instead of from the server!</p>
<p>Then <code>exportfs</code> is started and it is serving the <code>/</code> directory over 9P at port 12335. The <code>os</code> command runs a command on the host, so it just creates the folder that the system will be mounted to, and then uses <code>9pfs</code> to actually mount it. The nice thing here is that <code>9pfs</code> just connects to localhost.</p>
<h2>Using it</h2>
<p>As I said in the beginning, I did this to be able to edit files on the 9front server, and run compilers/interpreters on linux. The <code>os</code> command goes a long way, but the following script makes it even easier (I have this installed as <code>linux</code>):</p>
<code><pre>
#!/bin/rc

dir=/tmp/drawterm/`{pwd}
os -d $dir $*
</pre></code>
<p>This means I can just go into any directory on the server, type <code>linux ghci</code> and I get a haskell repl running in the correct directory, as seen in the gif below.</p>

<p><a href="https://images.pmikkelsen.com/linuxreverse.gif" /><img src="https://images.pmikkelsen.com/linuxreverse.gif" alt="An animated gif showing ghci loading a file on the 9front server" /></a></p>
<h2>Final notes</h2>
<p>The bind net trick still blows my mind a bit, since it is so trivial, yet so powerful. It is also fun to think about how one would do this on other systems than plan9, which I can't even imagine.</p>

</article>
</div>

<footer>
<a href="http://werc.cat-v.org">Powered by werc</a> © Peter Mikkelsen 2019-2025
</footer>
</body></html>