Skip to content

Commit 6f109ba

Browse files
Copilotdrzo
andcommitted
Implement core 9P protocol library and filesystem translator structure
Co-authored-by: drzo <15202748+drzo@users.noreply.github.com>
1 parent 6568ec9 commit 6f109ba

14 files changed

Lines changed: 1890 additions & 0 deletions

File tree

9pfs/9pfs.c

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
/* 9pfs.c - Main 9P filesystem translator
2+
*
3+
* Copyright (C) 2024 Free Software Foundation, Inc.
4+
*
5+
* This file implements the main entry point and initialization
6+
* for the 9P filesystem translator for GNU Hurd.
7+
*/
8+
9+
#include "9pfs.h"
10+
#include <argp.h>
11+
#include <error.h>
12+
#include <stdlib.h>
13+
#include <string.h>
14+
15+
/* Global variables */
16+
struct p9_connection *p9_conn = NULL;
17+
struct p9_namespace *p9_ns = NULL;
18+
char *p9_server_addr = NULL;
19+
int p9_server_port = 564; /* Default 9P port */
20+
char *p9_username = "root";
21+
char *p9_attach_name = "";
22+
23+
/* Command line options */
24+
static const struct argp_option options[] =
25+
{
26+
{"server", 's', "ADDRESS", 0, "9P server address", 0},
27+
{"port", 'p', "PORT", 0, "9P server port (default: 564)", 0},
28+
{"user", 'u', "USER", 0, "Username for 9P connection", 0},
29+
{"attach", 'a', "NAME", 0, "Attachment name", 0},
30+
{0}
31+
};
32+
33+
static const char doc[] = "9P filesystem translator for GNU Hurd";
34+
static const char args_doc[] = "UNDERLYING";
35+
36+
/* Parse command line arguments */
37+
static error_t
38+
parse_opt(int key, char *arg, struct argp_state *state)
39+
{
40+
switch (key)
41+
{
42+
case 's':
43+
p9_server_addr = strdup(arg);
44+
break;
45+
case 'p':
46+
p9_server_port = atoi(arg);
47+
break;
48+
case 'u':
49+
p9_username = strdup(arg);
50+
break;
51+
case 'a':
52+
p9_attach_name = strdup(arg);
53+
break;
54+
case ARGP_KEY_ARG:
55+
if (state->arg_num >= 1)
56+
argp_usage(state);
57+
/* Store underlying node - not used in this implementation */
58+
break;
59+
case ARGP_KEY_NO_ARGS:
60+
if (!p9_server_addr)
61+
argp_error(state, "server address is required");
62+
break;
63+
default:
64+
return ARGP_ERR_UNKNOWN;
65+
}
66+
return 0;
67+
}
68+
69+
static const struct argp argp = { options, parse_opt, args_doc, doc };
70+
71+
/* Initialize the 9P filesystem */
72+
error_t
73+
p9fs_init(void)
74+
{
75+
error_t err;
76+
struct p9_fid *root_fid;
77+
78+
/* Create namespace */
79+
p9_ns = p9_namespace_create();
80+
if (!p9_ns)
81+
return p9_to_hurd_error(p9_errno);
82+
83+
/* Connect to 9P server */
84+
p9_conn = p9_connect(p9_server_addr, p9_server_port);
85+
if (!p9_conn) {
86+
p9_namespace_destroy(p9_ns);
87+
return p9_to_hurd_error(p9_errno);
88+
}
89+
90+
/* Negotiate protocol version */
91+
if (p9_version(p9_conn, P9_VERSION, 8192) < 0) {
92+
err = p9_to_hurd_error(p9_errno);
93+
goto cleanup;
94+
}
95+
96+
/* Attach to filesystem root */
97+
root_fid = p9_attach(p9_conn, p9_username, p9_attach_name);
98+
if (!root_fid) {
99+
err = p9_to_hurd_error(p9_errno);
100+
goto cleanup;
101+
}
102+
103+
/* Create root netfs node */
104+
netfs_root_node = p9fs_make_node(root_fid);
105+
if (!netfs_root_node) {
106+
p9_clunk(root_fid);
107+
err = ENOMEM;
108+
goto cleanup;
109+
}
110+
111+
return 0;
112+
113+
cleanup:
114+
p9_disconnect(p9_conn);
115+
p9_namespace_destroy(p9_ns);
116+
return err;
117+
}
118+
119+
/* Shutdown the 9P filesystem */
120+
void
121+
p9fs_shutdown(void)
122+
{
123+
if (p9_conn) {
124+
p9_disconnect(p9_conn);
125+
p9_conn = NULL;
126+
}
127+
128+
if (p9_ns) {
129+
p9_namespace_destroy(p9_ns);
130+
p9_ns = NULL;
131+
}
132+
}
133+
134+
/* Convert 9P errors to Hurd errors */
135+
error_t
136+
p9_to_hurd_error(int p9_error)
137+
{
138+
switch (p9_error) {
139+
case 0:
140+
return 0;
141+
case P9_EIO:
142+
return EIO;
143+
case P9_EPROTO:
144+
return EPROTO;
145+
case P9_ENOMEM:
146+
return ENOMEM;
147+
case P9_EINVAL:
148+
return EINVAL;
149+
case P9_ENOENT:
150+
return ENOENT;
151+
case P9_EACCES:
152+
return EACCES;
153+
case P9_EEXIST:
154+
return EEXIST;
155+
case P9_EISDIR:
156+
return EISDIR;
157+
case P9_ENOTDIR:
158+
return ENOTDIR;
159+
case P9_EMFILE:
160+
return EMFILE;
161+
default:
162+
return EIO;
163+
}
164+
}
165+
166+
/* Convert 9P mode to Hurd mode */
167+
mode_t
168+
p9_to_hurd_mode(uint32_t p9_mode)
169+
{
170+
mode_t mode = 0;
171+
172+
/* File type */
173+
if (p9_mode & P9_DMDIR)
174+
mode |= S_IFDIR;
175+
else
176+
mode |= S_IFREG;
177+
178+
/* Permissions */
179+
mode |= (p9_mode & 0777);
180+
181+
return mode;
182+
}
183+
184+
/* Convert Hurd mode to 9P mode */
185+
uint32_t
186+
hurd_to_p9_mode(mode_t mode)
187+
{
188+
uint32_t p9_mode = 0;
189+
190+
/* File type */
191+
if (S_ISDIR(mode))
192+
p9_mode |= P9_DMDIR;
193+
194+
/* Permissions */
195+
p9_mode |= (mode & 0777);
196+
197+
return p9_mode;
198+
}
199+
200+
/* Main function */
201+
int
202+
main(int argc, char **argv)
203+
{
204+
error_t err;
205+
206+
/* Parse arguments */
207+
argp_parse(&argp, argc, argv, 0, 0, 0);
208+
209+
/* Set default server if not specified */
210+
if (!p9_server_addr)
211+
p9_server_addr = "localhost";
212+
213+
/* Initialize netfs */
214+
netfs_init();
215+
216+
/* Initialize 9P filesystem */
217+
err = p9fs_init();
218+
if (err)
219+
error(1, err, "cannot initialize 9P filesystem");
220+
221+
/* Set up signal handlers for clean shutdown */
222+
signal(SIGINT, (void (*)(int))p9fs_shutdown);
223+
signal(SIGTERM, (void (*)(int))p9fs_shutdown);
224+
225+
/* Start netfs server */
226+
netfs_server_loop();
227+
228+
/* Cleanup */
229+
p9fs_shutdown();
230+
231+
return 0;
232+
}

9pfs/9pfs.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* 9pfs.h - 9P filesystem translator header
2+
*
3+
* Copyright (C) 2024 Free Software Foundation, Inc.
4+
*
5+
* This file provides the main definitions for the 9P filesystem
6+
* translator for GNU Hurd.
7+
*/
8+
9+
#ifndef _9PFS_H
10+
#define _9PFS_H
11+
12+
#include <hurd/netfs.h>
13+
#include <pthread.h>
14+
#include "9p.h"
15+
16+
/* Node-specific information */
17+
struct netnode
18+
{
19+
/* 9P connection and FID information */
20+
struct p9_connection *conn; /* 9P connection */
21+
struct p9_fid *fid; /* 9P file identifier */
22+
23+
/* File information */
24+
struct p9_qid qid; /* 9P QID */
25+
struct p9_stat stat; /* 9P stat information */
26+
27+
/* Hurd-specific information */
28+
pthread_mutex_t lock; /* Node lock */
29+
int refs; /* Reference count */
30+
31+
/* Caching */
32+
time_t stat_cache_time; /* Last stat update time */
33+
int stat_cache_valid; /* Stat cache validity */
34+
};
35+
36+
/* Global 9P filesystem state */
37+
extern struct p9_connection *p9_conn;
38+
extern struct p9_namespace *p9_ns;
39+
extern char *p9_server_addr;
40+
extern int p9_server_port;
41+
extern char *p9_username;
42+
extern char *p9_attach_name;
43+
44+
/* Function declarations */
45+
error_t p9fs_init(void);
46+
void p9fs_shutdown(void);
47+
48+
/* Node operations */
49+
struct node *p9fs_make_node(struct p9_fid *fid);
50+
void p9fs_free_node(struct node *node);
51+
error_t p9fs_refresh_node(struct node *node);
52+
53+
/* Directory operations */
54+
error_t p9fs_dir_lookup(struct node *dir, const char *name, struct node **node);
55+
error_t p9fs_dir_readdir(struct node *dir, char **entries, size_t *count);
56+
57+
/* File operations */
58+
error_t p9fs_file_read(struct node *node, off_t offset, size_t count,
59+
void *buf, size_t *bytes_read);
60+
error_t p9fs_file_write(struct node *node, off_t offset, size_t count,
61+
const void *buf, size_t *bytes_written);
62+
63+
/* Utility functions */
64+
error_t p9_to_hurd_error(int p9_error);
65+
mode_t p9_to_hurd_mode(uint32_t p9_mode);
66+
uint32_t hurd_to_p9_mode(mode_t mode);
67+
68+
#endif /* _9PFS_H */

9pfs/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Makefile for 9pfs - 9P filesystem translator
2+
#
3+
# This translator provides 9P protocol file system access for GNU Hurd
4+
# using the universal file interface abstraction
5+
6+
dir := 9pfs
7+
makemode := server
8+
9+
target = 9pfs
10+
SRCS = 9pfs.c node.c ops.c netfs.c
11+
12+
# Use Hurd libraries
13+
HURDLIBS = netfs fshelp iohelp ports shouldbeinlibc
14+
LDLIBS += -lpthread
15+
16+
# Include the 9P library
17+
CPPFLAGS += -I../lib9p
18+
9pfs-LDFLAGS = -L../lib9p -l9p
19+
20+
include ../Makeconf

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ lib-subdirs = libshouldbeinlibc libihash libiohelp libports \
4242
libbpf \
4343
libmachdev \
4444
libirqhelp \
45+
lib9p \
4546

4647
# Hurd programs
4748
prog-subdirs = auth proc exec term \

lib9p/9p-auth.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* 9p-auth.c - 9P authentication implementation (stub)
2+
*
3+
* Copyright (C) 2024 Free Software Foundation, Inc.
4+
*/
5+
6+
#include "9p-internal.h"
7+
#include <stdlib.h>
8+
9+
struct p9_auth *
10+
p9_auth_create(const char *method)
11+
{
12+
(void)method;
13+
p9_errno = P9_EPROTO; /* Not implemented yet */
14+
return NULL;
15+
}
16+
17+
void
18+
p9_auth_destroy(struct p9_auth *auth)
19+
{
20+
(void)auth;
21+
}
22+
23+
int
24+
p9_auth_challenge(struct p9_auth *auth, const void *chal, size_t chal_len,
25+
void *resp, size_t *resp_len)
26+
{
27+
(void)auth; (void)chal; (void)chal_len; (void)resp; (void)resp_len;
28+
return -1;
29+
}

0 commit comments

Comments
 (0)