diff options
28 files changed, 902 insertions, 181 deletions
diff --git a/etc/Makefile b/etc/Makefile index c50014d..1030f5f 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -86,10 +86,6 @@ BIN1+= apmd.conf BIN1+= auto_master .endif -.if ${MK_BSNMP} != "no" -BIN1+= snmpd.config -.endif - .if ${MK_FREEBSD_UPDATE} != "no" BIN1+= freebsd-update.conf .endif @@ -218,6 +214,11 @@ distribution: ${BIN2} ${DESTDIR}/etc; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 600 \ master.passwd nsmb.conf opieaccess ${DESTDIR}/etc; +.if ${MK_BSNMP} != "no" + cd ${.CURDIR}; \ + ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 600 \ + snmpd.config ${DESTDIR}/etc; +.endif .if ${MK_AT} == "no" sed -i "" -e 's;.*/usr/libexec/atrun;#&;' ${DESTDIR}/etc/crontab .endif diff --git a/release/doc/en_US.ISO8859-1/errata/article.xml b/release/doc/en_US.ISO8859-1/errata/article.xml index 1ec6688..fee035f 100644 --- a/release/doc/en_US.ISO8859-1/errata/article.xml +++ b/release/doc/en_US.ISO8859-1/errata/article.xml @@ -19,7 +19,7 @@ <pubdate>$FreeBSD$</pubdate> <copyright> - <year>2015</year> + <year>2016</year> <holder role="mailto:doc@FreeBSD.org">The &os; Documentation Project</holder> diff --git a/release/doc/share/xml/errata.xml b/release/doc/share/xml/errata.xml index 95438a8..b476244 100644 --- a/release/doc/share/xml/errata.xml +++ b/release/doc/share/xml/errata.xml @@ -89,6 +89,29 @@ <entry><para>Applications exiting due to segmentation violation on a correct memory address.</para></entry> </row> + + <row> + <entry><link + xlink:href="&security.url;/FreeBSD-EN-16:01.filemon.asc">FreeBSD-EN-16:01.filemon</link></entry> + <entry>14 January 2016</entry> + <entry><para><application>bmake</application> and + &man.filemon.4; stability issues.</para></entry> + </row> + + <row> + <entry><link + xlink:href="&security.url;/FreeBSD-EN-16:02.pf.asc">FreeBSD-EN-16:02.pf</link></entry> + <entry>14 January 2016</entry> + <entry><para>Invalid TCP checksum issue.</para></entry> + </row> + + <row> + <entry><link + xlink:href="&security.url;/FreeBSD-EN-16:03.yplib.asc">FreeBSD-EN-16:03.yplib</link></entry> + <entry>14 January 2016</entry> + <entry><para><application>YP/NIS</application> library + bug.</para></entry> + </row> </tbody> </tgroup> </informaltable> diff --git a/release/doc/share/xml/security.xml b/release/doc/share/xml/security.xml index 660e434..8bd3cbe 100644 --- a/release/doc/share/xml/security.xml +++ b/release/doc/share/xml/security.xml @@ -53,6 +53,52 @@ <entry>5 December 2015</entry> <entry><para>Multiple vulnerabilities</para></entry> </row> + + <row> + <entry><link + xlink:href="&security.url;/FreeBSD-SA-16:01.sctp.asc">FreeBSD-SA-16:01.sctp</link></entry> + <entry>15 January 2016</entry> + <entry><para>ICMPv6 error message vulnerability</para></entry> + </row> + + <row> + <entry><link + xlink:href="&security.url;/FreeBSD-SA-16:02.ntp.asc">FreeBSD-SA-16:02.ntp</link></entry> + <entry>15 January 2016</entry> + <entry><para>Panic threshold bypass + vulnerability</para></entry> + </row> + + <row> + <entry><link + xlink:href="&security.url;/FreeBSD-SA-16:03.linux.asc">FreeBSD-SA-16:03.linux</link></entry> + <entry>15 January 2016</entry> + <entry><para>Incorrect <literal>futex</literal> + handling</para></entry> + </row> + + <row> + <entry><link + xlink:href="&security.url;/FreeBSD-SA-16:04.linux.asc">FreeBSD-SA-16:04.linux</link></entry> + <entry>15 January 2016</entry> + <entry><para>&man.setgroups.2; system call + vulnerability</para></entry> + </row> + + <row> + <entry><link + xlink:href="&security.url;/FreeBSD-SA-16:05.tcp.asc">FreeBSD-SA-16:05.tcp</link></entry> + <entry>15 January 2016</entry> + <entry><para>MD5 signature denial of service</para></entry> + </row> + + <row> + <entry><link + xlink:href="&security.url;/FreeBSD-SA-16:06.bsnmpd.asc">FreeBSD-SA-16:06.bsnmpd</link></entry> + <entry>15 January 2016</entry> + <entry><para>Insecure default configuration file + permissions</para></entry> + </row> </tbody> </tgroup> </informaltable> diff --git a/release/release.sh b/release/release.sh index 313a16c..caa6f26 100755 --- a/release/release.sh +++ b/release/release.sh @@ -275,6 +275,7 @@ extra_chroot_setup() { PBUILD_FLAGS="${PBUILD_FLAGS} OSREL=${REVISION}" chroot ${CHROOTDIR} make -C /usr/ports/textproc/docproj \ ${PBUILD_FLAGS} OPTIONS_UNSET="FOP IGOR" \ + FORCE_PKG_REGISTER=1 \ install clean distclean fi fi diff --git a/sys/amd64/linux32/linux32_proto.h b/sys/amd64/linux32/linux32_proto.h index 09c63c9..56106d7 100644 --- a/sys/amd64/linux32/linux32_proto.h +++ b/sys/amd64/linux32/linux32_proto.h @@ -1023,7 +1023,7 @@ struct linux_set_robust_list_args { }; struct linux_get_robust_list_args { char pid_l_[PADL_(l_int)]; l_int pid; char pid_r_[PADR_(l_int)]; - char head_l_[PADL_(struct linux_robust_list_head *)]; struct linux_robust_list_head * head; char head_r_[PADR_(struct linux_robust_list_head *)]; + char head_l_[PADL_(struct linux_robust_list_head **)]; struct linux_robust_list_head ** head; char head_r_[PADR_(struct linux_robust_list_head **)]; char len_l_[PADL_(l_size_t *)]; l_size_t * len; char len_r_[PADR_(l_size_t *)]; }; struct linux_splice_args { diff --git a/sys/amd64/linux32/linux32_systrace_args.c b/sys/amd64/linux32/linux32_systrace_args.c index b6ccd33..80889bf 100644 --- a/sys/amd64/linux32/linux32_systrace_args.c +++ b/sys/amd64/linux32/linux32_systrace_args.c @@ -2122,7 +2122,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) case 312: { struct linux_get_robust_list_args *p = params; iarg[0] = p->pid; /* l_int */ - uarg[1] = (intptr_t) p->head; /* struct linux_robust_list_head * */ + uarg[1] = (intptr_t) p->head; /* struct linux_robust_list_head ** */ uarg[2] = (intptr_t) p->len; /* l_size_t * */ *n_args = 3; break; @@ -5551,7 +5551,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) p = "l_int"; break; case 1: - p = "struct linux_robust_list_head *"; + p = "struct linux_robust_list_head **"; break; case 2: p = "l_size_t *"; diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master index 5f688f3..6e09c5a 100644 --- a/sys/amd64/linux32/syscalls.master +++ b/sys/amd64/linux32/syscalls.master @@ -520,8 +520,8 @@ ; linux 2.6.17: 311 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \ l_size_t len); } -312 AUE_NULL STD { int linux_get_robust_list(l_int pid, struct linux_robust_list_head *head, \ - l_size_t *len); } +312 AUE_NULL STD { int linux_get_robust_list(l_int pid, \ + struct linux_robust_list_head **head, l_size_t *len); } 313 AUE_NULL STD { int linux_splice(void); } 314 AUE_NULL STD { int linux_sync_file_range(void); } 315 AUE_NULL STD { int linux_tee(void); } diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c index 4573f73..c7688ae 100644 --- a/sys/compat/linux/linux_futex.c +++ b/sys/compat/linux/linux_futex.c @@ -1132,7 +1132,7 @@ linux_get_robust_list(struct thread *td, struct linux_get_robust_list_args *args return (EFAULT); } - error = copyout(head, args->head, sizeof(struct linux_robust_list_head)); + error = copyout(&head, args->head, sizeof(head)); if (error) { LIN_SDT_PROBE1(futex, linux_get_robust_list, copyout_error, error); diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index d87d786..8f2a687 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1302,9 +1302,11 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args) if (error) goto out; newcred = crget(); + crextend(newcred, ngrp + 1); p = td->td_proc; PROC_LOCK(p); - oldcred = crcopysafe(p, newcred); + oldcred = p->p_ucred; + crcopy(newcred, oldcred); /* * cr_groups[0] holds egid. Setting the whole set from diff --git a/sys/dev/drm2/i915/i915_gem.c b/sys/dev/drm2/i915/i915_gem.c index f2c8ecb..5114008 100644 --- a/sys/dev/drm2/i915/i915_gem.c +++ b/sys/dev/drm2/i915/i915_gem.c @@ -2771,10 +2771,8 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) ret = 0; if (obj->gtt_space == NULL) return (0); - if (obj->pin_count != 0) { - DRM_ERROR("Attempting to unbind pinned buffer\n"); + if (obj->pin_count != 0) return (-EINVAL); - } ret = i915_gem_object_finish_gpu(obj); if (ret == -ERESTARTSYS || ret == -EINTR) diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c index ce943ea..5339aa2 100644 --- a/sys/fs/ext2fs/ext2_vfsops.c +++ b/sys/fs/ext2fs/ext2_vfsops.c @@ -590,7 +590,7 @@ ext2_mountfs(struct vnode *devvp, struct mount *mp) * while Linux keeps the super block in a locked buffer. */ ump->um_e2fs = malloc(sizeof(struct m_ext2fs), - M_EXT2MNT, M_WAITOK); + M_EXT2MNT, M_WAITOK | M_ZERO); ump->um_e2fs->e2fs = malloc(sizeof(struct ext2fs), M_EXT2MNT, M_WAITOK); mtx_init(EXT2_MTX(ump), "EXT2FS", "EXT2FS Lock", MTX_DEF); diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master index e6609a9..248770c 100644 --- a/sys/i386/linux/syscalls.master +++ b/sys/i386/linux/syscalls.master @@ -528,8 +528,8 @@ ; linux 2.6.17: 311 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \ l_size_t len); } -312 AUE_NULL STD { int linux_get_robust_list(l_int pid, struct linux_robust_list_head **head, \ - l_size_t *len); } +312 AUE_NULL STD { int linux_get_robust_list(l_int pid, \ + struct linux_robust_list_head **head, l_size_t *len); } 313 AUE_NULL STD { int linux_splice(void); } 314 AUE_NULL STD { int linux_sync_file_range(void); } 315 AUE_NULL STD { int linux_tee(void); } diff --git a/sys/kern/kern_ktr.c b/sys/kern/kern_ktr.c index 428afae..e988f2b 100644 --- a/sys/kern/kern_ktr.c +++ b/sys/kern/kern_ktr.c @@ -54,9 +54,6 @@ __FBSDID("$FreeBSD$"); #include <sys/time.h> #include <machine/cpu.h> -#ifdef __sparc64__ -#include <machine/ktr.h> -#endif #ifdef DDB #include <ddb/ddb.h> diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 9b97be4..03b9001 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -88,7 +88,6 @@ static MALLOC_DEFINE(M_CRED, "cred", "credentials"); SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy"); -static void crextend(struct ucred *cr, int n); static void crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups); @@ -1981,7 +1980,7 @@ crcopysafe(struct proc *p, struct ucred *cr) /* * Extend the passed in credential to hold n items. */ -static void +void crextend(struct ucred *cr, int n) { int cnt; diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index c7dc547..2ca0fb5 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -745,8 +745,8 @@ send: * segments. Options for SYN-ACK segments are handled in TCP * syncache. */ + to.to_flags = 0; if ((tp->t_flags & TF_NOOPT) == 0) { - to.to_flags = 0; /* Maximum segment size. */ if (flags & TH_SYN) { tp->snd_nxt = tp->iss; @@ -1226,7 +1226,7 @@ send: tp->snd_up = tp->snd_una; /* drag it along */ #ifdef TCP_SIGNATURE - if (tp->t_flags & TF_SIGNATURE) { + if (to.to_flags & TOF_SIGNATURE) { int sigoff = to.to_signature - opt; tcp_signature_compute(m, 0, len, optlen, (u_char *)(th + 1) + sigoff, IPSEC_DIR_OUTBOUND); @@ -1696,6 +1696,7 @@ tcp_addoptions(struct tcpopt *to, u_char *optp) bcopy((u_char *)&to->to_tsecr, optp, sizeof(to->to_tsecr)); optp += sizeof(to->to_tsecr); break; +#ifdef TCP_SIGNATURE case TOF_SIGNATURE: { int siglen = TCPOLEN_SIGNATURE - 2; @@ -1714,6 +1715,7 @@ tcp_addoptions(struct tcpopt *to, u_char *optp) *optp++ = 0; break; } +#endif case TOF_SACK: { int sackblks = 0; diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c index 536cc91..7670289 100644 --- a/sys/netinet6/sctp6_usrreq.c +++ b/sys/netinet6/sctp6_usrreq.c @@ -386,7 +386,6 @@ sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d) * XXX: We assume that when IPV6 is non NULL, M and OFF are * valid. */ - /* check if we can safely examine src and dst ports */ struct sctp_inpcb *inp = NULL; struct sctp_tcb *stcb = NULL; struct sctp_nets *net = NULL; @@ -395,6 +394,10 @@ sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d) if (ip6cp->ip6c_m == NULL) return; + /* Check if we can safely examine the SCTP header. */ + if (ip6cp->ip6c_m->m_pkthdr.len < ip6cp->ip6c_off + sizeof(sh)) + return; + bzero(&sh, sizeof(sh)); bzero(&final, sizeof(final)); inp = NULL; diff --git a/sys/sparc64/include/ktr.h b/sys/sparc64/include/ktr.h index 0a7f0e1..e7c6112 100644 --- a/sys/sparc64/include/ktr.h +++ b/sys/sparc64/include/ktr.h @@ -34,14 +34,10 @@ #include <sys/ktr.h> -#ifndef LOCORE - -#define KTR_CPU PCPU_GET(mid) - -#else +#ifdef LOCORE /* - * XXX could really use another register... + * XXX could really use another register ... */ #define ATR(desc, r1, r2, r3, l1, l2) \ .sect .rodata ; \ @@ -63,16 +59,13 @@ l2: add r2, 1, r3 ; \ add r1, r2, r1 ; \ rd %tick, r2 ; \ stx r2, [r1 + KTR_TIMESTAMP] ; \ - lduw [PCPU(MID)], r2 ; \ + lduw [PCPU(CPUID)], r2 ; \ stw r2, [r1 + KTR_CPU] ; \ stw %g0, [r1 + KTR_LINE] ; \ stx %g0, [r1 + KTR_FILE] ; \ SET(l1 ## b, r3, r2) ; \ stx r2, [r1 + KTR_DESC] -/* - * NB: this clobbers %y. - */ #define CATR(mask, desc, r1, r2, r3, l1, l2, l3) \ set mask, r1 ; \ SET(ktr_mask, r3, r2) ; \ @@ -82,16 +75,14 @@ l2: add r2, 1, r3 ; \ nop ; \ lduw [PCPU(CPUID)], r2 ; \ mov _NCPUBITS, r3 ; \ - mov %g0, %y ; \ - udiv r2, r3, r2 ; \ + udivx r2, r3, r2 ; \ srl r2, 0, r2 ; \ sllx r2, PTR_SHIFT, r2 ; \ SET(ktr_cpumask, r3, r1) ; \ ldx [r1 + r2], r1 ; \ lduw [PCPU(CPUID)], r2 ; \ mov _NCPUBITS, r3 ; \ - mov %g0, %y ; \ - udiv r2, r3, r2 ; \ + udivx r2, r3, r2 ; \ srl r2, 0, r2 ; \ smul r2, r3, r3 ; \ lduw [PCPU(CPUID)], r2 ; \ diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S index 09db4e0..ba571cf 100644 --- a/sys/sparc64/sparc64/exception.S +++ b/sys/sparc64/sparc64/exception.S @@ -2627,9 +2627,9 @@ ENTRY(tl0_ret) andn %l4, TSTATE_CWP_MASK, %g2 /* - * Save %y in an alternate global. + * Restore %y. Could also be below if we had more alternate globals. */ - mov %l5, %g4 + wr %l5, 0, %y /* * Setup %wstate for return. We need to restore the user window state @@ -2674,8 +2674,8 @@ tl0_ret_fill: * Fixup %tstate so the saved %cwp points to the current window and * restore it. */ - rdpr %cwp, %g1 - wrpr %g2, %g1, %tstate + rdpr %cwp, %g4 + wrpr %g2, %g4, %tstate /* * Restore the user window state. The transition bit was set above @@ -2685,25 +2685,20 @@ tl0_ret_fill: #if KTR_COMPILE & KTR_TRAP CATR(KTR_TRAP, "tl0_ret: td=%#lx pil=%#lx pc=%#lx npc=%#lx sp=%#lx" - , %g1, %g2, %g3, 7, 8, 9) - ldx [PCPU(CURTHREAD)], %g2 - stx %g2, [%g1 + KTR_PARM1] - rdpr %pil, %g2 - stx %g2, [%g1 + KTR_PARM2] - rdpr %tpc, %g2 - stx %g2, [%g1 + KTR_PARM3] - rdpr %tnpc, %g2 - stx %g2, [%g1 + KTR_PARM4] - stx %sp, [%g1 + KTR_PARM5] + , %g2, %g3, %g4, 7, 8, 9) + ldx [PCPU(CURTHREAD)], %g3 + stx %g3, [%g2 + KTR_PARM1] + rdpr %pil, %g3 + stx %g3, [%g2 + KTR_PARM2] + rdpr %tpc, %g3 + stx %g3, [%g2 + KTR_PARM3] + rdpr %tnpc, %g3 + stx %g3, [%g2 + KTR_PARM4] + stx %sp, [%g2 + KTR_PARM5] 9: #endif /* - * Restore %y. Note that the CATR above clobbered it. - */ - wr %g4, 0, %y - - /* * Return to usermode. */ retry @@ -2717,11 +2712,6 @@ tl0_ret_fill_end: stx %l6, [%l0 + KTR_PARM2] stx %sp, [%l0 + KTR_PARM3] 9: - - /* - * Restore %y clobbered by the CATR. This was saved in %l5 above. - */ - wr %l5, 0, %y #endif /* @@ -2889,36 +2879,34 @@ ENTRY(tl1_ret) andn %l0, TSTATE_CWP_MASK, %g1 mov %l1, %g2 mov %l2, %g3 - mov %l4, %g4 wrpr %l3, 0, %pil + wr %l4, 0, %y restore wrpr %g0, 2, %tl + rdpr %cwp, %g4 + wrpr %g1, %g4, %tstate wrpr %g2, 0, %tpc wrpr %g3, 0, %tnpc - rdpr %cwp, %g2 - wrpr %g1, %g2, %tstate #if KTR_COMPILE & KTR_TRAP CATR(KTR_TRAP, "tl1_ret: td=%#lx pil=%#lx ts=%#lx pc=%#lx sp=%#lx" - , %g1, %g2, %g3, 7, 8, 9) - ldx [PCPU(CURTHREAD)], %g2 - stx %g2, [%g1 + KTR_PARM1] - rdpr %pil, %g2 - stx %g2, [%g1 + KTR_PARM2] - rdpr %tstate, %g2 - stx %g2, [%g1 + KTR_PARM3] - rdpr %tpc, %g2 - stx %g2, [%g1 + KTR_PARM4] - stx %sp, [%g1 + KTR_PARM5] + , %g2, %g3, %g4, 7, 8, 9) + ldx [PCPU(CURTHREAD)], %g3 + stx %g3, [%g2 + KTR_PARM1] + rdpr %pil, %g3 + stx %g3, [%g2 + KTR_PARM2] + rdpr %tstate, %g3 + stx %g3, [%g2 + KTR_PARM3] + rdpr %tpc, %g3 + stx %g3, [%g2 + KTR_PARM4] + stx %sp, [%g2 + KTR_PARM5] 9: #endif - wr %g4, 0, %y - retry END(tl1_ret) @@ -3019,35 +3007,33 @@ ENTRY(tl1_intr) andn %l0, TSTATE_CWP_MASK, %g1 mov %l1, %g2 mov %l2, %g3 - mov %l4, %g4 wrpr %l3, 0, %pil + wr %l4, 0, %y restore wrpr %g0, 2, %tl + rdpr %cwp, %g4 + wrpr %g1, %g4, %tstate wrpr %g2, 0, %tpc wrpr %g3, 0, %tnpc - rdpr %cwp, %g2 - wrpr %g1, %g2, %tstate #if KTR_COMPILE & KTR_INTR CATR(KTR_INTR, "tl1_intr: td=%#x pil=%#lx ts=%#lx pc=%#lx sp=%#lx" - , %g1, %g2, %g3, 7, 8, 9) - ldx [PCPU(CURTHREAD)], %g2 - stx %g2, [%g1 + KTR_PARM1] - rdpr %pil, %g2 - stx %g2, [%g1 + KTR_PARM2] - rdpr %tstate, %g2 - stx %g2, [%g1 + KTR_PARM3] - rdpr %tpc, %g2 - stx %g2, [%g1 + KTR_PARM4] - stx %sp, [%g1 + KTR_PARM5] + , %g2, %g3, %g4, 7, 8, 9) + ldx [PCPU(CURTHREAD)], %g3 + stx %g3, [%g2 + KTR_PARM1] + rdpr %pil, %g3 + stx %g3, [%g2 + KTR_PARM2] + rdpr %tstate, %g3 + stx %g3, [%g2 + KTR_PARM3] + rdpr %tpc, %g3 + stx %g3, [%g2 + KTR_PARM4] + stx %sp, [%g2 + KTR_PARM5] 9: #endif - wr %g4, 0, %y - retry END(tl1_intr) diff --git a/sys/sparc64/sparc64/mp_exception.S b/sys/sparc64/sparc64/mp_exception.S index 54a5e4d..9bd61b9 100644 --- a/sys/sparc64/sparc64/mp_exception.S +++ b/sys/sparc64/sparc64/mp_exception.S @@ -38,12 +38,10 @@ __FBSDID("$FreeBSD$"); .register %g2, #ignore .register %g3, #ignore -#define IPI_DONE(r1, r2, r3, r4, r5, r6) \ - rd %y, r6 ; \ +#define IPI_DONE(r1, r2, r3, r4, r5) \ lduw [PCPU(CPUID)], r2 ; \ mov _NCPUBITS, r3 ; \ - mov %g0, %y ; \ - udiv r2, r3, r4 ; \ + udivx r2, r3, r4 ; \ srl r4, 0, r5 ; \ sllx r5, PTR_SHIFT, r5 ; \ add r1, r5, r1 ; \ @@ -51,7 +49,6 @@ __FBSDID("$FreeBSD$"); sub r2, r3, r3 ; \ mov 1, r4 ; \ sllx r4, r3, r4 ; \ - wr r6, %y ; \ ATOMIC_CLEAR_LONG(r1, r2, r3, r4) /* @@ -89,7 +86,7 @@ ENTRY(tl_ipi_spitfire_dcache_page_inval) 2: brgz,pt %g2, 1b sub %g2, %g4, %g2 - IPI_DONE(%g5, %g1, %g2, %g3, %g4, %g6) + IPI_DONE(%g5, %g1, %g2, %g3, %g4) retry END(tl_ipi_spitfire_dcache_page_inval) @@ -129,7 +126,7 @@ ENTRY(tl_ipi_spitfire_icache_page_inval) 2: brgz,pt %g2, 1b sub %g2, %g4, %g2 - IPI_DONE(%g5, %g1, %g2, %g3, %g4, %g6) + IPI_DONE(%g5, %g1, %g2, %g3, %g4) retry END(tl_ipi_spitfire_icache_page_inval) @@ -160,7 +157,7 @@ ENTRY(tl_ipi_cheetah_dcache_page_inval) blt,a,pt %xcc, 1b nop - IPI_DONE(%g5, %g1, %g2, %g3, %g4, %g6) + IPI_DONE(%g5, %g1, %g2, %g3, %g4) retry END(tl_ipi_cheetah_dcache_page_inval) @@ -216,7 +213,7 @@ ENTRY(tl_ipi_tlb_page_demap) stxa %g0, [%g2] ASI_IMMU_DEMAP flush %g3 - IPI_DONE(%g5, %g1, %g2, %g3, %g4, %g6) + IPI_DONE(%g5, %g1, %g2, %g3, %g4) retry END(tl_ipi_tlb_page_demap) @@ -259,7 +256,7 @@ ENTRY(tl_ipi_tlb_range_demap) blt,a,pt %xcc, 1b sethi %hi(KERNBASE), %g6 - IPI_DONE(%g5, %g1, %g2, %g3, %g4, %g6) + IPI_DONE(%g5, %g1, %g2, %g3, %g4) retry END(tl_ipi_tlb_range_demap) @@ -283,7 +280,7 @@ ENTRY(tl_ipi_tlb_context_demap) stxa %g0, [%g1] ASI_IMMU_DEMAP flush %g3 - IPI_DONE(%g5, %g1, %g2, %g3, %g4, %g6) + IPI_DONE(%g5, %g1, %g2, %g3, %g4) retry END(tl_ipi_tlb_context_demap) @@ -295,7 +292,7 @@ ENTRY(tl_ipi_stick_rd) rd %asr24, %g2 stx %g2, [%g1] - IPI_DONE(%g5, %g1, %g2, %g3, %g4, %g6) + IPI_DONE(%g5, %g1, %g2, %g3, %g4) retry END(tl_ipi_stick_rd) @@ -307,6 +304,6 @@ ENTRY(tl_ipi_tick_rd) rd %tick, %g2 stx %g2, [%g1] - IPI_DONE(%g5, %g1, %g2, %g3, %g4, %g6) + IPI_DONE(%g5, %g1, %g2, %g3, %g4) retry END(tl_ipi_tick_rd) diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index 9073760..c138ef9 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -345,14 +345,18 @@ pmap_bootstrap(u_int cpu_impl) if (OF_getprop(pmem, "available", mra, sz) == -1) OF_panic("%s: getprop /memory/available", __func__); sz /= sizeof(*mra); - CTR0(KTR_PMAP, "pmap_bootstrap: physical memory"); +#ifdef DIAGNOSTIC + OF_printf("pmap_bootstrap: physical memory\n"); +#endif qsort(mra, sz, sizeof (*mra), mr_cmp); physsz = 0; getenv_quad("hw.physmem", &physmem); physmem = btoc(physmem); for (i = 0, j = 0; i < sz; i++, j += 2) { - CTR2(KTR_PMAP, "start=%#lx size=%#lx", mra[i].mr_start, +#ifdef DIAGNOSTIC + OF_printf("start=%#lx size=%#lx\n", mra[i].mr_start, mra[i].mr_size); +#endif if (physmem != 0 && btoc(physsz + mra[i].mr_size) >= physmem) { if (btoc(physsz) < physmem) { phys_avail[j] = mra[i].mr_start; @@ -616,13 +620,16 @@ pmap_bootstrap(u_int cpu_impl) __func__); sz /= sizeof(*translations); translations_size = sz; - CTR0(KTR_PMAP, "pmap_bootstrap: translations"); +#ifdef DIAGNOSTIC + OF_printf("pmap_bootstrap: translations\n"); +#endif qsort(translations, sz, sizeof (*translations), om_cmp); for (i = 0; i < sz; i++) { - CTR3(KTR_PMAP, - "translation: start=%#lx size=%#lx tte=%#lx", +#ifdef DIAGNOSTIC + OF_printf("translation: start=%#lx size=%#lx tte=%#lx\n", translations[i].om_start, translations[i].om_size, translations[i].om_tte); +#endif if ((translations[i].om_tte & TD_V) == 0) continue; if (translations[i].om_start < VM_MIN_PROM_ADDRESS || diff --git a/sys/sparc64/sparc64/swtch.S b/sys/sparc64/sparc64/swtch.S index 22db805..49d3cf5 100644 --- a/sys/sparc64/sparc64/swtch.S +++ b/sys/sparc64/sparc64/swtch.S @@ -173,8 +173,7 @@ ENTRY(cpu_switch) * active on this CPU. */ mov _NCPUBITS, %l5 - mov %g0, %y - udiv %l3, %l5, %l6 + udivx %l3, %l5, %l6 srl %l6, 0, %l4 sllx %l4, PTR_SHIFT, %l4 add %l4, PM_ACTIVE, %l4 @@ -242,8 +241,7 @@ ENTRY(cpu_switch) * Mark the pmap as active on this CPU. */ mov _NCPUBITS, %l5 - mov %g0, %y - udiv %l3, %l5, %l6 + udivx %l3, %l5, %l6 srl %l6, 0, %l4 sllx %l4, PTR_SHIFT, %l4 add %l4, PM_ACTIVE, %l4 diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index e1648d4..45ed0d5 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -104,6 +104,7 @@ void change_svuid(struct ucred *newcred, uid_t svuid); void crcopy(struct ucred *dest, struct ucred *src); struct ucred *crcopysafe(struct proc *p, struct ucred *cr); struct ucred *crdup(struct ucred *cr); +void crextend(struct ucred *cr, int n); void cred_update_thread(struct thread *td); void crfree(struct ucred *cr); struct ucred *crget(void); diff --git a/usr.sbin/sesutil/Makefile b/usr.sbin/sesutil/Makefile index 39ca86b..e7e7089 100644 --- a/usr.sbin/sesutil/Makefile +++ b/usr.sbin/sesutil/Makefile @@ -1,6 +1,10 @@ # $FreeBSD$ PROG= sesutil +SRCS= sesutil.c eltsub.c MAN= sesutil.8 +DPADD= ${LIBSBUF} +LDADD= -lsbuf + .include <bsd.prog.mk> diff --git a/usr.sbin/sesutil/eltsub.c b/usr.sbin/sesutil/eltsub.c new file mode 100644 index 0000000..287530d --- /dev/null +++ b/usr.sbin/sesutil/eltsub.c @@ -0,0 +1,235 @@ +/* $FreeBSD$ */ +/* + * Copyright (c) 2000 by Matthew Jacob + * 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, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * the GNU Public License ("GPL"). + * + * 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. + * + * Matthew Jacob + * Feral Software + * mjacob@feral.com + */ + +#include <sys/endian.h> +#include <sys/types.h> +#include <sys/sbuf.h> + +#include <err.h> +#include <unistd.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/ioctl.h> +#include <cam/scsi/scsi_all.h> +#include <cam/scsi/scsi_enc.h> + +#include "eltsub.h" + +/* + * offset by +20 degrees. + * The range of the value expresses a temperature between -19 and +235 degrees + * Celsius. A value of 00h is reserved. + */ +#define TEMPERATURE_OFFSET 20 + +char * +geteltnm(int type) +{ + static char rbuf[132]; + + switch (type) { + case ELMTYP_UNSPECIFIED: + sprintf(rbuf, "Unspecified"); + break; + case ELMTYP_DEVICE: + sprintf(rbuf, "Device Slot"); + break; + case ELMTYP_POWER: + sprintf(rbuf, "Power Supply"); + break; + case ELMTYP_FAN: + sprintf(rbuf, "Cooling"); + break; + case ELMTYP_THERM: + sprintf(rbuf, "Temperature Sensors"); + break; + case ELMTYP_DOORLOCK: + sprintf(rbuf, "Door Lock"); + break; + case ELMTYP_ALARM: + sprintf(rbuf, "Audible alarm"); + break; + case ELMTYP_ESCC: + sprintf(rbuf, "Enclosure Services Controller Electronics"); + break; + case ELMTYP_SCC: + sprintf(rbuf, "SCC Controller Electronics"); + break; + case ELMTYP_NVRAM: + sprintf(rbuf, "Nonvolatile Cache"); + break; + case ELMTYP_INV_OP_REASON: + sprintf(rbuf, "Invalid Operation Reason"); + break; + case ELMTYP_UPS: + sprintf(rbuf, "Uninterruptible Power Supply"); + break; + case ELMTYP_DISPLAY: + sprintf(rbuf, "Display"); + break; + case ELMTYP_KEYPAD: + sprintf(rbuf, "Key Pad Entry"); + break; + case ELMTYP_ENCLOSURE: + sprintf(rbuf, "Enclosure"); + break; + case ELMTYP_SCSIXVR: + sprintf(rbuf, "SCSI Port/Transceiver"); + break; + case ELMTYP_LANGUAGE: + sprintf(rbuf, "Language"); + break; + case ELMTYP_COMPORT: + sprintf(rbuf, "Communication Port"); + break; + case ELMTYP_VOM: + sprintf(rbuf, "Voltage Sensor"); + break; + case ELMTYP_AMMETER: + sprintf(rbuf, "Current Sensor"); + break; + case ELMTYP_SCSI_TGT: + sprintf(rbuf, "SCSI Target Port"); + break; + case ELMTYP_SCSI_INI: + sprintf(rbuf, "SCSI Initiator Port"); + break; + case ELMTYP_SUBENC: + sprintf(rbuf, "Simple Subenclosure"); + break; + case ELMTYP_ARRAY_DEV: + sprintf(rbuf, "Array Device Slot"); + break; + case ELMTYP_SAS_EXP: + sprintf(rbuf, "SAS Expander"); + break; + case ELMTYP_SAS_CONN: + sprintf(rbuf, "SAS Connector"); + break; + default: + (void) sprintf(rbuf, "<Type 0x%x>", type); + break; + } + return (rbuf); +} + +char * +scode2ascii(u_char code) +{ + static char rbuf[32]; + switch (code & 0xf) { + case SES_OBJSTAT_UNSUPPORTED: + sprintf(rbuf, "Unsupported"); + break; + case SES_OBJSTAT_OK: + sprintf(rbuf, "OK"); + break; + case SES_OBJSTAT_CRIT: + sprintf(rbuf, "Critical"); + break; + case SES_OBJSTAT_NONCRIT: + sprintf(rbuf, "Noncritical"); + break; + case SES_OBJSTAT_UNRECOV: + sprintf(rbuf, "Unrecoverable"); + break; + case SES_OBJSTAT_NOTINSTALLED: + sprintf(rbuf, "Not Installed"); + break; + case SES_OBJSTAT_UNKNOWN: + sprintf(rbuf, "Unknown"); + break; + case SES_OBJSTAT_NOTAVAIL: + sprintf(rbuf, "Not Available"); + break; + case SES_OBJSTAT_NOACCESS: + sprintf(rbuf, "No Access Allowed"); + break; + default: + sprintf(rbuf, "<Status 0x%x>", code & 0xf); + break; + } + return (rbuf); +} + +struct sbuf * +stat2sbuf(int eletype, u_char *cstat) +{ + struct sbuf *buf; + + buf = sbuf_new_auto(); + if (buf == NULL) + err(EXIT_FAILURE, "sbuf_new_auto()"); + + if (cstat[0] & 0x40) + sbuf_printf(buf, "\t\t- Predicted Failure\n"); + if (cstat[0] & 0x20) + sbuf_printf(buf, "\t\t- Disabled\n"); + if (cstat[0] & 0x10) + sbuf_printf(buf, "\t\t- Swapped\n"); + switch (eletype) { + case ELMTYP_DEVICE: + if (cstat[2] & 0x02) + sbuf_printf(buf, "\t\t- LED=locate\n"); + if (cstat[2] & 0x20) + sbuf_printf(buf, "\t\t- LED=fault\n"); + break; + case ELMTYP_ARRAY_DEV: + if (cstat[2] & 0x02) + sbuf_printf(buf, "\t\t- LED=locate\n"); + if (cstat[2] & 0x20) + sbuf_printf(buf, "\t\t- LED=fault\n"); + break; + case ELMTYP_FAN: + sbuf_printf(buf, "\t\t- Speed: %d rpm\n", + (((0x7 & cstat[1]) << 8) + cstat[2]) * 10); + break; + case ELMTYP_THERM: + if (cstat[2]) { + sbuf_printf(buf, "\t\t- Temperature: %d C\n", + cstat[2] - TEMPERATURE_OFFSET); + } else { + sbuf_printf(buf, "\t\t- Temperature: -reserved-\n"); + } + break; + case ELMTYP_VOM: + sbuf_printf(buf, "\t\t- Voltage: %.2f V\n", + be16dec(cstat + 2) / 100.0); + break; + } + sbuf_finish(buf); + return (buf); +} diff --git a/usr.sbin/sesutil/eltsub.h b/usr.sbin/sesutil/eltsub.h new file mode 100644 index 0000000..299ada3 --- /dev/null +++ b/usr.sbin/sesutil/eltsub.h @@ -0,0 +1,37 @@ +/* $FreeBSD$ */ +/* + * Copyright (c) 2000 by Matthew Jacob + * 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, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * the GNU Public License ("GPL"). + * + * 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. + * + * Matthew Jacob + * Feral Software + * mjacob@feral.com + */ + +char *geteltnm(int); +char *scode2ascii(u_char); +struct sbuf *stat2sbuf(int, u_char *); diff --git a/usr.sbin/sesutil/sesutil.8 b/usr.sbin/sesutil/sesutil.8 index 8c64922..79d0f66 100644 --- a/usr.sbin/sesutil/sesutil.8 +++ b/usr.sbin/sesutil/sesutil.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 1, 2015 +.Dd September 6, 2015 .Dt SESUTIL 8 .Os .Sh NAME @@ -32,34 +32,87 @@ .Nd Utility for managing SCSI Enclosure Services (SES) device .Sh SYNOPSIS .Nm -.Cm locate Ar disk Bq on|off +.Cm fault +.Op Fl u Ar /dev/sesN +.Aq Ar disk | Ar sesid | Li all +.Op on | off +.Nm +.Cm locate +.Op Fl u Ar /dev/sesN +.Aq Ar disk | Ar sesid | Li all +.Op on | off +.Nm +.Cm map +.Op Fl u Ar /dev/sesN +.Nm +.Cm status +.Op Fl u Ar /dev/sesN .Sh DESCRIPTION The .Nm -utility can be used to modify various parameter on SCSI Enclosure Services -(SES) device. +utility can be used to query and modify various parameter of SCSI Enclosure +Services (SES) devices. .Pp List of supported commands: .Bl -tag -width indent -.It Cm locate Ar disk Bq on|off -Change the state of the external LED associated with +.It Cm fault Oo Fl u Ar /dev/sesN Oc Ao Ar disk | Li all Ac Op on | off +Change the state of the external fault LED associated with +.Ar disk . +.Ar disk +can be the device name of the disk, like +.Cm da12 , +or +.Ql all . +to indicate all disks attached to SES controllers. +.It Cm fault Fl u Ar /dev/sesN Ar sesid Op on | off +Change the state of the external fault LED associated with an element +connected to the SES controller. +.Ar sesid +must be the element ID of a valid item attached to the controller. +Use the +.Cm map +command to list the elements attached to a controller. +.It Cm locate Oo Fl u Ar /dev/sesN Oc Ao Ar disk | Li all Ac Op on | off +Change the state of the external locate LED associated with .Ar disk . .Ar disk can be the device name of the disk, like .Cm da12 , or -.Cm all . +.Ql all . to indicate all disks attached to SES controllers. +.It Cm locate Fl u Ar /dev/sesN Ar sesid Op on | off +Change the state of the external locate LED associated with an element +connected to the SES controller. +.Ar sesid +must be the element ID of a valid item attached to the controller. +Use the +.Cm map +command to list the elements attached to a controller. +.It Cm map Op Fl u Ar /dev/sesN +Display a map of all elements connected to the specified +.Xr ses 4 +controller. +If no controller is specified, all controllers are mapped. +.It Cm status Op Fl u Ar /dev/sesN +Display the status of the specified +.Xr ses 4 +controller. +If no controller is specified, the status of each controller is returned. .El .Sh EXAMPLES -Turn off all external LEDs: +Turn off all locate LEDs: .Pp .Dl Nm Cm locate all off .Pp -Turn on the external LED of drive +Turn on the locate LED for the drive bay corresponding to .Pa da15 : .Pp .Dl Nm Cm locate da15 on +.Pp +Turn on the fault LED for a drive bay not associated with a device: +.Pp +.Dl Nm Cm fault -u /dev/ses2 7 on .Sh SEE ALSO .Xr ses 4 .Sh HISTORY @@ -68,6 +121,10 @@ The utility first appeared in .Fx 11.0 . .Sh AUTHORS +.An -nosplit The -.Nm utility was written by -.An Baptiste Daroussin Aq Mt bapt@FreeBSD.org . +.Nm +utility was written by +.An Baptiste Daroussin Aq Mt bapt@FreeBSD.org +and +.An Allan Jude Aq Mt allanjude@FreeBSD.org . diff --git a/usr.sbin/sesutil/sesutil.c b/usr.sbin/sesutil/sesutil.c index 1b38143..0f04c07 100644 --- a/usr.sbin/sesutil/sesutil.c +++ b/usr.sbin/sesutil/sesutil.c @@ -1,5 +1,7 @@ /*- * Copyright (c) 2015 Baptiste Daroussin <bapt@FreeBSD.org> + * Copyright (c) 2015 Allan Jude <allanjude@FreeBSD.org> + * Copyright (c) 2000 by Matthew Jacob * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,10 +31,13 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/sbuf.h> #include <err.h> #include <errno.h> #include <fcntl.h> +#include <getopt.h> #include <glob.h> #include <stdbool.h> #include <stddef.h> @@ -45,21 +50,66 @@ __FBSDID("$FreeBSD$"); #include <cam/scsi/scsi_all.h> #include <cam/scsi/scsi_enc.h> +#include "eltsub.h" + +static int encstatus(int argc, char **argv); +static int fault(int argc, char **argv); static int locate(int argc, char **argv); +static int objmap(int argc, char **argv); +static int sesled(int argc, char **argv, bool fault); static struct command { const char *name; + const char *param; const char *desc; int (*exec)(int argc, char **argv); } cmds[] = { - { "locate", "Change the state of the external LED associated with a" - " disk", locate} , + { "fault", + "(<disk>|<sesid>|all) (on|off)", + "Change the state of the fault LED associated with a disk", + fault }, + { "locate", + "(<disk>|<sesid>|all) (on|off)", + "Change the state of the locate LED associated with a disk", + locate }, + { "map", "", + "Print a map of the devices managed by the enclosure", objmap } , + { "status", "", "Print the status of the enclosure", + encstatus }, }; static const int nbcmds = nitems(cmds); +static const char *uflag; static void -do_locate(int fd, unsigned int idx, bool onoff) +usage(FILE *out, const char *subcmd) +{ + int i; + + if (subcmd == NULL) { + fprintf(out, "Usage: %s [-u /dev/ses<N>] <command> [options]\n", + getprogname()); + fprintf(out, "Commands supported:\n"); + } + for (i = 0; i < nbcmds; i++) { + if (subcmd != NULL) { + if (strcmp(subcmd, cmds[i].name) == 0) { + fprintf(out, "Usage: %s %s [-u /dev/ses<N>] " + "%s\n\t%s\n", getprogname(), subcmd, + cmds[i].param, cmds[i].desc); + break; + } + continue; + } + fprintf(out, " %-12s%s\n\t\t%s\n\n", cmds[i].name, + cmds[i].param, cmds[i].desc); + } + + exit(EXIT_FAILURE); +} + +static void +do_led(int fd, unsigned int idx, bool onoff, bool setfault) { encioc_elm_status_t o; @@ -69,10 +119,11 @@ do_locate(int fd, unsigned int idx, bool onoff) err(EXIT_FAILURE, "ENCIOC_GETELMSTAT"); } o.cstat[0] |= 0x80; - if (onoff) - o.cstat[2] |= 0x02; - else - o.cstat[2] &= 0xfd; + if (onoff) { + o.cstat[2] |= (setfault ? 0x20 : 0x02); + } else { + o.cstat[2] &= (setfault ? 0xdf : 0xfd); + } if (ioctl(fd, ENCIOC_SETELMSTAT, (caddr_t) &o) < 0) { close(fd); @@ -87,39 +138,54 @@ disk_match(const char *devnames, const char *disk, size_t len) dname = devnames; while ((dname = strstr(dname, disk)) != NULL) { - if (dname[len] == '\0' || dname[len] == ',') + if (dname[len] == '\0' || dname[len] == ',') { return (true); + } dname++; } + return (false); } static int -locate(int argc, char **argv) +sesled(int argc, char **argv, bool setfault) { encioc_elm_devnames_t objdn; encioc_element_t *objp; glob_t g; - char *disk; - size_t len, i; - int fd, nobj, j; - bool all = false; - bool onoff; - - if (argc != 2) { - errx(EXIT_FAILURE, "usage: %s locate [disk] [on|off]", - getprogname()); + char *disk, *endptr; + size_t len, i, ndisks; + int fd; + unsigned int nobj, j, sesid; + bool all, isses, onoff; + + isses = false; + all = false; + onoff = false; + + if (argc != 3) { + usage(stderr, (setfault ? "fault" : "locate")); } - disk = argv[0]; + disk = argv[1]; - if (strcmp(argv[1], "on") == 0) { + sesid = strtoul(disk, &endptr, 10); + if (*endptr == '\0') { + endptr = strrchr(uflag, '*'); + if (endptr != NULL && *endptr == '*') { + warnx("Must specifying a SES device (-u) to use a SES " + "id# to identify a disk"); + usage(stderr, (setfault ? "fault" : "locate")); + } + isses = true; + } + + if (strcmp(argv[2], "on") == 0) { onoff = true; - } else if (strcmp(argv[1], "off") == 0) { + } else if (strcmp(argv[2], "off") == 0) { onoff = false; } else { - errx(EXIT_FAILURE, "usage: %s locate [disk] [on|off]", - getprogname()); + usage(stderr, (setfault ? "fault" : "locate")); } if (strcmp(disk, "all") == 0) { @@ -128,97 +194,367 @@ locate(int argc, char **argv) len = strlen(disk); /* Get the list of ses devices */ - if (glob("/dev/ses[0-9]*", 0, NULL, &g) == GLOB_NOMATCH) { + if (glob((uflag != NULL ? uflag : "/dev/ses[0-9]*"), 0, NULL, &g) == + GLOB_NOMATCH) { globfree(&g); errx(EXIT_FAILURE, "No SES devices found"); } + + ndisks = 0; for (i = 0; i < g.gl_pathc; i++) { /* ensure we only got numbers after ses */ if (strspn(g.gl_pathv[i] + 8, "0123456789") != - strlen(g.gl_pathv[i] + 8)) + strlen(g.gl_pathv[i] + 8)) { continue; + } if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) { - if (errno == EACCES) - err(EXIT_FAILURE, "enable to access SES device"); - break; + /* + * Don't treat non-access errors as critical if we are + * accessing all devices + */ + if (errno == EACCES && g.gl_pathc > 1) { + err(EXIT_FAILURE, "unable to access SES device"); + } + warn("unable to access SES device: %s", g.gl_pathv[i]); + continue; } - if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) + if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) { + close(fd); err(EXIT_FAILURE, "ENCIOC_GETNELM"); + } objp = calloc(nobj, sizeof(encioc_element_t)); - if (objp == NULL) + if (objp == NULL) { + close(fd); err(EXIT_FAILURE, "calloc()"); + } - if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0) + if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0) { + close(fd); err(EXIT_FAILURE, "ENCIOC_GETELMMAP"); + } + if (isses) { + if (sesid > nobj) { + close(fd); + errx(EXIT_FAILURE, + "Requested SES ID does not exist"); + } + do_led(fd, sesid, onoff, setfault); + ndisks++; + close(fd); + break; + } for (j = 0; j < nobj; j++) { memset(&objdn, 0, sizeof(objdn)); objdn.elm_idx = objp[j].elm_idx; objdn.elm_names_size = 128; objdn.elm_devnames = calloc(128, sizeof(char)); - if (objdn.elm_devnames == NULL) + if (objdn.elm_devnames == NULL) { + close(fd); err(EXIT_FAILURE, "calloc()"); + } if (ioctl(fd, ENCIOC_GETELMDEVNAMES, - (caddr_t) &objdn) <0) + (caddr_t) &objdn) <0) { continue; + } if (objdn.elm_names_len > 0) { if (all) { - do_locate(fd, objdn.elm_idx, onoff); + do_led(fd, objdn.elm_idx, + onoff, setfault); continue; } if (disk_match(objdn.elm_devnames, disk, len)) { - do_locate(fd, objdn.elm_idx, onoff); + do_led(fd, objdn.elm_idx, + onoff, setfault); + ndisks++; break; } } - } + } close(fd); } globfree(&g); + if (ndisks == 0 && all == false) { + errx(EXIT_FAILURE, "Count not find the SES id of device '%s'", + disk); + } return (EXIT_SUCCESS); } -static void -usage(FILE *out) +static int +locate(int argc, char **argv) { - int i; - fprintf(out, "Usage: %s [command] [options]\n", getprogname()); - fprintf(out, "Commands supported:\n"); - for (i = 0; i < nbcmds; i++) - fprintf(out, "\t%-15s%s\n", cmds[i].name, cmds[i].desc); + return (sesled(argc, argv, false)); +} + +static int +fault(int argc, char **argv) +{ + + return (sesled(argc, argv, true)); +} + +static int +objmap(int argc, char **argv __unused) +{ + struct sbuf *extra; + encioc_string_t stri; + encioc_elm_devnames_t e_devname; + encioc_elm_status_t e_status; + encioc_elm_desc_t e_desc; + encioc_element_t *e_ptr; + glob_t g; + int fd; + unsigned int j, nobj; + size_t i; + char str[32]; + + if (argc != 1) { + usage(stderr, "map"); + } + + /* Get the list of ses devices */ + if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) { + globfree(&g); + errx(EXIT_FAILURE, "No SES devices found"); + } + for (i = 0; i < g.gl_pathc; i++) { + /* ensure we only got numbers after ses */ + if (strspn(g.gl_pathv[i] + 8, "0123456789") != + strlen(g.gl_pathv[i] + 8)) { + continue; + } + if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) { + /* + * Don't treat non-access errors as critical if we are + * accessing all devices + */ + if (errno == EACCES && g.gl_pathc > 1) { + err(EXIT_FAILURE, "unable to access SES device"); + } + warn("unable to access SES device: %s", g.gl_pathv[i]); + continue; + } + + if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) { + close(fd); + err(EXIT_FAILURE, "ENCIOC_GETNELM"); + } + + e_ptr = calloc(nobj, sizeof(encioc_element_t)); + if (e_ptr == NULL) { + close(fd); + err(EXIT_FAILURE, "calloc()"); + } + + if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) e_ptr) < 0) { + close(fd); + err(EXIT_FAILURE, "ENCIOC_GETELMMAP"); + } + + printf("%s:\n", g.gl_pathv[i] + 5); + stri.bufsiz = sizeof(str); + stri.buf = &str[0]; + if (ioctl(fd, ENCIOC_GETENCNAME, (caddr_t) &stri) == 0) + printf("\tEnclosure Name: %s\n", stri.buf); + stri.bufsiz = sizeof(str); + stri.buf = &str[0]; + if (ioctl(fd, ENCIOC_GETENCID, (caddr_t) &stri) == 0) + printf("\tEnclosure ID: %s\n", stri.buf); + + for (j = 0; j < nobj; j++) { + /* Get the status of the element */ + memset(&e_status, 0, sizeof(e_status)); + e_status.elm_idx = e_ptr[j].elm_idx; + if (ioctl(fd, ENCIOC_GETELMSTAT, + (caddr_t) &e_status) < 0) { + close(fd); + err(EXIT_FAILURE, "ENCIOC_GETELMSTAT"); + } + /* Get the description of the element */ + memset(&e_desc, 0, sizeof(e_desc)); + e_desc.elm_idx = e_ptr[j].elm_idx; + e_desc.elm_desc_len = UINT16_MAX; + e_desc.elm_desc_str = calloc(UINT16_MAX, sizeof(char)); + if (e_desc.elm_desc_str == NULL) { + close(fd); + err(EXIT_FAILURE, "calloc()"); + } + if (ioctl(fd, ENCIOC_GETELMDESC, + (caddr_t) &e_desc) < 0) { + close(fd); + err(EXIT_FAILURE, "ENCIOC_GETELMDESC"); + } + /* Get the device name(s) of the element */ + memset(&e_devname, 0, sizeof(e_devname)); + e_devname.elm_idx = e_ptr[j].elm_idx; + e_devname.elm_names_size = 128; + e_devname.elm_devnames = calloc(128, sizeof(char)); + if (e_devname.elm_devnames == NULL) { + close(fd); + err(EXIT_FAILURE, "calloc()"); + } + if (ioctl(fd, ENCIOC_GETELMDEVNAMES, + (caddr_t) &e_devname) <0) { + /* We don't care if this fails */ + e_devname.elm_devnames[0] = '\0'; + } + printf("\tElement %u, Type: %s\n", e_ptr[j].elm_idx, + geteltnm(e_ptr[j].elm_type)); + printf("\t\tStatus: %s (0x%02x 0x%02x 0x%02x 0x%02x)\n", + scode2ascii(e_status.cstat[0]), e_status.cstat[0], + e_status.cstat[1], e_status.cstat[2], + e_status.cstat[3]); + if (e_desc.elm_desc_len > 0) { + printf("\t\tDescription: %s\n", + e_desc.elm_desc_str); + } + if (e_devname.elm_names_len > 0) { + printf("\t\tDevice Names: %s\n", + e_devname.elm_devnames); + } + extra = stat2sbuf(e_ptr[j].elm_type, e_status.cstat); + if (sbuf_len(extra) > 0) { + printf("\t\tExtra status:\n%s", + sbuf_data(extra)); + } + sbuf_delete(extra); + free(e_devname.elm_devnames); + } + close(fd); + } + globfree(&g); + + return (EXIT_SUCCESS); +} + +static int +encstatus(int argc, char **argv __unused) +{ + glob_t g; + int fd, status; + size_t i, e; + u_char estat; + + status = 0; + if (argc != 1) { + usage(stderr, "status"); + } + + /* Get the list of ses devices */ + if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) { + globfree(&g); + errx(EXIT_FAILURE, "No SES devices found"); + } + for (i = 0; i < g.gl_pathc; i++) { + /* ensure we only got numbers after ses */ + if (strspn(g.gl_pathv[i] + 8, "0123456789") != + strlen(g.gl_pathv[i] + 8)) { + continue; + } + if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) { + /* + * Don't treat non-access errors as critical if we are + * accessing all devices + */ + if (errno == EACCES && g.gl_pathc > 1) { + err(EXIT_FAILURE, "unable to access SES device"); + } + warn("unable to access SES device: %s", g.gl_pathv[i]); + continue; + } + + if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &estat) < 0) { + close(fd); + err(EXIT_FAILURE, "ENCIOC_GETENCSTAT"); + } + + printf("%s: ", g.gl_pathv[i] + 5); + e = 0; + if (estat == 0) { + if (status == 0) { + status = 1; + } + printf("OK"); + } else { + if (estat & SES_ENCSTAT_INFO) { + printf("INFO"); + e++; + } + if (estat & SES_ENCSTAT_NONCRITICAL) { + if (e) + printf(","); + printf("NONCRITICAL"); + e++; + } + if (estat & SES_ENCSTAT_CRITICAL) { + if (e) + printf(","); + printf("CRITICAL"); + e++; + status = -1; + } + if (estat & SES_ENCSTAT_UNRECOV) { + if (e) + printf(","); + printf("UNRECOV"); + e++; + status = -1; + } + } + printf("\n"); + + close(fd); + } + globfree(&g); + + if (status == 1) { + return (EXIT_SUCCESS); + } else { + return (EXIT_FAILURE); + } } int main(int argc, char **argv) { - int i; + int i, ch; struct command *cmd = NULL; - if (argc < 2) { + uflag = "/dev/ses[0-9]*"; + while ((ch = getopt_long(argc, argv, "u:", NULL, NULL)) != -1) { + switch (ch) { + case 'u': + uflag = optarg; + break; + case '?': + default: + usage(stderr, NULL); + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { warnx("Missing command"); - usage(stderr); - return (EXIT_FAILURE); + usage(stderr, NULL); } for (i = 0; i < nbcmds; i++) { - if (strcmp(argv[1], cmds[i].name) == 0) { + if (strcmp(argv[0], cmds[i].name) == 0) { cmd = &cmds[i]; break; } } if (cmd == NULL) { - warnx("unknown command %s", argv[1]); - usage(stderr); - return (EXIT_FAILURE); + warnx("unknown command %s", argv[0]); + usage(stderr, NULL); } - argc-=2; - argv+=2; - return (cmd->exec(argc, argv)); } |