root / hw / virtio-9p-local.c @ 879c2813
History | View | Annotate | Download (11.9 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 | c494dd6f | Anthony Liguori | static int local_mknod(FsContext *ctx, const char *path, mode_t mode, dev_t dev) |
199 | c494dd6f | Anthony Liguori | { |
200 | c494dd6f | Anthony Liguori | return mknod(rpath(ctx, path), mode, dev);
|
201 | c494dd6f | Anthony Liguori | } |
202 | c494dd6f | Anthony Liguori | |
203 | c494dd6f | Anthony Liguori | static int local_mksock(FsContext *ctx2, const char *path) |
204 | c494dd6f | Anthony Liguori | { |
205 | c494dd6f | Anthony Liguori | struct sockaddr_un addr;
|
206 | c494dd6f | Anthony Liguori | int s;
|
207 | c494dd6f | Anthony Liguori | |
208 | c494dd6f | Anthony Liguori | addr.sun_family = AF_UNIX; |
209 | c494dd6f | Anthony Liguori | snprintf(addr.sun_path, 108, "%s", rpath(ctx2, path)); |
210 | c494dd6f | Anthony Liguori | |
211 | c494dd6f | Anthony Liguori | s = socket(PF_UNIX, SOCK_STREAM, 0);
|
212 | c494dd6f | Anthony Liguori | if (s == -1) { |
213 | c494dd6f | Anthony Liguori | return -1; |
214 | c494dd6f | Anthony Liguori | } |
215 | c494dd6f | Anthony Liguori | |
216 | c494dd6f | Anthony Liguori | if (bind(s, (struct sockaddr *)&addr, sizeof(addr))) { |
217 | c494dd6f | Anthony Liguori | close(s); |
218 | c494dd6f | Anthony Liguori | return -1; |
219 | c494dd6f | Anthony Liguori | } |
220 | c494dd6f | Anthony Liguori | |
221 | c494dd6f | Anthony Liguori | close(s); |
222 | c494dd6f | Anthony Liguori | return 0; |
223 | c494dd6f | Anthony Liguori | } |
224 | c494dd6f | Anthony Liguori | |
225 | 00ec5c37 | Venkateswararao Jujjuri (JV) | static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp) |
226 | c494dd6f | Anthony Liguori | { |
227 | 00ec5c37 | Venkateswararao Jujjuri (JV) | int err = -1; |
228 | 00ec5c37 | Venkateswararao Jujjuri (JV) | int serrno = 0; |
229 | 00ec5c37 | Venkateswararao Jujjuri (JV) | |
230 | 00ec5c37 | Venkateswararao Jujjuri (JV) | /* Determine the security model */
|
231 | 00ec5c37 | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
232 | 00ec5c37 | Venkateswararao Jujjuri (JV) | err = mkdir(rpath(fs_ctx, path), SM_LOCAL_DIR_MODE_BITS); |
233 | 00ec5c37 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
234 | 00ec5c37 | Venkateswararao Jujjuri (JV) | return err;
|
235 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } |
236 | 00ec5c37 | Venkateswararao Jujjuri (JV) | credp->fc_mode = credp->fc_mode|S_IFDIR; |
237 | 00ec5c37 | Venkateswararao Jujjuri (JV) | err = local_set_xattr(rpath(fs_ctx, path), credp); |
238 | 00ec5c37 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
239 | 00ec5c37 | Venkateswararao Jujjuri (JV) | serrno = errno; |
240 | 00ec5c37 | Venkateswararao Jujjuri (JV) | goto err_end;
|
241 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } |
242 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
243 | 00ec5c37 | Venkateswararao Jujjuri (JV) | err = mkdir(rpath(fs_ctx, path), credp->fc_mode); |
244 | 00ec5c37 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
245 | 00ec5c37 | Venkateswararao Jujjuri (JV) | return err;
|
246 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } |
247 | 00ec5c37 | Venkateswararao Jujjuri (JV) | err = local_post_create_passthrough(fs_ctx, path, credp); |
248 | 00ec5c37 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
249 | 00ec5c37 | Venkateswararao Jujjuri (JV) | serrno = errno; |
250 | 00ec5c37 | Venkateswararao Jujjuri (JV) | goto err_end;
|
251 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } |
252 | 00ec5c37 | Venkateswararao Jujjuri (JV) | } |
253 | 00ec5c37 | Venkateswararao Jujjuri (JV) | return err;
|
254 | 00ec5c37 | Venkateswararao Jujjuri (JV) | |
255 | 00ec5c37 | Venkateswararao Jujjuri (JV) | err_end:
|
256 | 00ec5c37 | Venkateswararao Jujjuri (JV) | remove(rpath(fs_ctx, path)); |
257 | 00ec5c37 | Venkateswararao Jujjuri (JV) | errno = serrno; |
258 | 00ec5c37 | Venkateswararao Jujjuri (JV) | return err;
|
259 | c494dd6f | Anthony Liguori | } |
260 | c494dd6f | Anthony Liguori | |
261 | 1237ad76 | Venkateswararao Jujjuri (JV) | static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf) |
262 | c494dd6f | Anthony Liguori | { |
263 | 1237ad76 | Venkateswararao Jujjuri (JV) | int err;
|
264 | 1237ad76 | Venkateswararao Jujjuri (JV) | err = fstat(fd, stbuf); |
265 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (err) {
|
266 | 1237ad76 | Venkateswararao Jujjuri (JV) | return err;
|
267 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
268 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
269 | 1237ad76 | Venkateswararao Jujjuri (JV) | /* Actual credentials are part of extended attrs */
|
270 | 1237ad76 | Venkateswararao Jujjuri (JV) | uid_t tmp_uid; |
271 | 1237ad76 | Venkateswararao Jujjuri (JV) | gid_t tmp_gid; |
272 | 1237ad76 | Venkateswararao Jujjuri (JV) | mode_t tmp_mode; |
273 | 1237ad76 | Venkateswararao Jujjuri (JV) | dev_t tmp_dev; |
274 | 1237ad76 | Venkateswararao Jujjuri (JV) | |
275 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fgetxattr(fd, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) { |
276 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_uid = tmp_uid; |
277 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
278 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fgetxattr(fd, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) { |
279 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_gid = tmp_gid; |
280 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
281 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fgetxattr(fd, "user.virtfs.mode", &tmp_mode, sizeof(mode_t)) > 0) { |
282 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_mode = tmp_mode; |
283 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
284 | 1237ad76 | Venkateswararao Jujjuri (JV) | if (fgetxattr(fd, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) { |
285 | 1237ad76 | Venkateswararao Jujjuri (JV) | stbuf->st_rdev = tmp_dev; |
286 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
287 | 1237ad76 | Venkateswararao Jujjuri (JV) | } |
288 | 1237ad76 | Venkateswararao Jujjuri (JV) | return err;
|
289 | c494dd6f | Anthony Liguori | } |
290 | c494dd6f | Anthony Liguori | |
291 | 4750a96f | Venkateswararao Jujjuri (JV) | static int local_open2(FsContext *fs_ctx, const char *path, int flags, |
292 | 4750a96f | Venkateswararao Jujjuri (JV) | FsCred *credp) |
293 | c494dd6f | Anthony Liguori | { |
294 | 4750a96f | Venkateswararao Jujjuri (JV) | int fd = -1; |
295 | 4750a96f | Venkateswararao Jujjuri (JV) | int err = -1; |
296 | 4750a96f | Venkateswararao Jujjuri (JV) | int serrno = 0; |
297 | 4750a96f | Venkateswararao Jujjuri (JV) | |
298 | 4750a96f | Venkateswararao Jujjuri (JV) | /* Determine the security model */
|
299 | 4750a96f | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
300 | 4750a96f | Venkateswararao Jujjuri (JV) | fd = open(rpath(fs_ctx, path), flags, SM_LOCAL_MODE_BITS); |
301 | 4750a96f | Venkateswararao Jujjuri (JV) | if (fd == -1) { |
302 | 4750a96f | Venkateswararao Jujjuri (JV) | return fd;
|
303 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
304 | 4750a96f | Venkateswararao Jujjuri (JV) | credp->fc_mode = credp->fc_mode|S_IFREG; |
305 | 4750a96f | Venkateswararao Jujjuri (JV) | /* Set cleint credentials in xattr */
|
306 | 4750a96f | Venkateswararao Jujjuri (JV) | err = local_set_xattr(rpath(fs_ctx, path), credp); |
307 | 4750a96f | Venkateswararao Jujjuri (JV) | if (err == -1) { |
308 | 4750a96f | Venkateswararao Jujjuri (JV) | serrno = errno; |
309 | 4750a96f | Venkateswararao Jujjuri (JV) | goto err_end;
|
310 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
311 | 4750a96f | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
312 | 4750a96f | Venkateswararao Jujjuri (JV) | fd = open(rpath(fs_ctx, path), flags, credp->fc_mode); |
313 | 4750a96f | Venkateswararao Jujjuri (JV) | if (fd == -1) { |
314 | 4750a96f | Venkateswararao Jujjuri (JV) | return fd;
|
315 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
316 | 4750a96f | Venkateswararao Jujjuri (JV) | err = local_post_create_passthrough(fs_ctx, path, credp); |
317 | 4750a96f | Venkateswararao Jujjuri (JV) | if (err == -1) { |
318 | 4750a96f | Venkateswararao Jujjuri (JV) | serrno = errno; |
319 | 4750a96f | Venkateswararao Jujjuri (JV) | goto err_end;
|
320 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
321 | 4750a96f | Venkateswararao Jujjuri (JV) | } |
322 | 4750a96f | Venkateswararao Jujjuri (JV) | return fd;
|
323 | 4750a96f | Venkateswararao Jujjuri (JV) | |
324 | 4750a96f | Venkateswararao Jujjuri (JV) | err_end:
|
325 | 4750a96f | Venkateswararao Jujjuri (JV) | close(fd); |
326 | 4750a96f | Venkateswararao Jujjuri (JV) | remove(rpath(fs_ctx, path)); |
327 | 4750a96f | Venkateswararao Jujjuri (JV) | errno = serrno; |
328 | 4750a96f | Venkateswararao Jujjuri (JV) | return err;
|
329 | c494dd6f | Anthony Liguori | } |
330 | c494dd6f | Anthony Liguori | |
331 | 758e8e38 | Venkateswararao Jujjuri (JV) | |
332 | 879c2813 | Venkateswararao Jujjuri (JV) | static int local_symlink(FsContext *fs_ctx, const char *oldpath, |
333 | 879c2813 | Venkateswararao Jujjuri (JV) | const char *newpath, FsCred *credp) |
334 | c494dd6f | Anthony Liguori | { |
335 | 879c2813 | Venkateswararao Jujjuri (JV) | int err = -1; |
336 | 879c2813 | Venkateswararao Jujjuri (JV) | int serrno = 0; |
337 | 879c2813 | Venkateswararao Jujjuri (JV) | |
338 | 879c2813 | Venkateswararao Jujjuri (JV) | /* Determine the security model */
|
339 | 879c2813 | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
340 | 879c2813 | Venkateswararao Jujjuri (JV) | int fd;
|
341 | 879c2813 | Venkateswararao Jujjuri (JV) | ssize_t oldpath_size, write_size; |
342 | 879c2813 | Venkateswararao Jujjuri (JV) | fd = open(rpath(fs_ctx, newpath), O_CREAT|O_EXCL|O_RDWR, |
343 | 879c2813 | Venkateswararao Jujjuri (JV) | SM_LOCAL_MODE_BITS); |
344 | 879c2813 | Venkateswararao Jujjuri (JV) | if (fd == -1) { |
345 | 879c2813 | Venkateswararao Jujjuri (JV) | return fd;
|
346 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
347 | 879c2813 | Venkateswararao Jujjuri (JV) | /* Write the oldpath (target) to the file. */
|
348 | 879c2813 | Venkateswararao Jujjuri (JV) | oldpath_size = strlen(oldpath) + 1;
|
349 | 879c2813 | Venkateswararao Jujjuri (JV) | do {
|
350 | 879c2813 | Venkateswararao Jujjuri (JV) | write_size = write(fd, (void *)oldpath, oldpath_size);
|
351 | 879c2813 | Venkateswararao Jujjuri (JV) | } while (write_size == -1 && errno == EINTR); |
352 | 879c2813 | Venkateswararao Jujjuri (JV) | |
353 | 879c2813 | Venkateswararao Jujjuri (JV) | if (write_size != oldpath_size) {
|
354 | 879c2813 | Venkateswararao Jujjuri (JV) | serrno = errno; |
355 | 879c2813 | Venkateswararao Jujjuri (JV) | close(fd); |
356 | 879c2813 | Venkateswararao Jujjuri (JV) | err = -1;
|
357 | 879c2813 | Venkateswararao Jujjuri (JV) | goto err_end;
|
358 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
359 | 879c2813 | Venkateswararao Jujjuri (JV) | close(fd); |
360 | 879c2813 | Venkateswararao Jujjuri (JV) | /* Set cleint credentials in symlink's xattr */
|
361 | 879c2813 | Venkateswararao Jujjuri (JV) | credp->fc_mode = credp->fc_mode|S_IFLNK; |
362 | 879c2813 | Venkateswararao Jujjuri (JV) | err = local_set_xattr(rpath(fs_ctx, newpath), credp); |
363 | 879c2813 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
364 | 879c2813 | Venkateswararao Jujjuri (JV) | serrno = errno; |
365 | 879c2813 | Venkateswararao Jujjuri (JV) | goto err_end;
|
366 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
367 | 879c2813 | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
368 | 879c2813 | Venkateswararao Jujjuri (JV) | err = symlink(oldpath, rpath(fs_ctx, newpath)); |
369 | 879c2813 | Venkateswararao Jujjuri (JV) | if (err) {
|
370 | 879c2813 | Venkateswararao Jujjuri (JV) | return err;
|
371 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
372 | 879c2813 | Venkateswararao Jujjuri (JV) | err = lchown(rpath(fs_ctx, newpath), credp->fc_uid, credp->fc_gid); |
373 | 879c2813 | Venkateswararao Jujjuri (JV) | if (err == -1) { |
374 | 879c2813 | Venkateswararao Jujjuri (JV) | serrno = errno; |
375 | 879c2813 | Venkateswararao Jujjuri (JV) | goto err_end;
|
376 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
377 | 879c2813 | Venkateswararao Jujjuri (JV) | } |
378 | 879c2813 | Venkateswararao Jujjuri (JV) | return err;
|
379 | 879c2813 | Venkateswararao Jujjuri (JV) | |
380 | 879c2813 | Venkateswararao Jujjuri (JV) | err_end:
|
381 | 879c2813 | Venkateswararao Jujjuri (JV) | remove(rpath(fs_ctx, newpath)); |
382 | 879c2813 | Venkateswararao Jujjuri (JV) | errno = serrno; |
383 | 879c2813 | Venkateswararao Jujjuri (JV) | return err;
|
384 | c494dd6f | Anthony Liguori | } |
385 | c494dd6f | Anthony Liguori | |
386 | c494dd6f | Anthony Liguori | static int local_link(FsContext *ctx, const char *oldpath, const char *newpath) |
387 | c494dd6f | Anthony Liguori | { |
388 | c494dd6f | Anthony Liguori | char *tmp = qemu_strdup(rpath(ctx, oldpath));
|
389 | c494dd6f | Anthony Liguori | int err, serrno = 0; |
390 | c494dd6f | Anthony Liguori | |
391 | c494dd6f | Anthony Liguori | if (tmp == NULL) { |
392 | c494dd6f | Anthony Liguori | return -ENOMEM;
|
393 | c494dd6f | Anthony Liguori | } |
394 | c494dd6f | Anthony Liguori | |
395 | c494dd6f | Anthony Liguori | err = link(tmp, rpath(ctx, newpath)); |
396 | c494dd6f | Anthony Liguori | if (err == -1) { |
397 | c494dd6f | Anthony Liguori | serrno = errno; |
398 | c494dd6f | Anthony Liguori | } |
399 | c494dd6f | Anthony Liguori | |
400 | c494dd6f | Anthony Liguori | qemu_free(tmp); |
401 | c494dd6f | Anthony Liguori | |
402 | c494dd6f | Anthony Liguori | if (err == -1) { |
403 | c494dd6f | Anthony Liguori | errno = serrno; |
404 | c494dd6f | Anthony Liguori | } |
405 | c494dd6f | Anthony Liguori | |
406 | c494dd6f | Anthony Liguori | return err;
|
407 | c494dd6f | Anthony Liguori | } |
408 | c494dd6f | Anthony Liguori | |
409 | 8cf89e00 | Anthony Liguori | static int local_truncate(FsContext *ctx, const char *path, off_t size) |
410 | 8cf89e00 | Anthony Liguori | { |
411 | 8cf89e00 | Anthony Liguori | return truncate(rpath(ctx, path), size);
|
412 | 8cf89e00 | Anthony Liguori | } |
413 | 8cf89e00 | Anthony Liguori | |
414 | 8cf89e00 | Anthony Liguori | static int local_rename(FsContext *ctx, const char *oldpath, |
415 | 8cf89e00 | Anthony Liguori | const char *newpath) |
416 | 8cf89e00 | Anthony Liguori | { |
417 | 8cf89e00 | Anthony Liguori | char *tmp;
|
418 | 8cf89e00 | Anthony Liguori | int err;
|
419 | 8cf89e00 | Anthony Liguori | |
420 | 8cf89e00 | Anthony Liguori | tmp = qemu_strdup(rpath(ctx, oldpath)); |
421 | 8cf89e00 | Anthony Liguori | if (tmp == NULL) { |
422 | 8cf89e00 | Anthony Liguori | return -1; |
423 | 8cf89e00 | Anthony Liguori | } |
424 | 8cf89e00 | Anthony Liguori | |
425 | 8cf89e00 | Anthony Liguori | err = rename(tmp, rpath(ctx, newpath)); |
426 | 8cf89e00 | Anthony Liguori | if (err == -1) { |
427 | 8cf89e00 | Anthony Liguori | int serrno = errno;
|
428 | 8cf89e00 | Anthony Liguori | qemu_free(tmp); |
429 | 8cf89e00 | Anthony Liguori | errno = serrno; |
430 | 8cf89e00 | Anthony Liguori | } else {
|
431 | 8cf89e00 | Anthony Liguori | qemu_free(tmp); |
432 | 8cf89e00 | Anthony Liguori | } |
433 | 8cf89e00 | Anthony Liguori | |
434 | 8cf89e00 | Anthony Liguori | return err;
|
435 | 8cf89e00 | Anthony Liguori | |
436 | 8cf89e00 | Anthony Liguori | } |
437 | 8cf89e00 | Anthony Liguori | |
438 | f7613bee | Venkateswararao Jujjuri (JV) | static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp) |
439 | 8cf89e00 | Anthony Liguori | { |
440 | f7613bee | Venkateswararao Jujjuri (JV) | if (fs_ctx->fs_sm == SM_MAPPED) {
|
441 | f7613bee | Venkateswararao Jujjuri (JV) | return local_set_xattr(rpath(fs_ctx, path), credp);
|
442 | f7613bee | Venkateswararao Jujjuri (JV) | } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { |
443 | f7613bee | Venkateswararao Jujjuri (JV) | return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
|
444 | f7613bee | Venkateswararao Jujjuri (JV) | } |
445 | f7613bee | Venkateswararao Jujjuri (JV) | return -1; |
446 | 8cf89e00 | Anthony Liguori | } |
447 | 8cf89e00 | Anthony Liguori | |
448 | 8cf89e00 | Anthony Liguori | static int local_utime(FsContext *ctx, const char *path, |
449 | 8cf89e00 | Anthony Liguori | const struct utimbuf *buf) |
450 | 8cf89e00 | Anthony Liguori | { |
451 | 8cf89e00 | Anthony Liguori | return utime(rpath(ctx, path), buf);
|
452 | 8cf89e00 | Anthony Liguori | } |
453 | 8cf89e00 | Anthony Liguori | |
454 | 5bae1900 | Anthony Liguori | static int local_remove(FsContext *ctx, const char *path) |
455 | 5bae1900 | Anthony Liguori | { |
456 | 5bae1900 | Anthony Liguori | return remove(rpath(ctx, path));
|
457 | 5bae1900 | Anthony Liguori | } |
458 | 5bae1900 | Anthony Liguori | |
459 | 8cf89e00 | Anthony Liguori | static int local_fsync(FsContext *ctx, int fd) |
460 | 8cf89e00 | Anthony Liguori | { |
461 | 8cf89e00 | Anthony Liguori | return fsync(fd);
|
462 | 8cf89e00 | Anthony Liguori | } |
463 | 8cf89e00 | Anthony Liguori | |
464 | 9f107513 | Anthony Liguori | FileOperations local_ops = { |
465 | 131dcb25 | Anthony Liguori | .lstat = local_lstat, |
466 | 131dcb25 | Anthony Liguori | .readlink = local_readlink, |
467 | 131dcb25 | Anthony Liguori | .close = local_close, |
468 | 131dcb25 | Anthony Liguori | .closedir = local_closedir, |
469 | a6568fe2 | Anthony Liguori | .open = local_open, |
470 | a6568fe2 | Anthony Liguori | .opendir = local_opendir, |
471 | a9231555 | Anthony Liguori | .rewinddir = local_rewinddir, |
472 | a9231555 | Anthony Liguori | .telldir = local_telldir, |
473 | a9231555 | Anthony Liguori | .readdir = local_readdir, |
474 | a9231555 | Anthony Liguori | .seekdir = local_seekdir, |
475 | a9231555 | Anthony Liguori | .readv = local_readv, |
476 | a9231555 | Anthony Liguori | .lseek = local_lseek, |
477 | 8449360c | Anthony Liguori | .writev = local_writev, |
478 | c494dd6f | Anthony Liguori | .chmod = local_chmod, |
479 | c494dd6f | Anthony Liguori | .mknod = local_mknod, |
480 | c494dd6f | Anthony Liguori | .mksock = local_mksock, |
481 | c494dd6f | Anthony Liguori | .mkdir = local_mkdir, |
482 | c494dd6f | Anthony Liguori | .fstat = local_fstat, |
483 | c494dd6f | Anthony Liguori | .open2 = local_open2, |
484 | c494dd6f | Anthony Liguori | .symlink = local_symlink, |
485 | c494dd6f | Anthony Liguori | .link = local_link, |
486 | 8cf89e00 | Anthony Liguori | .truncate = local_truncate, |
487 | 8cf89e00 | Anthony Liguori | .rename = local_rename, |
488 | 8cf89e00 | Anthony Liguori | .chown = local_chown, |
489 | 8cf89e00 | Anthony Liguori | .utime = local_utime, |
490 | 5bae1900 | Anthony Liguori | .remove = local_remove, |
491 | 8cf89e00 | Anthony Liguori | .fsync = local_fsync, |
492 | 9f107513 | Anthony Liguori | }; |