svn commit: r206810 - in stable/8: etc/defaults etc/rc.d sbin
sbin/ggate/ggatec sbin/ggate/ggatel sbin/hastctl sbin/hastd
share/examples share/examples/hast share/man/man5 sys/geom/gate
Pawel Jakub Dawidek
pjd at FreeBSD.org
Sun Apr 18 21:14:50 UTC 2010
Author: pjd
Date: Sun Apr 18 21:14:49 2010
New Revision: 206810
URL: http://svn.freebsd.org/changeset/base/206810
Log:
MFC r204076,r204077,r204083,r205279:
r204076:
Please welcome HAST - Highly Avalable Storage.
HAST allows to transparently store data on two physically separated machines
connected over the TCP/IP network. HAST works in Primary-Secondary
(Master-Backup, Master-Slave) configuration, which means that only one of the
cluster nodes can be active at any given time. Only Primary node is able to
handle I/O requests to HAST-managed devices. Currently HAST is limited to two
cluster nodes in total.
HAST operates on block level - it provides disk-like devices in /dev/hast/
directory for use by file systems and/or applications. Working on block level
makes it transparent for file systems and applications. There in no difference
between using HAST-provided device and raw disk, partition, etc. All of them
are just regular GEOM providers in FreeBSD.
For more information please consult hastd(8), hastctl(8) and hast.conf(5)
manual pages, as well as http://wiki.FreeBSD.org/HAST.
Sponsored by: FreeBSD Foundation
Sponsored by: OMCnet Internet Service GmbH
Sponsored by: TransIP BV
r204077:
Remove some lines left over by accident.
r204083:
Add missing KEYWORD line.
Pointed out by: dougb
r205279 sys:
Simplify loops.
Added:
stable/8/etc/rc.d/hastd
- copied, changed from r204076, head/etc/rc.d/hastd
stable/8/sbin/hastctl/
- copied from r204076, head/sbin/hastctl/
stable/8/sbin/hastd/
- copied from r204076, head/sbin/hastd/
stable/8/share/examples/hast/
- copied from r204076, head/share/examples/hast/
Modified:
stable/8/etc/defaults/rc.conf
stable/8/etc/rc.d/Makefile
stable/8/sbin/Makefile
stable/8/sbin/ggate/ggatec/ggatec.c
stable/8/sbin/ggate/ggatel/ggatel.c
stable/8/share/examples/Makefile
stable/8/share/man/man5/rc.conf.5
stable/8/sys/geom/gate/g_gate.c
stable/8/sys/geom/gate/g_gate.h
Directory Properties:
stable/8/etc/ (props changed)
stable/8/sbin/ (props changed)
stable/8/sbin/atacontrol/ (props changed)
stable/8/sbin/bsdlabel/ (props changed)
stable/8/sbin/camcontrol/ (props changed)
stable/8/sbin/ddb/ (props changed)
stable/8/sbin/devfs/ (props changed)
stable/8/sbin/dhclient/ (props changed)
stable/8/sbin/dump/ (props changed)
stable/8/sbin/dumpfs/ (props changed)
stable/8/sbin/fsck/ (props changed)
stable/8/sbin/fsck_ffs/ (props changed)
stable/8/sbin/geom/ (props changed)
stable/8/sbin/geom/class/stripe/ (props changed)
stable/8/sbin/ggate/ (props changed)
stable/8/sbin/growfs/ (props changed)
stable/8/sbin/ifconfig/ (props changed)
stable/8/sbin/iscontrol/ (props changed)
stable/8/sbin/mdconfig/ (props changed)
stable/8/sbin/mksnap_ffs/ (props changed)
stable/8/sbin/mount/ (props changed)
stable/8/sbin/mount_cd9660/ (props changed)
stable/8/sbin/mount_msdosfs/ (props changed)
stable/8/sbin/mount_nfs/ (props changed)
stable/8/sbin/natd/ (props changed)
stable/8/sbin/newfs/ (props changed)
stable/8/sbin/restore/ (props changed)
stable/8/sbin/routed/ (props changed)
stable/8/sbin/sysctl/ (props changed)
stable/8/sbin/tunefs/ (props changed)
stable/8/sbin/umount/ (props changed)
stable/8/share/examples/ (props changed)
stable/8/share/man/man5/ (props changed)
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/dev/uath/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/etc/defaults/rc.conf
==============================================================================
--- stable/8/etc/defaults/rc.conf Sun Apr 18 20:34:46 2010 (r206809)
+++ stable/8/etc/defaults/rc.conf Sun Apr 18 21:14:49 2010 (r206810)
@@ -258,6 +258,9 @@ syslogd_flags="-s" # Flags to syslogd (
inetd_enable="NO" # Run the network daemon dispatcher (YES/NO).
inetd_program="/usr/sbin/inetd" # path to inetd, if you want a different one.
inetd_flags="-wW -C 60" # Optional flags to inetd
+hastd_enable="NO" # Run the HAST daemon (YES/NO).
+hastd_program="/sbin/hastd" # path to hastd, if you want a different one.
+hastd_flags="" # Optional flags to hastd.
#
# named. It may be possible to run named in a sandbox, man security for
# details.
Modified: stable/8/etc/rc.d/Makefile
==============================================================================
--- stable/8/etc/rc.d/Makefile Sun Apr 18 20:34:46 2010 (r206809)
+++ stable/8/etc/rc.d/Makefile Sun Apr 18 21:14:49 2010 (r206810)
@@ -12,7 +12,7 @@ FILES= DAEMON FILESYSTEMS LOGIN NETWORKI
encswap \
fsck ftp-proxy ftpd \
gbde geli geli2 gssd \
- hcsecd \
+ hastd hcsecd \
hostapd hostid hostid_save hostname \
inetd initrandom \
ip6addrctl ipfilter ipfs ipfw ipmon \
Copied and modified: stable/8/etc/rc.d/hastd (from r204076, head/etc/rc.d/hastd)
==============================================================================
--- head/etc/rc.d/hastd Thu Feb 18 23:16:19 2010 (r204076, copy source)
+++ stable/8/etc/rc.d/hastd Sun Apr 18 21:14:49 2010 (r206810)
@@ -6,6 +6,7 @@
# PROVIDE: hastd
# REQUIRE: NETWORKING syslogd
# BEFORE: DAEMON
+# KEYWORD: nojail shutdown
. /etc/rc.subr
@@ -18,10 +19,6 @@ required_files="/etc/hast.conf"
stop_precmd="hastd_stop_precmd"
required_modules="geom_gate:g_gate"
-sockfile="/var/run/syslogd.sockets"
-evalargs="rc_flags=\"\`set_socketlist\` \$rc_flags\""
-altlog_proglist="named"
-
hastd_stop_precmd()
{
${hastctl} role init all
Modified: stable/8/sbin/Makefile
==============================================================================
--- stable/8/sbin/Makefile Sun Apr 18 20:34:46 2010 (r206809)
+++ stable/8/sbin/Makefile Sun Apr 18 21:14:49 2010 (r206810)
@@ -36,6 +36,8 @@ SUBDIR= adjkerntz \
ggate \
growfs \
gvinum \
+ hastctl \
+ hastd \
ifconfig \
init \
${_ipf} \
Modified: stable/8/sbin/ggate/ggatec/ggatec.c
==============================================================================
--- stable/8/sbin/ggate/ggatec/ggatec.c Sun Apr 18 20:34:46 2010 (r206809)
+++ stable/8/sbin/ggate/ggatec/ggatec.c Sun Apr 18 21:14:49 2010 (r206810)
@@ -59,7 +59,7 @@ enum { UNSET, CREATE, DESTROY, LIST, RES
static const char *path = NULL;
static const char *host = NULL;
-static int unit = -1;
+static int unit = G_GATE_UNIT_AUTO;
static unsigned flags = 0;
static int force = 0;
static unsigned queue_size = G_GATE_QUEUE_SIZE;
Modified: stable/8/sbin/ggate/ggatel/ggatel.c
==============================================================================
--- stable/8/sbin/ggate/ggatel/ggatel.c Sun Apr 18 20:34:46 2010 (r206809)
+++ stable/8/sbin/ggate/ggatel/ggatel.c Sun Apr 18 21:14:49 2010 (r206810)
@@ -50,7 +50,7 @@
enum { UNSET, CREATE, DESTROY, LIST, RESCUE } action = UNSET;
static const char *path = NULL;
-static int unit = -1;
+static int unit = G_GATE_UNIT_AUTO;
static unsigned flags = 0;
static int force = 0;
static unsigned queue_size = G_GATE_QUEUE_SIZE;
Modified: stable/8/share/examples/Makefile
==============================================================================
--- stable/8/share/examples/Makefile Sun Apr 18 20:34:46 2010 (r206809)
+++ stable/8/share/examples/Makefile Sun Apr 18 21:14:49 2010 (r206810)
@@ -13,6 +13,7 @@ LDIRS= BSD_daemon \
drivers \
etc \
find_interface \
+ hast \
ibcs2 \
ipfw \
kld \
@@ -69,6 +70,11 @@ XFILES= BSD_daemon/FreeBSD.pfa \
find_interface/Makefile \
find_interface/README \
find_interface/find_interface.c \
+ hast/ucarp.sh \
+ hast/ucarp_down.sh \
+ hast/ucarp_up.sh \
+ hast/vip-down.sh \
+ hast/vip-up.sh \
ibcs2/README \
ibcs2/hello.uu \
ipfw/change_rules.sh \
Modified: stable/8/share/man/man5/rc.conf.5
==============================================================================
--- stable/8/share/man/man5/rc.conf.5 Sun Apr 18 20:34:46 2010 (r206809)
+++ stable/8/share/man/man5/rc.conf.5 Sun Apr 18 21:14:49 2010 (r206810)
@@ -1645,6 +1645,27 @@ is set to
.Dq Li YES ,
these are the flags to pass to
.Xr inetd 8 .
+.It Va hastd_enable
+.Pq Vt bool
+If set to
+.Dq Li YES ,
+run the
+.Xr hastd 8
+daemon.
+.It Va hastd_program
+.Pq Vt str
+Path to
+.Xr hastd 8
+(default
+.Pa /sbin/hastd ) .
+.It Va hastd_flags
+.Pq Vt str
+If
+.Va hastd_enable
+is set to
+.Dq Li YES ,
+these are the flags to pass to
+.Xr hastd 8 .
.It Va named_enable
.Pq Vt bool
If set to
Modified: stable/8/sys/geom/gate/g_gate.c
==============================================================================
--- stable/8/sys/geom/gate/g_gate.c Sun Apr 18 20:34:46 2010 (r206809)
+++ stable/8/sys/geom/gate/g_gate.c Sun Apr 18 21:14:49 2010 (r206810)
@@ -1,7 +1,11 @@
/*-
* Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd at FreeBSD.org>
+ * Copyright (c) 2009-2010 The FreeBSD Foundation
* All rights reserved.
*
+ * Portions of this software were developed by Pawel Jakub Dawidek
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -53,9 +57,14 @@ static MALLOC_DEFINE(M_GATE, "gg_data",
SYSCTL_DECL(_kern_geom);
SYSCTL_NODE(_kern_geom, OID_AUTO, gate, CTLFLAG_RW, 0, "GEOM_GATE stuff");
-static u_int g_gate_debug = 0;
-SYSCTL_UINT(_kern_geom_gate, OID_AUTO, debug, CTLFLAG_RW, &g_gate_debug, 0,
+static int g_gate_debug = 0;
+TUNABLE_INT("kern.geom.gate.debug", &g_gate_debug);
+SYSCTL_INT(_kern_geom_gate, OID_AUTO, debug, CTLFLAG_RW, &g_gate_debug, 0,
"Debug level");
+static u_int g_gate_maxunits = 256;
+TUNABLE_INT("kern.geom.gate.maxunits", &g_gate_maxunits);
+SYSCTL_UINT(_kern_geom_gate, OID_AUTO, maxunits, CTLFLAG_RDTUN,
+ &g_gate_maxunits, 0, "Maximum number of ggate devices");
struct g_class g_gate_class = {
.name = G_GATE_CLASS_NAME,
@@ -71,10 +80,9 @@ static struct cdevsw g_gate_cdevsw = {
};
-static LIST_HEAD(, g_gate_softc) g_gate_list =
- LIST_HEAD_INITIALIZER(g_gate_list);
-static struct mtx g_gate_list_mtx;
-
+static struct g_gate_softc **g_gate_units;
+static u_int g_gate_nunits;
+static struct mtx g_gate_units_lock;
static int
g_gate_destroy(struct g_gate_softc *sc, boolean_t force)
@@ -84,13 +92,13 @@ g_gate_destroy(struct g_gate_softc *sc,
struct bio *bp;
g_topology_assert();
- mtx_assert(&g_gate_list_mtx, MA_OWNED);
+ mtx_assert(&g_gate_units_lock, MA_OWNED);
pp = sc->sc_provider;
if (!force && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
- mtx_unlock(&g_gate_list_mtx);
+ mtx_unlock(&g_gate_units_lock);
return (EBUSY);
}
- mtx_unlock(&g_gate_list_mtx);
+ mtx_unlock(&g_gate_units_lock);
mtx_lock(&sc->sc_queue_mtx);
if ((sc->sc_flags & G_GATE_FLAG_DESTROY) == 0)
sc->sc_flags |= G_GATE_FLAG_DESTROY;
@@ -101,38 +109,29 @@ g_gate_destroy(struct g_gate_softc *sc,
g_orphan_provider(pp, ENXIO);
callout_drain(&sc->sc_callout);
mtx_lock(&sc->sc_queue_mtx);
- for (;;) {
- bp = bioq_first(&sc->sc_inqueue);
- if (bp != NULL) {
- bioq_remove(&sc->sc_inqueue, bp);
- sc->sc_queue_count--;
- G_GATE_LOGREQ(1, bp, "Request canceled.");
- g_io_deliver(bp, ENXIO);
- } else {
- break;
- }
+ while ((bp = bioq_first(&sc->sc_inqueue)) != NULL) {
+ bioq_remove(&sc->sc_inqueue, bp);
+ sc->sc_queue_count--;
+ G_GATE_LOGREQ(1, bp, "Request canceled.");
+ g_io_deliver(bp, ENXIO);
}
- for (;;) {
- bp = bioq_first(&sc->sc_outqueue);
- if (bp != NULL) {
- bioq_remove(&sc->sc_outqueue, bp);
- sc->sc_queue_count--;
- G_GATE_LOGREQ(1, bp, "Request canceled.");
- g_io_deliver(bp, ENXIO);
- } else {
- break;
- }
+ while ((bp = bioq_first(&sc->sc_outqueue)) != NULL) {
+ bioq_remove(&sc->sc_outqueue, bp);
+ sc->sc_queue_count--;
+ G_GATE_LOGREQ(1, bp, "Request canceled.");
+ g_io_deliver(bp, ENXIO);
}
mtx_unlock(&sc->sc_queue_mtx);
g_topology_unlock();
- mtx_lock(&g_gate_list_mtx);
+ mtx_lock(&g_gate_units_lock);
/* One reference is ours. */
sc->sc_ref--;
- while (sc->sc_ref > 0) {
- msleep(&sc->sc_ref, &g_gate_list_mtx, 0, "gg:destroy", 0);
- }
- LIST_REMOVE(sc, sc_next);
- mtx_unlock(&g_gate_list_mtx);
+ while (sc->sc_ref > 0)
+ msleep(&sc->sc_ref, &g_gate_units_lock, 0, "gg:destroy", 0);
+ g_gate_units[sc->sc_unit] = NULL;
+ KASSERT(g_gate_nunits > 0, ("negative g_gate_nunits?"));
+ g_gate_nunits--;
+ mtx_unlock(&g_gate_units_lock);
mtx_destroy(&sc->sc_queue_mtx);
g_topology_lock();
G_GATE_DEBUG(0, "Device %s destroyed.", gp->name);
@@ -196,7 +195,7 @@ g_gate_start(struct bio *bp)
if (sc->sc_queue_count > sc->sc_queue_size) {
mtx_unlock(&sc->sc_queue_mtx);
G_GATE_LOGREQ(1, bp, "Queue full, request canceled.");
- g_io_deliver(bp, EIO);
+ g_io_deliver(bp, ENOMEM);
return;
}
@@ -211,18 +210,29 @@ g_gate_start(struct bio *bp)
}
static struct g_gate_softc *
-g_gate_hold(u_int unit)
+g_gate_hold(u_int unit, const char *name)
{
- struct g_gate_softc *sc;
+ struct g_gate_softc *sc = NULL;
- mtx_lock(&g_gate_list_mtx);
- LIST_FOREACH(sc, &g_gate_list, sc_next) {
- if (sc->sc_unit == unit)
+ mtx_lock(&g_gate_units_lock);
+ if (unit >= 0 && unit < g_gate_maxunits)
+ sc = g_gate_units[unit];
+ else if (unit == G_GATE_NAME_GIVEN) {
+ KASSERT(name != NULL, ("name is NULL"));
+ for (unit = 0; unit < g_gate_maxunits; unit++) {
+ if (g_gate_units[unit] == NULL)
+ continue;
+ if (strcmp(name,
+ g_gate_units[unit]->sc_provider->name) != 0) {
+ continue;
+ }
+ sc = g_gate_units[unit];
break;
+ }
}
if (sc != NULL)
sc->sc_ref++;
- mtx_unlock(&g_gate_list_mtx);
+ mtx_unlock(&g_gate_units_lock);
return (sc);
}
@@ -231,40 +241,34 @@ g_gate_release(struct g_gate_softc *sc)
{
g_topology_assert_not();
- mtx_lock(&g_gate_list_mtx);
+ mtx_lock(&g_gate_units_lock);
sc->sc_ref--;
KASSERT(sc->sc_ref >= 0, ("Negative sc_ref for %s.", sc->sc_name));
- if (sc->sc_ref == 0 && (sc->sc_flags & G_GATE_FLAG_DESTROY) != 0) {
+ if (sc->sc_ref == 0 && (sc->sc_flags & G_GATE_FLAG_DESTROY) != 0)
wakeup(&sc->sc_ref);
- mtx_unlock(&g_gate_list_mtx);
- } else {
- mtx_unlock(&g_gate_list_mtx);
- }
+ mtx_unlock(&g_gate_units_lock);
}
static int
-g_gate_getunit(int unit)
+g_gate_getunit(int unit, int *errorp)
{
- struct g_gate_softc *sc;
- mtx_assert(&g_gate_list_mtx, MA_OWNED);
+ mtx_assert(&g_gate_units_lock, MA_OWNED);
if (unit >= 0) {
- LIST_FOREACH(sc, &g_gate_list, sc_next) {
- if (sc->sc_unit == unit)
- return (-1);
- }
+ if (unit >= g_gate_maxunits)
+ *errorp = EINVAL;
+ else if (g_gate_units[unit] == NULL)
+ return (unit);
+ else
+ *errorp = EEXIST;
} else {
- unit = 0;
-once_again:
- LIST_FOREACH(sc, &g_gate_list, sc_next) {
- if (sc->sc_unit == unit) {
- if (++unit > 666)
- return (-1);
- goto once_again;
- }
+ for (unit = 0; unit < g_gate_maxunits; unit++) {
+ if (g_gate_units[unit] == NULL)
+ return (unit);
}
+ *errorp = ENFILE;
}
- return (unit);
+ return (-1);
}
static void
@@ -276,7 +280,7 @@ g_gate_guard(void *arg)
sc = arg;
binuptime(&curtime);
- g_gate_hold(sc->sc_unit);
+ g_gate_hold(sc->sc_unit, NULL);
mtx_lock(&sc->sc_queue_mtx);
TAILQ_FOREACH_SAFE(bp, &sc->sc_inqueue.queue, bio_queue, bp2) {
if (curtime.sec - bp->bio_t0.sec < 5)
@@ -311,7 +315,7 @@ g_gate_dumpconf(struct sbuf *sb, const c
sc = gp->softc;
if (sc == NULL || pp != NULL || cp != NULL)
return;
- g_gate_hold(sc->sc_unit);
+ g_gate_hold(sc->sc_unit, NULL);
if ((sc->sc_flags & G_GATE_FLAG_READONLY) != 0) {
sbuf_printf(sb, "%s<access>%s</access>\n", indent, "read-only");
} else if ((sc->sc_flags & G_GATE_FLAG_WRITEONLY) != 0) {
@@ -328,6 +332,7 @@ g_gate_dumpconf(struct sbuf *sb, const c
sbuf_printf(sb, "%s<queue_size>%u</queue_size>\n", indent,
sc->sc_queue_size);
sbuf_printf(sb, "%s<ref>%u</ref>\n", indent, sc->sc_ref);
+ sbuf_printf(sb, "%s<unit>%d</unit>\n", indent, sc->sc_unit);
g_topology_unlock();
g_gate_release(sc);
g_topology_lock();
@@ -339,6 +344,8 @@ g_gate_create(struct g_gate_ctl_create *
struct g_gate_softc *sc;
struct g_geom *gp;
struct g_provider *pp;
+ char name[NAME_MAX];
+ int error = 0, unit;
if (ggio->gctl_mediasize == 0) {
G_GATE_DEBUG(1, "Invalid media size.");
@@ -357,15 +364,22 @@ g_gate_create(struct g_gate_ctl_create *
G_GATE_DEBUG(1, "Invalid flags.");
return (EINVAL);
}
- if (ggio->gctl_unit < -1) {
+ if (ggio->gctl_unit != G_GATE_UNIT_AUTO &&
+ ggio->gctl_unit != G_GATE_NAME_GIVEN &&
+ ggio->gctl_unit < 0) {
G_GATE_DEBUG(1, "Invalid unit number.");
return (EINVAL);
}
+ if (ggio->gctl_unit == G_GATE_NAME_GIVEN &&
+ ggio->gctl_name[0] == '\0') {
+ G_GATE_DEBUG(1, "No device name.");
+ return (EINVAL);
+ }
sc = malloc(sizeof(*sc), M_GATE, M_WAITOK | M_ZERO);
sc->sc_flags = (ggio->gctl_flags & G_GATE_USERFLAGS);
strlcpy(sc->sc_info, ggio->gctl_info, sizeof(sc->sc_info));
- sc->sc_seq = 0;
+ sc->sc_seq = 1;
bioq_init(&sc->sc_inqueue);
bioq_init(&sc->sc_outqueue);
mtx_init(&sc->sc_queue_mtx, "gg:queue", NULL, MTX_DEF);
@@ -375,26 +389,44 @@ g_gate_create(struct g_gate_ctl_create *
sc->sc_queue_size = G_GATE_MAX_QUEUE_SIZE;
sc->sc_timeout = ggio->gctl_timeout;
callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
- mtx_lock(&g_gate_list_mtx);
- ggio->gctl_unit = g_gate_getunit(ggio->gctl_unit);
- if (ggio->gctl_unit == -1) {
- mtx_unlock(&g_gate_list_mtx);
+ mtx_lock(&g_gate_units_lock);
+ sc->sc_unit = g_gate_getunit(ggio->gctl_unit, &error);
+ if (sc->sc_unit < 0) {
+ mtx_unlock(&g_gate_units_lock);
mtx_destroy(&sc->sc_queue_mtx);
free(sc, M_GATE);
- return (EBUSY);
+ return (error);
}
- sc->sc_unit = ggio->gctl_unit;
- LIST_INSERT_HEAD(&g_gate_list, sc, sc_next);
- mtx_unlock(&g_gate_list_mtx);
+ if (ggio->gctl_unit == G_GATE_NAME_GIVEN)
+ snprintf(name, sizeof(name), "%s", ggio->gctl_name);
+ else {
+ snprintf(name, sizeof(name), "%s%d", G_GATE_PROVIDER_NAME,
+ sc->sc_unit);
+ }
+ /* Check for name collision. */
+ for (unit = 0; unit < g_gate_maxunits; unit++) {
+ if (g_gate_units[unit] == NULL)
+ continue;
+ if (strcmp(name, g_gate_units[unit]->sc_provider->name) != 0)
+ continue;
+ mtx_unlock(&g_gate_units_lock);
+ mtx_destroy(&sc->sc_queue_mtx);
+ free(sc, M_GATE);
+ return (EEXIST);
+ }
+ g_gate_units[sc->sc_unit] = sc;
+ g_gate_nunits++;
+ mtx_unlock(&g_gate_units_lock);
+
+ ggio->gctl_unit = sc->sc_unit;
g_topology_lock();
- gp = g_new_geomf(&g_gate_class, "%s%d", G_GATE_PROVIDER_NAME,
- sc->sc_unit);
+ gp = g_new_geomf(&g_gate_class, "%s", name);
gp->start = g_gate_start;
gp->access = g_gate_access;
gp->dumpconf = g_gate_dumpconf;
gp->softc = sc;
- pp = g_new_providerf(gp, "%s%d", G_GATE_PROVIDER_NAME, sc->sc_unit);
+ pp = g_new_providerf(gp, "%s", name);
pp->mediasize = ggio->gctl_mediasize;
pp->sectorsize = ggio->gctl_sectorsize;
sc->sc_provider = pp;
@@ -446,11 +478,11 @@ g_gate_ioctl(struct cdev *dev, u_long cm
struct g_gate_ctl_destroy *ggio = (void *)addr;
G_GATE_CHECK_VERSION(ggio);
- sc = g_gate_hold(ggio->gctl_unit);
+ sc = g_gate_hold(ggio->gctl_unit, ggio->gctl_name);
if (sc == NULL)
return (ENXIO);
g_topology_lock();
- mtx_lock(&g_gate_list_mtx);
+ mtx_lock(&g_gate_units_lock);
error = g_gate_destroy(sc, ggio->gctl_force);
g_topology_unlock();
if (error != 0)
@@ -463,7 +495,7 @@ g_gate_ioctl(struct cdev *dev, u_long cm
struct bio *tbp, *lbp;
G_GATE_CHECK_VERSION(ggio);
- sc = g_gate_hold(ggio->gctl_unit);
+ sc = g_gate_hold(ggio->gctl_unit, ggio->gctl_name);
if (sc == NULL)
return (ENXIO);
lbp = NULL;
@@ -491,6 +523,8 @@ g_gate_ioctl(struct cdev *dev, u_long cm
break;
}
}
+ if (ggio->gctl_unit == G_GATE_NAME_GIVEN)
+ ggio->gctl_unit = sc->sc_unit;
mtx_unlock(&sc->sc_queue_mtx);
g_gate_release(sc);
return (error);
@@ -500,7 +534,7 @@ g_gate_ioctl(struct cdev *dev, u_long cm
struct g_gate_ctl_io *ggio = (void *)addr;
G_GATE_CHECK_VERSION(ggio);
- sc = g_gate_hold(ggio->gctl_unit);
+ sc = g_gate_hold(ggio->gctl_unit, NULL);
if (sc == NULL)
return (ENXIO);
error = 0;
@@ -561,7 +595,7 @@ start_end:
struct g_gate_ctl_io *ggio = (void *)addr;
G_GATE_CHECK_VERSION(ggio);
- sc = g_gate_hold(ggio->gctl_unit);
+ sc = g_gate_hold(ggio->gctl_unit, NULL);
if (sc == NULL)
return (ENOENT);
error = 0;
@@ -631,20 +665,24 @@ g_gate_modevent(module_t mod, int type,
switch (type) {
case MOD_LOAD:
- mtx_init(&g_gate_list_mtx, "gg_list_lock", NULL, MTX_DEF);
+ mtx_init(&g_gate_units_lock, "gg_units_lock", NULL, MTX_DEF);
+ g_gate_units = malloc(g_gate_maxunits * sizeof(g_gate_units[0]),
+ M_GATE, M_WAITOK | M_ZERO);
+ g_gate_nunits = 0;
g_gate_device();
break;
case MOD_UNLOAD:
- mtx_lock(&g_gate_list_mtx);
- if (!LIST_EMPTY(&g_gate_list)) {
- mtx_unlock(&g_gate_list_mtx);
+ mtx_lock(&g_gate_units_lock);
+ if (g_gate_nunits > 0) {
+ mtx_unlock(&g_gate_units_lock);
error = EBUSY;
break;
}
- mtx_unlock(&g_gate_list_mtx);
- mtx_destroy(&g_gate_list_mtx);
+ mtx_unlock(&g_gate_units_lock);
+ mtx_destroy(&g_gate_units_lock);
if (status_dev != 0)
destroy_dev(status_dev);
+ free(g_gate_units, M_GATE);
break;
default:
return (EOPNOTSUPP);
Modified: stable/8/sys/geom/gate/g_gate.h
==============================================================================
--- stable/8/sys/geom/gate/g_gate.h Sun Apr 18 20:34:46 2010 (r206809)
+++ stable/8/sys/geom/gate/g_gate.h Sun Apr 18 21:14:49 2010 (r206810)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd at FreeBSD.org>
+ * Copyright (c) 2004-2009 Pawel Jakub Dawidek <pjd at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,7 +41,7 @@
#define G_GATE_MOD_NAME "ggate"
#define G_GATE_CTL_NAME "ggctl"
-#define G_GATE_VERSION 1
+#define G_GATE_VERSION 2
/*
* Maximum number of request that can be stored in
@@ -54,6 +54,15 @@
#define G_GATE_FLAG_DESTROY 0x1000
#define G_GATE_USERFLAGS (G_GATE_FLAG_READONLY | G_GATE_FLAG_WRITEONLY)
+/*
+ * Pick unit number automatically in /dev/ggate<unit>.
+ */
+#define G_GATE_UNIT_AUTO (-1)
+/*
+ * Full provider name is given, so don't use ggate<unit>.
+ */
+#define G_GATE_NAME_GIVEN (-2)
+
#define G_GATE_CMD_CREATE _IOWR('m', 0, struct g_gate_ctl_create)
#define G_GATE_CMD_DESTROY _IOWR('m', 1, struct g_gate_ctl_destroy)
#define G_GATE_CMD_CANCEL _IOWR('m', 2, struct g_gate_ctl_cancel)
@@ -120,20 +129,23 @@ struct g_gate_ctl_create {
u_int gctl_flags;
u_int gctl_maxcount;
u_int gctl_timeout;
+ char gctl_name[NAME_MAX];
char gctl_info[G_GATE_INFOSIZE];
- int gctl_unit; /* out */
+ int gctl_unit; /* in/out */
};
struct g_gate_ctl_destroy {
u_int gctl_version;
int gctl_unit;
int gctl_force;
+ char gctl_name[NAME_MAX];
};
struct g_gate_ctl_cancel {
u_int gctl_version;
int gctl_unit;
uintptr_t gctl_seq;
+ char gctl_name[NAME_MAX];
};
struct g_gate_ctl_io {
More information about the svn-src-stable-8
mailing list