Date: Sun, 1 Jul 2007 21:14:19 GMT From: Sonja Milicic <smilicic@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 122670 for review Message-ID: <200707012114.l61LEJSH090199@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=122670 Change 122670 by smilicic@tanarri_marilith on 2007/07/01 21:13:45 added and tested class methods(orphan, access etc), event queue and worker thread. also fixed some bugs with accidental null pointers. Affected files ... .. //depot/projects/soc2007/smilicic_glog/sys/geom/log/glog.c#3 edit Differences ... ==== //depot/projects/soc2007/smilicic_glog/sys/geom/log/glog.c#3 (text+ko) ==== @@ -1,272 +1,567 @@ -/*- - * Copyright (c) 2007 Sonja Milicic <tanarri@geri.cc.fer.hr> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/lock.h> -#include <sys/vnode.h> -#include <sys/mutex.h> -#include <sys/sx.h> -#include <sys/bio.h> -#include <sys/sysctl.h> -#include <sys/malloc.h> -#include <sys/time.h> -#include <vm/uma.h> -#include <sys/proc.h> -#include <sys/kthread.h> -#include <geom/geom.h> -#include <sys/fcntl.h> -#include <sys/namei.h> - -#include "glog.h" -#include "glog_fileops.h" - -static MALLOC_DEFINE(M_GLOG, "glog", "GEOM_LOG Data"); - -static uma_zone_t g_log_io_zone; -/*static uma_zone_t g_log_hl_zone;*/ - -static void g_log_ctlreq (struct gctl_req *req, struct g_class *mp, const char - *verb); -static enum gctl_verb g_log_verb_id(const char* verb); -static char *g_log_create_geom(const char *prov, const char *file, - struct g_class *mp); -static void g_log_start(struct bio *bp); -static int g_log_event_sink_init(struct g_log_softc *sc, - struct g_log_event_sink *es, void (*func)(void*), char* name); -static void g_log_worker(void *args); - -/*static g_ctl_destroy_geom_t g_log_destroy_geom;*/ -static g_init_t g_log_init; -static g_fini_t g_log_fini; - -SYSCTL_DECL(_kern_geom); -SYSCTL_NODE(_kern_geom, OID_AUTO, log, CTLFLAG_RW, 0, "GEOM_LOG information"); - -static u_int g_log_debug = 2; /* XXX: lower when released to public */ -TUNABLE_INT("kern.geom.log.debug", &g_log_debug); -SYSCTL_UINT(_kern_geom_log, OID_AUTO, debug, CTLFLAG_RW, &g_log_debug, 0, - "Debug level"); - -static u_int g_log_maxrecsector = 64; -TUNABLE_INT("kern.geom.log.maxrecsector", &g_log_maxrecsector); -SYSCTL_UINT(_kern_geom_log, OID_AUTO, maxrecsector, CTLFLAG_RD, - &g_log_maxrecsector, 0, "Maximum records in log descriptor sector"); - -static u_int g_log_maxmem = MAXPHYS * 100; -TUNABLE_INT("kern.geom.log.maxmem", &g_log_maxmem); -SYSCTL_UINT(_kern_geom_log, OID_AUTO, maxmem, CTLFLAG_RD, &g_log_maxmem, - 0, "Maximum memory that can be allocated for I/O (in bytes)"); -/* -extern u_int _hl_stat_hinted_lookups; -SYSCTL_UINT(_kern_geom_log, OID_AUTO, hl_hinted_lookups, - CTLFLAG_RD, &_hl_stat_hinted_lookups, 0, - "Number of hint cache hits for hinted interval list"); -*/ -static u_int g_log_alloc_failed = 0; -SYSCTL_UINT(_kern_geom_log, OID_AUTO, alloc_failed, CTLFLAG_RD, - &g_log_alloc_failed, 0, "How many times I/O allocation failed"); - - -struct g_class g_log_class = { - .name = G_LOG_CLASS_NAME, - .version = G_VERSION, - //.destroy_geom = g_log_destroy_geom, - .ctlreq = g_log_ctlreq, - .init = g_log_init, - .fini = g_log_fini -}; - -/*static int g_log_destroy_geom(struct g_log_softc *sc, boolean_t force); -static void g_log_collect_children(struct bio *bp); -static void g_log_commit(struct g_log_softc *sc); -static int g_log_rollback(struct g_log_softc *sc); -static int g_log_write(struct g_log_softc *sc); -static int g_log_read(struct g_log_softc *sc);*/ - -/* gctl verb IDs */ -enum gctl_verb { GCTL_INVALID, GCTL_COMMIT, GCTL_ROLLBACK, GCTL_START, - GCTL_STOP}; - -static void -g_log_init(struct g_class *mp __unused) -{ - g_log_io_zone = uma_zcreate("glog.io", MAXPHYS, NULL, NULL, NULL, NULL, - 0, UMA_ALIGN_CACHE); - g_log_maxmem -= g_log_maxmem % MAXPHYS; - uma_zone_set_max(g_log_io_zone, g_log_maxmem / MAXPHYS); - /* g_log_hl_zone = uma_zcreate("glog.hl", sizeof(struct hl_entry), NULL, NULL, - NULL, NULL, UMA_ALIGN_PTR, 0);*/ - G_LOG_DEBUG(DBG_NOTICE, "%s", __func__); -} - -static void -g_log_fini(struct g_class *mp __unused) -{ - uma_zdestroy(g_log_io_zone); - /*uma_zdestroy(g_log_hl_zone);*/ - G_LOG_DEBUG(DBG_NOTICE, "%s", __func__); -} -/* -static void -g_log_orphan(struct g_consumer *cp) -{ - struct g_log_softc *sc; - struct g_geom *gp; - - G_LOG_DEBUG(0, "%s", __func__); - - g_topology_assert(); - gp = cp->geom; - sc = gp->softc; - if (sc == NULL) - return; - - g_log_remove_disk(cp); - - if (g_log_nvalid(sc) == 0) - g_log_destroy(sc, 1); -} -*/ - -static char * -g_log_create_geom(const char *prov, const char *file, struct g_class *mp) -{ - struct g_geom *gp; - struct g_provider *pp; - struct g_log_softc *sc; - char *err_msg = NULL; - - /* create provider*/ - if (strncmp(prov, "/dev/", strlen("/dev/")) == 0) - prov += strlen("/dev/"); - - pp = g_provider_by_name(prov); - if (pp == NULL) - err_msg = "Provider doesn't exist."; - /*create geom*/ - gp = g_new_geomf(mp, "%s.log", prov); - if (gp == NULL) - err_msg = "Can not create geom."; - gp->start = g_log_start; - - sc = malloc(sizeof(*sc), M_GLOG, M_WAITOK | M_ZERO); - sc->sc_geom = gp; - sc->sc_provider = pp; - - if (g_log_event_sink_init(sc, &sc->sc_events, g_log_worker, "events") !=0) - err_msg = "Can not initialize worker thread."; - - /*open file*/ - sc->sc_vn = glog_open_file(file, FWRITE | O_TRUNC | O_CREAT); - - gp->softc = sc; - return err_msg; -} - -static int -g_log_event_sink_init(struct g_log_softc *sc, struct g_log_event_sink *es, - void (*func)(void*), char* name) -{ - int err; - es->sc = sc; - mtx_init(&es->eventq_mtx, "glog:event_sink", NULL, MTX_DEF); - TAILQ_INIT(&es->eventq); - if ((err = kthread_create(func, es, &es->worker_thread, 0, 0, "g_log %s", - name)) != 0) - return err; - es->flags = 0; - - return 0; -} - -static void -g_log_ctlreq (struct gctl_req *req, struct g_class *mp, const char *verb) -{ - int *num_arg; - const char *prov, *file; - char *err; - - g_topology_assert(); - - switch (g_log_verb_id(verb)) { - case GCTL_START: - num_arg = gctl_get_paraml(req, "nargs", sizeof(*num_arg)); - if (*num_arg == 2) { - prov = gctl_get_asciiparam(req, "arg0"); - file = gctl_get_asciiparam(req, "arg1"); - err = g_log_create_geom(prov, file, mp); - if (err != NULL) - gctl_error(req, "Error creating geom: %s", err); - } else - gctl_error(req,"Wrong number of parameters."); - break; - case GCTL_COMMIT: - break; - case GCTL_ROLLBACK: - break; - case GCTL_STOP: - break; - default: - panic("Unknown verb!"); - } -} - -static void -g_log_start(struct bio *bp) -{ - g_io_deliver(bp, ENOMEM); - return; -} - -static void -g_log_worker(void *args) -{ -} - -/* Convert verb to number */ -static enum gctl_verb -g_log_verb_id(const char* verb) -{ - if (strcmp(verb, "commit") == 0) - return GCTL_COMMIT; - else if (strcmp(verb, "rollback") == 0) - return GCTL_ROLLBACK; - else if (strcmp(verb, "start") == 0) - return GCTL_START; - else if (strcmp(verb, "stop") == 0) - return GCTL_STOP; - else - return GCTL_INVALID; -}; - -DECLARE_GEOM_CLASS(g_log_class, g_log); - +/*- + * Copyright (c) 2007 Sonja Milicic <tanarri@geri.cc.fer.hr> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/lock.h> +#include <sys/vnode.h> +#include <sys/mutex.h> +#include <sys/sx.h> +#include <sys/bio.h> +#include <sys/sysctl.h> +#include <sys/malloc.h> +#include <sys/time.h> +#include <vm/uma.h> +#include <sys/proc.h> +#include <sys/kthread.h> +#include <geom/geom.h> +#include <sys/fcntl.h> +#include <sys/namei.h> + +#include "glog.h" +#include "glog_fileops.h" + +static MALLOC_DEFINE(M_GLOG, "glog", "GEOM_LOG Data"); + +static uma_zone_t g_log_io_zone; +/*static uma_zone_t g_log_hl_zone;*/ + +static void g_log_ctlreq(struct gctl_req *req, struct g_class *mp, const char + *verb); +static enum gctl_verb g_log_verb_id(const char* verb); +static struct g_geom * g_log_create_geom(const char *prov, const char *file, + struct g_class *mp, int *err); +static int g_log_destroy_geom(struct gctl_req *req __unused, + struct g_class *mp __unused, struct g_geom *gp); +static void g_log_start(struct bio *bp); +static void g_log_stop(struct g_geom *gp, int force); +static int g_log_access(struct g_provider *pp, int dr, int dw, int de); +static int g_log_event_sink_init(struct g_log_softc *sc, + struct g_log_event_sink *es, void (*func)(void*), char* name); +static void g_log_worker(void *args); +static int g_log_post_event(struct g_log_event_sink *es, u_int type, + u_int flags, void* data1, int data2); +static struct g_log_event* g_log_get_event(struct g_log_event_sink *es); +static int g_log_no_events(struct g_log_event_sink *es); +static void g_log_write(struct bio *bp); +static void g_log_read(struct bio *bp); +static void g_log_dumpconf(struct sbuf *sb, const char *indent, + struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp); +static void g_log_ctl_destroy(struct gctl_req *req, struct g_class *mp); +static g_init_t g_log_init; +static g_fini_t g_log_fini; + +SYSCTL_DECL(_kern_geom); +SYSCTL_NODE(_kern_geom, OID_AUTO, log, CTLFLAG_RW, 0, "GEOM_LOG information"); + +static u_int g_log_debug = 10; /* XXX: lower when released to public */ +TUNABLE_INT("kern.geom.log.debug", &g_log_debug); +SYSCTL_UINT(_kern_geom_log, OID_AUTO, debug, CTLFLAG_RW, &g_log_debug, 0, + "Debug level"); + +static u_int g_log_maxrecsector = 64; +TUNABLE_INT("kern.geom.log.maxrecsector", &g_log_maxrecsector); +SYSCTL_UINT(_kern_geom_log, OID_AUTO, maxrecsector, CTLFLAG_RD, + &g_log_maxrecsector, 0, "Maximum records in log descriptor sector"); + +static u_int g_log_maxmem = MAXPHYS * 100; +TUNABLE_INT("kern.geom.log.maxmem", &g_log_maxmem); +SYSCTL_UINT(_kern_geom_log, OID_AUTO, maxmem, CTLFLAG_RD, &g_log_maxmem, + 0, "Maximum memory that can be allocated for I/O (in bytes)"); +/* +extern u_int _hl_stat_hinted_lookups; +SYSCTL_UINT(_kern_geom_log, OID_AUTO, hl_hinted_lookups, + CTLFLAG_RD, &_hl_stat_hinted_lookups, 0, + "Number of hint cache hits for hinted interval list"); +*/ +static u_int g_log_alloc_failed = 0; +SYSCTL_UINT(_kern_geom_log, OID_AUTO, alloc_failed, CTLFLAG_RD, + &g_log_alloc_failed, 0, "How many times I/O allocation failed"); + + +struct g_class g_log_class = { + .name = G_LOG_CLASS_NAME, + .version = G_VERSION, + .destroy_geom = g_log_destroy_geom, + .ctlreq = g_log_ctlreq, + .init = g_log_init, + .fini = g_log_fini +}; + +/* gctl verb IDs */ +enum gctl_verb { GCTL_INVALID, GCTL_COMMIT, GCTL_ROLLBACK, GCTL_START, + GCTL_STOP}; + +static void +g_log_init(struct g_class *mp __unused) +{ + g_log_io_zone = uma_zcreate("glog.io", MAXPHYS, NULL, NULL, NULL, NULL, + 0, UMA_ALIGN_CACHE); + g_log_maxmem -= g_log_maxmem % MAXPHYS; + uma_zone_set_max(g_log_io_zone, g_log_maxmem / MAXPHYS); + /* g_log_hl_zone = uma_zcreate("glog.hl", sizeof(struct hl_entry), NULL, NULL, + NULL, NULL, UMA_ALIGN_PTR, 0);*/ + G_LOG_DEBUG(DBG_NOTICE, "%s", __func__); +} + +static void +g_log_fini(struct g_class *mp __unused) +{ + uma_zdestroy(g_log_io_zone); + /*uma_zdestroy(g_log_hl_zone);*/ + G_LOG_DEBUG(DBG_NOTICE, "%s", __func__); +} + +static void +g_log_orphan(struct g_consumer *cp) +{ + struct g_log_softc *sc; + struct g_geom *gp; + + g_topology_assert(); + gp = cp->geom; + sc = gp->softc; + if (sc == NULL) + return; + g_log_stop(gp, 1); +} + +static struct g_geom * +g_log_create_geom(const char *prov, const char *file, struct g_class *mp, int *err) +{ + struct g_geom *gp; + struct g_provider *pp_log, *pp_disk; + struct g_log_softc *sc; + struct g_consumer *cp_disk; + + /*initialize softc*/ + sc = malloc(sizeof(*sc), M_GLOG, M_WAITOK | M_ZERO); + + /*create geom and provider for log*/ + gp = g_new_geomf(mp, "%s.log", prov); + gp->softc = sc; + gp->start = g_log_start; + gp->spoiled = g_log_orphan; + gp->orphan = g_log_orphan; + gp->access = g_log_access; + gp->dumpconf = g_log_dumpconf; + if (gp == NULL) + *err=3; + pp_log = g_new_providerf(gp, "%s.log", prov); + sc->sc_geom_log = gp; + sc->sc_prov_log = pp_log; + + if (g_log_event_sink_init(sc, &sc->sc_events, g_log_worker, "events") !=0) + *err=4; + + /* create provider and consumer for disk*/ + if (strncmp(prov, "/dev/", strlen("/dev/")) == 0) + prov += strlen("/dev/"); + pp_disk = g_provider_by_name(prov); + if (pp_disk == NULL) + *err = 1; + cp_disk = g_new_consumer(gp); + if (g_attach(cp_disk, pp_disk) != 0) + *err = 2; + sc->sc_prov_disk = pp_disk; + sc->sc_cons_disk = cp_disk; + + /*open file*/ + sc->sc_vn = glog_open_file(file, FWRITE | O_TRUNC | O_CREAT); + + + return gp; +} + +static int +g_log_event_sink_init(struct g_log_softc *sc, struct g_log_event_sink *es, + void (*func)(void*), char* name) +{ + int err; + es->sc = sc; + mtx_init(&es->eventq_mtx, "glog:event_sink", NULL, MTX_DEF); + TAILQ_INIT(&es->eventq); + if ((err = kthread_create(func, es, &es->worker_thread, 0, 0, "g_log %s", + name)) != 0) + return err; + es->flags = 0; + + return 0; +} + +static void +g_log_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb) +{ + struct g_geom *gp=NULL; + const char *prov, *file; + int *num_arg; + int err = 0; + char *err_text=NULL; + + g_topology_assert(); + num_arg = gctl_get_paraml(req, "nargs", sizeof(*num_arg)); + switch (g_log_verb_id(verb)) { + case GCTL_START: + if (*num_arg == 2) { + prov = gctl_get_asciiparam(req, "arg0"); + file = gctl_get_asciiparam(req, "arg1"); + gp = g_log_create_geom(prov, file, mp, &err); + if (err != 0){ + switch (err){ + case 1: + err_text="Cannot open provider"; + break; + case 2: + err_text="Cannot attach consumer to provider"; + break; + case 3: + err_text="Can not create geom"; + break; + case 4: + err_text="Can not start worker thread"; + break; + } + gctl_error(req, "Error starting geom log: %s", err_text); + } + } else + gctl_error(req, "Wrong number of parameters."); + break; + case GCTL_COMMIT: + if (*num_arg == 1) { + prov = gctl_get_asciiparam(req, "arg0"); + g_log_stop(gp,0); + + } else + gctl_error(req, "Wrong number of parameters."); + break; + case GCTL_ROLLBACK: + break; + case GCTL_STOP: + if (*num_arg == 1) { + g_log_ctl_destroy(req, mp); + } else + gctl_error(req, "Wrong number of parameters."); + break; + default: + panic("Unknown verb!"); + } +} + +/*start geom*/ +static void +g_log_start(struct bio *bp) +{ + struct g_log_softc *sc; + sc = bp->bio_to->geom->softc; + KASSERT(sc != NULL, + ("Provider's error should be set (error=%d)(device=%s).", + bp->bio_to->error, bp->bio_to->name)); + + G_LOG_LOGREQ(DBG_NOTICE, bp, "Request received."); + + switch(bp->bio_cmd) { + case BIO_WRITE: + g_log_post_event(&sc->sc_events, GLOG_EVWRITE, GLOG_FLAG_WAKEUP_SC, bp, 0); + break; + case BIO_READ: + g_log_post_event(&sc->sc_events, GLOG_EVREAD, GLOG_FLAG_WAKEUP_SC, bp, 0); + break; + default: + break; + } + return; +} + +/*stop geom*/ +static void +g_log_stop(struct g_geom *gp, int force) +{ + struct g_log_softc *sc; + sc=gp->softc; + + /*close log file*/ + glog_close_file(sc->sc_vn, FWRITE); + + /*clean up memory*/ + g_detach(sc->sc_cons_disk); + g_destroy_consumer(sc->sc_cons_disk); + gp->softc = NULL; + free(sc, M_GLOG); + + /*destroy geom*/ + g_topology_assert(); + g_wither_geom(gp, ENXIO); +} + +static int +g_log_access(struct g_provider *pp, int dr, int dw, int de) +{ + struct g_consumer *cp; + struct g_log_softc *sc; + struct g_geom *gp; + int err = 0; + + gp = pp->geom; + sc = gp->softc; + G_LOG_DEBUG(DBG_IMPORTANT, "%s: %d %d %d", __func__, dr, dw, de); + + if (sc == NULL) { + /* + * It looks like geom is being withered. + * In that case we allow only negative requests. + */ + KASSERT(dr <= 0 && dw <= 0 && de <= 0, + ("Positive access request (device=%s).", pp->name)); + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && + (pp->ace + de) == 0) { + G_LOG_DEBUG(0, "Device %s definitely destroyed.", gp->name); + } + return (0); + } + + LIST_FOREACH(cp, &gp->consumer, consumer){ + err = g_access(cp, dr ,dw, de); + if (err == 0) + continue; + } + return err; +} + +/*puts worker thread to sleep if there's nothing for it to do*/ +static void +g_log_worker_sleep(struct g_log_softc *sc) +{ + if (g_log_no_events(&sc->sc_events)) + tsleep(sc, PRIBIO, "glogidle", hz); +} + +/*worker thread*/ +static void +g_log_worker(void *args) +{ + struct g_log_event_sink *es; + struct g_log_softc *sc; + struct g_log_event *ev; + struct bio *bp; + es = args; + + if (es == NULL) + panic("No event sink!"); + sc = es->sc; + if (sc == NULL) + panic("No softc!"); + + while (1){ + ev = g_log_get_event(&sc->sc_events); + while (ev == NULL) + g_log_worker_sleep(sc); + bp = ev->data1; + switch (ev->type) { + case GLOG_EVCOMMIT: + break; + case GLOG_EVROLLBACK: + break; + case GLOG_EVREAD: + g_log_read(bp); + break; + case GLOG_EVWRITE: + g_log_write(bp); + break; + case GLOG_EVSTOP: + break; + } + free(ev,M_GLOG); + } +} +/* adds event to event queue */ +static int +g_log_post_event(struct g_log_event_sink *es, u_int type, u_int flags, + void* data1, int data2) +{ + struct g_log_softc *sc; + struct g_log_event *ev; + + KASSERT(es != NULL, ("%s: event_sink is null", __func__)); + sc = es->sc; + KASSERT(sc != NULL, ("%s: softc is null", __func__)); + + ev = malloc(sizeof(*ev), M_GLOG, M_NOWAIT); + if (ev == NULL) + return ENOMEM; + + ev->type = type; + ev->flags = flags; + ev->data1 = data1; + ev->data2 = data2; + + mtx_lock(&es->eventq_mtx); + TAILQ_INSERT_TAIL(&es->eventq, ev, linkage); + mtx_unlock(&es->eventq_mtx); + + if ( (flags & GLOG_FLAG_WAKEUP_SC) != 0) + wakeup(es); + + return 0; +} + +/*gets next event from event queue*/ +static struct g_log_event* +g_log_get_event(struct g_log_event_sink *es) +{ + struct g_log_softc *sc; + struct g_log_event *ev; + + KASSERT(es != NULL, ("%s: event_sink is null", __func__)); + sc = es->sc; + KASSERT(sc != NULL, ("%s: softc is null", __func__)); + + mtx_lock(&es->eventq_mtx); + ev = TAILQ_FIRST(&es->eventq); + if (ev != NULL) + TAILQ_REMOVE(&es->eventq, ev, linkage); + mtx_unlock(&es->eventq_mtx); + + return ev; +} + +/*is the event queue empty?*/ +static int +g_log_no_events(struct g_log_event_sink *es) +{ + return TAILQ_EMPTY(&es->eventq); +} + +/*writes data to log file*/ +static void +g_log_write(struct bio *bp) +{ + struct g_log_softc *sc; + void *data; + int err; + uprintf("Got a write request."); + sc = bp->bio_to->geom->softc; + data = bp->bio_data; + err = glog_write_file(sc->sc_vn, data, sizeof(data), 0); + if (err != 0) + printf ("Error writing to file"); + +} + +/*reads data*/ +static void +g_log_read(struct bio *bp) +{ + uprintf("Got a read request."); + +} + +/*commits the log file*/ +/*static void +g_log_commit(struct g_log_softc *sc) +{ +}*/ + +/*deletes the log file*/ +/*static void +g_log_rollback(struct g_log_softc *sc) +{ +} +*/ + +static int +g_log_destroy_geom(struct gctl_req *req __unused, struct g_class *mp __unused, + struct g_geom *gp) +{ + g_log_stop(gp, 0); + return 0; +} + +static void +g_log_ctl_destroy(struct gctl_req *req, struct g_class *mp) +{ + struct g_geom *gp; + int *num_args, *force; + const char *prov; + + g_topology_assert(); + + num_args = gctl_get_paraml(req, "nargs", sizeof(int)); + if (*num_args != 1){ + gctl_error(req, "Wrong number of arguments."); + return; + } + prov = gctl_get_asciiparam(req, "arg0"); + + force = gctl_get_paraml(req, "force", sizeof(int)); + gp = LIST_FIRST(&mp->geom); + g_log_stop(gp, *force); + + +} +/*XML*/ +static void +g_log_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, + struct g_consumer *cp, struct g_provider *pp) +{ + struct g_log_softc *sc; + + sc = gp->softc; + if (sc == NULL) + return; + if (pp != NULL) { + /* Nothing here. */ + } else if (cp != NULL) { + sbuf_printf(sb, "%s<Number>%u</Number>\n", indent, + (u_int)cp->index); + } else { + + + } +} + +/* Convert verb to number */ +static enum gctl_verb +g_log_verb_id(const char* verb) +{ + if (strcmp(verb, "commit") == 0) + return GCTL_COMMIT; + else if (strcmp(verb, "rollback") == 0) + return GCTL_ROLLBACK; + else if (strcmp(verb, "start") == 0) + return GCTL_START; + else if (strcmp(verb, "stop") == 0) + return GCTL_STOP; + else + return GCTL_INVALID; +}; + +DECLARE_GEOM_CLASS(g_log_class, g_log); +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707012114.l61LEJSH090199>