Module Name:    src
Committed By:   agc
Date:           Sat Jun 20 04:12:56 UTC 2009

Modified Files:
        src/usr.sbin/iscsi/initiator: Makefile iscsi-initiator.c
Added Files:
        src/usr.sbin/iscsi/initiator: libkmod.c libkmod.h

Log Message:
Add a library implementation of modload(3) and modstat(3).

Conditionally compiled in when MODULAR_KERNEL is defined in the Makefile
(or during the build process).

Use kmod functions to see if the puffs module is loaded in the kernel,
and to load it if it is not already loaded.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/iscsi/initiator/Makefile
cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/iscsi/initiator/iscsi-initiator.c
cvs rdiff -u -r0 -r1.1 src/usr.sbin/iscsi/initiator/libkmod.c \
    src/usr.sbin/iscsi/initiator/libkmod.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/iscsi/initiator/Makefile
diff -u src/usr.sbin/iscsi/initiator/Makefile:1.2 src/usr.sbin/iscsi/initiator/Makefile:1.3
--- src/usr.sbin/iscsi/initiator/Makefile:1.2	Fri Jun 19 16:13:49 2009
+++ src/usr.sbin/iscsi/initiator/Makefile	Sat Jun 20 04:12:55 2009
@@ -1,14 +1,21 @@
-# $NetBSD: Makefile,v 1.2 2009/06/19 16:13:49 agc Exp $
+# $NetBSD: Makefile,v 1.3 2009/06/20 04:12:55 agc Exp $
 
 .include <bsd.own.mk>
 
 PROG=iscsi-initiator
-SRCS=iscsi-initiator.c virtdir.c initiator.c
+SRCS=iscsi-initiator.c virtdir.c initiator.c libkmod.c
 LDADD+= -lrefuse -liscsi
+DPADD+= ${LIBREFUSE} ${LIBISCSI}
 CPPFLAGS+= -g -I${NETBSDSRCDIR}/dist/iscsi/include
 MAN=iscsi-initiator.8
 WARNS=4
 
+.ifdef MODULAR_KERNEL
+CPPFLAGS+= -DUSE_LIBKMOD
+LDADD+= -lprop
+DPADD+= ${LIBPROP}
+.endif
+
 .PATH: ${NETBSDSRCDIR}/dist/iscsi/src
 
 .include <bsd.prog.mk>

Index: src/usr.sbin/iscsi/initiator/iscsi-initiator.c
diff -u src/usr.sbin/iscsi/initiator/iscsi-initiator.c:1.1 src/usr.sbin/iscsi/initiator/iscsi-initiator.c:1.2
--- src/usr.sbin/iscsi/initiator/iscsi-initiator.c:1.1	Fri Jun 19 07:17:09 2009
+++ src/usr.sbin/iscsi/initiator/iscsi-initiator.c	Sat Jun 20 04:12:55 2009
@@ -47,6 +47,10 @@
 
 #include "virtdir.h"
 
+#if defined(__NetBSD__) && defined(USE_LIBKMOD)
+#include "libkmod.h"
+#endif
+
 #include "defs.h"
 
 static int		 verbose; /* how chatty are we? */
@@ -631,9 +635,15 @@
 		all_targets.c = CONFIG_INITIATOR_NUM_TARGETS;
 	}
 
-
 	sti.st.st_ino = 0x15c51;
 
+#if defined(__NetBSD__) && defined(USE_LIBKMOD)
+	/* check that the puffs module is loaded on NetBSD */
+	if (kmodstat("puffs", NULL) == 0 && !kmodload("puffs")) {
+		(void) fprintf(stderr, "initiator: can't load puffs module\n");
+	}
+#endif
+
 	for (u = 0 ; u < all_targets.c / 2 ; u++) {
 		ALLOC(targetinfo_t, tv.v, tv.size, tv.c, 10, 10, "iscsifs",
 				exit(EXIT_FAILURE));

Added files:

Index: src/usr.sbin/iscsi/initiator/libkmod.c
diff -u /dev/null src/usr.sbin/iscsi/initiator/libkmod.c:1.1
--- /dev/null	Sat Jun 20 04:12:56 2009
+++ src/usr.sbin/iscsi/initiator/libkmod.c	Sat Jun 20 04:12:55 2009
@@ -0,0 +1,219 @@
+/*	$NetBSD: libkmod.c,v 1.1 2009/06/20 04:12:55 agc Exp $	*/
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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>
+#ifndef lint
+__RCSID("$NetBSD: libkmod.c,v 1.1 2009/06/20 04:12:55 agc Exp $");
+#endif /* !lint */
+
+#include <sys/module.h>
+
+#include <prop/proplib.h>
+
+#include <assert.h>
+#include <err.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libkmod.h"
+
+#ifdef USE_LIBKMOD
+
+static const char *classes[] = {
+	"any",
+	"misc",
+	"vfs",
+	"driver",
+	"exec",
+};
+
+static const char *sources[] = {
+	"builtin",
+	"boot",
+	"filesys",
+};
+
+/* comparison routine for qsort */
+static int
+modcmp(const void *a, const void *b)
+{
+	const modstat_t *msa, *msb;
+
+	msa = a;
+	msb = b;
+	return strcmp(msa->ms_name, msb->ms_name);
+}
+
+/* function which "opens" a module */
+int
+openkmod(kernel_t *kernel)
+{
+	kernel->size = 4096;
+	for (;;) {
+		kernel->iov.iov_base = malloc(kernel->size);
+		kernel->iov.iov_len = kernel->size;
+		if (modctl(MODCTL_STAT, &kernel->iov)) {
+			warn("modctl(MODCTL_STAT)");
+			return 0;
+		}
+		if (kernel->size >= kernel->iov.iov_len) {
+			break;
+		}
+		free(kernel->iov.iov_base);
+		kernel->size = kernel->iov.iov_len;
+	}
+	kernel->size = kernel->iov.iov_len / sizeof(modstat_t);
+	qsort(kernel->iov.iov_base, kernel->size, sizeof(modstat_t), modcmp);
+	return 1;
+}
+
+/* return details on the module */
+int
+readkmod(kernel_t *kernel, kmod_t *module)
+{
+	modstat_t *ms;
+
+	if (kernel->c * sizeof(*ms) >= kernel->iov.iov_len) {
+		return 0;
+	}
+	ms = kernel->iov.iov_base;
+	ms += kernel->c++;
+	(void) memset(module, 0x0, sizeof(*module));
+	module->name = strdup(ms->ms_name);
+	module->class = strdup(classes[ms->ms_class]);
+	module->source = strdup(sources[ms->ms_source]);
+	module->refcnt = ms->ms_refcnt;
+	module->size = ms->ms_size;
+	if (ms->ms_required[0]) {
+		module->required = strdup(ms->ms_required);
+	}
+	return 1;
+}
+
+/* free up all resources allocated in a module read */
+void
+freekmod(kmod_t *module)
+{
+	(void) free(module->name);
+	(void) free(module->class);
+	(void) free(module->source);
+	if (module->required) {
+		(void) free(module->required);
+	}
+}
+
+/* "close" the module */
+int
+closekmod(kernel_t *kernel)
+{
+	(void) free(kernel->iov.iov_base);
+	return 1;
+}
+
+/* do the modstat operation */
+int
+kmodstat(const char *modname, FILE *fp)
+{
+	kernel_t	kernel;
+	kmod_t		module;
+	int		modc;
+
+	(void) memset(&kernel, 0x0, sizeof(kernel));
+	(void) memset(&module, 0x0, sizeof(module));
+	if (!openkmod(&kernel)) {
+		(void) fprintf(stderr, "can't read kernel modules\n");
+		return 0;
+	}
+	for (modc = 0 ; readkmod(&kernel, &module) ; ) {
+		if (modname == NULL || strcmp(modname, module.name) == 0) {
+			if (modc++ == 0) {
+				if (fp) {
+					(void) fprintf(fp,
+						"NAME\t\tCLASS\tSOURCE\tREFS"
+						"\tSIZE\tREQUIRES\n");
+				}
+			}
+			if (fp) {
+				(void) fprintf(fp, "%-16s%s\t%s\t%d\t%u\t%s\n",
+				module.name,
+				module.class,
+				module.source,
+				module.refcnt,
+				module.size,
+				(module.required) ? module.required : "-");
+			}
+			freekmod(&module);
+		}
+	}
+	(void) closekmod(&kernel);
+	return modc;
+}
+
+/* load the named module into the kernel */
+int
+kmodload(const char *module)
+{
+	prop_dictionary_t	 props;
+	modctl_load_t		 cmdargs;
+	char			*propsstr;
+
+	props = prop_dictionary_create();
+
+	propsstr = prop_dictionary_externalize(props);
+	if (propsstr == NULL) {
+		(void) fprintf(stderr, "Failed to process properties");
+		return 0;
+	}
+
+	cmdargs.ml_filename = module;
+	cmdargs.ml_flags = 0;
+	cmdargs.ml_props = propsstr;
+	cmdargs.ml_propslen = strlen(propsstr);
+
+	if (modctl(MODCTL_LOAD, &cmdargs)) {
+		(void) fprintf(stderr, "modctl failure\n");
+		return 0;
+	}
+
+	(void) free(propsstr);
+	prop_object_release(props);
+
+	return 1;
+}
+
+/* and unload the module from the kernel */
+int
+kmodunload(const char *name)
+{
+	return modctl(MODCTL_UNLOAD, __UNCONST(name)) == 0;
+}
+
+#endif /* USE_LIBKMOD */
Index: src/usr.sbin/iscsi/initiator/libkmod.h
diff -u /dev/null src/usr.sbin/iscsi/initiator/libkmod.h:1.1
--- /dev/null	Sat Jun 20 04:12:56 2009
+++ src/usr.sbin/iscsi/initiator/libkmod.h	Sat Jun 20 04:12:55 2009
@@ -0,0 +1,63 @@
+/*	$NetBSD: libkmod.h,v 1.1 2009/06/20 04:12:55 agc Exp $	*/
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+#ifndef LIBKMOD_H_
+#define LIBKMOD_H_	20090619
+
+#include <sys/module.h>
+
+#include <stdio.h>
+
+/* this struct describes the loaded modules in the kernel */
+typedef struct kernel_t {
+	size_t	 	size;	/* size of iovec array */
+	size_t		c;	/* counter during "read" operations */
+	struct iovec	iov;	/* iovecs from the modctl operation */
+} kernel_t;
+
+/* this struct describes a module */
+typedef struct kmod_t {
+	char		*name;		/* module name */
+	char		*class;		/* module class */
+	char		*source;	/* source of module loading */
+	int		 refcnt;	/* reference count */
+	unsigned	 size;		/* size of binary module */
+	char		*required;	/* any pre-reqs module has */
+} kmod_t;
+
+/* low level open, read, write ops */
+int openkmod(kernel_t *);
+int readkmod(kernel_t *, kmod_t *);
+void freekmod(kmod_t *);
+int closekmod(kernel_t *);
+
+/* high-level kmod operations */
+int kmodstat(const char *, FILE *);
+int kmodload(const char *);
+int kmodunload(const char *);
+
+#endif

Reply via email to