From owner-freebsd-bugs@FreeBSD.ORG Tue Jun 7 17:30:09 2011 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D69F4106566B for ; Tue, 7 Jun 2011 17:30:09 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id B2B708FC1A for ; Tue, 7 Jun 2011 17:30:09 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id p57HU9Zs045590 for ; Tue, 7 Jun 2011 17:30:09 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id p57HU90l045583; Tue, 7 Jun 2011 17:30:09 GMT (envelope-from gnats) Resent-Date: Tue, 7 Jun 2011 17:30:09 GMT Resent-Message-Id: <201106071730.p57HU90l045583@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, Christopher Key Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AF746106566B for ; Tue, 7 Jun 2011 17:23:16 +0000 (UTC) (envelope-from cjk32@cam.ac.uk) Received: from chacal.cjkey.org.uk (chacal.cjkey.org.uk [88.97.163.217]) by mx1.freebsd.org (Postfix) with ESMTP id 34D8D8FC14 for ; Tue, 7 Jun 2011 17:23:15 +0000 (UTC) Received: from chacal.wzl33 (localhost [127.0.0.1]) by chacal.cjkey.org.uk (8.14.4/8.14.4) with ESMTP id p57GjFDr018047 for ; Tue, 7 Jun 2011 17:45:15 +0100 (BST) (envelope-from chris@chacal.wzl33) Received: (from chris@localhost) by chacal.wzl33 (8.14.4/8.14.4/Submit) id p57GjFUL018046; Tue, 7 Jun 2011 17:45:15 +0100 (BST) (envelope-from chris) Message-Id: <201106071645.p57GjFUL018046@chacal.wzl33> Date: Tue, 7 Jun 2011 17:45:15 +0100 (BST) From: Christopher Key To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: bin/157691: [zfs] [patch] zpool import -d broken X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Christopher Key List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Jun 2011 17:30:09 -0000 >Number: 157691 >Category: bin >Synopsis: [zfs] [patch] zpool import -d broken >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Jun 07 17:30:09 UTC 2011 >Closed-Date: >Last-Modified: >Originator: Christopher Key >Release: FreeBSD 8.2-RC3 amd64 >Organization: >Environment: System: FreeBSD chacal.wzl33 8.2-RC3 FreeBSD 8.2-RC3 #6: Mon Feb 14 00:36:21 GMT 2011 root@chacal.wzl33:/usr/obj/usr/src/sys/CHACAL amd64 >Description: zfs import -d is supposed to enumerate the contents of dir, opening and statting each item within before possible further processing. However, the way in which the path to be opened and statted is built is broken. The fundamental problem is repeated usage of, snprintf(path, sizeof (path), "%s/%s", rdsk, dp->d_name) where, rdsk == path >How-To-Repeat: Without patch: chris@chacal:~> ls -al /dev/mirror total 1 dr-xr-xr-x 2 root wheel 512 6 Jun 19:20 . dr-xr-xr-x 11 root wheel 512 6 Jun 19:20 .. crw-r----- 1 root operator 0, 108 6 Jun 19:20 gm0 crw-r----- 1 root operator 0, 112 6 Jun 19:20 gm0p1 crw-r----- 1 root operator 0, 113 6 Jun 19:20 gm0p2 crw-r----- 1 root operator 0, 114 6 Jun 19:20 gm0p3 crw-r----- 1 root operator 0, 115 6 Jun 19:20 gm0p4 crw-r----- 1 root operator 0, 116 6 Jun 19:20 gm0p5 crw-r----- 1 root operator 0, 117 6 Jun 19:20 gm0p6 crw-r----- 1 root operator 0, 143 6 Jun 19:20 gm1 crw-r----- 1 root operator 0, 189 6 Jun 19:20 gm1s1 crw-r----- 1 root operator 0, 190 6 Jun 19:20 gm1s2 crw-r----- 1 root operator 0, 191 6 Jun 19:20 gm1s3 chris@chacal:~> sudo truss zpool import -d /dev/mirror 2>&1 | grep /dev open("/dev/zfs",O_RDWR,00) = 3 (0x3) open("/dev/zero",O_RDONLY,0666) = 4 (0x4) lstat("/dev",{ mode=dr-xr-xr-x ,inode=2,size=512,blksize=4096 }) = 0 (0x0) lstat("/dev/mirror",{ mode=dr-xr-xr-x ,inode=215,size=512,blksize=4096 }) = 0 (0x0) stat("/dev/mirror/",{ mode=dr-xr-xr-x ,inode=215,size=512,blksize=4096 }) = 0 (0x0) open("/dev/mirror/",O_NONBLOCK,01) = 6 (0x6) open("/dev/mirror//gm0",O_RDONLY,00) = 7 (0x7) open("/dev/mirror//gm0/gm0p1",O_RDONLY,00) ERR#20 'Not a directory' open("/dev/mirror//gm0/gm0p1/gm0p2",O_RDONLY,00) ERR#20 'Not a directory' open("/dev/mirror//gm0/gm0p1/gm0p2/gm0p3",O_RDONLY,00) ERR#20 'Not a directory' open("/dev/mirror//gm0/gm0p1/gm0p2/gm0p3/gm0p4",O_RDONLY,00) ERR#20 'Not a directory' open("/dev/mirror//gm0/gm0p1/gm0p2/gm0p3/gm0p4/gm0p5",O_RDONLY,00) ERR#20 'Not a directory' open("/dev/mirror//gm0/gm0p1/gm0p2/gm0p3/gm0p4/gm0p5/gm0p6",O_RDONLY,00) ERR#20 'Not a directory' open("/dev/mirror//gm0/gm0p1/gm0p2/gm0p3/gm0p4/gm0p5/gm0p6/gm1",O_RDONLY,00) ERR#20 'Not a directory' open("/dev/mirror//gm0/gm0p1/gm0p2/gm0p3/gm0p4/gm0p5/gm0p6/gm1/gm1s1",O_RDONLY,00) ERR#20 'Not a directory' open("/dev/mirror//gm0/gm0p1/gm0p2/gm0p3/gm0p4/gm0p5/gm0p6/gm1/gm1s1/gm1s2",O_RDONLY,00) ERR#20 'Not a directory' open("/dev/mirror//gm0/gm0p1/gm0p2/gm0p3/gm0p4/gm0p5/gm0p6/gm1/gm1s1/gm1s2/gm1s3",O_RDONLY,00) ERR#20 'Not a directory' With patch: chris@chacal:~> ls -al /dev/mirror total 1 dr-xr-xr-x 2 root wheel 512 6 Jun 19:20 . dr-xr-xr-x 11 root wheel 512 6 Jun 19:20 .. crw-r----- 1 root operator 0, 108 6 Jun 19:20 gm0 crw-r----- 1 root operator 0, 112 6 Jun 19:20 gm0p1 crw-r----- 1 root operator 0, 113 6 Jun 19:20 gm0p2 crw-r----- 1 root operator 0, 114 6 Jun 19:20 gm0p3 crw-r----- 1 root operator 0, 115 6 Jun 19:20 gm0p4 crw-r----- 1 root operator 0, 116 6 Jun 19:20 gm0p5 crw-r----- 1 root operator 0, 117 6 Jun 19:20 gm0p6 crw-r----- 1 root operator 0, 143 6 Jun 19:20 gm1 crw-r----- 1 root operator 0, 189 6 Jun 19:20 gm1s1 crw-r----- 1 root operator 0, 190 6 Jun 19:20 gm1s2 crw-r----- 1 root operator 0, 191 6 Jun 19:20 gm1s3 chris@chacal:~> sudo truss zpool import -d /dev/mirror 2>&1 | grep /dev open("/dev/zfs",O_RDWR,00) = 3 (0x3) open("/dev/zero",O_RDONLY,0666) = 4 (0x4) lstat("/dev",{ mode=dr-xr-xr-x ,inode=2,size=512,blksize=4096 }) = 0 (0x0) lstat("/dev/mirror",{ mode=dr-xr-xr-x ,inode=215,size=512,blksize=4096 }) = 0 (0x0) stat("/dev/mirror/",{ mode=dr-xr-xr-x ,inode=215,size=512,blksize=4096 }) = 0 (0x0) open("/dev/mirror/",O_NONBLOCK,0144) = 6 (0x6) open("/dev/mirror/gm0",O_RDONLY,01760) = 7 (0x7) open("/dev/mirror/gm0p1",O_RDONLY,01756) = 7 (0x7) open("/dev/mirror/gm0p2",O_RDONLY,01756) = 7 (0x7) open("/dev/mirror/gm0p3",O_RDONLY,01756) = 7 (0x7) open("/dev/mirror/gm0p4",O_RDONLY,01756) = 7 (0x7) open("/dev/mirror/gm0p5",O_RDONLY,01756) = 7 (0x7) open("/dev/mirror/gm0p6",O_RDONLY,01756) = 7 (0x7) open("/dev/mirror/gm1",O_RDONLY,01760) = 7 (0x7) open("/dev/mirror/gm1s1",O_RDONLY,01756) = 7 (0x7) open("/dev/mirror/gm1s2",O_RDONLY,01756) = 7 (0x7) open("/dev/mirror/gm1s3",O_RDONLY,01756) = 7 (0x7) >Fix: --- zpool-import-d-patch begins here --- Index: cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c =================================================================== --- cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c (revision 218622) +++ cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c (working copy) @@ -869,7 +869,6 @@ * and toplevel GUID. */ for (i = 0; i < argc; i++) { - char *rdsk; int dfd; /* use realpath to normalize the path */ @@ -889,21 +888,11 @@ continue; } - /* - * Using raw devices instead of block devices when we're - * reading the labels skips a bunch of slow operations during - * close(2) processing, so we replace /dev/dsk with /dev/rdsk. - */ - if (strcmp(path, "/dev/dsk/") == 0) - rdsk = "/dev/rdsk/"; - else - rdsk = path; - - if ((dirp = opendir(rdsk)) == NULL) { + if ((dirp = opendir(path)) == NULL) { zfs_error_aux(hdl, strerror(errno)); (void) zfs_error_fmt(hdl, EZFS_BADPATH, dgettext(TEXT_DOMAIN, "cannot open '%s'"), - rdsk); + path); goto error; } @@ -916,8 +905,7 @@ (name[1] == 0 || (name[1] == '.' && name[2] == 0))) continue; - (void) snprintf(path, sizeof (path), "%s/%s", rdsk, - dp->d_name); + (void) strlcpy(end, name, pathleft); if ((fd = open64(path, O_RDONLY)) < 0) continue; @@ -965,8 +953,7 @@ config = NULL; continue; } - /* use the non-raw path for the config */ - (void) strlcpy(end, name, pathleft); + if (add_config(hdl, &pools, path, config) != 0) goto error; } --- zpool-import-d-patch ends here --- >Release-Note: >Audit-Trail: >Unformatted: