Introduce -c [12], which can be used to open 1 or 2 ssh connections to the server. If "2" is specified, a separate connection is used for data and directory operations. Using two connections can significantly increase directory operation performance on a saturated link, at least up to 30x faster.diff -r1.18 -r1.19 src/usr.sbin/puffs/mount_psshfs/fs.c
(pooka)
--- src/usr.sbin/puffs/mount_psshfs/fs.c 2009/02/23 18:43:46 1.18
+++ src/usr.sbin/puffs/mount_psshfs/fs.c 2009/05/20 13:56:36 1.19
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: fs.c,v 1.18 2009/02/23 18:43:46 pooka Exp $ */ | 1 | /* $NetBSD: fs.c,v 1.19 2009/05/20 13:56:36 pooka Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2006 Antti Kantee. All Rights Reserved. | 4 | * Copyright (c) 2006 Antti Kantee. All Rights Reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -17,27 +17,27 @@ | @@ -17,27 +17,27 @@ | |||
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
21 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 21 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
25 | * SUCH DAMAGE. | 25 | * SUCH DAMAGE. | |
26 | */ | 26 | */ | |
27 | 27 | |||
28 | #include <sys/cdefs.h> | 28 | #include <sys/cdefs.h> | |
29 | #ifndef lint | 29 | #ifndef lint | |
30 | __RCSID("$NetBSD: fs.c,v 1.18 2009/02/23 18:43:46 pooka Exp $"); | 30 | __RCSID("$NetBSD: fs.c,v 1.19 2009/05/20 13:56:36 pooka Exp $"); | |
31 | #endif /* !lint */ | 31 | #endif /* !lint */ | |
32 | 32 | |||
33 | #include <err.h> | 33 | #include <err.h> | |
34 | #include <errno.h> | 34 | #include <errno.h> | |
35 | #include <puffs.h> | 35 | #include <puffs.h> | |
36 | #include <signal.h> | 36 | #include <signal.h> | |
37 | #include <stdio.h> | 37 | #include <stdio.h> | |
38 | #include <stdlib.h> | 38 | #include <stdlib.h> | |
39 | #include <unistd.h> | 39 | #include <unistd.h> | |
40 | 40 | |||
41 | #include "psshfs.h" | 41 | #include "psshfs.h" | |
42 | #include "sftp_proto.h" | 42 | #include "sftp_proto.h" | |
43 | 43 | |||
@@ -74,91 +74,91 @@ static const struct extunit { | @@ -74,91 +74,91 @@ static const struct extunit { | |||
74 | "2", | 74 | "2", | |
75 | SFTP_EXT_STATVFS, | 75 | SFTP_EXT_STATVFS, | |
76 | },{ | 76 | },{ | |
77 | "fstatvfs@openssh.com", | 77 | "fstatvfs@openssh.com", | |
78 | "2", | 78 | "2", | |
79 | SFTP_EXT_FSTATVFS, | 79 | SFTP_EXT_FSTATVFS, | |
80 | },{ | 80 | },{ | |
81 | NULL, | 81 | NULL, | |
82 | NULL, | 82 | NULL, | |
83 | 0 | 83 | 0 | |
84 | }}; | 84 | }}; | |
85 | 85 | |||
86 | int | 86 | int | |
87 | psshfs_handshake(struct puffs_usermount *pu) | 87 | psshfs_handshake(struct puffs_usermount *pu, int fd) | |
88 | { | 88 | { | |
89 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | 89 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | |
90 | struct puffs_framebuf *pb; | 90 | struct puffs_framebuf *pb; | |
91 | struct puffs_pathobj *po_root; | 91 | struct puffs_pathobj *po_root; | |
92 | struct puffs_node *pn_root; | 92 | struct puffs_node *pn_root; | |
93 | struct vattr va, *rva; | 93 | struct vattr va, *rva; | |
94 | const struct extunit *extu; | 94 | const struct extunit *extu; | |
95 | char *rootpath; | 95 | char *rootpath; | |
96 | char *ext, *val; | 96 | char *ext, *val; | |
97 | uint32_t count; | 97 | uint32_t count; | |
98 | int rv, done; | 98 | int rv, done; | |
99 | 99 | |||
100 | pb = psbuf_makeout(); | 100 | pb = psbuf_makeout(); | |
101 | psbuf_put_1(pb, SSH_FXP_INIT); | 101 | psbuf_put_1(pb, SSH_FXP_INIT); | |
102 | psbuf_put_4(pb, SFTP_PROTOVERSION); | 102 | psbuf_put_4(pb, SFTP_PROTOVERSION); | |
103 | DO_IO(psbuf_write, pu, pb, pctx->sshfd, &done, rv); | 103 | DO_IO(psbuf_write, pu, pb, fd, &done, rv); | |
104 | 104 | |||
105 | puffs_framebuf_recycle(pb); | 105 | puffs_framebuf_recycle(pb); | |
106 | DO_IO(psbuf_read, pu, pb, pctx->sshfd, &done, rv); | 106 | DO_IO(psbuf_read, pu, pb, fd, &done, rv); | |
107 | if (psbuf_get_type(pb) != SSH_FXP_VERSION) | 107 | if (psbuf_get_type(pb) != SSH_FXP_VERSION) | |
108 | reterr((stderr, "invalid server response: %d", | 108 | reterr((stderr, "invalid server response: %d", | |
109 | psbuf_get_type(pb)), EPROTO); | 109 | psbuf_get_type(pb)), EPROTO); | |
110 | pctx->protover = psbuf_get_reqid(pb); | 110 | pctx->protover = psbuf_get_reqid(pb); | |
111 | 111 | |||
112 | /* | 112 | /* | |
113 | * Check out which extensions are available. Currently | 113 | * Check out which extensions are available. Currently | |
114 | * we are only interested in the openssh statvfs extension. | 114 | * we are only interested in the openssh statvfs extension. | |
115 | */ | 115 | */ | |
116 | for (;;) { | 116 | for (;;) { | |
117 | if (psbuf_get_str(pb, &ext, NULL) != 0) | 117 | if (psbuf_get_str(pb, &ext, NULL) != 0) | |
118 | break; | 118 | break; | |
119 | if (psbuf_get_str(pb, &val, NULL) != 0) | 119 | if (psbuf_get_str(pb, &val, NULL) != 0) | |
120 | break; | 120 | break; | |
121 | 121 | |||
122 | for (extu = exttable; extu->ext; extu++) | 122 | for (extu = exttable; extu->ext; extu++) | |
123 | if (strcmp(ext, extu->ext) == 0 | 123 | if (strcmp(ext, extu->ext) == 0 | |
124 | && strcmp(val, extu->val) == 0) | 124 | && strcmp(val, extu->val) == 0) | |
125 | pctx->extensions |= extu->extflag; | 125 | pctx->extensions |= extu->extflag; | |
126 | } | 126 | } | |
127 | 127 | |||
128 | /* scope out our rootpath */ | 128 | /* scope out our rootpath */ | |
129 | psbuf_recycleout(pb); | 129 | psbuf_recycleout(pb); | |
130 | psbuf_put_1(pb, SSH_FXP_REALPATH); | 130 | psbuf_put_1(pb, SSH_FXP_REALPATH); | |
131 | psbuf_put_4(pb, NEXTREQ(pctx)); | 131 | psbuf_put_4(pb, NEXTREQ(pctx)); | |
132 | psbuf_put_str(pb, pctx->mountpath); | 132 | psbuf_put_str(pb, pctx->mountpath); | |
133 | DO_IO(psbuf_write, pu, pb, pctx->sshfd, &done, rv); | 133 | DO_IO(psbuf_write, pu, pb, fd, &done, rv); | |
134 | 134 | |||
135 | puffs_framebuf_recycle(pb); | 135 | puffs_framebuf_recycle(pb); | |
136 | DO_IO(psbuf_read, pu, pb, pctx->sshfd, &done, rv); | 136 | DO_IO(psbuf_read, pu, pb, fd, &done, rv); | |
137 | if (psbuf_get_type(pb) != SSH_FXP_NAME) | 137 | if (psbuf_get_type(pb) != SSH_FXP_NAME) | |
138 | reterr((stderr, "invalid server realpath response for \"%s\"", | 138 | reterr((stderr, "invalid server realpath response for \"%s\"", | |
139 | pctx->mountpath), EPROTO); | 139 | pctx->mountpath), EPROTO); | |
140 | if (psbuf_get_4(pb, &count) == -1) | 140 | if (psbuf_get_4(pb, &count) == -1) | |
141 | reterr((stderr, "invalid realpath response: count"), EPROTO); | 141 | reterr((stderr, "invalid realpath response: count"), EPROTO); | |
142 | if (psbuf_get_str(pb, &rootpath, NULL) == -1) | 142 | if (psbuf_get_str(pb, &rootpath, NULL) == -1) | |
143 | reterr((stderr, "invalid realpath response: rootpath"), EPROTO); | 143 | reterr((stderr, "invalid realpath response: rootpath"), EPROTO); | |
144 | 144 | |||
145 | /* stat the rootdir so that we know it's a dir */ | 145 | /* stat the rootdir so that we know it's a dir */ | |
146 | psbuf_recycleout(pb); | 146 | psbuf_recycleout(pb); | |
147 | psbuf_req_str(pb, SSH_FXP_LSTAT, NEXTREQ(pctx), rootpath); | 147 | psbuf_req_str(pb, SSH_FXP_LSTAT, NEXTREQ(pctx), rootpath); | |
148 | DO_IO(psbuf_write, pu, pb, pctx->sshfd, &done, rv); | 148 | DO_IO(psbuf_write, pu, pb, fd, &done, rv); | |
149 | 149 | |||
150 | puffs_framebuf_recycle(pb); | 150 | puffs_framebuf_recycle(pb); | |
151 | DO_IO(psbuf_read, pu, pb, pctx->sshfd, &done, rv); | 151 | DO_IO(psbuf_read, pu, pb, fd, &done, rv); | |
152 | 152 | |||
153 | rv = psbuf_expect_attrs(pb, &va); | 153 | rv = psbuf_expect_attrs(pb, &va); | |
154 | if (rv) | 154 | if (rv) | |
155 | reterr((stderr, "couldn't stat rootpath"), rv); | 155 | reterr((stderr, "couldn't stat rootpath"), rv); | |
156 | puffs_framebuf_destroy(pb); | 156 | puffs_framebuf_destroy(pb); | |
157 | 157 | |||
158 | if (puffs_mode2vt(va.va_mode) != VDIR) | 158 | if (puffs_mode2vt(va.va_mode) != VDIR) | |
159 | reterr((stderr, "remote path (%s) not a directory", rootpath), | 159 | reterr((stderr, "remote path (%s) not a directory", rootpath), | |
160 | ENOTDIR); | 160 | ENOTDIR); | |
161 | 161 | |||
162 | pn_root = puffs_getroot(pu); | 162 | pn_root = puffs_getroot(pu); | |
163 | rva = &pn_root->pn_va; | 163 | rva = &pn_root->pn_va; | |
164 | puffs_setvattr(rva, &va); | 164 | puffs_setvattr(rva, &va); | |
@@ -177,27 +177,27 @@ psshfs_fs_statvfs(struct puffs_usermount | @@ -177,27 +177,27 @@ psshfs_fs_statvfs(struct puffs_usermount | |||
177 | { | 177 | { | |
178 | PSSHFSAUTOVAR(pu); | 178 | PSSHFSAUTOVAR(pu); | |
179 | uint64_t tmpval; | 179 | uint64_t tmpval; | |
180 | uint8_t type; | 180 | uint8_t type; | |
181 | 181 | |||
182 | memset(sbp, 0, sizeof(*sbp)); | 182 | memset(sbp, 0, sizeof(*sbp)); | |
183 | sbp->f_bsize = sbp->f_frsize = sbp->f_iosize = 512; | 183 | sbp->f_bsize = sbp->f_frsize = sbp->f_iosize = 512; | |
184 | 184 | |||
185 | if ((pctx->extensions & SFTP_EXT_STATVFS) == 0) | 185 | if ((pctx->extensions & SFTP_EXT_STATVFS) == 0) | |
186 | goto out; | 186 | goto out; | |
187 | 187 | |||
188 | psbuf_req_str(pb, SSH_FXP_EXTENDED, reqid, "statvfs@openssh.com"); | 188 | psbuf_req_str(pb, SSH_FXP_EXTENDED, reqid, "statvfs@openssh.com"); | |
189 | psbuf_put_str(pb, pctx->mountpath); | 189 | psbuf_put_str(pb, pctx->mountpath); | |
190 | GETRESPONSE(pb); | 190 | GETRESPONSE(pb, pctx->sshfd); | |
191 | 191 | |||
192 | type = psbuf_get_type(pb); | 192 | type = psbuf_get_type(pb); | |
193 | if (type != SSH_FXP_EXTENDED_REPLY) { | 193 | if (type != SSH_FXP_EXTENDED_REPLY) { | |
194 | /* use the default */ | 194 | /* use the default */ | |
195 | goto out; | 195 | goto out; | |
196 | } | 196 | } | |
197 | 197 | |||
198 | psbuf_get_8(pb, &tmpval); | 198 | psbuf_get_8(pb, &tmpval); | |
199 | sbp->f_bsize = tmpval; | 199 | sbp->f_bsize = tmpval; | |
200 | psbuf_get_8(pb, &tmpval); | 200 | psbuf_get_8(pb, &tmpval); | |
201 | sbp->f_frsize = tmpval; | 201 | sbp->f_frsize = tmpval; | |
202 | psbuf_get_8(pb, &sbp->f_blocks); | 202 | psbuf_get_8(pb, &sbp->f_blocks); | |
203 | psbuf_get_8(pb, &sbp->f_bfree); | 203 | psbuf_get_8(pb, &sbp->f_bfree); | |
@@ -212,26 +212,31 @@ psshfs_fs_statvfs(struct puffs_usermount | @@ -212,26 +212,31 @@ psshfs_fs_statvfs(struct puffs_usermount | |||
212 | sbp->f_namemax = tmpval; | 212 | sbp->f_namemax = tmpval; | |
213 | 213 | |||
214 | out: | 214 | out: | |
215 | PSSHFSRETURN(rv); | 215 | PSSHFSRETURN(rv); | |
216 | } | 216 | } | |
217 | 217 | |||
218 | int | 218 | int | |
219 | psshfs_fs_unmount(struct puffs_usermount *pu, int flags) | 219 | psshfs_fs_unmount(struct puffs_usermount *pu, int flags) | |
220 | { | 220 | { | |
221 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | 221 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | |
222 | 222 | |||
223 | kill(pctx->sshpid, SIGTERM); | 223 | kill(pctx->sshpid, SIGTERM); | |
224 | close(pctx->sshfd); | 224 | close(pctx->sshfd); | |
225 | if (pctx->numconnections == 2) { | |||
226 | kill(pctx->sshpid_data, SIGTERM); | |||
227 | close(pctx->sshfd_data); | |||
228 | } | |||
229 | ||||
225 | return 0; | 230 | return 0; | |
226 | } | 231 | } | |
227 | 232 | |||
228 | int | 233 | int | |
229 | psshfs_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie, | 234 | psshfs_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie, | |
230 | void *fid, size_t *fidsize) | 235 | void *fid, size_t *fidsize) | |
231 | { | 236 | { | |
232 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | 237 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | |
233 | struct puffs_node *pn = cookie; | 238 | struct puffs_node *pn = cookie; | |
234 | struct psshfs_node *psn = pn->pn_data; | 239 | struct psshfs_node *psn = pn->pn_data; | |
235 | struct psshfs_fid *pf = fid; | 240 | struct psshfs_fid *pf = fid; | |
236 | 241 | |||
237 | pf->mounttime = pctx->mounttime; | 242 | pf->mounttime = pctx->mounttime; |
--- src/usr.sbin/puffs/mount_psshfs/mount_psshfs.8 2009/02/26 07:14:36 1.19
+++ src/usr.sbin/puffs/mount_psshfs/mount_psshfs.8 2009/05/20 13:56:36 1.20
@@ -1,39 +1,39 @@ | @@ -1,39 +1,39 @@ | |||
1 | .\" $NetBSD: mount_psshfs.8,v 1.19 2009/02/26 07:14:36 wiz Exp $ | 1 | .\" $NetBSD: mount_psshfs.8,v 1.20 2009/05/20 13:56:36 pooka Exp $ | |
2 | .\" | 2 | .\" | |
3 | .\" Copyright (c) 2007 Antti Kantee. All rights reserved. | 3 | .\" Copyright (c) 2007 Antti Kantee. All rights reserved. | |
4 | .\" | 4 | .\" | |
5 | .\" Redistribution and use in source and binary forms, with or without | 5 | .\" Redistribution and use in source and binary forms, with or without | |
6 | .\" modification, are permitted provided that the following conditions | 6 | .\" modification, are permitted provided that the following conditions | |
7 | .\" are met: | 7 | .\" are met: | |
8 | .\" 1. Redistributions of source code must retain the above copyright | 8 | .\" 1. Redistributions of source code must retain the above copyright | |
9 | .\" notice, this list of conditions and the following disclaimer. | 9 | .\" notice, this list of conditions and the following disclaimer. | |
10 | .\" 2. Redistributions in binary form must reproduce the above copyright | 10 | .\" 2. Redistributions in binary form must reproduce the above copyright | |
11 | .\" notice, this list of conditions and the following disclaimer in the | 11 | .\" notice, this list of conditions and the following disclaimer in the | |
12 | .\" documentation and/or other materials provided with the distribution. | 12 | .\" documentation and/or other materials provided with the distribution. | |
13 | .\" | 13 | .\" | |
14 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | 14 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
15 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 15 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
16 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 16 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
17 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 17 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
18 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 18 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
19 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 19 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
20 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 20 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
21 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 21 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
22 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 22 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
23 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 23 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
24 | .\" SUCH DAMAGE. | 24 | .\" SUCH DAMAGE. | |
25 | .\" | 25 | .\" | |
26 | .Dd February 25, 2009 | 26 | .Dd May 20, 2009 | |
27 | .Dt MOUNT_PSSHFS 8 | 27 | .Dt MOUNT_PSSHFS 8 | |
28 | .Os | 28 | .Os | |
29 | .Sh NAME | 29 | .Sh NAME | |
30 | .Nm mount_psshfs | 30 | .Nm mount_psshfs | |
31 | .Nd sshfs implementation for puffs | 31 | .Nd sshfs implementation for puffs | |
32 | .Sh SYNOPSIS | 32 | .Sh SYNOPSIS | |
33 | .Nm | 33 | .Nm | |
34 | .Op Ar options | 34 | .Op Ar options | |
35 | .Ar user@host[:path] | 35 | .Ar user@host[:path] | |
36 | .Ar mount_point | 36 | .Ar mount_point | |
37 | .Sh DESCRIPTION | 37 | .Sh DESCRIPTION | |
38 | The | 38 | The | |
39 | .Nm | 39 | .Nm | |
@@ -46,26 +46,39 @@ This functionality is commonly known as | @@ -46,26 +46,39 @@ This functionality is commonly known as | |||
46 | The mandatory parameters are the target host name and local mount | 46 | The mandatory parameters are the target host name and local mount | |
47 | point. | 47 | point. | |
48 | The target host parameter can optionally contain a username whose | 48 | The target host parameter can optionally contain a username whose | |
49 | credentials will be used by the remote sshd, and a relative or | 49 | credentials will be used by the remote sshd, and a relative or | |
50 | absolute path for the remote mount point's root. | 50 | absolute path for the remote mount point's root. | |
51 | If no user is given, the credentials of the user issuing the mount | 51 | If no user is given, the credentials of the user issuing the mount | |
52 | command are used. | 52 | command are used. | |
53 | If no path is given, the user's home directory on the remote machine | 53 | If no path is given, the user's home directory on the remote machine | |
54 | will be used. | 54 | will be used. | |
55 | .Pp | 55 | .Pp | |
56 | The following command line options are available: | 56 | The following command line options are available: | |
57 | .Pp | 57 | .Pp | |
58 | .Bl -tag -width xxx | 58 | .Bl -tag -width xxx | |
59 | .It Fl c Ar nconnect | |||
60 | Opens | |||
61 | .Ar nconnect | |||
62 | connections to the server. | |||
63 | Currently, the value has to be 1 or 2. | |||
64 | If 2 is specified, a second connection is opened for the reading | |||
65 | and writing of data, while directory operations are performed on | |||
66 | their own connection. | |||
67 | This can greatly increase directory operation performance (ls, | |||
68 | mkdir, etc.) if | |||
69 | .Nm | |||
70 | completely saturates the available bandwidth by doing bulk data copying. | |||
71 | The default is 1. | |||
59 | .It Fl e | 72 | .It Fl e | |
60 | Makes the mounted file system NFS exportable. | 73 | Makes the mounted file system NFS exportable. | |
61 | If this option is used, it is very important to understand that | 74 | If this option is used, it is very important to understand that | |
62 | .Nm | 75 | .Nm | |
63 | can not provide complete support for NFS due to the limitations in | 76 | can not provide complete support for NFS due to the limitations in | |
64 | the backend. | 77 | the backend. | |
65 | Files are valid only for the time that | 78 | Files are valid only for the time that | |
66 | .Nm | 79 | .Nm | |
67 | is running and in the event of e.g. a server crash, all client retries | 80 | is running and in the event of e.g. a server crash, all client retries | |
68 | to access files will fail. | 81 | to access files will fail. | |
69 | .It Fl F Ar configfile | 82 | .It Fl F Ar configfile | |
70 | Pass a configuration file to | 83 | Pass a configuration file to | |
71 | .Xr ssh 1 . | 84 | .Xr ssh 1 . |
--- src/usr.sbin/puffs/mount_psshfs/node.c 2009/03/29 16:06:53 1.56
+++ src/usr.sbin/puffs/mount_psshfs/node.c 2009/05/20 13:56:36 1.57
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: node.c,v 1.56 2009/03/29 16:06:53 pooka Exp $ */ | 1 | /* $NetBSD: node.c,v 1.57 2009/05/20 13:56:36 pooka Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2006 Antti Kantee. All Rights Reserved. | 4 | * Copyright (c) 2006 Antti Kantee. All Rights Reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -17,27 +17,27 @@ | @@ -17,27 +17,27 @@ | |||
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
21 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 21 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
25 | * SUCH DAMAGE. | 25 | * SUCH DAMAGE. | |
26 | */ | 26 | */ | |
27 | 27 | |||
28 | #include <sys/cdefs.h> | 28 | #include <sys/cdefs.h> | |
29 | #ifndef lint | 29 | #ifndef lint | |
30 | __RCSID("$NetBSD: node.c,v 1.56 2009/03/29 16:06:53 pooka Exp $"); | 30 | __RCSID("$NetBSD: node.c,v 1.57 2009/05/20 13:56:36 pooka Exp $"); | |
31 | #endif /* !lint */ | 31 | #endif /* !lint */ | |
32 | 32 | |||
33 | #include <assert.h> | 33 | #include <assert.h> | |
34 | #include <errno.h> | 34 | #include <errno.h> | |
35 | #include <stdio.h> | 35 | #include <stdio.h> | |
36 | #include <stdlib.h> | 36 | #include <stdlib.h> | |
37 | 37 | |||
38 | #include "psshfs.h" | 38 | #include "psshfs.h" | |
39 | #include "sftp_proto.h" | 39 | #include "sftp_proto.h" | |
40 | 40 | |||
41 | int | 41 | int | |
42 | psshfs_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc, | 42 | psshfs_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc, | |
43 | struct puffs_newinfo *pni, const struct puffs_cn *pcn) | 43 | struct puffs_newinfo *pni, const struct puffs_cn *pcn) | |
@@ -138,79 +138,79 @@ psshfs_node_setattr(struct puffs_usermou | @@ -138,79 +138,79 @@ psshfs_node_setattr(struct puffs_usermou | |||
138 | kludgeva.va_mtime.tv_sec = pn->pn_va.va_mtime.tv_sec; | 138 | kludgeva.va_mtime.tv_sec = pn->pn_va.va_mtime.tv_sec; | |
139 | else | 139 | else | |
140 | kludgeva.va_mtime.tv_sec = va->va_atime.tv_sec; | 140 | kludgeva.va_mtime.tv_sec = va->va_atime.tv_sec; | |
141 | } | 141 | } | |
142 | if (va->va_mtime.tv_sec != PUFFS_VNOVAL | 142 | if (va->va_mtime.tv_sec != PUFFS_VNOVAL | |
143 | && va->va_atime.tv_sec == PUFFS_VNOVAL) { | 143 | && va->va_atime.tv_sec == PUFFS_VNOVAL) { | |
144 | if (pn->pn_va.va_atime.tv_sec != PUFFS_VNOVAL) | 144 | if (pn->pn_va.va_atime.tv_sec != PUFFS_VNOVAL) | |
145 | kludgeva.va_atime.tv_sec = pn->pn_va.va_atime.tv_sec; | 145 | kludgeva.va_atime.tv_sec = pn->pn_va.va_atime.tv_sec; | |
146 | else | 146 | else | |
147 | kludgeva.va_atime.tv_sec = va->va_mtime.tv_sec; | 147 | kludgeva.va_atime.tv_sec = va->va_mtime.tv_sec; | |
148 | } | 148 | } | |
149 | 149 | |||
150 | psbuf_put_vattr(pb, &kludgeva); | 150 | psbuf_put_vattr(pb, &kludgeva); | |
151 | GETRESPONSE(pb); | 151 | GETRESPONSE(pb, pctx->sshfd); | |
152 | 152 | |||
153 | rv = psbuf_expect_status(pb); | 153 | rv = psbuf_expect_status(pb); | |
154 | if (rv == 0) | 154 | if (rv == 0) | |
155 | puffs_setvattr(&pn->pn_va, &kludgeva); | 155 | puffs_setvattr(&pn->pn_va, &kludgeva); | |
156 | 156 | |||
157 | out: | 157 | out: | |
158 | PSSHFSRETURN(rv); | 158 | PSSHFSRETURN(rv); | |
159 | } | 159 | } | |
160 | 160 | |||
161 | int | 161 | int | |
162 | psshfs_node_create(struct puffs_usermount *pu, puffs_cookie_t opc, | 162 | psshfs_node_create(struct puffs_usermount *pu, puffs_cookie_t opc, | |
163 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, | 163 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, | |
164 | const struct vattr *va) | 164 | const struct vattr *va) | |
165 | { | 165 | { | |
166 | PSSHFSAUTOVAR(pu); | 166 | PSSHFSAUTOVAR(pu); | |
167 | struct puffs_node *pn = opc; | 167 | struct puffs_node *pn = opc; | |
168 | struct puffs_node *pn_new; | 168 | struct puffs_node *pn_new; | |
169 | char *fhand = NULL; | 169 | char *fhand = NULL; | |
170 | uint32_t fhandlen; | 170 | uint32_t fhandlen; | |
171 | 171 | |||
172 | /* Create node on server first */ | 172 | /* Create node on server first */ | |
173 | psbuf_req_str(pb, SSH_FXP_OPEN, reqid, PCNPATH(pcn)); | 173 | psbuf_req_str(pb, SSH_FXP_OPEN, reqid, PCNPATH(pcn)); | |
174 | psbuf_put_4(pb, SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC); | 174 | psbuf_put_4(pb, SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC); | |
175 | psbuf_put_vattr(pb, va); | 175 | psbuf_put_vattr(pb, va); | |
176 | GETRESPONSE(pb); | 176 | GETRESPONSE(pb, pctx->sshfd); | |
177 | rv = psbuf_expect_handle(pb, &fhand, &fhandlen); | 177 | rv = psbuf_expect_handle(pb, &fhand, &fhandlen); | |
178 | if (rv) | 178 | if (rv) | |
179 | goto out; | 179 | goto out; | |
180 | 180 | |||
181 | /* | 181 | /* | |
182 | * Do *not* create the local node before getting a response | 182 | * Do *not* create the local node before getting a response | |
183 | * from the server. Otherwise we might screw up consistency, | 183 | * from the server. Otherwise we might screw up consistency, | |
184 | * namely that the node can be looked up before create has | 184 | * namely that the node can be looked up before create has | |
185 | * returned (mind you, the kernel will unlock the directory | 185 | * returned (mind you, the kernel will unlock the directory | |
186 | * before the create call from userspace returns). | 186 | * before the create call from userspace returns). | |
187 | */ | 187 | */ | |
188 | pn_new = allocnode(pu, pn, pcn->pcn_name, va); | 188 | pn_new = allocnode(pu, pn, pcn->pcn_name, va); | |
189 | if (!pn_new) { | 189 | if (!pn_new) { | |
190 | struct puffs_framebuf *pb2 = psbuf_makeout(); | 190 | struct puffs_framebuf *pb2 = psbuf_makeout(); | |
191 | reqid = NEXTREQ(pctx); | 191 | reqid = NEXTREQ(pctx); | |
192 | psbuf_req_str(pb2, SSH_FXP_REMOVE, reqid, PCNPATH(pcn)); | 192 | psbuf_req_str(pb2, SSH_FXP_REMOVE, reqid, PCNPATH(pcn)); | |
193 | JUSTSEND(pb2); | 193 | JUSTSEND(pb2, pctx->sshfd); | |
194 | rv = ENOMEM; | 194 | rv = ENOMEM; | |
195 | } | 195 | } | |
196 | 196 | |||
197 | if (pn_new) | 197 | if (pn_new) | |
198 | puffs_newinfo_setcookie(pni, pn_new); | 198 | puffs_newinfo_setcookie(pni, pn_new); | |
199 | 199 | |||
200 | reqid = NEXTREQ(pctx); | 200 | reqid = NEXTREQ(pctx); | |
201 | psbuf_recycleout(pb); | 201 | psbuf_recycleout(pb); | |
202 | psbuf_req_data(pb, SSH_FXP_CLOSE, reqid, fhand, fhandlen); | 202 | psbuf_req_data(pb, SSH_FXP_CLOSE, reqid, fhand, fhandlen); | |
203 | JUSTSEND(pb); | 203 | JUSTSEND(pb, pctx->sshfd); | |
204 | free(fhand); | 204 | free(fhand); | |
205 | return rv; | 205 | return rv; | |
206 | 206 | |||
207 | out: | 207 | out: | |
208 | free(fhand); | 208 | free(fhand); | |
209 | PSSHFSRETURN(rv); | 209 | PSSHFSRETURN(rv); | |
210 | } | 210 | } | |
211 | 211 | |||
212 | /* | 212 | /* | |
213 | * Open a file handle. This is used for read and write. We do not | 213 | * Open a file handle. This is used for read and write. We do not | |
214 | * wait here for the success or failure of this operation. This is | 214 | * wait here for the success or failure of this operation. This is | |
215 | * because otherwise opening and closing file handles would block | 215 | * because otherwise opening and closing file handles would block | |
216 | * reading potentially cached information. Rather, we defer the wait | 216 | * reading potentially cached information. Rather, we defer the wait | |
@@ -238,45 +238,45 @@ psshfs_node_open(struct puffs_usermount | @@ -238,45 +238,45 @@ psshfs_node_open(struct puffs_usermount | |||
238 | return 0; | 238 | return 0; | |
239 | 239 | |||
240 | puffs_setback(pcc, PUFFS_SETBACK_INACT_N1); | 240 | puffs_setback(pcc, PUFFS_SETBACK_INACT_N1); | |
241 | puffs_vattr_null(&va); | 241 | puffs_vattr_null(&va); | |
242 | didread = didwrite = 0; | 242 | didread = didwrite = 0; | |
243 | if (mode & FREAD && psn->fhand_r == NULL && psn->lazyopen_r == NULL) { | 243 | if (mode & FREAD && psn->fhand_r == NULL && psn->lazyopen_r == NULL) { | |
244 | pb = psbuf_makeout(); | 244 | pb = psbuf_makeout(); | |
245 | 245 | |||
246 | reqid = NEXTREQ(pctx); | 246 | reqid = NEXTREQ(pctx); | |
247 | psbuf_req_str(pb, SSH_FXP_OPEN, reqid, PNPATH(pn)); | 247 | psbuf_req_str(pb, SSH_FXP_OPEN, reqid, PNPATH(pn)); | |
248 | psbuf_put_4(pb, SSH_FXF_READ); | 248 | psbuf_put_4(pb, SSH_FXF_READ); | |
249 | psbuf_put_vattr(pb, &va); | 249 | psbuf_put_vattr(pb, &va); | |
250 | 250 | |||
251 | if (puffs_framev_enqueue_cb(pu, pctx->sshfd, pb, | 251 | if (puffs_framev_enqueue_cb(pu, pctx->sshfd_data, pb, | |
252 | lazyopen_rresp, psn, 0) == -1) { | 252 | lazyopen_rresp, psn, 0) == -1) { | |
253 | rv = errno; | 253 | rv = errno; | |
254 | puffs_framebuf_destroy(pb); | 254 | puffs_framebuf_destroy(pb); | |
255 | goto out; | 255 | goto out; | |
256 | } | 256 | } | |
257 | 257 | |||
258 | psn->lazyopen_r = pb; | 258 | psn->lazyopen_r = pb; | |
259 | didread = 1; | 259 | didread = 1; | |
260 | } | 260 | } | |
261 | if (mode & FWRITE && psn->fhand_w == NULL && psn->lazyopen_w == NULL) { | 261 | if (mode & FWRITE && psn->fhand_w == NULL && psn->lazyopen_w == NULL) { | |
262 | pb2 = psbuf_makeout(); | 262 | pb2 = psbuf_makeout(); | |
263 | 263 | |||
264 | reqid = NEXTREQ(pctx); | 264 | reqid = NEXTREQ(pctx); | |
265 | psbuf_req_str(pb2, SSH_FXP_OPEN, reqid, PNPATH(pn)); | 265 | psbuf_req_str(pb2, SSH_FXP_OPEN, reqid, PNPATH(pn)); | |
266 | psbuf_put_4(pb2, SSH_FXF_WRITE); | 266 | psbuf_put_4(pb2, SSH_FXF_WRITE); | |
267 | psbuf_put_vattr(pb2, &va); | 267 | psbuf_put_vattr(pb2, &va); | |
268 | 268 | |||
269 | if (puffs_framev_enqueue_cb(pu, pctx->sshfd, pb2, | 269 | if (puffs_framev_enqueue_cb(pu, pctx->sshfd_data, pb2, | |
270 | lazyopen_wresp, psn, 0) == -1) { | 270 | lazyopen_wresp, psn, 0) == -1) { | |
271 | rv = errno; | 271 | rv = errno; | |
272 | puffs_framebuf_destroy(pb2); | 272 | puffs_framebuf_destroy(pb2); | |
273 | goto out; | 273 | goto out; | |
274 | } | 274 | } | |
275 | 275 | |||
276 | psn->lazyopen_w = pb2; | 276 | psn->lazyopen_w = pb2; | |
277 | didwrite = 1; | 277 | didwrite = 1; | |
278 | } | 278 | } | |
279 | psn->stat &= ~PSN_HANDLECLOSE; | 279 | psn->stat &= ~PSN_HANDLECLOSE; | |
280 | 280 | |||
281 | out: | 281 | out: | |
282 | /* wait? */ | 282 | /* wait? */ | |
@@ -470,27 +470,27 @@ psshfs_node_read(struct puffs_usermount | @@ -470,27 +470,27 @@ psshfs_node_read(struct puffs_usermount | |||
470 | /* | 470 | /* | |
471 | * Do this *after* accessing the file, the handle might not | 471 | * Do this *after* accessing the file, the handle might not | |
472 | * exist after blocking. | 472 | * exist after blocking. | |
473 | */ | 473 | */ | |
474 | if (max_reads && ++psn->readcount > max_reads) { | 474 | if (max_reads && ++psn->readcount > max_reads) { | |
475 | struct psshfs_wait pw; | 475 | struct psshfs_wait pw; | |
476 | 476 | |||
477 | pw.pw_cc = pcc; | 477 | pw.pw_cc = pcc; | |
478 | pw.pw_type = PWTYPE_READ2; | 478 | pw.pw_type = PWTYPE_READ2; | |
479 | TAILQ_INSERT_TAIL(&psn->pw, &pw, pw_entries); | 479 | TAILQ_INSERT_TAIL(&psn->pw, &pw, pw_entries); | |
480 | puffs_cc_yield(pcc); | 480 | puffs_cc_yield(pcc); | |
481 | } | 481 | } | |
482 | 482 | |||
483 | GETRESPONSE(pb); | 483 | GETRESPONSE(pb, pctx->sshfd_data); | |
484 | 484 | |||
485 | rv = psbuf_do_data(pb, buf, &readlen); | 485 | rv = psbuf_do_data(pb, buf, &readlen); | |
486 | if (rv == 0) | 486 | if (rv == 0) | |
487 | *resid -= readlen; | 487 | *resid -= readlen; | |
488 | 488 | |||
489 | out: | 489 | out: | |
490 | if (max_reads && --psn->readcount >= max_reads) { | 490 | if (max_reads && --psn->readcount >= max_reads) { | |
491 | TAILQ_FOREACH(pwp, &psn->pw, pw_entries) | 491 | TAILQ_FOREACH(pwp, &psn->pw, pw_entries) | |
492 | if (pwp->pw_type == PWTYPE_READ2) | 492 | if (pwp->pw_type == PWTYPE_READ2) | |
493 | break; | 493 | break; | |
494 | assert(pwp != NULL); | 494 | assert(pwp != NULL); | |
495 | puffs_cc_schedule(pwp->pw_cc); | 495 | puffs_cc_schedule(pwp->pw_cc); | |
496 | TAILQ_REMOVE(&psn->pw, pwp, pw_entries); | 496 | TAILQ_REMOVE(&psn->pw, pwp, pw_entries); | |
@@ -564,27 +564,27 @@ psshfs_node_write(struct puffs_usermount | @@ -564,27 +564,27 @@ psshfs_node_write(struct puffs_usermount | |||
564 | goto out; | 564 | goto out; | |
565 | } | 565 | } | |
566 | 566 | |||
567 | if (!psn->fhand_w) { | 567 | if (!psn->fhand_w) { | |
568 | abort(); | 568 | abort(); | |
569 | rv = EINVAL; | 569 | rv = EINVAL; | |
570 | goto out; | 570 | goto out; | |
571 | } | 571 | } | |
572 | 572 | |||
573 | writelen = *resid; | 573 | writelen = *resid; | |
574 | psbuf_req_data(pb, SSH_FXP_WRITE, reqid, psn->fhand_w,psn->fhand_w_len); | 574 | psbuf_req_data(pb, SSH_FXP_WRITE, reqid, psn->fhand_w,psn->fhand_w_len); | |
575 | psbuf_put_8(pb, offset); | 575 | psbuf_put_8(pb, offset); | |
576 | psbuf_put_data(pb, buf, writelen); | 576 | psbuf_put_data(pb, buf, writelen); | |
577 | GETRESPONSE(pb); | 577 | GETRESPONSE(pb, pctx->sshfd_data); | |
578 | 578 | |||
579 | rv = psbuf_expect_status(pb); | 579 | rv = psbuf_expect_status(pb); | |
580 | if (rv == 0) | 580 | if (rv == 0) | |
581 | *resid = 0; | 581 | *resid = 0; | |
582 | 582 | |||
583 | if (pn->pn_va.va_size < offset + writelen) | 583 | if (pn->pn_va.va_size < offset + writelen) | |
584 | pn->pn_va.va_size = offset + writelen; | 584 | pn->pn_va.va_size = offset + writelen; | |
585 | 585 | |||
586 | out: | 586 | out: | |
587 | /* check if we need a lazyclose */ | 587 | /* check if we need a lazyclose */ | |
588 | if (psn->stat & PSN_HANDLECLOSE && psn->fhand_w) { | 588 | if (psn->stat & PSN_HANDLECLOSE && psn->fhand_w) { | |
589 | TAILQ_FOREACH(pwp, &psn->pw, pw_entries) | 589 | TAILQ_FOREACH(pwp, &psn->pw, pw_entries) | |
590 | if (pwp->pw_type == PWTYPE_WRITE) | 590 | if (pwp->pw_type == PWTYPE_WRITE) | |
@@ -616,27 +616,27 @@ psshfs_node_readlink(struct puffs_usermo | @@ -616,27 +616,27 @@ psshfs_node_readlink(struct puffs_usermo | |||
616 | * from the server if we get many requests at once, but that's | 616 | * from the server if we get many requests at once, but that's | |
617 | * quite harmless as this routine is reentrant. | 617 | * quite harmless as this routine is reentrant. | |
618 | */ | 618 | */ | |
619 | if (psn->symlink && !REFRESHTIMEOUT(pctx, time(NULL) - psn->slread)) | 619 | if (psn->symlink && !REFRESHTIMEOUT(pctx, time(NULL) - psn->slread)) | |
620 | goto copy; | 620 | goto copy; | |
621 | 621 | |||
622 | if (psn->symlink) { | 622 | if (psn->symlink) { | |
623 | free(psn->symlink); | 623 | free(psn->symlink); | |
624 | psn->symlink = NULL; | 624 | psn->symlink = NULL; | |
625 | psn->slread = 0; | 625 | psn->slread = 0; | |
626 | } | 626 | } | |
627 | 627 | |||
628 | psbuf_req_str(pb, SSH_FXP_READLINK, reqid, PNPATH(pn)); | 628 | psbuf_req_str(pb, SSH_FXP_READLINK, reqid, PNPATH(pn)); | |
629 | GETRESPONSE(pb); | 629 | GETRESPONSE(pb, pctx->sshfd); | |
630 | 630 | |||
631 | rv = psbuf_expect_name(pb, &count); | 631 | rv = psbuf_expect_name(pb, &count); | |
632 | if (rv) | 632 | if (rv) | |
633 | goto out; | 633 | goto out; | |
634 | if (count != 1) { | 634 | if (count != 1) { | |
635 | rv = EPROTO; | 635 | rv = EPROTO; | |
636 | goto out; | 636 | goto out; | |
637 | } | 637 | } | |
638 | 638 | |||
639 | rv = psbuf_get_str(pb, &psn->symlink, NULL); | 639 | rv = psbuf_get_str(pb, &psn->symlink, NULL); | |
640 | if (rv) | 640 | if (rv) | |
641 | goto out; | 641 | goto out; | |
642 | psn->slread = time(NULL); | 642 | psn->slread = time(NULL); | |
@@ -652,27 +652,27 @@ psshfs_node_readlink(struct puffs_usermo | @@ -652,27 +652,27 @@ psshfs_node_readlink(struct puffs_usermo | |||
652 | static int | 652 | static int | |
653 | doremove(struct puffs_usermount *pu, struct puffs_node *pn_dir, | 653 | doremove(struct puffs_usermount *pu, struct puffs_node *pn_dir, | |
654 | struct puffs_node *pn, const char *name) | 654 | struct puffs_node *pn, const char *name) | |
655 | { | 655 | { | |
656 | PSSHFSAUTOVAR(pu); | 656 | PSSHFSAUTOVAR(pu); | |
657 | int op; | 657 | int op; | |
658 | 658 | |||
659 | if (pn->pn_va.va_type == VDIR) | 659 | if (pn->pn_va.va_type == VDIR) | |
660 | op = SSH_FXP_RMDIR; | 660 | op = SSH_FXP_RMDIR; | |
661 | else | 661 | else | |
662 | op = SSH_FXP_REMOVE; | 662 | op = SSH_FXP_REMOVE; | |
663 | 663 | |||
664 | psbuf_req_str(pb, op, reqid, PNPATH(pn)); | 664 | psbuf_req_str(pb, op, reqid, PNPATH(pn)); | |
665 | GETRESPONSE(pb); | 665 | GETRESPONSE(pb, pctx->sshfd); | |
666 | 666 | |||
667 | rv = psbuf_expect_status(pb); | 667 | rv = psbuf_expect_status(pb); | |
668 | if (rv == 0) | 668 | if (rv == 0) | |
669 | nukenode(pn, name, 0); | 669 | nukenode(pn, name, 0); | |
670 | 670 | |||
671 | out: | 671 | out: | |
672 | PSSHFSRETURN(rv); | 672 | PSSHFSRETURN(rv); | |
673 | } | 673 | } | |
674 | 674 | |||
675 | int | 675 | int | |
676 | psshfs_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc, | 676 | psshfs_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc, | |
677 | puffs_cookie_t targ, const struct puffs_cn *pcn) | 677 | puffs_cookie_t targ, const struct puffs_cn *pcn) | |
678 | { | 678 | { | |
@@ -705,41 +705,41 @@ psshfs_node_rmdir(struct puffs_usermount | @@ -705,41 +705,41 @@ psshfs_node_rmdir(struct puffs_usermount | |||
705 | } | 705 | } | |
706 | 706 | |||
707 | int | 707 | int | |
708 | psshfs_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc, | 708 | psshfs_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc, | |
709 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, | 709 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, | |
710 | const struct vattr *va) | 710 | const struct vattr *va) | |
711 | { | 711 | { | |
712 | PSSHFSAUTOVAR(pu); | 712 | PSSHFSAUTOVAR(pu); | |
713 | struct puffs_node *pn = opc; | 713 | struct puffs_node *pn = opc; | |
714 | struct puffs_node *pn_new; | 714 | struct puffs_node *pn_new; | |
715 | 715 | |||
716 | psbuf_req_str(pb, SSH_FXP_MKDIR, reqid, PCNPATH(pcn)); | 716 | psbuf_req_str(pb, SSH_FXP_MKDIR, reqid, PCNPATH(pcn)); | |
717 | psbuf_put_vattr(pb, va); | 717 | psbuf_put_vattr(pb, va); | |
718 | GETRESPONSE(pb); | 718 | GETRESPONSE(pb, pctx->sshfd); | |
719 | 719 | |||
720 | rv = psbuf_expect_status(pb); | 720 | rv = psbuf_expect_status(pb); | |
721 | if (rv) | 721 | if (rv) | |
722 | goto out; | 722 | goto out; | |
723 | 723 | |||
724 | pn_new = allocnode(pu, pn, pcn->pcn_name, va); | 724 | pn_new = allocnode(pu, pn, pcn->pcn_name, va); | |
725 | if (pn_new) { | 725 | if (pn_new) { | |
726 | puffs_newinfo_setcookie(pni, pn_new); | 726 | puffs_newinfo_setcookie(pni, pn_new); | |
727 | } else { | 727 | } else { | |
728 | struct puffs_framebuf *pb2 = psbuf_makeout(); | 728 | struct puffs_framebuf *pb2 = psbuf_makeout(); | |
729 | reqid = NEXTREQ(pctx); | 729 | reqid = NEXTREQ(pctx); | |
730 | psbuf_recycleout(pb2); | 730 | psbuf_recycleout(pb2); | |
731 | psbuf_req_str(pb2, SSH_FXP_RMDIR, reqid, PCNPATH(pcn)); | 731 | psbuf_req_str(pb2, SSH_FXP_RMDIR, reqid, PCNPATH(pcn)); | |
732 | JUSTSEND(pb2); | 732 | JUSTSEND(pb2, pctx->sshfd); | |
733 | rv = ENOMEM; | 733 | rv = ENOMEM; | |
734 | } | 734 | } | |
735 | 735 | |||
736 | out: | 736 | out: | |
737 | PSSHFSRETURN(rv); | 737 | PSSHFSRETURN(rv); | |
738 | } | 738 | } | |
739 | 739 | |||
740 | int | 740 | int | |
741 | psshfs_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc, | 741 | psshfs_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc, | |
742 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, | 742 | struct puffs_newinfo *pni, const struct puffs_cn *pcn, | |
743 | const struct vattr *va, const char *link_target) | 743 | const struct vattr *va, const char *link_target) | |
744 | { | 744 | { | |
745 | PSSHFSAUTOVAR(pu); | 745 | PSSHFSAUTOVAR(pu); | |
@@ -747,41 +747,41 @@ psshfs_node_symlink(struct puffs_usermou | @@ -747,41 +747,41 @@ psshfs_node_symlink(struct puffs_usermou | |||
747 | struct puffs_node *pn_new; | 747 | struct puffs_node *pn_new; | |
748 | 748 | |||
749 | if (pctx->protover < 3) { | 749 | if (pctx->protover < 3) { | |
750 | rv = EOPNOTSUPP; | 750 | rv = EOPNOTSUPP; | |
751 | goto out; | 751 | goto out; | |
752 | } | 752 | } | |
753 | 753 | |||
754 | /* | 754 | /* | |
755 | * XXX: ietf says: source, target. openssh says: ietf who? | 755 | * XXX: ietf says: source, target. openssh says: ietf who? | |
756 | * Let's go with openssh and build quirk tables later if we care | 756 | * Let's go with openssh and build quirk tables later if we care | |
757 | */ | 757 | */ | |
758 | psbuf_req_str(pb, SSH_FXP_SYMLINK, reqid, link_target); | 758 | psbuf_req_str(pb, SSH_FXP_SYMLINK, reqid, link_target); | |
759 | psbuf_put_str(pb, PCNPATH(pcn)); | 759 | psbuf_put_str(pb, PCNPATH(pcn)); | |
760 | GETRESPONSE(pb); | 760 | GETRESPONSE(pb, pctx->sshfd); | |
761 | 761 | |||
762 | rv = psbuf_expect_status(pb); | 762 | rv = psbuf_expect_status(pb); | |
763 | if (rv) | 763 | if (rv) | |
764 | goto out; | 764 | goto out; | |
765 | 765 | |||
766 | pn_new = allocnode(pu, pn, pcn->pcn_name, va); | 766 | pn_new = allocnode(pu, pn, pcn->pcn_name, va); | |
767 | if (pn_new) { | 767 | if (pn_new) { | |
768 | puffs_newinfo_setcookie(pni, pn_new); | 768 | puffs_newinfo_setcookie(pni, pn_new); | |
769 | } else { | 769 | } else { | |
770 | struct puffs_framebuf *pb2 = psbuf_makeout(); | 770 | struct puffs_framebuf *pb2 = psbuf_makeout(); | |
771 | reqid = NEXTREQ(pctx); | 771 | reqid = NEXTREQ(pctx); | |
772 | psbuf_recycleout(pb2); | 772 | psbuf_recycleout(pb2); | |
773 | psbuf_req_str(pb2, SSH_FXP_REMOVE, reqid, PCNPATH(pcn)); | 773 | psbuf_req_str(pb2, SSH_FXP_REMOVE, reqid, PCNPATH(pcn)); | |
774 | JUSTSEND(pb2); | 774 | JUSTSEND(pb2, pctx->sshfd); | |
775 | rv = ENOMEM; | 775 | rv = ENOMEM; | |
776 | } | 776 | } | |
777 | 777 | |||
778 | out: | 778 | out: | |
779 | PSSHFSRETURN(rv); | 779 | PSSHFSRETURN(rv); | |
780 | } | 780 | } | |
781 | 781 | |||
782 | int | 782 | int | |
783 | psshfs_node_rename(struct puffs_usermount *pu, puffs_cookie_t opc, | 783 | psshfs_node_rename(struct puffs_usermount *pu, puffs_cookie_t opc, | |
784 | puffs_cookie_t src, const struct puffs_cn *pcn_src, | 784 | puffs_cookie_t src, const struct puffs_cn *pcn_src, | |
785 | puffs_cookie_t targ_dir, puffs_cookie_t targ, | 785 | puffs_cookie_t targ_dir, puffs_cookie_t targ, | |
786 | const struct puffs_cn *pcn_targ) | 786 | const struct puffs_cn *pcn_targ) | |
787 | { | 787 | { | |
@@ -794,27 +794,27 @@ psshfs_node_rename(struct puffs_usermoun | @@ -794,27 +794,27 @@ psshfs_node_rename(struct puffs_usermoun | |||
794 | if (pctx->protover < 2) { | 794 | if (pctx->protover < 2) { | |
795 | rv = EOPNOTSUPP; | 795 | rv = EOPNOTSUPP; | |
796 | goto out; | 796 | goto out; | |
797 | } | 797 | } | |
798 | 798 | |||
799 | if (pn_tf) { | 799 | if (pn_tf) { | |
800 | rv = doremove(pu, targ_dir, pn_tf, pcn_targ->pcn_name); | 800 | rv = doremove(pu, targ_dir, pn_tf, pcn_targ->pcn_name); | |
801 | if (rv) | 801 | if (rv) | |
802 | goto out; | 802 | goto out; | |
803 | } | 803 | } | |
804 | 804 | |||
805 | psbuf_req_str(pb, SSH_FXP_RENAME, reqid, PCNPATH(pcn_src)); | 805 | psbuf_req_str(pb, SSH_FXP_RENAME, reqid, PCNPATH(pcn_src)); | |
806 | psbuf_put_str(pb, PCNPATH(pcn_targ)); | 806 | psbuf_put_str(pb, PCNPATH(pcn_targ)); | |
807 | GETRESPONSE(pb); | 807 | GETRESPONSE(pb, pctx->sshfd); | |
808 | 808 | |||
809 | rv = psbuf_expect_status(pb); | 809 | rv = psbuf_expect_status(pb); | |
810 | if (rv == 0) { | 810 | if (rv == 0) { | |
811 | struct psshfs_dir *pd; | 811 | struct psshfs_dir *pd; | |
812 | 812 | |||
813 | /* | 813 | /* | |
814 | * XXX: interfaces didn't quite work with rename.. | 814 | * XXX: interfaces didn't quite work with rename.. | |
815 | * the song remains the same. go figure .. ;) | 815 | * the song remains the same. go figure .. ;) | |
816 | */ | 816 | */ | |
817 | nukenode(pn_sf, pcn_src->pcn_name, 0); | 817 | nukenode(pn_sf, pcn_src->pcn_name, 0); | |
818 | pd = direnter(pn_td, pcn_targ->pcn_name); | 818 | pd = direnter(pn_td, pcn_targ->pcn_name); | |
819 | pd->entry = pn_sf; | 819 | pd->entry = pn_sf; | |
820 | puffs_setvattr(&pd->va, &pn_sf->pn_va); | 820 | puffs_setvattr(&pd->va, &pn_sf->pn_va); |
--- src/usr.sbin/puffs/mount_psshfs/psshfs.c 2009/02/23 18:43:46 1.50
+++ src/usr.sbin/puffs/mount_psshfs/psshfs.c 2009/05/20 13:56:36 1.51
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: psshfs.c,v 1.50 2009/02/23 18:43:46 pooka Exp $ */ | 1 | /* $NetBSD: psshfs.c,v 1.51 2009/05/20 13:56:36 pooka Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2006 Antti Kantee. All Rights Reserved. | 4 | * Copyright (c) 2006 Antti Kantee. All Rights Reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -31,73 +31,73 @@ | @@ -31,73 +31,73 @@ | |||
31 | * psshfs implements sshfs functionality on top of puffs making it | 31 | * psshfs implements sshfs functionality on top of puffs making it | |
32 | * possible to mount a filesystme through the sftp service. | 32 | * possible to mount a filesystme through the sftp service. | |
33 | * | 33 | * | |
34 | * psshfs can execute multiple operations in "parallel" by using the | 34 | * psshfs can execute multiple operations in "parallel" by using the | |
35 | * puffs_cc framework for continuations. | 35 | * puffs_cc framework for continuations. | |
36 | * | 36 | * | |
37 | * Concurrency control is handled currently by vnode locking (this | 37 | * Concurrency control is handled currently by vnode locking (this | |
38 | * will change in the future). Context switch locations are easy to | 38 | * will change in the future). Context switch locations are easy to | |
39 | * find by grepping for puffs_framebuf_enqueue_cc(). | 39 | * find by grepping for puffs_framebuf_enqueue_cc(). | |
40 | */ | 40 | */ | |
41 | 41 | |||
42 | #include <sys/cdefs.h> | 42 | #include <sys/cdefs.h> | |
43 | #ifndef lint | 43 | #ifndef lint | |
44 | __RCSID("$NetBSD: psshfs.c,v 1.50 2009/02/23 18:43:46 pooka Exp $"); | 44 | __RCSID("$NetBSD: psshfs.c,v 1.51 2009/05/20 13:56:36 pooka Exp $"); | |
45 | #endif /* !lint */ | 45 | #endif /* !lint */ | |
46 | 46 | |||
47 | #include <sys/types.h> | 47 | #include <sys/types.h> | |
48 | 48 | |||
49 | #include <assert.h> | 49 | #include <assert.h> | |
50 | #include <err.h> | 50 | #include <err.h> | |
51 | #include <errno.h> | 51 | #include <errno.h> | |
52 | #include <mntopts.h> | 52 | #include <mntopts.h> | |
53 | #include <paths.h> | 53 | #include <paths.h> | |
54 | #include <poll.h> | 54 | #include <poll.h> | |
55 | #include <puffs.h> | 55 | #include <puffs.h> | |
56 | #include <signal.h> | 56 | #include <signal.h> | |
57 | #include <stdlib.h> | 57 | #include <stdlib.h> | |
58 | #include <util.h> | 58 | #include <util.h> | |
59 | #include <unistd.h> | 59 | #include <unistd.h> | |
60 | 60 | |||
61 | #include "psshfs.h" | 61 | #include "psshfs.h" | |
62 | 62 | |||
63 | static int pssh_connect(struct psshfs_ctx *); | 63 | static int pssh_connect(struct puffs_usermount *, int); | |
64 | static void psshfs_loopfn(struct puffs_usermount *); | 64 | static void psshfs_loopfn(struct puffs_usermount *); | |
65 | static void usage(void); | 65 | static void usage(void); | |
66 | static void add_ssharg(char ***, int *, char *); | 66 | static void add_ssharg(char ***, int *, char *); | |
67 | static void psshfs_notify(struct puffs_usermount *, int, int); | 67 | static void psshfs_notify(struct puffs_usermount *, int, int); | |
68 | 68 | |||
69 | #define SSH_PATH "/usr/bin/ssh" | 69 | #define SSH_PATH "/usr/bin/ssh" | |
70 | 70 | |||
71 | unsigned int max_reads; | 71 | unsigned int max_reads; | |
72 | static int sighup; | 72 | static int sighup; | |
73 | 73 | |||
74 | static void | 74 | static void | |
75 | add_ssharg(char ***sshargs, int *nargs, char *arg) | 75 | add_ssharg(char ***sshargs, int *nargs, char *arg) | |
76 | { | 76 | { | |
77 | 77 | |||
78 | *sshargs = realloc(*sshargs, (*nargs + 2) * sizeof(char*)); | 78 | *sshargs = realloc(*sshargs, (*nargs + 2) * sizeof(char*)); | |
79 | if (!*sshargs) | 79 | if (!*sshargs) | |
80 | err(1, "realloc"); | 80 | err(1, "realloc"); | |
81 | (*sshargs)[(*nargs)++] = arg; | 81 | (*sshargs)[(*nargs)++] = arg; | |
82 | (*sshargs)[*nargs] = NULL; | 82 | (*sshargs)[*nargs] = NULL; | |
83 | } | 83 | } | |
84 | 84 | |||
85 | static void | 85 | static void | |
86 | usage() | 86 | usage() | |
87 | { | 87 | { | |
88 | 88 | |||
89 | fprintf(stderr, "usage: %s " | 89 | fprintf(stderr, "usage: %s " | |
90 | "[-es] [-F configfile] [-O sshopt=value] [-o opts] " | 90 | "[-ceprst] [-F configfile] [-O sshopt=value] [-o opts] " | |
91 | "user@host:path mountpath\n", | 91 | "user@host:path mountpath\n", | |
92 | getprogname()); | 92 | getprogname()); | |
93 | exit(1); | 93 | exit(1); | |
94 | } | 94 | } | |
95 | 95 | |||
96 | static void | 96 | static void | |
97 | takehup(int sig) | 97 | takehup(int sig) | |
98 | { | 98 | { | |
99 | 99 | |||
100 | sighup = 1; | 100 | sighup = 1; | |
101 | } | 101 | } | |
102 | 102 | |||
103 | int | 103 | int | |
@@ -106,45 +106,55 @@ main(int argc, char *argv[]) | @@ -106,45 +106,55 @@ main(int argc, char *argv[]) | |||
106 | struct psshfs_ctx pctx; | 106 | struct psshfs_ctx pctx; | |
107 | struct puffs_usermount *pu; | 107 | struct puffs_usermount *pu; | |
108 | struct puffs_ops *pops; | 108 | struct puffs_ops *pops; | |
109 | struct psshfs_node *root = &pctx.psn_root; | 109 | struct psshfs_node *root = &pctx.psn_root; | |
110 | struct puffs_node *pn_root; | 110 | struct puffs_node *pn_root; | |
111 | puffs_framev_fdnotify_fn notfn; | 111 | puffs_framev_fdnotify_fn notfn; | |
112 | struct vattr *rva; | 112 | struct vattr *rva; | |
113 | mntoptparse_t mp; | 113 | mntoptparse_t mp; | |
114 | char **sshargs; | 114 | char **sshargs; | |
115 | char *userhost; | 115 | char *userhost; | |
116 | char *hostpath; | 116 | char *hostpath; | |
117 | int mntflags, pflags, ch; | 117 | int mntflags, pflags, ch; | |
118 | int detach; | 118 | int detach; | |
119 | int exportfs, refreshival; | 119 | int exportfs, refreshival, numconnections; | |
120 | int nargs, x; | 120 | int nargs; | |
121 | 121 | |||
122 | setprogname(argv[0]); | 122 | setprogname(argv[0]); | |
123 | 123 | |||
124 | if (argc < 3) | 124 | if (argc < 3) | |
125 | usage(); | 125 | usage(); | |
126 | 126 | |||
127 | mntflags = pflags = exportfs = nargs = 0; | 127 | mntflags = pflags = exportfs = nargs = 0; | |
128 | numconnections = 1; | |||
128 | detach = 1; | 129 | detach = 1; | |
129 | refreshival = DEFAULTREFRESH; | 130 | refreshival = DEFAULTREFRESH; | |
130 | notfn = puffs_framev_unmountonclose; | 131 | notfn = puffs_framev_unmountonclose; | |
131 | sshargs = NULL; | 132 | sshargs = NULL; | |
132 | add_ssharg(&sshargs, &nargs, SSH_PATH); | 133 | add_ssharg(&sshargs, &nargs, SSH_PATH); | |
133 | add_ssharg(&sshargs, &nargs, "-axs"); | 134 | add_ssharg(&sshargs, &nargs, "-axs"); | |
134 | add_ssharg(&sshargs, &nargs, "-oClearAllForwardings=yes"); | 135 | add_ssharg(&sshargs, &nargs, "-oClearAllForwardings=yes"); | |
135 | 136 | |||
136 | while ((ch = getopt(argc, argv, "eF:o:O:pr:st:")) != -1) { | 137 | while ((ch = getopt(argc, argv, "c:eF:o:O:pr:st:")) != -1) { | |
137 | switch (ch) { | 138 | switch (ch) { | |
139 | case 'c': | |||
140 | numconnections = atoi(optarg); | |||
141 | if (numconnections < 1 || numconnections > 2) { | |||
142 | fprintf(stderr, "%s: only 1 or 2 connections " | |||
143 | "permitted currently\n", getprogname()); | |||
144 | usage(); | |||
145 | /*NOTREACHED*/ | |||
146 | } | |||
147 | break; | |||
138 | case 'e': | 148 | case 'e': | |
139 | exportfs = 1; | 149 | exportfs = 1; | |
140 | break; | 150 | break; | |
141 | case 'F': | 151 | case 'F': | |
142 | add_ssharg(&sshargs, &nargs, "-F"); | 152 | add_ssharg(&sshargs, &nargs, "-F"); | |
143 | add_ssharg(&sshargs, &nargs, optarg); | 153 | add_ssharg(&sshargs, &nargs, optarg); | |
144 | break; | 154 | break; | |
145 | case 'O': | 155 | case 'O': | |
146 | add_ssharg(&sshargs, &nargs, "-o"); | 156 | add_ssharg(&sshargs, &nargs, "-o"); | |
147 | add_ssharg(&sshargs, &nargs, optarg); | 157 | add_ssharg(&sshargs, &nargs, optarg); | |
148 | break; | 158 | break; | |
149 | case 'o': | 159 | case 'o': | |
150 | mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags); | 160 | mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags); | |
@@ -204,171 +214,201 @@ main(int argc, char *argv[]) | @@ -204,171 +214,201 @@ main(int argc, char *argv[]) | |||
204 | PUFFSOP_SET(pops, psshfs, node, symlink); | 214 | PUFFSOP_SET(pops, psshfs, node, symlink); | |
205 | PUFFSOP_SET(pops, psshfs, node, rename); | 215 | PUFFSOP_SET(pops, psshfs, node, rename); | |
206 | PUFFSOP_SET(pops, psshfs, node, read); | 216 | PUFFSOP_SET(pops, psshfs, node, read); | |
207 | PUFFSOP_SET(pops, psshfs, node, write); | 217 | PUFFSOP_SET(pops, psshfs, node, write); | |
208 | PUFFSOP_SET(pops, psshfs, node, reclaim); | 218 | PUFFSOP_SET(pops, psshfs, node, reclaim); | |
209 | 219 | |||
210 | pu = puffs_init(pops, argv[0], "psshfs", &pctx, pflags); | 220 | pu = puffs_init(pops, argv[0], "psshfs", &pctx, pflags); | |
211 | if (pu == NULL) | 221 | if (pu == NULL) | |
212 | err(1, "puffs_init"); | 222 | err(1, "puffs_init"); | |
213 | 223 | |||
214 | memset(&pctx, 0, sizeof(pctx)); | 224 | memset(&pctx, 0, sizeof(pctx)); | |
215 | pctx.mounttime = time(NULL); | 225 | pctx.mounttime = time(NULL); | |
216 | pctx.refreshival = refreshival; | 226 | pctx.refreshival = refreshival; | |
227 | pctx.numconnections = numconnections; | |||
217 | 228 | |||
218 | userhost = argv[0]; | 229 | userhost = argv[0]; | |
219 | hostpath = strchr(userhost, ':'); | 230 | hostpath = strchr(userhost, ':'); | |
220 | if (hostpath) { | 231 | if (hostpath) { | |
221 | *hostpath++ = '\0'; | 232 | *hostpath++ = '\0'; | |
222 | pctx.mountpath = hostpath; | 233 | pctx.mountpath = hostpath; | |
223 | } else | 234 | } else | |
224 | pctx.mountpath = "."; | 235 | pctx.mountpath = "."; | |
225 | 236 | |||
226 | add_ssharg(&sshargs, &nargs, argv[0]); | 237 | add_ssharg(&sshargs, &nargs, argv[0]); | |
227 | add_ssharg(&sshargs, &nargs, "sftp"); | 238 | add_ssharg(&sshargs, &nargs, "sftp"); | |
228 | pctx.sshargs = sshargs; | 239 | pctx.sshargs = sshargs; | |
229 | 240 | |||
230 | pctx.nextino = 2; | 241 | pctx.nextino = 2; | |
231 | memset(root, 0, sizeof(struct psshfs_node)); | 242 | memset(root, 0, sizeof(struct psshfs_node)); | |
232 | pn_root = puffs_pn_new(pu, root); | 243 | pn_root = puffs_pn_new(pu, root); | |
233 | if (pn_root == NULL) | 244 | if (pn_root == NULL) | |
234 | return errno; | 245 | return errno; | |
235 | puffs_setroot(pu, pn_root); | 246 | puffs_setroot(pu, pn_root); | |
236 | 247 | |||
248 | puffs_framev_init(pu, psbuf_read, psbuf_write, psbuf_cmp, NULL, notfn); | |||
249 | ||||
237 | signal(SIGHUP, takehup); | 250 | signal(SIGHUP, takehup); | |
238 | puffs_ml_setloopfn(pu, psshfs_loopfn); | 251 | puffs_ml_setloopfn(pu, psshfs_loopfn); | |
239 | if (pssh_connect(&pctx) == -1) | 252 | if (pssh_connect(pu, PSSHFD_META) == -1) | |
240 | err(1, "can't connect"); | 253 | err(1, "can't connect meta"); | |
254 | if (puffs_framev_addfd(pu, pctx.sshfd, | |||
255 | PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1) | |||
256 | err(1, "framebuf addfd meta"); | |||
257 | if (numconnections == 2) { | |||
258 | if (pssh_connect(pu, PSSHFD_DATA) == -1) | |||
259 | err(1, "can't connect data"); | |||
260 | if (puffs_framev_addfd(pu, pctx.sshfd_data, | |||
261 | PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1) | |||
262 | err(1, "framebuf addfd data"); | |||
263 | } else { | |||
264 | pctx.sshfd_data = pctx.sshfd; | |||
265 | } | |||
241 | 266 | |||
242 | if (exportfs) | 267 | if (exportfs) | |
243 | puffs_setfhsize(pu, sizeof(struct psshfs_fid), | 268 | puffs_setfhsize(pu, sizeof(struct psshfs_fid), | |
244 | PUFFS_FHFLAG_NFSV2 | PUFFS_FHFLAG_NFSV3); | 269 | PUFFS_FHFLAG_NFSV2 | PUFFS_FHFLAG_NFSV3); | |
245 | 270 | |||
246 | if (psshfs_handshake(pu) != 0) | |||
247 | errx(1, "psshfs_handshake"); | |||
248 | x = 1; | |||
249 | if (ioctl(pctx.sshfd, FIONBIO, &x) == -1) | |||
250 | err(1, "nonblocking descriptor"); | |||
251 | ||||
252 | puffs_framev_init(pu, psbuf_read, psbuf_write, psbuf_cmp, NULL, notfn); | |||
253 | if (puffs_framev_addfd(pu, pctx.sshfd, | |||
254 | PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1) | |||
255 | err(1, "framebuf addfd"); | |||
256 | ||||
257 | rva = &pn_root->pn_va; | 271 | rva = &pn_root->pn_va; | |
258 | rva->va_fileid = pctx.nextino++; | 272 | rva->va_fileid = pctx.nextino++; | |
259 | rva->va_nlink = 101; /* XXX */ | 273 | rva->va_nlink = 101; /* XXX */ | |
260 | 274 | |||
261 | if (detach) | 275 | if (detach) | |
262 | if (puffs_daemon(pu, 1, 1) == -1) | 276 | if (puffs_daemon(pu, 1, 1) == -1) | |
263 | err(1, "puffs_daemon"); | 277 | err(1, "puffs_daemon"); | |
264 | 278 | |||
265 | if (puffs_mount(pu, argv[1], mntflags, puffs_getroot(pu)) == -1) | 279 | if (puffs_mount(pu, argv[1], mntflags, puffs_getroot(pu)) == -1) | |
266 | err(1, "puffs_mount"); | 280 | err(1, "puffs_mount"); | |
267 | if (puffs_setblockingmode(pu, PUFFSDEV_NONBLOCK) == -1) | 281 | if (puffs_setblockingmode(pu, PUFFSDEV_NONBLOCK) == -1) | |
268 | err(1, "setblockingmode"); | 282 | err(1, "setblockingmode"); | |
269 | 283 | |||
270 | if (puffs_mainloop(pu) == -1) | 284 | if (puffs_mainloop(pu) == -1) | |
271 | err(1, "mainloop"); | 285 | err(1, "mainloop"); | |
272 | puffs_exit(pu, 1); | 286 | puffs_exit(pu, 1); | |
273 | 287 | |||
274 | return 0; | 288 | return 0; | |
275 | } | 289 | } | |
276 | 290 | |||
277 | #define RETRY_MAX 100 | 291 | #define RETRY_MAX 100 | |
278 | 292 | |||
279 | void | 293 | void | |
280 | psshfs_notify(struct puffs_usermount *pu, int fd, int what) | 294 | psshfs_notify(struct puffs_usermount *pu, int fd, int what) | |
281 | { | 295 | { | |
282 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | 296 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | |
283 | int x, nretry; | 297 | int x, nretry, which, newfd; | |
298 | ||||
299 | if (fd == pctx->sshfd) { | |||
300 | which = PSSHFD_META; | |||
301 | } else { | |||
302 | assert(fd == pctx->sshfd_data); | |||
303 | which = PSSHFD_DATA; | |||
304 | } | |||
284 | 305 | |||
285 | if (puffs_getstate(pu) != PUFFS_STATE_RUNNING) | 306 | if (puffs_getstate(pu) != PUFFS_STATE_RUNNING) | |
286 | return; | 307 | return; | |
287 | 308 | |||
288 | if (what != (PUFFS_FBIO_READ | PUFFS_FBIO_WRITE)) { | 309 | if (what != (PUFFS_FBIO_READ | PUFFS_FBIO_WRITE)) { | |
289 | puffs_framev_removefd(pu, pctx->sshfd, ECONNRESET); | 310 | puffs_framev_removefd(pu, fd, ECONNRESET); | |
290 | return; | 311 | return; | |
291 | } | 312 | } | |
292 | close(pctx->sshfd); | 313 | close(fd); | |
293 | 314 | |||
294 | for (nretry = 0;;nretry++) { | 315 | for (nretry = 0;;nretry++) { | |
295 | if (pssh_connect(pctx) == -1) | 316 | if ((newfd = pssh_connect(pu, which)) == -1) | |
296 | goto retry2; | 317 | goto retry2; | |
297 | 318 | |||
298 | if (psshfs_handshake(pu) != 0) | 319 | if (psshfs_handshake(pu, newfd) != 0) | |
299 | goto retry1; | 320 | goto retry1; | |
300 | 321 | |||
301 | x = 1; | 322 | x = 1; | |
302 | if (ioctl(pctx->sshfd, FIONBIO, &x) == -1) | 323 | if (ioctl(newfd, FIONBIO, &x) == -1) | |
303 | goto retry1; | 324 | goto retry1; | |
304 | 325 | |||
305 | if (puffs_framev_addfd(pu, pctx->sshfd, | 326 | if (puffs_framev_addfd(pu, newfd, | |
306 | PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1) | 327 | PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1) | |
307 | goto retry1; | 328 | goto retry1; | |
308 | 329 | |||
309 | break; | 330 | break; | |
310 | retry1: | 331 | retry1: | |
311 | fprintf(stderr, "reconnect failed... "); | 332 | fprintf(stderr, "reconnect failed... "); | |
312 | close(pctx->sshfd); | 333 | close(newfd); | |
313 | retry2: | 334 | retry2: | |
314 | if (nretry < RETRY_MAX) { | 335 | if (nretry < RETRY_MAX) { | |
315 | fprintf(stderr, "retrying\n"); | 336 | fprintf(stderr, "retrying\n"); | |
316 | sleep(nretry); | 337 | sleep(nretry); | |
317 | } else { | 338 | } else { | |
318 | fprintf(stderr, "retry count exceeded, going south\n"); | 339 | fprintf(stderr, "retry count exceeded, going south\n"); | |
319 | exit(1); /* XXXXXXX */ | 340 | exit(1); /* XXXXXXX */ | |
320 | } | 341 | } | |
321 | } | 342 | } | |
322 | } | 343 | } | |
323 | 344 | |||
324 | static int | 345 | static int | |
325 | pssh_connect(struct psshfs_ctx *pctx) | 346 | pssh_connect(struct puffs_usermount *pu, int which) | |
326 | { | 347 | { | |
348 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | |||
327 | char **sshargs = pctx->sshargs; | 349 | char **sshargs = pctx->sshargs; | |
328 | int fds[2]; | 350 | int fds[2]; | |
329 | pid_t pid; | 351 | pid_t pid; | |
330 | int dnfd; | 352 | int dnfd, x; | |
353 | int *sshfd; | |||
354 | pid_t *sshpid; | |||
355 | ||||
356 | if (which == PSSHFD_META) { | |||
357 | sshfd = &pctx->sshfd; | |||
358 | sshpid = &pctx->sshpid; | |||
359 | } else { | |||
360 | assert(which == PSSHFD_DATA); | |||
361 | sshfd = &pctx->sshfd_data; | |||
362 | sshpid = &pctx->sshpid_data; | |||
363 | } | |||
331 | 364 | |||
332 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) | 365 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) | |
333 | return -1; | 366 | return -1; | |
334 | 367 | |||
335 | pid = fork(); | 368 | pid = fork(); | |
336 | switch (pid) { | 369 | switch (pid) { | |
337 | case -1: | 370 | case -1: | |
338 | return -1; | 371 | return -1; | |
339 | /*NOTREACHED*/ | 372 | /*NOTREACHED*/ | |
340 | case 0: /* child */ | 373 | case 0: /* child */ | |
341 | if (dup2(fds[0], STDIN_FILENO) == -1) | 374 | if (dup2(fds[0], STDIN_FILENO) == -1) | |
342 | err(1, "child dup2"); | 375 | err(1, "child dup2"); | |
343 | if (dup2(fds[0], STDOUT_FILENO) == -1) | 376 | if (dup2(fds[0], STDOUT_FILENO) == -1) | |
344 | err(1, "child dup2"); | 377 | err(1, "child dup2"); | |
345 | close(fds[0]); | 378 | close(fds[0]); | |
346 | close(fds[1]); | 379 | close(fds[1]); | |
347 | 380 | |||
348 | dnfd = open(_PATH_DEVNULL, O_RDWR); | 381 | dnfd = open(_PATH_DEVNULL, O_RDWR); | |
349 | if (dnfd != -1) | 382 | if (dnfd != -1) | |
350 | dup2(dnfd, STDERR_FILENO); | 383 | dup2(dnfd, STDERR_FILENO); | |
351 | 384 | |||
352 | execvp(sshargs[0], sshargs); | 385 | execvp(sshargs[0], sshargs); | |
386 | /*NOTREACHED*/ | |||
353 | break; | 387 | break; | |
354 | default: | 388 | default: | |
355 | pctx->sshpid = pid; | 389 | *sshpid = pid; | |
356 | pctx->sshfd = fds[1]; | 390 | *sshfd = fds[1]; | |
357 | close(fds[0]); | 391 | close(fds[0]); | |
358 | break; | 392 | break; | |
359 | } | 393 | } | |
360 | 394 | |||
361 | return 0; | 395 | if (psshfs_handshake(pu, *sshfd) != 0) | |
396 | errx(1, "psshfs_handshake %d", which); | |||
397 | x = 1; | |||
398 | if (ioctl(*sshfd, FIONBIO, &x) == -1) | |||
399 | err(1, "nonblocking descriptor %d", which); | |||
400 | ||||
401 | return *sshfd; | |||
362 | } | 402 | } | |
363 | 403 | |||
364 | static void * | 404 | static void * | |
365 | invalone(struct puffs_usermount *pu, struct puffs_node *pn, void *arg) | 405 | invalone(struct puffs_usermount *pu, struct puffs_node *pn, void *arg) | |
366 | { | 406 | { | |
367 | struct psshfs_node *psn = pn->pn_data; | 407 | struct psshfs_node *psn = pn->pn_data; | |
368 | 408 | |||
369 | psn->attrread = 0; | 409 | psn->attrread = 0; | |
370 | psn->dentread = 0; | 410 | psn->dentread = 0; | |
371 | psn->slread = 0; | 411 | psn->slread = 0; | |
372 | 412 | |||
373 | return NULL; | 413 | return NULL; | |
374 | } | 414 | } |
--- src/usr.sbin/puffs/mount_psshfs/psshfs.h 2009/02/23 18:43:46 1.35
+++ src/usr.sbin/puffs/mount_psshfs/psshfs.h 2009/05/20 13:56:36 1.36
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: psshfs.h,v 1.35 2009/02/23 18:43:46 pooka Exp $ */ | 1 | /* $NetBSD: psshfs.h,v 1.36 2009/05/20 13:56:36 pooka Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2006, 2007 Antti Kantee. All Rights Reserved. | 4 | * Copyright (c) 2006, 2007 Antti Kantee. All Rights Reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -55,45 +55,45 @@ PUFFSOP_PROTOS(psshfs); | @@ -55,45 +55,45 @@ PUFFSOP_PROTOS(psshfs); | |||
55 | 55 | |||
56 | #define NEXTREQ(pctx) ((pctx->nextreq)++) | 56 | #define NEXTREQ(pctx) ((pctx->nextreq)++) | |
57 | #define PSSHFSAUTOVAR(pu) \ | 57 | #define PSSHFSAUTOVAR(pu) \ | |
58 | struct puffs_cc *pcc = puffs_cc_getcc(pu); \ | 58 | struct puffs_cc *pcc = puffs_cc_getcc(pu); \ | |
59 | struct psshfs_ctx *pctx = puffs_getspecific(pu); \ | 59 | struct psshfs_ctx *pctx = puffs_getspecific(pu); \ | |
60 | uint32_t reqid = NEXTREQ(pctx); \ | 60 | uint32_t reqid = NEXTREQ(pctx); \ | |
61 | struct puffs_framebuf *pb = psbuf_makeout(); \ | 61 | struct puffs_framebuf *pb = psbuf_makeout(); \ | |
62 | int rv = 0 | 62 | int rv = 0 | |
63 | 63 | |||
64 | #define PSSHFSRETURN(rv) \ | 64 | #define PSSHFSRETURN(rv) \ | |
65 | puffs_framebuf_destroy(pb); \ | 65 | puffs_framebuf_destroy(pb); \ | |
66 | return (rv) | 66 | return (rv) | |
67 | 67 | |||
68 | #define GETRESPONSE(pb) \ | 68 | #define GETRESPONSE(pb, fd) \ | |
69 | do { \ | 69 | do { \ | |
70 | if (puffs_framev_enqueue_cc(pcc, pctx->sshfd, pb, 0) == -1) { \ | 70 | if (puffs_framev_enqueue_cc(pcc, fd, pb, 0) == -1) { \ | |
71 | rv = errno; \ | 71 | rv = errno; \ | |
72 | goto out; \ | 72 | goto out; \ | |
73 | } \ | 73 | } \ | |
74 | } while (/*CONSTCOND*/0) | 74 | } while (/*CONSTCOND*/0) | |
75 | 75 | |||
76 | #define JUSTSEND(pb) \ | 76 | #define JUSTSEND(pb,fd) \ | |
77 | do { \ | 77 | do { \ | |
78 | if (puffs_framev_enqueue_justsend(pu,pctx->sshfd,pb,1,0) == -1){\ | 78 | if (puffs_framev_enqueue_justsend(pu, fd, pb, 1, 0) == -1) { \ | |
79 | rv = errno; \ | 79 | rv = errno; \ | |
80 | goto out; \ | 80 | goto out; \ | |
81 | } \ | 81 | } \ | |
82 | } while (/*CONSTCOND*/0) | 82 | } while (/*CONSTCOND*/0) | |
83 | 83 | |||
84 | #define SENDCB(pb, f, a) \ | 84 | #define SENDCB(pb, fd, f, a) \ | |
85 | do { \ | 85 | do { \ | |
86 | if (puffs_framev_enqueue_cb(pu, pctx->sshfd, pb,f,a,0) == -1) { \ | 86 | if (puffs_framev_enqueue_cb(pu, fd, pb, f, a, 0) == -1) { \ | |
87 | rv = errno; \ | 87 | rv = errno; \ | |
88 | goto out; \ | 88 | goto out; \ | |
89 | } \ | 89 | } \ | |
90 | } while (/*CONSTCOND*/0) | 90 | } while (/*CONSTCOND*/0) | |
91 | 91 | |||
92 | struct psshfs_dir { | 92 | struct psshfs_dir { | |
93 | int valid; | 93 | int valid; | |
94 | struct puffs_node *entry; | 94 | struct puffs_node *entry; | |
95 | 95 | |||
96 | char *entryname; | 96 | char *entryname; | |
97 | struct vattr va; | 97 | struct vattr va; | |
98 | time_t attrread; | 98 | time_t attrread; | |
99 | }; | 99 | }; | |
@@ -143,48 +143,54 @@ struct psshfs_node { | @@ -143,48 +143,54 @@ struct psshfs_node { | |||
143 | #define PSN_RECLAIMED 0x01 | 143 | #define PSN_RECLAIMED 0x01 | |
144 | #define PSN_HASFH 0x02 | 144 | #define PSN_HASFH 0x02 | |
145 | #define PSN_READDIR 0x04 | 145 | #define PSN_READDIR 0x04 | |
146 | #define PSN_DOLAZY_R 0x08 | 146 | #define PSN_DOLAZY_R 0x08 | |
147 | #define PSN_DOLAZY_W 0x10 | 147 | #define PSN_DOLAZY_W 0x10 | |
148 | #define PSN_LAZYWAIT_R 0x20 | 148 | #define PSN_LAZYWAIT_R 0x20 | |
149 | #define PSN_LAZYWAIT_W 0x40 | 149 | #define PSN_LAZYWAIT_W 0x40 | |
150 | #define PSN_HANDLECLOSE 0x80 | 150 | #define PSN_HANDLECLOSE 0x80 | |
151 | 151 | |||
152 | #define HANDLE_READ 0x1 | 152 | #define HANDLE_READ 0x1 | |
153 | #define HANDLE_WRITE 0x2 | 153 | #define HANDLE_WRITE 0x2 | |
154 | 154 | |||
155 | struct psshfs_ctx { | 155 | struct psshfs_ctx { | |
156 | int numconnections; | |||
156 | int sshfd; | 157 | int sshfd; | |
158 | int sshfd_data; | |||
157 | pid_t sshpid; | 159 | pid_t sshpid; | |
160 | pid_t sshpid_data; | |||
161 | ||||
158 | const char *mountpath; | 162 | const char *mountpath; | |
159 | char **sshargs; | 163 | char **sshargs; | |
160 | 164 | |||
161 | int protover; | 165 | int protover; | |
162 | int extensions; | 166 | int extensions; | |
163 | 167 | |||
164 | uint32_t nextreq; | 168 | uint32_t nextreq; | |
165 | 169 | |||
166 | struct puffs_framebuf *curpb; | 170 | struct puffs_framebuf *curpb; | |
167 | 171 | |||
168 | struct psshfs_node psn_root; | 172 | struct psshfs_node psn_root; | |
169 | ino_t nextino; | 173 | ino_t nextino; | |
170 | 174 | |||
171 | int canexport; | 175 | int canexport; | |
172 | time_t mounttime; | 176 | time_t mounttime; | |
173 | 177 | |||
174 | int refreshival; | 178 | int refreshival; | |
175 | }; | 179 | }; | |
180 | #define PSSHFD_META 0 | |||
181 | #define PSSHFD_DATA 1 | |||
176 | 182 | |||
177 | int psshfs_handshake(struct puffs_usermount *); | 183 | int psshfs_handshake(struct puffs_usermount *, int); | |
178 | 184 | |||
179 | int psbuf_read(struct puffs_usermount *, struct puffs_framebuf *,int,int*); | 185 | int psbuf_read(struct puffs_usermount *, struct puffs_framebuf *,int,int*); | |
180 | int psbuf_write(struct puffs_usermount *, struct puffs_framebuf *,int,int*); | 186 | int psbuf_write(struct puffs_usermount *, struct puffs_framebuf *,int,int*); | |
181 | int psbuf_cmp(struct puffs_usermount *, | 187 | int psbuf_cmp(struct puffs_usermount *, | |
182 | struct puffs_framebuf *, struct puffs_framebuf *, int *); | 188 | struct puffs_framebuf *, struct puffs_framebuf *, int *); | |
183 | 189 | |||
184 | struct puffs_framebuf *psbuf_makeout(void); | 190 | struct puffs_framebuf *psbuf_makeout(void); | |
185 | void psbuf_recycleout(struct puffs_framebuf *); | 191 | void psbuf_recycleout(struct puffs_framebuf *); | |
186 | 192 | |||
187 | void psbuf_put_1(struct puffs_framebuf *, uint8_t); | 193 | void psbuf_put_1(struct puffs_framebuf *, uint8_t); | |
188 | void psbuf_put_2(struct puffs_framebuf *, uint16_t); | 194 | void psbuf_put_2(struct puffs_framebuf *, uint16_t); | |
189 | void psbuf_put_4(struct puffs_framebuf *, uint32_t); | 195 | void psbuf_put_4(struct puffs_framebuf *, uint32_t); | |
190 | void psbuf_put_8(struct puffs_framebuf *, uint64_t); | 196 | void psbuf_put_8(struct puffs_framebuf *, uint64_t); |
--- src/usr.sbin/puffs/mount_psshfs/subr.c 2007/12/13 14:59:00 1.45
+++ src/usr.sbin/puffs/mount_psshfs/subr.c 2009/05/20 13:56:36 1.46
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: subr.c,v 1.45 2007/12/13 14:59:00 pooka Exp $ */ | 1 | /* $NetBSD: subr.c,v 1.46 2009/05/20 13:56:36 pooka Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2006 Antti Kantee. All Rights Reserved. | 4 | * Copyright (c) 2006 Antti Kantee. All Rights Reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * | 14 | * | |
@@ -17,27 +17,27 @@ | @@ -17,27 +17,27 @@ | |||
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
21 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 21 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
25 | * SUCH DAMAGE. | 25 | * SUCH DAMAGE. | |
26 | */ | 26 | */ | |
27 | 27 | |||
28 | #include <sys/cdefs.h> | 28 | #include <sys/cdefs.h> | |
29 | #ifndef lint | 29 | #ifndef lint | |
30 | __RCSID("$NetBSD: subr.c,v 1.45 2007/12/13 14:59:00 pooka Exp $"); | 30 | __RCSID("$NetBSD: subr.c,v 1.46 2009/05/20 13:56:36 pooka Exp $"); | |
31 | #endif /* !lint */ | 31 | #endif /* !lint */ | |
32 | 32 | |||
33 | #include <assert.h> | 33 | #include <assert.h> | |
34 | #include <err.h> | 34 | #include <err.h> | |
35 | #include <errno.h> | 35 | #include <errno.h> | |
36 | #include <puffs.h> | 36 | #include <puffs.h> | |
37 | #include <stdlib.h> | 37 | #include <stdlib.h> | |
38 | #include <util.h> | 38 | #include <util.h> | |
39 | 39 | |||
40 | #include "psshfs.h" | 40 | #include "psshfs.h" | |
41 | #include "sftp_proto.h" | 41 | #include "sftp_proto.h" | |
42 | 42 | |||
43 | static void | 43 | static void | |
@@ -124,39 +124,39 @@ void | @@ -124,39 +124,39 @@ void | |||
124 | closehandles(struct puffs_usermount *pu, struct psshfs_node *psn, int which) | 124 | closehandles(struct puffs_usermount *pu, struct psshfs_node *psn, int which) | |
125 | { | 125 | { | |
126 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | 126 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | |
127 | struct puffs_framebuf *pb1, *pb2; | 127 | struct puffs_framebuf *pb1, *pb2; | |
128 | uint32_t reqid; | 128 | uint32_t reqid; | |
129 | 129 | |||
130 | if (psn->fhand_r && (which & HANDLE_READ)) { | 130 | if (psn->fhand_r && (which & HANDLE_READ)) { | |
131 | assert(psn->lazyopen_r == NULL); | 131 | assert(psn->lazyopen_r == NULL); | |
132 | 132 | |||
133 | pb1 = psbuf_makeout(); | 133 | pb1 = psbuf_makeout(); | |
134 | reqid = NEXTREQ(pctx); | 134 | reqid = NEXTREQ(pctx); | |
135 | psbuf_req_data(pb1, SSH_FXP_CLOSE, reqid, | 135 | psbuf_req_data(pb1, SSH_FXP_CLOSE, reqid, | |
136 | psn->fhand_r, psn->fhand_r_len); | 136 | psn->fhand_r, psn->fhand_r_len); | |
137 | puffs_framev_enqueue_justsend(pu, pctx->sshfd, pb1, 1, 0); | 137 | puffs_framev_enqueue_justsend(pu, pctx->sshfd_data, pb1, 1, 0); | |
138 | free(psn->fhand_r); | 138 | free(psn->fhand_r); | |
139 | psn->fhand_r = NULL; | 139 | psn->fhand_r = NULL; | |
140 | } | 140 | } | |
141 | 141 | |||
142 | if (psn->fhand_w && (which & HANDLE_WRITE)) { | 142 | if (psn->fhand_w && (which & HANDLE_WRITE)) { | |
143 | assert(psn->lazyopen_w == NULL); | 143 | assert(psn->lazyopen_w == NULL); | |
144 | 144 | |||
145 | pb2 = psbuf_makeout(); | 145 | pb2 = psbuf_makeout(); | |
146 | reqid = NEXTREQ(pctx); | 146 | reqid = NEXTREQ(pctx); | |
147 | psbuf_req_data(pb2, SSH_FXP_CLOSE, reqid, | 147 | psbuf_req_data(pb2, SSH_FXP_CLOSE, reqid, | |
148 | psn->fhand_w, psn->fhand_w_len); | 148 | psn->fhand_w, psn->fhand_w_len); | |
149 | puffs_framev_enqueue_justsend(pu, pctx->sshfd, pb2, 1, 0); | 149 | puffs_framev_enqueue_justsend(pu, pctx->sshfd_data, pb2, 1, 0); | |
150 | free(psn->fhand_w); | 150 | free(psn->fhand_w); | |
151 | psn->fhand_w = NULL; | 151 | psn->fhand_w = NULL; | |
152 | } | 152 | } | |
153 | 153 | |||
154 | psn->stat |= PSN_HANDLECLOSE; | 154 | psn->stat |= PSN_HANDLECLOSE; | |
155 | } | 155 | } | |
156 | 156 | |||
157 | void | 157 | void | |
158 | lazyopen_rresp(struct puffs_usermount *pu, struct puffs_framebuf *pb, | 158 | lazyopen_rresp(struct puffs_usermount *pu, struct puffs_framebuf *pb, | |
159 | void *arg, int error) | 159 | void *arg, int error) | |
160 | { | 160 | { | |
161 | struct psshfs_node *psn = arg; | 161 | struct psshfs_node *psn = arg; | |
162 | 162 | |||
@@ -210,27 +210,27 @@ lazyopen_wresp(struct puffs_usermount *p | @@ -210,27 +210,27 @@ lazyopen_wresp(struct puffs_usermount *p | |||
210 | 210 | |||
211 | struct readdirattr { | 211 | struct readdirattr { | |
212 | struct psshfs_node *psn; | 212 | struct psshfs_node *psn; | |
213 | int idx; | 213 | int idx; | |
214 | char entryname[MAXPATHLEN+1]; | 214 | char entryname[MAXPATHLEN+1]; | |
215 | }; | 215 | }; | |
216 | 216 | |||
217 | int | 217 | int | |
218 | getpathattr(struct puffs_usermount *pu, const char *path, struct vattr *vap) | 218 | getpathattr(struct puffs_usermount *pu, const char *path, struct vattr *vap) | |
219 | { | 219 | { | |
220 | PSSHFSAUTOVAR(pu); | 220 | PSSHFSAUTOVAR(pu); | |
221 | 221 | |||
222 | psbuf_req_str(pb, SSH_FXP_LSTAT, reqid, path); | 222 | psbuf_req_str(pb, SSH_FXP_LSTAT, reqid, path); | |
223 | GETRESPONSE(pb); | 223 | GETRESPONSE(pb, pctx->sshfd); | |
224 | 224 | |||
225 | rv = psbuf_expect_attrs(pb, vap); | 225 | rv = psbuf_expect_attrs(pb, vap); | |
226 | 226 | |||
227 | out: | 227 | out: | |
228 | PSSHFSRETURN(rv); | 228 | PSSHFSRETURN(rv); | |
229 | } | 229 | } | |
230 | 230 | |||
231 | int | 231 | int | |
232 | getnodeattr(struct puffs_usermount *pu, struct puffs_node *pn) | 232 | getnodeattr(struct puffs_usermount *pu, struct puffs_node *pn) | |
233 | { | 233 | { | |
234 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | 234 | struct psshfs_ctx *pctx = puffs_getspecific(pu); | |
235 | struct psshfs_node *psn = pn->pn_data; | 235 | struct psshfs_node *psn = pn->pn_data; | |
236 | struct vattr va; | 236 | struct vattr va; | |
@@ -297,27 +297,27 @@ sftp_readdir(struct puffs_usermount *pu, | @@ -297,27 +297,27 @@ sftp_readdir(struct puffs_usermount *pu, | |||
297 | * large directories might expire before the directory itself and | 297 | * large directories might expire before the directory itself and | |
298 | * result in one-by-one attribute fetching. | 298 | * result in one-by-one attribute fetching. | |
299 | */ | 299 | */ | |
300 | psn->dentread = time(NULL); | 300 | psn->dentread = time(NULL); | |
301 | 301 | |||
302 | psn->dentnext = 0; | 302 | psn->dentnext = 0; | |
303 | psn->denttot = 0; | 303 | psn->denttot = 0; | |
304 | psn->dir = NULL; | 304 | psn->dir = NULL; | |
305 | 305 | |||
306 | for (;;) { | 306 | for (;;) { | |
307 | reqid = NEXTREQ(pctx); | 307 | reqid = NEXTREQ(pctx); | |
308 | psbuf_recycleout(pb); | 308 | psbuf_recycleout(pb); | |
309 | psbuf_req_data(pb, SSH_FXP_READDIR, reqid, dhand, dhandlen); | 309 | psbuf_req_data(pb, SSH_FXP_READDIR, reqid, dhand, dhandlen); | |
310 | GETRESPONSE(pb); | 310 | GETRESPONSE(pb, pctx->sshfd); | |
311 | 311 | |||
312 | /* check for EOF */ | 312 | /* check for EOF */ | |
313 | if (psbuf_get_type(pb) == SSH_FXP_STATUS) { | 313 | if (psbuf_get_type(pb) == SSH_FXP_STATUS) { | |
314 | rv = psbuf_expect_status(pb); | 314 | rv = psbuf_expect_status(pb); | |
315 | goto out; | 315 | goto out; | |
316 | } | 316 | } | |
317 | rv = psbuf_expect_name(pb, &count); | 317 | rv = psbuf_expect_name(pb, &count); | |
318 | if (rv) | 318 | if (rv) | |
319 | goto out; | 319 | goto out; | |
320 | 320 | |||
321 | for (; count--; idx++) { | 321 | for (; count--; idx++) { | |
322 | if (idx == psn->denttot) | 322 | if (idx == psn->denttot) | |
323 | allocdirs(psn); | 323 | allocdirs(psn); |