From owner-freebsd-geom@FreeBSD.ORG Tue May 4 08:47:16 2004 Return-Path: Delivered-To: freebsd-geom@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4206016A4CE for ; Tue, 4 May 2004 08:47:16 -0700 (PDT) Received: from darkness.comp.waw.pl (darkness.comp.waw.pl [195.117.238.236]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5888543D39 for ; Tue, 4 May 2004 08:47:15 -0700 (PDT) (envelope-from pjd@darkness.comp.waw.pl) Received: by darkness.comp.waw.pl (Postfix, from userid 1009) id F333EACAF4; Tue, 4 May 2004 17:47:13 +0200 (CEST) Date: Tue, 4 May 2004 17:47:13 +0200 From: Pawel Jakub Dawidek To: geom@freebsd.org Message-ID: <20040504154713.GD24376@darkness.comp.waw.pl> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="qCPPoBTQI/bIC4sS" Content-Disposition: inline User-Agent: Mutt/1.4.2i X-PGP-Key-URL: http://people.freebsd.org/~pjd/pjd.asc X-OS: FreeBSD 5.2.1-RC2 i386 Subject: geom(8) model proposal. X-BeenThere: freebsd-geom@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: GEOM-specific discussions and implementations List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 May 2004 15:47:16 -0000 --qCPPoBTQI/bIC4sS Content-Type: text/plain; charset=iso-8859-2 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hello. I've quite finished I think geom(8) model that should simplify and unify control over GEOM classes. The main part is geom(8) utility that is responsible for loading shared libraries with class-specific code, for commutication with kernel (GEOM) through libgeom(3) and versions control. Geom(8) can be called in two ways: # geom or: # g What shared library should specify. I'll explain this on examples. Imagine a GEOM NULL class which implements only two commands: gnull create [-v] [dev2 [...]] gnull destroy [-fv] [dev2 [...]] Inside shared library source one should specify available commands in that way: struct g_command class_commands[] =3D { { "create", G_FLAG_VERBOSE | G_FLAG_LOADKLD, NULL, G_NULL_OPTS }, { "destroy", G_FLAG_VERBOSE, NULL, { { 'f', "force", NULL, G_TYPE_NONE }, G_OPT_SENTINEL } }, G_CMD_SENTINEL }; Ok, now: "create" stands for command name, G_FLAG_VERBOSE means that '-v' option is available, G_FLAG_LOADKLD means that geom_null.ko should be loaded if not present in kernel. NULL means it should be handle by geom(8) itself and G_NULL_OPTS means that there are no other options. Arguments after options (dev1, dev2, etc.) are passed to GEOM NULL class. 2nd command: "destroy" - command name, 'f' is option character, "force" is variable name, it will be passed with this name to the kernel, NULL means that it is boolean value (no argument after option), so if specified 1 will be passed to GEOM NULL class as 'force' variable. Other possiblities: intmax_t stripe =3D 65536; [...] { 's', "stripesize", &stripe, G_TYPE_NUMBER } Means: '-s' option is available, it is a number and its default value is 65536 (so it don't have to be specified). { 's', "stripesize", NULL, G_TYPE_NUMBER } Same as above, but '-s' have to be specified, because there is no default value. { 'n', "name", NULL, G_TYPE_STRING } Same as above, but '-n' requires string argument. int force =3D 1; [...] { 'f', "force", &force, G_TYPE_NONE } '-f' is optional with default value of 1. That were options for commands, now commands: { "clear", G_FLAG_VERBOSE, stripe_clear, G_NULL_OPTS }, Field stripe_clear means that one wants to handle this option by himself and stripe_clear is a function name to call: /* * This is simlar to how GEOM class should handle commands in kernel. */ static void stripe_clear(struct gctl_req *req, unsigned flags) { int i, *nargs, verbose =3D 0; const char *name; char param[16]; if ((flags & G_FLAG_VERBOSE) !=3D 0) verbose =3D 1; /* 'nargs' contains number of additional arguments. */ nargs =3D gctl_get_paraml(req, "nargs", sizeof(*nargs)); if (nargs =3D=3D NULL) { gctl_error(req, "No '%s' argument.", "nargs"); return; } if (*nargs < 1) { gctl_error(req, "Too few arguments."); return; } /* * Arguments after options are named "argX" * where X is argument's number. */ for (i =3D 0; i < *nargs; i++) { snprintf(param, sizeof(param), "arg%u", i); name =3D gctl_get_asciiparam(req, param); /* Clear metadata. */ error =3D g_metadata_clear(name); if (error !=3D 0) { gctl_error(req, "Can't store metadata on %s: %s.", name, strerror(error)); return; } if (verbose) printf("Metadata cleared on %s.\n", name); } } ETC. There are some more things to talk about (e.g. standard commands like 'list' and 'unload' or versions control), but for now it should be enough. Maybe it doesn't look too easy, or maybe it's my English, but I've already implemented: gconcat(8), gstripe(8), gnull(8) and gmirror(8) with this model without any problems, so I think it is flexible enough. If there are no objections I want to commit it, as few folks are waiting for geom_stripe class and it will be cool also to have geom_null class for test purposes. Some other classes could be reimplemented to use this model, for example ccd(4) and I can do that if there is such need. --=20 Pawel Jakub Dawidek http://www.FreeBSD.org pjd@FreeBSD.org http://garage.freebsd.pl FreeBSD committer Am I Evil? Yes, I Am! --qCPPoBTQI/bIC4sS Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (FreeBSD) iD8DBQFAl7sBForvXbEpPzQRAs4kAKDQaLIKu9TdeQAS8qE70fk7kYAj1ACg5DWW tzl9wG5U8JNuzaji6Ln0K0I= =8cUJ -----END PGP SIGNATURE----- --qCPPoBTQI/bIC4sS--