From nobody@FreeBSD.org  Thu Dec 19 04:40:41 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1])
	(using TLSv1 with cipher ADH-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by hub.freebsd.org (Postfix) with ESMTPS id 786AFD83
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 19 Dec 2013 04:40:41 +0000 (UTC)
Received: from oldred.freebsd.org (oldred.freebsd.org [IPv6:2001:1900:2254:206a::50:4])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by mx1.freebsd.org (Postfix) with ESMTPS id 5901217C6
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 19 Dec 2013 04:40:41 +0000 (UTC)
Received: from oldred.freebsd.org ([127.0.1.6])
	by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id rBJ4ee6c092944
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 19 Dec 2013 04:40:40 GMT
	(envelope-from nobody@oldred.freebsd.org)
Received: (from nobody@localhost)
	by oldred.freebsd.org (8.14.5/8.14.5/Submit) id rBJ4eeT6092920;
	Thu, 19 Dec 2013 04:40:40 GMT
	(envelope-from nobody)
Message-Id: <201312190440.rBJ4eeT6092920@oldred.freebsd.org>
Date: Thu, 19 Dec 2013 04:40:40 GMT
From: Kurt Lidl <lidl@pix.net>
To: freebsd-gnats-submit@FreeBSD.org
Subject: gmirror panic on deactivated mirror
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         184985
>Category:       kern
>Synopsis:       gmirror panic on deactivated mirror
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ae
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Dec 19 04:50:00 UTC 2013
>Closed-Date:    Fri Jan 10 12:11:41 UTC 2014
>Last-Modified:  Fri Jan 10 12:11:41 UTC 2014
>Originator:     Kurt Lidl
>Release:        9.2-RELEASE / 10.0-RC2
>Organization:
>Environment:
FreeBSD b524-fbsd10rc2.pix.net 10.0-RC2 FreeBSD 10.0-RC2 #0 r259404: Sun Dec 15 08:18:20 UTC 2013     root@snap.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64

FreeBSD b524-fbsd9_2.pix.net 9.2-RELEASE FreeBSD 9.2-RELEASE #0 r255898: Thu Sep 26 22:50:31 UTC 2013     root@bake.isc.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64
>Description:
I have verified the following problem on both a virtual machine running 9.2-RELEASE,
as well as a virtual machine running 10.0-RC2.  (This problem was originally spotted
on a real machine, but it's been narrowed down using just virtual machines.)

The machine panics when 'gmirror status' is run after a gmirror is completely
deactivated.

The machine MUST have >1 CPU for the panic to occur.  With only a single processor on
the machine, the panic will not occur.

Panic looks like this under 10.0-RC2:
root@b524-fbsd10rc2:/var/crash # kgdb /boot/kernel/kernel vmcore.0
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...

Unread portion of the kernel message buffer:
GEOM_MIRROR: Device scratch: provider ada0p3 disconnected.
GEOM_MIRROR: Device scratch: provider mirror/scratch destroyed.
GEOM_MIRROR: Device scratch destroyed.


Fatal trap 12: page fault while in kernel mode
cpuid = 1; apic id = 01
fault virtual address	= 0x378
fault code		= supervisor read data, page not present
instruction pointer	= 0x20:0xffffffff808b78c6
stack pointer	        = 0x28:0xfffffe001ddfea10
frame pointer	        = 0x28:0xfffffe001ddfeab0
code segment		= base 0x0, limit 0xfffff, type 0x1b
			= DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags	= interrupt enabled, resume, IOPL = 0
current process		= 13 (g_event)
trap number		= 12
panic: page fault
cpuid = 1
KDB: stack backtrace:
#0 0xffffffff808e7d60 at kdb_backtrace+0x60
#1 0xffffffff808af845 at panic+0x155
#2 0xffffffff80c8e612 at trap_fatal+0x3a2
#3 0xffffffff80c8e8e9 at trap_pfault+0x2c9
#4 0xffffffff80c8e076 at trap+0x5e6
#5 0xffffffff80c75312 at calltrap+0x8
#6 0xffffffff808b7442 at _sx_xlock+0x62
#7 0xffffffff81a371bf at g_mirror_dumpconf+0x12f
#8 0xffffffff8081a35c at g_conf_specific+0x14c
#9 0xffffffff8081acd6 at g_run_events+0x166
#10 0xffffffff8088191a at fork_exit+0x9a
#11 0xffffffff80c7584e at fork_trampoline+0xe
Uptime: 33s
Dumping 78 out of 487 MB:..21%..41%..61%..82%

Reading symbols from /boot/kernel/zfs.ko.symbols...done.
Loaded symbols for /boot/kernel/zfs.ko.symbols
Reading symbols from /boot/kernel/opensolaris.ko.symbols...done.
Loaded symbols for /boot/kernel/opensolaris.ko.symbols
Reading symbols from /boot/kernel/geom_mirror.ko.symbols...done.
Loaded symbols for /boot/kernel/geom_mirror.ko.symbols
#0  doadump (textdump=<value optimized out>) at pcpu.h:219
219	pcpu.h: No such file or directory.
	in pcpu.h
(kgdb) bt
#0  doadump (textdump=<value optimized out>) at pcpu.h:219
#1  0xffffffff808af4c0 in kern_reboot (howto=260)
    at /usr/src/sys/kern/kern_shutdown.c:447
#2  0xffffffff808af884 in panic (fmt=<value optimized out>)
    at /usr/src/sys/kern/kern_shutdown.c:754
#3  0xffffffff80c8e612 in trap_fatal (frame=<value optimized out>, 
    eva=<value optimized out>) at /usr/src/sys/amd64/amd64/trap.c:882
#4  0xffffffff80c8e8e9 in trap_pfault (frame=0xfffffe001ddfe960, usermode=0)
    at /usr/src/sys/amd64/amd64/trap.c:699
#5  0xffffffff80c8e076 in trap (frame=0xfffffe001ddfe960)
    at /usr/src/sys/amd64/amd64/trap.c:463
#6  0xffffffff80c75312 in calltrap ()
    at /usr/src/sys/amd64/amd64/exception.S:232
#7  0xffffffff808b78c6 in _sx_xlock_hard (sx=0xfffff80018321240, 
    tid=18446735277652013056, opts=<value optimized out>, 
    file=0x2beff0 <Address 0x2beff0 out of bounds>, line=0)
    at /usr/src/sys/kern/kern_sx.c:556
#8  0xffffffff808b7442 in _sx_xlock (sx=0x2beff0, opts=0, 
    file=<value optimized out>, line=2879472) at sx.h:152
#9  0xffffffff81a371bf in g_mirror_dumpconf (sb=0xfffff80018310540, 
    indent=0xffffffff80ea9f7d "\t", gp=<value optimized out>, 
    cp=<value optimized out>, pp=<value optimized out>)
    at /usr/src/sys/modules/geom/geom_mirror/../../../geom/mirror/g_mirror.c:320---Type <return> to continue, or q <return> to quit--- 
2
#10 0xffffffff8081a35c in g_conf_specific (sb=0xfffff80018310540, mp=0x0, 
    gp=0x0, pp=0x0, cp=0x0) at /usr/src/sys/geom/geom_dump.c:238
#11 0xffffffff8081acd6 in g_run_events () at /usr/src/sys/geom/geom_event.c:257
#12 0xffffffff8088191a in fork_exit (
    callout=0xffffffff8081c8e0 <g_event_procbody>, arg=0x0, 
    frame=0xfffffe001ddfec00) at /usr/src/sys/kern/kern_fork.c:995
#13 0xffffffff80c7584e in fork_trampoline ()
    at /usr/src/sys/amd64/amd64/exception.S:606
#14 0x0000000000000000 in ?? ()
Current language:  auto; currently minimal
(kgdb) 

>How-To-Repeat:
Assuming, an unused partition on /dev/ada0p3:

while :
do
  gmirror label -v scratch /dev/ada0p3
  newfs /dev/mirror/scratch
  mount /dev/mirror/scratch /mnt
  umount -f /mnt
  gmirror deactivate scratch /dev/ada0p3
  gmirror status scratch
done

The machine will panic on the final 'gmirror status scratch' command.
This happens 100% of the time on the first run through the loop on 9.2-RELEASE.
On 10.0-RC2, it may take two or three iterations of the loop before the panic.

>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->ae 
Responsible-Changed-By: ae 
Responsible-Changed-When: Thu Dec 19 13:53:59 UTC 2013 
Responsible-Changed-Why:  
Take it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=184985 
State-Changed-From-To: open->patched 
State-Changed-By: ae 
State-Changed-When: Thu Dec 19 22:13:30 UTC 2013 
State-Changed-Why:  
Patched in head/. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=184985 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/184985: commit references a PR
Date: Thu, 19 Dec 2013 22:13:19 +0000 (UTC)

 Author: ae
 Date: Thu Dec 19 22:13:12 2013
 New Revision: 259634
 URL: http://svnweb.freebsd.org/changeset/base/259634
 
 Log:
   Prevent users from deactivating the last component of a mirror.
   
   PR:		184985
   MFC after:	1 week
 
 Modified:
   head/sys/geom/mirror/g_mirror_ctl.c
 
 Modified: head/sys/geom/mirror/g_mirror_ctl.c
 ==============================================================================
 --- head/sys/geom/mirror/g_mirror_ctl.c	Thu Dec 19 21:35:33 2013	(r259633)
 +++ head/sys/geom/mirror/g_mirror_ctl.c	Thu Dec 19 22:13:12 2013	(r259634)
 @@ -695,7 +695,7 @@ g_mirror_ctl_deactivate(struct gctl_req 
  	const char *name;
  	char param[16];
  	int *nargs;
 -	u_int i;
 +	u_int i, active;
  
  	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
  	if (nargs == NULL) {
 @@ -716,6 +716,7 @@ g_mirror_ctl_deactivate(struct gctl_req 
  		gctl_error(req, "No such device: %s.", name);
  		return;
  	}
 +	active = g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE);
  	for (i = 1; i < (u_int)*nargs; i++) {
  		snprintf(param, sizeof(param), "arg%u", i);
  		name = gctl_get_asciiparam(req, param);
 @@ -728,6 +729,16 @@ g_mirror_ctl_deactivate(struct gctl_req 
  			gctl_error(req, "No such provider: %s.", name);
  			continue;
  		}
 +		if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) {
 +			if (active > 1)
 +				active--;
 +			else {
 +				gctl_error(req, "%s: Can't deactivate the "
 +				    "last ACTIVE component %s.",
 +				    sc->sc_geom->name, name);
 +				continue;
 +			}
 +		}
  		disk->d_flags |= G_MIRROR_DISK_FLAG_INACTIVE;
  		disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC;
  		g_mirror_update_metadata(disk);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/184985: commit references a PR
Date: Fri, 10 Jan 2014 07:48:45 +0000 (UTC)

 Author: ae
 Date: Fri Jan 10 07:48:36 2014
 New Revision: 260503
 URL: http://svnweb.freebsd.org/changeset/base/260503
 
 Log:
   MFC r259634:
     Prevent users from deactivating the last component of a mirror.
   
   MFC r259929:
     Add an ability to stop gmirror and clear its metadata in one command.
     This fixes the problem, when gmirror starts again just after stop.
   
     The problem occurs when gmirror's component has geom label with equal size.
     E.g. gpt and gptid have the same size as partition, diskid has the same
     size as entire disk. When gmirror's geom has been destroyed, glabel
     creates its providers and this initiate retaste.
   
     Now "gmirror destroy" command is available. It destroys geom and also
     erases gmirror's metadata.
   
   PR:		184985
 
 Modified:
   stable/10/sbin/geom/class/mirror/geom_mirror.c
   stable/10/sbin/geom/class/mirror/gmirror.8
   stable/10/sys/geom/mirror/g_mirror.c
   stable/10/sys/geom/mirror/g_mirror.h
   stable/10/sys/geom/mirror/g_mirror_ctl.c
 Directory Properties:
   stable/10/   (props changed)
 
 Modified: stable/10/sbin/geom/class/mirror/geom_mirror.c
 ==============================================================================
 --- stable/10/sbin/geom/class/mirror/geom_mirror.c	Fri Jan 10 07:43:40 2014	(r260502)
 +++ stable/10/sbin/geom/class/mirror/geom_mirror.c	Fri Jan 10 07:48:36 2014	(r260503)
 @@ -82,6 +82,13 @@ struct g_command class_commands[] = {
  	{ "deactivate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
  	    "[-v] name prov ..."
  	},
 +	{ "destroy", G_FLAG_VERBOSE, NULL,
 +	    {
 +		{ 'f', "force", NULL, G_TYPE_BOOL },
 +		G_OPT_SENTINEL
 +	    },
 +	    "[-fv] name ..."
 +	},
  	{ "dump", 0, mirror_main, G_NULL_OPTS,
  	    "prov ..."
  	},
 
 Modified: stable/10/sbin/geom/class/mirror/gmirror.8
 ==============================================================================
 --- stable/10/sbin/geom/class/mirror/gmirror.8	Fri Jan 10 07:43:40 2014	(r260502)
 +++ stable/10/sbin/geom/class/mirror/gmirror.8	Fri Jan 10 07:48:36 2014	(r260503)
 @@ -24,7 +24,7 @@
  .\"
  .\" $FreeBSD$
  .\"
 -.Dd November 20, 2013
 +.Dd December 27, 2013
  .Dt GMIRROR 8
  .Os
  .Sh NAME
 @@ -86,6 +86,10 @@
  .Ar name
  .Ar prov ...
  .Nm
 +.Cm destroy
 +.Op Fl fv
 +.Ar name ...
 +.Nm
  .Cm forget
  .Op Fl v
  .Ar name ...
 @@ -227,6 +231,14 @@ Activate the given component(s), which w
  .It Cm deactivate
  Mark the given component(s) as inactive, so it will not be automatically
  connected to the mirror.
 +.It Cm destroy
 +Stop the given mirror and clear metadata on all its components.
 +.Pp
 +Additional options include:
 +.Bl -tag -width ".Fl f"
 +.It Fl f
 +Stop the given mirror even if it is opened.
 +.El
  .It Cm forget
  Forget about components which are not connected.
  This command is useful when a disk has failed and cannot be reconnected, preventing the
 
 Modified: stable/10/sys/geom/mirror/g_mirror.c
 ==============================================================================
 --- stable/10/sys/geom/mirror/g_mirror.c	Fri Jan 10 07:43:40 2014	(r260502)
 +++ stable/10/sys/geom/mirror/g_mirror.c	Fri Jan 10 07:48:36 2014	(r260503)
 @@ -642,7 +642,8 @@ g_mirror_write_metadata(struct g_mirror_
  	length = cp->provider->sectorsize;
  	offset = cp->provider->mediasize - length;
  	sector = malloc((size_t)length, M_MIRROR, M_WAITOK | M_ZERO);
 -	if (md != NULL) {
 +	if (md != NULL &&
 +	    (sc->sc_flags & G_MIRROR_DEVICE_FLAG_WIPE) == 0) {
  		/*
  		 * Handle the case, when the size of parent provider reduced.
  		 */
 @@ -749,7 +750,8 @@ g_mirror_update_metadata(struct g_mirror
  	sc = disk->d_softc;
  	sx_assert(&sc->sc_lock, SX_LOCKED);
  
 -	g_mirror_fill_metadata(sc, disk, &md);
 +	if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_WIPE) == 0)
 +		g_mirror_fill_metadata(sc, disk, &md);
  	error = g_mirror_write_metadata(disk, &md);
  	if (error == 0) {
  		G_MIRROR_DEBUG(2, "Metadata on %s updated.",
 
 Modified: stable/10/sys/geom/mirror/g_mirror.h
 ==============================================================================
 --- stable/10/sys/geom/mirror/g_mirror.h	Fri Jan 10 07:43:40 2014	(r260502)
 +++ stable/10/sys/geom/mirror/g_mirror.h	Fri Jan 10 07:48:36 2014	(r260503)
 @@ -160,6 +160,7 @@ struct g_mirror_event {
  #define	G_MIRROR_DEVICE_FLAG_WAIT	0x0200000000000000ULL
  #define	G_MIRROR_DEVICE_FLAG_DESTROYING	0x0400000000000000ULL
  #define	G_MIRROR_DEVICE_FLAG_TASTING	0x0800000000000000ULL
 +#define	G_MIRROR_DEVICE_FLAG_WIPE	0x1000000000000000ULL
  
  #define	G_MIRROR_DEVICE_STATE_STARTING		0
  #define	G_MIRROR_DEVICE_STATE_RUNNING		1
 
 Modified: stable/10/sys/geom/mirror/g_mirror_ctl.c
 ==============================================================================
 --- stable/10/sys/geom/mirror/g_mirror_ctl.c	Fri Jan 10 07:43:40 2014	(r260502)
 +++ stable/10/sys/geom/mirror/g_mirror_ctl.c	Fri Jan 10 07:48:36 2014	(r260503)
 @@ -695,7 +695,7 @@ g_mirror_ctl_deactivate(struct gctl_req 
  	const char *name;
  	char param[16];
  	int *nargs;
 -	u_int i;
 +	u_int i, active;
  
  	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
  	if (nargs == NULL) {
 @@ -716,6 +716,7 @@ g_mirror_ctl_deactivate(struct gctl_req 
  		gctl_error(req, "No such device: %s.", name);
  		return;
  	}
 +	active = g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE);
  	for (i = 1; i < (u_int)*nargs; i++) {
  		snprintf(param, sizeof(param), "arg%u", i);
  		name = gctl_get_asciiparam(req, param);
 @@ -728,6 +729,16 @@ g_mirror_ctl_deactivate(struct gctl_req 
  			gctl_error(req, "No such provider: %s.", name);
  			continue;
  		}
 +		if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) {
 +			if (active > 1)
 +				active--;
 +			else {
 +				gctl_error(req, "%s: Can't deactivate the "
 +				    "last ACTIVE component %s.",
 +				    sc->sc_geom->name, name);
 +				continue;
 +			}
 +		}
  		disk->d_flags |= G_MIRROR_DISK_FLAG_INACTIVE;
  		disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC;
  		g_mirror_update_metadata(disk);
 @@ -786,7 +797,7 @@ g_mirror_ctl_forget(struct gctl_req *req
  }
  
  static void
 -g_mirror_ctl_stop(struct gctl_req *req, struct g_class *mp)
 +g_mirror_ctl_stop(struct gctl_req *req, struct g_class *mp, int wipe)
  {
  	struct g_mirror_softc *sc;
  	int *force, *nargs, error;
 @@ -827,10 +838,14 @@ g_mirror_ctl_stop(struct gctl_req *req, 
  			return;
  		}
  		g_cancel_event(sc);
 +		if (wipe)
 +			sc->sc_flags |= G_MIRROR_DEVICE_FLAG_WIPE;
  		error = g_mirror_destroy(sc, how);
  		if (error != 0) {
  			gctl_error(req, "Cannot destroy device %s (error=%d).",
  			    sc->sc_geom->name, error);
 +			if (wipe)
 +				sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_WIPE;
  			sx_xunlock(&sc->sc_lock);
  			return;
  		}
 @@ -871,7 +886,9 @@ g_mirror_config(struct gctl_req *req, st
  	else if (strcmp(verb, "forget") == 0)
  		g_mirror_ctl_forget(req, mp);
  	else if (strcmp(verb, "stop") == 0)
 -		g_mirror_ctl_stop(req, mp);
 +		g_mirror_ctl_stop(req, mp, 0);
 +	else if (strcmp(verb, "destroy") == 0)
 +		g_mirror_ctl_stop(req, mp, 1);
  	else
  		gctl_error(req, "Unknown verb.");
  	g_topology_lock();
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/184985: commit references a PR
Date: Fri, 10 Jan 2014 12:09:47 +0000 (UTC)

 Author: ae
 Date: Fri Jan 10 12:09:38 2014
 New Revision: 260507
 URL: http://svnweb.freebsd.org/changeset/base/260507
 
 Log:
   MFC r259634:
     Prevent users from deactivating the last component of a mirror.
   
   MFC r259929:
     Add an ability to stop gmirror and clear its metadata in one command.
     This fixes the problem, when gmirror starts again just after stop.
   
     The problem occurs when gmirror's component has geom label with equal size.
     E.g. gpt and gptid have the same size as partition, diskid has the same
     size as entire disk. When gmirror's geom has been destroyed, glabel
     creates its providers and this initiate retaste.
   
     Now "gmirror destroy" command is available. It destroys geom and also
     erases gmirror's metadata.
   
   PR:		184985
 
 Modified:
   stable/9/sbin/geom/class/mirror/geom_mirror.c
   stable/9/sbin/geom/class/mirror/gmirror.8
   stable/9/sys/geom/mirror/g_mirror.c
   stable/9/sys/geom/mirror/g_mirror.h
   stable/9/sys/geom/mirror/g_mirror_ctl.c
 Directory Properties:
   stable/9/sbin/geom/class/mirror/   (props changed)
   stable/9/sys/   (props changed)
 
 Modified: stable/9/sbin/geom/class/mirror/geom_mirror.c
 ==============================================================================
 --- stable/9/sbin/geom/class/mirror/geom_mirror.c	Fri Jan 10 10:39:01 2014	(r260506)
 +++ stable/9/sbin/geom/class/mirror/geom_mirror.c	Fri Jan 10 12:09:38 2014	(r260507)
 @@ -80,6 +80,13 @@ struct g_command class_commands[] = {
  	{ "deactivate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
  	    "[-v] name prov ..."
  	},
 +	{ "destroy", G_FLAG_VERBOSE, NULL,
 +	    {
 +		{ 'f', "force", NULL, G_TYPE_BOOL },
 +		G_OPT_SENTINEL
 +	    },
 +	    "[-fv] name ..."
 +	},
  	{ "dump", 0, mirror_main, G_NULL_OPTS,
  	    "prov ..."
  	},
 
 Modified: stable/9/sbin/geom/class/mirror/gmirror.8
 ==============================================================================
 --- stable/9/sbin/geom/class/mirror/gmirror.8	Fri Jan 10 10:39:01 2014	(r260506)
 +++ stable/9/sbin/geom/class/mirror/gmirror.8	Fri Jan 10 12:09:38 2014	(r260507)
 @@ -24,7 +24,7 @@
  .\"
  .\" $FreeBSD$
  .\"
 -.Dd December 8, 2009
 +.Dd December 27, 2013
  .Dt GMIRROR 8
  .Os
  .Sh NAME
 @@ -81,6 +81,10 @@
  .Ar name
  .Ar prov ...
  .Nm
 +.Cm destroy
 +.Op Fl fv
 +.Ar name ...
 +.Nm
  .Cm forget
  .Op Fl v
  .Ar name ...
 @@ -212,6 +216,14 @@ Activate the given component(s), which w
  .It Cm deactivate
  Mark the given component(s) as inactive, so it will not be automatically
  connected to the mirror.
 +.It Cm destroy
 +Stop the given mirror and clear metadata on all its components.
 +.Pp
 +Additional options include:
 +.Bl -tag -width ".Fl f"
 +.It Fl f
 +Stop the given mirror even if it is opened.
 +.El
  .It Cm forget
  Forget about components which are not connected.
  This command is useful when a disk has failed and cannot be reconnected, preventing the
 
 Modified: stable/9/sys/geom/mirror/g_mirror.c
 ==============================================================================
 --- stable/9/sys/geom/mirror/g_mirror.c	Fri Jan 10 10:39:01 2014	(r260506)
 +++ stable/9/sys/geom/mirror/g_mirror.c	Fri Jan 10 12:09:38 2014	(r260507)
 @@ -638,7 +638,8 @@ g_mirror_write_metadata(struct g_mirror_
  	length = cp->provider->sectorsize;
  	offset = cp->provider->mediasize - length;
  	sector = malloc((size_t)length, M_MIRROR, M_WAITOK | M_ZERO);
 -	if (md != NULL)
 +	if (md != NULL &&
 +	    (sc->sc_flags & G_MIRROR_DEVICE_FLAG_WIPE) == 0)
  		mirror_metadata_encode(md, sector);
  	error = g_write_data(cp, offset, sector, length);
  	free(sector, M_MIRROR);
 @@ -737,7 +738,8 @@ g_mirror_update_metadata(struct g_mirror
  	sc = disk->d_softc;
  	sx_assert(&sc->sc_lock, SX_LOCKED);
  
 -	g_mirror_fill_metadata(sc, disk, &md);
 +	if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_WIPE) == 0)
 +		g_mirror_fill_metadata(sc, disk, &md);
  	error = g_mirror_write_metadata(disk, &md);
  	if (error == 0) {
  		G_MIRROR_DEBUG(2, "Metadata on %s updated.",
 
 Modified: stable/9/sys/geom/mirror/g_mirror.h
 ==============================================================================
 --- stable/9/sys/geom/mirror/g_mirror.h	Fri Jan 10 10:39:01 2014	(r260506)
 +++ stable/9/sys/geom/mirror/g_mirror.h	Fri Jan 10 12:09:38 2014	(r260507)
 @@ -160,6 +160,7 @@ struct g_mirror_event {
  #define	G_MIRROR_DEVICE_FLAG_WAIT	0x0200000000000000ULL
  #define	G_MIRROR_DEVICE_FLAG_DESTROYING	0x0400000000000000ULL
  #define	G_MIRROR_DEVICE_FLAG_TASTING	0x0800000000000000ULL
 +#define	G_MIRROR_DEVICE_FLAG_WIPE	0x1000000000000000ULL
  
  #define	G_MIRROR_DEVICE_STATE_STARTING		0
  #define	G_MIRROR_DEVICE_STATE_RUNNING		1
 
 Modified: stable/9/sys/geom/mirror/g_mirror_ctl.c
 ==============================================================================
 --- stable/9/sys/geom/mirror/g_mirror_ctl.c	Fri Jan 10 10:39:01 2014	(r260506)
 +++ stable/9/sys/geom/mirror/g_mirror_ctl.c	Fri Jan 10 12:09:38 2014	(r260507)
 @@ -624,7 +624,7 @@ g_mirror_ctl_deactivate(struct gctl_req 
  	const char *name;
  	char param[16];
  	int *nargs;
 -	u_int i;
 +	u_int i, active;
  
  	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
  	if (nargs == NULL) {
 @@ -645,6 +645,7 @@ g_mirror_ctl_deactivate(struct gctl_req 
  		gctl_error(req, "No such device: %s.", name);
  		return;
  	}
 +	active = g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE);
  	for (i = 1; i < (u_int)*nargs; i++) {
  		snprintf(param, sizeof(param), "arg%u", i);
  		name = gctl_get_asciiparam(req, param);
 @@ -657,6 +658,16 @@ g_mirror_ctl_deactivate(struct gctl_req 
  			gctl_error(req, "No such provider: %s.", name);
  			continue;
  		}
 +		if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) {
 +			if (active > 1)
 +				active--;
 +			else {
 +				gctl_error(req, "%s: Can't deactivate the "
 +				    "last ACTIVE component %s.",
 +				    sc->sc_geom->name, name);
 +				continue;
 +			}
 +		}
  		disk->d_flags |= G_MIRROR_DISK_FLAG_INACTIVE;
  		disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC;
  		g_mirror_update_metadata(disk);
 @@ -715,7 +726,7 @@ g_mirror_ctl_forget(struct gctl_req *req
  }
  
  static void
 -g_mirror_ctl_stop(struct gctl_req *req, struct g_class *mp)
 +g_mirror_ctl_stop(struct gctl_req *req, struct g_class *mp, int wipe)
  {
  	struct g_mirror_softc *sc;
  	int *force, *nargs, error;
 @@ -756,10 +767,14 @@ g_mirror_ctl_stop(struct gctl_req *req, 
  			return;
  		}
  		g_cancel_event(sc);
 +		if (wipe)
 +			sc->sc_flags |= G_MIRROR_DEVICE_FLAG_WIPE;
  		error = g_mirror_destroy(sc, how);
  		if (error != 0) {
  			gctl_error(req, "Cannot destroy device %s (error=%d).",
  			    sc->sc_geom->name, error);
 +			if (wipe)
 +				sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_WIPE;
  			sx_xunlock(&sc->sc_lock);
  			return;
  		}
 @@ -798,7 +813,9 @@ g_mirror_config(struct gctl_req *req, st
  	else if (strcmp(verb, "forget") == 0)
  		g_mirror_ctl_forget(req, mp);
  	else if (strcmp(verb, "stop") == 0)
 -		g_mirror_ctl_stop(req, mp);
 +		g_mirror_ctl_stop(req, mp, 0);
 +	else if (strcmp(verb, "destroy") == 0)
 +		g_mirror_ctl_stop(req, mp, 1);
  	else
  		gctl_error(req, "Unknown verb.");
  	g_topology_lock();
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: ae 
State-Changed-When: Fri Jan 10 12:11:12 UTC 2014 
State-Changed-Why:  
Merged to stable/9 and stable/10. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=184985 
>Unformatted:
