xref: /openbmc/qemu/tests/qtest/libqos/virtio-9p-client.h (revision 74a160aba921a2ca37b026dbfcdd03386bc05e85)
1 /*
2  * 9P network client for VirtIO 9P test cases (based on QTest)
3  *
4  * Copyright (c) 2014 SUSE LINUX Products GmbH
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7  * See the COPYING file in the top-level directory.
8  */
9 
10 /*
11  * Not so fast! You might want to read the 9p developer docs first:
12  * https://wiki.qemu.org/Documentation/9p
13  */
14 
15 #ifndef TESTS_LIBQOS_VIRTIO_9P_CLIENT_H
16 #define TESTS_LIBQOS_VIRTIO_9P_CLIENT_H
17 
18 #include "hw/9pfs/9p.h"
19 #include "hw/9pfs/9p-synth.h"
20 #include "virtio-9p.h"
21 #include "qgraph.h"
22 #include "tests/qtest/libqtest-single.h"
23 
24 #define P9_MAX_SIZE 4096 /* Max size of a T-message or R-message */
25 
26 typedef struct {
27     QTestState *qts;
28     QVirtio9P *v9p;
29     uint16_t tag;
30     uint64_t t_msg;
31     uint32_t t_size;
32     uint64_t r_msg;
33     /* No r_size, it is hardcoded to P9_MAX_SIZE */
34     size_t t_off;
35     size_t r_off;
36     uint32_t free_head;
37 } P9Req;
38 
39 /* type[1] version[4] path[8] */
40 typedef char v9fs_qid[13];
41 
42 typedef struct v9fs_attr {
43     uint64_t valid;
44     v9fs_qid qid;
45     uint32_t mode;
46     uint32_t uid;
47     uint32_t gid;
48     uint64_t nlink;
49     uint64_t rdev;
50     uint64_t size;
51     uint64_t blksize;
52     uint64_t blocks;
53     uint64_t atime_sec;
54     uint64_t atime_nsec;
55     uint64_t mtime_sec;
56     uint64_t mtime_nsec;
57     uint64_t ctime_sec;
58     uint64_t ctime_nsec;
59     uint64_t btime_sec;
60     uint64_t btime_nsec;
61     uint64_t gen;
62     uint64_t data_version;
63 } v9fs_attr;
64 
65 #define P9_GETATTR_BASIC    0x000007ffULL /* Mask for fields up to BLOCKS */
66 
67 struct V9fsDirent {
68     v9fs_qid qid;
69     uint64_t offset;
70     uint8_t type;
71     char *name;
72     struct V9fsDirent *next;
73 };
74 
75 /* options for 'Twalk' 9p request */
76 typedef struct TWalkOpt {
77     /* 9P client being used (mandatory) */
78     QVirtio9P *client;
79     /* user supplied tag number being returned with response (optional) */
80     uint16_t tag;
81     /* file ID of directory from where walk should start (optional) */
82     uint32_t fid;
83     /* file ID for target directory being walked to (optional) */
84     uint32_t newfid;
85     /* low level variant of path to walk to (optional) */
86     uint16_t nwname;
87     char **wnames;
88     /* high level variant of path to walk to (optional) */
89     const char *path;
90     /* data being received from 9p server as 'Rwalk' response (optional) */
91     struct {
92         uint16_t *nwqid;
93         v9fs_qid **wqid;
94     } rwalk;
95     /* only send Twalk request but not wait for a reply? (optional) */
96     bool requestOnly;
97     /* do we expect an Rlerror response, if yes which error code? (optional) */
98     uint32_t expectErr;
99 } TWalkOpt;
100 
101 /* result of 'Twalk' 9p request */
102 typedef struct TWalkRes {
103     /* file ID of target directory been walked to */
104     uint32_t newfid;
105     /* if requestOnly was set: request object for further processing */
106     P9Req *req;
107 } TWalkRes;
108 
109 /* options for 'Tversion' 9p request */
110 typedef struct TVersionOpt {
111     /* 9P client being used (mandatory) */
112     QVirtio9P *client;
113     /* user supplied tag number being returned with response (optional) */
114     uint16_t tag;
115     /* maximum message size that can be handled by client (optional) */
116     uint32_t msize;
117     /* protocol version (optional) */
118     const char *version;
119     /* only send Tversion request but not wait for a reply? (optional) */
120     bool requestOnly;
121     /* do we expect an Rlerror response, if yes which error code? (optional) */
122     uint32_t expectErr;
123 } TVersionOpt;
124 
125 /* result of 'Tversion' 9p request */
126 typedef struct TVersionRes {
127     /* if requestOnly was set: request object for further processing */
128     P9Req *req;
129 } TVersionRes;
130 
131 /* options for 'Tattach' 9p request */
132 typedef struct TAttachOpt {
133     /* 9P client being used (mandatory) */
134     QVirtio9P *client;
135     /* user supplied tag number being returned with response (optional) */
136     uint16_t tag;
137     /* file ID to be associated with root of file tree (optional) */
138     uint32_t fid;
139     /* numerical uid of user being introduced to server (optional) */
140     uint32_t n_uname;
141     /* data being received from 9p server as 'Rattach' response (optional) */
142     struct {
143         /* server's idea of the root of the file tree */
144         v9fs_qid *qid;
145     } rattach;
146     /* only send Tattach request but not wait for a reply? (optional) */
147     bool requestOnly;
148     /* do we expect an Rlerror response, if yes which error code? (optional) */
149     uint32_t expectErr;
150 } TAttachOpt;
151 
152 /* result of 'Tattach' 9p request */
153 typedef struct TAttachRes {
154     /* if requestOnly was set: request object for further processing */
155     P9Req *req;
156 } TAttachRes;
157 
158 void v9fs_set_allocator(QGuestAllocator *t_alloc);
159 void v9fs_memwrite(P9Req *req, const void *addr, size_t len);
160 void v9fs_memskip(P9Req *req, size_t len);
161 void v9fs_memread(P9Req *req, void *addr, size_t len);
162 void v9fs_uint8_read(P9Req *req, uint8_t *val);
163 void v9fs_uint16_write(P9Req *req, uint16_t val);
164 void v9fs_uint16_read(P9Req *req, uint16_t *val);
165 void v9fs_uint32_write(P9Req *req, uint32_t val);
166 void v9fs_uint64_write(P9Req *req, uint64_t val);
167 void v9fs_uint32_read(P9Req *req, uint32_t *val);
168 void v9fs_uint64_read(P9Req *req, uint64_t *val);
169 uint16_t v9fs_string_size(const char *string);
170 void v9fs_string_write(P9Req *req, const char *string);
171 void v9fs_string_read(P9Req *req, uint16_t *len, char **string);
172 P9Req *v9fs_req_init(QVirtio9P *v9p, uint32_t size, uint8_t id,
173                      uint16_t tag);
174 void v9fs_req_send(P9Req *req);
175 void v9fs_req_wait_for_reply(P9Req *req, uint32_t *len);
176 void v9fs_req_recv(P9Req *req, uint8_t id);
177 void v9fs_req_free(P9Req *req);
178 void v9fs_rlerror(P9Req *req, uint32_t *err);
179 TVersionRes v9fs_tversion(TVersionOpt);
180 void v9fs_rversion(P9Req *req, uint16_t *len, char **version);
181 TAttachRes v9fs_tattach(TAttachOpt);
182 void v9fs_rattach(P9Req *req, v9fs_qid *qid);
183 TWalkRes v9fs_twalk(TWalkOpt opt);
184 void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid);
185 P9Req *v9fs_tgetattr(QVirtio9P *v9p, uint32_t fid, uint64_t request_mask,
186                      uint16_t tag);
187 void v9fs_rgetattr(P9Req *req, v9fs_attr *attr);
188 P9Req *v9fs_treaddir(QVirtio9P *v9p, uint32_t fid, uint64_t offset,
189                      uint32_t count, uint16_t tag);
190 void v9fs_rreaddir(P9Req *req, uint32_t *count, uint32_t *nentries,
191                    struct V9fsDirent **entries);
192 void v9fs_free_dirents(struct V9fsDirent *e);
193 P9Req *v9fs_tlopen(QVirtio9P *v9p, uint32_t fid, uint32_t flags,
194                    uint16_t tag);
195 void v9fs_rlopen(P9Req *req, v9fs_qid *qid, uint32_t *iounit);
196 P9Req *v9fs_twrite(QVirtio9P *v9p, uint32_t fid, uint64_t offset,
197                    uint32_t count, const void *data, uint16_t tag);
198 void v9fs_rwrite(P9Req *req, uint32_t *count);
199 P9Req *v9fs_tflush(QVirtio9P *v9p, uint16_t oldtag, uint16_t tag);
200 void v9fs_rflush(P9Req *req);
201 P9Req *v9fs_tmkdir(QVirtio9P *v9p, uint32_t dfid, const char *name,
202                    uint32_t mode, uint32_t gid, uint16_t tag);
203 void v9fs_rmkdir(P9Req *req, v9fs_qid *qid);
204 P9Req *v9fs_tlcreate(QVirtio9P *v9p, uint32_t fid, const char *name,
205                      uint32_t flags, uint32_t mode, uint32_t gid,
206                      uint16_t tag);
207 void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit);
208 P9Req *v9fs_tsymlink(QVirtio9P *v9p, uint32_t fid, const char *name,
209                      const char *symtgt, uint32_t gid, uint16_t tag);
210 void v9fs_rsymlink(P9Req *req, v9fs_qid *qid);
211 P9Req *v9fs_tlink(QVirtio9P *v9p, uint32_t dfid, uint32_t fid,
212                   const char *name, uint16_t tag);
213 void v9fs_rlink(P9Req *req);
214 P9Req *v9fs_tunlinkat(QVirtio9P *v9p, uint32_t dirfd, const char *name,
215                       uint32_t flags, uint16_t tag);
216 void v9fs_runlinkat(P9Req *req);
217 
218 #endif
219