From eugen@k-45-pc-1.sd.rdtc.ru  Fri Feb 18 09:14:56 2011
Return-Path: <eugen@k-45-pc-1.sd.rdtc.ru>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 0965C106564A
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 18 Feb 2011 09:14:56 +0000 (UTC)
	(envelope-from eugen@k-45-pc-1.sd.rdtc.ru)
Received: from k-45-pc-1.sd.rdtc.ru (k-45-pc-1.sd.rdtc.ru [62.231.160.109])
	by mx1.freebsd.org (Postfix) with ESMTP id 609B88FC1A
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 18 Feb 2011 09:14:55 +0000 (UTC)
Received: from k-45-pc-1.sd.rdtc.ru (localhost [127.0.0.1])
	by k-45-pc-1.sd.rdtc.ru (8.14.4/8.14.4) with ESMTP id p1I8aSS7087546
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 18 Feb 2011 14:36:28 +0600 (NOVT)
	(envelope-from eugen@k-45-pc-1.sd.rdtc.ru)
Received: (from eugen@localhost)
	by k-45-pc-1.sd.rdtc.ru (8.14.4/8.14.4/Submit) id p1I8aNtY087545;
	Fri, 18 Feb 2011 14:36:23 +0600 (NOVT)
	(envelope-from eugen)
Message-Id: <201102180836.p1I8aNtY087545@k-45-pc-1.sd.rdtc.ru>
Date: Fri, 18 Feb 2011 14:36:23 +0600 (NOVT)
From: Eugene Grosbein <egrosbein@rdtc.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [gmirror] [panic] geom_mirror panices system on specific sector contents
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         154860
>Category:       kern
>Synopsis:       gmirror(8): [panic] geom_mirror panices system on specific sector contents
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    ae
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Feb 18 09:20:10 UTC 2011
>Closed-Date:    Fri May 25 04:28:08 UTC 2012
>Last-Modified:  Fri May 25 04:30:13 UTC 2012
>Originator:     Eugene Grosbein
>Release:        FreeBSD 8.2-PRERELEASE amd64
>Organization:
RDTC JSC
>Environment:
System: FreeBSD k-45-pc-1.sd.rdtc.ru 8.2-PRERELEASE FreeBSD 8.2-PRERELEASE #20: Fri Feb 18 13:08:00 NOVT 2011 root@k-45-pc-1.sd.rdtc.ru:/usr/local/obj/home/src/sys/PPPOE amd64

>Description:
	My 8.2-PRERELEASE/amd64 system has two HDDs:
	ad8 and ad14 having equal sector number:

# atacontrol cap ad8

Protocol              SATA revision 2.x
device model          WDC WD3200AAJS-00L7A0
serial number         WD-WMAV2DP22862
firmware revision     01.03E01
cylinders             16383
heads                 16
sectors/track         63
lba supported         268435455 sectors
lba48 supported       625142448 sectors

	Both disks were combined to one gmirror /dev/mirror/gm0.
	After unclean system shutdown this mirror became dirty
	and started rebuilding process from ad8 to ad14.
	Meantime, background fsck started to repair /usr/local
	and /home simultaneously (they are mounted in fstab by UFS labels).

	I/O contention was high so I decided to remove ad14 from the mirror
	to speedup fsck hoping reinsert ad14 to the mirror later:

gmirror remove gm0 ad14

	Immediately I've got kernel panic and system rebooted at once.
	Then it paniced again just at the moment of gmirror initialization.
	And again, and again... So I was forced to use loader
	to disable loading of geom_mirror.ko and go to single user mode
	mounting root from ad14.

	I've attempted to load geom_mirror.ko from single user mode
	and it panices the system at once.

	So I've saved contents of last sector of ad8 and ad14 to files.
	Last sector of ad14 contained only zero bytes. Last sector of ad8
	comes here gzipped and uuencoded.

begin 644 sector.gz
M'XL(`&8G7DT``W-W]?>ULO+U#`KR#V+X__\_"P,#0WJN`4,QIV$#D/L_8=>A
M!;_E+R\I/!>6S@B48P`3#`(,#$P,<5=;O4`<)A!1=H6%`0&8&'"`!(B>RR^8
<MW]9=E';:`-?=&/LV:,,HV!@``"LL=3X``(`````
`
end

	Then I've erased this sector with zeroes and this allowed
	me to load geom_mirror.ko without following panic
	and recreate my mirror.

>How-To-Repeat:

1. Perform unclean shutdown of system booting from gmirror to make it dirty.
2. After reboot, remove dirty component of gmirror (this paniced my system).
3. Then geom_mirror panices all the time until its signature erased from HDD.

>Fix:

	Unknown.
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-geom 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sat Feb 19 05:53:17 UTC 2011 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=154860 
Responsible-Changed-From-To: freebsd-geom->ae 
Responsible-Changed-By: ae 
Responsible-Changed-When: Sun Feb 20 16:09:46 UTC 2011 
Responsible-Changed-Why:  
Take it. 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/154860: commit references a PR
Date: Fri, 18 May 2012 09:19:21 +0000 (UTC)

 Author: ae
 Date: Fri May 18 09:19:07 2012
 New Revision: 235599
 URL: http://svn.freebsd.org/changeset/base/235599
 
 Log:
   Introduce new device flag G_MIRROR_DEVICE_FLAG_TASTING. It should
   protect geom from destroying while it is tasting.
   
   PR:		kern/154860
   Reviewed by:	pjd
   MFC after:	1 week
 
 Modified:
   head/sys/geom/mirror/g_mirror.c
   head/sys/geom/mirror/g_mirror.h
 
 Modified: head/sys/geom/mirror/g_mirror.c
 ==============================================================================
 --- head/sys/geom/mirror/g_mirror.c	Fri May 18 05:36:04 2012	(r235598)
 +++ head/sys/geom/mirror/g_mirror.c	Fri May 18 09:19:07 2012	(r235599)
 @@ -1693,6 +1693,8 @@ g_mirror_can_destroy(struct g_mirror_sof
  	gp = sc->sc_geom;
  	if (gp->softc == NULL)
  		return (1);
 +	if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_TASTING) != 0)
 +		return (0);
  	LIST_FOREACH(cp, &gp->consumer, consumer) {
  		if (g_mirror_is_busy(sc, cp))
  			return (0);
 @@ -3054,6 +3056,7 @@ g_mirror_taste(struct g_class *mp, struc
  	G_MIRROR_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name);
  	g_topology_unlock();
  	sx_xlock(&sc->sc_lock);
 +	sc->sc_flags |= G_MIRROR_DEVICE_FLAG_TASTING;
  	error = g_mirror_add_disk(sc, pp, &md);
  	if (error != 0) {
  		G_MIRROR_DEBUG(0, "Cannot add disk %s to %s (error=%d).",
 @@ -3066,6 +3069,12 @@ g_mirror_taste(struct g_class *mp, struc
  		}
  		gp = NULL;
  	}
 +	sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_TASTING;
 +	if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
 +		g_mirror_destroy(sc, G_MIRROR_DESTROY_HARD);
 +		g_topology_lock();
 +		return (NULL);
 +	}
  	sx_xunlock(&sc->sc_lock);
  	g_topology_lock();
  	return (gp);
 
 Modified: head/sys/geom/mirror/g_mirror.h
 ==============================================================================
 --- head/sys/geom/mirror/g_mirror.h	Fri May 18 05:36:04 2012	(r235598)
 +++ head/sys/geom/mirror/g_mirror.h	Fri May 18 09:19:07 2012	(r235599)
 @@ -157,6 +157,7 @@ struct g_mirror_event {
  #define	G_MIRROR_DEVICE_FLAG_DESTROY	0x0100000000000000ULL
  #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_STATE_STARTING		0
  #define	G_MIRROR_DEVICE_STATE_RUNNING		1
 _______________________________________________
 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: open->patched 
State-Changed-By: ae 
State-Changed-When: Fri May 18 09:27:38 UTC 2012 
State-Changed-Why:  
Patched in head/. Thanks! 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/154860: commit references a PR
Date: Fri, 18 May 2012 09:22:32 +0000 (UTC)

 Author: ae
 Date: Fri May 18 09:22:21 2012
 New Revision: 235600
 URL: http://svn.freebsd.org/changeset/base/235600
 
 Log:
   Prevent removing of the last active component from a mirror.
   
   PR:		kern/154860
   Reviewed by:	pjd
   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	Fri May 18 09:19:07 2012	(r235599)
 +++ head/sys/geom/mirror/g_mirror_ctl.c	Fri May 18 09:22:21 2012	(r235600)
 @@ -560,7 +560,7 @@ g_mirror_ctl_remove(struct gctl_req *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) {
 @@ -587,6 +587,7 @@ g_mirror_ctl_remove(struct gctl_req *req
  		    "first.");
  		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);
 @@ -599,6 +600,16 @@ g_mirror_ctl_remove(struct gctl_req *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 remove the last "
 +				    "ACTIVE component %s.", sc->sc_geom->name,
 +				    name);
 +				continue;
 +			}
 +		}
  		g_mirror_event_send(disk, G_MIRROR_DISK_STATE_DESTROY,
  		    G_MIRROR_EVENT_DONTWAIT);
  	}
 _______________________________________________
 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 May 25 04:27:34 UTC 2012 
State-Changed-Why:  
Merged to stable/[7-9]. Thanks! 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/154860: commit references a PR
Date: Fri, 25 May 2012 04:26:31 +0000 (UTC)

 Author: ae
 Date: Fri May 25 04:26:14 2012
 New Revision: 235968
 URL: http://svn.freebsd.org/changeset/base/235968
 
 Log:
   MFC r235599:
     Introduce new device flag G_MIRROR_DEVICE_FLAG_TASTING. It should
     protect geom from destroying while it is tasting.
   
   MFC r235600:
     Prevent removing of the last active component from a mirror.
   
   PR:		kern/154860
   Reviewed by:	pjd
   Tested by:	Eugene Grosbein
 
 Modified:
   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/sys/   (props changed)
 
 Modified: stable/9/sys/geom/mirror/g_mirror.c
 ==============================================================================
 --- stable/9/sys/geom/mirror/g_mirror.c	Fri May 25 03:46:56 2012	(r235967)
 +++ stable/9/sys/geom/mirror/g_mirror.c	Fri May 25 04:26:14 2012	(r235968)
 @@ -1692,6 +1692,8 @@ g_mirror_can_destroy(struct g_mirror_sof
  	gp = sc->sc_geom;
  	if (gp->softc == NULL)
  		return (1);
 +	if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_TASTING) != 0)
 +		return (0);
  	LIST_FOREACH(cp, &gp->consumer, consumer) {
  		if (g_mirror_is_busy(sc, cp))
  			return (0);
 @@ -3053,6 +3055,7 @@ g_mirror_taste(struct g_class *mp, struc
  	G_MIRROR_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name);
  	g_topology_unlock();
  	sx_xlock(&sc->sc_lock);
 +	sc->sc_flags |= G_MIRROR_DEVICE_FLAG_TASTING;
  	error = g_mirror_add_disk(sc, pp, &md);
  	if (error != 0) {
  		G_MIRROR_DEBUG(0, "Cannot add disk %s to %s (error=%d).",
 @@ -3065,6 +3068,12 @@ g_mirror_taste(struct g_class *mp, struc
  		}
  		gp = NULL;
  	}
 +	sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_TASTING;
 +	if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
 +		g_mirror_destroy(sc, G_MIRROR_DESTROY_HARD);
 +		g_topology_lock();
 +		return (NULL);
 +	}
  	sx_xunlock(&sc->sc_lock);
  	g_topology_lock();
  	return (gp);
 
 Modified: stable/9/sys/geom/mirror/g_mirror.h
 ==============================================================================
 --- stable/9/sys/geom/mirror/g_mirror.h	Fri May 25 03:46:56 2012	(r235967)
 +++ stable/9/sys/geom/mirror/g_mirror.h	Fri May 25 04:26:14 2012	(r235968)
 @@ -157,6 +157,7 @@ struct g_mirror_event {
  #define	G_MIRROR_DEVICE_FLAG_DESTROY	0x0100000000000000ULL
  #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_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 May 25 03:46:56 2012	(r235967)
 +++ stable/9/sys/geom/mirror/g_mirror_ctl.c	Fri May 25 04:26:14 2012	(r235968)
 @@ -560,7 +560,7 @@ g_mirror_ctl_remove(struct gctl_req *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) {
 @@ -587,6 +587,7 @@ g_mirror_ctl_remove(struct gctl_req *req
  		    "first.");
  		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);
 @@ -599,6 +600,16 @@ g_mirror_ctl_remove(struct gctl_req *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 remove the last "
 +				    "ACTIVE component %s.", sc->sc_geom->name,
 +				    name);
 +				continue;
 +			}
 +		}
  		g_mirror_event_send(disk, G_MIRROR_DISK_STATE_DESTROY,
  		    G_MIRROR_EVENT_DONTWAIT);
  	}
 _______________________________________________
 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/154860: commit references a PR
Date: Fri, 25 May 2012 04:27:06 +0000 (UTC)

 Author: ae
 Date: Fri May 25 04:26:44 2012
 New Revision: 235969
 URL: http://svn.freebsd.org/changeset/base/235969
 
 Log:
   MFC r235599:
     Introduce new device flag G_MIRROR_DEVICE_FLAG_TASTING. It should
     protect geom from destroying while it is tasting.
   
   MFC r235600:
     Prevent removing of the last active component from a mirror.
   
   PR:		kern/154860
   Reviewed by:	pjd
   Tested by:	Eugene Grosbein
 
 Modified:
   stable/8/sys/geom/mirror/g_mirror.c
   stable/8/sys/geom/mirror/g_mirror.h
   stable/8/sys/geom/mirror/g_mirror_ctl.c
 Directory Properties:
   stable/8/sys/   (props changed)
 
 Modified: stable/8/sys/geom/mirror/g_mirror.c
 ==============================================================================
 --- stable/8/sys/geom/mirror/g_mirror.c	Fri May 25 04:26:14 2012	(r235968)
 +++ stable/8/sys/geom/mirror/g_mirror.c	Fri May 25 04:26:44 2012	(r235969)
 @@ -1690,6 +1690,8 @@ g_mirror_can_destroy(struct g_mirror_sof
  	gp = sc->sc_geom;
  	if (gp->softc == NULL)
  		return (1);
 +	if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_TASTING) != 0)
 +		return (0);
  	LIST_FOREACH(cp, &gp->consumer, consumer) {
  		if (g_mirror_is_busy(sc, cp))
  			return (0);
 @@ -3051,6 +3053,7 @@ g_mirror_taste(struct g_class *mp, struc
  	G_MIRROR_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name);
  	g_topology_unlock();
  	sx_xlock(&sc->sc_lock);
 +	sc->sc_flags |= G_MIRROR_DEVICE_FLAG_TASTING;
  	error = g_mirror_add_disk(sc, pp, &md);
  	if (error != 0) {
  		G_MIRROR_DEBUG(0, "Cannot add disk %s to %s (error=%d).",
 @@ -3063,6 +3066,12 @@ g_mirror_taste(struct g_class *mp, struc
  		}
  		gp = NULL;
  	}
 +	sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_TASTING;
 +	if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
 +		g_mirror_destroy(sc, G_MIRROR_DESTROY_HARD);
 +		g_topology_lock();
 +		return (NULL);
 +	}
  	sx_xunlock(&sc->sc_lock);
  	g_topology_lock();
  	return (gp);
 
 Modified: stable/8/sys/geom/mirror/g_mirror.h
 ==============================================================================
 --- stable/8/sys/geom/mirror/g_mirror.h	Fri May 25 04:26:14 2012	(r235968)
 +++ stable/8/sys/geom/mirror/g_mirror.h	Fri May 25 04:26:44 2012	(r235969)
 @@ -157,6 +157,7 @@ struct g_mirror_event {
  #define	G_MIRROR_DEVICE_FLAG_DESTROY	0x0100000000000000ULL
  #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_STATE_STARTING		0
  #define	G_MIRROR_DEVICE_STATE_RUNNING		1
 
 Modified: stable/8/sys/geom/mirror/g_mirror_ctl.c
 ==============================================================================
 --- stable/8/sys/geom/mirror/g_mirror_ctl.c	Fri May 25 04:26:14 2012	(r235968)
 +++ stable/8/sys/geom/mirror/g_mirror_ctl.c	Fri May 25 04:26:44 2012	(r235969)
 @@ -560,7 +560,7 @@ g_mirror_ctl_remove(struct gctl_req *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) {
 @@ -587,6 +587,7 @@ g_mirror_ctl_remove(struct gctl_req *req
  		    "first.");
  		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);
 @@ -599,6 +600,16 @@ g_mirror_ctl_remove(struct gctl_req *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 remove the last "
 +				    "ACTIVE component %s.", sc->sc_geom->name,
 +				    name);
 +				continue;
 +			}
 +		}
  		g_mirror_event_send(disk, G_MIRROR_DISK_STATE_DESTROY,
  		    G_MIRROR_EVENT_DONTWAIT);
  	}
 _______________________________________________
 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/154860: commit references a PR
Date: Fri, 25 May 2012 04:27:39 +0000 (UTC)

 Author: ae
 Date: Fri May 25 04:27:08 2012
 New Revision: 235970
 URL: http://svn.freebsd.org/changeset/base/235970
 
 Log:
   MFC r235599:
     Introduce new device flag G_MIRROR_DEVICE_FLAG_TASTING. It should
     protect geom from destroying while it is tasting.
   
   MFC r235600:
     Prevent removing of the last active component from a mirror.
   
   PR:		kern/154860
   Reviewed by:	pjd
   Tested by:	Eugene Grosbein
 
 Modified:
   stable/7/sys/geom/mirror/g_mirror.c
   stable/7/sys/geom/mirror/g_mirror.h
   stable/7/sys/geom/mirror/g_mirror_ctl.c
 Directory Properties:
   stable/7/sys/   (props changed)
 
 Modified: stable/7/sys/geom/mirror/g_mirror.c
 ==============================================================================
 --- stable/7/sys/geom/mirror/g_mirror.c	Fri May 25 04:26:44 2012	(r235969)
 +++ stable/7/sys/geom/mirror/g_mirror.c	Fri May 25 04:27:08 2012	(r235970)
 @@ -1690,6 +1690,8 @@ g_mirror_can_destroy(struct g_mirror_sof
  	gp = sc->sc_geom;
  	if (gp->softc == NULL)
  		return (1);
 +	if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_TASTING) != 0)
 +		return (0);
  	LIST_FOREACH(cp, &gp->consumer, consumer) {
  		if (g_mirror_is_busy(sc, cp))
  			return (0);
 @@ -3041,6 +3043,7 @@ g_mirror_taste(struct g_class *mp, struc
  	G_MIRROR_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name);
  	g_topology_unlock();
  	sx_xlock(&sc->sc_lock);
 +	sc->sc_flags |= G_MIRROR_DEVICE_FLAG_TASTING;
  	error = g_mirror_add_disk(sc, pp, &md);
  	if (error != 0) {
  		G_MIRROR_DEBUG(0, "Cannot add disk %s to %s (error=%d).",
 @@ -3053,6 +3056,12 @@ g_mirror_taste(struct g_class *mp, struc
  		}
  		gp = NULL;
  	}
 +	sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_TASTING;
 +	if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
 +		g_mirror_destroy(sc, G_MIRROR_DESTROY_HARD);
 +		g_topology_lock();
 +		return (NULL);
 +	}
  	sx_xunlock(&sc->sc_lock);
  	g_topology_lock();
  	return (gp);
 
 Modified: stable/7/sys/geom/mirror/g_mirror.h
 ==============================================================================
 --- stable/7/sys/geom/mirror/g_mirror.h	Fri May 25 04:26:44 2012	(r235969)
 +++ stable/7/sys/geom/mirror/g_mirror.h	Fri May 25 04:27:08 2012	(r235970)
 @@ -157,6 +157,7 @@ struct g_mirror_event {
  #define	G_MIRROR_DEVICE_FLAG_DESTROY	0x0100000000000000ULL
  #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_STATE_STARTING		0
  #define	G_MIRROR_DEVICE_STATE_RUNNING		1
 
 Modified: stable/7/sys/geom/mirror/g_mirror_ctl.c
 ==============================================================================
 --- stable/7/sys/geom/mirror/g_mirror_ctl.c	Fri May 25 04:26:44 2012	(r235969)
 +++ stable/7/sys/geom/mirror/g_mirror_ctl.c	Fri May 25 04:27:08 2012	(r235970)
 @@ -560,7 +560,7 @@ g_mirror_ctl_remove(struct gctl_req *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) {
 @@ -587,6 +587,7 @@ g_mirror_ctl_remove(struct gctl_req *req
  		    "first.");
  		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);
 @@ -599,6 +600,16 @@ g_mirror_ctl_remove(struct gctl_req *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 remove the last "
 +				    "ACTIVE component %s.", sc->sc_geom->name,
 +				    name);
 +				continue;
 +			}
 +		}
  		g_mirror_event_send(disk, G_MIRROR_DISK_STATE_DESTROY,
  		    G_MIRROR_EVENT_DONTWAIT);
  	}
 _______________________________________________
 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"
 
>Unformatted:
