Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Mar 2010 13:59:48 GMT
From:      Bruce Cran <bruce@cran.org.uk>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/144905: [geom][gpart] panic in gpart_ctlreq when unplugging card reader
Message-ID:  <201003201359.o2KDxmu1076602@www.freebsd.org>
Resent-Message-ID: <201003201400.o2KE0AeI006623@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         144905
>Category:       kern
>Synopsis:       [geom][gpart] panic in gpart_ctlreq when unplugging card reader
>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:   Sat Mar 20 14:00:10 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Bruce Cran
>Release:        9.0-CURRENT
>Organization:
>Environment:
FreeBSD core.draftnet 9.0-CURRENT FreeBSD 9.0-CURRENT #0 r204965M: Wed Mar 10 19:02:41 GMT 2010     brucec@core.draftnet:/usr/obj/usr/src/head/sys/CORE  amd64
>Description:
A crash can occur if a gpart query is being run when a card reader is removed from the computer.

Using an 8GB uSD card partitioned using GPT attached to a card reader, I plugged the card reader into the computer, then the card into the reader. When I unplugged the reader, a panic with the following stack trace occurred:

g_part_ctlreq
g_run_events
g_event_procbody
fork_exit
fork_trampoline


>How-To-Repeat:
It can be reliably triggered by running the attached program in a script with 1 second between each run.
>Fix:


Patch attached with submission follows:

#include <libgeom.h>
#include <stdio.h>
#include <string.h>

int 
main(void)
{
	int		nEntries = 4;
	struct gctl_req *g = gctl_get_handle();
	gctl_ro_param(g, "class", -1, "PART");
	gctl_ro_param(g, "verb", -1, "create");
	gctl_ro_param(g, "provider", -1, "da0");
	gctl_ro_param(g, "scheme", -1, "mbr");
	const char     *err = gctl_issue(g);

	struct gmesh	mesh;
	int		i = geom_gettree(&mesh);
	if (i >= 0) {
		struct gclass  *classp;
		LIST_FOREACH(classp, &(&mesh)->lg_class, lg_class) {
			if (strcmp(classp->lg_name, "DISK") == 0 || strcmp(classp->lg_name, "MD") == 0) {
				struct ggeom   *geomp;
				LIST_FOREACH(geomp, &classp->lg_geom, lg_geom) {
					struct gprovider *providerp;
					if (strncmp(geomp->lg_name, "cd", 2) == 0)
						continue;

					LIST_FOREACH(providerp, &geomp->lg_provider, lg_provider) {
						if (providerp->lg_mediasize > 0)
							printf("GEOM provider %s"
							       " has media size %lluMB\n", providerp->lg_name, providerp->lg_mediasize / 1024 / 1024);
					}
				}
			}
		}
		geom_deletetree(&mesh);
	}
	gctl_free(g);

	return 0;
}


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003201359.o2KDxmu1076602>