Module Name: src Committed By: ozaki-r Date: Fri May 17 08:48:04 UTC 2019
Modified Files: src/usr.sbin/puffs/mount_9p: fs.c mount_9p.8 nineproto.c nineproto.h ninepuffs.c ninepuffs.h node.c Log Message: mount_9p: add initial support for 9P2000.u The implementation enables to work with a server talking 9P2000.u. However, it doesn't use the extended fields yet; it just ignores those of received messages and sets "please ignore" values to those of sending messages such as zero-length strings and maximum unsigned values. The feature is enabled by the -u option. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/usr.sbin/puffs/mount_9p/fs.c \ src/usr.sbin/puffs/mount_9p/nineproto.c cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/puffs/mount_9p/mount_9p.8 cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/puffs/mount_9p/nineproto.h cvs rdiff -u -r1.24 -r1.25 src/usr.sbin/puffs/mount_9p/ninepuffs.c cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/puffs/mount_9p/ninepuffs.h cvs rdiff -u -r1.21 -r1.22 src/usr.sbin/puffs/mount_9p/node.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/puffs/mount_9p/fs.c diff -u src/usr.sbin/puffs/mount_9p/fs.c:1.9 src/usr.sbin/puffs/mount_9p/fs.c:1.10 --- src/usr.sbin/puffs/mount_9p/fs.c:1.9 Wed Jun 22 04:03:23 2011 +++ src/usr.sbin/puffs/mount_9p/fs.c Fri May 17 08:48:04 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: fs.c,v 1.9 2011/06/22 04:03:23 mrg Exp $ */ +/* $NetBSD: fs.c,v 1.10 2019/05/17 08:48:04 ozaki-r Exp $ */ /* * Copyright (c) 2007 Antti Kantee. All Rights Reserved. @@ -27,7 +27,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: fs.c,v 1.9 2011/06/22 04:03:23 mrg Exp $"); +__RCSID("$NetBSD: fs.c,v 1.10 2019/05/17 08:48:04 ozaki-r Exp $"); #endif /* !lint */ #include <assert.h> @@ -48,6 +48,17 @@ __RCSID("$NetBSD: fs.c,v 1.9 2011/06/22 rv = fname(a1, a2, a3, a4); \ if (rv) errx(1, "p9p_handshake io failed %d, %d", rv, *a4) +static const char * +p9p_ver2str(int version) +{ + + switch (version) { + case P9PROTO_VERSION: return P9PROTO_VERSTR; + case P9PROTO_VERSION_U: return P9PROTO_VERSTR_U; + } + return NULL; +} + struct puffs_node * p9p_handshake(struct puffs_usermount *pu, const char *username, const char *path) @@ -63,13 +74,15 @@ p9p_handshake(struct puffs_usermount *pu const char *p; uint8_t type; int rv, done, x = 1, ncomp; + uint16_t strsize; + char *str; /* send initial handshake */ pb = p9pbuf_makeout(); p9pbuf_put_1(pb, P9PROTO_T_VERSION); p9pbuf_put_2(pb, P9PROTO_NOTAG); p9pbuf_put_4(pb, p9p->maxreq); - p9pbuf_put_str(pb, P9PROTO_VERSION); + p9pbuf_put_str(pb, p9p_ver2str(p9p->protover)); DO_IO(p9pbuf_write, pu, pb, p9p->servsock, &done, rv); puffs_framebuf_recycle(pb); @@ -89,6 +102,13 @@ p9p_handshake(struct puffs_usermount *pu "%d vs. %d", P9P_MINREQLEN, maxreq); p9p->maxreq = maxreq; + if (p9pbuf_get_str(pb, &str, &strsize)) + errx(1, "server invalid response: no version"); + if (strncmp(str, p9p_ver2str(p9p->protover), P9PROTO_VERSTR_MAXLEN) != 0) { + errx(1, "server doesn't support %s", p9p_ver2str(p9p->protover)); + /* Should downgrade from 9P2000.u to 9P2000 if the server request? */ + } + /* tell the server we don't support authentication */ p9pbuf_recycleout(pb); tagid = NEXTTAG(p9p); @@ -97,6 +117,8 @@ p9p_handshake(struct puffs_usermount *pu p9pbuf_put_4(pb, P9PROTO_NOFID); p9pbuf_put_str(pb, username); p9pbuf_put_str(pb, ""); + if (p9p->protover == P9PROTO_VERSION_U) + p9pbuf_put_4(pb, P9PROTO_NUNAME_UNSPECIFIED); /* n_uname[4] */ DO_IO(p9pbuf_write, pu, pb, p9p->servsock, &done, rv); puffs_framebuf_recycle(pb); @@ -117,6 +139,8 @@ p9p_handshake(struct puffs_usermount *pu p9pbuf_put_4(pb, P9PROTO_NOFID); p9pbuf_put_str(pb, username); p9pbuf_put_str(pb, ""); + if (p9p->protover == P9PROTO_VERSION_U) + p9pbuf_put_4(pb, P9PROTO_NUNAME_UNSPECIFIED); /* n_uname[4] */ DO_IO(p9pbuf_write, pu, pb, p9p->servsock, &done, rv); puffs_framebuf_recycle(pb); @@ -213,7 +237,7 @@ p9p_handshake(struct puffs_usermount *pu errx(1, "server invalid tag: %d vs. %d", tagid, rtagid); if (p9pbuf_get_2(pb, &dummy)) errx(1, "couldn't get stat len parameter"); - if (proto_getstat(pb, &rootva, NULL, NULL)) + if (proto_getstat(pu, pb, &rootva, NULL, NULL)) errx(1, "could not parse root attributes"); puffs_framebuf_destroy(pb); Index: src/usr.sbin/puffs/mount_9p/nineproto.c diff -u src/usr.sbin/puffs/mount_9p/nineproto.c:1.9 src/usr.sbin/puffs/mount_9p/nineproto.c:1.10 --- src/usr.sbin/puffs/mount_9p/nineproto.c:1.9 Fri Nov 30 19:02:38 2007 +++ src/usr.sbin/puffs/mount_9p/nineproto.c Fri May 17 08:48:04 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nineproto.c,v 1.9 2007/11/30 19:02:38 pooka Exp $ */ +/* $NetBSD: nineproto.c,v 1.10 2019/05/17 08:48:04 ozaki-r Exp $ */ /* * Copyright (c) 2007 Antti Kantee. All Rights Reserved. @@ -27,7 +27,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: nineproto.c,v 1.9 2007/11/30 19:02:38 pooka Exp $"); +__RCSID("$NetBSD: nineproto.c,v 1.10 2019/05/17 08:48:04 ozaki-r Exp $"); #endif /* !lint */ #include <sys/types.h> @@ -117,9 +117,10 @@ do { \ size -= *strsize; \ } while (/*CONSTCOND*/0) int -proto_getstat(struct puffs_framebuf *pb, struct vattr *vap, +proto_getstat(struct puffs_usermount *pu, struct puffs_framebuf *pb, struct vattr *vap, char **name, uint16_t *rs) { + struct puffs9p *p9p = puffs_getspecific(pu); char *uid, *gid; struct qid9p qid; uint64_t flen; @@ -176,6 +177,13 @@ proto_getstat(struct puffs_framebuf *pb, /* muid, not used */ GETSTR(NULL, &v16); + if (p9p->protover == P9PROTO_VERSION_U) { + uint32_t dummy; + GETSTR(NULL, &v16); /* extention[s], not used */ + GETFIELD(p9pbuf_get_4, &dummy, 4); /* n_uid[4], not used */ + GETFIELD(p9pbuf_get_4, &dummy, 4); /* n_gid[4], not used */ + GETFIELD(p9pbuf_get_4, &dummy, 4); /* n_muid[4], not used */ + } return 0; } @@ -269,9 +277,10 @@ proto_cc_open(struct puffs_usermount *pu } void -proto_make_stat(struct puffs_framebuf *pb, const struct vattr *vap, - const char *filename, enum vtype vt) +proto_make_stat(struct puffs_usermount *pu, struct puffs_framebuf *pb, + const struct vattr *vap, const char *filename, enum vtype vt) { + struct puffs9p *p9p = puffs_getspecific(pu); struct vattr fakeva; uint32_t mode, atime, mtime; uint64_t flen; @@ -324,6 +333,12 @@ proto_make_stat(struct puffs_framebuf *p p9pbuf_put_str(pb, owner); p9pbuf_put_str(pb, group); p9pbuf_put_str(pb, ""); /* muid */ + if (p9p->protover == P9PROTO_VERSION_U) { + p9pbuf_put_str(pb, P9PROTO_STAT_NOSTR); /* extentions[s] */ + p9pbuf_put_4(pb, P9PROTO_STAT_NOVAL4); /* n_uid[4] */ + p9pbuf_put_4(pb, P9PROTO_STAT_NOVAL4); /* n_gid[4] */ + p9pbuf_put_4(pb, P9PROTO_STAT_NOVAL4); /* n_muid[4] */ + } curoff = puffs_framebuf_telloff(pb); puffs_framebuf_seekset(pb, startoff); @@ -352,7 +367,8 @@ proto_expect_qid(struct puffs_framebuf * } int -proto_expect_stat(struct puffs_framebuf *pb, struct vattr *va) +proto_expect_stat(struct puffs_usermount *pu, struct puffs_framebuf *pb, + struct vattr *va) { uint16_t dummy; int rv; @@ -361,5 +377,5 @@ proto_expect_stat(struct puffs_framebuf return EPROTO; if ((rv = p9pbuf_get_2(pb, &dummy))) return rv; - return proto_getstat(pb, va, NULL, NULL); + return proto_getstat(pu, pb, va, NULL, NULL); } Index: src/usr.sbin/puffs/mount_9p/mount_9p.8 diff -u src/usr.sbin/puffs/mount_9p/mount_9p.8:1.7 src/usr.sbin/puffs/mount_9p/mount_9p.8:1.8 --- src/usr.sbin/puffs/mount_9p/mount_9p.8:1.7 Fri May 17 08:26:20 2019 +++ src/usr.sbin/puffs/mount_9p/mount_9p.8 Fri May 17 08:48:04 2019 @@ -1,4 +1,4 @@ -.\" $NetBSD: mount_9p.8,v 1.7 2019/05/17 08:26:20 wiz Exp $ +.\" $NetBSD: mount_9p.8,v 1.8 2019/05/17 08:48:04 ozaki-r Exp $ .\" .\" Copyright (c) 2007 Antti Kantee. All rights reserved. .\" @@ -32,6 +32,7 @@ .Sh SYNOPSIS .Nm .Op Fl s +.Op Fl u .Op Fl o Ar mntopts .Op Fl p Ar port .Ar [user@]host[:path] @@ -61,6 +62,16 @@ With the option .Nm runs in the forground. +.Pp +By default +.Nm +follows the 9P2000 protocol. +With +.Fl u +option +.Nm +follows the 9P2000.u protocol that includes extensions to better support Unix +environments. .Sh SEE ALSO .Xr puffs 3 , .Xr puffs 4 , @@ -74,6 +85,9 @@ The .Nm utility first appeared in .Nx 5.0 . +.Pp +Experimental 9P2000.u support appeared in +.Nx 9.0 . .Sh CAVEATS Permissions are not handled well. .Pp @@ -82,3 +96,5 @@ Authentication support is missing. Error code handling is missing. .Pp Under construction. +.Pp +9P2000.u support doesn't use extension fields. Index: src/usr.sbin/puffs/mount_9p/nineproto.h diff -u src/usr.sbin/puffs/mount_9p/nineproto.h:1.1 src/usr.sbin/puffs/mount_9p/nineproto.h:1.2 --- src/usr.sbin/puffs/mount_9p/nineproto.h:1.1 Sat Apr 21 14:21:43 2007 +++ src/usr.sbin/puffs/mount_9p/nineproto.h Fri May 17 08:48:04 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nineproto.h,v 1.1 2007/04/21 14:21:43 pooka Exp $ */ +/* $NetBSD: nineproto.h,v 1.2 2019/05/17 08:48:04 ozaki-r Exp $ */ /* * Copyright (c) 2007 Antti Kantee. All Rights Reserved. @@ -30,7 +30,12 @@ #include <stdint.h> -#define P9PROTO_VERSION "9P2000" +#define P9PROTO_VERSION 0 +#define P9PROTO_VERSION_U 1 + +#define P9PROTO_VERSTR "9P2000" +#define P9PROTO_VERSTR_U "9P2000.u" +#define P9PROTO_VERSTR_MAXLEN (sizeof(P9PROTO_VERSTR_U)) #define P9PROTO_T_VERSION 100 #define P9PROTO_R_VERSION 101 @@ -66,12 +71,18 @@ #define P9PROTO_NOFID (uint32_t)~0 #define P9PROTO_NOTAG (uint16_t)~0 +#define P9PROTO_NUNAME_UNSPECIFIED (uint16_t)~0 + /* type field in a qid */ #define P9PROTO_QID_TYPE_DIR 0x80 #define P9PROTO_QID_TYPE_APPEND 0x40 #define P9PROTO_QID_TYPE_EXCL 0x20 #define P9PROTO_QID_TYPE_MOUNT 0x10 #define P9PROTO_QID_TYPE_AUTH 0x08 +/* P92000.u extensions */ +#define P9PROTO_QID_TYPE_TMP 0x04 +#define P9PROTO_QID_TYPE_LINK 0x02 +#define P9PROTO_QID_TYPE_FILE 0x00 /* mode in open */ #define P9PROTO_OMODE_READ 0x00 @@ -83,11 +94,24 @@ /* for creating directories */ #define P9PROTO_CPERM_DIR 0x80000000 +#define P9PROTO_CPERM_APPEND 0x40000000 +#define P9PROTO_CPERM_EXCL 0x20000000 +#define P9PROTO_CPERM_MOUNT 0x10000000 +#define P9PROTO_CPERM_AUTH 0x08000000 +#define P9PROTO_CPERM_TMP 0x04000000 +#define P9PROTO_CPERM_SYMLINK 0x02000000 +/* P92000.u extensions */ +#define P9PROTO_CPERM_DEVICE 0x00800000 +#define P9PROTO_CPERM_NAMEDPIPE 0x00200000 +#define P9PROTO_CPERM_SOCKET 0x00100000 +#define P9PROTO_CPERM_SETUID 0x00080000 +#define P9PROTO_CPERM_SETGID 0x00040000 /* stat non-values */ #define P9PROTO_STAT_NOVAL1 (uint8_t)~0 #define P9PROTO_STAT_NOVAL2 (uint16_t)~0 #define P9PROTO_STAT_NOVAL4 (uint32_t)~0 #define P9PROTO_STAT_NOVAL8 (uint64_t)~0 +#define P9PROTO_STAT_NOSTR "" #endif /* PUFFS9P_PROTO_H_ */ Index: src/usr.sbin/puffs/mount_9p/ninepuffs.c diff -u src/usr.sbin/puffs/mount_9p/ninepuffs.c:1.24 src/usr.sbin/puffs/mount_9p/ninepuffs.c:1.25 --- src/usr.sbin/puffs/mount_9p/ninepuffs.c:1.24 Wed Aug 31 13:32:39 2011 +++ src/usr.sbin/puffs/mount_9p/ninepuffs.c Fri May 17 08:48:04 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: ninepuffs.c,v 1.24 2011/08/31 13:32:39 joerg Exp $ */ +/* $NetBSD: ninepuffs.c,v 1.25 2019/05/17 08:48:04 ozaki-r Exp $ */ /* * Copyright (c) 2007 Antti Kantee. All Rights Reserved. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: ninepuffs.c,v 1.24 2011/08/31 13:32:39 joerg Exp $"); +__RCSID("$NetBSD: ninepuffs.c,v 1.25 2019/05/17 08:48:04 ozaki-r Exp $"); #endif /* !lint */ #include <sys/types.h> @@ -50,6 +50,7 @@ __RCSID("$NetBSD: ninepuffs.c,v 1.24 201 #include <unistd.h> #include "ninepuffs.h" +#include "nineproto.h" #define DEFPORT_9P 564 @@ -107,6 +108,7 @@ main(int argc, char *argv[]) unsigned short port; int mntflags, pflags, ch; int detach; + int protover = P9PROTO_VERSION; setprogname(argv[0]); @@ -117,7 +119,7 @@ main(int argc, char *argv[]) detach = 1; port = DEFPORT_9P; - while ((ch = getopt(argc, argv, "o:p:s")) != -1) { + while ((ch = getopt(argc, argv, "o:p:su")) != -1) { switch (ch) { case 'o': mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags); @@ -131,6 +133,9 @@ main(int argc, char *argv[]) case 's': detach = 0; break; + case 'u': + protover = P9PROTO_VERSION_U; + break; default: usage(); /*NOTREACHED*/ @@ -177,6 +182,7 @@ main(int argc, char *argv[]) memset(&p9p, 0, sizeof(p9p)); p9p.maxreq = P9P_DEFREQLEN; p9p.nextfid = 1; + p9p.protover = protover; /* user@ */ if ((p = strchr(argv[0], '@')) != NULL) { Index: src/usr.sbin/puffs/mount_9p/ninepuffs.h diff -u src/usr.sbin/puffs/mount_9p/ninepuffs.h:1.12 src/usr.sbin/puffs/mount_9p/ninepuffs.h:1.13 --- src/usr.sbin/puffs/mount_9p/ninepuffs.h:1.12 Fri Nov 30 19:02:38 2007 +++ src/usr.sbin/puffs/mount_9p/ninepuffs.h Fri May 17 08:48:04 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: ninepuffs.h,v 1.12 2007/11/30 19:02:38 pooka Exp $ */ +/* $NetBSD: ninepuffs.h,v 1.13 2019/05/17 08:48:04 ozaki-r Exp $ */ /* * Copyright (c) 2007 Antti Kantee. All Rights Reserved. @@ -103,6 +103,8 @@ struct puffs9p { p9pfid_t nextfid; size_t maxreq; /* negotiated with server */ + + int protover; }; struct dirfid { @@ -147,18 +149,19 @@ uint8_t p9pbuf_get_type(struct puffs_fr uint16_t p9pbuf_get_tag(struct puffs_framebuf *); int proto_getqid(struct puffs_framebuf *, struct qid9p *); -int proto_getstat(struct puffs_framebuf *, struct vattr *, +int proto_getstat(struct puffs_usermount *, struct puffs_framebuf *, struct vattr *, char **, uint16_t *); int proto_expect_walk_nqids(struct puffs_framebuf *, uint16_t *); -int proto_expect_stat(struct puffs_framebuf *, struct vattr *); +int proto_expect_stat(struct puffs_usermount *, struct puffs_framebuf *, + struct vattr *); int proto_expect_qid(struct puffs_framebuf *, uint8_t, struct qid9p *); int proto_cc_dupfid(struct puffs_usermount *, p9pfid_t, p9pfid_t); int proto_cc_clunkfid(struct puffs_usermount *, p9pfid_t, int); int proto_cc_open(struct puffs_usermount *, p9pfid_t, p9pfid_t, int); -void proto_make_stat(struct puffs_framebuf *, const struct vattr *, - const char *, enum vtype); +void proto_make_stat(struct puffs_usermount *, struct puffs_framebuf *, + const struct vattr *, const char *, enum vtype); struct puffs_node *p9p_handshake(struct puffs_usermount *, const char *, const char *); Index: src/usr.sbin/puffs/mount_9p/node.c diff -u src/usr.sbin/puffs/mount_9p/node.c:1.21 src/usr.sbin/puffs/mount_9p/node.c:1.22 --- src/usr.sbin/puffs/mount_9p/node.c:1.21 Sun Jan 18 10:10:47 2009 +++ src/usr.sbin/puffs/mount_9p/node.c Fri May 17 08:48:04 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: node.c,v 1.21 2009/01/18 10:10:47 lukem Exp $ */ +/* $NetBSD: node.c,v 1.22 2019/05/17 08:48:04 ozaki-r Exp $ */ /* * Copyright (c) 2007 Antti Kantee. All Rights Reserved. @@ -27,7 +27,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: node.c,v 1.21 2009/01/18 10:10:47 lukem Exp $"); +__RCSID("$NetBSD: node.c,v 1.22 2019/05/17 08:48:04 ozaki-r Exp $"); #endif /* !lint */ #include <assert.h> @@ -62,7 +62,7 @@ do_getattr(struct puffs_usermount *pu, s p9pbuf_put_4(pb, p9n->fid_base); GETRESPONSE(pb); - rv = proto_expect_stat(pb, vap); + rv = proto_expect_stat(pu, pb, vap); out: RETURN(rv); @@ -120,7 +120,7 @@ puffs9p_node_lookup(struct puffs_usermou p9pbuf_put_2(pb, tag); p9pbuf_put_4(pb, tfid); GETRESPONSE(pb); - if ((rv = proto_expect_stat(pb, &va)) != 0) { + if ((rv = proto_expect_stat(pu, pb, &va)) != 0) { proto_cc_clunkfid(pu, tfid, 0); rv = ENOENT; goto out; @@ -194,7 +194,7 @@ puffs9p_node_readdir(struct puffs_usermo } while (count > 0) { - if ((rv = proto_getstat(pb, &va, &name, &statsize))) { + if ((rv = proto_getstat(pu, pb, &va, &name, &statsize))) { /* * If there was an error, it's unlikely we'll be * coming back, so just nuke the dfp. If we do @@ -231,7 +231,7 @@ puffs9p_node_setattr(struct puffs_usermo p9pbuf_put_1(pb, P9PROTO_T_WSTAT); p9pbuf_put_2(pb, tag); p9pbuf_put_4(pb, p9n->fid_base); - proto_make_stat(pb, va, NULL, pn->pn_va.va_type); + proto_make_stat(pu, pb, va, NULL, pn->pn_va.va_type); GETRESPONSE(pb); if (p9pbuf_get_type(pb) != P9PROTO_R_WSTAT) @@ -426,6 +426,8 @@ nodecreate(struct puffs_usermount *pu, s p9pbuf_put_str(pb, name); p9pbuf_put_4(pb, dirbit | (vap->va_mode & 0777)); p9pbuf_put_1(pb, 0); + if (p9p->protover == P9PROTO_VERSION_U) + p9pbuf_put_str(pb, ""); /* extension[s] */ GETRESPONSE(pb); rv = proto_expect_qid(pb, P9PROTO_R_CREATE, &nqid); @@ -579,7 +581,7 @@ puffs9p_node_rename(struct puffs_usermou p9pbuf_put_1(pb, P9PROTO_T_WSTAT); p9pbuf_put_2(pb, tag); p9pbuf_put_4(pb, p9n_src->fid_base); - proto_make_stat(pb, NULL, pcn_targ->pcn_name, pn_src->pn_va.va_type); + proto_make_stat(pu, pb, NULL, pcn_targ->pcn_name, pn_src->pn_va.va_type); GETRESPONSE(pb); if (p9pbuf_get_type(pb) != P9PROTO_R_WSTAT)