From owner-freebsd-bugs@FreeBSD.ORG Mon Feb 20 19:10:04 2006 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id F057A16A420 for ; Mon, 20 Feb 2006 19:10:04 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 71CB443D48 for ; Mon, 20 Feb 2006 19:10:04 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k1KJA4gZ016292 for ; Mon, 20 Feb 2006 19:10:04 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k1KJA4q8016288; Mon, 20 Feb 2006 19:10:04 GMT (envelope-from gnats) Resent-Date: Mon, 20 Feb 2006 19:10:04 GMT Resent-Message-Id: <200602201910.k1KJA4q8016288@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Ken Lalonde Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DFA2716A420 for ; Mon, 20 Feb 2006 19:03:23 +0000 (GMT) (envelope-from ken@globalremit.com) Received: from dev.torus.ca (dev.torus.ca [159.18.147.50]) by mx1.FreeBSD.org (Postfix) with ESMTP id 74AC043D5D for ; Mon, 20 Feb 2006 19:03:21 +0000 (GMT) (envelope-from ken@globalremit.com) Received: from p2.torus.ca ([10.0.0.8]) by dev.torus.ca (8.13.5/8.13.5) with ESMTP id k1KJ36uE008346 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Mon, 20 Feb 2006 14:03:07 -0500 (EST) Received: from p2.torus.ca (localhost [127.0.0.1]) by p2.torus.ca (8.13.4/8.13.4) with ESMTP id k1KJ36t7000960 for ; Mon, 20 Feb 2006 14:03:06 -0500 (EST) (envelope-from ken@p2.torus.ca) Received: (from ken@localhost) by p2.torus.ca (8.13.4/8.13.4/Submit) id k1KJ35tC000959; Mon, 20 Feb 2006 14:03:05 -0500 (EST) (envelope-from ken) Message-Id: <200602201903.k1KJ35tC000959@p2.torus.ca> Date: Mon, 20 Feb 2006 14:03:05 -0500 (EST) From: Ken Lalonde To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: bin/93603: restore fails if /tmp fills [patch] X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Ken Lalonde List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Feb 2006 19:10:05 -0000 >Number: 93603 >Category: bin >Synopsis: restore fails if /tmp fills [patch] >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Feb 20 19:10:03 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Ken Lalonde >Release: FreeBSD 6.0-RELEASE i386 >Organization: Global Remittance Network >Environment: System: FreeBSD p2.torus.ca 6.0-RELEASE FreeBSD 6.0-RELEASE #1: Wed Feb 8 00:26:53 EST 2006 ken@p2.torus.ca:/usr/src/sys/i386/compile/P2 i386 >Description: restore(8) does not check for write failure while building two temp files containing directory and ownership data. If /tmp fills, the console is blasted with zillions of "file system full" errors, and restore continues on, even though directory and/or ownership data has been lost. This is particularly likely to happen when running from the live CD, which has little /tmp space. >How-To-Repeat: Boot the live CD and attempt to restore a large filesystem, or just inspect the code. >Fix: The attached patch against the 6.0 source causes restore to quit with an appropriate error message in the event of write failure. If the failure is ENOSPC, a further suggestion is displayed. Also, failure to re-open the directory data file is now fatal. --- d begins here --- --- dirs.c 2006/02/18 00:22:58 1.1 +++ dirs.c 2006/02/20 18:22:47 @@ -118,6 +118,7 @@ static void rst_seekdir(RST_DIR *, long, long); static long rst_telldir(RST_DIR *); static struct direct *searchdir(ino_t, char *); +static void tmp_write_failed(char *); /* * Extract directory contents, building up a directory structure @@ -171,13 +172,16 @@ curfile.name = ""; curfile.action = USING; if (curfile.mode == 0 || (curfile.mode & IFMT) != IFDIR) { - (void) fclose(df); + if (fclose(df)) + tmp_write_failed(dirfile); dirp = opendirfile(dirfile); - if (dirp == NULL) - fprintf(stderr, "opendirfile: %s\n", - strerror(errno)); + if (dirp == NULL) { + warn(dirfile); + done(1); + } if (mf != NULL) - (void) fclose(mf); + if (fclose(mf)) + tmp_write_failed(modefile); i = dirlookup(dot); if (i == 0) panic("Root directory is not on tape\n"); @@ -389,7 +393,8 @@ if (dirloc + dp->d_reclen > DIRBLKSIZ) { ((struct direct *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev; - (void) fwrite(dirbuf, 1, DIRBLKSIZ, df); + if (fwrite(dirbuf, DIRBLKSIZ, 1, df) != 1) + tmp_write_failed(dirfile); dirloc = 0; } memmove(dirbuf + dirloc, dp, (long)dp->d_reclen); @@ -404,7 +409,8 @@ flushent(void) { ((struct direct *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev; - (void) fwrite(dirbuf, (int)dirloc, 1, df); + if (fwrite(dirbuf, dirloc, 1, df) != 1) + tmp_write_failed(dirfile); seekpt = ftell(df); dirloc = 0; } @@ -688,7 +694,8 @@ node.flags = ctxp->file_flags; node.uid = ctxp->uid; node.gid = ctxp->gid; - (void) fwrite((char *)&node, 1, sizeof(struct modeinfo), mf); + if (fwrite((char *)&node, sizeof(struct modeinfo), 1, mf) != 1) + tmp_write_failed(modefile); return (itp); } @@ -719,4 +726,19 @@ if (dirfile[0] != '#') (void) unlink(dirfile); exit(exitcode); +} + +static void +tmp_write_failed(char *path) +{ + const char *tmpdir; + + warn("%s: write", path); + if (errno == ENOSPC) { + if ((tmpdir = getenv("TMPDIR")) == NULL || tmpdir[0] == '\0') + tmpdir = _PATH_TMP; + fprintf(stderr, "Try making space in %s, or set TMPDIR elsewhere.", + tmpdir); + } + done(1); } --- d ends here --- >Release-Note: >Audit-Trail: >Unformatted: