FreeBSD/sys/geom/vinum/geom_vinum_drive.c
/* Save the vinum configuration back to each involved disk. */
Save the vinum configuration back to each involved disk.
Save the vinum configuration back to each involved disk .
void
gv_save_config(struct gv_softc *sc)
{
	struct g_consumer *cp;
	struct gv_drive *d;
	struct gv_hdr *vhdr, *hdr;
	struct sbuf *sb;
	struct timeval last_update;
	int error;
	KASSERT(sc != NULL, ("gv_save_config: null sc"));
	vhdr = g_malloc(GV_HDR_LEN, M_WAITOK | M_ZERO);
	vhdr->magic = GV_MAGIC;
	vhdr->config_length = GV_CFG_LEN;
	microtime(&last_update);
	sb = sbuf_new(NULL, NULL, GV_CFG_LEN, SBUF_FIXEDLEN);
	gv_format_config(sc, sb, 1, NULL);
	sbuf_finish(sb);
	LIST_FOREACH(d, &sc->drives, drive) {
		if (d->state != GV_DRIVE_UP)
			continue;
		cp = d->consumer;
		if (cp == NULL) {
			G_VINUM_DEBUG(0, "drive '%s' has no consumer!",
			    d->name);
			continue;
		}
		hdr = d->hdr;
		if (hdr == NULL) {
			G_VINUM_DEBUG(0, "drive '%s' has no header",
			    d->name);
			g_free(vhdr);
			continue;
		}
		bcopy(&last_update, &hdr->label.last_update,
		    sizeof(struct timeval));
		bcopy(&hdr->label, &vhdr->label, sizeof(struct gv_label));
		g_topology_lock();
		error = g_access(cp, 0, 1, 0);
		if (error) {
			G_VINUM_DEBUG(0, "g_access failed on "
			    "drive %s, errno %d", d->name, error);
			g_topology_unlock();
			continue;
		}
		g_topology_unlock();
		error = gv_write_header(cp, vhdr);
		if (error) {
			G_VINUM_DEBUG(0, "writing vhdr failed on drive %s, "
			    "errno %d", d->name, error);
			g_topology_lock();
			g_access(cp, 0, -1, 0);
			g_topology_unlock();
			continue;
		}
		error = g_write_data(cp, GV_CFG_OFFSET, sbuf_data(sb),
		    GV_CFG_LEN);
		if (error) {
			G_VINUM_DEBUG(0, "writing first config copy failed on "
			    "drive %s, errno %d", d->name, error);
			g_topology_lock();
			g_access(cp, 0, -1, 0);
			g_topology_unlock();
			continue;
		}
		error = g_write_data(cp, GV_CFG_OFFSET + GV_CFG_LEN,
		    sbuf_data(sb), GV_CFG_LEN);
		if (error)
			G_VINUM_DEBUG(0, "writing second config copy failed on "
			    "drive %s, errno %d", d->name, error);
		g_topology_lock();
		g_access(cp, 0, -1, 0);
		g_topology_unlock();
	}
	sbuf_delete(sb);
	g_free(vhdr);
}
void gv_save_config ( struct gv_softc * sc ) { struct g_consumer * cp ; struct gv_drive * d ; struct gv_hdr * vhdr , * hdr ; struct sbuf * sb ; struct timeval last_update ; int error ; KASSERT ( sc != NULL , ( " " ) ) ; vhdr = g_malloc ( GV_HDR_LEN , M_WAITOK | M_ZERO ) ; vhdr -> magic = GV_MAGIC ; vhdr -> config_length = GV_CFG_LEN ; microtime ( & last_update ) ; sb = sbuf_new ( NULL , NULL , GV_CFG_LEN , SBUF_FIXEDLEN ) ; gv_format_config ( sc , sb , 1 , NULL ) ; sbuf_finish ( sb ) ; LIST_FOREACH ( d , & sc -> drives , drive ) { if ( d -> state != GV_DRIVE_UP ) continue ; cp = d -> consumer ; if ( cp == NULL ) { G_VINUM_DEBUG ( 0 , " " , d -> name ) ; continue ; } hdr = d -> hdr ; if ( hdr == NULL ) { G_VINUM_DEBUG ( 0 , " " , d -> name ) ; g_free ( vhdr ) ; continue ; } bcopy ( & last_update , & hdr -> label . last_update , sizeof ( struct timeval ) ) ; bcopy ( & hdr -> label , & vhdr -> label , sizeof ( struct gv_label ) ) ; g_topology_lock ( ) ; error = g_access ( cp , 0 , 1 , 0 ) ; if ( error ) { G_VINUM_DEBUG ( 0 , " " " " , d -> name , error ) ; g_topology_unlock ( ) ; continue ; } g_topology_unlock ( ) ; error = gv_write_header ( cp , vhdr ) ; if ( error ) { G_VINUM_DEBUG ( 0 , " " " " , d -> name , error ) ; g_topology_lock ( ) ; g_access ( cp , 0 , -1 , 0 ) ; g_topology_unlock ( ) ; continue ; } error = g_write_data ( cp , GV_CFG_OFFSET , sbuf_data ( sb ) , GV_CFG_LEN ) ; if ( error ) { G_VINUM_DEBUG ( 0 , " " " " , d -> name , error ) ; g_topology_lock ( ) ; g_access ( cp , 0 , -1 , 0 ) ; g_topology_unlock ( ) ; continue ; } error = g_write_data ( cp , GV_CFG_OFFSET + GV_CFG_LEN , sbuf_data ( sb ) , GV_CFG_LEN ) ; if ( error ) G_VINUM_DEBUG ( 0 , " " " " , d -> name , error ) ; g_topology_lock ( ) ; g_access ( cp , 0 , -1 , 0 ) ; g_topology_unlock ( ) ; } sbuf_delete ( sb ) ; g_free ( vhdr ) ; }
Save the vinum configuration back to each involved disk.
Save the vinum configuration back to each involved disk .
/*
		 * We can't save the config on a drive that isn't up, but
		 * drives that were just created aren't officially up yet, so
		 * we check a special flag.
		 */ /* First config copy. */ /* Second config copy. */