diff options
435 files changed, 9456 insertions, 10590 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1 index c27abd6..c1a071a 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1768,7 +1768,7 @@ secure/lib/libssh__L: lib/libz__L secure/lib/libcrypto__L lib/libcrypt__L .if ${MK_LDNS} != "no" secure/lib/libssh__L: lib/libldns__L .endif -.if ${MK_KERBEROS_SUPPORT} != "no" +.if ${MK_GSSAPI} != "no" && ${MK_KERBEROS_SUPPORT} != "no" secure/lib/libssh__L: lib/libgssapi__L kerberos5/lib/libkrb5__L \ kerberos5/lib/libhx509__L kerberos5/lib/libasn1__L lib/libcom_err__L \ lib/libmd__L kerberos5/lib/libroken__L diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index c2b8b1b..d5a4a1c 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,10 @@ # xargs -n1 | sort | uniq -d; # done +# 20161229: Three files from gnop tests consolidated into one +OLD_FILES+=usr/tests/sys/geom/class/nop/1_test +OLD_FILES+=usr/tests/sys/geom/class/nop/2_test +OLD_FILES+=usr/tests/sys/geom/class/nop/conf.sh # 20161121: Hyper-V manuals only apply to amd64 and i386. .if ${TARGET_ARCH} != "amd64" && ${TARGET_ARCH} != "i386" OLD_FILES+=usr/share/man/man4/hv_kvp.4.gz diff --git a/bin/kill/kill.1 b/bin/kill/kill.1 index 6e77c59..b6b655c 100644 --- a/bin/kill/kill.1 +++ b/bin/kill/kill.1 @@ -32,7 +32,7 @@ .\" @(#)kill.1 8.2 (Berkeley) 4/28/95 .\" $FreeBSD$ .\" -.Dd April 28, 1995 +.Dd October 3, 2016 .Dt KILL 1 .Os .Sh NAME @@ -147,7 +147,8 @@ compatible. A .Nm command appeared in -.At v3 . +.At v3 +in section 8 of the manual. .Sh BUGS A replacement for the command .Dq Li kill 0 diff --git a/bin/ls/tests/ls_tests.sh b/bin/ls/tests/ls_tests.sh index 4e805d5..9499293 100755 --- a/bin/ls/tests/ls_tests.sh +++ b/bin/ls/tests/ls_tests.sh @@ -689,7 +689,6 @@ atf_test_case o_flag o_flag_head() { atf_set "descr" "Verify that the output from ls -o prints out the chflag values or '-' if none are set" - atf_set "require.user" "root" } o_flag_body() @@ -703,6 +702,7 @@ o_flag_body() atf_check -e ignore -o empty -s exit:0 dd if=/dev/zero of=b.file \ bs=$size count=1 atf_check -e empty -o empty -s exit:0 chflags uarch a.file + atf_check -e empty -o empty -s exit:0 chflags 0 b.file atf_check -e empty -o match:"[[:space:]]+uarch[[:space:]]$size+.+a\\.file" \ -s exit:0 ls -lo a.file diff --git a/contrib/bsnmp/gensnmpdef/gensnmpdef.c b/contrib/bsnmp/gensnmpdef/gensnmpdef.c index 32c835d..b0bfdaf 100644 --- a/contrib/bsnmp/gensnmpdef/gensnmpdef.c +++ b/contrib/bsnmp/gensnmpdef/gensnmpdef.c @@ -126,9 +126,11 @@ open_node(const SmiNode *n, u_int level, SmiNode **last) while (level < n->oidlen - 1) { if (level >= cut) { + n1 = smiGetNodeByOID(level + 1, n->oid); + if (n1 == NULL) + continue; pindent(level); printf("(%u", n->oid[level]); - n1 = smiGetNodeByOID(level + 1, n->oid); printf(" "); print_name(n1); printf("\n"); @@ -397,12 +399,11 @@ static void save_typdef(char *name) { struct tdef *t; - t = malloc(sizeof(struct tdef)); + t = calloc(1, sizeof(struct tdef)); if (t == NULL) err(1, NULL); - memset(t, 0 , sizeof(struct tdef)); t->name = name; SLIST_INSERT_HEAD(&tdefs, t, link); } @@ -559,7 +560,11 @@ main(int argc, char *argv[]) level = 0; last = NULL; for (opt = 0; opt < argc; opt++) { + if (mods[opt] == NULL) /* smiGetModule failed above */ + continue; n = smiGetFirstNode(mods[opt], SMI_NODEKIND_ANY); + if (n == NULL) + continue; for (;;) { if (do_typedef == 0) { level = open_node(n, level, &last); diff --git a/contrib/bsnmp/lib/snmp.c b/contrib/bsnmp/lib/snmp.c index 68f46f9..d86f88a 100644 --- a/contrib/bsnmp/lib/snmp.c +++ b/contrib/bsnmp/lib/snmp.c @@ -1154,8 +1154,11 @@ snmp_pdu_dump(const struct snmp_pdu *pdu) void snmp_value_free(struct snmp_value *value) { - if (value->syntax == SNMP_SYNTAX_OCTETSTRING) + + if (value->syntax == SNMP_SYNTAX_OCTETSTRING) { free(value->v.octetstring.octets); + value->v.octetstring.octets = NULL; + } value->syntax = SNMP_SYNTAX_NULL; } @@ -1216,6 +1219,7 @@ snmp_pdu_free(struct snmp_pdu *pdu) for (i = 0; i < pdu->nbindings; i++) snmp_value_free(&pdu->bindings[i]); + pdu->nbindings = 0; } /* diff --git a/contrib/bsnmp/lib/snmpclient.c b/contrib/bsnmp/lib/snmpclient.c index 90b7d4a..10c58f5 100644 --- a/contrib/bsnmp/lib/snmpclient.c +++ b/contrib/bsnmp/lib/snmpclient.c @@ -728,8 +728,11 @@ snmp_table_fetch_async(const struct snmp_table *descr, void *list, work->last_change = 0; table_init_pdu(descr, &work->pdu); - if (snmp_pdu_send(&work->pdu, table_cb, work) == -1) + if (snmp_pdu_send(&work->pdu, table_cb, work) == -1) { + free(work); + work = NULL; return (-1); + } return (0); } @@ -1231,7 +1234,7 @@ snmp_send_packet(struct snmp_pdu * pdu) struct asn_buf b; ssize_t ret; - if ((buf = malloc(snmp_client.txbuflen)) == NULL) { + if ((buf = calloc(1, snmp_client.txbuflen)) == NULL) { seterr(&snmp_client, "%s", strerror(errno)); return (-1); } @@ -1256,7 +1259,7 @@ snmp_send_packet(struct snmp_pdu * pdu) } free(buf); - return pdu->request_id; + return (pdu->request_id); } /* @@ -1352,7 +1355,7 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv) socklen_t optlen; #endif - if ((buf = malloc(snmp_client.rxbuflen)) == NULL) { + if ((buf = calloc(1, snmp_client.rxbuflen)) == NULL) { seterr(&snmp_client, "%s", strerror(errno)); return (-1); } diff --git a/contrib/bsnmp/snmp_mibII/BEGEMOT-IP-MIB.txt b/contrib/bsnmp/snmp_mibII/BEGEMOT-IP-MIB.txt index 761876a..29f7844 100644 --- a/contrib/bsnmp/snmp_mibII/BEGEMOT-IP-MIB.txt +++ b/contrib/bsnmp/snmp_mibII/BEGEMOT-IP-MIB.txt @@ -54,6 +54,9 @@ begemotIp MODULE-IDENTITY E-mail: harti@freebsd.org" DESCRIPTION "The MIB for IP stuff that is not in the official IP MIBs." + REVISION "200602130000Z" + DESCRIPTION + "Initial revision." ::= { begemot 3 } begemotIpObjects OBJECT IDENTIFIER ::= { begemotIp 1 } diff --git a/contrib/bsnmp/snmp_mibII/mibII.c b/contrib/bsnmp/snmp_mibII/mibII.c index 85c61d5..e66a951 100644 --- a/contrib/bsnmp/snmp_mibII/mibII.c +++ b/contrib/bsnmp/snmp_mibII/mibII.c @@ -265,7 +265,7 @@ mib_if_admin(struct mibif *ifp, int up) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr) == -1) { syslog(LOG_ERR, "SIOCGIFFLAGS(%s): %m", ifp->name); return (-1); @@ -319,7 +319,7 @@ fetch_generic_mib(struct mibif *ifp, const struct ifmibdata *old) name[5] = IFDATA_GENERAL; len = sizeof(ifp->mib); - if (sysctl(name, 6, &ifp->mib, &len, NULL, 0) == -1) { + if (sysctl(name, nitems(name), &ifp->mib, &len, NULL, 0) == -1) { if (errno != ENOENT) syslog(LOG_WARNING, "sysctl(ifmib, %s) failed %m", ifp->name); @@ -480,7 +480,7 @@ mib_fetch_ifmib(struct mibif *ifp) name[3] = IFMIB_IFDATA; name[4] = ifp->sysindex; name[5] = IFDATA_LINKSPECIFIC; - if (sysctl(name, 6, NULL, &len, NULL, 0) == -1) { + if (sysctl(name, nitems(name), NULL, &len, NULL, 0) == -1) { syslog(LOG_WARNING, "sysctl linkmib estimate (%s): %m", ifp->name); if (ifp->specmib != NULL) { @@ -506,7 +506,7 @@ mib_fetch_ifmib(struct mibif *ifp) ifp->specmib = newmib; ifp->specmiblen = len; } - if (sysctl(name, 6, ifp->specmib, &len, NULL, 0) == -1) { + if (sysctl(name, nitems(name), ifp->specmib, &len, NULL, 0) == -1) { syslog(LOG_WARNING, "sysctl linkmib (%s): %m", ifp->name); if (ifp->specmib != NULL) { ifp->specmib = NULL; @@ -515,7 +515,7 @@ mib_fetch_ifmib(struct mibif *ifp) } out: - strncpy(irr.ifr_name, ifp->name, sizeof(irr.ifr_name)); + strlcpy(irr.ifr_name, ifp->name, sizeof(irr.ifr_name)); irr.ifr_buffer.buffer = MIBIF_PRIV(ifp)->alias; irr.ifr_buffer.length = sizeof(MIBIF_PRIV(ifp)->alias); if (ioctl(mib_netsock, SIOCGIFDESCR, &irr) == -1) { @@ -902,7 +902,7 @@ mib_refresh_iflist(void) for (idx = 1; idx <= count; idx++) { name[4] = idx; len = sizeof(mib); - if (sysctl(name, 6, &mib, &len, NULL, 0) == -1) { + if (sysctl(name, nitems(name), &mib, &len, NULL, 0) == -1) { if (errno == ENOENT) continue; syslog(LOG_ERR, "ifmib(%u): %m", idx); @@ -1213,7 +1213,7 @@ mib_fetch_rtab(int af, int info, int arg, size_t *lenp) *lenp = 0; /* initial estimate */ - if (sysctl(name, 6, NULL, lenp, NULL, 0) == -1) { + if (sysctl(name, nitems(name), NULL, lenp, NULL, 0) == -1) { syslog(LOG_ERR, "sysctl estimate (%d,%d,%d,%d,%d,%d): %m", name[0], name[1], name[2], name[3], name[4], name[5]); return (NULL); @@ -1230,7 +1230,7 @@ mib_fetch_rtab(int af, int info, int arg, size_t *lenp) } buf = newbuf; - if (sysctl(name, 6, buf, lenp, NULL, 0) == 0) + if (sysctl(name, nitems(name), buf, lenp, NULL, 0) == 0) break; if (errno != ENOMEM) { @@ -1384,7 +1384,7 @@ siocaifaddr(char *ifname, struct in_addr addr, struct in_addr mask, struct sockaddr_in *sa; memset(&addreq, 0, sizeof(addreq)); - strncpy(addreq.ifra_name, ifname, sizeof(addreq.ifra_name)); + strlcpy(addreq.ifra_name, ifname, sizeof(addreq.ifra_name)); sa = (struct sockaddr_in *)(void *)&addreq.ifra_addr; sa->sin_family = AF_INET; @@ -1414,7 +1414,7 @@ siocdifaddr(const char *ifname, struct in_addr addr) struct sockaddr_in *sa; memset(&delreq, 0, sizeof(delreq)); - strncpy(delreq.ifr_name, ifname, sizeof(delreq.ifr_name)); + strlcpy(delreq.ifr_name, ifname, sizeof(delreq.ifr_name)); sa = (struct sockaddr_in *)(void *)&delreq.ifr_addr; sa->sin_family = AF_INET; sa->sin_len = sizeof(*sa); @@ -1433,7 +1433,7 @@ verify_ifa(const char *name, struct mibifa *ifa) struct sockaddr_in *sa; memset(&req, 0, sizeof(req)); - strncpy(req.ifr_name, name, sizeof(req.ifr_name)); + strlcpy(req.ifr_name, name, sizeof(req.ifr_name)); sa = (struct sockaddr_in *)(void *)&req.ifr_addr; sa->sin_family = AF_INET; sa->sin_len = sizeof(*sa); diff --git a/contrib/bsnmp/snmp_mibII/mibII_interfaces.c b/contrib/bsnmp/snmp_mibII/mibII_interfaces.c index c0f61c7..03ca28c 100644 --- a/contrib/bsnmp/snmp_mibII/mibII_interfaces.c +++ b/contrib/bsnmp/snmp_mibII/mibII_interfaces.c @@ -77,7 +77,7 @@ ifchange_func(struct snmp_context *ctx __unused, struct snmp_dependency *dep, switch (op) { case SNMP_DEPOP_COMMIT: - strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr) == -1) { syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name); return (SNMP_ERR_GENERR); @@ -95,7 +95,7 @@ ifchange_func(struct snmp_context *ctx __unused, struct snmp_dependency *dep, ifc->rb |= IFRB_FLAGS; } if (ifc->rb & IFRB_FLAGS) { - strncpy(ifr1.ifr_name, ifp->name, sizeof(ifr1.ifr_name)); + strlcpy(ifr1.ifr_name, ifp->name, sizeof(ifr1.ifr_name)); if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr1) == -1) { syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name); return (SNMP_ERR_GENERR); @@ -116,7 +116,7 @@ ifchange_func(struct snmp_context *ctx __unused, struct snmp_dependency *dep, case SNMP_DEPOP_ROLLBACK: if (ifc->rb & IFRB_FLAGS) { - strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); ifr.ifr_flags = ifc->rb_flags; if (ioctl(mib_netsock, SIOCSIFFLAGS, &ifr) == -1) { syslog(LOG_ERR, "SIFFLAGS(%s): %m", ifp->name); diff --git a/contrib/bsnmp/snmp_mibII/snmp_mibII.3 b/contrib/bsnmp/snmp_mibII/snmp_mibII.3 index 36653e6..09a9145 100644 --- a/contrib/bsnmp/snmp_mibII/snmp_mibII.3 +++ b/contrib/bsnmp/snmp_mibII/snmp_mibII.3 @@ -31,7 +31,7 @@ .\" .\" $Begemot: bsnmp/snmp_mibII/snmp_mibII.3,v 1.10 2005/10/04 08:46:52 brandt_h Exp $ .\" -.Dd October 4, 2005 +.Dd January 4, 2017 .Dt SNMP_MIBII 3 .Os .Sh NAME @@ -63,6 +63,8 @@ .Sh LIBRARY .Pq begemotSnmpdModulePath."mibII" = "@MODPATH@snmp_mibII.so" .Sh SYNOPSIS +.In net/if.h +.In net/if_mib.h .In bsnmp/snmpmod.h .In bsnmp/snmp_mibII.h .Ft typedef void diff --git a/contrib/bsnmp/snmp_usm/usm_snmp.c b/contrib/bsnmp/snmp_usm/usm_snmp.c index 6ed639a..a6c7b86 100644 --- a/contrib/bsnmp/snmp_usm/usm_snmp.c +++ b/contrib/bsnmp/snmp_usm/usm_snmp.c @@ -169,8 +169,12 @@ op_usm_users(struct snmp_context *ctx, struct snmp_value *val, val->var.subs[sub - 1] != LEAF_usmUserCloneFrom) return (SNMP_ERR_NOSUCHNAME); + /* + * XXX (ngie): need to investigate the MIB to determine how + * this is possible given some of the transitions below. + */ if (community != COMM_INITIALIZE && - uuser->type == StorageType_readOnly) + uuser != NULL && uuser->type == StorageType_readOnly) return (SNMP_ERR_NOT_WRITEABLE); switch (val->var.subs[sub - 1]) { diff --git a/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt b/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt index 9d99eab..d7f6099 100644 --- a/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt +++ b/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt @@ -54,6 +54,9 @@ begemot MODULE-IDENTITY E-mail: harti@freebsd.org" DESCRIPTION "The root of the Begemot subtree of the fokus tree." + REVISION "200201300000Z" + DESCRIPTION + "Initial revision." ::= { fokus 1 } END diff --git a/contrib/bsnmp/snmpd/FOKUS-MIB.txt b/contrib/bsnmp/snmpd/FOKUS-MIB.txt index d4671e8..f356d14 100644 --- a/contrib/bsnmp/snmpd/FOKUS-MIB.txt +++ b/contrib/bsnmp/snmpd/FOKUS-MIB.txt @@ -52,6 +52,9 @@ fokus MODULE-IDENTITY E-mail: harti@freebsd.org" DESCRIPTION "The root of the Fokus enterprises tree." + REVISION "200202050000Z" + DESCRIPTION + "Initial revision." ::= { enterprises 12325 } END diff --git a/contrib/bsnmp/snmpd/main.c b/contrib/bsnmp/snmpd/main.c index 2ab8bbd..a2053e8 100644 --- a/contrib/bsnmp/snmpd/main.c +++ b/contrib/bsnmp/snmpd/main.c @@ -1024,154 +1024,6 @@ snmp_input_consume(struct port_input *pi) pi->length -= pi->consumed; } -static void -check_priv_dgram(struct port_input *pi, struct sockcred *cred) -{ - - /* process explicitly sends credentials */ - if (cred) - pi->priv = (cred->sc_euid == 0); - else - pi->priv = 0; -} - -static void -check_priv_stream(struct port_input *pi) -{ - struct xucred ucred; - socklen_t ucredlen; - - /* obtain the accept time credentials */ - ucredlen = sizeof(ucred); - - if (getsockopt(pi->fd, 0, LOCAL_PEERCRED, &ucred, &ucredlen) == 0 && - ucredlen >= sizeof(ucred) && ucred.cr_version == XUCRED_VERSION) - pi->priv = (ucred.cr_uid == 0); - else - pi->priv = 0; -} - -/* - * Input from a stream socket. - */ -static int -recv_stream(struct port_input *pi) -{ - struct msghdr msg; - struct iovec iov[1]; - ssize_t len; - - if (pi->buf == NULL) { - /* no buffer yet - allocate one */ - if ((pi->buf = buf_alloc(0)) == NULL) { - /* ups - could not get buffer. Return an error - * the caller must close the transport. */ - return (-1); - } - pi->buflen = buf_size(0); - pi->consumed = 0; - pi->length = 0; - } - - /* try to get a message */ - msg.msg_name = pi->peer; - msg.msg_namelen = pi->peerlen; - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - iov[0].iov_base = pi->buf + pi->length; - iov[0].iov_len = pi->buflen - pi->length; - - len = recvmsg(pi->fd, &msg, 0); - - if (len == -1 || len == 0) - /* receive error */ - return (-1); - - pi->length += len; - - if (pi->cred) - check_priv_stream(pi); - - return (0); -} - -/* - * Input from a datagram socket. - * Each receive should return one datagram. - */ -static int -recv_dgram(struct port_input *pi, struct in_addr *laddr) -{ - u_char embuf[1000]; - char cbuf[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) + - CMSG_SPACE(sizeof(struct in_addr))]; - struct msghdr msg; - struct iovec iov[1]; - ssize_t len; - struct cmsghdr *cmsg; - struct sockcred *cred = NULL; - - if (pi->buf == NULL) { - /* no buffer yet - allocate one */ - if ((pi->buf = buf_alloc(0)) == NULL) { - /* ups - could not get buffer. Read away input - * and drop it */ - (void)recvfrom(pi->fd, embuf, sizeof(embuf), - 0, NULL, NULL); - /* return error */ - return (-1); - } - pi->buflen = buf_size(0); - } - - /* try to get a message */ - msg.msg_name = pi->peer; - msg.msg_namelen = pi->peerlen; - msg.msg_iov = iov; - msg.msg_iovlen = 1; - memset(cbuf, 0, sizeof(cbuf)); - msg.msg_control = cbuf; - msg.msg_controllen = sizeof(cbuf); - msg.msg_flags = 0; - - iov[0].iov_base = pi->buf; - iov[0].iov_len = pi->buflen; - - len = recvmsg(pi->fd, &msg, 0); - - if (len == -1 || len == 0) - /* receive error */ - return (-1); - - if (msg.msg_flags & MSG_TRUNC) { - /* truncated - drop */ - snmpd_stats.silentDrops++; - snmpd_stats.inTooLong++; - return (-1); - } - - pi->length = (size_t)len; - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == IPPROTO_IP && - cmsg->cmsg_type == IP_RECVDSTADDR) - memcpy(laddr, CMSG_DATA(cmsg), sizeof(struct in_addr)); - if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_CREDS) - cred = (struct sockcred *)CMSG_DATA(cmsg); - } - - if (pi->cred) - check_priv_dgram(pi, cred); - - return (0); -} - /* * Input from a socket */ @@ -1183,43 +1035,13 @@ snmpd_input(struct port_input *pi, struct tport *tport) struct snmp_pdu pdu; enum snmpd_input_err ierr, ferr; enum snmpd_proxy_err perr; + ssize_t ret, slen; int32_t vi; - int ret; - ssize_t slen; #ifdef USE_TCPWRAPPERS char client[16]; #endif - struct msghdr msg; - struct iovec iov[1]; - char cbuf[CMSG_SPACE(sizeof(struct in_addr))]; - struct cmsghdr *cmsgp; - - /* get input depending on the transport */ - if (pi->stream) { - msg.msg_control = NULL; - msg.msg_controllen = 0; - - ret = recv_stream(pi); - } else { - struct in_addr *laddr; - - memset(cbuf, 0, CMSG_SPACE(sizeof(struct in_addr))); - msg.msg_control = cbuf; - msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr)); - cmsgp = CMSG_FIRSTHDR(&msg); - cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); - cmsgp->cmsg_level = IPPROTO_IP; - cmsgp->cmsg_type = IP_SENDSRCADDR; - laddr = (struct in_addr *)CMSG_DATA(cmsgp); - - ret = recv_dgram(pi, laddr); - - if (laddr->s_addr == 0) { - msg.msg_control = NULL; - msg.msg_controllen = 0; - } - } + ret = tport->transport->vtab->recv(tport, pi); if (ret == -1) return (-1); @@ -1362,21 +1184,15 @@ snmpd_input(struct port_input *pi, struct tport *tport) sndbuf, &sndlen, "SNMP", ierr, vi, NULL); if (ferr == SNMPD_INPUT_OK) { - msg.msg_name = pi->peer; - msg.msg_namelen = pi->peerlen; - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_flags = 0; - iov[0].iov_base = sndbuf; - iov[0].iov_len = sndlen; - - slen = sendmsg(pi->fd, &msg, 0); + slen = tport->transport->vtab->send(tport, sndbuf, sndlen, + pi->peer, pi->peerlen); if (slen == -1) - syslog(LOG_ERR, "sendmsg: %m"); + syslog(LOG_ERR, "send*: %m"); else if ((size_t)slen != sndlen) - syslog(LOG_ERR, "sendmsg: short write %zu/%zu", - sndlen, (size_t)slen); + syslog(LOG_ERR, "send*: short write %zu/%zu", sndlen, + (size_t)slen); } + snmp_pdu_free(&pdu); free(sndbuf); snmp_input_consume(pi); @@ -2508,13 +2324,12 @@ lm_load(const char *path, const char *section) } m->handle = NULL; m->flags = 0; - strcpy(m->section, section); + strlcpy(m->section, section, sizeof(m->section)); - if ((m->path = malloc(strlen(path) + 1)) == NULL) { + if ((m->path = strdup(path)) == NULL) { syslog(LOG_ERR, "lm_load: %m"); goto err; } - strcpy(m->path, path); /* * Make index diff --git a/contrib/bsnmp/snmpd/snmpd.h b/contrib/bsnmp/snmpd/snmpd.h index 009b2e7..6afbc96 100644 --- a/contrib/bsnmp/snmpd/snmpd.h +++ b/contrib/bsnmp/snmpd/snmpd.h @@ -193,6 +193,7 @@ struct transport_def { ssize_t (*send)(struct tport *, const u_char *, size_t, const struct sockaddr *, size_t); + ssize_t (*recv)(struct tport *, struct port_input *); }; struct transport { struct asn_oid index; /* transport table index */ diff --git a/contrib/bsnmp/snmpd/trans_lsock.c b/contrib/bsnmp/snmpd/trans_lsock.c index 6c168ac..a390839 100644 --- a/contrib/bsnmp/snmpd/trans_lsock.c +++ b/contrib/bsnmp/snmpd/trans_lsock.c @@ -33,6 +33,7 @@ #include <sys/types.h> #include <sys/queue.h> #include <sys/stat.h> +#include <sys/ucred.h> #include <sys/un.h> #include <errno.h> @@ -58,6 +59,7 @@ static void lsock_close_port(struct tport *); static int lsock_init_port(struct tport *); static ssize_t lsock_send(struct tport *, const u_char *, size_t, const struct sockaddr *, size_t); +static ssize_t lsock_recv(struct tport *, struct port_input *); /* exported */ const struct transport_def lsock_trans = { @@ -67,7 +69,8 @@ const struct transport_def lsock_trans = { lsock_stop, lsock_close_port, lsock_init_port, - lsock_send + lsock_send, + lsock_recv }; static struct transport *my_trans; @@ -302,10 +305,9 @@ lsock_init_port(struct tport *tp) return (SNMP_ERR_RES_UNAVAIL); } - strcpy(sa.sun_path, p->name); + strlcpy(sa.sun_path, p->name, sizeof(sa.sun_path)); sa.sun_family = AF_LOCAL; - sa.sun_len = strlen(p->name) + - offsetof(struct sockaddr_un, sun_path); + sa.sun_len = SUN_LEN(&sa); (void)remove(p->name); @@ -357,10 +359,9 @@ lsock_init_port(struct tport *tp) return (SNMP_ERR_GENERR); } - strcpy(sa.sun_path, p->name); + strlcpy(sa.sun_path, p->name, sizeof(sa.sun_path)); sa.sun_family = AF_LOCAL; - sa.sun_len = strlen(p->name) + - offsetof(struct sockaddr_un, sun_path); + sa.sun_len = SUN_LEN(&sa); (void)remove(p->name); @@ -418,6 +419,73 @@ lsock_send(struct tport *tp, const u_char *buf, size_t len, return (sendto(peer->input.fd, buf, len, 0, addr, addrlen)); } +static void +check_priv_stream(struct port_input *pi) +{ + struct xucred ucred; + socklen_t ucredlen; + + /* obtain the accept time credentials */ + ucredlen = sizeof(ucred); + + if (getsockopt(pi->fd, 0, LOCAL_PEERCRED, &ucred, &ucredlen) == 0 && + ucredlen >= sizeof(ucred) && ucred.cr_version == XUCRED_VERSION) + pi->priv = (ucred.cr_uid == 0); + else + pi->priv = 0; +} + +/* + * Receive something + */ +static ssize_t +lsock_recv(struct tport *tp __unused, struct port_input *pi) +{ + struct msghdr msg; + struct iovec iov[1]; + ssize_t len; + + msg.msg_control = NULL; + msg.msg_controllen = 0; + + if (pi->buf == NULL) { + /* no buffer yet - allocate one */ + if ((pi->buf = buf_alloc(0)) == NULL) { + /* ups - could not get buffer. Return an error + * the caller must close the transport. */ + return (-1); + } + pi->buflen = buf_size(0); + pi->consumed = 0; + pi->length = 0; + } + + /* try to get a message */ + msg.msg_name = pi->peer; + msg.msg_namelen = pi->peerlen; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + iov[0].iov_base = pi->buf + pi->length; + iov[0].iov_len = pi->buflen - pi->length; + + len = recvmsg(pi->fd, &msg, 0); + + if (len == -1 || len == 0) + /* receive error */ + return (-1); + + pi->length += len; + + if (pi->cred) + check_priv_stream(pi); + + return (0); +} + /* * Dependency to create a lsock port */ diff --git a/contrib/bsnmp/snmpd/trans_udp.c b/contrib/bsnmp/snmpd/trans_udp.c index a41d3f0..5c9a7fd 100644 --- a/contrib/bsnmp/snmpd/trans_udp.c +++ b/contrib/bsnmp/snmpd/trans_udp.c @@ -32,7 +32,9 @@ */ #include <sys/types.h> #include <sys/queue.h> +#include <sys/ucred.h> +#include <stdbool.h> #include <stdlib.h> #include <syslog.h> #include <string.h> @@ -54,6 +56,7 @@ static void udp_close_port(struct tport *); static int udp_init_port(struct tport *); static ssize_t udp_send(struct tport *, const u_char *, size_t, const struct sockaddr *, size_t); +static ssize_t udp_recv(struct tport *, struct port_input *); /* exported */ const struct transport_def udp_trans = { @@ -63,7 +66,8 @@ const struct transport_def udp_trans = { udp_stop, udp_close_port, udp_init_port, - udp_send + udp_send, + udp_recv }; static struct transport *my_trans; @@ -116,13 +120,15 @@ udp_init_port(struct tport *tp) addr.sin_port = htons(p->port); addr.sin_family = AF_INET; addr.sin_len = sizeof(addr); - if (addr.sin_addr.s_addr == INADDR_ANY && - setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on, - sizeof(on)) == -1) { - syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m"); - close(p->input.fd); - p->input.fd = -1; - return (SNMP_ERR_GENERR); + if (addr.sin_addr.s_addr == INADDR_ANY) { + if (setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on, + sizeof(on)) == -1) { + syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m"); + close(p->input.fd); + p->input.fd = -1; + return (SNMP_ERR_GENERR); + } + p->recvdstaddr = true; } if (bind(p->input.fd, (struct sockaddr *)&addr, sizeof(addr))) { if (errno == EADDRNOTAVAIL) { @@ -214,8 +220,121 @@ udp_send(struct tport *tp, const u_char *buf, size_t len, const struct sockaddr *addr, size_t addrlen) { struct udp_port *p = (struct udp_port *)tp; + struct cmsghdr *cmsg; + struct msghdr msg; + char cbuf[CMSG_SPACE(sizeof(struct in_addr))]; + struct iovec iov; + + iov.iov_base = __DECONST(void*, buf); + iov.iov_len = len; + + msg.msg_flags = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_name = __DECONST(void *, addr); + msg.msg_namelen = addrlen; + + if (p->recvdstaddr) { + msg.msg_control = cbuf; + msg.msg_controllen = sizeof(cbuf); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_SENDSRCADDR; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); + memcpy(CMSG_DATA(cmsg), &p->dstaddr, sizeof(struct in_addr)); + } else { + msg.msg_control = NULL; + msg.msg_controllen = 0; + } + + return (sendmsg(p->input.fd, &msg, 0)); +} + +static void +check_priv_dgram(struct port_input *pi, struct sockcred *cred) +{ + + /* process explicitly sends credentials */ + if (cred) + pi->priv = (cred->sc_euid == 0); + else + pi->priv = 0; +} + +/* + * Input from a datagram socket. + * Each receive should return one datagram. + */ +static ssize_t +udp_recv(struct tport *tp, struct port_input *pi) +{ + u_char embuf[1000]; + char cbuf[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) + + CMSG_SPACE(sizeof(struct in_addr))]; + struct udp_port *p = (struct udp_port *)tp; + struct msghdr msg; + struct iovec iov[1]; + ssize_t len; + struct cmsghdr *cmsg; + struct sockcred *cred = NULL; + + if (pi->buf == NULL) { + /* no buffer yet - allocate one */ + if ((pi->buf = buf_alloc(0)) == NULL) { + /* ups - could not get buffer. Read away input + * and drop it */ + (void)recvfrom(pi->fd, embuf, sizeof(embuf), + 0, NULL, NULL); + /* return error */ + return (-1); + } + pi->buflen = buf_size(0); + } + + /* try to get a message */ + msg.msg_name = pi->peer; + msg.msg_namelen = pi->peerlen; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + memset(cbuf, 0, sizeof(cbuf)); + msg.msg_control = cbuf; + msg.msg_controllen = sizeof(cbuf); + msg.msg_flags = 0; + + iov[0].iov_base = pi->buf; + iov[0].iov_len = pi->buflen; + + len = recvmsg(pi->fd, &msg, 0); + + if (len == -1 || len == 0) + /* receive error */ + return (-1); + + if (msg.msg_flags & MSG_TRUNC) { + /* truncated - drop */ + snmpd_stats.silentDrops++; + snmpd_stats.inTooLong++; + return (-1); + } + + pi->length = (size_t)len; + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == IPPROTO_IP && + cmsg->cmsg_type == IP_RECVDSTADDR) + memcpy(&p->dstaddr, CMSG_DATA(cmsg), + sizeof(struct in_addr)); + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_CREDS) + cred = (struct sockcred *)CMSG_DATA(cmsg); + } + + if (pi->cred) + check_priv_dgram(pi, cred); - return (sendto(p->input.fd, buf, len, 0, addr, addrlen)); + return (0); } /* diff --git a/contrib/bsnmp/snmpd/trans_udp.h b/contrib/bsnmp/snmpd/trans_udp.h index d383711..2f50e2a 100644 --- a/contrib/bsnmp/snmpd/trans_udp.h +++ b/contrib/bsnmp/snmpd/trans_udp.h @@ -39,6 +39,9 @@ struct udp_port { struct port_input input; /* common input stuff */ struct sockaddr_in ret; /* the return address */ + + bool recvdstaddr; /* IP_RECVDSTADDR is on */ + struct in_addr dstaddr; /* address the request was sent to */ }; /* argument for open call */ diff --git a/contrib/bzip2/bzip2.c b/contrib/bzip2/bzip2.c index 6de9d1d..e6e8369 100644 --- a/contrib/bzip2/bzip2.c +++ b/contrib/bzip2/bzip2.c @@ -1890,7 +1890,9 @@ IntNative main ( IntNative argc, Char *argv[] ) case '8': blockSize100k = 8; break; case '9': blockSize100k = 9; break; case 'V': - case 'L': license(); break; + case 'L': license(); + exit ( 0 ); + break; case 'v': verbosity++; break; case 'h': usage ( progName ); exit ( 0 ); @@ -1916,8 +1918,8 @@ IntNative main ( IntNative argc, Char *argv[] ) if (ISFLAG("--keep")) keepInputFiles = True; else if (ISFLAG("--small")) smallMode = True; else if (ISFLAG("--quiet")) noisy = False; else - if (ISFLAG("--version")) license(); else - if (ISFLAG("--license")) license(); else + if (ISFLAG("--version")) { license(); exit ( 0 ); } else + if (ISFLAG("--license")) { license(); exit ( 0 ); } else if (ISFLAG("--exponential")) workFactor = 1; else if (ISFLAG("--repetitive-best")) redundant(aa->name); else if (ISFLAG("--repetitive-fast")) redundant(aa->name); else diff --git a/contrib/ipfilter/tools/ipf.c b/contrib/ipfilter/tools/ipf.c index 901728b..1660631 100644 --- a/contrib/ipfilter/tools/ipf.c +++ b/contrib/ipfilter/tools/ipf.c @@ -408,14 +408,16 @@ static void flushfilter(arg, filter) } closedevice(); return; - } - - if (strchr(arg, 'i') || strchr(arg, 'I')) + } else if (strchr(arg, 'i') || strchr(arg, 'I')) fl = FR_INQUE; - if (strchr(arg, 'o') || strchr(arg, 'O')) + else if (strchr(arg, 'o') || strchr(arg, 'O')) fl = FR_OUTQUE; - if (strchr(arg, 'a') || strchr(arg, 'A')) + else if (strchr(arg, 'a') || strchr(arg, 'A')) fl = FR_OUTQUE|FR_INQUE; + else { + fprintf(stderr, "Incorrect flush argument: %s\n", arg); + usage(); + } if (opts & OPT_INACTIVE) fl |= FR_INACTIVE; rem = fl; diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/check_bound.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/check_bound.c deleted file mode 100644 index 2ea7c31..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/check_bound.c +++ /dev/null @@ -1,231 +0,0 @@ -/* $NetBSD: check_bound.c,v 1.1 2010/07/26 15:53:00 pooka Exp $ */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. - */ - -/* #ident "@(#)check_bound.c 1.15 93/07/05 SMI" */ - -#if 0 -#ifndef lint -static char sccsid[] = "@(#)check_bound.c 1.11 89/04/21 Copyr 1989 Sun Micro"; -#endif -#endif - -/* - * check_bound.c - * Checks to see whether the program is still bound to the - * claimed address and returns the univeral merged address - * - */ - -#include <sys/types.h> -#include <sys/socket.h> -#include <rpc/rpc.h> -#include <stdio.h> -#include <netconfig.h> -#include <syslog.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> - -#include <rump/rump.h> -#include <rump/rump_syscalls.h> - -#include "rpcbind.h" - -struct fdlist { - int fd; - struct netconfig *nconf; - struct fdlist *next; - int check_binding; -}; - -static struct fdlist *fdhead; /* Link list of the check fd's */ -static struct fdlist *fdtail; -static const char emptystring[] = ""; - -static bool_t check_bound(struct fdlist *, const char *uaddr); - -/* - * Returns 1 if the given address is bound for the given addr & transport - * For all error cases, we assume that the address is bound - * Returns 0 for success. - */ -static bool_t -check_bound(struct fdlist *fdl, const char *uaddr) -{ - int fd; - struct netbuf *na; - int ans; - - if (fdl->check_binding == FALSE) - return (TRUE); - - na = uaddr2taddr(fdl->nconf, uaddr); - if (!na) - return (TRUE); /* punt, should never happen */ - - fd = __rpc_nconf2fd(fdl->nconf); - if (fd < 0) { - free(na); - return (TRUE); - } - - ans = bind(fd, (struct sockaddr *)na->buf, na->len); - - rump_sys_close(fd); - free(na); - - return (ans == 0 ? FALSE : TRUE); -} - -int -add_bndlist(struct netconfig *nconf, struct netbuf *baddr) -{ - struct fdlist *fdl; - struct netconfig *newnconf; - - newnconf = getnetconfigent(nconf->nc_netid); - if (newnconf == NULL) - return (-1); - fdl = (struct fdlist *)malloc((u_int)sizeof (struct fdlist)); - if (fdl == NULL) { - freenetconfigent(newnconf); - syslog(LOG_ERR, "no memory!"); - return (-1); - } - fdl->nconf = newnconf; - fdl->next = NULL; - if (fdhead == NULL) { - fdhead = fdl; - fdtail = fdl; - } else { - fdtail->next = fdl; - fdtail = fdl; - } - /* XXX no bound checking for now */ - fdl->check_binding = FALSE; - - return 0; -} - -bool_t -is_bound(const char *netid, const char *uaddr) -{ - struct fdlist *fdl; - - for (fdl = fdhead; fdl; fdl = fdl->next) - if (strcmp(fdl->nconf->nc_netid, netid) == 0) - break; - if (fdl == NULL) - return (TRUE); - return (check_bound(fdl, uaddr)); -} - -/* - * Returns NULL if there was some system error. - * Returns "" if the address was not bound, i.e the server crashed. - * Returns the merged address otherwise. - */ -char * -mergeaddr(SVCXPRT *xprt, char *netid, char *uaddr, char *saddr) -{ - struct fdlist *fdl; - char *c_uaddr, *s_uaddr, *m_uaddr, *allocated_uaddr = NULL; - - for (fdl = fdhead; fdl; fdl = fdl->next) - if (strcmp(fdl->nconf->nc_netid, netid) == 0) - break; - if (fdl == NULL) - return (NULL); - if (check_bound(fdl, uaddr) == FALSE) - /* that server died */ - return strdup(emptystring); - /* - * If saddr is not NULL, the remote client may have included the - * address by which it contacted us. Use that for the "client" uaddr, - * otherwise use the info from the SVCXPRT. - */ - if (saddr != NULL) { - c_uaddr = saddr; - } else { - c_uaddr = taddr2uaddr(fdl->nconf, svc_getrpccaller(xprt)); - if (c_uaddr == NULL) { - syslog(LOG_ERR, "taddr2uaddr failed for %s", - fdl->nconf->nc_netid); - return (NULL); - } - allocated_uaddr = c_uaddr; - } - -#ifdef RPCBIND_DEBUG - if (debugging) { - if (saddr == NULL) { - fprintf(stderr, "mergeaddr: client uaddr = %s\n", - c_uaddr); - } else { - fprintf(stderr, "mergeaddr: contact uaddr = %s\n", - c_uaddr); - } - } -#endif - s_uaddr = uaddr; - /* - * This is all we should need for IP 4 and 6 - */ - m_uaddr = addrmerge(svc_getrpccaller(xprt), s_uaddr, c_uaddr, netid); -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "mergeaddr: uaddr = %s, merged uaddr = %s\n", - uaddr, m_uaddr); -#endif - if (allocated_uaddr != NULL) - free(allocated_uaddr); - return (m_uaddr); -} - -/* - * Returns a netconf structure from its internal list. This - * structure should not be freed. - */ -struct netconfig * -rpcbind_get_conf(const char *netid) -{ - struct fdlist *fdl; - - for (fdl = fdhead; fdl; fdl = fdl->next) - if (strcmp(fdl->nconf->nc_netid, netid) == 0) - break; - if (fdl == NULL) - return (NULL); - return (fdl->nconf); -} diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/pmap_svc.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/pmap_svc.c deleted file mode 100644 index 3f9eb47..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/pmap_svc.c +++ /dev/null @@ -1,366 +0,0 @@ -/* $NetBSD: pmap_svc.c,v 1.2 2013/10/19 17:45:00 christos Exp $ */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1984 - 1991 by Sun Microsystems, Inc. - */ - -/* #ident "@(#)pmap_svc.c 1.14 93/07/05 SMI" */ - -#if 0 -#ifndef lint -static char sccsid[] = "@(#)pmap_svc.c 1.23 89/04/05 Copyr 1984 Sun Micro"; -#endif -#endif - -/* - * pmap_svc.c - * The server procedure for the version 2 portmapper. - * All the portmapper related interface from the portmap side. - */ - -#ifdef PORTMAP -#include <sys/types.h> -#include <sys/socket.h> -#include <stdio.h> -#include <rpc/rpc.h> -#include <rpc/pmap_prot.h> -#include <rpc/rpcb_prot.h> -#ifdef RPCBIND_DEBUG -#include <stdlib.h> -#endif -#include "rpcbind.h" - -static struct pmaplist *find_service_pmap(rpcprog_t, rpcvers_t, rpcprot_t); -static bool_t pmapproc_change(struct svc_req *, SVCXPRT *, u_long); -static bool_t pmapproc_getport(struct svc_req *, SVCXPRT *); -static bool_t pmapproc_dump(struct svc_req *, SVCXPRT *); - -/* - * Called for all the version 2 inquiries. - */ -void -pmap_service(struct svc_req *rqstp, SVCXPRT *xprt) -{ - rpcbs_procinfo(RPCBVERS_2_STAT, rqstp->rq_proc); - switch (rqstp->rq_proc) { - case PMAPPROC_NULL: - /* - * Null proc call - */ -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "PMAPPROC_NULL\n"); -#endif - check_access(xprt, rqstp->rq_proc, NULL, PMAPVERS); - if ((!svc_sendreply(xprt, (xdrproc_t) xdr_void, NULL)) && - debugging) { - if (doabort) { - rpcbind_abort(); - } - } - break; - - case PMAPPROC_SET: - /* - * Set a program, version to port mapping - */ - pmapproc_change(rqstp, xprt, rqstp->rq_proc); - break; - - case PMAPPROC_UNSET: - /* - * Remove a program, version to port mapping. - */ - pmapproc_change(rqstp, xprt, rqstp->rq_proc); - break; - - case PMAPPROC_GETPORT: - /* - * Lookup the mapping for a program, version and return its - * port number. - */ - pmapproc_getport(rqstp, xprt); - break; - - case PMAPPROC_DUMP: - /* - * Return the current set of mapped program, version - */ -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "PMAPPROC_DUMP\n"); -#endif - pmapproc_dump(rqstp, xprt); - break; - - case PMAPPROC_CALLIT: - /* - * Calls a procedure on the local machine. If the requested - * procedure is not registered this procedure does not return - * error information!! - * This procedure is only supported on rpc/udp and calls via - * rpc/udp. It passes null authentication parameters. - */ - rpcbproc_callit_com(rqstp, xprt, PMAPPROC_CALLIT, PMAPVERS); - break; - - default: - svcerr_noproc(xprt); - break; - } -} - -/* - * returns the item with the given program, version number. If that version - * number is not found, it returns the item with that program number, so that - * the port number is now returned to the caller. The caller when makes a - * call to this program, version number, the call will fail and it will - * return with PROGVERS_MISMATCH. The user can then determine the highest - * and the lowest version number for this program using clnt_geterr() and - * use those program version numbers. - */ -static struct pmaplist * -find_service_pmap(rpcprog_t prog, rpcvers_t vers, rpcprot_t prot) -{ - register struct pmaplist *hit = NULL; - register struct pmaplist *pml; - - for (pml = list_pml; pml != NULL; pml = pml->pml_next) { - if ((pml->pml_map.pm_prog != prog) || - (pml->pml_map.pm_prot != prot)) - continue; - hit = pml; - if (pml->pml_map.pm_vers == vers) - break; - } - return (hit); -} - -static bool_t -pmapproc_change(struct svc_req *rqstp, SVCXPRT *xprt, unsigned long op) -{ - struct pmap reg; - RPCB rpcbreg; - long ans; - struct sockcred *sc; - char uidbuf[32]; - -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "%s request for (%lu, %lu) : ", - op == PMAPPROC_SET ? "PMAP_SET" : "PMAP_UNSET", - reg.pm_prog, reg.pm_vers); -#endif - - if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)®)) { - svcerr_decode(xprt); - return (FALSE); - } - - if (!check_access(xprt, op, ®, PMAPVERS)) { - svcerr_weakauth(xprt); - return FALSE; - } - - (void)svc_getcaller(xprt); - sc = __svc_getcallercreds(xprt); - - /* - * Can't use getpwnam here. We might end up calling ourselves - * and looping. - */ - if (sc == NULL) - rpcbreg.r_owner = __UNCONST(rpcbind_unknown); - else if (sc->sc_uid == 0) - rpcbreg.r_owner = __UNCONST(rpcbind_superuser); - else { - /* r_owner will be strdup-ed later */ - snprintf(uidbuf, sizeof uidbuf, "%d", sc->sc_uid); - rpcbreg.r_owner = uidbuf; - } - - rpcbreg.r_prog = reg.pm_prog; - rpcbreg.r_vers = reg.pm_vers; - - if (op == PMAPPROC_SET) { - char buf[32]; - - snprintf(buf, sizeof(buf), "0.0.0.0.%d.%d", - (int)((reg.pm_port >> 8) & 0xff), - (int)(reg.pm_port & 0xff)); - rpcbreg.r_addr = buf; - if (reg.pm_prot == IPPROTO_UDP) { - rpcbreg.r_netid = __UNCONST(udptrans); - } else if (reg.pm_prot == IPPROTO_TCP) { - rpcbreg.r_netid = __UNCONST(tcptrans); - } else { - ans = FALSE; - goto done_change; - } - ans = map_set(&rpcbreg, rpcbreg.r_owner); - } else if (op == PMAPPROC_UNSET) { - bool_t ans1, ans2; - - rpcbreg.r_addr = NULL; - rpcbreg.r_netid = __UNCONST(tcptrans); - ans1 = map_unset(&rpcbreg, rpcbreg.r_owner); - rpcbreg.r_netid = __UNCONST(udptrans); - ans2 = map_unset(&rpcbreg, rpcbreg.r_owner); - ans = ans1 || ans2; - } else { - ans = FALSE; - } -done_change: - if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t) &ans)) && - debugging) { - fprintf(stderr, "portmap: svc_sendreply\n"); - if (doabort) { - rpcbind_abort(); - } - } -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "%s\n", ans == TRUE ? "succeeded" : "failed"); -#endif - if (op == PMAPPROC_SET) - rpcbs_set(RPCBVERS_2_STAT, ans); - else - rpcbs_unset(RPCBVERS_2_STAT, ans); - return (TRUE); -} - -/* ARGSUSED */ -static bool_t -pmapproc_getport(struct svc_req *rqstp, SVCXPRT *xprt) -{ - struct pmap reg; - long lport; - int port = 0; - struct pmaplist *fnd; -#ifdef RPCBIND_DEBUG - char *uaddr; -#endif - - if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)®)) { - svcerr_decode(xprt); - return (FALSE); - } - - if (!check_access(xprt, PMAPPROC_GETPORT, ®, PMAPVERS)) { - svcerr_weakauth(xprt); - return FALSE; - } - -#ifdef RPCBIND_DEBUG - if (debugging) { - uaddr = taddr2uaddr(rpcbind_get_conf(xprt->xp_netid), - svc_getrpccaller(xprt)); - fprintf(stderr, "PMAP_GETPORT req for (%lu, %lu, %s) from %s :", - reg.pm_prog, reg.pm_vers, - reg.pm_prot == IPPROTO_UDP ? "udp" : "tcp", uaddr); - free(uaddr); - } -#endif - fnd = find_service_pmap(reg.pm_prog, reg.pm_vers, reg.pm_prot); - if (fnd) { - char serveuaddr[32]; - int h1, h2, h3, h4, p1, p2; - const char *netid, *ua; - - if (reg.pm_prot == IPPROTO_UDP) { - ua = udp_uaddr; - netid = udptrans; - } else { - ua = tcp_uaddr; /* To get the len */ - netid = tcptrans; - } - if (ua == NULL) { - goto sendreply; - } - if (sscanf(ua, "%d.%d.%d.%d.%d.%d", &h1, &h2, &h3, - &h4, &p1, &p2) == 6) { - p1 = (fnd->pml_map.pm_port >> 8) & 0xff; - p2 = (fnd->pml_map.pm_port) & 0xff; - snprintf(serveuaddr, sizeof(serveuaddr), - "%d.%d.%d.%d.%d.%d", h1, h2, h3, h4, p1, p2); - if (is_bound(netid, serveuaddr)) { - port = fnd->pml_map.pm_port; - } else { /* this service is dead; delete it */ - delete_prog(reg.pm_prog); - } - } - } -sendreply: - lport = port; - if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t)&lport)) && - debugging) { - (void) fprintf(stderr, "portmap: svc_sendreply\n"); - if (doabort) { - rpcbind_abort(); - } - } -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "port = %d\n", port); -#endif - rpcbs_getaddr(RPCBVERS_2_STAT, reg.pm_prog, reg.pm_vers, - reg.pm_prot == IPPROTO_UDP ? udptrans : tcptrans, - port ? udptrans : ""); - - return (TRUE); -} - -/* ARGSUSED */ -static bool_t -pmapproc_dump(struct svc_req *rqstp, SVCXPRT *xprt) -{ - if (!svc_getargs(xprt, (xdrproc_t)xdr_void, NULL)) { - svcerr_decode(xprt); - return (FALSE); - } - - if (!check_access(xprt, PMAPPROC_DUMP, NULL, PMAPVERS)) { - svcerr_weakauth(xprt); - return FALSE; - } - - if ((!svc_sendreply(xprt, (xdrproc_t) xdr_pmaplist_ptr, - (caddr_t)&list_pml)) && debugging) { - if (debugging) - (void) fprintf(stderr, "portmap: svc_sendreply\n"); - if (doabort) { - rpcbind_abort(); - } - } - return (TRUE); -} - -#endif /* PORTMAP */ diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_stat.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_stat.c deleted file mode 100644 index 5bc5a0f..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_stat.c +++ /dev/null @@ -1,206 +0,0 @@ -/* $NetBSD: rpcb_stat.c,v 1.1 2010/07/26 15:53:00 pooka Exp $ */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* #pragma ident "@(#)rpcb_stat.c 1.7 94/04/25 SMI" */ - -/* - * rpcb_stat.c - * Allows for gathering of statistics - * - * Copyright (c) 1990 by Sun Microsystems, Inc. - */ - -#include <stdio.h> -#include <netconfig.h> -#include <rpc/rpc.h> -#include <rpc/rpcb_prot.h> -#include <sys/stat.h> -#ifdef PORTMAP -#include <rpc/pmap_prot.h> -#endif -#include <stdlib.h> -#include <string.h> -#include "rpcbind.h" - -static rpcb_stat_byvers inf; - -void -rpcbs_init(void) -{ - -} - -void -rpcbs_procinfo(rpcvers_t rtype, rpcproc_t proc) -{ - switch (rtype + 2) { -#ifdef PORTMAP - case PMAPVERS: /* version 2 */ - if (proc > rpcb_highproc_2) - return; - break; -#endif - case RPCBVERS: /* version 3 */ - if (proc > rpcb_highproc_3) - return; - break; - case RPCBVERS4: /* version 4 */ - if (proc > rpcb_highproc_4) - return; - break; - default: return; - } - inf[rtype].info[proc]++; - return; -} - -void -rpcbs_set(rpcvers_t rtype, bool_t success) -{ - if ((rtype >= RPCBVERS_STAT) || (success == FALSE)) - return; - inf[rtype].setinfo++; - return; -} - -void -rpcbs_unset(rpcvers_t rtype, bool_t success) -{ - if ((rtype >= RPCBVERS_STAT) || (success == FALSE)) - return; - inf[rtype].unsetinfo++; - return; -} - -void -rpcbs_getaddr(rpcvers_t rtype, rpcprog_t prog, rpcvers_t vers, - const char *netid, const char *uaddr) -{ - rpcbs_addrlist *al; - struct netconfig *nconf; - - if (rtype >= RPCBVERS_STAT) - return; - for (al = inf[rtype].addrinfo; al; al = al->next) { - - if(al->netid == NULL) - return; - if ((al->prog == prog) && (al->vers == vers) && - (strcmp(al->netid, netid) == 0)) { - if ((uaddr == NULL) || (uaddr[0] == 0)) - al->failure++; - else - al->success++; - return; - } - } - nconf = rpcbind_get_conf(netid); - if (nconf == NULL) { - return; - } - al = (rpcbs_addrlist *) malloc(sizeof (rpcbs_addrlist)); - if (al == NULL) { - return; - } - al->prog = prog; - al->vers = vers; - al->netid = nconf->nc_netid; - if ((uaddr == NULL) || (uaddr[0] == 0)) { - al->failure = 1; - al->success = 0; - } else { - al->failure = 0; - al->success = 1; - } - al->next = inf[rtype].addrinfo; - inf[rtype].addrinfo = al; -} - -void -rpcbs_rmtcall(rpcvers_t rtype, rpcproc_t rpcbproc, rpcprog_t prog, - rpcvers_t vers, rpcproc_t proc, char *netid, rpcblist_ptr rbl) -{ - rpcbs_rmtcalllist *rl; - struct netconfig *nconf; - - if (rtype >= RPCBVERS_STAT) - return; - for (rl = inf[rtype].rmtinfo; rl; rl = rl->next) { - - if(rl->netid == NULL) - return; - - if ((rl->prog == prog) && (rl->vers == vers) && - (rl->proc == proc) && - (strcmp(rl->netid, netid) == 0)) { - if ((rbl == NULL) || - (rbl->rpcb_map.r_vers != vers)) - rl->failure++; - else - rl->success++; - if (rpcbproc == RPCBPROC_INDIRECT) - rl->indirect++; - return; - } - } - nconf = rpcbind_get_conf(netid); - if (nconf == NULL) { - return; - } - rl = (rpcbs_rmtcalllist *) malloc(sizeof (rpcbs_rmtcalllist)); - if (rl == NULL) { - return; - } - rl->prog = prog; - rl->vers = vers; - rl->proc = proc; - rl->netid = nconf->nc_netid; - if ((rbl == NULL) || - (rbl->rpcb_map.r_vers != vers)) { - rl->failure = 1; - rl->success = 0; - } else { - rl->failure = 0; - rl->success = 1; - } - rl->indirect = 1; - rl->next = inf[rtype].rmtinfo; - inf[rtype].rmtinfo = rl; - return; -} - -/* - */ -void * -rpcbproc_getstat(void *arg, struct svc_req *req, SVCXPRT *xprt, - rpcvers_t versnum) -{ - return (void *)&inf; -} diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_svc.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_svc.c deleted file mode 100644 index 16c86f6..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_svc.c +++ /dev/null @@ -1,232 +0,0 @@ -/* $NetBSD: rpcb_svc.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. - */ - -/* #ident "@(#)rpcb_svc.c 1.16 93/07/05 SMI" */ - -/* - * rpcb_svc.c - * The server procedure for the version 3 rpcbind (TLI). - * - * It maintains a separate list of all the registered services with the - * version 3 of rpcbind. - */ -#include <sys/types.h> -#include <rpc/rpc.h> -#include <rpc/rpcb_prot.h> -#include <netconfig.h> -#include <syslog.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "rpcbind.h" - -static void *rpcbproc_getaddr_3_local(void *, struct svc_req *, SVCXPRT *, - rpcvers_t); -static void *rpcbproc_dump_3_local(void *, struct svc_req *, SVCXPRT *, - rpcvers_t); - -/* - * Called by svc_getreqset. There is a separate server handle for - * every transport that it waits on. - */ -void -rpcb_service_3(struct svc_req *rqstp, SVCXPRT *transp) -{ - union { - RPCB rpcbproc_set_3_arg; - RPCB rpcbproc_unset_3_arg; - RPCB rpcbproc_getaddr_3_local_arg; - struct rpcb_rmtcallargs rpcbproc_callit_3_arg; - char *rpcbproc_uaddr2taddr_3_arg; - struct netbuf rpcbproc_taddr2uaddr_3_arg; - } argument; - char *result; - xdrproc_t xdr_argument, xdr_result; - void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t); - - rpcbs_procinfo(RPCBVERS_3_STAT, rqstp->rq_proc); - - switch (rqstp->rq_proc) { - case NULLPROC: - /* - * Null proc call - */ -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_NULL\n"); -#endif - /* This call just logs, no actual checks */ - check_access(transp, rqstp->rq_proc, NULL, RPCBVERS); - (void) svc_sendreply(transp, (xdrproc_t)xdr_void, NULL); - return; - - case RPCBPROC_SET: - xdr_argument = (xdrproc_t )xdr_rpcb; - xdr_result = (xdrproc_t )xdr_bool; - local = rpcbproc_set_com; - break; - - case RPCBPROC_UNSET: - xdr_argument = (xdrproc_t)xdr_rpcb; - xdr_result = (xdrproc_t)xdr_bool; - local = rpcbproc_unset_com; - break; - - case RPCBPROC_GETADDR: - xdr_argument = (xdrproc_t)xdr_rpcb; - xdr_result = (xdrproc_t)xdr_wrapstring; - local = rpcbproc_getaddr_3_local; - break; - - case RPCBPROC_DUMP: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_DUMP\n"); -#endif - xdr_argument = (xdrproc_t)xdr_void; - xdr_result = (xdrproc_t)xdr_rpcblist_ptr; - local = rpcbproc_dump_3_local; - break; - - case RPCBPROC_CALLIT: - rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS); - return; - - case RPCBPROC_GETTIME: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_GETTIME\n"); -#endif - xdr_argument = (xdrproc_t)xdr_void; - xdr_result = (xdrproc_t)xdr_u_long; - local = rpcbproc_gettime_com; - break; - - case RPCBPROC_UADDR2TADDR: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_UADDR2TADDR\n"); -#endif - xdr_argument = (xdrproc_t)xdr_wrapstring; - xdr_result = (xdrproc_t)xdr_netbuf; - local = rpcbproc_uaddr2taddr_com; - break; - - case RPCBPROC_TADDR2UADDR: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_TADDR2UADDR\n"); -#endif - xdr_argument = (xdrproc_t)xdr_netbuf; - xdr_result = (xdrproc_t)xdr_wrapstring; - local = rpcbproc_taddr2uaddr_com; - break; - - default: - svcerr_noproc(transp); - return; - } - (void) memset((char *)&argument, 0, sizeof (argument)); - if (!svc_getargs(transp, (xdrproc_t) xdr_argument, - (char *) &argument)) { - svcerr_decode(transp); - if (debugging) - (void) fprintf(stderr, "rpcbind: could not decode\n"); - return; - } - if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS)) { - svcerr_weakauth(transp); - goto done; - } - result = (*local)(&argument, rqstp, transp, RPCBVERS); - if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result, - result)) { - svcerr_systemerr(transp); - if (debugging) { - (void) fprintf(stderr, "rpcbind: svc_sendreply\n"); - if (doabort) { - rpcbind_abort(); - } - } - } -done: - if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *) - &argument)) { - if (debugging) { - (void) fprintf(stderr, "unable to free arguments\n"); - if (doabort) { - rpcbind_abort(); - } - } - } -} - -/* - * Lookup the mapping for a program, version and return its - * address. Assuming that the caller wants the address of the - * server running on the transport on which the request came. - * - * We also try to resolve the universal address in terms of - * address of the caller. - */ -/* ARGSUSED */ -static void * -rpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t versnum) -{ - RPCB *regp = (RPCB *)arg; -#ifdef RPCBIND_DEBUG - if (debugging) { - char *uaddr; - - uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), - svc_getrpccaller(transp)); - fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ", - (unsigned long)regp->r_prog, (unsigned long)regp->r_vers, - regp->r_netid, uaddr); - free(uaddr); - } -#endif - return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS, - RPCB_ALLVERS)); -} - -/* ARGSUSED */ -static void * -rpcbproc_dump_3_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t versnum) -{ - return ((void *)&list_rbl); -} diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_svc_4.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_svc_4.c deleted file mode 100644 index c4e8edb..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_svc_4.c +++ /dev/null @@ -1,455 +0,0 @@ -/* $NetBSD: rpcb_svc_4.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. - */ - -/* #ident "@(#)rpcb_svc_4.c 1.8 93/07/05 SMI" */ - -/* - * rpcb_svc_4.c - * The server procedure for the version 4 rpcbind. - * - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <rpc/rpc.h> -#include <stdio.h> -#include <unistd.h> -#include <netconfig.h> -#include <syslog.h> -#include <string.h> -#include <stdlib.h> -#include "rpcbind.h" - -static void *rpcbproc_getaddr_4_local(void *, struct svc_req *, SVCXPRT *, - rpcvers_t); -static void *rpcbproc_getversaddr_4_local(void *, struct svc_req *, SVCXPRT *, - rpcvers_t); -static void *rpcbproc_getaddrlist_4_local(void *, struct svc_req *, SVCXPRT *, - rpcvers_t); -static void free_rpcb_entry_list(rpcb_entry_list_ptr *); -static void *rpcbproc_dump_4_local(void *, struct svc_req *, SVCXPRT *, - rpcvers_t); - -/* - * Called by svc_getreqset. There is a separate server handle for - * every transport that it waits on. - */ -void -rpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp) -{ - union { - rpcb rpcbproc_set_4_arg; - rpcb rpcbproc_unset_4_arg; - rpcb rpcbproc_getaddr_4_local_arg; - char *rpcbproc_uaddr2taddr_4_arg; - struct netbuf rpcbproc_taddr2uaddr_4_arg; - } argument; - char *result; - xdrproc_t xdr_argument, xdr_result; - void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t); - - rpcbs_procinfo(RPCBVERS_4_STAT, rqstp->rq_proc); - - switch (rqstp->rq_proc) { - case NULLPROC: - /* - * Null proc call - */ -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_NULL\n"); -#endif - check_access(transp, rqstp->rq_proc, NULL, RPCBVERS4); - (void) svc_sendreply(transp, (xdrproc_t) xdr_void, NULL); - return; - - case RPCBPROC_SET: - /* - * Check to see whether the message came from - * loopback transports (for security reasons) - */ - xdr_argument = (xdrproc_t)xdr_rpcb; - xdr_result = (xdrproc_t)xdr_bool; - local = rpcbproc_set_com; - break; - - case RPCBPROC_UNSET: - /* - * Check to see whether the message came from - * loopback transports (for security reasons) - */ - xdr_argument = (xdrproc_t)xdr_rpcb; - xdr_result = (xdrproc_t)xdr_bool; - local = rpcbproc_unset_com; - break; - - case RPCBPROC_GETADDR: - xdr_argument = (xdrproc_t)xdr_rpcb; - xdr_result = (xdrproc_t)xdr_wrapstring; - local = rpcbproc_getaddr_4_local; - break; - - case RPCBPROC_GETVERSADDR: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_GETVERSADDR\n"); -#endif - xdr_argument = (xdrproc_t)xdr_rpcb; - xdr_result = (xdrproc_t)xdr_wrapstring; - local = rpcbproc_getversaddr_4_local; - break; - - case RPCBPROC_DUMP: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_DUMP\n"); -#endif - xdr_argument = (xdrproc_t)xdr_void; - xdr_result = (xdrproc_t)xdr_rpcblist_ptr; - local = rpcbproc_dump_4_local; - break; - - case RPCBPROC_INDIRECT: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_INDIRECT\n"); -#endif - rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4); - return; - -/* case RPCBPROC_CALLIT: */ - case RPCBPROC_BCAST: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_BCAST\n"); -#endif - rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4); - return; - - case RPCBPROC_GETTIME: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_GETTIME\n"); -#endif - xdr_argument = (xdrproc_t)xdr_void; - xdr_result = (xdrproc_t)xdr_u_long; - local = rpcbproc_gettime_com; - break; - - case RPCBPROC_UADDR2TADDR: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_UADDR2TADDR\n"); -#endif - xdr_argument = (xdrproc_t)xdr_wrapstring; - xdr_result = (xdrproc_t)xdr_netbuf; - local = rpcbproc_uaddr2taddr_com; - break; - - case RPCBPROC_TADDR2UADDR: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_TADDR2UADDR\n"); -#endif - xdr_argument = (xdrproc_t)xdr_netbuf; - xdr_result = (xdrproc_t)xdr_wrapstring; - local = rpcbproc_taddr2uaddr_com; - break; - - case RPCBPROC_GETADDRLIST: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_GETADDRLIST\n"); -#endif - xdr_argument = (xdrproc_t)xdr_rpcb; - xdr_result = (xdrproc_t)xdr_rpcb_entry_list_ptr; - local = rpcbproc_getaddrlist_4_local; - break; - - case RPCBPROC_GETSTAT: -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCBPROC_GETSTAT\n"); -#endif - xdr_argument = (xdrproc_t)xdr_void; - xdr_result = (xdrproc_t)xdr_rpcb_stat_byvers; - local = rpcbproc_getstat; - break; - - default: - svcerr_noproc(transp); - return; - } - memset((char *)&argument, 0, sizeof (argument)); - if (!svc_getargs(transp, (xdrproc_t) xdr_argument, - (char *)&argument)) { - svcerr_decode(transp); - if (debugging) - (void) fprintf(stderr, "rpcbind: could not decode\n"); - return; - } - if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS4)) { - svcerr_weakauth(transp); - goto done; - } - result = (*local)(&argument, rqstp, transp, RPCBVERS4); - if (result != NULL && !svc_sendreply(transp, (xdrproc_t) xdr_result, - result)) { - svcerr_systemerr(transp); - if (debugging) { - (void) fprintf(stderr, "rpcbind: svc_sendreply\n"); - if (doabort) { - rpcbind_abort(); - } - } - } -done: - if (!svc_freeargs(transp, (xdrproc_t) xdr_argument, - (char *)&argument)) { - if (debugging) { - (void) fprintf(stderr, "unable to free arguments\n"); - if (doabort) { - rpcbind_abort(); - } - } - } - return; -} - -/* - * Lookup the mapping for a program, version and return its - * address. Assuming that the caller wants the address of the - * server running on the transport on which the request came. - * Even if a service with a different version number is available, - * it will return that address. The client should check with an - * clnt_call to verify whether the service is the one that is desired. - * We also try to resolve the universal address in terms of - * address of the caller. - */ -/* ARGSUSED */ -static void * -rpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t rpcbversnum) -{ - RPCB *regp = (RPCB *)arg; -#ifdef RPCBIND_DEBUG - if (debugging) { - char *uaddr; - - uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), - svc_getrpccaller(transp)); - fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ", - (unsigned long)regp->r_prog, (unsigned long)regp->r_vers, - regp->r_netid, uaddr); - free(uaddr); - } -#endif - return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4, - RPCB_ALLVERS)); -} - -/* - * Lookup the mapping for a program, version and return its - * address. Assuming that the caller wants the address of the - * server running on the transport on which the request came. - * - * We also try to resolve the universal address in terms of - * address of the caller. - */ -/* ARGSUSED */ -static void * -rpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t versnum) -{ - RPCB *regp = (RPCB *)arg; -#ifdef RPCBIND_DEBUG - if (debugging) { - char *uaddr; - - uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), - svc_getrpccaller(transp)); - fprintf(stderr, "RPCB_GETVERSADDR rqst for (%lu, %lu, %s)" - " from %s : ", - (unsigned long)regp->r_prog, (unsigned long)regp->r_vers, - regp->r_netid, uaddr); - free(uaddr); - } -#endif - return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4, - RPCB_ONEVERS)); -} - -/* - * Lookup the mapping for a program, version and return the - * addresses for all transports in the current transport family. - * We return a merged address. - */ -/* ARGSUSED */ -static void * -rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t versnum) -{ - RPCB *regp = (RPCB *)arg; - static rpcb_entry_list_ptr rlist; - register rpcblist_ptr rbl; - rpcb_entry_list_ptr rp, tail = NULL; - rpcprog_t prog; - rpcvers_t vers; - rpcb_entry *a; - struct netconfig *nconf; - struct netconfig *reg_nconf; - char *saddr, *maddr = NULL; - - free_rpcb_entry_list(&rlist); - prog = regp->r_prog; - vers = regp->r_vers; - reg_nconf = rpcbind_get_conf(transp->xp_netid); - if (reg_nconf == NULL) - return (NULL); - if (*(regp->r_addr) != '\0') { - saddr = regp->r_addr; - } else { - saddr = NULL; - } -#ifdef RPCBIND_DEBUG - if (debugging) { - fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n", - regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly); - } -#endif - for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) { - if ((rbl->rpcb_map.r_prog == prog) && - (rbl->rpcb_map.r_vers == vers)) { - nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid); - if (nconf == NULL) - goto fail; - if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly) - != 0) { - continue; /* not same proto family */ - } -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "\tmerge with: %s\n", rbl->rpcb_map.r_addr); -#endif - if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid, - rbl->rpcb_map.r_addr, saddr)) == NULL) { -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, " FAILED\n"); -#endif - continue; - } else if (!maddr[0]) { -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, " SUCCEEDED, but port died - maddr: nullstring\n"); -#endif - /* The server died. Unset this combination */ - delete_prog(regp->r_prog); - free(maddr); - continue; - } -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr); -#endif - /* - * Add it to rlist. - */ - rp = (rpcb_entry_list_ptr) - malloc((u_int)sizeof (rpcb_entry_list)); - if (rp == NULL) { - free(maddr); - goto fail; - } - a = &rp->rpcb_entry_map; - a->r_maddr = maddr; - a->r_nc_netid = nconf->nc_netid; - a->r_nc_semantics = nconf->nc_semantics; - a->r_nc_protofmly = nconf->nc_protofmly; - a->r_nc_proto = nconf->nc_proto; - rp->rpcb_entry_next = NULL; - if (rlist == NULL) { - rlist = rp; - tail = rp; - } else if (tail) { - tail->rpcb_entry_next = rp; - tail = rp; - } - rp = NULL; - } - } -#ifdef RPCBIND_DEBUG - if (debugging) { - for (rp = rlist; rp; rp = rp->rpcb_entry_next) { - fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr, - rp->rpcb_entry_map.r_nc_proto); - } - } -#endif - /* - * XXX: getaddrlist info is also being stuffed into getaddr. - * Perhaps wrong, but better than it not getting counted at all. - */ - rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr); - return (void *)&rlist; - -fail: free_rpcb_entry_list(&rlist); - return (NULL); -} - -/* - * Free only the allocated structure, rest is all a pointer to some - * other data somewhere else. - */ -static void -free_rpcb_entry_list(rpcb_entry_list_ptr *rlistp) -{ - register rpcb_entry_list_ptr rbl, tmp; - - for (rbl = *rlistp; rbl != NULL; ) { - tmp = rbl; - rbl = rbl->rpcb_entry_next; - free((char *)tmp->rpcb_entry_map.r_maddr); - free((char *)tmp); - } - *rlistp = NULL; -} - -/* ARGSUSED */ -static void * -rpcbproc_dump_4_local(void *arg, struct svc_req *req, SVCXPRT *xprt, - rpcvers_t versnum) -{ - return ((void *)&list_rbl); -} diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_svc_com.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_svc_com.c deleted file mode 100644 index d7ac0db..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcb_svc_com.c +++ /dev/null @@ -1,1460 +0,0 @@ -/* $NetBSD: rpcb_svc_com.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. - */ - -/* #ident "@(#)rpcb_svc_com.c 1.18 94/05/02 SMI" */ - -/* - * rpcb_svc_com.c - * The commom server procedure for the rpcbind. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <rpc/rpc.h> -#include <rpc/rpcb_prot.h> -#include <netconfig.h> -#include <errno.h> -#include <syslog.h> -#include <unistd.h> -#include <stdio.h> -#include <poll.h> -#ifdef PORTMAP -#include <netinet/in.h> -#include <rpc/pmap_prot.h> -#endif /* PORTMAP */ -#include <string.h> -#include <stdlib.h> - -#include <rump/rump.h> -#include <rump/rump_syscalls.h> - -#include "rpcbind.h" -#include "svc_dg.h" -#include "svc_fdset.h" - -#define RPC_BUF_MAX 65536 /* can be raised if required */ - -static char emptystring[] = ""; -static int rpcb_rmtcalls; - -struct rmtcallfd_list { - int fd; - SVCXPRT *xprt; - char *netid; - struct rmtcallfd_list *next; -}; - -#define NFORWARD 64 -#define MAXTIME_OFF 300 /* 5 minutes */ - -struct finfo { - int flag; -#define FINFO_ACTIVE 0x1 - u_int32_t caller_xid; - struct netbuf *caller_addr; - u_int32_t forward_xid; - int forward_fd; - char *uaddr; - rpcproc_t reply_type; - rpcvers_t versnum; - time_t time; -}; -static struct finfo FINFO[NFORWARD]; - - -static bool_t xdr_encap_parms(XDR *, struct encap_parms *); -static bool_t xdr_rmtcall_args(XDR *, struct r_rmtcall_args *); -static bool_t xdr_rmtcall_result(XDR *, struct r_rmtcall_args *); -static bool_t xdr_opaque_parms(XDR *, struct r_rmtcall_args *); -static int find_rmtcallfd_by_netid(char *); -static SVCXPRT *find_rmtcallxprt_by_fd(int); -static u_int32_t forward_register(u_int32_t, struct netbuf *, int, char *, - rpcproc_t, rpcvers_t); -static struct finfo *forward_find(u_int32_t); -static int free_slot_by_xid(u_int32_t); -static int free_slot_by_index(int); -static int netbufcmp(struct netbuf *, struct netbuf *); -static struct netbuf *netbufdup(struct netbuf *); -static void netbuffree(struct netbuf *); -static int check_rmtcalls(struct pollfd *, int); -static void xprt_set_caller(SVCXPRT *, struct finfo *); -static void send_svcsyserr(SVCXPRT *, struct finfo *); -static void handle_reply(int, SVCXPRT *); -static void find_versions(rpcprog_t, char *, rpcvers_t *, rpcvers_t *); -static rpcblist_ptr find_service(rpcprog_t, rpcvers_t, char *); -static char *getowner(SVCXPRT *, char *, size_t); -static int add_pmaplist(RPCB *); -static int del_pmaplist(RPCB *); - -/* - * Set a mapping of program, version, netid - */ -/* ARGSUSED */ -void * -rpcbproc_set_com(void *arg, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t rpcbversnum) -{ - RPCB *regp = (RPCB *)arg; - static bool_t ans; - char owner[64]; - -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCB_SET request for (%lu, %lu, %s, %s) : ", - (unsigned long)regp->r_prog, (unsigned long)regp->r_vers, - regp->r_netid, regp->r_addr); -#endif - ans = map_set(regp, getowner(transp, owner, sizeof owner)); -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "%s\n", ans == TRUE ? "succeeded" : "failed"); -#endif - /* XXX: should have used some defined constant here */ - rpcbs_set(rpcbversnum - 2, ans); - return (void *)&ans; -} - -bool_t -map_set(RPCB *regp, char *owner) -{ - RPCB reg, *a; - rpcblist_ptr rbl, fnd; - - reg = *regp; - /* - * check to see if already used - * find_service returns a hit even if - * the versions don't match, so check for it - */ - fnd = find_service(reg.r_prog, reg.r_vers, reg.r_netid); - if (fnd && (fnd->rpcb_map.r_vers == reg.r_vers)) { - if (!strcmp(fnd->rpcb_map.r_addr, reg.r_addr)) - /* - * if these match then it is already - * registered so just say "OK". - */ - return (TRUE); - else - return (FALSE); - } - /* - * add to the end of the list - */ - rbl = (rpcblist_ptr) malloc((u_int)sizeof (RPCBLIST)); - if (rbl == NULL) { - return (FALSE); - } - a = &(rbl->rpcb_map); - a->r_prog = reg.r_prog; - a->r_vers = reg.r_vers; - a->r_netid = strdup(reg.r_netid); - a->r_addr = strdup(reg.r_addr); - a->r_owner = strdup(owner); - if (!a->r_addr || !a->r_netid || !a->r_owner) { - if (a->r_netid) - free((void *) a->r_netid); - if (a->r_addr) - free((void *) a->r_addr); - if (a->r_owner) - free((void *) a->r_owner); - free((void *)rbl); - return (FALSE); - } - rbl->rpcb_next = NULL; - if (list_rbl == NULL) { - list_rbl = rbl; - } else { - for (fnd = list_rbl; fnd->rpcb_next; - fnd = fnd->rpcb_next) - ; - fnd->rpcb_next = rbl; - } -#ifdef PORTMAP - (void) add_pmaplist(regp); -#endif - return (TRUE); -} - -/* - * Unset a mapping of program, version, netid - */ -/* ARGSUSED */ -void * -rpcbproc_unset_com(void *arg, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t rpcbversnum) -{ - RPCB *regp = (RPCB *)arg; - static bool_t ans; - char owner[64]; - -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "RPCB_UNSET request for (%lu, %lu, %s) : ", - (unsigned long)regp->r_prog, (unsigned long)regp->r_vers, - regp->r_netid); -#endif - ans = map_unset(regp, getowner(transp, owner, sizeof owner)); -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "%s\n", ans == TRUE ? "succeeded" : "failed"); -#endif - /* XXX: should have used some defined constant here */ - rpcbs_unset(rpcbversnum - 2, ans); - return (void *)&ans; -} - -bool_t -map_unset(RPCB *regp, const char *owner) -{ - int ans = 0; - rpcblist_ptr rbl, prev, tmp; - - if (owner == NULL) - return (0); - - for (prev = NULL, rbl = list_rbl; rbl; /* cstyle */) { - if ((rbl->rpcb_map.r_prog != regp->r_prog) || - (rbl->rpcb_map.r_vers != regp->r_vers) || - (regp->r_netid[0] && strcasecmp(regp->r_netid, - rbl->rpcb_map.r_netid))) { - /* both rbl & prev move forwards */ - prev = rbl; - rbl = rbl->rpcb_next; - continue; - } - /* - * Check whether appropriate uid. Unset only - * if superuser or the owner itself. - */ - if (strcmp(owner, rpcbind_superuser) && - strcmp(rbl->rpcb_map.r_owner, owner)) - return (0); - /* found it; rbl moves forward, prev stays */ - ans = 1; - tmp = rbl; - rbl = rbl->rpcb_next; - if (prev == NULL) - list_rbl = rbl; - else - prev->rpcb_next = rbl; - free((void *) tmp->rpcb_map.r_addr); - free((void *) tmp->rpcb_map.r_netid); - free((void *) tmp->rpcb_map.r_owner); - free((void *) tmp); - } -#ifdef PORTMAP - if (ans) - (void) del_pmaplist(regp); -#endif - /* - * We return 1 either when the entry was not there or it - * was able to unset it. It can come to this point only if - * atleast one of the conditions is true. - */ - return (1); -} - -void -delete_prog(int prog) -{ - RPCB reg; - register rpcblist_ptr rbl; - - for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) { - if ((rbl->rpcb_map.r_prog != prog)) - continue; - if (is_bound(rbl->rpcb_map.r_netid, rbl->rpcb_map.r_addr)) - continue; - reg.r_prog = rbl->rpcb_map.r_prog; - reg.r_vers = rbl->rpcb_map.r_vers; - reg.r_netid = strdup(rbl->rpcb_map.r_netid); - (void)map_unset(®, rpcbind_superuser); - free(reg.r_netid); - } -} - -void * -rpcbproc_getaddr_com(RPCB *regp, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t rpcbversnum, rpcvers_t verstype) -{ - static char *uaddr; - char *saddr = NULL; - rpcblist_ptr fnd; - - if (uaddr && uaddr[0]) - free((void *) uaddr); - fnd = find_service(regp->r_prog, regp->r_vers, transp->xp_netid); - if (fnd && ((verstype == RPCB_ALLVERS) || - (regp->r_vers == fnd->rpcb_map.r_vers))) { - if (*(regp->r_addr) != '\0') { /* may contain a hint about */ - saddr = regp->r_addr; /* the interface that we */ - } /* should use */ - if (!(uaddr = mergeaddr(transp, transp->xp_netid, - fnd->rpcb_map.r_addr, saddr))) { - /* Try whatever we have */ - uaddr = strdup(fnd->rpcb_map.r_addr); - } else if (!uaddr[0]) { - /* - * The server died. Unset all versions of this prog. - */ - delete_prog(regp->r_prog); - uaddr = emptystring; - } - } else { - uaddr = emptystring; - } -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "getaddr: %s\n", uaddr); -#endif - /* XXX: should have used some defined constant here */ - rpcbs_getaddr(rpcbversnum - 2, regp->r_prog, regp->r_vers, - transp->xp_netid, uaddr); - return (void *)&uaddr; -} - -/* ARGSUSED */ -void * -rpcbproc_gettime_com(void *arg, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t rpcbversnum) -{ - static time_t curtime; - - (void) time(&curtime); - return (void *)&curtime; -} - -/* - * Convert uaddr to taddr. Should be used only by - * local servers/clients. (kernel level stuff only) - */ -/* ARGSUSED */ -void * -rpcbproc_uaddr2taddr_com(void *arg, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t rpcbversnum) -{ - char **uaddrp = (char **)arg; - struct netconfig *nconf; - static struct netbuf nbuf; - static struct netbuf *taddr; - - if (taddr) { - free((void *) taddr->buf); - free((void *) taddr); - } - if (((nconf = rpcbind_get_conf(transp->xp_netid)) == NULL) || - ((taddr = uaddr2taddr(nconf, *uaddrp)) == NULL)) { - (void) memset((char *)&nbuf, 0, sizeof (struct netbuf)); - return (void *)&nbuf; - } - return (void *)taddr; -} - -/* - * Convert taddr to uaddr. Should be used only by - * local servers/clients. (kernel level stuff only) - */ -/* ARGSUSED */ -void * -rpcbproc_taddr2uaddr_com(void *arg, struct svc_req *rqstp, SVCXPRT *transp, - rpcvers_t rpcbversnum) -{ - struct netbuf *taddr = (struct netbuf *)arg; - static char *uaddr; - struct netconfig *nconf; - - if (uaddr && !uaddr[0]) - free((void *) uaddr); - if (((nconf = rpcbind_get_conf(transp->xp_netid)) == NULL) || - ((uaddr = taddr2uaddr(nconf, taddr)) == NULL)) { - uaddr = emptystring; - } - return (void *)&uaddr; -} - - -static bool_t -xdr_encap_parms(XDR *xdrs, struct encap_parms *epp) -{ - return (xdr_bytes(xdrs, &(epp->args), (u_int *) &(epp->arglen), ~0)); -} - -/* - * XDR remote call arguments. It ignores the address part. - * written for XDR_DECODE direction only - */ -static bool_t -xdr_rmtcall_args(XDR *xdrs, struct r_rmtcall_args *cap) -{ - /* does not get the address or the arguments */ - if (xdr_u_int32_t(xdrs, &(cap->rmt_prog)) && - xdr_u_int32_t(xdrs, &(cap->rmt_vers)) && - xdr_u_int32_t(xdrs, &(cap->rmt_proc))) { - return (xdr_encap_parms(xdrs, &(cap->rmt_args))); - } - return (FALSE); -} - -/* - * XDR remote call results along with the address. Ignore - * program number, version number and proc number. - * Written for XDR_ENCODE direction only. - */ -static bool_t -xdr_rmtcall_result(XDR *xdrs, struct r_rmtcall_args *cap) -{ - bool_t result; - -#ifdef PORTMAP - if (cap->rmt_localvers == PMAPVERS) { - int h1, h2, h3, h4, p1, p2; - u_long port; - - /* interpret the universal address for TCP/IP */ - if (sscanf(cap->rmt_uaddr, "%d.%d.%d.%d.%d.%d", - &h1, &h2, &h3, &h4, &p1, &p2) != 6) - return (FALSE); - port = ((p1 & 0xff) << 8) + (p2 & 0xff); - result = xdr_u_long(xdrs, &port); - } else -#endif - if ((cap->rmt_localvers == RPCBVERS) || - (cap->rmt_localvers == RPCBVERS4)) { - result = xdr_wrapstring(xdrs, &(cap->rmt_uaddr)); - } else { - return (FALSE); - } - if (result == TRUE) - return (xdr_encap_parms(xdrs, &(cap->rmt_args))); - return (FALSE); -} - -/* - * only worries about the struct encap_parms part of struct r_rmtcall_args. - * The arglen must already be set!! - */ -static bool_t -xdr_opaque_parms(XDR *xdrs, struct r_rmtcall_args *cap) -{ - return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen)); -} - -static struct rmtcallfd_list *rmthead; -static struct rmtcallfd_list *rmttail; - -int -create_rmtcall_fd(struct netconfig *nconf) -{ - int fd; - struct rmtcallfd_list *rmt; - SVCXPRT *xprt; - - if ((fd = __rpc_nconf2fd(nconf)) == -1) { - if (debugging) - fprintf(stderr, - "create_rmtcall_fd: couldn't open \"%s\" (errno %d)\n", - nconf->nc_device, errno); - return (-1); - } - xprt = svc_tli_create(fd, 0, (struct t_bind *) 0, 0, 0); - if (xprt == NULL) { - if (debugging) - fprintf(stderr, - "create_rmtcall_fd: svc_tli_create failed\n"); - return (-1); - } - rmt = (struct rmtcallfd_list *)malloc((u_int) - sizeof (struct rmtcallfd_list)); - if (rmt == NULL) { - syslog(LOG_ERR, "create_rmtcall_fd: no memory!"); - return (-1); - } - rmt->xprt = xprt; - rmt->netid = strdup(nconf->nc_netid); - xprt->xp_netid = rmt->netid; - rmt->fd = fd; - rmt->next = NULL; - if (rmthead == NULL) { - rmthead = rmt; - rmttail = rmt; - } else { - rmttail->next = rmt; - rmttail = rmt; - } - /* XXX not threadsafe */ - if (fd > *get_fdsetmax()) - *get_fdsetmax() = fd; - FD_SET(fd, get_fdset()); - return (fd); -} - -static int -find_rmtcallfd_by_netid(char *netid) -{ - struct rmtcallfd_list *rmt; - - for (rmt = rmthead; rmt != NULL; rmt = rmt->next) { - if (strcmp(netid, rmt->netid) == 0) { - return (rmt->fd); - } - } - return (-1); -} - -static SVCXPRT * -find_rmtcallxprt_by_fd(int fd) -{ - struct rmtcallfd_list *rmt; - - for (rmt = rmthead; rmt != NULL; rmt = rmt->next) { - if (fd == rmt->fd) { - return (rmt->xprt); - } - } - return (NULL); -} - - -/* - * Call a remote procedure service. This procedure is very quiet when things - * go wrong. The proc is written to support broadcast rpc. In the broadcast - * case, a machine should shut-up instead of complain, lest the requestor be - * overrun with complaints at the expense of not hearing a valid reply. - * When receiving a request and verifying that the service exists, we - * - * receive the request - * - * open a new TLI endpoint on the same transport on which we received - * the original request - * - * remember the original request's XID (which requires knowing the format - * of the svc_dg_data structure) - * - * forward the request, with a new XID, to the requested service, - * remembering the XID used to send this request (for later use in - * reassociating the answer with the original request), the requestor's - * address, the file descriptor on which the forwarded request is - * made and the service's address. - * - * mark the file descriptor on which we anticipate receiving a reply from - * the service and one to select for in our private svc_run procedure - * - * At some time in the future, a reply will be received from the service to - * which we forwarded the request. At that time, we detect that the socket - * used was for forwarding (by looking through the finfo structures to see - * whether the fd corresponds to one of those) and call handle_reply() to - * - * receive the reply - * - * bundle the reply, along with the service's universal address - * - * create a SVCXPRT structure and use a version of svc_sendreply - * that allows us to specify the reply XID and destination, send the reply - * to the original requestor. - */ - -void -rpcbproc_callit_com(struct svc_req *rqstp, SVCXPRT *transp, - rpcproc_t reply_type, rpcvers_t versnum) -{ - register rpcblist_ptr rbl; - struct netconfig *nconf; - struct netbuf *caller; - struct r_rmtcall_args a; - char *buf_alloc = NULL, *outbufp; - char *outbuf_alloc = NULL; - char buf[RPC_BUF_MAX], outbuf[RPC_BUF_MAX]; - struct netbuf *na = NULL; - struct rpc_msg call_msg; - int outlen; - u_int sendsz; - XDR outxdr; - AUTH *auth; - int fd = -1; - char *uaddr, *m_uaddr, *local_uaddr = NULL; - u_int32_t *xidp; - struct __rpc_sockinfo si; - struct sockaddr *localsa; - struct netbuf tbuf; - - if (!__rpc_fd2sockinfo(transp->xp_fd, &si)) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - return; - } - if (si.si_socktype != SOCK_DGRAM) - return; /* Only datagram type accepted */ - sendsz = __rpc_get_t_size(si.si_af, si.si_proto, UDPMSGSIZE); - if (sendsz == 0) { /* data transfer not supported */ - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - return; - } - /* - * Should be multiple of 4 for XDR. - */ - sendsz = ((sendsz + 3) / 4) * 4; - if (sendsz > RPC_BUF_MAX) { -#ifdef notyet - buf_alloc = alloca(sendsz); /* not in IDR2? */ -#else - buf_alloc = malloc(sendsz); -#endif /* notyet */ - if (buf_alloc == NULL) { - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: No Memory!\n"); - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - return; - } - a.rmt_args.args = buf_alloc; - } else { - a.rmt_args.args = buf; - } - - call_msg.rm_xid = 0; /* For error checking purposes */ - if (!svc_getargs(transp, (xdrproc_t) xdr_rmtcall_args, (char *) &a)) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_decode(transp); - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: svc_getargs failed\n"); - goto error; - } - - if (!check_callit(transp, &a, versnum)) { - svcerr_weakauth(transp); - goto error; - } - - caller = svc_getrpccaller(transp); -#ifdef RPCBIND_DEBUG - if (debugging) { - uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid), caller); - fprintf(stderr, "%s %s req for (%lu, %lu, %lu, %s) from %s : ", - versnum == PMAPVERS ? "pmap_rmtcall" : - versnum == RPCBVERS ? "rpcb_rmtcall" : - versnum == RPCBVERS4 ? "rpcb_indirect" : - rpcbind_unknown, - reply_type == RPCBPROC_INDIRECT ? "indirect" : "callit", - (unsigned long)a.rmt_prog, (unsigned long)a.rmt_vers, - (unsigned long)a.rmt_proc, transp->xp_netid, - uaddr ? uaddr : rpcbind_unknown); - if (uaddr) - free((void *) uaddr); - } -#endif - - rbl = find_service(a.rmt_prog, a.rmt_vers, transp->xp_netid); - - rpcbs_rmtcall(versnum - 2, reply_type, a.rmt_prog, a.rmt_vers, - a.rmt_proc, transp->xp_netid, rbl); - - if (rbl == NULL) { -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "not found\n"); -#endif - if (reply_type == RPCBPROC_INDIRECT) - svcerr_noprog(transp); - goto error; - } - if (rbl->rpcb_map.r_vers != a.rmt_vers) { - if (reply_type == RPCBPROC_INDIRECT) { - rpcvers_t vers_low, vers_high; - - find_versions(a.rmt_prog, transp->xp_netid, - &vers_low, &vers_high); - svcerr_progvers(transp, vers_low, vers_high); - } - goto error; - } - -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "found at uaddr %s\n", rbl->rpcb_map.r_addr); -#endif - /* - * Check whether this entry is valid and a server is present - * Mergeaddr() returns NULL if no such entry is present, and - * returns "" if the entry was present but the server is not - * present (i.e., it crashed). - */ - if (reply_type == RPCBPROC_INDIRECT) { - uaddr = mergeaddr(transp, transp->xp_netid, - rbl->rpcb_map.r_addr, NULL); - if (uaddr == NULL || uaddr[0] == '\0') { - svcerr_noprog(transp); - if (uaddr != NULL) { - free((void *) uaddr); - } - goto error; - } - if (uaddr != NULL) { - free((void *) uaddr); - } - } - nconf = rpcbind_get_conf(transp->xp_netid); - if (nconf == NULL) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: rpcbind_get_conf failed\n"); - goto error; - } - localsa = local_sa(((struct sockaddr *)caller->buf)->sa_family); - if (localsa == NULL) { - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: no local address\n"); - goto error; - } - tbuf.len = tbuf.maxlen = localsa->sa_len; - tbuf.buf = localsa; - local_uaddr = - addrmerge(&tbuf, rbl->rpcb_map.r_addr, NULL, nconf->nc_netid); - m_uaddr = addrmerge(caller, rbl->rpcb_map.r_addr, NULL, - nconf->nc_netid); -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "merged uaddr %s\n", m_uaddr); -#endif - if ((fd = find_rmtcallfd_by_netid(nconf->nc_netid)) == -1) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - free((void *) m_uaddr); - goto error; - } - xidp = __rpcb_get_dg_xidp(transp); - call_msg.rm_xid = forward_register(*xidp, - caller, fd, m_uaddr, reply_type, versnum); - if (call_msg.rm_xid == 0) { - /* - * A duplicate request for the slow server. Let's not - * beat on it any more. - */ - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: duplicate request\n"); - free((void *) m_uaddr); - goto error; - } else if (call_msg.rm_xid == -1) { - /* forward_register failed. Perhaps no memory. */ - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: forward_register failed\n"); - free((void *) m_uaddr); - goto error; - } - -#ifdef DEBUG_RMTCALL - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: original XID %x, new XID %x\n", - *xidp, call_msg.rm_xid); -#endif - call_msg.rm_direction = CALL; - call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - call_msg.rm_call.cb_prog = a.rmt_prog; - call_msg.rm_call.cb_vers = a.rmt_vers; - if (sendsz > RPC_BUF_MAX) { -#ifdef notyet - outbuf_alloc = alloca(sendsz); /* not in IDR2? */ -#else - outbuf_alloc = malloc(sendsz); -#endif /* notyet */ - if (outbuf_alloc == NULL) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: No memory!\n"); - goto error; - } - xdrmem_create(&outxdr, outbuf_alloc, sendsz, XDR_ENCODE); - } else { - xdrmem_create(&outxdr, outbuf, sendsz, XDR_ENCODE); - } - if (!xdr_callhdr(&outxdr, &call_msg)) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: xdr_callhdr failed\n"); - goto error; - } - if (!xdr_u_int32_t(&outxdr, &(a.rmt_proc))) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: xdr_u_long failed\n"); - goto error; - } - - if (rqstp->rq_cred.oa_flavor == AUTH_NULL) { - auth = authnone_create(); - } else if (rqstp->rq_cred.oa_flavor == AUTH_SYS) { - struct authunix_parms *au; - - au = (struct authunix_parms *)rqstp->rq_clntcred; - auth = authunix_create(au->aup_machname, - au->aup_uid, au->aup_gid, - au->aup_len, au->aup_gids); - if (auth == NULL) /* fall back */ - auth = authnone_create(); - } else { - /* we do not support any other authentication scheme */ - if (debugging) - fprintf(stderr, -"rpcbproc_callit_com: oa_flavor != AUTH_NONE and oa_flavor != AUTH_SYS\n"); - if (reply_type == RPCBPROC_INDIRECT) - svcerr_weakauth(transp); /* XXX too strong.. */ - goto error; - } - if (auth == NULL) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: authwhatever_create returned NULL\n"); - goto error; - } - if (!AUTH_MARSHALL(auth, &outxdr)) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - AUTH_DESTROY(auth); - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: AUTH_MARSHALL failed\n"); - goto error; - } - AUTH_DESTROY(auth); - if (!xdr_opaque_parms(&outxdr, &a)) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: xdr_opaque_parms failed\n"); - goto error; - } - outlen = (int) XDR_GETPOS(&outxdr); - if (outbuf_alloc) - outbufp = outbuf_alloc; - else - outbufp = outbuf; - - na = uaddr2taddr(nconf, local_uaddr); - if (!na) { - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - goto error; - } - - if (sendto(fd, outbufp, outlen, 0, (struct sockaddr *)na->buf, na->len) - != outlen) { - if (debugging) - fprintf(stderr, - "rpcbproc_callit_com: sendto failed: errno %d\n", errno); - if (reply_type == RPCBPROC_INDIRECT) - svcerr_systemerr(transp); - goto error; - } - goto out; - -error: - if (call_msg.rm_xid != 0) - (void) free_slot_by_xid(call_msg.rm_xid); -out: - if (local_uaddr) - free(local_uaddr); - if (buf_alloc) - free((void *) buf_alloc); - if (outbuf_alloc) - free((void *) outbuf_alloc); - if (na) { - free(na->buf); - free(na); - } -} - -/* - * Makes an entry into the FIFO for the given request. - * If duplicate request, returns a 0, else returns the xid of its call. - */ -static u_int32_t -forward_register(u_int32_t caller_xid, struct netbuf *caller_addr, - int forward_fd, char *uaddr, rpcproc_t reply_type, - rpcvers_t versnum) -{ - int i; - int j = 0; - time_t min_time, time_now; - static u_int32_t lastxid; - int entry = -1; - - min_time = FINFO[0].time; - time_now = time((time_t *)0); - /* initialization */ - if (lastxid == 0) - lastxid = time_now * NFORWARD; - - /* - * Check if it is an duplicate entry. Then, - * try to find an empty slot. If not available, then - * use the slot with the earliest time. - */ - for (i = 0; i < NFORWARD; i++) { - if (FINFO[i].flag & FINFO_ACTIVE) { - if ((FINFO[i].caller_xid == caller_xid) && - (FINFO[i].reply_type == reply_type) && - (FINFO[i].versnum == versnum) && - (!netbufcmp(FINFO[i].caller_addr, - caller_addr))) { - FINFO[i].time = time((time_t *)0); - return (0); /* Duplicate entry */ - } else { - /* Should we wait any longer */ - if ((time_now - FINFO[i].time) > MAXTIME_OFF) - (void) free_slot_by_index(i); - } - } - if (entry == -1) { - if ((FINFO[i].flag & FINFO_ACTIVE) == 0) { - entry = i; - } else if (FINFO[i].time < min_time) { - j = i; - min_time = FINFO[i].time; - } - } - } - if (entry != -1) { - /* use this empty slot */ - j = entry; - } else { - (void) free_slot_by_index(j); - } - if ((FINFO[j].caller_addr = netbufdup(caller_addr)) == NULL) { - return (-1); - } - rpcb_rmtcalls++; /* no of pending calls */ - FINFO[j].flag = FINFO_ACTIVE; - FINFO[j].reply_type = reply_type; - FINFO[j].versnum = versnum; - FINFO[j].time = time_now; - FINFO[j].caller_xid = caller_xid; - FINFO[j].forward_fd = forward_fd; - /* - * Though uaddr is not allocated here, it will still be freed - * from free_slot_*(). - */ - FINFO[j].uaddr = uaddr; - lastxid = lastxid + NFORWARD; - FINFO[j].forward_xid = lastxid + j; /* encode slot */ - return (FINFO[j].forward_xid); /* forward on this xid */ -} - -static struct finfo * -forward_find(u_int32_t reply_xid) -{ - int i; - - i = reply_xid % NFORWARD; - if (i < 0) - i += NFORWARD; - if ((FINFO[i].flag & FINFO_ACTIVE) && - (FINFO[i].forward_xid == reply_xid)) { - return (&FINFO[i]); - } - return (NULL); -} - -static int -free_slot_by_xid(u_int32_t xid) -{ - int entry; - - entry = xid % NFORWARD; - if (entry < 0) - entry += NFORWARD; - return (free_slot_by_index(entry)); -} - -static int -free_slot_by_index(int idx) -{ - struct finfo *fi; - - fi = &FINFO[idx]; - if (fi->flag & FINFO_ACTIVE) { - netbuffree(fi->caller_addr); - /* XXX may be too big, but can't access xprt array here */ - if (fi->forward_fd >= *get_fdsetmax()) - (*get_fdsetmax())--; - free((void *) fi->uaddr); - fi->flag &= ~FINFO_ACTIVE; - rpcb_rmtcalls--; - return (1); - } - return (0); -} - -static int -netbufcmp(struct netbuf *n1, struct netbuf *n2) -{ - return ((n1->len != n2->len) || memcmp(n1->buf, n2->buf, n1->len)); -} - -static struct netbuf * -netbufdup(struct netbuf *ap) -{ - struct netbuf *np; - - np = (struct netbuf *) malloc(sizeof (struct netbuf) + ap->len); - if (np) { - np->maxlen = np->len = ap->len; - np->buf = ((char *) np) + sizeof (struct netbuf); - (void) memcpy(np->buf, ap->buf, ap->len); - } - return (np); -} - -static void -netbuffree(struct netbuf *ap) -{ - free((void *) ap); -} - - -#define MASKVAL (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND) -extern bool_t __svc_clean_idle(fd_set *, int, bool_t); - -void -my_svc_run() -{ - size_t nfds; - struct pollfd pollfds[FD_SETSIZE]; - int poll_ret, check_ret; - int n; -#ifdef SVC_RUN_DEBUG - int i; -#endif - register struct pollfd *p; - fd_set cleanfds; - - for (;;) { - p = pollfds; - for (n = 0; n <= *get_fdsetmax(); n++) { - if (FD_ISSET(n, get_fdset())) { - p->fd = n; - p->events = MASKVAL; - p++; - } - } - nfds = p - pollfds; - poll_ret = 0; -#ifdef SVC_RUN_DEBUG - if (debugging) { - fprintf(stderr, "polling for read on fd < "); - for (i = 0, p = pollfds; i < nfds; i++, p++) - if (p->events) - fprintf(stderr, "%d ", p->fd); - fprintf(stderr, ">\n"); - } -#endif - poll_ret = rump_sys_poll(pollfds, nfds, 30 * 1000); - //printf("rpcbind poll got %d\n", poll_ret); - switch (poll_ret) { - case -1: - /* - * We ignore all errors, continuing with the assumption - * that it was set by the signal handlers (or any - * other outside event) and not caused by poll(). - */ - case 0: - cleanfds = *get_fdset(); - __svc_clean_idle(&cleanfds, 30, FALSE); - continue; - default: -#ifdef SVC_RUN_DEBUG - if (debugging) { - fprintf(stderr, "poll returned read fds < "); - for (i = 0, p = pollfds; i < nfds; i++, p++) - if (p->revents) - fprintf(stderr, "%d (0x%x) ", p->fd, p->revents); - fprintf(stderr, ">\n"); - } -#endif - /* - * If we found as many replies on callback fds - * as the number of descriptors selectable which - * poll() returned, there can be no more so we - * don't call svc_getreq_poll. Otherwise, there - * must be another so we must call svc_getreq_poll. - */ - if ((check_ret = check_rmtcalls(pollfds, nfds)) == - poll_ret) - continue; - svc_getreq_poll(pollfds, poll_ret-check_ret); - } -#ifdef SVC_RUN_DEBUG - if (debugging) { - fprintf(stderr, "svc_maxfd now %u\n", *get_fdsetmax()); - } -#endif - } -} - -static int -check_rmtcalls(struct pollfd *pfds, int nfds) -{ - int j, ncallbacks_found = 0, rmtcalls_pending; - SVCXPRT *xprt; - - if (rpcb_rmtcalls == 0) - return (0); - - rmtcalls_pending = rpcb_rmtcalls; - for (j = 0; j < nfds; j++) { - if ((xprt = find_rmtcallxprt_by_fd(pfds[j].fd)) != NULL) { - if (pfds[j].revents) { - ncallbacks_found++; -#ifdef DEBUG_RMTCALL - if (debugging) - fprintf(stderr, -"my_svc_run: polled on forwarding fd %d, netid %s - calling handle_reply\n", - pfds[j].fd, xprt->xp_netid); -#endif - handle_reply(pfds[j].fd, xprt); - pfds[j].revents = 0; - if (ncallbacks_found >= rmtcalls_pending) { - break; - } - } - } - } - return (ncallbacks_found); -} - -static void -xprt_set_caller(SVCXPRT *xprt, struct finfo *fi) -{ - u_int32_t *xidp; - - *(svc_getrpccaller(xprt)) = *(fi->caller_addr); - xidp = __rpcb_get_dg_xidp(xprt); - *xidp = fi->caller_xid; -} - -/* - * Call svcerr_systemerr() only if RPCBVERS4 - */ -static void -send_svcsyserr(SVCXPRT *xprt, struct finfo *fi) -{ - if (fi->reply_type == RPCBPROC_INDIRECT) { - xprt_set_caller(xprt, fi); - svcerr_systemerr(xprt); - } - return; -} - -static void -handle_reply(int fd, SVCXPRT *xprt) -{ - XDR reply_xdrs; - struct rpc_msg reply_msg; - struct rpc_err reply_error; - char *buffer; - struct finfo *fi; - int inlen, pos, len; - struct r_rmtcall_args a; - struct sockaddr_storage ss; - socklen_t fromlen; -#ifdef SVC_RUN_DEBUG - char *uaddr; -#endif - - buffer = malloc(RPC_BUF_MAX); - if (buffer == NULL) - goto done; - - do { - fromlen = sizeof ss; - inlen = recvfrom(fd, buffer, RPC_BUF_MAX, 0, - (struct sockaddr *)&ss, &fromlen); - } while (inlen < 0 && errno == EINTR); - if (inlen < 0) { - if (debugging) - fprintf(stderr, - "handle_reply: recvfrom returned %d, errno %d\n", inlen, errno); - goto done; - } - - reply_msg.acpted_rply.ar_verf = _null_auth; - reply_msg.acpted_rply.ar_results.where = 0; - reply_msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; - - xdrmem_create(&reply_xdrs, buffer, (u_int)inlen, XDR_DECODE); - if (!xdr_replymsg(&reply_xdrs, &reply_msg)) { - if (debugging) - (void) fprintf(stderr, - "handle_reply: xdr_replymsg failed\n"); - goto done; - } - fi = forward_find(reply_msg.rm_xid); -#ifdef SVC_RUN_DEBUG - if (debugging) { - fprintf(stderr, "handle_reply: reply xid: %d fi addr: %p\n", - reply_msg.rm_xid, fi); - } -#endif - if (fi == NULL) { - goto done; - } - _seterr_reply(&reply_msg, &reply_error); - if (reply_error.re_status != RPC_SUCCESS) { - if (debugging) - (void) fprintf(stderr, "handle_reply: %s\n", - clnt_sperrno(reply_error.re_status)); - send_svcsyserr(xprt, fi); - goto done; - } - pos = XDR_GETPOS(&reply_xdrs); - len = inlen - pos; - a.rmt_args.args = &buffer[pos]; - a.rmt_args.arglen = len; - a.rmt_uaddr = fi->uaddr; - a.rmt_localvers = fi->versnum; - - xprt_set_caller(xprt, fi); -#ifdef SVC_RUN_DEBUG - uaddr = taddr2uaddr(rpcbind_get_conf("udp"), - svc_getrpccaller(xprt)); - if (debugging) { - fprintf(stderr, "handle_reply: forwarding address %s to %s\n", - a.rmt_uaddr, uaddr ? uaddr : rpcbind_unknown); - } - if (uaddr) - free((void *) uaddr); -#endif - svc_sendreply(xprt, (xdrproc_t) xdr_rmtcall_result, (char *) &a); -done: - if (buffer) - free(buffer); - - if (reply_msg.rm_xid == 0) { -#ifdef SVC_RUN_DEBUG - if (debugging) { - fprintf(stderr, "handle_reply: NULL xid on exit!\n"); - } -#endif - } else - (void) free_slot_by_xid(reply_msg.rm_xid); - return; -} - -static void -find_versions(rpcprog_t prog, char *netid, rpcvers_t *lowvp, rpcvers_t *highvp) -{ - register rpcblist_ptr rbl; - int lowv = 0; - int highv = 0; - - for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) { - if ((rbl->rpcb_map.r_prog != prog) || - ((rbl->rpcb_map.r_netid != NULL) && - (strcasecmp(rbl->rpcb_map.r_netid, netid) != 0))) - continue; - if (lowv == 0) { - highv = rbl->rpcb_map.r_vers; - lowv = highv; - } else if (rbl->rpcb_map.r_vers < lowv) { - lowv = rbl->rpcb_map.r_vers; - } else if (rbl->rpcb_map.r_vers > highv) { - highv = rbl->rpcb_map.r_vers; - } - } - *lowvp = lowv; - *highvp = highv; - return; -} - -/* - * returns the item with the given program, version number and netid. - * If that version number is not found, it returns the item with that - * program number, so that address is now returned to the caller. The - * caller when makes a call to this program, version number, the call - * will fail and it will return with PROGVERS_MISMATCH. The user can - * then determine the highest and the lowest version number for this - * program using clnt_geterr() and use those program version numbers. - * - * Returns the RPCBLIST for the given prog, vers and netid - */ -static rpcblist_ptr -find_service(rpcprog_t prog, rpcvers_t vers, char *netid) -{ - register rpcblist_ptr hit = NULL; - register rpcblist_ptr rbl; - - for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) { - if ((rbl->rpcb_map.r_prog != prog) || - ((rbl->rpcb_map.r_netid != NULL) && - (strcasecmp(rbl->rpcb_map.r_netid, netid) != 0))) - continue; - hit = rbl; - if (rbl->rpcb_map.r_vers == vers) - break; - } - return (hit); -} - -/* - * Copies the name associated with the uid of the caller and returns - * a pointer to it. Similar to getwd(). - */ -static char * -getowner(SVCXPRT *transp, char *owner, size_t ownersize) -{ - struct sockcred *sc; - - sc = __svc_getcallercreds(transp); - if (sc == NULL) - strlcpy(owner, rpcbind_unknown, ownersize); - else if (sc->sc_uid == 0) - strlcpy(owner, rpcbind_superuser, ownersize); - else - snprintf(owner, ownersize, "%d", sc->sc_uid); - - return owner; -} - -#ifdef PORTMAP -/* - * Add this to the pmap list only if it is UDP or TCP. - */ -static int -add_pmaplist(RPCB *arg) -{ - struct pmap pmap; - struct pmaplist *pml; - int h1, h2, h3, h4, p1, p2; - - if (strcmp(arg->r_netid, udptrans) == 0) { - /* It is UDP! */ - pmap.pm_prot = IPPROTO_UDP; - } else if (strcmp(arg->r_netid, tcptrans) == 0) { - /* It is TCP */ - pmap.pm_prot = IPPROTO_TCP; - } else - /* Not a IP protocol */ - return (0); - - /* interpret the universal address for TCP/IP */ - if (sscanf(arg->r_addr, "%d.%d.%d.%d.%d.%d", - &h1, &h2, &h3, &h4, &p1, &p2) != 6) - return (0); - pmap.pm_port = ((p1 & 0xff) << 8) + (p2 & 0xff); - pmap.pm_prog = arg->r_prog; - pmap.pm_vers = arg->r_vers; - /* - * add to END of list - */ - pml = (struct pmaplist *) malloc((u_int)sizeof (struct pmaplist)); - if (pml == NULL) { - (void) syslog(LOG_ERR, "rpcbind: no memory!\n"); - return (1); - } - pml->pml_map = pmap; - pml->pml_next = NULL; - if (list_pml == NULL) { - list_pml = pml; - } else { - struct pmaplist *fnd; - - /* Attach to the end of the list */ - for (fnd = list_pml; fnd->pml_next; fnd = fnd->pml_next) - ; - fnd->pml_next = pml; - } - return (0); -} - -/* - * Delete this from the pmap list only if it is UDP or TCP. - */ -static int -del_pmaplist(RPCB *arg) -{ - struct pmaplist *pml; - struct pmaplist *prevpml, *fnd; - long prot; - - if (strcmp(arg->r_netid, udptrans) == 0) { - /* It is UDP! */ - prot = IPPROTO_UDP; - } else if (strcmp(arg->r_netid, tcptrans) == 0) { - /* It is TCP */ - prot = IPPROTO_TCP; - } else if (arg->r_netid[0] == 0) { - prot = 0; /* Remove all occurrences */ - } else { - /* Not a IP protocol */ - return (0); - } - for (prevpml = NULL, pml = list_pml; pml; /* cstyle */) { - if ((pml->pml_map.pm_prog != arg->r_prog) || - (pml->pml_map.pm_vers != arg->r_vers) || - (prot && (pml->pml_map.pm_prot != prot))) { - /* both pml & prevpml move forwards */ - prevpml = pml; - pml = pml->pml_next; - continue; - } - /* found it; pml moves forward, prevpml stays */ - fnd = pml; - pml = pml->pml_next; - if (prevpml == NULL) - list_pml = pml; - else - prevpml->pml_next = pml; - free((void *) fnd); - } - return (0); -} -#endif /* PORTMAP */ diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcbind.8 b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcbind.8 deleted file mode 100644 index c77f1d5..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcbind.8 +++ /dev/null @@ -1,127 +0,0 @@ -.\" $NetBSD: rpcbind.8,v 1.1 2010/07/26 15:53:00 pooka Exp $ -.\" @(#)rpcbind.1m 1.19 92/09/14 SMI; from SVr4 -.\" Copyright 1989 AT&T -.\" Copyright 1991 Sun Microsystems, Inc. -.Dd October 19, 2008 -.Dt RPCBIND 8 -.Sh NAME -.Nm rpcbind -.Nd universal addresses to RPC program number mapper -.Sh SYNOPSIS -.Nm -.Op Fl dilLs -.Sh DESCRIPTION -.Nm -is a server that converts -.Tn RPC -program numbers into -universal addresses. -It must be running on the host to be able to make -.Tn RPC -calls -on a server on that machine. -.Pp -When an -.Tn RPC -service is started, -it tells -.Nm -the address at which it is listening, -and the -.Tn RPC -program numbers it is prepared to serve. -When a client wishes to make an -.Tn RPC -call to a given program number, -it first contacts -.Nm -on the server machine to determine -the address where -.Tn RPC -requests should be sent. -.Pp -.Nm -should be started before any other RPC service. -Normally, standard -.Tn RPC -servers are started by port monitors, so -.Nm -must be started before port monitors are invoked. -.Pp -When -.Nm -is started, it checks that certain name-to-address -translation-calls function correctly. -If they fail, the network configuration databases may be corrupt. -Since -.Tn RPC -services cannot function correctly in this situation, -.Nm -reports the condition and terminates. -.Pp -.Nm -can only be started by the super-user. -.Pp -Access control is provided by -.Pa /etc/hosts.allow -and -.Pa /etc/hosts.deny , -as described in -.Xr hosts_access 5 -with daemon name -.Nm . -.Sh OPTIONS -.Bl -tag -width Ds -.It Fl d -Run in debug mode. -In this mode, -.Nm -will not fork when it starts, will print additional information -during operation, and will abort on certain errors. -With this option, the name-to-address translation consistency -checks are shown in detail. -.It Fl i -.Dq insecure -mode. -Allows calls to SET and UNSET from any host. -Normally -.Nm -accepts these requests only from the loopback interface for security reasons. -This change is necessary for programs that were compiled with earlier -versions of the rpc library and do not make those requests using the -loopback interface. -.It Fl l -Turns on libwrap connection logging. -.It Fl s -Causes -.Nm -to change to the user daemon as soon as possible. -This causes -.Nm -to use non-privileged ports for outgoing connections, preventing non-privileged -clients from using -.Nm -to connect to services from a privileged port. -.It Fl L -Allow old-style local connections over the loopback interface. -Without this flag, local connections are only allowed over a local socket, -.Pa /var/run/rpcbind.sock -.El -.Sh NOTES -All RPC servers must be restarted if -.Nm -is restarted. -.Sh FILES -.Bl -tag -width "/var/run/rpcbind.sock" -compact -.It Pa /var/run/rpcbind.sock -.It Pa /etc/hosts.allow -explicit remote host access list. -.It Pa /etc/hosts.deny -explicit remote host denial of service list. -.El -.Sh SEE ALSO -.Xr rpcbind 3 , -.Xr hosts_access 5 , -.Xr hosts_options 5 , -.Xr netconfig 5 , -.Xr rpcinfo 8 diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcbind.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcbind.c deleted file mode 100644 index 492b0b6..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcbind.c +++ /dev/null @@ -1,613 +0,0 @@ -/* $NetBSD: rpcbind.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1984 - 1991 by Sun Microsystems, Inc. - */ - -/* #ident "@(#)rpcbind.c 1.19 94/04/25 SMI" */ - -#if 0 -#ifndef lint -static char sccsid[] = "@(#)rpcbind.c 1.35 89/04/21 Copyr 1984 Sun Micro"; -#endif -#endif - -/* - * rpcbind.c - * Implements the program, version to address mapping for rpc. - * - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/errno.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/wait.h> -#include <sys/signal.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <rpc/rpc.h> -#ifdef PORTMAP -#include <netinet/in.h> -#endif -#include <netdb.h> -#include <stdio.h> -#include <netconfig.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <err.h> -#include <util.h> -#include <pwd.h> -#include <semaphore.h> -#include <string.h> -#include <errno.h> -#include "rpcbind.h" - -#include <rump/rump.h> -#include <rump/rump_syscalls.h> - -/* Global variables */ -int debugging = 1; /* Tell me what's going on */ -int doabort = 0; /* When debugging, do an abort on errors */ -rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */ - -#include "svc_fdset.h" - -/* who to suid to if -s is given */ -#define RUN_AS "daemon" - -int runasdaemon = 0; -int insecure = 0; -int oldstyle_local = 0; -int verboselog = 0; - -#ifdef WARMSTART -/* Local Variable */ -static int warmstart = 0; /* Grab a old copy of registrations */ -#endif - -#ifdef PORTMAP -struct pmaplist *list_pml; /* A list of version 2 rpcbind services */ -const char *udptrans; /* Name of UDP transport */ -const char *tcptrans; /* Name of TCP transport */ -const char *udp_uaddr; /* Universal UDP address */ -const char *tcp_uaddr; /* Universal TCP address */ -#endif -static const char servname[] = "sunrpc"; - -const char rpcbind_superuser[] = "superuser"; -const char rpcbind_unknown[] = "unknown"; - -static int init_transport(struct netconfig *); -static void rbllist_add(rpcprog_t, rpcvers_t, struct netconfig *, - struct netbuf *); -static void terminate(int); -#if 0 -static void parseargs(int, char *[]); -#endif - -int rpcbind_main(void *); -int -rpcbind_main(void *arg) -{ - struct netconfig *nconf; - void *nc_handle; /* Net config handle */ - struct rlimit rl; - int maxrec = RPC_MAXDATASIZE; - extern sem_t gensem; - -#if 0 - parseargs(argc, argv); -#endif - - alloc_fdset(); - - getrlimit(RLIMIT_NOFILE, &rl); - if (rl.rlim_cur < 128) { - if (rl.rlim_max <= 128) - rl.rlim_cur = rl.rlim_max; - else - rl.rlim_cur = 128; - setrlimit(RLIMIT_NOFILE, &rl); - } -#if 0 - if (geteuid()) /* This command allowed only to root */ - errx(1, "Sorry. You are not superuser"); -#endif - nc_handle = setnetconfig(); /* open netconfig file */ - if (nc_handle == NULL) - errx(1, "could not read /etc/netconfig"); -#ifdef PORTMAP - udptrans = ""; - tcptrans = ""; -#endif - - nconf = getnetconfigent("local"); - if (nconf == NULL) - errx(1, "can't find local transport"); - - rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); - - init_transport(nconf); - - while ((nconf = getnetconfig(nc_handle))) { - if (nconf->nc_flag & NC_VISIBLE) - init_transport(nconf); - } - endnetconfig(nc_handle); - - /* catch the usual termination signals for graceful exit */ - (void) signal(SIGCHLD, reap); - (void) signal(SIGINT, terminate); - (void) signal(SIGTERM, terminate); - (void) signal(SIGQUIT, terminate); - /* ignore others that could get sent */ - (void) signal(SIGPIPE, SIG_IGN); - //(void) signal(SIGHUP, SIG_IGN); used by mountd - (void) signal(SIGUSR1, SIG_IGN); - (void) signal(SIGUSR2, SIG_IGN); -#ifdef WARMSTART - if (warmstart) { - read_warmstart(); - } -#endif - if (debugging) { - printf("rpcbind debugging enabled."); - if (doabort) { - printf(" Will abort on errors!\n"); - } else { - printf("\n"); - } - } else { - if (daemon(0, 0)) - err(1, "fork failed"); - } - - openlog("rpcbind", 0, LOG_DAEMON); - pidfile(NULL); - - if (runasdaemon) { - struct passwd *p; - - if((p = getpwnam(RUN_AS)) == NULL) { - syslog(LOG_ERR, "cannot get uid of daemon: %m"); - exit(1); - } - if (setuid(p->pw_uid) == -1) { - syslog(LOG_ERR, "setuid to daemon failed: %m"); - exit(1); - } - } - - network_init(); - - sem_post(&gensem); - my_svc_run(); - syslog(LOG_ERR, "svc_run returned unexpectedly"); - rpcbind_abort(); - /* NOTREACHED */ - - return 0; -} - -/* - * Adds the entry into the rpcbind database. - * If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also - * Returns 0 if succeeds, else fails - */ -static int -init_transport(struct netconfig *nconf) -{ - int fd; - struct t_bind taddr; - struct addrinfo hints, *res = NULL; - struct __rpc_sockinfo si; - SVCXPRT *my_xprt; - int aicode, status, addrlen; - struct sockaddr *sa; - struct sockaddr_un sun; - const int one = 1; - - if ((nconf->nc_semantics != NC_TPI_CLTS) && - (nconf->nc_semantics != NC_TPI_COTS) && - (nconf->nc_semantics != NC_TPI_COTS_ORD)) - return 1; /* not my type */ -#ifdef RPCBIND_DEBUG - if (debugging) { - int i; - char **s; - - (void)fprintf(stderr, "%s: %ld lookup routines :\n", - nconf->nc_netid, nconf->nc_nlookups); - for (i = 0, s = nconf->nc_lookups; i < nconf->nc_nlookups; - i++, s++) - (void)fprintf(stderr, "[%d] - %s\n", i, *s); - } -#endif - - /* - * XXX - using RPC library internal functions. - */ - if ((fd = __rpc_nconf2fd(nconf)) < 0) { - if (errno == EAFNOSUPPORT) - return 1; - warn("Cannot create socket for `%s'", nconf->nc_netid); - return 1; - } - - if (!__rpc_nconf2sockinfo(nconf, &si)) { - warnx("Cannot get information for `%s'", nconf->nc_netid); - return 1; - } - - if (si.si_af == AF_INET6) { - /* - * We're doing host-based access checks here, so don't allow - * v4-in-v6 to confuse things. - */ - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, - sizeof one) < 0) { - warn("Can't make socket ipv6 only"); - return 1; - } - } - - - if (!strcmp(nconf->nc_netid, "local")) { - (void)memset(&sun, 0, sizeof sun); - sun.sun_family = AF_LOCAL; - (void)rump_sys_unlink(_PATH_RPCBINDSOCK); - (void)strlcpy(sun.sun_path, _PATH_RPCBINDSOCK, - sizeof(sun.sun_path)); - sun.sun_len = SUN_LEN(&sun); - addrlen = sizeof(struct sockaddr_un); - sa = (struct sockaddr *)&sun; - } else { - /* Get rpcbind's address on this transport */ - - (void)memset(&hints, 0, sizeof hints); - hints.ai_flags = AI_PASSIVE; - hints.ai_family = si.si_af; - hints.ai_socktype = si.si_socktype; - hints.ai_protocol = si.si_proto; - if ((aicode = getaddrinfo(NULL, servname, &hints, &res)) != 0) { - warnx("Cannot get local address for `%s' (%s)", - nconf->nc_netid, gai_strerror(aicode)); - return 1; - } - addrlen = res->ai_addrlen; - sa = (struct sockaddr *)res->ai_addr; - } - - if (bind(fd, sa, addrlen) < 0) { - warn("Cannot bind `%s'", nconf->nc_netid); - if (res != NULL) - freeaddrinfo(res); - return 1; - } -#if 0 - if (sa->sa_family == AF_LOCAL) - if (rump_sys_chmod(sun.sun_path, S_IRWXU|S_IRWXG|S_IRWXO) == -1) - warn("Cannot chmod `%s'", sun.sun_path); -#endif - - /* Copy the address */ - taddr.addr.len = taddr.addr.maxlen = addrlen; - taddr.addr.buf = malloc(addrlen); - if (taddr.addr.buf == NULL) { - warn("Cannot allocate memory for `%s' address", - nconf->nc_netid); - if (res != NULL) - freeaddrinfo(res); - return 1; - } - (void)memcpy(taddr.addr.buf, sa, addrlen); -#ifdef RPCBIND_DEBUG - if (debugging) { - /* for debugging print out our universal address */ - char *uaddr; - struct netbuf nb; - - nb.buf = sa; - nb.len = nb.maxlen = sa->sa_len; - uaddr = taddr2uaddr(nconf, &nb); - (void)fprintf(stderr, "rpcbind: my address is %s\n", uaddr); - (void)free(uaddr); - } -#endif - - if (res != NULL) - freeaddrinfo(res); - - if (nconf->nc_semantics != NC_TPI_CLTS) - listen(fd, SOMAXCONN); - - my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, - RPC_MAXDATASIZE); - if (my_xprt == NULL) { - warnx("Could not create service for `%s'", nconf->nc_netid); - goto error; - } - -#ifdef PORTMAP - /* - * Register both the versions for tcp/ip, udp/ip and local. - */ - if ((strcmp(nconf->nc_protofmly, NC_INET) == 0 && - (strcmp(nconf->nc_proto, NC_TCP) == 0 || - strcmp(nconf->nc_proto, NC_UDP) == 0)) || - strcmp(nconf->nc_netid, "local") == 0) { - struct pmaplist *pml; - - if (!svc_register(my_xprt, PMAPPROG, PMAPVERS, - pmap_service, 0)) { - warn("Could not register on `%s'", nconf->nc_netid); - goto error; - } - pml = malloc(sizeof (struct pmaplist)); - if (pml == NULL) { - warn("Cannot allocate memory"); - goto error; - } - pml->pml_map.pm_prog = PMAPPROG; - pml->pml_map.pm_vers = PMAPVERS; - pml->pml_map.pm_port = PMAPPORT; - if (strcmp(nconf->nc_proto, NC_TCP) == 0) { - if (tcptrans[0]) { - warnx( - "Cannot have more than one TCP transport"); - free(pml); - goto error; - } - tcptrans = strdup(nconf->nc_netid); - if (tcptrans == NULL) { - free(pml); - warn("Cannot allocate memory"); - goto error; - } - pml->pml_map.pm_prot = IPPROTO_TCP; - - /* Let's snarf the universal address */ - /* "h1.h2.h3.h4.p1.p2" */ - tcp_uaddr = taddr2uaddr(nconf, &taddr.addr); - } else if (strcmp(nconf->nc_proto, NC_UDP) == 0) { - if (udptrans[0]) { - free(pml); - warnx( - "Cannot have more than one UDP transport"); - goto error; - } - udptrans = strdup(nconf->nc_netid); - if (udptrans == NULL) { - free(pml); - warn("Cannot allocate memory"); - goto error; - } - pml->pml_map.pm_prot = IPPROTO_UDP; - - /* Let's snarf the universal address */ - /* "h1.h2.h3.h4.p1.p2" */ - udp_uaddr = taddr2uaddr(nconf, &taddr.addr); - } - pml->pml_next = list_pml; - list_pml = pml; - - /* Add version 3 information */ - pml = malloc(sizeof (struct pmaplist)); - if (pml == NULL) { - warn("Cannot allocate memory"); - goto error; - } - pml->pml_map = list_pml->pml_map; - pml->pml_map.pm_vers = RPCBVERS; - pml->pml_next = list_pml; - list_pml = pml; - - /* Add version 4 information */ - pml = malloc(sizeof (struct pmaplist)); - if (pml == NULL) { - warn("Cannot allocate memory"); - goto error; - } - pml->pml_map = list_pml->pml_map; - pml->pml_map.pm_vers = RPCBVERS4; - pml->pml_next = list_pml; - list_pml = pml; - - /* Also add version 2 stuff to rpcbind list */ - rbllist_add(PMAPPROG, PMAPVERS, nconf, &taddr.addr); - } -#endif - - /* version 3 registration */ - if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) { - warn("Could not register %s version 3", nconf->nc_netid); - goto error; - } - rbllist_add(RPCBPROG, RPCBVERS, nconf, &taddr.addr); - - /* version 4 registration */ - if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) { - warn("Could not register %s version 4", nconf->nc_netid); - goto error; - } - rbllist_add(RPCBPROG, RPCBVERS4, nconf, &taddr.addr); - - /* decide if bound checking works for this transport */ - status = add_bndlist(nconf, &taddr.addr); -#ifdef RPCBIND_DEBUG - if (debugging) { - if (status < 0) { - fprintf(stderr, "Error in finding bind status for %s\n", - nconf->nc_netid); - } else if (status == 0) { - fprintf(stderr, "check binding for %s\n", - nconf->nc_netid); - } else if (status > 0) { - fprintf(stderr, "No check binding for %s\n", - nconf->nc_netid); - } - } -#else - __USE(status); -#endif - /* - * rmtcall only supported on CLTS transports for now. - */ - if (nconf->nc_semantics == NC_TPI_CLTS) { - status = create_rmtcall_fd(nconf); - -#ifdef RPCBIND_DEBUG - if (debugging) { - if (status < 0) { - fprintf(stderr, - "Could not create rmtcall fd for %s\n", - nconf->nc_netid); - } else { - fprintf(stderr, "rmtcall fd for %s is %d\n", - nconf->nc_netid, status); - } - } -#endif - } - return (0); -error: - (void)rump_sys_close(fd); - return (1); -} - -static void -rbllist_add(rpcprog_t prog, rpcvers_t vers, struct netconfig *nconf, - struct netbuf *addr) -{ - rpcblist_ptr rbl; - - rbl = malloc(sizeof(rpcblist)); - if (rbl == NULL) { - warn("Out of memory"); - return; - } - - rbl->rpcb_map.r_prog = prog; - rbl->rpcb_map.r_vers = vers; - rbl->rpcb_map.r_netid = strdup(nconf->nc_netid); - rbl->rpcb_map.r_addr = taddr2uaddr(nconf, addr); - rbl->rpcb_map.r_owner = strdup(rpcbind_superuser); - rbl->rpcb_next = list_rbl; /* Attach to global list */ - list_rbl = rbl; -} - -/* - * Catch the signal and die - */ -static void -terminate(int dummy) -{ -#ifdef WARMSTART - syslog(LOG_ERR, - "rpcbind terminating on signal. Restart with \"rpcbind -w\""); - write_warmstart(); /* Dump yourself */ -#endif - exit(2); -} - -void -rpcbind_abort() -{ -#ifdef WARMSTART - write_warmstart(); /* Dump yourself */ -#endif - abort(); -} - -#if 0 -/* get command line options */ -static void -parseargs(int argc, char *argv[]) -{ - int c; - - while ((c = getopt(argc, argv, "dwailLs")) != -1) { - switch (c) { - case 'a': - doabort = 1; /* when debugging, do an abort on */ - break; /* errors; for rpcbind developers */ - /* only! */ - case 'd': - debugging = 1; - break; - case 'i': - insecure = 1; - break; - case 'L': - oldstyle_local = 1; - break; - case 'l': - verboselog = 1; - break; - case 's': - runasdaemon = 1; - break; -#ifdef WARMSTART - case 'w': - warmstart = 1; - break; -#endif - default: /* error */ - fprintf(stderr, "usage: rpcbind [-Idwils]\n"); - exit (1); - } - } - if (doabort && !debugging) { - fprintf(stderr, - "-a (abort) specified without -d (debugging) -- ignored.\n"); - doabort = 0; - } -} -#endif - -void -reap(int dummy) -{ - int save_errno = errno; - - while (wait3(NULL, WNOHANG, NULL) > 0) - ; - errno = save_errno; -} - -void -toggle_verboselog(int dummy) -{ - verboselog = !verboselog; -} diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcbind.h b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcbind.h deleted file mode 100644 index 1717e31..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/rpcbind.h +++ /dev/null @@ -1,146 +0,0 @@ -/* $NetBSD: rpcbind.h,v 1.1 2010/07/26 15:53:00 pooka Exp $ */ - -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. - */ - -/* #ident "@(#)rpcbind.h 1.4 90/04/12 SMI" */ - -/* - * rpcbind.h - * The common header declarations - */ - -#ifndef rpcbind_h -#define rpcbind_h - -#ifdef PORTMAP -#include <rpc/pmap_prot.h> -#endif -#include <rpc/rpcb_prot.h> - -/* - * Stuff for the rmtcall service - */ -struct encap_parms { - u_int32_t arglen; - char *args; -}; - -struct r_rmtcall_args { - u_int32_t rmt_prog; - u_int32_t rmt_vers; - u_int32_t rmt_proc; - int rmt_localvers; /* whether to send port # or uaddr */ - char *rmt_uaddr; - struct encap_parms rmt_args; -}; - -extern int debugging; -extern int doabort; -extern int verboselog; -extern int insecure; -extern int oldstyle_local; -extern rpcblist_ptr list_rbl; /* A list of version 3 & 4 rpcbind services */ - -#ifdef PORTMAP -extern struct pmaplist *list_pml; /* A list of version 2 rpcbind services */ -extern const char *udptrans; /* Name of UDP transport */ -extern const char *tcptrans; /* Name of TCP transport */ -extern const char *udp_uaddr; /* Universal UDP address */ -extern const char *tcp_uaddr; /* Universal TCP address */ -#endif - -extern const char rpcbind_superuser[]; -extern const char rpcbind_unknown[]; - -int add_bndlist(struct netconfig *, struct netbuf *); -bool_t is_bound(const char *, const char *); -char *mergeaddr(SVCXPRT *, char *, char *, char *); -struct netconfig *rpcbind_get_conf(const char *); - -void rpcbs_init(void); -void rpcbs_procinfo(rpcvers_t, rpcproc_t); -void rpcbs_set(rpcvers_t, bool_t); -void rpcbs_unset(rpcvers_t, bool_t); -void rpcbs_getaddr(rpcvers_t, rpcprog_t, rpcvers_t, const char *, const char *); -void rpcbs_rmtcall(rpcvers_t, rpcproc_t, rpcprog_t, rpcvers_t, rpcproc_t, - char *, rpcblist_ptr); -void *rpcbproc_getstat(void *, struct svc_req *, SVCXPRT *, rpcvers_t); - -void rpcb_service_3(struct svc_req *, SVCXPRT *); -void rpcb_service_4(struct svc_req *, SVCXPRT *); - -/* Common functions shared between versions */ -void *rpcbproc_set_com(void *, struct svc_req *, SVCXPRT *, rpcvers_t); -void *rpcbproc_unset_com(void *, struct svc_req *, SVCXPRT *, rpcvers_t); -bool_t map_set(RPCB *, char *); -bool_t map_unset(RPCB *, const char *); -void delete_prog(int); -void *rpcbproc_getaddr_com(RPCB *, struct svc_req *, SVCXPRT *, rpcvers_t, - rpcvers_t); -void *rpcbproc_gettime_com(void *, struct svc_req *, SVCXPRT *, - rpcvers_t); -void *rpcbproc_uaddr2taddr_com(void *, struct svc_req *, - SVCXPRT *, rpcvers_t); -void *rpcbproc_taddr2uaddr_com(void *, struct svc_req *, SVCXPRT *, - rpcvers_t); -int create_rmtcall_fd(struct netconfig *); -void rpcbproc_callit_com(struct svc_req *, SVCXPRT *, rpcvers_t, - rpcvers_t); -void my_svc_run(void); - -void rpcbind_abort(void); -void reap(int); -void toggle_verboselog(int); - -int check_access(SVCXPRT *, rpcproc_t, void *, int); -int check_callit(SVCXPRT *, struct r_rmtcall_args *, int); -void logit(int, struct sockaddr *, rpcproc_t, rpcprog_t, const char *); -int is_loopback(struct netbuf *); - -#ifdef PORTMAP -extern void pmap_service(struct svc_req *, SVCXPRT *); -#endif - -void write_warmstart(void); -void read_warmstart(void); - -char *addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr, - char *netid); -void network_init(void); -struct sockaddr *local_sa(int); - -/* For different getaddr semantics */ -#define RPCB_ALLVERS 0 -#define RPCB_ONEVERS 1 - -#endif /* rpcbind_h */ diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/security.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/security.c deleted file mode 100644 index 755c0d3..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/security.c +++ /dev/null @@ -1,282 +0,0 @@ -/* $NetBSD: security.c,v 1.1 2010/07/26 15:53:01 pooka Exp $ */ - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <rpc/rpc.h> -#include <rpc/rpcb_prot.h> -#include <rpc/pmap_prot.h> -#include <err.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <util.h> -#include <syslog.h> -#include <netdb.h> - -/* - * XXX for special case checks in check_callit. - */ -#include <rpcsvc/mount.h> -#include <rpcsvc/rquota.h> -#include <rpcsvc/nfs_prot.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> -#include <rpcsvc/yppasswd.h> - -#include "rpcbind.h" - -#ifdef LIBWRAP -# include <tcpd.h> -#ifndef LIBWRAP_ALLOW_FACILITY -# define LIBWRAP_ALLOW_FACILITY LOG_AUTH -#endif -#ifndef LIBWRAP_ALLOW_SEVERITY -# define LIBWRAP_ALLOW_SEVERITY LOG_INFO -#endif -#ifndef LIBWRAP_DENY_FACILITY -# define LIBWRAP_DENY_FACILITY LOG_AUTH -#endif -#ifndef LIBWRAP_DENY_SEVERITY -# define LIBWRAP_DENY_SEVERITY LOG_WARNING -#endif -int allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY; -int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY; -#endif - -#ifndef PORTMAP_LOG_FACILITY -# define PORTMAP_LOG_FACILITY LOG_AUTH -#endif -#ifndef PORTMAP_LOG_SEVERITY -# define PORTMAP_LOG_SEVERITY LOG_INFO -#endif -int log_severity = PORTMAP_LOG_FACILITY|PORTMAP_LOG_SEVERITY; - -extern int verboselog; - -int -check_access(SVCXPRT *xprt, rpcproc_t proc, void *args, int rpcbvers) -{ - struct netbuf *caller = svc_getrpccaller(xprt); - struct sockaddr *addr = (struct sockaddr *)caller->buf; -#ifdef LIBWRAP - struct request_info req; -#endif - rpcprog_t prog = 0; - rpcb *rpcbp; - struct pmap *pmap; - - /* - * The older PMAP_* equivalents have the same numbers, so - * they are accounted for here as well. - */ - switch (proc) { - case RPCBPROC_GETADDR: - case RPCBPROC_SET: - case RPCBPROC_UNSET: - if (rpcbvers > PMAPVERS) { - rpcbp = (rpcb *)args; - prog = rpcbp->r_prog; - } else { - pmap = (struct pmap *)args; - prog = pmap->pm_prog; - } - if (proc == RPCBPROC_GETADDR) - break; - if (!insecure && !is_loopback(caller)) { - if (verboselog) - logit(log_severity, addr, proc, prog, - " declined (non-loopback sender)"); - return 0; - } - break; - case RPCBPROC_CALLIT: - case RPCBPROC_INDIRECT: - case RPCBPROC_DUMP: - case RPCBPROC_GETTIME: - case RPCBPROC_UADDR2TADDR: - case RPCBPROC_TADDR2UADDR: - case RPCBPROC_GETVERSADDR: - case RPCBPROC_GETADDRLIST: - case RPCBPROC_GETSTAT: - default: - break; - } - -#ifdef LIBWRAP - if (addr->sa_family == AF_LOCAL) - return 1; - request_init(&req, RQ_DAEMON, "rpcbind", RQ_CLIENT_SIN, addr, 0); - sock_methods(&req); - if(!hosts_access(&req)) { - logit(deny_severity, addr, proc, prog, ": request from unauthorized host"); - return 0; - } -#endif - if (verboselog) - logit(log_severity, addr, proc, prog, ""); - return 1; -} - -int -is_loopback(struct netbuf *nbuf) -{ - struct sockaddr *addr = (struct sockaddr *)nbuf->buf; - struct sockaddr_in *sin; -#ifdef INET6 - struct sockaddr_in6 *sin6; -#endif - - switch (addr->sa_family) { - case AF_INET: - if (!oldstyle_local) - return 0; - sin = (struct sockaddr_in *)addr; - return ((sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) && - (ntohs(sin->sin_port) < IPPORT_RESERVED)); -#ifdef INET6 - case AF_INET6: - if (!oldstyle_local) - return 0; - sin6 = (struct sockaddr_in6 *)addr; - return (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) && - (ntohs(sin6->sin6_port) < IPV6PORT_RESERVED)); -#endif - case AF_LOCAL: - return 1; - default: - break; - } - - return 0; -} - - -/* logit - report events of interest via the syslog daemon */ -void -logit(int severity, struct sockaddr *addr, rpcproc_t procnum, rpcprog_t prognum, - const char *text) -{ - const char *procname; - char procbuf[32]; - char *progname; - char progbuf[32]; - char fromname[NI_MAXHOST]; - struct rpcent *rpc; - static const char *procmap[] = { - /* RPCBPROC_NULL */ "null", - /* RPCBPROC_SET */ "set", - /* RPCBPROC_UNSET */ "unset", - /* RPCBPROC_GETADDR */ "getport/addr", - /* RPCBPROC_DUMP */ "dump", - /* RPCBPROC_CALLIT */ "callit", - /* RPCBPROC_GETTIME */ "gettime", - /* RPCBPROC_UADDR2TADDR */ "uaddr2taddr", - /* RPCBPROC_TADDR2UADDR */ "taddr2uaddr", - /* RPCBPROC_GETVERSADDR */ "getversaddr", - /* RPCBPROC_INDIRECT */ "indirect", - /* RPCBPROC_GETADDRLIST */ "getaddrlist", - /* RPCBPROC_GETSTAT */ "getstat" - }; - - /* - * Fork off a process or the portmap daemon might hang while - * getrpcbynumber() or syslog() does its thing. - */ - - if (fork() == 0) { - setproctitle("logit"); - - /* Try to map program number to name. */ - - if (prognum == 0) { - progname = __UNCONST(""); - } else if ((rpc = getrpcbynumber((int) prognum))) { - progname = rpc->r_name; - } else { - snprintf(progname = progbuf, sizeof(progbuf), "%u", - (unsigned)prognum); - } - - /* Try to map procedure number to name. */ - - if (procnum >= (sizeof procmap / sizeof (char *))) { - snprintf(procbuf, sizeof procbuf, "%u", - (unsigned)procnum); - procname = procbuf; - } else - procname = procmap[procnum]; - - /* Write syslog record. */ - - if (addr->sa_family == AF_LOCAL) - strlcpy(fromname, "local", sizeof(fromname)); - else - getnameinfo(addr, addr->sa_len, fromname, - sizeof fromname, NULL, 0, NI_NUMERICHOST); - - syslog(severity, "connect from %s to %s(%s)%s", - fromname, procname, progname, text); - _exit(0); - } -} - -int -check_callit(SVCXPRT *xprt, struct r_rmtcall_args *args, int versnum) -{ - struct sockaddr *sa = (struct sockaddr *)svc_getrpccaller(xprt)->buf; - - /* - * Always allow calling NULLPROC - */ - if (args->rmt_proc == 0) - return 1; - - /* - * XXX - this special casing sucks. - */ - switch (args->rmt_prog) { - case RPCBPROG: - /* - * Allow indirect calls to ourselves in insecure mode. - * The is_loopback checks aren't useful then anyway. - */ - if (!insecure) - goto deny; - break; - case MOUNTPROG: - if (args->rmt_proc != MOUNTPROC_MNT && - args->rmt_proc != MOUNTPROC_UMNT) - break; - goto deny; - case YPBINDPROG: - if (args->rmt_proc != YPBINDPROC_SETDOM) - break; - /* FALLTHROUGH */ - case YPPASSWDPROG: - case NFS_PROGRAM: - case RQUOTAPROG: - goto deny; - case YPPROG: - switch (args->rmt_proc) { - case YPPROC_ALL: - case YPPROC_MATCH: - case YPPROC_FIRST: - case YPPROC_NEXT: - goto deny; - default: - break; - } - default: - break; - } - - return 1; -deny: - logit(deny_severity, sa, args->rmt_proc, args->rmt_prog, - ": indirect call not allowed"); - - return 0; -} diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/util.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/util.c deleted file mode 100644 index f67e98d..0000000 --- a/contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind/util.c +++ /dev/null @@ -1,401 +0,0 @@ -/* $NetBSD: util.c,v 1.2 2011/06/11 18:03:17 christos Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Frank van der Linden. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/queue.h> -#include <net/if.h> -#include <netinet/in.h> -#include <assert.h> -#include <ifaddrs.h> -#include <poll.h> -#include <rpc/rpc.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <netdb.h> -#include <netconfig.h> -#include <stdio.h> -#include <arpa/inet.h> - -#include <rump/rump.h> -#include <rump/rump_syscalls.h> - -#include "rpcbind.h" - -static struct sockaddr_in *local_in4; -#ifdef INET6 -static struct sockaddr_in6 *local_in6; -#endif - -static int bitmaskcmp(void *, void *, void *, int); -#ifdef INET6 -static void in6_fillscopeid(struct sockaddr_in6 *); -#endif - -/* - * For all bits set in "mask", compare the corresponding bits in - * "dst" and "src", and see if they match. - */ -static int -bitmaskcmp(void *dst, void *src, void *mask, int bytelen) -{ - int i, j; - u_int8_t *p1 = dst, *p2 = src, *netmask = mask; - u_int8_t bitmask; - - for (i = 0; i < bytelen; i++) { - for (j = 0; j < 8; j++) { - bitmask = 1 << j; - if (!(netmask[i] & bitmask)) - continue; - if ((p1[i] & bitmask) != (p2[i] & bitmask)) - return 1; - } - } - - return 0; -} - -/* - * Taken from ifconfig.c - */ -#ifdef INET6 -static void -in6_fillscopeid(struct sockaddr_in6 *sin6) -{ - if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - sin6->sin6_scope_id = - ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]); - sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0; - } -} -#endif - -char * -addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr, - char *netid) -{ - struct ifaddrs *ifap, *ifp, *bestif; -#ifdef INET6 - struct sockaddr_in6 *servsin6, *sin6mask, *clntsin6, *ifsin6, *realsin6; - struct sockaddr_in6 *newsin6; -#endif - struct sockaddr_in *servsin, *sinmask, *clntsin, *newsin, *ifsin; - struct netbuf *serv_nbp, *clnt_nbp = NULL, tbuf; - struct sockaddr *serv_sa; - struct sockaddr *clnt_sa; - struct sockaddr_storage ss; - struct netconfig *nconf; - struct sockaddr *clnt = caller->buf; - char *ret = NULL; - -#ifdef INET6 - servsin6 = ifsin6 = newsin6 = NULL; /* XXXGCC -Wuninitialized */ -#endif - servsin = newsin = NULL; /* XXXGCC -Wuninitialized */ - -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "addrmerge(caller, %s, %s, %s\n", serv_uaddr, - clnt_uaddr, netid); -#endif - nconf = getnetconfigent(netid); - if (nconf == NULL) - return NULL; - - /* - * Local merge, just return a duplicate. - */ - if (clnt_uaddr != NULL && strncmp(clnt_uaddr, "0.0.0.0.", 8) == 0) - return strdup(clnt_uaddr); - - serv_nbp = uaddr2taddr(nconf, serv_uaddr); - if (serv_nbp == NULL) - return NULL; - - serv_sa = (struct sockaddr *)serv_nbp->buf; - if (clnt_uaddr != NULL) { - clnt_nbp = uaddr2taddr(nconf, clnt_uaddr); - if (clnt_nbp == NULL) { - free(serv_nbp); - return NULL; - } - clnt_sa = (struct sockaddr *)clnt_nbp->buf; - if (clnt_sa->sa_family == AF_LOCAL) { - free(serv_nbp); - free(clnt_nbp); - free(clnt_sa); - return strdup(serv_uaddr); - } - } else { - clnt_sa = (struct sockaddr *) - malloc(sizeof (struct sockaddr_storage)); - memcpy(clnt_sa, clnt, clnt->sa_len); - } - - if (getifaddrs(&ifp) < 0) { - free(serv_nbp); - free(clnt_sa); - if (clnt_nbp != NULL) - free(clnt_nbp); - return 0; - } - - /* - * Loop through all interfaces. For each interface, see if the - * network portion of its address is equal to that of the client. - * If so, we have found the interface that we want to use. - */ - for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) { - if (ifap->ifa_addr->sa_family != clnt->sa_family || - !(ifap->ifa_flags & IFF_UP)) - continue; - - switch (clnt->sa_family) { - case AF_INET: - /* - * realsin: address that recvfrom gave us. - * ifsin: address of interface being examined. - * clntsin: address that client want us to contact - * it on - * servsin: local address of RPC service. - * sinmask: netmask of this interface - * newsin: initially a copy of clntsin, eventually - * the merged address - */ - servsin = (struct sockaddr_in *)serv_sa; - clntsin = (struct sockaddr_in *)clnt_sa; - sinmask = (struct sockaddr_in *)ifap->ifa_netmask; - newsin = (struct sockaddr_in *)&ss; - ifsin = (struct sockaddr_in *)ifap->ifa_addr; - if (!bitmaskcmp(&ifsin->sin_addr, &clntsin->sin_addr, - &sinmask->sin_addr, sizeof (struct in_addr))) { - goto found; - } - break; -#ifdef INET6 - case AF_INET6: - /* - * realsin6: address that recvfrom gave us. - * ifsin6: address of interface being examined. - * clntsin6: address that client want us to contact - * it on - * servsin6: local address of RPC service. - * sin6mask: netmask of this interface - * newsin6: initially a copy of clntsin, eventually - * the merged address - * - * For v6 link local addresses, if the client contacted - * us via a link-local address, and wants us to reply - * to one, use the scope id to see which one. - */ - realsin6 = (struct sockaddr_in6 *)clnt; - ifsin6 = (struct sockaddr_in6 *)ifap->ifa_addr; - in6_fillscopeid(ifsin6); - clntsin6 = (struct sockaddr_in6 *)clnt_sa; - servsin6 = (struct sockaddr_in6 *)serv_sa; - sin6mask = (struct sockaddr_in6 *)ifap->ifa_netmask; - newsin6 = (struct sockaddr_in6 *)&ss; - if (IN6_IS_ADDR_LINKLOCAL(&ifsin6->sin6_addr) && - IN6_IS_ADDR_LINKLOCAL(&realsin6->sin6_addr) && - IN6_IS_ADDR_LINKLOCAL(&clntsin6->sin6_addr)) { - if (ifsin6->sin6_scope_id != - realsin6->sin6_scope_id) - continue; - goto found; - } - if (!bitmaskcmp(&ifsin6->sin6_addr, - &clntsin6->sin6_addr, &sin6mask->sin6_addr, - sizeof (struct in6_addr))) - goto found; - break; -#endif - default: - goto freeit; - } - } - /* - * Didn't find anything. Get the first possibly useful interface, - * preferring "normal" interfaces to point-to-point and loopback - * ones. - */ - bestif = NULL; - for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) { - if (ifap->ifa_addr->sa_family != clnt->sa_family || - !(ifap->ifa_flags & IFF_UP)) - continue; - if (!(ifap->ifa_flags & IFF_LOOPBACK) && - !(ifap->ifa_flags & IFF_POINTOPOINT)) { - bestif = ifap; - break; - } - if (bestif == NULL) - bestif = ifap; - else if ((bestif->ifa_flags & IFF_LOOPBACK) && - !(ifap->ifa_flags & IFF_LOOPBACK)) - bestif = ifap; - } - ifap = bestif; -found: - switch (clnt->sa_family) { - case AF_INET: - memcpy(newsin, ifap->ifa_addr, clnt_sa->sa_len); - newsin->sin_port = servsin->sin_port; - tbuf.len = clnt_sa->sa_len; - tbuf.maxlen = sizeof (struct sockaddr_storage); - tbuf.buf = newsin; - break; -#ifdef INET6 - case AF_INET6: - assert(newsin6); - memcpy(newsin6, ifsin6, clnt_sa->sa_len); - newsin6->sin6_port = servsin6->sin6_port; - tbuf.maxlen = sizeof (struct sockaddr_storage); - tbuf.len = clnt_sa->sa_len; - tbuf.buf = newsin6; - break; -#endif - default: - goto freeit; - } - if (ifap != NULL) - ret = taddr2uaddr(nconf, &tbuf); -freeit: - freenetconfigent(nconf); - free(serv_sa); - free(serv_nbp); - if (clnt_sa != NULL) - free(clnt_sa); - if (clnt_nbp != NULL) - free(clnt_nbp); - freeifaddrs(ifp); - -#ifdef RPCBIND_DEBUG - if (debugging) - fprintf(stderr, "addrmerge: returning %s\n", ret); -#endif - return ret; -} - -void -network_init() -{ -#ifdef INET6 - struct ifaddrs *ifap, *ifp; - struct ipv6_mreq mreq6; - int ifindex, s; -#endif - int ecode; - struct addrinfo hints, *res; - - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_INET; - if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) { - if (debugging) - fprintf(stderr, "can't get local ip4 address: %s\n", - gai_strerror(ecode)); - } else { - local_in4 = (struct sockaddr_in *)malloc(sizeof *local_in4); - if (local_in4 == NULL) { - if (debugging) - fprintf(stderr, "can't alloc local ip4 addr\n"); - } - memcpy(local_in4, res->ai_addr, sizeof *local_in4); - } - -#ifdef INET6 - hints.ai_family = AF_INET6; - if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) { - if (debugging) - fprintf(stderr, "can't get local ip6 address: %s\n", - gai_strerror(ecode)); - } else { - local_in6 = (struct sockaddr_in6 *)malloc(sizeof *local_in6); - if (local_in6 == NULL) { - if (debugging) - fprintf(stderr, "can't alloc local ip6 addr\n"); - } - memcpy(local_in6, res->ai_addr, sizeof *local_in6); - } - - /* - * Now join the RPC ipv6 multicast group on all interfaces. - */ - if (getifaddrs(&ifp) < 0) - return; - - mreq6.ipv6mr_interface = 0; - inet_pton(AF_INET6, RPCB_MULTICAST_ADDR, &mreq6.ipv6mr_multiaddr); - - s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - - /* - * Loop through all interfaces. For each interface, see if the - * network portion of its address is equal to that of the client. - * If so, we have found the interface that we want to use. - */ - for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) { - if (ifap->ifa_addr->sa_family != AF_INET6 || - !(ifap->ifa_flags & IFF_MULTICAST)) - continue; - ifindex = if_nametoindex(ifap->ifa_name); - if (ifindex == mreq6.ipv6mr_interface) - /* - * Already did this one. - */ - continue; - mreq6.ipv6mr_interface = ifindex; - if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, - sizeof mreq6) < 0) - if (debugging) - warn("setsockopt v6 multicast"); - } -#endif - - /* close(s); */ -} - -struct sockaddr * -local_sa(int af) -{ - switch (af) { - case AF_INET: - return (struct sockaddr *)local_in4; -#ifdef INET6 - case AF_INET6: - return (struct sockaddr *)local_in6; -#endif - default: - return NULL; - } -} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_dir.c b/contrib/netbsd-tests/lib/libc/gen/t_dir.c index 81412c1..b37d89d 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_dir.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_dir.c @@ -39,6 +39,10 @@ #include <sys/stat.h> +#ifdef __FreeBSD__ +#include <errno.h> +#endif + ATF_TC(seekdir_basic); ATF_TC_HEAD(seekdir_basic, tc) { @@ -54,10 +58,26 @@ ATF_TC_BODY(seekdir_basic, tc) struct dirent *entry; long here; +#ifdef __FreeBSD__ +#define CREAT(x, m) do { \ + int _creat_fd; \ + ATF_REQUIRE_MSG((_creat_fd = creat((x), (m))) != -1, \ + "creat(%s, %x) failed: %s", (x), (m), \ + strerror(errno)); \ + (void)close(_creat_fd); \ + } while(0); + + ATF_REQUIRE_MSG(mkdir("t", 0755) == 0, + "mkdir failed: %s", strerror(errno)); + CREAT("t/a", 0600); + CREAT("t/b", 0600); + CREAT("t/c", 0600); +#else mkdir("t", 0755); creat("t/a", 0600); creat("t/b", 0600); creat("t/c", 0600); +#endif dp = opendir("t"); if ( dp == NULL) @@ -70,9 +90,17 @@ ATF_TC_BODY(seekdir_basic, tc) /* get first entry */ entry = readdir(dp); here = telldir(dp); +#ifdef __FreeBSD__ + ATF_REQUIRE_MSG(here != -1, + "telldir failed: %s", strerror(errno)); +#endif /* get second entry */ entry = readdir(dp); +#ifdef __FreeBSD__ + ATF_REQUIRE_MSG(entry != NULL, + "readdir failed: %s", strerror(errno)); +#endif wasname = strdup(entry->d_name); if (wasname == NULL) atf_tc_fail("cannot allocate memory"); @@ -109,6 +137,9 @@ ATF_TC_BODY(seekdir_basic, tc) atf_tc_fail("3rd seekdir found wrong name"); closedir(dp); +#ifdef __FreeBSD__ + free(wasname); +#endif } ATF_TC(telldir_leak); diff --git a/contrib/netbsd-tests/lib/libc/gen/t_raise.c b/contrib/netbsd-tests/lib/libc/gen/t_raise.c index d6f888f..91a8c37 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_raise.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_raise.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $ */ +/* $NetBSD: t_raise.c,v 1.6 2016/11/03 22:08:31 kamil Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $"); +__RCSID("$NetBSD: t_raise.c,v 1.6 2016/11/03 22:08:31 kamil Exp $"); #include <atf-c.h> @@ -180,7 +180,7 @@ ATF_TC_BODY(raise_stress, tc) (void)raise(SIGUSR1); if (count != maxiter) - atf_tc_fail("not all signals were catched"); + atf_tc_fail("not all signals were caught"); } ATF_TP_ADD_TCS(tp) diff --git a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c index f51eb2a..02dd176 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c @@ -64,7 +64,7 @@ ATF_TC_BODY(setdomainname_basic, tc) (void)memset(name, 0, sizeof(name)); #ifdef __FreeBSD__ - /* + /* * Sanity checks to ensure that the wrong invariant isn't being * tested for per PR # 181127 */ diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c index 1972f7d..136fa7c 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c @@ -66,7 +66,7 @@ ATF_TC_BODY(sethostname_basic, tc) (void)memset(name, 0, sizeof(name)); #ifdef __FreeBSD__ - /* + /* * Sanity checks to ensure that the wrong invariant isn't being * tested for per PR # 181127 */ diff --git a/contrib/netbsd-tests/lib/libc/regex/debug.c b/contrib/netbsd-tests/lib/libc/regex/debug.c index 3fc6d5b..22f0b90 100644 --- a/contrib/netbsd-tests/lib/libc/regex/debug.c +++ b/contrib/netbsd-tests/lib/libc/regex/debug.c @@ -48,9 +48,7 @@ #ifdef __NetBSD__ static void s_print(struct re_guts *, FILE *); static char *regchar(int); -#endif -#ifdef __NetBSD__ /* * regprint - print a regexp for debugging */ diff --git a/contrib/netbsd-tests/lib/libc/sys/t_select.c b/contrib/netbsd-tests/lib/libc/sys/t_select.c index 7af725a..437b67b 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_select.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_select.c @@ -135,6 +135,9 @@ child(const struct timespec *ts) "after timeout %s != %s", prmask(&nset, nbuf, sizeof(nbuf)), prmask(&oset, obuf, sizeof(obuf))); +#ifdef __FreeBSD__ + _exit(0); +#endif } ATF_TC(pselect_sigmask); @@ -154,6 +157,9 @@ ATF_TC_BODY(pselect_sigmask, tc) switch (pid = fork()) { case 0: child(NULL); +#ifdef __FreeBSD__ + break; +#endif case -1: err(1, "fork"); default: diff --git a/contrib/netbsd-tests/lib/libc/sys/t_unlink.c b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c index 8d94668..b504bb0 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_unlink.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c @@ -111,8 +111,15 @@ ATF_TC_HEAD(unlink_fifo, tc) ATF_TC_BODY(unlink_fifo, tc) { +#ifdef __FreeBSD__ + int fd; + ATF_REQUIRE_MSG((fd = mkfifo(path, 0666)) == 0, + "mkfifo failed: %s", strerror(errno)); + (void)close(fd); +#else ATF_REQUIRE(mkfifo(path, 0666) == 0); +#endif ATF_REQUIRE(unlink(path) == 0); errno = 0; diff --git a/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c b/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c index 1e42536..7f60d78 100644 --- a/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c +++ b/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_ttyio.c,v 1.2 2011/04/19 20:07:53 martin Exp $ */ +/* $NetBSD: t_ttyio.c,v 1.3 2017/01/10 01:31:40 christos Exp $ */ /* * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #include <sys/cdefs.h> __COPYRIGHT("@(#) Copyright (c) 2008\ The NetBSD Foundation, inc. All rights reserved."); -__RCSID("$NetBSD: t_ttyio.c,v 1.2 2011/04/19 20:07:53 martin Exp $"); +__RCSID("$NetBSD: t_ttyio.c,v 1.3 2017/01/10 01:31:40 christos Exp $"); #include <sys/types.h> #include <sys/wait.h> @@ -150,11 +150,9 @@ ATF_TC_BODY(ioctl, tc) /* wait for last child */ sa.sa_handler = SIG_DFL; REQUIRE_ERRNO(sigaction(SIGCHLD, &sa, NULL), -1); - (void) wait(NULL); + (void)wait(NULL); -#ifdef __FreeBSD__ (void)close(s); -#endif ATF_REQUIRE_EQ(rc, 0); } diff --git a/contrib/netbsd-tests/lib/libpthread/t_condwait.c b/contrib/netbsd-tests/lib/libpthread/t_condwait.c index 17bbb89..99793d0 100644 --- a/contrib/netbsd-tests/lib/libpthread/t_condwait.c +++ b/contrib/netbsd-tests/lib/libpthread/t_condwait.c @@ -42,6 +42,8 @@ __RCSID("$NetBSD: t_condwait.c,v 1.4 2013/04/12 17:18:11 christos Exp $"); #ifdef __FreeBSD__ #include <sys/time.h> + +#include "h_common.h" #endif #define WAITTIME 2 /* Timeout wait secound */ @@ -60,8 +62,13 @@ run(void *param) clck = *(clockid_t *)param; +#ifdef __FreeBSD__ + PTHREAD_REQUIRE(pthread_condattr_init(&attr)); + PTHREAD_REQUIRE(pthread_condattr_setclock(&attr, clck)); +#else pthread_condattr_init(&attr); pthread_condattr_setclock(&attr, clck); /* MONOTONIC or MONOTONIC */ +#endif pthread_cond_init(&cond, &attr); ATF_REQUIRE_EQ((ret = pthread_mutex_lock(&m)), 0); diff --git a/contrib/netbsd-tests/lib/libpthread/t_fpu.c b/contrib/netbsd-tests/lib/libpthread/t_fpu.c index 4047b1f..6a385d9 100644 --- a/contrib/netbsd-tests/lib/libpthread/t_fpu.c +++ b/contrib/netbsd-tests/lib/libpthread/t_fpu.c @@ -58,6 +58,11 @@ __RCSID("$NetBSD: t_fpu.c,v 1.2 2013/01/27 14:47:37 mbalmer Exp $"); #include <atf-c.h> +#ifdef __FreeBSD__ +#include <errno.h> +#include <string.h> +#endif + #include "h_common.h" #define N_RECURSE 10 @@ -77,14 +82,24 @@ stir(void *p) for (;;) { x = sin ((y = cos (x + y + .4)) - (z = cos (x + z + .6))); +#ifdef __FreeBSD__ + ATF_REQUIRE_MSG(sched_yield() == 0, + "sched_yield failed: %s", strerror(errno)); +#else PTHREAD_REQUIRE(sched_yield()); +#endif } } static double mul3(double x, double y, double z) { +#ifdef __FreeBSD__ + ATF_REQUIRE_MSG(sched_yield() == 0, + "sched_yield failed: %s", strerror(errno)); +#else PTHREAD_REQUIRE(sched_yield()); +#endif return x * y * z; } @@ -114,7 +129,11 @@ bar(void *p) static void recurse(void) { pthread_t s2; +#ifdef __FreeBSD__ + PTHREAD_REQUIRE(pthread_create(&s2, 0, bar, 0)); +#else pthread_create(&s2, 0, bar, 0); +#endif sleep(20); /* XXX must be long enough for our slowest machine */ } @@ -134,7 +153,11 @@ ATF_TC_BODY(fpu, tc) PTHREAD_REQUIRE(pthread_mutex_init(&recursion_depth_lock, 0)); +#ifdef __FreeBSD__ + PTHREAD_REQUIRE(pthread_create(&s5, 0, stir, stirseed)); +#else pthread_create(&s5, 0, stir, stirseed); +#endif recurse(); atf_tc_fail("exiting from main"); diff --git a/contrib/ngatm/snmp_atm/snmp_atm.c b/contrib/ngatm/snmp_atm/snmp_atm.c index c922c6f..a2590ae 100644 --- a/contrib/ngatm/snmp_atm/snmp_atm.c +++ b/contrib/ngatm/snmp_atm/snmp_atm.c @@ -170,7 +170,7 @@ atmif_check_carrier(struct atmif_priv *aif) aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; return; } - if (!ifmr.ifm_status & IFM_AVALID) { + if (!(ifmr.ifm_status & IFM_AVALID)) { aif->pub.carrier = ATMIF_CARRIER_UNKNOWN; return; } diff --git a/contrib/tcp_wrappers/clean_exit.c b/contrib/tcp_wrappers/clean_exit.c index cb9d4f5..41caaf0 100644 --- a/contrib/tcp_wrappers/clean_exit.c +++ b/contrib/tcp_wrappers/clean_exit.c @@ -13,6 +13,7 @@ static char sccsid[] = "@(#) clean_exit.c 1.4 94/12/28 17:42:19"; #endif #include <stdio.h> +#include <unistd.h> extern void exit(); diff --git a/contrib/tcp_wrappers/hosts_access.c b/contrib/tcp_wrappers/hosts_access.c index 03d305b..af0433b 100644 --- a/contrib/tcp_wrappers/hosts_access.c +++ b/contrib/tcp_wrappers/hosts_access.c @@ -44,6 +44,7 @@ static char sccsid[] = "@(#) hosts_access.c 1.21 97/02/12 02:13:22"; #ifdef INET6 #include <netdb.h> #endif +#include <stdlib.h> extern char *fgets(); extern int errno; @@ -102,6 +103,11 @@ static int masked_match6(); #define BUFLEN 2048 +/* definition to be used from workarounds.c */ +#ifdef NETGROUP +int yp_get_default_domain(char **); +#endif + /* hosts_access - host access control facility */ int hosts_access(request) @@ -269,7 +275,7 @@ struct request_info *request; static int hostfile_match(path, host) char *path; -struct hosts_info *host; +struct host_info *host; { char tok[BUFSIZ]; int match = NO; diff --git a/contrib/tcp_wrappers/options.c b/contrib/tcp_wrappers/options.c index 97d3127..04ae174 100644 --- a/contrib/tcp_wrappers/options.c +++ b/contrib/tcp_wrappers/options.c @@ -50,6 +50,8 @@ static char sccsid[] = "@(#) options.c 1.17 96/02/11 17:01:31"; #include <ctype.h> #include <setjmp.h> #include <string.h> +#include <unistd.h> +#include <stdlib.h> #ifndef MAXPATHNAMELEN #define MAXPATHNAMELEN BUFSIZ @@ -441,16 +443,21 @@ struct request_info *request; /* severity_map - lookup facility or severity value */ static int severity_map(table, name) -CODE *table; +const CODE *table; char *name; { - CODE *t; + const CODE *t; + int ret = -1; for (t = table; t->c_name; t++) - if (STR_EQ(t->c_name, name)) - return (t->c_val); - tcpd_jump("bad syslog facility or severity: \"%s\"", name); - /* NOTREACHED */ + if (STR_EQ(t->c_name, name)) { + ret = t->c_val; + break; + } + if (ret == -1) + tcpd_jump("bad syslog facility or severity: \"%s\"", name); + + return (ret); } /* severity_option - change logging severity for this event (Dave Mitchell) */ diff --git a/contrib/tcp_wrappers/percent_x.c b/contrib/tcp_wrappers/percent_x.c index c95a1ea..9b37329 100644 --- a/contrib/tcp_wrappers/percent_x.c +++ b/contrib/tcp_wrappers/percent_x.c @@ -19,6 +19,7 @@ static char sccsid[] = "@(#) percent_x.c 1.4 94/12/28 17:42:37"; #include <stdio.h> #include <syslog.h> #include <string.h> +#include <unistd.h> extern void exit(); diff --git a/contrib/tcp_wrappers/rfc931.c b/contrib/tcp_wrappers/rfc931.c index e7fb3d1..924dac3 100644 --- a/contrib/tcp_wrappers/rfc931.c +++ b/contrib/tcp_wrappers/rfc931.c @@ -25,6 +25,7 @@ static char sccsid[] = "@(#) rfc931.c 1.10 95/01/02 16:11:34"; #include <setjmp.h> #include <signal.h> #include <string.h> +#include <unistd.h> #ifndef SEEK_SET #define SEEK_SET 0 diff --git a/contrib/tcp_wrappers/scaffold.c b/contrib/tcp_wrappers/scaffold.c index 8da9df0..bef8467 100644 --- a/contrib/tcp_wrappers/scaffold.c +++ b/contrib/tcp_wrappers/scaffold.c @@ -235,16 +235,6 @@ struct request_info *request; exit(0); } -/* dummy function to intercept the real rfc931() */ - -/* ARGSUSED */ - -void rfc931(request) -struct request_info *request; -{ - strcpy(request->user, unknown); -} - /* check_path - examine accessibility */ int check_path(path, st) diff --git a/contrib/tcp_wrappers/shell_cmd.c b/contrib/tcp_wrappers/shell_cmd.c index 62d31bc..4928636 100644 --- a/contrib/tcp_wrappers/shell_cmd.c +++ b/contrib/tcp_wrappers/shell_cmd.c @@ -16,10 +16,13 @@ static char sccsid[] = "@(#) shell_cmd.c 1.5 94/12/28 17:42:44"; #include <sys/types.h> #include <sys/param.h> +#include <sys/wait.h> #include <signal.h> #include <stdio.h> #include <syslog.h> #include <string.h> +#include <unistd.h> +#include <fcntl.h> extern void exit(); diff --git a/contrib/tcp_wrappers/tcpd.h b/contrib/tcp_wrappers/tcpd.h index af17c07..1078073 100644 --- a/contrib/tcp_wrappers/tcpd.h +++ b/contrib/tcp_wrappers/tcpd.h @@ -6,6 +6,17 @@ * $FreeBSD$ */ +#ifdef INET6 +#define TCPD_SOCKADDR struct sockaddr +#else +#define TCPD_SOCKADDR struct sockaddr_in +#endif + +#ifndef _STDFILE_DECLARED +#define _STDFILE_DECLARED +typedef struct __sFILE FILE; +#endif + /* Structure to describe one communications endpoint. */ #define STRING_LENGTH 128 /* hosts, users, processes */ @@ -13,11 +24,7 @@ struct host_info { char name[STRING_LENGTH]; /* access via eval_hostname(host) */ char addr[STRING_LENGTH]; /* access via eval_hostaddr(host) */ -#ifdef INET6 - struct sockaddr *sin; /* socket address or 0 */ -#else - struct sockaddr_in *sin; /* socket address or 0 */ -#endif + TCPD_SOCKADDR *sin; /* socket address or 0 */ struct t_unitdata *unit; /* TLI transport address or 0 */ struct request_info *request; /* for shared information */ }; @@ -67,21 +74,22 @@ extern char paranoid[]; /* Global functions. */ #if defined(TLI) || defined(PTX) || defined(TLI_SEQUENT) -extern void fromhost(); /* get/validate client host info */ +void fromhost(struct request_info *); /* get/validate client host info */ #else #define fromhost sock_host /* no TLI support needed */ #endif -extern int hosts_access(); /* access control */ -extern int hosts_ctl(); /* wrapper around request_init() */ -extern void shell_cmd(); /* execute shell command */ -extern char *percent_x(); /* do %<char> expansion */ -extern void rfc931(); /* client name from RFC 931 daemon */ -extern void clean_exit(); /* clean up and exit */ -extern void refuse(); /* clean up and exit */ -extern char *xgets(); /* fgets() on steroids */ -extern char *split_at(); /* strchr() and split */ -extern unsigned long dot_quad_addr(); /* restricted inet_addr() */ +int hosts_access(struct request_info *); /* access control */ +int hosts_ctl(char *, char *, char *, char *); /* wrapper around request_init() */ +void shell_cmd(char *); /* execute shell command */ +char *percent_x(char *, int, char *, struct request_info *); /* do %<char> expansion */ +void rfc931(TCPD_SOCKADDR *, TCPD_SOCKADDR *, char *); /* client name from RFC 931 daemon */ +void clean_exit(struct request_info *); /* clean up and exit */ +void refuse(struct request_info *); /* clean up and exit */ +char *xgets(char *, int, FILE *); /* fgets() on steroids */ + +char *split_at(char *, int); /* strchr() and split */ +unsigned long dot_quad_addr(char *); /* restricted inet_addr() */ /* Global variables. */ @@ -98,13 +106,8 @@ extern int resident; /* > 0 if resident process */ * attributes. Each attribute has its own key. */ -#ifdef __STDC__ -extern struct request_info *request_init(struct request_info *,...); -extern struct request_info *request_set(struct request_info *,...); -#else -extern struct request_info *request_init(); /* initialize request */ -extern struct request_info *request_set(); /* update request structure */ -#endif +struct request_info *request_init(struct request_info *,...); /* initialize request */ +struct request_info *request_set(struct request_info *,...); /* update request structure */ #define RQ_FILE 1 /* file descriptor */ #define RQ_DAEMON 2 /* server process (argv[0]) */ @@ -124,27 +127,27 @@ extern struct request_info *request_set(); /* update request structure */ * host_info structures serve as caches for the lookup results. */ -extern char *eval_user(); /* client user */ -extern char *eval_hostname(); /* printable hostname */ -extern char *eval_hostaddr(); /* printable host address */ -extern char *eval_hostinfo(); /* host name or address */ -extern char *eval_client(); /* whatever is available */ -extern char *eval_server(); /* whatever is available */ +char *eval_user(struct request_info *); /* client user */ +char *eval_hostname(struct host_info *); /* printable hostname */ +char *eval_hostaddr(struct host_info *); /* printable host address */ +char *eval_hostinfo(struct host_info *); /* host name or address */ +char *eval_client(struct request_info *); /* whatever is available */ +char *eval_server(struct request_info *); /* whatever is available */ #define eval_daemon(r) ((r)->daemon) /* daemon process name */ #define eval_pid(r) ((r)->pid) /* process id */ /* Socket-specific methods, including DNS hostname lookups. */ -extern void sock_host(); /* look up endpoint addresses */ -extern void sock_hostname(); /* translate address to hostname */ -extern void sock_hostaddr(); /* address to printable address */ +void sock_host(struct request_info *); /* look up endpoint addresses */ +void sock_hostname(struct host_info *); /* translate address to hostname */ +void sock_hostaddr(struct host_info *); /* address to printable address */ #define sock_methods(r) \ { (r)->hostname = sock_hostname; (r)->hostaddr = sock_hostaddr; } /* The System V Transport-Level Interface (TLI) interface. */ #if defined(TLI) || defined(PTX) || defined(TLI_SEQUENT) -extern void tli_host(); /* look up endpoint addresses etc. */ +void tli_host(struct request_info *); /* look up endpoint addresses etc. */ #endif /* @@ -153,13 +156,8 @@ extern void tli_host(); /* look up endpoint addresses etc. */ * everyone would have to include <setjmp.h>. */ -#ifdef __STDC__ -extern void tcpd_warn(char *, ...); /* report problem and proceed */ -extern void tcpd_jump(char *, ...); /* report problem and jump */ -#else -extern void tcpd_warn(); -extern void tcpd_jump(); -#endif +void tcpd_warn(char *, ...); /* report problem and proceed */ +void tcpd_jump(char *, ...); /* report problem and jump */ struct tcpd_context { char *file; /* current file */ @@ -185,42 +183,42 @@ extern struct tcpd_context tcpd_context; * behavior. */ -extern void process_options(); /* execute options */ -extern int dry_run; /* verification flag */ +void process_options(char *, struct request_info *); /* execute options */ +extern int dry_run; /* verification flag */ /* Bug workarounds. */ #ifdef INET_ADDR_BUG /* inet_addr() returns struct */ #define inet_addr fix_inet_addr -extern long fix_inet_addr(); +long fix_inet_addr(char *); #endif #ifdef BROKEN_FGETS /* partial reads from sockets */ #define fgets fix_fgets -extern char *fix_fgets(); +char *fix_fgets(char *, int, FILE *); #endif #ifdef RECVFROM_BUG /* no address family info */ #define recvfrom fix_recvfrom -extern int fix_recvfrom(); +int fix_recvfrom(int, char *, int, int, struct sockaddr *, int *); #endif #ifdef GETPEERNAME_BUG /* claims success with UDP */ #define getpeername fix_getpeername -extern int fix_getpeername(); +int fix_getpeername(int, struct sockaddr *, int *); #endif #ifdef SOLARIS_24_GETHOSTBYNAME_BUG /* lists addresses as aliases */ #define gethostbyname fix_gethostbyname -extern struct hostent *fix_gethostbyname(); +struct hostent *fix_gethostbyname(char *); #endif #ifdef USE_STRSEP /* libc calls strtok() */ #define strtok fix_strtok -extern char *fix_strtok(); +char *fix_strtok(char *, char *); #endif #ifdef LIBC_CALLS_STRTOK /* libc calls strtok() */ #define strtok my_strtok -extern char *my_strtok(); +char *my_strtok(char *, char *); #endif diff --git a/contrib/tcp_wrappers/update.c b/contrib/tcp_wrappers/update.c index b612d5e..db73753 100644 --- a/contrib/tcp_wrappers/update.c +++ b/contrib/tcp_wrappers/update.c @@ -24,6 +24,7 @@ static char sccsid[] = "@(#) update.c 1.1 94/12/28 17:42:56"; #include <stdio.h> #include <syslog.h> #include <string.h> +#include <unistd.h> /* Local stuff. */ diff --git a/contrib/xz/ChangeLog b/contrib/xz/ChangeLog index 27d9ea4..781b673 100644 --- a/contrib/xz/ChangeLog +++ b/contrib/xz/ChangeLog @@ -1,3 +1,563 @@ +commit 3d566cd519017eee1a400e7961ff14058dfaf33c +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-12-30 13:26:36 +0200 + + Bump version and soname for 5.2.3. + + src/liblzma/Makefile.am | 2 +- + src/liblzma/api/lzma/version.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 053e624fe33795e779ff736f16ce44a129c829b5 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-12-30 13:25:10 +0200 + + Update NEWS for 5.2.3. + + NEWS | 39 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 39 insertions(+) + +commit cae412b2b77d7fd88d187ed7659331709311f80d +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-04-01 14:45:25 +0300 + + xz: Fix the Capsicum rights on user_abort_pipe. + + src/xz/file_io.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +commit 9ccbae41000572193b9a09e7102f9e84dc6d96de +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-12-28 21:05:22 +0200 + + Mention potential sandboxing bugs in INSTALL. + + INSTALL | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit e013a337d3de77cce24360dffe956ea2339489b6 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-11-21 20:24:50 +0200 + + liblzma: Avoid multiple definitions of lzma_coder structures. + + Only one definition was visible in a translation unit. + It avoided a few casts and temp variables but seems that + this hack doesn't work with link-time optimizations in compilers + as it's not C99/C11 compliant. + + Fixes: + http://www.mail-archive.com/xz-devel@tukaani.org/msg00279.html + + src/liblzma/common/alone_decoder.c | 44 +++++---- + src/liblzma/common/alone_encoder.c | 34 ++++--- + src/liblzma/common/auto_decoder.c | 35 ++++--- + src/liblzma/common/block_decoder.c | 41 ++++---- + src/liblzma/common/block_encoder.c | 40 ++++---- + src/liblzma/common/common.h | 18 ++-- + src/liblzma/common/index_decoder.c | 33 ++++--- + src/liblzma/common/index_encoder.c | 16 ++-- + src/liblzma/common/stream_decoder.c | 50 +++++----- + src/liblzma/common/stream_encoder.c | 56 ++++++----- + src/liblzma/common/stream_encoder_mt.c | 124 ++++++++++++++----------- + src/liblzma/delta/delta_common.c | 25 ++--- + src/liblzma/delta/delta_decoder.c | 6 +- + src/liblzma/delta/delta_encoder.c | 12 ++- + src/liblzma/delta/delta_private.h | 4 +- + src/liblzma/lz/lz_decoder.c | 60 ++++++------ + src/liblzma/lz/lz_decoder.h | 13 ++- + src/liblzma/lz/lz_encoder.c | 57 +++++++----- + src/liblzma/lz/lz_encoder.h | 9 +- + src/liblzma/lzma/lzma2_decoder.c | 32 ++++--- + src/liblzma/lzma/lzma2_encoder.c | 51 +++++----- + src/liblzma/lzma/lzma_decoder.c | 27 +++--- + src/liblzma/lzma/lzma_encoder.c | 29 +++--- + src/liblzma/lzma/lzma_encoder.h | 9 +- + src/liblzma/lzma/lzma_encoder_optimum_fast.c | 3 +- + src/liblzma/lzma/lzma_encoder_optimum_normal.c | 23 ++--- + src/liblzma/lzma/lzma_encoder_private.h | 6 +- + src/liblzma/simple/arm.c | 2 +- + src/liblzma/simple/armthumb.c | 2 +- + src/liblzma/simple/ia64.c | 2 +- + src/liblzma/simple/powerpc.c | 2 +- + src/liblzma/simple/simple_coder.c | 61 ++++++------ + src/liblzma/simple/simple_private.h | 12 +-- + src/liblzma/simple/sparc.c | 2 +- + src/liblzma/simple/x86.c | 15 +-- + 35 files changed, 532 insertions(+), 423 deletions(-) + +commit 8e0f1af3dcaec00a3879cce8ad7441edc6359d1c +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-12-26 20:50:25 +0200 + + Document --enable-sandbox configure option in INSTALL. + + INSTALL | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +commit ce2542d220de06acd618fd9f5c0a6683029fb4eb +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-03-31 22:19:34 +0300 + + xz: Add support for sandboxing with Capsicum (disabled by default). + + In the v5.2 branch this feature is considered experimental + and thus disabled by default. + + The sandboxing is used conditionally as described in main.c. + This isn't optimal but it was much easier to implement than + a full sandboxing solution and it still covers the most common + use cases where xz is writing to standard output. This should + have practically no effect on performance even with small files + as fork() isn't needed. + + C and locale libraries can open files as needed. This has been + fine in the past, but it's a problem with things like Capsicum. + io_sandbox_enter() tries to ensure that various locale-related + files have been loaded before cap_enter() is called, but it's + possible that there are other similar problems which haven't + been seen yet. + + Currently Capsicum is available on FreeBSD 10 and later + and there is a port to Linux too. + + Thanks to Loganaden Velvindron for help. + + configure.ac | 41 +++++++++++++++++++++++++++ + src/xz/Makefile.am | 2 +- + src/xz/file_io.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/xz/file_io.h | 6 ++++ + src/xz/main.c | 18 ++++++++++++ + src/xz/private.h | 4 +++ + 6 files changed, 151 insertions(+), 1 deletion(-) + +commit 3ca1d5e6320111043e19434da881065fadafa0e4 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-03-31 21:12:30 +0300 + + Fix bugs and otherwise improve ax_check_capsicum.m4. + + AU_ALIAS was removed because the new version is incompatible + with the old version. + + It no longer checks for <sys/capability.h> separately. + It's enough to test for it as part of AC_CHECK_DECL. + The defines HAVE_CAPSICUM_SYS_CAPSICUM_H and + HAVE_CAPSICUM_SYS_CAPABILITY_H were removed as unneeded. + HAVE_SYS_CAPSICUM_H from AC_CHECK_HEADERS is enough. + + It no longer does a useless search for the Capsicum library + if the header wasn't found. + + Fixed a bug in ACTION-IF-FOUND (the first argument). Specifying + the argument omitted the default action but the given action + wasn't used instead. + + AC_DEFINE([HAVE_CAPSICUM]) is now always called when Capsicum + support is found. Previously it was part of the default + ACTION-IF-FOUND which a custom action would override. Now + the default action only prepends ${CAPSICUM_LIB} to LIBS. + + The documentation was updated. + + Since there as no serial number, "#serial 2" was added. + + m4/ax_check_capsicum.m4 | 103 ++++++++++++++++++++++++------------------------ + 1 file changed, 51 insertions(+), 52 deletions(-) + +commit 5f3a742b64197fe8bedb6f05fc6ce5d177d11145 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-03-31 19:20:24 +0300 + + Add m4/ax_check_capsicum.m4 for detecting Capsicum support. + + The file was loaded from this web page: + https://github.com/google/capsicum-test/blob/dev/autoconf/m4/ax_check_capsicum.m4 + + Thanks to Loganaden Velvindron for pointing it out for me. + + m4/ax_check_capsicum.m4 | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 86 insertions(+) + +commit d74377e62b4c649e40294dd441de72c0f092e67c +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-10-12 20:29:09 +0300 + + liblzma: Fix a memory leak in error path of lzma_index_dup(). + + lzma_index_dup() calls index_dup_stream() which, in case of + an error, calls index_stream_end() to free memory allocated + by index_stream_init(). However, it illogically didn't + actually free the memory. To make it logical, the tree + handling code was modified a bit in addition to changing + index_stream_end(). + + Thanks to Evan Nemerson for the bug report. + + src/liblzma/common/index.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +commit f580732216dcf971f3f006fe8e01cd4979e1d964 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-10-24 18:53:25 +0300 + + Update THANKS. + + THANKS | 1 + + 1 file changed, 1 insertion(+) + +commit 88d7a7fd153bf1355cdf798ffdac7443d0169afc +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-10-24 18:51:36 +0300 + + tuklib_cpucores: Add support for sched_getaffinity(). + + It's available in glibc (GNU/Linux, GNU/kFreeBSD). It's better + than sysconf(_SC_NPROCESSORS_ONLN) because sched_getaffinity() + gives the number of cores available to the process instead of + the total number of cores online. + + As a side effect, this commit fixes a bug on GNU/kFreeBSD where + configure would detect the FreeBSD-specific cpuset_getaffinity() + but it wouldn't actually work because on GNU/kFreeBSD it requires + using -lfreebsd-glue when linking. Now the glibc-specific function + will be used instead. + + Thanks to Sebastian Andrzej Siewior for the original patch + and testing. + + m4/tuklib_cpucores.m4 | 30 +++++++++++++++++++++++++++++- + src/common/tuklib_cpucores.c | 9 +++++++++ + 2 files changed, 38 insertions(+), 1 deletion(-) + +commit 51baf684376903dbeddd840582bfdf9fa91b311b +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-06-30 20:27:36 +0300 + + xz: Fix copying of timestamps on Windows. + + xz used to call utime() on Windows, but its result gets lost + on close(). Using _futime() seems to work. + + Thanks to Martok for reporting the bug: + http://www.mail-archive.com/xz-devel@tukaani.org/msg00261.html + + configure.ac | 2 +- + src/xz/file_io.c | 18 ++++++++++++++++++ + 2 files changed, 19 insertions(+), 1 deletion(-) + +commit 1ddc479851139d6e8202e5835421bfe6578d9e07 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-06-16 22:46:02 +0300 + + xz: Silence warnings from -Wlogical-op. + + Thanks to Evan Nemerson. + + src/xz/file_io.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +commit be647ff5ed5a1c244a65722af6ce250259f3b14a +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-04-10 20:55:49 +0300 + + Build: Fix = to += for xz_SOURCES in src/xz/Makefile.am. + + Thanks to Christian Kujau. + + src/xz/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit fb6d50c15343831f35305982cefa82053099191d +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-04-10 20:54:17 +0300 + + Build: Bump GNU Gettext version requirement to 0.19. + + It silences a few warnings and most people probably have + 0.19 even on stable distributions. + + Thanks to Christian Kujau. + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 74f8dad9f912a2993768d93d108ea2b0b2c196e0 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-03-13 20:21:49 +0200 + + liblzma: Disable external SHA-256 by default. + + This is the sane thing to do. The conflict with OpenSSL + on some OSes and especially that the OS-provided versions + can be significantly slower makes it clear that it was + a mistake to have the external SHA-256 support enabled by + default. + + Those who want it can now pass --enable-external-sha256 to + configure. INSTALL was updated with notes about OSes where + this can be a bad idea. + + The SHA-256 detection code in configure.ac had some bugs that + could lead to a build failure in some situations. These were + fixed, although it doesn't matter that much now that the + external SHA-256 is disabled by default. + + MINIX >= 3.2.0 uses NetBSD's libc and thus has SHA256_Init + in libc instead of libutil. Support for the libutil version + was removed. + + INSTALL | 36 ++++++++++++++++++++++ + configure.ac | 76 +++++++++++++++++++++++------------------------ + src/liblzma/check/check.h | 16 ++++------ + 3 files changed, 79 insertions(+), 49 deletions(-) + +commit ea7f6ff04cb5bb1498088eb09960a4c3f13dfe39 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-03-10 20:27:05 +0200 + + Update THANKS. + + THANKS | 1 + + 1 file changed, 1 insertion(+) + +commit d0e018016b311232e82d9a98dc68f1e3dabce794 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2016-03-10 20:26:49 +0200 + + Build: Avoid SHA256_Init on FreeBSD and MINIX 3. + + On FreeBSD 10 and older, SHA256_Init from libmd conflicts + with libcrypto from OpenSSL. The OpenSSL version has + different sizeof(SHA256_CTX) and it can cause weird + problems if wrong SHA256_Init gets used. + + Looking at the source, MINIX 3 seems to have a similar issue but + I'm not sure. To be safe, I disabled SHA256_Init on MINIX 3 too. + + NetBSD has SHA256_Init in libc and they had a similar problem, + but they already fixed it in 2009. + + Thanks to Jim Wilcoxson for the bug report that helped + in finding the problem. + + configure.ac | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +commit 5daae123915f32a4ed6dc948b831533c2d1beec3 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-08 20:16:10 +0200 + + tuklib_physmem: Hopefully silence a warning on Windows. + + src/common/tuklib_physmem.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 491acc406e098167ccb7fce0728b94c2f32cff9f +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-04 23:17:43 +0200 + + Update THANKS. + + THANKS | 1 + + 1 file changed, 1 insertion(+) + +commit 8173ff8790ad3502d04e1c07d014cb84a3b8187b +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-04 23:14:00 +0200 + + liblzma: Make Valgrind happier with optimized (gcc -O2) liblzma. + + When optimizing, GCC can reorder code so that an uninitialized + value gets used in a comparison, which makes Valgrind unhappy. + It doesn't happen when compiled with -O0, which I tend to use + when running Valgrind. + + Thanks to Rich Prohaska. I remember this being mentioned long + ago by someone else but nothing was done back then. + + src/liblzma/lz/lz_encoder.c | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 013de2b5ab8094d2c82a2771f3d143eeb656eda9 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-03 20:55:45 +0200 + + liblzma: Rename lzma_presets.c back to lzma_encoder_presets.c. + + It would be too annoying to update other build systems + just because of this. + + src/liblzma/lzma/Makefile.inc | 2 +- + src/liblzma/lzma/{lzma_presets.c => lzma_encoder_presets.c} | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit a322f70ad96de88968c2c36e6a36bc08ae30bd20 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-03 20:47:07 +0200 + + Build: Disable xzdec, lzmadec, and lzmainfo when they cannot be built. + + They all need decoder support and if that isn't available, + there's no point trying to build them. + + configure.ac | 3 +++ + 1 file changed, 3 insertions(+) + +commit 8ea49606cf6427e32319de7693eca9e43f1c8ad6 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-03 20:35:19 +0200 + + Build: Simplify $enable_{encoders,decoders} usage a bit. + + configure.ac | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 42131a25e52bfe400acfa7df93469a96bb78bb78 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-03 20:31:31 +0200 + + Windows/MSVC: Update config.h. + + windows/config.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit e9184e87cc989d14c7413e6adb3eca98f6ae0290 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-03 20:29:58 +0200 + + DOS: Update config.h. + + dos/config.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit 2296778f3c9a1e3a8699973b09dd3610b8baa402 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-03 20:29:33 +0200 + + xz: Make xz buildable even when encoders or decoders are disabled. + + The patch is quite long but it's mostly about adding new #ifdefs + to omit code when encoders or decoders have been disabled. + + This adds two new #defines to config.h: HAVE_ENCODERS and + HAVE_DECODERS. + + configure.ac | 4 ++++ + src/xz/Makefile.am | 8 ++++++-- + src/xz/args.c | 16 ++++++++++++++++ + src/xz/coder.c | 33 +++++++++++++++++++++++++-------- + src/xz/main.c | 9 +++++++-- + src/xz/private.h | 5 ++++- + 6 files changed, 62 insertions(+), 13 deletions(-) + +commit 97a3109281e475d9cf1b5095237d672fa0ad25e5 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-03 18:06:40 +0200 + + Build: Build LZMA1/2 presets also when only decoder is wanted. + + People shouldn't rely on the presets when decoding raw streams, + but xz uses the presets as the starting point for raw decoder + options anyway. + + lzma_encocder_presets.c was renamed to lzma_presets.c to + make it clear it's not used solely by the encoder code. + + src/liblzma/lzma/Makefile.inc | 6 +++++- + src/liblzma/lzma/{lzma_encoder_presets.c => lzma_presets.c} | 3 ++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +commit dc6b78d7f0f6fe43e9d4215146e8581feb8090e7 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-03 17:54:48 +0200 + + Build: Fix configure to handle LZMA1 dependency with LZMA2. + + Now it gives an error if LZMA1 encoder/decoder is missing + when LZMA2 encoder/decoder was requested. Even better would + be LZMA2 implicitly enabling LZMA1 but it would need more code. + + configure.ac | 5 ----- + 1 file changed, 5 deletions(-) + +commit 46d76c9cd3cb26a31f5ae6c3a8bbcf38e6da1add +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-03 17:41:54 +0200 + + Build: Don't omit lzma_cputhreads() unless using --disable-threads. + + Previously it was omitted if encoders were disabled + with --disable-encoders. It didn't make sense and + it also broke the build. + + src/liblzma/common/Makefile.inc | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 16d68f874d89f1e4a1919786a35bbaef7d71a077 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-02 18:16:51 +0200 + + liblzma: Fix a build failure related to external SHA-256 support. + + If an appropriate header and structure were found by configure, + but a library with a usable SHA-256 functions wasn't, the build + failed. + + src/liblzma/check/check.h | 32 +++++++++++++++++++++++--------- + 1 file changed, 23 insertions(+), 9 deletions(-) + +commit d9311647fc1ab512a3394596221ab8039c00af6b +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-11-02 15:19:10 +0200 + + xz: Always close the file before trying to delete it. + + unlink() can return EBUSY in errno for open files on some + operating systems and file systems. + + src/xz/file_io.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +commit f59c4183f3c9066626ce45dc3db4642fa603fa21 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-10-12 21:08:42 +0300 + + Update THANKS. + + THANKS | 1 + + 1 file changed, 1 insertion(+) + +commit 35f189673e280c12e4c5129f9f97e54eef3bbc04 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-10-12 21:07:41 +0300 + + Tests: Add tests for the two bugs fixed in index.c. + + tests/test_index.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +commit e10bfdb0fcaff12f3a6dadee51e0a022aadccb51 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-10-12 20:45:15 +0300 + + liblzma: Fix lzma_index_dup() for empty Streams. + + Stream Flags and Stream Padding weren't copied from + empty Streams. + + src/liblzma/common/index.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +commit 06f434bd8980f25ca23232eb7bb7df7e37dc8448 +Author: Lasse Collin <lasse.collin@tukaani.org> +Date: 2015-10-12 20:31:44 +0300 + + liblzma: Add a note to index.c for those using static analyzers. + + src/liblzma/common/index.c | 3 +++ + 1 file changed, 3 insertions(+) + commit 9815cdf6987ef91a85493bfcfd1ce2aaf3b47a0a Author: Lasse Collin <lasse.collin@tukaani.org> Date: 2015-09-29 13:59:35 +0300 @@ -129,11 +689,10 @@ Date: 2015-06-19 20:21:30 +0300 Windows: Update the docs. - INSTALL | 29 ++++++---- - windows/INSTALL-MSVC.txt | 47 +++++++++++++++ - windows/INSTALL-MinGW.txt | 138 ++++++++++++++++++++++++++++++++++++++++++++ - windows/INSTALL-Windows.txt | 138 -------------------------------------------- - 4 files changed, 204 insertions(+), 148 deletions(-) + INSTALL | 29 ++++++++----- + windows/INSTALL-MSVC.txt | 47 ++++++++++++++++++++++ + windows/{INSTALL-Windows.txt => INSTALL-MinGW.txt} | 2 +- + 3 files changed, 67 insertions(+), 11 deletions(-) commit 28195e4c877007cc760ecea1d17f740693d66873 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -1587,11 +2146,10 @@ Date: 2014-05-04 11:07:17 +0300 It can be confusing that two header files have the same name. The public API file is still lzma.h. - src/liblzma/api/Makefile.am | 2 +- - src/liblzma/api/lzma.h | 2 +- - src/liblzma/api/lzma/lzma.h | 420 ------------------------------------------ - src/liblzma/api/lzma/lzma12.h | 420 ++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 422 insertions(+), 422 deletions(-) + src/liblzma/api/Makefile.am | 2 +- + src/liblzma/api/lzma.h | 2 +- + src/liblzma/api/lzma/{lzma.h => lzma12.h} | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) commit 1555a9c5664afc7893a2b75e9970105437f01ef1 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -2650,20 +3208,20 @@ Date: 2012-11-19 00:10:10 -0800 with “|-”. That worked well for a while, but the version string from ‘less’ versions 448 (June, 2012) is misparsed, producing a warning: - $ xzless /tmp/test.xz; echo $? - /usr/bin/xzless: line 49: test: 456 (GNU regular expressions): \ - integer expression expected - 0 + $ xzless /tmp/test.xz; echo $? + /usr/bin/xzless: line 49: test: 456 (GNU regular expressions): \ + integer expression expected + 0 More precisely, modern ‘less’ lists the regexp implementation along with its version number, and xzless passes the entire version number with attached parenthetical phrase as a number to "test $a -gt $b", producing the above confusing message. - $ less-444 -V | head -1 - less 444 - $ less -V | head -1 - less 456 (no regular expressions) + $ less-444 -V | head -1 + less 444 + $ less -V | head -1 + less 456 (no regular expressions) So relax the pattern matched --- instead of expecting "less <number>", look for a line of the form "less <number>[ (extra parenthetical)]". @@ -3058,11 +3616,9 @@ Date: 2012-06-14 10:33:27 +0300 copied the decompressor bug from xz_pipe_decomp.c he has an example how to easily fix it. - doc/examples/xz_pipe_comp.c | 127 -------------------------------------- - doc/examples/xz_pipe_decomp.c | 123 ------------------------------------ - doc/examples_old/xz_pipe_comp.c | 127 ++++++++++++++++++++++++++++++++++++++ - doc/examples_old/xz_pipe_decomp.c | 123 ++++++++++++++++++++++++++++++++++++ - 4 files changed, 250 insertions(+), 250 deletions(-) + doc/{examples => examples_old}/xz_pipe_comp.c | 0 + doc/{examples => examples_old}/xz_pipe_decomp.c | 0 + 2 files changed, 0 insertions(+), 0 deletions(-) commit 905f0ab5b5ce544d4b68a2ed6077df0f3d021292 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -4159,10 +4715,9 @@ Date: 2011-04-10 14:58:10 +0300 DOS: Update the docs and include notes about 8.3 filenames. - dos/INSTALL.txt | 79 ++++++++++++++++++++++++++++++++++++ - dos/README | 88 ---------------------------------------- - dos/README.txt | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 202 insertions(+), 88 deletions(-) + dos/{README => INSTALL.txt} | 13 +---- + dos/README.txt | 123 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 125 insertions(+), 11 deletions(-) commit ebd54dbd6e481d31e80757f900ac8109ad1423c6 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -4279,10 +4834,9 @@ Date: 2011-04-05 17:12:20 +0300 It was renamed to ax_pthread.m4 in Autoconf Archive. - configure.ac | 2 +- - m4/acx_pthread.m4 | 279 ----------------------------------------------------- - m4/ax_pthread.m4 | 283 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 284 insertions(+), 280 deletions(-) + configure.ac | 2 +- + m4/{acx_pthread.m4 => ax_pthread.m4} | 170 ++++++++++++++++++----------------- + 2 files changed, 88 insertions(+), 84 deletions(-) commit 1039bfcfc098b69d56ecb39d198a092552eacf6d Author: Lasse Collin <lasse.collin@tukaani.org> @@ -4664,10 +5218,10 @@ Date: 2010-11-12 15:22:13 -0600 Builds from a separate build directory with - mkdir build - cd build - ../configure - doxygen Doxyfile + mkdir build + cd build + ../configure + doxygen Doxyfile include an even longer prefix /home/someone/src/xz/src; this patch has the nice side-effect of eliminating that prefix, too. @@ -5232,12 +5786,11 @@ Date: 2010-09-28 10:59:53 +0300 Move version.sh to build-aux. - Makefile.am | 4 ++-- - build-aux/version.sh | 24 ++++++++++++++++++++++++ - configure.ac | 2 +- - version.sh | 24 ------------------------ - windows/build.bash | 2 +- - 5 files changed, 28 insertions(+), 28 deletions(-) + Makefile.am | 4 ++-- + version.sh => build-aux/version.sh | 0 + configure.ac | 2 +- + windows/build.bash | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) commit 84af9d8770451339a692e9b70f96cf56156a6069 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -5739,11 +6292,10 @@ Date: 2010-07-27 20:45:03 +0300 Windows: build.sh is a bash script so name it correctly. - INSTALL | 2 +- - windows/INSTALL-Windows.txt | 6 +- - windows/build.bash | 189 ++++++++++++++++++++++++++++++++++++++++++++ - windows/build.sh | 189 -------------------------------------------- - 4 files changed, 193 insertions(+), 193 deletions(-) + INSTALL | 2 +- + windows/INSTALL-Windows.txt | 6 +++--- + windows/{build.sh => build.bash} | 6 +++--- + 3 files changed, 7 insertions(+), 7 deletions(-) commit b1cbfd40f049a646a639eb78a3e41e9e3ef73339 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -7597,48 +8149,44 @@ Date: 2009-09-19 09:47:30 +0300 building XZ Utils on OpenVMS. Thanks to Jouk Jansen for the original patch. - THANKS | 1 + - configure.ac | 12 ++-- - m4/lc_cpucores.m4 | 57 ---------------- - m4/lc_physmem.m4 | 84 ----------------------- - m4/tuklib_common.m4 | 22 ++++++ - m4/tuklib_cpucores.m4 | 72 ++++++++++++++++++++ - m4/tuklib_physmem.m4 | 119 ++++++++++++++++++++++++++++++++ - m4/tuklib_progname.m4 | 25 +++++++ - src/common/cpucores.h | 51 -------------- - src/common/open_stdxxx.h | 49 -------------- - src/common/physmem.h | 144 --------------------------------------- - src/common/sysdefs.h | 4 -- - src/common/tuklib_common.h | 67 ++++++++++++++++++ - src/common/tuklib_config.h | 1 + - src/common/tuklib_cpucores.c | 46 +++++++++++++ - src/common/tuklib_cpucores.h | 23 +++++++ - src/common/tuklib_exit.c | 57 ++++++++++++++++ - src/common/tuklib_exit.h | 25 +++++++ - src/common/tuklib_gettext.h | 44 ++++++++++++ - src/common/tuklib_open_stdxxx.c | 51 ++++++++++++++ - src/common/tuklib_open_stdxxx.h | 23 +++++++ - src/common/tuklib_physmem.c | 146 ++++++++++++++++++++++++++++++++++++++++ - src/common/tuklib_physmem.h | 28 ++++++++ - src/common/tuklib_progname.c | 50 ++++++++++++++ - src/common/tuklib_progname.h | 32 +++++++++ - src/lzmainfo/Makefile.am | 5 +- - src/lzmainfo/lzmainfo.c | 65 ++++++------------ - src/xz/Makefile.am | 7 +- - src/xz/args.c | 8 +-- - src/xz/file_io.c | 43 ++++++------ - src/xz/hardware.c | 8 +-- - src/xz/main.c | 100 ++++++--------------------- - src/xz/main.h | 7 -- - src/xz/message.c | 30 +++++---- - src/xz/message.h | 8 +-- - src/xz/private.h | 11 +-- - src/xz/signals.c | 2 + - src/xz/signals.h | 17 +++-- - src/xz/suffix.c | 2 +- - src/xzdec/Makefile.am | 13 +++- - src/xzdec/xzdec.c | 55 +++++---------- - 41 files changed, 974 insertions(+), 640 deletions(-) + THANKS | 1 + + configure.ac | 12 +-- + m4/lc_physmem.m4 | 84 --------------- + m4/tuklib_common.m4 | 22 ++++ + m4/{lc_cpucores.m4 => tuklib_cpucores.m4} | 83 ++++++++------ + m4/tuklib_physmem.m4 | 119 +++++++++++++++++++++ + m4/tuklib_progname.m4 | 25 +++++ + src/common/sysdefs.h | 4 - + src/common/tuklib_common.h | 67 ++++++++++++ + src/common/tuklib_config.h | 1 + + src/common/{cpucores.h => tuklib_cpucores.c} | 39 +++---- + src/common/tuklib_cpucores.h | 23 ++++ + src/common/tuklib_exit.c | 57 ++++++++++ + src/common/tuklib_exit.h | 25 +++++ + src/common/tuklib_gettext.h | 44 ++++++++ + src/common/{open_stdxxx.h => tuklib_open_stdxxx.c} | 24 +++-- + src/common/tuklib_open_stdxxx.h | 23 ++++ + src/common/{physmem.h => tuklib_physmem.c} | 58 +++++----- + src/common/tuklib_physmem.h | 28 +++++ + src/common/tuklib_progname.c | 50 +++++++++ + src/common/tuklib_progname.h | 32 ++++++ + src/lzmainfo/Makefile.am | 5 +- + src/lzmainfo/lzmainfo.c | 65 ++++------- + src/xz/Makefile.am | 7 +- + src/xz/args.c | 8 +- + src/xz/file_io.c | 43 ++++---- + src/xz/hardware.c | 8 +- + src/xz/main.c | 100 ++++------------- + src/xz/main.h | 7 -- + src/xz/message.c | 30 +++--- + src/xz/message.h | 8 +- + src/xz/private.h | 11 +- + src/xz/signals.c | 2 + + src/xz/signals.h | 17 ++- + src/xz/suffix.c | 2 +- + src/xzdec/Makefile.am | 13 ++- + src/xzdec/xzdec.c | 55 +++------- + 37 files changed, 768 insertions(+), 434 deletions(-) commit 49cfc8d392cf535f8dd10233225b1fc726fec9ef Author: Lasse Collin <lasse.collin@tukaani.org> @@ -8268,11 +8816,11 @@ Date: 2009-08-09 13:22:12 -0500 It can be somewhat confusing that - less < some_file.txt + less < some_file.txt works fine, whereas - xzless < some_file.txt.xz + xzless < some_file.txt.xz does not. Since version 429, ‘less’ allows a filter specified in the LESSOPEN environment variable to preprocess its input even if @@ -8760,18 +9308,13 @@ Date: 2009-06-27 17:28:01 +0300 Moved the Windows resource files outside the windows directory to prepare for building them with Autotools. - src/common/common_w32res.rc | 46 +++++++++++++++++++++++++++++++++++++++++++ - src/liblzma/liblzma_w32res.rc | 5 +++++ - src/xz/xz_w32res.rc | 5 +++++ - src/xzdec/lzmadec_w32res.rc | 5 +++++ - src/xzdec/xzdec_w32res.rc | 5 +++++ - windows/Makefile | 35 +++++++++++++++++--------------- - windows/common.rc | 46 ------------------------------------------- - windows/liblzma.rc | 5 ----- - windows/lzmadec.rc | 5 ----- - windows/xz.rc | 5 ----- - windows/xzdec.rc | 5 ----- - 11 files changed, 85 insertions(+), 82 deletions(-) + windows/common.rc => src/common/common_w32res.rc | 0 + .../liblzma.rc => src/liblzma/liblzma_w32res.rc | 2 +- + windows/xz.rc => src/xz/xz_w32res.rc | 2 +- + windows/lzmadec.rc => src/xzdec/lzmadec_w32res.rc | 2 +- + windows/xzdec.rc => src/xzdec/xzdec_w32res.rc | 2 +- + windows/Makefile | 35 ++++++++++++---------- + 6 files changed, 23 insertions(+), 20 deletions(-) commit 449c634674f35336a4815d398172e447659a135e Author: Lasse Collin <lasse.collin@tukaani.org> @@ -8853,19 +9396,15 @@ Date: 2009-06-26 20:49:54 +0300 to avoid problems on systems with system headers with those names. - dos/Makefile | 4 +- - src/xz/Makefile.am | 8 +- - src/xz/coder.c | 488 ++++++++++++++++++++++++++++++++++++ - src/xz/coder.h | 57 +++++ - src/xz/file_io.c | 716 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/xz/file_io.h | 86 +++++++ - src/xz/io.c | 716 ----------------------------------------------------- - src/xz/io.h | 86 ------- - src/xz/private.h | 4 +- - src/xz/process.c | 488 ------------------------------------ - src/xz/process.h | 57 ----- - windows/Makefile | 4 +- - 12 files changed, 1357 insertions(+), 1357 deletions(-) + dos/Makefile | 4 ++-- + src/xz/Makefile.am | 8 ++++---- + src/xz/{process.c => coder.c} | 0 + src/xz/{process.h => coder.h} | 0 + src/xz/{io.c => file_io.c} | 0 + src/xz/{io.h => file_io.h} | 0 + src/xz/private.h | 4 ++-- + windows/Makefile | 4 ++-- + 8 files changed, 10 insertions(+), 10 deletions(-) commit 5e1257466dcb66f1d7a3f71814a5ad885cba43e8 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -9247,9 +9786,8 @@ Date: 2009-05-01 11:20:23 +0300 Renamed the file format specification to xz-file-format.txt which is the filename used on the WWW. - doc/file-format.txt | 1127 ------------------------------------------------ - doc/xz-file-format.txt | 1127 ++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 1127 insertions(+), 1127 deletions(-) + doc/{file-format.txt => xz-file-format.txt} | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) commit 21c6b94373d239d7e86bd480fcd558e30391712f Author: Lasse Collin <lasse.collin@tukaani.org> @@ -9318,20 +9856,14 @@ Date: 2009-04-13 14:49:48 +0300 Quick & dirty update to support xz in diff/grep/more scripts. - src/scripts/Makefile.am | 38 +++++++++------ - src/scripts/lzdiff | 67 -------------------------- - src/scripts/lzdiff.1 | 51 -------------------- - src/scripts/lzgrep | 123 ------------------------------------------------ - src/scripts/lzgrep.1 | 61 ------------------------ - src/scripts/lzmore | 74 ----------------------------- - src/scripts/lzmore.1 | 55 ---------------------- - src/scripts/xzdiff | 67 ++++++++++++++++++++++++++ - src/scripts/xzdiff.1 | 58 +++++++++++++++++++++++ - src/scripts/xzgrep | 123 ++++++++++++++++++++++++++++++++++++++++++++++++ - src/scripts/xzgrep.1 | 77 ++++++++++++++++++++++++++++++ - src/scripts/xzmore | 74 +++++++++++++++++++++++++++++ - src/scripts/xzmore.1 | 66 ++++++++++++++++++++++++++ - 13 files changed, 489 insertions(+), 445 deletions(-) + src/scripts/Makefile.am | 38 +++++++++++++++++++----------- + src/scripts/{lzdiff => xzdiff} | 24 +++++++++---------- + src/scripts/{lzdiff.1 => xzdiff.1} | 29 ++++++++++++++--------- + src/scripts/{lzgrep => xzgrep} | 10 ++++---- + src/scripts/{lzgrep.1 => xzgrep.1} | 48 +++++++++++++++++++++++++------------- + src/scripts/{lzmore => xzmore} | 12 +++++----- + src/scripts/{lzmore.1 => xzmore.1} | 33 +++++++++++++++++--------- + 7 files changed, 119 insertions(+), 75 deletions(-) commit 02ddf09bc3079b3e17297729b9e43f14d407b8fc Author: Lasse Collin <lasse.collin@tukaani.org> @@ -9675,16 +10207,15 @@ Date: 2009-02-17 10:43:00 +0200 pieces to avoid unneeded dependencies making statically linked applications bigger than needed. - dos/Makefile | 6 +- - src/liblzma/common/easy.c | 128 ----------------------------- - src/liblzma/common/easy_buffer_encoder.c | 34 ++++++++ - src/liblzma/common/easy_decoder_memusage.c | 31 +++++++ - src/liblzma/common/easy_encoder.c | 87 ++++++++++++++++++++ - src/liblzma/common/easy_encoder_memusage.c | 31 +++++++ - src/liblzma/common/easy_preset.c | 34 ++++++++ - src/liblzma/common/easy_preset.h | 39 +++++++++ - windows/Makefile | 6 +- - 9 files changed, 266 insertions(+), 130 deletions(-) + dos/Makefile | 6 ++- + src/liblzma/common/easy_buffer_encoder.c | 34 +++++++++++++++++ + src/liblzma/common/easy_decoder_memusage.c | 31 ++++++++++++++++ + src/liblzma/common/{easy.c => easy_encoder.c} | 53 +++------------------------ + src/liblzma/common/easy_encoder_memusage.c | 31 ++++++++++++++++ + src/liblzma/common/easy_preset.c | 34 +++++++++++++++++ + src/liblzma/common/easy_preset.h | 39 ++++++++++++++++++++ + windows/Makefile | 6 ++- + 8 files changed, 185 insertions(+), 49 deletions(-) commit 7494816ab08d82f4d6409788825930c4e43cfd0d Author: Lasse Collin <lasse.collin@tukaani.org> @@ -10657,15 +11188,14 @@ Date: 2008-12-31 16:29:39 +0200 The internal implementation is still using the name "simple". It may need some cleanups, so I look at it later. - src/liblzma/api/Makefile.am | 2 +- - src/liblzma/api/lzma.h | 2 +- - src/liblzma/api/lzma/bcj.h | 94 +++++++++++++++++++++++++++++++++++++ - src/liblzma/api/lzma/simple.h | 94 ------------------------------------- - src/liblzma/simple/simple_coder.c | 2 +- - src/liblzma/simple/simple_decoder.c | 4 +- - src/liblzma/simple/simple_encoder.c | 4 +- - tests/test_filter_flags.c | 8 ++-- - 8 files changed, 105 insertions(+), 105 deletions(-) + src/liblzma/api/Makefile.am | 2 +- + src/liblzma/api/lzma.h | 2 +- + src/liblzma/api/lzma/{simple.h => bcj.h} | 22 +++++++++++----------- + src/liblzma/simple/simple_coder.c | 2 +- + src/liblzma/simple/simple_decoder.c | 4 ++-- + src/liblzma/simple/simple_encoder.c | 4 ++-- + tests/test_filter_flags.c | 8 ++++---- + 7 files changed, 22 insertions(+), 22 deletions(-) commit 7eea8bec3abfed883efba66264a1452a1c04f6b0 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -10719,47 +11249,44 @@ Date: 2008-12-31 00:30:49 +0200 as the more bloated uint32_t array on x86; hopefully it's not bad on other architectures. - configure.ac | 29 ++++++++-- - src/common/mythread.h | 34 ++++++++++++ - src/liblzma/api/Makefile.am | 1 - - src/liblzma/api/lzma.h | 1 - - src/liblzma/api/lzma/init.h | 85 ----------------------------- - src/liblzma/check/Makefile.am | 29 ++++------ - src/liblzma/check/check.c | 10 ++-- - src/liblzma/check/check.h | 25 ++++----- - src/liblzma/check/check_init.c | 37 ------------- - src/liblzma/check/crc32.c | 88 ------------------------------- - src/liblzma/check/crc32_fast.c | 88 +++++++++++++++++++++++++++++++ - src/liblzma/check/crc32_init.c | 55 ------------------- - src/liblzma/check/crc32_small.c | 54 +++++++++++++++++++ - src/liblzma/check/crc32_tablegen.c | 55 ++++++++++++++++--- - src/liblzma/check/crc64.c | 75 -------------------------- - src/liblzma/check/crc64_fast.c | 75 ++++++++++++++++++++++++++ - src/liblzma/check/crc64_small.c | 54 +++++++++++++++++++ - src/liblzma/check/crc64_tablegen.c | 55 ++++++++++++++++--- - src/liblzma/common/Makefile.am | 3 -- - src/liblzma/common/common.h | 1 + - src/liblzma/common/init.c | 39 -------------- - src/liblzma/common/init_decoder.c | 31 ----------- - src/liblzma/common/init_encoder.c | 40 -------------- - src/liblzma/liblzma.pc.in | 12 +++++ - src/liblzma/lz/lz_encoder.c | 6 +++ - src/liblzma/lzma.pc.in | 11 ---- - src/liblzma/rangecoder/Makefile.am | 8 +-- - src/liblzma/rangecoder/price.h | 16 +----- - src/liblzma/rangecoder/price_table.c | 2 +- - src/liblzma/rangecoder/price_table_init.c | 55 ------------------- - src/liblzma/rangecoder/price_tablegen.c | 51 +++++++++++++++--- - src/xz/Makefile.am | 5 +- - src/xz/main.c | 3 -- - src/xzdec/xzdec.c | 3 -- - tests/test_block_header.c | 1 - - tests/test_check.c | 2 - - tests/test_filter_flags.c | 2 - - tests/test_index.c | 2 - - tests/test_stream_flags.c | 2 - - tests/tests.h | 2 +- - 40 files changed, 519 insertions(+), 628 deletions(-) + configure.ac | 29 ++++++++-- + src/common/mythread.h | 34 ++++++++++++ + src/liblzma/api/Makefile.am | 1 - + src/liblzma/api/lzma.h | 1 - + src/liblzma/api/lzma/init.h | 85 ----------------------------- + src/liblzma/check/Makefile.am | 29 ++++------ + src/liblzma/check/check.c | 10 ++-- + src/liblzma/check/check.h | 25 +++------ + src/liblzma/check/check_init.c | 37 ------------- + src/liblzma/check/{crc32.c => crc32_fast.c} | 0 + src/liblzma/check/crc32_init.c | 55 ------------------- + src/liblzma/check/crc32_small.c | 54 ++++++++++++++++++ + src/liblzma/check/crc32_tablegen.c | 55 ++++++++++++++++--- + src/liblzma/check/{crc64.c => crc64_fast.c} | 0 + src/liblzma/check/crc64_small.c | 54 ++++++++++++++++++ + src/liblzma/check/crc64_tablegen.c | 55 ++++++++++++++++--- + src/liblzma/common/Makefile.am | 3 - + src/liblzma/common/common.h | 1 + + src/liblzma/common/init.c | 39 ------------- + src/liblzma/common/init_decoder.c | 31 ----------- + src/liblzma/common/init_encoder.c | 40 -------------- + src/liblzma/{lzma.pc.in => liblzma.pc.in} | 5 +- + src/liblzma/lz/lz_encoder.c | 6 ++ + src/liblzma/rangecoder/Makefile.am | 8 +-- + src/liblzma/rangecoder/price.h | 16 +----- + src/liblzma/rangecoder/price_table.c | 2 +- + src/liblzma/rangecoder/price_table_init.c | 55 ------------------- + src/liblzma/rangecoder/price_tablegen.c | 51 ++++++++++++++--- + src/xz/Makefile.am | 5 +- + src/xz/main.c | 3 - + src/xzdec/xzdec.c | 3 - + tests/test_block_header.c | 1 - + tests/test_check.c | 2 - + tests/test_filter_flags.c | 2 - + tests/test_index.c | 2 - + tests/test_stream_flags.c | 2 - + tests/tests.h | 2 +- + 37 files changed, 347 insertions(+), 456 deletions(-) commit 5cda29b5665004fc0f21d0c41d78022a6a559ab2 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -11212,58 +11739,35 @@ Date: 2008-11-19 23:52:24 +0200 compatibility with LZMA Utils 4.32.x; I'm not sure if this should be the default though. - configure.ac | 4 +- - po/POTFILES.in | 21 +- - src/Makefile.am | 2 +- - src/lzma/Makefile.am | 72 ---- - src/lzma/args.c | 500 --------------------------- - src/lzma/args.h | 56 --- - src/lzma/hardware.c | 122 ------- - src/lzma/hardware.h | 45 --- - src/lzma/io.c | 658 ----------------------------------- - src/lzma/io.h | 97 ------ - src/lzma/list.c | 477 -------------------------- - src/lzma/main.c | 402 ---------------------- - src/lzma/main.h | 60 ---- - src/lzma/message.c | 892 ------------------------------------------------ - src/lzma/message.h | 132 ------- - src/lzma/options.c | 352 ------------------- - src/lzma/options.h | 46 --- - src/lzma/private.h | 52 --- - src/lzma/process.c | 391 --------------------- - src/lzma/process.h | 70 ---- - src/lzma/suffix.c | 213 ------------ - src/lzma/suffix.h | 40 --- - src/lzma/util.c | 199 ----------- - src/lzma/util.h | 71 ---- - src/lzmadec/Makefile.am | 29 -- - src/lzmadec/lzmadec.c | 492 -------------------------- - src/xz/Makefile.am | 74 ++++ - src/xz/args.c | 500 +++++++++++++++++++++++++++ - src/xz/args.h | 56 +++ - src/xz/hardware.c | 122 +++++++ - src/xz/hardware.h | 45 +++ - src/xz/io.c | 658 +++++++++++++++++++++++++++++++++++ - src/xz/io.h | 97 ++++++ - src/xz/list.c | 477 ++++++++++++++++++++++++++ - src/xz/main.c | 402 ++++++++++++++++++++++ - src/xz/main.h | 60 ++++ - src/xz/message.c | 892 ++++++++++++++++++++++++++++++++++++++++++++++++ - src/xz/message.h | 132 +++++++ - src/xz/options.c | 352 +++++++++++++++++++ - src/xz/options.h | 46 +++ - src/xz/private.h | 52 +++ - src/xz/process.c | 391 +++++++++++++++++++++ - src/xz/process.h | 70 ++++ - src/xz/suffix.c | 213 ++++++++++++ - src/xz/suffix.h | 40 +++ - src/xz/util.c | 199 +++++++++++ - src/xz/util.h | 71 ++++ - src/xzdec/Makefile.am | 29 ++ - src/xzdec/xzdec.c | 492 ++++++++++++++++++++++++++ - tests/test_compress.sh | 29 +- - tests/test_files.sh | 4 +- - 51 files changed, 5498 insertions(+), 5500 deletions(-) + configure.ac | 4 ++-- + po/POTFILES.in | 21 +++++++++------------ + src/Makefile.am | 2 +- + src/{lzma => xz}/Makefile.am | 32 +++++++++++++++++--------------- + src/{lzma => xz}/args.c | 0 + src/{lzma => xz}/args.h | 0 + src/{lzma => xz}/hardware.c | 0 + src/{lzma => xz}/hardware.h | 0 + src/{lzma => xz}/io.c | 0 + src/{lzma => xz}/io.h | 0 + src/{lzma => xz}/list.c | 0 + src/{lzma => xz}/main.c | 0 + src/{lzma => xz}/main.h | 0 + src/{lzma => xz}/message.c | 0 + src/{lzma => xz}/message.h | 0 + src/{lzma => xz}/options.c | 0 + src/{lzma => xz}/options.h | 0 + src/{lzma => xz}/private.h | 0 + src/{lzma => xz}/process.c | 0 + src/{lzma => xz}/process.h | 0 + src/{lzma => xz}/suffix.c | 0 + src/{lzma => xz}/suffix.h | 0 + src/{lzma => xz}/util.c | 0 + src/{lzma => xz}/util.h | 0 + src/{lzmadec => xzdec}/Makefile.am | 12 ++++++------ + src/{lzmadec/lzmadec.c => xzdec/xzdec.c} | 4 ++-- + tests/test_compress.sh | 29 ++++++++++++++--------------- + tests/test_files.sh | 4 ++-- + 28 files changed, 53 insertions(+), 55 deletions(-) commit e114502b2bc371e4a45449832cb69be036360722 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -11289,9 +11793,8 @@ Date: 2008-11-19 20:46:52 +0200 doc/file-format.txt | 260 ++++---- lib/Makefile.am | 10 +- lib/getopt.c | 14 +- - lib/getopt.in.h | 226 +++++++ + lib/{getopt_.h => getopt.in.h} | 8 +- lib/getopt1.c | 8 +- - lib/getopt_.h | 226 ------- lib/gettext.h | 240 ------- m4/getopt.m4 | 64 +- src/common/bswap.h | 15 +- @@ -11393,7 +11896,7 @@ Date: 2008-11-19 20:46:52 +0200 tests/files/unsupported-filter_flags-3.xz | Bin 68 -> 68 bytes tests/test_block_header.c | 16 +- tests/test_index.c | 42 +- - 113 files changed, 3462 insertions(+), 2946 deletions(-) + 112 files changed, 3240 insertions(+), 2724 deletions(-) commit 3c3905b53462ae235c9438d86a4dc51086410932 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -11467,123 +11970,66 @@ Date: 2008-09-30 17:43:55 +0300 Renamed the test files from .lzma suffix to .xz suffix. - tests/files/README | 128 ++++++++++++------------- - tests/files/bad-0-backward_size.lzma | Bin 32 -> 0 bytes - tests/files/bad-0-backward_size.xz | Bin 0 -> 32 bytes - tests/files/bad-0-empty-truncated.lzma | Bin 31 -> 0 bytes - tests/files/bad-0-empty-truncated.xz | Bin 0 -> 31 bytes - tests/files/bad-0-footer_magic.lzma | Bin 32 -> 0 bytes - tests/files/bad-0-footer_magic.xz | Bin 0 -> 32 bytes - tests/files/bad-0-header_magic.lzma | Bin 32 -> 0 bytes - tests/files/bad-0-header_magic.xz | Bin 0 -> 32 bytes - tests/files/bad-0-nonempty_index.lzma | Bin 32 -> 0 bytes - tests/files/bad-0-nonempty_index.xz | Bin 0 -> 32 bytes - tests/files/bad-0cat-alone.lzma | Bin 55 -> 0 bytes - tests/files/bad-0cat-alone.xz | Bin 0 -> 55 bytes - tests/files/bad-0cat-header_magic.lzma | Bin 64 -> 0 bytes - tests/files/bad-0cat-header_magic.xz | Bin 0 -> 64 bytes - tests/files/bad-0catpad-empty.lzma | Bin 69 -> 0 bytes - tests/files/bad-0catpad-empty.xz | Bin 0 -> 69 bytes - tests/files/bad-0pad-empty.lzma | Bin 37 -> 0 bytes - tests/files/bad-0pad-empty.xz | Bin 0 -> 37 bytes - tests/files/bad-1-block_header-1.lzma | Bin 64 -> 0 bytes - tests/files/bad-1-block_header-1.xz | Bin 0 -> 64 bytes - tests/files/bad-1-block_header-2.lzma | Bin 64 -> 0 bytes - tests/files/bad-1-block_header-2.xz | Bin 0 -> 64 bytes - tests/files/bad-1-block_header-3.lzma | Bin 68 -> 0 bytes - tests/files/bad-1-block_header-3.xz | Bin 0 -> 68 bytes - tests/files/bad-1-block_header-4.lzma | Bin 72 -> 0 bytes - tests/files/bad-1-block_header-4.xz | Bin 0 -> 72 bytes - tests/files/bad-1-check-crc32.lzma | Bin 68 -> 0 bytes - tests/files/bad-1-check-crc32.xz | Bin 0 -> 68 bytes - tests/files/bad-1-check-crc64.lzma | Bin 72 -> 0 bytes - tests/files/bad-1-check-crc64.xz | Bin 0 -> 72 bytes - tests/files/bad-1-check-sha256.lzma | Bin 96 -> 0 bytes - tests/files/bad-1-check-sha256.xz | Bin 0 -> 96 bytes - tests/files/bad-1-lzma2-1.lzma | Bin 64 -> 0 bytes - tests/files/bad-1-lzma2-1.xz | Bin 0 -> 64 bytes - tests/files/bad-1-lzma2-2.lzma | Bin 424 -> 0 bytes - tests/files/bad-1-lzma2-2.xz | Bin 0 -> 424 bytes - tests/files/bad-1-lzma2-3.lzma | Bin 424 -> 0 bytes - tests/files/bad-1-lzma2-3.xz | Bin 0 -> 424 bytes - tests/files/bad-1-lzma2-4.lzma | Bin 408 -> 0 bytes - tests/files/bad-1-lzma2-4.xz | Bin 0 -> 408 bytes - tests/files/bad-1-lzma2-5.lzma | Bin 408 -> 0 bytes - tests/files/bad-1-lzma2-5.xz | Bin 0 -> 408 bytes - tests/files/bad-1-lzma2-6.lzma | Bin 68 -> 0 bytes - tests/files/bad-1-lzma2-6.xz | Bin 0 -> 68 bytes - tests/files/bad-1-lzma2-7.lzma | Bin 408 -> 0 bytes - tests/files/bad-1-lzma2-7.xz | Bin 0 -> 408 bytes - tests/files/bad-1-stream_flags-1.lzma | Bin 68 -> 0 bytes - tests/files/bad-1-stream_flags-1.xz | Bin 0 -> 68 bytes - tests/files/bad-1-stream_flags-2.lzma | Bin 68 -> 0 bytes - tests/files/bad-1-stream_flags-2.xz | Bin 0 -> 68 bytes - tests/files/bad-1-stream_flags-3.lzma | Bin 68 -> 0 bytes - tests/files/bad-1-stream_flags-3.xz | Bin 0 -> 68 bytes - tests/files/bad-1-vli-1.lzma | Bin 72 -> 0 bytes - tests/files/bad-1-vli-1.xz | Bin 0 -> 72 bytes - tests/files/bad-1-vli-2.lzma | Bin 72 -> 0 bytes - tests/files/bad-1-vli-2.xz | Bin 0 -> 72 bytes - tests/files/bad-2-compressed_data_padding.lzma | Bin 92 -> 0 bytes - tests/files/bad-2-compressed_data_padding.xz | Bin 0 -> 92 bytes - tests/files/bad-2-index-1.lzma | Bin 92 -> 0 bytes - tests/files/bad-2-index-1.xz | Bin 0 -> 92 bytes - tests/files/bad-2-index-2.lzma | Bin 92 -> 0 bytes - tests/files/bad-2-index-2.xz | Bin 0 -> 92 bytes - tests/files/bad-2-index-3.lzma | Bin 92 -> 0 bytes - tests/files/bad-2-index-3.xz | Bin 0 -> 92 bytes - tests/files/bad-2-index-4.lzma | Bin 92 -> 0 bytes - tests/files/bad-2-index-4.xz | Bin 0 -> 92 bytes - tests/files/good-0-empty.lzma | Bin 32 -> 0 bytes - tests/files/good-0-empty.xz | Bin 0 -> 32 bytes - tests/files/good-0cat-empty.lzma | Bin 64 -> 0 bytes - tests/files/good-0cat-empty.xz | Bin 0 -> 64 bytes - tests/files/good-0catpad-empty.lzma | Bin 68 -> 0 bytes - tests/files/good-0catpad-empty.xz | Bin 0 -> 68 bytes - tests/files/good-0pad-empty.lzma | Bin 36 -> 0 bytes - tests/files/good-0pad-empty.xz | Bin 0 -> 36 bytes - tests/files/good-1-3delta-lzma2.lzma | Bin 528 -> 0 bytes - tests/files/good-1-3delta-lzma2.xz | Bin 0 -> 528 bytes - tests/files/good-1-block_header-1.lzma | Bin 72 -> 0 bytes - tests/files/good-1-block_header-1.xz | Bin 0 -> 72 bytes - tests/files/good-1-block_header-2.lzma | Bin 68 -> 0 bytes - tests/files/good-1-block_header-2.xz | Bin 0 -> 68 bytes - tests/files/good-1-block_header-3.lzma | Bin 68 -> 0 bytes - tests/files/good-1-block_header-3.xz | Bin 0 -> 68 bytes - tests/files/good-1-check-crc32.lzma | Bin 68 -> 0 bytes - tests/files/good-1-check-crc32.xz | Bin 0 -> 68 bytes - tests/files/good-1-check-crc64.lzma | Bin 72 -> 0 bytes - tests/files/good-1-check-crc64.xz | Bin 0 -> 72 bytes - tests/files/good-1-check-none.lzma | Bin 64 -> 0 bytes - tests/files/good-1-check-none.xz | Bin 0 -> 64 bytes - tests/files/good-1-check-sha256.lzma | Bin 96 -> 0 bytes - tests/files/good-1-check-sha256.xz | Bin 0 -> 96 bytes - tests/files/good-1-delta-lzma2.tiff.lzma | Bin 51312 -> 0 bytes - tests/files/good-1-delta-lzma2.tiff.xz | Bin 0 -> 51312 bytes - tests/files/good-1-lzma2-1.lzma | Bin 424 -> 0 bytes - tests/files/good-1-lzma2-1.xz | Bin 0 -> 424 bytes - tests/files/good-1-lzma2-2.lzma | Bin 424 -> 0 bytes - tests/files/good-1-lzma2-2.xz | Bin 0 -> 424 bytes - tests/files/good-1-lzma2-3.lzma | Bin 408 -> 0 bytes - tests/files/good-1-lzma2-3.xz | Bin 0 -> 408 bytes - tests/files/good-1-sparc-lzma2.lzma | Bin 2292 -> 0 bytes - tests/files/good-1-sparc-lzma2.xz | Bin 0 -> 2292 bytes - tests/files/good-1-x86-lzma2.lzma | Bin 1936 -> 0 bytes - tests/files/good-1-x86-lzma2.xz | Bin 0 -> 1936 bytes - tests/files/good-2-lzma2.lzma | Bin 92 -> 0 bytes - tests/files/good-2-lzma2.xz | Bin 0 -> 92 bytes - tests/files/unsupported-block_header.lzma | Bin 68 -> 0 bytes - tests/files/unsupported-block_header.xz | Bin 0 -> 68 bytes - tests/files/unsupported-check.lzma | Bin 68 -> 0 bytes - tests/files/unsupported-check.xz | Bin 0 -> 68 bytes - tests/files/unsupported-filter_flags-1.lzma | Bin 68 -> 0 bytes - tests/files/unsupported-filter_flags-1.xz | Bin 0 -> 68 bytes - tests/files/unsupported-filter_flags-2.lzma | Bin 68 -> 0 bytes - tests/files/unsupported-filter_flags-2.xz | Bin 0 -> 68 bytes - tests/files/unsupported-filter_flags-3.lzma | Bin 68 -> 0 bytes - tests/files/unsupported-filter_flags-3.xz | Bin 0 -> 68 bytes - tests/test_files.sh | 6 +- - 116 files changed, 66 insertions(+), 68 deletions(-) + tests/files/README | 128 ++++++++++----------- + ...0-backward_size.lzma => bad-0-backward_size.xz} | Bin + ...pty-truncated.lzma => bad-0-empty-truncated.xz} | Bin + ...d-0-footer_magic.lzma => bad-0-footer_magic.xz} | Bin + ...d-0-header_magic.lzma => bad-0-header_magic.xz} | Bin + ...nonempty_index.lzma => bad-0-nonempty_index.xz} | Bin + .../{bad-0cat-alone.lzma => bad-0cat-alone.xz} | Bin + ...-header_magic.lzma => bad-0cat-header_magic.xz} | Bin + ...bad-0catpad-empty.lzma => bad-0catpad-empty.xz} | Bin + .../{bad-0pad-empty.lzma => bad-0pad-empty.xz} | Bin + ...block_header-1.lzma => bad-1-block_header-1.xz} | Bin + ...block_header-2.lzma => bad-1-block_header-2.xz} | Bin + ...block_header-3.lzma => bad-1-block_header-3.xz} | Bin + ...block_header-4.lzma => bad-1-block_header-4.xz} | Bin + ...bad-1-check-crc32.lzma => bad-1-check-crc32.xz} | Bin + ...bad-1-check-crc64.lzma => bad-1-check-crc64.xz} | Bin + ...d-1-check-sha256.lzma => bad-1-check-sha256.xz} | Bin + .../files/{bad-1-lzma2-1.lzma => bad-1-lzma2-1.xz} | Bin + .../files/{bad-1-lzma2-2.lzma => bad-1-lzma2-2.xz} | Bin + .../files/{bad-1-lzma2-3.lzma => bad-1-lzma2-3.xz} | Bin + .../files/{bad-1-lzma2-4.lzma => bad-1-lzma2-4.xz} | Bin + .../files/{bad-1-lzma2-5.lzma => bad-1-lzma2-5.xz} | Bin + .../files/{bad-1-lzma2-6.lzma => bad-1-lzma2-6.xz} | Bin + .../files/{bad-1-lzma2-7.lzma => bad-1-lzma2-7.xz} | Bin + ...stream_flags-1.lzma => bad-1-stream_flags-1.xz} | Bin + ...stream_flags-2.lzma => bad-1-stream_flags-2.xz} | Bin + ...stream_flags-3.lzma => bad-1-stream_flags-3.xz} | Bin + tests/files/{bad-1-vli-1.lzma => bad-1-vli-1.xz} | Bin + tests/files/{bad-1-vli-2.lzma => bad-1-vli-2.xz} | Bin + ...dding.lzma => bad-2-compressed_data_padding.xz} | Bin + .../files/{bad-2-index-1.lzma => bad-2-index-1.xz} | Bin + .../files/{bad-2-index-2.lzma => bad-2-index-2.xz} | Bin + .../files/{bad-2-index-3.lzma => bad-2-index-3.xz} | Bin + .../files/{bad-2-index-4.lzma => bad-2-index-4.xz} | Bin + tests/files/{good-0-empty.lzma => good-0-empty.xz} | Bin + .../{good-0cat-empty.lzma => good-0cat-empty.xz} | Bin + ...od-0catpad-empty.lzma => good-0catpad-empty.xz} | Bin + .../{good-0pad-empty.lzma => good-0pad-empty.xz} | Bin + ...-1-3delta-lzma2.lzma => good-1-3delta-lzma2.xz} | Bin + ...lock_header-1.lzma => good-1-block_header-1.xz} | Bin + ...lock_header-2.lzma => good-1-block_header-2.xz} | Bin + ...lock_header-3.lzma => good-1-block_header-3.xz} | Bin + ...od-1-check-crc32.lzma => good-1-check-crc32.xz} | Bin + ...od-1-check-crc64.lzma => good-1-check-crc64.xz} | Bin + ...good-1-check-none.lzma => good-1-check-none.xz} | Bin + ...-1-check-sha256.lzma => good-1-check-sha256.xz} | Bin + ...-lzma2.tiff.lzma => good-1-delta-lzma2.tiff.xz} | Bin + .../{good-1-lzma2-1.lzma => good-1-lzma2-1.xz} | Bin + .../{good-1-lzma2-2.lzma => good-1-lzma2-2.xz} | Bin + .../{good-1-lzma2-3.lzma => good-1-lzma2-3.xz} | Bin + ...od-1-sparc-lzma2.lzma => good-1-sparc-lzma2.xz} | Bin + .../{good-1-x86-lzma2.lzma => good-1-x86-lzma2.xz} | Bin + tests/files/{good-2-lzma2.lzma => good-2-lzma2.xz} | Bin + ...ock_header.lzma => unsupported-block_header.xz} | Bin + ...unsupported-check.lzma => unsupported-check.xz} | Bin + ..._flags-1.lzma => unsupported-filter_flags-1.xz} | Bin + ..._flags-2.lzma => unsupported-filter_flags-2.xz} | Bin + ..._flags-3.lzma => unsupported-filter_flags-3.xz} | Bin + tests/test_files.sh | 6 +- + 59 files changed, 66 insertions(+), 68 deletions(-) commit 8e60c889a2816a63013a35c99ce26bf28f5b78eb Author: Lasse Collin <lasse.collin@tukaani.org> @@ -12174,7 +12620,7 @@ Date: 2008-08-28 22:53:15 +0300 configure.ac | 356 +++--- debug/Makefile.am | 5 +- - debug/crc32.c | 45 + + .../lz/lz_encoder_private.h => debug/crc32.c | 41 +- debug/full_flush.c | 14 +- debug/hex2bin.c | 54 + debug/known_sizes.c | 135 ++ @@ -12223,15 +12669,8 @@ Date: 2008-08-28 22:53:15 +0300 src/liblzma/common/block_header_decoder.c | 6 +- src/liblzma/common/block_header_encoder.c | 9 +- src/liblzma/common/block_util.c | 10 +- - src/liblzma/common/code.c | 203 --- - src/liblzma/common/common.c | 298 +++++ + src/liblzma/common/{code.c => common.c} | 129 +- src/liblzma/common/common.h | 237 ++-- - src/liblzma/common/delta_common.c | 66 - - src/liblzma/common/delta_common.h | 44 - - src/liblzma/common/delta_decoder.c | 61 - - src/liblzma/common/delta_decoder.h | 28 - - src/liblzma/common/delta_encoder.c | 98 -- - src/liblzma/common/delta_encoder.h | 28 - src/liblzma/common/easy.c | 18 +- src/liblzma/common/features.c | 66 - src/liblzma/common/filter_common.c | 262 ++++ @@ -12249,33 +12688,27 @@ Date: 2008-08-28 22:53:15 +0300 src/liblzma/common/memory_usage.c | 112 -- src/liblzma/common/next_coder.c | 65 - src/liblzma/common/raw_common.c | 127 -- - src/liblzma/common/raw_common.h | 30 - src/liblzma/common/raw_decoder.c | 116 -- - src/liblzma/common/raw_decoder.h | 29 - src/liblzma/common/raw_encoder.c | 111 -- - src/liblzma/common/raw_encoder.h | 29 - src/liblzma/common/stream_common.c | 23 - - src/liblzma/common/stream_common.h | 31 - src/liblzma/common/stream_decoder.c | 238 +++- src/liblzma/common/stream_decoder.h | 4 +- src/liblzma/common/stream_encoder.c | 35 +- src/liblzma/common/stream_encoder.h | 2 +- - src/liblzma/common/stream_flags_common.c | 40 + - src/liblzma/common/stream_flags_common.h | 31 + + ...{stream_flags_equal.c => stream_flags_common.c} | 14 +- + .../{stream_common.h => stream_flags_common.h} | 8 +- src/liblzma/common/stream_flags_decoder.c | 2 +- src/liblzma/common/stream_flags_encoder.c | 2 +- - src/liblzma/common/stream_flags_equal.c | 36 - - src/liblzma/common/version.c | 25 - src/liblzma/common/vli_decoder.c | 29 +- src/liblzma/common/vli_encoder.c | 23 +- - src/liblzma/common/vli_size.c | 37 + + src/liblzma/common/{version.c => vli_size.c} | 22 +- src/liblzma/delta/Makefile.am | 34 + - src/liblzma/delta/delta_common.c | 66 + - src/liblzma/delta/delta_common.h | 44 + - src/liblzma/delta/delta_decoder.c | 82 ++ - src/liblzma/delta/delta_decoder.h | 32 + - src/liblzma/delta/delta_encoder.c | 119 ++ - src/liblzma/delta/delta_encoder.h | 30 + + src/liblzma/{common => delta}/delta_common.c | 2 +- + src/liblzma/{common => delta}/delta_common.h | 0 + src/liblzma/{common => delta}/delta_decoder.c | 21 + + src/liblzma/{common => delta}/delta_decoder.h | 4 + + src/liblzma/{common => delta}/delta_encoder.c | 21 + + src/liblzma/{common => delta}/delta_encoder.h | 2 + src/liblzma/lz/Makefile.am | 35 +- src/liblzma/lz/bt2.c | 27 - src/liblzma/lz/bt2.h | 31 - @@ -12293,7 +12726,6 @@ Date: 2008-08-28 22:53:15 +0300 src/liblzma/lz/lz_encoder.h | 334 +++-- src/liblzma/lz/lz_encoder_hash.h | 104 ++ src/liblzma/lz/lz_encoder_mf.c | 780 ++++++++++++ - src/liblzma/lz/lz_encoder_private.h | 40 - src/liblzma/lz/match_c.h | 412 ------ src/liblzma/lz/match_h.h | 69 -- src/liblzma/lzma/Makefile.am | 37 +- @@ -12301,7 +12733,7 @@ Date: 2008-08-28 22:53:15 +0300 src/liblzma/lzma/lzma2_decoder.c | 318 +++++ src/liblzma/lzma/lzma2_decoder.h | 35 + src/liblzma/lzma/lzma2_encoder.c | 406 ++++++ - src/liblzma/lzma/lzma2_encoder.h | 34 + + .../{common/raw_common.h => lzma/lzma2_encoder.h} | 22 +- src/liblzma/lzma/lzma_common.h | 208 +++- src/liblzma/lzma/lzma_decoder.c | 1306 ++++++++++++-------- src/liblzma/lzma/lzma_decoder.h | 21 +- @@ -12320,18 +12752,17 @@ Date: 2008-08-28 22:53:15 +0300 src/liblzma/rangecoder/Makefile.am | 10 +- src/liblzma/rangecoder/price.h | 111 ++ src/liblzma/rangecoder/price_table.c | 84 +- - src/liblzma/rangecoder/price_table_gen.c | 55 - src/liblzma/rangecoder/price_table_init.c | 33 +- - src/liblzma/rangecoder/price_tablegen.c | 56 + + .../{price_table_gen.c => price_tablegen.c} | 19 +- src/liblzma/rangecoder/range_common.h | 17 +- src/liblzma/rangecoder/range_decoder.h | 209 ++-- src/liblzma/rangecoder/range_encoder.h | 92 +- src/liblzma/simple/Makefile.am | 12 + src/liblzma/simple/simple_coder.c | 8 +- src/liblzma/simple/simple_decoder.c | 47 + - src/liblzma/simple/simple_decoder.h | 29 + + .../raw_decoder.h => simple/simple_decoder.h} | 18 +- src/liblzma/simple/simple_encoder.c | 45 + - src/liblzma/simple/simple_encoder.h | 30 + + .../raw_encoder.h => simple/simple_encoder.h} | 17 +- src/liblzma/subblock/Makefile.am | 4 +- src/liblzma/subblock/subblock_decoder.c | 20 +- src/liblzma/subblock/subblock_decoder_helper.c | 2 +- @@ -12423,8 +12854,8 @@ Date: 2008-08-28 22:53:15 +0300 tests/files/good-1-lzma2-1.lzma | Bin 0 -> 424 bytes tests/files/good-1-lzma2-2.lzma | Bin 0 -> 424 bytes tests/files/good-1-lzma2-3.lzma | Bin 0 -> 408 bytes - tests/files/good-1-sparc-lzma2.lzma | Bin 0 -> 2292 bytes - tests/files/good-1-x86-lzma2.lzma | Bin 0 -> 1936 bytes + ...gle-sparc-lzma.lzma => good-1-sparc-lzma2.lzma} | Bin 2263 -> 2292 bytes + ...-single-x86-lzma.lzma => good-1-x86-lzma2.lzma} | Bin 1909 -> 1936 bytes tests/files/good-2-lzma2.lzma | Bin 0 -> 92 bytes tests/files/good-cat-single-none-pad.lzma | Bin 64 -> 0 bytes tests/files/good-multi-none-1.lzma | Bin 75 -> 0 bytes @@ -12447,11 +12878,9 @@ Date: 2008-08-28 22:53:15 +0300 tests/files/good-single-none-empty_3.lzma | Bin 19 -> 0 bytes tests/files/good-single-none-pad.lzma | Bin 32 -> 0 bytes tests/files/good-single-none.lzma | Bin 30 -> 0 bytes - tests/files/good-single-sparc-lzma.lzma | Bin 2263 -> 0 bytes tests/files/good-single-subblock-lzma.lzma | Bin 50 -> 0 bytes tests/files/good-single-subblock_implicit.lzma | Bin 35 -> 0 bytes tests/files/good-single-subblock_rle.lzma | Bin 118 -> 0 bytes - tests/files/good-single-x86-lzma.lzma | Bin 1909 -> 0 bytes tests/files/malicious-multi-metadata-64PiB.lzma | Bin 51 -> 0 bytes tests/files/malicious-single-subblock-256MiB.lzma | Bin 30 -> 0 bytes tests/files/malicious-single-subblock-64PiB.lzma | Bin 45 -> 0 bytes @@ -12466,7 +12895,7 @@ Date: 2008-08-28 22:53:15 +0300 tests/test_filter_flags.c | 51 +- tests/test_stream_flags.c | 4 +- tests/tests.h | 8 + - 294 files changed, 9768 insertions(+), 8195 deletions(-) + 277 files changed, 9050 insertions(+), 7477 deletions(-) commit 57b9a145a527f0716822615e5ed536d33aebd3fc Author: Lasse Collin <lasse.collin@tukaani.org> @@ -12542,122 +12971,116 @@ Date: 2008-06-18 18:02:10 +0300 updated once the encoded format of the Subblock filter has been decided. - configure.ac | 41 +- - debug/full_flush.c | 16 +- - debug/sync_flush.c | 15 +- - src/common/bswap.h | 44 ++ - src/common/integer.h | 167 +++++ - src/liblzma/api/Makefile.am | 5 +- - src/liblzma/api/lzma.h | 9 +- - src/liblzma/api/lzma/alone.h | 32 +- - src/liblzma/api/lzma/auto.h | 7 +- - src/liblzma/api/lzma/base.h | 15 + - src/liblzma/api/lzma/block.h | 306 +++------- - src/liblzma/api/lzma/check.h | 18 +- - src/liblzma/api/lzma/copy.h | 29 - - src/liblzma/api/lzma/easy.h | 61 +- - src/liblzma/api/lzma/extra.h | 114 ---- - src/liblzma/api/lzma/filter.h | 5 +- - src/liblzma/api/lzma/index.h | 204 ++++++- - src/liblzma/api/lzma/index_hash.h | 94 +++ - src/liblzma/api/lzma/info.h | 315 ---------- - src/liblzma/api/lzma/lzma.h | 2 +- - src/liblzma/api/lzma/metadata.h | 100 --- - src/liblzma/api/lzma/raw.h | 20 +- - src/liblzma/api/lzma/stream.h | 157 +---- - src/liblzma/api/lzma/stream_flags.h | 146 +++-- - src/liblzma/api/lzma/version.h | 2 +- - src/liblzma/api/lzma/vli.h | 83 ++- - src/liblzma/check/Makefile.am | 1 - - src/liblzma/check/check.c | 55 +- - src/liblzma/check/check.h | 47 +- - src/liblzma/check/check_byteswap.h | 43 -- - src/liblzma/check/crc32_init.c | 2 +- - src/liblzma/check/crc64_init.c | 2 +- - src/liblzma/check/crc_macros.h | 2 +- - src/liblzma/check/sha256.c | 53 +- - src/liblzma/common/Makefile.am | 31 +- - src/liblzma/common/alignment.c | 5 +- - src/liblzma/common/alone_decoder.c | 77 +-- - src/liblzma/common/alone_encoder.c | 99 ++- - src/liblzma/common/auto_decoder.c | 18 +- - src/liblzma/common/block_decoder.c | 298 +++------ - src/liblzma/common/block_encoder.c | 228 ++----- - src/liblzma/common/block_header_decoder.c | 400 +++--------- - src/liblzma/common/block_header_encoder.c | 207 +++---- - src/liblzma/common/block_private.h | 51 +- - src/liblzma/common/block_util.c | 73 +++ - src/liblzma/common/common.h | 44 +- - src/liblzma/common/copy_coder.c | 144 ----- - src/liblzma/common/copy_coder.h | 31 - - src/liblzma/common/delta_common.c | 4 - - src/liblzma/common/delta_common.h | 4 - - src/liblzma/common/delta_decoder.c | 55 +- - src/liblzma/common/delta_encoder.c | 7 +- - src/liblzma/common/easy.c | 122 ++++ - src/liblzma/common/easy_common.c | 54 -- - src/liblzma/common/easy_common.h | 28 - - src/liblzma/common/easy_multi.c | 103 ---- - src/liblzma/common/easy_single.c | 37 -- - src/liblzma/common/extra.c | 34 -- - src/liblzma/common/features.c | 4 - - src/liblzma/common/filter_flags_decoder.c | 384 ++++-------- - src/liblzma/common/filter_flags_encoder.c | 120 +--- - src/liblzma/common/index.c | 773 ++++++++++++++++++++--- - src/liblzma/common/index.h | 67 ++ - src/liblzma/common/index_decoder.c | 252 ++++++++ - src/liblzma/common/index_encoder.c | 222 +++++++ - src/liblzma/common/index_encoder.h | 30 + - src/liblzma/common/index_hash.c | 340 +++++++++++ - src/liblzma/common/info.c | 814 ------------------------- - src/liblzma/common/memory_usage.c | 1 - - src/liblzma/common/metadata_decoder.c | 578 ------------------ - src/liblzma/common/metadata_decoder.h | 31 - - src/liblzma/common/metadata_encoder.c | 435 ------------- - src/liblzma/common/metadata_encoder.h | 30 - - src/liblzma/common/raw_common.c | 178 ++---- - src/liblzma/common/raw_common.h | 5 +- - src/liblzma/common/raw_decoder.c | 19 +- - src/liblzma/common/raw_decoder.h | 3 +- - src/liblzma/common/raw_encoder.c | 101 +-- - src/liblzma/common/raw_encoder.h | 3 +- - src/liblzma/common/stream_common.h | 3 + - src/liblzma/common/stream_decoder.c | 458 +++++--------- - src/liblzma/common/stream_decoder.h | 28 + - src/liblzma/common/stream_encoder.c | 282 +++++++++ - src/liblzma/common/stream_encoder.h | 30 + - src/liblzma/common/stream_encoder_multi.c | 445 -------------- - src/liblzma/common/stream_encoder_multi.h | 26 - - src/liblzma/common/stream_encoder_single.c | 219 ------- - src/liblzma/common/stream_flags_decoder.c | 260 ++------ - src/liblzma/common/stream_flags_encoder.c | 56 +- - src/liblzma/common/stream_flags_equal.c | 36 ++ - src/liblzma/common/vli_decoder.c | 68 ++- - src/liblzma/common/vli_encoder.c | 59 +- - src/liblzma/common/vli_reverse_decoder.c | 55 -- - src/liblzma/lz/lz_decoder.c | 6 +- - src/liblzma/lz/lz_decoder.h | 10 +- - src/liblzma/lzma/lzma_decoder.c | 13 +- - src/liblzma/lzma/lzma_decoder.h | 10 +- - src/liblzma/simple/simple_coder.c | 29 +- - src/liblzma/simple/simple_private.h | 4 - - src/liblzma/subblock/subblock_decoder.c | 106 +--- - src/liblzma/subblock/subblock_decoder_helper.c | 5 +- - src/liblzma/subblock/subblock_encoder.c | 8 +- - src/lzma/args.c | 22 +- - src/lzma/args.h | 2 - - src/lzma/error.c | 6 + - src/lzma/process.c | 26 +- - src/lzmadec/lzmadec.c | 8 +- - tests/Makefile.am | 5 +- - tests/test_block_header.c | 411 +++++-------- - tests/test_compress.sh | 65 +- - tests/test_filter_flags.c | 116 ++-- - tests/test_index.c | 504 ++++++++++++++- - tests/test_info.c | 717 ---------------------- - tests/test_stream_flags.c | 134 ++-- - tests/tests.h | 14 +- - 115 files changed, 4846 insertions(+), 8156 deletions(-) + configure.ac | 41 +- + debug/full_flush.c | 16 +- + debug/sync_flush.c | 15 +- + .../check/check_byteswap.h => common/bswap.h} | 15 +- + src/common/integer.h | 167 +++++ + src/liblzma/api/Makefile.am | 5 +- + src/liblzma/api/lzma.h | 9 +- + src/liblzma/api/lzma/alone.h | 32 +- + src/liblzma/api/lzma/auto.h | 7 +- + src/liblzma/api/lzma/base.h | 15 + + src/liblzma/api/lzma/block.h | 306 +++----- + src/liblzma/api/lzma/check.h | 18 +- + src/liblzma/api/lzma/copy.h | 29 - + src/liblzma/api/lzma/easy.h | 61 +- + src/liblzma/api/lzma/extra.h | 114 --- + src/liblzma/api/lzma/filter.h | 5 +- + src/liblzma/api/lzma/index.h | 204 +++++- + src/liblzma/api/lzma/index_hash.h | 94 +++ + src/liblzma/api/lzma/info.h | 315 -------- + src/liblzma/api/lzma/lzma.h | 2 +- + src/liblzma/api/lzma/metadata.h | 100 --- + src/liblzma/api/lzma/raw.h | 20 +- + src/liblzma/api/lzma/stream.h | 157 +--- + src/liblzma/api/lzma/stream_flags.h | 146 ++-- + src/liblzma/api/lzma/version.h | 2 +- + src/liblzma/api/lzma/vli.h | 83 +-- + src/liblzma/check/Makefile.am | 1 - + src/liblzma/check/check.c | 55 +- + src/liblzma/check/check.h | 47 +- + src/liblzma/check/crc32_init.c | 2 +- + src/liblzma/check/crc64_init.c | 2 +- + src/liblzma/check/crc_macros.h | 2 +- + src/liblzma/check/sha256.c | 53 +- + src/liblzma/common/Makefile.am | 31 +- + src/liblzma/common/alignment.c | 5 +- + src/liblzma/common/alone_decoder.c | 77 +- + src/liblzma/common/alone_encoder.c | 99 ++- + src/liblzma/common/auto_decoder.c | 18 +- + src/liblzma/common/block_decoder.c | 298 ++------ + src/liblzma/common/block_encoder.c | 228 ++---- + src/liblzma/common/block_header_decoder.c | 400 ++-------- + src/liblzma/common/block_header_encoder.c | 207 ++---- + src/liblzma/common/block_private.h | 51 +- + src/liblzma/common/block_util.c | 73 ++ + src/liblzma/common/common.h | 44 +- + src/liblzma/common/copy_coder.c | 144 ---- + src/liblzma/common/copy_coder.h | 31 - + src/liblzma/common/delta_common.c | 4 - + src/liblzma/common/delta_common.h | 4 - + src/liblzma/common/delta_decoder.c | 55 +- + src/liblzma/common/delta_encoder.c | 7 +- + src/liblzma/common/{easy_multi.c => easy.c} | 87 ++- + src/liblzma/common/easy_common.c | 54 -- + src/liblzma/common/extra.c | 34 - + src/liblzma/common/features.c | 4 - + src/liblzma/common/filter_flags_decoder.c | 384 +++------- + src/liblzma/common/filter_flags_encoder.c | 120 +-- + src/liblzma/common/index.c | 773 ++++++++++++++++--- + src/liblzma/common/index.h | 67 ++ + src/liblzma/common/index_decoder.c | 252 +++++++ + src/liblzma/common/index_encoder.c | 222 ++++++ + .../{stream_encoder_multi.h => index_encoder.h} | 18 +- + src/liblzma/common/index_hash.c | 340 +++++++++ + src/liblzma/common/info.c | 814 --------------------- + src/liblzma/common/memory_usage.c | 1 - + src/liblzma/common/metadata_decoder.c | 578 --------------- + src/liblzma/common/metadata_decoder.h | 31 - + src/liblzma/common/metadata_encoder.c | 435 ----------- + src/liblzma/common/raw_common.c | 178 ++--- + src/liblzma/common/raw_common.h | 5 +- + src/liblzma/common/raw_decoder.c | 19 +- + src/liblzma/common/raw_decoder.h | 3 +- + src/liblzma/common/raw_encoder.c | 101 +-- + src/liblzma/common/raw_encoder.h | 3 +- + src/liblzma/common/stream_common.h | 3 + + src/liblzma/common/stream_decoder.c | 458 ++++-------- + .../common/{easy_common.h => stream_decoder.h} | 14 +- + src/liblzma/common/stream_encoder.c | 282 +++++++ + .../{metadata_encoder.h => stream_encoder.h} | 14 +- + src/liblzma/common/stream_encoder_multi.c | 445 ----------- + src/liblzma/common/stream_encoder_single.c | 219 ------ + src/liblzma/common/stream_flags_decoder.c | 260 ++----- + src/liblzma/common/stream_flags_encoder.c | 56 +- + .../common/{easy_single.c => stream_flags_equal.c} | 27 +- + src/liblzma/common/vli_decoder.c | 68 +- + src/liblzma/common/vli_encoder.c | 59 +- + src/liblzma/common/vli_reverse_decoder.c | 55 -- + src/liblzma/lz/lz_decoder.c | 6 +- + src/liblzma/lz/lz_decoder.h | 10 +- + src/liblzma/lzma/lzma_decoder.c | 13 +- + src/liblzma/lzma/lzma_decoder.h | 10 +- + src/liblzma/simple/simple_coder.c | 29 +- + src/liblzma/simple/simple_private.h | 4 - + src/liblzma/subblock/subblock_decoder.c | 106 +-- + src/liblzma/subblock/subblock_decoder_helper.c | 5 +- + src/liblzma/subblock/subblock_encoder.c | 8 +- + src/lzma/args.c | 22 +- + src/lzma/args.h | 2 - + src/lzma/error.c | 6 + + src/lzma/process.c | 26 +- + src/lzmadec/lzmadec.c | 8 +- + tests/Makefile.am | 5 +- + tests/test_block_header.c | 411 ++++------- + tests/test_compress.sh | 65 +- + tests/test_filter_flags.c | 116 ++- + tests/test_index.c | 504 ++++++++++++- + tests/test_info.c | 717 ------------------ + tests/test_stream_flags.c | 134 ++-- + tests/tests.h | 14 +- + 109 files changed, 4655 insertions(+), 7965 deletions(-) commit bf6348d1a3ff09fdc06940468f318f75ffa6af11 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -12825,17 +13248,16 @@ Date: 2008-04-28 17:06:34 +0300 Fixed wrong spelling "limitter" to "limiter". This affects liblzma's API. - doc/liblzma-security.txt | 14 +- - src/liblzma/api/lzma/base.h | 4 +- - src/liblzma/api/lzma/memlimit.h | 10 +- - src/liblzma/api/lzma/stream.h | 4 +- - src/liblzma/common/Makefile.am | 2 +- - src/liblzma/common/memory_limiter.c | 288 +++++++++++++++++++++++++++++++++++ - src/liblzma/common/memory_limitter.c | 288 ----------------------------------- - src/lzma/list.c | 6 +- - src/lzmadec/lzmadec.c | 12 +- - tests/test_memlimit.c | 4 +- - 10 files changed, 316 insertions(+), 316 deletions(-) + doc/liblzma-security.txt | 14 +++++++------- + src/liblzma/api/lzma/base.h | 4 ++-- + src/liblzma/api/lzma/memlimit.h | 10 +++++----- + src/liblzma/api/lzma/stream.h | 4 ++-- + src/liblzma/common/Makefile.am | 2 +- + src/liblzma/common/{memory_limitter.c => memory_limiter.c} | 2 +- + src/lzma/list.c | 6 +++--- + src/lzmadec/lzmadec.c | 12 ++++++------ + tests/test_memlimit.c | 4 ++-- + 9 files changed, 29 insertions(+), 29 deletions(-) commit beeb81060821dfec4e7898e0d44b7900dcb2215e Author: Lasse Collin <lasse.collin@tukaani.org> @@ -13656,18 +14078,17 @@ Date: 2008-01-19 15:19:21 +0200 Support for LZMA_SYNC_FLUSH was added to the Delta encoder. This doesn't change anything in the file format. - src/liblzma/common/Makefile.am | 14 ++- - src/liblzma/common/delta_coder.c | 189 ------------------------------------- - src/liblzma/common/delta_coder.h | 31 ------ - src/liblzma/common/delta_common.c | 70 ++++++++++++++ - src/liblzma/common/delta_common.h | 48 ++++++++++ - src/liblzma/common/delta_decoder.c | 102 ++++++++++++++++++++ - src/liblzma/common/delta_decoder.h | 28 ++++++ - src/liblzma/common/delta_encoder.c | 97 +++++++++++++++++++ - src/liblzma/common/delta_encoder.h | 28 ++++++ - src/liblzma/common/raw_decoder.c | 2 +- - src/liblzma/common/raw_encoder.c | 2 +- - 11 files changed, 387 insertions(+), 224 deletions(-) + src/liblzma/common/Makefile.am | 14 +- + src/liblzma/common/delta_coder.c | 189 --------------------- + src/liblzma/common/delta_common.c | 70 ++++++++ + src/liblzma/common/delta_common.h | 48 ++++++ + src/liblzma/common/delta_decoder.c | 102 +++++++++++ + .../common/{delta_coder.h => delta_decoder.h} | 11 +- + src/liblzma/common/delta_encoder.c | 97 +++++++++++ + src/liblzma/common/delta_encoder.h | 28 +++ + src/liblzma/common/raw_decoder.c | 2 +- + src/liblzma/common/raw_encoder.c | 2 +- + 10 files changed, 363 insertions(+), 200 deletions(-) commit 61dc82f3e306b25ce3cd3d529df9ec7a0ec04b73 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -14001,15 +14422,14 @@ Date: 2008-01-15 07:40:21 +0200 Added precomputed range coder probability price table. - src/liblzma/common/init_encoder.c | 5 ++- - src/liblzma/rangecoder/Makefile.am | 9 +++- - src/liblzma/rangecoder/price_table.c | 70 +++++++++++++++++++++++++++++++ - src/liblzma/rangecoder/price_table_gen.c | 55 ++++++++++++++++++++++++ - src/liblzma/rangecoder/price_table_init.c | 48 +++++++++++++++++++++ - src/liblzma/rangecoder/range_common.h | 4 +- - src/liblzma/rangecoder/range_encoder.c | 46 -------------------- - src/liblzma/rangecoder/range_encoder.h | 21 +++++----- - 8 files changed, 197 insertions(+), 61 deletions(-) + src/liblzma/common/init_encoder.c | 5 +- + src/liblzma/rangecoder/Makefile.am | 9 ++- + src/liblzma/rangecoder/price_table.c | 70 ++++++++++++++++++++++ + src/liblzma/rangecoder/price_table_gen.c | 55 +++++++++++++++++ + .../{range_encoder.c => price_table_init.c} | 6 +- + src/liblzma/rangecoder/range_common.h | 4 +- + src/liblzma/rangecoder/range_encoder.h | 21 ++++--- + 7 files changed, 153 insertions(+), 17 deletions(-) commit 362dc3843b373c1007a50a4719f378981f18ae03 Author: Lasse Collin <lasse.collin@tukaani.org> @@ -14199,10 +14619,9 @@ Date: 2008-01-08 13:35:36 +0200 tests/files/bad-cat-single-none-pad_garbage_1.lzma | Bin 0 -> 65 bytes tests/files/bad-cat-single-none-pad_garbage_2.lzma | Bin 0 -> 65 bytes tests/files/bad-cat-single-none-pad_garbage_3.lzma | Bin 0 -> 65 bytes - tests/files/bad-single-data_after_eopm.lzma | Bin 55 -> 0 bytes - tests/files/bad-single-data_after_eopm_1.lzma | Bin 0 -> 55 bytes + ...eopm.lzma => bad-single-data_after_eopm_1.lzma} | Bin tests/files/bad-single-none-truncated.lzma | Bin 0 -> 29 bytes - 7 files changed, 18 insertions(+), 3 deletions(-) + 6 files changed, 18 insertions(+), 3 deletions(-) commit b4943ccf73b64fc93a90a23474509c316f55eb2b Author: Lasse Collin <lasse.collin@tukaani.org> @@ -14292,12 +14711,10 @@ Date: 2008-01-07 14:19:05 +0200 Cleaned up the tests/files directory. - tests/files/bad-single-subblock-padding_loop.lzma | Bin 0 -> 43 bytes - tests/files/bad-single-subblock1023-slow.lzma | Bin 0 -> 7886 bytes - tests/files/malicious-single-subblock-loop.lzma | Bin 43 -> 0 bytes - tests/files/malicious-single-subblock-lzma.lzma | Bin 505 -> 0 bytes - tests/files/malicious-single-subblock1023-slow.lzma | Bin 7886 -> 0 bytes - 5 files changed, 0 insertions(+), 0 deletions(-) + ...ck-loop.lzma => bad-single-subblock-padding_loop.lzma} | Bin + ...ck1023-slow.lzma => bad-single-subblock1023-slow.lzma} | Bin + tests/files/malicious-single-subblock-lzma.lzma | Bin 505 -> 0 bytes + 3 files changed, 0 insertions(+), 0 deletions(-) commit 908b2ac604b9940369d7fe8a45e9eb6da5d2a24c Author: Lasse Collin <lasse.collin@tukaani.org> @@ -14483,12 +14900,10 @@ Date: 2007-12-14 10:07:10 +0200 which are not supported by some non-GNU assemblers (Solaris) that otherwise work with this code. - src/liblzma/check/Makefile.am | 4 +- - src/liblzma/check/crc32_x86.S | 217 ++++++++++++++++++++++++++++++++++++++++++ - src/liblzma/check/crc32_x86.s | 217 ------------------------------------------ - src/liblzma/check/crc64_x86.S | 203 +++++++++++++++++++++++++++++++++++++++ - src/liblzma/check/crc64_x86.s | 203 --------------------------------------- - 5 files changed, 422 insertions(+), 422 deletions(-) + src/liblzma/check/Makefile.am | 4 ++-- + src/liblzma/check/{crc32_x86.s => crc32_x86.S} | 0 + src/liblzma/check/{crc64_x86.s => crc64_x86.S} | 0 + 3 files changed, 2 insertions(+), 2 deletions(-) commit ec1c82b2e82f395f6e8e19ac212a639644330cd7 Author: Lasse Collin <lasse.collin@tukaani.org> diff --git a/contrib/xz/THANKS b/contrib/xz/THANKS index d9c62d4..1f40c65 100644 --- a/contrib/xz/THANKS +++ b/contrib/xz/THANKS @@ -64,6 +64,7 @@ has been important. :-) In alphabetical order: - Conley Moorhous - Rafał Mużyło - Adrien Nader + - Evan Nemerson - Hongbo Ni - Jonathan Nieder - Andre Noll @@ -74,6 +75,7 @@ has been important. :-) In alphabetical order: - Diego Elio Pettenò - Elbert Pol - Mikko Pouru + - Rich Prohaska - Trần Ngọc Quân - Pavel Raiskup - Ole André Vadla Ravnås @@ -89,6 +91,7 @@ has been important. :-) In alphabetical order: - Andreas Schwab - Dan Shechter - Stuart Shelton + - Sebastian Andrzej Siewior - Brad Smith - Jonathan Stott - Dan Stromberg @@ -102,6 +105,7 @@ has been important. :-) In alphabetical order: - Christian Weisgerber - Bert Wesarg - Fredrik Wikstrom + - Jim Wilcoxson - Ralf Wildenhues - Charles Wilson - Lars Wirzenius diff --git a/contrib/xz/src/common/tuklib_cpucores.c b/contrib/xz/src/common/tuklib_cpucores.c index e235fd1..c16e188 100644 --- a/contrib/xz/src/common/tuklib_cpucores.c +++ b/contrib/xz/src/common/tuklib_cpucores.c @@ -18,6 +18,10 @@ # endif # include <windows.h> +// glibc >= 2.9 +#elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY) +# include <sched.h> + // FreeBSD #elif defined(TUKLIB_CPUCORES_CPUSET) # include <sys/param.h> @@ -49,6 +53,11 @@ tuklib_cpucores(void) GetSystemInfo(&sysinfo); ret = sysinfo.dwNumberOfProcessors; +#elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY) + cpu_set_t cpu_mask; + if (sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask) == 0) + ret = CPU_COUNT(&cpu_mask); + #elif defined(TUKLIB_CPUCORES_CPUSET) cpuset_t set; if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, diff --git a/contrib/xz/src/common/tuklib_physmem.c b/contrib/xz/src/common/tuklib_physmem.c index cd2437d..4053ad0 100644 --- a/contrib/xz/src/common/tuklib_physmem.c +++ b/contrib/xz/src/common/tuklib_physmem.c @@ -86,7 +86,8 @@ tuklib_physmem(void) // GlobalMemoryStatusEx() conditionally. HMODULE kernel32 = GetModuleHandle("kernel32.dll"); if (kernel32 != NULL) { - BOOL (WINAPI *gmse)(LPMEMORYSTATUSEX) = GetProcAddress( + typedef BOOL (WINAPI *gmse_type)(LPMEMORYSTATUSEX); + gmse_type gmse = (gmse_type)GetProcAddress( kernel32, "GlobalMemoryStatusEx"); if (gmse != NULL) { MEMORYSTATUSEX meminfo; diff --git a/contrib/xz/src/liblzma/api/lzma/version.h b/contrib/xz/src/liblzma/api/lzma/version.h index 8bdc7f0..b5e061c 100644 --- a/contrib/xz/src/liblzma/api/lzma/version.h +++ b/contrib/xz/src/liblzma/api/lzma/version.h @@ -22,7 +22,7 @@ */ #define LZMA_VERSION_MAJOR 5 #define LZMA_VERSION_MINOR 2 -#define LZMA_VERSION_PATCH 2 +#define LZMA_VERSION_PATCH 3 #define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_STABLE #ifndef LZMA_VERSION_COMMIT diff --git a/contrib/xz/src/liblzma/check/check.h b/contrib/xz/src/liblzma/check/check.h index 0f96f65..3007d88 100644 --- a/contrib/xz/src/liblzma/check/check.h +++ b/contrib/xz/src/liblzma/check/check.h @@ -15,7 +15,18 @@ #include "common.h" -#if defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) +// If the function for external SHA-256 is missing, use the internal SHA-256 +// code. Due to how configure works, these defines can only get defined when +// both a usable header and a type have already been found. +#if !(defined(HAVE_CC_SHA256_INIT) \ + || defined(HAVE_SHA256_INIT) \ + || defined(HAVE_SHA256INIT)) +# define HAVE_INTERNAL_SHA256 1 +#endif + +#if defined(HAVE_INTERNAL_SHA256) +// Nothing +#elif defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) # include <CommonCrypto/CommonDigest.h> #elif defined(HAVE_SHA256_H) # include <sys/types.h> @@ -23,18 +34,9 @@ #elif defined(HAVE_SHA2_H) # include <sys/types.h> # include <sha2.h> -#elif defined(HAVE_MINIX_SHA2_H) -# include <sys/types.h> -# include <minix/sha2.h> #endif -#if defined(HAVE_CC_SHA256_CTX) -typedef CC_SHA256_CTX lzma_sha256_state; -#elif defined(HAVE_SHA256_CTX) -typedef SHA256_CTX lzma_sha256_state; -#elif defined(HAVE_SHA2_CTX) -typedef SHA2_CTX lzma_sha256_state; -#else +#if defined(HAVE_INTERNAL_SHA256) /// State for the internal SHA-256 implementation typedef struct { /// Internal state @@ -43,9 +45,17 @@ typedef struct { /// Size of the message excluding padding uint64_t size; } lzma_sha256_state; +#elif defined(HAVE_CC_SHA256_CTX) +typedef CC_SHA256_CTX lzma_sha256_state; +#elif defined(HAVE_SHA256_CTX) +typedef SHA256_CTX lzma_sha256_state; +#elif defined(HAVE_SHA2_CTX) +typedef SHA2_CTX lzma_sha256_state; #endif -#if defined(HAVE_CC_SHA256_INIT) +#if defined(HAVE_INTERNAL_SHA256) +// Nothing +#elif defined(HAVE_CC_SHA256_INIT) # define LZMA_SHA256FUNC(x) CC_SHA256_ ## x #elif defined(HAVE_SHA256_INIT) # define LZMA_SHA256FUNC(x) SHA256_ ## x diff --git a/contrib/xz/src/liblzma/common/alone_decoder.c b/contrib/xz/src/liblzma/common/alone_decoder.c index c1360ca..dd68176 100644 --- a/contrib/xz/src/liblzma/common/alone_decoder.c +++ b/contrib/xz/src/liblzma/common/alone_decoder.c @@ -15,7 +15,7 @@ #include "lz_decoder.h" -struct lzma_coder_s { +typedef struct { lzma_next_coder next; enum { @@ -46,17 +46,19 @@ struct lzma_coder_s { /// Options decoded from the header needed to initialize /// the LZMA decoder lzma_options_lzma options; -}; +} lzma_alone_coder; static lzma_ret -alone_decode(lzma_coder *coder, +alone_decode(void *coder_ptr, const lzma_allocator *allocator lzma_attribute((__unused__)), const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_alone_coder *coder = coder_ptr; + while (*out_pos < out_size && (coder->sequence == SEQ_CODE || *in_pos < in_size)) switch (coder->sequence) { @@ -166,8 +168,9 @@ alone_decode(lzma_coder *coder, static void -alone_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) +alone_decoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_alone_coder *coder = coder_ptr; lzma_next_end(&coder->next, allocator); lzma_free(coder, allocator); return; @@ -175,9 +178,11 @@ alone_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) static lzma_ret -alone_decoder_memconfig(lzma_coder *coder, uint64_t *memusage, +alone_decoder_memconfig(void *coder_ptr, uint64_t *memusage, uint64_t *old_memlimit, uint64_t new_memlimit) { + lzma_alone_coder *coder = coder_ptr; + *memusage = coder->memusage; *old_memlimit = coder->memlimit; @@ -201,26 +206,29 @@ lzma_alone_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, if (memlimit == 0) return LZMA_PROG_ERROR; - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_alone_coder *coder = next->coder; + + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_alone_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &alone_decode; next->end = &alone_decoder_end; next->memconfig = &alone_decoder_memconfig; - next->coder->next = LZMA_NEXT_CODER_INIT; + coder->next = LZMA_NEXT_CODER_INIT; } - next->coder->sequence = SEQ_PROPERTIES; - next->coder->picky = picky; - next->coder->pos = 0; - next->coder->options.dict_size = 0; - next->coder->options.preset_dict = NULL; - next->coder->options.preset_dict_size = 0; - next->coder->uncompressed_size = 0; - next->coder->memlimit = memlimit; - next->coder->memusage = LZMA_MEMUSAGE_BASE; + coder->sequence = SEQ_PROPERTIES; + coder->picky = picky; + coder->pos = 0; + coder->options.dict_size = 0; + coder->options.preset_dict = NULL; + coder->options.preset_dict_size = 0; + coder->uncompressed_size = 0; + coder->memlimit = memlimit; + coder->memusage = LZMA_MEMUSAGE_BASE; return LZMA_OK; } diff --git a/contrib/xz/src/liblzma/common/alone_encoder.c b/contrib/xz/src/liblzma/common/alone_encoder.c index a2bc9ee..4853cfd 100644 --- a/contrib/xz/src/liblzma/common/alone_encoder.c +++ b/contrib/xz/src/liblzma/common/alone_encoder.c @@ -17,7 +17,7 @@ #define ALONE_HEADER_SIZE (1 + 4 + 8) -struct lzma_coder_s { +typedef struct { lzma_next_coder next; enum { @@ -27,17 +27,19 @@ struct lzma_coder_s { size_t header_pos; uint8_t header[ALONE_HEADER_SIZE]; -}; +} lzma_alone_coder; static lzma_ret -alone_encode(lzma_coder *coder, +alone_encode(void *coder_ptr, const lzma_allocator *allocator lzma_attribute((__unused__)), const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_alone_coder *coder = coder_ptr; + while (*out_pos < out_size) switch (coder->sequence) { case SEQ_HEADER: @@ -65,8 +67,9 @@ alone_encode(lzma_coder *coder, static void -alone_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) +alone_encoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_alone_coder *coder = coder_ptr; lzma_next_end(&coder->next, allocator); lzma_free(coder, allocator); return; @@ -80,23 +83,26 @@ alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, { lzma_next_coder_init(&alone_encoder_init, next, allocator); - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_alone_coder *coder = next->coder; + + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_alone_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &alone_encode; next->end = &alone_encoder_end; - next->coder->next = LZMA_NEXT_CODER_INIT; + coder->next = LZMA_NEXT_CODER_INIT; } // Basic initializations - next->coder->sequence = SEQ_HEADER; - next->coder->header_pos = 0; + coder->sequence = SEQ_HEADER; + coder->header_pos = 0; // Encode the header: // - Properties (1 byte) - if (lzma_lzma_lclppb_encode(options, next->coder->header)) + if (lzma_lzma_lclppb_encode(options, coder->header)) return LZMA_OPTIONS_ERROR; // - Dictionary size (4 bytes) @@ -116,10 +122,10 @@ alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, if (d != UINT32_MAX) ++d; - unaligned_write32le(next->coder->header + 1, d); + unaligned_write32le(coder->header + 1, d); // - Uncompressed size (always unknown and using EOPM) - memset(next->coder->header + 1 + 4, 0xFF, 8); + memset(coder->header + 1 + 4, 0xFF, 8); // Initialize the LZMA encoder. const lzma_filter_info filters[2] = { @@ -131,7 +137,7 @@ alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, } }; - return lzma_next_filter_init(&next->coder->next, allocator, filters); + return lzma_next_filter_init(&coder->next, allocator, filters); } diff --git a/contrib/xz/src/liblzma/common/auto_decoder.c b/contrib/xz/src/liblzma/common/auto_decoder.c index bf35507..09acd6d 100644 --- a/contrib/xz/src/liblzma/common/auto_decoder.c +++ b/contrib/xz/src/liblzma/common/auto_decoder.c @@ -14,7 +14,7 @@ #include "alone_decoder.h" -struct lzma_coder_s { +typedef struct { /// Stream decoder or LZMA_Alone decoder lzma_next_coder next; @@ -26,15 +26,17 @@ struct lzma_coder_s { SEQ_CODE, SEQ_FINISH, } sequence; -}; +} lzma_auto_coder; static lzma_ret -auto_decode(lzma_coder *coder, const lzma_allocator *allocator, +auto_decode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_auto_coder *coder = coder_ptr; + switch (coder->sequence) { case SEQ_INIT: if (*in_pos >= in_size) @@ -100,8 +102,9 @@ auto_decode(lzma_coder *coder, const lzma_allocator *allocator, static void -auto_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) +auto_decoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_auto_coder *coder = coder_ptr; lzma_next_end(&coder->next, allocator); lzma_free(coder, allocator); return; @@ -109,8 +112,10 @@ auto_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) static lzma_check -auto_decoder_get_check(const lzma_coder *coder) +auto_decoder_get_check(const void *coder_ptr) { + const lzma_auto_coder *coder = coder_ptr; + // It is LZMA_Alone if get_check is NULL. return coder->next.get_check == NULL ? LZMA_CHECK_NONE : coder->next.get_check(coder->next.coder); @@ -118,9 +123,11 @@ auto_decoder_get_check(const lzma_coder *coder) static lzma_ret -auto_decoder_memconfig(lzma_coder *coder, uint64_t *memusage, +auto_decoder_memconfig(void *coder_ptr, uint64_t *memusage, uint64_t *old_memlimit, uint64_t new_memlimit) { + lzma_auto_coder *coder = coder_ptr; + lzma_ret ret; if (coder->next.memconfig != NULL) { @@ -154,21 +161,23 @@ auto_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, if (flags & ~LZMA_SUPPORTED_FLAGS) return LZMA_OPTIONS_ERROR; - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_auto_coder *coder = next->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_auto_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &auto_decode; next->end = &auto_decoder_end; next->get_check = &auto_decoder_get_check; next->memconfig = &auto_decoder_memconfig; - next->coder->next = LZMA_NEXT_CODER_INIT; + coder->next = LZMA_NEXT_CODER_INIT; } - next->coder->memlimit = memlimit; - next->coder->flags = flags; - next->coder->sequence = SEQ_INIT; + coder->memlimit = memlimit; + coder->flags = flags; + coder->sequence = SEQ_INIT; return LZMA_OK; } diff --git a/contrib/xz/src/liblzma/common/block_decoder.c b/contrib/xz/src/liblzma/common/block_decoder.c index 685c3b0..075bd27 100644 --- a/contrib/xz/src/liblzma/common/block_decoder.c +++ b/contrib/xz/src/liblzma/common/block_decoder.c @@ -15,7 +15,7 @@ #include "check.h" -struct lzma_coder_s { +typedef struct { enum { SEQ_CODE, SEQ_PADDING, @@ -48,7 +48,7 @@ struct lzma_coder_s { /// True if the integrity check won't be calculated and verified. bool ignore_check; -}; +} lzma_block_coder; static inline bool @@ -74,11 +74,13 @@ is_size_valid(lzma_vli size, lzma_vli reference) static lzma_ret -block_decode(lzma_coder *coder, const lzma_allocator *allocator, +block_decode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_block_coder *coder = coder_ptr; + switch (coder->sequence) { case SEQ_CODE: { const size_t in_start = *in_pos; @@ -177,8 +179,9 @@ block_decode(lzma_coder *coder, const lzma_allocator *allocator, static void -block_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) +block_decoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_block_coder *coder = coder_ptr; lzma_next_end(&coder->next, allocator); lzma_free(coder, allocator); return; @@ -198,27 +201,29 @@ lzma_block_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, || !lzma_vli_is_valid(block->uncompressed_size)) return LZMA_PROG_ERROR; - // Allocate and initialize *next->coder if needed. - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + // Allocate *next->coder if needed. + lzma_block_coder *coder = next->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_block_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &block_decode; next->end = &block_decoder_end; - next->coder->next = LZMA_NEXT_CODER_INIT; + coder->next = LZMA_NEXT_CODER_INIT; } // Basic initializations - next->coder->sequence = SEQ_CODE; - next->coder->block = block; - next->coder->compressed_size = 0; - next->coder->uncompressed_size = 0; + coder->sequence = SEQ_CODE; + coder->block = block; + coder->compressed_size = 0; + coder->uncompressed_size = 0; // If Compressed Size is not known, we calculate the maximum allowed // value so that encoded size of the Block (including Block Padding) // is still a valid VLI and a multiple of four. - next->coder->compressed_limit + coder->compressed_limit = block->compressed_size == LZMA_VLI_UNKNOWN ? (LZMA_VLI_MAX & ~LZMA_VLI_C(3)) - block->header_size @@ -228,14 +233,14 @@ lzma_block_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, // Initialize the check. It's caller's problem if the Check ID is not // supported, and the Block decoder cannot verify the Check field. // Caller can test lzma_check_is_supported(block->check). - next->coder->check_pos = 0; - lzma_check_init(&next->coder->check, block->check); + coder->check_pos = 0; + lzma_check_init(&coder->check, block->check); - next->coder->ignore_check = block->version >= 1 + coder->ignore_check = block->version >= 1 ? block->ignore_check : false; // Initialize the filter chain. - return lzma_raw_decoder_init(&next->coder->next, allocator, + return lzma_raw_decoder_init(&coder->next, allocator, block->filters); } diff --git a/contrib/xz/src/liblzma/common/block_encoder.c b/contrib/xz/src/liblzma/common/block_encoder.c index def5864..168846a 100644 --- a/contrib/xz/src/liblzma/common/block_encoder.c +++ b/contrib/xz/src/liblzma/common/block_encoder.c @@ -15,7 +15,7 @@ #include "check.h" -struct lzma_coder_s { +typedef struct { /// The filters in the chain; initialized with lzma_raw_decoder_init(). lzma_next_coder next; @@ -41,15 +41,17 @@ struct lzma_coder_s { /// Check of the uncompressed data lzma_check_state check; -}; +} lzma_block_coder; static lzma_ret -block_encode(lzma_coder *coder, const lzma_allocator *allocator, +block_encode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_block_coder *coder = coder_ptr; + // Check that our amount of input stays in proper limits. if (LZMA_VLI_MAX - coder->uncompressed_size < in_size - *in_pos) return LZMA_DATA_ERROR; @@ -134,8 +136,9 @@ block_encode(lzma_coder *coder, const lzma_allocator *allocator, static void -block_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) +block_encoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_block_coder *coder = coder_ptr; lzma_next_end(&coder->next, allocator); lzma_free(coder, allocator); return; @@ -143,10 +146,12 @@ block_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) static lzma_ret -block_encoder_update(lzma_coder *coder, const lzma_allocator *allocator, +block_encoder_update(void *coder_ptr, const lzma_allocator *allocator, const lzma_filter *filters lzma_attribute((__unused__)), const lzma_filter *reversed_filters) { + lzma_block_coder *coder = coder_ptr; + if (coder->sequence != SEQ_CODE) return LZMA_PROG_ERROR; @@ -178,30 +183,31 @@ lzma_block_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, return LZMA_UNSUPPORTED_CHECK; // Allocate and initialize *next->coder if needed. - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_block_coder *coder = next->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_block_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &block_encode; next->end = &block_encoder_end; next->update = &block_encoder_update; - next->coder->next = LZMA_NEXT_CODER_INIT; + coder->next = LZMA_NEXT_CODER_INIT; } // Basic initializations - next->coder->sequence = SEQ_CODE; - next->coder->block = block; - next->coder->compressed_size = 0; - next->coder->uncompressed_size = 0; - next->coder->pos = 0; + coder->sequence = SEQ_CODE; + coder->block = block; + coder->compressed_size = 0; + coder->uncompressed_size = 0; + coder->pos = 0; // Initialize the check - lzma_check_init(&next->coder->check, block->check); + lzma_check_init(&coder->check, block->check); // Initialize the requested filters. - return lzma_raw_encoder_init(&next->coder->next, allocator, - block->filters); + return lzma_raw_encoder_init(&coder->next, allocator, block->filters); } diff --git a/contrib/xz/src/liblzma/common/common.h b/contrib/xz/src/liblzma/common/common.h index 955d784..b3d3b7a 100644 --- a/contrib/xz/src/liblzma/common/common.h +++ b/contrib/xz/src/liblzma/common/common.h @@ -88,10 +88,6 @@ #define LZMA_TIMED_OUT 32 -/// Type of encoder/decoder specific data; the actual structure is defined -/// differently in different coders. -typedef struct lzma_coder_s lzma_coder; - typedef struct lzma_next_coder_s lzma_next_coder; typedef struct lzma_filter_info_s lzma_filter_info; @@ -107,7 +103,7 @@ typedef lzma_ret (*lzma_init_function)( /// input and output buffers, but for simplicity they still use this same /// function prototype. typedef lzma_ret (*lzma_code_function)( - lzma_coder *coder, const lzma_allocator *allocator, + void *coder, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, @@ -115,7 +111,7 @@ typedef lzma_ret (*lzma_code_function)( /// Type of a function to free the memory allocated for the coder typedef void (*lzma_end_function)( - lzma_coder *coder, const lzma_allocator *allocator); + void *coder, const lzma_allocator *allocator); /// Raw coder validates and converts an array of lzma_filter structures to @@ -138,7 +134,7 @@ struct lzma_filter_info_s { /// Hold data and function pointers of the next filter in the chain. struct lzma_next_coder_s { /// Pointer to coder-specific data - lzma_coder *coder; + void *coder; /// Filter ID. This is LZMA_VLI_UNKNOWN when this structure doesn't /// point to a filter coder. @@ -160,21 +156,21 @@ struct lzma_next_coder_s { /// Pointer to a function to get progress information. If this is NULL, /// lzma_stream.total_in and .total_out are used instead. - void (*get_progress)(lzma_coder *coder, + void (*get_progress)(void *coder, uint64_t *progress_in, uint64_t *progress_out); /// Pointer to function to return the type of the integrity check. /// Most coders won't support this. - lzma_check (*get_check)(const lzma_coder *coder); + lzma_check (*get_check)(const void *coder); /// Pointer to function to get and/or change the memory usage limit. /// If new_memlimit == 0, the limit is not changed. - lzma_ret (*memconfig)(lzma_coder *coder, uint64_t *memusage, + lzma_ret (*memconfig)(void *coder, uint64_t *memusage, uint64_t *old_memlimit, uint64_t new_memlimit); /// Update the filter-specific options or the whole filter chain /// in the encoder. - lzma_ret (*update)(lzma_coder *coder, const lzma_allocator *allocator, + lzma_ret (*update)(void *coder, const lzma_allocator *allocator, const lzma_filter *filters, const lzma_filter *reversed_filters); }; diff --git a/contrib/xz/src/liblzma/common/index.c b/contrib/xz/src/liblzma/common/index.c index e897646..26e4e51 100644 --- a/contrib/xz/src/liblzma/common/index.c +++ b/contrib/xz/src/liblzma/common/index.c @@ -202,22 +202,21 @@ index_tree_node_end(index_tree_node *node, const lzma_allocator *allocator, if (node->right != NULL) index_tree_node_end(node->right, allocator, free_func); - if (free_func != NULL) - free_func(node, allocator); - - lzma_free(node, allocator); + free_func(node, allocator); return; } -/// Free the meory allocated for a tree. If free_func is not NULL, -/// it is called on each node before freeing the node. This is used -/// to free the Record groups from each index_stream before freeing -/// the index_stream itself. +/// Free the memory allocated for a tree. Each node is freed using the +/// given free_func which is either &lzma_free or &index_stream_end. +/// The latter is used to free the Record groups from each index_stream +/// before freeing the index_stream itself. static void index_tree_end(index_tree *tree, const lzma_allocator *allocator, void (*free_func)(void *node, const lzma_allocator *allocator)) { + assert(free_func != NULL); + if (tree->root != NULL) index_tree_node_end(tree->root, allocator, free_func); @@ -371,7 +370,8 @@ static void index_stream_end(void *node, const lzma_allocator *allocator) { index_stream *s = node; - index_tree_end(&s->groups, allocator, NULL); + index_tree_end(&s->groups, allocator, &lzma_free); + lzma_free(s, allocator); return; } @@ -829,6 +829,9 @@ lzma_index_cat(lzma_index *restrict dest, lzma_index *restrict src, s->groups.rightmost = &newg->node; lzma_free(g, allocator); + + // NOTE: newg isn't leaked here because + // newg == (void *)&newg->node. } } @@ -869,11 +872,8 @@ index_dup_stream(const index_stream *src, const lzma_allocator *allocator) index_stream *dest = index_stream_init(src->node.compressed_base, src->node.uncompressed_base, src->number, src->block_number_base, allocator); - - // Return immediately if allocation failed or if there are - // no groups to duplicate. - if (dest == NULL || src->groups.leftmost == NULL) - return dest; + if (dest == NULL) + return NULL; // Copy the overall information. dest->record_count = src->record_count; @@ -881,6 +881,10 @@ index_dup_stream(const index_stream *src, const lzma_allocator *allocator) dest->stream_flags = src->stream_flags; dest->stream_padding = src->stream_padding; + // Return if there are no groups to duplicate. + if (src->groups.leftmost == NULL) + return dest; + // Allocate memory for the Records. We put all the Records into // a single group. It's simplest and also tends to make // lzma_index_locate() a little bit faster with very big Indexes. diff --git a/contrib/xz/src/liblzma/common/index_decoder.c b/contrib/xz/src/liblzma/common/index_decoder.c index 795d183..1e33f0b 100644 --- a/contrib/xz/src/liblzma/common/index_decoder.c +++ b/contrib/xz/src/liblzma/common/index_decoder.c @@ -14,7 +14,7 @@ #include "check.h" -struct lzma_coder_s { +typedef struct { enum { SEQ_INDICATOR, SEQ_COUNT, @@ -50,11 +50,11 @@ struct lzma_coder_s { /// CRC32 of the List of Records field uint32_t crc32; -}; +} lzma_index_coder; static lzma_ret -index_decode(lzma_coder *coder, const lzma_allocator *allocator, +index_decode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out lzma_attribute((__unused__)), @@ -62,6 +62,8 @@ index_decode(lzma_coder *coder, const lzma_allocator *allocator, size_t out_size lzma_attribute((__unused__)), lzma_action action lzma_attribute((__unused__))) { + lzma_index_coder *coder = coder_ptr; + // Similar optimization as in index_encoder.c const size_t in_start = *in_pos; lzma_ret ret = LZMA_OK; @@ -207,8 +209,9 @@ out: static void -index_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) +index_decoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_index_coder *coder = coder_ptr; lzma_index_end(coder->index, allocator); lzma_free(coder, allocator); return; @@ -216,9 +219,11 @@ index_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) static lzma_ret -index_decoder_memconfig(lzma_coder *coder, uint64_t *memusage, +index_decoder_memconfig(void *coder_ptr, uint64_t *memusage, uint64_t *old_memlimit, uint64_t new_memlimit) { + lzma_index_coder *coder = coder_ptr; + *memusage = lzma_index_memusage(1, coder->count); *old_memlimit = coder->memlimit; @@ -234,7 +239,7 @@ index_decoder_memconfig(lzma_coder *coder, uint64_t *memusage, static lzma_ret -index_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator, +index_decoder_reset(lzma_index_coder *coder, const lzma_allocator *allocator, lzma_index **i, uint64_t memlimit) { // Remember the pointer given by the application. We will set it @@ -269,20 +274,22 @@ index_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, if (i == NULL || memlimit == 0) return LZMA_PROG_ERROR; - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_index_coder *coder = next->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_index_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &index_decode; next->end = &index_decoder_end; next->memconfig = &index_decoder_memconfig; - next->coder->index = NULL; + coder->index = NULL; } else { - lzma_index_end(next->coder->index, allocator); + lzma_index_end(coder->index, allocator); } - return index_decoder_reset(next->coder, allocator, i, memlimit); + return index_decoder_reset(coder, allocator, i, memlimit); } @@ -309,7 +316,7 @@ lzma_index_buffer_decode(lzma_index **i, uint64_t *memlimit, return LZMA_PROG_ERROR; // Initialize the decoder. - lzma_coder coder; + lzma_index_coder coder; return_if_error(index_decoder_reset(&coder, allocator, i, *memlimit)); // Store the input start position so that we can restore it in case diff --git a/contrib/xz/src/liblzma/common/index_encoder.c b/contrib/xz/src/liblzma/common/index_encoder.c index d25ac7d..ac97d0c 100644 --- a/contrib/xz/src/liblzma/common/index_encoder.c +++ b/contrib/xz/src/liblzma/common/index_encoder.c @@ -15,7 +15,7 @@ #include "check.h" -struct lzma_coder_s { +typedef struct { enum { SEQ_INDICATOR, SEQ_COUNT, @@ -37,11 +37,11 @@ struct lzma_coder_s { /// CRC32 of the List of Records field uint32_t crc32; -}; +} lzma_index_coder; static lzma_ret -index_encode(lzma_coder *coder, +index_encode(void *coder_ptr, const lzma_allocator *allocator lzma_attribute((__unused__)), const uint8_t *restrict in lzma_attribute((__unused__)), size_t *restrict in_pos lzma_attribute((__unused__)), @@ -50,6 +50,8 @@ index_encode(lzma_coder *coder, size_t out_size, lzma_action action lzma_attribute((__unused__))) { + lzma_index_coder *coder = coder_ptr; + // Position where to start calculating CRC32. The idea is that we // need to call lzma_crc32() only once per call to index_encode(). const size_t out_start = *out_pos; @@ -159,7 +161,7 @@ out: static void -index_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) +index_encoder_end(void *coder, const lzma_allocator *allocator) { lzma_free(coder, allocator); return; @@ -167,7 +169,7 @@ index_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) static void -index_encoder_reset(lzma_coder *coder, const lzma_index *i) +index_encoder_reset(lzma_index_coder *coder, const lzma_index *i) { lzma_index_iter_init(&coder->iter, i); @@ -190,7 +192,7 @@ lzma_index_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, return LZMA_PROG_ERROR; if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); + next->coder = lzma_alloc(sizeof(lzma_index_coder), allocator); if (next->coder == NULL) return LZMA_MEM_ERROR; @@ -230,7 +232,7 @@ lzma_index_buffer_encode(const lzma_index *i, // The Index encoder needs just one small data structure so we can // allocate it on stack. - lzma_coder coder; + lzma_index_coder coder; index_encoder_reset(&coder, i); // Do the actual encoding. This should never fail, but store diff --git a/contrib/xz/src/liblzma/common/stream_decoder.c b/contrib/xz/src/liblzma/common/stream_decoder.c index 3ab938c..7ae7a67 100644 --- a/contrib/xz/src/liblzma/common/stream_decoder.c +++ b/contrib/xz/src/liblzma/common/stream_decoder.c @@ -14,7 +14,7 @@ #include "block_decoder.h" -struct lzma_coder_s { +typedef struct { enum { SEQ_STREAM_HEADER, SEQ_BLOCK_HEADER, @@ -80,11 +80,11 @@ struct lzma_coder_s { /// Buffer to hold Stream Header, Block Header, and Stream Footer. /// Block Header has biggest maximum size. uint8_t buffer[LZMA_BLOCK_HEADER_SIZE_MAX]; -}; +} lzma_stream_coder; static lzma_ret -stream_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator) +stream_decoder_reset(lzma_stream_coder *coder, const lzma_allocator *allocator) { // Initialize the Index hash used to verify the Index. coder->index_hash = lzma_index_hash_init(coder->index_hash, allocator); @@ -100,11 +100,13 @@ stream_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator) static lzma_ret -stream_decode(lzma_coder *coder, const lzma_allocator *allocator, +stream_decode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_stream_coder *coder = coder_ptr; + // When decoding the actual Block, it may be able to produce more // output even if we don't give it any new input. while (true) @@ -375,8 +377,9 @@ stream_decode(lzma_coder *coder, const lzma_allocator *allocator, static void -stream_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) +stream_decoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_stream_coder *coder = coder_ptr; lzma_next_end(&coder->block_decoder, allocator); lzma_index_hash_end(coder->index_hash, allocator); lzma_free(coder, allocator); @@ -385,16 +388,19 @@ stream_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) static lzma_check -stream_decoder_get_check(const lzma_coder *coder) +stream_decoder_get_check(const void *coder_ptr) { + const lzma_stream_coder *coder = coder_ptr; return coder->stream_flags.check; } static lzma_ret -stream_decoder_memconfig(lzma_coder *coder, uint64_t *memusage, +stream_decoder_memconfig(void *coder_ptr, uint64_t *memusage, uint64_t *old_memlimit, uint64_t new_memlimit) { + lzma_stream_coder *coder = coder_ptr; + *memusage = coder->memusage; *old_memlimit = coder->memlimit; @@ -422,31 +428,33 @@ lzma_stream_decoder_init( if (flags & ~LZMA_SUPPORTED_FLAGS) return LZMA_OPTIONS_ERROR; - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_stream_coder *coder = next->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_stream_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &stream_decode; next->end = &stream_decoder_end; next->get_check = &stream_decoder_get_check; next->memconfig = &stream_decoder_memconfig; - next->coder->block_decoder = LZMA_NEXT_CODER_INIT; - next->coder->index_hash = NULL; + coder->block_decoder = LZMA_NEXT_CODER_INIT; + coder->index_hash = NULL; } - next->coder->memlimit = memlimit; - next->coder->memusage = LZMA_MEMUSAGE_BASE; - next->coder->tell_no_check = (flags & LZMA_TELL_NO_CHECK) != 0; - next->coder->tell_unsupported_check + coder->memlimit = memlimit; + coder->memusage = LZMA_MEMUSAGE_BASE; + coder->tell_no_check = (flags & LZMA_TELL_NO_CHECK) != 0; + coder->tell_unsupported_check = (flags & LZMA_TELL_UNSUPPORTED_CHECK) != 0; - next->coder->tell_any_check = (flags & LZMA_TELL_ANY_CHECK) != 0; - next->coder->ignore_check = (flags & LZMA_IGNORE_CHECK) != 0; - next->coder->concatenated = (flags & LZMA_CONCATENATED) != 0; - next->coder->first_stream = true; + coder->tell_any_check = (flags & LZMA_TELL_ANY_CHECK) != 0; + coder->ignore_check = (flags & LZMA_IGNORE_CHECK) != 0; + coder->concatenated = (flags & LZMA_CONCATENATED) != 0; + coder->first_stream = true; - return stream_decoder_reset(next->coder, allocator); + return stream_decoder_reset(coder, allocator); } diff --git a/contrib/xz/src/liblzma/common/stream_encoder.c b/contrib/xz/src/liblzma/common/stream_encoder.c index a7663bc..858cba4 100644 --- a/contrib/xz/src/liblzma/common/stream_encoder.c +++ b/contrib/xz/src/liblzma/common/stream_encoder.c @@ -14,7 +14,7 @@ #include "index_encoder.h" -struct lzma_coder_s { +typedef struct { enum { SEQ_STREAM_HEADER, SEQ_BLOCK_INIT, @@ -55,11 +55,11 @@ struct lzma_coder_s { /// Buffer to hold Stream Header, Block Header, and Stream Footer. /// Block Header has biggest maximum size. uint8_t buffer[LZMA_BLOCK_HEADER_SIZE_MAX]; -}; +} lzma_stream_coder; static lzma_ret -block_encoder_init(lzma_coder *coder, const lzma_allocator *allocator) +block_encoder_init(lzma_stream_coder *coder, const lzma_allocator *allocator) { // Prepare the Block options. Even though Block encoder doesn't need // compressed_size, uncompressed_size, and header_size to be @@ -78,11 +78,13 @@ block_encoder_init(lzma_coder *coder, const lzma_allocator *allocator) static lzma_ret -stream_encode(lzma_coder *coder, const lzma_allocator *allocator, +stream_encode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_stream_coder *coder = coder_ptr; + // Main loop while (*out_pos < out_size) switch (coder->sequence) { @@ -209,8 +211,10 @@ stream_encode(lzma_coder *coder, const lzma_allocator *allocator, static void -stream_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) +stream_encoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_stream_coder *coder = coder_ptr; + lzma_next_end(&coder->block_encoder, allocator); lzma_next_end(&coder->index_encoder, allocator); lzma_index_end(coder->index, allocator); @@ -224,10 +228,12 @@ stream_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) static lzma_ret -stream_encoder_update(lzma_coder *coder, const lzma_allocator *allocator, +stream_encoder_update(void *coder_ptr, const lzma_allocator *allocator, const lzma_filter *filters, const lzma_filter *reversed_filters) { + lzma_stream_coder *coder = coder_ptr; + if (coder->sequence <= SEQ_BLOCK_INIT) { // There is no incomplete Block waiting to be finished, // thus we can change the whole filter chain. Start by @@ -271,30 +277,33 @@ stream_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, if (filters == NULL) return LZMA_PROG_ERROR; - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_stream_coder *coder = next->coder; + + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_stream_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &stream_encode; next->end = &stream_encoder_end; next->update = &stream_encoder_update; - next->coder->filters[0].id = LZMA_VLI_UNKNOWN; - next->coder->block_encoder = LZMA_NEXT_CODER_INIT; - next->coder->index_encoder = LZMA_NEXT_CODER_INIT; - next->coder->index = NULL; + coder->filters[0].id = LZMA_VLI_UNKNOWN; + coder->block_encoder = LZMA_NEXT_CODER_INIT; + coder->index_encoder = LZMA_NEXT_CODER_INIT; + coder->index = NULL; } // Basic initializations - next->coder->sequence = SEQ_STREAM_HEADER; - next->coder->block_options.version = 0; - next->coder->block_options.check = check; + coder->sequence = SEQ_STREAM_HEADER; + coder->block_options.version = 0; + coder->block_options.check = check; // Initialize the Index - lzma_index_end(next->coder->index, allocator); - next->coder->index = lzma_index_init(allocator); - if (next->coder->index == NULL) + lzma_index_end(coder->index, allocator); + coder->index = lzma_index_init(allocator); + if (coder->index == NULL) return LZMA_MEM_ERROR; // Encode the Stream Header @@ -303,16 +312,15 @@ stream_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, .check = check, }; return_if_error(lzma_stream_header_encode( - &stream_flags, next->coder->buffer)); + &stream_flags, coder->buffer)); - next->coder->buffer_pos = 0; - next->coder->buffer_size = LZMA_STREAM_HEADER_SIZE; + coder->buffer_pos = 0; + coder->buffer_size = LZMA_STREAM_HEADER_SIZE; // Initialize the Block encoder. This way we detect unsupported // filter chains when initializing the Stream encoder instead of // giving an error after Stream Header has already written out. - return stream_encoder_update( - next->coder, allocator, filters, NULL); + return stream_encoder_update(coder, allocator, filters, NULL); } diff --git a/contrib/xz/src/liblzma/common/stream_encoder_mt.c b/contrib/xz/src/liblzma/common/stream_encoder_mt.c index 9780ed0..2efe44c 100644 --- a/contrib/xz/src/liblzma/common/stream_encoder_mt.c +++ b/contrib/xz/src/liblzma/common/stream_encoder_mt.c @@ -44,6 +44,7 @@ typedef enum { } worker_state; +typedef struct lzma_stream_coder_s lzma_stream_coder; typedef struct worker_thread_s worker_thread; struct worker_thread_s { @@ -65,7 +66,7 @@ struct worker_thread_s { /// Pointer to the main structure is needed when putting this /// thread back to the stack of free threads. - lzma_coder *coder; + lzma_stream_coder *coder; /// The allocator is set by the main thread. Since a copy of the /// pointer is kept here, the application must not change the @@ -96,7 +97,7 @@ struct worker_thread_s { }; -struct lzma_coder_s { +struct lzma_stream_coder_s { enum { SEQ_STREAM_HEADER, SEQ_BLOCK, @@ -417,7 +418,7 @@ worker_start(void *thr_ptr) /// Make the threads stop but not exit. Optionally wait for them to stop. static void -threads_stop(lzma_coder *coder, bool wait_for_threads) +threads_stop(lzma_stream_coder *coder, bool wait_for_threads) { // Tell the threads to stop. for (uint32_t i = 0; i < coder->threads_initialized; ++i) { @@ -446,7 +447,7 @@ threads_stop(lzma_coder *coder, bool wait_for_threads) /// Stop the threads and free the resources associated with them. /// Wait until the threads have exited. static void -threads_end(lzma_coder *coder, const lzma_allocator *allocator) +threads_end(lzma_stream_coder *coder, const lzma_allocator *allocator) { for (uint32_t i = 0; i < coder->threads_initialized; ++i) { mythread_sync(coder->threads[i].mutex) { @@ -468,7 +469,8 @@ threads_end(lzma_coder *coder, const lzma_allocator *allocator) /// Initialize a new worker_thread structure and create a new thread. static lzma_ret -initialize_new_thread(lzma_coder *coder, const lzma_allocator *allocator) +initialize_new_thread(lzma_stream_coder *coder, + const lzma_allocator *allocator) { worker_thread *thr = &coder->threads[coder->threads_initialized]; @@ -510,7 +512,7 @@ error_mutex: static lzma_ret -get_thread(lzma_coder *coder, const lzma_allocator *allocator) +get_thread(lzma_stream_coder *coder, const lzma_allocator *allocator) { // If there are no free output subqueues, there is no // point to try getting a thread. @@ -548,7 +550,7 @@ get_thread(lzma_coder *coder, const lzma_allocator *allocator) static lzma_ret -stream_encode_in(lzma_coder *coder, const lzma_allocator *allocator, +stream_encode_in(lzma_stream_coder *coder, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, lzma_action action) { @@ -616,7 +618,7 @@ stream_encode_in(lzma_coder *coder, const lzma_allocator *allocator, /// Wait until more input can be consumed, more output can be read, or /// an optional timeout is reached. static bool -wait_for_work(lzma_coder *coder, mythread_condtime *wait_abs, +wait_for_work(lzma_stream_coder *coder, mythread_condtime *wait_abs, bool *has_blocked, bool has_input) { if (coder->timeout != 0 && !*has_blocked) { @@ -662,11 +664,13 @@ wait_for_work(lzma_coder *coder, mythread_condtime *wait_abs, static lzma_ret -stream_encode_mt(lzma_coder *coder, const lzma_allocator *allocator, +stream_encode_mt(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_stream_coder *coder = coder_ptr; + switch (coder->sequence) { case SEQ_STREAM_HEADER: lzma_bufcpy(coder->header, &coder->header_pos, @@ -834,8 +838,10 @@ stream_encode_mt(lzma_coder *coder, const lzma_allocator *allocator, static void -stream_encoder_mt_end(lzma_coder *coder, const lzma_allocator *allocator) +stream_encoder_mt_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_stream_coder *coder = coder_ptr; + // Threads must be killed before the output queue can be freed. threads_end(coder, allocator); lzma_outq_end(&coder->outq, allocator); @@ -907,10 +913,12 @@ get_options(const lzma_mt *options, lzma_options_easy *opt_easy, static void -get_progress(lzma_coder *coder, uint64_t *progress_in, uint64_t *progress_out) +get_progress(void *coder_ptr, uint64_t *progress_in, uint64_t *progress_out) { + lzma_stream_coder *coder = coder_ptr; + // Lock coder->mutex to prevent finishing threads from moving their - // progress info from the worker_thread structure to lzma_coder. + // progress info from the worker_thread structure to lzma_stream_coder. mythread_sync(coder->mutex) { *progress_in = coder->progress_in; *progress_out = coder->progress_out; @@ -962,24 +970,27 @@ stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator, return LZMA_UNSUPPORTED_CHECK; // Allocate and initialize the base structure if needed. - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_stream_coder *coder = next->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_stream_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; + // For the mutex and condition variable initializations // the error handling has to be done here because // stream_encoder_mt_end() doesn't know if they have // already been initialized or not. - if (mythread_mutex_init(&next->coder->mutex)) { - lzma_free(next->coder, allocator); + if (mythread_mutex_init(&coder->mutex)) { + lzma_free(coder, allocator); next->coder = NULL; return LZMA_MEM_ERROR; } - if (mythread_cond_init(&next->coder->cond)) { - mythread_mutex_destroy(&next->coder->mutex); - lzma_free(next->coder, allocator); + if (mythread_cond_init(&coder->cond)) { + mythread_mutex_destroy(&coder->mutex); + lzma_free(coder, allocator); next->coder = NULL; return LZMA_MEM_ERROR; } @@ -989,76 +1000,76 @@ stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator, next->get_progress = &get_progress; // next->update = &stream_encoder_mt_update; - next->coder->filters[0].id = LZMA_VLI_UNKNOWN; - next->coder->index_encoder = LZMA_NEXT_CODER_INIT; - next->coder->index = NULL; - memzero(&next->coder->outq, sizeof(next->coder->outq)); - next->coder->threads = NULL; - next->coder->threads_max = 0; - next->coder->threads_initialized = 0; + coder->filters[0].id = LZMA_VLI_UNKNOWN; + coder->index_encoder = LZMA_NEXT_CODER_INIT; + coder->index = NULL; + memzero(&coder->outq, sizeof(coder->outq)); + coder->threads = NULL; + coder->threads_max = 0; + coder->threads_initialized = 0; } // Basic initializations - next->coder->sequence = SEQ_STREAM_HEADER; - next->coder->block_size = (size_t)(block_size); - next->coder->thread_error = LZMA_OK; - next->coder->thr = NULL; + coder->sequence = SEQ_STREAM_HEADER; + coder->block_size = (size_t)(block_size); + coder->thread_error = LZMA_OK; + coder->thr = NULL; // Allocate the thread-specific base structures. assert(options->threads > 0); - if (next->coder->threads_max != options->threads) { - threads_end(next->coder, allocator); + if (coder->threads_max != options->threads) { + threads_end(coder, allocator); - next->coder->threads = NULL; - next->coder->threads_max = 0; + coder->threads = NULL; + coder->threads_max = 0; - next->coder->threads_initialized = 0; - next->coder->threads_free = NULL; + coder->threads_initialized = 0; + coder->threads_free = NULL; - next->coder->threads = lzma_alloc( + coder->threads = lzma_alloc( options->threads * sizeof(worker_thread), allocator); - if (next->coder->threads == NULL) + if (coder->threads == NULL) return LZMA_MEM_ERROR; - next->coder->threads_max = options->threads; + coder->threads_max = options->threads; } else { // Reuse the old structures and threads. Tell the running // threads to stop and wait until they have stopped. - threads_stop(next->coder, true); + threads_stop(coder, true); } // Output queue - return_if_error(lzma_outq_init(&next->coder->outq, allocator, + return_if_error(lzma_outq_init(&coder->outq, allocator, outbuf_size_max, options->threads)); // Timeout - next->coder->timeout = options->timeout; + coder->timeout = options->timeout; // Free the old filter chain and copy the new one. - for (size_t i = 0; next->coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i) - lzma_free(next->coder->filters[i].options, allocator); + for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i) + lzma_free(coder->filters[i].options, allocator); return_if_error(lzma_filters_copy( - filters, next->coder->filters, allocator)); + filters, coder->filters, allocator)); // Index - lzma_index_end(next->coder->index, allocator); - next->coder->index = lzma_index_init(allocator); - if (next->coder->index == NULL) + lzma_index_end(coder->index, allocator); + coder->index = lzma_index_init(allocator); + if (coder->index == NULL) return LZMA_MEM_ERROR; // Stream Header - next->coder->stream_flags.version = 0; - next->coder->stream_flags.check = options->check; + coder->stream_flags.version = 0; + coder->stream_flags.check = options->check; return_if_error(lzma_stream_header_encode( - &next->coder->stream_flags, next->coder->header)); + &coder->stream_flags, coder->header)); - next->coder->header_pos = 0; + coder->header_pos = 0; // Progress info - next->coder->progress_in = 0; - next->coder->progress_out = LZMA_STREAM_HEADER_SIZE; + coder->progress_in = 0; + coder->progress_out = LZMA_STREAM_HEADER_SIZE; return LZMA_OK; } @@ -1111,7 +1122,8 @@ lzma_stream_encoder_mt_memusage(const lzma_mt *options) return UINT64_MAX; // Sum them with overflow checking. - uint64_t total_memusage = LZMA_MEMUSAGE_BASE + sizeof(lzma_coder) + uint64_t total_memusage = LZMA_MEMUSAGE_BASE + + sizeof(lzma_stream_coder) + options->threads * sizeof(worker_thread); if (UINT64_MAX - total_memusage < inbuf_memusage) diff --git a/contrib/xz/src/liblzma/delta/delta_common.c b/contrib/xz/src/liblzma/delta/delta_common.c index 13dd468..4768201 100644 --- a/contrib/xz/src/liblzma/delta/delta_common.c +++ b/contrib/xz/src/liblzma/delta/delta_common.c @@ -15,8 +15,9 @@ static void -delta_coder_end(lzma_coder *coder, const lzma_allocator *allocator) +delta_coder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_delta_coder *coder = coder_ptr; lzma_next_end(&coder->next, allocator); lzma_free(coder, allocator); return; @@ -28,14 +29,17 @@ lzma_delta_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters) { // Allocate memory for the decoder if needed. - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_delta_coder *coder = next->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_delta_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; + // End function is the same for encoder and decoder. next->end = &delta_coder_end; - next->coder->next = LZMA_NEXT_CODER_INIT; + coder->next = LZMA_NEXT_CODER_INIT; } // Validate the options. @@ -44,15 +48,14 @@ lzma_delta_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, // Set the delta distance. const lzma_options_delta *opt = filters[0].options; - next->coder->distance = opt->dist; + coder->distance = opt->dist; // Initialize the rest of the variables. - next->coder->pos = 0; - memzero(next->coder->history, LZMA_DELTA_DIST_MAX); + coder->pos = 0; + memzero(coder->history, LZMA_DELTA_DIST_MAX); // Initialize the next decoder in the chain, if any. - return lzma_next_filter_init(&next->coder->next, - allocator, filters + 1); + return lzma_next_filter_init(&coder->next, allocator, filters + 1); } @@ -66,5 +69,5 @@ lzma_delta_coder_memusage(const void *options) || opt->dist > LZMA_DELTA_DIST_MAX) return UINT64_MAX; - return sizeof(lzma_coder); + return sizeof(lzma_delta_coder); } diff --git a/contrib/xz/src/liblzma/delta/delta_decoder.c b/contrib/xz/src/liblzma/delta/delta_decoder.c index 726d023..6859afa 100644 --- a/contrib/xz/src/liblzma/delta/delta_decoder.c +++ b/contrib/xz/src/liblzma/delta/delta_decoder.c @@ -15,7 +15,7 @@ static void -decode_buffer(lzma_coder *coder, uint8_t *buffer, size_t size) +decode_buffer(lzma_delta_coder *coder, uint8_t *buffer, size_t size) { const size_t distance = coder->distance; @@ -27,11 +27,13 @@ decode_buffer(lzma_coder *coder, uint8_t *buffer, size_t size) static lzma_ret -delta_decode(lzma_coder *coder, const lzma_allocator *allocator, +delta_decode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_delta_coder *coder = coder_ptr; + assert(coder->next.code != NULL); const size_t out_start = *out_pos; diff --git a/contrib/xz/src/liblzma/delta/delta_encoder.c b/contrib/xz/src/liblzma/delta/delta_encoder.c index 5a84263..3841651 100644 --- a/contrib/xz/src/liblzma/delta/delta_encoder.c +++ b/contrib/xz/src/liblzma/delta/delta_encoder.c @@ -18,7 +18,7 @@ /// is the first filter in the chain (and thus the last filter in the /// encoder's filter stack). static void -copy_and_encode(lzma_coder *coder, +copy_and_encode(lzma_delta_coder *coder, const uint8_t *restrict in, uint8_t *restrict out, size_t size) { const size_t distance = coder->distance; @@ -35,7 +35,7 @@ copy_and_encode(lzma_coder *coder, /// Encodes the data in place. This is used when we are the last filter /// in the chain (and thus non-last filter in the encoder's filter stack). static void -encode_in_place(lzma_coder *coder, uint8_t *buffer, size_t size) +encode_in_place(lzma_delta_coder *coder, uint8_t *buffer, size_t size) { const size_t distance = coder->distance; @@ -49,11 +49,13 @@ encode_in_place(lzma_coder *coder, uint8_t *buffer, size_t size) static lzma_ret -delta_encode(lzma_coder *coder, const lzma_allocator *allocator, +delta_encode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_delta_coder *coder = coder_ptr; + lzma_ret ret; if (coder->next.code == NULL) { @@ -84,10 +86,12 @@ delta_encode(lzma_coder *coder, const lzma_allocator *allocator, static lzma_ret -delta_encoder_update(lzma_coder *coder, const lzma_allocator *allocator, +delta_encoder_update(void *coder_ptr, const lzma_allocator *allocator, const lzma_filter *filters_null lzma_attribute((__unused__)), const lzma_filter *reversed_filters) { + lzma_delta_coder *coder = coder_ptr; + // Delta doesn't and will never support changing the options in // the middle of encoding. If the app tries to change them, we // simply ignore them. diff --git a/contrib/xz/src/liblzma/delta/delta_private.h b/contrib/xz/src/liblzma/delta/delta_private.h index 46ce0c6..0d6cb38 100644 --- a/contrib/xz/src/liblzma/delta/delta_private.h +++ b/contrib/xz/src/liblzma/delta/delta_private.h @@ -15,7 +15,7 @@ #include "delta_common.h" -struct lzma_coder_s { +typedef struct { /// Next coder in the chain lzma_next_coder next; @@ -27,7 +27,7 @@ struct lzma_coder_s { /// Buffer to hold history of the original data uint8_t history[LZMA_DELTA_DIST_MAX]; -}; +} lzma_delta_coder; extern lzma_ret lzma_delta_coder_init( diff --git a/contrib/xz/src/liblzma/lz/lz_decoder.c b/contrib/xz/src/liblzma/lz/lz_decoder.c index 2328a8e..c708644 100644 --- a/contrib/xz/src/liblzma/lz/lz_decoder.c +++ b/contrib/xz/src/liblzma/lz/lz_decoder.c @@ -20,7 +20,7 @@ #include "lz_decoder.h" -struct lzma_coder_s { +typedef struct { /// Dictionary (history buffer) lzma_dict dict; @@ -48,7 +48,7 @@ struct lzma_coder_s { size_t size; uint8_t buffer[LZMA_BUFFER_SIZE]; } temp; -}; +} lzma_coder; static void @@ -125,13 +125,15 @@ decode_buffer(lzma_coder *coder, static lzma_ret -lz_decode(lzma_coder *coder, +lz_decode(void *coder_ptr, const lzma_allocator *allocator lzma_attribute((__unused__)), const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_coder *coder = coder_ptr; + if (coder->next.code == NULL) return decode_buffer(coder, in, in_pos, in_size, out, out_pos, out_size); @@ -184,8 +186,10 @@ lz_decode(lzma_coder *coder, static void -lz_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) +lz_decoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_coder *coder = coder_ptr; + lzma_next_end(&coder->next, allocator); lzma_free(coder->dict.buf, allocator); @@ -207,24 +211,26 @@ lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, lzma_lz_options *lz_options)) { // Allocate the base structure if it isn't already allocated. - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_coder *coder = next->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &lz_decode; next->end = &lz_decoder_end; - next->coder->dict.buf = NULL; - next->coder->dict.size = 0; - next->coder->lz = LZMA_LZ_DECODER_INIT; - next->coder->next = LZMA_NEXT_CODER_INIT; + coder->dict.buf = NULL; + coder->dict.size = 0; + coder->lz = LZMA_LZ_DECODER_INIT; + coder->next = LZMA_NEXT_CODER_INIT; } // Allocate and initialize the LZ-based decoder. It will also give // us the dictionary size. lzma_lz_options lz_options; - return_if_error(lz_init(&next->coder->lz, allocator, + return_if_error(lz_init(&coder->lz, allocator, filters[0].options, &lz_options)); // If the dictionary size is very small, increase it to 4096 bytes. @@ -248,14 +254,14 @@ lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, lz_options.dict_size = (lz_options.dict_size + 15) & ~((size_t)(15)); // Allocate and initialize the dictionary. - if (next->coder->dict.size != lz_options.dict_size) { - lzma_free(next->coder->dict.buf, allocator); - next->coder->dict.buf + if (coder->dict.size != lz_options.dict_size) { + lzma_free(coder->dict.buf, allocator); + coder->dict.buf = lzma_alloc(lz_options.dict_size, allocator); - if (next->coder->dict.buf == NULL) + if (coder->dict.buf == NULL) return LZMA_MEM_ERROR; - next->coder->dict.size = lz_options.dict_size; + coder->dict.size = lz_options.dict_size; } lz_decoder_reset(next->coder); @@ -268,21 +274,20 @@ lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const size_t copy_size = my_min(lz_options.preset_dict_size, lz_options.dict_size); const size_t offset = lz_options.preset_dict_size - copy_size; - memcpy(next->coder->dict.buf, lz_options.preset_dict + offset, + memcpy(coder->dict.buf, lz_options.preset_dict + offset, copy_size); - next->coder->dict.pos = copy_size; - next->coder->dict.full = copy_size; + coder->dict.pos = copy_size; + coder->dict.full = copy_size; } // Miscellaneous initializations - next->coder->next_finished = false; - next->coder->this_finished = false; - next->coder->temp.pos = 0; - next->coder->temp.size = 0; + coder->next_finished = false; + coder->this_finished = false; + coder->temp.pos = 0; + coder->temp.size = 0; // Initialize the next filter in the chain, if any. - return lzma_next_filter_init(&next->coder->next, allocator, - filters + 1); + return lzma_next_filter_init(&coder->next, allocator, filters + 1); } @@ -294,7 +299,8 @@ lzma_lz_decoder_memusage(size_t dictionary_size) extern void -lzma_lz_decoder_uncompressed(lzma_coder *coder, lzma_vli uncompressed_size) +lzma_lz_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size) { + lzma_coder *coder = coder_ptr; coder->lz.set_uncompressed(coder->lz.coder, uncompressed_size); } diff --git a/contrib/xz/src/liblzma/lz/lz_decoder.h b/contrib/xz/src/liblzma/lz/lz_decoder.h index 277900a..754ccf3 100644 --- a/contrib/xz/src/liblzma/lz/lz_decoder.h +++ b/contrib/xz/src/liblzma/lz/lz_decoder.h @@ -53,21 +53,20 @@ typedef struct { typedef struct { /// Data specific to the LZ-based decoder - lzma_coder *coder; + void *coder; /// Function to decode from in[] to *dict - lzma_ret (*code)(lzma_coder *restrict coder, + lzma_ret (*code)(void *coder, lzma_dict *restrict dict, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size); - void (*reset)(lzma_coder *coder, const void *options); + void (*reset)(void *coder, const void *options); /// Set the uncompressed size - void (*set_uncompressed)(lzma_coder *coder, - lzma_vli uncompressed_size); + void (*set_uncompressed)(void *coder, lzma_vli uncompressed_size); /// Free allocated resources - void (*end)(lzma_coder *coder, const lzma_allocator *allocator); + void (*end)(void *coder, const lzma_allocator *allocator); } lzma_lz_decoder; @@ -92,7 +91,7 @@ extern lzma_ret lzma_lz_decoder_init(lzma_next_coder *next, extern uint64_t lzma_lz_decoder_memusage(size_t dictionary_size); extern void lzma_lz_decoder_uncompressed( - lzma_coder *coder, lzma_vli uncompressed_size); + void *coder, lzma_vli uncompressed_size); ////////////////////// diff --git a/contrib/xz/src/liblzma/lz/lz_encoder.c b/contrib/xz/src/liblzma/lz/lz_encoder.c index 48bc487..9a74b7c 100644 --- a/contrib/xz/src/liblzma/lz/lz_encoder.c +++ b/contrib/xz/src/liblzma/lz/lz_encoder.c @@ -23,7 +23,7 @@ #include "memcmplen.h" -struct lzma_coder_s { +typedef struct { /// LZ-based encoder e.g. LZMA lzma_lz_encoder lz; @@ -32,7 +32,7 @@ struct lzma_coder_s { /// Next coder in the chain lzma_next_coder next; -}; +} lzma_coder; /// \brief Moves the data in the input window to free space for new data @@ -157,12 +157,14 @@ fill_window(lzma_coder *coder, const lzma_allocator *allocator, static lzma_ret -lz_encode(lzma_coder *coder, const lzma_allocator *allocator, +lz_encode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_coder *coder = coder_ptr; + while (*out_pos < out_size && (*in_pos < in_size || action != LZMA_RUN)) { // Read more data to coder->mf.buffer if needed. @@ -481,8 +483,10 @@ lzma_lz_encoder_memusage(const lzma_lz_options *lz_options) static void -lz_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) +lz_encoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_coder *coder = coder_ptr; + lzma_next_end(&coder->next, allocator); lzma_free(coder->mf.son, allocator); @@ -500,10 +504,12 @@ lz_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) static lzma_ret -lz_encoder_update(lzma_coder *coder, const lzma_allocator *allocator, +lz_encoder_update(void *coder_ptr, const lzma_allocator *allocator, const lzma_filter *filters_null lzma_attribute((__unused__)), const lzma_filter *reversed_filters) { + lzma_coder *coder = coder_ptr; + if (coder->lz.options_update == NULL) return LZMA_PROG_ERROR; @@ -528,46 +534,51 @@ lzma_lz_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, #endif // Allocate and initialize the base data structure. - if (next->coder == NULL) { - next->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (next->coder == NULL) + lzma_coder *coder = next->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &lz_encode; next->end = &lz_encoder_end; next->update = &lz_encoder_update; - next->coder->lz.coder = NULL; - next->coder->lz.code = NULL; - next->coder->lz.end = NULL; - - next->coder->mf.buffer = NULL; - next->coder->mf.hash = NULL; - next->coder->mf.son = NULL; - next->coder->mf.hash_count = 0; - next->coder->mf.sons_count = 0; - - next->coder->next = LZMA_NEXT_CODER_INIT; + coder->lz.coder = NULL; + coder->lz.code = NULL; + coder->lz.end = NULL; + + // mf.size is initialized to silence Valgrind + // when used on optimized binaries (GCC may reorder + // code in a way that Valgrind gets unhappy). + coder->mf.buffer = NULL; + coder->mf.size = 0; + coder->mf.hash = NULL; + coder->mf.son = NULL; + coder->mf.hash_count = 0; + coder->mf.sons_count = 0; + + coder->next = LZMA_NEXT_CODER_INIT; } // Initialize the LZ-based encoder. lzma_lz_options lz_options; - return_if_error(lz_init(&next->coder->lz, allocator, + return_if_error(lz_init(&coder->lz, allocator, filters[0].options, &lz_options)); - // Setup the size information into next->coder->mf and deallocate + // Setup the size information into coder->mf and deallocate // old buffers if they have wrong size. - if (lz_encoder_prepare(&next->coder->mf, allocator, &lz_options)) + if (lz_encoder_prepare(&coder->mf, allocator, &lz_options)) return LZMA_OPTIONS_ERROR; // Allocate new buffers if needed, and do the rest of // the initialization. - if (lz_encoder_init(&next->coder->mf, allocator, &lz_options)) + if (lz_encoder_init(&coder->mf, allocator, &lz_options)) return LZMA_MEM_ERROR; // Initialize the next filter in the chain, if any. - return lzma_next_filter_init(&next->coder->next, allocator, - filters + 1); + return lzma_next_filter_init(&coder->next, allocator, filters + 1); } diff --git a/contrib/xz/src/liblzma/lz/lz_encoder.h b/contrib/xz/src/liblzma/lz/lz_encoder.h index dad9c6b..426dcd8 100644 --- a/contrib/xz/src/liblzma/lz/lz_encoder.h +++ b/contrib/xz/src/liblzma/lz/lz_encoder.h @@ -191,19 +191,18 @@ typedef struct { typedef struct { /// Data specific to the LZ-based encoder - lzma_coder *coder; + void *coder; /// Function to encode from *dict to out[] - lzma_ret (*code)(lzma_coder *restrict coder, + lzma_ret (*code)(void *coder, lzma_mf *restrict mf, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size); /// Free allocated resources - void (*end)(lzma_coder *coder, const lzma_allocator *allocator); + void (*end)(void *coder, const lzma_allocator *allocator); /// Update the options in the middle of the encoding. - lzma_ret (*options_update)(lzma_coder *coder, - const lzma_filter *filter); + lzma_ret (*options_update)(void *coder, const lzma_filter *filter); } lzma_lz_encoder; diff --git a/contrib/xz/src/liblzma/lzma/lzma2_decoder.c b/contrib/xz/src/liblzma/lzma/lzma2_decoder.c index 84982d2..878c870 100644 --- a/contrib/xz/src/liblzma/lzma/lzma2_decoder.c +++ b/contrib/xz/src/liblzma/lzma/lzma2_decoder.c @@ -16,7 +16,7 @@ #include "lzma_decoder.h" -struct lzma_coder_s { +typedef struct { enum sequence { SEQ_CONTROL, SEQ_UNCOMPRESSED_1, @@ -50,14 +50,16 @@ struct lzma_coder_s { bool need_dictionary_reset; lzma_options_lzma options; -}; +} lzma_lzma2_coder; static lzma_ret -lzma2_decode(lzma_coder *restrict coder, lzma_dict *restrict dict, +lzma2_decode(void *coder_ptr, lzma_dict *restrict dict, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size) { + lzma_lzma2_coder *restrict coder = coder_ptr; + // With SEQ_LZMA it is possible that no new input is needed to do // some progress. The rest of the sequences assume that there is // at least one byte of input. @@ -209,8 +211,10 @@ lzma2_decode(lzma_coder *restrict coder, lzma_dict *restrict dict, static void -lzma2_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) +lzma2_decoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_lzma2_coder *coder = coder_ptr; + assert(coder->lzma.end == NULL); lzma_free(coder->lzma.coder, allocator); @@ -224,25 +228,27 @@ static lzma_ret lzma2_decoder_init(lzma_lz_decoder *lz, const lzma_allocator *allocator, const void *opt, lzma_lz_options *lz_options) { - if (lz->coder == NULL) { - lz->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (lz->coder == NULL) + lzma_lzma2_coder *coder = lz->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_lzma2_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + lz->coder = coder; lz->code = &lzma2_decode; lz->end = &lzma2_decoder_end; - lz->coder->lzma = LZMA_LZ_DECODER_INIT; + coder->lzma = LZMA_LZ_DECODER_INIT; } const lzma_options_lzma *options = opt; - lz->coder->sequence = SEQ_CONTROL; - lz->coder->need_properties = true; - lz->coder->need_dictionary_reset = options->preset_dict == NULL + coder->sequence = SEQ_CONTROL; + coder->need_properties = true; + coder->need_dictionary_reset = options->preset_dict == NULL || options->preset_dict_size == 0; - return lzma_lzma_decoder_create(&lz->coder->lzma, + return lzma_lzma_decoder_create(&coder->lzma, allocator, options, lz_options); } @@ -263,7 +269,7 @@ lzma_lzma2_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, extern uint64_t lzma_lzma2_decoder_memusage(const void *options) { - return sizeof(lzma_coder) + return sizeof(lzma_lzma2_coder) + lzma_lzma_decoder_memusage_nocheck(options); } diff --git a/contrib/xz/src/liblzma/lzma/lzma2_encoder.c b/contrib/xz/src/liblzma/lzma/lzma2_encoder.c index b6756bf..63588ee 100644 --- a/contrib/xz/src/liblzma/lzma/lzma2_encoder.c +++ b/contrib/xz/src/liblzma/lzma/lzma2_encoder.c @@ -17,7 +17,7 @@ #include "lzma2_encoder.h" -struct lzma_coder_s { +typedef struct { enum { SEQ_INIT, SEQ_LZMA_ENCODE, @@ -27,7 +27,7 @@ struct lzma_coder_s { } sequence; /// LZMA encoder - lzma_coder *lzma; + void *lzma; /// LZMA options currently in use. lzma_options_lzma opt_cur; @@ -48,11 +48,11 @@ struct lzma_coder_s { /// Buffer to hold the chunk header and LZMA compressed data uint8_t buf[LZMA2_HEADER_MAX + LZMA2_CHUNK_MAX]; -}; +} lzma_lzma2_coder; static void -lzma2_header_lzma(lzma_coder *coder) +lzma2_header_lzma(lzma_lzma2_coder *coder) { assert(coder->uncompressed_size > 0); assert(coder->uncompressed_size <= LZMA2_UNCOMPRESSED_MAX); @@ -108,7 +108,7 @@ lzma2_header_lzma(lzma_coder *coder) static void -lzma2_header_uncompressed(lzma_coder *coder) +lzma2_header_uncompressed(lzma_lzma2_coder *coder) { assert(coder->uncompressed_size > 0); assert(coder->uncompressed_size <= LZMA2_CHUNK_MAX); @@ -133,10 +133,12 @@ lzma2_header_uncompressed(lzma_coder *coder) static lzma_ret -lzma2_encode(lzma_coder *restrict coder, lzma_mf *restrict mf, +lzma2_encode(void *coder_ptr, lzma_mf *restrict mf, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size) { + lzma_lzma2_coder *restrict coder = coder_ptr; + while (*out_pos < out_size) switch (coder->sequence) { case SEQ_INIT: @@ -262,8 +264,9 @@ lzma2_encode(lzma_coder *restrict coder, lzma_mf *restrict mf, static void -lzma2_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) +lzma2_encoder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_lzma2_coder *coder = coder_ptr; lzma_free(coder->lzma, allocator); lzma_free(coder, allocator); return; @@ -271,8 +274,10 @@ lzma2_encoder_end(lzma_coder *coder, const lzma_allocator *allocator) static lzma_ret -lzma2_encoder_options_update(lzma_coder *coder, const lzma_filter *filter) +lzma2_encoder_options_update(void *coder_ptr, const lzma_filter *filter) { + lzma_lzma2_coder *coder = coder_ptr; + // New options can be set only when there is no incomplete chunk. // This is the case at the beginning of the raw stream and right // after LZMA_SYNC_FLUSH. @@ -310,30 +315,32 @@ lzma2_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator, if (options == NULL) return LZMA_PROG_ERROR; - if (lz->coder == NULL) { - lz->coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (lz->coder == NULL) + lzma_lzma2_coder *coder = lz->coder; + if (coder == NULL) { + coder = lzma_alloc(sizeof(lzma_lzma2_coder), allocator); + if (coder == NULL) return LZMA_MEM_ERROR; + lz->coder = coder; lz->code = &lzma2_encode; lz->end = &lzma2_encoder_end; lz->options_update = &lzma2_encoder_options_update; - lz->coder->lzma = NULL; + coder->lzma = NULL; } - lz->coder->opt_cur = *(const lzma_options_lzma *)(options); + coder->opt_cur = *(const lzma_options_lzma *)(options); - lz->coder->sequence = SEQ_INIT; - lz->coder->need_properties = true; - lz->coder->need_state_reset = false; - lz->coder->need_dictionary_reset - = lz->coder->opt_cur.preset_dict == NULL - || lz->coder->opt_cur.preset_dict_size == 0; + coder->sequence = SEQ_INIT; + coder->need_properties = true; + coder->need_state_reset = false; + coder->need_dictionary_reset + = coder->opt_cur.preset_dict == NULL + || coder->opt_cur.preset_dict_size == 0; // Initialize LZMA encoder - return_if_error(lzma_lzma_encoder_create(&lz->coder->lzma, allocator, - &lz->coder->opt_cur, lz_options)); + return_if_error(lzma_lzma_encoder_create(&coder->lzma, allocator, + &coder->opt_cur, lz_options)); // Make sure that we will always have enough history available in // case we need to use uncompressed chunks. They are used when the @@ -364,7 +371,7 @@ lzma_lzma2_encoder_memusage(const void *options) if (lzma_mem == UINT64_MAX) return UINT64_MAX; - return sizeof(lzma_coder) + lzma_mem; + return sizeof(lzma_lzma2_coder) + lzma_mem; } diff --git a/contrib/xz/src/liblzma/lzma/lzma_decoder.c b/contrib/xz/src/liblzma/lzma/lzma_decoder.c index b8f9317..eedc073 100644 --- a/contrib/xz/src/liblzma/lzma/lzma_decoder.c +++ b/contrib/xz/src/liblzma/lzma/lzma_decoder.c @@ -161,7 +161,7 @@ typedef struct { } lzma_length_decoder; -struct lzma_coder_s { +typedef struct { /////////////////// // Probabilities // /////////////////// @@ -277,14 +277,16 @@ struct lzma_coder_s { /// If decoding a literal: match byte. /// If decoding a match: length of the match. uint32_t len; -}; +} lzma_lzma1_decoder; static lzma_ret -lzma_decode(lzma_coder *restrict coder, lzma_dict *restrict dictptr, +lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size) { + lzma_lzma1_decoder *restrict coder = coder_ptr; + //////////////////// // Initialization // //////////////////// @@ -840,23 +842,17 @@ out: static void -lzma_decoder_uncompressed(lzma_coder *coder, lzma_vli uncompressed_size) +lzma_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size) { + lzma_lzma1_decoder *coder = coder_ptr; coder->uncompressed_size = uncompressed_size; } -/* -extern void -lzma_lzma_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size) -{ - // This is hack. - (*(lzma_coder **)(coder))->uncompressed_size = uncompressed_size; -} -*/ static void -lzma_decoder_reset(lzma_coder *coder, const void *opt) +lzma_decoder_reset(void *coder_ptr, const void *opt) { + lzma_lzma1_decoder *coder = coder_ptr; const lzma_options_lzma *options = opt; // NOTE: We assume that lc/lp/pb are valid since they were @@ -941,7 +937,7 @@ lzma_lzma_decoder_create(lzma_lz_decoder *lz, const lzma_allocator *allocator, const void *opt, lzma_lz_options *lz_options) { if (lz->coder == NULL) { - lz->coder = lzma_alloc(sizeof(lzma_coder), allocator); + lz->coder = lzma_alloc(sizeof(lzma_lzma1_decoder), allocator); if (lz->coder == NULL) return LZMA_MEM_ERROR; @@ -1014,7 +1010,8 @@ extern uint64_t lzma_lzma_decoder_memusage_nocheck(const void *options) { const lzma_options_lzma *const opt = options; - return sizeof(lzma_coder) + lzma_lz_decoder_memusage(opt->dict_size); + return sizeof(lzma_lzma1_decoder) + + lzma_lz_decoder_memusage(opt->dict_size); } diff --git a/contrib/xz/src/liblzma/lzma/lzma_encoder.c b/contrib/xz/src/liblzma/lzma/lzma_encoder.c index 4c5f99c..ba9ce69 100644 --- a/contrib/xz/src/liblzma/lzma/lzma_encoder.c +++ b/contrib/xz/src/liblzma/lzma/lzma_encoder.c @@ -43,7 +43,7 @@ literal_matched(lzma_range_encoder *rc, probability *subcoder, static inline void -literal(lzma_coder *coder, lzma_mf *mf, uint32_t position) +literal(lzma_lzma1_encoder *coder, lzma_mf *mf, uint32_t position) { // Locate the literal byte to be encoded and the subcoder. const uint8_t cur_byte = mf->buffer[ @@ -140,7 +140,7 @@ length(lzma_range_encoder *rc, lzma_length_encoder *lc, /////////// static inline void -match(lzma_coder *coder, const uint32_t pos_state, +match(lzma_lzma1_encoder *coder, const uint32_t pos_state, const uint32_t distance, const uint32_t len) { update_match(coder->state); @@ -187,7 +187,7 @@ match(lzma_coder *coder, const uint32_t pos_state, //////////////////// static inline void -rep_match(lzma_coder *coder, const uint32_t pos_state, +rep_match(lzma_lzma1_encoder *coder, const uint32_t pos_state, const uint32_t rep, const uint32_t len) { if (rep == 0) { @@ -231,7 +231,7 @@ rep_match(lzma_coder *coder, const uint32_t pos_state, ////////// static void -encode_symbol(lzma_coder *coder, lzma_mf *mf, +encode_symbol(lzma_lzma1_encoder *coder, lzma_mf *mf, uint32_t back, uint32_t len, uint32_t position) { const uint32_t pos_state = position & coder->pos_mask; @@ -265,7 +265,7 @@ encode_symbol(lzma_coder *coder, lzma_mf *mf, static bool -encode_init(lzma_coder *coder, lzma_mf *mf) +encode_init(lzma_lzma1_encoder *coder, lzma_mf *mf) { assert(mf_position(mf) == 0); @@ -293,7 +293,7 @@ encode_init(lzma_coder *coder, lzma_mf *mf) static void -encode_eopm(lzma_coder *coder, uint32_t position) +encode_eopm(lzma_lzma1_encoder *coder, uint32_t position) { const uint32_t pos_state = position & coder->pos_mask; rc_bit(&coder->rc, &coder->is_match[coder->state][pos_state], 1); @@ -309,7 +309,7 @@ encode_eopm(lzma_coder *coder, uint32_t position) extern lzma_ret -lzma_lzma_encode(lzma_coder *restrict coder, lzma_mf *restrict mf, +lzma_lzma_encode(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, uint32_t limit) { @@ -402,7 +402,7 @@ lzma_lzma_encode(lzma_coder *restrict coder, lzma_mf *restrict mf, static lzma_ret -lzma_encode(lzma_coder *restrict coder, lzma_mf *restrict mf, +lzma_encode(void *coder, lzma_mf *restrict mf, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size) { @@ -473,7 +473,8 @@ length_encoder_reset(lzma_length_encoder *lencoder, extern lzma_ret -lzma_lzma_encoder_reset(lzma_coder *coder, const lzma_options_lzma *options) +lzma_lzma_encoder_reset(lzma_lzma1_encoder *coder, + const lzma_options_lzma *options) { if (!is_options_valid(options)) return LZMA_OPTIONS_ERROR; @@ -545,18 +546,18 @@ lzma_lzma_encoder_reset(lzma_coder *coder, const lzma_options_lzma *options) extern lzma_ret -lzma_lzma_encoder_create(lzma_coder **coder_ptr, +lzma_lzma_encoder_create(void **coder_ptr, const lzma_allocator *allocator, const lzma_options_lzma *options, lzma_lz_options *lz_options) { - // Allocate lzma_coder if it wasn't already allocated. + // Allocate lzma_lzma1_encoder if it wasn't already allocated. if (*coder_ptr == NULL) { - *coder_ptr = lzma_alloc(sizeof(lzma_coder), allocator); + *coder_ptr = lzma_alloc(sizeof(lzma_lzma1_encoder), allocator); if (*coder_ptr == NULL) return LZMA_MEM_ERROR; } - lzma_coder *coder = *coder_ptr; + lzma_lzma1_encoder *coder = *coder_ptr; // Set compression mode. We haven't validates the options yet, // but it's OK here, since nothing bad happens with invalid @@ -636,7 +637,7 @@ lzma_lzma_encoder_memusage(const void *options) if (lz_memusage == UINT64_MAX) return UINT64_MAX; - return (uint64_t)(sizeof(lzma_coder)) + lz_memusage; + return (uint64_t)(sizeof(lzma_lzma1_encoder)) + lz_memusage; } diff --git a/contrib/xz/src/liblzma/lzma/lzma_encoder.h b/contrib/xz/src/liblzma/lzma/lzma_encoder.h index cc9cc2f..6cfdf22 100644 --- a/contrib/xz/src/liblzma/lzma/lzma_encoder.h +++ b/contrib/xz/src/liblzma/lzma/lzma_encoder.h @@ -17,6 +17,9 @@ #include "common.h" +typedef struct lzma_lzma1_encoder_s lzma_lzma1_encoder; + + extern lzma_ret lzma_lzma_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters); @@ -36,16 +39,16 @@ extern bool lzma_lzma_lclppb_encode( /// Initializes raw LZMA encoder; this is used by LZMA2. extern lzma_ret lzma_lzma_encoder_create( - lzma_coder **coder_ptr, const lzma_allocator *allocator, + void **coder_ptr, const lzma_allocator *allocator, const lzma_options_lzma *options, lzma_lz_options *lz_options); /// Resets an already initialized LZMA encoder; this is used by LZMA2. extern lzma_ret lzma_lzma_encoder_reset( - lzma_coder *coder, const lzma_options_lzma *options); + lzma_lzma1_encoder *coder, const lzma_options_lzma *options); -extern lzma_ret lzma_lzma_encode(lzma_coder *restrict coder, +extern lzma_ret lzma_lzma_encode(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, uint32_t read_limit); diff --git a/contrib/xz/src/liblzma/lzma/lzma_encoder_optimum_fast.c b/contrib/xz/src/liblzma/lzma/lzma_encoder_optimum_fast.c index 9b30347..6c53d2b 100644 --- a/contrib/xz/src/liblzma/lzma/lzma_encoder_optimum_fast.c +++ b/contrib/xz/src/liblzma/lzma/lzma_encoder_optimum_fast.c @@ -18,7 +18,8 @@ extern void -lzma_lzma_optimum_fast(lzma_coder *restrict coder, lzma_mf *restrict mf, +lzma_lzma_optimum_fast(lzma_lzma1_encoder *restrict coder, + lzma_mf *restrict mf, uint32_t *restrict back_res, uint32_t *restrict len_res) { const uint32_t nice_len = mf->nice_len; diff --git a/contrib/xz/src/liblzma/lzma/lzma_encoder_optimum_normal.c b/contrib/xz/src/liblzma/lzma/lzma_encoder_optimum_normal.c index a360579..59f7734 100644 --- a/contrib/xz/src/liblzma/lzma/lzma_encoder_optimum_normal.c +++ b/contrib/xz/src/liblzma/lzma/lzma_encoder_optimum_normal.c @@ -19,7 +19,7 @@ //////////// static uint32_t -get_literal_price(const lzma_coder *const coder, const uint32_t pos, +get_literal_price(const lzma_lzma1_encoder *const coder, const uint32_t pos, const uint32_t prev_byte, const bool match_mode, uint32_t match_byte, uint32_t symbol) { @@ -65,7 +65,7 @@ get_len_price(const lzma_length_encoder *const lencoder, static inline uint32_t -get_short_rep_price(const lzma_coder *const coder, +get_short_rep_price(const lzma_lzma1_encoder *const coder, const lzma_lzma_state state, const uint32_t pos_state) { return rc_bit_0_price(coder->is_rep0[state]) @@ -74,7 +74,7 @@ get_short_rep_price(const lzma_coder *const coder, static inline uint32_t -get_pure_rep_price(const lzma_coder *const coder, const uint32_t rep_index, +get_pure_rep_price(const lzma_lzma1_encoder *const coder, const uint32_t rep_index, const lzma_lzma_state state, uint32_t pos_state) { uint32_t price; @@ -99,7 +99,7 @@ get_pure_rep_price(const lzma_coder *const coder, const uint32_t rep_index, static inline uint32_t -get_rep_price(const lzma_coder *const coder, const uint32_t rep_index, +get_rep_price(const lzma_lzma1_encoder *const coder, const uint32_t rep_index, const uint32_t len, const lzma_lzma_state state, const uint32_t pos_state) { @@ -109,7 +109,7 @@ get_rep_price(const lzma_coder *const coder, const uint32_t rep_index, static inline uint32_t -get_dist_len_price(const lzma_coder *const coder, const uint32_t dist, +get_dist_len_price(const lzma_lzma1_encoder *const coder, const uint32_t dist, const uint32_t len, const uint32_t pos_state) { const uint32_t dist_state = get_dist_state(len); @@ -130,7 +130,7 @@ get_dist_len_price(const lzma_coder *const coder, const uint32_t dist, static void -fill_dist_prices(lzma_coder *coder) +fill_dist_prices(lzma_lzma1_encoder *coder) { for (uint32_t dist_state = 0; dist_state < DIST_STATES; ++dist_state) { @@ -185,7 +185,7 @@ fill_dist_prices(lzma_coder *coder) static void -fill_align_prices(lzma_coder *coder) +fill_align_prices(lzma_lzma1_encoder *coder) { for (uint32_t i = 0; i < ALIGN_SIZE; ++i) coder->align_prices[i] = rc_bittree_reverse_price( @@ -221,7 +221,7 @@ make_short_rep(lzma_optimal *optimal) static void -backward(lzma_coder *restrict coder, uint32_t *restrict len_res, +backward(lzma_lzma1_encoder *restrict coder, uint32_t *restrict len_res, uint32_t *restrict back_res, uint32_t cur) { coder->opts_end_index = cur; @@ -269,7 +269,7 @@ backward(lzma_coder *restrict coder, uint32_t *restrict len_res, ////////// static inline uint32_t -helper1(lzma_coder *restrict coder, lzma_mf *restrict mf, +helper1(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, uint32_t *restrict back_res, uint32_t *restrict len_res, uint32_t position) { @@ -441,7 +441,7 @@ helper1(lzma_coder *restrict coder, lzma_mf *restrict mf, static inline uint32_t -helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf, +helper2(lzma_lzma1_encoder *coder, uint32_t *reps, const uint8_t *buf, uint32_t len_end, uint32_t position, const uint32_t cur, const uint32_t nice_len, const uint32_t buf_avail_full) { @@ -797,7 +797,8 @@ helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf, extern void -lzma_lzma_optimum_normal(lzma_coder *restrict coder, lzma_mf *restrict mf, +lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder, + lzma_mf *restrict mf, uint32_t *restrict back_res, uint32_t *restrict len_res, uint32_t position) { diff --git a/contrib/xz/src/liblzma/lzma/lzma_encoder_presets.c b/contrib/xz/src/liblzma/lzma/lzma_encoder_presets.c index 8484b77..711df02 100644 --- a/contrib/xz/src/liblzma/lzma/lzma_encoder_presets.c +++ b/contrib/xz/src/liblzma/lzma/lzma_encoder_presets.c @@ -2,6 +2,7 @@ // /// \file lzma_encoder_presets.c /// \brief Encoder presets +/// \note xz needs this even when only decoding is enabled. // // Author: Lasse Collin // diff --git a/contrib/xz/src/liblzma/lzma/lzma_encoder_private.h b/contrib/xz/src/liblzma/lzma/lzma_encoder_private.h index 2f62d6c..a2da969 100644 --- a/contrib/xz/src/liblzma/lzma/lzma_encoder_private.h +++ b/contrib/xz/src/liblzma/lzma/lzma_encoder_private.h @@ -69,7 +69,7 @@ typedef struct { } lzma_optimal; -struct lzma_coder_s { +struct lzma_lzma1_encoder_s { /// Range encoder lzma_range_encoder rc; @@ -138,10 +138,10 @@ struct lzma_coder_s { extern void lzma_lzma_optimum_fast( - lzma_coder *restrict coder, lzma_mf *restrict mf, + lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, uint32_t *restrict back_res, uint32_t *restrict len_res); -extern void lzma_lzma_optimum_normal(lzma_coder *restrict coder, +extern void lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, uint32_t *restrict back_res, uint32_t *restrict len_res, uint32_t position); diff --git a/contrib/xz/src/liblzma/simple/arm.c b/contrib/xz/src/liblzma/simple/arm.c index 258d870..181d0e3 100644 --- a/contrib/xz/src/liblzma/simple/arm.c +++ b/contrib/xz/src/liblzma/simple/arm.c @@ -15,7 +15,7 @@ static size_t -arm_code(lzma_simple *simple lzma_attribute((__unused__)), +arm_code(void *simple lzma_attribute((__unused__)), uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size) { diff --git a/contrib/xz/src/liblzma/simple/armthumb.c b/contrib/xz/src/liblzma/simple/armthumb.c index 06c21e4..eab4862 100644 --- a/contrib/xz/src/liblzma/simple/armthumb.c +++ b/contrib/xz/src/liblzma/simple/armthumb.c @@ -15,7 +15,7 @@ static size_t -armthumb_code(lzma_simple *simple lzma_attribute((__unused__)), +armthumb_code(void *simple lzma_attribute((__unused__)), uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size) { diff --git a/contrib/xz/src/liblzma/simple/ia64.c b/contrib/xz/src/liblzma/simple/ia64.c index ba7249c..580529e 100644 --- a/contrib/xz/src/liblzma/simple/ia64.c +++ b/contrib/xz/src/liblzma/simple/ia64.c @@ -15,7 +15,7 @@ static size_t -ia64_code(lzma_simple *simple lzma_attribute((__unused__)), +ia64_code(void *simple lzma_attribute((__unused__)), uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size) { diff --git a/contrib/xz/src/liblzma/simple/powerpc.c b/contrib/xz/src/liblzma/simple/powerpc.c index 4689919..54dfbf1 100644 --- a/contrib/xz/src/liblzma/simple/powerpc.c +++ b/contrib/xz/src/liblzma/simple/powerpc.c @@ -15,7 +15,7 @@ static size_t -powerpc_code(lzma_simple *simple lzma_attribute((__unused__)), +powerpc_code(void *simple lzma_attribute((__unused__)), uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size) { diff --git a/contrib/xz/src/liblzma/simple/simple_coder.c b/contrib/xz/src/liblzma/simple/simple_coder.c index dba5417..13ebabc 100644 --- a/contrib/xz/src/liblzma/simple/simple_coder.c +++ b/contrib/xz/src/liblzma/simple/simple_coder.c @@ -18,7 +18,7 @@ /// Copied or encodes/decodes more data to out[]. static lzma_ret -copy_or_code(lzma_coder *coder, const lzma_allocator *allocator, +copy_or_code(lzma_simple_coder *coder, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) @@ -55,7 +55,7 @@ copy_or_code(lzma_coder *coder, const lzma_allocator *allocator, static size_t -call_filter(lzma_coder *coder, uint8_t *buffer, size_t size) +call_filter(lzma_simple_coder *coder, uint8_t *buffer, size_t size) { const size_t filtered = coder->filter(coder->simple, coder->now_pos, coder->is_encoder, @@ -66,11 +66,13 @@ call_filter(lzma_coder *coder, uint8_t *buffer, size_t size) static lzma_ret -simple_code(lzma_coder *coder, const lzma_allocator *allocator, +simple_code(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action) { + lzma_simple_coder *coder = coder_ptr; + // TODO: Add partial support for LZMA_SYNC_FLUSH. We can support it // in cases when the filter is able to filter everything. With most // simple filters it can be done at offset that is a multiple of 2, @@ -198,8 +200,9 @@ simple_code(lzma_coder *coder, const lzma_allocator *allocator, static void -simple_coder_end(lzma_coder *coder, const lzma_allocator *allocator) +simple_coder_end(void *coder_ptr, const lzma_allocator *allocator) { + lzma_simple_coder *coder = coder_ptr; lzma_next_end(&coder->next, allocator); lzma_free(coder->simple, allocator); lzma_free(coder, allocator); @@ -208,10 +211,12 @@ simple_coder_end(lzma_coder *coder, const lzma_allocator *allocator) static lzma_ret -simple_coder_update(lzma_coder *coder, const lzma_allocator *allocator, +simple_coder_update(void *coder_ptr, const lzma_allocator *allocator, const lzma_filter *filters_null lzma_attribute((__unused__)), const lzma_filter *reversed_filters) { + lzma_simple_coder *coder = coder_ptr; + // No update support, just call the next filter in the chain. return lzma_next_filter_update( &coder->next, allocator, reversed_filters + 1); @@ -221,57 +226,57 @@ simple_coder_update(lzma_coder *coder, const lzma_allocator *allocator, extern lzma_ret lzma_simple_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters, - size_t (*filter)(lzma_simple *simple, uint32_t now_pos, + size_t (*filter)(void *simple, uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size), size_t simple_size, size_t unfiltered_max, uint32_t alignment, bool is_encoder) { - // Allocate memory for the lzma_coder structure if needed. - if (next->coder == NULL) { + // Allocate memory for the lzma_simple_coder structure if needed. + lzma_simple_coder *coder = next->coder; + if (coder == NULL) { // Here we allocate space also for the temporary buffer. We // need twice the size of unfiltered_max, because then it // is always possible to filter at least unfiltered_max bytes // more data in coder->buffer[] if it can be filled completely. - next->coder = lzma_alloc(sizeof(lzma_coder) + coder = lzma_alloc(sizeof(lzma_simple_coder) + 2 * unfiltered_max, allocator); - if (next->coder == NULL) + if (coder == NULL) return LZMA_MEM_ERROR; + next->coder = coder; next->code = &simple_code; next->end = &simple_coder_end; next->update = &simple_coder_update; - next->coder->next = LZMA_NEXT_CODER_INIT; - next->coder->filter = filter; - next->coder->allocated = 2 * unfiltered_max; + coder->next = LZMA_NEXT_CODER_INIT; + coder->filter = filter; + coder->allocated = 2 * unfiltered_max; // Allocate memory for filter-specific data structure. if (simple_size > 0) { - next->coder->simple = lzma_alloc( - simple_size, allocator); - if (next->coder->simple == NULL) + coder->simple = lzma_alloc(simple_size, allocator); + if (coder->simple == NULL) return LZMA_MEM_ERROR; } else { - next->coder->simple = NULL; + coder->simple = NULL; } } if (filters[0].options != NULL) { const lzma_options_bcj *simple = filters[0].options; - next->coder->now_pos = simple->start_offset; - if (next->coder->now_pos & (alignment - 1)) + coder->now_pos = simple->start_offset; + if (coder->now_pos & (alignment - 1)) return LZMA_OPTIONS_ERROR; } else { - next->coder->now_pos = 0; + coder->now_pos = 0; } // Reset variables. - next->coder->is_encoder = is_encoder; - next->coder->end_was_reached = false; - next->coder->pos = 0; - next->coder->filtered = 0; - next->coder->size = 0; - - return lzma_next_filter_init( - &next->coder->next, allocator, filters + 1); + coder->is_encoder = is_encoder; + coder->end_was_reached = false; + coder->pos = 0; + coder->filtered = 0; + coder->size = 0; + + return lzma_next_filter_init(&coder->next, allocator, filters + 1); } diff --git a/contrib/xz/src/liblzma/simple/simple_private.h b/contrib/xz/src/liblzma/simple/simple_private.h index bb20cb4..9d2c0fd 100644 --- a/contrib/xz/src/liblzma/simple/simple_private.h +++ b/contrib/xz/src/liblzma/simple/simple_private.h @@ -16,9 +16,7 @@ #include "simple_coder.h" -typedef struct lzma_simple_s lzma_simple; - -struct lzma_coder_s { +typedef struct { /// Next filter in the chain lzma_next_coder next; @@ -33,12 +31,12 @@ struct lzma_coder_s { /// Pointer to filter-specific function, which does /// the actual filtering. - size_t (*filter)(lzma_simple *simple, uint32_t now_pos, + size_t (*filter)(void *simple, uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size); /// Pointer to filter-specific data, or NULL if filter doesn't need /// any extra data. - lzma_simple *simple; + void *simple; /// The lowest 32 bits of the current position in the data. Most /// filters need this to do conversions between absolute and relative @@ -62,13 +60,13 @@ struct lzma_coder_s { /// Temporary buffer uint8_t buffer[]; -}; +} lzma_simple_coder; extern lzma_ret lzma_simple_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters, - size_t (*filter)(lzma_simple *simple, uint32_t now_pos, + size_t (*filter)(void *simple, uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size), size_t simple_size, size_t unfiltered_max, uint32_t alignment, bool is_encoder); diff --git a/contrib/xz/src/liblzma/simple/sparc.c b/contrib/xz/src/liblzma/simple/sparc.c index 53ee49d..74b2655 100644 --- a/contrib/xz/src/liblzma/simple/sparc.c +++ b/contrib/xz/src/liblzma/simple/sparc.c @@ -15,7 +15,7 @@ static size_t -sparc_code(lzma_simple *simple lzma_attribute((__unused__)), +sparc_code(void *simple lzma_attribute((__unused__)), uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size) { diff --git a/contrib/xz/src/liblzma/simple/x86.c b/contrib/xz/src/liblzma/simple/x86.c index 3b2b4f8..0b14807 100644 --- a/contrib/xz/src/liblzma/simple/x86.c +++ b/contrib/xz/src/liblzma/simple/x86.c @@ -17,14 +17,14 @@ #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) -struct lzma_simple_s { +typedef struct { uint32_t prev_mask; uint32_t prev_pos; -}; +} lzma_simple_x86; static size_t -x86_code(lzma_simple *simple, uint32_t now_pos, bool is_encoder, +x86_code(void *simple_ptr, uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size) { static const bool MASK_TO_ALLOWED_STATUS[8] @@ -33,6 +33,7 @@ x86_code(lzma_simple *simple, uint32_t now_pos, bool is_encoder, static const uint32_t MASK_TO_BIT_NUMBER[8] = { 0, 1, 2, 2, 3, 3, 3, 3 }; + lzma_simple_x86 *simple = simple_ptr; uint32_t prev_mask = simple->prev_mask; uint32_t prev_pos = simple->prev_pos; @@ -127,11 +128,13 @@ x86_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters, bool is_encoder) { const lzma_ret ret = lzma_simple_coder_init(next, allocator, filters, - &x86_code, sizeof(lzma_simple), 5, 1, is_encoder); + &x86_code, sizeof(lzma_simple_x86), 5, 1, is_encoder); if (ret == LZMA_OK) { - next->coder->simple->prev_mask = 0; - next->coder->simple->prev_pos = (uint32_t)(-5); + lzma_simple_coder *coder = next->coder; + lzma_simple_x86 *simple = coder->simple; + simple->prev_mask = 0; + simple->prev_pos = (uint32_t)(-5); } return ret; diff --git a/contrib/xz/src/xz/args.c b/contrib/xz/src/xz/args.c index 041c800..341f29e 100644 --- a/contrib/xz/src/xz/args.c +++ b/contrib/xz/src/xz/args.c @@ -635,6 +635,22 @@ args_parse(args_info *args, int argc, char **argv) // Then from the command line parse_real(args, argc, argv); + // If encoder or decoder support was omitted at build time, + // show an error now so that the rest of the code can rely on + // that whatever is in opt_mode is also supported. +#ifndef HAVE_ENCODERS + if (opt_mode == MODE_COMPRESS) + message_fatal(_("Compression support was disabled " + "at build time")); +#endif +#ifndef HAVE_DECODERS + // Even MODE_LIST cannot work without decoder support so MODE_COMPRESS + // is the only valid choice. + if (opt_mode != MODE_COMPRESS) + message_fatal(_("Decompression support was disabled " + "at build time")); +#endif + // Never remove the source file when the destination is not on disk. // In test mode the data is written nowhere, but setting opt_stdout // will make the rest of the code behave well. diff --git a/contrib/xz/src/xz/coder.c b/contrib/xz/src/xz/coder.c index a94bdb8..3c6a01c 100644 --- a/contrib/xz/src/xz/coder.c +++ b/contrib/xz/src/xz/coder.c @@ -51,7 +51,7 @@ static lzma_check check; /// This becomes false if the --check=CHECK option is used. static bool check_default = true; -#ifdef MYTHREAD_ENABLED +#if defined(HAVE_ENCODERS) && defined(MYTHREAD_ENABLED) static lzma_mt mt_options = { .flags = 0, .timeout = 300, @@ -221,9 +221,10 @@ coder_set_compression_settings(void) // Get the memory usage. Note that if --format=raw was used, // we can be decompressing. const uint64_t memory_limit = hardware_memlimit_get(opt_mode); - uint64_t memory_usage; + uint64_t memory_usage = UINT64_MAX; if (opt_mode == MODE_COMPRESS) { -#ifdef MYTHREAD_ENABLED +#ifdef HAVE_ENCODERS +# ifdef MYTHREAD_ENABLED if (opt_format == FORMAT_XZ && hardware_threads_get() > 1) { mt_options.threads = hardware_threads_get(); mt_options.block_size = opt_block_size; @@ -235,12 +236,15 @@ coder_set_compression_settings(void) " threads."), mt_options.threads); } else -#endif +# endif { memory_usage = lzma_raw_encoder_memusage(filters); } +#endif } else { +#ifdef HAVE_DECODERS memory_usage = lzma_raw_decoder_memusage(filters); +#endif } if (memory_usage == UINT64_MAX) @@ -248,7 +252,11 @@ coder_set_compression_settings(void) // Print memory usage info before possible dictionary // size auto-adjusting. + // + // NOTE: If only encoder support was built, we cannot show the + // what the decoder memory usage will be. message_mem_needed(V_DEBUG, memory_usage); +#ifdef HAVE_DECODERS if (opt_mode == MODE_COMPRESS) { const uint64_t decmem = lzma_raw_decoder_memusage(filters); if (decmem != UINT64_MAX) @@ -256,6 +264,7 @@ coder_set_compression_settings(void) "%s MiB of memory."), uint64_to_str( round_up_to_mib(decmem), 0)); } +#endif if (memory_usage <= memory_limit) return; @@ -268,7 +277,8 @@ coder_set_compression_settings(void) assert(opt_mode == MODE_COMPRESS); -#ifdef MYTHREAD_ENABLED +#ifdef HAVE_ENCODERS +# ifdef MYTHREAD_ENABLED if (opt_format == FORMAT_XZ && mt_options.threads > 1) { // Try to reduce the number of threads before // adjusting the compression settings down. @@ -295,7 +305,7 @@ coder_set_compression_settings(void) uint64_to_str(round_up_to_mib( memory_limit), 2)); } -#endif +# endif if (memory_usage <= memory_limit) return; @@ -349,11 +359,13 @@ coder_set_compression_settings(void) uint64_to_str(orig_dict_size >> 20, 0), uint64_to_str(opt->dict_size >> 20, 1), uint64_to_str(round_up_to_mib(memory_limit), 2)); +#endif return; } +#ifdef HAVE_DECODERS /// Return true if the data in in_buf seems to be in the .xz format. static bool is_format_xz(void) @@ -411,6 +423,7 @@ is_format_lzma(void) return true; } +#endif /// Detect the input file type (for now, this done only when decompressing), @@ -424,6 +437,7 @@ coder_init(file_pair *pair) lzma_ret ret = LZMA_PROG_ERROR; if (opt_mode == MODE_COMPRESS) { +#ifdef HAVE_ENCODERS switch (opt_format) { case FORMAT_AUTO: // args.c ensures this. @@ -431,12 +445,12 @@ coder_init(file_pair *pair) break; case FORMAT_XZ: -#ifdef MYTHREAD_ENABLED +# ifdef MYTHREAD_ENABLED if (hardware_threads_get() > 1) ret = lzma_stream_encoder_mt( &strm, &mt_options); else -#endif +# endif ret = lzma_stream_encoder( &strm, filters, check); break; @@ -449,7 +463,9 @@ coder_init(file_pair *pair) ret = lzma_raw_encoder(&strm, filters); break; } +#endif } else { +#ifdef HAVE_DECODERS uint32_t flags = 0; // It seems silly to warn about unsupported check if the @@ -531,6 +547,7 @@ coder_init(file_pair *pair) strm.avail_out = 0; ret = lzma_code(&strm, LZMA_RUN); } +#endif } if (ret != LZMA_OK) { diff --git a/contrib/xz/src/xz/file_io.c b/contrib/xz/src/xz/file_io.c index 9bd515d..c01f4e8 100644 --- a/contrib/xz/src/xz/file_io.c +++ b/contrib/xz/src/xz/file_io.c @@ -23,10 +23,20 @@ static bool warn_fchown; #if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES) # include <sys/time.h> +#elif defined(HAVE__FUTIME) +# include <sys/utime.h> #elif defined(HAVE_UTIME) # include <utime.h> #endif +#ifdef HAVE_CAPSICUM +# ifdef HAVE_SYS_CAPSICUM_H +# include <sys/capsicum.h> +# else +# include <sys/capability.h> +# endif +#endif + #include "tuklib_open_stdxxx.h" #ifndef O_BINARY @@ -37,6 +47,14 @@ static bool warn_fchown; # define O_NOCTTY 0 #endif +// Using this macro to silence a warning from gcc -Wlogical-op. +#if EAGAIN == EWOULDBLOCK +# define IS_EAGAIN_OR_EWOULDBLOCK(e) ((e) == EAGAIN) +#else +# define IS_EAGAIN_OR_EWOULDBLOCK(e) \ + ((e) == EAGAIN || (e) == EWOULDBLOCK) +#endif + typedef enum { IO_WAIT_MORE, // Reading or writing is possible. @@ -48,6 +66,11 @@ typedef enum { /// If true, try to create sparse files when decompressing. static bool try_sparse = true; +#ifdef ENABLE_SANDBOX +/// True if the conditions for sandboxing (described in main()) have been met. +static bool sandbox_allowed = false; +#endif + #ifndef TUKLIB_DOSLIKE /// File status flags of standard input. This is used by io_open_src() /// and io_close_src(). @@ -132,6 +155,73 @@ io_no_sparse(void) } +#ifdef ENABLE_SANDBOX +extern void +io_allow_sandbox(void) +{ + sandbox_allowed = true; + return; +} + + +/// Enables operating-system-specific sandbox if it is possible. +/// src_fd is the file descriptor of the input file. +static void +io_sandbox_enter(int src_fd) +{ + if (!sandbox_allowed) { + message(V_DEBUG, _("Sandbox is disabled due " + "to incompatible command line arguments")); + return; + } + + const char dummy_str[] = "x"; + + // Try to ensure that both libc and xz locale files have been + // loaded when NLS is enabled. + snprintf(NULL, 0, "%s%s", _(dummy_str), strerror(EINVAL)); + + // Try to ensure that iconv data files needed for handling multibyte + // characters have been loaded. This is needed at least with glibc. + tuklib_mbstr_width(dummy_str, NULL); + +#ifdef HAVE_CAPSICUM + // Capsicum needs FreeBSD 10.0 or later. + cap_rights_t rights; + + if (cap_rights_limit(src_fd, cap_rights_init(&rights, + CAP_EVENT, CAP_FCNTL, CAP_LOOKUP, CAP_READ, CAP_SEEK))) + goto error; + + if (cap_rights_limit(STDOUT_FILENO, cap_rights_init(&rights, + CAP_EVENT, CAP_FCNTL, CAP_FSTAT, CAP_LOOKUP, + CAP_WRITE, CAP_SEEK))) + goto error; + + if (cap_rights_limit(user_abort_pipe[0], cap_rights_init(&rights, + CAP_EVENT))) + goto error; + + if (cap_rights_limit(user_abort_pipe[1], cap_rights_init(&rights, + CAP_WRITE))) + goto error; + + if (cap_enter()) + goto error; + +#else +# error ENABLE_SANDBOX is defined but no sandboxing method was found. +#endif + + message(V_DEBUG, _("Sandbox was successfully enabled")); + return; + +error: + message(V_DEBUG, _("Failed to enable the sandbox")); +} +#endif // ENABLE_SANDBOX + + #ifndef TUKLIB_DOSLIKE /// \brief Waits for input or output to become available or for a signal /// @@ -369,6 +459,22 @@ io_copy_attrs(const file_pair *pair) (void)utimes(pair->dest_name, tv); # endif +#elif defined(HAVE__FUTIME) + // Use one-second precision with Windows-specific _futime(). + // We could use utime() too except that for some reason the + // timestamp will get reset at close(). With _futime() it works. + // This struct cannot be const as _futime() takes a non-const pointer. + struct _utimbuf buf = { + .actime = pair->src_st.st_atime, + .modtime = pair->src_st.st_mtime, + }; + + // Avoid warnings. + (void)atime_nsec; + (void)mtime_nsec; + + (void)_futime(pair->dest_fd, &buf); + #elif defined(HAVE_UTIME) // Use one-second precision. utime() doesn't support using file // descriptor either. Some systems have broken utime() prototype @@ -649,6 +755,11 @@ io_open_src(const char *src_name) const bool error = io_open_src_real(&pair); signals_unblock(); +#ifdef ENABLE_SANDBOX + if (!error) + io_sandbox_enter(pair.src_fd); +#endif + return error ? NULL : &pair; } @@ -675,23 +786,22 @@ io_close_src(file_pair *pair, bool success) #endif if (pair->src_fd != STDIN_FILENO && pair->src_fd != -1) { -#ifdef TUKLIB_DOSLIKE + // Close the file before possibly unlinking it. On DOS-like + // systems this is always required since unlinking will fail + // if the file is open. On POSIX systems it usually works + // to unlink open files, but in some cases it doesn't and + // one gets EBUSY in errno. + // + // xz 5.2.2 and older unlinked the file before closing it + // (except on DOS-like systems). The old code didn't handle + // EBUSY and could fail e.g. on some CIFS shares. The + // advantage of unlinking before closing is negligible + // (avoids a race between close() and stat()/lstat() and + // unlink()), so let's keep this simple. (void)close(pair->src_fd); -#endif - // If we are going to unlink(), do it before closing the file. - // This way there's no risk that someone replaces the file and - // happens to get same inode number, which would make us - // unlink() wrong file. - // - // NOTE: DOS-like systems are an exception to this, because - // they don't allow unlinking files that are open. *sigh* if (success && !opt_keep_original) io_unlink(pair->src_name, &pair->src_st); - -#ifndef TUKLIB_DOSLIKE - (void)close(pair->src_fd); -#endif } return; @@ -1018,7 +1128,7 @@ io_read(file_pair *pair, io_buf *buf_union, size_t size) } #ifndef TUKLIB_DOSLIKE - if (errno == EAGAIN || errno == EWOULDBLOCK) { + if (IS_EAGAIN_OR_EWOULDBLOCK(errno)) { const io_wait_ret ret = io_wait(pair, mytime_get_flush_timeout(), true); @@ -1106,7 +1216,7 @@ io_write_buf(file_pair *pair, const uint8_t *buf, size_t size) } #ifndef TUKLIB_DOSLIKE - if (errno == EAGAIN || errno == EWOULDBLOCK) { + if (IS_EAGAIN_OR_EWOULDBLOCK(errno)) { if (io_wait(pair, -1, false) == IO_WAIT_MORE) continue; diff --git a/contrib/xz/src/xz/file_io.h b/contrib/xz/src/xz/file_io.h index 2de3379..6722aef 100644 --- a/contrib/xz/src/xz/file_io.h +++ b/contrib/xz/src/xz/file_io.h @@ -80,6 +80,12 @@ extern void io_write_to_user_abort_pipe(void); extern void io_no_sparse(void); +#ifdef ENABLE_SANDBOX +/// \brief main() calls this if conditions for sandboxing have been met. +extern void io_allow_sandbox(void); +#endif + + /// \brief Open the source file extern file_pair *io_open_src(const char *src_name); diff --git a/contrib/xz/src/xz/main.c b/contrib/xz/src/xz/main.c index 5608229..af550c4 100644 --- a/contrib/xz/src/xz/main.c +++ b/contrib/xz/src/xz/main.c @@ -205,10 +205,31 @@ main(int argc, char **argv) if (opt_mode != MODE_LIST) signals_init(); +#ifdef ENABLE_SANDBOX + // Set a flag that sandboxing is allowed if all these are true: + // - --files or --files0 wasn't used. + // - There is exactly one input file or we are reading from stdin. + // - We won't create any files: output goes to stdout or --test + // or --list was used. Note that --test implies opt_stdout = true + // but --list doesn't. + // + // This is obviously not ideal but it was easy to implement and + // it covers the most common use cases. + // + // TODO: Make sandboxing work for other situations too. + if (args.files_name == NULL && args.arg_count == 1 + && (opt_stdout || strcmp("-", args.arg_names[0]) == 0 + || opt_mode == MODE_LIST)) + io_allow_sandbox(); +#endif + // coder_run() handles compression, decompression, and testing. // list_file() is for --list. - void (*run)(const char *filename) = opt_mode == MODE_LIST - ? &list_file : &coder_run; + void (*run)(const char *filename) = &coder_run; +#ifdef HAVE_DECODERS + if (opt_mode == MODE_LIST) + run = &list_file; +#endif // Process the files given on the command line. Note that if no names // were given, args_parse() gave us a fake "-" filename. @@ -267,6 +288,7 @@ main(int argc, char **argv) (void)fclose(args.files_file); } +#ifdef HAVE_DECODERS // All files have now been handled. If in --list mode, display // the totals before exiting. We don't have signal handlers // enabled in --list mode, so we don't need to check user_abort. @@ -274,6 +296,7 @@ main(int argc, char **argv) assert(!user_abort); list_totals(); } +#endif #ifndef NDEBUG coder_free(); diff --git a/contrib/xz/src/xz/private.h b/contrib/xz/src/xz/private.h index 4acfa8d..e61563a 100644 --- a/contrib/xz/src/xz/private.h +++ b/contrib/xz/src/xz/private.h @@ -45,6 +45,10 @@ # define STDERR_FILENO (fileno(stderr)) #endif +#ifdef HAVE_CAPSICUM +# define ENABLE_SANDBOX 1 +#endif + #include "main.h" #include "mytime.h" #include "coder.h" @@ -56,4 +60,7 @@ #include "signals.h" #include "suffix.h" #include "util.h" -#include "list.h" + +#ifdef HAVE_DECODERS +# include "list.h" +#endif diff --git a/lib/libz/ChangeLog b/contrib/zlib/ChangeLog index f22aaba..f22aaba 100644 --- a/lib/libz/ChangeLog +++ b/contrib/zlib/ChangeLog diff --git a/lib/libz/FAQ b/contrib/zlib/FAQ index 99b7cf9..99b7cf9 100644 --- a/lib/libz/FAQ +++ b/contrib/zlib/FAQ diff --git a/lib/libz/README b/contrib/zlib/README index 5ca9d12..5ca9d12 100644 --- a/lib/libz/README +++ b/contrib/zlib/README diff --git a/lib/libz/adler32.c b/contrib/zlib/adler32.c index a868f07..a868f07 100644 --- a/lib/libz/adler32.c +++ b/contrib/zlib/adler32.c diff --git a/lib/libz/compress.c b/contrib/zlib/compress.c index 6e97626..6e97626 100644 --- a/lib/libz/compress.c +++ b/contrib/zlib/compress.c diff --git a/lib/libz/contrib/README.contrib b/contrib/zlib/contrib/README.contrib index c66349b..c66349b 100644 --- a/lib/libz/contrib/README.contrib +++ b/contrib/zlib/contrib/README.contrib diff --git a/lib/libz/contrib/asm686/README.686 b/contrib/zlib/contrib/asm686/README.686 index a0bf3be..a0bf3be 100644 --- a/lib/libz/contrib/asm686/README.686 +++ b/contrib/zlib/contrib/asm686/README.686 diff --git a/lib/libz/contrib/asm686/match.S b/contrib/zlib/contrib/asm686/match.S index fa42109..fa42109 100644 --- a/lib/libz/contrib/asm686/match.S +++ b/contrib/zlib/contrib/asm686/match.S diff --git a/lib/libz/contrib/gcc_gvmat64/gvmat64.S b/contrib/zlib/contrib/gcc_gvmat64/gvmat64.S index 23309fa..23309fa 100644 --- a/lib/libz/contrib/gcc_gvmat64/gvmat64.S +++ b/contrib/zlib/contrib/gcc_gvmat64/gvmat64.S diff --git a/lib/libz/crc32.c b/contrib/zlib/crc32.c index 979a719..979a719 100644 --- a/lib/libz/crc32.c +++ b/contrib/zlib/crc32.c diff --git a/lib/libz/crc32.h b/contrib/zlib/crc32.h index 9e0c778..9e0c778 100644 --- a/lib/libz/crc32.h +++ b/contrib/zlib/crc32.h diff --git a/lib/libz/deflate.c b/contrib/zlib/deflate.c index 6969577..6969577 100644 --- a/lib/libz/deflate.c +++ b/contrib/zlib/deflate.c diff --git a/lib/libz/deflate.h b/contrib/zlib/deflate.h index ce0299e..ce0299e 100644 --- a/lib/libz/deflate.h +++ b/contrib/zlib/deflate.h diff --git a/lib/libz/doc/algorithm.txt b/contrib/zlib/doc/algorithm.txt index c97f495..c97f495 100644 --- a/lib/libz/doc/algorithm.txt +++ b/contrib/zlib/doc/algorithm.txt diff --git a/lib/libz/doc/rfc1950.txt b/contrib/zlib/doc/rfc1950.txt index ce6428a..ce6428a 100644 --- a/lib/libz/doc/rfc1950.txt +++ b/contrib/zlib/doc/rfc1950.txt diff --git a/lib/libz/doc/rfc1951.txt b/contrib/zlib/doc/rfc1951.txt index 403c8c7..403c8c7 100644 --- a/lib/libz/doc/rfc1951.txt +++ b/contrib/zlib/doc/rfc1951.txt diff --git a/lib/libz/doc/rfc1952.txt b/contrib/zlib/doc/rfc1952.txt index a8e51b4..a8e51b4 100644 --- a/lib/libz/doc/rfc1952.txt +++ b/contrib/zlib/doc/rfc1952.txt diff --git a/lib/libz/doc/txtvsbin.txt b/contrib/zlib/doc/txtvsbin.txt index 3d0f063..3d0f063 100644 --- a/lib/libz/doc/txtvsbin.txt +++ b/contrib/zlib/doc/txtvsbin.txt diff --git a/lib/libz/gzclose.c b/contrib/zlib/gzclose.c index caeb99a..caeb99a 100644 --- a/lib/libz/gzclose.c +++ b/contrib/zlib/gzclose.c diff --git a/lib/libz/gzguts.h b/contrib/zlib/gzguts.h index d87659d..d87659d 100644 --- a/lib/libz/gzguts.h +++ b/contrib/zlib/gzguts.h diff --git a/lib/libz/gzlib.c b/contrib/zlib/gzlib.c index d8dbb7e..d8dbb7e 100644 --- a/lib/libz/gzlib.c +++ b/contrib/zlib/gzlib.c diff --git a/lib/libz/gzread.c b/contrib/zlib/gzread.c index a8292ea..a8292ea 100644 --- a/lib/libz/gzread.c +++ b/contrib/zlib/gzread.c diff --git a/lib/libz/gzwrite.c b/contrib/zlib/gzwrite.c index 99cb3c2..99cb3c2 100644 --- a/lib/libz/gzwrite.c +++ b/contrib/zlib/gzwrite.c diff --git a/lib/libz/infback.c b/contrib/zlib/infback.c index f3833c2..f3833c2 100644 --- a/lib/libz/infback.c +++ b/contrib/zlib/infback.c diff --git a/lib/libz/inffast.c b/contrib/zlib/inffast.c index bda59ce..bda59ce 100644 --- a/lib/libz/inffast.c +++ b/contrib/zlib/inffast.c diff --git a/lib/libz/inffast.h b/contrib/zlib/inffast.h index e5c1aa4..e5c1aa4 100644 --- a/lib/libz/inffast.h +++ b/contrib/zlib/inffast.h diff --git a/lib/libz/inffixed.h b/contrib/zlib/inffixed.h index d628327..d628327 100644 --- a/lib/libz/inffixed.h +++ b/contrib/zlib/inffixed.h diff --git a/lib/libz/inflate.c b/contrib/zlib/inflate.c index b51a8a5..b51a8a5 100644 --- a/lib/libz/inflate.c +++ b/contrib/zlib/inflate.c diff --git a/lib/libz/inflate.h b/contrib/zlib/inflate.h index 95f4986..95f4986 100644 --- a/lib/libz/inflate.h +++ b/contrib/zlib/inflate.h diff --git a/lib/libz/inftrees.c b/contrib/zlib/inftrees.c index 44d89cf..44d89cf 100644 --- a/lib/libz/inftrees.c +++ b/contrib/zlib/inftrees.c diff --git a/lib/libz/inftrees.h b/contrib/zlib/inftrees.h index baa53a0..baa53a0 100644 --- a/lib/libz/inftrees.h +++ b/contrib/zlib/inftrees.h diff --git a/lib/libz/test/example.c b/contrib/zlib/test/example.c index 138a699..138a699 100644 --- a/lib/libz/test/example.c +++ b/contrib/zlib/test/example.c diff --git a/lib/libz/test/infcover.c b/contrib/zlib/test/infcover.c index fe3d920..fe3d920 100644 --- a/lib/libz/test/infcover.c +++ b/contrib/zlib/test/infcover.c diff --git a/lib/libz/test/minigzip.c b/contrib/zlib/test/minigzip.c index b3025a4..b3025a4 100644 --- a/lib/libz/test/minigzip.c +++ b/contrib/zlib/test/minigzip.c diff --git a/lib/libz/trees.c b/contrib/zlib/trees.c index 1fd7759..1fd7759 100644 --- a/lib/libz/trees.c +++ b/contrib/zlib/trees.c diff --git a/lib/libz/trees.h b/contrib/zlib/trees.h index d35639d..d35639d 100644 --- a/lib/libz/trees.h +++ b/contrib/zlib/trees.h diff --git a/lib/libz/uncompr.c b/contrib/zlib/uncompr.c index 242e949..242e949 100644 --- a/lib/libz/uncompr.c +++ b/contrib/zlib/uncompr.c diff --git a/lib/libz/zconf.h b/contrib/zlib/zconf.h index 13a2e1c..13a2e1c 100644 --- a/lib/libz/zconf.h +++ b/contrib/zlib/zconf.h diff --git a/contrib/zlib/zconf.h.in b/contrib/zlib/zconf.h.in new file mode 100644 index 0000000..9987a77 --- /dev/null +++ b/contrib/zlib/zconf.h.in @@ -0,0 +1,511 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include <limits.h> +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include <sys/types.h> /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include <stdarg.h> /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include <stddef.h> /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include <unixio.h> /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/lib/libz/zlib.3 b/contrib/zlib/zlib.3 index 0160e62..0160e62 100644 --- a/lib/libz/zlib.3 +++ b/contrib/zlib/zlib.3 diff --git a/lib/libz/zlib.h b/contrib/zlib/zlib.h index 3e0c767..3e0c767 100644 --- a/lib/libz/zlib.h +++ b/contrib/zlib/zlib.h diff --git a/contrib/zlib/zlib.map b/contrib/zlib/zlib.map new file mode 100644 index 0000000..55c6647 --- /dev/null +++ b/contrib/zlib/zlib.map @@ -0,0 +1,83 @@ +ZLIB_1.2.0 { + global: + compressBound; + deflateBound; + inflateBack; + inflateBackEnd; + inflateBackInit_; + inflateCopy; + local: + deflate_copyright; + inflate_copyright; + inflate_fast; + inflate_table; + zcalloc; + zcfree; + z_errmsg; + gz_error; + gz_intmax; + _*; +}; + +ZLIB_1.2.0.2 { + gzclearerr; + gzungetc; + zlibCompileFlags; +} ZLIB_1.2.0; + +ZLIB_1.2.0.8 { + deflatePrime; +} ZLIB_1.2.0.2; + +ZLIB_1.2.2 { + adler32_combine; + crc32_combine; + deflateSetHeader; + inflateGetHeader; +} ZLIB_1.2.0.8; + +ZLIB_1.2.2.3 { + deflateTune; + gzdirect; +} ZLIB_1.2.2; + +ZLIB_1.2.2.4 { + inflatePrime; +} ZLIB_1.2.2.3; + +ZLIB_1.2.3.3 { + adler32_combine64; + crc32_combine64; + gzopen64; + gzseek64; + gztell64; + inflateUndermine; +} ZLIB_1.2.2.4; + +ZLIB_1.2.3.4 { + inflateReset2; + inflateMark; +} ZLIB_1.2.3.3; + +ZLIB_1.2.3.5 { + gzbuffer; + gzoffset; + gzoffset64; + gzclose_r; + gzclose_w; +} ZLIB_1.2.3.4; + +ZLIB_1.2.5.1 { + deflatePending; +} ZLIB_1.2.3.5; + +ZLIB_1.2.5.2 { + deflateResetKeep; + gzgetc_; + inflateResetKeep; +} ZLIB_1.2.5.1; + +ZLIB_1.2.7.1 { + inflateGetDictionary; + gzvprintf; +} ZLIB_1.2.5.2; diff --git a/contrib/zlib/zlib.pc.in b/contrib/zlib/zlib.pc.in new file mode 100644 index 0000000..7e5acf9 --- /dev/null +++ b/contrib/zlib/zlib.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +sharedlibdir=@sharedlibdir@ +includedir=@includedir@ + +Name: zlib +Description: zlib compression library +Version: @VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz +Cflags: -I${includedir} diff --git a/lib/libz/zutil.c b/contrib/zlib/zutil.c index 23d2ebe..23d2ebe 100644 --- a/lib/libz/zutil.c +++ b/contrib/zlib/zutil.c diff --git a/lib/libz/zutil.h b/contrib/zlib/zutil.h index 24ab06b..24ab06b 100644 --- a/lib/libz/zutil.h +++ b/contrib/zlib/zutil.h diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h index ecd014b..3c86255 100644 --- a/crypto/openssh/config.h +++ b/crypto/openssh/config.h @@ -1408,7 +1408,7 @@ /* #undef LASTLOG_WRITE_PUTUTXLINE */ /* Define if you want TCP Wrappers support */ -#define LIBWRAP 1 +/* #undef LIBWRAP */ /* Define to whatever link() returns for "not supported" if it doesn't return EOPNOTSUPP. */ diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c index 80d1db5..f5c362d 100644 --- a/crypto/openssh/serverloop.c +++ b/crypto/openssh/serverloop.c @@ -995,7 +995,7 @@ server_request_direct_streamlocal(void) /* XXX fine grained permissions */ if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && - !no_port_forwarding_flag) { + !no_port_forwarding_flag && use_privsep) { c = channel_connect_to_path(target, "direct-streamlocal@openssh.com", "direct-streamlocal"); } else { @@ -1279,7 +1279,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) /* check permissions */ if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0 - || no_port_forwarding_flag) { + || no_port_forwarding_flag || !use_privsep) { success = 0; packet_send_debug("Server has disabled port forwarding."); } else { diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1 index b8cd0c5..3806b62 100644 --- a/crypto/openssh/ssh-agent.1 +++ b/crypto/openssh/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.62 2015/11/15 23:54:15 jmc Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.63 2016/11/30 03:07:37 djm Exp $ .\" $FreeBSD$ .\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -48,6 +48,7 @@ .Op Fl a Ar bind_address .Op Fl E Ar fingerprint_hash .Op Fl t Ar life +.Op Fl P Ar pkcs11_whitelist .Op Ar command Op Ar arg ... .Nm ssh-agent .Op Fl c | s @@ -122,6 +123,18 @@ The default is Kill the current agent (given by the .Ev SSH_AGENT_PID environment variable). +.It Fl P +Specify a pattern-list of acceptable paths for PKCS#11 shared libraries +that may be added using the +.Fl s +option to +.Xr ssh-add 1 . +The default is to allow loading PKCS#11 libraries from +.Dq /usr/lib/*,/usr/local/lib/* . +PKCS#11 libraries that do not match the whitelist will be refused. +See PATTERNS in +.Xr ssh_config 5 +for a description of pattern-list syntax. .It Fl s Generate Bourne shell commands on .Dv stdout . diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c index 8113022..9cad00a 100644 --- a/crypto/openssh/ssh-agent.c +++ b/crypto/openssh/ssh-agent.c @@ -84,11 +84,16 @@ __RCSID("$FreeBSD$"); #include "misc.h" #include "digest.h" #include "ssherr.h" +#include "match.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" #endif +#ifndef DEFAULT_PKCS11_WHITELIST +# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*" +#endif + #if defined(HAVE_SYS_PRCTL_H) #include <sys/prctl.h> /* For prctl() and PR_SET_DUMPABLE */ #endif @@ -140,6 +145,9 @@ pid_t cleanup_pid = 0; char socket_name[PATH_MAX]; char socket_dir[PATH_MAX]; +/* PKCS#11 path whitelist */ +static char *pkcs11_whitelist; + /* locking */ #define LOCK_SIZE 32 #define LOCK_SALT_SIZE 16 @@ -761,7 +769,7 @@ no_identities(SocketEntry *e, u_int type) static void process_add_smartcard_key(SocketEntry *e) { - char *provider = NULL, *pin; + char *provider = NULL, *pin, canonical_provider[PATH_MAX]; int r, i, version, count = 0, success = 0, confirm = 0; u_int seconds; time_t death = 0; @@ -793,10 +801,21 @@ process_add_smartcard_key(SocketEntry *e) goto send; } } + if (realpath(provider, canonical_provider) == NULL) { + verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", + provider, strerror(errno)); + goto send; + } + if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { + verbose("refusing PKCS#11 add of \"%.100s\": " + "provider not whitelisted", canonical_provider); + goto send; + } + debug("%s: add %.100s", __func__, canonical_provider); if (lifetime && !death) death = monotime() + lifetime; - count = pkcs11_add_provider(provider, pin, &keys); + count = pkcs11_add_provider(canonical_provider, pin, &keys); for (i = 0; i < count; i++) { k = keys[i]; version = k->type == KEY_RSA1 ? 1 : 2; @@ -804,8 +823,8 @@ process_add_smartcard_key(SocketEntry *e) if (lookup_identity(k, version) == NULL) { id = xcalloc(1, sizeof(Identity)); id->key = k; - id->provider = xstrdup(provider); - id->comment = xstrdup(provider); /* XXX */ + id->provider = xstrdup(canonical_provider); + id->comment = xstrdup(canonical_provider); /* XXX */ id->death = death; id->confirm = confirm; TAILQ_INSERT_TAIL(&tab->idlist, id, next); @@ -1200,7 +1219,7 @@ usage(void) { fprintf(stderr, "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" - " [-t life] [command [arg ...]]\n" + " [-P pkcs11_whitelist] [-t life] [command [arg ...]]\n" " ssh-agent [-c | -s] -k\n"); fprintf(stderr, " -x Exit when the last client disconnects.\n"); exit(1); @@ -1246,7 +1265,7 @@ main(int ac, char **av) __progname = ssh_get_progname(av[0]); seed_rng(); - while ((ch = getopt(ac, av, "cDdksE:a:t:x")) != -1) { + while ((ch = getopt(ac, av, "cDdksE:a:P:t:x")) != -1) { switch (ch) { case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); @@ -1261,6 +1280,11 @@ main(int ac, char **av) case 'k': k_flag++; break; + case 'P': + if (pkcs11_whitelist != NULL) + fatal("-P option already specified"); + pkcs11_whitelist = xstrdup(optarg); + break; case 's': if (c_flag) usage(); @@ -1298,6 +1322,9 @@ main(int ac, char **av) if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) usage(); + if (pkcs11_whitelist == NULL) + pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST); + if (ac == 0 && !c_flag && !s_flag) { shell = getenv("SHELL"); if (shell != NULL && (len = strlen(shell)) > 2 && @@ -1445,7 +1472,7 @@ skip: signal(SIGTERM, cleanup_handler); nalloc = 0; - if (pledge("stdio cpath unix id proc exec", NULL) == -1) + if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1) fatal("%s: pledge: %s", __progname, strerror(errno)); platform_pledge_agent(); diff --git a/crypto/openssh/ssh_config b/crypto/openssh/ssh_config index 8eca345..54dffac 100644 --- a/crypto/openssh/ssh_config +++ b/crypto/openssh/ssh_config @@ -50,4 +50,4 @@ # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h # VerifyHostKeyDNS yes -# VersionAddendum FreeBSD-20160310 +# VersionAddendum FreeBSD-20161230 diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5 index 226a802..2a0a123 100644 --- a/crypto/openssh/ssh_config.5 +++ b/crypto/openssh/ssh_config.5 @@ -1733,7 +1733,7 @@ See also VERIFYING HOST KEYS in Specifies a string to append to the regular version string to identify OS- or site-specific modifications. The default is -.Dq FreeBSD-20160310 . +.Dq FreeBSD-20161230 . The value .Dq none may be used to disable this. diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config index 6ea0b08..88b4964 100644 --- a/crypto/openssh/sshd_config +++ b/crypto/openssh/sshd_config @@ -120,7 +120,7 @@ #MaxStartups 10:30:100 #PermitTunnel no #ChrootDirectory none -#VersionAddendum FreeBSD-20160310 +#VersionAddendum FreeBSD-20161230 # no default banner path #Banner none diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5 index cc43aad..8b077f2 100644 --- a/crypto/openssh/sshd_config.5 +++ b/crypto/openssh/sshd_config.5 @@ -1631,7 +1631,7 @@ The default is Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. The default is -.Dq FreeBSD-20160310 . +.Dq FreeBSD-20161230 . The value .Dq none may be used to disable this. diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h index 031bb87..540aad8 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -6,7 +6,7 @@ #define SSH_PORTABLE "p2" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE -#define SSH_VERSION_FREEBSD "FreeBSD-20160310" +#define SSH_VERSION_FREEBSD "FreeBSD-20161230" #ifdef WITH_OPENSSL #define OPENSSL_VERSION SSLeay_version(SSLEAY_VERSION) diff --git a/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c b/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c index 2da1117..ca53913 100644 --- a/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c +++ b/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c @@ -267,6 +267,8 @@ static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, len = p[arg - 2] << 8 | p[arg - 1]; if (!ctx->encrypt) { + if (len < MD5_DIGEST_LENGTH) + return -1; len -= MD5_DIGEST_LENGTH; p[arg - 2] = len >> 8; p[arg - 1] = len; diff --git a/etc/snmpd.config b/etc/snmpd.config index 7787542..22a9921 100644 --- a/etc/snmpd.config +++ b/etc/snmpd.config @@ -116,6 +116,14 @@ snmpEnableAuthenTraps = 2 # modules # +# Control configuration for the modules in the module specific sections, e.g. +# the "usm" module (begemotSnmpdModulePath."usm") can be controlled in the +# %usm specific section. You must uncomment the section specific header in +# order to use the enclosed variables, e.g. `usmUserStatus.$(engine).$(user1)` +# can only be used if %usm is uncommented. +# + +# # Bridge module # This requires the mibII module. # diff --git a/include/paths.h b/include/paths.h index 89c9fc9..2ba0623 100644 --- a/include/paths.h +++ b/include/paths.h @@ -98,6 +98,7 @@ #define _PATH_VARDB "/var/db/" #define _PATH_VARRUN "/var/run/" #define _PATH_VARTMP "/var/tmp/" +#define _PATH_DEVVMM "/dev/vmm/" #define _PATH_YP "/var/yp/" #define _PATH_UUCPLOCK "/var/spool/lock/" diff --git a/lib/Makefile b/lib/Makefile index d2cda1e..57bfc65 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -130,7 +130,7 @@ SUBDIR_DEPEND_libdpv= libfigpar ncurses libutil SUBDIR_DEPEND_libedit= ncurses SUBDIR_DEPEND_libg++= msun SUBDIR_DEPEND_libgeom= libexpat libsbuf -SUBDIR_DEPEND_liblibrpcsec_gss= libgssapi +SUBDIR_DEPEND_librpcsec_gss= libgssapi SUBDIR_DEPEND_libmagic= libz SUBDIR_DEPEND_libmemstat= libkvm SUBDIR_DEPEND_libopie= libmd diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index b6a6ff7..0f1ed85 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -268,6 +268,8 @@ void _malloc_thread_cleanup(void); * thread is exiting, so its thread-local dtors should be called. */ void __cxa_thread_call_dtors(void); +int __cxa_thread_atexit_hidden(void (*dtor_func)(void *), void *obj, + void *dso_symbol) __hidden; /* * These functions are used by the threading libraries in order to protect diff --git a/lib/libc/regex/grot/Makefile b/lib/libc/regex/grot/Makefile index 056b55e..df639ba 100644 --- a/lib/libc/regex/grot/Makefile +++ b/lib/libc/regex/grot/Makefile @@ -5,7 +5,7 @@ # Do not take -DPOSIX_MISTAKE out. REGCFLAGS isn't important to you (it's # for my use in some special contexts). -PATHS= ${.CURDIR}/.. ${.CURDIR}/../../locale ${.CURDIR}/../../../../include +PATHS= ${.CURDIR:H} ${.CURDIR:H:H}/locale ${SRCTOP}/include .PATH: ${PATHS} CFLAGS+= -static -DPOSIX_MISTAKE -DREDEBUG $(REGCFLAGS) diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 9bffd7e..1fb8c44 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -5,7 +5,9 @@ .PATH: ${.CURDIR}/${LIBC_ARCH}/stdlib ${.CURDIR}/stdlib MISRCS+=_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \ - bsearch.c cxa_thread_atexit.c div.c exit.c getenv.c getopt.c getopt_long.c \ + bsearch.c \ + cxa_thread_atexit.c cxa_thread_atexit_impl.c \ + div.c exit.c getenv.c getopt.c getopt_long.c \ getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c \ insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \ merge.c ptsname.c qsort.c qsort_r.c quick_exit.c radixsort.c rand.c \ diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map index f6b62a9..dc11a3a 100644 --- a/lib/libc/stdlib/Symbol.map +++ b/lib/libc/stdlib/Symbol.map @@ -106,6 +106,7 @@ FBSD_1.3 { FBSD_1.5 { __cxa_thread_atexit; + __cxa_thread_atexit_impl; }; FBSDprivate_1.0 { diff --git a/lib/libc/stdlib/cxa_thread_atexit.c b/lib/libc/stdlib/cxa_thread_atexit.c index c966731..6f03ef0 100644 --- a/lib/libc/stdlib/cxa_thread_atexit.c +++ b/lib/libc/stdlib/cxa_thread_atexit.c @@ -1,7 +1,10 @@ /*- - * Copyright (c) 2016 Mahdi Mokhtari <mokhi64@gmail.com> + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -27,114 +30,11 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <sys/queue.h> -#include "namespace.h" -#include <errno.h> -#include <link.h> -#include <pthread.h> -#include <stddef.h> -#include <stdlib.h> -#include <stdio.h> -#include "un-namespace.h" #include "libc_private.h" -/* - * C++11 introduces the thread_local scope (like __thread with some - * additions). As a key-feature it should support non-trivial - * destructors, registered with __cxa_thread_atexit() to be executed - * at the thread termination. - * - * The implemention keeps a _Thread_local list of destructors per each - * thread, and calls __cxa_thread_call_dtors() on each thread's exit - * to do cleanup. For a thread calling exit(3), in particular, for - * the initial thread returning from main(), we call - * __cxa_thread_call_dtors() inside exit(). - * - * It could be possible that a dynamically loaded library, use - * thread_local variable but is dlclose()'d before thread exit. The - * destructor of this variable will then try to access the address, - * for calling it but it's unloaded, so it'll crash. We're using - * __elf_phdr_match_addr() to detect and prevent such cases and so - * prevent the crash. - */ - -#define CXA_DTORS_ITERATIONS 4 - -struct cxa_thread_dtor { - void *obj; - void (*func)(void *); - void *dso; - LIST_ENTRY(cxa_thread_dtor) entry; -}; -static _Thread_local LIST_HEAD(dtor_list, cxa_thread_dtor) dtors = - LIST_HEAD_INITIALIZER(dtors); - int __cxa_thread_atexit(void (*dtor_func)(void *), void *obj, void *dso_symbol) { - struct cxa_thread_dtor *new_dtor; - - new_dtor = malloc(sizeof(*new_dtor)); - if (new_dtor == NULL) { - errno = ENOMEM; /* forcibly override malloc(3) error */ - return (-1); - } - - new_dtor->obj = obj; - new_dtor->func = dtor_func; - new_dtor->dso = dso_symbol; - LIST_INSERT_HEAD(&dtors, new_dtor, entry); - return (0); -} - -static void -walk_cb_call(struct cxa_thread_dtor *dtor) -{ - struct dl_phdr_info phdr_info; - - if (_rtld_addr_phdr(dtor->dso, &phdr_info) && - __elf_phdr_match_addr(&phdr_info, dtor->func)) - dtor->func(dtor->obj); - else - fprintf(stderr, "__cxa_thread_call_dtors: dtr %p from " - "unloaded dso, skipping\n", (void *)(dtor->func)); -} - -static void -walk_cb_nocall(struct cxa_thread_dtor *dtor __unused) -{ -} - -static void -cxa_thread_walk(void (*cb)(struct cxa_thread_dtor *)) -{ - struct cxa_thread_dtor *dtor, *tdtor; - - LIST_FOREACH_SAFE(dtor, &dtors, entry, tdtor) { - LIST_REMOVE(dtor, entry); - cb(dtor); - free(dtor); - } -} - -/* - * This is the callback function we use to call destructors, once for - * each thread. It is called in exit(3) in libc/stdlib/exit.c and - * before exit_thread() in libthr/thread/thr_exit.c. - */ -void -__cxa_thread_call_dtors(void) -{ - int i; - - for (i = 0; i < CXA_DTORS_ITERATIONS && !LIST_EMPTY(&dtors); i++) - cxa_thread_walk(walk_cb_call); - if (!LIST_EMPTY(&dtors)) { - fprintf(stderr, "Thread %p is exiting with more " - "thread-specific dtors created after %d iterations " - "of destructor calls\n", - _pthread_self(), i); - cxa_thread_walk(walk_cb_nocall); - } + return (__cxa_thread_atexit_hidden(dtor_func, obj, dso_symbol)); } diff --git a/lib/libc/stdlib/cxa_thread_atexit_impl.c b/lib/libc/stdlib/cxa_thread_atexit_impl.c new file mode 100644 index 0000000..0f0a7a3 --- /dev/null +++ b/lib/libc/stdlib/cxa_thread_atexit_impl.c @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 2016 Mahdi Mokhtari <mokhi64@gmail.com> + * Copyright (c) 2016, 2017 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/queue.h> +#include "namespace.h" +#include <errno.h> +#include <link.h> +#include <pthread.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include "un-namespace.h" +#include "libc_private.h" + +/* + * C++11 introduces the thread_local scope (like __thread with some + * additions). As a key-feature it should support non-trivial + * destructors, registered with __cxa_thread_atexit() to be executed + * at the thread termination. + * + * The implemention keeps a _Thread_local list of destructors per each + * thread, and calls __cxa_thread_call_dtors() on each thread's exit + * to do cleanup. For a thread calling exit(3), in particular, for + * the initial thread returning from main(), we call + * __cxa_thread_call_dtors() inside exit(). + * + * It could be possible that a dynamically loaded library, use + * thread_local variable but is dlclose()'d before thread exit. The + * destructor of this variable will then try to access the address, + * for calling it but it's unloaded, so it'll crash. We're using + * __elf_phdr_match_addr() to detect and prevent such cases and so + * prevent the crash. + */ + +#define CXA_DTORS_ITERATIONS 4 + +struct cxa_thread_dtor { + void *obj; + void (*func)(void *); + void *dso; + LIST_ENTRY(cxa_thread_dtor) entry; +}; +static _Thread_local LIST_HEAD(dtor_list, cxa_thread_dtor) dtors = + LIST_HEAD_INITIALIZER(dtors); + +int +__cxa_thread_atexit_impl(void (*dtor_func)(void *), void *obj, + void *dso_symbol) +{ + + return (__cxa_thread_atexit_hidden(dtor_func, obj, dso_symbol)); +} + +int +__cxa_thread_atexit_hidden(void (*dtor_func)(void *), void *obj, + void *dso_symbol) +{ + struct cxa_thread_dtor *new_dtor; + + new_dtor = malloc(sizeof(*new_dtor)); + if (new_dtor == NULL) { + errno = ENOMEM; /* forcibly override malloc(3) error */ + return (-1); + } + + new_dtor->obj = obj; + new_dtor->func = dtor_func; + new_dtor->dso = dso_symbol; + LIST_INSERT_HEAD(&dtors, new_dtor, entry); + return (0); +} + +static void +walk_cb_call(struct cxa_thread_dtor *dtor) +{ + struct dl_phdr_info phdr_info; + + if (_rtld_addr_phdr(dtor->dso, &phdr_info) && + __elf_phdr_match_addr(&phdr_info, dtor->func)) + dtor->func(dtor->obj); + else + fprintf(stderr, "__cxa_thread_call_dtors: dtr %p from " + "unloaded dso, skipping\n", (void *)(dtor->func)); +} + +static void +walk_cb_nocall(struct cxa_thread_dtor *dtor __unused) +{ +} + +static void +cxa_thread_walk(void (*cb)(struct cxa_thread_dtor *)) +{ + struct cxa_thread_dtor *dtor, *tdtor; + + LIST_FOREACH_SAFE(dtor, &dtors, entry, tdtor) { + LIST_REMOVE(dtor, entry); + cb(dtor); + free(dtor); + } +} + +/* + * This is the callback function we use to call destructors, once for + * each thread. It is called in exit(3) in libc/stdlib/exit.c and + * before exit_thread() in libthr/thread/thr_exit.c. + */ +void +__cxa_thread_call_dtors(void) +{ + int i; + + for (i = 0; i < CXA_DTORS_ITERATIONS && !LIST_EMPTY(&dtors); i++) + cxa_thread_walk(walk_cb_call); + + if (!LIST_EMPTY(&dtors)) { + fprintf(stderr, "Thread %p is exiting with more " + "thread-specific dtors created after %d iterations " + "of destructor calls\n", + _pthread_self(), i); + cxa_thread_walk(walk_cb_nocall); + } +} diff --git a/lib/libcam/scsi_cmdparse.c b/lib/libcam/scsi_cmdparse.c index 4a322ba..8b43066 100644 --- a/lib/libcam/scsi_cmdparse.c +++ b/lib/libcam/scsi_cmdparse.c @@ -100,10 +100,11 @@ __FBSDID("$FreeBSD$"); */ static int -do_buff_decode(u_int8_t *databuf, size_t len, +do_buff_decode(u_int8_t *buff, size_t len, void (*arg_put)(void *, int , void *, int, char *), void *puthook, const char *fmt, va_list *ap) { + int ind = 0; int assigned = 0; int width; int suppress; @@ -112,21 +113,17 @@ do_buff_decode(u_int8_t *databuf, size_t len, static u_char mask[] = {0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; int value; - u_char *base = databuf; char *intendp; char letter; char field_name[80]; -# define ARG_PUT(ARG) \ - do \ - { \ - if (!suppress) \ - { \ +#define ARG_PUT(ARG) \ + do { \ + if (!suppress) { \ if (arg_put) \ - (*arg_put)(puthook, (letter == 't' ? \ - 'b' : letter), \ - (void *)((long)(ARG)), width, \ - field_name); \ + (*arg_put)(puthook, (letter == 't' ? 'b' : \ + letter), (void *)((long)(ARG)), width, \ + field_name); \ else \ *(va_arg(*ap, int *)) = (ARG); \ assigned++; \ @@ -187,7 +184,11 @@ do_buff_decode(u_int8_t *databuf, size_t len, done = 1; else { if (shift <= 0) { - bits = *databuf++; + if (ind >= len) { + done = 1; + break; + } + bits = buff[ind++]; shift = 8; } value = (bits >> (shift - width)) & @@ -209,29 +210,31 @@ do_buff_decode(u_int8_t *databuf, size_t len, fmt++; width = strtol(fmt, &intendp, 10); fmt = intendp; + if (ind + width > len) { + done = 1; + break; + } switch(width) { case 1: - ARG_PUT(*databuf); - databuf++; + ARG_PUT(buff[ind]); + ind++; break; case 2: - ARG_PUT((*databuf) << 8 | *(databuf + 1)); - databuf += 2; + ARG_PUT(buff[ind] << 8 | buff[ind + 1]); + ind += 2; break; case 3: - ARG_PUT((*databuf) << 16 | - (*(databuf + 1)) << 8 | *(databuf + 2)); - databuf += 3; + ARG_PUT(buff[ind] << 16 | + buff[ind + 1] << 8 | buff[ind + 2]); + ind += 3; break; case 4: - ARG_PUT((*databuf) << 24 | - (*(databuf + 1)) << 16 | - (*(databuf + 2)) << 8 | - *(databuf + 3)); - databuf += 4; + ARG_PUT(buff[ind] << 24 | buff[ind + 1] << 16 | + buff[ind + 2] << 8 | buff[ind + 3]); + ind += 4; break; default: @@ -242,32 +245,35 @@ do_buff_decode(u_int8_t *databuf, size_t len, break; case 'c': /* Characters (i.e., not swapped) */ - case 'z': /* Characters with zeroed trailing - spaces */ + case 'z': /* Characters with zeroed trailing spaces */ shift = 0; fmt++; width = strtol(fmt, &intendp, 10); fmt = intendp; + if (ind + width > len) { + done = 1; + break; + } if (!suppress) { if (arg_put) (*arg_put)(puthook, - (letter == 't' ? 'b' : letter), - databuf, width, field_name); + (letter == 't' ? 'b' : letter), + &buff[ind], width, field_name); else { char *dest; dest = va_arg(*ap, char *); - bcopy(databuf, dest, width); + bcopy(&buff[ind], dest, width); if (letter == 'z') { char *p; for (p = dest + width - 1; - (p >= (char *)dest) - && (*p == ' '); p--) + p >= dest && *p == ' '; + p--) *p = 0; } } assigned++; } - databuf += width; + ind += width; field_name[0] = 0; suppress = 0; break; @@ -295,9 +301,9 @@ do_buff_decode(u_int8_t *databuf, size_t len, } if (plus) - databuf += width; /* Relative seek */ + ind += width; /* Relative seek */ else - databuf = base + width; /* Absolute seek */ + ind = width; /* Absolute seek */ break; diff --git a/lib/libfetch/fetch.3 b/lib/libfetch/fetch.3 index f7b444f..bb295f1 100644 --- a/lib/libfetch/fetch.3 +++ b/lib/libfetch/fetch.3 @@ -783,27 +783,27 @@ library first appeared in The .Nm fetch library was mostly written by -.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org +.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org with numerous suggestions and contributions from -.An Jordan K. Hubbard Aq jkh@FreeBSD.org , -.An Eugene Skepner Aq eu@qub.com , -.An Hajimu Umemoto Aq ume@FreeBSD.org , -.An Henry Whincup Aq henry@techiebod.com , -.An Jukka A. Ukkonen Aq jau@iki.fi , -.An Jean-Fran\(,cois Dockes Aq jf@dockes.org , -.An Michael Gmelin Aq freebsd@grem.de +.An Jordan K. Hubbard Aq Mt jkh@FreeBSD.org , +.An Eugene Skepner Aq Mt eu@qub.com , +.An Hajimu Umemoto Aq Mt ume@FreeBSD.org , +.An Henry Whincup Aq Mt henry@techiebod.com , +.An Jukka A. Ukkonen Aq Mt jau@iki.fi , +.An Jean-Fran\(,cois Dockes Aq Mt jf@dockes.org , +.An Michael Gmelin Aq Mt freebsd@grem.de and others. It replaces the older .Nm ftpio library written by -.An Poul-Henning Kamp Aq phk@FreeBSD.org +.An Poul-Henning Kamp Aq Mt phk@FreeBSD.org and -.An Jordan K. Hubbard Aq jkh@FreeBSD.org . +.An Jordan K. Hubbard Aq Mt jkh@FreeBSD.org . .Pp This manual page was written by -.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org +.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org and -.An Michael Gmelin Aq freebsd@grem.de . +.An Michael Gmelin Aq Mt freebsd@grem.de . .Sh BUGS Some parts of the library are not yet implemented. The most notable diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c index 1a43b56..814c4a3 100644 --- a/lib/libfetch/ftp.c +++ b/lib/libfetch/ftp.c @@ -929,7 +929,7 @@ ftp_authenticate(conn_t *conn, struct url *url, struct url *purl) if (*pwd == '\0') pwd = getenv("FTP_PASSWORD"); if (pwd == NULL || *pwd == '\0') { - if ((logname = getlogin()) == 0) + if ((logname = getlogin()) == NULL) logname = FTP_ANONYMOUS_USER; if ((len = snprintf(pbuf, MAXLOGNAME + 1, "%s@", logname)) < 0) len = 0; diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c index ca522a6..bb509c1 100644 --- a/lib/libfetch/http.c +++ b/lib/libfetch/http.c @@ -114,6 +114,7 @@ __FBSDID("$FreeBSD$"); #define HTTP_REDIRECT(xyz) ((xyz) == HTTP_MOVED_PERM \ || (xyz) == HTTP_MOVED_TEMP \ || (xyz) == HTTP_TEMP_REDIRECT \ + || (xyz) == HTTP_PERM_REDIRECT \ || (xyz) == HTTP_USE_PROXY \ || (xyz) == HTTP_SEE_OTHER) @@ -875,7 +876,7 @@ http_parse_mtime(const char *p, time_t *mtime) char locale[64], *r; struct tm tm; - strncpy(locale, setlocale(LC_TIME, NULL), sizeof(locale)); + strlcpy(locale, setlocale(LC_TIME, NULL), sizeof(locale)); setlocale(LC_TIME, "C"); r = strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm); /* @@ -1431,7 +1432,7 @@ http_connect(struct url *URL, struct url *purl, const char *flags) default: /* ignore */ ; } - } while (h < hdr_end); + } while (h > hdr_end); } if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && fetch_ssl(conn, URL, verbose) == -1) { @@ -1767,6 +1768,8 @@ http_request_body(struct url *URL, const char *op, struct url_stat *us, break; case HTTP_MOVED_PERM: case HTTP_MOVED_TEMP: + case HTTP_TEMP_REDIRECT: + case HTTP_PERM_REDIRECT: case HTTP_SEE_OTHER: case HTTP_USE_PROXY: /* diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c index 9181a49..85f50ad 100644 --- a/lib/libkvm/kvm.c +++ b/lib/libkvm/kvm.c @@ -198,8 +198,10 @@ _kvm_open(kvm_t *kd, const char *uf, const char *mf, int flag, char *errout) return (kd); } } + /* - * This is a crash dump. + * This is either a crash dump or a remote live system with its physical + * memory fully accessible via a special device. * Initialize the virtual address translation machinery, * but first setup the namelist fd. */ @@ -207,8 +209,11 @@ _kvm_open(kvm_t *kd, const char *uf, const char *mf, int flag, char *errout) _kvm_syserr(kd, kd->program, "%s", uf); goto failed; } - if (strncmp(mf, _PATH_FWMEM, strlen(_PATH_FWMEM)) == 0) + if (strncmp(mf, _PATH_FWMEM, strlen(_PATH_FWMEM)) == 0 || + strncmp(mf, _PATH_DEVVMM, strlen(_PATH_DEVVMM)) == 0) { kd->rawdump = 1; + kd->writable = 1; + } if (_kvm_initvtop(kd) < 0) goto failed; return (kd); @@ -557,6 +562,15 @@ ssize_t kvm_write(kvm_t *kd, u_long kva, const void *buf, size_t len) { int cc; + ssize_t cw; + off_t pa; + const char *cp; + + if (!ISALIVE(kd) && !kd->writable) { + _kvm_err(kd, kd->program, + "kvm_write not implemented for dead kernels"); + return (-1); + } if (ISALIVE(kd)) { /* @@ -574,10 +588,36 @@ kvm_write(kvm_t *kd, u_long kva, const void *buf, size_t len) } else if ((size_t)cc < len) _kvm_err(kd, kd->program, "short write"); return (cc); - } else { - _kvm_err(kd, kd->program, - "kvm_write not implemented for dead kernels"); - return (-1); } - /* NOTREACHED */ + + cp = buf; + while (len > 0) { + cc = _kvm_kvatop(kd, kva, &pa); + if (cc == 0) + return (-1); + if (cc > (ssize_t)len) + cc = len; + errno = 0; + if (lseek(kd->pmfd, pa, 0) == -1 && errno != 0) { + _kvm_syserr(kd, 0, _PATH_MEM); + break; + } + cw = write(kd->pmfd, cp, cc); + if (cw < 0) { + _kvm_syserr(kd, kd->program, "kvm_write"); + break; + } + /* + * If ka_kvatop returns a bogus value or our core file is + * truncated, we might wind up seeking beyond the end of the + * core file in which case the read will return 0 (EOF). + */ + if (cw == 0) + break; + cp += cw; + kva += cw; + len -= cw; + } + + return (cp - (char *)buf); } diff --git a/lib/libkvm/kvm.h b/lib/libkvm/kvm.h index d697795..6c2b102 100644 --- a/lib/libkvm/kvm.h +++ b/lib/libkvm/kvm.h @@ -58,11 +58,11 @@ struct proc; struct kvm_swap { char ksw_devname[32]; - int ksw_used; - int ksw_total; + u_int ksw_used; + u_int ksw_total; int ksw_flags; - int ksw_reserved1; - int ksw_reserved2; + u_int ksw_reserved1; + u_int ksw_reserved2; }; #define SWIF_DEV_PREFIX 0x0002 diff --git a/lib/libkvm/kvm_getswapinfo.3 b/lib/libkvm/kvm_getswapinfo.3 index edd2068..bb4e67e 100644 --- a/lib/libkvm/kvm_getswapinfo.3 +++ b/lib/libkvm/kvm_getswapinfo.3 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 22, 1999 +.Dd January 2, 2017 .Dt KVM_SWAPINFO 3 .Os .Sh NAME @@ -78,9 +78,9 @@ This structure contains the following fields: .It .Va char ksw_devname[] ; .It -.Va int ksw_total ; +.Va u_int ksw_total ; .It -.Va int ksw_used ; +.Va u_int ksw_used ; .It .Va int ksw_flags ; .El diff --git a/lib/libkvm/kvm_getswapinfo.c b/lib/libkvm/kvm_getswapinfo.c index d79d70c..7d9c8a9 100644 --- a/lib/libkvm/kvm_getswapinfo.c +++ b/lib/libkvm/kvm_getswapinfo.c @@ -112,7 +112,8 @@ int kvm_getswapinfo_kvm(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, int flags) { - int i, ttl; + int i; + swblk_t ttl; TAILQ_HEAD(, swdevt) swtailq; struct swdevt *sp, swinfo; struct kvm_swap tot; @@ -157,7 +158,8 @@ int kvm_getswapinfo_sysctl(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, int flags) { - int ti, ttl; + int ti; + swblk_t ttl; size_t mibi, len; int soid[SWI_MAXMIB]; struct xswdev xsd; diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h index b3eeea7..c47eb07 100644 --- a/lib/libkvm/kvm_private.h +++ b/lib/libkvm/kvm_private.h @@ -62,6 +62,7 @@ struct __kvm { */ struct vmstate *vmst; int rawdump; /* raw dump format */ + int writable; /* physical memory is writable */ int vnet_initialized; /* vnet fields set up */ uintptr_t vnet_start; /* start of kernel's vnet region */ diff --git a/lib/liblzma/config.h b/lib/liblzma/config.h index f1adce4..70b931f 100644 --- a/lib/liblzma/config.h +++ b/lib/liblzma/config.h @@ -25,17 +25,20 @@ /* Define to 1 if you have the <byteswap.h> header file. */ /* #undef HAVE_BYTESWAP_H */ +/* Define to 1 if Capsicum is available. */ +/* #undef HAVE_CAPSICUM */ + /* Define to 1 if the system has the type `CC_SHA256_CTX'. */ /* #undef HAVE_CC_SHA256_CTX */ /* Define to 1 if you have the `CC_SHA256_Init' function. */ /* #undef HAVE_CC_SHA256_INIT */ -/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the +/* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework. */ /* #undef HAVE_CFLOCALECOPYCURRENT */ -/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in +/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework. */ /* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */ @@ -67,6 +70,9 @@ to 0 if you don't. */ #define HAVE_DECL_PROGRAM_INVOCATION_NAME 0 +/* Define to 1 if any of HAVE_DECODER_foo have been defined. */ +#define HAVE_DECODERS 1 + /* Define to 1 if arm decoder is enabled. */ #define HAVE_DECODER_ARM 1 @@ -97,6 +103,9 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #define HAVE_DLFCN_H 1 +/* Define to 1 if any of HAVE_ENCODER_foo have been defined. */ +#define HAVE_ENCODERS 1 + /* Define to 1 if arm encoder is enabled. */ #define HAVE_ENCODER_ARM 1 @@ -182,9 +191,6 @@ /* Define to 1 to enable hc4 match finder. */ #define HAVE_MF_HC4 1 -/* Define to 1 if you have the <minix/sha2.h> header file. */ -/* #undef HAVE_MINIX_SHA2_H */ - /* Define to 1 if getopt.h declares extern int optreset. */ #define HAVE_OPTRESET 1 @@ -254,6 +260,9 @@ /* Define to 1 if you have the <sys/byteorder.h> header file. */ /* #undef HAVE_SYS_BYTEORDER_H */ +/* Define to 1 if you have the <sys/capsicum.h> header file. */ +/* #undef HAVE_SYS_CAPSICUM_H */ + /* Define to 1 if you have the <sys/endian.h> header file. */ #define HAVE_SYS_ENDIAN_H 1 @@ -291,6 +300,9 @@ /* Define to 1 if the system has the type `_Bool'. */ #define HAVE__BOOL 1 +/* Define to 1 if you have the `_futime' function. */ +/* #undef HAVE__FUTIME */ + /* Define to 1 if _mm_movemask_epi8 is available. */ #if defined(__FreeBSD__) && defined(__amd64__) #define HAVE__MM_MOVEMASK_EPI8 1 @@ -323,7 +335,7 @@ #define PACKAGE_NAME "XZ Utils" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "XZ Utils 5.2.2" +#define PACKAGE_STRING "XZ Utils 5.2.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "xz" @@ -332,7 +344,7 @@ #define PACKAGE_URL "http://tukaani.org/xz/" /* Define to the version of this package. */ -#define PACKAGE_VERSION "5.2.2" +#define PACKAGE_VERSION "5.2.3" /* Define to necessary symbol if this constant uses a non-standard name on your system. */ @@ -353,6 +365,10 @@ /* #undef TUKLIB_CPUCORES_PSTAT_GETDYNAMIC */ /* Define to 1 if the number of available CPU cores can be detected with + sched_getaffinity() */ +/* #undef TUKLIB_CPUCORES_SCHED_GETAFFINITY */ + +/* Define to 1 if the number of available CPU cores can be detected with sysconf(_SC_NPROCESSORS_ONLN) or sysconf(_SC_NPROC_ONLN). */ /* #undef TUKLIB_CPUCORES_SYSCONF */ @@ -416,7 +432,7 @@ /* Version number of package */ -#define VERSION "5.2.2" +#define VERSION "5.2.3" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ diff --git a/lib/libnetbsd/sys/cdefs.h b/lib/libnetbsd/sys/cdefs.h index 051959f..06e46fd 100644 --- a/lib/libnetbsd/sys/cdefs.h +++ b/lib/libnetbsd/sys/cdefs.h @@ -69,4 +69,13 @@ */ #define __arraycount(__x) (sizeof(__x) / sizeof(__x[0])) +/* __BIT(n): nth bit, where __BIT(0) == 0x1. */ +#define __BIT(__n) \ + (((uintmax_t)(__n) >= NBBY * sizeof(uintmax_t)) ? 0 : \ + ((uintmax_t)1 << (uintmax_t)((__n) & (NBBY * sizeof(uintmax_t) - 1)))) + +/* __BITS(m, n): bits m through n, m < n. */ +#define __BITS(__m, __n) \ + ((__BIT(MAX((__m), (__n)) + 1) - 1) ^ (__BIT(MIN((__m), (__n))) - 1)) + #endif /* _LIBNETBSD_SYS_CDEFS_H_ */ diff --git a/lib/libprocstat/Makefile b/lib/libprocstat/Makefile index af5a775..45c0a9b 100644 --- a/lib/libprocstat/Makefile +++ b/lib/libprocstat/Makefile @@ -8,11 +8,11 @@ SRCS= cd9660.c \ common_kvm.c \ core.c \ libprocstat.c \ - msdosfs.c \ + msdosfs.c \ smbfs.c \ udf.c -VERSION_DEF= ${.CURDIR}/Versions.def +VERSION_DEF= ${SRCTOP}/lib/libc/Versions.def SYMBOL_MAPS= ${.CURDIR}/Symbol.map INCS= libprocstat.h diff --git a/lib/libprocstat/Versions.def b/lib/libprocstat/Versions.def deleted file mode 100644 index ed958db..0000000 --- a/lib/libprocstat/Versions.def +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -# This version was first added to 9.0-current. -FBSD_1.2 { -}; - -# This version was first added to 10.0-current. -FBSD_1.3 { -} FBSD_1.2; - diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index 7b0722c..b362e56 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -282,7 +282,7 @@ procstat_getprocs(struct procstat *procstat, int what, int arg, name[1] = KERN_PROC; name[2] = what; name[3] = arg; - error = sysctl(name, 4, NULL, &len, NULL, 0); + error = sysctl(name, nitems(name), NULL, &len, NULL, 0); if (error < 0 && errno != EPERM) { warn("sysctl(kern.proc)"); goto fail; @@ -299,7 +299,7 @@ procstat_getprocs(struct procstat *procstat, int what, int arg, goto fail; } olen = len; - error = sysctl(name, 4, p, &len, NULL, 0); + error = sysctl(name, nitems(name), p, &len, NULL, 0); } while (error < 0 && errno == ENOMEM && olen == len); if (error < 0 && errno != EPERM) { warn("sysctl(kern.proc)"); @@ -1760,7 +1760,7 @@ getargv(struct procstat *procstat, struct kinfo_proc *kp, size_t nchr, int env) name[2] = env ? KERN_PROC_ENV : KERN_PROC_ARGS; name[3] = kp->ki_pid; len = nchr; - error = sysctl(name, 4, av->buf, &len, NULL, 0); + error = sysctl(name, nitems(name), av->buf, &len, NULL, 0); if (error != 0 && errno != ESRCH && errno != EPERM) warn("sysctl(kern.proc.%s)", env ? "env" : "args"); if (error != 0 || len == 0) @@ -1983,7 +1983,7 @@ procstat_getgroups_sysctl(pid_t pid, unsigned int *cntp) warn("malloc(%zu)", len); return (NULL); } - if (sysctl(mib, 4, groups, &len, NULL, 0) == -1) { + if (sysctl(mib, nitems(mib), groups, &len, NULL, 0) == -1) { warn("sysctl: kern.proc.groups: %d", pid); free(groups); return (NULL); @@ -2059,7 +2059,7 @@ procstat_getumask_sysctl(pid_t pid, unsigned short *maskp) mib[2] = KERN_PROC_UMASK; mib[3] = pid; len = sizeof(*maskp); - error = sysctl(mib, 4, maskp, &len, NULL, 0); + error = sysctl(mib, nitems(mib), maskp, &len, NULL, 0); if (error != 0 && errno != ESRCH && errno != EPERM) warn("sysctl: kern.proc.umask: %d", pid); return (error); @@ -2139,7 +2139,7 @@ procstat_getrlimit_sysctl(pid_t pid, int which, struct rlimit* rlimit) name[3] = pid; name[4] = which; len = sizeof(struct rlimit); - error = sysctl(name, 5, rlimit, &len, NULL, 0); + error = sysctl(name, nitems(name), rlimit, &len, NULL, 0); if (error < 0 && errno != ESRCH) { warn("sysctl: kern.proc.rlimit: %d", pid); return (-1); @@ -2201,7 +2201,7 @@ procstat_getpathname_sysctl(pid_t pid, char *pathname, size_t maxlen) name[2] = KERN_PROC_PATHNAME; name[3] = pid; len = maxlen; - error = sysctl(name, 4, pathname, &len, NULL, 0); + error = sysctl(name, nitems(name), pathname, &len, NULL, 0); if (error != 0 && errno != ESRCH) warn("sysctl: kern.proc.pathname: %d", pid); if (len == 0) @@ -2281,7 +2281,7 @@ procstat_getosrel_sysctl(pid_t pid, int *osrelp) name[2] = KERN_PROC_OSREL; name[3] = pid; len = sizeof(*osrelp); - error = sysctl(name, 4, osrelp, &len, NULL, 0); + error = sysctl(name, nitems(name), osrelp, &len, NULL, 0); if (error != 0 && errno != ESRCH) warn("sysctl: kern.proc.osrel: %d", pid); return (error); @@ -2341,7 +2341,7 @@ is_elf32_sysctl(pid_t pid) name[2] = KERN_PROC_SV_NAME; name[3] = pid; len = sizeof(sv_name); - error = sysctl(name, 4, sv_name, &len, NULL, 0); + error = sysctl(name, nitems(name), sv_name, &len, NULL, 0); if (error != 0 || len == 0) return (0); for (i = 0; i < sizeof(elf32_sv_names) / sizeof(*elf32_sv_names); i++) { @@ -2372,7 +2372,7 @@ procstat_getauxv32_sysctl(pid_t pid, unsigned int *cntp) warn("malloc(%zu)", len); goto out; } - if (sysctl(name, 4, auxv32, &len, NULL, 0) == -1) { + if (sysctl(name, nitems(name), auxv32, &len, NULL, 0) == -1) { if (errno != ESRCH && errno != EPERM) warn("sysctl: kern.proc.auxv: %d: %d", pid, errno); goto out; @@ -2421,7 +2421,7 @@ procstat_getauxv_sysctl(pid_t pid, unsigned int *cntp) warn("malloc(%zu)", len); return (NULL); } - if (sysctl(name, 4, auxv, &len, NULL, 0) == -1) { + if (sysctl(name, nitems(name), auxv, &len, NULL, 0) == -1) { if (errno != ESRCH && errno != EPERM) warn("sysctl: kern.proc.auxv: %d: %d", pid, errno); free(auxv); @@ -2482,7 +2482,7 @@ procstat_getkstack_sysctl(pid_t pid, int *cntp) name[3] = pid; len = 0; - error = sysctl(name, 4, NULL, &len, NULL, 0); + error = sysctl(name, nitems(name), NULL, &len, NULL, 0); if (error < 0 && errno != ESRCH && errno != EPERM && errno != ENOENT) { warn("sysctl: kern.proc.kstack: %d", pid); return (NULL); @@ -2499,7 +2499,7 @@ procstat_getkstack_sysctl(pid_t pid, int *cntp) warn("malloc(%zu)", len); return (NULL); } - if (sysctl(name, 4, kkstp, &len, NULL, 0) == -1) { + if (sysctl(name, nitems(name), kkstp, &len, NULL, 0) == -1) { warn("sysctl: kern.proc.pid: %d", pid); free(kkstp); return (NULL); diff --git a/lib/libstand/Makefile b/lib/libstand/Makefile index 754bac4..ea361c1 100644 --- a/lib/libstand/Makefile +++ b/lib/libstand/Makefile @@ -9,16 +9,20 @@ .include <bsd.own.mk> MK_SSP= no +LIBSTAND_SRC?= ${.CURDIR} +LIBSTAND_CPUARCH?=${MACHINE_CPUARCH} +LIBC_SRC= ${LIBSTAND_SRC}/../libc + LIB= stand NO_PROFILE= NO_PIC= -INCS= stand.h -MAN= libstand.3 +INCS?= stand.h +MAN?= libstand.3 WARNS?= 0 CFLAGS+= -ffreestanding -Wformat -CFLAGS+= -I${.CURDIR} +CFLAGS+= -I${LIBSTAND_SRC} .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float @@ -50,12 +54,12 @@ SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c environment.c getopt.c gets.c \ # private (pruned) versions of libc string functions SRCS+= strcasecmp.c -.PATH: ${.CURDIR}/../libc/net +.PATH: ${LIBC_SRC}/net SRCS+= ntoh.c # string functions from libc -.PATH: ${.CURDIR}/../libc/string +.PATH: ${LIBC_SRC}/string .if ${MACHINE_CPUARCH} != "ia64" SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \ memmove.c memset.c qdivrem.c strcat.c strchr.c strcmp.c strcpy.c \ @@ -63,60 +67,60 @@ SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \ strpbrk.c strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c .endif .if ${MACHINE_CPUARCH} == "arm" -.PATH: ${.CURDIR}/../libc/arm/gen +.PATH: ${LIBC_SRC}/arm/gen .if ${MK_ARM_EABI} == "no" SRCS+= divsi3.S .else # Compiler support functions -.PATH: ${.CURDIR}/../../contrib/compiler-rt/lib/ +.PATH: ${LIBSTAND_SRC}/../../contrib/compiler-rt/lib/ # __clzsi2 and ctzsi2 for various builtin functions SRCS+= clzsi2.c ctzsi2.c # Divide and modulus functions called by the compiler SRCS+= divmoddi4.c divmodsi4.c divdi3.c divsi3.c moddi3.c modsi3.c SRCS+= udivmoddi4.c udivmodsi4.c udivdi3.c udivsi3.c umoddi3.c umodsi3.c -.PATH: ${.CURDIR}/../../contrib/compiler-rt/lib/arm/ +.PATH: ${LIBSTAND_SRC}/../../contrib/compiler-rt/lib/arm/ SRCS+= aeabi_idivmod.S aeabi_ldivmod.S aeabi_uidivmod.S aeabi_uldivmod.S SRCS+= aeabi_memcmp.S aeabi_memcpy.S aeabi_memmove.S aeabi_memset.S .endif .endif .if ${MACHINE_CPUARCH} == "ia64" -.PATH: ${.CURDIR}/../libc/ia64/string +.PATH: ${LIBC_SRC}/ia64/string SRCS+= bcmp.c bcopy.S bzero.S ffs.S memccpy.c memchr.c memcmp.c memcpy.S \ memmove.S memset.c strcat.c strchr.c strcmp.c strcpy.c strcspn.c \ strlcat.c strlcpy.c \ strlen.c strncat.c strncmp.c strncpy.c strpbrk.c strrchr.c strsep.c \ strspn.c strstr.c strtok.c swab.c -.PATH: ${.CURDIR}/../libc/ia64/gen +.PATH: ${LIBC_SRC}/ia64/gen SRCS+= __divdi3.S __divsi3.S __moddi3.S __modsi3.S SRCS+= __udivdi3.S __udivsi3.S __umoddi3.S __umodsi3.S .endif .if ${MACHINE_CPUARCH} == "powerpc" -.PATH: ${.CURDIR}/../libc/quad +.PATH: ${LIBC_SRC}/quad SRCS+= ashldi3.c ashrdi3.c -.PATH: ${.CURDIR}/../libc/powerpc/gen +.PATH: ${LIBC_SRC}/powerpc/gen SRCS+= syncicache.c .endif # uuid functions from libc -.PATH: ${.CURDIR}/../libc/uuid +.PATH: ${LIBC_SRC}/uuid SRCS+= uuid_equal.c uuid_is_nil.c # _setjmp/_longjmp .if ${MACHINE_ARCH} == "powerpc64" -.PATH: ${.CURDIR}/powerpc +.PATH: ${LIBSTAND_SRC}/powerpc .else -.PATH: ${.CURDIR}/${MACHINE_CPUARCH} +.PATH: ${LIBSTAND_SRC}/${LIBSTAND_CPUARCH} .endif SRCS+= _setjmp.S # decompression functionality from libbz2 # NOTE: to actually test this functionality after libbz2 upgrade compile # loader(8) with LOADER_BZIP2_SUPPORT defined -.PATH: ${.CURDIR}/../../contrib/bzip2 +.PATH: ${LIBSTAND_SRC}/../../contrib/bzip2 CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS SRCS+= libstand_bzlib_private.h @@ -134,8 +138,8 @@ libstand_bzlib_private.h: bzlib_private.h ${.ALLSRC} > ${.TARGET} # decompression functionality from libz -.PATH: ${.CURDIR}/../libz -CFLAGS+=-DHAVE_MEMCPY -I${.CURDIR}/../libz +.PATH: ${LIBSTAND_SRC}/../../contrib/zlib +CFLAGS+=-DHAVE_MEMCPY -I${LIBSTAND_SRC}/../../contrib/zlib SRCS+= adler32.c crc32.c libstand_zutil.h libstand_gzguts.h .for file in infback.c inffast.c inflate.c inftrees.c zutil.c diff --git a/lib/libutil/kinfo_getallproc.c b/lib/libutil/kinfo_getallproc.c index 0f43ce2..8620f48 100644 --- a/lib/libutil/kinfo_getallproc.c +++ b/lib/libutil/kinfo_getallproc.c @@ -31,8 +31,8 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> -#include <sys/user.h> #include <sys/sysctl.h> +#include <sys/user.h> #include <stdlib.h> #include <string.h> @@ -75,14 +75,14 @@ kinfo_getallproc(int *cntp) mib[2] = KERN_PROC_PROC; len = 0; - if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) + if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) < 0) return (NULL); kipp = malloc(len); if (kipp == NULL) return (NULL); - if (sysctl(mib, 3, kipp, &len, NULL, 0) < 0) + if (sysctl(mib, nitems(mib), kipp, &len, NULL, 0) < 0) goto bad; if (len % sizeof(*kipp) != 0) goto bad; diff --git a/lib/libutil/kinfo_getfile.c b/lib/libutil/kinfo_getfile.c index 8a5477f..22baf53 100644 --- a/lib/libutil/kinfo_getfile.c +++ b/lib/libutil/kinfo_getfile.c @@ -2,8 +2,8 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> -#include <sys/user.h> #include <sys/sysctl.h> +#include <sys/user.h> #include <stdlib.h> #include <string.h> @@ -26,14 +26,14 @@ kinfo_getfile(pid_t pid, int *cntp) mib[2] = KERN_PROC_FILEDESC; mib[3] = pid; - error = sysctl(mib, 4, NULL, &len, NULL, 0); + error = sysctl(mib, nitems(mib), NULL, &len, NULL, 0); if (error) return (NULL); len = len * 4 / 3; buf = malloc(len); if (buf == NULL) return (NULL); - error = sysctl(mib, 4, buf, &len, NULL, 0); + error = sysctl(mib, nitems(mib), buf, &len, NULL, 0); if (error) { free(buf); return (NULL); diff --git a/lib/libutil/kinfo_getproc.c b/lib/libutil/kinfo_getproc.c index 2ae6b57..496f71f 100644 --- a/lib/libutil/kinfo_getproc.c +++ b/lib/libutil/kinfo_getproc.c @@ -30,8 +30,8 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> -#include <sys/user.h> #include <sys/sysctl.h> +#include <sys/user.h> #include <stdlib.h> #include <string.h> @@ -49,14 +49,14 @@ kinfo_getproc(pid_t pid) mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = pid; - if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) + if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) < 0) return (NULL); kipp = malloc(len); if (kipp == NULL) return (NULL); - if (sysctl(mib, 4, kipp, &len, NULL, 0) < 0) + if (sysctl(mib, nitems(mib), kipp, &len, NULL, 0) < 0) goto bad; if (len != sizeof(*kipp)) goto bad; diff --git a/lib/libutil/kinfo_getvmmap.c b/lib/libutil/kinfo_getvmmap.c index 9d9e427..e01f482 100644 --- a/lib/libutil/kinfo_getvmmap.c +++ b/lib/libutil/kinfo_getvmmap.c @@ -2,8 +2,8 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> -#include <sys/user.h> #include <sys/sysctl.h> +#include <sys/user.h> #include <stdlib.h> #include <string.h> @@ -26,14 +26,14 @@ kinfo_getvmmap(pid_t pid, int *cntp) mib[2] = KERN_PROC_VMMAP; mib[3] = pid; - error = sysctl(mib, 4, NULL, &len, NULL, 0); + error = sysctl(mib, nitems(mib), NULL, &len, NULL, 0); if (error) return (NULL); len = len * 4 / 3; buf = malloc(len); if (buf == NULL) return (NULL); - error = sysctl(mib, 4, buf, &len, NULL, 0); + error = sysctl(mib, nitems(mib), buf, &len, NULL, 0); if (error) { free(buf); return (NULL); diff --git a/lib/libwrap/Makefile b/lib/libwrap/Makefile index 0e3490c..a6d8520 100644 --- a/lib/libwrap/Makefile +++ b/lib/libwrap/Makefile @@ -14,7 +14,7 @@ MLINKS= hosts_access.3 hosts_ctl.3 \ hosts_access.3 request_set.3 \ hosts_options.5 hosts.allow.5 -.PATH: ${.CURDIR}/../../contrib/tcp_wrappers +.PATH: ${SRCTOP}/contrib/tcp_wrappers CFLAGS+=-DFACILITY=LOG_AUTH -DHOSTS_ACCESS -DNETGROUP -DDAEMON_UMASK=022 \ -DREAL_DAEMON_DIR=\"${LIBEXECDIR}\" -DPROCESS_OPTIONS \ diff --git a/lib/libz/FREEBSD-upgrade b/lib/libz/FREEBSD-upgrade index d2d251b..6ff6f48 100644 --- a/lib/libz/FREEBSD-upgrade +++ b/lib/libz/FREEBSD-upgrade @@ -1,44 +1,16 @@ $FreeBSD: head/lib/libz/FREEBSD-upgrade 146082 2005-05-11 03:50:50Z kientzle $ -ZLib 1.2.2 - -Original distribution from http://www.gzip.org/zlib/ - -Vendor files removed from distribution before import: - INDEX configure qnx/ - Makefile contrib/ win32/ - Makefile.in msdos/ zconf.in.h - amiga/ old/ - as400/ projects/ - -Vendor files imported: - ChangeLog example.c minigzip.c - FAQ gzio.c trees.c - README infback.c trees.h - adler32.c inffast.c uncompr.c - algorithm.txt inffast.h zconf.h - compress.c inffixed.h zlib.3 - crc32.c inflate.c zlib.h - crc32.h inflate.h zutil.c - deflate.c inftrees.c zutil.h - deflate.h inftrees.h - -As of April, 2005, only the following three vendor files -had non-trivial local changes: - gzio.c minigzip.c zconf.h - -Added files (not from vendor): - Makefile zopen.c FREEBSD-upgrade +Original distribution from http://zlib.net/. Currently, only trivial +changes were made to support build of libstand and to suppress certain +compiler warnings, we upstream our local changes whenever they would +benefit other consumers. To Update: 1) Unpack vendor sources into a clean directory. - 2) Delete unnecessary files. - 3) Import onto the vendor branch. The 1.2.2 import was done like this: - cvs -d <CVSROOT> import -ko -m "ZLib 1.2.2" src/lib/libz ZLIB v1_2_2 - 4) In a clean directory, check out a fresh copy of HEAD, - merging in vendor changes since the last import. - cvs -d <CVSROOT> co -jZLIB:yesterday -jZLIB src/lib/libz - 5) Resolve any conflicts and commit them. - 6) Update this file with any changes to the file list or update procedure. + 2) Import onto the vendor area. + 3) Merge the vendor tree to contrib/zlib, which contains a stripped down + version of upstream source, resolve any conflicts. + 4) Double check zconf.h, zlib.pc, and Symbol.map to make sure that we + have the required changes. Test universe and commit them. -kientzle@FreeBSD.org +delphij@FreeBSD.org diff --git a/lib/libz/Makefile b/lib/libz/Makefile index dca7a1b..28eb4e4 100644 --- a/lib/libz/Makefile +++ b/lib/libz/Makefile @@ -7,6 +7,10 @@ SHLIBDIR?= /lib SHLIB_MAJOR= 6 MAN= zlib.3 +ZLIBSRC= ${SRCTOP}/contrib/zlib + +.PATH: ${ZLIBSRC} + #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 #CFLAGS=-g -DDEBUG #CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ @@ -36,14 +40,14 @@ SRCS+= zopen.c SRCS+= zutil.c #.if ${MACHINE_ARCH} == "i386" && ${MACHINE_CPU:M*i686*} -#.PATH: ${.CURDIR}/contrib/asm686 +#.PATH: ${ZLIBSRC}/contrib/asm686 #SRCS+= match.S #CFLAGS+= -DASMV -DNO_UNDERLINE #ACFLAGS+= -Wa,--noexecstack #.endif #.if ${MACHINE_ARCH} == "amd64" -#.PATH: ${.CURDIR}/contrib/gcc_gvmat64 +#.PATH: ${ZLIBSRC}/contrib/gcc_gvmat64 #SRCS+= gvmat64.S #CFLAGS+= -DASMV -DNO_UNDERLINE #ACFLAGS+= -Wa,--noexecstack @@ -55,7 +59,7 @@ CFLAGS+= -DSYMBOL_VERSIONING INCS= zconf.h zlib.h -.PATH: ${.CURDIR}/test +.PATH: ${ZLIBSRC}/test minigzip: all minigzip.o $(CC) -o minigzip minigzip.o -L. -lz diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index f5b43db..1be409b 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -104,6 +104,7 @@ static int load_needed_objects(Obj_Entry *, int); static int load_preload_objects(void); static Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int); static void map_stacks_exec(RtldLockState *); +static int obj_enforce_relro(Obj_Entry *); static Obj_Entry *obj_from_addr(const void *); static void objlist_call_fini(Objlist *, Obj_Entry *, RtldLockState *); static void objlist_call_init(Objlist *, RtldLockState *); @@ -609,6 +610,10 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) if (do_copy_relocations(obj_main) == -1) rtld_die(); + dbg("enforcing main obj relro"); + if (obj_enforce_relro(obj_main) == -1) + rtld_die(); + if (getenv(LD_ "DUMP_REL_POST") != NULL) { dump_relocations(obj_main); exit (0); @@ -2691,14 +2696,8 @@ relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj, reloc_non_plt(obj, rtldobj, flags | SYMLOOK_IFUNC, lockstate)) return (-1); - if (obj->relro_size > 0) { - if (mprotect(obj->relro_page, obj->relro_size, - PROT_READ) == -1) { - _rtld_error("%s: Cannot enforce relro protection: %s", - obj->path, rtld_strerror(errno)); - return (-1); - } - } + if (!obj->mainprog && obj_enforce_relro(obj) == -1) + return (-1); /* * Set up the magic number and version in the Obj_Entry. These @@ -3471,7 +3470,7 @@ dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param) error = 0; wlock_acquire(rtld_phdr_lock, &phdr_lockstate); - rlock_acquire(rtld_bind_lock, &bind_lockstate); + wlock_acquire(rtld_bind_lock, &bind_lockstate); for (obj = globallist_curr(TAILQ_FIRST(&obj_list)); obj != NULL;) { TAILQ_INSERT_AFTER(&obj_list, obj, &marker, next); rtld_fill_dl_phdr_info(obj, &phdr_info); @@ -3479,7 +3478,7 @@ dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param) error = callback(&phdr_info, sizeof phdr_info, param); - rlock_acquire(rtld_bind_lock, &bind_lockstate); + wlock_acquire(rtld_bind_lock, &bind_lockstate); obj = globallist_next(&marker); TAILQ_REMOVE(&obj_list, &marker, next); if (error != 0) { @@ -4986,6 +4985,19 @@ _rtld_is_dlopened(void *arg) return (res); } +int +obj_enforce_relro(Obj_Entry *obj) +{ + + if (obj->relro_size > 0 && mprotect(obj->relro_page, obj->relro_size, + PROT_READ) == -1) { + _rtld_error("%s: Cannot enforce relro protection: %s", + obj->path, rtld_strerror(errno)); + return (-1); + } + return (0); +} + static void map_stacks_exec(RtldLockState *lockstate) { diff --git a/libexec/rtld-elf/rtld_lock.c b/libexec/rtld-elf/rtld_lock.c index f31546c..c4d2a0b 100644 --- a/libexec/rtld-elf/rtld_lock.c +++ b/libexec/rtld-elf/rtld_lock.c @@ -38,8 +38,8 @@ * In this algorithm the lock is a single word. Its low-order bit is * set when a writer holds the lock. The remaining high-order bits * contain a count of readers desiring the lock. The algorithm requires - * atomic "compare_and_store" and "add" operations, which we implement - * using assembly language sequences in "rtld_start.S". + * atomic "compare_and_store" and "add" operations, which we take + * from machine/atomic.h. */ #include <sys/param.h> @@ -64,10 +64,10 @@ typedef struct Struct_Lock { } Lock; static sigset_t fullsigmask, oldsigmask; -static int thread_flag; +static int thread_flag, wnested; static void * -def_lock_create() +def_lock_create(void) { void *base; char *p; @@ -117,29 +117,34 @@ def_rlock_acquire(void *lock) static void def_wlock_acquire(void *lock) { - Lock *l = (Lock *)lock; - sigset_t tmp_oldsigmask; + Lock *l; + sigset_t tmp_oldsigmask; - for ( ; ; ) { - sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask); - if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG)) - break; - sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL); - } - oldsigmask = tmp_oldsigmask; + l = (Lock *)lock; + for (;;) { + sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask); + if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG)) + break; + sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL); + } + if (atomic_fetchadd_int(&wnested, 1) == 0) + oldsigmask = tmp_oldsigmask; } static void def_lock_release(void *lock) { - Lock *l = (Lock *)lock; - - if ((l->lock & WAFLAG) == 0) - atomic_add_rel_int(&l->lock, -RC_INCR); - else { - atomic_add_rel_int(&l->lock, -WAFLAG); - sigprocmask(SIG_SETMASK, &oldsigmask, NULL); - } + Lock *l; + + l = (Lock *)lock; + if ((l->lock & WAFLAG) == 0) + atomic_add_rel_int(&l->lock, -RC_INCR); + else { + assert(wnested > 0); + atomic_add_rel_int(&l->lock, -WAFLAG); + if (atomic_fetchadd_int(&wnested, -1) == 1) + sigprocmask(SIG_SETMASK, &oldsigmask, NULL); + } } static int @@ -269,7 +274,7 @@ lock_restart_for_upgrade(RtldLockState *lockstate) } void -lockdflt_init() +lockdflt_init(void) { int i; @@ -373,12 +378,12 @@ _rtld_atfork_pre(int *locks) return; /* - * Warning: this does not work with the rtld compat locks - * above, since the thread signal mask is corrupted (set to - * all signals blocked) if two locks are taken in write mode. - * The caller of the _rtld_atfork_pre() must provide the - * working implementation of the locks, and libthr locks are - * fine. + * Warning: this did not worked well with the rtld compat + * locks above, when the thread signal mask was corrupted (set + * to all signals blocked) if two locks were taken + * simultaneously in the write mode. The caller of the + * _rtld_atfork_pre() must provide the working implementation + * of the locks anyway, and libthr locks are fine. */ wlock_acquire(rtld_phdr_lock, &ls[0]); wlock_acquire(rtld_bind_lock, &ls[1]); diff --git a/libexec/tftpd/Makefile b/libexec/tftpd/Makefile index f005001..abee70c 100644 --- a/libexec/tftpd/Makefile +++ b/libexec/tftpd/Makefile @@ -1,13 +1,18 @@ # @(#)Makefile 8.1 (Berkeley) 6/4/93 # $FreeBSD$ +.include <bsd.own.mk> + PROG= tftpd MAN= tftpd.8 SRCS= tftp-file.c tftp-io.c tftp-options.c tftp-transfer.c tftp-utils.c SRCS+= tftpd.c WFORMAT=0 -DPADD= ${LIBWRAP} -LDADD= -lwrap +.if ${MK_TCP_WRAPPERS} != "no" +CFLAGS+= -DLIBWRAP +DPADD+= ${LIBWRAP} +LDADD+= -lwrap +.endif .include <bsd.prog.mk> diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c index 571fa59..26d8105 100644 --- a/libexec/tftpd/tftpd.c +++ b/libexec/tftpd/tftpd.c @@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$"); #include <stdlib.h> #include <string.h> #include <syslog.h> -#include <tcpd.h> #include <unistd.h> #include "tftp-file.h" @@ -75,6 +74,10 @@ __FBSDID("$FreeBSD$"); #include "tftp-transfer.h" #include "tftp-options.h" +#ifdef LIBWRAP +#include <tcpd.h> +#endif + static void tftp_wrq(int peer, char *, ssize_t); static void tftp_rrq(int peer, char *, ssize_t); @@ -281,6 +284,7 @@ main(int argc, char *argv[]) } } +#ifdef LIBWRAP /* * See if the client is allowed to talk to me. * (This needs to be done before the chroot()) @@ -329,6 +333,7 @@ main(int argc, char *argv[]) "Full access allowed" "in /etc/hosts.allow"); } +#endif /* * Since we exit here, we should do that only after the above diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8 index 9f2211c..87ea011 100644 --- a/sbin/camcontrol/camcontrol.8 +++ b/sbin/camcontrol/camcontrol.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 26, 2016 +.Dd January 6, 2017 .Dt CAMCONTROL 8 .Os .Sh NAME @@ -121,7 +121,7 @@ .Ic modepage .Op device id .Op generic args -.Aq Fl m Ar page | Fl l +.Aq Fl m Ar page[,subpage] | Fl l .Op Fl P Ar pgctl .Op Fl b | Fl e .Op Fl d @@ -678,9 +678,10 @@ The editor will be invoked if detects that standard input is terminal. .It Fl l Lists all available mode pages. -.It Fl m Ar mode_page -This specifies the number of the mode page the user would like to view -and/or edit. +If specified more then once, also lists subpages. +.It Fl m Ar page[,subpage] +This specifies the number of the mode page and optionally subpage the user +would like to view and/or edit. This argument is mandatory unless .Fl l is specified. diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index cae7ec2..0050c3b 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -122,12 +122,9 @@ typedef enum { CAM_ARG_GET_STDINQ = 0x00002000, CAM_ARG_GET_XFERRATE = 0x00004000, CAM_ARG_INQ_MASK = 0x00007000, - CAM_ARG_MODE_EDIT = 0x00008000, - CAM_ARG_PAGE_CNTL = 0x00010000, CAM_ARG_TIMEOUT = 0x00020000, CAM_ARG_CMD_IN = 0x00040000, CAM_ARG_CMD_OUT = 0x00080000, - CAM_ARG_DBD = 0x00100000, CAM_ARG_ERR_RECOVER = 0x00200000, CAM_ARG_RETRIES = 0x00400000, CAM_ARG_START_UNIT = 0x00800000, @@ -3982,8 +3979,8 @@ reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks) #ifndef MINIMALISTIC void -mode_sense(struct cam_device *device, int mode_page, int page_control, - int dbd, int retry_count, int timeout, u_int8_t *data, int datalen) +mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage, + int retry_count, int timeout, u_int8_t *data, int datalen) { union ccb *ccb; int retval; @@ -3995,15 +3992,17 @@ mode_sense(struct cam_device *device, int mode_page, int page_control, CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); - scsi_mode_sense(&ccb->csio, + scsi_mode_sense_subpage(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ MSG_SIMPLE_Q_TAG, /* dbd */ dbd, - /* page_code */ page_control << 6, - /* page */ mode_page, + /* pc */ pc << 6, + /* page */ page, + /* subpage */ subpage, /* param_buf */ data, /* param_len */ datalen, + /* minimum_cmd_size */ 0, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); @@ -4084,8 +4083,9 @@ void modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { - int c, mode_page = -1, page_control = 0; - int binary = 0, list = 0; + char *str_subpage; + int c, page = -1, subpage = -1, pc = 0; + int binary = 0, dbd = 0, edit = 0, list = 0; while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { @@ -4093,40 +4093,44 @@ modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, binary = 1; break; case 'd': - arglist |= CAM_ARG_DBD; + dbd = 1; break; case 'e': - arglist |= CAM_ARG_MODE_EDIT; + edit = 1; break; case 'l': - list = 1; + list++; break; case 'm': - mode_page = strtol(optarg, NULL, 0); - if (mode_page < 0) - errx(1, "invalid mode page %d", mode_page); + str_subpage = optarg; + strsep(&str_subpage, ","); + page = strtol(optarg, NULL, 0); + if (str_subpage) + subpage = strtol(str_subpage, NULL, 0); + else + subpage = 0; + if (page < 0) + errx(1, "invalid mode page %d", page); + if (subpage < 0) + errx(1, "invalid mode subpage %d", subpage); break; case 'P': - page_control = strtol(optarg, NULL, 0); - if ((page_control < 0) || (page_control > 3)) - errx(1, "invalid page control field %d", - page_control); - arglist |= CAM_ARG_PAGE_CNTL; + pc = strtol(optarg, NULL, 0); + if ((pc < 0) || (pc > 3)) + errx(1, "invalid page control field %d", pc); break; default: break; } } - if (mode_page == -1 && list == 0) + if (page == -1 && list == 0) errx(1, "you must specify a mode page!"); - if (list) { - mode_list(device, page_control, arglist & CAM_ARG_DBD, - retry_count, timeout); + if (list != 0) { + mode_list(device, dbd, pc, list > 1, retry_count, timeout); } else { - mode_edit(device, mode_page, page_control, - arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary, + mode_edit(device, dbd, pc, page, subpage, edit, binary, retry_count, timeout); } } @@ -4141,7 +4145,7 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, u_int8_t cdb[20]; u_int8_t atacmd[12]; struct get_hook hook; - int c, data_bytes = 0; + int c, data_bytes = 0, valid_bytes; int cdb_len = 0; int atacmd_len = 0; int dmacmd = 0; @@ -4445,16 +4449,20 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, } } + if (cdb_len) + valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid; + else + valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid; if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) && (arglist & CAM_ARG_CMD_IN) - && (data_bytes > 0)) { + && (valid_bytes > 0)) { if (fd_data == 0) { - buff_decode_visit(data_ptr, data_bytes, datastr, + buff_decode_visit(data_ptr, valid_bytes, datastr, arg_put, NULL); fprintf(stdout, "\n"); } else { ssize_t amt_written; - int amt_to_write = data_bytes; + int amt_to_write = valid_bytes; u_int8_t *buf_ptr = data_ptr; for (amt_written = 0; (amt_to_write > 0) && @@ -4469,7 +4477,7 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, } else if ((amt_written == 0) && (amt_to_write > 0)) { warnx("only wrote %u bytes out of %u", - data_bytes - amt_to_write, data_bytes); + valid_bytes - amt_to_write, valid_bytes); } } } diff --git a/sbin/camcontrol/camcontrol.h b/sbin/camcontrol/camcontrol.h index bb2fe4f..3d6b98d 100644 --- a/sbin/camcontrol/camcontrol.h +++ b/sbin/camcontrol/camcontrol.h @@ -73,14 +73,14 @@ int camxferrate(struct cam_device *device); int fwdownload(struct cam_device *device, int argc, char **argv, char *combinedopt, int printerrors, int retry_count, int timeout); -void mode_sense(struct cam_device *device, int mode_page, int page_control, - int dbd, int retry_count, int timeout, u_int8_t *data, +void mode_sense(struct cam_device *device, int dbd, int pc, int page, + int subpage, int retry_count, int timeout, uint8_t *data, int datalen); void mode_select(struct cam_device *device, int save_pages, int retry_count, int timeout, u_int8_t *data, int datalen); -void mode_edit(struct cam_device *device, int page, int page_control, int dbd, +void mode_edit(struct cam_device *device, int dbd, int pc, int page, int subpage, int edit, int binary, int retry_count, int timeout); -void mode_list(struct cam_device *device, int page_control, int dbd, +void mode_list(struct cam_device *device, int dbd, int pc, int subpages, int retry_count, int timeout); int scsidoinquiry(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); diff --git a/sbin/camcontrol/modeedit.c b/sbin/camcontrol/modeedit.c index 8262c3c..90862db 100644 --- a/sbin/camcontrol/modeedit.c +++ b/sbin/camcontrol/modeedit.c @@ -66,9 +66,6 @@ __FBSDID("$FreeBSD$"); #define MODE_PAGE_HEADER(mh) \ (struct scsi_mode_page_header *)find_mode_page_6(mh) -#define MODE_PAGE_DATA(mph) \ - (u_int8_t *)(mph) + sizeof(struct scsi_mode_page_header) - struct editentry { STAILQ_ENTRY(editentry) link; @@ -86,7 +83,8 @@ static int editlist_changed = 0; /* Whether any entries were changed. */ struct pagename { SLIST_ENTRY(pagename) link; - int pagenum; + int page; + int subpage; char *name; }; static SLIST_HEAD(, pagename) namelist; /* Page number to name mappings. */ @@ -106,21 +104,22 @@ static int editentry_save(void *hook, char *name); static struct editentry *editentry_lookup(char *name); static int editentry_set(char *name, char *newvalue, int editonly); -static void editlist_populate(struct cam_device *device, - int modepage, int page_control, - int dbd, int retries, int timeout); -static void editlist_save(struct cam_device *device, int modepage, - int page_control, int dbd, int retries, - int timeout); -static void nameentry_create(int pagenum, char *name); -static struct pagename *nameentry_lookup(int pagenum); -static int load_format(const char *pagedb_path, int page); +static void editlist_populate(struct cam_device *device, int dbd, + int pc, int page, int subpage, + int retries, int timeout); +static void editlist_save(struct cam_device *device, int dbd, + int pc, int page, int subpage, + int retries, int timeout); +static void nameentry_create(int page, int subpage, char *name); +static struct pagename *nameentry_lookup(int page, int subpage); +static int load_format(const char *pagedb_path, int lpage, + int lsubpage); static int modepage_write(FILE *file, int editonly); static int modepage_read(FILE *file); static void modepage_edit(void); -static void modepage_dump(struct cam_device *device, int page, - int page_control, int dbd, int retries, - int timeout); +static void modepage_dump(struct cam_device *device, int dbd, + int pc, int page, int subpage, int retries, + int timeout); static void cleanup_editfile(void); @@ -193,7 +192,14 @@ editentry_save(void *hook __unused, char *name) struct editentry *src; /* Entry value to save. */ src = editentry_lookup(name); - assert(src != NULL); + if (src == 0) { + /* + * This happens if field does not fit into read page size. + * It also means that this field won't be written, so the + * returned value does not really matter. + */ + return (0); + } switch (src->type) { case 'i': /* Byte-sized integral type. */ @@ -318,10 +324,10 @@ editentry_set(char *name, char *newvalue, int editonly) } static void -nameentry_create(int pagenum, char *name) { +nameentry_create(int page, int subpage, char *name) { struct pagename *newentry; - if (pagenum < 0 || name == NULL || name[0] == '\0') + if (page < 0 || subpage < 0 || name == NULL || name[0] == '\0') return; /* Allocate memory for the new entry and a copy of the entry name. */ @@ -332,16 +338,17 @@ nameentry_create(int pagenum, char *name) { /* Trim any trailing whitespace for the page name. */ RTRIM(newentry->name); - newentry->pagenum = pagenum; + newentry->page = page; + newentry->subpage = subpage; SLIST_INSERT_HEAD(&namelist, newentry, link); } static struct pagename * -nameentry_lookup(int pagenum) { +nameentry_lookup(int page, int subpage) { struct pagename *scan; SLIST_FOREACH(scan, &namelist, link) { - if (pagenum == scan->pagenum) + if (page == scan->page && subpage == scan->subpage) return (scan); } @@ -350,12 +357,14 @@ nameentry_lookup(int pagenum) { } static int -load_format(const char *pagedb_path, int page) +load_format(const char *pagedb_path, int lpage, int lsubpage) { FILE *pagedb; - char str_pagenum[MAX_PAGENUM_LEN]; + char str_page[MAX_PAGENUM_LEN]; + char *str_subpage; char str_pagename[MAX_PAGENAME_LEN]; - int pagenum; + int page; + int subpage; int depth; /* Quoting depth. */ int found; int lineno; @@ -364,9 +373,10 @@ load_format(const char *pagedb_path, int page) char c; #define SETSTATE_LOCATE do { \ - str_pagenum[0] = '\0'; \ + str_page[0] = '\0'; \ str_pagename[0] = '\0'; \ - pagenum = -1; \ + page = -1; \ + subpage = -1; \ state = LOCATE; \ } while (0) @@ -443,32 +453,46 @@ load_format(const char *pagedb_path, int page) * modes without providing a mode definition). */ /* Record the name of this page. */ - pagenum = strtol(str_pagenum, NULL, 0); - nameentry_create(pagenum, str_pagename); + str_subpage = str_page; + strsep(&str_subpage, ","); + page = strtol(str_page, NULL, 0); + if (str_subpage) + subpage = strtol(str_subpage, NULL, 0); + else + subpage = 0; + nameentry_create(page, subpage, str_pagename); SETSTATE_LOCATE; } else if (depth == 0 && c == PAGENAME_START) { SETSTATE_PAGENAME; } else if (c == PAGEDEF_START) { - pagenum = strtol(str_pagenum, NULL, 0); + str_subpage = str_page; + strsep(&str_subpage, ","); + page = strtol(str_page, NULL, 0); + if (str_subpage) + subpage = strtol(str_subpage, NULL, 0); + else + subpage = 0; if (depth == 1) { /* Record the name of this page. */ - nameentry_create(pagenum, str_pagename); + nameentry_create(page, subpage, + str_pagename); /* * Only record the format if this is * the page we are interested in. */ - if (page == pagenum && !found) + if (lpage == page && + lsubpage == subpage && !found) SETSTATE_PAGEDEF; } } else if (c == PAGEDEF_END) { /* Reset the processor state. */ SETSTATE_LOCATE; - } else if (depth == 0 && ! BUFFERFULL(str_pagenum)) { - strncat(str_pagenum, &c, 1); + } else if (depth == 0 && ! BUFFERFULL(str_page)) { + strncat(str_page, &c, 1); } else if (depth == 0) { errx(EX_OSFILE, "%s:%d: %s %zd %s", pagedb_path, lineno, "page identifier exceeds", - sizeof(str_pagenum) - 1, "characters"); + sizeof(str_page) - 1, "characters"); } break; @@ -484,7 +508,7 @@ load_format(const char *pagedb_path, int page) } else { errx(EX_OSFILE, "%s:%d: %s %zd %s", pagedb_path, lineno, "page name exceeds", - sizeof(str_pagenum) - 1, "characters"); + sizeof(str_page) - 1, "characters"); } break; @@ -525,88 +549,97 @@ load_format(const char *pagedb_path, int page) } static void -editlist_populate(struct cam_device *device, int modepage, int page_control, - int dbd, int retries, int timeout) +editlist_populate(struct cam_device *device, int dbd, int pc, int page, + int subpage, int retries, int timeout) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ u_int8_t *mode_pars; /* Pointer to modepage params. */ struct scsi_mode_header_6 *mh; /* Location of mode header. */ struct scsi_mode_page_header *mph; + struct scsi_mode_page_header_sp *mphsp; + size_t len; STAILQ_INIT(&editlist); /* Fetch changeable values; use to build initial editlist. */ - mode_sense(device, modepage, 1, dbd, retries, timeout, data, + mode_sense(device, dbd, 1, page, subpage, retries, timeout, data, sizeof(data)); mh = (struct scsi_mode_header_6 *)data; mph = MODE_PAGE_HEADER(mh); - mode_pars = MODE_PAGE_DATA(mph); + if ((mph->page_code & SMPH_SPF) == 0) { + mode_pars = (uint8_t *)(mph + 1); + len = mph->page_length; + } else { + mphsp = (struct scsi_mode_page_header_sp *)mph; + mode_pars = (uint8_t *)(mphsp + 1); + len = scsi_2btoul(mphsp->page_length); + } + len = MIN(len, sizeof(data) - (mode_pars - data)); /* Decode the value data, creating edit_entries for each value. */ - buff_decode_visit(mode_pars, mh->data_length, format, - editentry_create, 0); + buff_decode_visit(mode_pars, len, format, editentry_create, 0); /* Fetch the current/saved values; use to set editentry values. */ - mode_sense(device, modepage, page_control, dbd, retries, timeout, data, - sizeof(data)); - buff_decode_visit(mode_pars, mh->data_length, format, - editentry_update, 0); + mode_sense(device, dbd, pc, page, subpage, retries, timeout, + data, sizeof(data)); + buff_decode_visit(mode_pars, len, format, editentry_update, 0); } static void -editlist_save(struct cam_device *device, int modepage, int page_control, - int dbd, int retries, int timeout) +editlist_save(struct cam_device *device, int dbd, int pc, int page, + int subpage, int retries, int timeout) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ u_int8_t *mode_pars; /* Pointer to modepage params. */ struct scsi_mode_header_6 *mh; /* Location of mode header. */ struct scsi_mode_page_header *mph; + struct scsi_mode_page_header_sp *mphsp; + size_t len, hlen; /* Make sure that something changed before continuing. */ if (! editlist_changed) return; - /* - * Preload the CDB buffer with the current mode page data. - * XXX If buff_encode_visit would return the number of bytes encoded - * we *should* use that to build a header from scratch. As it is - * now, we need mode_sense to find out the page length. - */ - mode_sense(device, modepage, page_control, dbd, retries, timeout, data, - sizeof(data)); + /* Preload the CDB buffer with the current mode page data. */ + mode_sense(device, dbd, pc, page, subpage, retries, timeout, + data, sizeof(data)); /* Initial headers & offsets. */ mh = (struct scsi_mode_header_6 *)data; mph = MODE_PAGE_HEADER(mh); - mode_pars = MODE_PAGE_DATA(mph); + if ((mph->page_code & SMPH_SPF) == 0) { + hlen = sizeof(*mph); + mode_pars = (uint8_t *)(mph + 1); + len = mph->page_length; + } else { + mphsp = (struct scsi_mode_page_header_sp *)mph; + hlen = sizeof(*mphsp); + mode_pars = (uint8_t *)(mphsp + 1); + len = scsi_2btoul(mphsp->page_length); + } + len = MIN(len, sizeof(data) - (mode_pars - data)); /* Encode the value data to be passed back to the device. */ - buff_encode_visit(mode_pars, mh->data_length, format, - editentry_save, 0); + buff_encode_visit(mode_pars, len, format, editentry_save, 0); /* Eliminate block descriptors. */ - bcopy(mph, ((u_int8_t *)mh) + sizeof(*mh), - sizeof(*mph) + mph->page_length); + bcopy(mph, mh + 1, hlen + len); /* Recalculate headers & offsets. */ - mh->blk_desc_len = 0; /* No block descriptors. */ + mh->data_length = 0; /* Reserved for MODE SELECT command. */ mh->dev_spec = 0; /* Clear device-specific parameters. */ + mh->blk_desc_len = 0; /* No block descriptors. */ mph = MODE_PAGE_HEADER(mh); - mode_pars = MODE_PAGE_DATA(mph); - - mph->page_code &= SMS_PAGE_CODE;/* Isolate just the page code. */ - mh->data_length = 0; /* Reserved for MODE SELECT command. */ + mph->page_code &= ~SMPH_PS; /* Reserved for MODE SELECT command. */ /* * Write the changes back to the device. If the user editted control * page 3 (saved values) then request the changes be permanently * recorded. */ - mode_select(device, - (page_control << PAGE_CTRL_SHIFT == SMS_PAGE_CTRL_SAVED), - retries, timeout, (u_int8_t *)mh, - sizeof(*mh) + mh->blk_desc_len + sizeof(*mph) + mph->page_length); + mode_select(device, (pc << PAGE_CTRL_SHIFT == SMS_PAGE_CTRL_SAVED), + retries, timeout, (u_int8_t *)mh, sizeof(*mh) + hlen + len); } static int @@ -775,24 +808,33 @@ modepage_edit(void) } static void -modepage_dump(struct cam_device *device, int page, int page_control, int dbd, +modepage_dump(struct cam_device *device, int dbd, int pc, int page, int subpage, int retries, int timeout) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ u_int8_t *mode_pars; /* Pointer to modepage params. */ struct scsi_mode_header_6 *mh; /* Location of mode header. */ struct scsi_mode_page_header *mph; - int indx; /* Index for scanning mode params. */ + struct scsi_mode_page_header_sp *mphsp; + size_t indx, len; - mode_sense(device, page, page_control, dbd, retries, timeout, data, - sizeof(data)); + mode_sense(device, dbd, pc, page, subpage, retries, timeout, + data, sizeof(data)); mh = (struct scsi_mode_header_6 *)data; mph = MODE_PAGE_HEADER(mh); - mode_pars = MODE_PAGE_DATA(mph); + if ((mph->page_code & SMPH_SPF) == 0) { + mode_pars = (uint8_t *)(mph + 1); + len = mph->page_length; + } else { + mphsp = (struct scsi_mode_page_header_sp *)mph; + mode_pars = (uint8_t *)(mphsp + 1); + len = scsi_2btoul(mphsp->page_length); + } + len = MIN(len, sizeof(data) - (mode_pars - data)); /* Print the raw mode page data with newlines each 8 bytes. */ - for (indx = 0; indx < mph->page_length; indx++) { + for (indx = 0; indx < len; indx++) { printf("%02x%c",mode_pars[indx], (((indx + 1) % 8) == 0) ? '\n' : ' '); } @@ -810,7 +852,7 @@ cleanup_editfile(void) } void -mode_edit(struct cam_device *device, int page, int page_control, int dbd, +mode_edit(struct cam_device *device, int dbd, int pc, int page, int subpage, int edit, int binary, int retry_count, int timeout) { const char *pagedb_path; /* Path to modepage database. */ @@ -822,15 +864,17 @@ mode_edit(struct cam_device *device, int page, int page_control, int dbd, if ((pagedb_path = getenv("SCSI_MODES")) == NULL) pagedb_path = DEFAULT_SCSI_MODE_DB; - if (load_format(pagedb_path, page) != 0 && (edit || verbose)) { + if (load_format(pagedb_path, page, subpage) != 0 && + (edit || verbose)) { if (errno == ENOENT) { /* Modepage database file not found. */ warn("cannot open modepage database \"%s\"", pagedb_path); } else if (errno == ESRCH) { /* Modepage entry not found in database. */ - warnx("modepage %d not found in database" - "\"%s\"", page, pagedb_path); + warnx("modepage 0x%02x,0x%02x not found in " + "database \"%s\"", page, subpage, + pagedb_path); } /* We can recover in display mode, otherwise we exit. */ if (!edit) { @@ -840,22 +884,20 @@ mode_edit(struct cam_device *device, int page, int page_control, int dbd, exit(EX_OSFILE); } - editlist_populate(device, page, page_control, dbd, retry_count, + editlist_populate(device, dbd, pc, page, subpage, retry_count, timeout); } if (edit) { - if (page_control << PAGE_CTRL_SHIFT != SMS_PAGE_CTRL_CURRENT && - page_control << PAGE_CTRL_SHIFT != SMS_PAGE_CTRL_SAVED) + if (pc << PAGE_CTRL_SHIFT != SMS_PAGE_CTRL_CURRENT && + pc << PAGE_CTRL_SHIFT != SMS_PAGE_CTRL_SAVED) errx(EX_USAGE, "it only makes sense to edit page 0 " "(current) or page 3 (saved values)"); modepage_edit(); - editlist_save(device, page, page_control, dbd, retry_count, - timeout); + editlist_save(device, dbd, pc, page, subpage, retry_count, timeout); } else if (binary || STAILQ_EMPTY(&editlist)) { /* Display without formatting information. */ - modepage_dump(device, page, page_control, dbd, retry_count, - timeout); + modepage_dump(device, dbd, pc, page, subpage, retry_count, timeout); } else { /* Display with format. */ modepage_write(stdout, 0); @@ -863,44 +905,55 @@ mode_edit(struct cam_device *device, int page, int page_control, int dbd, } void -mode_list(struct cam_device *device, int page_control, int dbd, +mode_list(struct cam_device *device, int dbd, int pc, int subpages, int retry_count, int timeout) { u_int8_t data[MAX_COMMAND_SIZE];/* Buffer to hold sense data. */ struct scsi_mode_header_6 *mh; /* Location of mode header. */ struct scsi_mode_page_header *mph; + struct scsi_mode_page_header_sp *mphsp; struct pagename *nameentry; const char *pagedb_path; - int len; + int len, page, subpage; if ((pagedb_path = getenv("SCSI_MODES")) == NULL) pagedb_path = DEFAULT_SCSI_MODE_DB; - if (load_format(pagedb_path, 0) != 0 && verbose && errno == ENOENT) { + if (load_format(pagedb_path, 0, 0) != 0 && verbose && errno == ENOENT) { /* Modepage database file not found. */ warn("cannot open modepage database \"%s\"", pagedb_path); } /* Build the list of all mode pages by querying the "all pages" page. */ - mode_sense(device, SMS_ALL_PAGES_PAGE, page_control, dbd, retry_count, - timeout, data, sizeof(data)); + mode_sense(device, dbd, pc, SMS_ALL_PAGES_PAGE, + subpages ? SMS_SUBPAGE_ALL : 0, + retry_count, timeout, data, sizeof(data)); mh = (struct scsi_mode_header_6 *)data; len = sizeof(*mh) + mh->blk_desc_len; /* Skip block descriptors. */ /* Iterate through the pages in the reply. */ while (len < mh->data_length) { /* Locate the next mode page header. */ - mph = (struct scsi_mode_page_header *) - ((intptr_t)mh + len); - - mph->page_code &= SMS_PAGE_CODE; - nameentry = nameentry_lookup(mph->page_code); - - if (nameentry == NULL || nameentry->name == NULL) - printf("0x%02x\n", mph->page_code); - else - printf("0x%02x\t%s\n", mph->page_code, - nameentry->name); - len += mph->page_length + sizeof(*mph); + mph = (struct scsi_mode_page_header *)((intptr_t)mh + len); + + if ((mph->page_code & SMPH_SPF) == 0) { + page = mph->page_code & SMS_PAGE_CODE; + subpage = 0; + len += sizeof(*mph) + mph->page_length; + } else { + mphsp = (struct scsi_mode_page_header_sp *)mph; + page = mphsp->page_code & SMS_PAGE_CODE; + subpage = mphsp->subpage; + len += sizeof(*mphsp) + scsi_2btoul(mphsp->page_length); + } + + nameentry = nameentry_lookup(page, subpage); + if (subpage == 0) { + printf("0x%02x\t%s\n", page, + nameentry ? nameentry->name : ""); + } else { + printf("0x%02x,0x%02x\t%s\n", page, subpage, + nameentry ? nameentry->name : ""); + } } } diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c index 3317ceb..d493717 100644 --- a/sbin/dhclient/dispatch.c +++ b/sbin/dhclient/dispatch.c @@ -453,16 +453,12 @@ add_protocol(char *name, int fd, void (*handler)(struct protocol *), void remove_protocol(struct protocol *proto) { - struct protocol *p, *next, *prev; + struct protocol *p, *next; - prev = NULL; for (p = protocols; p; p = next) { next = p->next; if (p == proto) { - if (prev) - prev->next = p->next; - else - protocols = p->next; + protocols = p->next; free(p); } } diff --git a/secure/lib/libcrypto/Makefile b/secure/lib/libcrypto/Makefile index ca1520b..0c28f08 100644 --- a/secure/lib/libcrypto/Makefile +++ b/secure/lib/libcrypto/Makefile @@ -22,9 +22,9 @@ MAN+= config.5 des_modes.7 # base sources SRCS= cpt_err.c cryptlib.c cversion.c ex_data.c mem.c mem_dbg.c o_dir.c \ o_fips.c o_init.c o_str.c o_time.c uid.c -.if ${MACHINE_CPUARCH} == "amd64" +.if defined(ASM_amd64) SRCS+= x86_64cpuid.S -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) SRCS+= x86cpuid.S .else SRCS+= mem_clr.c @@ -33,10 +33,10 @@ INCS+= crypto.h ebcdic.h opensslv.h ossl_typ.h symhacks.h ../e_os2.h # aes SRCS+= aes_cfb.c aes_ctr.c aes_ecb.c aes_ige.c aes_misc.c aes_ofb.c aes_wrap.c -.if ${MACHINE_CPUARCH} == "amd64" +.if defined(ASM_amd64) SRCS+= aes-x86_64.S aesni-sha1-x86_64.S aesni-x86_64.S bsaes-x86_64.S \ vpaes-x86_64.S -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) SRCS+= aes-586.S aesni-x86.S vpaes-x86.S .else SRCS+= aes_cbc.c aes_core.c @@ -60,7 +60,7 @@ INCS+= asn1.h asn1_mac.h asn1t.h # bf SRCS+= bf_cfb64.c bf_ecb.c bf_ofb64.c bf_skey.c -.if ${MACHINE_CPUARCH} == "i386" +.if defined(ASM_i386) .if ${MACHINE_CPU:Mi686} SRCS+= bf-686.S .else @@ -82,10 +82,10 @@ SRCS+= bn_add.c bn_blind.c bn_const.c bn_ctx.c bn_depr.c bn_div.c bn_err.c \ bn_exp.c bn_exp2.c bn_gcd.c bn_gf2m.c bn_kron.c bn_lib.c bn_mod.c \ bn_mont.c bn_mpi.c bn_mul.c bn_nist.c bn_prime.c bn_print.c bn_rand.c \ bn_recp.c bn_shift.c bn_sqr.c bn_sqrt.c bn_word.c bn_x931p.c -.if ${MACHINE_CPUARCH} == "amd64" +.if defined(ASM_amd64) SRCS+= modexp512-x86_64.S x86_64-gcc.c x86_64-gf2m.S x86_64-mont.S \ x86_64-mont5.S -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) SRCS+= bn-586.S co-586.S x86-gf2m.S x86-mont.S .else SRCS+= bn_asm.c @@ -98,9 +98,9 @@ INCS+= buffer.h # camellia SRCS+= cmll_cfb.c cmll_ctr.c cmll_ecb.c cmll_ofb.c cmll_utl.c -.if ${MACHINE_CPUARCH} == "amd64" +.if defined(ASM_amd64) SRCS+= cmll_misc.c cmll-x86_64.S -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) SRCS+= cmll-x86.S .else SRCS+= camellia.c cmll_cbc.c cmll_misc.c @@ -134,7 +134,7 @@ SRCS+= cbc_cksm.c cbc_enc.c cfb64ede.c cfb64enc.c cfb_enc.c des_old.c \ des_old2.c ecb3_enc.c ecb_enc.c ede_cbcm_enc.c enc_read.c enc_writ.c \ fcrypt.c ofb64ede.c ofb64enc.c ofb_enc.c pcbc_enc.c qud_cksm.c \ rand_key.c read2pwd.c rpc_enc.c set_key.c str2key.c xcbc_enc.c -.if ${MACHINE_CPUARCH} == "i386" +.if defined(ASM_i386) SRCS+= crypt586.S des-586.S .else SRCS+= des_enc.c fcrypt_b.c @@ -215,9 +215,9 @@ INCS+= md4.h # md5 SRCS+= md5_dgst.c md5_one.c -.if ${MACHINE_CPUARCH} == "amd64" +.if defined(ASM_amd64) SRCS+= md5-x86_64.S -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) SRCS+= md5-586.S .endif INCS+= md5.h @@ -228,9 +228,9 @@ INCS+= mdc2.h # modes SRCS+= cbc128.c ccm128.c cfb128.c ctr128.c cts128.c gcm128.c ofb128.c xts128.c -.if ${MACHINE_CPUARCH} == "amd64" +.if defined(ASM_amd64) SRCS+= ghash-x86_64.S -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) SRCS+= ghash-x86.S .endif INCS+= modes.h @@ -274,9 +274,9 @@ INCS+= rc2.h # rc4 SRCS+= rc4_utl.c -.if ${MACHINE_CPUARCH} == "amd64" +.if defined(ASM_amd64) SRCS+= rc4-md5-x86_64.S rc4-x86_64.S -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) SRCS+= rc4-586.S .else SRCS+= rc4_enc.c rc4_skey.c @@ -285,7 +285,7 @@ INCS+= rc4.h # rc5 SRCS+= rc5_ecb.c rc5_skey.c rc5cfb64.c rc5ofb64.c -.if ${MACHINE_CPUARCH} == "i386" +.if defined(ASM_i386) SRCS+= rc5-586.S .else SRCS+= rc5_enc.c @@ -294,7 +294,7 @@ INCS+= rc5.h # ripemd SRCS+= rmd_dgst.c rmd_one.c -.if ${MACHINE_CPUARCH} == "i386" +.if defined(ASM_i386) SRCS+= rmd-586.S .endif INCS+= ripemd.h @@ -312,9 +312,9 @@ INCS+= seed.h # sha SRCS+= sha1_one.c sha1dgst.c sha256.c sha512.c sha_dgst.c sha_one.c -.if ${MACHINE_CPUARCH} == "amd64" +.if defined(ASM_amd64) SRCS+= sha1-x86_64.S sha256-x86_64.S sha512-x86_64.S -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) SRCS+= sha1-586.S sha256-586.S sha512-586.S .endif INCS+= sha.h @@ -343,9 +343,9 @@ INCS+= ui.h ui_compat.h # whrlpool SRCS+= wp_dgst.c -.if ${MACHINE_CPUARCH} == "amd64" +.if defined(ASM_amd64) SRCS+= wp-x86_64.S -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) SRCS+= wp-mmx.S wp_block.c .else SRCS+= wp_block.c @@ -382,7 +382,7 @@ CFLAGS+= -I${LCRYPTO_SRC}/crypto/modes ACFLAGS+= -Wa,--noexecstack .endif -CLEANFILES= buildinf.h opensslconf.h +CLEANFILES= buildinf.h opensslconf.h opensslconf.h.tmp buildinf.h: ${.CURDIR}/Makefile ( echo "#ifndef MK1MF_BUILD"; \ @@ -391,23 +391,21 @@ buildinf.h: ${.CURDIR}/Makefile echo " #define PLATFORM \"platform: FreeBSD-${MACHINE_ARCH}\""; \ echo "#endif" ) > ${.TARGET} -.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" -opensslconf.h: opensslconf-x86.h +opensslconf.h: opensslconf-${MACHINE_CPUARCH:C/^(amd64|i386)$/x86/}.h.in +.if defined(ASM_${MACHINE_CPUARCH}) + sed 's/%%ASM%%//; /%%NO_ASM%%/d' ${.ALLSRC} > ${.TARGET}.tmp .else -opensslconf.h: opensslconf-${MACHINE_CPUARCH}.h + sed '/%%ASM%%/d; s/%%NO_ASM%%//' ${.ALLSRC} > ${.TARGET}.tmp .endif - cp -f ${.ALLSRC} ${.TARGET} + cp -f ${.TARGET}.tmp ${.TARGET} .include <bsd.lib.mk> -.if ${MACHINE_CPUARCH} == "amd64" -.PATH: ${.CURDIR}/amd64 -.elif ${MACHINE_CPUARCH} == "i386" -.PATH: ${.CURDIR}/i386 +.if defined(ASM_${MACHINE_CPUARCH}) +.PATH: ${.CURDIR}/${MACHINE_CPUARCH} +.if defined(ASM_amd64) +.PATH: ${LCRYPTO_SRC}/crypto/bn/asm .endif - -.if ${MACHINE_CPUARCH} == "amd64" -_bn_asmpath= ${LCRYPTO_SRC}/crypto/bn/asm .endif .PATH: ${LCRYPTO_SRC}/crypto \ @@ -416,7 +414,6 @@ _bn_asmpath= ${LCRYPTO_SRC}/crypto/bn/asm ${LCRYPTO_SRC}/crypto/bf \ ${LCRYPTO_SRC}/crypto/bio \ ${LCRYPTO_SRC}/crypto/bn \ - ${_bn_asmpath} \ ${LCRYPTO_SRC}/crypto/buffer \ ${LCRYPTO_SRC}/crypto/camellia \ ${LCRYPTO_SRC}/crypto/cast \ diff --git a/secure/lib/libcrypto/Makefile.asm b/secure/lib/libcrypto/Makefile.asm index 16ea250..42a7194 100644 --- a/secure/lib/libcrypto/Makefile.asm +++ b/secure/lib/libcrypto/Makefile.asm @@ -6,7 +6,7 @@ .include "Makefile.inc" -.if ${MACHINE_CPUARCH} == "amd64" +.if defined(ASM_amd64) .PATH: ${LCRYPTO_SRC}/crypto \ ${LCRYPTO_SRC}/crypto/aes/asm \ @@ -73,7 +73,7 @@ ${s}.S: ${s}.s cat ${s}.s ) > ${.TARGET} .endfor -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) .PATH: ${LCRYPTO_SRC}/crypto \ ${LCRYPTO_SRC}/crypto/aes/asm \ diff --git a/secure/lib/libcrypto/Makefile.inc b/secure/lib/libcrypto/Makefile.inc index c770cf2..c2da05b 100644 --- a/secure/lib/libcrypto/Makefile.inc +++ b/secure/lib/libcrypto/Makefile.inc @@ -21,7 +21,17 @@ CFLAGS+=-DL_ENDIAN CFLAGS+=-DB_ENDIAN .endif -.if ${MACHINE_CPUARCH} == "amd64" +.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" +_ASM_AVX!= { \ + echo vzeroall | \ + ${CC} -x assembler -o /dev/null -c - 2> /dev/null; \ + } && echo yes || echo no +.if ${_ASM_AVX} == yes +ASM_${MACHINE_CPUARCH}= +.endif +.endif + +.if defined(ASM_amd64) CFLAGS+=-DOPENSSL_IA32_SSE2 CFLAGS+=-DAES_ASM -DBSAES_ASM -DVPAES_ASM CFLAGS+=-DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m @@ -29,7 +39,7 @@ CFLAGS+=-DMD5_ASM CFLAGS+=-DGHASH_ASM CFLAGS+=-DSHA1_ASM -DSHA256_ASM -DSHA512_ASM CFLAGS+=-DWHIRLPOOL_ASM -.elif ${MACHINE_CPUARCH} == "i386" +.elif defined(ASM_i386) CFLAGS+=-DOPENSSL_IA32_SSE2 CFLAGS+=-DAES_ASM -DVPAES_ASM CFLAGS+=-DOPENSSL_BN_ASM_PART_WORDS -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m diff --git a/secure/lib/libcrypto/opensslconf-arm.h b/secure/lib/libcrypto/opensslconf-arm.h.in index 11bebb6..c36c00a 100644 --- a/secure/lib/libcrypto/opensslconf-arm.h +++ b/secure/lib/libcrypto/opensslconf-arm.h.in @@ -42,9 +42,9 @@ extern "C" { #ifndef OPENSSL_THREADS # define OPENSSL_THREADS #endif -#ifndef OPENSSL_NO_ASM -# define OPENSSL_NO_ASM -#endif +%%NO_ASM%%#ifndef OPENSSL_NO_ASM +%%NO_ASM%%# define OPENSSL_NO_ASM +%%NO_ASM%%#endif #ifndef OPENSSL_NO_STATIC_ENGINE # define OPENSSL_NO_STATIC_ENGINE #endif @@ -83,6 +83,8 @@ extern "C" { # endif #endif +%%ASM%%#define OPENSSL_CPUID_OBJ +%%ASM%% /* crypto/opensslconf.h.in */ /* Generate 80386 code? */ diff --git a/secure/lib/libcrypto/opensslconf-ia64.h b/secure/lib/libcrypto/opensslconf-ia64.h.in index f4bd669..8e953b7 100644 --- a/secure/lib/libcrypto/opensslconf-ia64.h +++ b/secure/lib/libcrypto/opensslconf-ia64.h.in @@ -36,9 +36,9 @@ #ifndef OPENSSL_THREADS # define OPENSSL_THREADS #endif -#ifndef OPENSSL_NO_ASM -# define OPENSSL_NO_ASM -#endif +%%NO_ASM%%#ifndef OPENSSL_NO_ASM +%%NO_ASM%%# define OPENSSL_NO_ASM +%%NO_ASM%%#endif #ifndef OPENSSL_NO_STATIC_ENGINE # define OPENSSL_NO_STATIC_ENGINE #endif diff --git a/secure/lib/libcrypto/opensslconf-mips.h b/secure/lib/libcrypto/opensslconf-mips.h.in index fe4af3b..ee8fcd7 100644 --- a/secure/lib/libcrypto/opensslconf-mips.h +++ b/secure/lib/libcrypto/opensslconf-mips.h.in @@ -42,9 +42,9 @@ extern "C" { #ifndef OPENSSL_THREADS # define OPENSSL_THREADS #endif -#ifndef OPENSSL_NO_ASM -# define OPENSSL_NO_ASM -#endif +%%NO_ASM%%#ifndef OPENSSL_NO_ASM +%%NO_ASM%%# define OPENSSL_NO_ASM +%%NO_ASM%%#endif #ifndef OPENSSL_NO_STATIC_ENGINE # define OPENSSL_NO_STATIC_ENGINE #endif diff --git a/secure/lib/libcrypto/opensslconf-powerpc.h b/secure/lib/libcrypto/opensslconf-powerpc.h.in index ba593ed..f0567e1 100644 --- a/secure/lib/libcrypto/opensslconf-powerpc.h +++ b/secure/lib/libcrypto/opensslconf-powerpc.h.in @@ -42,9 +42,9 @@ extern "C" { #ifndef OPENSSL_THREADS # define OPENSSL_THREADS #endif -#ifndef OPENSSL_NO_ASM -# define OPENSSL_NO_ASM -#endif +%%NO_ASM%%#ifndef OPENSSL_NO_ASM +%%NO_ASM%%# define OPENSSL_NO_ASM +%%NO_ASM%%#endif #ifndef OPENSSL_NO_STATIC_ENGINE # define OPENSSL_NO_STATIC_ENGINE #endif @@ -83,6 +83,8 @@ extern "C" { # endif #endif +%%ASM%%#define OPENSSL_CPUID_OBJ +%%ASM%% /* crypto/opensslconf.h.in */ /* Generate 80386 code? */ diff --git a/secure/lib/libcrypto/opensslconf-sparc64.h b/secure/lib/libcrypto/opensslconf-sparc64.h.in index 2bd0b2c..b83d403 100644 --- a/secure/lib/libcrypto/opensslconf-sparc64.h +++ b/secure/lib/libcrypto/opensslconf-sparc64.h.in @@ -42,9 +42,9 @@ extern "C" { #ifndef OPENSSL_THREADS # define OPENSSL_THREADS #endif -#ifndef OPENSSL_NO_ASM -# define OPENSSL_NO_ASM -#endif +%%NO_ASM%%#ifndef OPENSSL_NO_ASM +%%NO_ASM%%# define OPENSSL_NO_ASM +%%NO_ASM%%#endif #ifndef OPENSSL_NO_STATIC_ENGINE # define OPENSSL_NO_STATIC_ENGINE #endif @@ -83,6 +83,8 @@ extern "C" { # endif #endif +%%ASM%%#define OPENSSL_CPUID_OBJ +%%ASM%% /* crypto/opensslconf.h.in */ /* Generate 80386 code? */ diff --git a/secure/lib/libcrypto/opensslconf-x86.h b/secure/lib/libcrypto/opensslconf-x86.h.in index 43f62bc..d1905adc 100644 --- a/secure/lib/libcrypto/opensslconf-x86.h +++ b/secure/lib/libcrypto/opensslconf-x86.h.in @@ -42,6 +42,9 @@ extern "C" { #ifndef OPENSSL_THREADS # define OPENSSL_THREADS #endif +%%NO_ASM%%#ifndef OPENSSL_NO_ASM +%%NO_ASM%%# define OPENSSL_NO_ASM +%%NO_ASM%%#endif #ifndef OPENSSL_NO_STATIC_ENGINE # define OPENSSL_NO_STATIC_ENGINE #endif @@ -80,8 +83,8 @@ extern "C" { # endif #endif -#define OPENSSL_CPUID_OBJ - +%%ASM%%#define OPENSSL_CPUID_OBJ +%%ASM%% /* crypto/opensslconf.h.in */ /* Generate 80386 code? */ diff --git a/secure/lib/libssh/Makefile b/secure/lib/libssh/Makefile index 92ba2bd..9ee878e 100644 --- a/secure/lib/libssh/Makefile +++ b/secure/lib/libssh/Makefile @@ -47,7 +47,7 @@ USEPRIVATELIB+= ldns CFLAGS+= -I${SSHDIR} -include ssh_namespace.h SRCS+= ssh_namespace.h -.if ${MK_KERBEROS_SUPPORT} != "no" +.if ${MK_GSSAPI} != "no" && ${MK_KERBEROS_SUPPORT} != "no" CFLAGS+= -include krb5_config.h SRCS+= krb5_config.h DPADD+= ${LIBGSSAPI} ${LIBKRB5} ${LIBHX509} ${LIBASN1} ${LIBCOM_ERR} ${LIBMD} ${LIBROKEN} diff --git a/secure/usr.bin/ssh/Makefile b/secure/usr.bin/ssh/Makefile index 24f02b3..99ade34 100644 --- a/secure/usr.bin/ssh/Makefile +++ b/secure/usr.bin/ssh/Makefile @@ -27,7 +27,7 @@ LDADD+= -lldns USEPRIVATELIB+= ldns .endif -.if ${MK_KERBEROS_SUPPORT} != "no" +.if ${MK_GSSAPI} != "no" && ${MK_KERBEROS_SUPPORT} != "no" CFLAGS+= -include krb5_config.h SRCS+= krb5_config.h DPADD+= ${LIBGSSAPI} diff --git a/secure/usr.sbin/sshd/Makefile b/secure/usr.sbin/sshd/Makefile index 51a944a..ff82ebf 100644 --- a/secure/usr.sbin/sshd/Makefile +++ b/secure/usr.sbin/sshd/Makefile @@ -25,8 +25,8 @@ MAN= sshd.8 sshd_config.5 CFLAGS+=-I${SSHDIR} -include ssh_namespace.h SRCS+= ssh_namespace.h -DPADD= ${LIBSSH} ${LIBUTIL} ${LIBWRAP} ${LIBPAM} -LDADD= -lssh -lutil -lwrap ${MINUSLPAM} +DPADD= ${LIBSSH} ${LIBUTIL} ${LIBPAM} +LDADD= -lssh -lutil ${MINUSLPAM} USEPRIVATELIB= ssh .if ${MK_LDNS} != "no" @@ -42,7 +42,7 @@ DPADD+= ${LIBBSM} LDADD+= -lbsm .endif -.if ${MK_KERBEROS_SUPPORT} != "no" +.if ${MK_GSSAPI} != "no" && ${MK_KERBEROS_SUPPORT} != "no" CFLAGS+= -include krb5_config.h SRCS+= krb5_config.h DPADD+= ${LIBGSSAPI_KRB5} ${LIBGSSAPI} ${LIBKRB5} ${LIBHX509} ${LIBASN1} \ @@ -51,6 +51,12 @@ LDADD+= -lgssapi_krb5 -lgssapi -lkrb5 -lhx509 -lasn1 \ -lcom_err -lroken -lwind -lheimbase -lheimipcc .endif +.if ${MK_TCP_WRAPPERS} != "no" +CFLAGS+= -DLIBWRAP +DPADD+= ${LIBWRAP} +LDADD+= -lwrap +.endif + DPADD+= ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} LDADD+= -lcrypt -lcrypto -lz diff --git a/share/man/man4/alc.4 b/share/man/man4/alc.4 index b67e31d..1fff8ba 100644 --- a/share/man/man4/alc.4 +++ b/share/man/man4/alc.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 8, 2014 +.Dd August 22, 2016 .Dt ALC 4 .Os .Sh NAME @@ -122,6 +122,8 @@ Atheros AR8171 PCI Express Gigabit Ethernet controller Atheros AR8172 PCI Express Fast Ethernet controller .It Killer E2200 Gigabit Ethernet controller +.It +Killer E2400 Gigabit Ethernet controller .El .Sh LOADER TUNABLES Tunables can be set at the diff --git a/share/man/man4/sfxge.4 b/share/man/man4/sfxge.4 index 40f324c..9e80991 100644 --- a/share/man/man4/sfxge.4 +++ b/share/man/man4/sfxge.4 @@ -158,6 +158,16 @@ port will be the value of .Va hw.sfxge.mcdi_logging. The logging may also be enabled or disabled after the driver is loaded using the sysctl .Va dev.sfxge.%d.mcdi_logging. +.It Va hw.sfxge.stats_update_period_ms +Period in milliseconds to refresh interface statistics from hardware. +The accepted range is 0 to 65535, the default is 1000 (1 second). +Use zero value to disable periodic statistics update. +Supported on SFN8xxx series adapters with firmware v6.2.1.1033 and later and +SFN5xxx and SFN6xxx series adapters. +SFN7xxx series adapters and SFN8xxx series with earlier firmware use a +fixed 1000 milliseconds statistics update period. +The period may also be changed after the driver is loaded using the sysctl +.Va dev.sfxge.%d.stats_update_period_ms . .El .Sh SUPPORT For general information and support, diff --git a/share/man/man5/tmpfs.5 b/share/man/man5/tmpfs.5 index 78568d2..6f785de 100644 --- a/share/man/man5/tmpfs.5 +++ b/share/man/man5/tmpfs.5 @@ -1,7 +1,12 @@ .\"- .\" Copyright (c) 2007 Xin LI +.\" Copyright (c) 2017 The FreeBSD Foundation, Inc. .\" All rights reserved. .\" +.\" Part of this documentation was written by +.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship +.\" from the FreeBSD Foundation. +.\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: @@ -49,12 +54,12 @@ .\" .\" $FreeBSD$ .\" -.Dd April 23, 2012 +.Dd January 20, 2017 .Dt TMPFS 5 .Os .Sh NAME .Nm tmpfs -.Nd "efficient memory file system" +.Nd "in-memory file system" .Sh SYNOPSIS To compile this driver into the kernel, place the following line in your @@ -72,17 +77,40 @@ tmpfs_load="YES" .Sh DESCRIPTION The .Nm -driver will permit the -.Fx -kernel to access +driver implements an in-memory, or .Tn tmpfs -file systems. +file system. +The filesystem stores both file metadata and data in main memory. +This allows very fast and low latency accesses to the data. +The data is volatile. +An umount or system reboot invalidates it. +These properties make the filesystem's mounts suitable for fast +scratch storage, like +.Pa /tmp . +.Pp +If the system becomes low on memory and swap is configured (see +.Xr swapon 8 ), +the system can transfer file data to swap space, freeing memory +for other needs. +Metadata, including the directory content, is never swapped out by the +current implementation. +Keep this in mind when planning the mount limits, especially when expecting +to place many small files on a tmpfs mount. +.Pp +When +.Xr mmap 2 +is used on a file from a tmpfs mount, the swap VM object managing the +file pages is used to implement mapping and avoid double-copying of +the file data. +This quirk causes process inspection tools, like +.Xr procstat 1 , +to report anonymous memory mappings instead of file mappings. .Sh OPTIONS The following options are available when mounting .Nm file systems: -.Bl -tag -width indent +.Bl -tag -width "It Cm maxfilesize" .It Cm gid Specifies the group ID of the root inode of the file system. Defaults to the mount point's GID. @@ -92,6 +120,10 @@ Defaults to the mount point's UID. .It Cm mode Specifies the mode (in octal notation) of the root inode of the file system. Defaults to the mount point's mode. +.It Cm nonc +Do not use namecache to resolve names to files for the created mount. +This saves memory, but currently might impair scalability for highly +used mounts on large machines. .It Cm inodes Specifies the maximum number of nodes available to the file system. If not specified, the file system chooses a reasonable maximum based on @@ -114,11 +146,15 @@ memory file system: .Pp .Dl "mount -t tmpfs tmpfs /tmp" .Sh SEE ALSO +.Xr procstat 1 , .Xr nmount 2 , +.Xr mmap 2 , .Xr unmount 2 , .Xr fstab 5 , .Xr mdmfs 8 , -.Xr mount 8 +.Xr mount 8 , +.Xr swapinfo 8 , +.Xr swapon 8 .Sh HISTORY The .Nm @@ -130,7 +166,7 @@ The .Nm kernel implementation was written by .An Julio M. Merino Vidal Aq jmmv@NetBSD.org -as a Google SoC project. +as a Google Summer of Code project. .Pp .An Rohit Jalan and others ported it from @@ -140,5 +176,3 @@ to .Pp This manual page was written by .An Xin LI Aq delphij@FreeBSD.org . -.Sh BUGS -Some file system mount time options may not be well-supported. diff --git a/share/man/man9/ifnet.9 b/share/man/man9/ifnet.9 index 8cb436f7..43ab012 100644 --- a/share/man/man9/ifnet.9 +++ b/share/man/man9/ifnet.9 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 26, 2013 +.Dd July 11, 2016 .Dt IFNET 9 .Os .Sh NAME @@ -795,18 +795,6 @@ The interface will compute IP checksums. The interface will compute TCP checksums. .It Dv CSUM_UDP The interface will compute UDP checksums. -.It Dv CSUM_IP_FRAGS -The interface can compute a TCP or UDP checksum for a packet -fragmented by the host CPU. -Makes sense only along with -.Dv CSUM_TCP -or -.Dv CSUM_UDP . -.It Dv CSUM_FRAGMENT -The interface will do the fragmentation of IP packets if necessary. -The host CPU does not need to care about MTU on this interface -as long as a packet to transmit through it is an IP one and it -does not exceed the size of the hardware buffer. .El .Pp An interface notifies the TCP/IP module about the tasks diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree index c3a2d25..ff36c6f 100644 --- a/share/misc/bsd-family-tree +++ b/share/misc/bsd-family-tree @@ -258,6 +258,9 @@ FreeBSD 5.2 | | | | | | 8.3 | | | | | | | | | | | | NetBSD | | | | | | | | 5.1.3 | | + | | | | | | | | | + | | | | | | NetBSD | | + | | | | | | 5.1.4 | | | | | | | | OpenBSD 5.1 | | | | Mac OS X | `----. | | | | | 10.8 | \ | | @@ -268,14 +271,17 @@ FreeBSD 5.2 | | | | | | | | | | | | | | | | | | | | | NetBSD | | | | | | | | | 5.2.1 | | + | | | | | | | | | | + | | | | | | | NetBSD | | + | | | | | | | 5.2.2 | | | | | | | | | | | | | | | | | \ | | | | | | | | NetBSD | | | | | | | | 6.0.1 | | - | | | | | | | | | + | | | | | | | OpenBSD 5.3 DragonFly 3.4.1 | | | | | | NetBSD | | | | | | | | 6.0.2 | | - | | | | | | | OpenBSD 5.3 DragonFly 3.4.1 + | | | | | | | | | | | | | | | NetBSD | | | | | | | | 6.0.3 | | | | | | | | | | | @@ -296,25 +302,55 @@ FreeBSD 5.2 | | | | | \ | | | | | *--FreeBSD | | | NetBSD 6.1.3 | | | 10.0 | | | | | | - | | | | | | DragonFly 3.6.1 - | | | | | | | - | | | | | | | - | | | | | | DragonFly 3.6.2 - | | | | NetBSD 6.1.4 | | - | | | | | | - | | | | OpenBSD 5.5 | - | | | | | DragonFly 3.8.0 - | FreeBSD | | | | - | 9.3 | | | | - | | | | | - | | | | | - | | | | | - | | | | | - | | | | | - | | | | | + | | | | | | | DragonFly 3.6.1 + | | | | | | | | + | | | | | | | | + | | | | | | | DragonFly 3.6.2 + | | | | | NetBSD 6.1.4 | | + | | | | | | | | + | | | | | | OpenBSD 5.5 | + | | | | | | | | + | | | | | | | DragonFly 3.8.0 + | | | | | | | | + | | | | | | | | + | | | | | | | DragonFly 3.8.1 + | | | | | | | | + | | | | | | | | + | | | | | | | DragonFly 3.6.3 + | | | | | | | | + | | FreeBSD | | | | | + | | 9.3 | | | | | + | | | | NetBSD 6.1.5 | DragonFly 3.8.2 + | | Mac OS X | | | + | | 10.10 | | | + | | | | OpenBSD 5.6 | + | FreeBSD | | | | + | 10.1 | | | DragonFly 4.0.1 + | | | | | | + | | | | | DragonFly 4.0.2 + | | | | | | + | | | | | DragonFly 4.0.3 + | | | | | | + | | | | | DragonFly 4.0.4 + | | | | | | + | | | | | DragonFly 4.0.5 + | | | | | | + | | | | OpenBSD 5.7 | + | | | | | DragonFly 4.2.0 + | FreeBSD | | | | + | 10.2 | | | | + | | OS X NetBSD 7.0 | | + | | 10.11 | OpenBSD 5.8 | + | | | | | DragonFly 4.4.1 + | FreeBSD | | OpenBSD 5.9 | + | 10.3 | | | | + | | NetBSD 7.0.1 | | + | | | | DragonFly 4.6.0 + *--FreeBSD | | OpenBSD 6.0 | + | 11.0 | | | | | | | | | | | | | | -FreeBSD 11 -current | NetBSD -current OpenBSD -current DragonFly -current +FreeBSD 12 -current | NetBSD -current OpenBSD -current DragonFly -current | | | | | v v v v v @@ -632,15 +668,42 @@ Mac OS X 10.9 2013-10-22 [APL] OpenBSD 5.4 2013-11-01 [OBD] DragonFly 3.6.0 2013-11-25 [DFB] FreeBSD 10.0 2014-01-20 [FBD] -NetBSD 6.0.4 2014-01-27 [NBD] -NetBSD 6.1.3 2014-01-27 [NBD] +NetBSD 5.1.4 2014-01-25 [NBD] +NetBSD 5.2.2 2014-01-25 [NBD] +NetBSD 6.0.4 2014-01-25 [NBD] +NetBSD 6.1.3 2014-01-25 [NBD] DragonFly 3.6.1 2014-02-22 [DFB] DragonFly 3.6.2 2014-04-10 [DFB] -NetBSD 6.0.5 2014-04-19 [NDB] -NetBSD 6.1.4 2014-04-19 [NDB] +NetBSD 6.0.5 2014-04-12 [NDB] +NetBSD 6.1.4 2014-04-12 [NDB] OpenBSD 5.5 2014-05-01 [OBD] DragonFly 3.8.0 2014-06-04 [DFB] +DragonFly 3.8.1 2014-06-16 [DFB] +DragonFly 3.6.3 2014-06-17 [DFB] FreeBSD 9.3 2014-07-05 [FBD] +DragonFly 3.8.2 2014-08-08 [DFB] +NetBSD 6.1.5 2014-09-22 [NBD] +Mac OS X 10.10 2014-10-16 [APL] +OpenBSD 5.6 2014-11-01 [OBD] +FreeBSD 10.1 2014-11-14 [FBD] +DragonFly 4.0.1 2014-11-25 [DFB] +DragonFly 4.0.2 2015-01-07 [DFB] +DragonFly 4.0.3 2015-01-21 [DFB] +DragonFly 4.0.4 2015-03-09 [DFB] +DragonFly 4.0.5 2015-03-23 [DFB] +OpenBSD 5.7 2015-05-01 [OBD] +DragonFly 4.2.0 2015-06-29 [DFB] +FreeBSD 10.2 2015-08-13 [FBD] +NetBSD 7.0 2015-09-25 [NBD] +OS X 10.11 2015-09-30 [APL] +OpenBSD 5.8 2015-10-18 [OBD] +DragonFly 4.4.1 2015-12-07 [DFB] +OpenBSD 5.9 2016-03-29 [OBD] +FreeBSD 10.3 2016-04-04 [FBD] +NetBSD 7.0.1 2016-05-22 [NBD] +DragonFly 4.6.0 2016-08-02 [DFB] +OpenBSD 6.0 2016-09-01 [OBD] +FreeBSD 11.0 2016-10-10 [FBD] Bibliography ------------------------ @@ -660,6 +723,10 @@ McKusick, Marshall Kirk, George Neville-Neil. The Design and Implementation of the FreeBSD Operating System. Addison-Wesley Professional, Published: Aug 2, 2004. ISBN 0-201-70245-2 +McKusick, Marshall Kirk, George Neville-Neil, Robert Watson. The +Design and Implementation of the FreeBSD Operating System, 2nd Edition. +Pearson Education, Inc., 2014. ISBN 0-321-96897-2 + Doug McIlroy. Research Unix Reader. Michael G. Brown. The Role of BSD in the Development of Unix. diff --git a/share/misc/pci_vendors b/share/misc/pci_vendors index 6254a60..7ffc6df 100644 --- a/share/misc/pci_vendors +++ b/share/misc/pci_vendors @@ -3,8 +3,8 @@ # # List of PCI ID's # -# Version: 2016.11.21 -# Date: 2016-11-21 03:15:01 +# Version: 2017.01.08 +# Date: 2017-01-08 03:15:02 # # Maintained by Albert Pool, Martin Mares, and other volunteers from # the PCI ID Project at http://pci-ids.ucw.cz/. @@ -249,6 +249,7 @@ 0014 MegaRAID Tri-Mode SAS3516 1028 1fd4 PERC H745P MX 1d49 0602 ThinkSystem RAID 930-16i 4GB Flash PCIe 12Gb Adapter + 0015 MegaRAID Tri-Mode SAS3416 0016 MegaRAID Tri-Mode SAS3508 1028 1fc9 PERC H840 Adapter 1028 1fcb PERC H740P Adapter @@ -548,6 +549,7 @@ 1028 1f53 HBA330 Mini 1028 1fd2 HBA330 MX 1028 1fd3 HBA330 MMZ + 1bd4 0011 Inspur 12Gb 8i-3008 IT SAS HBA 00ab SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC) 00ac SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) 1d49 0201 ThinkSystem 430-16i SAS/SATA 12Gb HBA @@ -2201,6 +2203,11 @@ 67b9 Vesuvius [Radeon R9 295X2] 67be Hawaii LE 67c0 Ellesmere [Polaris10] + 67c4 Ellesmere [Radeon Pro WX 7100] + 67c7 Ellesmere [Radeon Pro WX 5100] + 67ca Ellesmere [Polaris10] + 67cc Ellesmere [Polaris10] + 67cf Ellesmere [Polaris10] 67df Ellesmere [Radeon RX 470/480] 1002 0b37 Radeon RX 480 1043 04a8 Radeon RX 480 @@ -2218,6 +2225,7 @@ 1787 a480 Radeon RX 480 67e0 Baffin [Polaris11] 67e1 Baffin [Polaris11] + 67e3 Baffin [Radeon Pro WX 4100] 67e8 Baffin [Polaris11] 67e9 Baffin [Polaris11] 67eb Baffin [Polaris11] @@ -2924,6 +2932,12 @@ 148c 9380 Radeon R9 380 # Make naming scheme consistent 174b e308 Radeon R9 380 Nitro 4G D5 + 6980 Polaris12 + 6981 Polaris12 + 6985 Polaris12 + 6986 Polaris12 + 6987 Polaris12 + 699f Polaris12 700f RS100 AGP Bridge 7010 RS200/RS250 AGP Bridge 7100 R520 [Radeon X1800 XT] @@ -5095,6 +5109,7 @@ 0675 1704 ISDN Adapter (PCI Bus, D, C) 0675 1707 ISDN Adapter (PCI Bus, DV, W) 10cf 105e ISDN Adapter (PCI Bus, DV, W) + 13a0 Transformer Book T101HA-GR030R # Should be 1022:9602 9602 AMD RS780/RS880 PCI to PCI bridge (int gfx) 1043 83a2 M4A785TD Motherboard @@ -10077,6 +10092,7 @@ 10c3 GT218 [GeForce 8400 GS Rev. 3] 10c5 GT218 [GeForce 405] 10d8 GT218 [NVS 300] + 10ef GP102 HDMI Audio Controller 10f0 GP104 High Definition Audio Controller 1140 GF117M [GeForce 610M/710M/810M/820M / GT 620M/625M/630M/720M] 1019 0799 GeForce 820M @@ -10620,7 +10636,7 @@ 13f1 GM204GL [Quadro M4000] 13f2 GM204GL [Tesla M60] 13f3 GM204GL [Tesla M6] - 13f8 GM204GLM [Quadro M5000M] + 13f8 GM204GLM [Quadro M5000M / M5000 SE] 13f9 GM204GLM [Quadro M4000M] 13fa GM204GLM [Quadro M3000M] 10de 11c9 Quadro M3000 SE @@ -10634,8 +10650,9 @@ 1431 GM206GL [Tesla M4] 15f0 GP100GL 15f1 GP100GL - 15f8 GP100GL - 15f9 GP100GL + 15f7 GP100GL [Tesla P100 PCIe 12GB] + 15f8 GP100GL [Tesla P100 PCIe 16GB] + 15f9 GP100GL [Tesla P100 SMX2 16GB] 1617 GM204M [GeForce GTX 980M] 1618 GM204M [GeForce GTX 970M] 1619 GM204M [GeForce GTX 965M] @@ -10659,10 +10676,12 @@ 1b81 GP104 [GeForce GTX 1070] 1b82 GP104 1b83 GP104 + 1b84 GP104 [GeForce GTX 1060 3GB] 1ba0 GP104M [GeForce GTX 1080] 1ba1 GP104M [GeForce GTX 1070] 1bb0 GP104GL [Quadro P5000] 1bb1 GP104GL + 1bb3 GP104GL [Tesla P4] 1bb4 GP104GL 1be0 GP104M [GeForce GTX 1080] 1be1 GP104M [GeForce GTX 1070] @@ -10678,6 +10697,9 @@ 1c80 GP107 1c81 GP107 [GeForce GTX 1050] 1c82 GP107 [GeForce GTX 1050 Ti] + 1c8c GP107M [GeForce GTX 1050 Ti] + 1c8d GP107M [GeForce GTX 1050] + 1c8e GP107M 1ca7 GP107GL 1ca8 GP107GL 1caa GP107GL @@ -12103,7 +12125,11 @@ 111f Precision Digital Images 4a47 Precision MX Video engine interface 5243 Frame capture bus interface -1120 EMC Corporation +# formerly EMC Corporation +1120 Dell EMC + 2306 Unity Fibre Channel Controller + 2501 Unity Ethernet Controller + 2505 Unity Fibre Channel Controller 1121 Zilog 1122 Multi-tech Systems, Inc. 1123 Excellent Design, Inc. @@ -15975,7 +16001,7 @@ 5081 T540-5081 Unified Wire Ethernet Controller 5082 T504-5082 Unified Wire Ethernet Controller 5083 T540-5083 Unified Wire Ethernet Controller - 5084 T580-5084 Unified Wire Ethernet Controller + 5084 T540-5084 Unified Wire Ethernet Controller 5085 T580-5085 Unified Wire Ethernet Controller 5086 T580-5086 Unified Wire Ethernet Controller 5087 T580-5087 Unified Wire Ethernet Controller @@ -15994,6 +16020,7 @@ 509a T520-509A Unified Wire Ethernet Controller 509b T540-509B Unified Wire Ethernet Controller 509c T520-509C Unified Wire Ethernet Controller + 509d T540-509D Unified Wire Ethernet Controller 5401 T520-CR Unified Wire Ethernet Controller 5402 T522-CR Unified Wire Ethernet Controller 5403 T540-CR Unified Wire Ethernet Controller @@ -16041,6 +16068,7 @@ 549a T520-509A Unified Wire Ethernet Controller 549b T540-509B Unified Wire Ethernet Controller 549c T520-509C Unified Wire Ethernet Controller + 549d T540-509D Unified Wire Ethernet Controller 5501 T520-CR Unified Wire Storage Controller 5502 T522-CR Unified Wire Storage Controller 5503 T540-CR Unified Wire Storage Controller @@ -16088,6 +16116,7 @@ 559a T520-509A Unified Wire Storage Controller 559b T540-509B Unified Wire Storage Controller 559c T520-509C Unified Wire Storage Controller + 559d T540-509D Unified Wire Storage Controller 5601 T520-CR Unified Wire Storage Controller 5602 T522-CR Unified Wire Storage Controller 5603 T540-CR Unified Wire Storage Controller @@ -16135,6 +16164,7 @@ 569a T520-509A Unified Wire Storage Controller 569b T540-509B Unified Wire Storage Controller 569c T520-509C Unified Wire Storage Controller + 569d T540-509D Unified Wire Storage Controller 5701 T520-CR Unified Wire Ethernet Controller 5702 T522-CR Unified Wire Ethernet Controller 5703 T540-CR Unified Wire Ethernet Controller @@ -16221,6 +16251,7 @@ 589a T520-509A Unified Wire Ethernet Controller [VF] 589b T540-509B Unified Wire Ethernet Controller [VF] 589c T520-509C Unified Wire Ethernet Controller [VF] + 589d T540-509D Unified Wire Ethernet Controller [VF] 6001 T6225-CR Unified Wire Ethernet Controller 6002 T6225-SO-CR Unified Wire Ethernet Controller 6003 T6425-CR Unified Wire Ethernet Controller @@ -16357,7 +16388,8 @@ 144d Samsung Electronics Co Ltd 1600 Apple PCIe SSD a800 XP941 PCIe SSD - a802 NVMe SSD Controller + a802 NVMe SSD Controller SM951/PM951 + a804 NVMe SSD Controller SM961/PM961 a820 NVMe SSD Controller 171X 1028 1f95 Express Flash NVMe XS1715 SSD 400GB 1028 1f96 Express Flash NVMe XS1715 SSD 800GB @@ -17968,11 +18000,13 @@ 15b3 Mellanox Technologies 0191 MT25408 [ConnectX IB Flash Recovery] 01f6 MT27500 Family [ConnectX-3 Flash Recovery] + 01f8 MT27520 Family [ConnectX-3 Pro Flash Recovery] 01ff MT27600 Family [Connect-IB Flash Recovery] 0209 MT27700 Family [ConnectX-4 Flash Recovery] 020b MT27710 Family [ConnectX-4 Lx Flash Recovery] 020d MT28800 Family [ConnectX-5 Flash Recovery] 020f MT28908A0 Family [ConnectX-6 Flash Recovery] + 0211 MT416842 Family [BlueField SoC Flash Recovery] # reserved for RM#105916 024e MT53100 [Spectrum-2, Flash recovery mode] # Actual value to be used @@ -18732,6 +18766,7 @@ 7013 AP440-3: 32-Channel Isolated Digital Input Module 7014 AP445: 32-Channel Isolated Digital Output Module 7016 AP470 48-Channel TTL Level Digital Input/Output Module + 7017 AP323 16-bit, 20 or 40 Channel Analog Input Module 7018 AP408: 32-Channel Digital I/O Module 701a AP220-16 12-Bit, 16-Channel Analog Output Module 701b AP231-16 16-Bit, 16-Channel Analog Output Module @@ -18992,6 +19027,7 @@ 1160 ARC-1160 16-Port PCI-X to SATA RAID Controller 1170 ARC-1170 24-Port PCI-X to SATA RAID Controller 1201 ARC-1200 2-Port PCI-Express to SATA II RAID Controller + 1203 ARC-1203 2/4/8 Port PCIe 2.0 to SATA 6Gb RAID Controller 1210 ARC-1210 4-Port PCI-Express to SATA RAID Controller 1214 ARC-12x4 PCIe 2.0 to SAS/SATA 6Gb RAID Controller 17d3 1214 ARC-1214 4-Port PCIe 2.0 to SAS/SATA 6Gb RAID Controller @@ -19510,7 +19546,7 @@ 1924 5105 SFN4111T-R5 1924 5201 SFN4112F-R1 1924 5202 SFN4112F-R2 - 0803 SFC9020 [Solarstorm] + 0803 SFC9020 10G Ethernet Controller 1014 0478 2-port 10GbE Low-Latency (R7) 1014 0479 2-port 10GbE OpenOnload (R7) 1014 04a7 Solarflare 10Gb Low-latency Dual-port HBA (R7) @@ -19540,7 +19576,7 @@ 1924 7207 SFN5162F-R7 SFP+ Server Adapter 1924 7a06 SFN5152F-R6 SFP+ Server Adapter 1924 7a07 SFN5152F-R7 SFP+ Server Adapter - 0813 SFL9021 [Solarstorm] + 0813 SFL9021 10GBASE-T Ethernet Controller 1924 6100 SFN5121T-R0 10GBASE-T Server Adapter 1924 6102 SFN5121T-R2 10GBASE-T Server Adapter 1924 6103 SFN5121T-R3 10GBASE-T Server Adapter @@ -19549,7 +19585,7 @@ 1924 6904 SFN5111T-R4 10GBASE-T Server Adapter 1924 7104 SFN5161T-R4 10GBASE-T Server Adapter 1924 7904 SFN5151T-R4 10GBASE-T Server Adapter - 0903 SFC9120 + 0903 SFC9120 10G Ethernet Controller 1014 04cc SFN7122F-R2 2x10GbE SFP+ Flareon Ultra 1924 8002 SFN7122F-R1 SFP+ Server Adapter 1924 8003 SFN7x41Q-R1 Flareon Ultra 7000 Series 10/40G Adapter @@ -19561,11 +19597,11 @@ 1924 800d SFN7x02F-R3 Flareon 7000 Series 10G Adapter 1924 8010 SFA7942Q-R1 QSFP+ AOE Adapter 1924 8015 SFA7942Q-A5-0-R1 QSFP+ AOE Adapter - 0923 SFC9140 + 0923 SFC9140 10/40G Ethernet Controller 1924 800b SFN7x42Q-R1 Flareon Ultra 7000 Series 10/40G Adapter 1924 800e SFN7x42Q-R2 Flareon Ultra 7000 Series 10/40G Adapter 1924 800f SFN7xx4F-R1 Flareon Ultra 7000 Series 10G Adapter - 0a03 SFC9220 + 0a03 SFC9220 10/40G Ethernet Controller 1924 8011 SFN 8022-R1 Solarflare Flareon 8000 Series 10G Adapter 1924 8012 SFN8522-R1 Flareon Ultra 8000 Series 10G Adapter 1924 8013 SFN8042-R1 Solarflare Flareon 8000 Series 10/40G Adapter @@ -19574,10 +19610,11 @@ 1924 8017 SFN8522-R2 Flareon Ultra 8000 Series 10G Adapter 1924 8018 SFN8042-R2 Flareon 8000 Series 10/40G Adapter 1924 8019 SFN8542-R2 Flareon Ultra 8000 Series 10/40G Adapter - 1803 SFC9020 Virtual Function [Solarstorm] - 1813 SFL9021 Virtual Function [Solarstorm] - 1903 SFC9120 Virtual Function - 1923 SFC9140 Virtual Function + 1803 SFC9020 10G Ethernet Controller (Virtual Function) + 1813 SFL9021 10GBASE-T Ethernet Controller (Virtual Function) + 1903 SFC9120 10G Ethernet Controller (Virtual Function) + 1923 SFC9140 10/40G Ethernet Controller (Virtual Function) + 1a03 SFC9220 10/40G Ethernet Controller (Virtual Function) 6703 SFC4000 rev A iSCSI/Onload [Solarstorm] 10b8 0102 SMC10GPCIe-10BT (A2) [TigerCard] 10b8 0103 SMC10GPCIe-10BT (A3) [TigerCard] @@ -19864,6 +19901,7 @@ 5801 DDRdrive X1 5808 DDRdrive X8 dd52 DDRdrive X1-30 +19e5 Huawei Technologies Co., Ltd. 19e7 NET (Network Equipment Technologies) 1001 STIX DSP Card 1002 STIX - 1 Port T1/E1 Card @@ -20303,6 +20341,8 @@ 0303 Simulyzer-RT CompactPCI Serial PSI5-SIM-1 card 0304 Simulyzer-RT CompactPCI Serial PWR-ANA-1 card 0305 Simulyzer-RT CompactPCI Serial CAN-1 card +1cd7 Nanjing Magewell Electronics Co., Ltd. + 0010 Pro Capture Endpoint 1cdd secunet Security Networks AG 1ce4 Exablaze 0001 ExaNIC X4 @@ -20310,6 +20350,7 @@ 0003 ExaNIC X10 0004 ExaNIC X10-GM 0005 ExaNIC X40 + 0006 ExaNIC X10-HPT 1cf7 Subspace Dynamics 1d00 Pure Storage 1d1d CNEX Labs @@ -21336,6 +21377,27 @@ 0813 Moorestown SC DMA 0814 Moorestown LPE DMA 0815 Moorestown SSP0 + 0817 Medfield Serial IO I2C Controller #3 + 0818 Medfield Serial IO I2C Controller #4 + 0819 Medfield Serial IO I2C Controller #5 + 081a Medfield GPIO Controller [Core] + 081b Medfield Serial IO HSUART Controller #1 + 081c Medfield Serial IO HSUART Controller #2 + 081d Medfield Serial IO HSUART Controller #3 + 081e Medfield Serial IO HSUART DMA Controller + 081f Medfield GPIO Controller [AON] + 0820 Medfield SD Host Controller + 0821 Medfield SDIO Controller #1 + 0822 Medfield SDIO Controller #2 + 0823 Medfield eMMC Controller #0 + 0824 Medfield eMMC Controller #1 + 0827 Medfield Serial IO DMA Controller + 0828 Medfield Power Management Unit + 0829 Medfield USB Device Controller (OTG) + 082a Medfield SCU IPC + 082c Medfield Serial IO I2C Controller #0 + 082d Medfield Serial IO I2C Controller #1 + 082e Medfield Serial IO I2C Controller #2 0885 Centrino Wireless-N + WiMAX 6150 8086 1305 Centrino Wireless-N + WiMAX 6150 BGN 8086 1307 Centrino Wireless-N + WiMAX 6150 BG @@ -22445,6 +22507,18 @@ 1161 82806AA PCI64 Hub Advanced Programmable Interrupt Controller 8086 1161 82806AA PCI64 Hub APIC 1162 Xscale 80200 Big Endian Companion Chip + 1190 Merrifield SD/SDIO/eMMC Controller + 1191 Merrifield Serial IO HSUART Controller + 1192 Merrifield Serial IO HSUART DMA Controller + 1194 Merrifield Serial IO SPI Controller + 1195 Merrifield Serial IO I2C Controller + 1196 Merrifield Serial IO I2C Controller + 1199 Merrifield GPIO Controller + 119e Merrifield USB Device Controller (OTG) + 11a0 Merrifield SCU IPC + 11a1 Merrifield Power Management Unit + 11a2 Merrifield Serial IO DMA Controller + 11a5 Merrifield Serial IO PWM Controller 1200 IXP1200 Network Processor 172a 0000 AEP SSL Accelerator 1209 8255xER/82551IT Fast Ethernet Controller @@ -22917,8 +22991,8 @@ 103c 0000 HPE Ethernet 10/20Gb 2-port 660FLB Adapter 103c 22fe HPE Ethernet 10/20Gb 2-port 660FLB Adapter 1588 Ethernet Controller XL710 for 20GbE backplane - 103c 0000 HPE Ethernet 10/20Gb 2-port 660M Adapter - 103c 22ff HPE Ethernet 10/20Gb 2-port 660M Adapter + 103c 0000 Ethernet 10/20Gb 2-port 660M Adapter + 103c 22ff Ethernet 10/20Gb 2-port 660M Adapter 1589 Ethernet Controller X710/X557-AT 10GBASE-T 108e 0000 Quad Port 10GBase-T Adapter 108e 7b1c Quad Port 10GBase-T Adapter @@ -22951,12 +23025,17 @@ 15ac Ethernet Connection X552 10 GbE SFP+ 15ad Ethernet Connection X552/X557-AT 10GBASE-T 15ae Ethernet Connection X552 1000BASE-T + 15b0 Ethernet Connection X552 Backplane 15b4 X553 Virtual Function 15b5 DSL6340 USB 3.1 Controller [Alpine Ridge] 15b6 DSL6540 USB 3.1 Controller [Alpine Ridge] 15b7 Ethernet Connection (2) I219-LM 15b8 Ethernet Connection (2) I219-V 15b9 Ethernet Connection (3) I219-LM + 15bb Ethernet Connection (7) I219-LM + 15bc Ethernet Connection (7) I219-V + 15bd Ethernet Connection (6) I219-LM + 15be Ethernet Connection (6) I219-V 15bf JHL6240 Thunderbolt 3 NHI (Low Power) [Alpine Ridge LP 2016] 15c0 JHL6240 Thunderbolt 3 Bridge (Low Power) [Alpine Ridge LP 2016] 15c5 X553 Virtual Function @@ -24258,6 +24337,9 @@ 24f4 Wireless 8260 # Snow Field Peak AC 8086 0030 Dual Band Wireless-AC 8260 + 24fd Wireless 8265 / 8275 +# Windstorm Peak + 8086 0010 Dual Band Wireless-AC 8265 2500 82820 820 (Camino) Chipset Host Bridge (MCH) 1028 0095 Precision Workstation 220 Chipset 1043 801c P3C-2000 system chipset @@ -25145,12 +25227,12 @@ 1028 01da OptiPlex 745 1462 7235 P965 Neo MS-7235 mainboard 2826 C600/X79 series chipset SATA RAID Controller - 1d49 0100 ThinkSystem RAID 331 - 1d49 0101 ThinkSystem RAID 331 - 1d49 0102 ThinkSystem RAID 331 - 1d49 0103 ThinkSystem RAID 331 - 1d49 0104 ThinkSystem RAID 331 - 1d49 0105 ThinkSystem RAID 331 + 1d49 0100 Intel RSTe SATA Software RAID + 1d49 0101 Intel RSTe SATA Software RAID + 1d49 0102 Intel RSTe SATA Software RAID + 1d49 0103 Intel RSTe SATA Software RAID + 1d49 0104 Intel RSTe SATA Software RAID + 1d49 0105 Intel RSTe SATA Software RAID 2827 C610/X99 series chipset sSATA Controller [RAID mode] 2828 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] 1028 01f3 Inspiron 1420 @@ -26950,41 +27032,41 @@ 530d 80310 (IOP) IO Processor 5845 QEMU NVM Express Controller 1af4 1100 QEMU Virtual Machine - 5a84 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Integrated Graphics Controller - 5a88 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Imaging Unit - 5a98 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Audio Cluster - 5a9a Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Trusted Execution Engine - 5aa2 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Integrated Sensor Hub - 5aa8 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series USB xHCI - 5aac Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #1 - 5aae Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #2 - 5ab0 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #3 - 5ab2 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #4 - 5ab4 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #5 - 5ab6 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #6 - 5ab8 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #7 - 5aba Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series I2C Controller #8 - 5abc Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series HSUART Controller #1 - 5abe Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series HSUART Controller #2 - 5ac0 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series HSUART Controller #3 - 5ac2 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SPI Controller #1 - 5ac4 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SPI Controller #2 - 5ac6 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SPI Controller #3 - 5ac8 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PWM Pin Controller - 5aca Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SDXC/MMC Host Controller - 5acc Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series eMMC Controller - 5ad0 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SDIO Controller - 5ad4 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SMBus Controller - 5ad6 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port B #1 - 5ad7 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port B #2 - 5ad8 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port A #1 - 5ad9 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port A #2 - 5ada Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port A #3 - 5adb Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series PCI Express Port A #4 - 5ae3 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series SATA AHCI Controller - 5ae8 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Low Pin Count Interface - 5aee Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series HSUART Controller #4 - 5af0 Atom/Celeron/Pentium Processor N4200/N3350/E3900 Series Host Bridge + 5a84 Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Graphics Controller + 5a88 Celeron N3350/Pentium N4200/Atom E3900 Series Imaging Unit + 5a98 Celeron N3350/Pentium N4200/Atom E3900 Series Audio Cluster + 5a9a Celeron N3350/Pentium N4200/Atom E3900 Series Trusted Execution Engine + 5aa2 Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Sensor Hub + 5aa8 Celeron N3350/Pentium N4200/Atom E3900 Series USB xHCI + 5aac Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #1 + 5aae Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #2 + 5ab0 Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #3 + 5ab2 Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #4 + 5ab4 Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #5 + 5ab6 Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #6 + 5ab8 Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #7 + 5aba Celeron N3350/Pentium N4200/Atom E3900 Series I2C Controller #8 + 5abc Celeron N3350/Pentium N4200/Atom E3900 Series HSUART Controller #1 + 5abe Celeron N3350/Pentium N4200/Atom E3900 Series HSUART Controller #2 + 5ac0 Celeron N3350/Pentium N4200/Atom E3900 Series HSUART Controller #3 + 5ac2 Celeron N3350/Pentium N4200/Atom E3900 Series SPI Controller #1 + 5ac4 Celeron N3350/Pentium N4200/Atom E3900 Series SPI Controller #2 + 5ac6 Celeron N3350/Pentium N4200/Atom E3900 Series SPI Controller #3 + 5ac8 Celeron N3350/Pentium N4200/Atom E3900 Series PWM Pin Controller + 5aca Celeron N3350/Pentium N4200/Atom E3900 Series SDXC/MMC Host Controller + 5acc Celeron N3350/Pentium N4200/Atom E3900 Series eMMC Controller + 5ad0 Celeron N3350/Pentium N4200/Atom E3900 Series SDIO Controller + 5ad4 Celeron N3350/Pentium N4200/Atom E3900 Series SMBus Controller + 5ad6 Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port B #1 + 5ad7 Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port B #2 + 5ad8 Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #1 + 5ad9 Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #2 + 5ada Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #3 + 5adb Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port A #4 + 5ae3 Celeron N3350/Pentium N4200/Atom E3900 Series SATA AHCI Controller + 5ae8 Celeron N3350/Pentium N4200/Atom E3900 Series Low Pin Count Interface + 5aee Celeron N3350/Pentium N4200/Atom E3900 Series HSUART Controller #4 + 5af0 Celeron N3350/Pentium N4200/Atom E3900 Series Host Bridge 65c0 5100 Chipset Memory Controller Hub 65e2 5100 Chipset PCI Express x4 Port 2 65e3 5100 Chipset PCI Express x4 Port 3 @@ -27826,6 +27908,25 @@ a243 Lewisburg LPC or eSPI Controller a252 Lewisburg SSATA Controller [AHCI mode] a256 Lewisburg SSATA Controller [RAID mode] + a282 200 Series PCH SATA controller [AHCI mode] + a294 200 Series PCH PCI Express Root Port #1 + a2a1 200 Series PCH PMC + a2a3 200 Series PCH SMBus Controller + a2a7 200 Series PCH Serial IO UART Controller #0 + a2a8 200 Series PCH Serial IO UART Controller #1 + a2a9 200 Series PCH Serial IO SPI Controller #0 + a2aa 200 Series PCH Serial IO SPI Controller #1 + a2af 200 Series PCH USB 3.0 xHCI Controller + a2b1 200 Series PCH Thermal Subsystem + a2ba 200 Series PCH CSME HECI #1 + a2bb 200 Series PCH CSME HECI #2 + a2c6 200 Series PCH LPC Controller + a2e0 200 Series PCH Serial IO I2C Controller #0 + a2e1 200 Series PCH Serial IO I2C Controller #1 + a2e2 200 Series PCH Serial IO I2C Controller #2 + a2e3 200 Series PCH Serial IO I2C Controller #3 + a2e6 200 Series PCH Serial IO UART Controller #2 + a2f0 200 Series PCH HD Audio a620 6400/6402 Advanced Memory Buffer (AMB) abc0 Omni-Path Fabric Switch Silicon 100 Series b152 21152 PCI-to-PCI Bridge @@ -28605,6 +28706,7 @@ f1d0 AJA Video cafe Kona SD cfee Xena LS/SD-22-DA/SD-DA daff KONA LHi + db09 Corvid 24 dcaf Kona HD dfee Xena HD-DA efac Xena SD-MM/SD-22-MM diff --git a/share/misc/scsi_modes b/share/misc/scsi_modes index 80752e7..f51721a 100644 --- a/share/misc/scsi_modes +++ b/share/misc/scsi_modes @@ -49,7 +49,11 @@ # ALL DEVICE TYPES -0x0a "Control Mode Page" { +0x0a,0x03 "Command Duration Limit A"; + +0x0a,0x04 "Command Duration Limit B"; + +0x0a "Control" { {TST} t3 {TMF_ONLY} t1 {DPICZ} t1 @@ -71,14 +75,25 @@ {TAS} t1 {ATMPE} t1 {RWWP} t1 - {Reserved} *t1 + {SBLP (Supported Block Lengths and Protection)} t1 {Autoload Mode} t3 {Ready AEN Holdoff Period} i2 {Busy Timeout Period} i2 {Extended Self-Test Completion Time} i2 } -0x02 "Disconnect-Reconnect Page" { +0x0a,0x01 "Control Extension" { + {Reserved} *t4 + {DLC} t1 + {TCMOS} t1 + {SCSIP} t1 + {IALUAE} t1 + {Reserved} *t4 + {Initial Command Priority} t4 + {Maximum Sense Data Length} i1 +} + +0x02 "Disconnect-Reconnect" { {Buffer Full Ratio} i1 {Buffer Empty Ratio} i1 {Bus Inactivity Limit} i2 @@ -92,26 +107,11 @@ {Reserved} *i1 } -0x15 "Extended Page"; - -0x16 "Extended Device-Type Specific Page"; +0x15 "Extended"; -0x1c "Informational Exceptions Control Page" { - {PERF} t1 - {Reserved} *t1 - {EBF} t1 - {EWasc} t1 - {DExcpt} t1 - {TEST} t1 - {EBACKERR} t1 - {LogErr} t1 - {Reserved} *t4 - {MRIE} t4 - {Interval Timer} i4 - {Report Count} i4 -} +0x16 "Extended Device-Type Specific"; -0x09 "Peripheral Device Page" { +0x09 "Peripheral Device" { {Interface Identifier} i2 {Reserved} *i1 {Reserved} *i1 @@ -119,21 +119,69 @@ {Reserved} *i1 } -0x1a "Power Condition Page" { - {Reserved} *i1 +0x1a "Power Condition" { + {PM_BG_PRECEDENCE} t1 {Reserved} *t6 - {Idle} t1 - {Standby} t1 - {Idle Condition Timer} i4 - {Standby Condition Timer} i4 + {STANDBY_Y} t1 + {Reserved} *t4 + {IDLE_C} t1 + {IDLE_B} t1 + {IDLE_A} t1 + {STANDBY_Z} t1 + {IDLE_A Condition Timer} i4 + {STANDBY_Z Condition Timer} i4 + {IDLE_B Condition Timer} i4 + {IDLE_C Condition Timer} i4 + {STANDBY_Y Condition Timer} i4 + {Reserved} *i4 + {Reserved} *i4 + {Reserved} *i4 + {Reserved} *i3 + {CCF Idle} t2 + {CCF Standby} t2 + {CCF Stopped} t2 + {Reserved} *t2 } -0x18 "Protocol-Specific LUN Page"; +0x1a,0x01 "Power Consumption" { + {Reserved} *i2 + {Reserved} *t6 + {Active Level} t2 + {Power Consumption Identifier} i1 + {Reserved} *i4 + {Reserved} *i4 +} -0x19 "Protocol-Specific Port Page"; +0x18 "Protocol-Specific Logical Unit"; + +0x19 "Protocol-Specific Port"; # DIRECT ACCESS DEVICES -0x08 "Caching Page" { + +0x0a,0x02 "Application Tag"; + +0x1a,0xf1 "ATA Power Condition"; + +0x1c,0x01 "Background Control" { + {Reserved} *t5 + {S_L_FULL} *t1 + {LOWIR} *t1 + {EN_BMS} *t1 + {Reserved} *t7 + {EN_PS} *t1 + {Background Medium Scan Interval Time} i2 + {Background Pre-Scan Time Limit} i2 + {Minimum Idle Time Before Background Scan} i2 + {Maximum Time To Suspend Background Scan} i2 + {Reserved} *i2 +} + +0x0a,0x06 "Background Operation Control" { + {BO_MODE} t2 + {Reserved} *t6 +} + +0x08 "Caching" { {IC} t1 {ABPF} t1 {CAP} t1 @@ -148,9 +196,18 @@ {Minimum Pre-fetch} i2 {Maximum Pre-fetch} i2 {Maximum Pre-fetch Ceiling} i2 + {FSW (Force Sequential Write)} t1 + {LBCSS (Logical Block Cache Segment Size)} t1 + {DRA (Disable Read-Ahead)} t1 + {Vendor Specific} t2 + {SYNC_PROG} t1 + {NV_DIS} t1 + {Number of Cache Segments} i1 + {Cache Segment Size} i2 + {Reserved} *t4 } -0x05 "Flexible Disk Page" { +0x05 "Flexible Disk" { {Transfer rate} i2 {Number of heads} i1 {Sectors per track} i1 @@ -181,7 +238,7 @@ {Reserved} *i1 } -0x03 "Format Device Page" { +0x03 "Format Device" { {Tracks per Zone} i2 {Alternate Sectors per Zone} i2 {Alternate Tracks per Zone} i2 @@ -198,7 +255,34 @@ {Reserved} *t4 } -0x0b "Medium Types Supported Page" { +0x0a,0x05 "I/O Advice Hints Grouping"; + +0x1c "Informational Exceptions Control" { + {PERF} t1 + {Reserved} *t1 + {EBF} t1 + {EWasc} t1 + {DExcpt} t1 + {TEST} t1 + {EBACKERR} t1 + {LogErr} t1 + {Reserved} *t4 + {MRIE} t4 + {Interval Timer} i4 + {Report Count} i4 +} + +0x1c,0x02 "Logical Block Provisioning" { + {Reserved} *t7 + {SITUA} t1 + {Reserved} *i1 + {Reserved} *i1 + {Reserved} *i1 + {Reserved} *i4 + {Reserved} *i4 +} + +0x0b "Medium Types Supported" { {Reserved} *i1 {Reserved} *i1 {Medium type one supported} i1 @@ -207,10 +291,11 @@ {Medium type four supported} i1 } -# Notch page (0x0c) -0x0c "Notch and Partition Page"; +0x0c "Notch and Partition"; + +0x0a,0xf1 "PATA Control"; -0x01 "Read-Write Error Recovery Page" { +0x01 "Read-Write Error Recovery" { {AWRE (Auto Write Reallocation Enbld)} t1 {ARRE (Auto Read Reallocation Enbld)} t1 {TB (Transfer Block)} t1 @@ -224,13 +309,14 @@ {Head Offset Count} i1 {Data Strobe Offset Count} i1 {LBPERE (LBP Error Reporting Enabled)} t1 - {Reserved} *t7 + {MWR (Misaligned Write Reporting)} t2 + {Reserved} *t5 {Write Retry Count} i1 {Reserved} *i1 {Recovery Time Limit} i2 } -0x04 "Rigid Disk Drive Geometry Page" { +0x04 "Rigid Disk Drive Geometry" { {Number of Cylinders} i3 {Number of Heads} i1 {Starting Cylinder-Write Precompensation} i3 @@ -246,7 +332,7 @@ {Reserved} *i1 } -0x07 "Verify Error Recovery Page" { +0x07 "Verify Error Recovery" { {Reserved} *t4 {EER} t1 {PER} t1 @@ -262,7 +348,7 @@ {Verify Recovery Time Limit} i2 } -0x0E "CD-ROM Audio Control Parameters Page" { +0x0E "CD-ROM Audio Control Parameters" { {Reserved} *t5 {Immed} t1 {SOTC} t1 @@ -287,7 +373,7 @@ } # SEQUENTIAL ACCESS DEVICES -0x10 "Device Configuration Page" { +0x10 "Device Configuration" { {Reserved} *t1 {Change Active Partition} t1 {Change Active Format} t1 @@ -316,7 +402,7 @@ {SCSI-3 Permanent Write Protect} t1 } -0x0f "Data Compression Page" { +0x0f "Data Compression" { {Data Compression Enabled} t1 {Date Compression Capable} t1 {Reserved} *t6 @@ -329,7 +415,7 @@ } # Removable devices -0x1b "Removable Block Access Capacities Page" { +0x1b "Removable Block Access Capacities" { {System Floppy Type Device} t1 {Supports Reporting Format Progress} t1 {Reserved} *t6 @@ -341,7 +427,7 @@ } # CD-ROM (and CD-R[W]) devices -0x2a "CD capabilities and mechanical status page" { +0x2a "CD capabilities and mechanical status" { {Reserved} *t4 {Method 2} t1 {CD-RW Read} t1 @@ -392,4 +478,17 @@ {Current Write Speed Supported (kBps)} i2 }; +0x1d "Timeout and Protect" { + {Reserved} *i2 + {Reserved} *t4 + {G3Enable} t1 + {TMOE} t1 + {DISP} t1 + {SWPP} t1 + {Reserved} *i1 + {Group 1 Minimum Timeout} i2 + {Group 2 Minimum Timeout} i2 + {Group 3 Timeout} i2 +}; + 0x00 "Vendor-Specific"; diff --git a/share/mk/bsd.README b/share/mk/bsd.README index df973d5..ea46202 100644 --- a/share/mk/bsd.README +++ b/share/mk/bsd.README @@ -350,6 +350,82 @@ If foo has multiple source files, add the line: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +The include file, <bsd.snmpmod.mk>, handles building MIB modules for bsnmpd +from one or more source files, along with their manual pages. It has a +limited number of suffixes, consistent with the current needs of the BSD +tree. + +bsd.snmpmod.mk leverages bsd.lib.mk for building MIB modules and +bsd.files.mk for installing MIB description and definition files. + +It implements the following additional targets: + + smilint: + execute smilint on the MIBs defined by BMIBS. + + The net-mgmt/libsmi package must be installed before + executing this target. The net-mgmt/net-snmp package + should be installed as well to reduce false positives + from smilint. + +It sets/uses the following variables: + +BMIBS The MIB definitions to install. + +BMIBSDIR The directory where the MIB definitions are installed. + This defaults to `${SHAREDIR}/snmp/mibs`. + +DEFS The MIB description files to install. + +DEFSDIR The directory where MIB description files are installed. + This defaults to `${SHAREDIR}/snmp/defs`. + +EXTRAMIBDEFS Extra MIB description files to use as input when + generating ${MOD}_oid.h and ${MOD}_tree.[ch]. + +EXTRAMIBSYMS Extra MIB definition files used only for extracting + symbols. + + EXTRAMIBSYMS are useful when resolving inter-module + dependencies and are useful with files containing only + enum-definitions. + + See ${MOD}_oid.h for more details. + +LOCALBASE The package root where smilint and the net-snmp + definitions can be found + +MOD The bsnmpd module name. + +SMILINT smilint binary to use with the smilint make target. + +SMILINT_FLAGS flags to pass to smilint. + +SMIPATH A colon-separated directory path where MIBs definitions + can be found. See "SMIPATH" in smi_config for more + details. + +XSYM MIB names to extract symbols for. See ${MOD}_oid.h for + more details. + +It generates the following files: + +${MOD}_tree.c A source file and header which programmatically describes +${MOD}_tree.h the MIB (type, OID name, ACCESS attributes, etc). + + The files are generated via "gensnmptree -p". + + See gensnmptree(1) for more details. + +${MOD}_oid.h A header which programmatically describes the MIB root and + MIB tables. + + The files are generated via "gensnmptree -e". + + See gensnmptree(1) for more details. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + The include file <bsd.subdir.mk> contains the default targets for building subdirectories. It has the same seven targets as <bsd.prog.mk>: all, clean, cleandir, depend, install, lint, and tags. For all of the directories diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index 6f0fd3e..0d21cb3 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -602,6 +602,24 @@ MK_TESTS:= no # # +# MK_* options whose default value depends on another option. +# +.for vv in \ + GSSAPI/KERBEROS \ + MAN_UTILS/MAN +.if defined(WITH_${vv:H}) && defined(WITHOUT_${vv:H}) +.error WITH_${vv:H} and WITHOUT_${vv:H} can't both be set. +.endif +.if defined(WITH_${vv:H}) +MK_${vv:H}:= yes +.elif defined(WITHOUT_${vv:H}) +MK_${vv:H}:= no +.else +MK_${vv:H}:= ${MK_${vv:T}} +.endif +.endfor + +# # MK_*_SUPPORT options which default to "yes" unless their corresponding # MK_* variable is set to "no". # @@ -627,24 +645,6 @@ MK_${var}_SUPPORT:= yes .endfor # -# MK_* options whose default value depends on another option. -# -.for vv in \ - GSSAPI/KERBEROS \ - MAN_UTILS/MAN -.if defined(WITH_${vv:H}) && defined(WITHOUT_${vv:H}) -.error WITH_${vv:H} and WITHOUT_${vv:H} can't both be set. -.endif -.if defined(WITH_${vv:H}) -MK_${vv:H}:= yes -.elif defined(WITHOUT_${vv:H}) -MK_${vv:H}:= no -.else -MK_${vv:H}:= ${MK_${vv:T}} -.endif -.endfor - -# # MK_* options that default to "yes" if the compiler is a C++11 compiler. # .include <bsd.compiler.mk> diff --git a/share/mk/bsd.snmpmod.mk b/share/mk/bsd.snmpmod.mk index 552f936..2814da9 100644 --- a/share/mk/bsd.snmpmod.mk +++ b/share/mk/bsd.snmpmod.mk @@ -24,4 +24,18 @@ FILESGROUPS+= BMIBS BMIBSDIR= ${SHAREDIR}/snmp/mibs .endif +.if !target(smilint) && !empty(BMIBS) +LOCALBASE?= /usr/local + +SMILINT?= ${LOCALBASE}/bin/smilint + +SMIPATH?= ${BMIBSDIR}:${LOCALBASE}/share/snmp/mibs + +SMILINT_FLAGS?= -c /dev/null -l6 -i group-membership + +smilint: ${BMIBS} + SMIPATH=${SMIPATH} ${SMILINT} ${SMILINT_FLAGS} ${.ALLSRC} +.endif +smilint: .PHONY + .include <bsd.lib.mk> diff --git a/share/skel/dot.shrc b/share/skel/dot.shrc index ea32f35..974db46 100644 --- a/share/skel/dot.shrc +++ b/share/skel/dot.shrc @@ -13,12 +13,8 @@ # # umask 022 -# Enable the builtin emacs(1) command line editor in sh(1), -# e.g. C-a -> beginning-of-line. -set -o emacs - -# Uncomment this and comment the above to enable the builtin vi(1) command -# line editor in sh(1), e.g. ESC to go into visual mode. +# Uncomment this to enable the builtin vi(1) command line editor in sh(1), +# e.g. ESC to go into visual mode. # set -o vi diff --git a/share/zoneinfo/Makefile b/share/zoneinfo/Makefile index 7f022c8..a3c81b9 100644 --- a/share/zoneinfo/Makefile +++ b/share/zoneinfo/Makefile @@ -67,6 +67,10 @@ TZBUILDSUBDIRS= \ Pacific \ SystemV +.if defined(OLDTIMEZONES) +TZBUILDSUBDIRS+= US Mexico Chile Canada Brazil +.endif + all: zoneinfo .PHONY: zoneinfo @@ -78,6 +82,8 @@ zoneinfo: yearistype ${TDATA} ${LEAPFILE} -y ${.OBJDIR}/yearistype ${TZFILES} beforeinstall: + mkdir -p ${DESTDIR}/usr/share/zoneinfo + cd ${DESTDIR}/usr/share/zoneinfo; mkdir -p ${TZBUILDSUBDIRS} cd ${TZBUILDDIR} && \ find -s * -type f -print -exec ${INSTALL} \ -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} \ diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c index 66e465e..1b358bc 100644 --- a/sys/amd64/amd64/initcpu.c +++ b/sys/amd64/amd64/initcpu.c @@ -253,12 +253,17 @@ initializecpucache(void) * CPUID_SS feature even though the native CPU supports it. */ TUNABLE_INT_FETCH("hw.clflush_disable", &hw_clflush_disable); - if (vm_guest != VM_GUEST_NO && hw_clflush_disable == -1) + if (vm_guest != VM_GUEST_NO && hw_clflush_disable == -1) { cpu_feature &= ~CPUID_CLFSH; + cpu_stdext_feature &= ~CPUID_STDEXT_CLFLUSHOPT; + } + /* - * Allow to disable CLFLUSH feature manually by - * hw.clflush_disable tunable. + * The kernel's use of CLFLUSH{,OPT} can be disabled manually + * by setting the hw.clflush_disable tunable. */ - if (hw_clflush_disable == 1) + if (hw_clflush_disable == 1) { cpu_feature &= ~CPUID_CLFSH; + cpu_stdext_feature &= ~CPUID_STDEXT_CLFLUSHOPT; + } } diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index d7c5213..1f6aaf5 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -912,7 +912,12 @@ pmap_bootstrap(vm_paddr_t *firstaddr) virtual_avail = va; - /* Initialize the PAT MSR. */ + /* + * Initialize the PAT MSR. + * pmap_init_pat() clears and sets CR4_PGE, which, as a + * side-effect, invalidates stale PG_G TLB entries that might + * have been created in our pre-boot environment. + */ pmap_init_pat(); /* Initialize TLB Context Id. */ @@ -1789,9 +1794,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) if ((cpu_feature & CPUID_SS) != 0 && !force) ; /* If "Self Snoop" is supported and allowed, do nothing. */ - else if ((cpu_feature & CPUID_CLFSH) != 0 && + else if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0 && eva - sva < PMAP_CLFLUSH_THRESHOLD) { - /* * XXX: Some CPUs fault, hang, or trash the local APIC * registers if we use CLFLUSH on the local APIC @@ -1802,16 +1806,29 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) return; /* - * Otherwise, do per-cache line flush. Use the mfence + * Otherwise, do per-cache line flush. Use the sfence * instruction to insure that previous stores are * included in the write-back. The processor * propagates flush to other processors in the cache * coherence domain. */ - mfence(); + sfence(); + for (; sva < eva; sva += cpu_clflush_line_size) + clflushopt(sva); + sfence(); + } else if ((cpu_feature & CPUID_CLFSH) != 0 && + eva - sva < PMAP_CLFLUSH_THRESHOLD) { + if (pmap_kextract(sva) == lapic_paddr) + return; + /* + * Writes are ordered by CLFLUSH on Intel CPUs. + */ + if (cpu_vendor_id != CPU_VENDOR_INTEL) + mfence(); for (; sva < eva; sva += cpu_clflush_line_size) clflush(sva); - mfence(); + if (cpu_vendor_id != CPU_VENDOR_INTEL) + mfence(); } else { /* @@ -1835,19 +1852,31 @@ pmap_invalidate_cache_pages(vm_page_t *pages, int count) { vm_offset_t daddr, eva; int i; + bool useclflushopt; + useclflushopt = (cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0; if (count >= PMAP_CLFLUSH_THRESHOLD / PAGE_SIZE || - (cpu_feature & CPUID_CLFSH) == 0) + ((cpu_feature & CPUID_CLFSH) == 0 && !useclflushopt)) pmap_invalidate_cache(); else { - mfence(); + if (useclflushopt) + sfence(); + else if (cpu_vendor_id != CPU_VENDOR_INTEL) + mfence(); for (i = 0; i < count; i++) { daddr = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pages[i])); eva = daddr + PAGE_SIZE; - for (; daddr < eva; daddr += cpu_clflush_line_size) - clflush(daddr); + for (; daddr < eva; daddr += cpu_clflush_line_size) { + if (useclflushopt) + clflushopt(daddr); + else + clflush(daddr); + } } - mfence(); + if (useclflushopt) + sfence(); + else if (cpu_vendor_id != CPU_VENDOR_INTEL) + mfence(); } } @@ -3348,6 +3377,7 @@ pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, vm_offset_t va, vm_paddr_t mptepa; vm_page_t mpte; struct spglist free; + vm_offset_t sva; int PG_PTE_CACHE; PG_G = pmap_global_bit(pmap); @@ -3386,9 +3416,9 @@ pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, vm_offset_t va, DMAP_MAX_ADDRESS ? VM_ALLOC_INTERRUPT : VM_ALLOC_NORMAL) | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED)) == NULL) { SLIST_INIT(&free); - pmap_remove_pde(pmap, pde, trunc_2mpage(va), &free, - lockp); - pmap_invalidate_page(pmap, trunc_2mpage(va)); + sva = trunc_2mpage(va); + pmap_remove_pde(pmap, pde, sva, &free, lockp); + pmap_invalidate_range(pmap, sva, sva + NBPDR - 1); pmap_free_zero_pages(&free); CTR2(KTR_PMAP, "pmap_demote_pde: failure for va %#lx" " in pmap %p", va, pmap); @@ -3531,11 +3561,23 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva, pmap->pm_stats.wired_count -= NBPDR / PAGE_SIZE; /* - * Machines that don't support invlpg, also don't support - * PG_G. + * When workaround_erratum383 is false, a promotion to a 2M + * page mapping does not invalidate the 512 4K page mappings + * from the TLB. Consequently, at this point, the TLB may + * hold both 4K and 2M page mappings. Therefore, the entire + * range of addresses must be invalidated here. In contrast, + * when workaround_erratum383 is true, a promotion does + * invalidate the 512 4K page mappings, and so a single INVLPG + * suffices to invalidate the 2M page mapping. */ - if (oldpde & PG_G) - pmap_invalidate_page(kernel_pmap, sva); + if ((oldpde & PG_G) != 0) { + if (workaround_erratum383) + pmap_invalidate_page(kernel_pmap, sva); + else + pmap_invalidate_range(kernel_pmap, sva, + sva + NBPDR - 1); + } + pmap_resident_count_dec(pmap, NBPDR / PAGE_SIZE); if (oldpde & PG_MANAGED) { CHANGE_PV_LIST_LOCK_TO_PHYS(lockp, oldpde & PG_PS_FRAME); @@ -3890,9 +3932,14 @@ retry: if (newpde != oldpde) { if (!atomic_cmpset_long(pde, oldpde, newpde)) goto retry; - if (oldpde & PG_G) - pmap_invalidate_page(pmap, sva); - else + if (oldpde & PG_G) { + /* See pmap_remove_pde() for explanation. */ + if (workaround_erratum383) + pmap_invalidate_page(kernel_pmap, sva); + else + pmap_invalidate_range(kernel_pmap, sva, + sva + NBPDR - 1); + } else anychanged = TRUE; } return (anychanged); diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h index a3d82e8..dacfe32 100644 --- a/sys/amd64/include/cpufunc.h +++ b/sys/amd64/include/cpufunc.h @@ -327,6 +327,13 @@ mfence(void) } static __inline void +sfence(void) +{ + + __asm __volatile("sfence" : : : "memory"); +} + +static __inline void ia32_pause(void) { __asm __volatile("pause"); diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c index 13f9199..dba213b 100644 --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -718,7 +718,7 @@ exec_linux_imgact_try(struct image_params *imgp) { const char *head = (const char *)imgp->image_header; char *rpath; - int error = -1, len; + int error = -1; /* * The interpreter for shell scripts run from a linux binary needs @@ -736,17 +736,12 @@ exec_linux_imgact_try(struct image_params *imgp) linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc), imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, AT_FDCWD); - if (rpath != NULL) { - len = strlen(rpath) + 1; - - if (len <= MAXSHELLCMDLEN) - memcpy(imgp->interpreter_name, - rpath, len); - free(rpath, M_TEMP); - } + if (rpath != NULL) + imgp->args->fname_buf = + imgp->interpreter_name = rpath; } } - return(error); + return (error); } #define LINUX_VSYSCALL_START (-10UL << 20) diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c index 5cb4150..53a8bdc 100644 --- a/sys/amd64/vmm/vmm_dev.c +++ b/sys/amd64/vmm/vmm_dev.c @@ -258,7 +258,7 @@ alloc_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg) if (VM_MEMSEG_NAME(mseg)) { sysmem = false; name = malloc(SPECNAMELEN + 1, M_VMMDEV, M_WAITOK); - error = copystr(VM_MEMSEG_NAME(mseg), name, SPECNAMELEN + 1, 0); + error = copystr(mseg->name, name, SPECNAMELEN + 1, 0); if (error) goto done; } diff --git a/sys/boot/common/reloc_elf.c b/sys/boot/common/reloc_elf.c index 2b60d18..6d4a00f 100644 --- a/sys/boot/common/reloc_elf.c +++ b/sys/boot/common/reloc_elf.c @@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> #include <machine/elf.h> -#include <errno.h> #include <stand.h> #define FREEBSD_ELF diff --git a/sys/boot/efi/boot1/boot_module.h b/sys/boot/efi/boot1/boot_module.h index 296d5a6..3a6b827 100644 --- a/sys/boot/efi/boot1/boot_module.h +++ b/sys/boot/efi/boot1/boot_module.h @@ -64,7 +64,7 @@ typedef struct boot_module_t const char *name; /* init is the optional initialiser for the module. */ - void (*init)(); + void (*init)(void); /* * probe checks to see if the module can handle dev. @@ -89,10 +89,10 @@ typedef struct boot_module_t void **buf, size_t *bufsize); /* status outputs information about the probed devices. */ - void (*status)(); + void (*status)(void); /* valid devices as found by probe. */ - dev_info_t *(*devices)(); + dev_info_t *(*devices)(void); } boot_module_t; /* Standard boot modules. */ diff --git a/sys/boot/efi/include/efiapi.h b/sys/boot/efi/include/efiapi.h index 25e40a2..1ce7f62 100644 --- a/sys/boot/efi/include/efiapi.h +++ b/sys/boot/efi/include/efiapi.h @@ -536,6 +536,7 @@ EFI_STATUS typedef EFI_STATUS (EFIAPI *EFI_RESERVED_SERVICE) ( + VOID ); typedef diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index 7cf0bcf..afc63f0 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -84,6 +84,7 @@ module_path="/boot/modules" # Set the module search path #prompt="\\${interpret}" # Set the command prompt #root_disk_unit="0" # Force the root disk unit number #rootdev="disk1s1a" # Set the root filesystem +#dumpdev="disk1s1b" # Set a dump device early in the boot process #tftp.blksize="1428" # Set the RFC 2348 TFTP block size. # If the TFTP server does not support RFC 2348, # the block size is set to 512. If the value diff --git a/sys/boot/libstand32/Makefile b/sys/boot/libstand32/Makefile index c2bb701..be7a4f4 100644 --- a/sys/boot/libstand32/Makefile +++ b/sys/boot/libstand32/Makefile @@ -1,189 +1,27 @@ # $FreeBSD$ -# Originally from $NetBSD: Makefile,v 1.21 1997/10/26 22:08:38 lukem Exp $ -# -# Notes: -# - We don't use the libc strerror/sys_errlist because the string table is -# quite large. -# - -MAN= .include <bsd.own.mk> -MK_SSP= no - -S= ${.CURDIR}/../../../lib/libstand - -.PATH: ${S} -LIB= stand -INTERNALLIB= -NO_PROFILE= -NO_PIC= - -WARNS?= 0 - -CFLAGS+= -ffreestanding -Wformat -CFLAGS+= -I${S} - -.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" -CFLAGS.gcc+= -mpreferred-stack-boundary=2 -CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float -.endif -.if ${MACHINE} == "pc98" -CFLAGS+= -Os -.endif -.if ${MACHINE_CPUARCH} == "powerpc" -CFLAGS+= -msoft-float -D_STANDALONE -DNETIF_DEBUG -.endif -.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -I. -.endif -.if ${MACHINE_CPUARCH} == "arm" -CFLAGS+= -msoft-float -D_STANDALONE -.endif -.if ${MACHINE_CPUARCH} == "mips" -CFLAGS+= -G0 -fno-pic -mno-abicalls -.endif - -# standalone components and stuff we have modified locally -SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c environment.c getopt.c gets.c \ - globals.c pager.c printf.c strdup.c strerror.c strtol.c strtoul.c random.c \ - sbrk.c twiddle.c zalloc.c zalloc_malloc.c - -# private (pruned) versions of libc string functions -SRCS+= strcasecmp.c - -LIBC= ${S}/../libc - -.PATH: ${LIBC}/net - -SRCS+= ntoh.c - -# string functions from libc -.PATH: ${LIBC}/string -.if ${MACHINE_CPUARCH} != "ia64" -SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \ - memmove.c memset.c qdivrem.c strcat.c strchr.c strcmp.c strcpy.c \ - strcspn.c strlcat.c strlcpy.c strlen.c strncat.c strncmp.c strncpy.c \ - strpbrk.c strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c -.endif -.if ${MACHINE_CPUARCH} == "arm" -.PATH: ${LIBC}/arm/gen - -.if ${MK_ARM_EABI} == "no" -SRCS+= divsi3.S -.else -# Compiler support functions -.PATH: ${.CURDIR}/../../../contrib/compiler-rt/lib/ -# __clzsi2 and ctzsi2 for various builtin functions -SRCS+= clzsi2.c ctzsi2.c -# Divide and modulus functions called by the compiler -SRCS+= divmoddi4.c divmodsi4.c divdi3.c divsi3.c moddi3.c modsi3.c -SRCS+= udivmoddi4.c udivmodsi4.c udivdi3.c udivsi3.c umoddi3.c umodsi3.c - -.PATH: ${.CURDIR}/../../../contrib/compiler-rt/lib/arm/ -SRCS+= aeabi_idivmod.S aeabi_ldivmod.S aeabi_uidivmod.S aeabi_uldivmod.S -SRCS+= aeabi_memcmp.S aeabi_memcpy.S aeabi_memmove.S aeabi_memset.S -.endif - -.endif -.if ${MACHINE_CPUARCH} == "ia64" -.PATH: ${LIBC}/ia64/string -SRCS+= bcmp.c bcopy.S bzero.S ffs.S memccpy.c memchr.c memcmp.c memcpy.S \ - memmove.S memset.c strcat.c strchr.c strcmp.c strcpy.c strcspn.c \ - strlen.c strncat.c strncmp.c strncpy.c strpbrk.c strrchr.c strsep.c \ - strspn.c strstr.c strtok.c swab.c - -.PATH: ${LIBC}/ia64/gen -SRCS+= __divdi3.S __divsi3.S __moddi3.S __modsi3.S -SRCS+= __udivdi3.S __udivsi3.S __umoddi3.S __umodsi3.S -.endif -.if ${MACHINE_CPUARCH} == "powerpc" -.PATH: ${LIBC}/quad -SRCS+= ashldi3.c ashrdi3.c -.PATH: ${LIBC}/powerpc/gen -SRCS+= syncicache.c -.endif -# uuid functions from libc -.PATH: ${LIBC}/uuid -SRCS+= uuid_equal.c uuid_is_nil.c +LIBSTAND_SRC= ${.CURDIR}/../../../lib/libstand -# _setjmp/_longjmp .if ${MACHINE_CPUARCH} == "amd64" -.PATH: ${S}/i386 -.elif ${MACHINE_ARCH} == "powerpc64" -.PATH: ${S}/powerpc +LIBSTAND_CPUARCH=i386 .else -.PATH: ${S}/${MACHINE_CPUARCH} +LIBSTAND_CPUARCH=${MACHINE_CPUARCH} .endif -SRCS+= _setjmp.S - -# decompression functionality from libbz2 -# NOTE: to actually test this functionality after libbz2 upgrade compile -# loader(8) with LOADER_BZIP2_SUPPORT defined -.PATH: ${.CURDIR}/../../../contrib/bzip2 -CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS -SRCS+= libstand_bzlib_private.h - -.for file in bzlib.c crctable.c decompress.c huffman.c randtable.c -SRCS+= _${file} -CLEANFILES+= _${file} - -_${file}: ${file} - sed "s|bzlib_private\.h|libstand_bzlib_private.h|" ${.ALLSRC} > ${.TARGET} -.endfor - -CLEANFILES+= libstand_bzlib_private.h -libstand_bzlib_private.h: bzlib_private.h - sed -e 's|<stdlib.h>|"stand.h"|' \ - ${.ALLSRC} > ${.TARGET} - -# decompression functionality from libz -.PATH: ${S}/../libz -CFLAGS+=-DHAVE_MEMCPY -I${S}/../libz -SRCS+= adler32.c crc32.c libstand_zutil.h libstand_gzguts.h - -.for file in infback.c inffast.c inflate.c inftrees.c zutil.c -SRCS+= _${file} -CLEANFILES+= _${file} - -_${file}: ${file} - sed -e "s|zutil\.h|libstand_zutil.h|" \ - -e "s|gzguts\.h|libstand_gzguts.h|" \ - ${.ALLSRC} > ${.TARGET} -.endfor - -# depend on stand.h being able to be included multiple times -.for file in zutil.h gzguts.h -CLEANFILES+= libstand_${file} -libstand_${file}: ${file} - sed -e 's|<fcntl.h>|"stand.h"|' \ - -e 's|<stddef.h>|"stand.h"|' \ - -e 's|<string.h>|"stand.h"|' \ - -e 's|<stdio.h>|"stand.h"|' \ - -e 's|<stdlib.h>|"stand.h"|' \ - ${.ALLSRC} > ${.TARGET} -.endfor - -# io routines -SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \ - fstat.c close.c lseek.c open.c read.c write.c readdir.c - -# network routines -SRCS+= arp.c ether.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c - -# network info services: -SRCS+= bootp.c rarp.c bootparam.c +LIBC_SRC= ${LIBSTAND_SRC}/../libc +INTERNALLIB= +INCS= +MAN= +.PATH: ${LIBSTAND_SRC} -# boot filesystems -SRCS+= ufs.c nfs.c cd9660.c tftp.c gzipfs.c bzipfs.c -SRCS+= dosfs.c ext2fs.c -SRCS+= splitfs.c -.if ${MK_NAND} != "no" -SRCS+= nandfs.c +.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "powerpc64" +CFLAGS+= -m32 -I. .endif -.include <bsd.lib.mk> +WARNS?= 0 + +.include "${LIBSTAND_SRC}/Makefile" .if ${MACHINE_CPUARCH} == "amd64" CLEANFILES+= machine diff --git a/sys/boot/userboot/libstand/Makefile b/sys/boot/userboot/libstand/Makefile index 53d6e85..11bfdee 100644 --- a/sys/boot/userboot/libstand/Makefile +++ b/sys/boot/userboot/libstand/Makefile @@ -1,166 +1,12 @@ # $FreeBSD$ -# Originally from $NetBSD: Makefile,v 1.21 1997/10/26 22:08:38 lukem Exp $ -# -# Notes: -# - We don't use the libc strerror/sys_errlist because the string table is -# quite large. -# - -MAN= .include <bsd.own.mk> -MK_SSP= no -S= ${.CURDIR}/../../../../lib/libstand +LIBSTAND_SRC= ${.CURDIR}/../../../../lib/libstand -.PATH: ${S} -LIB= stand INTERNALLIB= -NO_PROFILE= -NO_PIC= - -WARNS?= 0 - -CFLAGS+= -ffreestanding -Wformat -fPIC -CFLAGS+= -I${.CURDIR}/../../../../lib/libstand - -.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" -CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -.endif -.if ${MACHINE_CPUARCH} == "i386" -CFLAGS.gcc+= -mpreferred-stack-boundary=2 -CFLAGS+= -mno-sse3 -.endif -.if ${MACHINE} == "pc98" -CFLAGS+= -Os -.endif -.if ${MACHINE_CPUARCH} == "powerpc" -CFLAGS+= -msoft-float -D_STANDALONE -DNETIF_DEBUG -.endif -.if ${MACHINE_CPUARCH} == "arm" -CFLAGS+= -msoft-float -D_STANDALONE -.endif - -# standalone components and stuff we have modified locally -SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c environment.c getopt.c gets.c \ - globals.c pager.c printf.c strdup.c strerror.c strtol.c random.c \ - sbrk.c twiddle.c zalloc.c zalloc_malloc.c - -# private (pruned) versions of libc string functions -SRCS+= strcasecmp.c - -LIBC= ${.CURDIR}/../../../../lib/libc - -.PATH: ${LIBC}/net - -SRCS+= ntoh.c - -# string functions from libc -.PATH: ${LIBC}/string -.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "powerpc" || \ - ${MACHINE_CPUARCH} == "sparc64" || ${MACHINE_CPUARCH} == "amd64" || \ - ${MACHINE_CPUARCH} == "arm" -SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \ - memmove.c memset.c qdivrem.c strcat.c strchr.c strcmp.c strcpy.c \ - strcspn.c strlen.c strncat.c strncmp.c strncpy.c strpbrk.c \ - strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c -.endif -.if ${MACHINE_CPUARCH} == "arm" -.PATH: ${LIBC}/arm/gen -SRCS+= divsi3.S -.endif -.if ${MACHINE_CPUARCH} == "ia64" -.PATH: ${LIBC}/ia64/string -SRCS+= bcmp.c bcopy.S bzero.S ffs.S index.c memccpy.c memchr.c memcmp.c \ - memcpy.S memmove.S memset.c rindex.c strcat.c strchr.c \ - strcmp.c strcpy.c strcspn.c strlen.c \ - strncat.c strncmp.c strncpy.c strpbrk.c strrchr.c strsep.c \ - strspn.c strstr.c strtok.c swab.c - -.PATH: ${LIBC}/ia64/gen -SRCS+= __divdi3.S __divsi3.S __moddi3.S __modsi3.S -SRCS+= __udivdi3.S __udivsi3.S __umoddi3.S __umodsi3.S -.endif -.if ${MACHINE_CPUARCH} == "powerpc" -.PATH: ${LIBC}/libc/quad -SRCS+= ashldi3.c ashrdi3.c -.PATH: ${LIBC}/powerpc/gen -SRCS+= syncicache.c -.endif - -# uuid functions from libc -.PATH: ${LIBC}/uuid -SRCS+= uuid_equal.c uuid_is_nil.c - -# _setjmp/_longjmp -.if ${MACHINE_CPUARCH} == "amd64" -.PATH: ${S}/amd64 -.elif ${MACHINE_ARCH} == "powerpc64" -.PATH: ${S}/powerpc -.else -.PATH: ${S}/${MACHINE_CPUARCH} -.endif -SRCS+= _setjmp.S - -# decompression functionality from libbz2 -# NOTE: to actually test this functionality after libbz2 upgrade compile -# loader(8) with LOADER_BZIP2_SUPPORT defined -.PATH: ${.CURDIR}/../../../../contrib/bzip2 -CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS -SRCS+= libstand_bzlib_private.h - -.for file in bzlib.c crctable.c decompress.c huffman.c randtable.c -SRCS+= _${file} -CLEANFILES+= _${file} - -_${file}: ${file} - sed "s|bzlib_private\.h|libstand_bzlib_private.h|" ${.ALLSRC} > ${.TARGET} -.endfor - -CLEANFILES+= libstand_bzlib_private.h -libstand_bzlib_private.h: bzlib_private.h - sed -e 's|<stdlib.h>|"stand.h"|' \ - ${.ALLSRC} > ${.TARGET} - -# decompression functionality from libz -.PATH: ${.CURDIR}/../../../../lib/libz -CFLAGS+=-DHAVE_MEMCPY -I${.CURDIR}/../../../../lib/libz -SRCS+= adler32.c crc32.c libstand_zutil.h libstand_gzguts.h - -.for file in infback.c inffast.c inflate.c inftrees.c zutil.c -SRCS+= _${file} -CLEANFILES+= _${file} - -_${file}: ${file} - sed -e "s|zutil\.h|libstand_zutil.h|" \ - -e "s|gzguts\.h|libstand_gzguts.h|" ${.ALLSRC} > ${.TARGET} -.endfor - -# depend on stand.h being able to be included multiple times -.for file in zutil.h gzguts.h -CLEANFILES+= libstand_${file} -libstand_${file}: ${file} - sed -e 's|<fcntl.h>|"stand.h"|' \ - -e 's|<stddef.h>|"stand.h"|' \ - -e 's|<string.h>|"stand.h"|' \ - -e 's|<stdio.h>|"stand.h"|' \ - -e 's|<stdlib.h>|"stand.h"|' \ - ${.ALLSRC} > ${.TARGET} -.endfor - -# io routines -SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \ - fstat.c close.c lseek.c open.c read.c write.c readdir.c - -# network routines -SRCS+= arp.c ether.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c - -# network info services: -SRCS+= bootp.c rarp.c bootparam.c - -# boot filesystems -SRCS+= ufs.c nfs.c cd9660.c tftp.c gzipfs.c bzipfs.c -SRCS+= dosfs.c ext2fs.c -SRCS+= splitfs.c +INCS= +MAN= +.PATH: ${LIBSTAND_SRC} -.include <bsd.lib.mk> +.include "${LIBSTAND_SRC}/Makefile" diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index 1d56ac7..1cbb082 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -727,6 +727,13 @@ struct ccb_scsiio { u_int init_id; /* initiator id of who selected */ }; +static __inline uint8_t * +scsiio_cdb_ptr(struct ccb_scsiio *ccb) +{ + return ((ccb->ccb_h.flags & CAM_CDB_POINTER) ? + ccb->cdb_io.cdb_ptr : ccb->cdb_io.cdb_bytes); +} + /* * ATA I/O Request CCB used for the XPT_ATA_IO function code. */ @@ -760,6 +767,13 @@ struct ccb_accept_tio { struct scsi_sense_data sense_data; }; +static __inline uint8_t * +atio_cdb_ptr(struct ccb_accept_tio *ccb) +{ + return ((ccb->ccb_h.flags & CAM_CDB_POINTER) ? + ccb->cdb_io.cdb_ptr : ccb->cdb_io.cdb_bytes); +} + /* Release SIM Queue */ struct ccb_relsim { struct ccb_hdr ccb_h; diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 9a59155..c540780 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -1909,10 +1909,7 @@ cam_periph_devctl_notify(union ccb *ccb) if (ccb->ccb_h.func_code == XPT_SCSI_IO) { sbuf_printf(&sb, "CDB=\""); - if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) - scsi_cdb_sbuf(ccb->csio.cdb_io.cdb_ptr, &sb); - else - scsi_cdb_sbuf(ccb->csio.cdb_io.cdb_bytes, &sb); + scsi_cdb_sbuf(scsiio_cdb_ptr(&ccb->csio), &sb); sbuf_printf(&sb, "\" "); } else if (ccb->ccb_h.func_code == XPT_ATA_IO) { sbuf_printf(&sb, "ACB=\""); diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 1a24641..1b3a57f 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -1,7 +1,7 @@ /*- * Copyright (c) 2003-2009 Silicon Graphics International Corp. * Copyright (c) 2012 The FreeBSD Foundation - * Copyright (c) 2015 Alexander Motin <mav@FreeBSD.org> + * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Portions of this software were developed by Edward Tomasz Napierala @@ -409,6 +409,9 @@ static int ctl_debug = CTL_DEBUG_NONE; TUNABLE_INT("kern.cam.ctl.debug", &ctl_debug); SYSCTL_INT(_kern_cam_ctl, OID_AUTO, debug, CTLFLAG_RWTUN, &ctl_debug, 0, "Enabled debug flags"); +static int ctl_lun_map_size = 1024; +SYSCTL_INT(_kern_cam_ctl, OID_AUTO, lun_map_size, CTLFLAG_RWTUN, + &ctl_lun_map_size, 0, "Size of per-port LUN map (max LUN + 1)"); /* * Supported pages (0x00), Serial number (0x80), Device ID (0x83), @@ -423,10 +426,10 @@ static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event, static void ctl_copy_sense_data(union ctl_ha_msg *src, union ctl_io *dest); static void ctl_copy_sense_data_back(union ctl_io *src, union ctl_ha_msg *dest); static int ctl_init(void); -void ctl_shutdown(void); +static int ctl_shutdown(void); static int ctl_open(struct cdev *dev, int flags, int fmt, struct thread *td); static int ctl_close(struct cdev *dev, int flags, int fmt, struct thread *td); -static int ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio); +static void ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio); static void ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num, struct ctl_ooa *ooa_hdr, struct ctl_ooa_entry *kern_entries); @@ -436,7 +439,6 @@ static int ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *lun, struct ctl_be_lun *be_lun); static int ctl_free_lun(struct ctl_lun *lun); static void ctl_create_lun(struct ctl_be_lun *be_lun); -static struct ctl_port * ctl_io_port(struct ctl_io_hdr *io_hdr); static int ctl_do_mode_select(union ctl_io *io); static int ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, @@ -447,7 +449,7 @@ static int ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, struct scsi_per_res_out_parms* param); static void ctl_pro_preempt_other(struct ctl_lun *lun, union ctl_ha_msg *msg); -static void ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg); +static void ctl_hndl_per_res_out_on_other_sc(union ctl_io *io); static int ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len); static int ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len); static int ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len); @@ -520,6 +522,8 @@ static const struct ctl_cmd_entry * ctl_validate_command(struct ctl_scsiio *ctsio); static int ctl_cmd_applicable(uint8_t lun_type, const struct ctl_cmd_entry *entry); +static int ctl_ha_init(void); +static int ctl_ha_shutdown(void); static uint64_t ctl_get_prkey(struct ctl_lun *lun, uint32_t residx); static void ctl_clr_prkey(struct ctl_lun *lun, uint32_t residx); @@ -561,18 +565,60 @@ MODULE_VERSION(ctl, 1); static struct ctl_frontend ha_frontend = { .name = "ha", + .init = ctl_ha_init, + .shutdown = ctl_ha_shutdown, +}; + +static int +ctl_ha_init(void) +{ + struct ctl_softc *softc = control_softc; + + if (ctl_pool_create(softc, "othersc", CTL_POOL_ENTRIES_OTHER_SC, + &softc->othersc_pool) != 0) + return (ENOMEM); + if (ctl_ha_msg_init(softc) != CTL_HA_STATUS_SUCCESS) { + ctl_pool_free(softc->othersc_pool); + return (EIO); + } + if (ctl_ha_msg_register(CTL_HA_CHAN_CTL, ctl_isc_event_handler) + != CTL_HA_STATUS_SUCCESS) { + ctl_ha_msg_destroy(softc); + ctl_pool_free(softc->othersc_pool); + return (EIO); + } + return (0); +}; + +static int +ctl_ha_shutdown(void) +{ + struct ctl_softc *softc = control_softc; + struct ctl_port *port; + + ctl_ha_msg_shutdown(softc); + if (ctl_ha_msg_deregister(CTL_HA_CHAN_CTL) != CTL_HA_STATUS_SUCCESS) + return (EIO); + if (ctl_ha_msg_destroy(softc) != CTL_HA_STATUS_SUCCESS) + return (EIO); + ctl_pool_free(softc->othersc_pool); + while ((port = STAILQ_FIRST(&ha_frontend.port_list)) != NULL) { + ctl_port_deregister(port); + free(port->port_name, M_CTL); + free(port, M_CTL); + } + return (0); }; static void ctl_ha_datamove(union ctl_io *io) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(io); struct ctl_sg_entry *sgl; union ctl_ha_msg msg; uint32_t sg_entries_sent; int do_sg_copy, i, j; - lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; memset(&msg.dt, 0, sizeof(msg.dt)); msg.hdr.msg_type = CTL_MSG_DATAMOVE; msg.hdr.original_sc = io->io_hdr.original_sc; @@ -697,8 +743,6 @@ ctl_ha_done(union ctl_io *io) msg.scsi.tag_num = io->scsiio.tag_num; msg.scsi.tag_type = io->scsiio.tag_type; msg.scsi.sense_len = io->scsiio.sense_len; - msg.scsi.sense_residual = io->scsiio.sense_residual; - msg.scsi.residual = io->scsiio.residual; memcpy(&msg.scsi.sense_data, &io->scsiio.sense_data, io->scsiio.sense_len); ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, @@ -726,8 +770,6 @@ ctl_isc_handler_finish_xfer(struct ctl_softc *ctl_softc, ctsio->io_hdr.status = msg_info->hdr.status; ctsio->scsi_status = msg_info->scsi.scsi_status; ctsio->sense_len = msg_info->scsi.sense_len; - ctsio->sense_residual = msg_info->scsi.sense_residual; - ctsio->residual = msg_info->scsi.residual; memcpy(&ctsio->sense_data, &msg_info->scsi.sense_data, msg_info->scsi.sense_len); ctl_enqueue_isc((union ctl_io *)ctsio); @@ -828,7 +870,7 @@ ctl_isc_announce_port(struct ctl_port *port) return; i = sizeof(msg->port) + strlen(port->port_name) + 1; if (port->lun_map) - i += sizeof(uint32_t) * CTL_MAX_LUNS; + i += port->lun_map_size * sizeof(uint32_t); if (port->port_devid) i += port->port_devid->len; if (port->target_devid) @@ -848,7 +890,7 @@ ctl_isc_announce_port(struct ctl_port *port) "%d:%s", softc->ha_id, port->port_name) + 1; i += msg->port.name_len; if (port->lun_map) { - msg->port.lun_map_len = sizeof(uint32_t) * CTL_MAX_LUNS; + msg->port.lun_map_len = port->lun_map_size * sizeof(uint32_t); memcpy(&msg->port.data[i], port->lun_map, msg->port.lun_map_len); i += msg->port.lun_map_len; @@ -1026,27 +1068,27 @@ ctl_isc_ua(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) uint32_t iid = ctl_get_initindex(&msg->hdr.nexus); mtx_lock(&softc->ctl_lock); - if (msg->hdr.nexus.targ_lun < CTL_MAX_LUNS && - (lun = softc->ctl_luns[msg->hdr.nexus.targ_mapped_lun]) != NULL) { - mtx_lock(&lun->lun_lock); - mtx_unlock(&softc->ctl_lock); - if (msg->ua.ua_type == CTL_UA_THIN_PROV_THRES && - msg->ua.ua_set) - memcpy(lun->ua_tpt_info, msg->ua.ua_info, 8); - if (msg->ua.ua_all) { - if (msg->ua.ua_set) - ctl_est_ua_all(lun, iid, msg->ua.ua_type); - else - ctl_clr_ua_all(lun, iid, msg->ua.ua_type); - } else { - if (msg->ua.ua_set) - ctl_est_ua(lun, iid, msg->ua.ua_type); - else - ctl_clr_ua(lun, iid, msg->ua.ua_type); - } - mtx_unlock(&lun->lun_lock); - } else + if (msg->hdr.nexus.targ_mapped_lun >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[msg->hdr.nexus.targ_mapped_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); + return; + } + mtx_lock(&lun->lun_lock); + mtx_unlock(&softc->ctl_lock); + if (msg->ua.ua_type == CTL_UA_THIN_PROV_THRES && msg->ua.ua_set) + memcpy(lun->ua_tpt_info, msg->ua.ua_info, 8); + if (msg->ua.ua_all) { + if (msg->ua.ua_set) + ctl_est_ua_all(lun, iid, msg->ua.ua_type); + else + ctl_clr_ua_all(lun, iid, msg->ua.ua_type); + } else { + if (msg->ua.ua_set) + ctl_est_ua(lun, iid, msg->ua.ua_type); + else + ctl_clr_ua(lun, iid, msg->ua.ua_type); + } + mtx_unlock(&lun->lun_lock); } static void @@ -1060,8 +1102,8 @@ ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) targ_lun = msg->hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); - if ((targ_lun >= CTL_MAX_LUNS) || - ((lun = softc->ctl_luns[targ_lun]) == NULL)) { + if (targ_lun >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[targ_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); return; } @@ -1076,7 +1118,7 @@ ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) memcmp(&msg->lun.data[0], lun->lun_devid->data, i) != 0)) { mtx_unlock(&lun->lun_lock); printf("%s: Received conflicting HA LUN %d\n", - __func__, msg->hdr.nexus.targ_lun); + __func__, targ_lun); return; } else { /* Record whether peer is primary. */ @@ -1110,7 +1152,7 @@ ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) mtx_unlock(&lun->lun_lock); CTL_DEBUG_PRINT(("%s: Known LUN %d, peer is %s\n", - __func__, msg->hdr.nexus.targ_lun, + __func__, targ_lun, (msg->lun.flags & CTL_LUN_PRIMARY_SC) ? "primary" : "secondary")); @@ -1157,19 +1199,25 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) M_CTL); i += msg->port.name_len; if (msg->port.lun_map_len != 0) { - if (port->lun_map == NULL) - port->lun_map = malloc(sizeof(uint32_t) * CTL_MAX_LUNS, + if (port->lun_map == NULL || + port->lun_map_size * sizeof(uint32_t) < + msg->port.lun_map_len) { + port->lun_map_size = 0; + free(port->lun_map, M_CTL); + port->lun_map = malloc(msg->port.lun_map_len, M_CTL, M_WAITOK); - memcpy(port->lun_map, &msg->port.data[i], - sizeof(uint32_t) * CTL_MAX_LUNS); + } + memcpy(port->lun_map, &msg->port.data[i], msg->port.lun_map_len); + port->lun_map_size = msg->port.lun_map_len / sizeof(uint32_t); i += msg->port.lun_map_len; } else { + port->lun_map_size = 0; free(port->lun_map, M_CTL); port->lun_map = NULL; } if (msg->port.port_devid_len != 0) { if (port->port_devid == NULL || - port->port_devid->len != msg->port.port_devid_len) { + port->port_devid->len < msg->port.port_devid_len) { free(port->port_devid, M_CTL); port->port_devid = malloc(sizeof(struct ctl_devid) + msg->port.port_devid_len, M_CTL, M_WAITOK); @@ -1184,7 +1232,7 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) } if (msg->port.target_devid_len != 0) { if (port->target_devid == NULL || - port->target_devid->len != msg->port.target_devid_len) { + port->target_devid->len < msg->port.target_devid_len) { free(port->target_devid, M_CTL); port->target_devid = malloc(sizeof(struct ctl_devid) + msg->port.target_devid_len, M_CTL, M_WAITOK); @@ -1199,7 +1247,7 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) } if (msg->port.init_devid_len != 0) { if (port->init_devid == NULL || - port->init_devid->len != msg->port.init_devid_len) { + port->init_devid->len < msg->port.init_devid_len) { free(port->init_devid, M_CTL); port->init_devid = malloc(sizeof(struct ctl_devid) + msg->port.init_devid_len, M_CTL, M_WAITOK); @@ -1220,7 +1268,7 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) } mtx_lock(&softc->ctl_lock); STAILQ_FOREACH(lun, &softc->lun_list, links) { - if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + if (ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX) continue; mtx_lock(&lun->lun_lock); ctl_est_ua_all(lun, -1, CTL_UA_INQ_CHANGE); @@ -1291,8 +1339,8 @@ ctl_isc_mode_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) targ_lun = msg->hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); - if ((targ_lun >= CTL_MAX_LUNS) || - ((lun = softc->ctl_luns[targ_lun]) == NULL)) { + if (targ_lun >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[targ_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); return; } @@ -1490,13 +1538,12 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) io->io_hdr.msg_type = CTL_MSG_DATAMOVE_DONE; io->io_hdr.flags &= ~CTL_FLAG_DMA_INPROG; io->io_hdr.flags |= CTL_FLAG_IO_ACTIVE; - io->io_hdr.port_status = msg->scsi.fetd_status; - io->scsiio.residual = msg->scsi.residual; + io->io_hdr.port_status = msg->scsi.port_status; + io->scsiio.kern_data_resid = msg->scsi.kern_data_resid; if (msg->hdr.status != CTL_STATUS_NONE) { io->io_hdr.status = msg->hdr.status; io->scsiio.scsi_status = msg->scsi.scsi_status; io->scsiio.sense_len = msg->scsi.sense_len; - io->scsiio.sense_residual =msg->scsi.sense_residual; memcpy(&io->scsiio.sense_data, &msg->scsi.sense_data, msg->scsi.sense_len); @@ -1782,7 +1829,6 @@ ctl_init(void) { struct make_dev_args args; struct ctl_softc *softc; - void *other_pool; int i, error; softc = control_softc = malloc(sizeof(*control_softc), M_DEVBUF, @@ -1796,7 +1842,8 @@ ctl_init(void) args.mda_si_drv1 = softc; error = make_dev_s(&args, &softc->dev, "cam/ctl"); if (error != 0) { - free(control_softc, M_DEVBUF); + free(softc, M_DEVBUF); + control_softc = NULL; return (error); } @@ -1808,7 +1855,7 @@ ctl_init(void) if (softc->sysctl_tree == NULL) { printf("%s: unable to allocate sysctl tree\n", __func__); destroy_dev(softc->dev); - free(control_softc, M_DEVBUF); + free(softc, M_DEVBUF); control_softc = NULL; return (ENOMEM); } @@ -1856,15 +1903,6 @@ ctl_init(void) STAILQ_INIT(&softc->be_list); ctl_tpc_init(softc); - if (ctl_pool_create(softc, "othersc", CTL_POOL_ENTRIES_OTHER_SC, - &other_pool) != 0) - { - printf("ctl: can't allocate %d entry other SC pool, " - "exiting\n", CTL_POOL_ENTRIES_OTHER_SC); - return (ENOMEM); - } - softc->othersc_pool = other_pool; - if (worker_threads <= 0) worker_threads = max(1, mp_ncpus / 4); if (worker_threads > CTL_MAX_THREADS) @@ -1884,22 +1922,19 @@ ctl_init(void) &softc->ctl_proc, &thr->thread, 0, 0, "ctl", "work%d", i); if (error != 0) { printf("error creating CTL work thread!\n"); - ctl_pool_free(other_pool); return (error); } } error = kproc_kthread_add(ctl_lun_thread, softc, - &softc->ctl_proc, NULL, 0, 0, "ctl", "lun"); + &softc->ctl_proc, &softc->lun_thread, 0, 0, "ctl", "lun"); if (error != 0) { printf("error creating CTL lun thread!\n"); - ctl_pool_free(other_pool); return (error); } error = kproc_kthread_add(ctl_thresh_thread, softc, - &softc->ctl_proc, NULL, 0, 0, "ctl", "thresh"); + &softc->ctl_proc, &softc->thresh_thread, 0, 0, "ctl", "thresh"); if (error != 0) { printf("error creating CTL threshold thread!\n"); - ctl_pool_free(other_pool); return (error); } @@ -1908,58 +1943,54 @@ ctl_init(void) softc, 0, ctl_ha_role_sysctl, "I", "HA role for this head"); if (softc->is_single == 0) { - ctl_frontend_register(&ha_frontend); - if (ctl_ha_msg_init(softc) != CTL_HA_STATUS_SUCCESS) { - printf("ctl_init: ctl_ha_msg_init failed.\n"); - softc->is_single = 1; - } else - if (ctl_ha_msg_register(CTL_HA_CHAN_CTL, ctl_isc_event_handler) - != CTL_HA_STATUS_SUCCESS) { - printf("ctl_init: ctl_ha_msg_register failed.\n"); + if (ctl_frontend_register(&ha_frontend) != 0) softc->is_single = 1; - } } return (0); } -void +static int ctl_shutdown(void) { struct ctl_softc *softc = control_softc; - struct ctl_lun *lun, *next_lun; + int i; - if (softc->is_single == 0) { - ctl_ha_msg_shutdown(softc); - if (ctl_ha_msg_deregister(CTL_HA_CHAN_CTL) - != CTL_HA_STATUS_SUCCESS) - printf("%s: ctl_ha_msg_deregister failed.\n", __func__); - if (ctl_ha_msg_destroy(softc) != CTL_HA_STATUS_SUCCESS) - printf("%s: ctl_ha_msg_destroy failed.\n", __func__); + if (softc->is_single == 0) ctl_frontend_deregister(&ha_frontend); - } - mtx_lock(&softc->ctl_lock); - - STAILQ_FOREACH_SAFE(lun, &softc->lun_list, links, next_lun) - ctl_free_lun(lun); - - mtx_unlock(&softc->ctl_lock); + destroy_dev(softc->dev); -#if 0 - ctl_shutdown_thread(softc->work_thread); - mtx_destroy(&softc->queue_lock); -#endif + /* Shutdown CTL threads. */ + softc->shutdown = 1; + for (i = 0; i < worker_threads; i++) { + struct ctl_thread *thr = &softc->threads[i]; + while (thr->thread != NULL) { + wakeup(thr); + if (thr->thread != NULL) + pause("CTL thr shutdown", 1); + } + mtx_destroy(&thr->queue_lock); + } + while (softc->lun_thread != NULL) { + wakeup(&softc->pending_lun_queue); + if (softc->lun_thread != NULL) + pause("CTL thr shutdown", 1); + } + while (softc->thresh_thread != NULL) { + wakeup(softc->thresh_thread); + if (softc->thresh_thread != NULL) + pause("CTL thr shutdown", 1); + } ctl_tpc_shutdown(softc); uma_zdestroy(softc->io_zone); mtx_destroy(&softc->ctl_lock); - destroy_dev(softc->dev); - sysctl_ctx_free(&softc->sysctl_ctx); - free(control_softc, M_DEVBUF); + free(softc, M_DEVBUF); control_softc = NULL; + return (0); } static int @@ -1970,7 +2001,7 @@ ctl_module_event_handler(module_t mod, int what, void *arg) case MOD_LOAD: return (ctl_init()); case MOD_UNLOAD: - return (EBUSY); + return (ctl_shutdown()); default: return (EOPNOTSUPP); } @@ -2197,22 +2228,19 @@ ctl_create_iid(struct ctl_port *port, int iid, uint8_t *buf) * command on this side (XFER mode) or tell the other side to execute it * (SER_ONLY mode). */ -static int +static void ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_port *port = CTL_PORT(ctsio); union ctl_ha_msg msg_info; - struct ctl_port *port; struct ctl_lun *lun; const struct ctl_cmd_entry *entry; - int retval = 0; uint32_t targ_lun; targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun; - mtx_lock(&softc->ctl_lock); /* Make sure that we know about this port. */ - port = ctl_io_port(&ctsio->io_hdr); if (port == NULL || (port->status & CTL_PORT_STATUS_ONLINE) == 0) { ctl_set_internal_failure(ctsio, /*sks_valid*/ 0, /*retry_count*/ 1); @@ -2220,24 +2248,11 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) } /* Make sure that we know about this LUN. */ - if ((targ_lun < CTL_MAX_LUNS) && - ((lun = softc->ctl_luns[targ_lun]) != NULL)) { - mtx_lock(&lun->lun_lock); - mtx_unlock(&softc->ctl_lock); - /* - * If the LUN is invalid, pretend that it doesn't exist. - * It will go away as soon as all pending I/O has been - * completed. - */ - if (lun->flags & CTL_LUN_DISABLED) { - mtx_unlock(&lun->lun_lock); - lun = NULL; - } - } else { + mtx_lock(&softc->ctl_lock); + if (targ_lun >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[targ_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); - lun = NULL; - } - if (lun == NULL) { + /* * The other node would not send this request to us unless * received announce that we are primary node for this LUN. @@ -2247,6 +2262,18 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) ctl_set_busy(ctsio); goto badjuju; } + mtx_lock(&lun->lun_lock); + mtx_unlock(&softc->ctl_lock); + + /* + * If the LUN is invalid, pretend that it doesn't exist. + * It will go away as soon as all pending I/Os completed. + */ + if (lun->flags & CTL_LUN_DISABLED) { + mtx_unlock(&lun->lun_lock); + ctl_set_busy(ctsio); + goto badjuju; + } entry = ctl_get_cmd_entry(ctsio, NULL); if (ctl_scsiio_lun_check(lun, entry, ctsio) != 0) { @@ -2254,8 +2281,8 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) goto badjuju; } - ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr = lun; - ctsio->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptr = lun->be_lun; + CTL_LUN(ctsio) = lun; + CTL_BACKEND_LUN(ctsio) = lun->be_lun; /* * Every I/O goes into the OOA queue for a @@ -2318,10 +2345,9 @@ badjuju: msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU; ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info, sizeof(msg_info.scsi), M_WAITOK); - retval = 1; + ctl_free_io((union ctl_io *)ctsio); break; } - return (retval); } /* @@ -2555,6 +2581,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { struct ctl_softc *softc = dev->si_drv1; + struct ctl_port *port; struct ctl_lun *lun; int retval; @@ -2676,9 +2703,9 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, } mtx_lock(&softc->ctl_lock); - if (((ooa_hdr->flags & CTL_OOA_FLAG_ALL_LUNS) == 0) - && ((ooa_hdr->lun_num >= CTL_MAX_LUNS) - || (softc->ctl_luns[ooa_hdr->lun_num] == NULL))) { + if ((ooa_hdr->flags & CTL_OOA_FLAG_ALL_LUNS) == 0 && + (ooa_hdr->lun_num >= CTL_MAX_LUNS || + softc->ctl_luns[ooa_hdr->lun_num] == NULL)) { mtx_unlock(&softc->ctl_lock); free(entries, M_CTL); printf("%s: CTL_GET_OOA: invalid LUN %ju\n", @@ -2730,89 +2757,75 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, #ifdef CTL_IO_DELAY mtx_lock(&softc->ctl_lock); - - if ((delay_info->lun_id >= CTL_MAX_LUNS) - || (softc->ctl_luns[delay_info->lun_id] == NULL)) { + if (delay_info->lun_id >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[delay_info->lun_id]) == NULL) { + mtx_unlock(&softc->ctl_lock); delay_info->status = CTL_DELAY_STATUS_INVALID_LUN; - } else { - lun = softc->ctl_luns[delay_info->lun_id]; - mtx_lock(&lun->lun_lock); - - delay_info->status = CTL_DELAY_STATUS_OK; - - switch (delay_info->delay_type) { - case CTL_DELAY_TYPE_CONT: - break; - case CTL_DELAY_TYPE_ONESHOT: - break; - default: - delay_info->status = - CTL_DELAY_STATUS_INVALID_TYPE; - break; - } - - switch (delay_info->delay_loc) { - case CTL_DELAY_LOC_DATAMOVE: - lun->delay_info.datamove_type = - delay_info->delay_type; - lun->delay_info.datamove_delay = - delay_info->delay_secs; - break; - case CTL_DELAY_LOC_DONE: - lun->delay_info.done_type = - delay_info->delay_type; - lun->delay_info.done_delay = - delay_info->delay_secs; - break; - default: - delay_info->status = - CTL_DELAY_STATUS_INVALID_LOC; - break; - } - mtx_unlock(&lun->lun_lock); + break; } - + mtx_lock(&lun->lun_lock); mtx_unlock(&softc->ctl_lock); + delay_info->status = CTL_DELAY_STATUS_OK; + switch (delay_info->delay_type) { + case CTL_DELAY_TYPE_CONT: + case CTL_DELAY_TYPE_ONESHOT: + break; + default: + delay_info->status = CTL_DELAY_STATUS_INVALID_TYPE; + break; + } + switch (delay_info->delay_loc) { + case CTL_DELAY_LOC_DATAMOVE: + lun->delay_info.datamove_type = delay_info->delay_type; + lun->delay_info.datamove_delay = delay_info->delay_secs; + break; + case CTL_DELAY_LOC_DONE: + lun->delay_info.done_type = delay_info->delay_type; + lun->delay_info.done_delay = delay_info->delay_secs; + break; + default: + delay_info->status = CTL_DELAY_STATUS_INVALID_LOC; + break; + } + mtx_unlock(&lun->lun_lock); #else delay_info->status = CTL_DELAY_STATUS_NOT_IMPLEMENTED; #endif /* CTL_IO_DELAY */ break; } +#ifdef CTL_LEGACY_STATS case CTL_GETSTATS: { - struct ctl_stats *stats; + struct ctl_stats *stats = (struct ctl_stats *)addr; int i; - stats = (struct ctl_stats *)addr; - - if ((sizeof(struct ctl_lun_io_stats) * softc->num_luns) > - stats->alloc_len) { - stats->status = CTL_SS_NEED_MORE_SPACE; - stats->num_luns = softc->num_luns; - break; - } /* * XXX KDM no locking here. If the LUN list changes, * things can blow up. */ i = 0; + stats->status = CTL_SS_OK; + stats->fill_len = 0; STAILQ_FOREACH(lun, &softc->lun_list, links) { - retval = copyout(&lun->stats, &stats->lun_stats[i++], - sizeof(lun->stats)); + if (stats->fill_len + sizeof(lun->legacy_stats) > + stats->alloc_len) { + stats->status = CTL_SS_NEED_MORE_SPACE; + break; + } + retval = copyout(&lun->legacy_stats, &stats->lun_stats[i++], + sizeof(lun->legacy_stats)); if (retval != 0) break; + stats->fill_len += sizeof(lun->legacy_stats); } stats->num_luns = softc->num_luns; - stats->fill_len = sizeof(struct ctl_lun_io_stats) * - softc->num_luns; - stats->status = CTL_SS_OK; -#ifdef CTL_TIME_IO - stats->flags = CTL_STATS_FLAG_TIME_VALID; -#else stats->flags = CTL_STATS_FLAG_NONE; +#ifdef CTL_TIME_IO + stats->flags |= CTL_STATS_FLAG_TIME_VALID; #endif getnanouptime(&stats->timestamp); break; } +#endif /* CTL_LEGACY_STATS */ case CTL_ERROR_INJECT: { struct ctl_error_desc *err_desc, *new_err_desc; @@ -2823,8 +2836,8 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, bcopy(err_desc, new_err_desc, sizeof(*new_err_desc)); mtx_lock(&softc->ctl_lock); - lun = softc->ctl_luns[err_desc->lun_id]; - if (lun == NULL) { + if (err_desc->lun_id >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[err_desc->lun_id]) == NULL) { mtx_unlock(&softc->ctl_lock); free(new_err_desc, M_CTL); printf("%s: CTL_ERROR_INJECT: invalid LUN %ju\n", @@ -2867,8 +2880,8 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, delete_done = 0; mtx_lock(&softc->ctl_lock); - lun = softc->ctl_luns[delete_desc->lun_id]; - if (lun == NULL) { + if (delete_desc->lun_id >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[delete_desc->lun_id]) == NULL) { mtx_unlock(&softc->ctl_lock); printf("%s: CTL_ERROR_INJECT_DELETE: invalid LUN %ju\n", __func__, (uintmax_t)delete_desc->lun_id); @@ -2897,18 +2910,18 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, break; } case CTL_DUMP_STRUCTS: { - int i, j, k; + int j, k; struct ctl_port *port; struct ctl_frontend *fe; mtx_lock(&softc->ctl_lock); printf("CTL Persistent Reservation information start:\n"); - for (i = 0; i < CTL_MAX_LUNS; i++) { - lun = softc->ctl_luns[i]; - - if ((lun == NULL) - || ((lun->flags & CTL_LUN_DISABLED) != 0)) + STAILQ_FOREACH(lun, &softc->lun_list, links) { + mtx_lock(&lun->lun_lock); + if ((lun->flags & CTL_LUN_DISABLED) != 0) { + mtx_unlock(&lun->lun_lock); continue; + } for (j = 0; j < CTL_MAX_PORTS; j++) { if (lun->pr_keys[j] == NULL) @@ -2916,11 +2929,12 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, for (k = 0; k < CTL_MAX_INIT_PER_PORT; k++){ if (lun->pr_keys[j][k] == 0) continue; - printf(" LUN %d port %d iid %d key " - "%#jx\n", i, j, k, + printf(" LUN %ju port %d iid %d key " + "%#jx\n", lun->lun, j, k, (uintmax_t)lun->pr_keys[j][k]); } } + mtx_unlock(&lun->lun_lock); } printf("CTL Persistent Reservation information end\n"); printf("CTL Ports:\n"); @@ -3301,9 +3315,9 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, if (port->lun_map != NULL) { sbuf_printf(sb, "\t<lun_map>on</lun_map>\n"); - for (j = 0; j < CTL_MAX_LUNS; j++) { + for (j = 0; j < port->lun_map_size; j++) { plun = ctl_lun_map_from_port(port, j); - if (plun >= CTL_MAX_LUNS) + if (plun == UINT32_MAX) continue; sbuf_printf(sb, "\t<lun id=\"%u\">%u</lun>\n", @@ -3371,8 +3385,8 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, } if (port->status & CTL_PORT_STATUS_ONLINE) { STAILQ_FOREACH(lun, &softc->lun_list, links) { - if (ctl_lun_map_to_port(port, lun->lun) >= - CTL_MAX_LUNS) + if (ctl_lun_map_to_port(port, lun->lun) == + UINT32_MAX) continue; mtx_lock(&lun->lun_lock); ctl_est_ua_port(lun, lm->port, -1, @@ -3381,7 +3395,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, } } mtx_unlock(&softc->ctl_lock); // XXX: port_enable sleeps - if (lm->plun < CTL_MAX_LUNS) { + if (lm->plun != UINT32_MAX) { if (lm->lun == UINT32_MAX) retval = ctl_lun_map_unset(port, lm->plun); else if (lm->lun < CTL_MAX_LUNS && @@ -3389,17 +3403,82 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, retval = ctl_lun_map_set(port, lm->plun, lm->lun); else return (ENXIO); - } else if (lm->plun == UINT32_MAX) { + } else { if (lm->lun == UINT32_MAX) retval = ctl_lun_map_deinit(port); else retval = ctl_lun_map_init(port); - } else - return (ENXIO); + } if (port->status & CTL_PORT_STATUS_ONLINE) ctl_isc_announce_port(port); break; } + case CTL_GET_LUN_STATS: { + struct ctl_get_io_stats *stats = (struct ctl_get_io_stats *)addr; + int i; + + /* + * XXX KDM no locking here. If the LUN list changes, + * things can blow up. + */ + i = 0; + stats->status = CTL_SS_OK; + stats->fill_len = 0; + STAILQ_FOREACH(lun, &softc->lun_list, links) { + if (lun->lun < stats->first_item) + continue; + if (stats->fill_len + sizeof(lun->stats) > + stats->alloc_len) { + stats->status = CTL_SS_NEED_MORE_SPACE; + break; + } + retval = copyout(&lun->stats, &stats->stats[i++], + sizeof(lun->stats)); + if (retval != 0) + break; + stats->fill_len += sizeof(lun->stats); + } + stats->num_items = softc->num_luns; + stats->flags = CTL_STATS_FLAG_NONE; +#ifdef CTL_TIME_IO + stats->flags |= CTL_STATS_FLAG_TIME_VALID; +#endif + getnanouptime(&stats->timestamp); + break; + } + case CTL_GET_PORT_STATS: { + struct ctl_get_io_stats *stats = (struct ctl_get_io_stats *)addr; + int i; + + /* + * XXX KDM no locking here. If the LUN list changes, + * things can blow up. + */ + i = 0; + stats->status = CTL_SS_OK; + stats->fill_len = 0; + STAILQ_FOREACH(port, &softc->port_list, links) { + if (port->targ_port < stats->first_item) + continue; + if (stats->fill_len + sizeof(port->stats) > + stats->alloc_len) { + stats->status = CTL_SS_NEED_MORE_SPACE; + break; + } + retval = copyout(&port->stats, &stats->stats[i++], + sizeof(port->stats)); + if (retval != 0) + break; + stats->fill_len += sizeof(port->stats); + } + stats->num_items = softc->num_ports; + stats->flags = CTL_STATS_FLAG_NONE; +#ifdef CTL_TIME_IO + stats->flags |= CTL_STATS_FLAG_TIME_VALID; +#endif + getnanouptime(&stats->timestamp); + break; + } default: { /* XXX KDM should we fix this? */ #if 0 @@ -3448,15 +3527,20 @@ ctl_lun_map_init(struct ctl_port *port) { struct ctl_softc *softc = port->ctl_softc; struct ctl_lun *lun; + int size = ctl_lun_map_size; uint32_t i; - if (port->lun_map == NULL) - port->lun_map = malloc(sizeof(uint32_t) * CTL_MAX_LUNS, + if (port->lun_map == NULL || port->lun_map_size < size) { + port->lun_map_size = 0; + free(port->lun_map, M_CTL); + port->lun_map = malloc(size * sizeof(uint32_t), M_CTL, M_NOWAIT); + } if (port->lun_map == NULL) return (ENOMEM); - for (i = 0; i < CTL_MAX_LUNS; i++) + for (i = 0; i < size; i++) port->lun_map[i] = UINT32_MAX; + port->lun_map_size = size; if (port->status & CTL_PORT_STATUS_ONLINE) { if (port->lun_disable != NULL) { STAILQ_FOREACH(lun, &softc->lun_list, links) @@ -3475,6 +3559,7 @@ ctl_lun_map_deinit(struct ctl_port *port) if (port->lun_map == NULL) return (0); + port->lun_map_size = 0; free(port->lun_map, M_CTL); port->lun_map = NULL; if (port->status & CTL_PORT_STATUS_ONLINE) { @@ -3498,9 +3583,11 @@ ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun) if (status != 0) return (status); } + if (plun >= port->lun_map_size) + return (EINVAL); old = port->lun_map[plun]; port->lun_map[plun] = glun; - if ((port->status & CTL_PORT_STATUS_ONLINE) && old >= CTL_MAX_LUNS) { + if ((port->status & CTL_PORT_STATUS_ONLINE) && old == UINT32_MAX) { if (port->lun_enable != NULL) port->lun_enable(port->targ_lun_arg, plun); ctl_isc_announce_port(port); @@ -3513,11 +3600,11 @@ ctl_lun_map_unset(struct ctl_port *port, uint32_t plun) { uint32_t old; - if (port->lun_map == NULL) + if (port->lun_map == NULL || plun >= port->lun_map_size) return (0); old = port->lun_map[plun]; port->lun_map[plun] = UINT32_MAX; - if ((port->status & CTL_PORT_STATUS_ONLINE) && old < CTL_MAX_LUNS) { + if ((port->status & CTL_PORT_STATUS_ONLINE) && old != UINT32_MAX) { if (port->lun_disable != NULL) port->lun_disable(port->targ_lun_arg, plun); ctl_isc_announce_port(port); @@ -3531,8 +3618,10 @@ ctl_lun_map_from_port(struct ctl_port *port, uint32_t lun_id) if (port == NULL) return (UINT32_MAX); - if (port->lun_map == NULL || lun_id >= CTL_MAX_LUNS) + if (port->lun_map == NULL) return (lun_id); + if (lun_id > port->lun_map_size) + return (UINT32_MAX); return (port->lun_map[lun_id]); } @@ -3545,7 +3634,7 @@ ctl_lun_map_to_port(struct ctl_port *port, uint32_t lun_id) return (UINT32_MAX); if (port->lun_map == NULL) return (lun_id); - for (i = 0; i < CTL_MAX_LUNS; i++) { + for (i = 0; i < port->lun_map_size; i++) { if (port->lun_map[i] == lun_id) return (i); } @@ -3613,13 +3702,6 @@ ctl_encode_lun(uint32_t decoded) return ((((uint64_t)RPL_LUNDATA_ATYP_EXTLUN | 0x22) << 56) | (l << 16)); } -static struct ctl_port * -ctl_io_port(struct ctl_io_hdr *io_hdr) -{ - - return (control_softc->ctl_ports[io_hdr->nexus.targ_port]); -} - int ctl_ffz(uint32_t *mask, uint32_t first, uint32_t last) { @@ -3737,7 +3819,6 @@ int ctl_pool_create(struct ctl_softc *ctl_softc, const char *pool_name, uint32_t total_ctl_io, void **npool) { -#ifdef IO_POOLS struct ctl_io_pool *pool; pool = (struct ctl_io_pool *)malloc(sizeof(*pool), M_CTL, @@ -3747,14 +3828,15 @@ ctl_pool_create(struct ctl_softc *ctl_softc, const char *pool_name, snprintf(pool->name, sizeof(pool->name), "CTL IO %s", pool_name); pool->ctl_softc = ctl_softc; +#ifdef IO_POOLS pool->zone = uma_zsecond_create(pool->name, NULL, NULL, NULL, NULL, ctl_softc->io_zone); /* uma_prealloc(pool->zone, total_ctl_io); */ - - *npool = pool; #else - *npool = ctl_softc->io_zone; + pool->zone = ctl_softc->io_zone; #endif + + *npool = pool; return (0); } @@ -3767,64 +3849,54 @@ ctl_pool_free(struct ctl_io_pool *pool) #ifdef IO_POOLS uma_zdestroy(pool->zone); - free(pool, M_CTL); #endif + free(pool, M_CTL); } union ctl_io * ctl_alloc_io(void *pool_ref) { - union ctl_io *io; -#ifdef IO_POOLS struct ctl_io_pool *pool = (struct ctl_io_pool *)pool_ref; + union ctl_io *io; io = uma_zalloc(pool->zone, M_WAITOK); -#else - io = uma_zalloc((uma_zone_t)pool_ref, M_WAITOK); -#endif - if (io != NULL) + if (io != NULL) { io->io_hdr.pool = pool_ref; + CTL_SOFTC(io) = pool->ctl_softc; + } return (io); } union ctl_io * ctl_alloc_io_nowait(void *pool_ref) { - union ctl_io *io; -#ifdef IO_POOLS struct ctl_io_pool *pool = (struct ctl_io_pool *)pool_ref; + union ctl_io *io; io = uma_zalloc(pool->zone, M_NOWAIT); -#else - io = uma_zalloc((uma_zone_t)pool_ref, M_NOWAIT); -#endif - if (io != NULL) + if (io != NULL) { io->io_hdr.pool = pool_ref; + CTL_SOFTC(io) = pool->ctl_softc; + } return (io); } void ctl_free_io(union ctl_io *io) { -#ifdef IO_POOLS struct ctl_io_pool *pool; -#endif if (io == NULL) return; -#ifdef IO_POOLS pool = (struct ctl_io_pool *)io->io_hdr.pool; uma_zfree(pool->zone, io); -#else - uma_zfree((uma_zone_t)io->io_hdr.pool, io); -#endif } void ctl_zero_io(union ctl_io *io) { - void *pool_ref; + struct ctl_io_pool *pool; if (io == NULL) return; @@ -3832,9 +3904,10 @@ ctl_zero_io(union ctl_io *io) /* * May need to preserve linked list pointers at some point too. */ - pool_ref = io->io_hdr.pool; + pool = io->io_hdr.pool; memset(io, 0, sizeof(*io)); - io->io_hdr.pool = pool_ref; + io->io_hdr.pool = pool; + CTL_SOFTC(io) = pool->ctl_softc; } int @@ -4400,7 +4473,7 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, struct scsi_vpd_id_descriptor *desc; struct scsi_vpd_id_t10 *t10id; const char *eui, *naa, *scsiname, *uuid, *vendor, *value; - int lun_number, i, lun_malloced; + int lun_number, lun_malloced; int devidlen, idlen1, idlen2 = 0, len; if (be_lun == NULL) @@ -4534,6 +4607,8 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, printf("ctl: requested LUN ID %d is already " "in use\n", be_lun->req_lun_id); } +fail: + free(lun->lun_devid, M_CTL); if (lun->flags & CTL_LUN_MALLOCED) free(lun, M_CTL); be_lun->lun_config_status(be_lun->be_lun, @@ -4546,14 +4621,11 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, if (lun_number == -1) { mtx_unlock(&ctl_softc->ctl_lock); printf("ctl: can't allocate LUN, out of LUNs\n"); - if (lun->flags & CTL_LUN_MALLOCED) - free(lun, M_CTL); - be_lun->lun_config_status(be_lun->be_lun, - CTL_LUN_CONFIG_FAILURE); - return (ENOSPC); + goto fail; } } ctl_set_mask(ctl_softc->ctl_lun_mask, lun_number); + mtx_unlock(&ctl_softc->ctl_lock); mtx_init(&lun->lun_lock, "CTL LUN", NULL, MTX_DEF); lun->lun = lun_number; @@ -4594,6 +4666,10 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, lun->ie_reported = 1; callout_init_mtx(&lun->ie_callout, &lun->lun_lock, 0); ctl_tpc_lun_init(lun); + if (lun->flags & CTL_LUN_REMOVABLE) { + lun->prevent = malloc((CTL_MAX_INITIATORS + 31) / 32 * 4, + M_CTL, M_WAITOK); + } /* * Initialize the mode and log page index. @@ -4601,31 +4677,31 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, ctl_init_page_index(lun); ctl_init_log_page_index(lun); + /* Setup statistics gathering */ +#ifdef CTL_LEGACY_STATS + lun->legacy_stats.device_type = be_lun->lun_type; + lun->legacy_stats.lun_number = lun_number; + lun->legacy_stats.blocksize = be_lun->blocksize; + if (be_lun->blocksize == 0) + lun->legacy_stats.flags = CTL_LUN_STATS_NO_BLOCKSIZE; + for (len = 0; len < CTL_MAX_PORTS; len++) + lun->legacy_stats.ports[len].targ_port = len; +#endif /* CTL_LEGACY_STATS */ + lun->stats.item = lun_number; + /* * Now, before we insert this lun on the lun list, set the lun * inventory changed UA for all other luns. */ + mtx_lock(&ctl_softc->ctl_lock); STAILQ_FOREACH(nlun, &ctl_softc->lun_list, links) { mtx_lock(&nlun->lun_lock); ctl_est_ua_all(nlun, -1, CTL_UA_LUN_CHANGE); mtx_unlock(&nlun->lun_lock); } - STAILQ_INSERT_TAIL(&ctl_softc->lun_list, lun, links); - ctl_softc->ctl_luns[lun_number] = lun; - ctl_softc->num_luns++; - - /* Setup statistics gathering */ - lun->stats.device_type = be_lun->lun_type; - lun->stats.lun_number = lun_number; - lun->stats.blocksize = be_lun->blocksize; - if (be_lun->blocksize == 0) - lun->stats.flags = CTL_LUN_STATS_NO_BLOCKSIZE; - for (i = 0;i < CTL_MAX_PORTS;i++) - lun->stats.ports[i].targ_port = i; - mtx_unlock(&ctl_softc->ctl_lock); lun->be_lun->lun_config_status(lun->be_lun->be_lun, CTL_LUN_CONFIG_OK); @@ -4641,12 +4717,10 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, static int ctl_free_lun(struct ctl_lun *lun) { - struct ctl_softc *softc; + struct ctl_softc *softc = lun->ctl_softc; struct ctl_lun *nlun; int i; - softc = lun->ctl_softc; - mtx_assert(&softc->ctl_lock, MA_OWNED); STAILQ_REMOVE(&softc->lun_list, lun, ctl_lun, links); @@ -4677,6 +4751,7 @@ ctl_free_lun(struct ctl_lun *lun) for (i = 0; i < CTL_MAX_PORTS; i++) free(lun->pr_keys[i], M_CTL); free(lun->write_buffer, M_CTL); + free(lun->prevent, M_CTL); if (lun->flags & CTL_LUN_MALLOCED) free(lun, M_CTL); @@ -4992,18 +5067,13 @@ ctl_config_move_done(union ctl_io *io) if ((io->io_hdr.port_status != 0) && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE || (io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) { - /* - * For hardware error sense keys, the sense key - * specific value is defined to be a retry count, - * but we use it to pass back an internal FETD - * error code. XXX KDM Hopefully the FETD is only - * using 16 bits for an error code, since that's - * all the space we have in the sks field. - */ - ctl_set_internal_failure(&io->scsiio, - /*sks_valid*/ 1, - /*retry_count*/ - io->io_hdr.port_status); + ctl_set_internal_failure(&io->scsiio, /*sks_valid*/ 1, + /*retry_count*/ io->io_hdr.port_status); + } else if (io->scsiio.kern_data_resid != 0 && + (io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_OUT && + ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE || + (io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) { + ctl_set_invalid_field_ciu(&io->scsiio); } if (ctl_debug & CTL_DEBUG_CDB_DATA) @@ -5147,13 +5217,12 @@ ctl_config_read_done(union ctl_io *io) int ctl_scsi_release(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); uint32_t residx; CTL_DEBUG_PRINT(("ctl_scsi_release\n")); residx = ctl_get_initindex(&ctsio->io_hdr.nexus); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; /* * XXX KDM right now, we only support LUN reservation. We don't @@ -5185,13 +5254,12 @@ ctl_scsi_release(struct ctl_scsiio *ctsio) int ctl_scsi_reserve(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); uint32_t residx; CTL_DEBUG_PRINT(("ctl_reserve\n")); residx = ctl_get_initindex(&ctsio->io_hdr.nexus); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; /* * XXX KDM right now, we only support LUN reservation. We don't @@ -5226,13 +5294,12 @@ bailout: int ctl_start_stop(struct ctl_scsiio *ctsio) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_start_stop_unit *cdb; - struct ctl_lun *lun; int retval; CTL_DEBUG_PRINT(("ctl_start_stop\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_start_stop_unit *)ctsio->cdb; if ((cdb->how & SSS_PC_MASK) == 0) { @@ -5281,17 +5348,16 @@ ctl_start_stop(struct ctl_scsiio *ctsio) int ctl_prevent_allow(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_prevent *cdb; int retval; uint32_t initidx; CTL_DEBUG_PRINT(("ctl_prevent_allow\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_prevent *)ctsio->cdb; - if ((lun->flags & CTL_LUN_REMOVABLE) == 0) { + if ((lun->flags & CTL_LUN_REMOVABLE) == 0 || lun->prevent == NULL) { ctl_set_invalid_opcode(ctsio); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); @@ -5322,8 +5388,7 @@ ctl_prevent_allow(struct ctl_scsiio *ctsio) int ctl_sync_cache(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; - struct ctl_softc *softc; + struct ctl_lun *lun = CTL_LUN(ctsio); struct ctl_lba_len_flags *lbalen; uint64_t starting_lba; uint32_t block_count; @@ -5332,8 +5397,6 @@ ctl_sync_cache(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_sync_cache\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - softc = lun->ctl_softc; retval = 0; switch (ctsio->cdb[0]) { @@ -5389,13 +5452,10 @@ int ctl_format(struct ctl_scsiio *ctsio) { struct scsi_format *cdb; - struct ctl_lun *lun; int length, defect_list_len; CTL_DEBUG_PRINT(("ctl_format\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - cdb = (struct scsi_format *)ctsio->cdb; length = 0; @@ -5411,7 +5471,6 @@ ctl_format(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(length, M_CTL, M_WAITOK); ctsio->kern_data_len = length; ctsio->kern_total_len = length; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -5474,7 +5533,7 @@ bailout: int ctl_read_buffer(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); uint64_t buffer_offset; uint32_t len; uint8_t byte2; @@ -5482,7 +5541,7 @@ ctl_read_buffer(struct ctl_scsiio *ctsio) static uint8_t echo_descr[4] = { 0 }; CTL_DEBUG_PRINT(("ctl_read_buffer\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + switch (ctsio->cdb[0]) { case READ_BUFFER: { struct scsi_read_buffer *cdb; @@ -5537,7 +5596,6 @@ ctl_read_buffer(struct ctl_scsiio *ctsio) } ctsio->kern_data_len = len; ctsio->kern_total_len = len; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctl_set_success(ctsio); @@ -5549,13 +5607,12 @@ ctl_read_buffer(struct ctl_scsiio *ctsio) int ctl_write_buffer(struct ctl_scsiio *ctsio) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_write_buffer *cdb; - struct ctl_lun *lun; int buffer_offset, len; CTL_DEBUG_PRINT(("ctl_write_buffer\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_write_buffer *)ctsio->cdb; len = scsi_3btoul(cdb->length); @@ -5584,7 +5641,6 @@ ctl_write_buffer(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = lun->write_buffer + buffer_offset; ctsio->kern_data_len = len; ctsio->kern_total_len = len; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -5602,7 +5658,7 @@ ctl_write_buffer(struct ctl_scsiio *ctsio) int ctl_write_same(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct ctl_lba_len_flags *lbalen; uint64_t lba; uint32_t num_blocks; @@ -5611,8 +5667,6 @@ ctl_write_same(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_write_same\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - switch (ctsio->cdb[0]) { case WRITE_SAME_10: { struct scsi_write_same_10 *cdb; @@ -5694,7 +5748,6 @@ ctl_write_same(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK); ctsio->kern_data_len = len; ctsio->kern_total_len = len; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -5716,7 +5769,7 @@ ctl_write_same(struct ctl_scsiio *ctsio) int ctl_unmap(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_unmap *cdb; struct ctl_ptr_len_flags *ptrlen; struct scsi_unmap_header *hdr; @@ -5728,9 +5781,7 @@ ctl_unmap(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_unmap\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_unmap *)ctsio->cdb; - len = scsi_2btoul(cdb->length); byte2 = cdb->byte2; @@ -5742,7 +5793,6 @@ ctl_unmap(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK); ctsio->kern_data_len = len; ctsio->kern_total_len = len; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -5820,24 +5870,20 @@ int ctl_default_page_handler(struct ctl_scsiio *ctsio, struct ctl_page_index *page_index, uint8_t *page_ptr) { - struct ctl_lun *lun; - uint8_t *current_cp, *saved_cp; + struct ctl_lun *lun = CTL_LUN(ctsio); + uint8_t *current_cp; int set_ua; uint32_t initidx; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; initidx = ctl_get_initindex(&ctsio->io_hdr.nexus); set_ua = 0; current_cp = (page_index->page_data + (page_index->page_len * CTL_PAGE_CURRENT)); - saved_cp = (page_index->page_data + (page_index->page_len * - CTL_PAGE_SAVED)); mtx_lock(&lun->lun_lock); if (memcmp(current_cp, page_ptr, page_index->page_len)) { memcpy(current_cp, page_ptr, page_index->page_len); - memcpy(saved_cp, page_ptr, page_index->page_len); set_ua = 1; } if (set_ua != 0) @@ -5878,13 +5924,12 @@ int ctl_ie_page_handler(struct ctl_scsiio *ctsio, struct ctl_page_index *page_index, uint8_t *page_ptr) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_info_exceptions_page *pg; - struct ctl_lun *lun; uint64_t t; (void)ctl_default_page_handler(ctsio, page_index, page_ptr); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; pg = (struct scsi_info_exceptions_page *)page_ptr; mtx_lock(&lun->lun_lock); if (pg->info_flags & SIEP_FLAGS_TEST) { @@ -5921,19 +5966,18 @@ ctl_ie_page_handler(struct ctl_scsiio *ctsio, static int ctl_do_mode_select(union ctl_io *io) { + struct ctl_lun *lun = CTL_LUN(io); struct scsi_mode_page_header *page_header; struct ctl_page_index *page_index; struct ctl_scsiio *ctsio; int page_len, page_len_offset, page_len_size; union ctl_modepage_info *modepage_info; - struct ctl_lun *lun; - int *len_left, *len_used; + uint16_t *len_left, *len_used; int retval, i; ctsio = &io->scsiio; page_index = NULL; page_len = 0; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; modepage_info = (union ctl_modepage_info *) ctsio->io_hdr.ctl_private[CTL_PRIV_MODEPAGE].bytes; @@ -6146,10 +6190,12 @@ bailout_no_done: int ctl_mode_select(struct ctl_scsiio *ctsio) { - int param_len, pf, sp; - int header_size, bd_len; + struct ctl_lun *lun = CTL_LUN(ctsio); union ctl_modepage_info *modepage_info; + int bd_len, i, header_size, param_len, pf, rtd, sp; + uint32_t initidx; + initidx = ctl_get_initindex(&ctsio->io_hdr.nexus); switch (ctsio->cdb[0]) { case MODE_SELECT_6: { struct scsi_mode_select_6 *cdb; @@ -6157,6 +6203,7 @@ ctl_mode_select(struct ctl_scsiio *ctsio) cdb = (struct scsi_mode_select_6 *)ctsio->cdb; pf = (cdb->byte2 & SMS_PF) ? 1 : 0; + rtd = (cdb->byte2 & SMS_RTD) ? 1 : 0; sp = (cdb->byte2 & SMS_SP) ? 1 : 0; param_len = cdb->length; header_size = sizeof(struct scsi_mode_header_6); @@ -6168,6 +6215,7 @@ ctl_mode_select(struct ctl_scsiio *ctsio) cdb = (struct scsi_mode_select_10 *)ctsio->cdb; pf = (cdb->byte2 & SMS_PF) ? 1 : 0; + rtd = (cdb->byte2 & SMS_RTD) ? 1 : 0; sp = (cdb->byte2 & SMS_SP) ? 1 : 0; param_len = scsi_2btoul(cdb->length); header_size = sizeof(struct scsi_mode_header_10); @@ -6179,6 +6227,30 @@ ctl_mode_select(struct ctl_scsiio *ctsio) return (CTL_RETVAL_COMPLETE); } + if (rtd) { + if (param_len != 0) { + ctl_set_invalid_field(ctsio, /*sks_valid*/ 0, + /*command*/ 1, /*field*/ 0, + /*bit_valid*/ 0, /*bit*/ 0); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + + /* Revert to defaults. */ + ctl_init_page_index(lun); + mtx_lock(&lun->lun_lock); + ctl_est_ua_all(lun, initidx, CTL_UA_MODE_CHANGE); + mtx_unlock(&lun->lun_lock); + for (i = 0; i < CTL_NUM_MODE_PAGES; i++) { + ctl_isc_announce_mode(lun, -1, + lun->mode_pages.index[i].page_code & SMPH_PC_MASK, + lun->mode_pages.index[i].subpage); + } + ctl_set_success(ctsio); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + /* * From SPC-3: * "A parameter list length of zero indicates that the Data-Out Buffer @@ -6210,7 +6282,6 @@ ctl_mode_select(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(param_len, M_CTL, M_WAITOK); ctsio->kern_data_len = param_len; ctsio->kern_total_len = param_len; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -6267,7 +6338,7 @@ ctl_mode_select(struct ctl_scsiio *ctsio) int ctl_mode_sense(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); int pc, page_code, dbd, llba, subpage; int alloc_len, page_len, header_len, total_len; struct scsi_mode_block_descr *block_desc; @@ -6279,7 +6350,6 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_mode_sense\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; switch (ctsio->cdb[0]) { case MODE_SENSE_6: { struct scsi_mode_sense_6 *cdb; @@ -6441,17 +6511,9 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); ctsio->kern_sg_entries = 0; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; switch (ctsio->cdb[0]) { case MODE_SENSE_6: { @@ -6615,12 +6677,11 @@ ctl_lbp_log_sense_handler(struct ctl_scsiio *ctsio, struct ctl_page_index *page_index, int pc) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_log_param_header *phdr; uint8_t *data; uint64_t val; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; data = page_index->page_data; if (lun->backend->lun_attr != NULL && @@ -6684,41 +6745,31 @@ ctl_sap_log_sense_handler(struct ctl_scsiio *ctsio, struct ctl_page_index *page_index, int pc) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct stat_page *data; - uint64_t rn, wn, rb, wb; - struct bintime rt, wt; - int i; + struct bintime *t; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; data = (struct stat_page *)page_index->page_data; scsi_ulto2b(SLP_SAP, data->sap.hdr.param_code); data->sap.hdr.param_control = SLP_LBIN; data->sap.hdr.param_len = sizeof(struct scsi_log_stat_and_perf) - sizeof(struct scsi_log_param_header); - rn = wn = rb = wb = 0; - bintime_clear(&rt); - bintime_clear(&wt); - for (i = 0; i < CTL_MAX_PORTS; i++) { - rn += lun->stats.ports[i].operations[CTL_STATS_READ]; - wn += lun->stats.ports[i].operations[CTL_STATS_WRITE]; - rb += lun->stats.ports[i].bytes[CTL_STATS_READ]; - wb += lun->stats.ports[i].bytes[CTL_STATS_WRITE]; - bintime_add(&rt, &lun->stats.ports[i].time[CTL_STATS_READ]); - bintime_add(&wt, &lun->stats.ports[i].time[CTL_STATS_WRITE]); - } - scsi_u64to8b(rn, data->sap.read_num); - scsi_u64to8b(wn, data->sap.write_num); - if (lun->stats.blocksize > 0) { - scsi_u64to8b(wb / lun->stats.blocksize, - data->sap.recvieved_lba); - scsi_u64to8b(rb / lun->stats.blocksize, - data->sap.transmitted_lba); - } - scsi_u64to8b((uint64_t)rt.sec * 1000 + rt.frac / (UINT64_MAX / 1000), + scsi_u64to8b(lun->stats.operations[CTL_STATS_READ], + data->sap.read_num); + scsi_u64to8b(lun->stats.operations[CTL_STATS_WRITE], + data->sap.write_num); + if (lun->be_lun->blocksize > 0) { + scsi_u64to8b(lun->stats.bytes[CTL_STATS_WRITE] / + lun->be_lun->blocksize, data->sap.recvieved_lba); + scsi_u64to8b(lun->stats.bytes[CTL_STATS_READ] / + lun->be_lun->blocksize, data->sap.transmitted_lba); + } + t = &lun->stats.time[CTL_STATS_READ]; + scsi_u64to8b((uint64_t)t->sec * 1000 + t->frac / (UINT64_MAX / 1000), data->sap.read_int); - scsi_u64to8b((uint64_t)wt.sec * 1000 + wt.frac / (UINT64_MAX / 1000), + t = &lun->stats.time[CTL_STATS_WRITE]; + scsi_u64to8b((uint64_t)t->sec * 1000 + t->frac / (UINT64_MAX / 1000), data->sap.write_int); scsi_u64to8b(0, data->sap.weighted_num); scsi_u64to8b(0, data->sap.weighted_int); @@ -6743,10 +6794,9 @@ ctl_ie_log_sense_handler(struct ctl_scsiio *ctsio, struct ctl_page_index *page_index, int pc) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_log_informational_exceptions *data; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; data = (struct scsi_log_informational_exceptions *)page_index->page_data; scsi_ulto2b(SLP_IE_GEN, data->hdr.param_code); @@ -6762,7 +6812,7 @@ ctl_ie_log_sense_handler(struct ctl_scsiio *ctsio, int ctl_log_sense(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); int i, pc, page_code, subpage; int alloc_len, total_len; struct ctl_page_index *page_index; @@ -6771,7 +6821,6 @@ ctl_log_sense(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_log_sense\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_log_sense *)ctsio->cdb; pc = (cdb->page & SLS_PAGE_CTRL_MASK) >> 6; page_code = cdb->page & SLS_PAGE_CODE; @@ -6807,17 +6856,9 @@ ctl_log_sense(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); ctsio->kern_sg_entries = 0; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; header = (struct scsi_log_header *)ctsio->kern_data_ptr; header->page = page_index->page_code; @@ -6848,9 +6889,9 @@ ctl_log_sense(struct ctl_scsiio *ctsio) int ctl_read_capacity(struct ctl_scsiio *ctsio) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_read_capacity *cdb; struct scsi_read_capacity_data *data; - struct ctl_lun *lun; uint32_t lba; CTL_DEBUG_PRINT(("ctl_read_capacity\n")); @@ -6870,14 +6911,10 @@ ctl_read_capacity(struct ctl_scsiio *ctsio) return (CTL_RETVAL_COMPLETE); } - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctsio->kern_data_ptr = malloc(sizeof(*data), M_CTL, M_WAITOK | M_ZERO); data = (struct scsi_read_capacity_data *)ctsio->kern_data_ptr; - ctsio->residual = 0; ctsio->kern_data_len = sizeof(*data); ctsio->kern_total_len = sizeof(*data); - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; @@ -6906,9 +6943,9 @@ ctl_read_capacity(struct ctl_scsiio *ctsio) int ctl_read_capacity_16(struct ctl_scsiio *ctsio) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_read_capacity_16 *cdb; struct scsi_read_capacity_data_long *data; - struct ctl_lun *lun; uint64_t lba; uint32_t alloc_len; @@ -6931,23 +6968,12 @@ ctl_read_capacity_16(struct ctl_scsiio *ctsio) return (CTL_RETVAL_COMPLETE); } - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctsio->kern_data_ptr = malloc(sizeof(*data), M_CTL, M_WAITOK | M_ZERO); data = (struct scsi_read_capacity_data_long *)ctsio->kern_data_ptr; - - if (sizeof(*data) < alloc_len) { - ctsio->residual = alloc_len - sizeof(*data); - ctsio->kern_data_len = sizeof(*data); - ctsio->kern_total_len = sizeof(*data); - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(sizeof(*data), alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; scsi_u64to8b(lun->be_lun->maxlba, data->addr); /* XXX KDM this may not be 512 bytes... */ @@ -6967,9 +6993,9 @@ ctl_read_capacity_16(struct ctl_scsiio *ctsio) int ctl_get_lba_status(struct ctl_scsiio *ctsio) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_get_lba_status *cdb; struct scsi_get_lba_status_data *data; - struct ctl_lun *lun; struct ctl_lba_len_flags *lbalen; uint64_t lba; uint32_t alloc_len, total_len; @@ -6977,7 +7003,6 @@ ctl_get_lba_status(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_get_lba_status\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_get_lba_status *)ctsio->cdb; lba = scsi_8btou64(cdb->addr); alloc_len = scsi_4btoul(cdb->alloc_len); @@ -6991,19 +7016,10 @@ ctl_get_lba_status(struct ctl_scsiio *ctsio) total_len = sizeof(*data) + sizeof(data->descr[0]); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); data = (struct scsi_get_lba_status_data *)ctsio->kern_data_ptr; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* Fill dummy data in case backend can't tell anything. */ scsi_ulto4b(4 + sizeof(data->descr[0]), data->length); @@ -7054,18 +7070,10 @@ ctl_read_defect(struct ctl_scsiio *ctsio) } ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; if (ctsio->cdb[0] == READ_DEFECT_DATA_10) { data10 = (struct scsi_read_defect_data_hdr_10 *) @@ -7090,12 +7098,12 @@ ctl_read_defect(struct ctl_scsiio *ctsio) int ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) { + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_maintenance_in *cdb; int retval; int alloc_len, ext, total_len = 0, g, pc, pg, ts, os; int num_ha_groups, num_target_ports, shared_group; - struct ctl_lun *lun; - struct ctl_softc *softc; struct ctl_port *port; struct scsi_target_group_data *rtg_ptr; struct scsi_target_group_data_extended *rtg_ext_ptr; @@ -7104,9 +7112,6 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_report_tagret_port_groups\n")); cdb = (struct scsi_maintenance_in *)ctsio->cdb; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - softc = lun->ctl_softc; - retval = CTL_RETVAL_COMPLETE; switch (cdb->byte2 & STG_PDF_MASK) { @@ -7133,7 +7138,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) STAILQ_FOREACH(port, &softc->port_list, links) { if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; - if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + if (ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX) continue; num_target_ports++; if (port->status & CTL_PORT_STATUS_HA_SHARED) @@ -7153,20 +7158,10 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) alloc_len = scsi_4btoul(cdb->length); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - ctsio->kern_sg_entries = 0; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; if (ext) { rtg_ext_ptr = (struct scsi_target_group_data_extended *) @@ -7225,7 +7220,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) if (!softc->is_single && (port->status & CTL_PORT_STATUS_HA_SHARED) == 0) continue; - if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + if (ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX) continue; scsi_ulto2b(port->targ_port, tpg_desc->descriptors[pc]. relative_target_port_identifier); @@ -7250,7 +7245,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) continue; if (port->status & CTL_PORT_STATUS_HA_SHARED) continue; - if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + if (ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX) continue; scsi_ulto2b(port->targ_port, tpg_desc->descriptors[pc]. relative_target_port_identifier); @@ -7272,7 +7267,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) int ctl_report_supported_opcodes(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_report_supported_opcodes *cdb; const struct ctl_cmd_entry *entry, *sentry; struct scsi_report_supported_opcodes_all *all; @@ -7285,8 +7280,6 @@ ctl_report_supported_opcodes(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_report_supported_opcodes\n")); cdb = (struct scsi_report_supported_opcodes *)ctsio->cdb; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - retval = CTL_RETVAL_COMPLETE; opcode = cdb->requested_opcode; @@ -7356,20 +7349,10 @@ ctl_report_supported_opcodes(struct ctl_scsiio *ctsio) alloc_len = scsi_4btoul(cdb->length); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - ctsio->kern_sg_entries = 0; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; switch (cdb->options & RSO_OPTIONS_MASK) { case RSO_OPTIONS_ALL: @@ -7470,20 +7453,10 @@ ctl_report_supported_tmf(struct ctl_scsiio *ctsio) alloc_len = scsi_4btoul(cdb->length); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - ctsio->kern_sg_entries = 0; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; data = (struct scsi_report_supported_tmf_ext_data *)ctsio->kern_data_ptr; data->byte1 |= RST_ATS | RST_ATSS | RST_CTSS | RST_LURS | RST_QTS | @@ -7518,20 +7491,10 @@ ctl_report_timestamp(struct ctl_scsiio *ctsio) alloc_len = scsi_4btoul(cdb->length); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - ctsio->kern_sg_entries = 0; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; data = (struct scsi_report_timestamp_data *)ctsio->kern_data_ptr; scsi_ulto2b(sizeof(*data) - 2, data->length); @@ -7551,11 +7514,11 @@ ctl_report_timestamp(struct ctl_scsiio *ctsio) int ctl_persistent_reserve_in(struct ctl_scsiio *ctsio) { + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_per_res_in *cdb; int alloc_len, total_len = 0; /* struct scsi_per_res_in_rsrv in_data; */ - struct ctl_lun *lun; - struct ctl_softc *softc; uint64_t key; CTL_DEBUG_PRINT(("ctl_persistent_reserve_in\n")); @@ -7564,9 +7527,6 @@ ctl_persistent_reserve_in(struct ctl_scsiio *ctsio) alloc_len = scsi_2btoul(cdb->length); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - softc = lun->ctl_softc; - retry: mtx_lock(&lun->lun_lock); switch (cdb->action) { @@ -7595,20 +7555,10 @@ retry: mtx_unlock(&lun->lun_lock); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; mtx_lock(&lun->lun_lock); switch (cdb->action) { @@ -8129,12 +8079,12 @@ ctl_pro_preempt_other(struct ctl_lun *lun, union ctl_ha_msg *msg) int ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) { + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_lun *lun = CTL_LUN(ctsio); int retval; u_int32_t param_len; struct scsi_per_res_out *cdb; - struct ctl_lun *lun; struct scsi_per_res_out_parms* param; - struct ctl_softc *softc; uint32_t residx; uint64_t res_key, sa_res_key, key; uint8_t type; @@ -8143,11 +8093,8 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_persistent_reserve_out\n")); - retval = CTL_RETVAL_COMPLETE; - cdb = (struct scsi_per_res_out *)ctsio->cdb; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - softc = lun->ctl_softc; + retval = CTL_RETVAL_COMPLETE; /* * We only support whole-LUN scope. The scope & type are ignored for @@ -8187,7 +8134,6 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(param_len, M_CTL, M_WAITOK); ctsio->kern_data_len = param_len; ctsio->kern_total_len = param_len; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -8521,17 +8467,18 @@ done: * in sync. */ static void -ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) +ctl_hndl_per_res_out_on_other_sc(union ctl_io *io) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(io); + union ctl_ha_msg *msg = (union ctl_ha_msg *)&io->presio.pr_msg; struct ctl_lun *lun; int i; uint32_t residx, targ_lun; targ_lun = msg->hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); - if ((targ_lun >= CTL_MAX_LUNS) || - ((lun = softc->ctl_luns[targ_lun]) == NULL)) { + if (targ_lun >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[targ_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); return; } @@ -8642,15 +8589,13 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) int ctl_read_write(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct ctl_lba_len_flags *lbalen; uint64_t lba; uint32_t num_blocks; int flags, retval; int isread; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - CTL_DEBUG_PRINT(("ctl_read_write: command: %#x\n", ctsio->cdb[0])); flags = 0; @@ -8835,15 +8780,14 @@ ctl_read_write(struct ctl_scsiio *ctsio) static int ctl_cnw_cont(union ctl_io *io) { + struct ctl_lun *lun = CTL_LUN(io); struct ctl_scsiio *ctsio; - struct ctl_lun *lun; struct ctl_lba_len_flags *lbalen; int retval; ctsio = &io->scsiio; ctsio->io_hdr.status = CTL_STATUS_NONE; ctsio->io_hdr.flags &= ~CTL_FLAG_IO_CONT; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; lbalen = (struct ctl_lba_len_flags *) &ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; lbalen->flags &= ~CTL_LLF_COMPARE; @@ -8857,14 +8801,12 @@ ctl_cnw_cont(union ctl_io *io) int ctl_cnw(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct ctl_lba_len_flags *lbalen; uint64_t lba; uint32_t num_blocks; int flags, retval; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - CTL_DEBUG_PRINT(("ctl_cnw: command: %#x\n", ctsio->cdb[0])); flags = 0; @@ -8945,15 +8887,13 @@ ctl_cnw(struct ctl_scsiio *ctsio) int ctl_verify(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct ctl_lba_len_flags *lbalen; uint64_t lba; uint32_t num_blocks; int bytchk, flags; int retval; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - CTL_DEBUG_PRINT(("ctl_verify: command: %#x\n", ctsio->cdb[0])); bytchk = 0; @@ -9049,27 +8989,25 @@ ctl_verify(struct ctl_scsiio *ctsio) int ctl_report_luns(struct ctl_scsiio *ctsio) { - struct ctl_softc *softc; + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_port *port = CTL_PORT(ctsio); + struct ctl_lun *lun, *request_lun = CTL_LUN(ctsio); struct scsi_report_luns *cdb; struct scsi_report_luns_data *lun_data; - struct ctl_lun *lun, *request_lun; - struct ctl_port *port; - int num_luns, retval; + int num_filled, num_luns, num_port_luns, retval; uint32_t alloc_len, lun_datalen; - int num_filled; uint32_t initidx, targ_lun_id, lun_id; retval = CTL_RETVAL_COMPLETE; cdb = (struct scsi_report_luns *)ctsio->cdb; - port = ctl_io_port(&ctsio->io_hdr); - softc = port->ctl_softc; CTL_DEBUG_PRINT(("ctl_report_luns\n")); - mtx_lock(&softc->ctl_lock); num_luns = 0; - for (targ_lun_id = 0; targ_lun_id < CTL_MAX_LUNS; targ_lun_id++) { - if (ctl_lun_map_from_port(port, targ_lun_id) < CTL_MAX_LUNS) + num_port_luns = port->lun_map ? port->lun_map_size : CTL_MAX_LUNS; + mtx_lock(&softc->ctl_lock); + for (targ_lun_id = 0; targ_lun_id < num_port_luns; targ_lun_id++) { + if (ctl_lun_map_from_port(port, targ_lun_id) != UINT32_MAX) num_luns++; } mtx_unlock(&softc->ctl_lock); @@ -9114,9 +9052,6 @@ ctl_report_luns(struct ctl_scsiio *ctsio) return (retval); } - request_lun = (struct ctl_lun *) - ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - lun_datalen = sizeof(*lun_data) + (num_luns * sizeof(struct scsi_report_luns_lundata)); @@ -9127,9 +9062,11 @@ ctl_report_luns(struct ctl_scsiio *ctsio) initidx = ctl_get_initindex(&ctsio->io_hdr.nexus); mtx_lock(&softc->ctl_lock); - for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) { + for (targ_lun_id = 0, num_filled = 0; + targ_lun_id < num_port_luns && num_filled < num_luns; + targ_lun_id++) { lun_id = ctl_lun_map_from_port(port, targ_lun_id); - if (lun_id >= CTL_MAX_LUNS) + if (lun_id == UINT32_MAX) continue; lun = softc->ctl_luns[lun_id]; if (lun == NULL) @@ -9168,19 +9105,10 @@ ctl_report_luns(struct ctl_scsiio *ctsio) */ lun_datalen = sizeof(*lun_data) + (num_filled * sizeof(struct scsi_report_luns_lundata)); - - if (lun_datalen < alloc_len) { - ctsio->residual = alloc_len - lun_datalen; - ctsio->kern_data_len = lun_datalen; - ctsio->kern_total_len = lun_datalen; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(lun_datalen, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * We set this to the actual data length, regardless of how much @@ -9205,10 +9133,10 @@ ctl_report_luns(struct ctl_scsiio *ctsio) int ctl_request_sense(struct ctl_scsiio *ctsio) { + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_request_sense *cdb; struct scsi_sense_data *sense_ptr; - struct ctl_softc *softc; - struct ctl_lun *lun; uint32_t initidx; int have_error; u_int sense_len = SSD_FULL_SIZE; @@ -9218,9 +9146,6 @@ ctl_request_sense(struct ctl_scsiio *ctsio) cdb = (struct scsi_request_sense *)ctsio->cdb; - softc = control_softc; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - CTL_DEBUG_PRINT(("ctl_request_sense\n")); /* @@ -9234,20 +9159,16 @@ ctl_request_sense(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(sizeof(*sense_ptr), M_CTL, M_WAITOK); sense_ptr = (struct scsi_sense_data *)ctsio->kern_data_ptr; ctsio->kern_sg_entries = 0; + ctsio->kern_rel_offset = 0; /* * struct scsi_sense_data, which is currently set to 256 bytes, is * larger than the largest allowed value for the length field in the * REQUEST SENSE CDB, which is 252 bytes as of SPC-4. */ - ctsio->residual = 0; ctsio->kern_data_len = cdb->length; ctsio->kern_total_len = cdb->length; - ctsio->kern_data_resid = 0; - ctsio->kern_rel_offset = 0; - ctsio->kern_sg_entries = 0; - /* * If we don't have a LUN, we don't have any pending sense. */ @@ -9363,31 +9284,19 @@ ctl_tur(struct ctl_scsiio *ctsio) static int ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_vpd_supported_pages *pages; int sup_page_size; - struct ctl_lun *lun; int p; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - sup_page_size = sizeof(struct scsi_vpd_supported_pages) * SCSI_EVPD_NUM_SUPPORTED_PAGES; ctsio->kern_data_ptr = malloc(sup_page_size, M_CTL, M_WAITOK | M_ZERO); pages = (struct scsi_vpd_supported_pages *)ctsio->kern_data_ptr; - ctsio->kern_sg_entries = 0; - - if (sup_page_size < alloc_len) { - ctsio->residual = alloc_len - sup_page_size; - ctsio->kern_data_len = sup_page_size; - ctsio->kern_total_len = sup_page_size; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(sup_page_size, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * The control device is always connected. The disk device, on the @@ -9438,27 +9347,17 @@ ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len) static int ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_vpd_unit_serial_number *sn_ptr; - struct ctl_lun *lun; int data_len; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - data_len = 4 + CTL_SN_LEN; ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); sn_ptr = (struct scsi_vpd_unit_serial_number *)ctsio->kern_data_ptr; - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * The control device is always connected. The disk device, on the @@ -9497,29 +9396,17 @@ ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len) static int ctl_inquiry_evpd_eid(struct ctl_scsiio *ctsio, int alloc_len) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_vpd_extended_inquiry_data *eid_ptr; - struct ctl_lun *lun; int data_len; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - data_len = sizeof(struct scsi_vpd_extended_inquiry_data); ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); eid_ptr = (struct scsi_vpd_extended_inquiry_data *)ctsio->kern_data_ptr; ctsio->kern_sg_entries = 0; - - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; - ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * The control device is always connected. The disk device, on the @@ -9549,6 +9436,11 @@ ctl_inquiry_evpd_eid(struct ctl_scsiio *ctsio, int alloc_len) eid_ptr->flags4 = SVPD_EID_LUICLR; /* + * We support revert to defaults (RTD) bit in MODE SELECT. + */ + eid_ptr->flags5 = SVPD_EID_RTD_SUP; + + /* * XXX KDM in order to correctly answer this, we would need * information from the SIM to determine how much sense data it * can send. So this would really be a path inquiry field, most @@ -9568,31 +9460,19 @@ ctl_inquiry_evpd_eid(struct ctl_scsiio *ctsio, int alloc_len) static int ctl_inquiry_evpd_mpp(struct ctl_scsiio *ctsio, int alloc_len) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_vpd_mode_page_policy *mpp_ptr; - struct ctl_lun *lun; int data_len; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - data_len = sizeof(struct scsi_vpd_mode_page_policy) + sizeof(struct scsi_vpd_mode_page_policy_descr); ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); mpp_ptr = (struct scsi_vpd_mode_page_policy *)ctsio->kern_data_ptr; - ctsio->kern_sg_entries = 0; - - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * The control device is always connected. The disk device, on the @@ -9622,19 +9502,14 @@ ctl_inquiry_evpd_mpp(struct ctl_scsiio *ctsio, int alloc_len) static int ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len) { + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_port *port = CTL_PORT(ctsio); + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_vpd_device_id *devid_ptr; struct scsi_vpd_id_descriptor *desc; - struct ctl_softc *softc; - struct ctl_lun *lun; - struct ctl_port *port; int data_len, g; uint8_t proto; - softc = control_softc; - - port = ctl_io_port(&ctsio->io_hdr); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - data_len = sizeof(struct scsi_vpd_device_id) + sizeof(struct scsi_vpd_id_descriptor) + sizeof(struct scsi_vpd_id_rel_trgt_port_id) + @@ -9650,19 +9525,10 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len) ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); devid_ptr = (struct scsi_vpd_device_id *)ctsio->kern_data_ptr; ctsio->kern_sg_entries = 0; - - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * The control device is always connected. The disk device, on the @@ -9747,16 +9613,14 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len) static int ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_vpd_scsi_ports *sp; struct scsi_vpd_port_designation *pd; struct scsi_vpd_port_designation_cont *pdc; - struct ctl_lun *lun; struct ctl_port *port; int data_len, num_target_ports, iid_len, id_len; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - num_target_ports = 0; iid_len = 0; id_len = 0; @@ -9765,7 +9629,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len) if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; if (lun != NULL && - ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX) continue; num_target_ports++; if (port->init_devid) @@ -9781,19 +9645,10 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len) ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); sp = (struct scsi_vpd_scsi_ports *)ctsio->kern_data_ptr; ctsio->kern_sg_entries = 0; - - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * The control device is always connected. The disk device, on the @@ -9816,7 +9671,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len) if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; if (lun != NULL && - ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX) continue; scsi_ulto2b(port->targ_port, pd->relative_port_id); if (port->init_devid) { @@ -9850,28 +9705,17 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len) static int ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_vpd_block_limits *bl_ptr; - struct ctl_lun *lun; uint64_t ival; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctsio->kern_data_ptr = malloc(sizeof(*bl_ptr), M_CTL, M_WAITOK | M_ZERO); bl_ptr = (struct scsi_vpd_block_limits *)ctsio->kern_data_ptr; ctsio->kern_sg_entries = 0; - - if (sizeof(*bl_ptr) < alloc_len) { - ctsio->residual = alloc_len - sizeof(*bl_ptr); - ctsio->kern_data_len = sizeof(*bl_ptr); - ctsio->kern_total_len = sizeof(*bl_ptr); - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(sizeof(*bl_ptr), alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * The control device is always connected. The disk device, on the @@ -9927,29 +9771,17 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len) static int ctl_inquiry_evpd_bdc(struct ctl_scsiio *ctsio, int alloc_len) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_vpd_block_device_characteristics *bdc_ptr; - struct ctl_lun *lun; const char *value; u_int i; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctsio->kern_data_ptr = malloc(sizeof(*bdc_ptr), M_CTL, M_WAITOK | M_ZERO); bdc_ptr = (struct scsi_vpd_block_device_characteristics *)ctsio->kern_data_ptr; ctsio->kern_sg_entries = 0; - - if (sizeof(*bdc_ptr) < alloc_len) { - ctsio->residual = alloc_len - sizeof(*bdc_ptr); - ctsio->kern_data_len = sizeof(*bdc_ptr); - ctsio->kern_total_len = sizeof(*bdc_ptr); - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; - ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(sizeof(*bdc_ptr), alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * The control device is always connected. The disk device, on the @@ -9987,28 +9819,16 @@ ctl_inquiry_evpd_bdc(struct ctl_scsiio *ctsio, int alloc_len) static int ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_vpd_logical_block_prov *lbp_ptr; - struct ctl_lun *lun; const char *value; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctsio->kern_data_ptr = malloc(sizeof(*lbp_ptr), M_CTL, M_WAITOK | M_ZERO); lbp_ptr = (struct scsi_vpd_logical_block_prov *)ctsio->kern_data_ptr; ctsio->kern_sg_entries = 0; - - if (sizeof(*lbp_ptr) < alloc_len) { - ctsio->residual = alloc_len - sizeof(*lbp_ptr); - ctsio->kern_data_len = sizeof(*lbp_ptr); - ctsio->kern_total_len = sizeof(*lbp_ptr); - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; - ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(sizeof(*lbp_ptr), alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * The control device is always connected. The disk device, on the @@ -10050,11 +9870,10 @@ ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len) static int ctl_inquiry_evpd(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_inquiry *cdb; int alloc_len, retval; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_inquiry *)ctsio->cdb; alloc_len = scsi_2btoul(cdb->length); @@ -10117,21 +9936,19 @@ err: static int ctl_inquiry_std(struct ctl_scsiio *ctsio) { + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_port *port = CTL_PORT(ctsio); + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_inquiry_data *inq_ptr; struct scsi_inquiry *cdb; - struct ctl_softc *softc = control_softc; - struct ctl_port *port; - struct ctl_lun *lun; char *val; uint32_t alloc_len, data_len; ctl_port_type port_type; - port = ctl_io_port(&ctsio->io_hdr); port_type = port->port_type; if (port_type == CTL_PORT_IOCTL || port_type == CTL_PORT_INTERNAL) port_type = CTL_PORT_SCSI; - lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_inquiry *)ctsio->cdb; alloc_len = scsi_2btoul(cdb->length); @@ -10144,18 +9961,9 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); inq_ptr = (struct scsi_inquiry_data *)ctsio->kern_data_ptr; ctsio->kern_sg_entries = 0; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; - - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; if (lun != NULL) { if ((lun->flags & CTL_LUN_PRIMARY_SC) || @@ -10345,14 +10153,13 @@ ctl_inquiry(struct ctl_scsiio *ctsio) int ctl_get_config(struct ctl_scsiio *ctsio) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_get_config_header *hdr; struct scsi_get_config_feature *feature; struct scsi_get_config *cdb; - struct ctl_lun *lun; uint32_t alloc_len, data_len; int rt, starting; - lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_get_config *)ctsio->cdb; rt = (cdb->rt & SGC_RT_MASK); starting = scsi_2btoul(cdb->starting_feature); @@ -10373,7 +10180,6 @@ ctl_get_config(struct ctl_scsiio *ctsio) sizeof(struct scsi_get_config_feature) + 4; ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); ctsio->kern_sg_entries = 0; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; hdr = (struct scsi_get_config_header *)ctsio->kern_data_ptr; @@ -10541,15 +10347,8 @@ done: data_len = (uint8_t *)feature - (uint8_t *)hdr; } scsi_ulto4b(data_len - 4, hdr->data_length); - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; ctl_set_success(ctsio); ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -10563,11 +10362,9 @@ ctl_get_event_status(struct ctl_scsiio *ctsio) { struct scsi_get_event_status_header *hdr; struct scsi_get_event_status *cdb; - struct ctl_lun *lun; uint32_t alloc_len, data_len; int notif_class; - lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_get_event_status *)ctsio->cdb; if ((cdb->byte2 & SGESN_POLLED) == 0) { ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 1, @@ -10581,18 +10378,9 @@ ctl_get_event_status(struct ctl_scsiio *ctsio) data_len = sizeof(struct scsi_get_event_status_header); ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); ctsio->kern_sg_entries = 0; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; - - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; hdr = (struct scsi_get_event_status_header *)ctsio->kern_data_ptr; scsi_ulto2b(0, hdr->descr_length); @@ -10611,28 +10399,17 @@ ctl_mechanism_status(struct ctl_scsiio *ctsio) { struct scsi_mechanism_status_header *hdr; struct scsi_mechanism_status *cdb; - struct ctl_lun *lun; uint32_t alloc_len, data_len; - lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_mechanism_status *)ctsio->cdb; alloc_len = scsi_2btoul(cdb->length); data_len = sizeof(struct scsi_mechanism_status_header); ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); ctsio->kern_sg_entries = 0; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; - - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; hdr = (struct scsi_mechanism_status_header *)ctsio->kern_data_ptr; hdr->state1 = 0x00; @@ -10662,14 +10439,13 @@ ctl_ultomsf(uint32_t lba, uint8_t *buf) int ctl_read_toc(struct ctl_scsiio *ctsio) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_read_toc_hdr *hdr; struct scsi_read_toc_type01_descr *descr; struct scsi_read_toc *cdb; - struct ctl_lun *lun; uint32_t alloc_len, data_len; int format, msf; - lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_read_toc *)ctsio->cdb; msf = (cdb->byte2 & CD_MSF) != 0; format = cdb->format; @@ -10682,18 +10458,9 @@ ctl_read_toc(struct ctl_scsiio *ctsio) data_len += sizeof(struct scsi_read_toc_type01_descr); ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); ctsio->kern_sg_entries = 0; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; - - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; hdr = (struct scsi_read_toc_hdr *)ctsio->kern_data_ptr; if (format == 0) { @@ -11416,7 +11183,7 @@ ctl_failover_io(union ctl_io *io, int have_lock) static void ctl_failover_lun(union ctl_io *rio) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(rio); struct ctl_lun *lun; struct ctl_io_hdr *io, *next_io; uint32_t targ_lun; @@ -11426,18 +11193,17 @@ ctl_failover_lun(union ctl_io *rio) /* Find and lock the LUN. */ mtx_lock(&softc->ctl_lock); - if ((targ_lun < CTL_MAX_LUNS) && - ((lun = softc->ctl_luns[targ_lun]) != NULL)) { - mtx_lock(&lun->lun_lock); - mtx_unlock(&softc->ctl_lock); - if (lun->flags & CTL_LUN_DISABLED) { - mtx_unlock(&lun->lun_lock); - return; - } - } else { + if (targ_lun > CTL_MAX_LUNS || + (lun = softc->ctl_luns[targ_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); return; } + mtx_lock(&lun->lun_lock); + mtx_unlock(&softc->ctl_lock); + if (lun->flags & CTL_LUN_DISABLED) { + mtx_unlock(&lun->lun_lock); + return; + } if (softc->ha_mode == CTL_HA_MODE_XFER) { TAILQ_FOREACH_SAFE(io, &lun->ooa_queue, ooa_links, next_io) { @@ -11505,15 +11271,13 @@ ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio) struct ctl_lun *lun; const struct ctl_cmd_entry *entry; uint32_t initidx, targ_lun; - int retval; - - retval = 0; + int retval = 0; lun = NULL; - targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun; - if ((targ_lun < CTL_MAX_LUNS) - && ((lun = softc->ctl_luns[targ_lun]) != NULL)) { + if (targ_lun < CTL_MAX_LUNS) + lun = softc->ctl_luns[targ_lun]; + if (lun) { /* * If the LUN is invalid, pretend that it doesn't exist. * It will go away as soon as all pending I/O has been @@ -11523,29 +11287,21 @@ ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio) if (lun->flags & CTL_LUN_DISABLED) { mtx_unlock(&lun->lun_lock); lun = NULL; - ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr = NULL; - ctsio->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptr = NULL; - } else { - ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr = lun; - ctsio->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptr = - lun->be_lun; + } + } + CTL_LUN(ctsio) = lun; + if (lun) { + CTL_BACKEND_LUN(ctsio) = lun->be_lun; - /* - * Every I/O goes into the OOA queue for a - * particular LUN, and stays there until completion. - */ + /* + * Every I/O goes into the OOA queue for a particular LUN, + * and stays there until completion. + */ #ifdef CTL_TIME_IO - if (TAILQ_EMPTY(&lun->ooa_queue)) { - lun->idle_time += getsbinuptime() - - lun->last_busy; - } + if (TAILQ_EMPTY(&lun->ooa_queue)) + lun->idle_time += getsbinuptime() - lun->last_busy; #endif - TAILQ_INSERT_TAIL(&lun->ooa_queue, &ctsio->io_hdr, - ooa_links); - } - } else { - ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr = NULL; - ctsio->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptr = NULL; + TAILQ_INSERT_TAIL(&lun->ooa_queue, &ctsio->io_hdr, ooa_links); } /* Get command entry and return error if it is unsuppotyed. */ @@ -11849,7 +11605,7 @@ static int ctl_target_reset(struct ctl_softc *softc, union ctl_io *io, ctl_ua_type ua_type) { - struct ctl_port *port; + struct ctl_port *port = CTL_PORT(io); struct ctl_lun *lun; int retval; @@ -11870,10 +11626,9 @@ ctl_target_reset(struct ctl_softc *softc, union ctl_io *io, retval = 0; mtx_lock(&softc->ctl_lock); - port = ctl_io_port(&io->io_hdr); STAILQ_FOREACH(lun, &softc->lun_list, links) { if (port != NULL && - ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX) continue; retval += ctl_do_lun_reset(lun, io, ua_type); } @@ -11946,8 +11701,10 @@ ctl_do_lun_reset(struct ctl_lun *lun, union ctl_io *io, ctl_ua_type ua_type) ctl_clear_mask(lun->have_ca, i); #endif lun->prevent_count = 0; - for (i = 0; i < CTL_MAX_INITIATORS; i++) - ctl_clear_mask(lun->prevent, i); + if (lun->prevent) { + for (i = 0; i < CTL_MAX_INITIATORS; i++) + ctl_clear_mask(lun->prevent, i); + } mtx_unlock(&lun->lun_lock); return (0); @@ -11962,7 +11719,7 @@ ctl_lun_reset(struct ctl_softc *softc, union ctl_io *io) targ_lun = io->io_hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); - if ((targ_lun >= CTL_MAX_LUNS) || + if (targ_lun >= CTL_MAX_LUNS || (lun = softc->ctl_luns[targ_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; @@ -12032,7 +11789,7 @@ ctl_abort_tasks_lun(struct ctl_lun *lun, uint32_t targ_port, uint32_t init_id, static int ctl_abort_task_set(union ctl_io *io) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(io); struct ctl_lun *lun; uint32_t targ_lun; @@ -12041,7 +11798,7 @@ ctl_abort_task_set(union ctl_io *io) */ targ_lun = io->io_hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); - if ((targ_lun >= CTL_MAX_LUNS) || + if (targ_lun >= CTL_MAX_LUNS || (lun = softc->ctl_luns[targ_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; @@ -12066,7 +11823,7 @@ ctl_abort_task_set(union ctl_io *io) static int ctl_i_t_nexus_reset(union ctl_io *io) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(io); struct ctl_lun *lun; uint32_t initidx; @@ -12093,7 +11850,7 @@ ctl_i_t_nexus_reset(union ctl_io *io) #endif if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == initidx)) lun->flags &= ~CTL_LUN_RESERVED; - if (ctl_is_set(lun->prevent, initidx)) { + if (lun->prevent && ctl_is_set(lun->prevent, initidx)) { ctl_clear_mask(lun->prevent, initidx); lun->prevent_count--; } @@ -12108,9 +11865,9 @@ ctl_i_t_nexus_reset(union ctl_io *io) static int ctl_abort_task(union ctl_io *io) { + struct ctl_softc *softc = CTL_SOFTC(io); union ctl_io *xio; struct ctl_lun *lun; - struct ctl_softc *softc; #if 0 struct sbuf sb; char printbuf[128]; @@ -12118,7 +11875,6 @@ ctl_abort_task(union ctl_io *io) int found; uint32_t targ_lun; - softc = control_softc; found = 0; /* @@ -12126,7 +11882,7 @@ ctl_abort_task(union ctl_io *io) */ targ_lun = io->io_hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); - if ((targ_lun >= CTL_MAX_LUNS) || + if (targ_lun >= CTL_MAX_LUNS || (lun = softc->ctl_luns[targ_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; @@ -12242,16 +11998,15 @@ ctl_abort_task(union ctl_io *io) static int ctl_query_task(union ctl_io *io, int task_set) { + struct ctl_softc *softc = CTL_SOFTC(io); union ctl_io *xio; struct ctl_lun *lun; - struct ctl_softc *softc; int found = 0; uint32_t targ_lun; - softc = control_softc; targ_lun = io->io_hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); - if ((targ_lun >= CTL_MAX_LUNS) || + if (targ_lun >= CTL_MAX_LUNS || (lun = softc->ctl_luns[targ_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; @@ -12283,15 +12038,14 @@ ctl_query_task(union ctl_io *io, int task_set) static int ctl_query_async_event(union ctl_io *io) { + struct ctl_softc *softc = CTL_SOFTC(io); struct ctl_lun *lun; - struct ctl_softc *softc; ctl_ua_type ua; uint32_t targ_lun, initidx; - softc = control_softc; targ_lun = io->io_hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); - if ((targ_lun >= CTL_MAX_LUNS) || + if (targ_lun >= CTL_MAX_LUNS || (lun = softc->ctl_luns[targ_lun]) == NULL) { mtx_unlock(&softc->ctl_lock); io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; @@ -12312,7 +12066,7 @@ ctl_query_async_event(union ctl_io *io) static void ctl_run_task(union ctl_io *io) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(io); int retval = 1; CTL_DEBUG_PRINT(("ctl_run_task\n")); @@ -12374,29 +12128,25 @@ ctl_run_task(union ctl_io *io) static void ctl_handle_isc(union ctl_io *io) { - int free_io; + struct ctl_softc *softc = CTL_SOFTC(io); struct ctl_lun *lun; - struct ctl_softc *softc = control_softc; + const struct ctl_cmd_entry *entry; uint32_t targ_lun; targ_lun = io->io_hdr.nexus.targ_mapped_lun; - lun = softc->ctl_luns[targ_lun]; - switch (io->io_hdr.msg_type) { case CTL_MSG_SERIALIZE: - free_io = ctl_serialize_other_sc_cmd(&io->scsiio); + ctl_serialize_other_sc_cmd(&io->scsiio); break; - case CTL_MSG_R2R: { - const struct ctl_cmd_entry *entry; - - /* - * This is only used in SER_ONLY mode. - */ - free_io = 0; + case CTL_MSG_R2R: /* Only used in SER_ONLY mode. */ entry = ctl_get_cmd_entry(&io->scsiio, NULL); + if (targ_lun >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[targ_lun]) == NULL) { + ctl_done(io); + break; + } mtx_lock(&lun->lun_lock); - if (ctl_scsiio_lun_check(lun, - entry, (struct ctl_scsiio *)io) != 0) { + if (ctl_scsiio_lun_check(lun, entry, &io->scsiio) != 0) { mtx_unlock(&lun->lun_lock); ctl_done(io); break; @@ -12405,51 +12155,45 @@ ctl_handle_isc(union ctl_io *io) mtx_unlock(&lun->lun_lock); ctl_enqueue_rtr(io); break; - } case CTL_MSG_FINISH_IO: if (softc->ha_mode == CTL_HA_MODE_XFER) { - free_io = 0; ctl_done(io); - } else { - free_io = 1; - mtx_lock(&lun->lun_lock); - TAILQ_REMOVE(&lun->ooa_queue, &io->io_hdr, - ooa_links); - ctl_check_blocked(lun); - mtx_unlock(&lun->lun_lock); + break; + } + if (targ_lun >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[targ_lun]) == NULL) { + ctl_free_io(io); + break; } + mtx_lock(&lun->lun_lock); + TAILQ_REMOVE(&lun->ooa_queue, &io->io_hdr, ooa_links); + ctl_check_blocked(lun); + mtx_unlock(&lun->lun_lock); + ctl_free_io(io); break; case CTL_MSG_PERS_ACTION: - ctl_hndl_per_res_out_on_other_sc( - (union ctl_ha_msg *)&io->presio.pr_msg); - free_io = 1; + ctl_hndl_per_res_out_on_other_sc(io); + ctl_free_io(io); break; case CTL_MSG_BAD_JUJU: - free_io = 0; ctl_done(io); break; - case CTL_MSG_DATAMOVE: - /* Only used in XFER mode */ - free_io = 0; + case CTL_MSG_DATAMOVE: /* Only used in XFER mode */ ctl_datamove_remote(io); break; - case CTL_MSG_DATAMOVE_DONE: - /* Only used in XFER mode */ - free_io = 0; + case CTL_MSG_DATAMOVE_DONE: /* Only used in XFER mode */ io->scsiio.be_move_done(io); break; case CTL_MSG_FAILOVER: ctl_failover_lun(io); - free_io = 1; + ctl_free_io(io); break; default: - free_io = 1; printf("%s: Invalid message type %d\n", __func__, io->io_hdr.msg_type); + ctl_free_io(io); break; } - if (free_io) - ctl_free_io(io); } @@ -12601,14 +12345,15 @@ ctl_datamove_timer_wakeup(void *arg) void ctl_datamove(union ctl_io *io) { - struct ctl_lun *lun; void (*fe_datamove)(union ctl_io *io); - mtx_assert(&control_softc->ctl_lock, MA_NOTOWNED); + mtx_assert(&((struct ctl_softc *)CTL_SOFTC(io))->ctl_lock, MA_NOTOWNED); CTL_DEBUG_PRINT(("ctl_datamove\n")); - lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + /* No data transferred yet. Frontend must update this when done. */ + io->scsiio.kern_data_resid = io->scsiio.kern_data_len; + #ifdef CTL_TIME_IO if ((time_uptime - io->io_hdr.start_time) > ctl_time_io_secs) { char str[256]; @@ -12689,7 +12434,7 @@ ctl_datamove(union ctl_io *io) return; } - fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove; + fe_datamove = CTL_PORT(io)->fe_datamove; fe_datamove(io); } @@ -12707,15 +12452,14 @@ ctl_send_datamove_done(union ctl_io *io, int have_lock) msg.hdr.serializing_sc = io->io_hdr.serializing_sc; msg.hdr.nexus = io->io_hdr.nexus; msg.hdr.status = io->io_hdr.status; + msg.scsi.kern_data_resid = io->scsiio.kern_data_resid; msg.scsi.tag_num = io->scsiio.tag_num; msg.scsi.tag_type = io->scsiio.tag_type; msg.scsi.scsi_status = io->scsiio.scsi_status; memcpy(&msg.scsi.sense_data, &io->scsiio.sense_data, io->scsiio.sense_len); msg.scsi.sense_len = io->scsiio.sense_len; - msg.scsi.sense_residual = io->scsiio.sense_residual; - msg.scsi.fetd_status = io->io_hdr.port_status; - msg.scsi.residual = io->scsiio.residual; + msg.scsi.port_status = io->io_hdr.port_status; io->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE; if (io->io_hdr.flags & CTL_FLAG_FAILOVER) { ctl_failover_io(io, /*have_lock*/ have_lock); @@ -12807,7 +12551,7 @@ ctl_datamove_remote_write(union ctl_io *io) */ io->scsiio.be_move_done = ctl_datamove_remote_dm_write_cb; - fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove; + fe_datamove = CTL_PORT(io)->fe_datamove; fe_datamove(io); } @@ -12882,7 +12626,7 @@ ctl_datamove_remote_read_cb(struct ctl_ha_dt_req *rq) /* XXX KDM add checks like the ones in ctl_datamove? */ - fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove; + fe_datamove = CTL_PORT(io)->fe_datamove; fe_datamove(io); } @@ -13098,7 +12842,7 @@ static void ctl_datamove_remote(union ctl_io *io) { - mtx_assert(&control_softc->ctl_lock, MA_NOTOWNED); + mtx_assert(&((struct ctl_softc *)CTL_SOFTC(io))->ctl_lock, MA_NOTOWNED); if (io->io_hdr.flags & CTL_FLAG_FAILOVER) { ctl_failover_io(io, /*have_lock*/ 0); @@ -13134,14 +12878,14 @@ ctl_datamove_remote(union ctl_io *io) static void ctl_process_done(union ctl_io *io) { - struct ctl_lun *lun; - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(io); + struct ctl_port *port = CTL_PORT(io); + struct ctl_lun *lun = CTL_LUN(io); void (*fe_done)(union ctl_io *io); union ctl_ha_msg msg; - uint32_t targ_port = io->io_hdr.nexus.targ_port; CTL_DEBUG_PRINT(("ctl_process_done\n")); - fe_done = softc->ctl_ports[targ_port]->fe_done; + fe_done = port->fe_done; #ifdef CTL_TIME_IO if ((time_uptime - io->io_hdr.start_time) > ctl_time_io_secs) { @@ -13191,7 +12935,6 @@ ctl_process_done(union ctl_io *io) __func__, io->io_hdr.io_type); } - lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; if (lun == NULL) { CTL_DEBUG_PRINT(("NULL LUN for lun %d\n", io->io_hdr.nexus.targ_mapped_lun)); @@ -13245,11 +12988,13 @@ ctl_process_done(union ctl_io *io) */ if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS && io->io_hdr.io_type == CTL_IO_SCSI) { -#ifdef CTL_TIME_IO - struct bintime cur_bt; -#endif int type; +#ifdef CTL_TIME_IO + struct bintime bt; + getbinuptime(&bt); + bintime_sub(&bt, &io->io_hdr.start_bt); +#endif if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) type = CTL_STATS_READ; @@ -13259,18 +13004,38 @@ ctl_process_done(union ctl_io *io) else type = CTL_STATS_NO_IO; - lun->stats.ports[targ_port].bytes[type] += +#ifdef CTL_LEGACY_STATS + uint32_t targ_port = port->targ_port; + lun->legacy_stats.ports[targ_port].bytes[type] += io->scsiio.kern_total_len; - lun->stats.ports[targ_port].operations[type]++; + lun->legacy_stats.ports[targ_port].operations[type] ++; + lun->legacy_stats.ports[targ_port].num_dmas[type] += + io->io_hdr.num_dmas; #ifdef CTL_TIME_IO - bintime_add(&lun->stats.ports[targ_port].dma_time[type], + bintime_add(&lun->legacy_stats.ports[targ_port].dma_time[type], &io->io_hdr.dma_bt); - getbinuptime(&cur_bt); - bintime_sub(&cur_bt, &io->io_hdr.start_bt); - bintime_add(&lun->stats.ports[targ_port].time[type], &cur_bt); + bintime_add(&lun->legacy_stats.ports[targ_port].time[type], + &bt); #endif - lun->stats.ports[targ_port].num_dmas[type] += - io->io_hdr.num_dmas; +#endif /* CTL_LEGACY_STATS */ + + lun->stats.bytes[type] += io->scsiio.kern_total_len; + lun->stats.operations[type] ++; + lun->stats.dmas[type] += io->io_hdr.num_dmas; +#ifdef CTL_TIME_IO + bintime_add(&lun->stats.dma_time[type], &io->io_hdr.dma_bt); + bintime_add(&lun->stats.time[type], &bt); +#endif + + mtx_lock(&port->port_lock); + port->stats.bytes[type] += io->scsiio.kern_total_len; + port->stats.operations[type] ++; + port->stats.dmas[type] += io->io_hdr.num_dmas; +#ifdef CTL_TIME_IO + bintime_add(&port->stats.dma_time[type], &io->io_hdr.dma_bt); + bintime_add(&port->stats.time[type], &bt); +#endif + mtx_unlock(&port->port_lock); } /* @@ -13345,42 +13110,36 @@ bailout: int ctl_queue_sense(union ctl_io *io) { + struct ctl_softc *softc = CTL_SOFTC(io); + struct ctl_port *port = CTL_PORT(io); struct ctl_lun *lun; - struct ctl_port *port; - struct ctl_softc *softc; uint32_t initidx, targ_lun; - softc = control_softc; - CTL_DEBUG_PRINT(("ctl_queue_sense\n")); + targ_lun = ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun); + /* * LUN lookup will likely move to the ctl_work_thread() once we * have our new queueing infrastructure (that doesn't put things on * a per-LUN queue initially). That is so that we can handle * things like an INQUIRY to a LUN that we don't have enabled. We * can't deal with that right now. + * If we don't have a LUN for this, just toss the sense information. */ mtx_lock(&softc->ctl_lock); - - /* - * If we don't have a LUN for this, just toss the sense - * information. - */ - port = ctl_io_port(&ctsio->io_hdr); - targ_lun = ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun); - if ((targ_lun < CTL_MAX_LUNS) - && (softc->ctl_luns[targ_lun] != NULL)) - lun = softc->ctl_luns[targ_lun]; - else + if (targ_lun >= CTL_MAX_LUNS || + (lun = softc->ctl_luns[targ_lun]) == NULL) { + mtx_unlock(&softc->ctl_lock); goto bailout; - - initidx = ctl_get_initindex(&io->io_hdr.nexus); - + } mtx_lock(&lun->lun_lock); + mtx_unlock(&softc->ctl_lock); + /* * Already have CA set for this LUN...toss the sense information. */ + initidx = ctl_get_initindex(&io->io_hdr.nexus); if (ctl_is_set(lun->have_ca, initidx)) { mtx_unlock(&lun->lun_lock); goto bailout; @@ -13393,10 +13152,7 @@ ctl_queue_sense(union ctl_io *io) mtx_unlock(&lun->lun_lock); bailout: - mtx_unlock(&softc->ctl_lock); - ctl_free_io(io); - return (CTL_RETVAL_COMPLETE); } #endif @@ -13408,7 +13164,7 @@ bailout: int ctl_queue(union ctl_io *io) { - struct ctl_port *port; + struct ctl_port *port = CTL_PORT(io); CTL_DEBUG_PRINT(("ctl_queue cdb[0]=%02X\n", io->scsiio.cdb[0])); @@ -13418,7 +13174,6 @@ ctl_queue(union ctl_io *io) #endif /* CTL_TIME_IO */ /* Map FE-specific LUN ID into global one. */ - port = ctl_io_port(&io->io_hdr); io->io_hdr.nexus.targ_mapped_lun = ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun); @@ -13451,9 +13206,8 @@ ctl_done_timer_wakeup(void *arg) void ctl_serseq_done(union ctl_io *io) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(io);; - lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; if (lun->be_lun == NULL || lun->be_lun->serseq == CTL_LUN_SERSEQ_OFF) return; @@ -13503,9 +13257,7 @@ ctl_done(union ctl_io *io) if (io->io_hdr.flags & CTL_FLAG_DELAY_DONE) { io->io_hdr.flags &= ~CTL_FLAG_DELAY_DONE; } else { - struct ctl_lun *lun; - - lun =(struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + struct ctl_lun *lun = CTL_LUN(io); if ((lun != NULL) && (lun->delay_info.done_delay > 0)) { @@ -13535,7 +13287,7 @@ ctl_work_thread(void *arg) CTL_DEBUG_PRINT(("ctl_work_thread starting\n")); - for (;;) { + while (!softc->shutdown) { /* * We handle the queues in this order: * - ISC @@ -13585,6 +13337,8 @@ ctl_work_thread(void *arg) /* Sleep until we have something to do. */ mtx_sleep(thr, &thr->queue_lock, PDROP | PRIBIO, "-", 0); } + thr->thread = NULL; + kthread_exit(); } static void @@ -13595,7 +13349,7 @@ ctl_lun_thread(void *arg) CTL_DEBUG_PRINT(("ctl_lun_thread starting\n")); - for (;;) { + while (!softc->shutdown) { mtx_lock(&softc->ctl_lock); be_lun = STAILQ_FIRST(&softc->pending_lun_queue); if (be_lun != NULL) { @@ -13609,6 +13363,8 @@ ctl_lun_thread(void *arg) mtx_sleep(&softc->pending_lun_queue, &softc->ctl_lock, PDROP | PRIBIO, "-", 0); } + softc->lun_thread = NULL; + kthread_exit(); } static void @@ -13624,7 +13380,7 @@ ctl_thresh_thread(void *arg) CTL_DEBUG_PRINT(("ctl_thresh_thread starting\n")); - for (;;) { + while (!softc->shutdown) { mtx_lock(&softc->ctl_lock); STAILQ_FOREACH(lun, &softc->lun_list, links) { if ((lun->flags & CTL_LUN_DISABLED) || @@ -13709,15 +13465,17 @@ ctl_thresh_thread(void *arg) mtx_lock(&softc->ctl_lock); } } - mtx_unlock(&softc->ctl_lock); - pause("-", CTL_LBP_PERIOD * hz); + mtx_sleep(&softc->thresh_thread, &softc->ctl_lock, + PDROP | PRIBIO, "-", CTL_LBP_PERIOD * hz); } + softc->thresh_thread = NULL; + kthread_exit(); } static void ctl_enqueue_incoming(union ctl_io *io) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(io); struct ctl_thread *thr; u_int idx; @@ -13733,7 +13491,7 @@ ctl_enqueue_incoming(union ctl_io *io) static void ctl_enqueue_rtr(union ctl_io *io) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(io); struct ctl_thread *thr; thr = &softc->threads[io->io_hdr.nexus.targ_mapped_lun % worker_threads]; @@ -13746,7 +13504,7 @@ ctl_enqueue_rtr(union ctl_io *io) static void ctl_enqueue_done(union ctl_io *io) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(io); struct ctl_thread *thr; thr = &softc->threads[io->io_hdr.nexus.targ_mapped_lun % worker_threads]; @@ -13759,7 +13517,7 @@ ctl_enqueue_done(union ctl_io *io) static void ctl_enqueue_isc(union ctl_io *io) { - struct ctl_softc *softc = control_softc; + struct ctl_softc *softc = CTL_SOFTC(io); struct ctl_thread *thr; thr = &softc->threads[io->io_hdr.nexus.targ_mapped_lun % worker_threads]; diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h index 7b4d06c..d9a4f5a 100644 --- a/sys/cam/ctl/ctl.h +++ b/sys/cam/ctl/ctl.h @@ -74,18 +74,12 @@ struct ctl_port_entry { struct ctl_modepage_header { uint8_t page_code; uint8_t subpage; - int32_t len_used; - int32_t len_left; -}; - -struct ctl_modepage_aps { - struct ctl_modepage_header header; - uint8_t lock_active; + uint16_t len_used; + uint16_t len_left; }; union ctl_modepage_info { struct ctl_modepage_header header; - struct ctl_modepage_aps aps; }; /* diff --git a/sys/cam/ctl/ctl_backend.c b/sys/cam/ctl/ctl_backend.c index 86f7d3c..bac7e85 100644 --- a/sys/cam/ctl/ctl_backend.c +++ b/sys/cam/ctl/ctl_backend.c @@ -67,11 +67,10 @@ ctl_backend_register(struct ctl_backend_driver *be) { struct ctl_softc *softc = control_softc; struct ctl_backend_driver *be_tmp; + int error; + /* Sanity check, make sure this isn't a duplicate registration. */ mtx_lock(&softc->ctl_lock); - /* - * Sanity check, make sure this isn't a duplicate registration. - */ STAILQ_FOREACH(be_tmp, &softc->be_list, links) { if (strcmp(be_tmp->name, be->name) == 0) { mtx_unlock(&softc->ctl_lock); @@ -79,39 +78,24 @@ ctl_backend_register(struct ctl_backend_driver *be) } } mtx_unlock(&softc->ctl_lock); - - /* - * Call the backend's initialization routine. - */ - be->init(); - - mtx_lock(&softc->ctl_lock); - - STAILQ_INSERT_TAIL(&softc->be_list, be, links); - - softc->num_backends++; - - /* - * Don't want to increment the usage count for internal consumers, - * we won't be able to unload otherwise. - */ - /* XXX KDM find a substitute for this? */ -#if 0 - if ((be->flags & CTL_BE_FLAG_INTERNAL) == 0) - MOD_INC_USE_COUNT; -#endif - #ifdef CS_BE_CONFIG_MOVE_DONE_IS_NOT_USED be->config_move_done = ctl_config_move_done; #endif - /* XXX KDM fix this! */ be->num_luns = 0; -#if 0 - atomic_set(&be->num_luns, 0); -#endif - mtx_unlock(&softc->ctl_lock); + /* Call the backend's initialization routine. */ + if (be->init != NULL) { + if ((error = be->init()) != 0) { + printf("%s backend init error: %d\n", + be->name, error); + return (error); + } + } + mtx_lock(&softc->ctl_lock); + STAILQ_INSERT_TAIL(&softc->be_list, be, links); + softc->num_backends++; + mtx_unlock(&softc->ctl_lock); return (0); } @@ -119,30 +103,21 @@ int ctl_backend_deregister(struct ctl_backend_driver *be) { struct ctl_softc *softc = control_softc; - - mtx_lock(&softc->ctl_lock); - -#if 0 - if (atomic_read(&be->num_luns) != 0) { -#endif - /* XXX KDM fix this! */ - if (be->num_luns != 0) { - mtx_unlock(&softc->ctl_lock); - return (-1); + int error; + + /* Call the backend's shutdown routine. */ + if (be->shutdown != NULL) { + if ((error = be->shutdown()) != 0) { + printf("%s backend shutdown error: %d\n", + be->name, error); + return (error); + } } + mtx_lock(&softc->ctl_lock); STAILQ_REMOVE(&softc->be_list, be, ctl_backend_driver, links); - softc->num_backends--; - - /* XXX KDM find a substitute for this? */ -#if 0 - if ((be->flags & CTL_BE_FLAG_INTERNAL) == 0) - MOD_DEC_USE_COUNT; -#endif - mtx_unlock(&softc->ctl_lock); - return (0); } diff --git a/sys/cam/ctl/ctl_backend.h b/sys/cam/ctl/ctl_backend.h index 4177e2d..4202efc 100644 --- a/sys/cam/ctl/ctl_backend.h +++ b/sys/cam/ctl/ctl_backend.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 2003 Silicon Graphics International Corp. - * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> + * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,54 +40,7 @@ #ifndef _CTL_BACKEND_H_ #define _CTL_BACKEND_H_ -/* - * XXX KDM move this to another header file? - */ -#define CTL_BE_NAME_LEN 32 - -/* - * The ID_REQ flag is used to say that the caller has requested a - * particular LUN ID in the req_lun_id field. If we cannot allocate that - * LUN ID, the ctl_add_lun() call will fail. - * - * The STOPPED flag tells us that the LUN should default to the powered - * off state. It will return 0x04,0x02 until it is powered up. ("Logical - * unit not ready, initializing command required.") - * - * The NO_MEDIA flag tells us that the LUN has no media inserted. - * - * The PRIMARY flag tells us that this LUN is registered as a Primary LUN - * which is accessible via the Master shelf controller in an HA. This flag - * being set indicates a Primary LUN. This flag being reset represents a - * Secondary LUN controlled by the Secondary controller in an HA - * configuration. Flag is applicable at this time to T_DIRECT types. - * - * The SERIAL_NUM flag tells us that the serial_num field is filled in and - * valid for use in SCSI INQUIRY VPD page 0x80. - * - * The DEVID flag tells us that the device_id field is filled in and - * valid for use in SCSI INQUIRY VPD page 0x83. - * - * The DEV_TYPE flag tells us that the device_type field is filled in. - * - * The EJECTED flag tells us that the removable LUN has tray open. - * - * The UNMAP flag tells us that this LUN supports UNMAP. - * - * The OFFLINE flag tells us that this LUN can not access backing store. - */ -typedef enum { - CTL_LUN_FLAG_ID_REQ = 0x01, - CTL_LUN_FLAG_STOPPED = 0x02, - CTL_LUN_FLAG_NO_MEDIA = 0x04, - CTL_LUN_FLAG_PRIMARY = 0x08, - CTL_LUN_FLAG_SERIAL_NUM = 0x10, - CTL_LUN_FLAG_DEVID = 0x20, - CTL_LUN_FLAG_DEV_TYPE = 0x40, - CTL_LUN_FLAG_UNMAP = 0x80, - CTL_LUN_FLAG_EJECTED = 0x100, - CTL_LUN_FLAG_READONLY = 0x200 -} ctl_backend_lun_flags; +#include <cam/ctl/ctl_ioctl.h> typedef enum { CTL_LUN_SERSEQ_OFF, @@ -102,12 +55,13 @@ typedef enum { { \ switch (type) { \ case MOD_LOAD: \ - ctl_backend_register( \ - (struct ctl_backend_driver *)data); \ + return (ctl_backend_register( \ + (struct ctl_backend_driver *)data)); \ break; \ case MOD_UNLOAD: \ - printf(#name " module unload - not possible for this module type\n"); \ - return EINVAL; \ + return (ctl_backend_deregister( \ + (struct ctl_backend_driver *)data)); \ + break; \ default: \ return EOPNOTSUPP; \ } \ @@ -226,10 +180,10 @@ struct ctl_be_lun { typedef enum { CTL_BE_FLAG_NONE = 0x00, /* no flags */ CTL_BE_FLAG_HAS_CONFIG = 0x01, /* can do config reads, writes */ - CTL_BE_FLAG_INTERNAL = 0x02 /* don't inc mod refcount */ } ctl_backend_flags; typedef int (*be_init_t)(void); +typedef int (*be_shutdown_t)(void); typedef int (*be_func_t)(union ctl_io *io); typedef void (*be_vfunc_t)(union ctl_io *io); typedef int (*be_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag, @@ -241,6 +195,7 @@ struct ctl_backend_driver { char name[CTL_BE_NAME_LEN]; /* passed to CTL */ ctl_backend_flags flags; /* passed to CTL */ be_init_t init; /* passed to CTL */ + be_shutdown_t shutdown; /* passed to CTL */ be_func_t data_submit; /* passed to CTL */ be_func_t data_move_done; /* passed to CTL */ be_func_t config_read; /* passed to CTL */ diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index 8fa93cf..2ac0cdd 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -185,6 +185,7 @@ struct ctl_be_block_lun { */ struct ctl_be_block_softc { struct mtx lock; + uma_zone_t beio_zone; int num_luns; STAILQ_HEAD(, ctl_be_block_lun) lun_list; }; @@ -276,13 +277,15 @@ static int ctl_be_block_config_write(union ctl_io *io); static int ctl_be_block_config_read(union ctl_io *io); static int ctl_be_block_lun_info(void *be_lun, struct sbuf *sb); static uint64_t ctl_be_block_lun_attr(void *be_lun, const char *attrname); -int ctl_be_block_init(void); +static int ctl_be_block_init(void); +static int ctl_be_block_shutdown(void); static struct ctl_backend_driver ctl_be_block_driver = { .name = "block", .flags = CTL_BE_FLAG_HAS_CONFIG, .init = ctl_be_block_init, + .shutdown = ctl_be_block_shutdown, .data_submit = ctl_be_block_submit, .data_move_done = ctl_be_block_move_done, .config_read = ctl_be_block_config_read, @@ -295,14 +298,12 @@ static struct ctl_backend_driver ctl_be_block_driver = MALLOC_DEFINE(M_CTLBLK, "ctlblk", "Memory used for CTL block backend"); CTL_BACKEND_DECLARE(cbb, ctl_be_block_driver); -static uma_zone_t beio_zone; - static struct ctl_be_block_io * ctl_alloc_beio(struct ctl_be_block_softc *softc) { struct ctl_be_block_io *beio; - beio = uma_zalloc(beio_zone, M_WAITOK | M_ZERO); + beio = uma_zalloc(softc->beio_zone, M_WAITOK | M_ZERO); beio->softc = softc; return (beio); } @@ -335,7 +336,7 @@ ctl_free_beio(struct ctl_be_block_io *beio) duplicate_free, beio->num_segs); } - uma_zfree(beio_zone, beio); + uma_zfree(beio->softc->beio_zone, beio); } static void @@ -422,6 +423,16 @@ ctl_be_block_move_done(union ctl_io *io) */ if (io->io_hdr.flags & CTL_FLAG_ABORT) { ; + } else if ((io->io_hdr.port_status != 0) && + ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE || + (io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) { + ctl_set_internal_failure(&io->scsiio, /*sks_valid*/ 1, + /*retry_count*/ io->io_hdr.port_status); + } else if (io->scsiio.kern_data_resid != 0 && + (io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_OUT && + ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE || + (io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) { + ctl_set_invalid_field_ciu(&io->scsiio); } else if ((io->io_hdr.port_status == 0) && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) { lbalen = ARGS(beio->io); @@ -431,21 +442,6 @@ ctl_be_block_move_done(union ctl_io *io) /* We have two data blocks ready for comparison. */ ctl_be_block_compare(io); } - } else if ((io->io_hdr.port_status != 0) && - ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE || - (io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) { - /* - * For hardware error sense keys, the sense key - * specific value is defined to be a retry count, - * but we use it to pass back an internal FETD - * error code. XXX KDM Hopefully the FETD is only - * using 16 bits for an error code, since that's - * all the space we have in the sks field. - */ - ctl_set_internal_failure(&io->scsiio, - /*sks_valid*/ 1, - /*retry_count*/ - io->io_hdr.port_status); } /* @@ -1637,7 +1633,6 @@ ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun, else io->scsiio.kern_data_ptr = (uint8_t *)beio->sg_segs; io->scsiio.kern_data_len = beio->io_len; - io->scsiio.kern_data_resid = 0; io->scsiio.kern_sg_entries = beio->num_segs; io->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -1754,8 +1749,7 @@ ctl_be_block_submit(union ctl_io *io) DPRINTF("entered\n"); - cbe_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[ - CTL_PRIV_BACKEND_LUN].ptr; + cbe_lun = CTL_BACKEND_LUN(io); be_lun = (struct ctl_be_block_lun *)cbe_lun->be_lun; /* @@ -2731,8 +2725,7 @@ ctl_be_block_config_write(union ctl_io *io) DPRINTF("entered\n"); - cbe_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[ - CTL_PRIV_BACKEND_LUN].ptr; + cbe_lun = CTL_BACKEND_LUN(io); be_lun = (struct ctl_be_block_lun *)cbe_lun->be_lun; retval = 0; @@ -2817,8 +2810,7 @@ ctl_be_block_config_read(union ctl_io *io) DPRINTF("entered\n"); - cbe_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[ - CTL_PRIV_BACKEND_LUN].ptr; + cbe_lun = CTL_BACKEND_LUN(io); be_lun = (struct ctl_be_block_lun *)cbe_lun->be_lun; switch (io->scsiio.cdb[0]) { @@ -2882,19 +2874,40 @@ ctl_be_block_lun_attr(void *be_lun, const char *attrname) return (lun->getattr(lun, attrname)); } -int +static int ctl_be_block_init(void) { - struct ctl_be_block_softc *softc; - int retval; - - softc = &backend_block_softc; - retval = 0; + struct ctl_be_block_softc *softc = &backend_block_softc; mtx_init(&softc->lock, "ctlblock", NULL, MTX_DEF); - beio_zone = uma_zcreate("beio", sizeof(struct ctl_be_block_io), + softc->beio_zone = uma_zcreate("beio", sizeof(struct ctl_be_block_io), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); STAILQ_INIT(&softc->lun_list); + return (0); +} - return (retval); + +static int +ctl_be_block_shutdown(void) +{ + struct ctl_be_block_softc *softc = &backend_block_softc; + struct ctl_be_block_lun *lun, *next_lun; + + mtx_lock(&softc->lock); + STAILQ_FOREACH_SAFE(lun, &softc->lun_list, links, next_lun) { + /* + * Drop our lock here. Since ctl_invalidate_lun() can call + * back into us, this could potentially lead to a recursive + * lock of the same mutex, which would cause a hang. + */ + mtx_unlock(&softc->lock); + ctl_disable_lun(&lun->cbe_lun); + ctl_invalidate_lun(&lun->cbe_lun); + mtx_lock(&softc->lock); + } + mtx_unlock(&softc->lock); + + uma_zdestroy(softc->beio_zone); + mtx_destroy(&softc->lock); + return (0); } diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c index d170446..b743bc6 100644 --- a/sys/cam/ctl/ctl_backend_ramdisk.c +++ b/sys/cam/ctl/ctl_backend_ramdisk.c @@ -1,7 +1,7 @@ /*- * Copyright (c) 2003, 2008 Silicon Graphics International Corp. * Copyright (c) 2012 The FreeBSD Foundation - * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> + * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Portions of this software were developed by Edward Tomasz Napierala @@ -35,7 +35,7 @@ * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend_ramdisk.c#3 $ */ /* - * CAM Target Layer backend for a "fake" ramdisk. + * CAM Target Layer black hole and RAM disk backend. * * Author: Ken Merry <ken@FreeBSD.org> */ @@ -48,9 +48,11 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/condvar.h> #include <sys/types.h> +#include <sys/limits.h> #include <sys/lock.h> #include <sys/mutex.h> #include <sys/malloc.h> +#include <sys/sx.h> #include <sys/taskqueue.h> #include <sys/time.h> #include <sys/queue.h> @@ -71,6 +73,29 @@ __FBSDID("$FreeBSD$"); #include <cam/ctl/ctl_private.h> #include <cam/ctl/ctl_error.h> +#define PRIV(io) \ + ((struct ctl_ptr_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_BACKEND]) +#define ARGS(io) \ + ((struct ctl_lba_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]) + +#define PPP (PAGE_SIZE / sizeof(uint8_t **)) +#ifdef __LP64__ +#define PPPS (PAGE_SHIFT - 3) +#else +#define PPPS (PAGE_SHIFT - 2) +#endif +#define SGPP (PAGE_SIZE / sizeof(struct ctl_sg_entry)) + +#define P_UNMAPPED NULL /* Page is unmapped. */ +#define P_ANCHORED ((void *)(uintptr_t)1) /* Page is anchored. */ + +typedef enum { + GP_READ, /* Return data page or zero page. */ + GP_WRITE, /* Return data page, try allocate if none. */ + GP_ANCHOR, /* Return data page, try anchor if none. */ + GP_OTHER, /* Return what present, do not allocate/anchor. */ +} getpage_op_t; + typedef enum { CTL_BE_RAMDISK_LUN_UNCONFIGURED = 0x01, CTL_BE_RAMDISK_LUN_CONFIG_ERR = 0x02, @@ -79,28 +104,29 @@ typedef enum { struct ctl_be_ramdisk_lun { struct ctl_lun_create_params params; - char lunname[32]; - uint64_t size_bytes; - uint64_t size_blocks; + char lunname[32]; + int indir; + uint8_t **pages; + uint8_t *zero_page; + struct sx page_lock; + u_int pblocksize; + u_int pblockmul; + uint64_t size_bytes; + uint64_t size_blocks; + uint64_t cap_bytes; + uint64_t cap_used; struct ctl_be_ramdisk_softc *softc; ctl_be_ramdisk_lun_flags flags; STAILQ_ENTRY(ctl_be_ramdisk_lun) links; - struct ctl_be_lun cbe_lun; - struct taskqueue *io_taskqueue; - struct task io_task; + struct ctl_be_lun cbe_lun; + struct taskqueue *io_taskqueue; + struct task io_task; STAILQ_HEAD(, ctl_io_hdr) cont_queue; - struct mtx_padalign queue_lock; + struct mtx_padalign queue_lock; }; struct ctl_be_ramdisk_softc { struct mtx lock; - int rd_size; -#ifdef CTL_RAMDISK_PAGES - uint8_t **ramdisk_pages; - int num_pages; -#else - uint8_t *ramdisk_buffer; -#endif int num_luns; STAILQ_HEAD(, ctl_be_ramdisk_lun) lun_list; }; @@ -108,11 +134,16 @@ struct ctl_be_ramdisk_softc { static struct ctl_be_ramdisk_softc rd_softc; extern struct ctl_softc *control_softc; -int ctl_backend_ramdisk_init(void); -void ctl_backend_ramdisk_shutdown(void); +static int ctl_backend_ramdisk_init(void); +static int ctl_backend_ramdisk_shutdown(void); static int ctl_backend_ramdisk_move_done(union ctl_io *io); +static void ctl_backend_ramdisk_compare(union ctl_io *io); +static void ctl_backend_ramdisk_rw(union ctl_io *io); static int ctl_backend_ramdisk_submit(union ctl_io *io); -static void ctl_backend_ramdisk_continue(union ctl_io *io); +static void ctl_backend_ramdisk_worker(void *context, int pending); +static int ctl_backend_ramdisk_config_read(union ctl_io *io); +static int ctl_backend_ramdisk_config_write(union ctl_io *io); +static uint64_t ctl_backend_ramdisk_lun_attr(void *be_lun, const char *attrname); static int ctl_backend_ramdisk_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td); static int ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, @@ -121,63 +152,43 @@ static int ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, struct ctl_lun_req *req); static int ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc, struct ctl_lun_req *req); -static void ctl_backend_ramdisk_worker(void *context, int pending); static void ctl_backend_ramdisk_lun_shutdown(void *be_lun); static void ctl_backend_ramdisk_lun_config_status(void *be_lun, ctl_lun_config_status status); -static int ctl_backend_ramdisk_config_write(union ctl_io *io); -static int ctl_backend_ramdisk_config_read(union ctl_io *io); static struct ctl_backend_driver ctl_be_ramdisk_driver = { .name = "ramdisk", .flags = CTL_BE_FLAG_HAS_CONFIG, .init = ctl_backend_ramdisk_init, + .shutdown = ctl_backend_ramdisk_shutdown, .data_submit = ctl_backend_ramdisk_submit, .data_move_done = ctl_backend_ramdisk_move_done, .config_read = ctl_backend_ramdisk_config_read, .config_write = ctl_backend_ramdisk_config_write, - .ioctl = ctl_backend_ramdisk_ioctl + .ioctl = ctl_backend_ramdisk_ioctl, + .lun_attr = ctl_backend_ramdisk_lun_attr, }; MALLOC_DEFINE(M_RAMDISK, "ramdisk", "Memory used for CTL RAMdisk"); CTL_BACKEND_DECLARE(cbr, ctl_be_ramdisk_driver); -int +static int ctl_backend_ramdisk_init(void) { struct ctl_be_ramdisk_softc *softc = &rd_softc; -#ifdef CTL_RAMDISK_PAGES - int i; -#endif memset(softc, 0, sizeof(*softc)); mtx_init(&softc->lock, "ctlramdisk", NULL, MTX_DEF); STAILQ_INIT(&softc->lun_list); - softc->rd_size = 1024 * 1024; -#ifdef CTL_RAMDISK_PAGES - softc->num_pages = softc->rd_size / PAGE_SIZE; - softc->ramdisk_pages = (uint8_t **)malloc(sizeof(uint8_t *) * - softc->num_pages, M_RAMDISK, - M_WAITOK); - for (i = 0; i < softc->num_pages; i++) - softc->ramdisk_pages[i] = malloc(PAGE_SIZE, M_RAMDISK,M_WAITOK); -#else - softc->ramdisk_buffer = (uint8_t *)malloc(softc->rd_size, M_RAMDISK, - M_WAITOK); -#endif - return (0); } -void +static int ctl_backend_ramdisk_shutdown(void) { struct ctl_be_ramdisk_softc *softc = &rd_softc; struct ctl_be_ramdisk_lun *lun, *next_lun; -#ifdef CTL_RAMDISK_PAGES - int i; -#endif mtx_lock(&softc->lock); STAILQ_FOREACH_SAFE(lun, &softc->lun_list, links, next_lun) { @@ -192,35 +203,210 @@ ctl_backend_ramdisk_shutdown(void) mtx_lock(&softc->lock); } mtx_unlock(&softc->lock); - -#ifdef CTL_RAMDISK_PAGES - for (i = 0; i < softc->num_pages; i++) - free(softc->ramdisk_pages[i], M_RAMDISK); + mtx_destroy(&softc->lock); + return (0); +} - free(softc->ramdisk_pages, M_RAMDISK); -#else - free(softc->ramdisk_buffer, M_RAMDISK); -#endif +static uint8_t * +ctl_backend_ramdisk_getpage(struct ctl_be_ramdisk_lun *be_lun, off_t pn, + getpage_op_t op) +{ + uint8_t **p, ***pp; + off_t i; + int s; + + if (be_lun->cap_bytes == 0) { + switch (op) { + case GP_READ: + return (be_lun->zero_page); + case GP_WRITE: + return ((uint8_t *)be_lun->pages); + case GP_ANCHOR: + return (P_ANCHORED); + default: + return (P_UNMAPPED); + } + } + if (op == GP_WRITE || op == GP_ANCHOR) { + sx_xlock(&be_lun->page_lock); + pp = &be_lun->pages; + for (s = (be_lun->indir - 1) * PPPS; s >= 0; s -= PPPS) { + if (*pp == NULL) { + *pp = malloc(PAGE_SIZE, M_RAMDISK, + M_WAITOK|M_ZERO); + } + i = pn >> s; + pp = (uint8_t ***)&(*pp)[i]; + pn -= i << s; + } + if (*pp == P_UNMAPPED && be_lun->cap_used < be_lun->cap_bytes) { + if (op == GP_WRITE) { + *pp = malloc(be_lun->pblocksize, M_RAMDISK, + M_WAITOK|M_ZERO); + } else + *pp = P_ANCHORED; + be_lun->cap_used += be_lun->pblocksize; + } else if (*pp == P_ANCHORED && op == GP_WRITE) { + *pp = malloc(be_lun->pblocksize, M_RAMDISK, + M_WAITOK|M_ZERO); + } + sx_xunlock(&be_lun->page_lock); + return ((uint8_t *)*pp); + } else { + sx_slock(&be_lun->page_lock); + p = be_lun->pages; + for (s = (be_lun->indir - 1) * PPPS; s >= 0; s -= PPPS) { + if (p == NULL) + break; + i = pn >> s; + p = (uint8_t **)p[i]; + pn -= i << s; + } + sx_sunlock(&be_lun->page_lock); + if ((p == P_UNMAPPED || p == P_ANCHORED) && op == GP_READ) + return (be_lun->zero_page); + return ((uint8_t *)p); + } +}; - if (ctl_backend_deregister(&ctl_be_ramdisk_driver) != 0) { - printf("ctl_backend_ramdisk_shutdown: " - "ctl_backend_deregister() failed!\n"); +static void +ctl_backend_ramdisk_unmappage(struct ctl_be_ramdisk_lun *be_lun, off_t pn) +{ + uint8_t ***pp; + off_t i; + int s; + + if (be_lun->cap_bytes == 0) + return; + sx_xlock(&be_lun->page_lock); + pp = &be_lun->pages; + for (s = (be_lun->indir - 1) * PPPS; s >= 0; s -= PPPS) { + if (*pp == NULL) + goto noindir; + i = pn >> s; + pp = (uint8_t ***)&(*pp)[i]; + pn -= i << s; } + if (*pp == P_ANCHORED) { + be_lun->cap_used -= be_lun->pblocksize; + *pp = P_UNMAPPED; + } else if (*pp != P_UNMAPPED) { + free(*pp, M_RAMDISK); + be_lun->cap_used -= be_lun->pblocksize; + *pp = P_UNMAPPED; + } +noindir: + sx_xunlock(&be_lun->page_lock); +}; + +static void +ctl_backend_ramdisk_anchorpage(struct ctl_be_ramdisk_lun *be_lun, off_t pn) +{ + uint8_t ***pp; + off_t i; + int s; + + if (be_lun->cap_bytes == 0) + return; + sx_xlock(&be_lun->page_lock); + pp = &be_lun->pages; + for (s = (be_lun->indir - 1) * PPPS; s >= 0; s -= PPPS) { + if (*pp == NULL) + goto noindir; + i = pn >> s; + pp = (uint8_t ***)&(*pp)[i]; + pn -= i << s; + } + if (*pp == P_UNMAPPED && be_lun->cap_used < be_lun->cap_bytes) { + be_lun->cap_used += be_lun->pblocksize; + *pp = P_ANCHORED; + } else if (*pp != P_ANCHORED) { + free(*pp, M_RAMDISK); + *pp = P_ANCHORED; + } +noindir: + sx_xunlock(&be_lun->page_lock); +}; + +static void +ctl_backend_ramdisk_freeallpages(uint8_t **p, int indir) +{ + int i; + + if (p == NULL) + return; + if (indir == 0) { + free(p, M_RAMDISK); + return; + } + for (i = 0; i < PPP; i++) { + if (p[i] == NULL) + continue; + ctl_backend_ramdisk_freeallpages((uint8_t **)p[i], indir - 1); + } + free(p, M_RAMDISK); +}; + +static size_t +cmp(uint8_t *a, uint8_t *b, size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) { + if (a[i] != b[i]) + break; + } + return (i); +} + +static int +ctl_backend_ramdisk_cmp(union ctl_io *io) +{ + struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io); + struct ctl_be_ramdisk_lun *be_lun = cbe_lun->be_lun; + uint8_t *page; + uint8_t info[8]; + uint64_t lba; + u_int lbaoff, lbas, res, off; + + lbas = io->scsiio.kern_data_len / cbe_lun->blocksize; + lba = ARGS(io)->lba + PRIV(io)->len - lbas; + off = 0; + for (; lbas > 0; lbas--, lba++) { + page = ctl_backend_ramdisk_getpage(be_lun, + lba >> cbe_lun->pblockexp, GP_READ); + lbaoff = lba & ~(UINT_MAX << cbe_lun->pblockexp); + page += lbaoff * cbe_lun->blocksize; + res = cmp(io->scsiio.kern_data_ptr + off, page, + cbe_lun->blocksize); + off += res; + if (res < cbe_lun->blocksize) + break; + } + if (lbas > 0) { + off += io->scsiio.kern_rel_offset - io->scsiio.kern_data_len; + scsi_u64to8b(off, info); + ctl_set_sense(&io->scsiio, /*current_error*/ 1, + /*sense_key*/ SSD_KEY_MISCOMPARE, + /*asc*/ 0x1D, /*ascq*/ 0x00, + /*type*/ SSD_ELEM_INFO, + /*size*/ sizeof(info), /*data*/ &info, + /*type*/ SSD_ELEM_NONE); + return (1); + } + return (0); } static int ctl_backend_ramdisk_move_done(union ctl_io *io) { - struct ctl_be_lun *cbe_lun; - struct ctl_be_ramdisk_lun *be_lun; + struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io); + struct ctl_be_ramdisk_lun *be_lun = cbe_lun->be_lun; #ifdef CTL_TIME_IO struct bintime cur_bt; #endif CTL_DEBUG_PRINT(("ctl_backend_ramdisk_move_done\n")); - cbe_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[ - CTL_PRIV_BACKEND_LUN].ptr; - be_lun = (struct ctl_be_ramdisk_lun *)cbe_lun->be_lun; #ifdef CTL_TIME_IO getbinuptime(&cur_bt); bintime_sub(&cur_bt, &io->io_hdr.dma_start_bt); @@ -232,9 +418,24 @@ ctl_backend_ramdisk_move_done(union ctl_io *io) io->scsiio.kern_rel_offset += io->scsiio.kern_data_len; if (io->io_hdr.flags & CTL_FLAG_ABORT) { ; + } else if (io->io_hdr.port_status != 0 && + ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE || + (io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) { + ctl_set_internal_failure(&io->scsiio, /*sks_valid*/ 1, + /*retry_count*/ io->io_hdr.port_status); + } else if (io->scsiio.kern_data_resid != 0 && + (io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_OUT && + ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE || + (io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) { + ctl_set_invalid_field_ciu(&io->scsiio); } else if ((io->io_hdr.port_status == 0) && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) { - if (io->io_hdr.ctl_private[CTL_PRIV_BACKEND].integer > 0) { + if (ARGS(io)->flags & CTL_LLF_COMPARE) { + /* We have data block ready for comparison. */ + if (ctl_backend_ramdisk_cmp(io)) + goto done; + } + if (ARGS(io)->len > PRIV(io)->len) { mtx_lock(&be_lun->queue_lock); STAILQ_INSERT_TAIL(&be_lun->cont_queue, &io->io_hdr, links); @@ -244,93 +445,110 @@ ctl_backend_ramdisk_move_done(union ctl_io *io) return (0); } ctl_set_success(&io->scsiio); - } else if ((io->io_hdr.port_status != 0) && - ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE || - (io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) { - /* - * For hardware error sense keys, the sense key - * specific value is defined to be a retry count, - * but we use it to pass back an internal FETD - * error code. XXX KDM Hopefully the FETD is only - * using 16 bits for an error code, since that's - * all the space we have in the sks field. - */ - ctl_set_internal_failure(&io->scsiio, - /*sks_valid*/ 1, - /*retry_count*/ - io->io_hdr.port_status); } +done: ctl_data_submit_done(io); return(0); } -static int -ctl_backend_ramdisk_submit(union ctl_io *io) +static void +ctl_backend_ramdisk_compare(union ctl_io *io) { - struct ctl_be_lun *cbe_lun; - struct ctl_lba_len_flags *lbalen; + struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io); + u_int lbas, len; - cbe_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[ - CTL_PRIV_BACKEND_LUN].ptr; - lbalen = (struct ctl_lba_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; - if (lbalen->flags & CTL_LLF_VERIFY) { - ctl_set_success(&io->scsiio); - ctl_data_submit_done(io); - return (CTL_RETVAL_COMPLETE); - } - io->io_hdr.ctl_private[CTL_PRIV_BACKEND].integer = - lbalen->len * cbe_lun->blocksize; - ctl_backend_ramdisk_continue(io); - return (CTL_RETVAL_COMPLETE); + lbas = ARGS(io)->len - PRIV(io)->len; + lbas = MIN(lbas, 131072 / cbe_lun->blocksize); + len = lbas * cbe_lun->blocksize; + + io->scsiio.be_move_done = ctl_backend_ramdisk_move_done; + io->scsiio.kern_data_ptr = malloc(len, M_RAMDISK, M_WAITOK); + io->scsiio.kern_data_len = len; + io->scsiio.kern_sg_entries = 0; + io->io_hdr.flags |= CTL_FLAG_ALLOCATED; + PRIV(io)->len += lbas; +#ifdef CTL_TIME_IO + getbinuptime(&io->io_hdr.dma_start_bt); +#endif + ctl_datamove(io); } static void -ctl_backend_ramdisk_continue(union ctl_io *io) +ctl_backend_ramdisk_rw(union ctl_io *io) { - struct ctl_be_ramdisk_softc *softc; - int len, len_filled, sg_filled; -#ifdef CTL_RAMDISK_PAGES + struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io); + struct ctl_be_ramdisk_lun *be_lun = cbe_lun->be_lun; struct ctl_sg_entry *sg_entries; - int i; -#endif - - softc = &rd_softc; - len = io->io_hdr.ctl_private[CTL_PRIV_BACKEND].integer; -#ifdef CTL_RAMDISK_PAGES - sg_filled = min(btoc(len), softc->num_pages); - if (sg_filled > 1) { + uint8_t *page; + uint64_t lba; + u_int i, len, lbaoff, lbas, sgs, off; + getpage_op_t op; + + lba = ARGS(io)->lba + PRIV(io)->len; + lbaoff = lba & ~(UINT_MAX << cbe_lun->pblockexp); + lbas = ARGS(io)->len - PRIV(io)->len; + lbas = MIN(lbas, (SGPP << cbe_lun->pblockexp) - lbaoff); + sgs = (lbas + lbaoff + be_lun->pblockmul - 1) >> cbe_lun->pblockexp; + off = lbaoff * cbe_lun->blocksize; + op = (ARGS(io)->flags & CTL_LLF_WRITE) ? GP_WRITE : GP_READ; + if (sgs > 1) { io->scsiio.kern_data_ptr = malloc(sizeof(struct ctl_sg_entry) * - sg_filled, M_RAMDISK, - M_WAITOK); + sgs, M_RAMDISK, M_WAITOK); sg_entries = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr; - for (i = 0, len_filled = 0; i < sg_filled; i++) { - sg_entries[i].addr = softc->ramdisk_pages[i]; - sg_entries[i].len = MIN(PAGE_SIZE, len - len_filled); - len_filled += sg_entries[i].len; + len = lbas * cbe_lun->blocksize; + for (i = 0; i < sgs; i++) { + page = ctl_backend_ramdisk_getpage(be_lun, + (lba >> cbe_lun->pblockexp) + i, op); + if (page == P_UNMAPPED || page == P_ANCHORED) { + free(io->scsiio.kern_data_ptr, M_RAMDISK); +nospc: + ctl_set_space_alloc_fail(&io->scsiio); + ctl_data_submit_done(io); + return; + } + sg_entries[i].addr = page + off; + sg_entries[i].len = MIN(len, be_lun->pblocksize - off); + len -= sg_entries[i].len; + off = 0; } } else { - sg_filled = 0; - len_filled = len; - io->scsiio.kern_data_ptr = softc->ramdisk_pages[0]; + page = ctl_backend_ramdisk_getpage(be_lun, + lba >> cbe_lun->pblockexp, op); + if (page == P_UNMAPPED || page == P_ANCHORED) + goto nospc; + sgs = 0; + io->scsiio.kern_data_ptr = page + off; } -#else - sg_filled = 0; - len_filled = min(len, softc->rd_size); - io->scsiio.kern_data_ptr = softc->ramdisk_buffer; -#endif /* CTL_RAMDISK_PAGES */ io->scsiio.be_move_done = ctl_backend_ramdisk_move_done; - io->scsiio.kern_data_resid = 0; - io->scsiio.kern_data_len = len_filled; - io->scsiio.kern_sg_entries = sg_filled; + io->scsiio.kern_data_len = lbas * cbe_lun->blocksize; + io->scsiio.kern_sg_entries = sgs; io->io_hdr.flags |= CTL_FLAG_ALLOCATED; - io->io_hdr.ctl_private[CTL_PRIV_BACKEND].integer -= len_filled; + PRIV(io)->len += lbas; #ifdef CTL_TIME_IO getbinuptime(&io->io_hdr.dma_start_bt); #endif ctl_datamove(io); } +static int +ctl_backend_ramdisk_submit(union ctl_io *io) +{ + struct ctl_lba_len_flags *lbalen = ARGS(io); + + if (lbalen->flags & CTL_LLF_VERIFY) { + ctl_set_success(&io->scsiio); + ctl_data_submit_done(io); + return (CTL_RETVAL_COMPLETE); + } + PRIV(io)->len = 0; + if (lbalen->flags & CTL_LLF_COMPARE) + ctl_backend_ramdisk_compare(io); + else + ctl_backend_ramdisk_rw(io); + return (CTL_RETVAL_COMPLETE); +} + static void ctl_backend_ramdisk_worker(void *context, int pending) { @@ -338,7 +556,6 @@ ctl_backend_ramdisk_worker(void *context, int pending) union ctl_io *io; be_lun = (struct ctl_be_ramdisk_lun *)context; - mtx_lock(&be_lun->queue_lock); for (;;) { io = (union ctl_io *)STAILQ_FIRST(&be_lun->cont_queue); @@ -346,7 +563,10 @@ ctl_backend_ramdisk_worker(void *context, int pending) STAILQ_REMOVE(&be_lun->cont_queue, &io->io_hdr, ctl_io_hdr, links); mtx_unlock(&be_lun->queue_lock); - ctl_backend_ramdisk_continue(io); + if (ARGS(io)->flags & CTL_LLF_COMPARE) + ctl_backend_ramdisk_compare(io); + else + ctl_backend_ramdisk_rw(io); mtx_lock(&be_lun->queue_lock); continue; } @@ -361,6 +581,259 @@ ctl_backend_ramdisk_worker(void *context, int pending) } static int +ctl_backend_ramdisk_gls(union ctl_io *io) +{ + struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io); + struct ctl_be_ramdisk_lun *be_lun = cbe_lun->be_lun; + struct scsi_get_lba_status_data *data; + uint8_t *page; + u_int lbaoff; + + data = (struct scsi_get_lba_status_data *)io->scsiio.kern_data_ptr; + scsi_u64to8b(ARGS(io)->lba, data->descr[0].addr); + lbaoff = ARGS(io)->lba & ~(UINT_MAX << cbe_lun->pblockexp); + scsi_ulto4b(be_lun->pblockmul - lbaoff, data->descr[0].length); + page = ctl_backend_ramdisk_getpage(be_lun, + ARGS(io)->lba >> cbe_lun->pblockexp, GP_OTHER); + if (page == P_UNMAPPED) + data->descr[0].status = 1; + else if (page == P_ANCHORED) + data->descr[0].status = 2; + else + data->descr[0].status = 0; + ctl_config_read_done(io); + return (CTL_RETVAL_COMPLETE); +} + +static int +ctl_backend_ramdisk_config_read(union ctl_io *io) +{ + int retval = 0; + + switch (io->scsiio.cdb[0]) { + case SERVICE_ACTION_IN: + if (io->scsiio.cdb[1] == SGLS_SERVICE_ACTION) { + retval = ctl_backend_ramdisk_gls(io); + break; + } + ctl_set_invalid_field(&io->scsiio, + /*sks_valid*/ 1, + /*command*/ 1, + /*field*/ 1, + /*bit_valid*/ 1, + /*bit*/ 4); + ctl_config_read_done(io); + retval = CTL_RETVAL_COMPLETE; + break; + default: + ctl_set_invalid_opcode(&io->scsiio); + ctl_config_read_done(io); + retval = CTL_RETVAL_COMPLETE; + break; + } + return (retval); +} + +static void +ctl_backend_ramdisk_delete(struct ctl_be_lun *cbe_lun, off_t lba, off_t len, + int anchor) +{ + struct ctl_be_ramdisk_lun *be_lun = cbe_lun->be_lun; + uint8_t *page; + uint64_t p, lp; + u_int lbaoff; + getpage_op_t op = anchor ? GP_ANCHOR : GP_OTHER; + + /* Partially zero first partial page. */ + p = lba >> cbe_lun->pblockexp; + lbaoff = lba & ~(UINT_MAX << cbe_lun->pblockexp); + if (lbaoff != 0) { + page = ctl_backend_ramdisk_getpage(be_lun, p, op); + if (page != P_UNMAPPED && page != P_ANCHORED) { + memset(page + lbaoff * cbe_lun->blocksize, 0, + min(len, be_lun->pblockmul - lbaoff) * + cbe_lun->blocksize); + } + p++; + } + + /* Partially zero last partial page. */ + lp = (lba + len) >> cbe_lun->pblockexp; + lbaoff = (lba + len) & ~(UINT_MAX << cbe_lun->pblockexp); + if (p <= lp && lbaoff != 0) { + page = ctl_backend_ramdisk_getpage(be_lun, lp, op); + if (page != P_UNMAPPED && page != P_ANCHORED) + memset(page, 0, lbaoff * cbe_lun->blocksize); + } + + /* Delete remaining full pages. */ + if (anchor) { + for (; p < lp; p++) + ctl_backend_ramdisk_anchorpage(be_lun, p); + } else { + for (; p < lp; p++) + ctl_backend_ramdisk_unmappage(be_lun, p); + } +} + +static void +ctl_backend_ramdisk_ws(union ctl_io *io) +{ + struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io); + struct ctl_be_ramdisk_lun *be_lun = cbe_lun->be_lun; + struct ctl_lba_len_flags *lbalen = ARGS(io); + uint8_t *page; + uint64_t lba; + u_int lbaoff, lbas; + + if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP | SWS_ANCHOR | SWS_NDOB)) { + ctl_set_invalid_field(&io->scsiio, + /*sks_valid*/ 1, + /*command*/ 1, + /*field*/ 1, + /*bit_valid*/ 0, + /*bit*/ 0); + ctl_config_write_done(io); + return; + } + if (lbalen->flags & SWS_UNMAP) { + ctl_backend_ramdisk_delete(cbe_lun, lbalen->lba, lbalen->len, + (lbalen->flags & SWS_ANCHOR) != 0); + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + return; + } + + for (lba = lbalen->lba, lbas = lbalen->len; lbas > 0; lba++, lbas--) { + page = ctl_backend_ramdisk_getpage(be_lun, + lba >> cbe_lun->pblockexp, GP_WRITE); + if (page == P_UNMAPPED || page == P_ANCHORED) { + ctl_set_space_alloc_fail(&io->scsiio); + ctl_data_submit_done(io); + return; + } + lbaoff = lba & ~(UINT_MAX << cbe_lun->pblockexp); + page += lbaoff * cbe_lun->blocksize; + if (lbalen->flags & SWS_NDOB) { + memset(page, 0, cbe_lun->blocksize); + } else { + memcpy(page, io->scsiio.kern_data_ptr, + cbe_lun->blocksize); + } + if (lbalen->flags & SWS_LBDATA) + scsi_ulto4b(lba, page); + } + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); +} + +static void +ctl_backend_ramdisk_unmap(union ctl_io *io) +{ + struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io); + struct ctl_ptr_len_flags *ptrlen = (struct ctl_ptr_len_flags *)ARGS(io); + struct scsi_unmap_desc *buf, *end; + + if ((ptrlen->flags & ~SU_ANCHOR) != 0) { + ctl_set_invalid_field(&io->scsiio, + /*sks_valid*/ 0, + /*command*/ 0, + /*field*/ 0, + /*bit_valid*/ 0, + /*bit*/ 0); + ctl_config_write_done(io); + return; + } + + buf = (struct scsi_unmap_desc *)ptrlen->ptr; + end = buf + ptrlen->len / sizeof(*buf); + for (; buf < end; buf++) { + ctl_backend_ramdisk_delete(cbe_lun, + scsi_8btou64(buf->lba), scsi_4btoul(buf->length), + (ptrlen->flags & SU_ANCHOR) != 0); + } + + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); +} + +static int +ctl_backend_ramdisk_config_write(union ctl_io *io) +{ + struct ctl_be_lun *cbe_lun = CTL_BACKEND_LUN(io); + int retval = 0; + + switch (io->scsiio.cdb[0]) { + case SYNCHRONIZE_CACHE: + case SYNCHRONIZE_CACHE_16: + /* We have no cache to flush. */ + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + break; + case START_STOP_UNIT: { + struct scsi_start_stop_unit *cdb; + + cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb; + if ((cdb->how & SSS_PC_MASK) != 0) { + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + break; + } + if (cdb->how & SSS_START) { + if (cdb->how & SSS_LOEJ) + ctl_lun_has_media(cbe_lun); + ctl_start_lun(cbe_lun); + } else { + ctl_stop_lun(cbe_lun); + if (cdb->how & SSS_LOEJ) + ctl_lun_ejected(cbe_lun); + } + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + break; + } + case PREVENT_ALLOW: + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + break; + case WRITE_SAME_10: + case WRITE_SAME_16: + ctl_backend_ramdisk_ws(io); + break; + case UNMAP: + ctl_backend_ramdisk_unmap(io); + break; + default: + ctl_set_invalid_opcode(&io->scsiio); + ctl_config_write_done(io); + retval = CTL_RETVAL_COMPLETE; + break; + } + + return (retval); +} + +static uint64_t +ctl_backend_ramdisk_lun_attr(void *arg, const char *attrname) +{ + struct ctl_be_ramdisk_lun *be_lun = arg; + uint64_t val; + + val = UINT64_MAX; + if (be_lun->cap_bytes == 0) + return (val); + sx_slock(&be_lun->page_lock); + if (strcmp(attrname, "blocksused") == 0) { + val = be_lun->cap_used / be_lun->cbe_lun.blocksize; + } else if (strcmp(attrname, "blocksavail") == 0) { + val = (be_lun->cap_bytes - be_lun->cap_used) / + be_lun->cbe_lun.blocksize; + } + sx_sunlock(&be_lun->page_lock); + return (val); +} + +static int ctl_backend_ramdisk_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { @@ -477,6 +950,9 @@ ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc, taskqueue_drain_all(be_lun->io_taskqueue); taskqueue_free(be_lun->io_taskqueue); ctl_free_opts(&be_lun->cbe_lun.options); + free(be_lun->zero_page, M_RAMDISK); + ctl_backend_ramdisk_freeallpages(be_lun->pages, be_lun->indir); + sx_destroy(&be_lun->page_lock); mtx_destroy(&be_lun->queue_lock); free(be_lun, M_RAMDISK); } @@ -498,6 +974,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, struct ctl_lun_create_params *params; char *value; char tmpstr[32]; + uint64_t t; int retval; retval = 0; @@ -524,6 +1001,19 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, } else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF) cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY; + be_lun->pblocksize = PAGE_SIZE; + value = ctl_get_opt(&cbe_lun->options, "pblocksize"); + if (value != NULL) { + ctl_expand_number(value, &t); + be_lun->pblocksize = t; + } + if (be_lun->pblocksize < 512 || be_lun->pblocksize > 131072) { + snprintf(req->error_str, sizeof(req->error_str), + "%s: unsupported pblocksize %u", __func__, + be_lun->pblocksize); + goto bailout_error; + } + if (cbe_lun->lun_type == T_DIRECT || cbe_lun->lun_type == T_CDROM) { if (params->blocksize_bytes != 0) @@ -532,6 +1022,14 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, cbe_lun->blocksize = 2048; else cbe_lun->blocksize = 512; + be_lun->pblockmul = be_lun->pblocksize / cbe_lun->blocksize; + if (be_lun->pblockmul < 1 || !powerof2(be_lun->pblockmul)) { + snprintf(req->error_str, sizeof(req->error_str), + "%s: pblocksize %u not exp2 of blocksize %u", + __func__, + be_lun->pblocksize, cbe_lun->blocksize); + goto bailout_error; + } if (params->lun_size_bytes < cbe_lun->blocksize) { snprintf(req->error_str, sizeof(req->error_str), "%s: LUN size %ju < blocksize %u", __func__, @@ -540,9 +1038,25 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, } be_lun->size_blocks = params->lun_size_bytes / cbe_lun->blocksize; be_lun->size_bytes = be_lun->size_blocks * cbe_lun->blocksize; + be_lun->indir = 0; + t = be_lun->size_bytes / be_lun->pblocksize; + while (t > 1) { + t /= PPP; + be_lun->indir++; + } cbe_lun->maxlba = be_lun->size_blocks - 1; - cbe_lun->atomicblock = UINT32_MAX; - cbe_lun->opttxferlen = softc->rd_size / cbe_lun->blocksize; + cbe_lun->pblockexp = fls(be_lun->pblockmul) - 1; + cbe_lun->pblockoff = 0; + cbe_lun->ublockexp = cbe_lun->pblockexp; + cbe_lun->ublockoff = 0; + cbe_lun->atomicblock = be_lun->pblocksize; + cbe_lun->opttxferlen = SGPP * be_lun->pblocksize; + value = ctl_get_opt(&cbe_lun->options, "capacity"); + if (value != NULL) + ctl_expand_number(value, &be_lun->cap_bytes); + } else { + be_lun->pblockmul = 1; + cbe_lun->pblockexp = 0; } /* Tell the user the blocksize we ended up using */ @@ -550,7 +1064,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, params->lun_size_bytes = be_lun->size_bytes; value = ctl_get_opt(&cbe_lun->options, "unmap"); - if (value != NULL && strcmp(value, "on") == 0) + if (value == NULL || strcmp(value, "off") != 0) cbe_lun->flags |= CTL_LUN_FLAG_UNMAP; value = ctl_get_opt(&cbe_lun->options, "readonly"); if (value != NULL) { @@ -605,6 +1119,11 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, } STAILQ_INIT(&be_lun->cont_queue); + sx_init(&be_lun->page_lock, "cram page lock"); + if (be_lun->cap_bytes == 0) + be_lun->pages = malloc(be_lun->pblocksize, M_RAMDISK, M_WAITOK); + be_lun->zero_page = malloc(be_lun->pblocksize, M_RAMDISK, + M_WAITOK|M_ZERO); mtx_init(&be_lun->queue_lock, "cram queue lock", NULL, MTX_DEF); TASK_INIT(&be_lun->io_task, /*priority*/0, ctl_backend_ramdisk_worker, be_lun); @@ -679,10 +1198,12 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, bailout_error: req->status = CTL_LUN_ERROR; if (be_lun != NULL) { - if (be_lun->io_taskqueue != NULL) { + if (be_lun->io_taskqueue != NULL) taskqueue_free(be_lun->io_taskqueue); - } ctl_free_opts(&cbe_lun->options); + free(be_lun->zero_page, M_RAMDISK); + ctl_backend_ramdisk_freeallpages(be_lun->pages, be_lun->indir); + sx_destroy(&be_lun->page_lock); mtx_destroy(&be_lun->queue_lock); free(be_lun, M_RAMDISK); } @@ -838,104 +1359,3 @@ ctl_backend_ramdisk_lun_config_status(void *be_lun, } mtx_unlock(&softc->lock); } - -static int -ctl_backend_ramdisk_config_write(union ctl_io *io) -{ - struct ctl_be_lun *cbe_lun; - int retval; - - cbe_lun = (struct ctl_be_lun *)io->io_hdr.ctl_private[ - CTL_PRIV_BACKEND_LUN].ptr; - retval = 0; - switch (io->scsiio.cdb[0]) { - case SYNCHRONIZE_CACHE: - case SYNCHRONIZE_CACHE_16: - /* - * The upper level CTL code will filter out any CDBs with - * the immediate bit set and return the proper error. It - * will also not allow a sync cache command to go to a LUN - * that is powered down. - * - * We don't really need to worry about what LBA range the - * user asked to be synced out. When they issue a sync - * cache command, we'll sync out the whole thing. - * - * This is obviously just a stubbed out implementation. - * The real implementation will be in the RAIDCore/CTL - * interface, and can only really happen when RAIDCore - * implements a per-array cache sync. - */ - ctl_set_success(&io->scsiio); - ctl_config_write_done(io); - break; - case START_STOP_UNIT: { - struct scsi_start_stop_unit *cdb; - - cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb; - if ((cdb->how & SSS_PC_MASK) != 0) { - ctl_set_success(&io->scsiio); - ctl_config_write_done(io); - break; - } - if (cdb->how & SSS_START) { - if (cdb->how & SSS_LOEJ) - ctl_lun_has_media(cbe_lun); - ctl_start_lun(cbe_lun); - } else { - ctl_stop_lun(cbe_lun); - if (cdb->how & SSS_LOEJ) - ctl_lun_ejected(cbe_lun); - } - ctl_set_success(&io->scsiio); - ctl_config_write_done(io); - break; - } - case PREVENT_ALLOW: - case WRITE_SAME_10: - case WRITE_SAME_16: - case UNMAP: - ctl_set_success(&io->scsiio); - ctl_config_write_done(io); - break; - default: - ctl_set_invalid_opcode(&io->scsiio); - ctl_config_write_done(io); - retval = CTL_RETVAL_COMPLETE; - break; - } - - return (retval); -} - -static int -ctl_backend_ramdisk_config_read(union ctl_io *io) -{ - int retval = 0; - - switch (io->scsiio.cdb[0]) { - case SERVICE_ACTION_IN: - if (io->scsiio.cdb[1] == SGLS_SERVICE_ACTION) { - /* We have nothing to tell, leave default data. */ - ctl_config_read_done(io); - retval = CTL_RETVAL_COMPLETE; - break; - } - ctl_set_invalid_field(&io->scsiio, - /*sks_valid*/ 1, - /*command*/ 1, - /*field*/ 1, - /*bit_valid*/ 1, - /*bit*/ 4); - ctl_config_read_done(io); - retval = CTL_RETVAL_COMPLETE; - break; - default: - ctl_set_invalid_opcode(&io->scsiio); - ctl_config_read_done(io); - retval = CTL_RETVAL_COMPLETE; - break; - } - - return (retval); -} diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c index eaedea6..e42df74 100644 --- a/sys/cam/ctl/ctl_cmd_table.c +++ b/sys/cam/ctl/ctl_cmd_table.c @@ -990,7 +990,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT, - CTL_LUN_PAT_NONE, 6, {0x11, 0, 0, 0xff, 0x07}}, + CTL_LUN_PAT_NONE, 6, {0x13, 0, 0, 0xff, 0x07}}, /* 16 RESERVE(6) */ {ctl_scsi_reserve, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | @@ -1260,7 +1260,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = CTL_CMD_FLAG_OK_ON_NO_MEDIA | CTL_CMD_FLAG_OK_ON_STANDBY | CTL_FLAG_DATA_OUT, - CTL_LUN_PAT_NONE, 10, {0x11, 0, 0, 0, 0, 0, 0xff, 0xff, 0x07} }, + CTL_LUN_PAT_NONE, 10, {0x13, 0, 0, 0, 0, 0, 0xff, 0xff, 0x07} }, /* 56 RESERVE(10) */ {ctl_scsi_reserve, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | diff --git a/sys/cam/ctl/ctl_error.c b/sys/cam/ctl/ctl_error.c index 02330a1..9c222fa 100644 --- a/sys/cam/ctl/ctl_error.c +++ b/sys/cam/ctl/ctl_error.c @@ -129,7 +129,7 @@ ctl_set_sense(struct ctl_scsiio *ctsio, int current_error, int sense_key, * completed. Therefore we can safely access the LUN structure and * flags without the lock. */ - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + lun = CTL_LUN(ctsio); va_start(ap, ascq); sense_len = 0; @@ -641,6 +641,18 @@ ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command, /*data*/ sks, SSD_ELEM_NONE); } +void +ctl_set_invalid_field_ciu(struct ctl_scsiio *ctsio) +{ + + /* "Invalid field in command information unit" */ + ctl_set_sense(ctsio, + /*current_error*/ 1, + /*sense_key*/ SSD_KEY_ABORTED_COMMAND, + /*ascq*/ 0x0E, + /*ascq*/ 0x03, + SSD_ELEM_NONE); +} void ctl_set_invalid_opcode(struct ctl_scsiio *ctsio) diff --git a/sys/cam/ctl/ctl_error.h b/sys/cam/ctl/ctl_error.h index d4cdbb3..75c948c 100644 --- a/sys/cam/ctl/ctl_error.h +++ b/sys/cam/ctl/ctl_error.h @@ -66,6 +66,7 @@ void ctl_set_overlapped_cmd(struct ctl_scsiio *ctsio); void ctl_set_overlapped_tag(struct ctl_scsiio *ctsio, uint8_t tag); void ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command, int field, int bit_valid, int bit); +void ctl_set_invalid_field_ciu(struct ctl_scsiio *ctsio); void ctl_set_invalid_opcode(struct ctl_scsiio *ctsio); void ctl_set_param_len_error(struct ctl_scsiio *ctsio); void ctl_set_already_locked(struct ctl_scsiio *ctsio); diff --git a/sys/cam/ctl/ctl_frontend.c b/sys/cam/ctl/ctl_frontend.c index 75837b5..765a31d 100644 --- a/sys/cam/ctl/ctl_frontend.c +++ b/sys/cam/ctl/ctl_frontend.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003 Silicon Graphics International Corp. + * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -69,12 +70,11 @@ ctl_frontend_register(struct ctl_frontend *fe) { struct ctl_softc *softc = control_softc; struct ctl_frontend *fe_tmp; + int error; KASSERT(softc != NULL, ("CTL is not initialized")); - /* - * Sanity check, make sure this isn't a duplicate registration. - */ + /* Sanity check, make sure this isn't a duplicate registration. */ mtx_lock(&softc->ctl_lock); STAILQ_FOREACH(fe_tmp, &softc->fe_list, links) { if (strcmp(fe_tmp->name, fe->name) == 0) { @@ -85,11 +85,14 @@ ctl_frontend_register(struct ctl_frontend *fe) mtx_unlock(&softc->ctl_lock); STAILQ_INIT(&fe->port_list); - /* - * Call the frontend's initialization routine. - */ - if (fe->init != NULL) - fe->init(); + /* Call the frontend's initialization routine. */ + if (fe->init != NULL) { + if ((error = fe->init()) != 0) { + printf("%s frontend init error: %d\n", + fe->name, error); + return (error); + } + } mtx_lock(&softc->ctl_lock); softc->num_frontends++; @@ -102,20 +105,21 @@ int ctl_frontend_deregister(struct ctl_frontend *fe) { struct ctl_softc *softc = control_softc; - - if (!STAILQ_EMPTY(&fe->port_list)) - return (-1); + int error; + + /* Call the frontend's shutdown routine.*/ + if (fe->shutdown != NULL) { + if ((error = fe->shutdown()) != 0) { + printf("%s frontend shutdown error: %d\n", + fe->name, error); + return (error); + } + } mtx_lock(&softc->ctl_lock); STAILQ_REMOVE(&softc->fe_list, fe, ctl_frontend, links); softc->num_frontends--; mtx_unlock(&softc->ctl_lock); - - /* - * Call the frontend's shutdown routine. - */ - if (fe->shutdown != NULL) - fe->shutdown(); return (0); } @@ -192,13 +196,14 @@ error: mtx_unlock(&softc->ctl_lock); return (retval); } + port->targ_port = port_num; port->ctl_pool_ref = pool; - if (port->options.stqh_first == NULL) STAILQ_INIT(&port->options); + port->stats.item = port_num; + mtx_init(&port->port_lock, "CTL port", NULL, MTX_DEF); mtx_lock(&softc->ctl_lock); - port->targ_port = port_num; STAILQ_INSERT_TAIL(&port->frontend->port_list, port, fe_links); for (tport = NULL, nport = STAILQ_FIRST(&softc->port_list); nport != NULL && nport->targ_port < port_num; @@ -218,17 +223,11 @@ int ctl_port_deregister(struct ctl_port *port) { struct ctl_softc *softc = port->ctl_softc; - struct ctl_io_pool *pool; - int retval, i; - - retval = 0; + struct ctl_io_pool *pool = (struct ctl_io_pool *)port->ctl_pool_ref; + int i; - pool = (struct ctl_io_pool *)port->ctl_pool_ref; - - if (port->targ_port == -1) { - retval = 1; - goto bailout; - } + if (port->targ_port == -1) + return (1); mtx_lock(&softc->ctl_lock); STAILQ_REMOVE(&softc->port_list, port, ctl_port, links); @@ -251,9 +250,9 @@ ctl_port_deregister(struct ctl_port *port) for (i = 0; i < port->max_initiators; i++) free(port->wwpn_iid[i].name, M_CTL); free(port->wwpn_iid, M_CTL); + mtx_destroy(&port->port_lock); -bailout: - return (retval); + return (0); } void @@ -315,9 +314,9 @@ ctl_port_online(struct ctl_port *port) if (port->lun_enable != NULL) { if (port->lun_map) { - for (l = 0; l < CTL_MAX_LUNS; l++) { - if (ctl_lun_map_from_port(port, l) >= - CTL_MAX_LUNS) + for (l = 0; l < port->lun_map_size; l++) { + if (ctl_lun_map_from_port(port, l) == + UINT32_MAX) continue; port->lun_enable(port->targ_lun_arg, l); } @@ -338,7 +337,7 @@ ctl_port_online(struct ctl_port *port) } port->status |= CTL_PORT_STATUS_ONLINE; STAILQ_FOREACH(lun, &softc->lun_list, links) { - if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + if (ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX) continue; mtx_lock(&lun->lun_lock); ctl_est_ua_all(lun, -1, CTL_UA_INQ_CHANGE); @@ -359,9 +358,9 @@ ctl_port_offline(struct ctl_port *port) port->port_offline(port->onoff_arg); if (port->lun_disable != NULL) { if (port->lun_map) { - for (l = 0; l < CTL_MAX_LUNS; l++) { - if (ctl_lun_map_from_port(port, l) >= - CTL_MAX_LUNS) + for (l = 0; l < port->lun_map_size; l++) { + if (ctl_lun_map_from_port(port, l) == + UINT32_MAX) continue; port->lun_disable(port->targ_lun_arg, l); } @@ -373,7 +372,7 @@ ctl_port_offline(struct ctl_port *port) mtx_lock(&softc->ctl_lock); port->status &= ~CTL_PORT_STATUS_ONLINE; STAILQ_FOREACH(lun, &softc->lun_list, links) { - if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + if (ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX) continue; mtx_lock(&lun->lun_lock); ctl_est_ua_all(lun, -1, CTL_UA_INQ_CHANGE); diff --git a/sys/cam/ctl/ctl_frontend.h b/sys/cam/ctl/ctl_frontend.h index 1dd970a..38eb863 100644 --- a/sys/cam/ctl/ctl_frontend.h +++ b/sys/cam/ctl/ctl_frontend.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003 Silicon Graphics International Corp. + * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,6 +40,8 @@ #ifndef _CTL_FRONTEND_H_ #define _CTL_FRONTEND_H_ +#include <cam/ctl/ctl_ioctl.h> + typedef enum { CTL_PORT_STATUS_NONE = 0x00, CTL_PORT_STATUS_ONLINE = 0x01, @@ -46,7 +49,7 @@ typedef enum { } ctl_port_status; typedef int (*fe_init_t)(void); -typedef void (*fe_shutdown_t)(void); +typedef int (*fe_shutdown_t)(void); typedef void (*port_func_t)(void *onoff_arg); typedef int (*port_info_func_t)(void *onoff_arg, struct sbuf *sb); typedef int (*lun_func_t)(void *arg, int lun_id); @@ -58,12 +61,13 @@ typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag, { \ switch (type) { \ case MOD_LOAD: \ - ctl_frontend_register( \ - (struct ctl_frontend *)data); \ + return (ctl_frontend_register( \ + (struct ctl_frontend *)data)); \ break; \ case MOD_UNLOAD: \ - printf(#name " module unload - not possible for this module type\n"); \ - return EINVAL; \ + return (ctl_frontend_deregister( \ + (struct ctl_frontend *)data)); \ + break; \ default: \ return EOPNOTSUPP; \ } \ @@ -225,6 +229,7 @@ struct ctl_port { void *onoff_arg; /* passed to CTL */ lun_func_t lun_enable; /* passed to CTL */ lun_func_t lun_disable; /* passed to CTL */ + int lun_map_size; /* passed to CTL */ uint32_t *lun_map; /* passed to CTL */ void *targ_lun_arg; /* passed to CTL */ void (*fe_datamove)(union ctl_io *io); /* passed to CTL */ @@ -242,6 +247,8 @@ struct ctl_port { struct ctl_devid *port_devid; /* passed to CTL */ struct ctl_devid *target_devid; /* passed to CTL */ struct ctl_devid *init_devid; /* passed to CTL */ + struct ctl_io_stats stats; /* used by CTL */ + struct mtx port_lock; /* used by CTL */ STAILQ_ENTRY(ctl_port) fe_links; /* used by CTL */ STAILQ_ENTRY(ctl_port) links; /* used by CTL */ }; diff --git a/sys/cam/ctl/ctl_frontend_cam_sim.c b/sys/cam/ctl/ctl_frontend_cam_sim.c index 2166f45..9a0ca9a 100644 --- a/sys/cam/ctl/ctl_frontend_cam_sim.c +++ b/sys/cam/ctl/ctl_frontend_cam_sim.c @@ -94,15 +94,14 @@ struct cfcs_softc { CAM_SNS_BUF_PHYS | CAM_CDB_PHYS | CAM_SENSE_PTR | \ CAM_SENSE_PHYS) -int cfcs_init(void); +static int cfcs_init(void); +static int cfcs_shutdown(void); static void cfcs_poll(struct cam_sim *sim); static void cfcs_online(void *arg); static void cfcs_offline(void *arg); static void cfcs_datamove(union ctl_io *io); static void cfcs_done(union ctl_io *io); void cfcs_action(struct cam_sim *sim, union ccb *ccb); -static void cfcs_async(void *callback_arg, uint32_t code, - struct cam_path *path, void *arg); struct cfcs_softc cfcs_softc; /* @@ -121,14 +120,14 @@ static struct ctl_frontend cfcs_frontend = { .name = "camsim", .init = cfcs_init, + .shutdown = cfcs_shutdown, }; CTL_FRONTEND_DECLARE(ctlcfcs, cfcs_frontend); -int +static int cfcs_init(void) { struct cfcs_softc *softc; - struct ccb_setasync csa; struct ctl_port *port; int retval; @@ -214,13 +213,6 @@ cfcs_init(void) goto bailout; } - xpt_setup_ccb(&csa.ccb_h, softc->path, CAM_PRIORITY_NONE); - csa.ccb_h.func_code = XPT_SASYNC_CB; - csa.event_enable = AC_LOST_DEVICE; - csa.callback = cfcs_async; - csa.callback_arg = softc->sim; - xpt_action((union ccb *)&csa); - mtx_unlock(&softc->lock); return (retval); @@ -236,6 +228,27 @@ bailout: return (retval); } +static int +cfcs_shutdown(void) +{ + struct cfcs_softc *softc = &cfcs_softc; + struct ctl_port *port = &softc->port; + int error; + + ctl_port_offline(port); + + mtx_lock(&softc->lock); + xpt_free_path(softc->path); + xpt_bus_deregister(cam_sim_path(softc->sim)); + cam_sim_free(softc->sim, /*free_devq*/ TRUE); + mtx_unlock(&softc->lock); + mtx_destroy(&softc->lock); + + if ((error = ctl_port_deregister(port)) != 0) + printf("%s: cam_sim port deregistration failed\n", __func__); + return (error); +} + static void cfcs_poll(struct cam_sim *sim) { @@ -300,14 +313,10 @@ cfcs_datamove(union ctl_io *io) struct ctl_sg_entry ctl_sg_entry, *ctl_sglist; int cam_sg_count, ctl_sg_count, cam_sg_start; int cam_sg_offset; - int len_to_copy, len_copied; + int len_to_copy; int ctl_watermark, cam_watermark; int i, j; - - cam_sg_offset = 0; - cam_sg_start = 0; - ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; /* @@ -330,6 +339,8 @@ cfcs_datamove(union ctl_io *io) cam_sglist = (bus_dma_segment_t *)ccb->csio.data_ptr; cam_sg_count = ccb->csio.sglist_cnt; + cam_sg_start = cam_sg_count; + cam_sg_offset = 0; for (i = 0, len_seen = 0; i < cam_sg_count; i++) { if ((len_seen + cam_sglist[i].ds_len) >= @@ -367,7 +378,6 @@ cfcs_datamove(union ctl_io *io) ctl_watermark = 0; cam_watermark = cam_sg_offset; - len_copied = 0; for (i = cam_sg_start, j = 0; i < cam_sg_count && j < ctl_sg_count;) { uint8_t *cam_ptr, *ctl_ptr; @@ -389,9 +399,6 @@ cfcs_datamove(union ctl_io *io) ctl_ptr = (uint8_t *)ctl_sglist[j].addr; ctl_ptr = ctl_ptr + ctl_watermark; - ctl_watermark += len_to_copy; - cam_watermark += len_to_copy; - if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) { CTL_DEBUG_PRINT(("%s: copying %d bytes to CAM\n", @@ -407,24 +414,27 @@ cfcs_datamove(union ctl_io *io) bcopy(cam_ptr, ctl_ptr, len_to_copy); } - len_copied += len_to_copy; + io->scsiio.ext_data_filled += len_to_copy; + io->scsiio.kern_data_resid -= len_to_copy; + cam_watermark += len_to_copy; if (cam_sglist[i].ds_len == cam_watermark) { i++; cam_watermark = 0; } + ctl_watermark += len_to_copy; if (ctl_sglist[j].len == ctl_watermark) { j++; ctl_watermark = 0; } } - io->scsiio.ext_data_filled += len_copied; - if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS) { io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = NULL; io->io_hdr.flags |= CTL_FLAG_STATUS_SENT; + ccb->csio.resid = ccb->csio.dxfer_len - + io->scsiio.ext_data_filled; ccb->ccb_h.status &= ~CAM_STATUS_MASK; ccb->ccb_h.status |= CAM_REQ_CMP; xpt_done(ccb); @@ -453,6 +463,10 @@ cfcs_done(union ctl_io *io) /* * Translate CTL status to CAM status. */ + if (ccb->ccb_h.func_code == XPT_SCSI_IO) { + ccb->csio.resid = ccb->csio.dxfer_len - + io->scsiio.ext_data_filled; + } ccb->ccb_h.status &= ~CAM_STATUS_MASK; switch (io->io_hdr.status & CTL_STATUS_MASK) { case CTL_SUCCESS: @@ -587,8 +601,7 @@ cfcs_action(struct cam_sim *sim, union ccb *ccb) __func__, csio->cdb_len, sizeof(io->scsiio.cdb)); } io->scsiio.cdb_len = min(csio->cdb_len, sizeof(io->scsiio.cdb)); - bcopy(csio->cdb_io.cdb_bytes, io->scsiio.cdb, - io->scsiio.cdb_len); + bcopy(scsiio_cdb_ptr(csio), io->scsiio.cdb, io->scsiio.cdb_len); ccb->ccb_h.status |= CAM_SIM_QUEUED; err = ctl_queue(io); @@ -801,9 +814,3 @@ cfcs_action(struct cam_sim *sim, union ccb *ccb) break; } } - -static void -cfcs_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg) -{ - -} diff --git a/sys/cam/ctl/ctl_frontend_ioctl.c b/sys/cam/ctl/ctl_frontend_ioctl.c index 97f29f1..4063c97 100644 --- a/sys/cam/ctl/ctl_frontend_ioctl.c +++ b/sys/cam/ctl/ctl_frontend_ioctl.c @@ -76,7 +76,7 @@ struct cfi_softc { static struct cfi_softc cfi_softc; static int cfi_init(void); -static void cfi_shutdown(void); +static int cfi_shutdown(void); static void cfi_datamove(union ctl_io *io); static void cfi_done(union ctl_io *io); @@ -93,6 +93,7 @@ cfi_init(void) { struct cfi_softc *isoftc = &cfi_softc; struct ctl_port *port; + int error = 0; memset(isoftc, 0, sizeof(*isoftc)); @@ -108,24 +109,25 @@ cfi_init(void) port->targ_port = -1; port->max_initiators = 1; - if (ctl_port_register(port) != 0) { + if ((error = ctl_port_register(port)) != 0) { printf("%s: ioctl port registration failed\n", __func__); - return (0); + return (error); } ctl_port_online(port); return (0); } -void +static int cfi_shutdown(void) { struct cfi_softc *isoftc = &cfi_softc; - struct ctl_port *port; + struct ctl_port *port = &isoftc->port; + int error = 0; - port = &isoftc->port; ctl_port_offline(port); - if (ctl_port_deregister(&isoftc->port) != 0) - printf("%s: ctl_frontend_deregister() failed\n", __func__); + if ((error = ctl_port_deregister(port)) != 0) + printf("%s: ioctl port deregistration failed\n", __func__); + return (error); } /* @@ -138,22 +140,20 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio) struct ctl_sg_entry ext_entry, kern_entry; int ext_sglen, ext_sg_entries, kern_sg_entries; int ext_sg_start, ext_offset; - int len_to_copy, len_copied; + int len_to_copy; int kern_watermark, ext_watermark; int ext_sglist_malloced; int i, j; - ext_sglist_malloced = 0; - ext_sg_start = 0; - ext_offset = 0; - CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove\n")); /* * If this flag is set, fake the data transfer. */ if (ctsio->io_hdr.flags & CTL_FLAG_NO_DATAMOVE) { - ctsio->ext_data_filled = ctsio->ext_data_len; + ext_sglist_malloced = 0; + ctsio->ext_data_filled += ctsio->kern_data_len; + ctsio->kern_data_resid = 0; goto bailout; } @@ -165,7 +165,6 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio) int len_seen; ext_sglen = ctsio->ext_sg_entries * sizeof(*ext_sglist); - ext_sglist = (struct ctl_sg_entry *)malloc(ext_sglen, M_CTL, M_WAITOK); ext_sglist_malloced = 1; @@ -174,6 +173,8 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio) goto bailout; } ext_sg_entries = ctsio->ext_sg_entries; + ext_sg_start = ext_sg_entries; + ext_offset = 0; len_seen = 0; for (i = 0; i < ext_sg_entries; i++) { if ((len_seen + ext_sglist[i].len) >= @@ -186,6 +187,7 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio) } } else { ext_sglist = &ext_entry; + ext_sglist_malloced = 0; ext_sglist->addr = ctsio->ext_data_ptr; ext_sglist->len = ctsio->ext_data_len; ext_sg_entries = 1; @@ -203,10 +205,8 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio) kern_sg_entries = 1; } - kern_watermark = 0; ext_watermark = ext_offset; - len_copied = 0; for (i = ext_sg_start, j = 0; i < ext_sg_entries && j < kern_sg_entries;) { uint8_t *ext_ptr, *kern_ptr; @@ -228,9 +228,6 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio) kern_ptr = (uint8_t *)kern_sglist[j].addr; kern_ptr = kern_ptr + kern_watermark; - kern_watermark += len_to_copy; - ext_watermark += len_to_copy; - if ((ctsio->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) { CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: copying %d " @@ -252,21 +249,22 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio) } } - len_copied += len_to_copy; + ctsio->ext_data_filled += len_to_copy; + ctsio->kern_data_resid -= len_to_copy; + ext_watermark += len_to_copy; if (ext_sglist[i].len == ext_watermark) { i++; ext_watermark = 0; } + kern_watermark += len_to_copy; if (kern_sglist[j].len == kern_watermark) { j++; kern_watermark = 0; } } - ctsio->ext_data_filled += len_copied; - CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: ext_sg_entries: %d, " "kern_sg_entries: %d\n", ext_sg_entries, kern_sg_entries)); @@ -274,10 +272,7 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio) "kern_data_len = %d\n", ctsio->ext_data_len, ctsio->kern_data_len)); - - /* XXX KDM set residual?? */ bailout: - if (ext_sglist_malloced != 0) free(ext_sglist, M_CTL); @@ -397,7 +392,7 @@ ctl_ioctl_io(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { union ctl_io *io; - void *pool_tmp; + void *pool_tmp, *sc_tmp; int retval = 0; /* @@ -414,8 +409,10 @@ ctl_ioctl_io(struct cdev *dev, u_long cmd, caddr_t addr, int flag, * spammed by the user's ctl_io. */ pool_tmp = io->io_hdr.pool; + sc_tmp = CTL_SOFTC(io); memcpy(io, (void *)addr, sizeof(*io)); io->io_hdr.pool = pool_tmp; + CTL_SOFTC(io) = sc_tmp; /* * No status yet, so make sure the status is set properly. diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c index b844be6..8a47513 100644 --- a/sys/cam/ctl/ctl_frontend_iscsi.c +++ b/sys/cam/ctl/ctl_frontend_iscsi.c @@ -146,7 +146,8 @@ SYSCTL_INT(_kern_cam_ctl_iscsi, OID_AUTO, maxcmdsn_delta, CTLFLAG_RWTUN, #define PDU_TOTAL_TRANSFER_LEN(X) (X)->ip_prv1 #define PDU_R2TSN(X) (X)->ip_prv2 -int cfiscsi_init(void); +static int cfiscsi_init(void); +static int cfiscsi_shutdown(void); static void cfiscsi_online(void *arg); static void cfiscsi_offline(void *arg); static int cfiscsi_info(void *arg, struct sbuf *sb); @@ -178,6 +179,7 @@ static struct ctl_frontend cfiscsi_frontend = .name = "iscsi", .init = cfiscsi_init, .ioctl = cfiscsi_ioctl, + .shutdown = cfiscsi_shutdown, }; CTL_FRONTEND_DECLARE(ctlcfiscsi, cfiscsi_frontend); MODULE_DEPEND(ctlcfiscsi, icl, 1, 1, 1); @@ -765,6 +767,7 @@ cfiscsi_handle_data_segment(struct icl_pdu *request, struct cfiscsi_data_wait *c cdw->cdw_sg_len -= copy_len; off += copy_len; io->scsiio.ext_data_filled += copy_len; + io->scsiio.kern_data_resid -= copy_len; if (cdw->cdw_sg_len == 0) { /* @@ -1273,7 +1276,7 @@ cfiscsi_session_delete(struct cfiscsi_session *cs) free(cs, M_CFISCSI); } -int +static int cfiscsi_init(void) { struct cfiscsi_softc *softc; @@ -1296,6 +1299,23 @@ cfiscsi_init(void) return (0); } +static int +cfiscsi_shutdown(void) +{ + struct cfiscsi_softc *softc = &cfiscsi_softc; + + if (!TAILQ_EMPTY(&softc->sessions) || !TAILQ_EMPTY(&softc->targets)) + return (EBUSY); + + uma_zdestroy(cfiscsi_data_wait_zone); +#ifdef ICL_KERNEL_PROXY + cv_destroy(&softc->accept_cv); +#endif + cv_destroy(&softc->sessions_cv); + mtx_destroy(&softc->lock); + return (0); +} + #ifdef ICL_KERNEL_PROXY static void cfiscsi_accept(struct socket *so, struct sockaddr *sa, int portal_id) @@ -1998,7 +2018,8 @@ cfiscsi_ioctl_port_create(struct ctl_req *req) if (ct->ct_state == CFISCSI_TARGET_STATE_ACTIVE) { req->status = CTL_LUN_ERROR; snprintf(req->error_str, sizeof(req->error_str), - "target \"%s\" already exists", target); + "target \"%s\" for portal group tag %u already exists", + target, tag); cfiscsi_target_release(ct); ctl_free_opts(&opts); return; @@ -2425,6 +2446,7 @@ cfiscsi_datamove_in(union ctl_io *io) } sg_addr += len; sg_len -= len; + io->scsiio.kern_data_resid -= len; KASSERT(buffer_offset + response->ip_data_len <= expected_len, ("buffer_offset %zd + ip_data_len %zd > expected_len %zd", @@ -2510,7 +2532,7 @@ cfiscsi_datamove_out(union ctl_io *io) struct iscsi_bhs_r2t *bhsr2t; struct cfiscsi_data_wait *cdw; struct ctl_sg_entry ctl_sg_entry, *ctl_sglist; - uint32_t expected_len, r2t_off, r2t_len; + uint32_t expected_len, datamove_len, r2t_off, r2t_len; uint32_t target_transfer_tag; bool done; @@ -2529,16 +2551,15 @@ cfiscsi_datamove_out(union ctl_io *io) PDU_TOTAL_TRANSFER_LEN(request) = io->scsiio.kern_total_len; /* - * Report write underflow as error since CTL and backends don't - * really support it, and SCSI does not tell how to do it right. + * Complete write underflow. Not a single byte to read. Return. */ expected_len = ntohl(bhssc->bhssc_expected_data_transfer_length); - if (io->scsiio.kern_rel_offset + io->scsiio.kern_data_len > - expected_len) { - io->scsiio.io_hdr.port_status = 43; + if (io->scsiio.kern_rel_offset >= expected_len) { io->scsiio.be_move_done(io); return; } + datamove_len = MIN(io->scsiio.kern_data_len, + expected_len - io->scsiio.kern_rel_offset); target_transfer_tag = atomic_fetchadd_32(&cs->cs_target_transfer_tag, 1); @@ -2560,7 +2581,7 @@ cfiscsi_datamove_out(union ctl_io *io) cdw->cdw_ctl_io = io; cdw->cdw_target_transfer_tag = target_transfer_tag; cdw->cdw_initiator_task_tag = bhssc->bhssc_initiator_task_tag; - cdw->cdw_r2t_end = io->scsiio.kern_data_len; + cdw->cdw_r2t_end = datamove_len; cdw->cdw_datasn = 0; /* Set initial data pointer for the CDW respecting ext_data_filled. */ @@ -2569,7 +2590,7 @@ cfiscsi_datamove_out(union ctl_io *io) } else { ctl_sglist = &ctl_sg_entry; ctl_sglist->addr = io->scsiio.kern_data_ptr; - ctl_sglist->len = io->scsiio.kern_data_len; + ctl_sglist->len = datamove_len; } cdw->cdw_sg_index = 0; cdw->cdw_sg_addr = ctl_sglist[cdw->cdw_sg_index].addr; @@ -2600,7 +2621,7 @@ cfiscsi_datamove_out(union ctl_io *io) } r2t_off = io->scsiio.kern_rel_offset + io->scsiio.ext_data_filled; - r2t_len = MIN(io->scsiio.kern_data_len - io->scsiio.ext_data_filled, + r2t_len = MIN(datamove_len - io->scsiio.ext_data_filled, cs->cs_max_burst_length); cdw->cdw_r2t_end = io->scsiio.ext_data_filled + r2t_len; diff --git a/sys/cam/ctl/ctl_ha.c b/sys/cam/ctl/ctl_ha.c index 1d85847..9a63240 100644 --- a/sys/cam/ctl/ctl_ha.c +++ b/sys/cam/ctl/ctl_ha.c @@ -1001,7 +1001,7 @@ ctl_ha_msg_shutdown(struct ctl_softc *ctl_softc) softc->ha_shutdown = 1; softc->ha_wakeup = 1; wakeup(&softc->ha_wakeup); - while (softc->ha_shutdown < 2) { + while (softc->ha_shutdown < 2 && !SCHEDULER_STOPPED()) { msleep(&softc->ha_wakeup, &softc->ha_lock, 0, "shutdown", hz); } diff --git a/sys/cam/ctl/ctl_io.h b/sys/cam/ctl/ctl_io.h index bad030f..9c472f5 100644 --- a/sys/cam/ctl/ctl_io.h +++ b/sys/cam/ctl/ctl_io.h @@ -145,7 +145,9 @@ struct ctl_ptr_len_flags { union ctl_priv { uint8_t bytes[sizeof(uint64_t) * 2]; uint64_t integer; + uint64_t integers[2]; void *ptr; + void *ptrs[2]; }; /* @@ -164,6 +166,12 @@ union ctl_priv { #define CTL_PRIV_FRONTEND 4 /* Frontend storage */ #define CTL_PRIV_FRONTEND2 5 /* Another frontend storage */ +#define CTL_LUN(io) ((io)->io_hdr.ctl_private[CTL_PRIV_LUN].ptrs[0]) +#define CTL_SOFTC(io) ((io)->io_hdr.ctl_private[CTL_PRIV_LUN].ptrs[1]) +#define CTL_BACKEND_LUN(io) ((io)->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptrs[0]) +#define CTL_PORT(io) (((struct ctl_softc *)CTL_SOFTC(io))-> \ + ctl_ports[(io)->io_hdr.nexus.targ_port]) + #define CTL_INVALID_PORTNAME 0xFF #define CTL_UNMAPPED_IID 0xFF @@ -312,7 +320,7 @@ struct ctl_scsiio { uint8_t sense_len; /* Returned sense length */ uint8_t scsi_status; /* SCSI status byte */ uint8_t sense_residual; /* Unused. */ - uint32_t residual; /* data residual length */ + uint32_t residual; /* Unused */ uint32_t tag_num; /* tag number */ ctl_tag_type tag_type; /* simple, ordered, head of queue,etc.*/ uint8_t cdb_len; /* CDB length */ @@ -365,7 +373,7 @@ struct ctl_taskio { /* * HA link messages. */ -#define CTL_HA_VERSION 1 +#define CTL_HA_VERSION 3 /* * Used for CTL_MSG_LOGIN. @@ -461,7 +469,8 @@ struct ctl_ha_msg_dt { }; /* - * Used for CTL_MSG_SERIALIZE, CTL_MSG_FINISH_IO, CTL_MSG_BAD_JUJU. + * Used for CTL_MSG_SERIALIZE, CTL_MSG_FINISH_IO, CTL_MSG_BAD_JUJU, + * and CTL_MSG_DATAMOVE_DONE. */ struct ctl_ha_msg_scsi { struct ctl_ha_msg_hdr hdr; @@ -471,10 +480,9 @@ struct ctl_ha_msg_scsi { uint8_t cdb_len; /* CDB length */ uint8_t scsi_status; /* SCSI status byte */ uint8_t sense_len; /* Returned sense length */ - uint8_t sense_residual; /* sense residual length */ - uint32_t residual; /* data residual length */ - uint32_t fetd_status; /* trans status, set by FETD, + uint32_t port_status; /* trans status, set by FETD, 0 = good*/ + uint32_t kern_data_resid; /* for DATAMOVE_DONE */ struct scsi_sense_data sense_data; /* sense data */ }; diff --git a/sys/cam/ctl/ctl_ioctl.h b/sys/cam/ctl/ctl_ioctl.h index e8f6b87..ee4ce18 100644 --- a/sys/cam/ctl/ctl_ioctl.h +++ b/sys/cam/ctl/ctl_ioctl.h @@ -1,6 +1,7 @@ /*- * Copyright (c) 2003 Silicon Graphics International Corp. * Copyright (c) 2011 Spectra Logic Corporation + * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,6 +81,9 @@ /* Hopefully this won't conflict with new misc devices that pop up */ #define CTL_MINOR 225 +/* Legacy statistics accumulated for every port for every LU. */ +#define CTL_LEGACY_STATS 1 + typedef enum { CTL_DELAY_TYPE_NONE, CTL_DELAY_TYPE_CONT, @@ -117,6 +121,18 @@ typedef enum { #define CTL_STATS_NUM_TYPES 3 typedef enum { + CTL_SS_OK, + CTL_SS_NEED_MORE_SPACE, + CTL_SS_ERROR +} ctl_stats_status; + +typedef enum { + CTL_STATS_FLAG_NONE = 0x00, + CTL_STATS_FLAG_TIME_VALID = 0x01 +} ctl_stats_flags; + +#ifdef CTL_LEGACY_STATS +typedef enum { CTL_LUN_STATS_NO_BLOCKSIZE = 0x01 } ctl_lun_stats_flags; @@ -137,17 +153,6 @@ struct ctl_lun_io_stats { struct ctl_lun_io_port_stats ports[CTL_MAX_PORTS]; }; -typedef enum { - CTL_SS_OK, - CTL_SS_NEED_MORE_SPACE, - CTL_SS_ERROR -} ctl_stats_status; - -typedef enum { - CTL_STATS_FLAG_NONE = 0x00, - CTL_STATS_FLAG_TIME_VALID = 0x01 -} ctl_stats_flags; - struct ctl_stats { int alloc_len; /* passed to kernel */ struct ctl_lun_io_stats *lun_stats; /* passed to/from kernel */ @@ -157,6 +162,27 @@ struct ctl_stats { ctl_stats_flags flags; /* passed to userland */ struct timespec timestamp; /* passed to userland */ }; +#endif /* CTL_LEGACY_STATS */ + +struct ctl_io_stats { + uint32_t item; + uint64_t bytes[CTL_STATS_NUM_TYPES]; + uint64_t operations[CTL_STATS_NUM_TYPES]; + uint64_t dmas[CTL_STATS_NUM_TYPES]; + struct bintime time[CTL_STATS_NUM_TYPES]; + struct bintime dma_time[CTL_STATS_NUM_TYPES]; +}; + +struct ctl_get_io_stats { + struct ctl_io_stats *stats; /* passed to/from kernel */ + size_t alloc_len; /* passed to kernel */ + size_t fill_len; /* passed to userland */ + int first_item; /* passed to kernel */ + int num_items; /* passed to userland */ + ctl_stats_status status; /* passed to userland */ + ctl_stats_flags flags; /* passed to userland */ + struct timespec timestamp; /* passed to userland */ +}; /* * The types of errors that can be injected: @@ -342,12 +368,54 @@ typedef enum { CTL_LUNREQ_MODIFY, } ctl_lunreq_type; +/* + * The ID_REQ flag is used to say that the caller has requested a + * particular LUN ID in the req_lun_id field. If we cannot allocate that + * LUN ID, the ctl_add_lun() call will fail. + * + * The STOPPED flag tells us that the LUN should default to the powered + * off state. It will return 0x04,0x02 until it is powered up. ("Logical + * unit not ready, initializing command required.") + * + * The NO_MEDIA flag tells us that the LUN has no media inserted. + * + * The PRIMARY flag tells us that this LUN is registered as a Primary LUN + * which is accessible via the Master shelf controller in an HA. This flag + * being set indicates a Primary LUN. This flag being reset represents a + * Secondary LUN controlled by the Secondary controller in an HA + * configuration. Flag is applicable at this time to T_DIRECT types. + * + * The SERIAL_NUM flag tells us that the serial_num field is filled in and + * valid for use in SCSI INQUIRY VPD page 0x80. + * + * The DEVID flag tells us that the device_id field is filled in and + * valid for use in SCSI INQUIRY VPD page 0x83. + * + * The DEV_TYPE flag tells us that the device_type field is filled in. + * + * The EJECTED flag tells us that the removable LUN has tray open. + * + * The UNMAP flag tells us that this LUN supports UNMAP. + * + * The OFFLINE flag tells us that this LUN can not access backing store. + */ +typedef enum { + CTL_LUN_FLAG_ID_REQ = 0x01, + CTL_LUN_FLAG_STOPPED = 0x02, + CTL_LUN_FLAG_NO_MEDIA = 0x04, + CTL_LUN_FLAG_PRIMARY = 0x08, + CTL_LUN_FLAG_SERIAL_NUM = 0x10, + CTL_LUN_FLAG_DEVID = 0x20, + CTL_LUN_FLAG_DEV_TYPE = 0x40, + CTL_LUN_FLAG_UNMAP = 0x80, + CTL_LUN_FLAG_EJECTED = 0x100, + CTL_LUN_FLAG_READONLY = 0x200 +} ctl_backend_lun_flags; /* * LUN creation parameters: * - * flags: Various LUN flags, see ctl_backend.h for a - * description of the flag values and meanings. + * flags: Various LUN flags, see above. * * device_type: The SCSI device type. e.g. 0 for Direct Access, * 3 for Processor, etc. Only certain backends may @@ -465,6 +533,7 @@ union ctl_lunreq_data { * kern_be_args: For kernel use only. */ struct ctl_lun_req { +#define CTL_BE_NAME_LEN 32 char backend[CTL_BE_NAME_LEN]; ctl_lunreq_type reqtype; union ctl_lunreq_data reqdata; @@ -761,6 +830,8 @@ struct ctl_lun_map { #define CTL_PORT_REQ _IOWR(CTL_MINOR, 0x26, struct ctl_req) #define CTL_PORT_LIST _IOWR(CTL_MINOR, 0x27, struct ctl_lun_list) #define CTL_LUN_MAP _IOW(CTL_MINOR, 0x28, struct ctl_lun_map) +#define CTL_GET_LUN_STATS _IOWR(CTL_MINOR, 0x29, struct ctl_get_io_stats) +#define CTL_GET_PORT_STATS _IOWR(CTL_MINOR, 0x2a, struct ctl_get_io_stats) #endif /* _CTL_IOCTL_H_ */ diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h index e118343..40f0e61 100644 --- a/sys/cam/ctl/ctl_private.h +++ b/sys/cam/ctl/ctl_private.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 2003, 2004, 2005, 2008 Silicon Graphics International Corp. - * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> + * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -404,7 +404,10 @@ struct ctl_lun { struct callout ie_callout; /* INTERVAL TIMER */ struct ctl_mode_pages mode_pages; struct ctl_log_pages log_pages; - struct ctl_lun_io_stats stats; +#ifdef CTL_LEGACY_STATS + struct ctl_lun_io_stats legacy_stats; +#endif /* CTL_LEGACY_STATS */ + struct ctl_io_stats stats; uint32_t res_idx; uint32_t pr_generation; uint64_t *pr_keys[CTL_MAX_PORTS]; @@ -412,7 +415,7 @@ struct ctl_lun { uint32_t pr_res_idx; uint8_t pr_res_type; int prevent_count; - uint32_t prevent[(CTL_MAX_INITIATORS+31)/32]; + uint32_t *prevent; uint8_t *write_buffer; struct ctl_devid *lun_devid; TAILQ_HEAD(tpc_lists, tpc_list) tpc_lists; @@ -467,7 +470,10 @@ struct ctl_softc { STAILQ_HEAD(, ctl_backend_driver) be_list; struct uma_zone *io_zone; uint32_t cur_pool_id; + int shutdown; struct ctl_thread threads[CTL_MAX_THREADS]; + struct thread *lun_thread; + struct thread *thresh_thread; TAILQ_HEAD(tpc_tokens, tpc_token) tpc_tokens; struct callout tpc_timeout; struct mtx tpc_lock; diff --git a/sys/cam/ctl/ctl_tpc.c b/sys/cam/ctl/ctl_tpc.c index 484293b..c8d60ca 100644 --- a/sys/cam/ctl/ctl_tpc.c +++ b/sys/cam/ctl/ctl_tpc.c @@ -251,6 +251,7 @@ ctl_tpc_lun_shutdown(struct ctl_lun *lun) int ctl_inquiry_evpd_tpc(struct ctl_scsiio *ctsio, int alloc_len) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_vpd_tpc *tpc_ptr; struct scsi_vpd_tpc_descriptor *d_ptr; struct scsi_vpd_tpc_descriptor_bdrl *bdrl_ptr; @@ -264,11 +265,8 @@ ctl_inquiry_evpd_tpc(struct ctl_scsiio *ctsio, int alloc_len) struct scsi_vpd_tpc_descriptor_srt *srt_ptr; struct scsi_vpd_tpc_descriptor_srtd *srtd_ptr; struct scsi_vpd_tpc_descriptor_gco *gco_ptr; - struct ctl_lun *lun; int data_len; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - data_len = sizeof(struct scsi_vpd_tpc) + sizeof(struct scsi_vpd_tpc_descriptor_bdrl) + roundup2(sizeof(struct scsi_vpd_tpc_descriptor_sc) + @@ -284,20 +282,10 @@ ctl_inquiry_evpd_tpc(struct ctl_scsiio *ctsio, int alloc_len) ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); tpc_ptr = (struct scsi_vpd_tpc *)ctsio->kern_data_ptr; - ctsio->kern_sg_entries = 0; - - if (data_len < alloc_len) { - ctsio->residual = alloc_len - data_len; - ctsio->kern_data_len = data_len; - ctsio->kern_total_len = data_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; + ctsio->kern_data_len = min(data_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; /* * The control device is always connected. The disk device, on the @@ -460,20 +448,10 @@ ctl_receive_copy_operating_parameters(struct ctl_scsiio *ctsio) alloc_len = scsi_4btoul(cdb->length); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - ctsio->kern_sg_entries = 0; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; data = (struct scsi_receive_copy_operating_parameters_data *)ctsio->kern_data_ptr; scsi_ulto4b(sizeof(*data) - 4 + 4, data->length); @@ -521,7 +499,7 @@ tpc_find_list(struct ctl_lun *lun, uint32_t list_id, uint32_t init_idx) int ctl_receive_copy_status_lid1(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_receive_copy_status_lid1 *cdb; struct scsi_receive_copy_status_lid1_data *data; struct tpc_list *list; @@ -533,8 +511,6 @@ ctl_receive_copy_status_lid1(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_receive_copy_status_lid1\n")); cdb = (struct scsi_receive_copy_status_lid1 *)ctsio->cdb; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - retval = CTL_RETVAL_COMPLETE; list_id = cdb->list_identifier; @@ -560,20 +536,10 @@ ctl_receive_copy_status_lid1(struct ctl_scsiio *ctsio) alloc_len = scsi_4btoul(cdb->length); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - ctsio->kern_sg_entries = 0; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; data = (struct scsi_receive_copy_status_lid1_data *)ctsio->kern_data_ptr; scsi_ulto4b(sizeof(*data) - 4, data->available_data); @@ -603,7 +569,7 @@ ctl_receive_copy_status_lid1(struct ctl_scsiio *ctsio) int ctl_receive_copy_failure_details(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_receive_copy_failure_details *cdb; struct scsi_receive_copy_failure_details_data *data; struct tpc_list *list; @@ -615,8 +581,6 @@ ctl_receive_copy_failure_details(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_receive_copy_failure_details\n")); cdb = (struct scsi_receive_copy_failure_details *)ctsio->cdb; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - retval = CTL_RETVAL_COMPLETE; list_id = cdb->list_identifier; @@ -640,20 +604,10 @@ ctl_receive_copy_failure_details(struct ctl_scsiio *ctsio) alloc_len = scsi_4btoul(cdb->length); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - ctsio->kern_sg_entries = 0; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; data = (struct scsi_receive_copy_failure_details_data *)ctsio->kern_data_ptr; if (list_copy.completed && (list_copy.error || list_copy.abort)) { @@ -675,7 +629,7 @@ ctl_receive_copy_failure_details(struct ctl_scsiio *ctsio) int ctl_receive_copy_status_lid4(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_receive_copy_status_lid4 *cdb; struct scsi_receive_copy_status_lid4_data *data; struct tpc_list *list; @@ -687,8 +641,6 @@ ctl_receive_copy_status_lid4(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_receive_copy_status_lid4\n")); cdb = (struct scsi_receive_copy_status_lid4 *)ctsio->cdb; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - retval = CTL_RETVAL_COMPLETE; list_id = scsi_4btoul(cdb->list_identifier); @@ -714,20 +666,10 @@ ctl_receive_copy_status_lid4(struct ctl_scsiio *ctsio) alloc_len = scsi_4btoul(cdb->length); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - ctsio->kern_sg_entries = 0; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; data = (struct scsi_receive_copy_status_lid4_data *)ctsio->kern_data_ptr; scsi_ulto4b(sizeof(*data) - 4 + list_copy.sense_len, @@ -761,7 +703,7 @@ ctl_receive_copy_status_lid4(struct ctl_scsiio *ctsio) int ctl_copy_operation_abort(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_copy_operation_abort *cdb; struct tpc_list *list; int retval; @@ -770,8 +712,6 @@ ctl_copy_operation_abort(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_copy_operation_abort\n")); cdb = (struct scsi_copy_operation_abort *)ctsio->cdb; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - retval = CTL_RETVAL_COMPLETE; list_id = scsi_4btoul(cdb->list_identifier); @@ -894,7 +834,7 @@ tpc_process_b2b(struct tpc_list *list) dcscd = scsi_2btoul(seg->dst_cscd); sl = tpc_resolve(list, scscd, &srcblock, NULL, NULL); dl = tpc_resolve(list, dcscd, &dstblock, &pb, &pbo); - if (sl >= CTL_MAX_LUNS || dl >= CTL_MAX_LUNS) { + if (sl == UINT64_MAX || dl == UINT64_MAX) { ctl_set_sense(list->ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x08, /*ascq*/ 0x04, @@ -1042,7 +982,7 @@ tpc_process_verify(struct tpc_list *list) seg = (struct scsi_ec_segment_verify *)list->seg[list->curseg]; cscd = scsi_2btoul(seg->src_cscd); sl = tpc_resolve(list, cscd, NULL, NULL, NULL); - if (sl >= CTL_MAX_LUNS) { + if (sl == UINT64_MAX) { ctl_set_sense(list->ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x08, /*ascq*/ 0x04, @@ -1106,7 +1046,7 @@ tpc_process_register_key(struct tpc_list *list) seg = (struct scsi_ec_segment_register_key *)list->seg[list->curseg]; cscd = scsi_2btoul(seg->dst_cscd); dl = tpc_resolve(list, cscd, NULL, NULL, NULL); - if (dl >= CTL_MAX_LUNS) { + if (dl == UINT64_MAX) { ctl_set_sense(list->ctsio, /*current_error*/ 1, /*sense_key*/ SSD_KEY_COPY_ABORTED, /*asc*/ 0x08, /*ascq*/ 0x04, @@ -1705,11 +1645,11 @@ tpc_done(union ctl_io *io) int ctl_extended_copy_lid1(struct ctl_scsiio *ctsio) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_extended_copy *cdb; struct scsi_extended_copy_lid1_data *data; struct scsi_ec_cscd *cscd; struct scsi_ec_segment *seg; - struct ctl_lun *lun; struct tpc_list *list, *tlist; uint8_t *ptr; char *value; @@ -1717,7 +1657,6 @@ ctl_extended_copy_lid1(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_extended_copy_lid1\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_extended_copy *)ctsio->cdb; len = scsi_4btoul(cdb->length); @@ -1741,7 +1680,6 @@ ctl_extended_copy_lid1(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK); ctsio->kern_data_len = len; ctsio->kern_total_len = len; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -1861,11 +1799,11 @@ done: int ctl_extended_copy_lid4(struct ctl_scsiio *ctsio) { + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_extended_copy *cdb; struct scsi_extended_copy_lid4_data *data; struct scsi_ec_cscd *cscd; struct scsi_ec_segment *seg; - struct ctl_lun *lun; struct tpc_list *list, *tlist; uint8_t *ptr; char *value; @@ -1873,7 +1811,6 @@ ctl_extended_copy_lid4(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_extended_copy_lid4\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_extended_copy *)ctsio->cdb; len = scsi_4btoul(cdb->length); @@ -1897,7 +1834,6 @@ ctl_extended_copy_lid4(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK); ctsio->kern_data_len = len; ctsio->kern_total_len = len; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -2064,11 +2000,11 @@ tpc_create_token(struct ctl_lun *lun, struct ctl_port *port, off_t len, int ctl_populate_token(struct ctl_scsiio *ctsio) { + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_port *port = CTL_PORT(ctsio); + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_populate_token *cdb; struct scsi_populate_token_data *data; - struct ctl_softc *softc; - struct ctl_lun *lun; - struct ctl_port *port; struct tpc_list *list, *tlist; struct tpc_token *token; uint64_t lba; @@ -2076,9 +2012,6 @@ ctl_populate_token(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_populate_token\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - softc = lun->ctl_softc; - port = softc->ctl_ports[ctsio->io_hdr.nexus.targ_port]; cdb = (struct scsi_populate_token *)ctsio->cdb; len = scsi_4btoul(cdb->length); @@ -2098,7 +2031,6 @@ ctl_populate_token(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK); ctsio->kern_data_len = len; ctsio->kern_total_len = len; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -2232,10 +2164,10 @@ done: int ctl_write_using_token(struct ctl_scsiio *ctsio) { + struct ctl_softc *softc = CTL_SOFTC(ctsio); + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_write_using_token *cdb; struct scsi_write_using_token_data *data; - struct ctl_softc *softc; - struct ctl_lun *lun; struct tpc_list *list, *tlist; struct tpc_token *token; uint64_t lba; @@ -2243,8 +2175,6 @@ ctl_write_using_token(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_write_using_token\n")); - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - softc = lun->ctl_softc; cdb = (struct scsi_write_using_token *)ctsio->cdb; len = scsi_4btoul(cdb->length); @@ -2264,7 +2194,6 @@ ctl_write_using_token(struct ctl_scsiio *ctsio) ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK); ctsio->kern_data_len = len; ctsio->kern_total_len = len; - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; ctsio->kern_sg_entries = 0; ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -2389,7 +2318,7 @@ done: int ctl_receive_rod_token_information(struct ctl_scsiio *ctsio) { - struct ctl_lun *lun; + struct ctl_lun *lun = CTL_LUN(ctsio); struct scsi_receive_rod_token_information *cdb; struct scsi_receive_copy_status_lid4_data *data; struct tpc_list *list; @@ -2402,8 +2331,6 @@ ctl_receive_rod_token_information(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_receive_rod_token_information\n")); cdb = (struct scsi_receive_rod_token_information *)ctsio->cdb; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - retval = CTL_RETVAL_COMPLETE; list_id = scsi_4btoul(cdb->list_identifier); @@ -2430,20 +2357,10 @@ ctl_receive_rod_token_information(struct ctl_scsiio *ctsio) alloc_len = scsi_4btoul(cdb->length); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - ctsio->kern_sg_entries = 0; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; data = (struct scsi_receive_copy_status_lid4_data *)ctsio->kern_data_ptr; scsi_ulto4b(sizeof(*data) - 4 + list_copy.sense_len + @@ -2487,8 +2404,7 @@ ctl_receive_rod_token_information(struct ctl_scsiio *ctsio) int ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio) { - struct ctl_softc *softc; - struct ctl_lun *lun; + struct ctl_softc *softc = CTL_SOFTC(ctsio); struct scsi_report_all_rod_tokens *cdb; struct scsi_report_all_rod_tokens_data *data; struct tpc_token *token; @@ -2498,9 +2414,6 @@ ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_receive_rod_token_information\n")); cdb = (struct scsi_report_all_rod_tokens *)ctsio->cdb; - lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - softc = lun->ctl_softc; - retval = CTL_RETVAL_COMPLETE; tokens = 0; @@ -2515,20 +2428,10 @@ ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio) alloc_len = scsi_4btoul(cdb->length); ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO); - ctsio->kern_sg_entries = 0; - - if (total_len < alloc_len) { - ctsio->residual = alloc_len - total_len; - ctsio->kern_data_len = total_len; - ctsio->kern_total_len = total_len; - } else { - ctsio->residual = 0; - ctsio->kern_data_len = alloc_len; - ctsio->kern_total_len = alloc_len; - } - ctsio->kern_data_resid = 0; ctsio->kern_rel_offset = 0; + ctsio->kern_data_len = min(total_len, alloc_len); + ctsio->kern_total_len = ctsio->kern_data_len; data = (struct scsi_report_all_rod_tokens_data *)ctsio->kern_data_ptr; i = 0; diff --git a/sys/cam/ctl/ctl_tpc_local.c b/sys/cam/ctl/ctl_tpc_local.c index 4f368f9..e5e77b4 100644 --- a/sys/cam/ctl/ctl_tpc_local.c +++ b/sys/cam/ctl/ctl_tpc_local.c @@ -65,7 +65,7 @@ struct tpcl_softc { static struct tpcl_softc tpcl_softc; static int tpcl_init(void); -static void tpcl_shutdown(void); +static int tpcl_shutdown(void); static void tpcl_datamove(union ctl_io *io); static void tpcl_done(union ctl_io *io); @@ -84,7 +84,7 @@ tpcl_init(void) struct tpcl_softc *tsoftc = &tpcl_softc; struct ctl_port *port; struct scsi_transportid_spi *tid; - int len; + int error, len; memset(tsoftc, 0, sizeof(*tsoftc)); @@ -100,9 +100,9 @@ tpcl_init(void) port->targ_port = -1; port->max_initiators = 1; - if (ctl_port_register(port) != 0) { - printf("%s: ctl_port_register() failed with error\n", __func__); - return (0); + if ((error = ctl_port_register(port)) != 0) { + printf("%s: tpc port registration failed\n", __func__); + return (error); } len = sizeof(struct scsi_transportid_spi); @@ -118,16 +118,17 @@ tpcl_init(void) return (0); } -void +static int tpcl_shutdown(void) { struct tpcl_softc *tsoftc = &tpcl_softc; - struct ctl_port *port; + struct ctl_port *port = &tsoftc->port; + int error; - port = &tsoftc->port; ctl_port_offline(port); - if (ctl_port_deregister(&tsoftc->port) != 0) - printf("%s: ctl_frontend_deregister() failed\n", __func__); + if ((error = ctl_port_deregister(port)) != 0) + printf("%s: tpc port deregistration failed\n", __func__); + return (error); } static void @@ -137,7 +138,7 @@ tpcl_datamove(union ctl_io *io) struct ctl_sg_entry ext_entry, kern_entry; int ext_sg_entries, kern_sg_entries; int ext_sg_start, ext_offset; - int len_to_copy, len_copied; + int len_to_copy; int kern_watermark, ext_watermark; struct ctl_scsiio *ctsio; int i, j; @@ -196,7 +197,6 @@ tpcl_datamove(union ctl_io *io) kern_watermark = 0; ext_watermark = ext_offset; - len_copied = 0; for (i = ext_sg_start, j = 0; i < ext_sg_entries && j < kern_sg_entries;) { uint8_t *ext_ptr, *kern_ptr; @@ -218,9 +218,6 @@ tpcl_datamove(union ctl_io *io) kern_ptr = (uint8_t *)kern_sglist[j].addr; kern_ptr = kern_ptr + kern_watermark; - kern_watermark += len_to_copy; - ext_watermark += len_to_copy; - if ((ctsio->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) { CTL_DEBUG_PRINT(("%s: copying %d bytes to user\n", @@ -236,27 +233,27 @@ tpcl_datamove(union ctl_io *io) memcpy(kern_ptr, ext_ptr, len_to_copy); } - len_copied += len_to_copy; + ctsio->ext_data_filled += len_to_copy; + ctsio->kern_data_resid -= len_to_copy; + ext_watermark += len_to_copy; if (ext_sglist[i].len == ext_watermark) { i++; ext_watermark = 0; } + kern_watermark += len_to_copy; if (kern_sglist[j].len == kern_watermark) { j++; kern_watermark = 0; } } - ctsio->ext_data_filled += len_copied; - CTL_DEBUG_PRINT(("%s: ext_sg_entries: %d, kern_sg_entries: %d\n", __func__, ext_sg_entries, kern_sg_entries)); CTL_DEBUG_PRINT(("%s: ext_data_len = %d, kern_data_len = %d\n", __func__, ctsio->ext_data_len, ctsio->kern_data_len)); - /* XXX KDM set residual?? */ bailout: io->scsiio.be_move_done(io); } @@ -290,7 +287,7 @@ tpcl_resolve(struct ctl_softc *softc, int init_port, port = NULL; STAILQ_FOREACH(lun, &softc->lun_list, links) { if (port != NULL && - ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX) continue; if (lun->lun_devid == NULL) continue; diff --git a/sys/cam/ctl/ctl_util.c b/sys/cam/ctl/ctl_util.c index 6fcec03..33f0899 100644 --- a/sys/cam/ctl/ctl_util.c +++ b/sys/cam/ctl/ctl_util.c @@ -697,7 +697,6 @@ ctl_scsi_free_io(union ctl_io *io) free(io); } -#endif /* !_KERNEL */ void ctl_scsi_zero_io(union ctl_io *io) { @@ -707,11 +706,10 @@ ctl_scsi_zero_io(union ctl_io *io) return; pool_ref = io->io_hdr.pool; - memset(io, 0, sizeof(*io)); - io->io_hdr.pool = pool_ref; } +#endif /* !_KERNEL */ const char * ctl_scsi_task_string(struct ctl_taskio *taskio) diff --git a/sys/cam/ctl/ctl_util.h b/sys/cam/ctl/ctl_util.h index 2966b49..67c0915 100644 --- a/sys/cam/ctl/ctl_util.h +++ b/sys/cam/ctl/ctl_util.h @@ -96,8 +96,10 @@ void ctl_scsi_maintenance_in(union ctl_io *io, uint8_t *data_ptr, #ifndef _KERNEL union ctl_io *ctl_scsi_alloc_io(uint32_t initid); void ctl_scsi_free_io(union ctl_io *io); -#endif /* !_KERNEL */ void ctl_scsi_zero_io(union ctl_io *io); +#else +#define ctl_scsi_zero_io(io) ctl_zero_io(io) +#endif /* !_KERNEL */ const char *ctl_scsi_task_string(struct ctl_taskio *taskio); void ctl_io_sbuf(union ctl_io *io, struct sbuf *sb); void ctl_io_error_sbuf(union ctl_io *io, diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c index abdbdcd..dc82e91 100644 --- a/sys/cam/ctl/scsi_ctl.c +++ b/sys/cam/ctl/scsi_ctl.c @@ -185,8 +185,11 @@ MALLOC_DEFINE(M_CTLFE, "CAM CTL FE", "CAM CTL FE interface"); /* This is only used in the CTIO */ #define ccb_atio ppriv_ptr1 -int ctlfeinitialize(void); -void ctlfeshutdown(void); +#define PRIV_CCB(io) ((io)->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptrs[0]) +#define PRIV_INFO(io) ((io)->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptrs[1]) + +static int ctlfeinitialize(void); +static int ctlfeshutdown(void); static periph_init_t ctlfeperiphinit; static void ctlfeasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg); @@ -224,13 +227,15 @@ static struct ctl_frontend ctlfe_frontend = }; CTL_FRONTEND_DECLARE(ctlfe, ctlfe_frontend); -void +static int ctlfeshutdown(void) { - return; + + /* CAM does not support periph driver unregister now. */ + return (EBUSY); } -int +static int ctlfeinitialize(void) { @@ -240,7 +245,7 @@ ctlfeinitialize(void) return (0); } -void +static void ctlfeperiphinit(void) { cam_status status; @@ -554,7 +559,7 @@ ctlferegister(struct cam_periph *periph, void *arg) status = CAM_RESRC_UNAVAIL; break; } - new_io->io_hdr.ctl_private[CTL_PRIV_FRONTEND2].ptr = cmd_info; + PRIV_INFO(new_io) = cmd_info; softc->atios_alloced++; new_ccb->ccb_h.io_ptr = new_io; @@ -702,7 +707,7 @@ ctlfedata(struct ctlfe_lun_softc *softc, union ctl_io *io, size_t off; int i, idx; - cmd_info = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND2].ptr; + cmd_info = PRIV_INFO(io); bus_softc = softc->parent_softc; /* @@ -718,15 +723,18 @@ ctlfedata(struct ctlfe_lun_softc *softc, union ctl_io *io, idx = cmd_info->cur_transfer_index; off = cmd_info->cur_transfer_off; cmd_info->flags &= ~CTLFE_CMD_PIECEWISE; - if (io->scsiio.kern_sg_entries == 0) { - /* No S/G list. */ + if (io->scsiio.kern_sg_entries == 0) { /* No S/G list. */ + + /* One time shift for SRR offset. */ + off += io->scsiio.ext_data_filled; + io->scsiio.ext_data_filled = 0; + *data_ptr = io->scsiio.kern_data_ptr + off; if (io->scsiio.kern_data_len - off <= bus_softc->maxio) { *dxfer_len = io->scsiio.kern_data_len - off; } else { *dxfer_len = bus_softc->maxio; - cmd_info->cur_transfer_index = -1; - cmd_info->cur_transfer_off = bus_softc->maxio; + cmd_info->cur_transfer_off += bus_softc->maxio; cmd_info->flags |= CTLFE_CMD_PIECEWISE; } *sglist_cnt = 0; @@ -735,9 +743,18 @@ ctlfedata(struct ctlfe_lun_softc *softc, union ctl_io *io, *flags |= CAM_DATA_PADDR; else *flags |= CAM_DATA_VADDR; - } else { - /* S/G list with physical or virtual pointers. */ + } else { /* S/G list with physical or virtual pointers. */ ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr; + + /* One time shift for SRR offset. */ + while (io->scsiio.ext_data_filled >= ctl_sglist[idx].len - off) { + io->scsiio.ext_data_filled -= ctl_sglist[idx].len - off; + idx++; + off = 0; + } + off += io->scsiio.ext_data_filled; + io->scsiio.ext_data_filled = 0; + cam_sglist = cmd_info->cam_sglist; *dxfer_len = 0; for (i = 0; i < io->scsiio.kern_sg_entries - idx; i++) { @@ -806,7 +823,7 @@ ctlfestart(struct cam_periph *periph, union ccb *start_ccb) flags = atio->ccb_h.flags & (CAM_DIS_DISCONNECT|CAM_TAG_ACTION_VALID|CAM_DIR_MASK); - cmd_info = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND2].ptr; + cmd_info = PRIV_INFO(io); cmd_info->cur_transfer_index = 0; cmd_info->cur_transfer_off = 0; cmd_info->flags = 0; @@ -815,18 +832,8 @@ ctlfestart(struct cam_periph *periph, union ccb *start_ccb) /* * Datamove call, we need to setup the S/G list. */ - scsi_status = 0; - csio->cdb_len = atio->cdb_len; ctlfedata(softc, io, &flags, &data_ptr, &dxfer_len, &csio->sglist_cnt); - io->scsiio.ext_data_filled += dxfer_len; - if (io->scsiio.ext_data_filled > io->scsiio.kern_total_len) { - xpt_print(periph->path, "%s: tag 0x%04x " - "fill len %u > total %u\n", - __func__, io->scsiio.tag_num, - io->scsiio.ext_data_filled, - io->scsiio.kern_total_len); - } } else { /* * We're done, send status back. @@ -888,8 +895,8 @@ ctlfestart(struct cam_periph *periph, union ccb *start_ccb) data_ptr = NULL; dxfer_len = 0; csio->sglist_cnt = 0; - scsi_status = 0; } + scsi_status = 0; if ((io->io_hdr.flags & CTL_FLAG_STATUS_QUEUED) && (cmd_info->flags & CTLFE_CMD_PIECEWISE) == 0 && ((io->io_hdr.flags & CTL_FLAG_DMA_QUEUED) == 0 || @@ -938,7 +945,7 @@ ctlfestart(struct cam_periph *periph, union ccb *start_ccb) && (csio->sglist_cnt != 0))) { printf("%s: tag %04x cdb %02x flags %#x dxfer_len " "%d sg %u\n", __func__, atio->tag_id, - atio->cdb_io.cdb_bytes[0], flags, dxfer_len, + atio_cdb_ptr(atio)[0], flags, dxfer_len, csio->sglist_cnt); printf("%s: tag %04x io status %#x\n", __func__, atio->tag_id, io->io_hdr.status); @@ -987,7 +994,7 @@ ctlfe_free_ccb(struct cam_periph *periph, union ccb *ccb) switch (ccb->ccb_h.func_code) { case XPT_ACCEPT_TARGET_IO: softc->atios_freed++; - cmd_info = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND2].ptr; + cmd_info = PRIV_INFO(io); free(cmd_info, M_CTLFE); break; case XPT_IMMEDIATE_NOTIFY: @@ -1024,8 +1031,7 @@ ctlfe_adjust_cdb(struct ccb_accept_tio *atio, uint32_t offset) { uint64_t lba; uint32_t num_blocks, nbc; - uint8_t *cmdbyt = (atio->ccb_h.flags & CAM_CDB_POINTER)? - atio->cdb_io.cdb_ptr : atio->cdb_io.cdb_bytes; + uint8_t *cmdbyt = atio_cdb_ptr(atio); nbc = offset >> 9; /* ASSUMING 512 BYTE BLOCKS */ @@ -1154,12 +1160,12 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb) */ mtx_unlock(mtx); io = done_ccb->ccb_h.io_ptr; - cmd_info = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND2].ptr; + cmd_info = PRIV_INFO(io); ctl_zero_io(io); /* Save pointers on both sides */ - io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = done_ccb; - io->io_hdr.ctl_private[CTL_PRIV_FRONTEND2].ptr = cmd_info; + PRIV_CCB(io) = done_ccb; + PRIV_INFO(io) = cmd_info; done_ccb->ccb_h.io_ptr = io; /* @@ -1203,8 +1209,7 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb) __func__, atio->cdb_len, sizeof(io->scsiio.cdb)); } io->scsiio.cdb_len = min(atio->cdb_len, sizeof(io->scsiio.cdb)); - bcopy(atio->cdb_io.cdb_bytes, io->scsiio.cdb, - io->scsiio.cdb_len); + bcopy(atio_cdb_ptr(atio), io->scsiio.cdb, io->scsiio.cdb_len); #ifdef CTLFEDEBUG printf("%s: %u:%u:%u: tag %04x CDB %02x\n", __func__, @@ -1245,13 +1250,36 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb) | (done_ccb->csio.msg_ptr[6]); } + /* + * If we have an SRR and we're still sending data, we + * should be able to adjust offsets and cycle again. + * It is possible only if offset is from this datamove. + */ + if (srr && (io->io_hdr.flags & CTL_FLAG_DMA_INPROG) && + srr_off >= io->scsiio.kern_rel_offset && + srr_off < io->scsiio.kern_rel_offset + + io->scsiio.kern_data_len) { + io->scsiio.kern_data_resid = + io->scsiio.kern_rel_offset + + io->scsiio.kern_data_len - srr_off; + io->scsiio.ext_data_filled = srr_off; + io->scsiio.io_hdr.status = CTL_STATUS_NONE; + io->io_hdr.flags |= CTL_FLAG_DMA_QUEUED; + softc->ccbs_freed++; + xpt_release_ccb(done_ccb); + TAILQ_INSERT_HEAD(&softc->work_queue, &atio->ccb_h, + periph_links.tqe); + xpt_schedule(periph, /*priority*/ 1); + break; + } + + /* + * If status was being sent, the back end data is now history. + * Hack it up and resubmit a new command with the CDB adjusted. + * If the SIM does the right thing, all of the resid math + * should work. + */ if (srr && (io->io_hdr.flags & CTL_FLAG_DMA_INPROG) == 0) { - /* - * If status was being sent, the back end data is now - * history. Hack it up and resubmit a new command with - * the CDB adjusted. If the SIM does the right thing, - * all of the resid math should work. - */ softc->ccbs_freed++; xpt_release_ccb(done_ccb); if (ctlfe_adjust_cdb(atio, srr_off) == 0) { @@ -1261,22 +1289,6 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb) /* * Fall through to doom.... */ - } else if (srr) { - /* - * If we have an srr and we're still sending data, we - * should be able to adjust offsets and cycle again. - */ - io->scsiio.kern_rel_offset = - io->scsiio.ext_data_filled = srr_off; - io->scsiio.ext_data_len = io->scsiio.kern_total_len - - io->scsiio.kern_rel_offset; - softc->ccbs_freed++; - io->scsiio.io_hdr.status = CTL_STATUS_NONE; - xpt_release_ccb(done_ccb); - TAILQ_INSERT_HEAD(&softc->work_queue, &atio->ccb_h, - periph_links.tqe); - xpt_schedule(periph, /*priority*/ 1); - break; } if ((done_ccb->ccb_h.flags & CAM_SEND_STATUS) && @@ -1315,20 +1327,10 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb) struct ccb_scsiio *csio; csio = &done_ccb->csio; - cmd_info = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND2].ptr; + cmd_info = PRIV_INFO(io); io->io_hdr.flags &= ~CTL_FLAG_DMA_INPROG; - io->scsiio.ext_data_len += csio->dxfer_len; - if (io->scsiio.ext_data_len > - io->scsiio.kern_total_len) { - xpt_print(periph->path, "%s: tag 0x%04x " - "done len %u > total %u sent %u\n", - __func__, io->scsiio.tag_num, - io->scsiio.ext_data_len, - io->scsiio.kern_total_len, - io->scsiio.ext_data_filled); - } /* * Translate CAM status to CTL status. Success * does not change the overall, ctl_io status. In @@ -1338,6 +1340,7 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb) */ switch (done_ccb->ccb_h.status & CAM_STATUS_MASK) { case CAM_REQ_CMP: + io->scsiio.kern_data_resid -= csio->dxfer_len; io->io_hdr.port_status = 0; break; default: @@ -1367,7 +1370,6 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb) if ((cmd_info->flags & CTLFE_CMD_PIECEWISE) && (io->io_hdr.port_status == 0)) { ccb_flags flags; - uint8_t scsi_status; uint8_t *data_ptr; uint32_t dxfer_len; @@ -1378,14 +1380,12 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb) ctlfedata(softc, io, &flags, &data_ptr, &dxfer_len, &csio->sglist_cnt); - scsi_status = 0; - if (((flags & CAM_SEND_STATUS) == 0) && (dxfer_len == 0)) { printf("%s: tag %04x no status or " "len cdb = %02x\n", __func__, atio->tag_id, - atio->cdb_io.cdb_bytes[0]); + atio_cdb_ptr(atio)[0]); printf("%s: tag %04x io status %#x\n", __func__, atio->tag_id, io->io_hdr.status); @@ -1399,7 +1399,7 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb) MSG_SIMPLE_Q_TAG : 0, atio->tag_id, atio->init_id, - scsi_status, + 0, /*data_ptr*/ data_ptr, /*dxfer_len*/ dxfer_len, /*timeout*/ 5 * 1000); @@ -1444,7 +1444,7 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb) send_ctl_io = 1; io->io_hdr.io_type = CTL_IO_TASK; - io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr =done_ccb; + PRIV_CCB(io) = done_ccb; inot->ccb_h.io_ptr = io; io->io_hdr.nexus.initid = inot->initiator_id; io->io_hdr.nexus.targ_port = bus_softc->port.targ_port; @@ -2001,7 +2001,8 @@ ctlfe_datamove(union ctl_io *io) KASSERT(io->io_hdr.io_type == CTL_IO_SCSI, ("Unexpected io_type (%d) in ctlfe_datamove", io->io_hdr.io_type)); - ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; + io->scsiio.ext_data_filled = 0; + ccb = PRIV_CCB(io); periph = xpt_path_periph(ccb->ccb_h.path); cam_periph_lock(periph); softc = (struct ctlfe_lun_softc *)periph->softc; @@ -2021,7 +2022,7 @@ ctlfe_done(union ctl_io *io) struct cam_periph *periph; struct ctlfe_lun_softc *softc; - ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; + ccb = PRIV_CCB(io); periph = xpt_path_periph(ccb->ccb_h.path); cam_periph_lock(periph); softc = (struct ctlfe_lun_softc *)periph->softc; diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c index 3ebce7a..f28f8dc 100644 --- a/sys/cam/scsi/scsi_all.c +++ b/sys/cam/scsi/scsi_all.c @@ -1370,7 +1370,7 @@ static struct asc_table_entry asc_table[] = { { SST(0x0E, 0x02, SS_RDEF, /* XXX TBD */ "Information unit too long") }, /* DT P R MAEBK F */ - { SST(0x0E, 0x03, SS_RDEF, /* XXX TBD */ + { SST(0x0E, 0x03, SS_FATAL | EINVAL, "Invalid field in command information unit") }, /* D W O BK */ { SST(0x10, 0x00, SS_RDEF, @@ -3616,15 +3616,9 @@ scsi_command_string(struct cam_device *device, struct ccb_scsiio *csio, #endif /* _KERNEL/!_KERNEL */ - if ((csio->ccb_h.flags & CAM_CDB_POINTER) != 0) { - sbuf_printf(sb, "%s. CDB: ", - scsi_op_desc(csio->cdb_io.cdb_ptr[0], inq_data)); - scsi_cdb_sbuf(csio->cdb_io.cdb_ptr, sb); - } else { - sbuf_printf(sb, "%s. CDB: ", - scsi_op_desc(csio->cdb_io.cdb_bytes[0], inq_data)); - scsi_cdb_sbuf(csio->cdb_io.cdb_bytes, sb); - } + sbuf_printf(sb, "%s. CDB: ", + scsi_op_desc(scsiio_cdb_ptr(csio)[0], inq_data)); + scsi_cdb_sbuf(scsiio_cdb_ptr(csio), sb); #ifdef _KERNEL xpt_free_ccb((union ccb *)cgd); @@ -5029,7 +5023,6 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, struct ccb_getdev *cgd; #endif /* _KERNEL */ char path_str[64]; - uint8_t *cdb; #ifndef _KERNEL if (device == NULL) @@ -5127,14 +5120,9 @@ scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, sense = &csio->sense_data; } - if (csio->ccb_h.flags & CAM_CDB_POINTER) - cdb = csio->cdb_io.cdb_ptr; - else - cdb = csio->cdb_io.cdb_bytes; - scsi_sense_only_sbuf(sense, csio->sense_len - csio->sense_resid, sb, - path_str, inq_data, cdb, csio->cdb_len); - + path_str, inq_data, scsiio_cdb_ptr(csio), csio->cdb_len); + #ifdef _KERNEL xpt_free_ccb((union ccb*)cgd); #endif /* _KERNEL/!_KERNEL */ @@ -7622,24 +7610,34 @@ scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries, } void -scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries, - void (*cbfcnp)(struct cam_periph *, union ccb *), - u_int8_t tag_action, int dbd, u_int8_t page_code, - u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, - u_int8_t sense_len, u_int32_t timeout) +scsi_mode_sense(struct ccb_scsiio *csio, uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, + int dbd, uint8_t pc, uint8_t page, uint8_t *param_buf, uint32_t param_len, + uint8_t sense_len, uint32_t timeout) { - scsi_mode_sense_len(csio, retries, cbfcnp, tag_action, dbd, - page_code, page, param_buf, param_len, 0, - sense_len, timeout); + scsi_mode_sense_subpage(csio, retries, cbfcnp, tag_action, dbd, + pc, page, 0, param_buf, param_len, 0, sense_len, timeout); } void -scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, - void (*cbfcnp)(struct cam_periph *, union ccb *), - u_int8_t tag_action, int dbd, u_int8_t page_code, - u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, - int minimum_cmd_size, u_int8_t sense_len, u_int32_t timeout) +scsi_mode_sense_len(struct ccb_scsiio *csio, uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, + int dbd, uint8_t pc, uint8_t page, uint8_t *param_buf, uint32_t param_len, + int minimum_cmd_size, uint8_t sense_len, uint32_t timeout) +{ + + scsi_mode_sense_subpage(csio, retries, cbfcnp, tag_action, dbd, + pc, page, 0, param_buf, param_len, minimum_cmd_size, + sense_len, timeout); +} + +void +scsi_mode_sense_subpage(struct ccb_scsiio *csio, uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, + int dbd, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t *param_buf, + uint32_t param_len, int minimum_cmd_size, uint8_t sense_len, + uint32_t timeout) { u_int8_t cdb_len; @@ -7658,7 +7656,8 @@ scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, scsi_cmd->opcode = MODE_SENSE_6; if (dbd != 0) scsi_cmd->byte2 |= SMS_DBD; - scsi_cmd->page = page_code | page; + scsi_cmd->page = pc | page; + scsi_cmd->subpage = subpage; scsi_cmd->length = param_len; cdb_len = sizeof(*scsi_cmd); } else { @@ -7672,7 +7671,8 @@ scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, scsi_cmd->opcode = MODE_SENSE_10; if (dbd != 0) scsi_cmd->byte2 |= SMS_DBD; - scsi_cmd->page = page_code | page; + scsi_cmd->page = pc | page; + scsi_cmd->subpage = subpage; scsi_ulto2b(param_len, scsi_cmd->length); cdb_len = sizeof(*scsi_cmd); } diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h index 5dc496e..19ee882 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -228,6 +228,7 @@ struct scsi_mode_select_6 u_int8_t opcode; u_int8_t byte2; #define SMS_SP 0x01 +#define SMS_RTD 0x02 #define SMS_PF 0x10 u_int8_t unused[2]; u_int8_t length; @@ -3895,21 +3896,24 @@ void scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries, u_int8_t sense_len, u_int32_t timeout); void scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries, - void (*cbfcnp)(struct cam_periph *, - union ccb *), - u_int8_t tag_action, int dbd, - u_int8_t page_code, u_int8_t page, - u_int8_t *param_buf, u_int32_t param_len, - u_int8_t sense_len, u_int32_t timeout); + void (*cbfcnp)(struct cam_periph *, union ccb *), + uint8_t tag_action, int dbd, uint8_t pc, uint8_t page, + uint8_t *param_buf, uint32_t param_len, + uint8_t sense_len, uint32_t timeout); void scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, - void (*cbfcnp)(struct cam_periph *, - union ccb *), - u_int8_t tag_action, int dbd, - u_int8_t page_code, u_int8_t page, - u_int8_t *param_buf, u_int32_t param_len, - int minimum_cmd_size, u_int8_t sense_len, - u_int32_t timeout); + void (*cbfcnp)(struct cam_periph *, union ccb *), + uint8_t tag_action, int dbd, uint8_t pc, uint8_t page, + uint8_t *param_buf, uint32_t param_len, + int minimum_cmd_size, uint8_t sense_len, uint32_t timeout); + +void scsi_mode_sense_subpage(struct ccb_scsiio *csio, + uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + uint8_t tag_action, int dbd, uint8_t pc, + uint8_t page, uint8_t subpage, + uint8_t *param_buf, uint32_t param_len, + int minimum_cmd_size, uint8_t sense_len, uint32_t timeout); void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, diff --git a/sys/cam/scsi/scsi_ch.c b/sys/cam/scsi/scsi_ch.c index 077371d..24ce964 100644 --- a/sys/cam/scsi/scsi_ch.c +++ b/sys/cam/scsi/scsi_ch.c @@ -586,7 +586,7 @@ chstart(struct cam_periph *periph, union ccb *start_ccb) /* tag_action */ MSG_SIMPLE_Q_TAG, /* dbd */ (softc->quirks & CH_Q_NO_DBD) ? FALSE : TRUE, - /* page_code */ SMS_PAGE_CTRL_CURRENT, + /* pc */ SMS_PAGE_CTRL_CURRENT, /* page */ CH_ELEMENT_ADDR_ASSIGN_PAGE, /* param_buf */ (u_int8_t *)mode_buffer, /* param_len */ mode_buffer_len, @@ -1587,7 +1587,7 @@ chgetparams(struct cam_periph *periph) /* cbfcnp */ chdone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* dbd */ dbd, - /* page_code */ SMS_PAGE_CTRL_CURRENT, + /* pc */ SMS_PAGE_CTRL_CURRENT, /* page */ CH_ELEMENT_ADDR_ASSIGN_PAGE, /* param_buf */ (u_int8_t *)mode_buffer, /* param_len */ mode_buffer_len, @@ -1650,7 +1650,7 @@ chgetparams(struct cam_periph *periph) /* cbfcnp */ chdone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* dbd */ dbd, - /* page_code */ SMS_PAGE_CTRL_CURRENT, + /* pc */ SMS_PAGE_CTRL_CURRENT, /* page */ CH_DEVICE_CAP_PAGE, /* param_buf */ (u_int8_t *)mode_buffer, /* param_len */ mode_buffer_len, diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index 09694c5..d09d7d7 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -28,8 +28,6 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include "opt_kdtrace.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 2f60c13..db5e45d 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -244,7 +244,8 @@ copy_statfs(struct statfs *in, struct statfs32 *out) #ifdef COMPAT_FREEBSD4 int -freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) +freebsd4_freebsd32_getfsstat(struct thread *td, + struct freebsd4_freebsd32_getfsstat_args *uap) { struct statfs *buf, *sp; struct statfs32 stat32; diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 58b71f6..e5ab44a 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -747,8 +747,7 @@ options NETGRAPH_IPFW options NETGRAPH_KSOCKET options NETGRAPH_L2TP options NETGRAPH_LMI -# MPPC compression requires proprietary files (not included) -#options NETGRAPH_MPPC_COMPRESSION +options NETGRAPH_MPPC_COMPRESSION options NETGRAPH_MPPC_ENCRYPTION options NETGRAPH_NETFLOW options NETGRAPH_NAT @@ -1922,8 +1921,9 @@ device xmphy # XaQti XMAC II # cm: Arcnet SMC COM90c26 / SMC COM90c56 # (and SMC COM90c66 in '56 compatibility mode) adapters. # cxgb: Chelsio T3 based 1GbE/10GbE PCIe Ethernet adapters. -# cxgbe:Chelsio T4 and T5 based 1GbE/10GbE/40GbE PCIe Ethernet adapters. -# cxgbev: Chelsio T4 and T5 based PCIe Virtual Functions. +# cxgbe:Chelsio T4, T5, and T6-based 1/10/25/40/100GbE PCIe Ethernet +# adapters. +# cxgbev: Chelsio T4, T5, and T6-based PCIe Virtual Functions. # dc: Support for PCI fast ethernet adapters based on the DEC/Intel 21143 # and various workalikes including: # the ADMtek AL981 Comet and AN985 Centaur, the ASIX Electronics @@ -2072,9 +2072,6 @@ device bce # Broadcom BCM5706/BCM5708 Gigabit Ethernet device bfe # Broadcom BCM440x 10/100 Ethernet device bge # Broadcom BCM570xx Gigabit Ethernet device cas # Sun Cassini/Cassini+ and NS DP83065 Saturn -device cxgb # Chelsio T3 10 Gigabit Ethernet -device cxgb_t3fw # Chelsio T3 10 Gigabit Ethernet firmware -device cxgbe # Chelsio T4 and T5 1GbE/10GbE/40GbE device dc # DEC/Intel 21143 and various workalikes device et # Agere ET1310 10/100/Gigabit Ethernet device fxp # Intel EtherExpress PRO/100B (82557, 82558) @@ -2105,7 +2102,10 @@ device wb # Winbond W89C840F device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') # PCI Ethernet NICs. -device cxgbev # Chelsio T4 and T5 1GbE/10GbE/40GbE VF +device cxgb # Chelsio T3 10 Gigabit Ethernet +device cxgb_t3fw # Chelsio T3 10 Gigabit Ethernet firmware +device cxgbe # Chelsio T4-T6 1/10/25/40/100 Gigabit Ethernet +device cxgbev # Chelsio T4-T6 Virtual Functions device de # DEC/Intel DC21x4x (``Tulip'') device em # Intel Pro/1000 Gigabit Ethernet device igb # Intel Pro/1000 PCIE Gigabit Ethernet diff --git a/sys/conf/options b/sys/conf/options index acd31c4..3892268 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -512,7 +512,6 @@ NETGRAPH_IPFW opt_netgraph.h NETGRAPH_KSOCKET opt_netgraph.h NETGRAPH_L2TP opt_netgraph.h NETGRAPH_LMI opt_netgraph.h -# MPPC compression requires proprietary files (not included) NETGRAPH_MPPC_COMPRESSION opt_netgraph.h NETGRAPH_MPPC_ENCRYPTION opt_netgraph.h NETGRAPH_NAT opt_netgraph.h diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c index 7239121..51edec3 100644 --- a/sys/dev/age/if_age.c +++ b/sys/dev/age/if_age.c @@ -587,7 +587,7 @@ age_attach(device_t dev) /* Create device sysctl node. */ age_sysctl_node(sc); - if ((error = age_dma_alloc(sc) != 0)) + if ((error = age_dma_alloc(sc)) != 0) goto fail; /* Load station address. */ diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 5fabdaf..a9061bc 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -711,7 +711,7 @@ ahci_ch_attach(device_t dev) /* Construct SIM entry */ ch->sim = cam_sim_alloc(ahciaction, ahcipoll, "ahcich", ch, device_get_unit(dev), (struct mtx *)&ch->mtx, - min(2, ch->numslots), + (ch->quirks & AHCI_Q_NOCCS) ? 1 : min(2, ch->numslots), (ch->caps & AHCI_CAP_SNCQ) ? ch->numslots : 0, devq); if (ch->sim == NULL) { @@ -1122,8 +1122,6 @@ ahci_ch_intr(void *arg) /* Read interrupt statuses. */ istatus = ATA_INL(ch->r_mem, AHCI_P_IS); - if (istatus == 0) - return; mtx_lock(&ch->mtx); ahci_ch_intr_main(ch, istatus); @@ -1140,8 +1138,6 @@ ahci_ch_intr_direct(void *arg) /* Read interrupt statuses. */ istatus = ATA_INL(ch->r_mem, AHCI_P_IS); - if (istatus == 0) - return; mtx_lock(&ch->mtx); ch->batch = 1; @@ -1228,8 +1224,19 @@ ahci_ch_intr_main(struct ahci_channel *ch, uint32_t istatus) /* Process command errors */ if (istatus & (AHCI_P_IX_OF | AHCI_P_IX_IF | AHCI_P_IX_HBD | AHCI_P_IX_HBF | AHCI_P_IX_TFE)) { - ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CCS_MASK) - >> AHCI_P_CMD_CCS_SHIFT; + if (ch->quirks & AHCI_Q_NOCCS) { + /* + * ASMedia chips sometimes report failed commands as + * completed. Count all running commands as failed. + */ + cstatus |= ch->rslots; + + /* They also report wrong CCS, so try to guess one. */ + ccs = powerof2(cstatus) ? ffs(cstatus) - 1 : -1; + } else { + ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) & + AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT; + } //device_printf(dev, "%s ERROR is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x fbs %08x ccs %d\n", // __func__, istatus, cstatus, sstatus, ch->rslots, ATA_INL(ch->r_mem, AHCI_P_TFD), // serr, ATA_INL(ch->r_mem, AHCI_P_FBS), ccs); diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index 61643c1..ca7631e 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -574,6 +574,7 @@ enum ahci_err_type { #define AHCI_Q_SATA1_UNIT0 0x00008000 /* need better method for this */ #define AHCI_Q_ABAR0 0x00010000 #define AHCI_Q_1MSI 0x00020000 +#define AHCI_Q_NOCCS 0x00400000 #define AHCI_Q_BIT_STRING \ "\020" \ @@ -594,7 +595,8 @@ enum ahci_err_type { "\017MAXIO_64K" \ "\020SATA1_UNIT0" \ "\021ABAR0" \ - "\0221MSI" + "\0221MSI" \ + "\027NOCCS" int ahci_attach(device_t dev); int ahci_detach(device_t dev); diff --git a/sys/dev/ahci/ahci_pci.c b/sys/dev/ahci/ahci_pci.c index bb14ed6..7f4a1b6 100644 --- a/sys/dev/ahci/ahci_pci.c +++ b/sys/dev/ahci/ahci_pci.c @@ -73,8 +73,15 @@ static const struct { {0x78021022, 0x00, "AMD Hudson-2", 0}, {0x78031022, 0x00, "AMD Hudson-2", 0}, {0x78041022, 0x00, "AMD Hudson-2", 0}, - {0x06111b21, 0x00, "ASMedia ASM2106", 0}, - {0x06121b21, 0x00, "ASMedia ASM1061", 0}, + {0x06011b21, 0x00, "ASMedia ASM1060", AHCI_Q_NOCCS}, + {0x06021b21, 0x00, "ASMedia ASM1060", AHCI_Q_NOCCS}, + {0x06111b21, 0x00, "ASMedia ASM1061", AHCI_Q_NOCCS}, + {0x06121b21, 0x00, "ASMedia ASM1062", AHCI_Q_NOCCS}, + {0x06201b21, 0x00, "ASMedia ASM106x", AHCI_Q_NOCCS}, + {0x06211b21, 0x00, "ASMedia ASM106x", AHCI_Q_NOCCS}, + {0x06221b21, 0x00, "ASMedia ASM106x", AHCI_Q_NOCCS}, + {0x06241b21, 0x00, "ASMedia ASM106x", AHCI_Q_NOCCS}, + {0x06251b21, 0x00, "ASMedia ASM106x", AHCI_Q_NOCCS}, {0x26528086, 0x00, "Intel ICH6", AHCI_Q_NOFORCE}, {0x26538086, 0x00, "Intel ICH6M", AHCI_Q_NOFORCE}, {0x26818086, 0x00, "Intel ESB2", 0}, diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c index ba37b5f..76e4614 100644 --- a/sys/dev/alc/if_alc.c +++ b/sys/dev/alc/if_alc.c @@ -120,6 +120,8 @@ static struct alc_ident alc_ident_table[] = { "Atheros AR8172 PCIe Fast Ethernet" }, { VENDORID_ATHEROS, DEVICEID_ATHEROS_E2200, 9 * 1024, "Killer E2200 Gigabit Ethernet" }, + { VENDORID_ATHEROS, DEVICEID_ATHEROS_E2400, 9 * 1024, + "Killer E2400 Gigabit Ethernet" }, { 0, 0, 0, NULL} }; @@ -254,7 +256,7 @@ static struct resource_spec alc_irq_spec_msix[] = { { -1, 0, 0 } }; -static uint32_t alc_dma_burst[] = { 128, 256, 512, 1024, 2048, 4096, 0 }; +static uint32_t alc_dma_burst[] = { 128, 256, 512, 1024, 2048, 4096, 0, 0 }; static int alc_miibus_readreg(device_t dev, int phy, int reg) @@ -1079,6 +1081,7 @@ alc_phy_down(struct alc_softc *sc) switch (sc->alc_ident->deviceid) { case DEVICEID_ATHEROS_AR8161: case DEVICEID_ATHEROS_E2200: + case DEVICEID_ATHEROS_E2400: case DEVICEID_ATHEROS_AR8162: case DEVICEID_ATHEROS_AR8171: case DEVICEID_ATHEROS_AR8172: @@ -1396,12 +1399,15 @@ alc_attach(device_t dev) * shows the same PHY model/revision number of AR8131. */ switch (sc->alc_ident->deviceid) { + case DEVICEID_ATHEROS_E2200: + case DEVICEID_ATHEROS_E2400: + sc->alc_flags |= ALC_FLAG_E2X00; + /* FALLTHROUGH */ case DEVICEID_ATHEROS_AR8161: if (pci_get_subvendor(dev) == VENDORID_ATHEROS && pci_get_subdevice(dev) == 0x0091 && sc->alc_rev == 0) sc->alc_flags |= ALC_FLAG_LINK_WAR; /* FALLTHROUGH */ - case DEVICEID_ATHEROS_E2200: case DEVICEID_ATHEROS_AR8171: sc->alc_flags |= ALC_FLAG_AR816X_FAMILY; break; @@ -1472,6 +1478,12 @@ alc_attach(device_t dev) sc->alc_dma_rd_burst = 3; if (alc_dma_burst[sc->alc_dma_wr_burst] > 1024) sc->alc_dma_wr_burst = 3; + /* + * Force maximum payload size to 128 bytes for E2200/E2400. + * Otherwise it triggers DMA write error. + */ + if ((sc->alc_flags & ALC_FLAG_E2X00) != 0) + sc->alc_dma_wr_burst = 0; alc_init_pcie(sc); } @@ -1531,7 +1543,7 @@ alc_attach(device_t dev) /* Create device sysctl node. */ alc_sysctl_node(sc); - if ((error = alc_dma_alloc(sc) != 0)) + if ((error = alc_dma_alloc(sc)) != 0) goto fail; /* Load station address. */ @@ -4194,13 +4206,17 @@ alc_init_locked(struct alc_softc *sc) reg = (RXQ_CFG_RD_BURST_DEFAULT << RXQ_CFG_RD_BURST_SHIFT) & RXQ_CFG_RD_BURST_MASK; reg |= RXQ_CFG_RSS_MODE_DIS; - if ((sc->alc_flags & ALC_FLAG_AR816X_FAMILY) != 0) + if ((sc->alc_flags & ALC_FLAG_AR816X_FAMILY) != 0) { reg |= (RXQ_CFG_816X_IDT_TBL_SIZE_DEFAULT << RXQ_CFG_816X_IDT_TBL_SIZE_SHIFT) & RXQ_CFG_816X_IDT_TBL_SIZE_MASK; - if ((sc->alc_flags & ALC_FLAG_FASTETHER) == 0 && - sc->alc_ident->deviceid != DEVICEID_ATHEROS_AR8151_V2) - reg |= RXQ_CFG_ASPM_THROUGHPUT_LIMIT_1M; + if ((sc->alc_flags & ALC_FLAG_FASTETHER) == 0) + reg |= RXQ_CFG_ASPM_THROUGHPUT_LIMIT_100M; + } else { + if ((sc->alc_flags & ALC_FLAG_FASTETHER) == 0 && + sc->alc_ident->deviceid != DEVICEID_ATHEROS_AR8151_V2) + reg |= RXQ_CFG_ASPM_THROUGHPUT_LIMIT_100M; + } CSR_WRITE_4(sc, ALC_RXQ_CFG, reg); /* Configure DMA parameters. */ @@ -4224,12 +4240,12 @@ alc_init_locked(struct alc_softc *sc) switch (AR816X_REV(sc->alc_rev)) { case AR816X_REV_A0: case AR816X_REV_A1: - reg |= DMA_CFG_RD_CHNL_SEL_1; + reg |= DMA_CFG_RD_CHNL_SEL_2; break; case AR816X_REV_B0: /* FALLTHROUGH */ default: - reg |= DMA_CFG_RD_CHNL_SEL_3; + reg |= DMA_CFG_RD_CHNL_SEL_4; break; } } diff --git a/sys/dev/alc/if_alcreg.h b/sys/dev/alc/if_alcreg.h index 1ad75a3..ae63084 100644 --- a/sys/dev/alc/if_alcreg.h +++ b/sys/dev/alc/if_alcreg.h @@ -45,10 +45,11 @@ #define DEVICEID_ATHEROS_AR8152_B 0x2060 /* L2C V1.1 */ #define DEVICEID_ATHEROS_AR8152_B2 0x2062 /* L2C V2.0 */ #define DEVICEID_ATHEROS_AR8161 0x1091 -#define DEVICEID_ATHEROS_E2200 0xE091 #define DEVICEID_ATHEROS_AR8162 0x1090 #define DEVICEID_ATHEROS_AR8171 0x10A1 #define DEVICEID_ATHEROS_AR8172 0x10A0 +#define DEVICEID_ATHEROS_E2200 0xE091 +#define DEVICEID_ATHEROS_E2400 0xE0A1 #define ATHEROS_AR8152_B_V10 0xC0 #define ATHEROS_AR8152_B_V11 0xC1 diff --git a/sys/dev/alc/if_alcvar.h b/sys/dev/alc/if_alcvar.h index 9a73ef4..a1c3382 100644 --- a/sys/dev/alc/if_alcvar.h +++ b/sys/dev/alc/if_alcvar.h @@ -235,7 +235,8 @@ struct alc_softc { #define ALC_FLAG_APS 0x1000 #define ALC_FLAG_AR816X_FAMILY 0x2000 #define ALC_FLAG_LINK_WAR 0x4000 -#define ALC_FLAG_LINK 0x8000 +#define ALC_FLAG_E2X00 0x8000 +#define ALC_FLAG_LINK 0x10000 struct callout alc_tick_ch; struct alc_hw_stats alc_stats; diff --git a/sys/dev/ale/if_ale.c b/sys/dev/ale/if_ale.c index 6f0f83e..4eb5835 100644 --- a/sys/dev/ale/if_ale.c +++ b/sys/dev/ale/if_ale.c @@ -602,7 +602,7 @@ ale_attach(device_t dev) /* Create device sysctl node. */ ale_sysctl_node(sc); - if ((error = ale_dma_alloc(sc) != 0)) + if ((error = ale_dma_alloc(sc)) != 0) goto fail; /* Load station address. */ diff --git a/sys/dev/amdsbwd/amdsbwd.c b/sys/dev/amdsbwd/amdsbwd.c index f8824e5..628aef2 100644 --- a/sys/dev/amdsbwd/amdsbwd.c +++ b/sys/dev/amdsbwd/amdsbwd.c @@ -416,8 +416,8 @@ amdsbwd_probe(device_t dev) return (ENXIO); } rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0ul, ~0ul, - AMDSB_PMIO_WIDTH, RF_ACTIVE | RF_SHAREABLE); + res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, + RF_ACTIVE | RF_SHAREABLE); if (res == NULL) { device_printf(dev, "bus_alloc_resource for IO failed\n"); return (ENXIO); diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c index b4e6ce5..6bcadb7 100644 --- a/sys/dev/arcmsr/arcmsr.c +++ b/sys/dev/arcmsr/arcmsr.c @@ -872,7 +872,7 @@ static void arcmsr_srb_timeout(void *arg) ARCMSR_LOCK_ACQUIRE(&acb->isr_lock); if(srb->srb_state == ARCMSR_SRB_START) { - cmd = srb->pccb->csio.cdb_io.cdb_bytes[0]; + cmd = scsiio_cdb_ptr(&srb->pccb->csio)[0]; srb->srb_state = ARCMSR_SRB_TIMEOUT; srb->pccb->ccb_h.status |= CAM_CMD_TIMEOUT; arcmsr_srb_complete(srb, 1); @@ -997,7 +997,7 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb, arcmsr_cdb->LUN = pccb->ccb_h.target_lun; arcmsr_cdb->Function = 1; arcmsr_cdb->CdbLength = (u_int8_t)pcsio->cdb_len; - bcopy(pcsio->cdb_io.cdb_bytes, arcmsr_cdb->Cdb, pcsio->cdb_len); + bcopy(scsiio_cdb_ptr(pcsio), arcmsr_cdb->Cdb, pcsio->cdb_len); if(nseg != 0) { struct AdapterControlBlock *acb = srb->acb; bus_dmasync_op_t op; @@ -2453,10 +2453,11 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p struct CMD_MESSAGE_FIELD *pcmdmessagefld; int retvalue = 0, transfer_len = 0; char *buffer; - u_int32_t controlcode = (u_int32_t ) pccb->csio.cdb_io.cdb_bytes[5] << 24 | - (u_int32_t ) pccb->csio.cdb_io.cdb_bytes[6] << 16 | - (u_int32_t ) pccb->csio.cdb_io.cdb_bytes[7] << 8 | - (u_int32_t ) pccb->csio.cdb_io.cdb_bytes[8]; + uint8_t *ptr = scsiio_cdb_ptr(&pccb->csio); + u_int32_t controlcode = (u_int32_t ) ptr[5] << 24 | + (u_int32_t ) ptr[6] << 16 | + (u_int32_t ) ptr[7] << 8 | + (u_int32_t ) ptr[8]; /* 4 bytes: Areca io control code */ if ((pccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) { buffer = pccb->csio.data_ptr; @@ -2683,7 +2684,7 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, if(acb->devstate[target][lun] == ARECA_RAID_GONE) { u_int8_t block_cmd, cmd; - cmd = pccb->csio.cdb_io.cdb_bytes[0]; + cmd = scsiio_cdb_ptr(&pccb->csio)[0]; block_cmd = cmd & 0x0f; if(block_cmd == 0x08 || block_cmd == 0x0a) { printf("arcmsr%d:block 'read/write' command " @@ -2800,7 +2801,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, return; } pccb->ccb_h.status |= CAM_REQ_CMP; - switch (pccb->csio.cdb_io.cdb_bytes[0]) { + switch (scsiio_cdb_ptr(&pccb->csio)[0]) { case INQUIRY: { unsigned char inqdata[36]; char *buffer = pccb->csio.data_ptr; @@ -2853,6 +2854,12 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb) int target = pccb->ccb_h.target_id; int error; + if (pccb->ccb_h.flags & CAM_CDB_PHYS) { + pccb->ccb_h.status = CAM_REQ_INVALID; + xpt_done(pccb); + return; + } + if(target == 16) { /* virtual device for iop message transfer */ arcmsr_handle_virtual_command(acb, pccb); @@ -4143,7 +4150,7 @@ static u_int32_t arcmsr_initialize(device_t dev) u_int32_t rid0 = PCIR_BAR(0); vm_offset_t mem_base0; - acb->sys_res_arcmsr[0] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, 0x1000, RF_ACTIVE); + acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid0, RF_ACTIVE); if(acb->sys_res_arcmsr[0] == NULL) { arcmsr_free_resource(acb); printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); @@ -4177,11 +4184,11 @@ static u_int32_t arcmsr_initialize(device_t dev) size = sizeof(struct HBB_DOORBELL); for(i=0; i < 2; i++) { if(i == 0) { - acb->sys_res_arcmsr[i] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid[i], - 0ul, ~0ul, size, RF_ACTIVE); + acb->sys_res_arcmsr[i] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid[i], + RF_ACTIVE); } else { - acb->sys_res_arcmsr[i] = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid[i], - 0ul, ~0ul, sizeof(struct HBB_RWBUFFER), RF_ACTIVE); + acb->sys_res_arcmsr[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid[i], + RF_ACTIVE); } if(acb->sys_res_arcmsr[i] == NULL) { arcmsr_free_resource(acb); @@ -4224,7 +4231,7 @@ static u_int32_t arcmsr_initialize(device_t dev) u_int32_t rid0 = PCIR_BAR(1); vm_offset_t mem_base0; - acb->sys_res_arcmsr[0] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, sizeof(struct HBC_MessageUnit), RF_ACTIVE); + acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid0, RF_ACTIVE); if(acb->sys_res_arcmsr[0] == NULL) { arcmsr_free_resource(acb); printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); @@ -4251,7 +4258,7 @@ static u_int32_t arcmsr_initialize(device_t dev) u_int32_t rid0 = PCIR_BAR(0); vm_offset_t mem_base0; - acb->sys_res_arcmsr[0] = bus_alloc_resource(dev,SYS_RES_MEMORY, &rid0, 0ul, ~0ul, sizeof(struct HBD_MessageUnit), RF_ACTIVE); + acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid0, RF_ACTIVE); if(acb->sys_res_arcmsr[0] == NULL) { arcmsr_free_resource(acb); printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev)); diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index d976313..82d1dec 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -611,6 +611,7 @@ struct { #endif }, t6_pciids[] = { {0xc006, "Chelsio Terminator 6 FPGA"}, /* T6 PE10K6 FPGA (PF0) */ + {0x6400, "Chelsio T6225-DBG"}, /* 2 x 10/25G, debug */ {0x6401, "Chelsio T6225-CR"}, /* 2 x 10/25G */ {0x6402, "Chelsio T6225-SO-CR"}, /* 2 x 10/25G, nomem */ {0x6407, "Chelsio T62100-LP-CR"}, /* 2 x 40/50/100G */ diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index 9152d9f..d831f94 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -2289,7 +2289,7 @@ slowpath: w = &eq->desc[eq->pidx]; IDXINCR(eq->pidx, ndesc, eq->sidx); - if (__predict_false(eq->pidx < ndesc - 1)) { + if (__predict_false(cookie->pidx + ndesc > eq->sidx)) { w = &wrq->ss[0]; wrq->ss_pidx = cookie->pidx; wrq->ss_len = len16 * 16; @@ -3296,12 +3296,13 @@ ctrl_eq_alloc(struct adapter *sc, struct sge_eq *eq) c.cmpliqid_eqid = htonl(V_FW_EQ_CTRL_CMD_CMPLIQID(eq->iqid)); c.physeqid_pkd = htobe32(0); c.fetchszm_to_iqid = - htobe32(V_FW_EQ_CTRL_CMD_HOSTFCMODE(X_HOSTFCMODE_NONE) | + htobe32(V_FW_EQ_CTRL_CMD_HOSTFCMODE(X_HOSTFCMODE_STATUS_PAGE) | V_FW_EQ_CTRL_CMD_PCIECHN(eq->tx_chan) | F_FW_EQ_CTRL_CMD_FETCHRO | V_FW_EQ_CTRL_CMD_IQID(eq->iqid)); c.dcaen_to_eqsize = htobe32(V_FW_EQ_CTRL_CMD_FBMIN(X_FETCHBURSTMIN_64B) | V_FW_EQ_CTRL_CMD_FBMAX(X_FETCHBURSTMAX_512B) | + V_FW_EQ_CTRL_CMD_CIDXFTHRESH(X_CIDXFLUSHTHRESH_32) | V_FW_EQ_CTRL_CMD_EQSIZE(qsize)); c.eqaddr = htobe64(eq->ba); diff --git a/sys/dev/cxgbe/tom/t4_connect.c b/sys/dev/cxgbe/tom/t4_connect.c index 5ec627c..02f01ef 100644 --- a/sys/dev/cxgbe/tom/t4_connect.c +++ b/sys/dev/cxgbe/tom/t4_connect.c @@ -107,7 +107,7 @@ free_atid(struct adapter *sc, int atid) } /* - * Active open failed. + * Active open succeeded. */ static int do_act_establish(struct sge_iq *iq, const struct rss_header *rss, @@ -126,9 +126,10 @@ do_act_establish(struct sge_iq *iq, const struct rss_header *rss, CTR3(KTR_CXGBE, "%s: atid %u, tid %u", __func__, atid, tid); free_atid(sc, atid); + CURVNET_SET(toep->vnet); INP_WLOCK(inp); toep->tid = tid; - insert_tid(sc, tid, toep); + insert_tid(sc, tid, toep, inp->inp_vflag & INP_IPV6 ? 2 : 1); if (inp->inp_flags & INP_DROPPED) { /* socket closed by the kernel before hw told us it connected */ @@ -141,6 +142,7 @@ do_act_establish(struct sge_iq *iq, const struct rss_header *rss, make_established(toep, cpl->snd_isn, cpl->rcv_isn, cpl->tcp_opt); done: INP_WUNLOCK(inp); + CURVNET_RESTORE(); return (0); } @@ -178,6 +180,7 @@ act_open_failure_cleanup(struct adapter *sc, u_int atid, u_int status) free_atid(sc, atid); toep->tid = -1; + CURVNET_SET(toep->vnet); if (status != EAGAIN) INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); @@ -185,8 +188,12 @@ act_open_failure_cleanup(struct adapter *sc, u_int atid, u_int status) final_cpl_received(toep); /* unlocks inp */ if (status != EAGAIN) INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); } +/* + * Active open failed. + */ static int do_act_open_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) @@ -268,6 +275,14 @@ t4_init_connect_cpl_handlers(void) t4_register_cpl_handler(CPL_ACT_OPEN_RPL, do_act_open_rpl); } +void +t4_uninit_connect_cpl_handlers(void) +{ + + t4_register_cpl_handler(CPL_ACT_ESTABLISH, NULL); + t4_register_cpl_handler(CPL_ACT_OPEN_RPL, NULL); +} + #define DONT_OFFLOAD_ACTIVE_OPEN(x) do { \ reason = __LINE__; \ rc = (x); \ @@ -357,6 +372,7 @@ t4_connect(struct toedev *tod, struct socket *so, struct rtentry *rt, if (wr == NULL) DONT_OFFLOAD_ACTIVE_OPEN(ENOMEM); + toep->vnet = so->so_vnet; if (sc->tt.ddp && (so->so_options & SO_NO_DDP) == 0) set_tcpddp_ulp_mode(toep); else diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index f446432..6e26c2b 100644 --- a/sys/dev/cxgbe/tom/t4_cpl_io.c +++ b/sys/dev/cxgbe/tom/t4_cpl_io.c @@ -302,7 +302,6 @@ make_established(struct toepcb *toep, uint32_t snd_isn, uint32_t rcv_isn, uint16_t tcpopt = be16toh(opt); struct flowc_tx_params ftxp; - CURVNET_SET(so->so_vnet); INP_WLOCK_ASSERT(inp); KASSERT(tp->t_state == TCPS_SYN_SENT || tp->t_state == TCPS_SYN_RECEIVED, @@ -353,7 +352,6 @@ make_established(struct toepcb *toep, uint32_t snd_isn, uint32_t rcv_isn, send_flowc_wr(toep, &ftxp); soisconnected(so); - CURVNET_RESTORE(); } static int @@ -1107,6 +1105,7 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) KASSERT(toep->tid == tid, ("%s: toep tid mismatch", __func__)); + CURVNET_SET(toep->vnet); INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); tp = intotcpcb(inp); @@ -1150,6 +1149,7 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) tcp_twstart(tp); INP_UNLOCK_ASSERT(inp); /* safe, we have a ref on the inp */ INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); INP_WLOCK(inp); final_cpl_received(toep); @@ -1162,6 +1162,7 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) done: INP_WUNLOCK(inp); INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); return (0); } @@ -1188,6 +1189,7 @@ do_close_con_rpl(struct sge_iq *iq, const struct rss_header *rss, KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__)); KASSERT(toep->tid == tid, ("%s: toep tid mismatch", __func__)); + CURVNET_SET(toep->vnet); INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); tp = intotcpcb(inp); @@ -1207,6 +1209,7 @@ do_close_con_rpl(struct sge_iq *iq, const struct rss_header *rss, release: INP_UNLOCK_ASSERT(inp); /* safe, we have a ref on the inp */ INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); INP_WLOCK(inp); final_cpl_received(toep); /* no more CPLs expected */ @@ -1231,6 +1234,7 @@ release: done: INP_WUNLOCK(inp); INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); return (0); } @@ -1304,6 +1308,7 @@ do_abort_req(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) } inp = toep->inp; + CURVNET_SET(toep->vnet); INP_INFO_RLOCK(&V_tcbinfo); /* for tcp_close */ INP_WLOCK(inp); @@ -1339,6 +1344,7 @@ do_abort_req(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) final_cpl_received(toep); done: INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); send_abort_rpl(sc, ofld_txq, tid, CPL_ABORT_NO_RST); return (0); } @@ -1456,18 +1462,21 @@ do_rx_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) SOCKBUF_UNLOCK(sb); INP_WUNLOCK(inp); + CURVNET_SET(toep->vnet); INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); tp = tcp_drop(tp, ECONNRESET); if (tp) INP_WUNLOCK(inp); INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); return (0); } /* receive buffer autosize */ - CURVNET_SET(so->so_vnet); + MPASS(toep->vnet == so->so_vnet); + CURVNET_SET(toep->vnet); if (sb->sb_flags & SB_AUTOSIZE && V_tcp_do_autorcvbuf && sb->sb_hiwat < V_tcp_autorcvbuf_max && @@ -1674,10 +1683,12 @@ do_fw4_ack(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) if (toep->flags & TPF_TX_SUSPENDED && toep->tx_credits >= toep->tx_total / 4) { toep->flags &= ~TPF_TX_SUSPENDED; + CURVNET_SET(toep->vnet); if (toep->ulp_mode == ULP_MODE_ISCSI) t4_push_pdus(sc, toep, plen); else t4_push_frames(sc, toep, plen); + CURVNET_RESTORE(); } else if (plen > 0) { struct sockbuf *sb = &so->so_snd; int sbu; @@ -1787,11 +1798,11 @@ void t4_uninit_cpl_io_handlers(void) { - t4_register_cpl_handler(CPL_PEER_CLOSE, do_peer_close); - t4_register_cpl_handler(CPL_CLOSE_CON_RPL, do_close_con_rpl); - t4_register_cpl_handler(CPL_ABORT_REQ_RSS, do_abort_req); - t4_register_cpl_handler(CPL_ABORT_RPL_RSS, do_abort_rpl); - t4_register_cpl_handler(CPL_RX_DATA, do_rx_data); - t4_register_cpl_handler(CPL_FW4_ACK, do_fw4_ack); + t4_register_cpl_handler(CPL_PEER_CLOSE, NULL); + t4_register_cpl_handler(CPL_CLOSE_CON_RPL, NULL); + t4_register_cpl_handler(CPL_ABORT_REQ_RSS, NULL); + t4_register_cpl_handler(CPL_ABORT_RPL_RSS, NULL); + t4_register_cpl_handler(CPL_RX_DATA, NULL); + t4_register_cpl_handler(CPL_FW4_ACK, NULL); } #endif diff --git a/sys/dev/cxgbe/tom/t4_ddp.c b/sys/dev/cxgbe/tom/t4_ddp.c index f5f08c8..8dad045 100644 --- a/sys/dev/cxgbe/tom/t4_ddp.c +++ b/sys/dev/cxgbe/tom/t4_ddp.c @@ -392,6 +392,8 @@ handle_ddp_data(struct toepcb *toep, __be32 ddp_report, __be32 rcv_nxt, int len) discourage_ddp(toep); /* receive buffer autosize */ + MPASS(toep->vnet == so->so_vnet); + CURVNET_SET(toep->vnet); if (sb->sb_flags & SB_AUTOSIZE && V_tcp_do_autorcvbuf && sb->sb_hiwat < V_tcp_autorcvbuf_max && @@ -405,6 +407,7 @@ handle_ddp_data(struct toepcb *toep, __be32 ddp_report, __be32 rcv_nxt, int len) else toep->rx_credits += newsize - hiwat; } + CURVNET_RESTORE(); KASSERT(toep->sb_cc >= sb->sb_cc, ("%s: sb %p has more data (%d) than last time (%d).", diff --git a/sys/dev/cxgbe/tom/t4_listen.c b/sys/dev/cxgbe/tom/t4_listen.c index 2c2b427..844168d 100644 --- a/sys/dev/cxgbe/tom/t4_listen.c +++ b/sys/dev/cxgbe/tom/t4_listen.c @@ -220,6 +220,7 @@ alloc_lctx(struct adapter *sc, struct inpcb *inp, struct vi_info *vi) TAILQ_INIT(&lctx->synq); lctx->inp = inp; + lctx->vnet = inp->inp_socket->so_vnet; in_pcbref(inp); return (lctx); @@ -825,14 +826,16 @@ done_with_synqe(struct adapter *sc, struct synq_entry *synqe) struct inpcb *inp = lctx->inp; struct vi_info *vi = synqe->syn->m_pkthdr.rcvif->if_softc; struct l2t_entry *e = &sc->l2t->l2tab[synqe->l2e_idx]; + int ntids; INP_WLOCK_ASSERT(inp); + ntids = inp->inp_vflag & INP_IPV6 ? 2 : 1; TAILQ_REMOVE(&lctx->synq, synqe, link); inp = release_lctx(sc, lctx); if (inp) INP_WUNLOCK(inp); - remove_tid(sc, synqe->tid); + remove_tid(sc, synqe->tid, ntids); release_tid(sc, synqe->tid, &sc->sge.ctrlq[vi->pi->port_id]); t4_l2t_release(e); release_synqe(synqe); /* removed from synq list */ @@ -1235,7 +1238,7 @@ do_pass_accept_req(struct sge_iq *iq, const struct rss_header *rss, struct l2t_entry *e = NULL; int rscale, mtu_idx, rx_credits, rxqid, ulp_mode; struct synq_entry *synqe = NULL; - int reject_reason, v; + int reject_reason, v, ntids; uint16_t vid; #ifdef INVARIANTS unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl))); @@ -1253,6 +1256,8 @@ do_pass_accept_req(struct sge_iq *iq, const struct rss_header *rss, pi = sc->port[G_SYN_INTF(be16toh(cpl->l2info))]; + CURVNET_SET(lctx->vnet); + /* * Use the MAC index to lookup the associated VI. If this SYN * didn't match a perfect MAC filter, punt. @@ -1309,6 +1314,8 @@ found: */ if (!ifnet_has_ip6(ifp, &inc.inc6_laddr)) REJECT_PASS_ACCEPT(); + + ntids = 2; } else { /* Don't offload if the ifcap isn't enabled */ @@ -1321,8 +1328,17 @@ found: */ if (!ifnet_has_ip(ifp, inc.inc_laddr)) REJECT_PASS_ACCEPT(); + + ntids = 1; } + /* + * Don't offload if the ifnet that the SYN came in on is not in the same + * vnet as the listening socket. + */ + if (lctx->vnet != ifp->if_vnet) + REJECT_PASS_ACCEPT(); + e = get_l2te_for_nexthop(pi, ifp, &inc); if (e == NULL) REJECT_PASS_ACCEPT(); @@ -1362,7 +1378,6 @@ found: REJECT_PASS_ACCEPT(); } so = inp->inp_socket; - CURVNET_SET(so->so_vnet); mtu_idx = find_best_mtu_idx(sc, &inc, be16toh(cpl->tcpopt.mss)); rscale = cpl->tcpopt.wsf && V_tcp_do_rfc1323 ? select_rcv_wscale() : 0; @@ -1398,7 +1413,7 @@ found: synqe->rcv_bufsize = rx_credits; atomic_store_rel_ptr(&synqe->wr, (uintptr_t)wr); - insert_tid(sc, tid, synqe); + insert_tid(sc, tid, synqe, ntids); TAILQ_INSERT_TAIL(&lctx->synq, synqe, link); hold_synqe(synqe); /* hold for the duration it's in the synq */ hold_lctx(lctx); /* A synqe on the list has a ref on its lctx */ @@ -1409,7 +1424,6 @@ found: */ toe_syncache_add(&inc, &to, &th, inp, tod, synqe); INP_UNLOCK_ASSERT(inp); /* ok to assert, we have a ref on the inp */ - CURVNET_RESTORE(); /* * If we replied during syncache_add (synqe->wr has been consumed), @@ -1427,7 +1441,7 @@ found: if (m) m->m_pkthdr.rcvif = hw_ifp; - remove_tid(sc, synqe->tid); + remove_tid(sc, synqe->tid, ntids); free(wr, M_CXGBE); /* Yank the synqe out of the lctx synq. */ @@ -1459,15 +1473,18 @@ found: if (!(synqe->flags & TPF_SYNQE_EXPANDED)) send_reset_synqe(tod, synqe); INP_WUNLOCK(inp); + CURVNET_RESTORE(); release_synqe(synqe); /* extra hold */ return (__LINE__); } INP_WUNLOCK(inp); + CURVNET_RESTORE(); release_synqe(synqe); /* extra hold */ return (0); reject: + CURVNET_RESTORE(); CTR4(KTR_CXGBE, "%s: stid %u, tid %u, REJECT (%d)", __func__, stid, tid, reject_reason); @@ -1539,6 +1556,7 @@ do_pass_establish(struct sge_iq *iq, const struct rss_header *rss, KASSERT(synqe->flags & TPF_SYNQE, ("%s: tid %u (ctx %p) not a synqe", __func__, tid, synqe)); + CURVNET_SET(lctx->vnet); INP_INFO_RLOCK(&V_tcbinfo); /* for syncache_expand */ INP_WLOCK(inp); @@ -1556,6 +1574,7 @@ do_pass_establish(struct sge_iq *iq, const struct rss_header *rss, INP_WUNLOCK(inp); INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); return (0); } @@ -1581,6 +1600,7 @@ reset: send_reset_synqe(TOEDEV(ifp), synqe); INP_WUNLOCK(inp); INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); return (0); } toep->tid = tid; @@ -1617,6 +1637,8 @@ reset: /* New connection inpcb is already locked by syncache_expand(). */ new_inp = sotoinpcb(so); INP_WLOCK_ASSERT(new_inp); + MPASS(so->so_vnet == lctx->vnet); + toep->vnet = lctx->vnet; /* * This is for the unlikely case where the syncache entry that we added @@ -1640,6 +1662,7 @@ reset: if (inp != NULL) INP_WUNLOCK(inp); INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); release_synqe(synqe); return (0); @@ -1654,4 +1677,14 @@ t4_init_listen_cpl_handlers(void) t4_register_cpl_handler(CPL_PASS_ACCEPT_REQ, do_pass_accept_req); t4_register_cpl_handler(CPL_PASS_ESTABLISH, do_pass_establish); } + +void +t4_uninit_listen_cpl_handlers(void) +{ + + t4_register_cpl_handler(CPL_PASS_OPEN_RPL, NULL); + t4_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, NULL); + t4_register_cpl_handler(CPL_PASS_ACCEPT_REQ, NULL); + t4_register_cpl_handler(CPL_PASS_ESTABLISH, NULL); +} #endif diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c index f62fcac..4c58cf9 100644 --- a/sys/dev/cxgbe/tom/t4_tom.c +++ b/sys/dev/cxgbe/tom/t4_tom.c @@ -321,7 +321,7 @@ release_offload_resources(struct toepcb *toep) t4_l2t_release(toep->l2te); if (tid >= 0) { - remove_tid(sc, tid); + remove_tid(sc, tid, toep->ce ? 2 : 1); release_tid(sc, tid, toep->ctrlq); } @@ -432,12 +432,12 @@ final_cpl_received(struct toepcb *toep) } void -insert_tid(struct adapter *sc, int tid, void *ctx) +insert_tid(struct adapter *sc, int tid, void *ctx, int ntids) { struct tid_info *t = &sc->tids; t->tid_tab[tid] = ctx; - atomic_add_int(&t->tids_in_use, 1); + atomic_add_int(&t->tids_in_use, ntids); } void * @@ -457,12 +457,12 @@ update_tid(struct adapter *sc, int tid, void *ctx) } void -remove_tid(struct adapter *sc, int tid) +remove_tid(struct adapter *sc, int tid, int ntids) { struct tid_info *t = &sc->tids; t->tid_tab[tid] = NULL; - atomic_subtract_int(&t->tids_in_use, 1); + atomic_subtract_int(&t->tids_in_use, ntids); } void @@ -811,74 +811,96 @@ update_clip_table(struct adapter *sc, struct tom_data *td) struct in6_addr *lip, tlip; struct clip_head stale; struct clip_entry *ce, *ce_temp; - int rc, gen = atomic_load_acq_int(&in6_ifaddr_gen); + struct vi_info *vi; + int rc, gen, i, j; + uintptr_t last_vnet; ASSERT_SYNCHRONIZED_OP(sc); IN6_IFADDR_RLOCK(); mtx_lock(&td->clip_table_lock); + gen = atomic_load_acq_int(&in6_ifaddr_gen); if (gen == td->clip_gen) goto done; TAILQ_INIT(&stale); TAILQ_CONCAT(&stale, &td->clip_table, link); - TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { - lip = &ia->ia_addr.sin6_addr; + /* + * last_vnet optimizes the common cases where all if_vnet = NULL (no + * VIMAGE) or all if_vnet = vnet0. + */ + last_vnet = (uintptr_t)(-1); + for_each_port(sc, i) + for_each_vi(sc->port[i], j, vi) { + if (last_vnet == (uintptr_t)vi->ifp->if_vnet) + continue; - KASSERT(!IN6_IS_ADDR_MULTICAST(lip), - ("%s: mcast address in in6_ifaddr list", __func__)); + /* XXX: races with if_vmove */ + CURVNET_SET(vi->ifp->if_vnet); + TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { + lip = &ia->ia_addr.sin6_addr; + + KASSERT(!IN6_IS_ADDR_MULTICAST(lip), + ("%s: mcast address in in6_ifaddr list", __func__)); + + if (IN6_IS_ADDR_LOOPBACK(lip)) + continue; + if (IN6_IS_SCOPE_EMBED(lip)) { + /* Remove the embedded scope */ + tlip = *lip; + lip = &tlip; + in6_clearscope(lip); + } + /* + * XXX: how to weed out the link local address for the + * loopback interface? It's fe80::1 usually (always?). + */ + + /* + * If it's in the main list then we already know it's + * not stale. + */ + TAILQ_FOREACH(ce, &td->clip_table, link) { + if (IN6_ARE_ADDR_EQUAL(&ce->lip, lip)) + goto next; + } - if (IN6_IS_ADDR_LOOPBACK(lip)) - continue; - if (IN6_IS_SCOPE_EMBED(lip)) { - /* Remove the embedded scope */ - tlip = *lip; - lip = &tlip; - in6_clearscope(lip); - } - /* - * XXX: how to weed out the link local address for the loopback - * interface? It's fe80::1 usually (always?). - */ - - /* - * If it's in the main list then we already know it's not stale. - */ - TAILQ_FOREACH(ce, &td->clip_table, link) { - if (IN6_ARE_ADDR_EQUAL(&ce->lip, lip)) - goto next; - } + /* + * If it's in the stale list we should move it to the + * main list. + */ + TAILQ_FOREACH(ce, &stale, link) { + if (IN6_ARE_ADDR_EQUAL(&ce->lip, lip)) { + TAILQ_REMOVE(&stale, ce, link); + TAILQ_INSERT_TAIL(&td->clip_table, ce, + link); + goto next; + } + } - /* - * If it's in the stale list we should move it to the main list. - */ - TAILQ_FOREACH(ce, &stale, link) { - if (IN6_ARE_ADDR_EQUAL(&ce->lip, lip)) { - TAILQ_REMOVE(&stale, ce, link); + /* A new IP6 address; add it to the CLIP table */ + ce = malloc(sizeof(*ce), M_CXGBE, M_NOWAIT); + memcpy(&ce->lip, lip, sizeof(ce->lip)); + ce->refcount = 0; + rc = add_lip(sc, lip); + if (rc == 0) TAILQ_INSERT_TAIL(&td->clip_table, ce, link); - goto next; - } - } + else { + char ip[INET6_ADDRSTRLEN]; - /* A new IP6 address; add it to the CLIP table */ - ce = malloc(sizeof(*ce), M_CXGBE, M_NOWAIT); - memcpy(&ce->lip, lip, sizeof(ce->lip)); - ce->refcount = 0; - rc = add_lip(sc, lip); - if (rc == 0) - TAILQ_INSERT_TAIL(&td->clip_table, ce, link); - else { - char ip[INET6_ADDRSTRLEN]; - - inet_ntop(AF_INET6, &ce->lip, &ip[0], sizeof(ip)); - log(LOG_ERR, "%s: could not add %s (%d)\n", - __func__, ip, rc); - free(ce, M_CXGBE); - } + inet_ntop(AF_INET6, &ce->lip, &ip[0], + sizeof(ip)); + log(LOG_ERR, "%s: could not add %s (%d)\n", + __func__, ip, rc); + free(ce, M_CXGBE); + } next: - continue; + continue; + } + CURVNET_RESTORE(); + last_vnet = (uintptr_t)vi->ifp->if_vnet; } /* @@ -1203,6 +1225,10 @@ t4_tom_mod_unload(void) t4_ddp_mod_unload(); + t4_uninit_connect_cpl_handlers(); + t4_uninit_listen_cpl_handlers(); + t4_uninit_cpl_io_handlers(); + return (0); } #endif /* TCP_OFFLOAD */ diff --git a/sys/dev/cxgbe/tom/t4_tom.h b/sys/dev/cxgbe/tom/t4_tom.h index a1d723d..f5ca0cf 100644 --- a/sys/dev/cxgbe/tom/t4_tom.h +++ b/sys/dev/cxgbe/tom/t4_tom.h @@ -123,6 +123,7 @@ struct toepcb { u_int flags; /* miscellaneous flags */ struct tom_data *td; struct inpcb *inp; /* backpointer to host stack's PCB */ + struct vnet *vnet; struct vi_info *vi; /* virtual interface */ struct sge_wrq *ofld_txq; struct sge_ofld_rxq *ofld_rxq; @@ -199,6 +200,7 @@ struct listen_ctx { struct stid_region stid_region; int flags; struct inpcb *inp; /* listening socket's inp */ + struct vnet *vnet; struct sge_wrq *ctrlq; struct sge_ofld_rxq *ofld_rxq; struct clip_entry *ce; @@ -278,10 +280,10 @@ void free_toepcb(struct toepcb *); void offload_socket(struct socket *, struct toepcb *); void undo_offload_socket(struct socket *); void final_cpl_received(struct toepcb *); -void insert_tid(struct adapter *, int, void *); +void insert_tid(struct adapter *, int, void *, int); void *lookup_tid(struct adapter *, int); void update_tid(struct adapter *, int, void *); -void remove_tid(struct adapter *, int); +void remove_tid(struct adapter *, int, int); void release_tid(struct adapter *, int, struct sge_wrq *); int find_best_mtu_idx(struct adapter *, struct in_conninfo *, int); u_long select_rcv_wnd(struct socket *); @@ -296,12 +298,14 @@ void release_lip(struct tom_data *, struct clip_entry *); /* t4_connect.c */ void t4_init_connect_cpl_handlers(void); +void t4_uninit_connect_cpl_handlers(void); int t4_connect(struct toedev *, struct socket *, struct rtentry *, struct sockaddr *); void act_open_failure_cleanup(struct adapter *, u_int, u_int); /* t4_listen.c */ void t4_init_listen_cpl_handlers(void); +void t4_uninit_listen_cpl_handlers(void); int t4_listen_start(struct toedev *, struct tcpcb *); int t4_listen_stop(struct toedev *, struct tcpcb *); void t4_syncache_added(struct toedev *, void *); diff --git a/sys/dev/hpt27xx/hpt27xx_os_bsd.c b/sys/dev/hpt27xx/hpt27xx_os_bsd.c index 7970e35..12e0efa 100644 --- a/sys/dev/hpt27xx/hpt27xx_os_bsd.c +++ b/sys/dev/hpt27xx/hpt27xx_os_bsd.c @@ -120,13 +120,13 @@ void *os_map_pci_bar( if (base & 1) { hba->pcibar[index].type = SYS_RES_IOPORT; - hba->pcibar[index].res = bus_alloc_resource(hba->pcidev, - hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE); + hba->pcibar[index].res = bus_alloc_resource_any(hba->pcidev, + hba->pcibar[index].type, &hba->pcibar[index].rid, RF_ACTIVE); hba->pcibar[index].base = (void *)(unsigned long)(base & ~0x1); } else { hba->pcibar[index].type = SYS_RES_MEMORY; - hba->pcibar[index].res = bus_alloc_resource(hba->pcidev, - hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE); + hba->pcibar[index].res = bus_alloc_resource_any(hba->pcidev, + hba->pcibar[index].type, &hba->pcibar[index].rid, RF_ACTIVE); hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset; } diff --git a/sys/dev/hptmv/entry.c b/sys/dev/hptmv/entry.c index 37ff6c2..f4a3dd9 100644 --- a/sys/dev/hptmv/entry.c +++ b/sys/dev/hptmv/entry.c @@ -1356,8 +1356,8 @@ init_adapter(IAL_ADAPTER_T *pAdapter) /* also map EPROM address */ rid = 0x10; - if (!(pAdapter->mem_res = bus_alloc_resource(pAdapter->hpt_dev, SYS_RES_MEMORY, &rid, - 0, ~0, MV_SATA_PCI_BAR0_SPACE_SIZE+0x40000, RF_ACTIVE)) + if (!(pAdapter->mem_res = bus_alloc_resource_any(pAdapter->hpt_dev, + SYS_RES_MEMORY, &rid, RF_ACTIVE)) || !(pMvSataAdapter->adapterIoBaseAddress = rman_get_virtual(pAdapter->mem_res))) { diff --git a/sys/dev/hptnr/hptnr_os_bsd.c b/sys/dev/hptnr/hptnr_os_bsd.c index b019a7c..36f0c3c 100644 --- a/sys/dev/hptnr/hptnr_os_bsd.c +++ b/sys/dev/hptnr/hptnr_os_bsd.c @@ -106,13 +106,13 @@ void *os_map_pci_bar( if (base & 1) { hba->pcibar[index].type = SYS_RES_IOPORT; - hba->pcibar[index].res = bus_alloc_resource(hba->pcidev, - hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE); + hba->pcibar[index].res = bus_alloc_resource_any(hba->pcidev, + hba->pcibar[index].type, &hba->pcibar[index].rid, RF_ACTIVE); hba->pcibar[index].base = (void *)(unsigned long)(base & ~0x1); } else { hba->pcibar[index].type = SYS_RES_MEMORY; - hba->pcibar[index].res = bus_alloc_resource(hba->pcidev, - hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE); + hba->pcibar[index].res = bus_alloc_resource_any(hba->pcidev, + hba->pcibar[index].type, &hba->pcibar[index].rid, RF_ACTIVE); hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset; } diff --git a/sys/dev/hptrr/hptrr_os_bsd.c b/sys/dev/hptrr/hptrr_os_bsd.c index 8600a8c..6cd01e5 100644 --- a/sys/dev/hptrr/hptrr_os_bsd.c +++ b/sys/dev/hptrr/hptrr_os_bsd.c @@ -98,8 +98,8 @@ void *os_map_pci_bar( else hba->pcibar[index].type = SYS_RES_MEMORY; - hba->pcibar[index].res = bus_alloc_resource(hba->pcidev, - hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE); + hba->pcibar[index].res = bus_alloc_resource_any(hba->pcidev, + hba->pcibar[index].type, &hba->pcibar[index].rid, RF_ACTIVE); hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset; return hba->pcibar[index].base; diff --git a/sys/dev/iir/iir.c b/sys/dev/iir/iir.c index bf5cec5..e74698e 100644 --- a/sys/dev/iir/iir.c +++ b/sys/dev/iir/iir.c @@ -744,9 +744,9 @@ gdt_next(struct gdt_softc *gdt) ccb->ccb_h.flags)); csio = &ccb->csio; ccbh = &ccb->ccb_h; - cmd = csio->cdb_io.cdb_bytes[0]; - /* Max CDB length is 12 bytes */ - if (csio->cdb_len > 12) { + cmd = scsiio_cdb_ptr(csio)[0]; + /* Max CDB length is 12 bytes, can't be phys addr */ + if (csio->cdb_len > 12 || (ccbh->flags & CAM_CDB_PHYS)) { ccbh->status = CAM_REQ_INVALID; --gdt_stat.io_count_act; xpt_done(ccb); diff --git a/sys/dev/isci/isci_controller.c b/sys/dev/isci/isci_controller.c index b0f4285..d3ec045 100644 --- a/sys/dev/isci/isci_controller.c +++ b/sys/dev/isci/isci_controller.c @@ -740,6 +740,11 @@ void isci_action(struct cam_sim *sim, union ccb *ccb) } break; case XPT_SCSI_IO: + if (ccb->ccb_h.flags & CAM_CDB_PHYS) { + ccb->ccb_h.status = CAM_REQ_INVALID; + xpt_done(ccb); + break; + } isci_io_request_execute_scsi_io(ccb, controller); break; #if __FreeBSD_version >= 900026 @@ -802,6 +807,7 @@ isci_controller_release_queued_ccbs(struct ISCI_CONTROLLER *controller) { struct ISCI_REMOTE_DEVICE *dev; struct ccb_hdr *ccb_h; + uint8_t *ptr; int dev_idx; KASSERT(mtx_owned(&controller->lock), ("controller lock not owned")); @@ -821,8 +827,8 @@ isci_controller_release_queued_ccbs(struct ISCI_CONTROLLER *controller) if (ccb_h == NULL) continue; - isci_log_message(1, "ISCI", "release %p %x\n", ccb_h, - ((union ccb *)ccb_h)->csio.cdb_io.cdb_bytes[0]); + ptr = scsiio_cdb_ptr(&((union ccb *)ccb_h)->csio); + isci_log_message(1, "ISCI", "release %p %x\n", ccb_h, *ptr); dev->queued_ccb_in_progress = (union ccb *)ccb_h; isci_io_request_execute_scsi_io( diff --git a/sys/dev/isci/isci_io_request.c b/sys/dev/isci/isci_io_request.c index 4151900..066e0d9 100644 --- a/sys/dev/isci/isci_io_request.c +++ b/sys/dev/isci/isci_io_request.c @@ -86,6 +86,7 @@ isci_io_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller, struct ISCI_REMOTE_DEVICE *isci_remote_device; union ccb *ccb; BOOL complete_ccb; + struct ccb_scsiio *csio; complete_ccb = TRUE; isci_controller = (struct ISCI_CONTROLLER *) sci_object_get_association(scif_controller); @@ -93,7 +94,7 @@ isci_io_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller, (struct ISCI_REMOTE_DEVICE *) sci_object_get_association(remote_device); ccb = isci_request->ccb; - + csio = &ccb->csio; ccb->ccb_h.status &= ~CAM_STATUS_MASK; switch (completion_status) { @@ -124,7 +125,6 @@ isci_io_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller, SCI_SSP_RESPONSE_IU_T * response_buffer; uint32_t sense_length; int error_code, sense_key, asc, ascq; - struct ccb_scsiio *csio = &ccb->csio; response_buffer = (SCI_SSP_RESPONSE_IU_T *) scif_io_request_get_response_iu_address( @@ -146,7 +146,7 @@ isci_io_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller, isci_log_message(1, "ISCI", "isci: bus=%x target=%x lun=%x cdb[0]=%x status=%x key=%x asc=%x ascq=%x\n", ccb->ccb_h.path_id, ccb->ccb_h.target_id, - ccb->ccb_h.target_lun, csio->cdb_io.cdb_bytes[0], + ccb->ccb_h.target_lun, scsiio_cdb_ptr(csio), csio->scsi_status, sense_key, asc, ascq); break; } @@ -157,7 +157,7 @@ isci_io_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller, isci_log_message(0, "ISCI", "isci: bus=%x target=%x lun=%x cdb[0]=%x remote device reset required\n", ccb->ccb_h.path_id, ccb->ccb_h.target_id, - ccb->ccb_h.target_lun, ccb->csio.cdb_io.cdb_bytes[0]); + ccb->ccb_h.target_lun, scsiio_cdb_ptr(csio)); break; case SCI_IO_FAILURE_TERMINATED: @@ -165,7 +165,7 @@ isci_io_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller, isci_log_message(0, "ISCI", "isci: bus=%x target=%x lun=%x cdb[0]=%x terminated\n", ccb->ccb_h.path_id, ccb->ccb_h.target_id, - ccb->ccb_h.target_lun, ccb->csio.cdb_io.cdb_bytes[0]); + ccb->ccb_h.target_lun, scsiio_cdb_ptr(csio)); break; case SCI_IO_FAILURE_INVALID_STATE: @@ -208,7 +208,7 @@ isci_io_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller, isci_log_message(1, "ISCI", "isci: bus=%x target=%x lun=%x cdb[0]=%x completion status=%x\n", ccb->ccb_h.path_id, ccb->ccb_h.target_id, - ccb->ccb_h.target_lun, ccb->csio.cdb_io.cdb_bytes[0], + ccb->ccb_h.target_lun, scsiio_cdb_ptr(csio), completion_status); ccb->ccb_h.status |= CAM_REQ_CMP_ERR; break; @@ -285,13 +285,13 @@ isci_io_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller, * get a ready notification for this device. */ isci_log_message(1, "ISCI", "already queued %p %x\n", - ccb, ccb->csio.cdb_io.cdb_bytes[0]); + ccb, scsiio_cdb_ptr(csio)); isci_remote_device->queued_ccb_in_progress = NULL; } else { isci_log_message(1, "ISCI", "queue %p %x\n", ccb, - ccb->csio.cdb_io.cdb_bytes[0]); + scsiio_cdb_ptr(csio)); ccb->ccb_h.status |= CAM_SIM_QUEUED; TAILQ_INSERT_TAIL(&isci_remote_device->queued_ccbs, @@ -373,7 +373,7 @@ scif_cb_io_request_get_cdb_address(void * scif_user_io_request) struct ISCI_IO_REQUEST *isci_request = (struct ISCI_IO_REQUEST *)scif_user_io_request; - return (isci_request->ccb->csio.cdb_io.cdb_bytes); + return (scsiio_cdb_ptr(&isci_request->ccb->csio)); } /** diff --git a/sys/dev/isci/isci_task_request.c b/sys/dev/isci/isci_task_request.c index 6c8be45..2ed0afe 100644 --- a/sys/dev/isci/isci_task_request.c +++ b/sys/dev/isci/isci_task_request.c @@ -210,8 +210,9 @@ isci_task_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller, retry_task = FALSE; isci_log_message(0, "ISCI", "task timeout - not retrying\n"); - scif_cb_domain_device_removed(isci_controller, - isci_remote_device->domain, isci_remote_device); + scif_cb_domain_device_removed(scif_controller, + isci_remote_device->domain->sci_object, + remote_device); } else { retry_task = TRUE; isci_log_message(0, "ISCI", diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index 427f545..f059b2b 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -3800,6 +3800,7 @@ ixgbe_handle_msf(void *context, int pending) /* Adjust media types shown in ifconfig */ ifmedia_removeall(&adapter->media); ixgbe_add_media_types(adapter); + ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); return; } diff --git a/sys/dev/jme/if_jme.c b/sys/dev/jme/if_jme.c index 9bdb229..781d337 100644 --- a/sys/dev/jme/if_jme.c +++ b/sys/dev/jme/if_jme.c @@ -803,7 +803,7 @@ jme_attach(device_t dev) } /* Create coalescing sysctl node. */ jme_sysctl_node(sc); - if ((error = jme_dma_alloc(sc) != 0)) + if ((error = jme_dma_alloc(sc)) != 0) goto fail; ifp = sc->jme_ifp = if_alloc(IFT_ETHER); diff --git a/sys/dev/kbd/kbd.c b/sys/dev/kbd/kbd.c index ea84d46..3f076b0 100644 --- a/sys/dev/kbd/kbd.c +++ b/sys/dev/kbd/kbd.c @@ -884,7 +884,7 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) omapp->key[i].spcl = mapp->key[i].spcl; omapp->key[i].flgs = mapp->key[i].flgs; } - return (0); + break; case PIO_KEYMAP: /* set keyboard translation table */ case OPIO_KEYMAP: /* set keyboard translation table (compat) */ #ifndef KBD_DISABLE_KEYMAP_LOAD diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c index e84e05a..bb6ba93 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c @@ -306,6 +306,12 @@ mlx5e_update_carrier_work(struct work_struct *work) PRIV_UNLOCK(priv); } +/* + * This function reads the physical port counters from the firmware + * using a pre-defined layout defined by various MLX5E_PPORT_XXX() + * macros. The output is converted from big-endian 64-bit values into + * host endian ones and stored in the "priv->stats.pport" structure. + */ static void mlx5e_update_pport_counters(struct mlx5e_priv *priv) { @@ -314,25 +320,32 @@ mlx5e_update_pport_counters(struct mlx5e_priv *priv) struct mlx5e_port_stats_debug *s_debug = &priv->stats.port_stats_debug; u32 *in; u32 *out; - u64 *ptr; + const u64 *ptr; unsigned sz = MLX5_ST_SZ_BYTES(ppcnt_reg); unsigned x; unsigned y; + /* allocate firmware request structures */ in = mlx5_vzalloc(sz); out = mlx5_vzalloc(sz); if (in == NULL || out == NULL) goto free_out; - ptr = (uint64_t *)MLX5_ADDR_OF(ppcnt_reg, out, counter_set); + /* + * Get pointer to the 64-bit counter set which is located at a + * fixed offset in the output firmware request structure: + */ + ptr = (const uint64_t *)MLX5_ADDR_OF(ppcnt_reg, out, counter_set); MLX5_SET(ppcnt_reg, in, local_port, 1); + /* read IEEE802_3 counter group using predefined counter layout */ MLX5_SET(ppcnt_reg, in, grp, MLX5_IEEE_802_3_COUNTERS_GROUP); mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); for (x = y = 0; x != MLX5E_PPORT_IEEE802_3_STATS_NUM; x++, y++) s->arg[y] = be64toh(ptr[x]); + /* read RFC2819 counter group using predefined counter layout */ MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2819_COUNTERS_GROUP); mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); for (x = 0; x != MLX5E_PPORT_RFC2819_STATS_NUM; x++, y++) @@ -341,20 +354,29 @@ mlx5e_update_pport_counters(struct mlx5e_priv *priv) MLX5E_PPORT_RFC2819_STATS_DEBUG_NUM; x++, y++) s_debug->arg[y] = be64toh(ptr[x]); + /* read RFC2863 counter group using predefined counter layout */ MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2863_COUNTERS_GROUP); mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); for (x = 0; x != MLX5E_PPORT_RFC2863_STATS_DEBUG_NUM; x++, y++) s_debug->arg[y] = be64toh(ptr[x]); + /* read physical layer stats counter group using predefined counter layout */ MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_COUNTERS_GROUP); mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); for (x = 0; x != MLX5E_PPORT_PHYSICAL_LAYER_STATS_DEBUG_NUM; x++, y++) s_debug->arg[y] = be64toh(ptr[x]); free_out: + /* free firmware request structures */ kvfree(in); kvfree(out); } +/* + * This function is called regularly to collect all statistics + * counters from the firmware. The values can be viewed through the + * sysctl interface. Execution is serialized using the priv's global + * configuration lock. + */ static void mlx5e_update_stats_work(struct work_struct *work) { diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c index a41d807..3c70a99 100644 --- a/sys/dev/mmc/mmc.c +++ b/sys/dev/mmc/mmc.c @@ -401,7 +401,7 @@ mmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req) msleep(req, &sc->sc_mtx, 0, "mmcreq", 0); MMC_UNLOCK(sc); if (mmc_debug > 2 || (mmc_debug > 0 && req->cmd->error != MMC_ERR_NONE)) - device_printf(sc->dev, "CMD%d RESULT: %d\n", + device_printf(sc->dev, "CMD%d RESULT: %d\n", req->cmd->opcode, req->cmd->error); return (0); } @@ -511,7 +511,7 @@ mmc_idle_cards(struct mmc_softc *sc) { device_t dev; struct mmc_command cmd; - + dev = sc->dev; mmcbr_set_chip_select(dev, cs_high); mmcbr_update_ios(dev); @@ -795,7 +795,7 @@ mmc_test_bus_width(struct mmc_softc *sc) data.len = 8; data.flags = MMC_DATA_WRITE; mmc_wait_for_cmd(sc, &cmd, 0); - + memset(&cmd, 0, sizeof(cmd)); memset(&data, 0, sizeof(data)); cmd.opcode = MMC_BUSTEST_R; @@ -808,7 +808,7 @@ mmc_test_bus_width(struct mmc_softc *sc) data.flags = MMC_DATA_READ; err = mmc_wait_for_cmd(sc, &cmd, 0); sc->squelched--; - + mmcbr_set_bus_width(sc->dev, bus_width_1); mmcbr_update_ios(sc->dev); @@ -832,7 +832,7 @@ mmc_test_bus_width(struct mmc_softc *sc) data.len = 4; data.flags = MMC_DATA_WRITE; mmc_wait_for_cmd(sc, &cmd, 0); - + memset(&cmd, 0, sizeof(cmd)); memset(&data, 0, sizeof(data)); cmd.opcode = MMC_BUSTEST_R; @@ -1017,7 +1017,7 @@ mmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd) csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3); csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4); csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1); - } else + } else panic("unknown SD CSD version"); } @@ -1349,9 +1349,9 @@ mmc_discover_cards(struct mmc_softc *sc) if (ivar->csd.csd_structure > 0) ivar->high_cap = 1; ivar->tran_speed = ivar->csd.tran_speed; - ivar->erase_sector = ivar->csd.erase_sector * + ivar->erase_sector = ivar->csd.erase_sector * ivar->csd.write_bl_len / MMC_SECTOR_SIZE; - + err = mmc_send_status(sc, ivar->rca, &status); if (err != MMC_ERR_NONE) { device_printf(sc->dev, @@ -1446,7 +1446,7 @@ mmc_discover_cards(struct mmc_softc *sc) mmc_decode_csd_mmc(ivar->raw_csd, &ivar->csd); ivar->sec_count = ivar->csd.capacity / MMC_SECTOR_SIZE; ivar->tran_speed = ivar->csd.tran_speed; - ivar->erase_sector = ivar->csd.erase_sector * + ivar->erase_sector = ivar->csd.erase_sector * ivar->csd.write_bl_len / MMC_SECTOR_SIZE; err = mmc_send_status(sc, ivar->rca, &status); @@ -1655,7 +1655,7 @@ mmc_calculate_clock(struct mmc_softc *sc) int nkid, i, f_max; device_t *kids; struct mmc_ivars *ivar; - + f_max = mmcbr_get_f_max(sc->dev); max_dtr = max_hs_dtr = f_max; if ((mmcbr_get_caps(sc->dev) & MMC_CAP_HSPEED)) @@ -1770,7 +1770,7 @@ static void mmc_delayed_attach(void *xsc) { struct mmc_softc *sc = xsc; - + mmc_scan(sc); config_intrhook_disestablish(&sc->config_intrhook); } diff --git a/sys/dev/mmc/mmcreg.h b/sys/dev/mmc/mmcreg.h index f454ddb..080c14e 100644 --- a/sys/dev/mmc/mmcreg.h +++ b/sys/dev/mmc/mmcreg.h @@ -85,8 +85,11 @@ struct mmc_command { #define MMC_RSP_R1B (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY) #define MMC_RSP_R2 (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC) #define MMC_RSP_R3 (MMC_RSP_PRESENT) -#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC) -#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC) +#define MMC_RSP_R4 (MMC_RSP_PRESENT) +#define MMC_RSP_R5 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) +#define MMC_RSP_R5B (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY) +#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) +#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) #define MMC_RSP(x) ((x) & MMC_RSP_MASK) uint32_t retries; uint32_t error; @@ -352,8 +355,8 @@ struct mmc_request { */ #define MMC_OCR_VOLTAGE 0x3fffffffU /* Vdd Voltage mask */ #define MMC_OCR_LOW_VOLTAGE (1u << 7) /* Low Voltage Range -- tbd */ +#define MMC_OCR_MIN_VOLTAGE_SHIFT 7 #define MMC_OCR_200_210 (1U << 8) /* Vdd voltage 2.00 ~ 2.10 */ -#define MMC_OCR_MIN_VOLTAGE_SHIFT 8 #define MMC_OCR_210_220 (1U << 9) /* Vdd voltage 2.10 ~ 2.20 */ #define MMC_OCR_220_230 (1U << 10) /* Vdd voltage 2.20 ~ 2.30 */ #define MMC_OCR_230_240 (1U << 11) /* Vdd voltage 2.30 ~ 2.40 */ diff --git a/sys/dev/mmc/mmcsd.c b/sys/dev/mmc/mmcsd.c index 72094ed..1931f7b 100644 --- a/sys/dev/mmc/mmcsd.c +++ b/sys/dev/mmc/mmcsd.c @@ -160,16 +160,16 @@ mmcsd_attach(device_t dev) d->d_dump = mmcsd_dump; d->d_name = "mmcsd"; d->d_drv1 = sc; - d->d_maxsize = 4*1024*1024; /* Maximum defined SD card AU size. */ d->d_sectorsize = mmc_get_sector_size(dev); + d->d_maxsize = mmc_get_max_data(dev) * d->d_sectorsize; d->d_mediasize = (off_t)mmc_get_media_size(dev) * d->d_sectorsize; - d->d_stripeoffset = 0; d->d_stripesize = mmc_get_erase_sector(dev) * d->d_sectorsize; d->d_unit = device_get_unit(dev); d->d_flags = DISKFLAG_CANDELETE; - d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize * 1; /* conservative */ + d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize; strlcpy(d->d_ident, mmc_get_card_sn_string(dev), sizeof(d->d_ident)); strlcpy(d->d_descr, mmc_get_card_id_string(dev), sizeof(d->d_descr)); + d->d_rotation_rate = DISK_RR_NON_ROTATING; /* * Display in most natural units. There's no cards < 1MB. The SD @@ -545,6 +545,8 @@ mmcsd_task(void *arg) bp->bio_error = EIO; bp->bio_resid = (end - block) * sz; bp->bio_flags |= BIO_ERROR; + } else { + bp->bio_resid = 0; } biodone(bp); } diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c index d44e502..c9d83d8 100644 --- a/sys/dev/mpr/mpr_sas.c +++ b/sys/dev/mpr/mpr_sas.c @@ -1846,8 +1846,12 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb) if (csio->ccb_h.flags & CAM_CDB_POINTER) bcopy(csio->cdb_io.cdb_ptr, &req->CDB.CDB32[0], csio->cdb_len); - else + else { + KASSERT(csio->cdb_len <= IOCDBLEN, + ("cdb_len %d is greater than IOCDBLEN but CAM_CDB_POINTER is not set", + csio->cdb_len)); bcopy(csio->cdb_io.cdb_bytes, &req->CDB.CDB32[0],csio->cdb_len); + } req->IoFlags = htole16(csio->cdb_len); /* @@ -2429,6 +2433,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) * driver is being shutdown. */ if ((csio->cdb_io.cdb_bytes[0] == INQUIRY) && + (csio->data_ptr != NULL) && ((csio->data_ptr[0] & 0x1f) == T_DIRECT) && (sc->mapping_table[target_id].device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) && diff --git a/sys/dev/mpr/mpr_sas_lsi.c b/sys/dev/mpr/mpr_sas_lsi.c index 73e2f54..1eb78d1 100644 --- a/sys/dev/mpr/mpr_sas_lsi.c +++ b/sys/dev/mpr/mpr_sas_lsi.c @@ -1056,6 +1056,7 @@ out: mpr_free_command(sc, cm); else if (error == 0) error = EWOULDBLOCK; + cm->cm_data = NULL; free(buffer, M_MPR); return (error); } @@ -1196,18 +1197,18 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc) continue; } - ccb = xpt_alloc_ccb_nowait(); - if (ccb == NULL) { - mpr_dprint(sc, MPR_FAULT, "Unable to alloc CCB to stop " - "unit.\n"); - return; - } - /* * The stop_at_shutdown flag will be set if this device is * a SATA direct-access end device. */ if (target->stop_at_shutdown) { + ccb = xpt_alloc_ccb_nowait(); + if (ccb == NULL) { + mpr_dprint(sc, MPR_FAULT, "Unable to alloc CCB to stop " + "unit.\n"); + return; + } + if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, pathid, targetid, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 024f937..c464628 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1626,7 +1626,7 @@ msk_attach(device_t dev) callout_init_mtx(&sc_if->msk_tick_ch, &sc_if->msk_softc->msk_mtx, 0); msk_sysctl_node(sc_if); - if ((error = msk_txrx_dma_alloc(sc_if) != 0)) + if ((error = msk_txrx_dma_alloc(sc_if)) != 0) goto fail; msk_rx_dma_jalloc(sc_if); diff --git a/sys/dev/nand/nand_geom.c b/sys/dev/nand/nand_geom.c index 8786a0a..98373aa 100644 --- a/sys/dev/nand/nand_geom.c +++ b/sys/dev/nand/nand_geom.c @@ -394,6 +394,7 @@ create_geom_disk(struct nand_chip *chip) snprintf(ndisk->d_ident, sizeof(ndisk->d_ident), "nand: Man:0x%02x Dev:0x%02x", chip->id.man_id, chip->id.dev_id); + ndisk->d_rotation_rate = DISK_RR_NON_ROTATING; disk_create(ndisk, DISK_VERSION); @@ -415,6 +416,7 @@ create_geom_disk(struct nand_chip *chip) snprintf(rdisk->d_ident, sizeof(rdisk->d_ident), "nand_raw: Man:0x%02x Dev:0x%02x", chip->id.man_id, chip->id.dev_id); + disk->d_rotation_rate = DISK_RR_NON_ROTATING; disk_create(rdisk, DISK_VERSION); diff --git a/sys/dev/ntb/if_ntb/if_ntb.c b/sys/dev/ntb/if_ntb/if_ntb.c index 33645c4..47d6dd8 100644 --- a/sys/dev/ntb/if_ntb/if_ntb.c +++ b/sys/dev/ntb/if_ntb/if_ntb.c @@ -237,6 +237,11 @@ ntb_ioctl(struct ifnet *ifp, u_long command, caddr_t data) int error = 0; switch (command) { + case SIOCSIFFLAGS: + case SIOCADDMULTI: + case SIOCDELMULTI: + break; + case SIOCSIFMTU: { if (ifr->ifr_mtu > sc->mtu - ETHER_HDR_LEN) { diff --git a/sys/dev/nvd/nvd.c b/sys/dev/nvd/nvd.c index 989ed92..11e4f58 100644 --- a/sys/dev/nvd/nvd.c +++ b/sys/dev/nvd/nvd.c @@ -338,13 +338,11 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg) */ nvme_strvis(disk->d_ident, nvme_ns_get_serial_number(ns), sizeof(disk->d_ident), NVME_SERIAL_NUMBER_LENGTH); - nvme_strvis(descr, nvme_ns_get_model_number(ns), sizeof(descr), NVME_MODEL_NUMBER_LENGTH); - -#if __FreeBSD_version >= 900034 strlcpy(disk->d_descr, descr, sizeof(descr)); -#endif + + disk->d_rotation_rate = DISK_RR_NON_ROTATING; ndisk->ns = ns; ndisk->disk = disk; diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 792469f..26cf526 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -269,12 +269,13 @@ static const struct pci_quirk pci_quirks[] = { { 0x43851002, PCI_QUIRK_UNMAP_REG, 0x14, 0 }, /* - * Atheros AR8161/AR8162/E2200 Ethernet controllers have a bug that - * MSI interrupt does not assert if PCIM_CMD_INTxDIS bit of the - * command register is set. + * Atheros AR8161/AR8162/E2200/E2400 Ethernet controllers have a + * bug that MSI interrupt does not assert if PCIM_CMD_INTxDIS bit + * of the command register is set. */ { 0x10911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, { 0xE0911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, + { 0xE0A11969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, { 0x10901969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* diff --git a/sys/dev/ppbus/vpo.c b/sys/dev/ppbus/vpo.c index 9c9054f..a4f5226 100644 --- a/sys/dev/ppbus/vpo.c +++ b/sys/dev/ppbus/vpo.c @@ -187,17 +187,19 @@ vpo_intr(struct vpo_data *vpo, struct ccb_scsiio *csio) #ifdef VP0_DEBUG int i; #endif + uint8_t *ptr; + ptr = scsiio_cdb_ptr(csio); if (vpo->vpo_isplus) { errno = imm_do_scsi(&vpo->vpo_io, VP0_INITIATOR, csio->ccb_h.target_id, - (char *)&csio->cdb_io.cdb_bytes, csio->cdb_len, + ptr, csio->cdb_len, (char *)csio->data_ptr, csio->dxfer_len, &vpo->vpo_stat, &vpo->vpo_count, &vpo->vpo_error); } else { errno = vpoio_do_scsi(&vpo->vpo_io, VP0_INITIATOR, csio->ccb_h.target_id, - (char *)&csio->cdb_io.cdb_bytes, csio->cdb_len, + ptr, csio->cdb_len, (char *)csio->data_ptr, csio->dxfer_len, &vpo->vpo_stat, &vpo->vpo_count, &vpo->vpo_error); } @@ -208,7 +210,7 @@ vpo_intr(struct vpo_data *vpo, struct ccb_scsiio *csio) /* dump of command */ for (i=0; i<csio->cdb_len; i++) - printf("%x ", ((char *)&csio->cdb_io.cdb_bytes)[i]); + printf("%x ", ((char *)ptr)[i]); printf("\n"); #endif @@ -307,11 +309,15 @@ vpo_action(struct cam_sim *sim, union ccb *ccb) csio = &ccb->csio; + if (ccb->ccb_h.flags & CAM_CDB_PHYS) { + ccb->ccb_h.status = CAM_REQ_INVALID; + xpt_done(ccb); + break; + } #ifdef VP0_DEBUG device_printf(vpo->vpo_dev, "XPT_SCSI_IO (0x%x) request\n", - csio->cdb_io.cdb_bytes[0]); + scsiio_cdb_ptr(csio)); #endif - vpo_intr(vpo, csio); xpt_done(ccb); diff --git a/sys/dev/qlxgbe/ql_def.h b/sys/dev/qlxgbe/ql_def.h index ecc238c..3ffc94c 100644 --- a/sys/dev/qlxgbe/ql_def.h +++ b/sys/dev/qlxgbe/ql_def.h @@ -112,6 +112,16 @@ typedef struct _qla_tx_ring { uint64_t count; } qla_tx_ring_t; +typedef struct _qla_tx_fp { + struct mtx tx_mtx; + char tx_mtx_name[32]; + struct buf_ring *tx_br; + struct task fp_task; + struct taskqueue *fp_taskqueue; + void *ha; + uint32_t txr_idx; +} qla_tx_fp_t; + /* * Adapter structure contains the hardware independant information of the * pci function. @@ -178,10 +188,9 @@ struct qla_host { qla_tx_ring_t tx_ring[NUM_TX_RINGS]; bus_dma_tag_t tx_tag; - struct task tx_task; - struct taskqueue *tx_tq; struct callout tx_callout; - struct mtx tx_lock; + + qla_tx_fp_t tx_fp[MAX_SDS_RINGS]; qla_rx_ring_t rx_ring[MAX_RDS_RINGS]; bus_dma_tag_t rx_tag; diff --git a/sys/dev/qlxgbe/ql_glbl.h b/sys/dev/qlxgbe/ql_glbl.h index 8f92b0e..beafb41 100644 --- a/sys/dev/qlxgbe/ql_glbl.h +++ b/sys/dev/qlxgbe/ql_glbl.h @@ -39,6 +39,7 @@ */ extern void ql_mbx_isr(void *arg); extern void ql_isr(void *arg); +extern uint32_t ql_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count); /* * from ql_os.c @@ -66,7 +67,7 @@ extern void qla_reset_promisc(qla_host_t *ha); extern int ql_set_allmulti(qla_host_t *ha); extern void qla_reset_allmulti(qla_host_t *ha); extern void ql_update_link_state(qla_host_t *ha); -extern void ql_hw_tx_done(qla_host_t *ha); +extern void ql_hw_tx_done_locked(qla_host_t *ha, uint32_t txr_idx); extern int ql_set_max_mtu(qla_host_t *ha, uint32_t mtu, uint16_t cntxt_id); extern void ql_hw_stop_rcv(qla_host_t *ha); extern void ql_get_stats(qla_host_t *ha); @@ -76,7 +77,7 @@ extern void qla_hw_async_event(qla_host_t *ha); extern int qla_get_nic_partition(qla_host_t *ha, uint32_t *supports_9kb, uint32_t *num_rcvq); -extern int qla_iscsi_pdu(qla_host_t *ha, struct mbuf *mp); +extern int ql_iscsi_pdu(qla_host_t *ha, struct mbuf *mp); extern void ql_minidump(qla_host_t *ha); extern int ql_minidump_init(qla_host_t *ha); diff --git a/sys/dev/qlxgbe/ql_hw.c b/sys/dev/qlxgbe/ql_hw.c index 8c40aba..cc4b042a 100644 --- a/sys/dev/qlxgbe/ql_hw.c +++ b/sys/dev/qlxgbe/ql_hw.c @@ -51,7 +51,6 @@ static void qla_del_rcv_cntxt(qla_host_t *ha); static int qla_init_rcv_cntxt(qla_host_t *ha); static void qla_del_xmt_cntxt(qla_host_t *ha); static int qla_init_xmt_cntxt(qla_host_t *ha); -static void qla_hw_tx_done_locked(qla_host_t *ha, uint32_t txr_idx); static int qla_mbx_cmd(qla_host_t *ha, uint32_t *h_mbox, uint32_t n_hmbox, uint32_t *fw_mbox, uint32_t n_fwmbox, uint32_t no_pause); static int qla_config_intr_cntxt(qla_host_t *ha, uint32_t start_idx, @@ -2047,7 +2046,7 @@ ql_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs, ha->hw.iscsi_pkt_count++; if (hw->tx_cntxt[txr_idx].txr_free <= (num_tx_cmds + QLA_TX_MIN_FREE)) { - qla_hw_tx_done_locked(ha, txr_idx); + ql_hw_tx_done_locked(ha, txr_idx); if (hw->tx_cntxt[txr_idx].txr_free <= (num_tx_cmds + QLA_TX_MIN_FREE)) { QL_DPRINT8(ha, (dev, "%s: (hw->txr_free <= " @@ -2552,15 +2551,8 @@ qla_init_rcv_cntxt(qla_host_t *ha) qla_host_to_le64(hw->dma_buf.sds_ring[i].dma_addr); rcntxt->sds[i].size = qla_host_to_le32(NUM_STATUS_DESCRIPTORS); - if (ha->msix_count == 2) { - rcntxt->sds[i].intr_id = - qla_host_to_le16(hw->intr_id[0]); - rcntxt->sds[i].intr_src_bit = qla_host_to_le16((i)); - } else { - rcntxt->sds[i].intr_id = - qla_host_to_le16(hw->intr_id[i]); - rcntxt->sds[i].intr_src_bit = qla_host_to_le16(0); - } + rcntxt->sds[i].intr_id = qla_host_to_le16(hw->intr_id[i]); + rcntxt->sds[i].intr_src_bit = qla_host_to_le16(0); } for (i = 0; i < rcntxt_rds_rings; i++) { @@ -2672,17 +2664,11 @@ qla_add_rcv_rings(qla_host_t *ha, uint32_t sds_idx, uint32_t nsds) add_rcv->sds[i].size = qla_host_to_le32(NUM_STATUS_DESCRIPTORS); - if (ha->msix_count == 2) { - add_rcv->sds[i].intr_id = - qla_host_to_le16(hw->intr_id[0]); - add_rcv->sds[i].intr_src_bit = qla_host_to_le16(j); - } else { - add_rcv->sds[i].intr_id = - qla_host_to_le16(hw->intr_id[j]); - add_rcv->sds[i].intr_src_bit = qla_host_to_le16(0); - } + add_rcv->sds[i].intr_id = qla_host_to_le16(hw->intr_id[j]); + add_rcv->sds[i].intr_src_bit = qla_host_to_le16(0); } + for (i = 0; (i < nsds); i++) { j = i + sds_idx; @@ -2803,6 +2789,7 @@ qla_init_xmt_cntxt_i(qla_host_t *ha, uint32_t txr_idx) q80_rsp_tx_cntxt_t *tcntxt_rsp; uint32_t err; qla_hw_tx_cntxt_t *hw_tx_cntxt; + uint32_t intr_idx; hw_tx_cntxt = &hw->tx_cntxt[txr_idx]; @@ -2818,6 +2805,8 @@ qla_init_xmt_cntxt_i(qla_host_t *ha, uint32_t txr_idx) tcntxt->count_version = (sizeof (q80_rq_tx_cntxt_t) >> 2); tcntxt->count_version |= Q8_MBX_CMD_VERSION; + intr_idx = txr_idx; + #ifdef QL_ENABLE_ISCSI_TLV tcntxt->cap0 = Q8_TX_CNTXT_CAP0_BASEFW | Q8_TX_CNTXT_CAP0_LSO | @@ -2827,8 +2816,9 @@ qla_init_xmt_cntxt_i(qla_host_t *ha, uint32_t txr_idx) tcntxt->traffic_class = 1; } -#else + intr_idx = txr_idx % (ha->hw.num_tx_rings >> 1); +#else tcntxt->cap0 = Q8_TX_CNTXT_CAP0_BASEFW | Q8_TX_CNTXT_CAP0_LSO; #endif /* #ifdef QL_ENABLE_ISCSI_TLV */ @@ -2841,10 +2831,9 @@ qla_init_xmt_cntxt_i(qla_host_t *ha, uint32_t txr_idx) qla_host_to_le64(hw_tx_cntxt->tx_cons_paddr); tcntxt->tx_ring[0].nentries = qla_host_to_le16(NUM_TX_DESCRIPTORS); - tcntxt->tx_ring[0].intr_id = qla_host_to_le16(hw->intr_id[0]); + tcntxt->tx_ring[0].intr_id = qla_host_to_le16(hw->intr_id[intr_idx]); tcntxt->tx_ring[0].intr_src_bit = qla_host_to_le16(0); - hw_tx_cntxt->txr_free = NUM_TX_DESCRIPTORS; hw_tx_cntxt->txr_next = hw_tx_cntxt->txr_comp = 0; @@ -3166,11 +3155,11 @@ ql_hw_set_multi(qla_host_t *ha, uint8_t *mcast_addr, uint32_t mcnt, } /* - * Name: qla_hw_tx_done_locked + * Name: ql_hw_tx_done_locked * Function: Handle Transmit Completions */ -static void -qla_hw_tx_done_locked(qla_host_t *ha, uint32_t txr_idx) +void +ql_hw_tx_done_locked(qla_host_t *ha, uint32_t txr_idx) { qla_tx_buf_t *txb; qla_hw_t *hw = &ha->hw; @@ -3208,34 +3197,6 @@ qla_hw_tx_done_locked(qla_host_t *ha, uint32_t txr_idx) return; } -/* - * Name: ql_hw_tx_done - * Function: Handle Transmit Completions - */ -void -ql_hw_tx_done(qla_host_t *ha) -{ - int i; - uint32_t flag = 0; - - if (!mtx_trylock(&ha->tx_lock)) { - QL_DPRINT8(ha, (ha->pci_dev, - "%s: !mtx_trylock(&ha->tx_lock)\n", __func__)); - return; - } - for (i = 0; i < ha->hw.num_tx_rings; i++) { - qla_hw_tx_done_locked(ha, i); - if (ha->hw.tx_cntxt[i].txr_free <= (NUM_TX_DESCRIPTORS >> 1)) - flag = 1; - } - - if (!flag) - ha->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - QLA_TX_UNLOCK(ha); - return; -} - void ql_update_link_state(qla_host_t *ha) { @@ -3655,7 +3616,7 @@ qla_get_port_config(qla_host_t *ha, uint32_t *cfg_bits) } int -qla_iscsi_pdu(qla_host_t *ha, struct mbuf *mp) +ql_iscsi_pdu(qla_host_t *ha, struct mbuf *mp) { struct ether_vlan_header *eh; uint16_t etype; diff --git a/sys/dev/qlxgbe/ql_hw.h b/sys/dev/qlxgbe/ql_hw.h index e50bc5e..37090ff 100644 --- a/sys/dev/qlxgbe/ql_hw.h +++ b/sys/dev/qlxgbe/ql_hw.h @@ -1543,7 +1543,6 @@ typedef struct _qla_hw_tx_cntxt { uint32_t tx_prod_reg; uint16_t tx_cntxt_id; - uint8_t frame_hdr[QL_FRAME_HDR_SIZE]; } qla_hw_tx_cntxt_t; diff --git a/sys/dev/qlxgbe/ql_isr.c b/sys/dev/qlxgbe/ql_isr.c index ab7f908..19f2d71 100644 --- a/sys/dev/qlxgbe/ql_isr.c +++ b/sys/dev/qlxgbe/ql_isr.c @@ -159,7 +159,12 @@ qla_rx_intr(qla_host_t *ha, qla_sgl_rcv_t *sgc, uint32_t sds_idx) ifp->if_ipackets++; mpf->m_pkthdr.flowid = sgc->rss_hash; - M_HASHTYPE_SET(mpf, M_HASHTYPE_OPAQUE); + +#if __FreeBSD_version >= 1100000 + M_HASHTYPE_SET(mpf, M_HASHTYPE_OPAQUE_HASH); +#else + M_HASHTYPE_SET(mpf, M_HASHTYPE_NONE); +#endif /* #if __FreeBSD_version >= 1100000 */ (*ifp->if_input)(ifp, mpf); @@ -450,11 +455,11 @@ qla_rcv_cont_sds(qla_host_t *ha, uint32_t sds_idx, uint32_t comp_idx, } /* - * Name: qla_rcv_isr + * Name: ql_rcv_isr * Function: Main Interrupt Service Routine */ -static uint32_t -qla_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count) +uint32_t +ql_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count) { device_t dev; qla_hw_t *hw; @@ -704,7 +709,7 @@ qla_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count) } if (ha->flags.stop_rcv) - goto qla_rcv_isr_exit; + goto ql_rcv_isr_exit; if (hw->sds[sds_idx].sdsr_next != comp_idx) { QL_UPDATE_SDS_CONSUMER_INDEX(ha, sds_idx, comp_idx); @@ -727,7 +732,7 @@ qla_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count) if (opcode) ret = -1; -qla_rcv_isr_exit: +ql_rcv_isr_exit: hw->sds[sds_idx].rcv_active = 0; return (ret); @@ -931,7 +936,7 @@ ql_isr(void *arg) int idx; qla_hw_t *hw; struct ifnet *ifp; - uint32_t ret = 0; + qla_tx_fp_t *fp; ha = ivec->ha; hw = &ha->hw; @@ -940,17 +945,12 @@ ql_isr(void *arg) if ((idx = ivec->sds_idx) >= ha->hw.num_sds_rings) return; - if (idx == 0) - taskqueue_enqueue(ha->tx_tq, &ha->tx_task); - - ret = qla_rcv_isr(ha, idx, -1); - if (idx == 0) - taskqueue_enqueue(ha->tx_tq, &ha->tx_task); + fp = &ha->tx_fp[idx]; + + if (fp->fp_taskqueue != NULL) + taskqueue_enqueue(fp->fp_taskqueue, &fp->fp_task); - if (!ha->flags.stop_rcv) { - QL_ENABLE_INTERRUPTS(ha, idx); - } return; } diff --git a/sys/dev/qlxgbe/ql_os.c b/sys/dev/qlxgbe/ql_os.c index ecccdb81..94ddf7a 100644 --- a/sys/dev/qlxgbe/ql_os.c +++ b/sys/dev/qlxgbe/ql_os.c @@ -76,11 +76,11 @@ static void qla_release(qla_host_t *ha); static void qla_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error); static void qla_stop(qla_host_t *ha); -static int qla_send(qla_host_t *ha, struct mbuf **m_headp); -static void qla_tx_done(void *context, int pending); static void qla_get_peer(qla_host_t *ha); static void qla_error_recovery(void *context, int pending); static void qla_async_event(void *context, int pending); +static int qla_send(qla_host_t *ha, struct mbuf **m_headp, uint32_t txr_idx, + uint32_t iscsi_pdu); /* * Hooks to the Operating Systems @@ -93,7 +93,14 @@ static void qla_init(void *arg); static int qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); static int qla_media_change(struct ifnet *ifp); static void qla_media_status(struct ifnet *ifp, struct ifmediareq *ifmr); -static void qla_start(struct ifnet *ifp); + +static int qla_transmit(struct ifnet *ifp, struct mbuf *mp); +static void qla_qflush(struct ifnet *ifp); +static int qla_alloc_tx_br(qla_host_t *ha, qla_tx_fp_t *tx_fp); +static void qla_free_tx_br(qla_host_t *ha, qla_tx_fp_t *tx_fp); +static int qla_create_fp_taskqueues(qla_host_t *ha); +static void qla_destroy_fp_taskqueues(qla_host_t *ha); +static void qla_drain_fp_taskqueues(qla_host_t *ha); static device_method_t qla_pci_methods[] = { /* Device interface */ @@ -225,7 +232,6 @@ qla_watchdog(void *arg) qla_hw_t *hw; struct ifnet *ifp; uint32_t i; - qla_hw_tx_cntxt_t *hw_tx_cntxt; hw = &ha->hw; ifp = ha->ifp; @@ -254,19 +260,14 @@ qla_watchdog(void *arg) &ha->async_event_task); } - for (i = 0; i < ha->hw.num_tx_rings; i++) { - hw_tx_cntxt = &hw->tx_cntxt[i]; - if (qla_le32_to_host(*(hw_tx_cntxt->tx_cons)) != - hw_tx_cntxt->txr_comp) { - taskqueue_enqueue(ha->tx_tq, - &ha->tx_task); - break; - } - } + for (i = 0; i < ha->hw.num_sds_rings; i++) { + qla_tx_fp_t *fp = &ha->tx_fp[i]; - if ((ifp->if_snd.ifq_head != NULL) && QL_RUNNING(ifp)) { - taskqueue_enqueue(ha->tx_tq, &ha->tx_task); + if (fp->fp_taskqueue != NULL) + taskqueue_enqueue(fp->fp_taskqueue, + &fp->fp_task); } + ha->qla_watchdog_paused = 0; } else { ha->qla_watchdog_paused = 0; @@ -322,9 +323,7 @@ qla_pci_attach(device_t dev) rsrc_len = (uint32_t) bus_get_resource_count(dev, SYS_RES_MEMORY, ha->reg_rid); - mtx_init(&ha->hw_lock, "qla83xx_hw_lock", MTX_NETWORK_LOCK, MTX_SPIN); - - mtx_init(&ha->tx_lock, "qla83xx_tx_lock", MTX_NETWORK_LOCK, MTX_DEF); + mtx_init(&ha->hw_lock, "qla83xx_hw_lock", MTX_NETWORK_LOCK, MTX_DEF); qla_add_sysctls(ha); ql_hw_add_sysctls(ha); @@ -344,8 +343,9 @@ qla_pci_attach(device_t dev) } QL_DPRINT2(ha, (dev, "%s: ha %p pci_func 0x%x rsrc_count 0x%08x" - " msix_count 0x%x pci_reg %p\n", __func__, ha, - ha->pci_func, rsrc_len, ha->msix_count, ha->pci_reg)); + " msix_count 0x%x pci_reg %p pci_reg1 %p\n", __func__, ha, + ha->pci_func, rsrc_len, ha->msix_count, ha->pci_reg, + ha->pci_reg1)); /* initialize hardware */ if (ql_init_hw(ha)) { @@ -366,14 +366,15 @@ qla_pci_attach(device_t dev) goto qla_pci_attach_err; } device_printf(dev, "%s: ha %p pci_func 0x%x rsrc_count 0x%08x" - " msix_count 0x%x pci_reg %p num_rcvq = %d\n", __func__, ha, - ha->pci_func, rsrc_len, ha->msix_count, ha->pci_reg, num_rcvq); + " msix_count 0x%x pci_reg %p pci_reg1 %p num_rcvq = %d\n", + __func__, ha, ha->pci_func, rsrc_len, ha->msix_count, + ha->pci_reg, ha->pci_reg1, num_rcvq); #ifdef QL_ENABLE_ISCSI_TLV if ((ha->msix_count < 64) || (num_rcvq != 32)) { ha->hw.num_sds_rings = 15; - ha->hw.num_tx_rings = 32; + ha->hw.num_tx_rings = ha->hw.num_sds_rings * 2; } #endif /* #ifdef QL_ENABLE_ISCSI_TLV */ ha->hw.num_rds_rings = ha->hw.num_sds_rings; @@ -421,8 +422,20 @@ qla_pci_attach(device_t dev) device_printf(dev, "could not setup interrupt\n"); goto qla_pci_attach_err; } + + ha->tx_fp[i].ha = ha; + ha->tx_fp[i].txr_idx = i; + + if (qla_alloc_tx_br(ha, &ha->tx_fp[i])) { + device_printf(dev, "%s: could not allocate tx_br[%d]\n", + __func__, i); + goto qla_pci_attach_err; + } } + if (qla_create_fp_taskqueues(ha) != 0) + goto qla_pci_attach_err; + printf("%s: mp__ncpus %d sds %d rds %d msi-x %d\n", __func__, mp_ncpus, ha->hw.num_sds_rings, ha->hw.num_rds_rings, ha->msix_count); @@ -452,13 +465,6 @@ qla_pci_attach(device_t dev) ha->flags.qla_watchdog_active = 1; ha->flags.qla_watchdog_pause = 0; - - TASK_INIT(&ha->tx_task, 0, qla_tx_done, ha); - ha->tx_tq = taskqueue_create("qla_txq", M_NOWAIT, - taskqueue_thread_enqueue, &ha->tx_tq); - taskqueue_start_threads(&ha->tx_tq, 1, PI_NET, "%s txq", - device_get_nameunit(ha->pci_dev)); - callout_init(&ha->tx_callout, TRUE); ha->flags.qla_callout_init = 1; @@ -584,11 +590,6 @@ qla_release(qla_host_t *ha) taskqueue_free(ha->err_tq); } - if (ha->tx_tq) { - taskqueue_drain(ha->tx_tq, &ha->tx_task); - taskqueue_free(ha->tx_tq); - } - ql_del_cdev(ha); if (ha->flags.qla_watchdog_active) { @@ -626,13 +627,15 @@ qla_release(qla_host_t *ha) ha->irq_vec[i].irq_rid, ha->irq_vec[i].irq); } + + qla_free_tx_br(ha, &ha->tx_fp[i]); } + qla_destroy_fp_taskqueues(ha); if (ha->msix_count) pci_release_msi(dev); if (ha->flags.lock_init) { - mtx_destroy(&ha->tx_lock); mtx_destroy(&ha->hw_lock); } @@ -812,7 +815,9 @@ qla_init_ifnet(device_t dev, qla_host_t *ha) ifp->if_softc = ha; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = qla_ioctl; - ifp->if_start = qla_start; + + ifp->if_transmit = qla_transmit; + ifp->if_qflush = qla_qflush; IFQ_SET_MAXLEN(&ifp->if_snd, qla_get_ifq_snd_maxlen(ha)); ifp->if_snd.ifq_drv_maxlen = qla_get_ifq_snd_maxlen(ha); @@ -822,12 +827,13 @@ qla_init_ifnet(device_t dev, qla_host_t *ha) ether_ifattach(ifp, qla_get_mac_addr(ha)); - ifp->if_capabilities = IFCAP_HWCSUM | + ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | - IFCAP_JUMBO_MTU; - - ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; - ifp->if_capabilities |= IFCAP_VLAN_HWTSO; + IFCAP_JUMBO_MTU | + IFCAP_VLAN_HWTAGGING | + IFCAP_VLAN_MTU | + IFCAP_VLAN_HWTSO | + IFCAP_LRO; ifp->if_capenable = ifp->if_capabilities; @@ -922,10 +928,13 @@ qla_set_multi(qla_host_t *ha, uint32_t add_multi) if_maddr_runlock(ifp); - if (QLA_LOCK(ha, __func__, 1) == 0) { - ret = ql_hw_set_multi(ha, mta, mcnt, add_multi); - QLA_UNLOCK(ha, __func__); - } + //if (QLA_LOCK(ha, __func__, 1) == 0) { + // ret = ql_hw_set_multi(ha, mta, mcnt, add_multi); + // QLA_UNLOCK(ha, __func__); + //} + QLA_LOCK(ha, __func__, 1); + ret = ql_hw_set_multi(ha, mta, mcnt, add_multi); + QLA_UNLOCK(ha, __func__); return (ret); } @@ -1130,64 +1139,10 @@ qla_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) return; } -static void -qla_start(struct ifnet *ifp) -{ - struct mbuf *m_head; - qla_host_t *ha = (qla_host_t *)ifp->if_softc; - - QL_DPRINT8(ha, (ha->pci_dev, "%s: enter\n", __func__)); - - if (!mtx_trylock(&ha->tx_lock)) { - QL_DPRINT8(ha, (ha->pci_dev, - "%s: mtx_trylock(&ha->tx_lock) failed\n", __func__)); - return; - } - - if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING) { - QL_DPRINT8(ha, - (ha->pci_dev, "%s: !IFF_DRV_RUNNING\n", __func__)); - QLA_TX_UNLOCK(ha); - return; - } - - if (!ha->hw.link_up || !ha->watchdog_ticks) - ql_update_link_state(ha); - - if (!ha->hw.link_up) { - QL_DPRINT8(ha, (ha->pci_dev, "%s: link down\n", __func__)); - QLA_TX_UNLOCK(ha); - return; - } - - while (ifp->if_snd.ifq_head != NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); - - if (m_head == NULL) { - QL_DPRINT8(ha, (ha->pci_dev, "%s: m_head == NULL\n", - __func__)); - break; - } - - if (qla_send(ha, &m_head)) { - if (m_head == NULL) - break; - QL_DPRINT8(ha, (ha->pci_dev, "%s: PREPEND\n", __func__)); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - IF_PREPEND(&ifp->if_snd, m_head); - break; - } - /* Send a copy of the frame to the BPF listener */ - ETHER_BPF_MTAP(ifp, m_head); - } - QLA_TX_UNLOCK(ha); - QL_DPRINT8(ha, (ha->pci_dev, "%s: exit\n", __func__)); - return; -} static int -qla_send(qla_host_t *ha, struct mbuf **m_headp) +qla_send(qla_host_t *ha, struct mbuf **m_headp, uint32_t txr_idx, + uint32_t iscsi_pdu) { bus_dma_segment_t segs[QLA_MAX_SEGMENTS]; bus_dmamap_t map; @@ -1195,29 +1150,9 @@ qla_send(qla_host_t *ha, struct mbuf **m_headp) int ret = -1; uint32_t tx_idx; struct mbuf *m_head = *m_headp; - uint32_t txr_idx = ha->txr_idx; - uint32_t iscsi_pdu = 0; QL_DPRINT8(ha, (ha->pci_dev, "%s: enter\n", __func__)); - /* check if flowid is set */ - - if (M_HASHTYPE_GET(m_head) != M_HASHTYPE_NONE) { -#ifdef QL_ENABLE_ISCSI_TLV - if (qla_iscsi_pdu(ha, m_head) == 0) { - iscsi_pdu = 1; - txr_idx = m_head->m_pkthdr.flowid & - ((ha->hw.num_tx_rings >> 1) - 1); - } else { - txr_idx = m_head->m_pkthdr.flowid & - (ha->hw.num_tx_rings - 1); - } -#else - txr_idx = m_head->m_pkthdr.flowid & (ha->hw.num_tx_rings - 1); -#endif /* #ifdef QL_ENABLE_ISCSI_TLV */ - } - - tx_idx = ha->hw.tx_cntxt[txr_idx].txr_next; map = ha->tx_ring[txr_idx].tx_buf[tx_idx].map; @@ -1295,16 +1230,302 @@ qla_send(qla_host_t *ha, struct mbuf **m_headp) return (ret); } +static int +qla_alloc_tx_br(qla_host_t *ha, qla_tx_fp_t *fp) +{ + snprintf(fp->tx_mtx_name, sizeof(fp->tx_mtx_name), + "qla%d_fp%d_tx_mq_lock", ha->pci_func, fp->txr_idx); + + mtx_init(&fp->tx_mtx, fp->tx_mtx_name, NULL, MTX_DEF); + + fp->tx_br = buf_ring_alloc(NUM_TX_DESCRIPTORS, M_DEVBUF, + M_NOWAIT, &fp->tx_mtx); + if (fp->tx_br == NULL) { + QL_DPRINT1(ha, (ha->pci_dev, "buf_ring_alloc failed for " + " fp[%d, %d]\n", ha->pci_func, fp->txr_idx)); + return (-ENOMEM); + } + return 0; +} + +static void +qla_free_tx_br(qla_host_t *ha, qla_tx_fp_t *fp) +{ + struct mbuf *mp; + struct ifnet *ifp = ha->ifp; + + if (mtx_initialized(&fp->tx_mtx)) { + + if (fp->tx_br != NULL) { + + mtx_lock(&fp->tx_mtx); + + while ((mp = drbr_dequeue(ifp, fp->tx_br)) != NULL) { + m_freem(mp); + } + + mtx_unlock(&fp->tx_mtx); + + buf_ring_free(fp->tx_br, M_DEVBUF); + fp->tx_br = NULL; + } + mtx_destroy(&fp->tx_mtx); + } + return; +} + +static void +qla_fp_taskqueue(void *context, int pending) +{ + qla_tx_fp_t *fp; + qla_host_t *ha; + struct ifnet *ifp; + struct mbuf *mp; + int ret; + uint32_t txr_idx; + uint32_t iscsi_pdu = 0; + uint32_t rx_pkts_left; + + fp = context; + + if (fp == NULL) + return; + + ha = (qla_host_t *)fp->ha; + + ifp = ha->ifp; + + txr_idx = fp->txr_idx; + + mtx_lock(&fp->tx_mtx); + + if (((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING) || (!ha->hw.link_up)) { + mtx_unlock(&fp->tx_mtx); + goto qla_fp_taskqueue_exit; + } + + rx_pkts_left = ql_rcv_isr(ha, fp->txr_idx, 64); + +#ifdef QL_ENABLE_ISCSI_TLV + ql_hw_tx_done_locked(ha, fp->txr_idx); + ql_hw_tx_done_locked(ha, (fp->txr_idx + (ha->hw.num_tx_rings >> 1))); + txr_idx = txr_idx + (ha->hw.num_tx_rings >> 1); +#else + ql_hw_tx_done_locked(ha, fp->txr_idx); +#endif /* #ifdef QL_ENABLE_ISCSI_TLV */ + + mp = drbr_peek(ifp, fp->tx_br); + + while (mp != NULL) { + + if (M_HASHTYPE_GET(mp) != M_HASHTYPE_NONE) { +#ifdef QL_ENABLE_ISCSI_TLV + if (ql_iscsi_pdu(ha, mp) == 0) { + iscsi_pdu = 1; + } +#endif /* #ifdef QL_ENABLE_ISCSI_TLV */ + } + + ret = qla_send(ha, &mp, txr_idx, iscsi_pdu); + + if (ret) { + if (mp != NULL) + drbr_putback(ifp, fp->tx_br, mp); + else { + drbr_advance(ifp, fp->tx_br); + } + + mtx_unlock(&fp->tx_mtx); + + goto qla_fp_taskqueue_exit0; + } else { + drbr_advance(ifp, fp->tx_br); + } + + mp = drbr_peek(ifp, fp->tx_br); + } + + mtx_unlock(&fp->tx_mtx); + +qla_fp_taskqueue_exit0: + + if (rx_pkts_left || ((mp != NULL) && ret)) { + taskqueue_enqueue(fp->fp_taskqueue, &fp->fp_task); + } else { + if (!ha->flags.stop_rcv) { + QL_ENABLE_INTERRUPTS(ha, fp->txr_idx); + } + } + +qla_fp_taskqueue_exit: + + QL_DPRINT2(ha, (ha->pci_dev, "%s: exit ret = %d\n", __func__, ret)); + return; +} + +static int +qla_create_fp_taskqueues(qla_host_t *ha) +{ + int i; + uint8_t tq_name[32]; + + for (i = 0; i < ha->hw.num_sds_rings; i++) { + + qla_tx_fp_t *fp = &ha->tx_fp[i]; + + bzero(tq_name, sizeof (tq_name)); + snprintf(tq_name, sizeof (tq_name), "ql_fp_tq_%d", i); + + TASK_INIT(&fp->fp_task, 0, qla_fp_taskqueue, fp); + + fp->fp_taskqueue = taskqueue_create_fast(tq_name, M_NOWAIT, + taskqueue_thread_enqueue, + &fp->fp_taskqueue); + + if (fp->fp_taskqueue == NULL) + return (-1); + + taskqueue_start_threads(&fp->fp_taskqueue, 1, PI_NET, "%s", + tq_name); + + QL_DPRINT1(ha, (ha->pci_dev, "%s: %p\n", __func__, + fp->fp_taskqueue)); + } + + return (0); +} + +static void +qla_destroy_fp_taskqueues(qla_host_t *ha) +{ + int i; + + for (i = 0; i < ha->hw.num_sds_rings; i++) { + + qla_tx_fp_t *fp = &ha->tx_fp[i]; + + if (fp->fp_taskqueue != NULL) { + taskqueue_drain(fp->fp_taskqueue, &fp->fp_task); + taskqueue_free(fp->fp_taskqueue); + fp->fp_taskqueue = NULL; + } + } + return; +} + +static void +qla_drain_fp_taskqueues(qla_host_t *ha) +{ + int i; + + for (i = 0; i < ha->hw.num_sds_rings; i++) { + qla_tx_fp_t *fp = &ha->tx_fp[i]; + + if (fp->fp_taskqueue != NULL) { + taskqueue_drain(fp->fp_taskqueue, &fp->fp_task); + } + } + return; +} + +static int +qla_transmit(struct ifnet *ifp, struct mbuf *mp) +{ + qla_host_t *ha = (qla_host_t *)ifp->if_softc; + qla_tx_fp_t *fp; + int rss_id = 0; + int ret = 0; + + QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__)); + +#if __FreeBSD_version >= 1100000 + if (M_HASHTYPE_GET(mp) != M_HASHTYPE_NONE) +#else + if (mp->m_flags & M_FLOWID) +#endif + rss_id = (mp->m_pkthdr.flowid & Q8_RSS_IND_TBL_MAX_IDX) % + ha->hw.num_sds_rings; + fp = &ha->tx_fp[rss_id]; + + if (fp->tx_br == NULL) { + ret = EINVAL; + goto qla_transmit_exit; + } + + if (mp != NULL) { + ret = drbr_enqueue(ifp, fp->tx_br, mp); + } + + if (fp->fp_taskqueue != NULL) + taskqueue_enqueue(fp->fp_taskqueue, &fp->fp_task); + + ret = 0; + +qla_transmit_exit: + + QL_DPRINT2(ha, (ha->pci_dev, "%s: exit ret = %d\n", __func__, ret)); + return ret; +} + +static void +qla_qflush(struct ifnet *ifp) +{ + int i; + qla_tx_fp_t *fp; + struct mbuf *mp; + qla_host_t *ha; + + ha = (qla_host_t *)ifp->if_softc; + + QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__)); + + for (i = 0; i < ha->hw.num_sds_rings; i++) { + + fp = &ha->tx_fp[i]; + + if (fp == NULL) + continue; + + if (fp->tx_br) { + mtx_lock(&fp->tx_mtx); + + while ((mp = drbr_dequeue(ifp, fp->tx_br)) != NULL) { + m_freem(mp); + } + mtx_unlock(&fp->tx_mtx); + } + } + QL_DPRINT2(ha, (ha->pci_dev, "%s: exit\n", __func__)); + + return; +} + + static void qla_stop(qla_host_t *ha) { struct ifnet *ifp = ha->ifp; device_t dev; + int i = 0; dev = ha->pci_dev; ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); - QLA_TX_LOCK(ha); QLA_TX_UNLOCK(ha); + + for (i = 0; i < ha->hw.num_sds_rings; i++) { + qla_tx_fp_t *fp; + + fp = &ha->tx_fp[i]; + + if (fp == NULL) + continue; + + if (fp->tx_br != NULL) { + mtx_lock(&fp->tx_mtx); + mtx_unlock(&fp->tx_mtx); + } + } ha->flags.qla_watchdog_pause = 1; @@ -1313,6 +1534,8 @@ qla_stop(qla_host_t *ha) ha->flags.qla_interface_up = 0; + qla_drain_fp_taskqueues(ha); + ql_hw_stop_rcv(ha); ql_del_hw_if(ha); @@ -1653,25 +1876,6 @@ exit_ql_get_mbuf: return (ret); } -static void -qla_tx_done(void *context, int pending) -{ - qla_host_t *ha = context; - struct ifnet *ifp; - - ifp = ha->ifp; - - if (!ifp) - return; - - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - QL_DPRINT8(ha, (ha->pci_dev, "%s: !IFF_DRV_RUNNING\n", __func__)); - return; - } - ql_hw_tx_done(ha); - - qla_start(ha->ifp); -} static void qla_get_peer(qla_host_t *ha) @@ -1714,18 +1918,32 @@ qla_error_recovery(void *context, int pending) qla_host_t *ha = context; uint32_t msecs_100 = 100; struct ifnet *ifp = ha->ifp; + int i = 0; (void)QLA_LOCK(ha, __func__, 0); if (ha->flags.qla_interface_up) { - ha->hw.imd_compl = 1; - qla_mdelay(__func__, 300); + ha->hw.imd_compl = 1; + qla_mdelay(__func__, 300); - ql_hw_stop_rcv(ha); + ql_hw_stop_rcv(ha); - ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); - QLA_TX_LOCK(ha); QLA_TX_UNLOCK(ha); + ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); + + for (i = 0; i < ha->hw.num_sds_rings; i++) { + qla_tx_fp_t *fp; + + fp = &ha->tx_fp[i]; + + if (fp == NULL) + continue; + + if (fp->tx_br != NULL) { + mtx_lock(&fp->tx_mtx); + mtx_unlock(&fp->tx_mtx); + } + } } QLA_UNLOCK(ha, __func__); diff --git a/sys/dev/qlxgbe/ql_os.h b/sys/dev/qlxgbe/ql_os.h index 3ba6c3f..db71772 100644 --- a/sys/dev/qlxgbe/ql_os.h +++ b/sys/dev/qlxgbe/ql_os.h @@ -147,8 +147,8 @@ MALLOC_DECLARE(M_QLA83XXBUF); /* * Locks */ -#define QLA_LOCK(ha, str, no_delay) qla_lock(ha, str, no_delay) -#define QLA_UNLOCK(ha, str) qla_unlock(ha, str) +#define QLA_LOCK(ha, str, no_delay) mtx_lock(&ha->hw_lock) +#define QLA_UNLOCK(ha, str) mtx_unlock(&ha->hw_lock) #define QLA_TX_LOCK(ha) mtx_lock(&ha->tx_lock); #define QLA_TX_UNLOCK(ha) mtx_unlock(&ha->tx_lock); diff --git a/sys/dev/qlxgbe/ql_ver.h b/sys/dev/qlxgbe/ql_ver.h index 182fa32..90d61d2 100644 --- a/sys/dev/qlxgbe/ql_ver.h +++ b/sys/dev/qlxgbe/ql_ver.h @@ -36,6 +36,6 @@ #define QLA_VERSION_MAJOR 3 #define QLA_VERSION_MINOR 10 -#define QLA_VERSION_BUILD 31 +#define QLA_VERSION_BUILD 33 #endif /* #ifndef _QL_VER_H_ */ diff --git a/sys/dev/rl/if_rl.c b/sys/dev/rl/if_rl.c index 2ff1310..2f877c9 100644 --- a/sys/dev/rl/if_rl.c +++ b/sys/dev/rl/if_rl.c @@ -1938,15 +1938,13 @@ rl_stop(struct rl_softc *sc) */ for (i = 0; i < RL_TX_LIST_CNT; i++) { if (sc->rl_cdata.rl_tx_chain[i] != NULL) { - if (sc->rl_cdata.rl_tx_chain[i] != NULL) { - bus_dmamap_sync(sc->rl_cdata.rl_tx_tag, - sc->rl_cdata.rl_tx_dmamap[i], - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->rl_cdata.rl_tx_tag, - sc->rl_cdata.rl_tx_dmamap[i]); - m_freem(sc->rl_cdata.rl_tx_chain[i]); - sc->rl_cdata.rl_tx_chain[i] = NULL; - } + bus_dmamap_sync(sc->rl_cdata.rl_tx_tag, + sc->rl_cdata.rl_tx_dmamap[i], + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->rl_cdata.rl_tx_tag, + sc->rl_cdata.rl_tx_dmamap[i]); + m_freem(sc->rl_cdata.rl_tx_chain[i]); + sc->rl_cdata.rl_tx_chain[i] = NULL; CSR_WRITE_4(sc, RL_TXADDR0 + (i * sizeof(uint32_t)), 0x0000000); } diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c index 47d6340..d1b0ecf 100644 --- a/sys/dev/sdhci/sdhci.c +++ b/sys/dev/sdhci/sdhci.c @@ -74,6 +74,7 @@ static void sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock); static void sdhci_start(struct sdhci_slot *slot); static void sdhci_start_data(struct sdhci_slot *slot, struct mmc_data *data); +static void sdhci_card_poll(void *); static void sdhci_card_task(void *, int); /* helper routines */ @@ -90,6 +91,22 @@ static void sdhci_card_task(void *, int); #define SDHCI_200_MAX_DIVIDER 256 #define SDHCI_300_MAX_DIVIDER 2046 +#define SDHCI_CARD_PRESENT_TICKS (hz / 5) +#define SDHCI_INSERT_DELAY_TICKS (hz / 2) + +/* + * Broadcom BCM577xx Controller Constants + */ +#define BCM577XX_DEFAULT_MAX_DIVIDER 256 /* Maximum divider supported by the default clock source. */ +#define BCM577XX_ALT_CLOCK_BASE 63000000 /* Alternative clock's base frequency. */ + +#define BCM577XX_HOST_CONTROL 0x198 +#define BCM577XX_CTRL_CLKSEL_MASK 0xFFFFCFFF +#define BCM577XX_CTRL_CLKSEL_SHIFT 12 +#define BCM577XX_CTRL_CLKSEL_DEFAULT 0x0 +#define BCM577XX_CTRL_CLKSEL_64MHZ 0x3 + + static void sdhci_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) { @@ -152,8 +169,7 @@ sdhci_reset(struct sdhci_slot *slot, uint8_t mask) int timeout; if (slot->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { - if (!(RD4(slot, SDHCI_PRESENT_STATE) & - SDHCI_CARD_PRESENT)) + if (!SDHCI_GET_CARD_PRESENT(slot->bus, slot)) return; } @@ -218,10 +234,15 @@ sdhci_init(struct sdhci_slot *slot) slot->intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | - SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT | SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE | SDHCI_INT_ACMD12ERR; + + if (!(slot->quirks & SDHCI_QUIRK_POLL_CARD_PRESENT) && + !(slot->opt & SDHCI_NON_REMOVABLE)) { + slot->intmask |= SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT; + } + WR4(slot, SDHCI_INT_ENABLE, slot->intmask); WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask); } @@ -229,6 +250,8 @@ sdhci_init(struct sdhci_slot *slot) static void sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock) { + uint32_t clk_base; + uint32_t clk_sel; uint32_t res; uint16_t clk; uint16_t div; @@ -244,6 +267,22 @@ sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock) /* If no clock requested - left it so. */ if (clock == 0) return; + + /* Determine the clock base frequency */ + clk_base = slot->max_clk; + if (slot->quirks & SDHCI_QUIRK_BCM577XX_400KHZ_CLKSRC) { + clk_sel = RD2(slot, BCM577XX_HOST_CONTROL) & BCM577XX_CTRL_CLKSEL_MASK; + + /* Select clock source appropriate for the requested frequency. */ + if ((clk_base / BCM577XX_DEFAULT_MAX_DIVIDER) > clock) { + clk_base = BCM577XX_ALT_CLOCK_BASE; + clk_sel |= (BCM577XX_CTRL_CLKSEL_64MHZ << BCM577XX_CTRL_CLKSEL_SHIFT); + } else { + clk_sel |= (BCM577XX_CTRL_CLKSEL_DEFAULT << BCM577XX_CTRL_CLKSEL_SHIFT); + } + + WR2(slot, BCM577XX_HOST_CONTROL, clk_sel); + } /* Recalculate timeout clock frequency based on the new sd clock. */ if (slot->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK) @@ -251,7 +290,7 @@ sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock) if (slot->version < SDHCI_SPEC_300) { /* Looking for highest freq <= clock. */ - res = slot->max_clk; + res = clk_base; for (div = 1; div < SDHCI_200_MAX_DIVIDER; div <<= 1) { if (res <= clock) break; @@ -262,11 +301,11 @@ sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock) } else { /* Version 3.0 divisors are multiples of two up to 1023*2 */ - if (clock >= slot->max_clk) + if (clock >= clk_base) div = 0; else { for (div = 2; div < SDHCI_300_MAX_DIVIDER; div += 2) { - if ((slot->max_clk / div) <= clock) + if ((clk_base / div) <= clock) break; } } @@ -274,8 +313,8 @@ sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock) } if (bootverbose || sdhci_debug) - slot_printf(slot, "Divider %d for freq %d (max %d)\n", - div, clock, slot->max_clk); + slot_printf(slot, "Divider %d for freq %d (base %d)\n", + div, clock, clk_base); /* Now we have got divider, set it. */ clk = (div & SDHCI_DIVIDER_MASK) << SDHCI_DIVIDER_SHIFT; @@ -338,6 +377,13 @@ sdhci_set_power(struct sdhci_slot *slot, u_char power) /* Turn on the power. */ pwr |= SDHCI_POWER_ON; WR1(slot, SDHCI_POWER_CONTROL, pwr); + + if (slot->quirks & SDHCI_QUIRK_INTEL_POWER_UP_RESET) { + WR1(slot, SDHCI_POWER_CONTROL, pwr | 0x10); + DELAY(10); + WR1(slot, SDHCI_POWER_CONTROL, pwr); + DELAY(300); + } } static void @@ -445,23 +491,17 @@ sdhci_transfer_pio(struct sdhci_slot *slot) } } -static void -sdhci_card_delay(void *arg) -{ - struct sdhci_slot *slot = arg; - - taskqueue_enqueue(taskqueue_swi_giant, &slot->card_task); -} - static void sdhci_card_task(void *arg, int pending) { struct sdhci_slot *slot = arg; SDHCI_LOCK(slot); - if (RD4(slot, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT) { + if (SDHCI_GET_CARD_PRESENT(slot->bus, slot)) { if (slot->dev == NULL) { /* If card is present - attach mmc bus. */ + if (bootverbose || sdhci_debug) + slot_printf(slot, "Card inserted\n"); slot->dev = device_add_child(slot->bus, "mmc", -1); device_set_ivars(slot->dev, slot); SDHCI_UNLOCK(slot); @@ -471,6 +511,8 @@ sdhci_card_task(void *arg, int pending) } else { if (slot->dev != NULL) { /* If no card present - detach mmc bus. */ + if (bootverbose || sdhci_debug) + slot_printf(slot, "Card removed\n"); device_t d = slot->dev; slot->dev = NULL; SDHCI_UNLOCK(slot); @@ -480,6 +522,51 @@ sdhci_card_task(void *arg, int pending) } } +static void +sdhci_handle_card_present_locked(struct sdhci_slot *slot, bool is_present) +{ + bool was_present; + + /* + * If there was no card and now there is one, schedule the task to + * create the child device after a short delay. The delay is to + * debounce the card insert (sometimes the card detect pin stabilizes + * before the other pins have made good contact). + * + * If there was a card present and now it's gone, immediately schedule + * the task to delete the child device. No debouncing -- gone is gone, + * because once power is removed, a full card re-init is needed, and + * that happens by deleting and recreating the child device. + */ + was_present = slot->dev != NULL; + if (!was_present && is_present) { + taskqueue_enqueue_timeout(taskqueue_swi_giant, + &slot->card_delayed_task, -SDHCI_INSERT_DELAY_TICKS); + } else if (was_present && !is_present) { + taskqueue_enqueue(taskqueue_swi_giant, &slot->card_task); + } +} + +void +sdhci_handle_card_present(struct sdhci_slot *slot, bool is_present) +{ + + SDHCI_LOCK(slot); + sdhci_handle_card_present_locked(slot, is_present); + SDHCI_UNLOCK(slot); +} + +static void +sdhci_card_poll(void *arg) +{ + struct sdhci_slot *slot = arg; + + sdhci_handle_card_present(slot, + SDHCI_GET_CARD_PRESENT(slot->bus, slot)); + callout_reset(&slot->card_poll_callout, SDHCI_CARD_PRESENT_TICKS, + sdhci_card_poll, slot); +} + int sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) { @@ -550,9 +637,11 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) device_printf(dev, "Hardware doesn't specify base clock " "frequency, using %dMHz as default.\n", SDHCI_DEFAULT_MAX_FREQ); } - /* Calculate timeout clock frequency. */ + /* Calculate/set timeout clock frequency. */ if (slot->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK) { slot->timeout_clk = slot->max_clk / 1000; + } else if (slot->quirks & SDHCI_QUIRK_DATA_TIMEOUT_1MHZ) { + slot->timeout_clk = 1000; } else { slot->timeout_clk = (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; @@ -596,6 +685,8 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) slot->opt &= ~SDHCI_HAVE_DMA; if (slot->quirks & SDHCI_QUIRK_FORCE_DMA) slot->opt |= SDHCI_HAVE_DMA; + if (slot->quirks & SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE) + slot->opt |= SDHCI_NON_REMOVABLE; /* * Use platform-provided transfer backend @@ -608,18 +699,33 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) slot_printf(slot, "%uMHz%s %s%s%s%s %s\n", slot->max_clk / 1000000, (caps & SDHCI_CAN_DO_HISPD) ? " HS" : "", - (caps & MMC_CAP_8_BIT_DATA) ? "8bits" : - ((caps & MMC_CAP_4_BIT_DATA) ? "4bits" : "1bit"), + (slot->host.caps & MMC_CAP_8_BIT_DATA) ? "8bits" : + ((slot->host.caps & MMC_CAP_4_BIT_DATA) ? "4bits" : + "1bit"), (caps & SDHCI_CAN_VDD_330) ? " 3.3V" : "", (caps & SDHCI_CAN_VDD_300) ? " 3.0V" : "", (caps & SDHCI_CAN_VDD_180) ? " 1.8V" : "", (slot->opt & SDHCI_HAVE_DMA) ? "DMA" : "PIO"); sdhci_dumpregs(slot); } - + + slot->timeout = 10; + SYSCTL_ADD_INT(device_get_sysctl_ctx(slot->bus), + SYSCTL_CHILDREN(device_get_sysctl_tree(slot->bus)), OID_AUTO, + "timeout", CTLFLAG_RW, &slot->timeout, 0, + "Maximum timeout for SDHCI transfers (in secs)"); TASK_INIT(&slot->card_task, 0, sdhci_card_task, slot); - callout_init(&slot->card_callout, 1); + TIMEOUT_TASK_INIT(taskqueue_swi_giant, &slot->card_delayed_task, 0, + sdhci_card_task, slot); + callout_init(&slot->card_poll_callout, 1); callout_init_mtx(&slot->timeout_callout, &slot->mtx, 0); + + if ((slot->quirks & SDHCI_QUIRK_POLL_CARD_PRESENT) && + !(slot->opt & SDHCI_NON_REMOVABLE)) { + callout_reset(&slot->card_poll_callout, + SDHCI_CARD_PRESENT_TICKS, sdhci_card_poll, slot); + } + return (0); } @@ -635,8 +741,9 @@ sdhci_cleanup_slot(struct sdhci_slot *slot) device_t d; callout_drain(&slot->timeout_callout); - callout_drain(&slot->card_callout); + callout_drain(&slot->card_poll_callout); taskqueue_drain(taskqueue_swi_giant, &slot->card_task); + taskqueue_drain_timeout(taskqueue_swi_giant, &slot->card_delayed_task); SDHCI_LOCK(slot); d = slot->dev; @@ -682,6 +789,16 @@ sdhci_generic_min_freq(device_t brdev, struct sdhci_slot *slot) return (slot->max_clk / SDHCI_200_MAX_DIVIDER); } +bool +sdhci_generic_get_card_present(device_t brdev, struct sdhci_slot *slot) +{ + + if (slot->opt & SDHCI_NON_REMOVABLE) + return true; + + return (RD4(slot, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT); +} + int sdhci_generic_update_ios(device_t brdev, device_t reqdev) { @@ -779,7 +896,7 @@ static void sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd) { int flags, timeout; - uint32_t mask, state; + uint32_t mask; slot->curcmd = cmd; slot->cmd_done = 0; @@ -794,11 +911,9 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd) return; } - /* Read controller present state. */ - state = RD4(slot, SDHCI_PRESENT_STATE); /* Do not issue command if there is no card, clock or power. * Controller will not detect timeout without clock active. */ - if ((state & SDHCI_CARD_PRESENT) == 0 || + if (!SDHCI_GET_CARD_PRESENT(slot->bus, slot) || slot->power == 0 || slot->clock == 0) { cmd->error = MMC_ERR_FAILED; @@ -824,7 +939,7 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd) * (It's usually more like 20-30ms in the real world.) */ timeout = 250; - while (state & mask) { + while (mask & RD4(slot, SDHCI_PRESENT_STATE)) { if (timeout == 0) { slot_printf(slot, "Controller never released " "inhibit bit(s).\n"); @@ -835,7 +950,6 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd) } timeout--; DELAY(1000); - state = RD4(slot, SDHCI_PRESENT_STATE); } /* Prepare command flags. */ @@ -873,7 +987,8 @@ sdhci_start_command(struct sdhci_slot *slot, struct mmc_command *cmd) /* Start command. */ WR2(slot, SDHCI_COMMAND_FLAGS, (cmd->opcode << 8) | (flags & 0xff)); /* Start timeout callout. */ - callout_reset(&slot->timeout_callout, 2*hz, sdhci_timeout, slot); + callout_reset(&slot->timeout_callout, slot->timeout * hz, + sdhci_timeout, slot); } static void @@ -1272,7 +1387,7 @@ sdhci_acmd_irq(struct sdhci_slot *slot) void sdhci_generic_intr(struct sdhci_slot *slot) { - uint32_t intmask; + uint32_t intmask, present; SDHCI_LOCK(slot); /* Read slot interrupt status. */ @@ -1286,22 +1401,16 @@ sdhci_generic_intr(struct sdhci_slot *slot) /* Handle card presence interrupts. */ if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { + present = (intmask & SDHCI_INT_CARD_INSERT) != 0; + slot->intmask &= + ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE); + slot->intmask |= present ? SDHCI_INT_CARD_REMOVE : + SDHCI_INT_CARD_INSERT; + WR4(slot, SDHCI_INT_ENABLE, slot->intmask); + WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask); WR4(slot, SDHCI_INT_STATUS, intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)); - - if (intmask & SDHCI_INT_CARD_REMOVE) { - if (bootverbose || sdhci_debug) - slot_printf(slot, "Card removed\n"); - callout_stop(&slot->card_callout); - taskqueue_enqueue(taskqueue_swi_giant, - &slot->card_task); - } - if (intmask & SDHCI_INT_CARD_INSERT) { - if (bootverbose || sdhci_debug) - slot_printf(slot, "Card inserted\n"); - callout_reset(&slot->card_callout, hz / 2, - sdhci_card_delay, slot); - } + sdhci_handle_card_present_locked(slot, present); intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE); } /* Handle command interrupts. */ diff --git a/sys/dev/sdhci/sdhci.h b/sys/dev/sdhci/sdhci.h index b7d1960..4626816 100644 --- a/sys/dev/sdhci/sdhci.h +++ b/sys/dev/sdhci/sdhci.h @@ -63,6 +63,16 @@ #define SDHCI_QUIRK_WAITFOR_RESET_ASSERTED (1<<14) /* Leave controller in standard mode when putting card in HS mode. */ #define SDHCI_QUIRK_DONT_SET_HISPD_BIT (1<<15) +/* Alternate clock source is required when supplying a 400 KHz clock. */ +#define SDHCI_QUIRK_BCM577XX_400KHZ_CLKSRC (1<<16) +/* Card insert/remove interrupts don't work, polling required. */ +#define SDHCI_QUIRK_POLL_CARD_PRESENT (1<<17) +/* All controller slots are non-removable. */ +#define SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE (1<<18) +/* Issue custom Intel controller reset sequence after power-up. */ +#define SDHCI_QUIRK_INTEL_POWER_UP_RESET (1<<19) +/* Data timeout is invalid, use 1 MHz clock instead. */ +#define SDHCI_QUIRK_DATA_TIMEOUT_1MHZ (1<<20) /* * Controller registers @@ -151,6 +161,9 @@ #define SDHCI_CLOCK_CARD_EN 0x0004 #define SDHCI_CLOCK_INT_STABLE 0x0002 #define SDHCI_CLOCK_INT_EN 0x0001 +#define SDHCI_DIVIDERS_MASK \ + ((SDHCI_DIVIDER_MASK << SDHCI_DIVIDER_SHIFT) | \ + (SDHCI_DIVIDER_HI_MASK << SDHCI_DIVIDER_HI_SHIFT)) #define SDHCI_TIMEOUT_CONTROL 0x2E @@ -268,9 +281,11 @@ struct sdhci_slot { device_t dev; /* Slot device */ u_char num; /* Slot number */ u_char opt; /* Slot options */ -#define SDHCI_HAVE_DMA 1 -#define SDHCI_PLATFORM_TRANSFER 2 +#define SDHCI_HAVE_DMA 0x01 +#define SDHCI_PLATFORM_TRANSFER 0x02 +#define SDHCI_NON_REMOVABLE 0x04 u_char version; + int timeout; /* Transfer timeout */ uint32_t max_clk; /* Max possible freq */ uint32_t timeout_clk; /* Timeout freq */ bus_dma_tag_t dmatag; @@ -278,7 +293,9 @@ struct sdhci_slot { u_char *dmamem; bus_addr_t paddr; /* DMA buffer address */ struct task card_task; /* Card presence check task */ - struct callout card_callout; /* Card insert delay callout */ + struct timeout_task + card_delayed_task;/* Card insert delayed task */ + struct callout card_poll_callout;/* Card present polling callout */ struct callout timeout_callout;/* Card command/data response timeout */ struct mmc_host host; /* Host parameters */ struct mmc_request *req; /* Current request */ @@ -316,5 +333,7 @@ int sdhci_generic_acquire_host(device_t brdev, device_t reqdev); int sdhci_generic_release_host(device_t brdev, device_t reqdev); void sdhci_generic_intr(struct sdhci_slot *slot); uint32_t sdhci_generic_min_freq(device_t brdev, struct sdhci_slot *slot); +bool sdhci_generic_get_card_present(device_t brdev, struct sdhci_slot *slot); +void sdhci_handle_card_present(struct sdhci_slot *slot, bool is_present); #endif /* __SDHCI_H__ */ diff --git a/sys/dev/sdhci/sdhci_if.m b/sys/dev/sdhci/sdhci_if.m index b33cdcf..da02d31 100644 --- a/sys/dev/sdhci/sdhci_if.m +++ b/sys/dev/sdhci/sdhci_if.m @@ -152,3 +152,9 @@ METHOD uint32_t min_freq { device_t brdev; struct sdhci_slot *slot; } DEFAULT sdhci_generic_min_freq; + +METHOD bool get_card_present { + device_t brdev; + struct sdhci_slot *slot; +} DEFAULT sdhci_generic_get_card_present; + diff --git a/sys/dev/sdhci/sdhci_pci.c b/sys/dev/sdhci/sdhci_pci.c index b13a0c9..d8e8897 100644 --- a/sys/dev/sdhci/sdhci_pci.c +++ b/sys/dev/sdhci/sdhci_pci.c @@ -63,15 +63,15 @@ __FBSDID("$FreeBSD$"); #define PCI_SDHCI_IFVENDOR 0x02 #define PCI_SLOT_INFO 0x40 /* 8 bits */ -#define PCI_SLOT_INFO_SLOTS(x) (((x >> 4) & 7) + 1) -#define PCI_SLOT_INFO_FIRST_BAR(x) ((x) & 7) +#define PCI_SLOT_INFO_SLOTS(x) (((x >> 4) & 7) + 1) +#define PCI_SLOT_INFO_FIRST_BAR(x) ((x) & 7) /* * RICOH specific PCI registers */ #define SDHC_PCI_MODE_KEY 0xf9 #define SDHC_PCI_MODE 0x150 -#define SDHC_PCI_MODE_SD20 0x10 +#define SDHC_PCI_MODE_SD20 0x10 #define SDHC_PCI_BASE_FREQ_KEY 0xfc #define SDHC_PCI_BASE_FREQ 0xe1 @@ -105,6 +105,21 @@ static const struct sdhci_device { { 0x2381197B, 0xffff, "JMicron JMB38X SD", SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_RESET_AFTER_REQUEST }, + { 0x16bc14e4, 0xffff, "Broadcom BCM577xx SDXC/MMC Card Reader", + SDHCI_QUIRK_BCM577XX_400KHZ_CLKSRC }, + { 0x0f148086, 0xffff, "Intel Bay Trail eMMC 4.5 Controller", + SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE | + SDHCI_QUIRK_INTEL_POWER_UP_RESET }, + { 0x0f508086, 0xffff, "Intel Bay Trail eMMC 4.5 Controller", + SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE | + SDHCI_QUIRK_INTEL_POWER_UP_RESET }, + { 0x22948086, 0xffff, "Intel Braswell eMMC 4.5.1 Controller", + SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE | + SDHCI_QUIRK_DATA_TIMEOUT_1MHZ | + SDHCI_QUIRK_INTEL_POWER_UP_RESET }, + { 0x5acc8086, 0xffff, "Intel Apollo Lake eMMC 5.0 Controller", + SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE | + SDHCI_QUIRK_INTEL_POWER_UP_RESET }, { 0, 0xffff, NULL, 0 } }; @@ -117,8 +132,8 @@ struct sdhci_pci_softc { int num_slots; /* Number of slots on this controller */ struct sdhci_slot slots[6]; struct resource *mem_res[6]; /* Memory resource */ - uint8_t cfg_freq; /* Saved mode */ - uint8_t cfg_mode; /* Saved frequency */ + uint8_t cfg_freq; /* Saved frequency */ + uint8_t cfg_mode; /* Saved mode */ }; static int sdhci_enable_msi = 1; @@ -329,12 +344,14 @@ sdhci_pci_attach(device_t dev) /* Allocate memory. */ rid = PCIR_BAR(bar + i); - sc->mem_res[i] = bus_alloc_resource(dev, SYS_RES_MEMORY, - &rid, 0ul, ~0ul, 0x100, RF_ACTIVE); + sc->mem_res[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &rid, RF_ACTIVE); if (sc->mem_res[i] == NULL) { device_printf(dev, "Can't allocate memory for slot %d\n", i); continue; } + + slot->quirks = sc->quirks; if (sdhci_init_slot(dev, slot, i) != 0) continue; @@ -409,11 +426,16 @@ static int sdhci_pci_resume(device_t dev) { struct sdhci_pci_softc *sc = device_get_softc(dev); - int i; + int i, err; for (i = 0; i < sc->num_slots; i++) sdhci_generic_resume(&sc->slots[i]); - return (bus_generic_resume(dev)); + err = bus_generic_resume(dev); + if (err) + return (err); + if (sc->quirks & SDHCI_QUIRK_LOWER_FREQUENCY) + sdhci_lower_frequency(dev); + return (0); } static void @@ -442,11 +464,11 @@ static device_method_t sdhci_methods[] = { DEVMETHOD(bus_write_ivar, sdhci_generic_write_ivar), /* mmcbr_if */ - DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios), - DEVMETHOD(mmcbr_request, sdhci_generic_request), - DEVMETHOD(mmcbr_get_ro, sdhci_generic_get_ro), - DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host), - DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host), + DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios), + DEVMETHOD(mmcbr_request, sdhci_generic_request), + DEVMETHOD(mmcbr_get_ro, sdhci_generic_get_ro), + DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host), + DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host), /* SDHCI registers accessors */ DEVMETHOD(sdhci_read_1, sdhci_pci_read_1), diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c index e4a918a..4e7ff53 100644 --- a/sys/dev/sfxge/common/efx_mcdi.c +++ b/sys/dev/sfxge/common/efx_mcdi.c @@ -1725,7 +1725,8 @@ static __checkReturn efx_rc_t efx_mcdi_mac_stats( __in efx_nic_t *enp, __in_opt efsys_mem_t *esmp, - __in efx_stats_action_t action) + __in efx_stats_action_t action, + __in uint16_t period_ms) { efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_MAC_STATS_IN_LEN, @@ -1750,7 +1751,7 @@ efx_mcdi_mac_stats( MAC_STATS_IN_PERIODIC_CHANGE, enable | events | disable, MAC_STATS_IN_PERIODIC_ENABLE, enable | events, MAC_STATS_IN_PERIODIC_NOEVENT, !events, - MAC_STATS_IN_PERIOD_MS, (enable | events) ? 1000 : 0); + MAC_STATS_IN_PERIOD_MS, (enable | events) ? period_ms : 0); if (esmp != NULL) { int bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t); @@ -1800,7 +1801,7 @@ efx_mcdi_mac_stats_clear( { efx_rc_t rc; - if ((rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_CLEAR)) != 0) + if ((rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_CLEAR, 0)) != 0) goto fail1; return (0); @@ -1823,7 +1824,7 @@ efx_mcdi_mac_stats_upload( * avoid having to pull the statistics buffer into the cache to * maintain cumulative statistics. */ - if ((rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_UPLOAD)) != 0) + if ((rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_UPLOAD, 0)) != 0) goto fail1; return (0); @@ -1838,7 +1839,7 @@ fail1: efx_mcdi_mac_stats_periodic( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __in uint16_t period, + __in uint16_t period_ms, __in boolean_t events) { efx_rc_t rc; @@ -1847,14 +1848,17 @@ efx_mcdi_mac_stats_periodic( * The MC DMAs aggregate statistics for our convenience, so we can * avoid having to pull the statistics buffer into the cache to * maintain cumulative statistics. - * Huntington uses a fixed 1sec period, so use that on Siena too. + * Huntington uses a fixed 1sec period. + * Medford uses a fixed 1sec period before v6.2.1.1033 firmware. */ - if (period == 0) - rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_DISABLE); + if (period_ms == 0) + rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_DISABLE, 0); else if (events) - rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_EVENTS); + rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_EVENTS, + period_ms); else - rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_NOEVENTS); + rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_NOEVENTS, + period_ms); if (rc != 0) goto fail1; diff --git a/sys/dev/sfxge/common/efx_mcdi.h b/sys/dev/sfxge/common/efx_mcdi.h index ffa50f1..ee11789 100644 --- a/sys/dev/sfxge/common/efx_mcdi.h +++ b/sys/dev/sfxge/common/efx_mcdi.h @@ -218,7 +218,7 @@ extern __checkReturn efx_rc_t efx_mcdi_mac_stats_periodic( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __in uint16_t period, + __in uint16_t period_ms, __in boolean_t events); diff --git a/sys/dev/sfxge/sfxge.c b/sys/dev/sfxge/sfxge.c index 8b9edb0..f91275e 100644 --- a/sys/dev/sfxge/sfxge.c +++ b/sys/dev/sfxge/sfxge.c @@ -94,14 +94,6 @@ SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_ring, CTLFLAG_RDTUN, &sfxge_tx_ring_entries, 0, "Maximum number of descriptors in a transmit ring"); -#define SFXGE_PARAM_STATS_UPDATE_PERIOD SFXGE_PARAM(stats_update_period) -static int sfxge_stats_update_period = SFXGE_CALLOUT_TICKS; -TUNABLE_INT(SFXGE_PARAM_STATS_UPDATE_PERIOD, - &sfxge_stats_update_period); -SYSCTL_INT(_hw_sfxge, OID_AUTO, stats_update_period, CTLFLAG_RDTUN, - &sfxge_stats_update_period, 0, - "netstat interface statistics update period in ticks"); - #define SFXGE_PARAM_RESTART_ATTEMPTS SFXGE_PARAM(restart_attempts) static int sfxge_restart_attempts = 3; TUNABLE_INT(SFXGE_PARAM_RESTART_ATTEMPTS, &sfxge_restart_attempts); @@ -558,7 +550,8 @@ sfxge_tick(void *arg) sfxge_port_update_stats(sc); sfxge_tx_update_stats(sc); - callout_reset(&sc->tick_callout, sfxge_stats_update_period, + callout_reset(&sc->tick_callout, + hz * sc->port.stats_update_period_ms / 1000, sfxge_tick, sc); } @@ -623,7 +616,8 @@ sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc) if ((rc = sfxge_port_ifmedia_init(sc)) != 0) goto fail; - callout_reset(&sc->tick_callout, sfxge_stats_update_period, + callout_reset(&sc->tick_callout, + hz * sc->port.stats_update_period_ms / 1000, sfxge_tick, sc); return (0); diff --git a/sys/dev/sfxge/sfxge.h b/sys/dev/sfxge/sfxge.h index 62b1dc3..1929318 100644 --- a/sys/dev/sfxge/sfxge.h +++ b/sys/dev/sfxge/sfxge.h @@ -158,7 +158,7 @@ enum sfxge_evq_state { #define SFXGE_EV_BATCH 16384 -#define SFXGE_CALLOUT_TICKS 100 +#define SFXGE_STATS_UPDATE_PERIOD_MS 1000 struct sfxge_evq { /* Structure members below are sorted by usage order */ @@ -247,6 +247,7 @@ struct sfxge_port { #endif struct sfxge_hw_stats phy_stats; struct sfxge_hw_stats mac_stats; + uint16_t stats_update_period_ms; efx_link_mode_t link_mode; uint8_t mcast_addrs[EFX_MAC_MULTICAST_LIST_MAX * EFX_MAC_ADDR_LEN]; diff --git a/sys/dev/sfxge/sfxge_port.c b/sys/dev/sfxge/sfxge_port.c index 6e753a2..edc88ec 100644 --- a/sys/dev/sfxge/sfxge_port.c +++ b/sys/dev/sfxge/sfxge_port.c @@ -43,6 +43,15 @@ __FBSDID("$FreeBSD$"); #include "sfxge.h" +#define SFXGE_PARAM_STATS_UPDATE_PERIOD_MS \ + SFXGE_PARAM(stats_update_period_ms) +static int sfxge_stats_update_period_ms = SFXGE_STATS_UPDATE_PERIOD_MS; +TUNABLE_INT(SFXGE_PARAM_STATS_UPDATE_PERIOD_MS, + &sfxge_stats_update_period_ms); +SYSCTL_INT(_hw_sfxge, OID_AUTO, stats_update_period_ms, CTLFLAG_RDTUN, + &sfxge_stats_update_period_ms, 0, + "netstat interface statistics update period in milliseconds"); + static int sfxge_phy_cap_mask(struct sfxge_softc *, int, uint32_t *); static int @@ -51,6 +60,7 @@ sfxge_mac_stat_update(struct sfxge_softc *sc) struct sfxge_port *port = &sc->port; efsys_mem_t *esmp = &(port->mac_stats.dma_buf); clock_t now; + unsigned int min_ticks; unsigned int count; int rc; @@ -61,8 +71,10 @@ sfxge_mac_stat_update(struct sfxge_softc *sc) goto out; } + min_ticks = (unsigned int)hz * port->stats_update_period_ms / 1000; + now = ticks; - if ((unsigned int)(now - port->mac_stats.update_time) < (unsigned int)hz) { + if ((unsigned int)(now - port->mac_stats.update_time) < min_ticks) { rc = 0; goto out; } @@ -483,9 +495,10 @@ sfxge_port_start(struct sfxge_softc *sc) sfxge_mac_filter_set_locked(sc); - /* Update MAC stats by DMA every second */ + /* Update MAC stats by DMA every period */ if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, - 1000, B_FALSE)) != 0) + port->stats_update_period_ms, + B_FALSE)) != 0) goto fail6; if ((rc = efx_mac_drain(enp, B_FALSE)) != 0) @@ -642,6 +655,68 @@ sfxge_port_fini(struct sfxge_softc *sc) port->sc = NULL; } +static uint16_t +sfxge_port_stats_update_period_ms(struct sfxge_softc *sc) +{ + int period_ms = sfxge_stats_update_period_ms; + + if (period_ms < 0) { + device_printf(sc->dev, + "treat negative stats update period %d as 0 (disable)\n", + period_ms); + period_ms = 0; + } else if (period_ms > UINT16_MAX) { + device_printf(sc->dev, + "treat too big stats update period %d as %u\n", + period_ms, UINT16_MAX); + period_ms = UINT16_MAX; + } + + return period_ms; +} + +static int +sfxge_port_stats_update_period_ms_handler(SYSCTL_HANDLER_ARGS) +{ + struct sfxge_softc *sc; + struct sfxge_port *port; + unsigned int period_ms; + int error; + + sc = arg1; + port = &sc->port; + + if (req->newptr != NULL) { + error = SYSCTL_IN(req, &period_ms, sizeof(period_ms)); + if (error != 0) + return (error); + + if (period_ms > UINT16_MAX) + return (EINVAL); + + SFXGE_PORT_LOCK(port); + + if (port->stats_update_period_ms != period_ms) { + if (port->init_state == SFXGE_PORT_STARTED) + error = efx_mac_stats_periodic(sc->enp, + &port->mac_stats.dma_buf, + period_ms, B_FALSE); + if (error == 0) + port->stats_update_period_ms = period_ms; + } + + SFXGE_PORT_UNLOCK(port); + } else { + SFXGE_PORT_LOCK(port); + period_ms = port->stats_update_period_ms; + SFXGE_PORT_UNLOCK(port); + + error = SYSCTL_OUT(req, &period_ms, sizeof(period_ms)); + } + + return (error); +} + int sfxge_port_init(struct sfxge_softc *sc) { @@ -690,8 +765,14 @@ sfxge_port_init(struct sfxge_softc *sc) M_SFXGE, M_WAITOK | M_ZERO); if ((rc = sfxge_dma_alloc(sc, EFX_MAC_STATS_SIZE, mac_stats_buf)) != 0) goto fail2; + port->stats_update_period_ms = sfxge_port_stats_update_period_ms(sc); sfxge_mac_stat_init(sc); + SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, + "stats_update_period_ms", CTLTYPE_UINT|CTLFLAG_RW, sc, 0, + sfxge_port_stats_update_period_ms_handler, "IU", + "interface statistics refresh period"); + port->init_state = SFXGE_PORT_INITIALIZED; DBGPRINT(sc->dev, "success"); diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c index cc6fb17..d8ccbf1 100644 --- a/sys/dev/sfxge/sfxge_tx.c +++ b/sys/dev/sfxge/sfxge_tx.c @@ -356,8 +356,22 @@ static int sfxge_tx_queue_mbuf(struct sfxge_txq *txq, struct mbuf *mbuf) KASSERT(!txq->blocked, ("txq->blocked")); +#if SFXGE_TX_PARSE_EARLY + /* + * If software TSO is used, we still need to copy packet header, + * even if we have already parsed it early before enqueue. + */ + if ((mbuf->m_pkthdr.csum_flags & CSUM_TSO) && + (txq->tso_fw_assisted == 0)) + prefetch_read_many(mbuf->m_data); +#else + /* + * Prefetch packet header since we need to parse it and extract + * IP ID, TCP sequence number and flags. + */ if (mbuf->m_pkthdr.csum_flags & CSUM_TSO) prefetch_read_many(mbuf->m_data); +#endif if (__predict_false(txq->init_state != SFXGE_TXQ_STARTED)) { rc = EINTR; diff --git a/sys/dev/sound/pci/als4000.c b/sys/dev/sound/pci/als4000.c index 0cd51e3..404a58f 100644 --- a/sys/dev/sound/pci/als4000.c +++ b/sys/dev/sound/pci/als4000.c @@ -760,8 +760,8 @@ static int als_resource_grab(device_t dev, struct sc_info *sc) { sc->regid = PCIR_BAR(0); - sc->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->regid, 0, ~0, - ALS_CONFIG_SPACE_BYTES, RF_ACTIVE); + sc->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->regid, + RF_ACTIVE); if (sc->reg == 0) { device_printf(dev, "unable to allocate register space\n"); goto bad; diff --git a/sys/dev/sound/pci/cs4281.c b/sys/dev/sound/pci/cs4281.c index 6e1b17d..60e89e3 100644 --- a/sys/dev/sound/pci/cs4281.c +++ b/sys/dev/sound/pci/cs4281.c @@ -790,12 +790,11 @@ cs4281_pci_attach(device_t dev) sc->regid = PCIR_BAR(0); sc->regtype = SYS_RES_MEMORY; - sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid, - 0, ~0, CS4281PCI_BA0_SIZE, RF_ACTIVE); + sc->reg = bus_alloc_resource_any(dev, sc->regtype, &sc->regid, RF_ACTIVE); if (!sc->reg) { sc->regtype = SYS_RES_IOPORT; - sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid, - 0, ~0, CS4281PCI_BA0_SIZE, RF_ACTIVE); + sc->reg = bus_alloc_resource_any(dev, sc->regtype, &sc->regid, + RF_ACTIVE); if (!sc->reg) { device_printf(dev, "unable to allocate register space\n"); goto bad; @@ -805,8 +804,8 @@ cs4281_pci_attach(device_t dev) sc->sh = rman_get_bushandle(sc->reg); sc->memid = PCIR_BAR(1); - sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->memid, 0, - ~0, CS4281PCI_BA1_SIZE, RF_ACTIVE); + sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->memid, + RF_ACTIVE); if (sc->mem == NULL) { device_printf(dev, "unable to allocate fifo space\n"); goto bad; diff --git a/sys/dev/sound/pci/hda/hdaa_patches.c b/sys/dev/sound/pci/hda/hdaa_patches.c index 245815d..11d8e43 100644 --- a/sys/dev/sound/pci/hda/hdaa_patches.c +++ b/sys/dev/sound/pci/hda/hdaa_patches.c @@ -714,6 +714,15 @@ hdaa_patch_direct(struct hdaa_devinfo *devinfo) hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, 0xf88, 0xc0)); break; + case HDA_CODEC_ALC1150: + if (subid == 0xd9781462) { + /* Too low volume on MSI H170 GAMING M3. */ + hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, + 0x07)); + hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, 0x20, + 0x7cb)); + } + break; } if (subid == APPLE_INTEL_MAC) hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid, diff --git a/sys/dev/sound/pci/hda/hdac.h b/sys/dev/sound/pci/hda/hdac.h index 912a996..55888f2 100644 --- a/sys/dev/sound/pci/hda/hdac.h +++ b/sys/dev/sound/pci/hda/hdac.h @@ -367,6 +367,7 @@ #define HDA_CODEC_ALC889 HDA_CODEC_CONSTRUCT(REALTEK, 0x0889) #define HDA_CODEC_ALC892 HDA_CODEC_CONSTRUCT(REALTEK, 0x0892) #define HDA_CODEC_ALC899 HDA_CODEC_CONSTRUCT(REALTEK, 0x0899) +#define HDA_CODEC_ALC1150 HDA_CODEC_CONSTRUCT(REALTEK, 0x0900) #define HDA_CODEC_ALCXXXX HDA_CODEC_CONSTRUCT(REALTEK, 0xffff) /* Motorola */ diff --git a/sys/dev/sound/pci/hda/hdacc.c b/sys/dev/sound/pci/hda/hdacc.c index c8d617e..d186a82 100644 --- a/sys/dev/sound/pci/hda/hdacc.c +++ b/sys/dev/sound/pci/hda/hdacc.c @@ -111,6 +111,7 @@ static const struct { { HDA_CODEC_ALC889, 0, "Realtek ALC889" }, { HDA_CODEC_ALC892, 0, "Realtek ALC892" }, { HDA_CODEC_ALC899, 0, "Realtek ALC899" }, + { HDA_CODEC_ALC1150, 0, "Realtek ALC1150" }, { HDA_CODEC_AD1882, 0, "Analog Devices AD1882" }, { HDA_CODEC_AD1882A, 0, "Analog Devices AD1882A" }, { HDA_CODEC_AD1883, 0, "Analog Devices AD1883" }, diff --git a/sys/dev/sound/pci/vibes.c b/sys/dev/sound/pci/vibes.c index 733e0d8..acb0e0a 100644 --- a/sys/dev/sound/pci/vibes.c +++ b/sys/dev/sound/pci/vibes.c @@ -739,9 +739,8 @@ sv_attach(device_t dev) { #endif sc->enh_rid = SV_PCI_ENHANCED; sc->enh_type = SYS_RES_IOPORT; - sc->enh_reg = bus_alloc_resource(dev, sc->enh_type, - &sc->enh_rid, 0, ~0, - SV_PCI_ENHANCED_SIZE, RF_ACTIVE); + sc->enh_reg = bus_alloc_resource_any(dev, sc->enh_type, + &sc->enh_rid, RF_ACTIVE); if (sc->enh_reg == NULL) { device_printf(dev, "sv_attach: cannot allocate enh\n"); return ENXIO; @@ -832,9 +831,8 @@ sv_attach(device_t dev) { /* Cache resource short-cuts for dma_a */ sc->dmaa_rid = SV_PCI_DMAA; sc->dmaa_type = SYS_RES_IOPORT; - sc->dmaa_reg = bus_alloc_resource(dev, sc->dmaa_type, - &sc->dmaa_rid, 0, ~0, - SV_PCI_ENHANCED_SIZE, RF_ACTIVE); + sc->dmaa_reg = bus_alloc_resource_any(dev, sc->dmaa_type, + &sc->dmaa_rid, RF_ACTIVE); if (sc->dmaa_reg == NULL) { device_printf(dev, "sv_attach: cannot allocate dmaa\n"); goto fail; @@ -851,9 +849,8 @@ sv_attach(device_t dev) { /* Cache resource short-cuts for dma_c */ sc->dmac_rid = SV_PCI_DMAC; sc->dmac_type = SYS_RES_IOPORT; - sc->dmac_reg = bus_alloc_resource(dev, sc->dmac_type, - &sc->dmac_rid, 0, ~0, - SV_PCI_ENHANCED_SIZE, RF_ACTIVE); + sc->dmac_reg = bus_alloc_resource_any(dev, sc->dmac_type, + &sc->dmac_rid, RF_ACTIVE); if (sc->dmac_reg == NULL) { device_printf(dev, "sv_attach: cannot allocate dmac\n"); goto fail; diff --git a/sys/dev/stge/if_stge.c b/sys/dev/stge/if_stge.c index 3cc45b3..cad1a63 100644 --- a/sys/dev/stge/if_stge.c +++ b/sys/dev/stge/if_stge.c @@ -507,7 +507,7 @@ stge_attach(device_t dev) } } - if ((error = stge_dma_alloc(sc) != 0)) + if ((error = stge_dma_alloc(sc)) != 0) goto fail; /* diff --git a/sys/dev/tws/tws.c b/sys/dev/tws/tws.c index 6bb6dd1..73ab501 100644 --- a/sys/dev/tws/tws.c +++ b/sys/dev/tws/tws.c @@ -257,8 +257,8 @@ tws_attach(device_t dev) #ifndef TWS_PULL_MODE_ENABLE /* Allocate bus space for inbound mfa */ sc->mfa_res_id = TWS_PCI_BAR2; /* BAR2 offset */ - if ((sc->mfa_res = bus_alloc_resource(dev, SYS_RES_MEMORY, - &(sc->mfa_res_id), 0, ~0, 0x100000, RF_ACTIVE)) + if ((sc->mfa_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &(sc->mfa_res_id), RF_ACTIVE)) == NULL) { tws_log(sc, ALLOC_MEMORY_RES); goto attach_fail_2; diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 354e62d..7d74dd8 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -2272,6 +2272,11 @@ usb_needs_explore(struct usb_bus *bus, uint8_t do_probe) DPRINTF("\n"); + if (cold != 0) { + DPRINTF("Cold\n"); + return; + } + if (bus == NULL) { DPRINTF("No bus pointer!\n"); return; @@ -2337,6 +2342,26 @@ usb_needs_explore_all(void) } /*------------------------------------------------------------------------* + * usb_needs_explore_init + * + * This function will ensure that the USB controllers are not enumerated + * until the "cold" variable is cleared. + *------------------------------------------------------------------------*/ +static void +usb_needs_explore_init(void *arg) +{ + /* + * The cold variable should be cleared prior to this function + * being called: + */ + if (cold == 0) + usb_needs_explore_all(); + else + DPRINTFN(-1, "Cold variable is still set!\n"); +} +SYSINIT(usb_needs_explore_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_SECOND, usb_needs_explore_init, NULL); + +/*------------------------------------------------------------------------* * usb_bus_power_update * * This function will ensure that all USB devices on the given bus are diff --git a/sys/dev/usb/usb_process.c b/sys/dev/usb/usb_process.c index e70166c..0f17485 100644 --- a/sys/dev/usb/usb_process.c +++ b/sys/dev/usb/usb_process.c @@ -455,14 +455,15 @@ usb_proc_drain(struct usb_process *up) up->up_csleep = 0; cv_signal(&up->up_cv); } +#ifndef EARLY_AP_STARTUP /* Check if we are still cold booted */ - if (cold) { USB_THREAD_SUSPEND(up->up_ptr); printf("WARNING: A USB process has " "been left suspended\n"); break; } +#endif cv_wait(&up->up_cv, up->up_mtx); } /* Check if someone is waiting - should not happen */ diff --git a/sys/dev/vte/if_vte.c b/sys/dev/vte/if_vte.c index dfc06e5..5d06d4f 100644 --- a/sys/dev/vte/if_vte.c +++ b/sys/dev/vte/if_vte.c @@ -426,7 +426,7 @@ vte_attach(device_t dev) /* Reset the ethernet controller. */ vte_reset(sc); - if ((error = vte_dma_alloc(sc) != 0)) + if ((error = vte_dma_alloc(sc)) != 0) goto fail; /* Create device sysctl node. */ diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index cdbda07..a5029ae 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -2013,25 +2013,17 @@ again: } /* - * Check to see if entries in this directory can be safely acquired - * via VFS_VGET() or if a switch to VOP_LOOKUP() is required. - * ZFS snapshot directories need VOP_LOOKUP(), so that any - * automount of the snapshot directory that is required will - * be done. - * This needs to be done here for NFSv4, since NFSv4 never does - * a VFS_VGET() for "." or "..". + * For now ZFS requires VOP_LOOKUP as a workaround. Until ino_t is changed + * to 64 bit type a ZFS filesystem with over 1 billion files in it + * will suffer from 64bit -> 32bit truncation. */ - if (is_zfs == 1) { - r = VFS_VGET(mp, at.na_fileid, LK_SHARED, &nvp); - if (r == EOPNOTSUPP) { - usevget = 0; - cn.cn_nameiop = LOOKUP; - cn.cn_lkflags = LK_SHARED | LK_RETRY; - cn.cn_cred = nd->nd_cred; - cn.cn_thread = p; - } else if (r == 0) - vput(nvp); - } + if (is_zfs == 1) + usevget = 0; + + cn.cn_nameiop = LOOKUP; + cn.cn_lkflags = LK_SHARED | LK_RETRY; + cn.cn_cred = nd->nd_cred; + cn.cn_thread = p; /* * Save this position, in case there is an error before one entry @@ -2100,16 +2092,7 @@ again: else r = EOPNOTSUPP; if (r == EOPNOTSUPP) { - if (usevget) { - usevget = 0; - cn.cn_nameiop = LOOKUP; - cn.cn_lkflags = - LK_SHARED | - LK_RETRY; - cn.cn_cred = - nd->nd_cred; - cn.cn_thread = p; - } + usevget = 0; cn.cn_nameptr = dp->d_name; cn.cn_namelen = nlen; cn.cn_flags = ISLASTCN | diff --git a/sys/fs/pseudofs/pseudofs_vncache.c b/sys/fs/pseudofs/pseudofs_vncache.c index 1bec5a4..093d805 100644 --- a/sys/fs/pseudofs/pseudofs_vncache.c +++ b/sys/fs/pseudofs/pseudofs_vncache.c @@ -51,6 +51,7 @@ static struct mtx pfs_vncache_mutex; static struct pfs_vdata *pfs_vncache; static eventhandler_tag pfs_exit_tag; static void pfs_exit(void *arg, struct proc *p); +static void pfs_purge_locked(struct pfs_node *pn, bool force); static SYSCTL_NODE(_vfs_pfs, OID_AUTO, vncache, CTLFLAG_RW, 0, "pseudofs vnode cache"); @@ -97,6 +98,9 @@ pfs_vncache_unload(void) { EVENTHANDLER_DEREGISTER(process_exit, pfs_exit_tag); + mtx_lock(&pfs_vncache_mutex); + pfs_purge_locked(NULL, true); + mtx_unlock(&pfs_vncache_mutex); KASSERT(pfs_vncache_entries == 0, ("%d vncache entries remaining", pfs_vncache_entries)); mtx_destroy(&pfs_vncache_mutex); @@ -272,7 +276,7 @@ pfs_vncache_free(struct vnode *vp) * used to implement the cache. */ static void -pfs_purge_locked(struct pfs_node *pn) +pfs_purge_locked(struct pfs_node *pn, bool force) { struct pfs_vdata *pvd; struct vnode *vnp; @@ -280,7 +284,8 @@ pfs_purge_locked(struct pfs_node *pn) mtx_assert(&pfs_vncache_mutex, MA_OWNED); pvd = pfs_vncache; while (pvd != NULL) { - if (pvd->pvd_dead || (pn != NULL && pvd->pvd_pn == pn)) { + if (force || pvd->pvd_dead || + (pn != NULL && pvd->pvd_pn == pn)) { vnp = pvd->pvd_vnode; vhold(vnp); mtx_unlock(&pfs_vncache_mutex); @@ -301,7 +306,7 @@ pfs_purge(struct pfs_node *pn) { mtx_lock(&pfs_vncache_mutex); - pfs_purge_locked(pn); + pfs_purge_locked(pn, false); mtx_unlock(&pfs_vncache_mutex); } @@ -321,6 +326,6 @@ pfs_exit(void *arg, struct proc *p) if (pvd->pvd_pid == p->p_pid) dead = pvd->pvd_dead = 1; if (dead) - pfs_purge_locked(NULL); + pfs_purge_locked(NULL, false); mtx_unlock(&pfs_vncache_mutex); } diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h index b077489..37e5bbb 100644 --- a/sys/fs/tmpfs/tmpfs.h +++ b/sys/fs/tmpfs/tmpfs.h @@ -80,8 +80,10 @@ struct tmpfs_dirent { uint32_t td_hash; u_int td_namelen; - /* Pointer to the node this entry refers to. In case this field - * is NULL, the node is a whiteout. */ + /* + * Pointer to the node this entry refers to. In case this field + * is NULL, the node is a whiteout. + */ struct tmpfs_node * td_node; union { @@ -94,21 +96,24 @@ struct tmpfs_dirent { } ud; }; -/* A directory in tmpfs holds a list of directory entries, which in - * turn point to other files (which can be directories themselves). +/* + * A directory in tmpfs holds a collection of directory entries, which + * in turn point to other files (which can be directories themselves). * - * In tmpfs, this list is managed by a RB-Tree, whose head is defined by - * the struct tmpfs_dir type. + * In tmpfs, this collection is managed by a RB-Tree, whose head is + * defined by the struct tmpfs_dir type. * * It is important to notice that directories do not have entries for . and * .. as other file systems do. These can be generated when requested * based on information available by other means, such as the pointer to * the node itself in the former case or the pointer to the parent directory * in the latter case. This is done to simplify tmpfs's code and, more - * importantly, to remove redundancy. */ + * importantly, to remove redundancy. + */ RB_HEAD(tmpfs_dir, tmpfs_dirent); -/* Each entry in a directory has a cookie that identifies it. Cookies +/* + * Each entry in a directory has a cookie that identifies it. Cookies * supersede offsets within directories because, given how tmpfs stores * directories in memory, there is no such thing as an offset. * @@ -139,51 +144,67 @@ RB_HEAD(tmpfs_dir, tmpfs_dirent); * a particular type. The code must be careful to only access those * attributes that are actually allowed by the node's type. * - * * Below is the key of locks used to protected the fields in the following * structures. - * + * (v) vnode lock in exclusive mode + * (vi) vnode lock in exclusive mode, or vnode lock in shared vnode and + * tn_interlock + * (i) tn_interlock + * (m) tmpfs_mount tm_allnode_lock + * (c) stable after creation */ struct tmpfs_node { - /* Doubly-linked list entry which links all existing nodes for a - * single file system. This is provided to ease the removal of - * all nodes during the unmount operation. */ - LIST_ENTRY(tmpfs_node) tn_entries; + /* + * Doubly-linked list entry which links all existing nodes for + * a single file system. This is provided to ease the removal + * of all nodes during the unmount operation, and to support + * the implementation of VOP_VNTOCNP(). tn_attached is false + * when the node is removed from list and unlocked. + */ + LIST_ENTRY(tmpfs_node) tn_entries; /* (m) */ + bool tn_attached; /* (m) */ - /* The node's type. Any of 'VBLK', 'VCHR', 'VDIR', 'VFIFO', + /* + * The node's type. Any of 'VBLK', 'VCHR', 'VDIR', 'VFIFO', * 'VLNK', 'VREG' and 'VSOCK' is allowed. The usage of vnode * types instead of a custom enumeration is to make things simpler - * and faster, as we do not need to convert between two types. */ - enum vtype tn_type; + * and faster, as we do not need to convert between two types. + */ + enum vtype tn_type; /* (c) */ /* Node identifier. */ - ino_t tn_id; + ino_t tn_id; /* (c) */ - /* Node's internal status. This is used by several file system + /* + * Node's internal status. This is used by several file system * operations to do modifications to the node in a delayed - * fashion. */ - int tn_status; + * fashion. + */ + int tn_status; /* (vi) */ #define TMPFS_NODE_ACCESSED (1 << 1) #define TMPFS_NODE_MODIFIED (1 << 2) #define TMPFS_NODE_CHANGED (1 << 3) - /* The node size. It does not necessarily match the real amount - * of memory consumed by it. */ - off_t tn_size; + /* + * The node size. It does not necessarily match the real amount + * of memory consumed by it. + */ + off_t tn_size; /* (v) */ /* Generic node attributes. */ - uid_t tn_uid; - gid_t tn_gid; - mode_t tn_mode; - u_long tn_flags; - nlink_t tn_links; - struct timespec tn_atime; - struct timespec tn_mtime; - struct timespec tn_ctime; - struct timespec tn_birthtime; - unsigned long tn_gen; - - /* As there is a single vnode for each active file within the + uid_t tn_uid; /* (v) */ + gid_t tn_gid; /* (v) */ + mode_t tn_mode; /* (v) */ + u_long tn_flags; /* (v) */ + nlink_t tn_links; /* (v) */ + struct timespec tn_atime; /* (vi) */ + struct timespec tn_mtime; /* (vi) */ + struct timespec tn_ctime; /* (vi) */ + struct timespec tn_birthtime; /* (v) */ + unsigned long tn_gen; /* (c) */ + + /* + * As there is a single vnode for each active file within the * system, care has to be taken to avoid allocating more than one * vnode per file. In order to do this, a bidirectional association * is kept between vnodes and nodes. @@ -196,74 +217,84 @@ struct tmpfs_node { * tn_vnode. * * May be NULL when the node is unused (that is, no vnode has been - * allocated for it or it has been reclaimed). */ - struct vnode * tn_vnode; + * allocated for it or it has been reclaimed). + */ + struct vnode * tn_vnode; /* (i) */ - /* interlock to protect tn_vpstate */ + /* + * Interlock to protect tn_vpstate, and tn_status under shared + * vnode lock. + */ struct mtx tn_interlock; - /* Identify if current node has vnode assiocate with + /* + * Identify if current node has vnode assiocate with * or allocating vnode. */ - int tn_vpstate; + int tn_vpstate; /* (i) */ + + /* Transient refcounter on this node. */ + u_int tn_refcount; /* (m) + (i) */ /* misc data field for different tn_type node */ union { /* Valid when tn_type == VBLK || tn_type == VCHR. */ - dev_t tn_rdev; + dev_t tn_rdev; /* (c) */ /* Valid when tn_type == VDIR. */ struct tn_dir { - /* Pointer to the parent directory. The root + /* + * Pointer to the parent directory. The root * directory has a pointer to itself in this field; - * this property identifies the root node. */ + * this property identifies the root node. + */ struct tmpfs_node * tn_parent; - /* Head of a tree that links the contents of - * the directory together. */ + /* + * Head of a tree that links the contents of + * the directory together. + */ struct tmpfs_dir tn_dirhead; - /* Head of a list the contains fake directory entries + /* + * Head of a list the contains fake directory entries * heads, i.e. entries with TMPFS_DIRCOOKIE_DUPHEAD - * flag. */ + * flag. + */ struct tmpfs_dir_duphead tn_dupindex; - /* Number and pointer of the first directory entry + /* + * Number and pointer of the first directory entry * returned by the readdir operation if it were * called again to continue reading data from the * same directory as before. This is used to speed * up reads of long directories, assuming that no * more than one read is in progress at a given time. - * Otherwise, these values are discarded. */ + * Otherwise, these values are discarded. + */ off_t tn_readdir_lastn; struct tmpfs_dirent * tn_readdir_lastp; } tn_dir; /* Valid when tn_type == VLNK. */ /* The link's target, allocated from a string pool. */ - char * tn_link; + char * tn_link; /* (c) */ /* Valid when tn_type == VREG. */ struct tn_reg { - /* The contents of regular files stored in a tmpfs - * file system are represented by a single anonymous - * memory object (aobj, for short). The aobj provides - * direct access to any position within the file, - * because its contents are always mapped in a - * contiguous region of virtual memory. It is a task - * of the memory management subsystem (see uvm(9)) to - * issue the required page ins or page outs whenever - * a position within the file is accessed. */ - vm_object_t tn_aobj; - - }tn_reg; - - /* Valid when tn_type = VFIFO */ - struct tn_fifo { - fo_rdwr_t *tn_fo_read; - fo_rdwr_t *tn_fo_write; - }tn_fifo; - }tn_spec; + /* + * The contents of regular files stored in a + * tmpfs file system are represented by a + * single anonymous memory object (aobj, for + * short). The aobj provides direct access to + * any position within the file. It is a task + * of the memory management subsystem to issue + * the required page ins or page outs whenever + * a position within the file is accessed. + */ + vm_object_t tn_aobj; /* (c) */ + } tn_reg; + } tn_spec; /* (v) */ }; LIST_HEAD(tmpfs_node_list, tmpfs_node); @@ -281,21 +312,12 @@ LIST_HEAD(tmpfs_node_list, tmpfs_node); #ifdef INVARIANTS #define TMPFS_ASSERT_LOCKED(node) do { \ - MPASS(node != NULL); \ - MPASS(node->tn_vnode != NULL); \ - if (!VOP_ISLOCKED(node->tn_vnode) && \ - !mtx_owned(TMPFS_NODE_MTX(node))) \ - panic("tmpfs: node is not locked: %p", node); \ - } while (0) -#define TMPFS_ASSERT_ELOCKED(node) do { \ MPASS((node) != NULL); \ MPASS((node)->tn_vnode != NULL); \ - mtx_assert(TMPFS_NODE_MTX(node), MA_OWNED); \ - ASSERT_VOP_LOCKED((node)->tn_vnode, "tmpfs"); \ + ASSERT_VOP_LOCKED((node)->tn_vnode, "tmpfs assert"); \ } while (0) #else #define TMPFS_ASSERT_LOCKED(node) (void)0 -#define TMPFS_ASSERT_ELOCKED(node) (void)0 #endif #define TMPFS_VNODE_ALLOCATING 1 @@ -307,26 +329,32 @@ LIST_HEAD(tmpfs_node_list, tmpfs_node); * Internal representation of a tmpfs mount point. */ struct tmpfs_mount { - /* Maximum number of memory pages available for use by the file + /* + * Maximum number of memory pages available for use by the file * system, set during mount time. This variable must never be * used directly as it may be bigger than the current amount of - * free memory; in the extreme case, it will hold the SIZE_MAX - * value. */ - size_t tm_pages_max; + * free memory; in the extreme case, it will hold the ULONG_MAX + * value. + */ + u_long tm_pages_max; /* Number of pages in use by the file system. */ - size_t tm_pages_used; + u_long tm_pages_used; - /* Pointer to the node representing the root directory of this - * file system. */ + /* + * Pointer to the node representing the root directory of this + * file system. + */ struct tmpfs_node * tm_root; - /* Maximum number of possible nodes for this file system; set + /* + * Maximum number of possible nodes for this file system; set * during mount time. We need a hard limit on the maximum number * of nodes to avoid allocating too much of them; their objects * cannot be released until the file system is unmounted. * Otherwise, we could easily run out of memory by creating lots - * of empty files and then simply removing them. */ + * of empty files and then simply removing them. + */ ino_t tm_nodes_max; /* unrhdr used to allocate inode numbers */ @@ -335,38 +363,33 @@ struct tmpfs_mount { /* Number of nodes currently that are in use. */ ino_t tm_nodes_inuse; + /* Refcounter on this struct tmpfs_mount. */ + uint64_t tm_refcount; + /* maximum representable file size */ u_int64_t tm_maxfilesize; - /* Nodes are organized in two different lists. The used list - * contains all nodes that are currently used by the file system; - * i.e., they refer to existing files. The available list contains - * all nodes that are currently available for use by new files. - * Nodes must be kept in this list (instead of deleting them) - * because we need to keep track of their generation number (tn_gen - * field). - * - * Note that nodes are lazily allocated: if the available list is - * empty and we have enough space to create more nodes, they will be - * created and inserted in the used list. Once these are released, - * they will go into the available list, remaining alive until the - * file system is unmounted. */ + /* + * The used list contains all nodes that are currently used by + * the file system; i.e., they refer to existing files. + */ struct tmpfs_node_list tm_nodes_used; - /* All node lock to protect the node list and tmp_pages_used */ - struct mtx allnode_lock; + /* All node lock to protect the node list and tmp_pages_used. */ + struct mtx tm_allnode_lock; - /* Pools used to store file system meta data. These are not shared - * across several instances of tmpfs for the reasons described in - * tmpfs_pool.c. */ + /* Zones used to store file system meta data, per tmpfs mount. */ uma_zone_t tm_dirent_pool; uma_zone_t tm_node_pool; /* Read-only status. */ - int tm_ronly; + bool tm_ronly; + /* Do not use namecache. */ + bool tm_nonc; }; -#define TMPFS_LOCK(tm) mtx_lock(&(tm)->allnode_lock) -#define TMPFS_UNLOCK(tm) mtx_unlock(&(tm)->allnode_lock) +#define TMPFS_LOCK(tm) mtx_lock(&(tm)->tm_allnode_lock) +#define TMPFS_UNLOCK(tm) mtx_unlock(&(tm)->tm_allnode_lock) +#define TMPFS_MP_ASSERT_LOCKED(tm) mtx_assert(&(tm)->tm_allnode_lock, MA_OWNED) /* * This structure maps a file identifier to a tmpfs node. Used by the @@ -379,15 +402,24 @@ struct tmpfs_fid { unsigned long tf_gen; }; +struct tmpfs_dir_cursor { + struct tmpfs_dirent *tdc_current; + struct tmpfs_dirent *tdc_tree; +}; + #ifdef _KERNEL /* * Prototypes for tmpfs_subr.c. */ +void tmpfs_ref_node(struct tmpfs_node *node); +void tmpfs_ref_node_locked(struct tmpfs_node *node); int tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *, enum vtype, uid_t uid, gid_t gid, mode_t mode, struct tmpfs_node *, char *, dev_t, struct tmpfs_node **); void tmpfs_free_node(struct tmpfs_mount *, struct tmpfs_node *); +bool tmpfs_free_node_locked(struct tmpfs_mount *, struct tmpfs_node *, bool); +void tmpfs_free_tmp(struct tmpfs_mount *); int tmpfs_alloc_dirent(struct tmpfs_mount *, struct tmpfs_node *, const char *, u_int, struct tmpfs_dirent **); void tmpfs_free_dirent(struct tmpfs_mount *, struct tmpfs_dirent *); @@ -420,8 +452,13 @@ int tmpfs_chtimes(struct vnode *, struct vattr *, struct ucred *cred, void tmpfs_itimes(struct vnode *, const struct timespec *, const struct timespec *); +void tmpfs_set_status(struct tmpfs_node *node, int status); void tmpfs_update(struct vnode *); int tmpfs_truncate(struct vnode *, off_t); +struct tmpfs_dirent *tmpfs_dir_first(struct tmpfs_node *dnode, + struct tmpfs_dir_cursor *dc); +struct tmpfs_dirent *tmpfs_dir_next(struct tmpfs_node *dnode, + struct tmpfs_dir_cursor *dc); /* * Convenience macros to simplify some logical expressions. @@ -447,10 +484,6 @@ int tmpfs_truncate(struct vnode *, off_t); } while (0) /* - * Memory management stuff. - */ - -/* * Amount of memory pages to reserve for the system (e.g., to not use by * tmpfs). */ @@ -467,37 +500,41 @@ size_t tmpfs_pages_used(struct tmpfs_mount *tmp); * specific ones. */ -static inline -struct tmpfs_mount * +static inline struct tmpfs_mount * VFS_TO_TMPFS(struct mount *mp) { struct tmpfs_mount *tmp; - MPASS((mp) != NULL && (mp)->mnt_data != NULL); - tmp = (struct tmpfs_mount *)(mp)->mnt_data; - return tmp; + MPASS(mp != NULL && mp->mnt_data != NULL); + tmp = (struct tmpfs_mount *)mp->mnt_data; + return (tmp); } -static inline -struct tmpfs_node * +static inline struct tmpfs_node * VP_TO_TMPFS_NODE(struct vnode *vp) { struct tmpfs_node *node; - MPASS((vp) != NULL && (vp)->v_data != NULL); + MPASS(vp != NULL && vp->v_data != NULL); node = (struct tmpfs_node *)vp->v_data; - return node; + return (node); } -static inline -struct tmpfs_node * +static inline struct tmpfs_node * VP_TO_TMPFS_DIR(struct vnode *vp) { struct tmpfs_node *node; node = VP_TO_TMPFS_NODE(vp); TMPFS_VALIDATE_DIR(node); - return node; + return (node); +} + +static inline bool +tmpfs_use_nc(struct vnode *vp) +{ + + return (!(VFS_TO_TMPFS(vp->v_mount)->tm_nonc)); } #endif /* _FS_TMPFS_TMPFS_H_ */ diff --git a/sys/fs/tmpfs/tmpfs_fifoops.c b/sys/fs/tmpfs/tmpfs_fifoops.c index 89ebe85..f1743db 100644 --- a/sys/fs/tmpfs/tmpfs_fifoops.c +++ b/sys/fs/tmpfs/tmpfs_fifoops.c @@ -49,35 +49,14 @@ #include <fs/tmpfs/tmpfs_vnops.h> static int -tmpfs_fifo_kqfilter(struct vop_kqfilter_args *ap) -{ - struct vnode *vp; - struct tmpfs_node *node; - - vp = ap->a_vp; - node = VP_TO_TMPFS_NODE(vp); - - switch (ap->a_kn->kn_filter){ - case EVFILT_READ: - node->tn_status |= TMPFS_NODE_ACCESSED; - break; - case EVFILT_WRITE: - node->tn_status |= TMPFS_NODE_MODIFIED; - break; - } - - return fifo_specops.vop_kqfilter(ap); -} - -static int tmpfs_fifo_close(struct vop_close_args *v) { struct tmpfs_node *node; - node = VP_TO_TMPFS_NODE(v->a_vp); - node->tn_status |= TMPFS_NODE_ACCESSED; + node = VP_TO_TMPFS_NODE(v->a_vp); + tmpfs_set_status(node, TMPFS_NODE_ACCESSED); tmpfs_update(v->a_vp); - return fifo_specops.vop_close(v); + return (fifo_specops.vop_close(v)); } /* @@ -90,6 +69,5 @@ struct vop_vector tmpfs_fifoop_entries = { .vop_access = tmpfs_access, .vop_getattr = tmpfs_getattr, .vop_setattr = tmpfs_setattr, - .vop_kqfilter = tmpfs_fifo_kqfilter, }; diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c index 9781b2c..816b3cc 100644 --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -61,11 +61,6 @@ __FBSDID("$FreeBSD$"); #include <fs/tmpfs/tmpfs_fifoops.h> #include <fs/tmpfs/tmpfs_vnops.h> -struct tmpfs_dir_cursor { - struct tmpfs_dirent *tdc_current; - struct tmpfs_dirent *tdc_tree; -}; - SYSCTL_NODE(_vfs, OID_AUTO, tmpfs, CTLFLAG_RW, 0, "tmpfs file system"); static long tmpfs_pages_reserved = TMPFS_PAGES_MINRESERVED; @@ -129,13 +124,33 @@ tmpfs_pages_check_avail(struct tmpfs_mount *tmp, size_t req_pages) if (tmpfs_mem_avail() < req_pages) return (0); - if (tmp->tm_pages_max != SIZE_MAX && + if (tmp->tm_pages_max != ULONG_MAX && tmp->tm_pages_max < req_pages + tmpfs_pages_used(tmp)) return (0); return (1); } +void +tmpfs_ref_node(struct tmpfs_node *node) +{ + + TMPFS_NODE_LOCK(node); + tmpfs_ref_node_locked(node); + TMPFS_NODE_UNLOCK(node); +} + +void +tmpfs_ref_node_locked(struct tmpfs_node *node) +{ + + TMPFS_NODE_ASSERT_LOCKED(node); + KASSERT(node->tn_refcount > 0, ("node %p zero refcount", node)); + KASSERT(node->tn_refcount < UINT_MAX, ("node %p refcount %u", node, + node->tn_refcount)); + node->tn_refcount++; +} + /* * Allocates a new node of type 'type' inside the 'tmp' mount point, with * its owner set to 'uid', its group to 'gid' and its mode set to 'mode', @@ -198,8 +213,8 @@ tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *tmp, enum vtype type, return (EBUSY); } - nnode = (struct tmpfs_node *)uma_zalloc_arg( - tmp->tm_node_pool, tmp, M_WAITOK); + nnode = (struct tmpfs_node *)uma_zalloc_arg(tmp->tm_node_pool, tmp, + M_WAITOK); /* Generic initialization. */ nnode->tn_type = type; @@ -210,6 +225,7 @@ tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *tmp, enum vtype type, nnode->tn_gid = gid; nnode->tn_mode = mode; nnode->tn_id = alloc_unr(tmp->tm_ino_unr); + nnode->tn_refcount = 1; /* Type-specific initialization. */ switch (nnode->tn_type) { @@ -257,58 +273,65 @@ tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *tmp, enum vtype type, break; default: - panic("tmpfs_alloc_node: type %p %d", nnode, (int)nnode->tn_type); + panic("tmpfs_alloc_node: type %p %d", nnode, + (int)nnode->tn_type); } TMPFS_LOCK(tmp); LIST_INSERT_HEAD(&tmp->tm_nodes_used, nnode, tn_entries); + nnode->tn_attached = true; tmp->tm_nodes_inuse++; + tmp->tm_refcount++; TMPFS_UNLOCK(tmp); *node = nnode; - return 0; + return (0); } /* * Destroys the node pointed to by node from the file system 'tmp'. - * If the node does not belong to the given mount point, the results are - * unpredicted. - * - * If the node references a directory; no entries are allowed because - * their removal could need a recursive algorithm, something forbidden in - * kernel space. Furthermore, there is not need to provide such - * functionality (recursive removal) because the only primitives offered - * to the user are the removal of empty directories and the deletion of - * individual files. - * - * Note that nodes are not really deleted; in fact, when a node has been - * allocated, it cannot be deleted during the whole life of the file - * system. Instead, they are moved to the available list and remain there - * until reused. + * If the node references a directory, no entries are allowed. */ void tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node) { + + TMPFS_LOCK(tmp); + TMPFS_NODE_LOCK(node); + if (!tmpfs_free_node_locked(tmp, node, false)) { + TMPFS_NODE_UNLOCK(node); + TMPFS_UNLOCK(tmp); + } +} + +bool +tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node, + bool detach) +{ vm_object_t uobj; + TMPFS_MP_ASSERT_LOCKED(tmp); + TMPFS_NODE_ASSERT_LOCKED(node); + KASSERT(node->tn_refcount > 0, ("node %p refcount zero", node)); + + node->tn_refcount--; + if (node->tn_attached && (detach || node->tn_refcount == 0)) { + MPASS(tmp->tm_nodes_inuse > 0); + tmp->tm_nodes_inuse--; + LIST_REMOVE(node, tn_entries); + node->tn_attached = false; + } + if (node->tn_refcount > 0) + return (false); + #ifdef INVARIANTS - TMPFS_NODE_LOCK(node); MPASS(node->tn_vnode == NULL); MPASS((node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0); - TMPFS_NODE_UNLOCK(node); #endif - - TMPFS_LOCK(tmp); - LIST_REMOVE(node, tn_entries); - tmp->tm_nodes_inuse--; + TMPFS_NODE_UNLOCK(node); TMPFS_UNLOCK(tmp); switch (node->tn_type) { - case VNON: - /* Do not do anything. VNON is provided to let the - * allocation routine clean itself easily by avoiding - * duplicating code in it. */ - /* FALLTHROUGH */ case VBLK: /* FALLTHROUGH */ case VCHR: @@ -327,9 +350,7 @@ tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node) case VREG: uobj = node->tn_reg.tn_aobj; if (uobj != NULL) { - TMPFS_LOCK(tmp); - tmp->tm_pages_used -= uobj->size; - TMPFS_UNLOCK(tmp); + atomic_subtract_long(&tmp->tm_pages_used, uobj->size); KASSERT((uobj->flags & OBJ_TMPFS) == 0, ("leaked OBJ_TMPFS node %p vm_obj %p", node, uobj)); vm_object_deallocate(uobj); @@ -342,6 +363,9 @@ tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node) free_unr(tmp->tm_ino_unr, node->tn_id); uma_zfree(tmp->tm_node_pool, node); + TMPFS_LOCK(tmp); + tmpfs_free_tmp(tmp); + return (true); } static __inline uint32_t @@ -487,13 +511,16 @@ tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag, struct vnode **vpp) { struct vnode *vp; + struct tmpfs_mount *tm; vm_object_t object; int error; error = 0; -loop: + tm = VFS_TO_TMPFS(mp); TMPFS_NODE_LOCK(node); -loop1: + tmpfs_ref_node_locked(node); +loop: + TMPFS_NODE_ASSERT_LOCKED(node); if ((vp = node->tn_vnode) != NULL) { MPASS((node->tn_vpstate & TMPFS_VNODE_DOOMED) == 0); VI_LOCK(vp); @@ -513,12 +540,14 @@ loop1: msleep(&node->tn_vnode, TMPFS_NODE_MTX(node), 0, "tmpfsE", 0); } - goto loop1; + goto loop; } TMPFS_NODE_UNLOCK(node); error = vget(vp, lkflag | LK_INTERLOCK, curthread); - if (error == ENOENT) + if (error == ENOENT) { + TMPFS_NODE_LOCK(node); goto loop; + } if (error != 0) { vp = NULL; goto out; @@ -530,6 +559,7 @@ loop1: */ if (node->tn_vnode == NULL || node->tn_vnode != vp) { vput(vp); + TMPFS_NODE_LOCK(node); goto loop; } @@ -551,11 +581,9 @@ loop1: if (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) { node->tn_vpstate |= TMPFS_VNODE_WANT; error = msleep((caddr_t) &node->tn_vpstate, - TMPFS_NODE_MTX(node), PDROP | PCATCH, - "tmpfs_alloc_vp", 0); - if (error) - return error; - + TMPFS_NODE_MTX(node), 0, "tmpfs_alloc_vp", 0); + if (error != 0) + goto out; goto loop; } else node->tn_vpstate |= TMPFS_VNODE_ALLOCATING; @@ -563,7 +591,8 @@ loop1: TMPFS_NODE_UNLOCK(node); /* Get a new vnode and associate it with our node. */ - error = getnewvnode("tmpfs", mp, &tmpfs_vnodeop_entries, &vp); + error = getnewvnode("tmpfs", mp, VFS_TO_TMPFS(mp)->tm_nonc ? + &tmpfs_vnodeop_nonc_entries : &tmpfs_vnodeop_entries, &vp); if (error != 0) goto unlock; MPASS(vp != NULL); @@ -611,7 +640,7 @@ loop1: VN_LOCK_ASHARE(vp); error = insmntque1(vp, mp, tmpfs_insmntque_dtr, NULL); - if (error) + if (error != 0) vp = NULL; unlock: @@ -629,18 +658,19 @@ unlock: TMPFS_NODE_UNLOCK(node); out: - *vpp = vp; + if (error == 0) { + *vpp = vp; #ifdef INVARIANTS - if (error == 0) { MPASS(*vpp != NULL && VOP_ISLOCKED(*vpp)); TMPFS_NODE_LOCK(node); MPASS(*vpp == node->tn_vnode); TMPFS_NODE_UNLOCK(node); - } #endif + } + tmpfs_free_node(tm, node); - return error; + return (error); } /* @@ -683,7 +713,7 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap, struct tmpfs_node *node; struct tmpfs_node *parent; - MPASS(VOP_ISLOCKED(dvp)); + ASSERT_VOP_ELOCKED(dvp, "tmpfs_alloc_file"); MPASS(cnp->cn_flags & HASBUF); tmp = VFS_TO_TMPFS(dvp->v_mount); @@ -708,8 +738,8 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap, /* Allocate a node that represents the new file. */ error = tmpfs_alloc_node(dvp->v_mount, tmp, vap->va_type, - cnp->cn_cred->cr_uid, - dnode->tn_gid, vap->va_mode, parent, target, vap->va_rdev, &node); + cnp->cn_cred->cr_uid, dnode->tn_gid, vap->va_mode, parent, + target, vap->va_rdev, &node); if (error != 0) return (error); @@ -738,7 +768,7 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap, return (0); } -static struct tmpfs_dirent * +struct tmpfs_dirent * tmpfs_dir_first(struct tmpfs_node *dnode, struct tmpfs_dir_cursor *dc) { struct tmpfs_dirent *de; @@ -752,7 +782,7 @@ tmpfs_dir_first(struct tmpfs_node *dnode, struct tmpfs_dir_cursor *dc) return (dc->tdc_current); } -static struct tmpfs_dirent * +struct tmpfs_dirent * tmpfs_dir_next(struct tmpfs_node *dnode, struct tmpfs_dir_cursor *dc) { struct tmpfs_dirent *de; @@ -1092,9 +1122,9 @@ tmpfs_dir_getdotdent(struct tmpfs_node *node, struct uio *uio) else error = uiomove(&dent, dent.d_reclen, uio); - node->tn_status |= TMPFS_NODE_ACCESSED; + tmpfs_set_status(node, TMPFS_NODE_ACCESSED); - return error; + return (error); } /* @@ -1117,9 +1147,8 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio) * Return ENOENT if the current node is already removed. */ TMPFS_ASSERT_LOCKED(node); - if (node->tn_dir.tn_parent == NULL) { + if (node->tn_dir.tn_parent == NULL) return (ENOENT); - } TMPFS_NODE_LOCK(node->tn_dir.tn_parent); dent.d_fileno = node->tn_dir.tn_parent->tn_id; @@ -1137,9 +1166,9 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio) else error = uiomove(&dent, dent.d_reclen, uio); - node->tn_status |= TMPFS_NODE_ACCESSED; + tmpfs_set_status(node, TMPFS_NODE_ACCESSED); - return error; + return (error); } /* @@ -1282,7 +1311,7 @@ tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int maxcookies, node->tn_dir.tn_readdir_lastn = off; node->tn_dir.tn_readdir_lastp = de; - node->tn_status |= TMPFS_NODE_ACCESSED; + tmpfs_set_status(node, TMPFS_NODE_ACCESSED); return error; } @@ -1413,9 +1442,7 @@ retry: uobj->size = newpages; VM_OBJECT_WUNLOCK(uobj); - TMPFS_LOCK(tmp); - tmp->tm_pages_used += (newpages - oldpages); - TMPFS_UNLOCK(tmp); + atomic_add_long(&tmp->tm_pages_used, newpages - oldpages); node->tn_size = newsize; return (0); @@ -1458,7 +1485,7 @@ tmpfs_chflags(struct vnode *vp, u_long flags, struct ucred *cred, int error; struct tmpfs_node *node; - MPASS(VOP_ISLOCKED(vp)); + ASSERT_VOP_ELOCKED(vp, "chflags"); node = VP_TO_TMPFS_NODE(vp); @@ -1498,9 +1525,9 @@ tmpfs_chflags(struct vnode *vp, u_long flags, struct ucred *cred, node->tn_flags = flags; node->tn_status |= TMPFS_NODE_CHANGED; - MPASS(VOP_ISLOCKED(vp)); + ASSERT_VOP_ELOCKED(vp, "chflags2"); - return 0; + return (0); } /* @@ -1514,7 +1541,7 @@ tmpfs_chmod(struct vnode *vp, mode_t mode, struct ucred *cred, struct thread *p) int error; struct tmpfs_node *node; - MPASS(VOP_ISLOCKED(vp)); + ASSERT_VOP_ELOCKED(vp, "chmod"); node = VP_TO_TMPFS_NODE(vp); @@ -1554,9 +1581,9 @@ tmpfs_chmod(struct vnode *vp, mode_t mode, struct ucred *cred, struct thread *p) node->tn_status |= TMPFS_NODE_CHANGED; - MPASS(VOP_ISLOCKED(vp)); + ASSERT_VOP_ELOCKED(vp, "chmod2"); - return 0; + return (0); } /* @@ -1575,7 +1602,7 @@ tmpfs_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred, uid_t ouid; gid_t ogid; - MPASS(VOP_ISLOCKED(vp)); + ASSERT_VOP_ELOCKED(vp, "chown"); node = VP_TO_TMPFS_NODE(vp); @@ -1625,9 +1652,9 @@ tmpfs_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred, node->tn_mode &= ~(S_ISUID | S_ISGID); } - MPASS(VOP_ISLOCKED(vp)); + ASSERT_VOP_ELOCKED(vp, "chown2"); - return 0; + return (0); } /* @@ -1642,7 +1669,7 @@ tmpfs_chsize(struct vnode *vp, u_quad_t size, struct ucred *cred, int error; struct tmpfs_node *node; - MPASS(VOP_ISLOCKED(vp)); + ASSERT_VOP_ELOCKED(vp, "chsize"); node = VP_TO_TMPFS_NODE(vp); @@ -1680,9 +1707,9 @@ tmpfs_chsize(struct vnode *vp, u_quad_t size, struct ucred *cred, /* tmpfs_truncate will raise the NOTE_EXTEND and NOTE_ATTRIB kevents * for us, as will update tn_status; no need to do that here. */ - MPASS(VOP_ISLOCKED(vp)); + ASSERT_VOP_ELOCKED(vp, "chsize2"); - return error; + return (error); } /* @@ -1697,7 +1724,7 @@ tmpfs_chtimes(struct vnode *vp, struct vattr *vap, int error; struct tmpfs_node *node; - MPASS(VOP_ISLOCKED(vp)); + ASSERT_VOP_ELOCKED(vp, "chtimes"); node = VP_TO_TMPFS_NODE(vp); @@ -1728,9 +1755,20 @@ tmpfs_chtimes(struct vnode *vp, struct vattr *vap, if (vap->va_birthtime.tv_nsec != VNOVAL && vap->va_birthtime.tv_nsec != VNOVAL) node->tn_birthtime = vap->va_birthtime; - MPASS(VOP_ISLOCKED(vp)); + ASSERT_VOP_ELOCKED(vp, "chtimes2"); - return 0; + return (0); +} + +void +tmpfs_set_status(struct tmpfs_node *node, int status) +{ + + if ((node->tn_status & status) == status) + return; + TMPFS_NODE_LOCK(node); + node->tn_status |= status; + TMPFS_NODE_UNLOCK(node); } /* Sync timestamps */ @@ -1741,6 +1779,7 @@ tmpfs_itimes(struct vnode *vp, const struct timespec *acc, struct tmpfs_node *node; struct timespec now; + ASSERT_VOP_LOCKED(vp, "tmpfs_itimes"); node = VP_TO_TMPFS_NODE(vp); if ((node->tn_status & (TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED | @@ -1748,6 +1787,7 @@ tmpfs_itimes(struct vnode *vp, const struct timespec *acc, return; vfs_timestamp(&now); + TMPFS_NODE_LOCK(node); if (node->tn_status & TMPFS_NODE_ACCESSED) { if (acc == NULL) acc = &now; @@ -1758,11 +1798,12 @@ tmpfs_itimes(struct vnode *vp, const struct timespec *acc, mod = &now; node->tn_mtime = *mod; } - if (node->tn_status & TMPFS_NODE_CHANGED) { + if (node->tn_status & TMPFS_NODE_CHANGED) node->tn_ctime = now; - } - node->tn_status &= - ~(TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED | TMPFS_NODE_CHANGED); + node->tn_status &= ~(TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED | + TMPFS_NODE_CHANGED); + TMPFS_NODE_UNLOCK(node); + } void @@ -1794,14 +1835,13 @@ tmpfs_truncate(struct vnode *vp, off_t length) return (EFBIG); error = tmpfs_reg_resize(vp, length, FALSE); - if (error == 0) { + if (error == 0) node->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; - } out: tmpfs_update(vp); - return error; + return (error); } static __inline int diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c index 7af143b..65a2a12 100644 --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -78,7 +78,7 @@ static int tmpfs_statfs(struct mount *, struct statfs *); static const char *tmpfs_opts[] = { "from", "size", "maxfilesize", "inodes", "uid", "gid", "mode", "export", - "union", NULL + "union", "nonc", NULL }; static const char *tmpfs_updateopts[] = { @@ -137,6 +137,7 @@ tmpfs_mount(struct mount *mp) struct tmpfs_node *root; struct thread *td = curthread; int error; + bool nonc; /* Size counters. */ u_quad_t pages; off_t nodes_max, size_max, maxfilesize; @@ -185,11 +186,12 @@ tmpfs_mount(struct mount *mp) size_max = 0; if (vfs_getopt_size(mp->mnt_optnew, "maxfilesize", &maxfilesize) != 0) maxfilesize = 0; + nonc = vfs_getopt(mp->mnt_optnew, "nonc", NULL, NULL) == 0; /* Do not allow mounts if we do not have enough memory to preserve * the minimum reserved pages. */ if (tmpfs_mem_avail() < TMPFS_PAGES_MINRESERVED) - return ENOSPC; + return (ENOSPC); /* Get the maximum number of memory pages this file system is * allowed to use, based on the maximum size the user passed in @@ -218,37 +220,35 @@ tmpfs_mount(struct mount *mp) tmp = (struct tmpfs_mount *)malloc(sizeof(struct tmpfs_mount), M_TMPFSMNT, M_WAITOK | M_ZERO); - mtx_init(&tmp->allnode_lock, "tmpfs allnode lock", NULL, MTX_DEF); + mtx_init(&tmp->tm_allnode_lock, "tmpfs allnode lock", NULL, MTX_DEF); tmp->tm_nodes_max = nodes_max; tmp->tm_nodes_inuse = 0; + tmp->tm_refcount = 1; tmp->tm_maxfilesize = maxfilesize > 0 ? maxfilesize : OFF_MAX; LIST_INIT(&tmp->tm_nodes_used); tmp->tm_pages_max = pages; tmp->tm_pages_used = 0; - tmp->tm_ino_unr = new_unrhdr(2, INT_MAX, &tmp->allnode_lock); + tmp->tm_ino_unr = new_unrhdr(2, INT_MAX, &tmp->tm_allnode_lock); tmp->tm_dirent_pool = uma_zcreate("TMPFS dirent", - sizeof(struct tmpfs_dirent), - NULL, NULL, NULL, NULL, + sizeof(struct tmpfs_dirent), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); tmp->tm_node_pool = uma_zcreate("TMPFS node", - sizeof(struct tmpfs_node), - tmpfs_node_ctor, tmpfs_node_dtor, - tmpfs_node_init, tmpfs_node_fini, - UMA_ALIGN_PTR, 0); + sizeof(struct tmpfs_node), tmpfs_node_ctor, tmpfs_node_dtor, + tmpfs_node_init, tmpfs_node_fini, UMA_ALIGN_PTR, 0); tmp->tm_ronly = (mp->mnt_flag & MNT_RDONLY) != 0; + tmp->tm_nonc = nonc; /* Allocate the root node. */ - error = tmpfs_alloc_node(mp, tmp, VDIR, root_uid, - root_gid, root_mode & ALLPERMS, NULL, NULL, - VNOVAL, &root); + error = tmpfs_alloc_node(mp, tmp, VDIR, root_uid, root_gid, + root_mode & ALLPERMS, NULL, NULL, VNOVAL, &root); if (error != 0 || root == NULL) { - uma_zdestroy(tmp->tm_node_pool); - uma_zdestroy(tmp->tm_dirent_pool); - delete_unrhdr(tmp->tm_ino_unr); - free(tmp, M_TMPFSMNT); - return error; + uma_zdestroy(tmp->tm_node_pool); + uma_zdestroy(tmp->tm_dirent_pool); + delete_unrhdr(tmp->tm_ino_unr); + free(tmp, M_TMPFSMNT); + return (error); } KASSERT(root->tn_id == 2, ("tmpfs root with invalid ino: %ju", (uintmax_t)root->tn_id)); @@ -306,25 +306,17 @@ tmpfs_unmount(struct mount *mp, int mntflags) TMPFS_LOCK(tmp); while ((node = LIST_FIRST(&tmp->tm_nodes_used)) != NULL) { - TMPFS_UNLOCK(tmp); + TMPFS_NODE_LOCK(node); if (node->tn_type == VDIR) tmpfs_dir_destroy(tmp, node); - tmpfs_free_node(tmp, node); - TMPFS_LOCK(tmp); + if (tmpfs_free_node_locked(tmp, node, true)) + TMPFS_LOCK(tmp); + else + TMPFS_NODE_UNLOCK(node); } - TMPFS_UNLOCK(tmp); - - uma_zdestroy(tmp->tm_dirent_pool); - uma_zdestroy(tmp->tm_node_pool); - delete_unrhdr(tmp->tm_ino_unr); - mtx_destroy(&tmp->allnode_lock); - MPASS(tmp->tm_pages_used == 0); - MPASS(tmp->tm_nodes_inuse == 0); - - /* Throw away the tmpfs_mount structure. */ - free(mp->mnt_data, M_TMPFSMNT); mp->mnt_data = NULL; + tmpfs_free_tmp(tmp); vfs_write_resume(mp, VR_START_WRITE); MNT_ILOCK(mp); @@ -334,52 +326,74 @@ tmpfs_unmount(struct mount *mp, int mntflags) return (0); } +void +tmpfs_free_tmp(struct tmpfs_mount *tmp) +{ + + MPASS(tmp->tm_refcount > 0); + tmp->tm_refcount--; + if (tmp->tm_refcount > 0) { + TMPFS_UNLOCK(tmp); + return; + } + TMPFS_UNLOCK(tmp); + + uma_zdestroy(tmp->tm_dirent_pool); + uma_zdestroy(tmp->tm_node_pool); + delete_unrhdr(tmp->tm_ino_unr); + + mtx_destroy(&tmp->tm_allnode_lock); + MPASS(tmp->tm_pages_used == 0); + MPASS(tmp->tm_nodes_inuse == 0); + + free(tmp, M_TMPFSMNT); +} + static int tmpfs_root(struct mount *mp, int flags, struct vnode **vpp) { int error; - error = tmpfs_alloc_vp(mp, VFS_TO_TMPFS(mp)->tm_root, flags, vpp); - if (!error) + error = tmpfs_alloc_vp(mp, VFS_TO_TMPFS(mp)->tm_root, flags, vpp); + if (error == 0) (*vpp)->v_vflag |= VV_ROOT; - - return error; + return (error); } static int tmpfs_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp) { - boolean_t found; struct tmpfs_fid *tfhp; struct tmpfs_mount *tmp; struct tmpfs_node *node; + int error; tmp = VFS_TO_TMPFS(mp); tfhp = (struct tmpfs_fid *)fhp; if (tfhp->tf_len != sizeof(struct tmpfs_fid)) - return EINVAL; + return (EINVAL); if (tfhp->tf_id >= tmp->tm_nodes_max) - return EINVAL; - - found = FALSE; + return (EINVAL); TMPFS_LOCK(tmp); LIST_FOREACH(node, &tmp->tm_nodes_used, tn_entries) { if (node->tn_id == tfhp->tf_id && node->tn_gen == tfhp->tf_gen) { - found = TRUE; + tmpfs_ref_node(node); break; } } TMPFS_UNLOCK(tmp); - if (found) - return (tmpfs_alloc_vp(mp, node, LK_EXCLUSIVE, vpp)); - - return (EINVAL); + if (node != NULL) { + error = tmpfs_alloc_vp(mp, node, LK_EXCLUSIVE, vpp); + tmpfs_free_node(tmp, node); + } else + error = EINVAL; + return (error); } /* ARGSUSED2 */ @@ -395,7 +409,7 @@ tmpfs_statfs(struct mount *mp, struct statfs *sbp) sbp->f_bsize = PAGE_SIZE; used = tmpfs_pages_used(tmp); - if (tmp->tm_pages_max != SIZE_MAX) + if (tmp->tm_pages_max != ULONG_MAX) sbp->f_blocks = tmp->tm_pages_max; else sbp->f_blocks = used + tmpfs_mem_avail(); diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index f01c8be..6d6982f 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -76,13 +76,11 @@ tmpfs_vn_get_ino_alloc(struct mount *mp, void *arg, int lkflags, } static int -tmpfs_lookup(struct vop_cachedlookup_args *v) +tmpfs_lookup1(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) { - struct vnode *dvp = v->a_dvp; - struct vnode **vpp = v->a_vpp; - struct componentname *cnp = v->a_cnp; struct tmpfs_dirent *de; - struct tmpfs_node *dnode; + struct tmpfs_node *dnode, *pnode; + struct tmpfs_mount *tm; int error; dnode = VP_TO_TMPFS_DIR(dvp); @@ -104,8 +102,12 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) goto out; } if (cnp->cn_flags & ISDOTDOT) { + tm = VFS_TO_TMPFS(dvp->v_mount); + pnode = dnode->tn_dir.tn_parent; + tmpfs_ref_node(pnode); error = vn_vget_ino_gen(dvp, tmpfs_vn_get_ino_alloc, - dnode->tn_dir.tn_parent, cnp->cn_lkflags, vpp); + pnode, cnp->cn_lkflags, vpp); + tmpfs_free_node(tm, pnode); if (error != 0) goto out; } else if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') { @@ -117,10 +119,12 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) if (de != NULL && de->td_node == NULL) cnp->cn_flags |= ISWHITEOUT; if (de == NULL || de->td_node == NULL) { - /* The entry was not found in the directory. + /* + * The entry was not found in the directory. * This is OK if we are creating or renaming an * entry and are working on the last component of - * the path name. */ + * the path name. + */ if ((cnp->cn_flags & ISLASTCN) && (cnp->cn_nameiop == CREATE || \ cnp->cn_nameiop == RENAME || @@ -132,8 +136,10 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) if (error != 0) goto out; - /* Keep the component name in the buffer for - * future uses. */ + /* + * Keep the component name in the buffer for + * future uses. + */ cnp->cn_flags |= SAVENAME; error = EJUSTRETURN; @@ -142,14 +148,18 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) } else { struct tmpfs_node *tnode; - /* The entry was found, so get its associated - * tmpfs_node. */ + /* + * The entry was found, so get its associated + * tmpfs_node. + */ tnode = de->td_node; - /* If we are not at the last path component and + /* + * If we are not at the last path component and * found a non-directory or non-link entry (which * may itself be pointing to a directory), raise - * an error. */ + * an error. + */ if ((tnode->tn_type != VDIR && tnode->tn_type != VLNK) && !(cnp->cn_flags & ISLASTCN)) { @@ -157,9 +167,11 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) goto out; } - /* If we are deleting or renaming the entry, keep + /* + * If we are deleting or renaming the entry, keep * track of its tmpfs_dirent so that it can be - * easily deleted later. */ + * easily deleted later. + */ if ((cnp->cn_flags & ISLASTCN) && (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { @@ -175,8 +187,9 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) goto out; if ((dnode->tn_mode & S_ISTXT) && - VOP_ACCESS(dvp, VADMIN, cnp->cn_cred, cnp->cn_thread) && - VOP_ACCESS(*vpp, VADMIN, cnp->cn_cred, cnp->cn_thread)) { + VOP_ACCESS(dvp, VADMIN, cnp->cn_cred, + cnp->cn_thread) && VOP_ACCESS(*vpp, VADMIN, + cnp->cn_cred, cnp->cn_thread)) { error = EPERM; vput(*vpp); *vpp = NULL; @@ -192,18 +205,36 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) } } - /* Store the result of this lookup in the cache. Avoid this if the + /* + * Store the result of this lookup in the cache. Avoid this if the * request was for creation, as it does not improve timings on - * emprical tests. */ - if ((cnp->cn_flags & MAKEENTRY) != 0) + * emprical tests. + */ + if ((cnp->cn_flags & MAKEENTRY) != 0 && tmpfs_use_nc(dvp)) cache_enter(dvp, *vpp, cnp); out: - /* If there were no errors, *vpp cannot be null and it must be - * locked. */ + /* + * If there were no errors, *vpp cannot be null and it must be + * locked. + */ MPASS(IFF(error == 0, *vpp != NULLVP && VOP_ISLOCKED(*vpp))); - return error; + return (error); +} + +static int +tmpfs_cached_lookup(struct vop_cachedlookup_args *v) +{ + + return (tmpfs_lookup1(v->a_dvp, v->a_vpp, v->a_cnp)); +} + +static int +tmpfs_lookup(struct vop_lookup_args *v) +{ + + return (tmpfs_lookup1(v->a_dvp, v->a_vpp, v->a_cnp)); } static int @@ -218,7 +249,7 @@ tmpfs_create(struct vop_create_args *v) MPASS(vap->va_type == VREG || vap->va_type == VSOCK); error = tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL); - if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0) + if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0 && tmpfs_use_nc(dvp)) cache_enter(dvp, *vpp, cnp); return (error); } @@ -441,7 +472,7 @@ tmpfs_read(struct vop_read_args *v) if (uio->uio_offset < 0) return (EINVAL); node = VP_TO_TMPFS_NODE(vp); - node->tn_status |= TMPFS_NODE_ACCESSED; + tmpfs_set_status(node, TMPFS_NODE_ACCESSED); return (uiomove_object(node->tn_reg.tn_aobj, node->tn_size, uio)); } @@ -989,10 +1020,12 @@ tmpfs_rename(struct vop_rename_args *v) tmpfs_dir_attach(tdvp, de); - cache_purge(fvp); - if (tvp != NULL) - cache_purge(tvp); - cache_purge_negative(tdvp); + if (tmpfs_use_nc(fvp)) { + cache_purge(fvp); + if (tvp != NULL) + cache_purge(tvp); + cache_purge_negative(tdvp); + } error = 0; @@ -1078,8 +1111,8 @@ tmpfs_rmdir(struct vop_rmdir_args *v) v->a_cnp->cn_namelen)); /* Check flags to see if we are allowed to remove the directory. */ - if (dnode->tn_flags & APPEND - || node->tn_flags & (NOUNLINK | IMMUTABLE | APPEND)) { + if ((dnode->tn_flags & APPEND) != 0 || + (node->tn_flags & (NOUNLINK | IMMUTABLE | APPEND)) != 0) { error = EPERM; goto out; } @@ -1092,23 +1125,23 @@ tmpfs_rmdir(struct vop_rmdir_args *v) /* No vnode should be allocated for this entry from this point */ TMPFS_NODE_LOCK(node); - TMPFS_ASSERT_ELOCKED(node); node->tn_links--; node->tn_dir.tn_parent = NULL; - node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \ + node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; TMPFS_NODE_UNLOCK(node); TMPFS_NODE_LOCK(dnode); - TMPFS_ASSERT_ELOCKED(dnode); dnode->tn_links--; - dnode->tn_status |= TMPFS_NODE_ACCESSED | \ - TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; + dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | + TMPFS_NODE_MODIFIED; TMPFS_NODE_UNLOCK(dnode); - cache_purge(dvp); - cache_purge(vp); + if (tmpfs_use_nc(dvp)) { + cache_purge(dvp); + cache_purge(vp); + } /* Free the directory entry we just deleted. Note that the node * referred by it will not be removed until the vnode is really @@ -1216,9 +1249,9 @@ tmpfs_readlink(struct vop_readlink_args *v) error = uiomove(node->tn_link, MIN(node->tn_size, uio->uio_resid), uio); - node->tn_status |= TMPFS_NODE_ACCESSED; + tmpfs_set_status(node, TMPFS_NODE_ACCESSED); - return error; + return (error); } static int @@ -1252,10 +1285,10 @@ tmpfs_reclaim(struct vop_reclaim_args *v) else vnode_destroy_vobject(vp); vp->v_object = NULL; - cache_purge(vp); + if (tmpfs_use_nc(vp)) + cache_purge(vp); TMPFS_NODE_LOCK(node); - TMPFS_ASSERT_ELOCKED(node); tmpfs_free_vp(vp); /* If the node referenced by this vnode was deleted by the user, @@ -1385,13 +1418,139 @@ tmpfs_whiteout(struct vop_whiteout_args *ap) } } +static int +tmpfs_vptocnp_dir(struct tmpfs_node *tn, struct tmpfs_node *tnp, + struct tmpfs_dirent **pde) +{ + struct tmpfs_dir_cursor dc; + struct tmpfs_dirent *de; + + for (de = tmpfs_dir_first(tnp, &dc); de != NULL; + de = tmpfs_dir_next(tnp, &dc)) { + if (de->td_node == tn) { + *pde = de; + return (0); + } + } + return (ENOENT); +} + +static int +tmpfs_vptocnp_fill(struct vnode *vp, struct tmpfs_node *tn, + struct tmpfs_node *tnp, char *buf, int *buflen, struct vnode **dvp) +{ + struct tmpfs_dirent *de; + int error, i; + + error = vn_vget_ino_gen(vp, tmpfs_vn_get_ino_alloc, tnp, LK_SHARED, + dvp); + if (error != 0) + return (error); + error = tmpfs_vptocnp_dir(tn, tnp, &de); + if (error == 0) { + i = *buflen; + i -= de->td_namelen; + if (i < 0) { + error = ENOMEM; + } else { + bcopy(de->ud.td_name, buf + i, de->td_namelen); + *buflen = i; + } + } + if (error == 0) { + if (vp != *dvp) + VOP_UNLOCK(*dvp, 0); + } else { + if (vp != *dvp) + vput(*dvp); + else + vrele(vp); + } + return (error); +} + +static int +tmpfs_vptocnp(struct vop_vptocnp_args *ap) +{ + struct vnode *vp, **dvp; + struct tmpfs_node *tn, *tnp, *tnp1; + struct tmpfs_dirent *de; + struct tmpfs_mount *tm; + char *buf; + int *buflen; + int error; + + vp = ap->a_vp; + dvp = ap->a_vpp; + buf = ap->a_buf; + buflen = ap->a_buflen; + + tm = VFS_TO_TMPFS(vp->v_mount); + tn = VP_TO_TMPFS_NODE(vp); + if (tn->tn_type == VDIR) { + tnp = tn->tn_dir.tn_parent; + if (tnp == NULL) + return (ENOENT); + tmpfs_ref_node(tnp); + error = tmpfs_vptocnp_fill(vp, tn, tn->tn_dir.tn_parent, buf, + buflen, dvp); + tmpfs_free_node(tm, tnp); + return (error); + } +restart: + TMPFS_LOCK(tm); + LIST_FOREACH_SAFE(tnp, &tm->tm_nodes_used, tn_entries, tnp1) { + if (tnp->tn_type != VDIR) + continue; + TMPFS_NODE_LOCK(tnp); + tmpfs_ref_node_locked(tnp); + + /* + * tn_vnode cannot be instantiated while we hold the + * node lock, so the directory cannot be changed while + * we iterate over it. Do this to avoid instantiating + * vnode for directories which cannot point to our + * node. + */ + error = tnp->tn_vnode == NULL ? tmpfs_vptocnp_dir(tn, tnp, + &de) : 0; + + if (error == 0) { + TMPFS_NODE_UNLOCK(tnp); + TMPFS_UNLOCK(tm); + error = tmpfs_vptocnp_fill(vp, tn, tnp, buf, buflen, + dvp); + if (error == 0) { + tmpfs_free_node(tm, tnp); + return (0); + } + if ((vp->v_iflag & VI_DOOMED) != 0) { + tmpfs_free_node(tm, tnp); + return (ENOENT); + } + TMPFS_LOCK(tm); + TMPFS_NODE_LOCK(tnp); + } + if (tmpfs_free_node_locked(tm, tnp, false)) { + goto restart; + } else { + KASSERT(tnp->tn_refcount > 0, + ("node %p refcount zero", tnp)); + tnp1 = LIST_NEXT(tnp, tn_entries); + TMPFS_NODE_UNLOCK(tnp); + } + } + TMPFS_UNLOCK(tm); + return (ENOENT); +} + /* - * vnode operations vector used for files stored in a tmpfs file system. + * Vnode operations vector used for files stored in a tmpfs file system. */ struct vop_vector tmpfs_vnodeop_entries = { .vop_default = &default_vnodeops, .vop_lookup = vfs_cache_lookup, - .vop_cachedlookup = tmpfs_lookup, + .vop_cachedlookup = tmpfs_cached_lookup, .vop_create = tmpfs_create, .vop_mknod = tmpfs_mknod, .vop_open = tmpfs_open, @@ -1417,5 +1576,13 @@ struct vop_vector tmpfs_vnodeop_entries = { .vop_vptofh = tmpfs_vptofh, .vop_whiteout = tmpfs_whiteout, .vop_bmap = VOP_EOPNOTSUPP, + .vop_vptocnp = tmpfs_vptocnp, }; +/* + * Same vector for mounts which do not use namecache. + */ +struct vop_vector tmpfs_vnodeop_nonc_entries = { + .vop_default = &tmpfs_vnodeop_entries, + .vop_lookup = tmpfs_lookup, +}; diff --git a/sys/fs/tmpfs/tmpfs_vnops.h b/sys/fs/tmpfs/tmpfs_vnops.h index 1e06c13..db614a05 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.h +++ b/sys/fs/tmpfs/tmpfs_vnops.h @@ -44,6 +44,7 @@ */ extern struct vop_vector tmpfs_vnodeop_entries; +extern struct vop_vector tmpfs_vnodeop_nonc_entries; vop_access_t tmpfs_access; vop_getattr_t tmpfs_getattr; diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c index a0a357f..18402c4 100644 --- a/sys/geom/geom_disk.c +++ b/sys/geom/geom_disk.c @@ -589,12 +589,12 @@ g_disk_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g * special cases, and there's also a valid range. */ sbuf_printf(sb, "%s<rotationrate>", indent); - if (dp->d_rotation_rate == 0) /* Old drives don't */ - sbuf_printf(sb, "unknown"); /* report RPM. */ - else if (dp->d_rotation_rate == 1) /* Since 0 is used */ - sbuf_printf(sb, "0"); /* above, SSDs use 1. */ - else if ((dp->d_rotation_rate >= 0x041) && - (dp->d_rotation_rate <= 0xfffe)) + if (dp->d_rotation_rate == DISK_RR_UNKNOWN) /* Old drives */ + sbuf_printf(sb, "unknown"); /* don't report RPM. */ + else if (dp->d_rotation_rate == DISK_RR_NON_ROTATING) + sbuf_printf(sb, "0"); + else if ((dp->d_rotation_rate >= DISK_RR_MIN) && + (dp->d_rotation_rate <= DISK_RR_MAX)) sbuf_printf(sb, "%u", dp->d_rotation_rate); else sbuf_printf(sb, "invalid"); diff --git a/sys/geom/geom_disk.h b/sys/geom/geom_disk.h index 09194c0..948c664 100644 --- a/sys/geom/geom_disk.h +++ b/sys/geom/geom_disk.h @@ -113,6 +113,11 @@ struct disk { #define DISKFLAG_DIRECT_COMPLETION 0x20 #define DISKFLAG_LACKS_ROTRATE 0x40 +#define DISK_RR_UNKNOWN 0 +#define DISK_RR_NON_ROTATING 1 +#define DISK_RR_MIN 0x0401 +#define DISK_RR_MAX 0xfffe + struct disk *disk_alloc(void); void disk_create(struct disk *disk, int version); void disk_destroy(struct disk *disk); diff --git a/sys/geom/multipath/g_multipath.c b/sys/geom/multipath/g_multipath.c index b461747..0c24cd3 100644 --- a/sys/geom/multipath/g_multipath.c +++ b/sys/geom/multipath/g_multipath.c @@ -923,6 +923,7 @@ g_multipath_ctl_add_name(struct gctl_req *req, struct g_class *mp, struct g_provider *pp; const char *mpname; static const char devpf[6] = "/dev/"; + int error; g_topology_assert(); @@ -972,10 +973,9 @@ g_multipath_ctl_add_name(struct gctl_req *req, struct g_class *mp, return; } - /* - * Now add.... - */ - (void) g_multipath_add_disk(gp, pp); + error = g_multipath_add_disk(gp, pp); + if (error != 0) + gctl_error(req, "Provider addition error: %d", error); } static void diff --git a/sys/geom/vinum/geom_vinum_state.c b/sys/geom/vinum/geom_vinum_state.c index 568c784..67486da 100644 --- a/sys/geom/vinum/geom_vinum_state.c +++ b/sys/geom/vinum/geom_vinum_state.c @@ -183,7 +183,7 @@ gv_set_sd_state(struct gv_sd *s, int newstate, int flags) * Only do this if we're forced, since it usually is done * internally, and then we do use the force flag. */ - if (!flags & GV_SETSTATE_FORCE) + if (!(flags & GV_SETSTATE_FORCE)) return (GV_ERR_SETSTATE); break; diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c index 7025021..bc6a55b 100644 --- a/sys/i386/i386/initcpu.c +++ b/sys/i386/i386/initcpu.c @@ -826,14 +826,18 @@ initializecpucache(void) * CPUID_SS feature even though the native CPU supports it. */ TUNABLE_INT_FETCH("hw.clflush_disable", &hw_clflush_disable); - if (vm_guest != VM_GUEST_NO && hw_clflush_disable == -1) + if (vm_guest != VM_GUEST_NO && hw_clflush_disable == -1) { cpu_feature &= ~CPUID_CLFSH; + cpu_stdext_feature &= ~CPUID_STDEXT_CLFLUSHOPT; + } /* - * Allow to disable CLFLUSH feature manually by - * hw.clflush_disable tunable. + * The kernel's use of CLFLUSH{,OPT} can be disabled manually + * by setting the hw.clflush_disable tunable. */ - if (hw_clflush_disable == 1) + if (hw_clflush_disable == 1) { cpu_feature &= ~CPUID_CLFSH; + cpu_stdext_feature &= ~CPUID_STDEXT_CLFLUSHOPT; + } #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) /* diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index f55900c..607b08b 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -3157,8 +3157,7 @@ init386(first) #else register_t -init386(first) - int first; +init386(int first) { struct gate_descriptor *gdp; int gsel_tss, metadata_missing, x, pa; diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 299ee77..c383f34 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -517,7 +517,14 @@ pmap_bootstrap(vm_paddr_t firstaddr) for (i = 1; i < NKPT; i++) PTD[i] = 0; - /* Initialize the PAT MSR if present. */ + /* + * Initialize the PAT MSR if present. + * pmap_init_pat() clears and sets CR4_PGE, which, as a + * side-effect, invalidates stale PG_G TLB entries that might + * have been created in our pre-boot environment. We assume + * that PAT support implies PGE and in reverse, PGE presence + * comes with PAT. Both features were added for Pentium Pro. + */ pmap_init_pat(); /* Turn on PG_G on kernel page(s) */ @@ -545,7 +552,10 @@ pmap_init_pat(void) pat_table[PAT_WRITE_PROTECTED] = 3; pat_table[PAT_UNCACHED] = 3; - /* Bail if this CPU doesn't implement PAT. */ + /* + * Bail if this CPU doesn't implement PAT. + * We assume that PAT support implies PGE. + */ if ((cpu_feature & CPUID_PAT) == 0) { for (i = 0; i < PAT_INDEX_SIZE; i++) pat_index[i] = pat_table[i]; @@ -1222,9 +1232,8 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) if ((cpu_feature & CPUID_SS) != 0 && !force) ; /* If "Self Snoop" is supported and allowed, do nothing. */ - else if ((cpu_feature & CPUID_CLFSH) != 0 && + else if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0 && eva - sva < PMAP_CLFLUSH_THRESHOLD) { - #ifdef DEV_APIC /* * XXX: Some CPUs fault, hang, or trash the local APIC @@ -1236,16 +1245,29 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) return; #endif /* - * Otherwise, do per-cache line flush. Use the mfence + * Otherwise, do per-cache line flush. Use the sfence * instruction to insure that previous stores are * included in the write-back. The processor * propagates flush to other processors in the cache * coherence domain. */ - mfence(); + sfence(); + for (; sva < eva; sva += cpu_clflush_line_size) + clflushopt(sva); + sfence(); + } else if ((cpu_feature & CPUID_CLFSH) != 0 && + eva - sva < PMAP_CLFLUSH_THRESHOLD) { + if (pmap_kextract(sva) == lapic_paddr) + return; + /* + * Writes are ordered by CLFLUSH on Intel CPUs. + */ + if (cpu_vendor_id != CPU_VENDOR_INTEL) + mfence(); for (; sva < eva; sva += cpu_clflush_line_size) clflush(sva); - mfence(); + if (cpu_vendor_id != CPU_VENDOR_INTEL) + mfence(); } else { /* @@ -2675,6 +2697,7 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) vm_paddr_t mptepa; vm_page_t mpte; struct spglist free; + vm_offset_t sva; PMAP_LOCK_ASSERT(pmap, MA_OWNED); oldpde = *pde; @@ -2697,8 +2720,9 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va) va >> PDRSHIFT, VM_ALLOC_NOOBJ | VM_ALLOC_NORMAL | VM_ALLOC_WIRED)) == NULL) { SLIST_INIT(&free); - pmap_remove_pde(pmap, pde, trunc_4mpage(va), &free); - pmap_invalidate_page(pmap, trunc_4mpage(va)); + sva = trunc_4mpage(va); + pmap_remove_pde(pmap, pde, sva, &free); + pmap_invalidate_range(pmap, sva, sva + NBPDR - 1); pmap_free_zero_pages(&free); CTR2(KTR_PMAP, "pmap_demote_pde: failure for va %#x" " in pmap %p", va, pmap); @@ -2869,9 +2893,24 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva, /* * Machines that don't support invlpg, also don't support * PG_G. + * + * When workaround_erratum383 is false, a promotion to a 2M/4M + * page mapping does not invalidate the 512/1024 4K page mappings + * from the TLB. Consequently, at this point, the TLB may + * hold both 4K and 2M/4M page mappings. Therefore, the entire + * range of addresses must be invalidated here. In contrast, + * when workaround_erratum383 is true, a promotion does + * invalidate the 512/1024 4K page mappings, and so a single INVLPG + * suffices to invalidate the 2M/4M page mapping. */ - if (oldpde & PG_G) - pmap_invalidate_page(kernel_pmap, sva); + if ((oldpde & PG_G) != 0) { + if (workaround_erratum383) + pmap_invalidate_page(kernel_pmap, sva); + else + pmap_invalidate_range(kernel_pmap, sva, + sva + NBPDR - 1); + } + pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE; if (oldpde & PG_MANAGED) { pvh = pa_to_pvh(oldpde & PG_PS_FRAME); @@ -3181,9 +3220,14 @@ retry: if (newpde != oldpde) { if (!pde_cmpset(pde, oldpde, newpde)) goto retry; - if (oldpde & PG_G) - pmap_invalidate_page(pmap, sva); - else + if (oldpde & PG_G) { + /* See pmap_remove_pde() for explanation. */ + if (workaround_erratum383) + pmap_invalidate_page(kernel_pmap, sva); + else + pmap_invalidate_range(kernel_pmap, sva, + sva + NBPDR - 1); + } else anychanged = TRUE; } return (anychanged); @@ -5316,8 +5360,10 @@ pmap_flush_page(vm_page_t m) { struct sysmaps *sysmaps; vm_offset_t sva, eva; + bool useclflushopt; - if ((cpu_feature & CPUID_CLFSH) != 0) { + useclflushopt = (cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0; + if (useclflushopt || (cpu_feature & CPUID_CLFSH) != 0) { sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)]; mtx_lock(&sysmaps->lock); if (*sysmaps->CMAP2) @@ -5330,14 +5376,25 @@ pmap_flush_page(vm_page_t m) eva = sva + PAGE_SIZE; /* - * Use mfence despite the ordering implied by - * mtx_{un,}lock() because clflush is not guaranteed - * to be ordered by any other instruction. + * Use mfence or sfence despite the ordering implied by + * mtx_{un,}lock() because clflush on non-Intel CPUs + * and clflushopt are not guaranteed to be ordered by + * any other instruction. */ - mfence(); - for (; sva < eva; sva += cpu_clflush_line_size) - clflush(sva); - mfence(); + if (useclflushopt) + sfence(); + else if (cpu_vendor_id != CPU_VENDOR_INTEL) + mfence(); + for (; sva < eva; sva += cpu_clflush_line_size) { + if (useclflushopt) + clflushopt(sva); + else + clflush(sva); + } + if (useclflushopt) + sfence(); + else if (cpu_vendor_id != CPU_VENDOR_INTEL) + mfence(); *sysmaps->CMAP2 = 0; sched_unpin(); mtx_unlock(&sysmaps->lock); diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index c0e65d5..a76a5ec 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -209,11 +209,7 @@ alloc_fpusave(int flags) * ready to run and return to user mode. */ void -cpu_fork(td1, p2, td2, flags) - register struct thread *td1; - register struct proc *p2; - struct thread *td2; - int flags; +cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) { register struct proc *p1; struct pcb *pcb2; diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h index d3a7e08..02ed27a 100644 --- a/sys/i386/include/cpufunc.h +++ b/sys/i386/include/cpufunc.h @@ -175,6 +175,13 @@ mfence(void) __asm __volatile("mfence" : : : "memory"); } +static __inline void +sfence(void) +{ + + __asm __volatile("sfence" : : : "memory"); +} + #ifdef _KERNEL #define HAVE_INLINE_FFS diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c index dff0f5c..bc42bbb 100644 --- a/sys/i386/isa/npx.c +++ b/sys/i386/isa/npx.c @@ -559,8 +559,7 @@ SYSINIT(npxinitstate, SI_SUB_DRIVERS, SI_ORDER_ANY, npxinitstate, NULL); * Free coprocessor (if we have it). */ void -npxexit(td) - struct thread *td; +npxexit(struct thread *td) { critical_enter(); @@ -590,7 +589,7 @@ npxexit(td) } int -npxformat() +npxformat(void) { if (!hw_float) @@ -970,7 +969,7 @@ npxresume(union savefpu *addr) } void -npxdrop() +npxdrop(void) { struct thread *td; @@ -1203,8 +1202,7 @@ fpu_clean_state(void) #endif /* CPU_ENABLE_SSE */ static void -fpurstor(addr) - union savefpu *addr; +fpurstor(union savefpu *addr) { #ifdef CPU_ENABLE_SSE diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 293a65d..bdf709f 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -1176,9 +1176,31 @@ core_output(struct vnode *vp, void *base, size_t len, off_t offset, panic("shouldn't be here"); #endif } else { + /* + * EFAULT is a non-fatal error that we can get, for example, + * if the segment is backed by a file but extends beyond its + * end. + */ error = vn_rdwr_inchunks(UIO_WRITE, vp, base, len, offset, UIO_USERSPACE, IO_UNIT | IO_DIRECT, active_cred, file_cred, NULL, td); + if (error == EFAULT) { + log(LOG_WARNING, "Failed to fully fault in a core file " + "segment at VA %p with size 0x%zx to be written at " + "offset 0x%jx for process %s\n", base, len, offset, + curproc->p_comm); + + /* + * Write a "real" zero byte at the end of the target + * region in the case this is the last segment. + * The intermediate space will be implicitly + * zero-filled. + */ + error = vn_rdwr_inchunks(UIO_WRITE, vp, + __DECONST(void *, zero_region), 1, offset + len - 1, + UIO_SYSSPACE, IO_UNIT | IO_DIRECT, active_cred, + file_cred, NULL, td); + } } return (error); } @@ -2309,7 +2331,16 @@ compress_core (gzFile file, char *inbuf, char *dest_buf, unsigned int len, while (len) { if (inbuf != NULL) { chunk_len = (len > CORE_BUF_SIZE) ? CORE_BUF_SIZE : len; - copyin(inbuf, dest_buf, chunk_len); + + /* + * We can get EFAULT error here. In that case zero out + * the current chunk of the segment. + */ + error = copyin(inbuf, dest_buf, chunk_len); + if (error != 0) { + bzero(dest_buf, chunk_len); + error = 0; + } inbuf += chunk_len; } else { chunk_len = len; diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c index e6e432e..4ccf646 100644 --- a/sys/kern/kern_procctl.c +++ b/sys/kern/kern_procctl.c @@ -243,7 +243,7 @@ reap_kill(struct thread *td, struct proc *p, struct procctl_reaper_kill *rk) return (ECAPMODE); if (rk->rk_sig <= 0 || rk->rk_sig > _SIG_MAXSIG) return (EINVAL); - if ((rk->rk_flags & ~REAPER_KILL_CHILDREN) != 0) + if ((rk->rk_flags & ~(REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE)) != 0) return (EINVAL); PROC_UNLOCK(p); reap = (p->p_treeflag & P_TREE_REAPER) == 0 ? p->p_reaper : p; diff --git a/sys/kern/kern_switch.c b/sys/kern/kern_switch.c index d0009b1..f58acd5 100644 --- a/sys/kern/kern_switch.c +++ b/sys/kern/kern_switch.c @@ -206,7 +206,22 @@ critical_exit(void) if (td->td_critnest == 1) { td->td_critnest = 0; + + /* + * Interrupt handlers execute critical_exit() on + * leave, and td_owepreempt may be left set by an + * interrupt handler only when td_critnest > 0. If we + * are decrementing td_critnest from 1 to 0, read + * td_owepreempt after decrementing, to not miss the + * preempt. Disallow compiler to reorder operations. + */ + __compiler_membar(); if (td->td_owepreempt && !kdb_active) { + /* + * Microoptimization: we committed to switch, + * disable preemption in interrupt handlers + * while spinning for the thread lock. + */ td->td_critnest = 1; thread_lock(td); td->td_critnest--; diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index db23e1d..7309ae3 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -963,8 +963,8 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) sched_load_rem(); td->td_lastcpu = td->td_oncpu; - preempted = !((td->td_flags & TDF_SLICEEND) || - (flags & SWT_RELINQUISH)); + preempted = (td->td_flags & TDF_SLICEEND) == 0 && + (flags & SW_PREEMPT) != 0; td->td_flags &= ~(TDF_NEEDRESCHED | TDF_SLICEEND); td->td_owepreempt = 0; td->td_oncpu = NOCPU; diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c index 30aad12..53a46c9 100644 --- a/sys/kern/sched_ule.c +++ b/sys/kern/sched_ule.c @@ -1870,8 +1870,8 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) ts->ts_rltick = ticks; td->td_lastcpu = td->td_oncpu; td->td_oncpu = NOCPU; - preempted = !((td->td_flags & TDF_SLICEEND) || - (flags & SWT_RELINQUISH)); + preempted = (td->td_flags & TDF_SLICEEND) == 0 && + (flags & SW_PREEMPT) != 0; td->td_flags &= ~(TDF_NEEDRESCHED | TDF_SLICEEND); td->td_owepreempt = 0; if (!TD_IS_IDLETHREAD(td)) diff --git a/sys/kern/subr_unit.c b/sys/kern/subr_unit.c index 3bf7aaf..d53ec1e 100644 --- a/sys/kern/subr_unit.c +++ b/sys/kern/subr_unit.c @@ -192,7 +192,7 @@ CTASSERT(sizeof(struct unr) == sizeof(struct unrb)); * Consistency check function. * * Checks the internal consistency as well as we can. - * + * * Called at all boundaries of this API. */ static void @@ -220,7 +220,7 @@ check_unrhdr(struct unrhdr *uh, int line) ("UNR inconsistency: busy %u found %u (line %d)\n", ub->busy, w, line)); y += w; - } else if (up->ptr != NULL) + } else if (up->ptr != NULL) y += up->len; } KASSERT (y == uh->busy, @@ -355,7 +355,7 @@ is_bitmap(struct unrhdr *uh, struct unr *up) /* * Look for sequence of items which can be combined into a bitmap, if * multiple are present, take the one which saves most memory. - * + * * Return (1) if a sequence was found to indicate that another call * might be able to do more. Return (0) if we found no suitable sequence. * @@ -582,7 +582,7 @@ alloc_unrl(struct unrhdr *uh) } /* - * We can always allocate from the first list element, so if we have + * We can always allocate from the first list element, so if we have * nothing on the list, we must have run out of unit numbers. */ if (up == NULL) @@ -797,7 +797,7 @@ free_unrl(struct unrhdr *uh, u_int item, void **p1, void **p2) /* Handle bitmap items */ if (is_bitmap(uh, up)) { ub = up->ptr; - + KASSERT(bit_test(ub->map, item) != 0, ("UNR: Freeing free item %d (bitmap)\n", item)); bit_clear(ub->map, item); @@ -900,7 +900,7 @@ print_unr(struct unrhdr *uh, struct unr *up) for (x = 0; x < up->len; x++) { if (bit_test(ub->map, x)) printf("#"); - else + else printf(" "); } printf("]\n"); diff --git a/sys/kern/uipc_mbuf2.c b/sys/kern/uipc_mbuf2.c index 00472d3..f69b47e 100644 --- a/sys/kern/uipc_mbuf2.c +++ b/sys/kern/uipc_mbuf2.c @@ -161,7 +161,7 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp) * the target data is on <n, off>. * if we got enough data on the mbuf "n", we're done. */ - if ((off == 0 || offp) && len <= n->m_len - off && writable) + if ((off == 0 || offp) && len <= n->m_len - off) goto ok; /* diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 9f922db..5701e5a 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -464,7 +464,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, nmp = TAILQ_NEXT(mp, mnt_list); continue; } - if (sfsp && count < maxcount) { + if (sfsp != NULL && count < maxcount) { sp = &mp->mnt_stat; /* * Set these in case the underlying filesystem @@ -509,7 +509,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, vfs_unbusy(mp); } mtx_unlock(&mountlist_mtx); - if (sfsp && count > maxcount) + if (sfsp != NULL && count > maxcount) td->td_retval[0] = maxcount; else td->td_retval[0] = count; diff --git a/sys/modules/cam/Makefile b/sys/modules/cam/Makefile index c3ecf56..e3404f9 100644 --- a/sys/modules/cam/Makefile +++ b/sys/modules/cam/Makefile @@ -14,6 +14,7 @@ SRCS+= opt_cd.h SRCS+= opt_pt.h SRCS+= opt_sa.h SRCS+= opt_ses.h +SRCS+= opt_ddb.h SRCS+= device_if.h bus_if.h vnode_if.h SRCS+= cam.c SRCS+= cam_compat.c diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c index 36665ca..7ba5423 100644 --- a/sys/net/ieee8023ad_lacp.c +++ b/sys/net/ieee8023ad_lacp.c @@ -523,9 +523,6 @@ lacp_port_create(struct lagg_port *lgp) struct ifmultiaddr *rifma = NULL; int error; - boolean_t active = TRUE; /* XXX should be configurable */ - boolean_t fast = FALSE; /* Configurable via ioctl */ - bzero((char *)&sdl, sizeof(sdl)); sdl.sdl_len = sizeof(sdl); sdl.sdl_family = AF_LINK; @@ -557,9 +554,7 @@ lacp_port_create(struct lagg_port *lgp) lacp_fill_actorinfo(lp, &lp->lp_actor); lacp_fill_markerinfo(lp, &lp->lp_marker); - lp->lp_state = - (active ? LACP_STATE_ACTIVITY : 0) | - (fast ? LACP_STATE_TIMEOUT : 0); + lp->lp_state = LACP_STATE_ACTIVITY; lp->lp_aggregator = NULL; lacp_sm_rx_set_expired(lp); LACP_UNLOCK(lsc); diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index b22e324..7a465b4 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -866,14 +866,18 @@ bridge_mutecaps(struct bridge_softc *sc) mask &= bif->bif_savedcaps; } + BRIDGE_XLOCK(sc); LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { enabled = bif->bif_ifp->if_capenable; enabled &= ~BRIDGE_IFCAPS_STRIP; /* strip off mask bits and enable them again if allowed */ enabled &= ~BRIDGE_IFCAPS_MASK; enabled |= mask; + BRIDGE_UNLOCK(sc); bridge_set_ifcap(sc, bif, enabled); + BRIDGE_LOCK(sc); } + BRIDGE_XDROP(sc); } @@ -884,6 +888,8 @@ bridge_set_ifcap(struct bridge_softc *sc, struct bridge_iflist *bif, int set) struct ifreq ifr; int error; + BRIDGE_UNLOCK_ASSERT(sc); + bzero(&ifr, sizeof(ifr)); ifr.ifr_reqcap = set; diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h index 3210c03..480c90a 100644 --- a/sys/net/if_bridgevar.h +++ b/sys/net/if_bridgevar.h @@ -280,6 +280,7 @@ struct ifbpstpconf { #define BRIDGE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) #define BRIDGE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) #define BRIDGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) +#define BRIDGE_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED) #define BRIDGE_LOCK2REF(_sc, _err) do { \ mtx_assert(&(_sc)->sc_mtx, MA_OWNED); \ if ((_sc)->sc_iflist_xcnt > 0) \ diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index 93ec82e..5e8a598 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -862,7 +862,7 @@ lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) return (error); fallback: - if (lp->lp_ioctl != NULL) + if (lp != NULL && lp->lp_ioctl != NULL) return ((*lp->lp_ioctl)(ifp, cmd, data)); return (EINVAL); diff --git a/sys/net/if_media.c b/sys/net/if_media.c index 32e0712..7216220 100644 --- a/sys/net/if_media.c +++ b/sys/net/if_media.c @@ -105,6 +105,7 @@ ifmedia_removeall(ifm) LIST_REMOVE(entry, ifm_list); free(entry, M_IFADDR); } + ifm->ifm_cur = NULL; } /* diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c index 14d44de..02d9dea 100644 --- a/sys/netgraph/ng_mppc.c +++ b/sys/netgraph/ng_mppc.c @@ -66,7 +66,7 @@ #if !defined(NETGRAPH_MPPC_COMPRESSION) && !defined(NETGRAPH_MPPC_ENCRYPTION) #ifdef KLD_MODULE -/* XXX NETGRAPH_MPPC_COMPRESSION isn't functional yet */ +#define NETGRAPH_MPPC_COMPRESSION #define NETGRAPH_MPPC_ENCRYPTION #else /* This case is indicative of an error in sys/conf files */ @@ -81,7 +81,6 @@ static MALLOC_DEFINE(M_NETGRAPH_MPPC, "netgraph_mppc", "netgraph mppc node"); #endif #ifdef NETGRAPH_MPPC_COMPRESSION -/* XXX this file doesn't exist yet, but hopefully someday it will... */ #include <net/mppc.h> #endif #ifdef NETGRAPH_MPPC_ENCRYPTION @@ -546,7 +545,7 @@ err1: &destCnt, d->history, flags, 0); /* Check return value */ - KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__)); + /* KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__)); */ if ((rtn & MPPC_EXPANDED) == 0 && (rtn & MPPC_COMP_OK) == MPPC_COMP_OK) { outlen -= destCnt; @@ -808,7 +807,7 @@ failed: &sourceCnt, &destCnt, d->history, flags); /* Check return value */ - KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__)); + /* KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__)); */ if ((rtn & MPPC_DEST_EXHAUSTED) != 0 || (rtn & MPPC_DECOMP_OK) != MPPC_DECOMP_OK) { log(LOG_ERR, "%s: decomp returned 0x%x", diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index b5781d3..6dbfeaf 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1252,8 +1252,8 @@ send: #ifdef INET6 if (isipv6) { /* - * ip6_plen is not need to be filled now, and will be filled - * in ip6_output. + * There is no need to fill in ip6_plen right now. + * It will be filled later by ip6_output. */ m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; th->th_sum = in6_cksum_pseudo(ip6, sizeof(struct tcphdr) + diff --git a/sys/ofed/drivers/net/mlx4/main.c b/sys/ofed/drivers/net/mlx4/main.c index 217220a..46917ac 100644 --- a/sys/ofed/drivers/net/mlx4/main.c +++ b/sys/ofed/drivers/net/mlx4/main.c @@ -3637,47 +3637,61 @@ int mlx4_restart_one(struct pci_dev *pdev) static DEFINE_PCI_DEVICE_TABLE(mlx4_pci_table) = { /* MT25408 "Hermon" SDR */ - { PCI_VDEVICE(MELLANOX, 0x6340), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x6340), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT25408 "Hermon" DDR */ - { PCI_VDEVICE(MELLANOX, 0x634a), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x634a), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT25408 "Hermon" QDR */ - { PCI_VDEVICE(MELLANOX, 0x6354), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x6354), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT25408 "Hermon" DDR PCIe gen2 */ - { PCI_VDEVICE(MELLANOX, 0x6732), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x6732), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT25408 "Hermon" QDR PCIe gen2 */ - { PCI_VDEVICE(MELLANOX, 0x673c), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x673c), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT25408 "Hermon" EN 10GigE */ - { PCI_VDEVICE(MELLANOX, 0x6368), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x6368), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT25408 "Hermon" EN 10GigE PCIe gen2 */ - { PCI_VDEVICE(MELLANOX, 0x6750), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x6750), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */ - { PCI_VDEVICE(MELLANOX, 0x6372), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x6372), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ - { PCI_VDEVICE(MELLANOX, 0x675a), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x675a), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/ - { PCI_VDEVICE(MELLANOX, 0x6764), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x6764), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */ - { PCI_VDEVICE(MELLANOX, 0x6746), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x6746), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT26478 ConnectX2 40GigE PCIe gen2 */ - { PCI_VDEVICE(MELLANOX, 0x676e), MLX4_PCI_DEV_FORCE_SENSE_PORT }, + { PCI_VDEVICE(MELLANOX, 0x676e), + .driver_data = MLX4_PCI_DEV_FORCE_SENSE_PORT }, /* MT25400 Family [ConnectX-2 Virtual Function] */ - { PCI_VDEVICE(MELLANOX, 0x1002), MLX4_PCI_DEV_IS_VF }, + { PCI_VDEVICE(MELLANOX, 0x1002), + .driver_data = MLX4_PCI_DEV_IS_VF }, /* MT27500 Family [ConnectX-3] */ - { PCI_VDEVICE(MELLANOX, 0x1003), 0 }, + { PCI_VDEVICE(MELLANOX, 0x1003) }, /* MT27500 Family [ConnectX-3 Virtual Function] */ - { PCI_VDEVICE(MELLANOX, 0x1004), MLX4_PCI_DEV_IS_VF }, - { PCI_VDEVICE(MELLANOX, 0x1005), 0 }, /* MT27510 Family */ - { PCI_VDEVICE(MELLANOX, 0x1006), 0 }, /* MT27511 Family */ - { PCI_VDEVICE(MELLANOX, 0x1007), 0 }, /* MT27520 Family */ - { PCI_VDEVICE(MELLANOX, 0x1008), 0 }, /* MT27521 Family */ - { PCI_VDEVICE(MELLANOX, 0x1009), 0 }, /* MT27530 Family */ - { PCI_VDEVICE(MELLANOX, 0x100a), 0 }, /* MT27531 Family */ - { PCI_VDEVICE(MELLANOX, 0x100b), 0 }, /* MT27540 Family */ - { PCI_VDEVICE(MELLANOX, 0x100c), 0 }, /* MT27541 Family */ - { PCI_VDEVICE(MELLANOX, 0x100d), 0 }, /* MT27550 Family */ - { PCI_VDEVICE(MELLANOX, 0x100e), 0 }, /* MT27551 Family */ - { PCI_VDEVICE(MELLANOX, 0x100f), 0 }, /* MT27560 Family */ - { PCI_VDEVICE(MELLANOX, 0x1010), 0 }, /* MT27561 Family */ + { PCI_VDEVICE(MELLANOX, 0x1004), + .driver_data = MLX4_PCI_DEV_IS_VF }, + { PCI_VDEVICE(MELLANOX, 0x1005) }, /* MT27510 Family */ + { PCI_VDEVICE(MELLANOX, 0x1006) }, /* MT27511 Family */ + { PCI_VDEVICE(MELLANOX, 0x1007) }, /* MT27520 Family */ + { PCI_VDEVICE(MELLANOX, 0x1008) }, /* MT27521 Family */ + { PCI_VDEVICE(MELLANOX, 0x1009) }, /* MT27530 Family */ + { PCI_VDEVICE(MELLANOX, 0x100a) }, /* MT27531 Family */ + { PCI_VDEVICE(MELLANOX, 0x100b) }, /* MT27540 Family */ + { PCI_VDEVICE(MELLANOX, 0x100c) }, /* MT27541 Family */ + { PCI_VDEVICE(MELLANOX, 0x100d) }, /* MT27550 Family */ + { PCI_VDEVICE(MELLANOX, 0x100e) }, /* MT27551 Family */ + { PCI_VDEVICE(MELLANOX, 0x100f) }, /* MT27560 Family */ + { PCI_VDEVICE(MELLANOX, 0x1010) }, /* MT27561 Family */ { 0, } }; diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h index d6d92ab..0a44fc4 100644 --- a/sys/sys/unistd.h +++ b/sys/sys/unistd.h @@ -65,7 +65,7 @@ #define _POSIX_MONOTONIC_CLOCK 200112L #define _POSIX_NO_TRUNC 1 #define _POSIX_PRIORITIZED_IO (-1) -#define _POSIX_PRIORITY_SCHEDULING 200112L +#define _POSIX_PRIORITY_SCHEDULING 0 #define _POSIX_RAW_SOCKETS 200112L #define _POSIX_REALTIME_SIGNALS 200112L #define _POSIX_SEMAPHORES 200112L diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 750083f..99bda8c 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -4274,7 +4274,7 @@ DB_SHOW_COMMAND(procvm, procvm) struct proc *p; if (have_addr) { - p = (struct proc *) addr; + p = db_lookup_proc(addr); } else { p = curproc; } diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index f45aa9e..5dcb804 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -192,8 +192,8 @@ struct vm_object { #define OBJ_DISCONNECTWNT 0x4000 /* disconnect from vnode wanted */ #define OBJ_TMPFS 0x8000 /* has tmpfs vnode allocated */ -#define IDX_TO_OFF(idx) (((vm_ooffset_t)(idx)) << PAGE_SHIFT) -#define OFF_TO_IDX(off) ((vm_pindex_t)(((vm_ooffset_t)(off)) >> PAGE_SHIFT)) +#define IDX_TO_OFF(idx) (((vm_ooffset_t)(idx)) << PAGE_SHIFT) +#define OFF_TO_IDX(off) ((vm_pindex_t)(((vm_ooffset_t)(off)) >> PAGE_SHIFT)) #ifdef _KERNEL diff --git a/sys/x86/x86/mca.c b/sys/x86/x86/mca.c index 1bb8854..5278784 100644 --- a/sys/x86/x86/mca.c +++ b/sys/x86/x86/mca.c @@ -249,7 +249,7 @@ mca_error_mmtype(uint16_t mca_error) return ("???"); } -static int __nonnull(1) +static int mca_mute(const struct mca_record *rec) { @@ -278,7 +278,7 @@ mca_mute(const struct mca_record *rec) } /* Dump details about a single machine check. */ -static void __nonnull(1) +static void mca_log(const struct mca_record *rec) { uint16_t mca_error; @@ -417,7 +417,7 @@ mca_log(const struct mca_record *rec) printf("MCA: Misc 0x%llx\n", (long long)rec->mr_misc); } -static int __nonnull(2) +static int mca_check_status(int bank, struct mca_record *rec) { uint64_t status; @@ -484,7 +484,7 @@ mca_refill(void *context, int pending) mca_fill_freelist(); } -static void __nonnull(2) +static void mca_record_entry(enum scan_mode mode, const struct mca_record *record) { struct mca_internal *rec; diff --git a/tests/sys/Makefile.inc b/tests/sys/Makefile.inc new file mode 100644 index 0000000..f341842 --- /dev/null +++ b/tests/sys/Makefile.inc @@ -0,0 +1,3 @@ +# $FreeBSD$ + +WARNS?= 6 diff --git a/tests/sys/file/ftruncate_test.c b/tests/sys/file/ftruncate_test.c index 7eaba14..b657aca 100644 --- a/tests/sys/file/ftruncate_test.c +++ b/tests/sys/file/ftruncate_test.c @@ -57,7 +57,7 @@ static off_t lengths[] = {0, 1, 2, 3, 4, 127, 128, 129, 511, 512, 513, 1023, static int lengths_count = sizeof(lengths) / sizeof(off_t); int -main(int argc, char *argv[]) +main(void) { int error, fd, fds[2], i, read_only_fd; char path[PATH_MAX]; diff --git a/tests/sys/geom/class/eli/Makefile b/tests/sys/geom/class/eli/Makefile index 8f4ca60..f6e2fd1 100644 --- a/tests/sys/geom/class/eli/Makefile +++ b/tests/sys/geom/class/eli/Makefile @@ -9,6 +9,7 @@ TAP_TESTS_SH+= detach_l_test TAP_TESTS_SH+= init_B_test TAP_TESTS_SH+= init_J_test TAP_TESTS_SH+= init_a_test +TAP_TESTS_SH+= init_alias_test TAP_TESTS_SH+= init_i_P_test TAP_TESTS_SH+= init_test TAP_TESTS_SH+= integrity_copy_test diff --git a/tests/sys/geom/class/eli/conf.sh b/tests/sys/geom/class/eli/conf.sh index 0646e83..5ac291b 100755 --- a/tests/sys/geom/class/eli/conf.sh +++ b/tests/sys/geom/class/eli/conf.sh @@ -11,6 +11,54 @@ while [ -c /dev/md$no ]; do : $(( no += 1 )) done +# Execute `func` for each combination of cipher, sectorsize, and hmac algo +# `func` usage should be: +# func <cipher> <aalgo> <secsize> +for_each_geli_config() { + func=$1 + + for cipher in aes-xts:128 aes-xts:256 \ + aes-cbc:128 aes-cbc:192 aes-cbc:256 \ + 3des-cbc:192 \ + blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 \ + blowfish-cbc:224 blowfish-cbc:256 blowfish-cbc:288 \ + blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \ + blowfish-cbc:416 blowfish-cbc:448 \ + camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do + ealgo=${cipher%%:*} + keylen=${cipher##*:} + for aalgo in hmac/md5 hmac/sha1 hmac/ripemd160 hmac/sha256 \ + hmac/sha384 hmac/sha512; do + for secsize in 512 1024 2048 4096 8192; do + ${func} $cipher $aalgo $secsize + done + done + done +} + +# Execute `func` for each combination of cipher, and sectorsize, with no hmac +# `func` usage should be: +# func <cipher> <secsize> +for_each_geli_config_nointegrity() { + func=$1 + + for cipher in aes-xts:128 aes-xts:256 \ + aes-cbc:128 aes-cbc:192 aes-cbc:256 \ + 3des-cbc:192 \ + blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 \ + blowfish-cbc:224 blowfish-cbc:256 blowfish-cbc:288 \ + blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \ + blowfish-cbc:416 blowfish-cbc:448 \ + camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do + ealgo=${cipher%%:*} + keylen=${cipher##*:} + for secsize in 512 1024 2048 4096 8192; do + ${func} $cipher $aalgo $secsize + done + done +} + + geli_test_cleanup() { [ -c /dev/md${no}.eli ] && geli detach md${no}.eli diff --git a/tests/sys/geom/class/eli/init_a_test.sh b/tests/sys/geom/class/eli/init_a_test.sh index dbb24fe..9b5b251 100644 --- a/tests/sys/geom/class/eli/init_a_test.sh +++ b/tests/sys/geom/class/eli/init_a_test.sh @@ -6,55 +6,45 @@ base=`basename $0` sectors=100 keyfile=`mktemp $base.XXXXXX` || exit 1 +rnd=`mktemp $base.XXXXXX` || exit 1 -echo "1..1380" - -i=1 -for cipher in aes:0 aes:128 aes:256 \ - aes-xts:0 aes-xts:128 aes-xts:256 \ - aes-cbc:0 aes-cbc:128 aes-cbc:192 aes-cbc:256 \ - 3des:0 3des:192 \ - 3des-cbc:0 3des-cbc:192 \ - blowfish:0 blowfish:128 blowfish:160 blowfish:192 blowfish:224 \ - blowfish:256 blowfish:288 blowfish:320 blowfish:352 blowfish:384 \ - blowfish:416 blowfish:448 \ - blowfish-cbc:0 blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 blowfish-cbc:224 \ - blowfish-cbc:256 blowfish-cbc:288 blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \ - blowfish-cbc:416 blowfish-cbc:448 \ - camellia:0 camellia:128 camellia:192 camellia:256 \ - camellia-cbc:0 camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do +do_test() { + cipher=$1 + aalgo=$2 + secsize=$3 ealgo=${cipher%%:*} keylen=${cipher##*:} - for aalgo in hmac/md5 hmac/sha1 hmac/ripemd160 hmac/sha256 hmac/sha384 hmac/sha512; do - for secsize in 512 1024 2048 4096 8192; do - rnd=`mktemp $base.XXXXXX` || exit 1 - mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1 - dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 + mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1 + geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null + geli attach -p -k $keyfile md${no} + + secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'` - geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null - geli attach -p -k $keyfile md${no} + dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null - secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'` + md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5` + md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5` - dd if=/dev/random of=${rnd} bs=${secsize} count=${secs} >/dev/null 2>&1 - dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null + if [ ${md_rnd} = ${md_ddev} ]; then + echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) - md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5` - md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5` + geli detach md${no} + mdconfig -d -u $no +} + +echo "1..600" + +i=1 - if [ ${md_rnd} = ${md_ddev} ]; then - echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) +dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 +dd if=/dev/random of=${rnd} bs=8192 count=${sectors} >/dev/null 2>&1 - geli detach md${no} - rm -f $rnd - mdconfig -d -u $no - done - done -done +for_each_geli_config do_test +rm -f $rnd rm -f $keyfile diff --git a/tests/sys/geom/class/eli/init_alias_test.sh b/tests/sys/geom/class/eli/init_alias_test.sh new file mode 100755 index 0000000..0422bee --- /dev/null +++ b/tests/sys/geom/class/eli/init_alias_test.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# $FreeBSD$ + +# Test "geli init"'s various cipher aliases +. $(dirname $0)/conf.sh + +base=`basename $0` +sectors=100 +keyfile=`mktemp $base.XXXXXX` || exit 1 +rnd=`mktemp $base.XXXXXX` || exit 1 + +do_test() { + ealgo=$1 + keylen=$2 + expected_ealgo=$3 + expected_keylen=$4 + + geli init -B none -e $ealgo -l $keylen -P -K $keyfile md${no} 2>/dev/null + geli attach -p -k $keyfile md${no} + real_ealgo=`geli list md${no}.eli | awk '/EncryptionAlgorithm/ {print $2}'` + real_keylen=`geli list md${no}.eli | awk '/KeyLength/ {print $2}'` + + if [ ${real_ealgo} = ${expected_ealgo} ]; then + echo "ok $i - ${ealgo} aliased to ${real_ealgo}" + else + echo "not ok $i - expected ${expected_ealgo} but got ${real_ealgo}" + fi + i=$((i+1)) + + if [ ${real_keylen} = ${expected_keylen} ]; then + echo "ok $i - keylen=${keylen} for ealgo=${ealgo} aliases to ${real_keylen}" + else + echo "not ok $i - expected ${expected_keylen} but got ${real_keylen}" + fi + i=$((i+1)) + + geli detach md${no} +} + +echo "1..38" +i=1 +mdconfig -a -t malloc -s 1024k -u $no || exit 1 +dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 + +for spec in aes:0:AES-XTS:128 aes:128:AES-XTS:128 aes:256:AES-XTS:256 \ + 3des:0:3DES-CBC:192 3des:192:3DES-CBC:192 \ + blowfish:0:Blowfish-CBC:128 blowfish:128:Blowfish-CBC:128 \ + blowfish:160:Blowfish-CBC:160 blowfish:192:Blowfish-CBC:192 \ + blowfish:224:Blowfish-CBC:224 blowfish:256:Blowfish-CBC:256 \ + blowfish:288:Blowfish-CBC:288 blowfish:352:Blowfish-CBC:352 \ + blowfish:384:Blowfish-CBC:384 blowfish:416:Blowfish-CBC:416 \ + blowfish:448:Blowfish-CBC:448 \ + camellia:0:CAMELLIA-CBC:128 camellia:128:CAMELLIA-CBC:128 \ + camellia:256:CAMELLIA-CBC:256 ; do + + ealgo=`echo $spec | cut -d : -f 1` + keylen=`echo $spec | cut -d : -f 2` + expected_ealgo=`echo $spec | cut -d : -f 3` + expected_keylen=`echo $spec | cut -d : -f 4` + + do_test $ealgo $keylen $expected_ealgo $expected_keylen +done + +rm -f $keyfile diff --git a/tests/sys/geom/class/eli/init_test.sh b/tests/sys/geom/class/eli/init_test.sh index 71dd6e2..31fca55 100644 --- a/tests/sys/geom/class/eli/init_test.sh +++ b/tests/sys/geom/class/eli/init_test.sh @@ -4,62 +4,52 @@ . $(dirname $0)/conf.sh base=`basename $0` -sectors=100 +sectors=32 keyfile=`mktemp $base.XXXXXX` || exit 1 +rnd=`mktemp $base.XXXXXX` || exit 1 -echo "1..460" +echo "1..200" -i=1 -for cipher in aes:0 aes:128 aes:256 \ - aes-xts:0 aes-xts:128 aes-xts:256 \ - aes-cbc:0 aes-cbc:128 aes-cbc:192 aes-cbc:256 \ - 3des:0 3des:192 \ - 3des-cbc:0 3des-cbc:192 \ - blowfish:0 blowfish:128 blowfish:160 blowfish:192 blowfish:224 \ - blowfish:256 blowfish:288 blowfish:320 blowfish:352 blowfish:384 \ - blowfish:416 blowfish:448 \ - blowfish-cbc:0 blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 blowfish-cbc:224 \ - blowfish-cbc:256 blowfish-cbc:288 blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \ - blowfish-cbc:416 blowfish-cbc:448 \ - camellia:0 camellia:128 camellia:192 camellia:256 \ - camellia-cbc:0 camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do +do_test() { + cipher=$1 + secsize=$2 ealgo=${cipher%%:*} keylen=${cipher##*:} - for secsize in 512 1024 2048 4096 8192; do - rnd=`mktemp $base.XXXXXX` || exit 1 - mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1 - dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 + mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1 + + geli init -B none -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null + geli attach -p -k $keyfile md${no} - geli init -B none -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null - geli attach -p -k $keyfile md${no} + secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'` - secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'` + dd if=/dev/random of=${rnd} bs=${secsize} count=${secs} >/dev/null 2>&1 + dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null - dd if=/dev/random of=${rnd} bs=${secsize} count=${secs} >/dev/null 2>&1 - dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null + md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5` + md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5` + md_edev=`dd if=/dev/md${no} bs=${secsize} count=${secs} 2>/dev/null | md5` - md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5` - md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5` - md_edev=`dd if=/dev/md${no} bs=${secsize} count=${secs} 2>/dev/null | md5` + if [ ${md_rnd} = ${md_ddev} ]; then + echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) + if [ ${md_rnd} != ${md_edev} ]; then + echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) - if [ ${md_rnd} = ${md_ddev} ]; then - echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) - if [ ${md_rnd} != ${md_edev} ]; then - echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) + geli detach md${no} + mdconfig -d -u $no +} - geli detach md${no} - rm -f $rnd - mdconfig -d -u $no - done -done +i=1 +dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 +for_each_geli_config_nointegrity do_test +rm -f $rnd rm -f $keyfile diff --git a/tests/sys/geom/class/eli/integrity_copy_test.sh b/tests/sys/geom/class/eli/integrity_copy_test.sh index 4c8efd3..ae345d7 100644 --- a/tests/sys/geom/class/eli/integrity_copy_test.sh +++ b/tests/sys/geom/class/eli/integrity_copy_test.sh @@ -4,96 +4,85 @@ . $(dirname $0)/conf.sh base=`basename $0` -sectors=100 keyfile=`mktemp $base.XXXXXX` || exit 1 sector=`mktemp $base.XXXXXX` || exit 1 -echo "1..5520" +echo "1..2400" -i=1 -for cipher in aes:0 aes:128 aes:256 \ - aes-xts:0 aes-xts:128 aes-xts:256 \ - aes-cbc:0 aes-cbc:128 aes-cbc:192 aes-cbc:256 \ - 3des:0 3des:192 \ - 3des-cbc:0 3des-cbc:192 \ - blowfish:0 blowfish:128 blowfish:160 blowfish:192 blowfish:224 \ - blowfish:256 blowfish:288 blowfish:320 blowfish:352 blowfish:384 \ - blowfish:416 blowfish:448 \ - blowfish-cbc:0 blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 blowfish-cbc:224 \ - blowfish-cbc:256 blowfish-cbc:288 blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \ - blowfish-cbc:416 blowfish-cbc:448 \ - camellia:0 camellia:128 camellia:192 camellia:256 \ - camellia-cbc:0 camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do +do_test() { + cipher=$1 + aalgo=$2 + secsize=$3 ealgo=${cipher%%:*} keylen=${cipher##*:} - for aalgo in hmac/md5 hmac/sha1 hmac/ripemd160 hmac/sha256 hmac/sha384 hmac/sha512; do - for secsize in 512 1024 2048 4096 8192; do - #mdconfig -a -t malloc -s `expr $secsize \* 2 + 512`b -u $no || exit 1 - mdconfig -a -t malloc -s $sectors -u $no || exit 1 - - dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 - - geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null - geli attach -p -k $keyfile md${no} - - dd if=/dev/random of=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1 - - dd if=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "ok $i - small 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - small 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) - - geli detach md${no} - # Copy first small sector to the second small sector. - # This should be detected as corruption. - dd if=/dev/md${no} of=${sector} bs=512 count=1 >/dev/null 2>&1 - dd if=${sector} of=/dev/md${no} bs=512 count=1 seek=1 >/dev/null 2>&1 - geli attach -p -k $keyfile md${no} - - dd if=/dev/md${no}.eli of=/dev/null bs=${secsize} count=1 >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "ok $i - small 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - small 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) - - ms=`diskinfo /dev/md${no} | awk '{print $3 - 512}'` - ns=`diskinfo /dev/md${no}.eli | awk '{print $4}'` - usecsize=`echo "($ms / $ns) - (($ms / $ns) % 512)" | bc` - - dd if=/dev/random of=/dev/md${no}.eli bs=${secsize} count=2 >/dev/null 2>&1 - - dd if=/dev/md${no}.eli bs=${secsize} count=2 >/dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "ok $i - big 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - big 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) - - geli detach md${no} - # Copy first big sector to the second big sector. - # This should be detected as corruption. - dd if=/dev/md${no} of=${sector} bs=${usecsize} count=1 >/dev/null 2>&1 - dd if=${sector} of=/dev/md${no} bs=${usecsize} count=1 seek=1 >/dev/null 2>&1 - geli attach -p -k $keyfile md${no} - - dd if=/dev/md${no}.eli of=/dev/null bs=${secsize} count=2 >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "ok $i - big 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - big 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) - - geli detach md${no} - mdconfig -d -u $no - done - done -done + + mdconfig -a -t malloc -s `expr $secsize \* 2 + 512`b -u $no || exit 1 + geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null + geli attach -p -k $keyfile md${no} + + dd if=/dev/random of=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1 + + dd if=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "ok $i - small 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - small 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) + + geli detach md${no} + # Copy first small sector to the second small sector. + # This should be detected as corruption. + dd if=/dev/md${no} of=${sector} bs=512 count=1 >/dev/null 2>&1 + dd if=${sector} of=/dev/md${no} bs=512 count=1 seek=1 >/dev/null 2>&1 + geli attach -p -k $keyfile md${no} + + dd if=/dev/md${no}.eli of=/dev/null bs=${secsize} count=1 >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "ok $i - small 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - small 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) + + ms=`diskinfo /dev/md${no} | awk '{print $3 - 512}'` + ns=`diskinfo /dev/md${no}.eli | awk '{print $4}'` + usecsize=`echo "($ms / $ns) - (($ms / $ns) % 512)" | bc` + + # Fix the corruption + dd if=/dev/random of=/dev/md${no}.eli bs=${secsize} count=2 >/dev/null 2>&1 + + dd if=/dev/md${no}.eli bs=${secsize} count=2 >/dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "ok $i - big 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - big 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) + + geli detach md${no} + # Copy first big sector to the second big sector. + # This should be detected as corruption. + dd if=/dev/md${no} of=${sector} bs=${usecsize} count=1 >/dev/null 2>&1 + dd if=${sector} of=/dev/md${no} bs=${usecsize} count=1 seek=1 >/dev/null 2>&1 + geli attach -p -k $keyfile md${no} + + dd if=/dev/md${no}.eli of=/dev/null bs=${secsize} count=2 >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "ok $i - big 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - big 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) + + geli detach md${no} + mdconfig -d -u $no +} + + +i=1 +dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 + +for_each_geli_config do_test rm -f $keyfile $sector diff --git a/tests/sys/geom/class/eli/integrity_data_test.sh b/tests/sys/geom/class/eli/integrity_data_test.sh index 7ea7c96b..73b950a 100644 --- a/tests/sys/geom/class/eli/integrity_data_test.sh +++ b/tests/sys/geom/class/eli/integrity_data_test.sh @@ -4,66 +4,42 @@ . $(dirname $0)/conf.sh base=`basename $0` -sectors=100 keyfile=`mktemp $base.XXXXXX` || exit 1 sector=`mktemp $base.XXXXXX` || exit 1 -echo "1..2760" +echo "1..600" -i=1 -for cipher in aes:0 aes:128 aes:256 \ - aes-xts:0 aes-xts:128 aes-xts:256 \ - aes-cbc:0 aes-cbc:128 aes-cbc:192 aes-cbc:256 \ - 3des:0 3des:192 \ - 3des-cbc:0 3des-cbc:192 \ - blowfish:0 blowfish:128 blowfish:160 blowfish:192 blowfish:224 \ - blowfish:256 blowfish:288 blowfish:320 blowfish:352 blowfish:384 \ - blowfish:416 blowfish:448 \ - blowfish-cbc:0 blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 blowfish-cbc:224 \ - blowfish-cbc:256 blowfish-cbc:288 blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \ - blowfish-cbc:416 blowfish-cbc:448 \ - camellia:0 camellia:128 camellia:192 camellia:256 \ - camellia-cbc:0 camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do +do_test() { + cipher=$1 + aalgo=$2 + secsize=$3 ealgo=${cipher%%:*} keylen=${cipher##*:} - for aalgo in hmac/md5 hmac/sha1 hmac/ripemd160 hmac/sha256 hmac/sha384 hmac/sha512; do - for secsize in 512 1024 2048 4096 8192; do - mdconfig -a -t malloc -s `expr $secsize \* 2 + 512`b -u $no || exit 1 - - dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 - geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null - geli attach -p -k $keyfile md${no} + mdconfig -a -t malloc -s `expr $secsize \* 2 + 512`b -u $no || exit 1 + geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null - dd if=/dev/random of=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1 + # Corrupt 8 bytes of data. + dd if=/dev/md${no} of=${sector} bs=512 count=1 >/dev/null 2>&1 + dd if=/dev/random of=${sector} bs=1 count=8 seek=64 conv=notrunc >/dev/null 2>&1 + dd if=${sector} of=/dev/md${no} bs=512 count=1 >/dev/null 2>&1 + geli attach -p -k $keyfile md${no} - dd if=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) + dd if=/dev/md${no}.eli of=/dev/null bs=${secsize} count=1 >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) - geli detach md${no} - # Corrupt 8 bytes of data. - dd if=/dev/md${no} of=${sector} bs=512 count=1 >/dev/null 2>&1 - dd if=/dev/random of=${sector} bs=1 count=8 seek=64 conv=notrunc >/dev/null 2>&1 - dd if=${sector} of=/dev/md${no} bs=512 count=1 >/dev/null 2>&1 - geli attach -p -k $keyfile md${no} + geli detach md${no} + mdconfig -d -u $no +} - dd if=/dev/md${no}.eli of=/dev/null bs=${secsize} count=1 >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) +i=1 +dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 - geli detach md${no} - mdconfig -d -u $no - done - done -done +for_each_geli_config do_test rm -f $keyfile $sector diff --git a/tests/sys/geom/class/eli/integrity_hmac_test.sh b/tests/sys/geom/class/eli/integrity_hmac_test.sh index 243eac9..6e1dfa5 100644 --- a/tests/sys/geom/class/eli/integrity_hmac_test.sh +++ b/tests/sys/geom/class/eli/integrity_hmac_test.sh @@ -4,66 +4,43 @@ . $(dirname $0)/conf.sh base=`basename $0` -sectors=100 keyfile=`mktemp $base.XXXXXX` || exit 1 sector=`mktemp $base.XXXXXX` || exit 1 -echo "1..2760" +echo "1..600" -i=1 -for cipher in aes:0 aes:128 aes:256 \ - aes-xts:0 aes-xts:128 aes-xts:256 \ - aes-cbc:0 aes-cbc:128 aes-cbc:192 aes-cbc:256 \ - 3des:0 3des:192 \ - 3des-cbc:0 3des-cbc:192 \ - blowfish:0 blowfish:128 blowfish:160 blowfish:192 blowfish:224 \ - blowfish:256 blowfish:288 blowfish:320 blowfish:352 blowfish:384 \ - blowfish:416 blowfish:448 \ - blowfish-cbc:0 blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 blowfish-cbc:224 \ - blowfish-cbc:256 blowfish-cbc:288 blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \ - blowfish-cbc:416 blowfish-cbc:448 \ - camellia:0 camellia:128 camellia:192 camellia:256 \ - camellia-cbc:0 camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do +do_test() { + cipher=$1 + aalgo=$2 + secsize=$3 ealgo=${cipher%%:*} keylen=${cipher##*:} - for aalgo in hmac/md5 hmac/sha1 hmac/ripemd160 hmac/sha256 hmac/sha384 hmac/sha512; do - for secsize in 512 1024 2048 4096 8192; do - mdconfig -a -t malloc -s `expr $secsize \* 2 + 512`b -u $no || exit 1 - dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 + mdconfig -a -t malloc -s `expr $secsize \* 2 + 512`b -u $no || exit 2 + geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null - geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null - geli attach -p -k $keyfile md${no} + # Corrupt 8 bytes of HMAC. + dd if=/dev/md${no} of=${sector} bs=512 count=1 >/dev/null 2>&1 + dd if=/dev/random of=${sector} bs=1 count=16 conv=notrunc >/dev/null 2>&1 + dd if=${sector} of=/dev/md${no} bs=512 count=1 >/dev/null 2>&1 + geli attach -p -k $keyfile md${no} - dd if=/dev/random of=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1 + dd if=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) - dd if=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) + geli detach md${no} + mdconfig -d -u $no +} - geli detach md${no} - # Corrupt 8 bytes of HMAC. - dd if=/dev/md${no} of=${sector} bs=512 count=1 >/dev/null 2>&1 - dd if=/dev/random of=${sector} bs=1 count=16 conv=notrunc >/dev/null 2>&1 - dd if=${sector} of=/dev/md${no} bs=512 count=1 >/dev/null 2>&1 - geli attach -p -k $keyfile md${no} - dd if=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) +i=1 +dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1 - geli detach md${no} - mdconfig -d -u $no - done - done -done +for_each_geli_config do_test rm -f $keyfile $sector diff --git a/tests/sys/geom/class/eli/onetime_a_test.sh b/tests/sys/geom/class/eli/onetime_a_test.sh index 4e26dfb..0cccf30 100644 --- a/tests/sys/geom/class/eli/onetime_a_test.sh +++ b/tests/sys/geom/class/eli/onetime_a_test.sh @@ -4,51 +4,42 @@ . $(dirname $0)/conf.sh base=`basename $0` -sectors=100 +sectors=8 +rnd=`mktemp $base.XXXXXX` || exit 1 -echo "1..1380" +echo "1..600" -i=1 -for cipher in aes:0 aes:128 aes:256 \ - aes-xts:0 aes-xts:128 aes-xts:256 \ - aes-cbc:0 aes-cbc:128 aes-cbc:192 aes-cbc:256 \ - 3des:0 3des:192 \ - 3des-cbc:0 3des-cbc:192 \ - blowfish:0 blowfish:128 blowfish:160 blowfish:192 blowfish:224 \ - blowfish:256 blowfish:288 blowfish:320 blowfish:352 blowfish:384 \ - blowfish:416 blowfish:448 \ - blowfish-cbc:0 blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 blowfish-cbc:224 \ - blowfish-cbc:256 blowfish-cbc:288 blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \ - blowfish-cbc:416 blowfish-cbc:448 \ - camellia:0 camellia:128 camellia:192 camellia:256 \ - camellia-cbc:0 camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do +do_test() { + cipher=$1 + aalgo=$2 + secsize=$3 ealgo=${cipher%%:*} keylen=${cipher##*:} - for aalgo in hmac/md5 hmac/sha1 hmac/ripemd160 hmac/sha256 hmac/sha384 hmac/sha512; do - for secsize in 512 1024 2048 4096 8192; do - rnd=`mktemp $base.XXXXXX` || exit 1 - mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1 - - geli onetime -a $aalgo -e $ealgo -l $keylen -s $secsize md${no} 2>/dev/null - - secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'` - - dd if=/dev/random of=${rnd} bs=${secsize} count=${secs} >/dev/null 2>&1 - dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null - - md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5` - md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5` - - if [ ${md_rnd} = ${md_ddev} ]; then - echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) - - geli detach md${no} - rm -f $rnd - mdconfig -d -u $no - done - done -done + + mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1 + geli onetime -a $aalgo -e $ealgo -l $keylen -s $secsize md${no} 2>/dev/null + + secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'` + + dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null + + md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5` + md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5` + + if [ ${md_rnd} = ${md_ddev} ]; then + echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) + + geli detach md${no} + mdconfig -d -u $no +} + +i=1 +dd if=/dev/random of=${rnd} bs=1024 count=1024 >/dev/null 2>&1 + +for_each_geli_config do_test + +rm -f $rnd diff --git a/tests/sys/geom/class/eli/onetime_test.sh b/tests/sys/geom/class/eli/onetime_test.sh index 17061d0..3cade15 100644 --- a/tests/sys/geom/class/eli/onetime_test.sh +++ b/tests/sys/geom/class/eli/onetime_test.sh @@ -6,54 +6,45 @@ base=`basename $0` sectors=100 -echo "1..460" +echo "1..200" -i=1 -for cipher in aes:0 aes:128 aes:256 \ - aes-xts:0 aes-xts:128 aes-xts:256 \ - aes-cbc:0 aes-cbc:128 aes-cbc:192 aes-cbc:256 \ - 3des:0 3des:192 \ - 3des-cbc:0 3des-cbc:192 \ - blowfish:0 blowfish:128 blowfish:160 blowfish:192 blowfish:224 \ - blowfish:256 blowfish:288 blowfish:320 blowfish:352 blowfish:384 \ - blowfish:416 blowfish:448 \ - blowfish-cbc:0 blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 blowfish-cbc:224 \ - blowfish-cbc:256 blowfish-cbc:288 blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \ - blowfish-cbc:416 blowfish-cbc:448 \ - camellia:0 camellia:128 camellia:192 camellia:256 \ - camellia-cbc:0 camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do +do_test() { + cipher=$1 + secsize=$2 ealgo=${cipher%%:*} keylen=${cipher##*:} - for secsize in 512 1024 2048 4096 8192; do - rnd=`mktemp $base.XXXXXX` || exit 1 - mdconfig -a -t malloc -s `expr $secsize \* $sectors`b -u $no || exit 1 - - geli onetime -e $ealgo -l $keylen -s $secsize md${no} 2>/dev/null - - secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'` - - dd if=/dev/random of=${rnd} bs=${secsize} count=${secs} >/dev/null 2>&1 - dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null - - md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5` - md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5` - md_edev=`dd if=/dev/md${no} bs=${secsize} count=${secs} 2>/dev/null | md5` - - if [ ${md_rnd} = ${md_ddev} ]; then - echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) - if [ ${md_rnd} != ${md_edev} ]; then - echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - else - echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" - fi - i=$((i+1)) - - geli detach md${no} - rm -f $rnd - mdconfig -d -u $no - done -done + + rnd=`mktemp $base.XXXXXX` || exit 1 + mdconfig -a -t malloc -s `expr $secsize \* $sectors`b -u $no || exit 1 + + geli onetime -e $ealgo -l $keylen -s $secsize md${no} 2>/dev/null + + secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'` + + dd if=/dev/random of=${rnd} bs=${secsize} count=${secs} >/dev/null 2>&1 + dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null + + md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5` + md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5` + md_edev=`dd if=/dev/md${no} bs=${secsize} count=${secs} 2>/dev/null | md5` + + if [ ${md_rnd} = ${md_ddev} ]; then + echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) + if [ ${md_rnd} != ${md_edev} ]; then + echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + else + echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}" + fi + i=$((i+1)) + + geli detach md${no} + rm -f $rnd + mdconfig -d -u $no +} + +i=1 +for_each_geli_config_nointegrity do_test diff --git a/tests/sys/geom/class/nop/1_test.sh b/tests/sys/geom/class/nop/1_test.sh deleted file mode 100644 index 4d6b65d..0000000 --- a/tests/sys/geom/class/nop/1_test.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -. `dirname $0`/conf.sh - -echo "1..1" - -us=$(attach_md -t malloc -s 1M) || exit 1 - -gnop create /dev/${us} || exit 1 - -# Size of created device should be 1MB. - -size=`diskinfo /dev/${us}.nop | awk '{print $3}'` - -if [ $size -eq 1048576 ]; then - echo "ok 1" -else - echo "not ok 1" -fi diff --git a/tests/sys/geom/class/nop/2_test.sh b/tests/sys/geom/class/nop/2_test.sh deleted file mode 100644 index 7422345..0000000 --- a/tests/sys/geom/class/nop/2_test.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -. `dirname $0`/conf.sh - -src=`mktemp $base.XXXXXX` || exit 1 -dst=`mktemp $base.XXXXXX` || exit 1 - -echo "1..1" - -dd if=/dev/random of=${src} bs=1m count=1 >/dev/null 2>&1 - -us=$(attach_md -t malloc -s 1M) || exit 1 - -gnop create /dev/${us} || exit 1 - -dd if=${src} of=/dev/${us}.nop bs=1m count=1 >/dev/null 2>&1 -dd if=/dev/${us}.nop of=${dst} bs=1m count=1 >/dev/null 2>&1 - -if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then - echo "not ok 1" -else - echo "ok 1" -fi - -rm -f ${src} ${dst} diff --git a/tests/sys/geom/class/nop/Makefile b/tests/sys/geom/class/nop/Makefile index 5659b5d..40b295e 100644 --- a/tests/sys/geom/class/nop/Makefile +++ b/tests/sys/geom/class/nop/Makefile @@ -2,15 +2,6 @@ TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T} -TAP_TESTS_SH+= 1_test -TAP_TESTS_SH+= 2_test - -FILES+= conf.sh -FILESNAME_conf.sh= conf.sh -FILESDIR= ${TESTSDIR} - -.for t in ${TAP_TESTS_SH} -TEST_METADATA.$t+= required_user="root" -.endfor +ATF_TESTS_SH+= nop_test .include <bsd.test.mk> diff --git a/tests/sys/geom/class/nop/conf.sh b/tests/sys/geom/class/nop/conf.sh deleted file mode 100644 index e38e10c..0000000 --- a/tests/sys/geom/class/nop/conf.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# $FreeBSD$ - -class="nop" -base=`basename $0` - -gnop_test_cleanup() -{ - [ -c /dev/${us}.nop ] && gnop destroy ${us}.nop - geom_test_cleanup -} -trap gnop_test_cleanup ABRT EXIT INT TERM - -. `dirname $0`/../geom_subr.sh diff --git a/tests/sys/geom/class/nop/nop_test.sh b/tests/sys/geom/class/nop/nop_test.sh new file mode 100755 index 0000000..35cc191 --- /dev/null +++ b/tests/sys/geom/class/nop/nop_test.sh @@ -0,0 +1,166 @@ +# Copyright (c) 2016 Alan Somers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +MD_DEVS="md.devs" +PLAINFILES=plainfiles + +atf_test_case diskinfo cleanup +diskinfo_head() +{ + atf_set "descr" "gnop should preserve diskinfo's basic properties" + atf_set "require.user" "root" + atf_set "timeout" 15 +} +diskinfo_body() +{ + us=$(alloc_md) + atf_check gnop create /dev/${us} + md_secsize=$(diskinfo ${us} | cut -wf 2) + md_mediasize=$(diskinfo ${us} | cut -wf 3) + md_stripesize=$(diskinfo ${us} | cut -wf 5) + nop_secsize=$(diskinfo ${us}.nop | cut -wf 2) + nop_mediasize=$(diskinfo ${us}.nop | cut -wf 3) + nop_stripesize=$(diskinfo ${us}.nop | cut -wf 5) + atf_check_equal "$md_secsize" "$nop_secsize" + atf_check_equal "$md_mediasize" "$nop_mediasize" + atf_check_equal "$md_stripesize" "$nop_stripesize" +} +diskinfo_cleanup() +{ + common_cleanup +} + +atf_test_case io cleanup +io_head() +{ + atf_set "descr" "I/O works on gnop devices" + atf_set "require.user" "root" + atf_set "timeout" 15 +} +io_body() +{ + us=$(alloc_md) + atf_check gnop create /dev/${us} + + echo src >> $PLAINFILES + echo dst >> $PLAINFILES + dd if=/dev/random of=src bs=1m count=1 >/dev/null 2>&1 + dd if=src of=/dev/${us}.nop bs=1m count=1 > /dev/null 2>&1 + dd if=/dev/${us}.nop of=dst bs=1m count=1 > /dev/null 2>&1 + + atf_check_equal `md5 -q src` `md5 -q dst` +} +io_cleanup() +{ + common_cleanup +} + +atf_test_case size cleanup +size_head() +{ + atf_set "descr" "Test gnop's -s option" + atf_set "require.user" "root" + atf_set "timeout" 15 +} +size_body() +{ + us=$(alloc_md) + for mediasize in 65536 524288 1048576; do + atf_check gnop create -s ${mediasize} /dev/${us} + gnop_mediasize=`diskinfo /dev/${us}.nop | cut -wf 3` + atf_check_equal "${mediasize}" "${gnop_mediasize}" + atf_check gnop destroy /dev/${us}.nop + done + # We shouldn't be able to extend the provider's size + atf_check -s not-exit:0 -e ignore gnop create -s 2097152 /dev/${us} +} +size_cleanup() +{ + common_cleanup +} + +atf_test_case stripesize cleanup +stripesize_head() +{ + atf_set "descr" "Test gnop's -p and -P options" + atf_set "require.user" "root" + atf_set "timeout" 15 +} +stripesize_body() +{ + us=$(alloc_md) + for ss in 512 1024 2048 4096 8192; do + for sofs in `seq 0 512 ${ss}`; do + [ "$sofs" -eq "$ss" ] && continue + atf_check gnop create -p ${ss} -P ${sofs} /dev/${us} + gnop_ss=`diskinfo /dev/${us}.nop | cut -wf 5` + gnop_sofs=`diskinfo /dev/${us}.nop | cut -wf 6` + atf_check_equal "${ss}" "${gnop_ss}" + atf_check_equal "${sofs}" "${gnop_sofs}" + atf_check gnop destroy /dev/${us}.nop + done + done +} +stripesize_cleanup() +{ + common_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case io + atf_add_test_case diskinfo + atf_add_test_case stripesize + atf_add_test_case size +} + +alloc_md() +{ + local md + + md=$(mdconfig -a -t swap -s 1M) || atf_fail "mdconfig -a failed" + echo ${md} >> $MD_DEVS + echo ${md} +} + +common_cleanup() +{ + if [ -f "$MD_DEVS" ]; then + while read test_md; do + gnop destroy -f ${test_md}.nop 2>/dev/null + mdconfig -d -u $test_md 2>/dev/null + done < $MD_DEVS + rm $MD_DEVS + fi + + if [ -f "$PLAINFILES" ]; then + while read f; do + rm -f ${f} + done < ${PLAINFILES} + rm ${PLAINFILES} + fi + true +} diff --git a/tests/sys/kern/acct/Makefile b/tests/sys/kern/acct/Makefile index 89bf3e0..98a316c 100644 --- a/tests/sys/kern/acct/Makefile +++ b/tests/sys/kern/acct/Makefile @@ -13,6 +13,7 @@ acct_test.o: convert.c convert.c: ${.CURDIR:H:H:H:H}/sys/kern/kern_acct.c sed -n -e 's/log(/syslog(/g' \ + -e 's/exp/exponent/g' \ -e '/FLOAT_CONVERSION_START/,/FLOAT_CONVERSION_END/p' ${.ALLSRC} >${.TARGET}.tmp mv ${.TARGET}.tmp ${.TARGET} diff --git a/tests/sys/kern/execve/execve_helper.c b/tests/sys/kern/execve/execve_helper.c index 164a8f3..989b3e4 100644 --- a/tests/sys/kern/execve/execve_helper.c +++ b/tests/sys/kern/execve/execve_helper.c @@ -50,5 +50,5 @@ main(int argc, char **argv) } execve(argv[1], &argv[1], NULL); - err(1, ""); + err(1, "execve failed"); } diff --git a/tests/sys/kern/reaper.c b/tests/sys/kern/reaper.c index d11ee70..6031713 100644 --- a/tests/sys/kern/reaper.c +++ b/tests/sys/kern/reaper.c @@ -639,6 +639,107 @@ ATF_TC_BODY(reaper_kill_normal, tc) ATF_REQUIRE_EQ(0, r); } +ATF_TC_WITHOUT_HEAD(reaper_kill_subtree); +ATF_TC_BODY(reaper_kill_subtree, tc) +{ + struct procctl_reaper_kill params; + ssize_t sr; + pid_t parent, child1, child2, grandchild1, grandchild2, pid; + int r, status; + int pip[2]; + + parent = getpid(); + r = procctl(P_PID, parent, PROC_REAP_ACQUIRE, NULL); + ATF_REQUIRE_EQ(0, r); + + r = pipe(pip); + ATF_REQUIRE_EQ(0, r); + child1 = fork(); + ATF_REQUIRE(child1 != -1); + if (child1 == 0) { + if (close(pip[0]) != 0) + _exit(100); + grandchild1 = fork(); + if (grandchild1 == -1) + _exit(101); + if (grandchild1 == 0) { + if (write(pip[1], &(uint8_t){ 0 }, 1) != 1) + _exit(102); + for (;;) + pause(); + } + for (;;) + pause(); + } + child2 = fork(); + ATF_REQUIRE(child2 != -1); + if (child2 == 0) { + if (close(pip[0]) != 0) + _exit(100); + grandchild2 = fork(); + if (grandchild2 == -1) + _exit(101); + if (grandchild2 == 0) { + if (write(pip[1], &(uint8_t){ 0 }, 1) != 1) + _exit(102); + for (;;) + pause(); + } + for (;;) + pause(); + } + r = close(pip[1]); + ATF_REQUIRE_EQ(0, r); + + sr = read(pip[0], &(uint8_t){ 0 }, 1); + ATF_REQUIRE_EQ(1, sr); + sr = read(pip[0], &(uint8_t){ 0 }, 1); + ATF_REQUIRE_EQ(1, sr); + + params.rk_sig = SIGUSR1; + params.rk_flags = REAPER_KILL_SUBTREE; + params.rk_subtree = child1; + params.rk_killed = 77; + r = procctl(P_PID, parent, PROC_REAP_KILL, ¶ms); + ATF_REQUIRE_EQ(0, r); + ATF_REQUIRE_EQ(2, params.rk_killed); + ATF_CHECK_EQ(-1, params.rk_fpid); + + pid = waitpid(child1, &status, 0); + ATF_REQUIRE_EQ(child1, pid); + ATF_CHECK(WIFSIGNALED(status) && WTERMSIG(status) == SIGUSR1); + + pid = waitpid(-1, &status, 0); + ATF_REQUIRE(pid > 0); + ATF_CHECK(pid != parent); + ATF_CHECK(pid != child1); + ATF_CHECK(pid != child2); + ATF_CHECK(WIFSIGNALED(status) && WTERMSIG(status) == SIGUSR1); + + params.rk_sig = SIGUSR2; + params.rk_flags = REAPER_KILL_SUBTREE; + params.rk_subtree = child2; + params.rk_killed = 77; + r = procctl(P_PID, parent, PROC_REAP_KILL, ¶ms); + ATF_REQUIRE_EQ(0, r); + ATF_REQUIRE_EQ(2, params.rk_killed); + ATF_CHECK_EQ(-1, params.rk_fpid); + + pid = waitpid(child2, &status, 0); + ATF_REQUIRE_EQ(child2, pid); + ATF_CHECK(WIFSIGNALED(status) && WTERMSIG(status) == SIGUSR2); + + pid = waitpid(-1, &status, 0); + ATF_REQUIRE(pid > 0); + ATF_CHECK(pid != parent); + ATF_CHECK(pid != child1); + ATF_CHECK(pid != child2); + ATF_CHECK(WIFSIGNALED(status) && WTERMSIG(status) == SIGUSR2); + + r = close(pip[0]); + ATF_REQUIRE_EQ(0, r); +} + ATF_TP_ADD_TCS(tp) { @@ -652,5 +753,6 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, reaper_kill_sigzero); ATF_TP_ADD_TC(tp, reaper_kill_empty); ATF_TP_ADD_TC(tp, reaper_kill_normal); + ATF_TP_ADD_TC(tp, reaper_kill_subtree); return (atf_no_error()); } diff --git a/tests/sys/mac/bsdextended/ugidfw_test.c b/tests/sys/mac/bsdextended/ugidfw_test.c index aab8553..57a283b 100644 --- a/tests/sys/mac/bsdextended/ugidfw_test.c +++ b/tests/sys/mac/bsdextended/ugidfw_test.c @@ -71,7 +71,7 @@ static const char *test_groups[] = { "bin", }; -int test_num; +static int test_num; /* * List of test strings that must go in (and come out) of libugidfw intact. @@ -149,7 +149,8 @@ test_libugidfw_strings(void) struct mac_bsdextended_rule rule; char errorstr[256]; char rulestr[256]; - int error, i; + size_t i; + int error; for (i = 0; i < nitems(test_users); i++, test_num++) { if (getpwnam(test_users[i]) == NULL) @@ -171,7 +172,7 @@ test_libugidfw_strings(void) error = bsde_parse_rule_string(test_strings[i], &rule, sizeof(errorstr), errorstr); if (error == -1) - printf("not ok %d # bsde_parse_rule_string: '%s' (%d) " + printf("not ok %d # bsde_parse_rule_string: '%s' (%zu) " "failed: %s\n", test_num, test_strings[i], i, errorstr); else printf("ok %d\n", test_num); @@ -221,7 +222,7 @@ main(void) return (0); } - printf("1..%lu\n", nitems(test_users) + nitems(test_groups) + + printf("1..%zu\n", nitems(test_users) + nitems(test_groups) + 3 * nitems(test_strings) + 2); test_libugidfw_strings(); diff --git a/tests/sys/vm/mmap_test.c b/tests/sys/vm/mmap_test.c index df52072..86ea8e8 100644 --- a/tests/sys/vm/mmap_test.c +++ b/tests/sys/vm/mmap_test.c @@ -192,8 +192,7 @@ ATF_TC_WITHOUT_HEAD(mmap__dev_zero_private); ATF_TC_BODY(mmap__dev_zero_private, tc) { char *p1, *p2, *p3; - size_t i; - int fd, pagesize; + int fd, i, pagesize; ATF_REQUIRE((pagesize = getpagesize()) > 0); ATF_REQUIRE((fd = open("/dev/zero", O_RDONLY)) >= 0); @@ -205,7 +204,7 @@ ATF_TC_BODY(mmap__dev_zero_private, tc) ATF_REQUIRE(p2 != MAP_FAILED); for (i = 0; i < pagesize; i++) - ATF_REQUIRE_EQ_MSG(0, p1[i], "byte at p1[%zu] is %x", i, p1[i]); + ATF_REQUIRE_EQ_MSG(0, p1[i], "byte at p1[%d] is %x", i, p1[i]); ATF_REQUIRE(memcmp(p1, p2, pagesize) == 0); @@ -232,8 +231,7 @@ ATF_TC_WITHOUT_HEAD(mmap__dev_zero_shared); ATF_TC_BODY(mmap__dev_zero_shared, tc) { char *p1, *p2, *p3; - size_t i; - int fd, pagesize; + int fd, i, pagesize; ATF_REQUIRE((pagesize = getpagesize()) > 0); ATF_REQUIRE((fd = open("/dev/zero", O_RDWR)) >= 0); @@ -245,7 +243,7 @@ ATF_TC_BODY(mmap__dev_zero_shared, tc) ATF_REQUIRE(p2 != MAP_FAILED); for (i = 0; i < pagesize; i++) - ATF_REQUIRE_EQ_MSG(0, p1[i], "byte at p1[%zu] is %x", i, p1[i]); + ATF_REQUIRE_EQ_MSG(0, p1[i], "byte at p1[%d] is %x", i, p1[i]); ATF_REQUIRE(memcmp(p1, p2, pagesize) == 0); diff --git a/tools/tools/gensnmpdef/Makefile b/tools/tools/gensnmpdef/Makefile new file mode 100644 index 0000000..470e1de --- /dev/null +++ b/tools/tools/gensnmpdef/Makefile @@ -0,0 +1,24 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/contrib/bsnmp/gensnmpdef + +PROG= gensnmpdef + +SRCS= gensnmpdef.c + +MAN= gensnmpdef.1 + +LOCALBASE?= /usr/local + +BINDIR= ${LOCALBASE}/bin + +MANDIR= ${LOCALBASE}/man/man + +CFLAGS+= -I${LOCALBASE}/include +LDFLAGS+= -L${LOCALBASE}/lib + +LDADD+= -lsmi + +WARNS?= 6 + +.include <bsd.prog.mk> diff --git a/usr.bin/chat/chat.c b/usr.bin/chat/chat.c index fa2df10..c82a130 100644 --- a/usr.bin/chat/chat.c +++ b/usr.bin/chat/chat.c @@ -1173,7 +1173,7 @@ int get_string(char *string) { char temp[STR_LEN]; - int c, printed = 0; + int c; size_t len, minlen; char *s = temp, *end = s + STR_LEN; char *logged = temp; @@ -1306,13 +1306,6 @@ get_string(char *string) alarm(0); - if (verbose && printed) { - if (alarmed) - chat_logf(" -- read timed out"); - else - chat_logf(" -- read failed: %m"); - } - exit_code = 3; alarmed = 0; return (0); diff --git a/usr.bin/ctlstat/ctlstat.8 b/usr.bin/ctlstat/ctlstat.8 index 77eb790..038b8ca 100644 --- a/usr.bin/ctlstat/ctlstat.8 +++ b/usr.bin/ctlstat/ctlstat.8 @@ -34,7 +34,7 @@ .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.bin/ctlstat/ctlstat.8#2 $ .\" $FreeBSD$ .\" -.Dd September 21, 2015 +.Dd January 9, 2017 .Dt CTLSTAT 8 .Os .Sh NAME @@ -118,5 +118,6 @@ every 10 seconds. .Xr ctld 8 , .Xr iostat 8 .Sh AUTHORS -.An Ken Merry Aq ken@FreeBSD.org -.An Will Andrews Aq will@FreeBSD.org +.An Ken Merry Aq Mt ken@FreeBSD.org +.An Will Andrews Aq Mt will@FreeBSD.org +.An Alexander Motin Aq Mt mav@FreeBSD.org diff --git a/usr.bin/ctlstat/ctlstat.c b/usr.bin/ctlstat/ctlstat.c index 3587586..d55e004 100644 --- a/usr.bin/ctlstat/ctlstat.c +++ b/usr.bin/ctlstat/ctlstat.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2004, 2008, 2009 Silicon Graphics International Corp. + * Copyright (c) 2017 Alexander Motin <mav@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,17 +67,17 @@ __FBSDID("$FreeBSD$"); #include <cam/ctl/ctl_ioctl.h> /* - * The default amount of space we allocate for LUN storage space. We - * dynamically allocate more if needed. + * The default amount of space we allocate for stats storage space. + * We dynamically allocate more if needed. */ -#define CTL_STAT_NUM_LUNS 30 +#define CTL_STAT_NUM_ITEMS 256 /* * The default number of LUN selection bits we allocate. This is large * because we don't currently increase it if the user specifies a LUN * number of 1024 or larger. */ -#define CTL_STAT_LUN_BITS 1024L +#define CTL_STAT_BITS 1024L static const char *ctlstat_opts = "Cc:Ddhjl:n:p:tw:"; static const char *ctlstat_usage = "Usage: ctlstat [-CDdjht] [-l lunnum]" @@ -101,31 +102,32 @@ typedef enum { #define CTLSTAT_FLAG_FIRST_RUN (1 << 2) #define CTLSTAT_FLAG_TOTALS (1 << 3) #define CTLSTAT_FLAG_DMA_TIME (1 << 4) -#define CTLSTAT_FLAG_LUN_TIME_VALID (1 << 5) -#define CTLSTAT_FLAG_LUN_MASK (1 << 6) -#define CTLSTAT_FLAG_PORT_MASK (1 << 7) +#define CTLSTAT_FLAG_TIME_VALID (1 << 5) +#define CTLSTAT_FLAG_MASK (1 << 6) +#define CTLSTAT_FLAG_LUNS (1 << 7) +#define CTLSTAT_FLAG_PORTS (1 << 8) #define F_CPU(ctx) ((ctx)->flags & CTLSTAT_FLAG_CPU) #define F_HDR(ctx) ((ctx)->flags & CTLSTAT_FLAG_HEADER) #define F_FIRST(ctx) ((ctx)->flags & CTLSTAT_FLAG_FIRST_RUN) #define F_TOTALS(ctx) ((ctx)->flags & CTLSTAT_FLAG_TOTALS) #define F_DMA(ctx) ((ctx)->flags & CTLSTAT_FLAG_DMA_TIME) -#define F_LUNVAL(ctx) ((ctx)->flags & CTLSTAT_FLAG_LUN_TIME_VALID) -#define F_LUNMASK(ctx) ((ctx)->flags & CTLSTAT_FLAG_LUN_MASK) -#define F_PORTMASK(ctx) ((ctx)->flags & CTLSTAT_FLAG_PORT_MASK) +#define F_TIMEVAL(ctx) ((ctx)->flags & CTLSTAT_FLAG_TIME_VALID) +#define F_MASK(ctx) ((ctx)->flags & CTLSTAT_FLAG_MASK) +#define F_LUNS(ctx) ((ctx)->flags & CTLSTAT_FLAG_LUNS) +#define F_PORTS(ctx) ((ctx)->flags & CTLSTAT_FLAG_PORTS) struct ctlstat_context { ctlstat_mode_types mode; int flags; - struct ctl_lun_io_stats *cur_lun_stats, *prev_lun_stats, - *tmp_lun_stats; - struct ctl_lun_io_stats cur_total_stats[3], prev_total_stats[3]; + struct ctl_io_stats *cur_stats, *prev_stats; + struct ctl_io_stats cur_total_stats[3], prev_total_stats[3]; struct timespec cur_time, prev_time; struct ctl_cpu_stats cur_cpu, prev_cpu; uint64_t cur_total_jiffies, prev_total_jiffies; uint64_t cur_idle, prev_idle; - bitstr_t bit_decl(lun_mask, CTL_STAT_LUN_BITS); - bitstr_t bit_decl(port_mask, CTL_MAX_PORTS); - int num_luns; + bitstr_t bit_decl(item_mask, CTL_STAT_BITS); + int cur_items, prev_items; + int cur_alloc, prev_alloc; int numdevs; int header_interval; }; @@ -135,12 +137,11 @@ struct ctlstat_context { #endif static void usage(int error); -static int getstats(int fd, int *num_luns, struct ctl_lun_io_stats **xlun_stats, - struct timespec *cur_time, int *lun_time_valid); +static int getstats(int fd, int *alloc_items, int *num_items, + struct ctl_io_stats **xstats, struct timespec *cur_time, int *time_valid); static int getcpu(struct ctl_cpu_stats *cpu_stats); -static void compute_stats(struct ctlstat_context *ctx, - struct ctl_lun_io_stats *cur_stats, - struct ctl_lun_io_stats *prev_stats, +static void compute_stats(struct ctl_io_stats *cur_stats, + struct ctl_io_stats *prev_stats, long double etime, long double *mbsec, long double *kb_per_transfer, long double *transfers_per_second, @@ -155,64 +156,55 @@ usage(int error) } static int -getstats(int fd, int *num_luns, struct ctl_lun_io_stats **xlun_stats, +getstats(int fd, int *alloc_items, int *num_items, struct ctl_io_stats **stats, struct timespec *cur_time, int *flags) { - struct ctl_lun_io_stats *lun_stats; - struct ctl_stats stats; - int more_space_count; + struct ctl_get_io_stats get_stats; + int more_space_count = 0; - more_space_count = 0; - - if (*num_luns == 0) - *num_luns = CTL_STAT_NUM_LUNS; - - lun_stats = *xlun_stats; + if (*alloc_items == 0) + *alloc_items = CTL_STAT_NUM_ITEMS; retry: + if (*stats == NULL) + *stats = malloc(sizeof(**stats) * *alloc_items); - if (lun_stats == NULL) { - lun_stats = (struct ctl_lun_io_stats *)malloc( - sizeof(*lun_stats) * *num_luns); - } - - memset(&stats, 0, sizeof(stats)); - stats.alloc_len = *num_luns * sizeof(*lun_stats); - memset(lun_stats, 0, stats.alloc_len); - stats.lun_stats = lun_stats; + memset(&get_stats, 0, sizeof(get_stats)); + get_stats.alloc_len = *alloc_items * sizeof(**stats); + memset(*stats, 0, get_stats.alloc_len); + get_stats.stats = *stats; - if (ioctl(fd, CTL_GETSTATS, &stats) == -1) - err(1, "error returned from CTL_GETSTATS ioctl"); + if (ioctl(fd, (*flags & CTLSTAT_FLAG_PORTS) ? CTL_GET_PORT_STATS : + CTL_GET_LUN_STATS, &get_stats) == -1) + err(1, "CTL_GET_*_STATS ioctl returned error"); - switch (stats.status) { + switch (get_stats.status) { case CTL_SS_OK: break; case CTL_SS_ERROR: - err(1, "CTL_SS_ERROR returned from CTL_GETSTATS ioctl"); + err(1, "CTL_GET_*_STATS ioctl returned CTL_SS_ERROR"); break; case CTL_SS_NEED_MORE_SPACE: - if (more_space_count > 0) { - errx(1, "CTL_GETSTATS returned NEED_MORE_SPACE again"); - } - *num_luns = stats.num_luns; - free(lun_stats); - lun_stats = NULL; + if (more_space_count >= 2) + errx(1, "CTL_GET_*_STATS returned NEED_MORE_SPACE again"); + *alloc_items = get_stats.num_items * 5 / 4; + free(*stats); + *stats = NULL; more_space_count++; goto retry; break; /* NOTREACHED */ default: - errx(1, "unknown status %d returned from CTL_GETSTATS ioctl", - stats.status); + errx(1, "CTL_GET_*_STATS ioctl returned unknown status %d", + get_stats.status); break; } - *xlun_stats = lun_stats; - *num_luns = stats.num_luns; - cur_time->tv_sec = stats.timestamp.tv_sec; - cur_time->tv_nsec = stats.timestamp.tv_nsec; - if (stats.flags & CTL_STATS_FLAG_TIME_VALID) - *flags |= CTLSTAT_FLAG_LUN_TIME_VALID; + *num_items = get_stats.fill_len / sizeof(**stats); + cur_time->tv_sec = get_stats.timestamp.tv_sec; + cur_time->tv_nsec = get_stats.timestamp.tv_nsec; + if (get_stats.flags & CTL_STATS_FLAG_TIME_VALID) + *flags |= CTLSTAT_FLAG_TIME_VALID; else - *flags &= ~CTLSTAT_FLAG_LUN_TIME_VALID; + *flags &= ~CTLSTAT_FLAG_TIME_VALID; return (0); } @@ -240,14 +232,13 @@ getcpu(struct ctl_cpu_stats *cpu_stats) } static void -compute_stats(struct ctlstat_context *ctx, struct ctl_lun_io_stats *cur_stats, - struct ctl_lun_io_stats *prev_stats, long double etime, +compute_stats(struct ctl_io_stats *cur_stats, + struct ctl_io_stats *prev_stats, long double etime, long double *mbsec, long double *kb_per_transfer, long double *transfers_per_second, long double *ms_per_transfer, long double *ms_per_dma, long double *dmas_per_second) { uint64_t total_bytes = 0, total_operations = 0, total_dmas = 0; - uint32_t port; struct bintime total_time_bt, total_dma_bt; struct timespec total_time_ts, total_dma_ts; int i; @@ -256,31 +247,18 @@ compute_stats(struct ctlstat_context *ctx, struct ctl_lun_io_stats *cur_stats, bzero(&total_dma_bt, sizeof(total_dma_bt)); bzero(&total_time_ts, sizeof(total_time_ts)); bzero(&total_dma_ts, sizeof(total_dma_ts)); - for (port = 0; port < CTL_MAX_PORTS; port++) { - if (F_PORTMASK(ctx) && - bit_test(ctx->port_mask, port) == 0) - continue; - for (i = 0; i < CTL_STATS_NUM_TYPES; i++) { - total_bytes += cur_stats->ports[port].bytes[i]; - total_operations += - cur_stats->ports[port].operations[i]; - total_dmas += cur_stats->ports[port].num_dmas[i]; - bintime_add(&total_time_bt, - &cur_stats->ports[port].time[i]); - bintime_add(&total_dma_bt, - &cur_stats->ports[port].dma_time[i]); - if (prev_stats != NULL) { - total_bytes -= - prev_stats->ports[port].bytes[i]; - total_operations -= - prev_stats->ports[port].operations[i]; - total_dmas -= - prev_stats->ports[port].num_dmas[i]; - bintime_sub(&total_time_bt, - &prev_stats->ports[port].time[i]); - bintime_sub(&total_dma_bt, - &prev_stats->ports[port].dma_time[i]); - } + for (i = 0; i < CTL_STATS_NUM_TYPES; i++) { + total_bytes += cur_stats->bytes[i]; + total_operations += cur_stats->operations[i]; + total_dmas += cur_stats->dmas[i]; + bintime_add(&total_time_bt, &cur_stats->time[i]); + bintime_add(&total_dma_bt, &cur_stats->dma_time[i]); + if (prev_stats != NULL) { + total_bytes -= prev_stats->bytes[i]; + total_operations -= prev_stats->operations[i]; + total_dmas -= prev_stats->dmas[i]; + bintime_sub(&total_time_bt, &prev_stats->time[i]); + bintime_sub(&total_dma_bt, &prev_stats->dma_time[i]); } } @@ -340,35 +318,25 @@ compute_stats(struct ctlstat_context *ctx, struct ctl_lun_io_stats *cur_stats, static const char *iotypes[] = {"NO IO", "READ", "WRITE"}; static void -ctlstat_dump(struct ctlstat_context *ctx) { - int iotype, lun, port; - struct ctl_lun_io_stats *stats = ctx->cur_lun_stats; +ctlstat_dump(struct ctlstat_context *ctx) +{ + int iotype, i; + struct ctl_io_stats *stats = ctx->cur_stats; - for (lun = 0; lun < ctx->num_luns;lun++) { - if (F_LUNMASK(ctx) && bit_test(ctx->lun_mask, lun) == 0) + for (i = 0; i < ctx->cur_items;i++) { + if (F_MASK(ctx) && bit_test(ctx->item_mask, i) == 0) continue; - printf("lun %d\n", lun); - for (port = 0; port < CTL_MAX_PORTS; port++) { - if (F_PORTMASK(ctx) && - bit_test(ctx->port_mask, port) == 0) - continue; - printf(" port %d\n", - stats[lun].ports[port].targ_port); - for (iotype = 0; iotype < CTL_STATS_NUM_TYPES; - iotype++) { - printf(" io type %d (%s)\n", iotype, - iotypes[iotype]); - printf(" bytes %ju\n", (uintmax_t) - stats[lun].ports[port].bytes[iotype]); - printf(" operations %ju\n", (uintmax_t) - stats[lun].ports[port].operations[iotype]); - PRINT_BINTIME(" io time", - stats[lun].ports[port].time[iotype]); - printf(" num dmas %ju\n", (uintmax_t) - stats[lun].ports[port].num_dmas[iotype]); - PRINT_BINTIME(" dma time", - stats[lun].ports[port].dma_time[iotype]); - } + printf("%s %d\n", F_PORTS(ctx) ? "port" : "lun", stats[i].item); + for (iotype = 0; iotype < CTL_STATS_NUM_TYPES; iotype++) { + printf(" io type %d (%s)\n", iotype, iotypes[iotype]); + printf(" bytes %ju\n", (uintmax_t) + stats[i].bytes[iotype]); + printf(" operations %ju\n", (uintmax_t) + stats[i].operations[iotype]); + printf(" dmas %ju\n", (uintmax_t) + stats[i].dmas[iotype]); + PRINT_BINTIME(" io time", stats[i].time[iotype]); + PRINT_BINTIME(" dma time", stats[i].dma_time[iotype]); } } } @@ -378,63 +346,49 @@ ctlstat_dump(struct ctlstat_context *ctx) { (uintmax_t)(((bt).frac >> 32) * 1000000 >> 32)) static void ctlstat_json(struct ctlstat_context *ctx) { - int iotype, lun, port; - struct ctl_lun_io_stats *stats = ctx->cur_lun_stats; + int iotype, i; + struct ctl_io_stats *stats = ctx->cur_stats; - printf("{\"luns\":["); - for (lun = 0; lun < ctx->num_luns; lun++) { - if (F_LUNMASK(ctx) && bit_test(ctx->lun_mask, lun) == 0) + printf("{\"%s\":[", F_PORTS(ctx) ? "ports" : "luns"); + for (i = 0; i < ctx->cur_items; i++) { + if (F_MASK(ctx) && bit_test(ctx->item_mask, i) == 0) continue; - printf("{\"ports\":["); - for (port = 0; port < CTL_MAX_PORTS;port++) { - if (F_PORTMASK(ctx) && - bit_test(ctx->port_mask, port) == 0) - continue; - printf("{\"num\":%d,\"io\":[", - stats[lun].ports[port].targ_port); - for (iotype = 0; iotype < CTL_STATS_NUM_TYPES; - iotype++) { - printf("{\"type\":\"%s\",", iotypes[iotype]); - printf("\"bytes\":%ju,", (uintmax_t)stats[ - lun].ports[port].bytes[iotype]); - printf("\"operations\":%ju,", (uintmax_t)stats[ - lun].ports[port].operations[iotype]); - JSON_BINTIME("io time", - stats[lun].ports[port].time[iotype]); - JSON_BINTIME("dma time", - stats[lun].ports[port].dma_time[iotype]); - printf("\"num dmas\":%ju}", (uintmax_t) - stats[lun].ports[port].num_dmas[iotype]); - if (iotype < (CTL_STATS_NUM_TYPES - 1)) - printf(","); /* continue io array */ - } - printf("]}"); /* close port */ - if (port < (CTL_MAX_PORTS - 1)) - printf(","); /* continue port array */ + printf("{\"num\":%d,\"io\":[", + stats[i].item); + for (iotype = 0; iotype < CTL_STATS_NUM_TYPES; iotype++) { + printf("{\"type\":\"%s\",", iotypes[iotype]); + printf("\"bytes\":%ju,", (uintmax_t)stats[ + i].bytes[iotype]); + printf("\"operations\":%ju,", (uintmax_t)stats[ + i].operations[iotype]); + printf("\"dmas\":%ju}", (uintmax_t) + stats[i].dmas[iotype]); + JSON_BINTIME("io time", stats[i].time[iotype]); + JSON_BINTIME("dma time", stats[i].dma_time[iotype]); + if (iotype < (CTL_STATS_NUM_TYPES - 1)) + printf(","); /* continue io array */ } - printf("]}"); /* close lun */ - if (lun < (ctx->num_luns - 1)) + printf("]}"); + if (i < (ctx->cur_items - 1)) printf(","); /* continue lun array */ } - printf("]}"); /* close luns and toplevel */ + printf("]}"); } static void ctlstat_standard(struct ctlstat_context *ctx) { long double etime; uint64_t delta_jiffies, delta_idle; - uint32_t port; long double cpu_percentage; - int i; - int j; + int i, j; cpu_percentage = 0; if (F_CPU(ctx) && (getcpu(&ctx->cur_cpu) != 0)) errx(1, "error returned from getcpu()"); - etime = ctx->cur_time.tv_sec - ctx->prev_time.tv_sec + - (ctx->prev_time.tv_nsec - ctx->cur_time.tv_nsec) * 1e-9; + etime = ctx->cur_time.tv_sec - ctx->prev_time.tv_sec + + (ctx->prev_time.tv_nsec - ctx->cur_time.tv_nsec) * 1e-9; if (F_CPU(ctx)) { ctx->prev_total_jiffies = ctx->cur_total_jiffies; @@ -465,29 +419,28 @@ ctlstat_standard(struct ctlstat_context *ctx) { if (F_TOTALS(ctx)) { fprintf(stdout, "%s Read %s" " Write %s Total\n", - (F_LUNVAL(ctx) != 0) ? " " : "", - (F_LUNVAL(ctx) != 0) ? " " : "", - (F_LUNVAL(ctx) != 0) ? " " : ""); + (F_TIMEVAL(ctx) != 0) ? " " : "", + (F_TIMEVAL(ctx) != 0) ? " " : "", + (F_TIMEVAL(ctx) != 0) ? " " : ""); hdr_devs = 3; } else { - for (i = 0; i < min(CTL_STAT_LUN_BITS, - ctx->num_luns); i++) { - int lun; + for (i = 0; i < min(CTL_STAT_BITS, + ctx->cur_items); i++) { + int item; /* * Obviously this won't work with * LUN numbers greater than a signed * integer. */ - lun = (int)ctx->cur_lun_stats[i - ].lun_number; + item = (int)ctx->cur_stats[i].item; - if (F_LUNMASK(ctx) && - bit_test(ctx->lun_mask, lun) == 0) + if (F_MASK(ctx) && + bit_test(ctx->item_mask, item) == 0) continue; fprintf(stdout, "%15.6s%d %s", - "lun", lun, - (F_LUNVAL(ctx) != 0) ? " " : ""); + F_PORTS(ctx) ? "port" : "lun", item, + (F_TIMEVAL(ctx) != 0) ? " " : ""); hdr_devs++; } fprintf(stdout, "\n"); @@ -496,7 +449,7 @@ ctlstat_standard(struct ctlstat_context *ctx) { fprintf(stdout, " "); for (i = 0; i < hdr_devs; i++) fprintf(stdout, "%s KB/t %s MB/s", - (F_LUNVAL(ctx) != 0) ? " ms" : "", + (F_TIMEVAL(ctx) != 0) ? " ms" : "", (F_DMA(ctx) == 0) ? "tps" : "dps"); fprintf(stdout, "\n"); ctx->header_interval = 20; @@ -519,55 +472,48 @@ ctlstat_standard(struct ctlstat_context *ctx) { memset(&ctx->cur_total_stats, 0, sizeof(ctx->cur_total_stats)); /* Use macros to make the next loop more readable. */ -#define ADD_STATS_BYTES(st, p, i, j) \ - ctx->cur_total_stats[st].ports[p].bytes[j] += \ - ctx->cur_lun_stats[i].ports[p].bytes[j] -#define ADD_STATS_OPERATIONS(st, p, i, j) \ - ctx->cur_total_stats[st].ports[p].operations[j] += \ - ctx->cur_lun_stats[i].ports[p].operations[j] -#define ADD_STATS_NUM_DMAS(st, p, i, j) \ - ctx->cur_total_stats[st].ports[p].num_dmas[j] += \ - ctx->cur_lun_stats[i].ports[p].num_dmas[j] -#define ADD_STATS_TIME(st, p, i, j) \ - bintime_add(&ctx->cur_total_stats[st].ports[p].time[j], \ - &ctx->cur_lun_stats[i].ports[p].time[j]) -#define ADD_STATS_DMA_TIME(st, p, i, j) \ - bintime_add(&ctx->cur_total_stats[st].ports[p].dma_time[j], \ - &ctx->cur_lun_stats[i].ports[p].dma_time[j]) - - for (i = 0; i < ctx->num_luns; i++) { - if (F_LUNMASK(ctx) && bit_test(ctx->lun_mask, - (int)ctx->cur_lun_stats[i].lun_number) == 0) +#define ADD_STATS_BYTES(st, i, j) \ + ctx->cur_total_stats[st].bytes[j] += \ + ctx->cur_stats[i].bytes[j] +#define ADD_STATS_OPERATIONS(st, i, j) \ + ctx->cur_total_stats[st].operations[j] += \ + ctx->cur_stats[i].operations[j] +#define ADD_STATS_DMAS(st, i, j) \ + ctx->cur_total_stats[st].dmas[j] += \ + ctx->cur_stats[i].dmas[j] +#define ADD_STATS_TIME(st, i, j) \ + bintime_add(&ctx->cur_total_stats[st].time[j], \ + &ctx->cur_stats[i].time[j]) +#define ADD_STATS_DMA_TIME(st, i, j) \ + bintime_add(&ctx->cur_total_stats[st].dma_time[j], \ + &ctx->cur_stats[i].dma_time[j]) + + for (i = 0; i < ctx->cur_items; i++) { + if (F_MASK(ctx) && bit_test(ctx->item_mask, + (int)ctx->cur_stats[i].item) == 0) continue; - for (port = 0; port < CTL_MAX_PORTS; port++) { - if (F_PORTMASK(ctx) && - bit_test(ctx->port_mask, port) == 0) - continue; - for (j = 0; j < CTL_STATS_NUM_TYPES; j++) { - ADD_STATS_BYTES(2, port, i, j); - ADD_STATS_OPERATIONS(2, port, i, j); - ADD_STATS_NUM_DMAS(2, port, i, j); - ADD_STATS_TIME(2, port, i, j); - ADD_STATS_DMA_TIME(2, port, i, j); - } - ADD_STATS_BYTES(0, port, i, CTL_STATS_READ); - ADD_STATS_OPERATIONS(0, port, i, - CTL_STATS_READ); - ADD_STATS_NUM_DMAS(0, port, i, CTL_STATS_READ); - ADD_STATS_TIME(0, port, i, CTL_STATS_READ); - ADD_STATS_DMA_TIME(0, port, i, CTL_STATS_READ); - - ADD_STATS_BYTES(1, port, i, CTL_STATS_WRITE); - ADD_STATS_OPERATIONS(1, port, i, - CTL_STATS_WRITE); - ADD_STATS_NUM_DMAS(1, port, i, CTL_STATS_WRITE); - ADD_STATS_TIME(1, port, i, CTL_STATS_WRITE); - ADD_STATS_DMA_TIME(1, port, i, CTL_STATS_WRITE); + for (j = 0; j < CTL_STATS_NUM_TYPES; j++) { + ADD_STATS_BYTES(2, i, j); + ADD_STATS_OPERATIONS(2, i, j); + ADD_STATS_DMAS(2, i, j); + ADD_STATS_TIME(2, i, j); + ADD_STATS_DMA_TIME(2, i, j); } + ADD_STATS_BYTES(0, i, CTL_STATS_READ); + ADD_STATS_OPERATIONS(0, i, CTL_STATS_READ); + ADD_STATS_DMAS(0, i, CTL_STATS_READ); + ADD_STATS_TIME(0, i, CTL_STATS_READ); + ADD_STATS_DMA_TIME(0, i, CTL_STATS_READ); + + ADD_STATS_BYTES(1, i, CTL_STATS_WRITE); + ADD_STATS_OPERATIONS(1, i, CTL_STATS_WRITE); + ADD_STATS_DMAS(1, i, CTL_STATS_WRITE); + ADD_STATS_TIME(1, i, CTL_STATS_WRITE); + ADD_STATS_DMA_TIME(1, i, CTL_STATS_WRITE); } for (i = 0; i < 3; i++) { - compute_stats(ctx, &ctx->cur_total_stats[i], + compute_stats(&ctx->cur_total_stats[i], F_FIRST(ctx) ? NULL : &ctx->prev_total_stats[i], etime, &mbsec[i], &kb_per_transfer[i], &transfers_per_sec[i], @@ -576,7 +522,7 @@ ctlstat_standard(struct ctlstat_context *ctx) { if (F_DMA(ctx) != 0) fprintf(stdout, " %5.1Lf", ms_per_dma[i]); - else if (F_LUNVAL(ctx) != 0) + else if (F_TIMEVAL(ctx) != 0) fprintf(stdout, " %5.1Lf", ms_per_transfer[i]); fprintf(stdout, " %4.0Lf %5.0Lf %4.0Lf", @@ -585,25 +531,32 @@ ctlstat_standard(struct ctlstat_context *ctx) { dmas_per_sec[i], mbsec[i]); } } else { - for (i = 0; i < min(CTL_STAT_LUN_BITS, ctx->num_luns); i++) { + for (i = 0; i < min(CTL_STAT_BITS, ctx->cur_items); i++) { long double mbsec, kb_per_transfer; long double transfers_per_sec; long double ms_per_transfer; long double ms_per_dma; long double dmas_per_sec; - if (F_LUNMASK(ctx) && bit_test(ctx->lun_mask, - (int)ctx->cur_lun_stats[i].lun_number) == 0) + if (F_MASK(ctx) && bit_test(ctx->item_mask, + (int)ctx->cur_stats[i].item) == 0) continue; - compute_stats(ctx, &ctx->cur_lun_stats[i], - F_FIRST(ctx) ? NULL : &ctx->prev_lun_stats[i], + for (j = 0; j < ctx->prev_items; j++) { + if (ctx->prev_stats[j].item == + ctx->cur_stats[i].item) + break; + } + if (j >= ctx->prev_items) + j = -1; + compute_stats(&ctx->cur_stats[i], + j >= 0 ? &ctx->prev_stats[j] : NULL, etime, &mbsec, &kb_per_transfer, &transfers_per_sec, &ms_per_transfer, &ms_per_dma, &dmas_per_sec); if (F_DMA(ctx)) fprintf(stdout, " %5.1Lf", ms_per_dma); - else if (F_LUNVAL(ctx) != 0) + else if (F_TIMEVAL(ctx) != 0) fprintf(stdout, " %5.1Lf", ms_per_transfer); fprintf(stdout, " %4.0Lf %5.0Lf %4.0Lf", @@ -620,6 +573,7 @@ main(int argc, char **argv) int count, waittime; int fd, retval; struct ctlstat_context ctx; + struct ctl_io_stats *tmp_stats; /* default values */ retval = 0; @@ -658,15 +612,16 @@ main(int argc, char **argv) int cur_lun; cur_lun = atoi(optarg); - if (cur_lun > CTL_STAT_LUN_BITS) + if (cur_lun > CTL_STAT_BITS) errx(1, "Invalid LUN number %d", cur_lun); - if (!F_LUNMASK(&ctx)) + if (!F_MASK(&ctx)) ctx.numdevs = 1; else ctx.numdevs++; - bit_set(ctx.lun_mask, cur_lun); - ctx.flags |= CTLSTAT_FLAG_LUN_MASK; + bit_set(ctx.item_mask, cur_lun); + ctx.flags |= CTLSTAT_FLAG_MASK; + ctx.flags |= CTLSTAT_FLAG_LUNS; break; } case 'n': @@ -676,11 +631,16 @@ main(int argc, char **argv) int cur_port; cur_port = atoi(optarg); - if (cur_port > CTL_MAX_PORTS) - errx(1, "Invalid LUN number %d", cur_port); + if (cur_port > CTL_STAT_BITS) + errx(1, "Invalid port number %d", cur_port); - bit_set(ctx.port_mask, cur_port); - ctx.flags |= CTLSTAT_FLAG_PORT_MASK; + if (!F_MASK(&ctx)) + ctx.numdevs = 1; + else + ctx.numdevs++; + bit_set(ctx.item_mask, cur_port); + ctx.flags |= CTLSTAT_FLAG_MASK; + ctx.flags |= CTLSTAT_FLAG_PORTS; break; } case 't': @@ -697,29 +657,45 @@ main(int argc, char **argv) } } - if (!F_TOTALS(&ctx) && !F_LUNMASK(&ctx)) { + if (F_LUNS(&ctx) && F_PORTS(&ctx)) + errx(1, "Options -p and -l are exclusive."); + + if (!F_LUNS(&ctx) && !F_PORTS(&ctx)) { + if (F_TOTALS(&ctx)) + ctx.flags |= CTLSTAT_FLAG_PORTS; + else + ctx.flags |= CTLSTAT_FLAG_LUNS; + } + + if (!F_TOTALS(&ctx) && !F_MASK(&ctx)) { /* * Note that this just selects the first N LUNs to display, * but at this point we have no knoweledge of which LUN * numbers actually exist. So we may select LUNs that * aren't there. */ - bit_nset(ctx.lun_mask, 0, min(ctx.numdevs - 1, - CTL_STAT_LUN_BITS - 1)); - ctx.flags |= CTLSTAT_FLAG_LUN_MASK; + bit_nset(ctx.item_mask, 0, min(ctx.numdevs - 1, + CTL_STAT_BITS - 1)); + ctx.flags |= CTLSTAT_FLAG_MASK; } if ((fd = open(CTL_DEFAULT_DEV, O_RDWR)) == -1) err(1, "cannot open %s", CTL_DEFAULT_DEV); for (;count != 0;) { - ctx.tmp_lun_stats = ctx.prev_lun_stats; - ctx.prev_lun_stats = ctx.cur_lun_stats; - ctx.cur_lun_stats = ctx.tmp_lun_stats; + tmp_stats = ctx.prev_stats; + ctx.prev_stats = ctx.cur_stats; + ctx.cur_stats = tmp_stats; + c = ctx.prev_alloc; + ctx.prev_alloc = ctx.cur_alloc; + ctx.cur_alloc = c; + c = ctx.prev_items; + ctx.prev_items = ctx.cur_items; + ctx.cur_items = c; ctx.prev_time = ctx.cur_time; ctx.prev_cpu = ctx.cur_cpu; - if (getstats(fd, &ctx.num_luns, &ctx.cur_lun_stats, - &ctx.cur_time, &ctx.flags) != 0) + if (getstats(fd, &ctx.cur_alloc, &ctx.cur_items, + &ctx.cur_stats, &ctx.cur_time, &ctx.flags) != 0) errx(1, "error returned from getstats()"); switch(ctx.mode) { diff --git a/usr.bin/mail/send.c b/usr.bin/mail/send.c index 5be7405..a199323 100644 --- a/usr.bin/mail/send.c +++ b/usr.bin/mail/send.c @@ -59,7 +59,7 @@ sendmessage(struct message *mp, FILE *obuf, struct ignoretab *doign, FILE *ibuf; char *cp, *cp2, line[LINESIZE]; int ishead, infld, ignoring, dostat, firstline; - int c, length, prefixlen; + int c = 0, length, prefixlen; /* * Compute the prefix string, without trailing whitespace @@ -566,8 +566,13 @@ savemail(char name[], FILE *fi) char buf[BUFSIZ]; int i; time_t now; + mode_t saved_umask; - if ((fo = Fopen(name, "a")) == NULL) { + saved_umask = umask(077); + fo = Fopen(name, "a"); + umask(saved_umask); + + if (fo == NULL) { warn("%s", name); return (-1); } diff --git a/usr.bin/minigzip/Makefile b/usr.bin/minigzip/Makefile index b2cfc46..37f642e 100644 --- a/usr.bin/minigzip/Makefile +++ b/usr.bin/minigzip/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -SRCDIR= ${.CURDIR}/../../lib/libz/test +SRCDIR= ${.CURDIR}/../../contrib/zlib/test .PATH: ${SRCDIR} PROG= minigzip diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index 8ef9783..79adc9b 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -535,6 +535,9 @@ main(int argc, char *argv[]) if (xflag && Tflag) errx(1, "-x and -T are incompatible, pick one."); + /* Load all necessary kvm symbols */ + kresolve_list(nl); + if (Bflag) { if (!live) usage(); @@ -603,9 +606,6 @@ main(int argc, char *argv[]) exit(0); } - /* Load all necessary kvm symbols */ - kresolve_list(nl); - if (tp) { printproto(tp, tp->pr_name); exit(0); diff --git a/usr.bin/rpcgen/rpc_cout.c b/usr.bin/rpcgen/rpc_cout.c index 4c36ce6..45f0d90 100644 --- a/usr.bin/rpcgen/rpc_cout.c +++ b/usr.bin/rpcgen/rpc_cout.c @@ -551,7 +551,8 @@ emit_struct(definition *def) } for (dl = def->def.st.decls; dl != NULL; dl = dl->next) - if (dl->decl.rel == REL_VECTOR){ + if (dl->decl.rel == REL_VECTOR && + strcmp(dl->decl.type, "opaque") != 0){ f_print(fout, "\tint i;\n"); break; } diff --git a/usr.bin/rpcgen/rpc_parse.c b/usr.bin/rpcgen/rpc_parse.c index f7f857a..9f88033 100644 --- a/usr.bin/rpcgen/rpc_parse.c +++ b/usr.bin/rpcgen/rpc_parse.c @@ -290,7 +290,6 @@ def_union(definition *defp) declaration dec; case_list *cases; case_list **tailp; - int flag; defp->def_kind = DEF_UNION; scan(TOK_IDENT, &tok); @@ -309,7 +308,6 @@ def_union(definition *defp) cases->case_name = tok.str; scan(TOK_COLON, &tok); /* now peek at next token */ - flag = 0; if (peekscan(TOK_CASE, &tok)){ do { scan2(TOK_IDENT, TOK_CHARCONST, &tok); @@ -322,14 +320,6 @@ def_union(definition *defp) scan(TOK_COLON, &tok); } while (peekscan(TOK_CASE, &tok)); } - else - if (flag) - { - - *tailp = cases; - tailp = &cases->next; - cases = XALLOC(case_list); - }; get_declaration(&dec, DEF_UNION); cases->case_decl = dec; diff --git a/usr.bin/rpcgen/rpc_svcout.c b/usr.bin/rpcgen/rpc_svcout.c index 4b951a3..e868c01 100644 --- a/usr.bin/rpcgen/rpc_svcout.c +++ b/usr.bin/rpcgen/rpc_svcout.c @@ -728,7 +728,8 @@ write_timeout_func(void) if (tirpcflag) { f_print(fout, "\t\t\tstruct rlimit rl;\n\n"); f_print(fout, "\t\t\trl.rlim_max = 0;\n"); - f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n"); + f_print(fout, "\t\t\tif (getrlimit(RLIMIT_NOFILE, &rl) == -1)\n"); + f_print(fout, "\t\t\t\treturn;\n"); f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0) {\n"); if (mtflag) @@ -902,7 +903,11 @@ write_rpc_svc_fg(const char *infile, const char *sp) /* get number of file descriptors */ if (tirpcflag) { f_print(fout, "%srl.rlim_max = 0;\n", sp); - f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp); + f_print(fout, "%sif (getrlimit(RLIMIT_NOFILE, &rl) == -1) {\n", + sp); + f_print(fout, "%s\tperror(\"getrlimit\");\n", sp); + f_print(fout, "%s\texit(1);\n", sp); + f_print(fout, "%s}\n", sp); f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp); f_print(fout, "%s\texit(1);\n", sp); } else { diff --git a/usr.bin/sort/radixsort.c b/usr.bin/sort/radixsort.c index f6cf6ac..59d1571 100644 --- a/usr.bin/sort/radixsort.c +++ b/usr.bin/sort/radixsort.c @@ -83,12 +83,12 @@ static struct level_stack *g_ls; #if defined(SORT_THREADS) /* stack guarding mutex */ +static pthread_cond_t g_ls_cond; static pthread_mutex_t g_ls_mutex; /* counter: how many items are left */ static size_t sort_left; /* guarding mutex */ -static pthread_mutex_t sort_left_mutex; /* semaphore to count threads */ static sem_t mtsem; @@ -99,23 +99,25 @@ static sem_t mtsem; static inline void sort_left_dec(size_t n) { - - pthread_mutex_lock(&sort_left_mutex); + pthread_mutex_lock(&g_ls_mutex); sort_left -= n; - pthread_mutex_unlock(&sort_left_mutex); + if (sort_left == 0 && nthreads > 1) + pthread_cond_broadcast(&g_ls_cond); + pthread_mutex_unlock(&g_ls_mutex); } /* * Do we have something to sort ? + * + * This routine does not need to be locked. */ static inline bool have_sort_left(void) { bool ret; - pthread_mutex_lock(&sort_left_mutex); ret = (sort_left > 0); - pthread_mutex_unlock(&sort_left_mutex); + return (ret); } @@ -146,6 +148,11 @@ push_ls(struct sort_level* sl) #if defined(SORT_THREADS) if (nthreads > 1) + pthread_cond_signal(&g_ls_cond); +#endif + +#if defined(SORT_THREADS) + if (nthreads > 1) pthread_mutex_unlock(&g_ls_mutex); #endif } @@ -184,13 +191,19 @@ pop_ls_mt(void) pthread_mutex_lock(&g_ls_mutex); - if (g_ls) { - sl = g_ls->sl; - saved_ls = g_ls; - g_ls = g_ls->next; - } else { + for (;;) { + if (g_ls) { + sl = g_ls->sl; + saved_ls = g_ls; + g_ls = g_ls->next; + break; + } sl = NULL; saved_ls = NULL; + + if (have_sort_left() == 0) + break; + pthread_cond_wait(&g_ls_cond, &g_ls_mutex); } pthread_mutex_unlock(&g_ls_mutex); @@ -493,13 +506,8 @@ run_sort_cycle_mt(void) for (;;) { slc = pop_ls_mt(); - if (slc == NULL) { - if (have_sort_left()) { - pthread_yield(); - continue; - } + if (slc == NULL) break; - } run_sort_level_next(slc); } } @@ -510,9 +518,7 @@ run_sort_cycle_mt(void) static void* sort_thread(void* arg) { - run_sort_cycle_mt(); - sem_post(&mtsem); return (arg); @@ -608,8 +614,7 @@ run_top_sort_level(struct sort_level *sl) pthread_t pth; pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, - PTHREAD_DETACHED); + pthread_attr_setdetachstate(&attr, PTHREAD_DETACHED); for (;;) { int res = pthread_create(&pth, &attr, @@ -626,7 +631,7 @@ run_top_sort_level(struct sort_level *sl) pthread_attr_destroy(&attr); } - for(i = 0; i < nthreads; ++i) + for (i = 0; i < nthreads; ++i) sem_wait(&mtsem); } #endif /* defined(SORT_THREADS) */ @@ -649,7 +654,7 @@ run_sort(struct sort_list_item **base, size_t nmemb) pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_ADAPTIVE_NP); pthread_mutex_init(&g_ls_mutex, &mattr); - pthread_mutex_init(&sort_left_mutex, &mattr); + pthread_cond_init(&g_ls_cond, NULL); pthread_mutexattr_destroy(&mattr); @@ -677,7 +682,6 @@ run_sort(struct sort_list_item **base, size_t nmemb) if (nthreads > 1) { sem_destroy(&mtsem); pthread_mutex_destroy(&g_ls_mutex); - pthread_mutex_destroy(&sort_left_mutex); } nthreads = nthreads_save; #endif diff --git a/usr.bin/tail/reverse.c b/usr.bin/tail/reverse.c index 511f88c..8726905 100644 --- a/usr.bin/tail/reverse.c +++ b/usr.bin/tail/reverse.c @@ -117,6 +117,7 @@ r_reg(FILE *fp, const char *fn, enum STYLE style, off_t off, struct stat *sbp) map.start = NULL; map.mapoff = map.maxoff = size; map.fd = fileno(fp); + map.maplen = 0; /* * Last char is special, ignore whether newline or not. Note that @@ -205,7 +206,13 @@ r_buf(FILE *fp, const char *fn) (tl->l = malloc(BSZ)) == NULL) { if (!mark) err(1, "malloc"); - tl = enomem ? tl->next : mark; + if (enomem) + tl = tl->next; + else { + if (tl) + free(tl); + tl = mark; + } enomem += tl->len; } else if (mark) { tl->next = mark; diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c index 6978060..f247d95 100644 --- a/usr.bin/top/machine.c +++ b/usr.bin/top/machine.c @@ -363,7 +363,7 @@ machine_init(struct statics *statics, char do_unames) size = sizeof(long) * maxcpu * CPUSTATES; times = malloc(size); if (times == NULL) - err(1, "malloc %zd bytes", size); + err(1, "malloc %zu bytes", size); if (sysctlbyname("kern.cp_times", times, &size, NULL, 0) == -1) err(1, "sysctlbyname kern.cp_times"); pcpu_cp_time = calloc(1, size); @@ -396,7 +396,7 @@ format_header(char *uname_field) { static char Header[128]; const char *prehead; - + if (ps.jail) jidlength = TOP_JID_LEN + 1; /* +1 for extra left space. */ else @@ -536,7 +536,7 @@ get_system_info(struct system_info *si) arc_stats[5] = arc_stat >> 10; si->arc = arc_stats; } - + /* set arrays and strings */ if (pcpu_stats) { si->cpustates = pcpu_cpu_states; @@ -562,7 +562,7 @@ get_system_info(struct system_info *si) mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; size = sizeof(boottime); - if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && + if (sysctl(mib, nitems(mib), &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0) { si->boottime = boottime; } else { @@ -917,7 +917,7 @@ format_next_process(caddr_t handle, char *(*get_userid)(int), int flags) argbuflen = cmdlen * 4; argbuf = (char *)malloc(argbuflen + 1); if (argbuf == NULL) { - warn("malloc(%d)", argbuflen + 1); + warn("malloc(%zu)", argbuflen + 1); free(cmdbuf); return NULL; } @@ -970,7 +970,7 @@ format_next_process(caddr_t handle, char *(*get_userid)(int), int flags) } } - if (ps.jail == 0) + if (ps.jail == 0) jid_buf[0] = '\0'; else snprintf(jid_buf, sizeof(jid_buf), "%*d", @@ -1026,7 +1026,7 @@ format_next_process(caddr_t handle, char *(*get_userid)(int), int flags) thr_buf[0] = '\0'; else snprintf(thr_buf, sizeof(thr_buf), "%*d ", - sizeof(thr_buf) - 2, pp->ki_numthreads); + (int)(sizeof(thr_buf) - 2), pp->ki_numthreads); snprintf(fmt, sizeof(fmt), proc_fmt, pp->ki_pid, diff --git a/usr.sbin/amd/amd/Makefile b/usr.sbin/amd/amd/Makefile index f335ef0..273f71e 100644 --- a/usr.sbin/amd/amd/Makefile +++ b/usr.sbin/amd/amd/Makefile @@ -30,8 +30,8 @@ CFLAGS+= -I${.CURDIR}/../../../contrib/amd/amd \ -I${SRCTOP}/contrib/amd/include \ -I${.OBJDIR}/../../../include/rpcsvc -DPADD= ${LIBAMU} ${LIBWRAP} -LDADD= ${LIBAMU} -lwrap +DPADD= ${LIBAMU} +LDADD= ${LIBAMU} SRCS+= conf_parse.c conf_parse.h conf_tok.c SRCS+= sun_map_parse.c sun_map_parse.h sun_map_tok.c @@ -74,4 +74,10 @@ CFLAGS+= -DHAVE_MAP_HESIOD SRCS+= info_nis.c .endif +.if ${MK_TCP_WRAPPERS} != "no" +CFLAGS+= -DHAVE_LIBWRAP -DHAVE_TCPD_H +DPADD+= ${LIBWRAP} +LDADD+= -lwrap +.endif + .include <bsd.prog.mk> diff --git a/usr.sbin/amd/include/config.h b/usr.sbin/amd/include/config.h index edae5fd..2e46db1 100644 --- a/usr.sbin/amd/include/config.h +++ b/usr.sbin/amd/include/config.h @@ -530,7 +530,7 @@ /* #undef HAVE_LIBRT */ /* does libwrap exist? */ -#define HAVE_LIBWRAP 1 +/* #undef HAVE_LIBWRAP */ /* Define to 1 if you have the <limits.h> header file. */ #define HAVE_LIMITS_H 1 @@ -1207,7 +1207,7 @@ #define HAVE_SYS_WAIT_H 1 /* Define to 1 if you have the <tcpd.h> header file. */ -#define HAVE_TCPD_H 1 +/* #undef HAVE_TCPD_H */ /* Define to 1 if you have the <time.h> header file. */ #define HAVE_TIME_H 1 diff --git a/usr.sbin/bsdinstall/partedit/gpart_ops.c b/usr.sbin/bsdinstall/partedit/gpart_ops.c index 48bbb68..624077d 100644 --- a/usr.sbin/bsdinstall/partedit/gpart_ops.c +++ b/usr.sbin/bsdinstall/partedit/gpart_ops.c @@ -795,6 +795,7 @@ gpart_max_free(struct ggeom *geom, intmax_t *npartstart) { struct gconfig *gc; struct gprovider *pp, **providers; + intmax_t sectorsize, stripesize, offset; intmax_t lastend; intmax_t start, end; intmax_t maxsize, maxstart; @@ -845,12 +846,25 @@ gpart_max_free(struct ggeom *geom, intmax_t *npartstart) pp = LIST_FIRST(&geom->lg_consumer)->lg_provider; - /* Compute beginning of new partition and maximum available space */ - if (pp->lg_stripesize > 0 && - (maxstart*pp->lg_sectorsize % pp->lg_stripesize) != 0) { - intmax_t offset = (pp->lg_stripesize - - ((maxstart*pp->lg_sectorsize) % pp->lg_stripesize)) / - pp->lg_sectorsize; + /* + * Round the start and size of the largest available space up to + * the nearest multiple of the adjusted stripe size. + * + * The adjusted stripe size is the least common multiple of the + * actual stripe size, or the sector size if no stripe size was + * reported, and 4096. The reason for this is that contemporary + * disks often have 4096-byte physical sectors but report 512 + * bytes instead for compatibility with older / broken operating + * systems and BIOSes. For the same reasons, virtualized storage + * may also report a 512-byte stripe size, or none at all. + */ + sectorsize = pp->lg_sectorsize; + if ((stripesize = pp->lg_stripesize) == 0) + stripesize = sectorsize; + while (stripesize % 4096 != 0) + stripesize *= 2; + if ((offset = maxstart * sectorsize % stripesize) != 0) { + offset = (stripesize - offset) / sectorsize; maxstart += offset; maxsize -= offset; } diff --git a/usr.sbin/bsnmpd/modules/Makefile b/usr.sbin/bsnmpd/modules/Makefile index 09598b3..177909c 100644 --- a/usr.sbin/bsnmpd/modules/Makefile +++ b/usr.sbin/bsnmpd/modules/Makefile @@ -2,7 +2,7 @@ .include <bsd.own.mk> -.PATH: ${.CURDIR}/../../../contrib/bsnmp/snmpd +.PATH: ${SRCTOP}/contrib/bsnmp/snmpd .if ${MK_ATM} != "no" _snmp_atm= snmp_atm @@ -35,4 +35,6 @@ SUBDIR+=snmp_wlan INCS= snmpmod.h INCSDIR= ${INCLUDEDIR}/bsnmp +SUBDIR_TARGETS+= smilint + .include <bsd.prog.mk> diff --git a/usr.sbin/bsnmpd/modules/snmp_atm/BEGEMOT-ATM-FREEBSD-MIB.txt b/usr.sbin/bsnmpd/modules/snmp_atm/BEGEMOT-ATM-FREEBSD-MIB.txt index 85339a3..f288741 100644 --- a/usr.sbin/bsnmpd/modules/snmp_atm/BEGEMOT-ATM-FREEBSD-MIB.txt +++ b/usr.sbin/bsnmpd/modules/snmp_atm/BEGEMOT-ATM-FREEBSD-MIB.txt @@ -56,7 +56,9 @@ begemotAtmFreeBSDGroup MODULE-IDENTITY E-mail: harti@freebsd.org" DESCRIPTION "The FreeBSD specific Begemot MIB for ATM interfaces." - + REVISION "200408060000Z" + DESCRIPTION + "Initial revision." ::= { begemotAtmSysGroup 1 } -- Netgraph diff --git a/usr.sbin/bsnmpd/modules/snmp_atm/Makefile b/usr.sbin/bsnmpd/modules/snmp_atm/Makefile index 4bba7cb..82bd325 100644 --- a/usr.sbin/bsnmpd/modules/snmp_atm/Makefile +++ b/usr.sbin/bsnmpd/modules/snmp_atm/Makefile @@ -2,7 +2,7 @@ # # Author: Harti Brandt <harti@freebsd.org> -CONTRIB= ${.CURDIR}/../../../../contrib/ngatm +CONTRIB= ${SRCTOP}/contrib/ngatm .PATH: ${CONTRIB}/snmp_atm MOD= atm diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_sys.c b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_sys.c index 9caa331..0332f13 100644 --- a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_sys.c +++ b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_sys.c @@ -485,7 +485,7 @@ bridge_set_if_up(const char* b_name, int8_t up) struct ifreq ifr; bzero(&ifr, sizeof(ifr)); - strcpy(ifr.ifr_name, b_name); + strlcpy(ifr.ifr_name, b_name, sizeof(ifr.ifr_name)); if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "set bridge up: ioctl(SIOCGIFFLAGS) " "failed: %s", strerror(errno)); @@ -516,7 +516,7 @@ bridge_create(const char *b_name) struct ifreq ifr; bzero(&ifr, sizeof(ifr)); - strcpy(ifr.ifr_name, b_name); + strlcpy(ifr.ifr_name, b_name, sizeof(ifr.ifr_name)); if (ioctl(sock, SIOCIFCREATE, &ifr) < 0) { syslog(LOG_ERR, "create bridge: ioctl(SIOCIFCREATE) " @@ -549,7 +549,7 @@ bridge_destroy(const char *b_name) struct ifreq ifr; bzero(&ifr, sizeof(ifr)); - strcpy(ifr.ifr_name, b_name); + strlcpy(ifr.ifr_name, b_name, sizeof(ifr.ifr_name)); if (ioctl(sock, SIOCIFDESTROY, &ifr) < 0) { syslog(LOG_ERR, "destroy bridge: ioctl(SIOCIFDESTROY) " @@ -1459,9 +1459,9 @@ bridge_get_pfval(uint8_t which) int32_t bridge_do_pfctl(int32_t bridge_ctl, enum snmp_op op, int32_t *val) { - char mib_name[100]; - int32_t i, s_i; + char *mib_oid; size_t len, s_len; + int32_t i, s_i; if (bridge_ctl >= LEAF_begemotBridgeLayer2PfStatus) return (-2); @@ -1474,19 +1474,24 @@ bridge_do_pfctl(int32_t bridge_ctl, enum snmp_op op, int32_t *val) len = sizeof(i); - strcpy(mib_name, bridge_sysctl); + asprintf(&mib_oid, "%s%s", bridge_sysctl, + bridge_pf_sysctl[bridge_ctl].name); + if (mib_oid == NULL) + return (-1); - if (sysctlbyname(strcat(mib_name, - bridge_pf_sysctl[bridge_ctl].name), &i, &len, - (op == SNMP_OP_SET ? &s_i : NULL), s_len) == -1) { - syslog(LOG_ERR, "sysctl(%s%s) failed - %s", bridge_sysctl, - bridge_pf_sysctl[bridge_ctl].name, strerror(errno)); + if (sysctlbyname(mib_oid, &i, &len, (op == SNMP_OP_SET ? &s_i : NULL), + s_len) == -1) { + syslog(LOG_ERR, "sysctl(%s) failed - %s", mib_oid, + strerror(errno)); + free(mib_oid); return (-1); } bridge_pf_sysctl[bridge_ctl].val = i; *val = i; + free(mib_oid); + return (i); } @@ -1495,8 +1500,7 @@ bridge_pf_dump(void) { uint8_t i; - for (i = 0; i < sizeof(bridge_pf_sysctl) / sizeof(bridge_pf_sysctl[0]); - i++) { + for (i = 0; i < nitems(bridge_pf_sysctl); i++) { syslog(LOG_ERR, "%s%s = %d", bridge_sysctl, bridge_pf_sysctl[i].name, bridge_pf_sysctl[i].val); } diff --git a/usr.sbin/bsnmpd/modules/snmp_hast/Makefile b/usr.sbin/bsnmpd/modules/snmp_hast/Makefile index 6369918..d16d93c 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hast/Makefile +++ b/usr.sbin/bsnmpd/modules/snmp_hast/Makefile @@ -2,7 +2,7 @@ .include <bsd.own.mk> -.PATH: ${.CURDIR}/../../../../sbin/hastd +.PATH: ${SRCTOP}/sbin/hastd MOD= hast SRCS= ebuf.c @@ -18,7 +18,7 @@ MAN= snmp_hast.3 NO_WFORMAT= NO_WCAST_ALIGN= NO_WMISSING_VARIABLE_DECLARATIONS= -CFLAGS+=-I${.CURDIR}/../../../../sbin/hastd +CFLAGS+=-I${SRCTOP}/sbin/hastd CFLAGS+=-DHAVE_CAPSICUM CFLAGS+=-DINET .if ${MK_INET6_SUPPORT} != "no" diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/BEGEMOT-HOSTRES-MIB.txt b/usr.sbin/bsnmpd/modules/snmp_hostres/BEGEMOT-HOSTRES-MIB.txt index ee8d284..3c15e09 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/BEGEMOT-HOSTRES-MIB.txt +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/BEGEMOT-HOSTRES-MIB.txt @@ -54,6 +54,9 @@ begemotHostres MODULE-IDENTITY E-mail: harti@freebsd.org" DESCRIPTION "The MIB for additional HOST-RESOURCES data." + REVISION "200601030000Z" + DESCRIPTION + "Initial revision." ::= { begemot 202 } begemotHostresObjects OBJECT IDENTIFIER ::= { begemotHostres 1 } diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile index 2922f45..b888384 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile @@ -28,7 +28,7 @@ # $FreeBSD$ # -LPRSRC= ${.CURDIR}/../../../lpr/common_source +LPRSRC= ${SRCTOP}/usr.sbin/lpr/common_source .PATH: ${LPRSRC} MOD= hostres @@ -76,7 +76,3 @@ LDADD= -lkvm -ldevinfo -lm -lgeom -lmemstat printcap.So: printcap.c ${CC} ${PICFLAG} -DPIC ${CFLAGS:C/^-W.*//} -c ${.IMPSRC} -o ${.TARGET} - -smilint: - env SMIPATH=.:/usr/share/snmp/mibs:/usr/local/share/snmp/mibs \ - smilint -c /dev/null -l6 -i group-membership BEGEMOT-HOSTRES-MIB diff --git a/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile b/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile index 278dc24..22be412 100644 --- a/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile +++ b/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile @@ -2,7 +2,7 @@ # # Author: Harti Brandt <harti@freebsd.org> -CONTRIB= ${.CURDIR}/../../../../contrib/bsnmp +CONTRIB= ${SRCTOP}/contrib/bsnmp .PATH: ${CONTRIB}/snmp_mibII MOD= mibII @@ -21,7 +21,3 @@ INCS= snmp_${MOD}.h BMIBS= BEGEMOT-IP-MIB.txt BEGEMOT-MIB2-MIB.txt .include <bsd.snmpmod.mk> - -smilint: - env SMIPATH=/usr/share/snmp/mibs:/usr/local/share/snmp/mibs \ - smilint -c /dev/null -l6 -i group-membership ${BMIBS:C/^/${CONTRIB}\/snmp_mibII\//} diff --git a/usr.sbin/bsnmpd/modules/snmp_netgraph/BEGEMOT-NETGRAPH.txt b/usr.sbin/bsnmpd/modules/snmp_netgraph/BEGEMOT-NETGRAPH.txt index 1896fe6..b4f0e2a 100644 --- a/usr.sbin/bsnmpd/modules/snmp_netgraph/BEGEMOT-NETGRAPH.txt +++ b/usr.sbin/bsnmpd/modules/snmp_netgraph/BEGEMOT-NETGRAPH.txt @@ -59,6 +59,19 @@ begemotNg MODULE-IDENTITY E-mail: harti@freebsd.org" DESCRIPTION "The MIB for the NetGraph access module for SNMP." + REVISION "200311140000Z" + DESCRIPTION + "The maximum width of the following OCTET STRINGs was increased + from 15 to 31: + + - NgTypeName + - NgNodeName + - NgNodeNameOrEmpty + - NgHookName + " + REVISION "200201310000Z" + DESCRIPTION + "Initial revision." ::= { begemot 2 } begemotNgObjects OBJECT IDENTIFIER ::= { begemotNg 1 } diff --git a/usr.sbin/bsnmpd/modules/snmp_target/Makefile b/usr.sbin/bsnmpd/modules/snmp_target/Makefile index e6216ea..b25e9f8 100644 --- a/usr.sbin/bsnmpd/modules/snmp_target/Makefile +++ b/usr.sbin/bsnmpd/modules/snmp_target/Makefile @@ -2,7 +2,7 @@ # # Author: Shteryana Shopova <syrinx@freebsd.org> -CONTRIB= ${.CURDIR}/../../../../contrib/bsnmp +CONTRIB= ${SRCTOP}/contrib/bsnmp .PATH: ${CONTRIB}/snmp_target MOD= target diff --git a/usr.sbin/bsnmpd/modules/snmp_usm/Makefile b/usr.sbin/bsnmpd/modules/snmp_usm/Makefile index 1c42245..f3c10fa 100644 --- a/usr.sbin/bsnmpd/modules/snmp_usm/Makefile +++ b/usr.sbin/bsnmpd/modules/snmp_usm/Makefile @@ -2,7 +2,7 @@ # # Author: Shteryana Shopova <syrinx@freebsd.org> -CONTRIB= ${.CURDIR}/../../../../contrib/bsnmp +CONTRIB= ${SRCTOP}/contrib/bsnmp .PATH: ${CONTRIB}/snmp_usm MOD= usm diff --git a/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile b/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile index 4a09cde..b0099fe 100644 --- a/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile +++ b/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile @@ -2,7 +2,7 @@ # # Author: Shteryana Shopova <syrinx@freebsd.org> -CONTRIB= ${.CURDIR}/../../../../contrib/bsnmp +CONTRIB= ${SRCTOP}/contrib/bsnmp .PATH: ${CONTRIB}/snmp_vacm MOD= vacm diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c index 2a214aa..cc8cc33 100644 --- a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c +++ b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c @@ -400,13 +400,16 @@ snmptool_get(struct snmp_toolinfo *snmptoolctx) if (snmp_parse_resp(&resp, &req) >= 0) { snmp_output_resp(snmptoolctx, &resp, NULL); + snmp_pdu_free(&resp); break; } snmp_output_err_resp(snmptoolctx, &resp); if (GET_PDUTYPE(snmptoolctx) == SNMP_PDU_GETBULK || - !ISSET_RETRY(snmptoolctx)) + !ISSET_RETRY(snmptoolctx)) { + snmp_pdu_free(&resp); break; + } /* * Loop through the object list and set object->error to the @@ -414,15 +417,17 @@ snmptool_get(struct snmp_toolinfo *snmptoolctx) */ if (snmp_object_seterror(snmptoolctx, &(resp.bindings[resp.error_index - 1]), - resp.error_status) <= 0) + resp.error_status) <= 0) { + snmp_pdu_free(&resp); break; + } fprintf(stderr, "Retrying...\n"); snmp_pdu_free(&resp); snmp_pdu_create(&req, GET_PDUTYPE(snmptoolctx)); } - snmp_pdu_free(&resp); + snmp_pdu_free(&req); return (0); } @@ -498,27 +503,29 @@ snmptool_walk(struct snmp_toolinfo *snmptoolctx) } outputs += rc; - snmp_pdu_free(&resp); - if ((u_int)rc < resp.nbindings) + if ((u_int)rc < resp.nbindings) { + snmp_pdu_free(&resp); break; + } snmpwalk_nextpdu_create(op, &(resp.bindings[resp.nbindings - 1].var), &req); if (op == SNMP_PDU_GETBULK) snmpget_fix_getbulk(&req, GET_MAXREP(snmptoolctx), GET_NONREP(snmptoolctx)); + snmp_pdu_free(&resp); } /* Just in case our root was a leaf. */ if (outputs == 0) { snmpwalk_nextpdu_create(SNMP_PDU_GET, &root, &req); if (snmp_dialog(&req, &resp) == SNMP_CODE_OK) { - if (snmp_parse_resp(&resp,&req) < 0) + if (snmp_parse_resp(&resp, &req) < 0) snmp_output_err_resp(snmptoolctx, &resp); else - snmp_output_resp(snmptoolctx, &(resp), NULL); - + snmp_output_resp(snmptoolctx, &resp, + NULL); snmp_pdu_free(&resp); } else warn("Snmp dialog"); @@ -529,9 +536,12 @@ snmptool_walk(struct snmp_toolinfo *snmptoolctx) break; } + snmp_pdu_free(&req); snmp_pdu_create(&req, op); } + snmp_pdu_free(&req); + if (rc == 0) return (0); else @@ -1089,25 +1099,29 @@ snmptool_set(struct snmp_toolinfo *snmptoolctx) if (snmp_pdu_check(&req, &resp) > 0) { if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET) snmp_output_resp(snmptoolctx, &resp, NULL); + snmp_pdu_free(&resp); break; } snmp_output_err_resp(snmptoolctx, &resp); - if (!ISSET_RETRY(snmptoolctx)) + if (!ISSET_RETRY(snmptoolctx)) { + snmp_pdu_free(&resp); break; + } if (snmp_object_seterror(snmptoolctx, &(resp.bindings[resp.error_index - 1]), - resp.error_status) <= 0) + resp.error_status) <= 0) { + snmp_pdu_free(&resp); break; + } fprintf(stderr, "Retrying...\n"); snmp_pdu_free(&req); - snmp_pdu_free(&resp); snmp_pdu_create(&req, SNMP_PDU_SET); } - snmp_pdu_free(&resp); + snmp_pdu_free(&req); return (0); } diff --git a/usr.sbin/ctladm/ctladm.8 b/usr.sbin/ctladm/ctladm.8 index 5be1ba1..d8b0ae0 100644 --- a/usr.sbin/ctladm/ctladm.8 +++ b/usr.sbin/ctladm/ctladm.8 @@ -35,7 +35,7 @@ .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $ .\" $FreeBSD$ .\" -.Dd December 21, 2016 +.Dd January 23, 2017 .Dt CTLADM 8 .Os .Sh NAME @@ -941,6 +941,14 @@ Specifies file or device name to use for backing store. .It Va num_threads Specifies number of backend threads to use for this LUN. .El +.Pp +Options specific for ramdisk backend: +.Bl -tag -width 12n +.It Va capacity +Specifies capacity of backing store (maximum RAM for data). +The default value is zero, that disables backing store completely, +making all writes go to nowhere, while all reads return zeroes. +.El .Sh EXAMPLES .Dl ctladm tur 1 .Pp @@ -977,7 +985,14 @@ starting at LBA 0xff432140. Create a LUN with the .Dq fake ramdisk as a backing store. -The LUN will claim to have a size of approximately 10 terabytes. +The LUN will claim to have a size of approximately 10 terabytes, +while having no real data store (all written data are lost). +.Pp +.Dl ctladm create -b ramdisk -s 10T -o capacity=10G +.Pp +Create a thin provisioned LUN with a ramdisk as a backing store. +The LUN will have maximal backing store capacity of 10 gigabytes, +while reporting size of 10 terabytes, .Pp .Dl ctladm create -b block -o file=src/usr.sbin/ctladm/ctladm.8 .Pp diff --git a/usr.sbin/ctld/parse.y b/usr.sbin/ctld/parse.y index 1de1e88..da5d52c 100644 --- a/usr.sbin/ctld/parse.y +++ b/usr.sbin/ctld/parse.y @@ -808,6 +808,11 @@ lun_number: STR free($1); return (1); } + if (tmp >= MAX_LUNS) { + yyerror("LU number is too big"); + free($1); + return (1); + } ret = asprintf(&name, "%s,lun,%ju", target->t_name, tmp); if (ret <= 0) @@ -832,6 +837,11 @@ target_lun_ref: LUN STR STR return (1); } free($2); + if (tmp >= MAX_LUNS) { + yyerror("LU number is too big"); + free($3); + return (1); + } lun = lun_find(conf, $3); free($3); diff --git a/usr.sbin/diskinfo/diskinfo.c b/usr.sbin/diskinfo/diskinfo.c index 90beba2..dac7d12 100644 --- a/usr.sbin/diskinfo/diskinfo.c +++ b/usr.sbin/diskinfo/diskinfo.c @@ -89,13 +89,12 @@ main(int argc, char **argv) for (i = 0; i < argc; i++) { fd = open(argv[i], O_RDONLY); if (fd < 0 && errno == ENOENT && *argv[i] != '/') { - sprintf(buf, "%s%s", _PATH_DEV, argv[i]); + snprintf(buf, BUFSIZ, "%s%s", _PATH_DEV, argv[i]); fd = open(buf, O_RDONLY); } if (fd < 0) { warn("%s", argv[i]); - exitval = 1; - goto out; + exit(1); } error = ioctl(fd, DIOCGMEDIASIZE, &mediasize); if (error) { @@ -176,7 +175,8 @@ rdsect(int fd, off_t blockno, u_int sectorsize) { int error; - lseek(fd, (off_t)blockno * sectorsize, SEEK_SET); + if (lseek(fd, (off_t)blockno * sectorsize, SEEK_SET) == -1) + err(1, "lseek"); error = read(fd, sector, sectorsize); if (error == -1) err(1, "read"); @@ -241,6 +241,9 @@ speeddisk(int fd, off_t mediasize, u_int sectorsize) off_t b0, b1, sectorcount, step; sectorcount = mediasize / sectorsize; + if (sectorcount <= 0) + return; /* Can't test devices with no sectors */ + step = 1ULL << (flsll(sectorcount / (4 * 200)) - 1); if (step > 16384) step = 16384; diff --git a/usr.sbin/fstyp/tests/fstyp_test.sh b/usr.sbin/fstyp/tests/fstyp_test.sh index 8a1ea72..1a9836f 100755 --- a/usr.sbin/fstyp/tests/fstyp_test.sh +++ b/usr.sbin/fstyp/tests/fstyp_test.sh @@ -1,3 +1,29 @@ +#!/bin/sh +# +# Copyright (c) 2015 Alan Somers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + # $FreeBSD$ atf_test_case cd9660 @@ -9,7 +35,7 @@ cd9660_body() { atf_check -s exit:0 -o ignore makefs -t cd9660 -Z -s 64m cd9660.img dir atf_check -s exit:0 -o inline:"cd9660\n" fstyp cd9660.img atf_check -s exit:0 -o inline:"cd9660\n" fstyp -l cd9660.img -} +} atf_test_case cd9660_label cd9660_label_head() { @@ -21,7 +47,7 @@ cd9660_label_body() { atf_check -s exit:0 -o inline:"cd9660\n" fstyp cd9660.img # Note: cd9660 labels are always upper case atf_check -s exit:0 -o inline:"cd9660 FOO\n" fstyp -l cd9660.img -} +} atf_test_case dir dir_head() { @@ -177,7 +203,7 @@ ufs2_label_body() { atf_check -s exit:0 mkdir dir atf_check -s exit:0 -o ignore makefs -o version=2,label="foo" -Z -s 64m ufs.img dir atf_check -s exit:0 -o inline:"ufs foo\n" fstyp -l ufs.img -} +} atf_test_case ufs_on_device cleanup ufs_on_device_head() { diff --git a/usr.sbin/inetd/Makefile b/usr.sbin/inetd/Makefile index 29aacd1..043dd68 100644 --- a/usr.sbin/inetd/Makefile +++ b/usr.sbin/inetd/Makefile @@ -16,8 +16,14 @@ CFLAGS+= -DLOGIN_CAP CFLAGS+= -DINET6 .endif -DPADD= ${LIBUTIL} ${LIBWRAP} -LDADD= -lutil -lwrap +DPADD+= ${LIBUTIL} +LDADD+= -lutil + +.if ${MK_TCP_WRAPPERS} != "no" +CFLAGS+= -DLIBWRAP +DPADD+= ${LIBWRAP} +LDADD+= -lwrap +.endif # XXX for src/release/picobsd .if !defined(RELEASE_CRUNCH) diff --git a/usr.sbin/inetd/inetd.c b/usr.sbin/inetd/inetd.c index 5437ae1..56710b5b 100644 --- a/usr.sbin/inetd/inetd.c +++ b/usr.sbin/inetd/inetd.c @@ -138,7 +138,9 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <sysexits.h> #include <syslog.h> +#ifdef LIBWRAP #include <tcpd.h> +#endif #include <unistd.h> #include "inetd.h" @@ -297,6 +299,7 @@ getvalue(const char *arg, int *value, const char *whine) return 0; /* success */ } +#ifdef LIBWRAP static sa_family_t whichaf(struct request_info *req) { @@ -310,6 +313,7 @@ whichaf(struct request_info *req) return AF_INET; return sa->sa_family; } +#endif int main(int argc, char **argv) @@ -324,9 +328,11 @@ main(int argc, char **argv) #ifdef LOGIN_CAP login_cap_t *lc = NULL; #endif +#ifdef LIBWRAP struct request_info req; int denied; char *service = NULL; +#endif struct sockaddr_storage peer; int i; struct addrinfo hints, *res; @@ -736,6 +742,7 @@ main(int argc, char **argv) _exit(0); } } +#ifdef LIBWRAP if (ISWRAP(sep)) { inetd_setproctitle("wrapping", ctrl); service = sep->se_server_name ? @@ -764,6 +771,7 @@ main(int argc, char **argv) (whichaf(&req) == AF_INET6) ? "6" : ""); } } +#endif if (sep->se_bi) { (*sep->se_bi->bi_fn)(ctrl, sep); } else { diff --git a/usr.sbin/route6d/route6d.c b/usr.sbin/route6d/route6d.c index 287a9b1..926d82a 100644 --- a/usr.sbin/route6d/route6d.c +++ b/usr.sbin/route6d/route6d.c @@ -4,7 +4,7 @@ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -16,7 +16,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -34,34 +34,13 @@ static const char _rcsid[] = "$KAME: route6d.c,v 1.104 2003/10/31 00:30:20 itojun Exp $"; #endif -#include <stdio.h> - -#include <time.h> -#include <unistd.h> -#include <fnmatch.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> -#ifdef __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#include <syslog.h> -#include <stddef.h> -#include <errno.h> -#include <err.h> -#ifdef HAVE_POLL_H -#include <poll.h> -#endif - -#include <sys/types.h> #include <sys/param.h> #include <sys/file.h> -#include <sys/socket.h> #include <sys/ioctl.h> +#include <sys/socket.h> #include <sys/sysctl.h> #include <sys/uio.h> +#include <arpa/inet.h> #include <net/if.h> #include <net/if_var.h> #include <net/route.h> @@ -69,10 +48,27 @@ static const char _rcsid[] = "$KAME: route6d.c,v 1.104 2003/10/31 00:30:20 itoju #include <netinet/in_var.h> #include <netinet/ip6.h> #include <netinet/udp.h> -#include <netdb.h> +#include <err.h> +#include <errno.h> +#include <fnmatch.h> #include <ifaddrs.h> - -#include <arpa/inet.h> +#include <netdb.h> +#ifdef HAVE_POLL_H +#include <poll.h> +#endif +#include <signal.h> +#include <stdio.h> +#ifdef __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <time.h> +#include <unistd.h> #include "route6d.h" @@ -107,7 +103,7 @@ struct ifc { /* Configuration of an interface */ }; TAILQ_HEAD(, ifc) ifc_head = TAILQ_HEAD_INITIALIZER(ifc_head); -struct ifac { /* Adddress associated to an interface */ +struct ifac { /* Adddress associated to an interface */ TAILQ_ENTRY(ifac) ifac_next; struct ifc *ifac_ifc; /* back pointer */ @@ -674,7 +670,7 @@ init(void) fatal("rip IPV6_PKTINFO"); /*NOTREACHED*/ } -#endif +#endif #ifdef IPV6_RECVPKTINFO if (setsockopt(ripsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, @@ -820,8 +816,8 @@ ripsend(struct ifc *ifcp, struct sockaddr_in6 *sin6, int flag) * Request from non-link local address is not * a regular route6d update. */ - maxrte = (IFMINMTU - sizeof(struct ip6_hdr) - - sizeof(struct udphdr) - + maxrte = (IFMINMTU - sizeof(struct ip6_hdr) - + sizeof(struct udphdr) - sizeof(struct rip6) + sizeof(struct netinfo6)) / sizeof(struct netinfo6); nh = NULL; @@ -869,8 +865,8 @@ ripsend(struct ifc *ifcp, struct sockaddr_in6 *sin6, int flag) return; } - maxrte = (ifcp->ifc_mtu - sizeof(struct ip6_hdr) - - sizeof(struct udphdr) - + maxrte = (ifcp->ifc_mtu - sizeof(struct ip6_hdr) - + sizeof(struct udphdr) - sizeof(struct rip6) + sizeof(struct netinfo6)) / sizeof(struct netinfo6); @@ -954,13 +950,13 @@ out_filter(struct riprt *rrt, struct ifc *ifcp) /* * -A: filter out less specific routes, if we have aggregated * route configured. - */ + */ TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) { if (iffp->iff_type != 'A') continue; if (rrt->rrt_info.rip6_plen <= iffp->iff_plen) continue; - ia = rrt->rrt_info.rip6_dest; + ia = rrt->rrt_info.rip6_dest; applyplen(&ia, iffp->iff_plen); if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) return 0; @@ -996,7 +992,7 @@ out_filter(struct riprt *rrt, struct ifc *ifcp) continue; if (rrt->rrt_info.rip6_plen < iffp->iff_plen) continue; - ia = rrt->rrt_info.rip6_dest; + ia = rrt->rrt_info.rip6_dest; applyplen(&ia, iffp->iff_plen); if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) { ok = 1; @@ -1196,8 +1192,8 @@ riprecv(void) } else { riprequest(NULL, np, nn, &fsock); } - return; - } + return; + } if (!IN6_IS_ADDR_LINKLOCAL(&fsock.sin6_addr)) { trace(1, "Response from non-ll addr: %s\n", @@ -1224,7 +1220,7 @@ riprecv(void) * source address to be forwarded to a different link. * So we also check whether the destination address is a link-local * address or the hop limit is 255. Note that RFC2080 does not require - * the specific hop limit for a unicast response, so we cannot assume + * the specific hop limit for a unicast response, so we cannot assume * the limitation. */ if (!IN6_IS_ADDR_LINKLOCAL(&pi->ipi6_addr) && *hlimp != 255) { @@ -1246,7 +1242,7 @@ riprecv(void) return; /* The packet is from me; ignore */ if (rp->rip6_cmd != RIP6_RESPONSE) { trace(1, "Invalid command %d\n", rp->rip6_cmd); - return; + return; } /* -N: no use */ @@ -1324,7 +1320,7 @@ riprecv(void) /* special rule: ::/0 means default, not "in /0" */ if (iffp->iff_plen == 0 && np->rip6_plen > 0) continue; - ia = np->rip6_dest; + ia = np->rip6_dest; applyplen(&ia, iffp->iff_plen); if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) { ok = 1; @@ -1375,7 +1371,7 @@ riprecv(void) } else if (nq->rip6_metric == np->rip6_metric && np->rip6_metric < HOPCNT_INFINITY6) { if (rrt->rrt_index == ifcp->ifc_index && - IN6_ARE_ADDR_EQUAL(&nh, &rrt->rrt_gw)) { + IN6_ARE_ADDR_EQUAL(&nh, &rrt->rrt_gw)) { /* same metric, same route from same gw */ rrt->rrt_t = t; } else if (rrt->rrt_t < t_half_lifetime) { @@ -1390,7 +1386,7 @@ riprecv(void) rrt->rrt_t = t; } } - /* + /* * if nq->rip6_metric == HOPCNT_INFINITY6 then * do not update age value. Do nothing. */ @@ -1668,7 +1664,7 @@ ifremove(int ifindex) break; } if (ifcp == NULL) - return; + return; tracet(1, "ifremove: %s is departed.\n", ifcp->ifc_name); TAILQ_REMOVE(&ifc_head, ifcp, ifc_next); @@ -1825,7 +1821,7 @@ rtrecv(void) #if 0 if (rta[RTAX_DST] == NULL) { trace(1, "\tno destination, ignored\n"); - continue; + continue; } if (rta[RTAX_DST]->sin6_family != AF_INET6) { trace(1, "\taf mismatch, ignored\n"); @@ -2423,7 +2419,7 @@ getifmtu(int ifindex) mib[3] = AF_INET6; mib[4] = NET_RT_IFLIST; mib[5] = ifindex; - if (sysctl(mib, 6, NULL, &msize, NULL, 0) < 0) { + if (sysctl(mib, nitems(mib), NULL, &msize, NULL, 0) < 0) { fatal("sysctl estimate NET_RT_IFLIST"); /*NOTREACHED*/ } @@ -2431,7 +2427,7 @@ getifmtu(int ifindex) fatal("malloc"); /*NOTREACHED*/ } - if (sysctl(mib, 6, buf, &msize, NULL, 0) < 0) { + if (sysctl(mib, nitems(mib), buf, &msize, NULL, 0) < 0) { fatal("sysctl NET_RT_IFLIST"); /*NOTREACHED*/ } @@ -2606,7 +2602,7 @@ krtread(int again) free(buf); buf = NULL; } - if (sysctl(mib, 6, NULL, &msize, NULL, 0) < 0) { + if (sysctl(mib, nitems(mib), NULL, &msize, NULL, 0) < 0) { errmsg = "sysctl estimate"; continue; } @@ -2614,7 +2610,7 @@ krtread(int again) errmsg = "malloc"; continue; } - if (sysctl(mib, 6, buf, &msize, NULL, 0) < 0) { + if (sysctl(mib, nitems(mib), buf, &msize, NULL, 0) < 0) { errmsg = "sysctl NET_RT_DUMP"; continue; } @@ -3242,7 +3238,7 @@ ifonly: #if 0 /* * When the address has already been registered in the - * kernel routing table, it should be removed + * kernel routing table, it should be removed */ delroute(&rrt->rrt_info, &gw); #else @@ -3323,7 +3319,7 @@ mask2len(const struct in6_addr *addr, int lenlim) { int i = 0, j; const u_char *p = (const u_char *)addr; - + for (j = 0; j < lenlim; j++, p++) { if (*p != 0xff) break; @@ -3450,7 +3446,7 @@ ripsuptrig(void) time_t t; double r = rand(); - t = (int)(RIP_TRIG_INT6_MIN + + t = (int)(RIP_TRIG_INT6_MIN + (RIP_TRIG_INT6_MAX - RIP_TRIG_INT6_MIN) * (r / RAND_MAX)); sup_trig_update = time(NULL) + t; return t; diff --git a/usr.sbin/rpcbind/Makefile b/usr.sbin/rpcbind/Makefile index 43cb23f..2fbc6ae 100644 --- a/usr.sbin/rpcbind/Makefile +++ b/usr.sbin/rpcbind/Makefile @@ -8,19 +8,25 @@ MAN= rpcbind.8 SRCS= check_bound.c rpcb_stat.c rpcb_svc_4.c rpcbind.c pmap_svc.c \ rpcb_svc.c rpcb_svc_com.c security.c warmstart.c util.c -CFLAGS+= -DPORTMAP -DLIBWRAP +CFLAGS+= -DPORTMAP .if ${MK_INET6_SUPPORT} != "no" CFLAGS+= -DINET6 .endif +.if ${MK_TCP_WRAPPERS} != "no" +CFLAGS+= -DLIBWRAP +DPADD+= ${LIBWRAP} +LDADD+= -lwrap +.endif + .if ${MK_TESTS} != "no" SUBDIR+= tests .endif -WARNS?= 1 +DPADD+= ${LIBUTIL} +LDADD+= -lutil -DPADD= ${LIBWRAP} ${LIBUTIL} -LDADD= -lwrap -lutil +WARNS?= 1 .include <bsd.prog.mk> diff --git a/usr.sbin/rwhod/rwhod.c b/usr.sbin/rwhod/rwhod.c index ff7a60a3..df61c55 100644 --- a/usr.sbin/rwhod/rwhod.c +++ b/usr.sbin/rwhod/rwhod.c @@ -43,14 +43,14 @@ static char sccsid[] = "@(#)rwhod.c 8.1 (Berkeley) 6/6/93"; #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <sys/capsicum.h> #include <sys/param.h> +#include <sys/capsicum.h> +#include <sys/ioctl.h> +#include <sys/procdesc.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/signal.h> -#include <sys/ioctl.h> #include <sys/sysctl.h> -#include <sys/procdesc.h> #include <sys/wait.h> #include <net/if.h> @@ -549,7 +549,7 @@ getboottime(int signo __unused) mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; size = sizeof(tm); - if (sysctl(mib, 2, &tm, &size, NULL, 0) == -1) { + if (sysctl(mib, nitems(mib), &tm, &size, NULL, 0) == -1) { syslog(LOG_ERR, "cannot get boottime: %m"); exit(1); } @@ -630,11 +630,11 @@ configure(int so) mib[3] = AF_INET; mib[4] = NET_RT_IFLIST; mib[5] = 0; - if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0) quit("route-sysctl-estimate"); if ((buf = malloc(needed)) == NULL) quit("malloc"); - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0) quit("actual retrieval of interface table"); lim = buf + needed; diff --git a/usr.sbin/sendmail/Makefile b/usr.sbin/sendmail/Makefile index 5a850bf..c4e9ad9 100644 --- a/usr.sbin/sendmail/Makefile +++ b/usr.sbin/sendmail/Makefile @@ -37,7 +37,7 @@ NIS= -DNIS MAPS= -DMAP_REGEX -DDNSMAP CFLAGS+= -I${SMDIR} -I${SENDMAIL_DIR}/include -I. -CFLAGS+= ${DBMDEF} ${NIS} -DTCPWRAPPERS ${MAPS} +CFLAGS+= ${DBMDEF} ${NIS} ${MAPS} .if ${MK_INET6_SUPPORT} != "no" CFLAGS+= -DNETINET6 -DIPV6_FULL=0 @@ -45,8 +45,8 @@ CFLAGS+= -DNETINET6 -DIPV6_FULL=0 WARNS?= 0 -DPADD= ${LIBUTIL} ${LIBWRAP} -LDADD= -lutil -lwrap +DPADD= ${LIBUTIL} +LDADD= -lutil LIBSMDIR= ${.OBJDIR}/../../lib/libsm LIBSM= ${LIBSMDIR}/libsm.a @@ -67,6 +67,12 @@ DPADD+= ${LIBSSL} ${LIBCRYPTO} LDADD+= -lssl -lcrypto .endif +.if ${MK_TCP_WRAPPERS} != "no" +CFLAGS+= -DTCPWRAPPERS +DPADD+= ${LIBWRAP} +LDADD+= -lwrap +.endif + # User customizations to the sendmail build environment CFLAGS+=${SENDMAIL_CFLAGS} DPADD+=${SENDMAIL_DPADD} diff --git a/usr.sbin/ypserv/Makefile b/usr.sbin/ypserv/Makefile index cb24c43..389ffaa 100644 --- a/usr.sbin/ypserv/Makefile +++ b/usr.sbin/ypserv/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.include <bsd.own.mk> + RPCDIR= ${.CURDIR}/../../include/rpcsvc .PATH: ${RPCDIR} @@ -8,12 +10,15 @@ MAN= ypserv.8 ypinit.8 SRCS= yp_svc.c yp_server.c yp_dblookup.c yp_dnslookup.c \ ypxfr_clnt.c yp.h yp_main.c yp_error.c yp_access.c yp_svc_udp.c -CFLAGS+= -DDB_CACHE -DTCP_WRAPPER -I. +CFLAGS+= -DDB_CACHE -I. WARNS?= 0 -DPADD= ${LIBWRAP} -LDADD= -lwrap +.if ${MK_TCP_WRAPPERS} != "no" +CFLAGS+= -DTCP_WRAPPER +DPADD+= ${LIBWRAP} +LDADD+= -lwrap +.endif CLEANFILES= yp_svc.c ypxfr_clnt.c yp.h |