Home | History | Annotate | Line # | Download | only in mlxctl
dklist.c revision 1.3.2.2
      1  1.3.2.2  he /*	$NetBSD: dklist.c,v 1.3.2.2 2001/12/09 19:36:56 he Exp $	*/
      2  1.3.2.2  he 
      3  1.3.2.2  he /*-
      4  1.3.2.2  he  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      5  1.3.2.2  he  * All rights reserved.
      6  1.3.2.2  he  *
      7  1.3.2.2  he  * This code is derived from software contributed to The NetBSD Foundation
      8  1.3.2.2  he  * by Andrew Doran.
      9  1.3.2.2  he  *
     10  1.3.2.2  he  * Redistribution and use in source and binary forms, with or without
     11  1.3.2.2  he  * modification, are permitted provided that the following conditions
     12  1.3.2.2  he  * are met:
     13  1.3.2.2  he  * 1. Redistributions of source code must retain the above copyright
     14  1.3.2.2  he  *    notice, this list of conditions and the following disclaimer.
     15  1.3.2.2  he  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.3.2.2  he  *    notice, this list of conditions and the following disclaimer in the
     17  1.3.2.2  he  *    documentation and/or other materials provided with the distribution.
     18  1.3.2.2  he  * 3. All advertising materials mentioning features or use of this software
     19  1.3.2.2  he  *    must display the following acknowledgement:
     20  1.3.2.2  he  *        This product includes software developed by the NetBSD
     21  1.3.2.2  he  *        Foundation, Inc. and its contributors.
     22  1.3.2.2  he  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.3.2.2  he  *    contributors may be used to endorse or promote products derived
     24  1.3.2.2  he  *    from this software without specific prior written permission.
     25  1.3.2.2  he  *
     26  1.3.2.2  he  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.3.2.2  he  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.3.2.2  he  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.3.2.2  he  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.3.2.2  he  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.3.2.2  he  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.3.2.2  he  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.3.2.2  he  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.3.2.2  he  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.3.2.2  he  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.3.2.2  he  * POSSIBILITY OF SUCH DAMAGE.
     37  1.3.2.2  he  */
     38  1.3.2.2  he 
     39  1.3.2.2  he /*
     40  1.3.2.2  he  * Copyright (c) 1996 John M. Vinopal
     41  1.3.2.2  he  * All rights reserved.
     42  1.3.2.2  he  *
     43  1.3.2.2  he  * Redistribution and use in source and binary forms, with or without
     44  1.3.2.2  he  * modification, are permitted provided that the following conditions
     45  1.3.2.2  he  * are met:
     46  1.3.2.2  he  * 1. Redistributions of source code must retain the above copyright
     47  1.3.2.2  he  *    notice, this list of conditions and the following disclaimer.
     48  1.3.2.2  he  * 2. Redistributions in binary form must reproduce the above copyright
     49  1.3.2.2  he  *    notice, this list of conditions and the following disclaimer in the
     50  1.3.2.2  he  *    documentation and/or other materials provided with the distribution.
     51  1.3.2.2  he  * 3. All advertising materials mentioning features or use of this software
     52  1.3.2.2  he  *    must display the following acknowledgement:
     53  1.3.2.2  he  *      This product includes software developed for the NetBSD Project
     54  1.3.2.2  he  *      by John M. Vinopal.
     55  1.3.2.2  he  * 4. The name of the author may not be used to endorse or promote products
     56  1.3.2.2  he  *    derived from this software without specific prior written permission.
     57  1.3.2.2  he  *
     58  1.3.2.2  he  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     59  1.3.2.2  he  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     60  1.3.2.2  he  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     61  1.3.2.2  he  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     62  1.3.2.2  he  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     63  1.3.2.2  he  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     64  1.3.2.2  he  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     65  1.3.2.2  he  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     66  1.3.2.2  he  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67  1.3.2.2  he  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68  1.3.2.2  he  * SUCH DAMAGE.
     69  1.3.2.2  he  */
     70  1.3.2.2  he 
     71  1.3.2.2  he #ifndef lint
     72  1.3.2.2  he #include <sys/cdefs.h>
     73  1.3.2.2  he __RCSID("$NetBSD: dklist.c,v 1.3.2.2 2001/12/09 19:36:56 he Exp $");
     74  1.3.2.2  he #endif /* not lint */
     75  1.3.2.2  he 
     76  1.3.2.2  he #include <sys/types.h>
     77  1.3.2.2  he #include <sys/disk.h>
     78  1.3.2.2  he #include <sys/ioctl.h>
     79  1.3.2.2  he 
     80  1.3.2.2  he #include <dev/ic/mlxreg.h>
     81  1.3.2.2  he #include <dev/ic/mlxio.h>
     82  1.3.2.2  he 
     83  1.3.2.2  he #include <err.h>
     84  1.3.2.2  he #include <fcntl.h>
     85  1.3.2.2  he #include <kvm.h>
     86  1.3.2.2  he #include <limits.h>
     87  1.3.2.2  he #include <nlist.h>
     88  1.3.2.2  he #include <stdio.h>
     89  1.3.2.2  he #include <stdlib.h>
     90  1.3.2.2  he #include <string.h>
     91  1.3.2.2  he #include <ctype.h>
     92  1.3.2.2  he #include <unistd.h>
     93  1.3.2.2  he 
     94  1.3.2.2  he #include "extern.h"
     95  1.3.2.2  he 
     96  1.3.2.2  he static SIMPLEQ_HEAD(, mlx_disk) mlx_disks;
     97  1.3.2.2  he 
     98  1.3.2.2  he static struct nlist namelist[] = {
     99  1.3.2.2  he #define X_DISK_COUNT	0
    100  1.3.2.2  he 	{ "_disk_count" },	/* number of disks */
    101  1.3.2.2  he #define X_DISKLIST	1
    102  1.3.2.2  he 	{ "_disklist" },	/* TAILQ of disks */
    103  1.3.2.2  he 	{ NULL },
    104  1.3.2.2  he };
    105  1.3.2.2  he 
    106  1.3.2.2  he #define	KVM_ERROR(_string) {						\
    107  1.3.2.2  he 	warnx("%s", (_string));						\
    108  1.3.2.2  he 	errx(1, "%s", kvm_geterr(kd));					\
    109  1.3.2.2  he }
    110  1.3.2.2  he 
    111  1.3.2.2  he /*
    112  1.3.2.2  he  * Dereference the namelist pointer `v' and fill in the local copy
    113  1.3.2.2  he  * 'p' which is of size 's'.
    114  1.3.2.2  he  */
    115  1.3.2.2  he #define deref_nl(kd, v, p, s)	\
    116  1.3.2.2  he     deref_kptr(kd, (void *)namelist[(v)].n_value, (p), (s));
    117  1.3.2.2  he 
    118  1.3.2.2  he static void	deref_kptr(kvm_t *, void *, void *, size_t);
    119  1.3.2.2  he 
    120  1.3.2.2  he void
    121  1.3.2.2  he mlx_disk_init(void)
    122  1.3.2.2  he {
    123  1.3.2.2  he 
    124  1.3.2.2  he 	SIMPLEQ_INIT(&mlx_disks);
    125  1.3.2.2  he }
    126  1.3.2.2  he 
    127  1.3.2.2  he int
    128  1.3.2.2  he mlx_disk_empty(void)
    129  1.3.2.2  he {
    130  1.3.2.2  he 
    131  1.3.2.2  he 	return (SIMPLEQ_FIRST(&mlx_disks) == NULL);
    132  1.3.2.2  he }
    133  1.3.2.2  he 
    134  1.3.2.2  he void
    135  1.3.2.2  he mlx_disk_iterate(void (*func)(struct mlx_disk *))
    136  1.3.2.2  he {
    137  1.3.2.2  he 	struct mlx_disk *md;
    138  1.3.2.2  he 
    139  1.3.2.2  he 	SIMPLEQ_FOREACH(md, &mlx_disks, chain)
    140  1.3.2.2  he 		(*func)(md);
    141  1.3.2.2  he }
    142  1.3.2.2  he 
    143  1.3.2.2  he static int
    144  1.3.2.2  he mlx_disk_add0(const char *name)
    145  1.3.2.2  he {
    146  1.3.2.2  he 	struct mlx_disk *md;
    147  1.3.2.2  he 	int unit;
    148  1.3.2.2  he 
    149  1.3.2.2  he 	if (name[0] != 'l' || name[1] != 'd' || !isdigit(name[2]))
    150  1.3.2.2  he 		return (-1);
    151  1.3.2.2  he 
    152  1.3.2.2  he 	SIMPLEQ_FOREACH(md, &mlx_disks, chain)
    153  1.3.2.2  he 		if (strcmp(md->name, name) == 0)
    154  1.3.2.2  he 			return (0);
    155  1.3.2.2  he 
    156  1.3.2.2  he 	unit = atoi(name + 2);
    157  1.3.2.2  he 	if (ioctl(mlxfd, MLX_GET_SYSDRIVE, &unit) < 0)
    158  1.3.2.2  he 		return (-1);
    159  1.3.2.2  he 
    160  1.3.2.2  he 	if ((md = malloc(sizeof(*md))) == NULL)
    161  1.3.2.2  he 		err(EXIT_FAILURE, "mlx_disk_add()");
    162  1.3.2.2  he 
    163  1.3.2.2  he 	strlcpy(md->name, name, sizeof(md->name));
    164  1.3.2.2  he 	md->hwunit = unit;
    165  1.3.2.2  he 	SIMPLEQ_INSERT_TAIL(&mlx_disks, md, chain);
    166  1.3.2.2  he 	return (0);
    167  1.3.2.2  he }
    168  1.3.2.2  he 
    169  1.3.2.2  he void
    170  1.3.2.2  he mlx_disk_add(const char *name)
    171  1.3.2.2  he {
    172  1.3.2.2  he 
    173  1.3.2.2  he 	if (mlx_disk_add0(name) != 0)
    174  1.3.2.2  he 		errx(EXIT_FAILURE, "%s is not attached to %s", name, mlxname);
    175  1.3.2.2  he }
    176  1.3.2.2  he 
    177  1.3.2.2  he void
    178  1.3.2.2  he mlx_disk_add_all(void)
    179  1.3.2.2  he {
    180  1.3.2.2  he 	struct disklist_head disk_head;
    181  1.3.2.2  he 	struct disk cur_disk, *dk;
    182  1.3.2.2  he         char errbuf[_POSIX2_LINE_MAX];
    183  1.3.2.2  he 	char buf[12];
    184  1.3.2.2  he 	int i, ndrives;
    185  1.3.2.2  he 	kvm_t *kd;
    186  1.3.2.2  he 
    187  1.3.2.2  he 	/* Open the kernel. */
    188  1.3.2.2  he         if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == NULL)
    189  1.3.2.2  he 		errx(1, "kvm_openfiles: %s", errbuf);
    190  1.3.2.2  he 
    191  1.3.2.2  he 	/* Obtain the namelist symbols from the kernel. */
    192  1.3.2.2  he 	if (kvm_nlist(kd, namelist))
    193  1.3.2.2  he 		KVM_ERROR("kvm_nlist failed to read symbols.");
    194  1.3.2.2  he 
    195  1.3.2.2  he 	/* Get the number of attached drives. */
    196  1.3.2.2  he 	deref_nl(kd, X_DISK_COUNT, &ndrives, sizeof(ndrives));
    197  1.3.2.2  he 
    198  1.3.2.2  he 	if (ndrives < 0)
    199  1.3.2.2  he 		errx(EXIT_FAILURE, "invalid _disk_count %d.", ndrives);
    200  1.3.2.2  he 	if (ndrives == 0)
    201  1.3.2.2  he 		errx(EXIT_FAILURE, "no drives attached.");
    202  1.3.2.2  he 
    203  1.3.2.2  he 	/* Get a pointer to the first disk. */
    204  1.3.2.2  he 	deref_nl(kd, X_DISKLIST, &disk_head, sizeof(disk_head));
    205  1.3.2.2  he 	dk = TAILQ_FIRST(&disk_head);
    206  1.3.2.2  he 
    207  1.3.2.2  he 	/* Try to add each disk to the list. */
    208  1.3.2.2  he 	for (i = 0; i < ndrives; i++) {
    209  1.3.2.2  he 		deref_kptr(kd, dk, &cur_disk, sizeof(cur_disk));
    210  1.3.2.2  he 		deref_kptr(kd, cur_disk.dk_name, buf, sizeof(buf));
    211  1.3.2.2  he 		mlx_disk_add0(buf);
    212  1.3.2.2  he 		dk = TAILQ_NEXT(&cur_disk, dk_link);
    213  1.3.2.2  he 	}
    214  1.3.2.2  he 
    215  1.3.2.2  he 	kvm_close(kd);
    216  1.3.2.2  he }
    217  1.3.2.2  he 
    218  1.3.2.2  he /*
    219  1.3.2.2  he  * Dereference the kernel pointer `kptr' and fill in the local copy pointed
    220  1.3.2.2  he  * to by `ptr'.  The storage space must be pre-allocated, and the size of
    221  1.3.2.2  he  * the copy passed in `len'.
    222  1.3.2.2  he  */
    223  1.3.2.2  he static void
    224  1.3.2.2  he deref_kptr(kvm_t *kd, void *kptr, void *ptr, size_t len)
    225  1.3.2.2  he {
    226  1.3.2.2  he 	char buf[128];
    227  1.3.2.2  he 
    228  1.3.2.2  he 	if (kvm_read(kd, (u_long)kptr, (char *)ptr, len) != len) {
    229  1.3.2.2  he 		memset(buf, 0, sizeof(buf));
    230  1.3.2.2  he 		snprintf(buf, sizeof buf, "can't dereference kptr 0x%lx",
    231  1.3.2.2  he 		    (u_long)kptr);
    232  1.3.2.2  he 		KVM_ERROR(buf);
    233  1.3.2.2  he 	}
    234  1.3.2.2  he }
    235