root / hw / virtio-9p-local.c @ 10b468bd
History | View | Annotate | Download (13.3 kB)
1 | 9f107513 | Anthony Liguori | /*
|
---|---|---|---|
2 | 9f107513 | Anthony Liguori | * Virtio 9p Posix callback
|
3 | 9f107513 | Anthony Liguori | *
|
4 | 9f107513 | Anthony Liguori | * Copyright IBM, Corp. 2010
|
5 | 9f107513 | Anthony Liguori | *
|
6 | 9f107513 | Anthony Liguori | * Authors:
|
7 | 9f107513 | Anthony Liguori | * Anthony Liguori <aliguori@us.ibm.com>
|
8 | 9f107513 | Anthony Liguori | *
|
9 | 9f107513 | Anthony Liguori | * This work is licensed under the terms of the GNU GPL, version 2. See
|
10 | 9f107513 | Anthony Liguori | * the COPYING file in the top-level directory.
|
11 | 9f107513 | Anthony Liguori | *
|
12 | 9f107513 | Anthony Liguori | */
|
13 | 9f107513 | Anthony Liguori | #include "virtio.h" |
14 | 9f107513 | Anthony Liguori | #include "virtio-9p.h" |
15 | c494dd6f | Anthony Liguori | #include <arpa/inet.h> |
16 | 131dcb25 | Anthony Liguori | #include <pwd.h> |
17 | 131dcb25 | Anthony Liguori | #include <grp.h> |
18 | c494dd6f | Anthony Liguori | #include <sys/socket.h> |
19 | c494dd6f | Anthony Liguori | #include <sys/un.h> |
20 | 758e8e38 | Venkateswararao Jujjuri (JV) | #include <attr/xattr.h> |
21 | 131dcb25 | Anthony Liguori | |
22 | 131dcb25 | Anthony Liguori | static const char *rpath(FsContext *ctx, const char *path) |
23 | 131dcb25 | Anthony Liguori | { |
24 | 131dcb25 | Anthony Liguori | /* FIXME: so wrong... */
|
25 | 131dcb25 | Anthony Liguori | static char buffer[4096]; |
26 | 131dcb25 | Anthony Liguori | snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path); |
27 | 131dcb25 | Anthony Liguori | return buffer;
|
28 | 131dcb25 | Anthony Liguori | } |
29 | 131dcb25 | Anthony Liguori | |
30 | 1237ad76 | Venkateswararao Jujjuri (JV) | |
31 | 1237ad76 | Venkateswararao Jujjuri (JV) | static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf) |
32 | 131dcb25 | Anthony Liguori | { |
33 | 1237ad76 | Venkateswararao Jujjuri (JV) | int err;
|
34 | 1237ad76 | Venkateswararao Jujjuri (JV) | err = lstat(rpath(fs_ctx, path), stbuf); |
35 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (err) {
|
36 | 1237ad76 | Venkateswararao Jujjuri (JV) | return err;
|
37 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
38 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
39 | 1237ad76 | Venkateswararao Jujjuri (JV) | /* Actual credentials are part of extended attrs */
|
40 | 1237ad76 | Venkateswararao Jujjuri (JV) | uid_t tmp_uid; |
41 | 1237ad76 | Venkateswararao Jujjuri (JV) | gid_t tmp_gid; |
42 | 1237ad76 | Venkateswararao Jujjuri (JV) | mode_t tmp_mode; |
43 | 1237ad76 | Venkateswararao Jujjuri (JV) | dev_t tmp_dev; |
44 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (getxattr(rpath(fs_ctx, path), "user.virtfs.uid", &tmp_uid, |
45 | 1237ad76 | Venkateswararao Jujjuri (JV) | sizeof(uid_t)) > 0) { |
46 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_uid = tmp_uid; |
47 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
48 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (getxattr(rpath(fs_ctx, path), "user.virtfs.gid", &tmp_gid, |
49 | 1237ad76 | Venkateswararao Jujjuri (JV) | sizeof(gid_t)) > 0) { |
50 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_gid = tmp_gid; |
51 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
52 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (getxattr(rpath(fs_ctx, path), "user.virtfs.mode", &tmp_mode, |
53 | 1237ad76 | Venkateswararao Jujjuri (JV) | sizeof(mode_t)) > 0) { |
54 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_mode = tmp_mode; |
55 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
56 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (getxattr(rpath(fs_ctx, path), "user.virtfs.rdev", &tmp_dev, |
57 | 1237ad76 | Venkateswararao Jujjuri (JV) | sizeof(dev_t)) > 0) { |
58 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_rdev = tmp_dev; |
59 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
60 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
61 | 1237ad76 | Venkateswararao Jujjuri (JV) | return err;
|
62 | 131dcb25 | Anthony Liguori | } |
63 | 131dcb25 | Anthony Liguori | |
64 | 758e8e38 | Venkateswararao Jujjuri (JV) | static int local_set_xattr(const char *path, FsCred *credp) |
65 | 131dcb25 | Anthony Liguori | { |
66 | 758e8e38 | Venkateswararao Jujjuri (JV) | int err;
|
67 | 758e8e38 | Venkateswararao Jujjuri (JV) | if (credp->fc_uid != -1) { |
68 | 758e8e38 | Venkateswararao Jujjuri (JV) | err = setxattr(path, "user.virtfs.uid", &credp->fc_uid, sizeof(uid_t), |
69 | 758e8e38 | Venkateswararao Jujjuri (JV) | 0);
|
70 | 758e8e38 | Venkateswararao Jujjuri (JV) | if (err) {
|
71 | 758e8e38 | Venkateswararao Jujjuri (JV) | return err;
|
72 | 758e8e38 | Venkateswararao Jujjuri (JV) | } |
73 | 131dcb25 | Anthony Liguori | } |
74 | 758e8e38 | Venkateswararao Jujjuri (JV) | if (credp->fc_gid != -1) { |
75 | 758e8e38 | Venkateswararao Jujjuri (JV) | err = setxattr(path, "user.virtfs.gid", &credp->fc_gid, sizeof(gid_t), |
76 | 758e8e38 | Venkateswararao Jujjuri (JV) | 0);
|
77 | 758e8e38 | Venkateswararao Jujjuri (JV) | if (err) {
|
78 | 758e8e38 | Venkateswararao Jujjuri (JV) | return err;
|
79 | 758e8e38 | Venkateswararao Jujjuri (JV) | } |
80 | 131dcb25 | Anthony Liguori | } |
81 | 758e8e38 | Venkateswararao Jujjuri (JV) | if (credp->fc_mode != -1) { |
82 | 758e8e38 | Venkateswararao Jujjuri (JV) | err = setxattr(path, "user.virtfs.mode", &credp->fc_mode,
|
83 | 758e8e38 | Venkateswararao Jujjuri (JV) | sizeof(mode_t), 0); |
84 | 758e8e38 | Venkateswararao Jujjuri (JV) | if (err) {
|
85 | 758e8e38 | Venkateswararao Jujjuri (JV) | return err;
|
86 | 758e8e38 | Venkateswararao Jujjuri (JV) | } |
87 | 131dcb25 | Anthony Liguori | } |
88 | 758e8e38 | Venkateswararao Jujjuri (JV) | if (credp->fc_rdev != -1) { |
89 | 758e8e38 | Venkateswararao Jujjuri (JV) | err = setxattr(path, "user.virtfs.rdev", &credp->fc_rdev,
|
90 | 758e8e38 | Venkateswararao Jujjuri (JV) | sizeof(dev_t), 0); |
91 | 758e8e38 | Venkateswararao Jujjuri (JV) | if (err) {
|
92 | 758e8e38 | Venkateswararao Jujjuri (JV) | return err;
|
93 | 758e8e38 | Venkateswararao Jujjuri (JV) | } |
94 | 131dcb25 | Anthony Liguori | } |
95 | 131dcb25 | Anthony Liguori | return 0; |
96 | 131dcb25 | Anthony Liguori | } |
97 | 131dcb25 | Anthony Liguori | |
98 | 4750a96f | Venkateswararao Jujjuri (JV) | static int local_post_create_passthrough(FsContext *fs_ctx, const char *path, |
99 | 4750a96f | Venkateswararao Jujjuri (JV) | FsCred *credp) |
100 | 4750a96f | Venkateswararao Jujjuri (JV) | { |
101 | 4750a96f | Venkateswararao Jujjuri (JV) | if (chmod(rpath(fs_ctx, path), credp->fc_mode & 07777) < 0) { |
102 | 4750a96f | Venkateswararao Jujjuri (JV) | return -1; |
103 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
104 | 4750a96f | Venkateswararao Jujjuri (JV) | if (chown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid) < 0) { |
105 | 4750a96f | Venkateswararao Jujjuri (JV) | return -1; |
106 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
107 | 4750a96f | Venkateswararao Jujjuri (JV) | return 0; |
108 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
109 | 4750a96f | Venkateswararao Jujjuri (JV) | |
110 | 879c2813 | Venkateswararao Jujjuri (JV) | static ssize_t local_readlink(FsContext *fs_ctx, const char *path, |
111 | 879c2813 | Venkateswararao Jujjuri (JV) | char *buf, size_t bufsz)
|
112 | 131dcb25 | Anthony Liguori | { |
113 | 879c2813 | Venkateswararao Jujjuri (JV) | ssize_t tsize = -1;
|
114 | 879c2813 | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
115 | 879c2813 | Venkateswararao Jujjuri (JV) | int fd;
|
116 | 879c2813 | Venkateswararao Jujjuri (JV) | fd = open(rpath(fs_ctx, path), O_RDONLY); |
117 | 879c2813 | Venkateswararao Jujjuri (JV) | if (fd == -1) { |
118 | 879c2813 | Venkateswararao Jujjuri (JV) | return -1; |
119 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
120 | 879c2813 | Venkateswararao Jujjuri (JV) | do {
|
121 | 879c2813 | Venkateswararao Jujjuri (JV) | tsize = read(fd, (void *)buf, bufsz);
|
122 | 879c2813 | Venkateswararao Jujjuri (JV) | } while (tsize == -1 && errno == EINTR); |
123 | 879c2813 | Venkateswararao Jujjuri (JV) | close(fd); |
124 | 879c2813 | Venkateswararao Jujjuri (JV) | return tsize;
|
125 | 879c2813 | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
126 | 879c2813 | Venkateswararao Jujjuri (JV) | tsize = readlink(rpath(fs_ctx, path), buf, bufsz); |
127 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
128 | 879c2813 | Venkateswararao Jujjuri (JV) | return tsize;
|
129 | 131dcb25 | Anthony Liguori | } |
130 | 131dcb25 | Anthony Liguori | |
131 | 131dcb25 | Anthony Liguori | static int local_close(FsContext *ctx, int fd) |
132 | 131dcb25 | Anthony Liguori | { |
133 | 131dcb25 | Anthony Liguori | return close(fd);
|
134 | 131dcb25 | Anthony Liguori | } |
135 | 131dcb25 | Anthony Liguori | |
136 | 131dcb25 | Anthony Liguori | static int local_closedir(FsContext *ctx, DIR *dir) |
137 | 131dcb25 | Anthony Liguori | { |
138 | 131dcb25 | Anthony Liguori | return closedir(dir);
|
139 | 131dcb25 | Anthony Liguori | } |
140 | 9f107513 | Anthony Liguori | |
141 | a6568fe2 | Anthony Liguori | static int local_open(FsContext *ctx, const char *path, int flags) |
142 | a6568fe2 | Anthony Liguori | { |
143 | a6568fe2 | Anthony Liguori | return open(rpath(ctx, path), flags);
|
144 | a6568fe2 | Anthony Liguori | } |
145 | a6568fe2 | Anthony Liguori | |
146 | a6568fe2 | Anthony Liguori | static DIR *local_opendir(FsContext *ctx, const char *path) |
147 | a6568fe2 | Anthony Liguori | { |
148 | a6568fe2 | Anthony Liguori | return opendir(rpath(ctx, path));
|
149 | a6568fe2 | Anthony Liguori | } |
150 | a6568fe2 | Anthony Liguori | |
151 | a9231555 | Anthony Liguori | static void local_rewinddir(FsContext *ctx, DIR *dir) |
152 | a9231555 | Anthony Liguori | { |
153 | a9231555 | Anthony Liguori | return rewinddir(dir);
|
154 | a9231555 | Anthony Liguori | } |
155 | a9231555 | Anthony Liguori | |
156 | a9231555 | Anthony Liguori | static off_t local_telldir(FsContext *ctx, DIR *dir)
|
157 | a9231555 | Anthony Liguori | { |
158 | a9231555 | Anthony Liguori | return telldir(dir);
|
159 | a9231555 | Anthony Liguori | } |
160 | a9231555 | Anthony Liguori | |
161 | a9231555 | Anthony Liguori | static struct dirent *local_readdir(FsContext *ctx, DIR *dir) |
162 | a9231555 | Anthony Liguori | { |
163 | a9231555 | Anthony Liguori | return readdir(dir);
|
164 | a9231555 | Anthony Liguori | } |
165 | a9231555 | Anthony Liguori | |
166 | a9231555 | Anthony Liguori | static void local_seekdir(FsContext *ctx, DIR *dir, off_t off) |
167 | a9231555 | Anthony Liguori | { |
168 | a9231555 | Anthony Liguori | return seekdir(dir, off);
|
169 | a9231555 | Anthony Liguori | } |
170 | a9231555 | Anthony Liguori | |
171 | a9231555 | Anthony Liguori | static ssize_t local_readv(FsContext *ctx, int fd, const struct iovec *iov, |
172 | a9231555 | Anthony Liguori | int iovcnt)
|
173 | a9231555 | Anthony Liguori | { |
174 | a9231555 | Anthony Liguori | return readv(fd, iov, iovcnt);
|
175 | a9231555 | Anthony Liguori | } |
176 | a9231555 | Anthony Liguori | |
177 | a9231555 | Anthony Liguori | static off_t local_lseek(FsContext *ctx, int fd, off_t offset, int whence) |
178 | a9231555 | Anthony Liguori | { |
179 | a9231555 | Anthony Liguori | return lseek(fd, offset, whence);
|
180 | a9231555 | Anthony Liguori | } |
181 | a9231555 | Anthony Liguori | |
182 | 8449360c | Anthony Liguori | static ssize_t local_writev(FsContext *ctx, int fd, const struct iovec *iov, |
183 | 8449360c | Anthony Liguori | int iovcnt)
|
184 | 8449360c | Anthony Liguori | { |
185 | 8449360c | Anthony Liguori | return writev(fd, iov, iovcnt);
|
186 | 8449360c | Anthony Liguori | } |
187 | 8449360c | Anthony Liguori | |
188 | e95ead32 | Venkateswararao Jujjuri (JV) | static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp) |
189 | c494dd6f | Anthony Liguori | { |
190 | e95ead32 | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
191 | e95ead32 | Venkateswararao Jujjuri (JV) | return local_set_xattr(rpath(fs_ctx, path), credp);
|
192 | e95ead32 | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
193 | e95ead32 | Venkateswararao Jujjuri (JV) | return chmod(rpath(fs_ctx, path), credp->fc_mode);
|
194 | e95ead32 | Venkateswararao Jujjuri (JV) | } |
195 | e95ead32 | Venkateswararao Jujjuri (JV) | return -1; |
196 | c494dd6f | Anthony Liguori | } |
197 | c494dd6f | Anthony Liguori | |
198 | 1c293312 | Venkateswararao Jujjuri (JV) | static int local_mknod(FsContext *fs_ctx, const char *path, FsCred *credp) |
199 | c494dd6f | Anthony Liguori | { |
200 | 1c293312 | Venkateswararao Jujjuri (JV) | int err = -1; |
201 | 1c293312 | Venkateswararao Jujjuri (JV) | int serrno = 0; |
202 | 1c293312 | Venkateswararao Jujjuri (JV) | |
203 | 1c293312 | Venkateswararao Jujjuri (JV) | /* Determine the security model */
|
204 | 1c293312 | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
205 | 1c293312 | Venkateswararao Jujjuri (JV) | err = mknod(rpath(fs_ctx, path), SM_LOCAL_MODE_BITS|S_IFREG, 0);
|
206 | 1c293312 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
207 | 1c293312 | Venkateswararao Jujjuri (JV) | return err;
|
208 | 1c293312 | Venkateswararao Jujjuri (JV) | } |
209 | 1c293312 | Venkateswararao Jujjuri (JV) | local_set_xattr(rpath(fs_ctx, path), credp); |
210 | 1c293312 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
211 | 1c293312 | Venkateswararao Jujjuri (JV) | serrno = errno; |
212 | 1c293312 | Venkateswararao Jujjuri (JV) | goto err_end;
|
213 | 1c293312 | Venkateswararao Jujjuri (JV) | } |
214 | 1c293312 | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
215 | 1c293312 | Venkateswararao Jujjuri (JV) | err = mknod(rpath(fs_ctx, path), credp->fc_mode, credp->fc_rdev); |
216 | 1c293312 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
217 | 1c293312 | Venkateswararao Jujjuri (JV) | return err;
|
218 | 1c293312 | Venkateswararao Jujjuri (JV) | } |
219 | 1c293312 | Venkateswararao Jujjuri (JV) | err = local_post_create_passthrough(fs_ctx, path, credp); |
220 | 1c293312 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
221 | 1c293312 | Venkateswararao Jujjuri (JV) | serrno = errno; |
222 | 1c293312 | Venkateswararao Jujjuri (JV) | goto err_end;
|
223 | 1c293312 | Venkateswararao Jujjuri (JV) | } |
224 | 1c293312 | Venkateswararao Jujjuri (JV) | } |
225 | 1c293312 | Venkateswararao Jujjuri (JV) | return err;
|
226 | 1c293312 | Venkateswararao Jujjuri (JV) | |
227 | 1c293312 | Venkateswararao Jujjuri (JV) | err_end:
|
228 | 1c293312 | Venkateswararao Jujjuri (JV) | remove(rpath(fs_ctx, path)); |
229 | 1c293312 | Venkateswararao Jujjuri (JV) | errno = serrno; |
230 | 1c293312 | Venkateswararao Jujjuri (JV) | return err;
|
231 | c494dd6f | Anthony Liguori | } |
232 | c494dd6f | Anthony Liguori | |
233 | 00ec5c37 | Venkateswararao Jujjuri (JV) | static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp) |
234 | c494dd6f | Anthony Liguori | { |
235 | 00ec5c37 | Venkateswararao Jujjuri (JV) | int err = -1; |
236 | 00ec5c37 | Venkateswararao Jujjuri (JV) | int serrno = 0; |
237 | 00ec5c37 | Venkateswararao Jujjuri (JV) | |
238 | 00ec5c37 | Venkateswararao Jujjuri (JV) | /* Determine the security model */
|
239 | 00ec5c37 | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
240 | 00ec5c37 | Venkateswararao Jujjuri (JV) | err = mkdir(rpath(fs_ctx, path), SM_LOCAL_DIR_MODE_BITS); |
241 | 00ec5c37 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
242 | 00ec5c37 | Venkateswararao Jujjuri (JV) | return err;
|
243 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } |
244 | 00ec5c37 | Venkateswararao Jujjuri (JV) | credp->fc_mode = credp->fc_mode|S_IFDIR; |
245 | 00ec5c37 | Venkateswararao Jujjuri (JV) | err = local_set_xattr(rpath(fs_ctx, path), credp); |
246 | 00ec5c37 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
247 | 00ec5c37 | Venkateswararao Jujjuri (JV) | serrno = errno; |
248 | 00ec5c37 | Venkateswararao Jujjuri (JV) | goto err_end;
|
249 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } |
250 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
251 | 00ec5c37 | Venkateswararao Jujjuri (JV) | err = mkdir(rpath(fs_ctx, path), credp->fc_mode); |
252 | 00ec5c37 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
253 | 00ec5c37 | Venkateswararao Jujjuri (JV) | return err;
|
254 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } |
255 | 00ec5c37 | Venkateswararao Jujjuri (JV) | err = local_post_create_passthrough(fs_ctx, path, credp); |
256 | 00ec5c37 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
257 | 00ec5c37 | Venkateswararao Jujjuri (JV) | serrno = errno; |
258 | 00ec5c37 | Venkateswararao Jujjuri (JV) | goto err_end;
|
259 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } |
260 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } |
261 | 00ec5c37 | Venkateswararao Jujjuri (JV) | return err;
|
262 | 00ec5c37 | Venkateswararao Jujjuri (JV) | |
263 | 00ec5c37 | Venkateswararao Jujjuri (JV) | err_end:
|
264 | 00ec5c37 | Venkateswararao Jujjuri (JV) | remove(rpath(fs_ctx, path)); |
265 | 00ec5c37 | Venkateswararao Jujjuri (JV) | errno = serrno; |
266 | 00ec5c37 | Venkateswararao Jujjuri (JV) | return err;
|
267 | c494dd6f | Anthony Liguori | } |
268 | c494dd6f | Anthony Liguori | |
269 | 1237ad76 | Venkateswararao Jujjuri (JV) | static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf) |
270 | c494dd6f | Anthony Liguori | { |
271 | 1237ad76 | Venkateswararao Jujjuri (JV) | int err;
|
272 | 1237ad76 | Venkateswararao Jujjuri (JV) | err = fstat(fd, stbuf); |
273 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (err) {
|
274 | 1237ad76 | Venkateswararao Jujjuri (JV) | return err;
|
275 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
276 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
277 | 1237ad76 | Venkateswararao Jujjuri (JV) | /* Actual credentials are part of extended attrs */
|
278 | 1237ad76 | Venkateswararao Jujjuri (JV) | uid_t tmp_uid; |
279 | 1237ad76 | Venkateswararao Jujjuri (JV) | gid_t tmp_gid; |
280 | 1237ad76 | Venkateswararao Jujjuri (JV) | mode_t tmp_mode; |
281 | 1237ad76 | Venkateswararao Jujjuri (JV) | dev_t tmp_dev; |
282 | 1237ad76 | Venkateswararao Jujjuri (JV) | |
283 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fgetxattr(fd, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) { |
284 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_uid = tmp_uid; |
285 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
286 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fgetxattr(fd, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) { |
287 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_gid = tmp_gid; |
288 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
289 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fgetxattr(fd, "user.virtfs.mode", &tmp_mode, sizeof(mode_t)) > 0) { |
290 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_mode = tmp_mode; |
291 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
292 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fgetxattr(fd, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) { |
293 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_rdev = tmp_dev; |
294 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
295 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
296 | 1237ad76 | Venkateswararao Jujjuri (JV) | return err;
|
297 | c494dd6f | Anthony Liguori | } |
298 | c494dd6f | Anthony Liguori | |
299 | 4750a96f | Venkateswararao Jujjuri (JV) | static int local_open2(FsContext *fs_ctx, const char *path, int flags, |
300 | 4750a96f | Venkateswararao Jujjuri (JV) | FsCred *credp) |
301 | c494dd6f | Anthony Liguori | { |
302 | 4750a96f | Venkateswararao Jujjuri (JV) | int fd = -1; |
303 | 4750a96f | Venkateswararao Jujjuri (JV) | int err = -1; |
304 | 4750a96f | Venkateswararao Jujjuri (JV) | int serrno = 0; |
305 | 4750a96f | Venkateswararao Jujjuri (JV) | |
306 | 4750a96f | Venkateswararao Jujjuri (JV) | /* Determine the security model */
|
307 | 4750a96f | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
308 | 4750a96f | Venkateswararao Jujjuri (JV) | fd = open(rpath(fs_ctx, path), flags, SM_LOCAL_MODE_BITS); |
309 | 4750a96f | Venkateswararao Jujjuri (JV) | if (fd == -1) { |
310 | 4750a96f | Venkateswararao Jujjuri (JV) | return fd;
|
311 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
312 | 4750a96f | Venkateswararao Jujjuri (JV) | credp->fc_mode = credp->fc_mode|S_IFREG; |
313 | 4750a96f | Venkateswararao Jujjuri (JV) | /* Set cleint credentials in xattr */
|
314 | 4750a96f | Venkateswararao Jujjuri (JV) | err = local_set_xattr(rpath(fs_ctx, path), credp); |
315 | 4750a96f | Venkateswararao Jujjuri (JV) | if (err == -1) { |
316 | 4750a96f | Venkateswararao Jujjuri (JV) | serrno = errno; |
317 | 4750a96f | Venkateswararao Jujjuri (JV) | goto err_end;
|
318 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
319 | 4750a96f | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
320 | 4750a96f | Venkateswararao Jujjuri (JV) | fd = open(rpath(fs_ctx, path), flags, credp->fc_mode); |
321 | 4750a96f | Venkateswararao Jujjuri (JV) | if (fd == -1) { |
322 | 4750a96f | Venkateswararao Jujjuri (JV) | return fd;
|
323 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
324 | 4750a96f | Venkateswararao Jujjuri (JV) | err = local_post_create_passthrough(fs_ctx, path, credp); |
325 | 4750a96f | Venkateswararao Jujjuri (JV) | if (err == -1) { |
326 | 4750a96f | Venkateswararao Jujjuri (JV) | serrno = errno; |
327 | 4750a96f | Venkateswararao Jujjuri (JV) | goto err_end;
|
328 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
329 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
330 | 4750a96f | Venkateswararao Jujjuri (JV) | return fd;
|
331 | 4750a96f | Venkateswararao Jujjuri (JV) | |
332 | 4750a96f | Venkateswararao Jujjuri (JV) | err_end:
|
333 | 4750a96f | Venkateswararao Jujjuri (JV) | close(fd); |
334 | 4750a96f | Venkateswararao Jujjuri (JV) | remove(rpath(fs_ctx, path)); |
335 | 4750a96f | Venkateswararao Jujjuri (JV) | errno = serrno; |
336 | 4750a96f | Venkateswararao Jujjuri (JV) | return err;
|
337 | c494dd6f | Anthony Liguori | } |
338 | c494dd6f | Anthony Liguori | |
339 | 758e8e38 | Venkateswararao Jujjuri (JV) | |
340 | 879c2813 | Venkateswararao Jujjuri (JV) | static int local_symlink(FsContext *fs_ctx, const char *oldpath, |
341 | 879c2813 | Venkateswararao Jujjuri (JV) | const char *newpath, FsCred *credp) |
342 | c494dd6f | Anthony Liguori | { |
343 | 879c2813 | Venkateswararao Jujjuri (JV) | int err = -1; |
344 | 879c2813 | Venkateswararao Jujjuri (JV) | int serrno = 0; |
345 | 879c2813 | Venkateswararao Jujjuri (JV) | |
346 | 879c2813 | Venkateswararao Jujjuri (JV) | /* Determine the security model */
|
347 | 879c2813 | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
348 | 879c2813 | Venkateswararao Jujjuri (JV) | int fd;
|
349 | 879c2813 | Venkateswararao Jujjuri (JV) | ssize_t oldpath_size, write_size; |
350 | 879c2813 | Venkateswararao Jujjuri (JV) | fd = open(rpath(fs_ctx, newpath), O_CREAT|O_EXCL|O_RDWR, |
351 | 879c2813 | Venkateswararao Jujjuri (JV) | SM_LOCAL_MODE_BITS); |
352 | 879c2813 | Venkateswararao Jujjuri (JV) | if (fd == -1) { |
353 | 879c2813 | Venkateswararao Jujjuri (JV) | return fd;
|
354 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
355 | 879c2813 | Venkateswararao Jujjuri (JV) | /* Write the oldpath (target) to the file. */
|
356 | 879c2813 | Venkateswararao Jujjuri (JV) | oldpath_size = strlen(oldpath) + 1;
|
357 | 879c2813 | Venkateswararao Jujjuri (JV) | do {
|
358 | 879c2813 | Venkateswararao Jujjuri (JV) | write_size = write(fd, (void *)oldpath, oldpath_size);
|
359 | 879c2813 | Venkateswararao Jujjuri (JV) | } while (write_size == -1 && errno == EINTR); |
360 | 879c2813 | Venkateswararao Jujjuri (JV) | |
361 | 879c2813 | Venkateswararao Jujjuri (JV) | if (write_size != oldpath_size) {
|
362 | 879c2813 | Venkateswararao Jujjuri (JV) | serrno = errno; |
363 | 879c2813 | Venkateswararao Jujjuri (JV) | close(fd); |
364 | 879c2813 | Venkateswararao Jujjuri (JV) | err = -1;
|
365 | 879c2813 | Venkateswararao Jujjuri (JV) | goto err_end;
|
366 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
367 | 879c2813 | Venkateswararao Jujjuri (JV) | close(fd); |
368 | 879c2813 | Venkateswararao Jujjuri (JV) | /* Set cleint credentials in symlink's xattr */
|
369 | 879c2813 | Venkateswararao Jujjuri (JV) | credp->fc_mode = credp->fc_mode|S_IFLNK; |
370 | 879c2813 | Venkateswararao Jujjuri (JV) | err = local_set_xattr(rpath(fs_ctx, newpath), credp); |
371 | 879c2813 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
372 | 879c2813 | Venkateswararao Jujjuri (JV) | serrno = errno; |
373 | 879c2813 | Venkateswararao Jujjuri (JV) | goto err_end;
|
374 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
375 | 879c2813 | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
376 | 879c2813 | Venkateswararao Jujjuri (JV) | err = symlink(oldpath, rpath(fs_ctx, newpath)); |
377 | 879c2813 | Venkateswararao Jujjuri (JV) | if (err) {
|
378 | 879c2813 | Venkateswararao Jujjuri (JV) | return err;
|
379 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
380 | 879c2813 | Venkateswararao Jujjuri (JV) | err = lchown(rpath(fs_ctx, newpath), credp->fc_uid, credp->fc_gid); |
381 | 879c2813 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
382 | 879c2813 | Venkateswararao Jujjuri (JV) | serrno = errno; |
383 | 879c2813 | Venkateswararao Jujjuri (JV) | goto err_end;
|
384 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
385 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
386 | 879c2813 | Venkateswararao Jujjuri (JV) | return err;
|
387 | 879c2813 | Venkateswararao Jujjuri (JV) | |
388 | 879c2813 | Venkateswararao Jujjuri (JV) | err_end:
|
389 | 879c2813 | Venkateswararao Jujjuri (JV) | remove(rpath(fs_ctx, newpath)); |
390 | 879c2813 | Venkateswararao Jujjuri (JV) | errno = serrno; |
391 | 879c2813 | Venkateswararao Jujjuri (JV) | return err;
|
392 | c494dd6f | Anthony Liguori | } |
393 | c494dd6f | Anthony Liguori | |
394 | c494dd6f | Anthony Liguori | static int local_link(FsContext *ctx, const char *oldpath, const char *newpath) |
395 | c494dd6f | Anthony Liguori | { |
396 | c494dd6f | Anthony Liguori | char *tmp = qemu_strdup(rpath(ctx, oldpath));
|
397 | c494dd6f | Anthony Liguori | int err, serrno = 0; |
398 | c494dd6f | Anthony Liguori | |
399 | c494dd6f | Anthony Liguori | if (tmp == NULL) { |
400 | c494dd6f | Anthony Liguori | return -ENOMEM;
|
401 | c494dd6f | Anthony Liguori | } |
402 | c494dd6f | Anthony Liguori | |
403 | c494dd6f | Anthony Liguori | err = link(tmp, rpath(ctx, newpath)); |
404 | c494dd6f | Anthony Liguori | if (err == -1) { |
405 | c494dd6f | Anthony Liguori | serrno = errno; |
406 | c494dd6f | Anthony Liguori | } |
407 | c494dd6f | Anthony Liguori | |
408 | c494dd6f | Anthony Liguori | qemu_free(tmp); |
409 | c494dd6f | Anthony Liguori | |
410 | c494dd6f | Anthony Liguori | if (err == -1) { |
411 | c494dd6f | Anthony Liguori | errno = serrno; |
412 | c494dd6f | Anthony Liguori | } |
413 | c494dd6f | Anthony Liguori | |
414 | c494dd6f | Anthony Liguori | return err;
|
415 | c494dd6f | Anthony Liguori | } |
416 | c494dd6f | Anthony Liguori | |
417 | 8cf89e00 | Anthony Liguori | static int local_truncate(FsContext *ctx, const char *path, off_t size) |
418 | 8cf89e00 | Anthony Liguori | { |
419 | 8cf89e00 | Anthony Liguori | return truncate(rpath(ctx, path), size);
|
420 | 8cf89e00 | Anthony Liguori | } |
421 | 8cf89e00 | Anthony Liguori | |
422 | 8cf89e00 | Anthony Liguori | static int local_rename(FsContext *ctx, const char *oldpath, |
423 | 8cf89e00 | Anthony Liguori | const char *newpath) |
424 | 8cf89e00 | Anthony Liguori | { |
425 | 8cf89e00 | Anthony Liguori | char *tmp;
|
426 | 8cf89e00 | Anthony Liguori | int err;
|
427 | 8cf89e00 | Anthony Liguori | |
428 | 8cf89e00 | Anthony Liguori | tmp = qemu_strdup(rpath(ctx, oldpath)); |
429 | 8cf89e00 | Anthony Liguori | |
430 | 8cf89e00 | Anthony Liguori | err = rename(tmp, rpath(ctx, newpath)); |
431 | 8cf89e00 | Anthony Liguori | if (err == -1) { |
432 | 8cf89e00 | Anthony Liguori | int serrno = errno;
|
433 | 8cf89e00 | Anthony Liguori | qemu_free(tmp); |
434 | 8cf89e00 | Anthony Liguori | errno = serrno; |
435 | 8cf89e00 | Anthony Liguori | } else {
|
436 | 8cf89e00 | Anthony Liguori | qemu_free(tmp); |
437 | 8cf89e00 | Anthony Liguori | } |
438 | 8cf89e00 | Anthony Liguori | |
439 | 8cf89e00 | Anthony Liguori | return err;
|
440 | 8cf89e00 | Anthony Liguori | |
441 | 8cf89e00 | Anthony Liguori | } |
442 | 8cf89e00 | Anthony Liguori | |
443 | f7613bee | Venkateswararao Jujjuri (JV) | static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp) |
444 | 8cf89e00 | Anthony Liguori | { |
445 | c79ce737 | Sripathi Kodi | if ((credp->fc_uid == -1 && credp->fc_gid == -1) || |
446 | c79ce737 | Sripathi Kodi | (fs_ctx->fs_sm == SM_PASSTHROUGH)) { |
447 | c79ce737 | Sripathi Kodi | return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
|
448 | c79ce737 | Sripathi Kodi | } else if (fs_ctx->fs_sm == SM_MAPPED) { |
449 | f7613bee | Venkateswararao Jujjuri (JV) | return local_set_xattr(rpath(fs_ctx, path), credp);
|
450 | f7613bee | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
451 | f7613bee | Venkateswararao Jujjuri (JV) | return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
|
452 | f7613bee | Venkateswararao Jujjuri (JV) | } |
453 | f7613bee | Venkateswararao Jujjuri (JV) | return -1; |
454 | 8cf89e00 | Anthony Liguori | } |
455 | 8cf89e00 | Anthony Liguori | |
456 | 74bc02b2 | M. Mohan Kumar | static int local_utimensat(FsContext *s, const char *path, |
457 | 74bc02b2 | M. Mohan Kumar | const struct timespec *buf) |
458 | 8cf89e00 | Anthony Liguori | { |
459 | 74bc02b2 | M. Mohan Kumar | return utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW);
|
460 | 8cf89e00 | Anthony Liguori | } |
461 | 8cf89e00 | Anthony Liguori | |
462 | 5bae1900 | Anthony Liguori | static int local_remove(FsContext *ctx, const char *path) |
463 | 5bae1900 | Anthony Liguori | { |
464 | 5bae1900 | Anthony Liguori | return remove(rpath(ctx, path));
|
465 | 5bae1900 | Anthony Liguori | } |
466 | 5bae1900 | Anthony Liguori | |
467 | 8cf89e00 | Anthony Liguori | static int local_fsync(FsContext *ctx, int fd) |
468 | 8cf89e00 | Anthony Liguori | { |
469 | 8cf89e00 | Anthony Liguori | return fsync(fd);
|
470 | 8cf89e00 | Anthony Liguori | } |
471 | 8cf89e00 | Anthony Liguori | |
472 | be940c87 | M. Mohan Kumar | static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf) |
473 | be940c87 | M. Mohan Kumar | { |
474 | be940c87 | M. Mohan Kumar | return statfs(rpath(s, path), stbuf);
|
475 | be940c87 | M. Mohan Kumar | } |
476 | be940c87 | M. Mohan Kumar | |
477 | fa32ef88 | Aneesh Kumar K.V | static ssize_t local_lgetxattr(FsContext *ctx, const char *path, |
478 | fa32ef88 | Aneesh Kumar K.V | const char *name, void *value, size_t size) |
479 | fa32ef88 | Aneesh Kumar K.V | { |
480 | fa32ef88 | Aneesh Kumar K.V | return lgetxattr(rpath(ctx, path), name, value, size);
|
481 | fa32ef88 | Aneesh Kumar K.V | } |
482 | fa32ef88 | Aneesh Kumar K.V | |
483 | fa32ef88 | Aneesh Kumar K.V | static ssize_t local_llistxattr(FsContext *ctx, const char *path, |
484 | fa32ef88 | Aneesh Kumar K.V | void *value, size_t size)
|
485 | fa32ef88 | Aneesh Kumar K.V | { |
486 | fa32ef88 | Aneesh Kumar K.V | return llistxattr(rpath(ctx, path), value, size);
|
487 | fa32ef88 | Aneesh Kumar K.V | } |
488 | fa32ef88 | Aneesh Kumar K.V | |
489 | 10b468bd | Aneesh Kumar K.V | static int local_lsetxattr(FsContext *ctx, const char *path, const char *name, |
490 | 10b468bd | Aneesh Kumar K.V | void *value, size_t size, int flags) |
491 | 10b468bd | Aneesh Kumar K.V | { |
492 | 10b468bd | Aneesh Kumar K.V | return lsetxattr(rpath(ctx, path), name, value, size, flags);
|
493 | 10b468bd | Aneesh Kumar K.V | } |
494 | 10b468bd | Aneesh Kumar K.V | |
495 | 9f107513 | Anthony Liguori | FileOperations local_ops = { |
496 | 131dcb25 | Anthony Liguori | .lstat = local_lstat, |
497 | 131dcb25 | Anthony Liguori | .readlink = local_readlink, |
498 | 131dcb25 | Anthony Liguori | .close = local_close, |
499 | 131dcb25 | Anthony Liguori | .closedir = local_closedir, |
500 | a6568fe2 | Anthony Liguori | .open = local_open, |
501 | a6568fe2 | Anthony Liguori | .opendir = local_opendir, |
502 | a9231555 | Anthony Liguori | .rewinddir = local_rewinddir, |
503 | a9231555 | Anthony Liguori | .telldir = local_telldir, |
504 | a9231555 | Anthony Liguori | .readdir = local_readdir, |
505 | a9231555 | Anthony Liguori | .seekdir = local_seekdir, |
506 | a9231555 | Anthony Liguori | .readv = local_readv, |
507 | a9231555 | Anthony Liguori | .lseek = local_lseek, |
508 | 8449360c | Anthony Liguori | .writev = local_writev, |
509 | c494dd6f | Anthony Liguori | .chmod = local_chmod, |
510 | c494dd6f | Anthony Liguori | .mknod = local_mknod, |
511 | c494dd6f | Anthony Liguori | .mkdir = local_mkdir, |
512 | c494dd6f | Anthony Liguori | .fstat = local_fstat, |
513 | c494dd6f | Anthony Liguori | .open2 = local_open2, |
514 | c494dd6f | Anthony Liguori | .symlink = local_symlink, |
515 | c494dd6f | Anthony Liguori | .link = local_link, |
516 | 8cf89e00 | Anthony Liguori | .truncate = local_truncate, |
517 | 8cf89e00 | Anthony Liguori | .rename = local_rename, |
518 | 8cf89e00 | Anthony Liguori | .chown = local_chown, |
519 | 74bc02b2 | M. Mohan Kumar | .utimensat = local_utimensat, |
520 | 5bae1900 | Anthony Liguori | .remove = local_remove, |
521 | 8cf89e00 | Anthony Liguori | .fsync = local_fsync, |
522 | be940c87 | M. Mohan Kumar | .statfs = local_statfs, |
523 | fa32ef88 | Aneesh Kumar K.V | .lgetxattr = local_lgetxattr, |
524 | fa32ef88 | Aneesh Kumar K.V | .llistxattr = local_llistxattr, |
525 | 10b468bd | Aneesh Kumar K.V | .lsetxattr = local_lsetxattr, |
526 | 9f107513 | Anthony Liguori | }; |