Re: TIMEOUT_INITIALIZER() for src/sys/dev.c to avoid timeout_initialized()
On Mon, Dec 09, 2013 at 01:55:53PM +1000, David Gwynne wrote: this is a demonstration of using TIMEOUT_INITIALIZED(). because we know the timeout is always set up correctly, we dont have to test for it all over the place. [a bit of snipping...] - if (timeout_initialized(rnd_timeout)) - nanotime(ts); + nanotime(ts); I'm not sure you can do this; check revision 1.132 of this file: be more careful with nanotime() calls in early entropy storage, since at least sparc may not have the clock mapped (found by miod). while here, protect some more timeout_*() calls with timeout_initialized() Which reversed a diff that did much of what you're doing here. So calling nanotime without knowing that your clocks are fully wired up appears to be a possibility (or at least was, at one point).
timeout_pending is not the best
timeout_pending followed by timeot_del is pointless, as timeout_del effectively does the pending check itself. now that timeout_del returns whether the timeout was actually removed, you can make decisions based on that rather than race with timeout_pending checking timeout_pending shortly after you already went timeout_del is a waste of time too. Index: arch/loongson/dev/kb3310.c === RCS file: /cvs/src/sys/arch/loongson/dev/kb3310.c,v retrieving revision 1.18 diff -u -p -r1.18 kb3310.c --- arch/loongson/dev/kb3310.c 3 Oct 2012 21:44:51 - 1.18 +++ arch/loongson/dev/kb3310.c 9 Dec 2013 10:30:36 - @@ -520,8 +520,7 @@ ykbec_bell(void *arg, u_int pitch, u_int s = spltty(); bctrl = ykbec_read(sc, REG_BEEP_CONTROL); - if (volume == 0 || timeout_pending(sc-sc_bell_tmo)) { - timeout_del(sc-sc_bell_tmo); + if (volume == 0 || timeout_del(sc-sc_bell_tmo)) { /* inline ykbec_bell_stop(arg); */ ykbec_write(sc, REG_BEEP_CONTROL, bctrl ~BEEP_ENABLE); } Index: arch/sgi/dev/iockbc.c === RCS file: /cvs/src/sys/arch/sgi/dev/iockbc.c,v retrieving revision 1.8 diff -u -p -r1.8 iockbc.c --- arch/sgi/dev/iockbc.c 10 Aug 2012 17:49:31 - 1.8 +++ arch/sgi/dev/iockbc.c 9 Dec 2013 10:30:36 - @@ -441,7 +441,7 @@ iockbcintr_internal(struct pckbc_interna uint32_t val; /* Reschedule timeout further into the idle times. */ - if (timeout_pending(t-t_poll)) + if (timeout_del(t-t_poll)) timeout_add_sec(t-t_poll, 1); /* Index: arch/sgi/dev/mkbc.c === RCS file: /cvs/src/sys/arch/sgi/dev/mkbc.c,v retrieving revision 1.12 diff -u -p -r1.12 mkbc.c --- arch/sgi/dev/mkbc.c 10 Aug 2012 17:49:31 - 1.12 +++ arch/sgi/dev/mkbc.c 9 Dec 2013 10:30:36 - @@ -322,7 +322,7 @@ mkbcintr_internal(struct pckbc_internal u_int64_t data; /* Reschedule timeout further into the idle times. */ - if (timeout_pending(t-t_poll)) + if (timeout_del(t-t_poll)) timeout_add_sec(t-t_poll, 1); /* Index: arch/sparc/dev/be.c === RCS file: /cvs/src/sys/arch/sparc/dev/be.c,v retrieving revision 1.45 diff -u -p -r1.45 be.c --- arch/sparc/dev/be.c 27 Nov 2013 08:56:31 - 1.45 +++ arch/sparc/dev/be.c 9 Dec 2013 10:30:37 - @@ -323,8 +323,7 @@ bestop(sc) int tries; sc-sc_arpcom.ac_if.if_timer = 0; - if (timeout_pending(sc-sc_tick)) - timeout_del(sc-sc_tick); + timeout_del(sc-sc_tick); tries = 32; sc-sc_br-tx_cfg = 0; Index: dev/ic/cy.c === RCS file: /cvs/src/sys/dev/ic/cy.c,v retrieving revision 1.33 diff -u -p -r1.33 cy.c --- dev/ic/cy.c 18 Nov 2010 21:15:15 - 1.33 +++ dev/ic/cy.c 9 Dec 2013 10:30:37 - @@ -348,8 +348,7 @@ cyopen(dev, flag, mode, p) cy-cy_channel_control = 0; - if (!timeout_pending(sc-sc_poll_to)) - timeout_add(sc-sc_poll_to, 1); + timeout_add(sc-sc_poll_to, 1); /* this sets parameters and raises DTR */ cyparam(tp, tp-t_termios); Index: dev/ic/pckbc.c === RCS file: /cvs/src/sys/dev/ic/pckbc.c,v retrieving revision 1.37 diff -u -p -r1.37 pckbc.c --- dev/ic/pckbc.c 24 Sep 2013 08:33:50 - 1.37 +++ dev/ic/pckbc.c 9 Dec 2013 10:30:37 - @@ -976,7 +976,7 @@ pckbcintr_internal(struct pckbc_internal int served = 0, data; /* reschedule timeout further into the idle times */ - if (timeout_pending(t-t_poll)) + if (timeout_del(t-t_poll)) timeout_add_sec(t-t_poll, 1); for(;;) { Index: dev/pci/if_txp.c === RCS file: /cvs/src/sys/dev/pci/if_txp.c,v retrieving revision 1.108 diff -u -p -r1.108 if_txp.c --- dev/pci/if_txp.c26 Nov 2013 09:50:33 - 1.108 +++ dev/pci/if_txp.c9 Dec 2013 10:30:37 - @@ -1250,8 +1250,7 @@ txp_init(struct txp_softc *sc) ifp-if_flags |= IFF_RUNNING; ifp-if_flags = ~IFF_OACTIVE; - if (!timeout_pending(sc-sc_tick)) - timeout_add_sec(sc-sc_tick, 1); + timeout_add_sec(sc-sc_tick, 1); splx(s); } Index: dev/pci/if_vge.c === RCS file: /cvs/src/sys/dev/pci/if_vge.c,v retrieving revision 1.57 diff -u -p -r1.57 if_vge.c --- dev/pci/if_vge.c21 Aug 2013 05:21:44 - 1.57 +++ dev/pci/if_vge.c9 Dec 2013 10:30:37 - @@ -1678,8 +1678,7 @@ vge_init(struct ifnet *ifp)
Re: TIMEOUT_INITIALIZER() for src/sys/dev.c to avoid timeout_initialized()
On 9 Dec 2013, at 6:59 pm, Bret Lambert blamb...@openbsd.org wrote: On Mon, Dec 09, 2013 at 01:55:53PM +1000, David Gwynne wrote: this is a demonstration of using TIMEOUT_INITIALIZED(). because we know the timeout is always set up correctly, we dont have to test for it all over the place. [a bit of snipping...] -if (timeout_initialized(rnd_timeout)) -nanotime(ts); +nanotime(ts); I'm not sure you can do this; check revision 1.132 of this file: be more careful with nanotime() calls in early entropy storage, since at least sparc may not have the clock mapped (found by miod). while here, protect some more timeout_*() calls with timeout_initialized() Which reversed a diff that did much of what you're doing here. So calling nanotime without knowing that your clocks are fully wired up appears to be a possibility (or at least was, at one point). awesome. ill have a less mechanical look shortly. dlg
Re: TIMEOUT_INITIALIZER() for src/sys/dev.c to avoid timeout_initialized()
On 9 Dec 2013, at 10:01 pm, David Gwynne da...@gwynne.id.au wrote: On 9 Dec 2013, at 6:59 pm, Bret Lambert blamb...@openbsd.org wrote: On Mon, Dec 09, 2013 at 01:55:53PM +1000, David Gwynne wrote: this is a demonstration of using TIMEOUT_INITIALIZED(). because we know the timeout is always set up correctly, we dont have to test for it all over the place. [a bit of snipping...] - if (timeout_initialized(rnd_timeout)) - nanotime(ts); + nanotime(ts); I'm not sure you can do this; check revision 1.132 of this file: be more careful with nanotime() calls in early entropy storage, since at least sparc may not have the clock mapped (found by miod). while here, protect some more timeout_*() calls with timeout_initialized() Which reversed a diff that did much of what you're doing here. So calling nanotime without knowing that your clocks are fully wired up appears to be a possibility (or at least was, at one point). awesome. ill have a less mechanical look shortly. how about we check cold there instead? dlg
Re: TIMEOUT_INITIALIZER() for src/sys/dev.c to avoid timeout_initialized()
On Mon, Dec 09, 2013 at 10:18:06PM +1000, David Gwynne wrote: On 9 Dec 2013, at 10:01 pm, David Gwynne da...@gwynne.id.au wrote: On 9 Dec 2013, at 6:59 pm, Bret Lambert blamb...@openbsd.org wrote: On Mon, Dec 09, 2013 at 01:55:53PM +1000, David Gwynne wrote: this is a demonstration of using TIMEOUT_INITIALIZED(). because we know the timeout is always set up correctly, we dont have to test for it all over the place. [a bit of snipping...] - if (timeout_initialized(rnd_timeout)) - nanotime(ts); + nanotime(ts); I'm not sure you can do this; check revision 1.132 of this file: be more careful with nanotime() calls in early entropy storage, since at least sparc may not have the clock mapped (found by miod). while here, protect some more timeout_*() calls with timeout_initialized() Which reversed a diff that did much of what you're doing here. So calling nanotime without knowing that your clocks are fully wired up appears to be a possibility (or at least was, at one point). awesome. ill have a less mechanical look shortly. how about we check cold there instead? Seems reasonable, but I don't have a sparc machine to verify this on. dlg
Re: inteldrm diff
Thanks to Stefan Wollny, I now have a GM45-based system. It seems to work quite well. I'm still trying to figure out the (minor) screen corruption that happens in gnome, but after the latest set of changes I've not been able to make it hang in anyway. So that means the only generation of Intel graphics that jsg@ and I are still missing is the Intel 5/3400 Series chipset that goes together with the 1st generation Core i3/i5 processors. This shows up in dmesg as: pchb0 at pci0 dev 0 function 0 Intel Core Host rev 0x02 vga1 at pci0 dev 2 function 0 Intel HD Graphics rev 0x02 together with lots of Intel 3400 devices. If anybody has a laptop from that generation (x201, t410 for us thinkpad addicts) they are willing to donate, please let us know. Thanks to all involved developers and hardware donators especially Mark Kettenis, Stefan Sperling and Stefan Wollny. The problem is now really fixed by this commit: http://marc.info/?l=openbsd-cvsm=138637060322724w=2
Re: PATCH: Allow shared semaphores to be really shared
2013/12/8 Philip Guenther guent...@gmail.com: On Sat, Dec 7, 2013 at 10:35 AM, Ted Unangst t...@tedunangst.com wrote: One of the hallmarks of the original libpthread was that all data structures were opaque, and hidden via pointers. That in turn made it possible to write a binary compatible librthread. I never would have started librthread if it hadn't been for that compatibility. So I don't like turning my back on it. Exposing the size of sem_t is a *major* step. It may be time to actually make that jump. sem_t is actually an easy one to do it with, as it doesn't have the ownership issues of mutexes or spinlocks, or the lists of condvars or barriers. Those others will require more structure changes and kernel help. So what's the decision? Are there any objections still? If not, can I have a pair of okays? KDE4 really needs a decision to be made: people already had apps crashing without this diff, so I've put a dirty hack to stop KDE using of process-shared semaphores. But there could be more dragons, in other software. -- WBR, Vadim Zhukov
Re: TIMEOUT_INITIALIZER() for src/sys/dev.c to avoid timeout_initialized()
On Mon, Dec 09, 2013 at 01:55:53PM +1000, David Gwynne wrote: this is a demonstration of using TIMEOUT_INITIALIZED(). because we know the timeout is always set up correctly, we dont have to test for it all over the place. [a bit of snipping...] - if (timeout_initialized(rnd_timeout)) - nanotime(ts); + nanotime(ts); I'm not sure you can do this; check revision 1.132 of this file: be more careful with nanotime() calls in early entropy storage, since at least sparc may not have the clock mapped (found by miod). while here, protect some more timeout_*() calls with timeout_initialized() Which reversed a diff that did much of what you're doing here. So calling nanotime without knowing that your clocks are fully wired up appears to be a possibility (or at least was, at one point). Before the meme becomes this is about sparc, let's keep it simple. The initialization of the timeout is used as a flag, to allow the random subsystem to get entered via multiple paths at any and every stage of the boot sequence. It isn't about sparc, it is much bigger than that.
Re: PATCH: Allow shared semaphores to be really shared
On Mon, Dec 09, 2013 at 19:49, Vadim Zhukov wrote: So what's the decision? Are there any objections still? If not, can I have a pair of okays? KDE4 really needs a decision to be made: people already had apps crashing without this diff, so I've put a dirty hack to stop KDE using of process-shared semaphores. But there could be more dragons, in other software. If we go back to returning ENOMEM or whatever in sem_init, does that fix KDE? I don't mean to be a dick about this, but in general here's how we do things. If a feature is added and it introduces a regression, we revert. We don't dig the hole deeper by committing an even more intrusive diff. I'm not saying the diff is bad or can't be made to work, but I don't like using KDE needs this now to rush it in if there are other options. I also don't think the thing you're doing with the spinlock is something we want. I want time to get that right.
handle 1970 timestamps in tar
Since the switch to 64-bit time_t, our tar(1) can not archive files which timestamp are before 1970. Assuming these files: $ ls -l *gz -rw-r--r-- 1 miod dmg 34827 Jul 1 1904 comandr.mod.gz -rw-r--r-- 1 miod dmg 119280 Dec 3 1969 gbusa.mod.gz tar will fail to archive them: $ tar cf - *gz tar: Ustar header field is too small for gbusa.mod.gz tar: Ustar header field is too small for comandr.mod.gz Since the ustar file format stores the timestamp a width-limited octal value, which is expected to match a signed 32-bit value, it makes sense to handle the ustar timestamp as a 32-bit value (and switch to a different tar flavour by default at some point before 2038). The following diff allows me to archive these files correctly. Index: tar.c === RCS file: /cvs/src/bin/pax/tar.c,v retrieving revision 1.49 diff -u -p -r1.49 tar.c --- tar.c 21 Nov 2013 15:54:45 - 1.49 +++ tar.c 9 Dec 2013 20:04:40 - @@ -52,9 +52,11 @@ * Routines for reading, writing and header identify of various versions of tar */ +static time_t asc_time(char *, int, int); static size_t expandname(char *, size_t, char **, const char *, size_t); static u_long tar_chksm(char *, int); static char *name_split(char *, int); +static int time_oct(time_t, char *, int, int); static int ul_oct(u_long, char *, int, int); static int uqd_oct(u_quad_t, char *, int, int); #ifndef SMALL @@ -144,6 +146,43 @@ tar_trail(ARCHD *ignore, char *buf, int } /* + * asc_time() + * convert hex/octal character string into a time_t. We do not have to + * check for overflow! (the headers in all supported formats are not large + * enough to create an overflow). + * NOTE: strings passed to us are NOT TERMINATED. + * Return: + * time_t value + */ + +static time_t +asc_time(char *str, int len, int base) +{ + u_quad_t q; + + q = asc_uqd(str, len, base); + return (time_t)(int32_t)q; +} + +/* + * time_oct() + * convert a time_t to an octal string. This is actually a wrapper + * over either ul_oct(), if the time_t fits in a signed 32-bit value, + * or uqd_oct(). + * Return: + * 0 if the number fit into the string, -1 otherwise + */ + +static int +time_oct(time_t val, char *str, int len, int term) +{ + if (val == (int32_t)val) + return ul_oct((u_long)(int32_t)val, str, len, term); + else + return uqd_oct((u_quad_t)val, str, len, term); +} + +/* * ul_oct() * convert an unsigned long to an octal string. many oddball field * termination characters are used by the various versions of tar in the @@ -378,7 +417,6 @@ int tar_rd(ARCHD *arcn, char *buf) { HD_TAR *hd; - u_quad_t val; char *pt; /* @@ -409,11 +447,7 @@ tar_rd(ARCHD *arcn, char *buf) #else arcn-sb.st_size = (off_t)asc_uqd(hd-size, sizeof(hd-size), OCT); #endif - val = asc_uqd(hd-mtime, sizeof(hd-mtime), OCT); - if ((time_t)val 0 || (time_t)val != val) - arcn-sb.st_mtime = INT_MAX;/* XXX 2038 */ - else - arcn-sb.st_mtime = val; + arcn-sb.st_mtime = asc_time(hd-mtime, sizeof(hd-mtime), OCT); arcn-sb.st_ctime = arcn-sb.st_atime = arcn-sb.st_mtime; /* @@ -638,7 +672,7 @@ tar_wr(ARCHD *arcn) if (ul_oct((u_long)arcn-sb.st_mode, hd-mode, sizeof(hd-mode), 0) || ul_oct((u_long)arcn-sb.st_uid, hd-uid, sizeof(hd-uid), 0) || ul_oct((u_long)arcn-sb.st_gid, hd-gid, sizeof(hd-gid), 0) || - uqd_oct(arcn-sb.st_mtime, hd-mtime, sizeof(hd-mtime), 1)) + time_oct(arcn-sb.st_mtime, hd-mtime, sizeof(hd-mtime), 1)) goto out; /* @@ -747,7 +781,6 @@ ustar_rd(ARCHD *arcn, char *buf) int cnt = 0; dev_t devmajor; dev_t devminor; - u_quad_t val; /* * we only get proper sized buffers @@ -810,11 +843,7 @@ ustar_rd(ARCHD *arcn, char *buf) #else arcn-sb.st_size = (off_t)asc_uqd(hd-size, sizeof(hd-size), OCT); #endif - val = asc_uqd(hd-mtime, sizeof(hd-mtime), OCT); - if ((time_t)val 0 || (time_t)val != val) - arcn-sb.st_mtime = INT_MAX;/* XXX 2038 */ - else - arcn-sb.st_mtime = val; + arcn-sb.st_mtime = asc_time(hd-mtime, sizeof(hd-mtime), OCT); arcn-sb.st_ctime = arcn-sb.st_atime = arcn-sb.st_mtime; /* @@ -1094,7 +1123,7 @@ ustar_wr(ARCHD *arcn) goto out; } if (ul_oct((u_long)arcn-sb.st_mode, hd-mode, sizeof(hd-mode), 3) || - uqd_oct(arcn-sb.st_mtime, hd-mtime, sizeof(hd-mtime), 3)) + time_oct(arcn-sb.st_mtime, hd-mtime, sizeof(hd-mtime), 3)) goto out; if (!Nflag) { strncpy(hd-uname, name_uid(arcn-sb.st_uid, 0), sizeof(hd-uname));
lpd: remove printcap fc, fs, xc, xs capabilities
Bad news: That serial printer you hooked up 30 years ago, with magic numbers in a printcap file you haven't changed since, well, that configuration might stop working. This diff removes the printcap fc, fs, xc, xs capabilities from lpd. They allowed configuring a tty with magic numbers that were poked into sgtty. If you really need something like this, you can use the ms capability, which uses symbolic stty modes. There's a new description line in printcap.5, snatched from FreeBSD, which makes this a little bit clearer. ok? Index: share/man/man5/printcap.5 === RCS file: /cvs/src/share/man/man5/printcap.5,v retrieving revision 1.23 diff -u -p -r1.23 printcap.5 --- share/man/man5/printcap.5 3 Sep 2011 22:59:07 - 1.23 +++ share/man/man5/printcap.5 9 Dec 2013 19:47:19 - @@ -76,12 +76,8 @@ for a description of the file layout. call) .It cf Ta str Ta Dv NULL Ta cifplot data filter .It df Ta str Ta Dv NULL Ta tex data filter (DVI format) -.It fc Ta num Ta 0 Ta if lp is a tty, clear flag bits -.Pq Aq Pa sgtty.h .It ff Ta str Ta So Li \ef Sc Ta string to send for a form feed .It fo Ta bool Ta false Ta print a form feed when device is opened -.It fs Ta num Ta 0 Ta if lp is a tty, set flag bits -.Pq Aq Pa sgtty.h .It gf Ta str Ta Dv NULL Ta graph data filter .Pf ( Xr plot 3 format) @@ -92,7 +88,9 @@ format) .It lo Ta str Ta Pa lock Ta name of lock file .It lp Ta str Ta Pa /dev/lp Ta local printer device, or port@host for remote .It mc Ta num Ta 0 Ta maximum number of copies allowed; 0=unlimited -.It ms Ta str Ta Dv NULL Ta list of terminal modes to set or clear +.It ms Ta str Ta Dv NULL Ta if lp is a tty, a comma-separated, +.Xr stty 1 Ns -like +list describing the tty modes .It mx Ta num Ta 0 Ta max file size (in .Dv BUFSIZ blocks); 0=unlimited @@ -119,10 +117,6 @@ blocks); 0=unlimited .It tf Ta str Ta Dv NULL Ta troff data filter (cat phototypesetter) .It tr Ta str Ta Dv NULL Ta trailer string to print when queue empties .It vf Ta str Ta Dv NULL Ta raster image filter -.It xc Ta num Ta 0 Ta if lp is a tty, clear local mode bits -.Pq Xr tty 4 -.It xs Ta num Ta 0 Ta if lp is a tty, set local mode bits -.Pq Xr tty 4 .El .Pp If the local line printer driver supports indentation, the daemon Index: usr.sbin/lpr/common_source/common.c === RCS file: /cvs/src/usr.sbin/lpr/common_source/common.c,v retrieving revision 1.34 diff -u -p -r1.34 common.c --- usr.sbin/lpr/common_source/common.c 4 Mar 2012 04:05:15 - 1.34 +++ usr.sbin/lpr/common_source/common.c 9 Dec 2013 19:31:43 - @@ -66,9 +66,7 @@ long BR;/* baud rate if lp is a tty * char *CF;/* name of cifplot filter (per job) */ char *DF;/* name of tex filter (per job) */ longDU;/* daemon user-id */ -longFC;/* flags to clear if lp is a tty */ char *FF;/* form feed string */ -longFS;/* flags to set if lp is a tty */ char *GF;/* name of graph(1G) filter (per job) */ longHL;/* print header last */ char *IF;/* name of input filter (created per job) */ @@ -99,8 +97,6 @@ char *ST;/* status file name */ char *TF;/* name of troff filter (per job) */ char *TR;/* trailer string to be output when Q empties */ char *VF;/* name of vplot filter (per job) */ -longXC;/* flags to clear for local mode */ -longXS;/* flags to set for local mode */ char line[BUFSIZ]; intremote; /* true if sending files to a remote host */ Index: usr.sbin/lpr/common_source/lp.h === RCS file: /cvs/src/usr.sbin/lpr/common_source/lp.h,v retrieving revision 1.17 diff -u -p -r1.17 lp.h --- usr.sbin/lpr/common_source/lp.h 5 Dec 2012 23:20:26 - 1.17 +++ usr.sbin/lpr/common_source/lp.h 9 Dec 2013 19:31:24 - @@ -42,9 +42,7 @@ extern longBR;/* baud rate if lp is extern char*CF;/* name of cifplot filter (per job) */ extern char*DF;/* name of tex filter (per job) */ extern long DU;/* daemon user-id */ -extern long FC;/* flags to clear if lp is a tty */ extern char*FF;/* form feed string */ -extern long FS;/* flags to set if lp is a tty */ extern char*GF;/* name of graph(1G) filter (per job) */ extern long HL;/* print header last */ extern char*IF;/* name of input filter (created per job) */ @@ -75,8 +73,6 @@ extern char *ST;/* status file name */ extern char*TF;/* name of troff(1) filter (per job) */ extern char*TR;/* trailer string to be output when Q empties */ extern char*VF;
Re: dhclient support for /32 assignments
On Tue, Dec 3, 2013 at 4:15 PM, Matthew Dempsky matt...@dempsky.org wrote: The patch below extends dhclient to mimic this logic from ISC DHCP's linux script: if [ x$new_subnet_mask = x255.255.255.255 ] ; then route add -host $router dev $interface fi route add default gw $router $metric_arg dev $interface Just for the archive's benefit, I was able to track this down to this RELNOTES entry in ISC DHCP: - The dhclient-script was updated to create a host route for the default gateway if the supplied subnet mask for an IPv4 address was a /32. This allows the client to work in 'captive' network environments, where the operator does not want clients to crosstalk directly. listed under Changes since 4.0.0 (new features), which gives a bit more context for the change. I haven't found anything else interesting though, and I've given up hope of finding anything.
Re: handle 1970 timestamps in tar
On Mon, Dec 9, 2013 at 12:10 PM, Miod Vallat m...@online.fr wrote: Since the switch to 64-bit time_t, our tar(1) can not archive files which timestamp are before 1970. Assuming these files: $ ls -l *gz -rw-r--r-- 1 miod dmg 34827 Jul 1 1904 comandr.mod.gz -rw-r--r-- 1 miod dmg 119280 Dec 3 1969 gbusa.mod.gz tar will fail to archive them: $ tar cf - *gz tar: Ustar header field is too small for gbusa.mod.gz tar: Ustar header field is too small for comandr.mod.gz RATIONALE The time values are included as extended header records for those implementations needing more than the eleven octal digits allowed by the ustar format. Portable file timestamps cannot be negative. If pax encounters a file with a negative timestamp in copy or write mode, it can reject the file, substitute a non-negative timestamp, or generate a non-portable timestamp with a leading '-'. Even though some implementations can support finer file-time granularities than Since the ustar file format stores the timestamp a width-limited octal value, which is expected to match a signed 32-bit value, it makes sense to handle the ustar timestamp as a 32-bit value (and switch to a different tar flavour by default at some point before 2038). The following diff allows me to archive these files correctly. Index: tar.c === RCS file: /cvs/src/bin/pax/tar.c,v retrieving revision 1.49 diff -u -p -r1.49 tar.c --- tar.c 21 Nov 2013 15:54:45 - 1.49 +++ tar.c 9 Dec 2013 20:04:40 - @@ -52,9 +52,11 @@ * Routines for reading, writing and header identify of various versions of tar */ +static time_t asc_time(char *, int, int); static size_t expandname(char *, size_t, char **, const char *, size_t); static u_long tar_chksm(char *, int); static char *name_split(char *, int); +static int time_oct(time_t, char *, int, int); static int ul_oct(u_long, char *, int, int); static int uqd_oct(u_quad_t, char *, int, int); #ifndef SMALL @@ -144,6 +146,43 @@ tar_trail(ARCHD *ignore, char *buf, int } /* + * asc_time() + * convert hex/octal character string into a time_t. We do not have to + * check for overflow! (the headers in all supported formats are not large + * enough to create an overflow). + * NOTE: strings passed to us are NOT TERMINATED. + * Return: + * time_t value + */ + +static time_t +asc_time(char *str, int len, int base) +{ + u_quad_t q; + + q = asc_uqd(str, len, base); + return (time_t)(int32_t)q; +} + +/* + * time_oct() + * convert a time_t to an octal string. This is actually a wrapper + * over either ul_oct(), if the time_t fits in a signed 32-bit value, + * or uqd_oct(). + * Return: + * 0 if the number fit into the string, -1 otherwise + */ + +static int +time_oct(time_t val, char *str, int len, int term) +{ + if (val == (int32_t)val) + return ul_oct((u_long)(int32_t)val, str, len, term); + else + return uqd_oct((u_quad_t)val, str, len, term); +} + +/* * ul_oct() * convert an unsigned long to an octal string. many oddball field * termination characters are used by the various versions of tar in the @@ -378,7 +417,6 @@ int tar_rd(ARCHD *arcn, char *buf) { HD_TAR *hd; - u_quad_t val; char *pt; /* @@ -409,11 +447,7 @@ tar_rd(ARCHD *arcn, char *buf) #else arcn-sb.st_size = (off_t)asc_uqd(hd-size, sizeof(hd-size), OCT); #endif - val = asc_uqd(hd-mtime, sizeof(hd-mtime), OCT); - if ((time_t)val 0 || (time_t)val != val) - arcn-sb.st_mtime = INT_MAX;/* XXX 2038 */ - else - arcn-sb.st_mtime = val; + arcn-sb.st_mtime = asc_time(hd-mtime, sizeof(hd-mtime), OCT); arcn-sb.st_ctime = arcn-sb.st_atime = arcn-sb.st_mtime; /* @@ -638,7 +672,7 @@ tar_wr(ARCHD *arcn) if (ul_oct((u_long)arcn-sb.st_mode, hd-mode, sizeof(hd-mode), 0) || ul_oct((u_long)arcn-sb.st_uid, hd-uid, sizeof(hd-uid), 0) || ul_oct((u_long)arcn-sb.st_gid, hd-gid, sizeof(hd-gid), 0) || - uqd_oct(arcn-sb.st_mtime, hd-mtime, sizeof(hd-mtime), 1)) + time_oct(arcn-sb.st_mtime, hd-mtime, sizeof(hd-mtime), 1)) goto out; /* @@ -747,7 +781,6 @@ ustar_rd(ARCHD *arcn, char *buf) int cnt = 0; dev_t devmajor; dev_t devminor; - u_quad_t val; /* * we only get proper sized buffers @@ -810,11 +843,7 @@ ustar_rd(ARCHD *arcn, char *buf) #else arcn-sb.st_size = (off_t)asc_uqd(hd-size, sizeof(hd-size), OCT); #endif - val = asc_uqd(hd-mtime, sizeof(hd-mtime), OCT); - if ((time_t)val 0 || (time_t)val != val) - arcn-sb.st_mtime = INT_MAX;/* XXX 2038 */ - else -
Re: handle 1970 timestamps in tar
On Mon, Dec 9, 2013 at 12:57 PM, Philip Guenther guent...@gmail.com wrote: On Mon, Dec 9, 2013 at 12:10 PM, Miod Vallat m...@online.fr wrote: Since the switch to 64-bit time_t, our tar(1) can not archive files which timestamp are before 1970. Assuming these files: $ ls -l *gz -rw-r--r-- 1 miod dmg 34827 Jul 1 1904 comandr.mod.gz -rw-r--r-- 1 miod dmg 119280 Dec 3 1969 gbusa.mod.gz tar will fail to archive them: $ tar cf - *gz tar: Ustar header field is too small for gbusa.mod.gz tar: Ustar header field is too small for comandr.mod.gz Grr, flubbed the send. What I meant to say was that the POSIX pax RATIONALE includes this blurb: The time values are included as extended header records for those implementations needing more than the eleven octal digits allowed by the ustar format. Portable file timestamps cannot be negative. If pax encounters a file with a negative timestamp in copy or write mode, it can reject the file, substitute a non-negative timestamp, or generate a non-portable timestamp with a leading '-'. Right now it does the former, you're suggesting the middle (in a way that matches historical behavior?). Amusingly, the field is actually a 36bit field by virtue of being 12 characters wide in octal, so simply converting the 32bit twos-complement value into that won't even have the top bit of the field set, no? Oh the joys of oddly specified file formats. Still, that seems less likely to explode than the insane suggestions of adding a leading '-'. Since the ustar file format stores the timestamp a width-limited octal value, which is expected to match a signed 32-bit value, it makes sense to handle the ustar timestamp as a 32-bit value (and switch to a different tar flavour by default at some point before 2038). The good news is that pax extended records let you specify timestamps with an arbitrary number of digits, and with a decimal fraction of arbitrary precision, and it's defined to override the fixed-size field, so simply inserting those for all dates after 2^31-1 may be the best way to resolve the negative or 2^31? ambiguity. Philip
Re: 5.4 amd64 - Poor disk performance with Smart Array 6404
On Mon, Dec 09, 2013 at 07:24:19PM -0500, Adam Jensen wrote: I recently (last night) installed OpenBSD-5.4-amd64 on an HP-Proliant ML370-G4 that has a Smart Array 6404 controller card in a 64-bit, 133-MHz PCI-X slot. It has two Ultra320 SCSI channels and 192MB of RAM cache. One SCSI channel is connected to two 146GB U320 10kRPM drives which are configured as a RAID0 array. The Smart Array card presents the RAID0 as one SCSI device: /dev/sd0. [dmesg]: http://pastebin.com/Sxs801ef [pcidump]: http://pastebin.com/P5Zn1xM4 [sysctl]: http://pastebin.com/kmXeMZ02 [acpidump]: http://pastebin.com/xufZXdha acpi.headers only Disk performance is *very* bad. For example: dd if=/dev/zero of=test bs=1k count=32768 32768+0 records in 32768+0 records out 33554432 bytes transferred in 6.325 secs (5304659 bytes/sec) I tinkered with FreeBSD9.2 and CentOS6.4 on this hardware and they both transfer about 300M to 400M bytes/sec with that command. Large transfers (GB) write about 80M to 100M bytes/sec (if I remember correctly). I am preparing to recompile the system to 5.4-stable so there is an opportunity to make some tweaks to the default kernel configuration (maybe the SCSIDEBUG option) but I am very open to suggestions on how to proceed. I plan to add four more 146GB U320 10kRPM drives, place them on the second Ultra320 SCSI channel, and configure them as a RAID5 array. I intend to run OpenBSD on this machine for the foreseeable future so getting the RAID hardware configured for maximum utilization, performance, and reliability is of utmost importance. Any RAID hardware gurus willing to point me in the right direction will be much appreciated. Actually, *any* suggestions could potentially be useful. I'm rather stuck at the moment. Hmm. Googling 'openbsd ciss slow' led me to http://openbsd.7691.n7.nabble.com/ciss-4-write-very-slow-w-o-bbwc-td93173.html which led me to http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/ic/ciss.c.diff?r1=1.22r2=1.23only_with_tag=MAINf=h which induced me to create the diff below. This may not be the correct or final solution, but it would be interesting to see if it changes the performance on your machine. Ken Index: ciss.c === RCS file: /cvs/src/sys/dev/ic/ciss.c,v retrieving revision 1.68 diff -u -p -r1.68 ciss.c --- ciss.c 30 May 2013 16:15:02 - 1.68 +++ ciss.c 10 Dec 2013 00:52:51 - @@ -607,6 +607,7 @@ ciss_cmd(struct ciss_ccb *ccb, int flags int ciss_done(struct ciss_ccb *ccb) { + struct scsi_inquiry_data *inq; struct ciss_softc *sc = ccb-ccb_sc; struct scsi_xfer *xs = ccb-ccb_xs; struct ciss_cmd *cmd = ccb-ccb_cmd; @@ -635,6 +636,13 @@ ciss_done(struct ciss_ccb *ccb) if (xs) { xs-resid = 0; + if (xs-cmd-opcode == INQUIRY error != 0) { + /* Adaptor doesn't bother to claim being SCSI2+. */ + inq = (struct scsi_inquiry_data *)xs-data; + if (SCSISPC(inq-version) == 0 + (inq-flags SID_CmdQue) != 0) + inq-version |= 2; + } scsi_done(xs); }