Home | History | Annotate | Download | only in devfsadm
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2002-2003 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 #include <regex.h>
     30 #include <devfsadm.h>
     31 #include <stdio.h>
     32 #include <strings.h>
     33 #include <stdlib.h>
     34 #include <limits.h>
     35 #include <sys/stat.h>
     36 #include <sys/mkdev.h>
     37 #include <sys/ramdisk.h>
     38 
     39 static int ramdisk(di_minor_t di_minor, di_node_t node);
     40 
     41 /*
     42  * devfs create callback register
     43  */
     44 static devfsadm_create_t ramdisk_create_cbt[] = {
     45 	{ "pseudo", "ddi_pseudo", RD_DRIVER_NAME,
     46 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, ramdisk,
     47 	},
     48 };
     49 DEVFSADM_CREATE_INIT_V0(ramdisk_create_cbt);
     50 
     51 /*
     52  * devfs cleanup register
     53  */
     54 #define	RAMDISK_LINK_RE	"^r?ramdisk/.+$"
     55 
     56 static devfsadm_remove_t ramdisk_remove_cbt[] = {
     57 	{ "pseudo", RAMDISK_LINK_RE, RM_ALWAYS | RM_PRE | RM_HOT,
     58 	    ILEVEL_0, devfsadm_rm_all},
     59 };
     60 DEVFSADM_REMOVE_INIT_V0(ramdisk_remove_cbt);
     61 
     62 static char *debug_mid = "ramdisk_mid";
     63 
     64 int
     65 minor_init(void)
     66 {
     67 	devfsadm_print(debug_mid, "ramdisk_link: minor_init\n");
     68 	return (DEVFSADM_SUCCESS);
     69 }
     70 
     71 int
     72 minor_fini(void)
     73 {
     74 	devfsadm_print(debug_mid, "ramdisk_link: minor_fini\n");
     75 	return (DEVFSADM_SUCCESS);
     76 }
     77 
     78 /*
     79  * This function is called for every ramdisk minor node.
     80  * Calls enumerate to assign a logical ramdisk id, and then
     81  * devfsadm_mklink to make the link.
     82  *
     83  * For pseudo ramdisk devices:
     84  *
     85  *	/dev/ramdiskctl      -> /devices/pseudo/ramdisk@0:ctl
     86  *	/dev/ramdisk/<name>  -> /devices/pseudo/ramdisk@0:<name>
     87  *	/dev/rramdisk/<name> -> /devices/pseudo/ramdisk@0:<name>,raw
     88  *
     89  * For OBP-created ramdisk devices:
     90  *
     91  *	/dev/ramdisk/<name>  -> /devices/ramdisk-<name>:a
     92  *	/dev/rramdisk/<name> -> /devices/ramdisk-<name>:a,raw
     93  */
     94 static int
     95 ramdisk(di_minor_t di_minor, di_node_t node)
     96 {
     97 	char	*name;
     98 	char	devnm[MAXNAMELEN + 1];
     99 	char	path[PATH_MAX];
    100 
    101 	/*
    102 	 * If this is an OBP-created ramdisk use the node name, having first
    103 	 * stripped the "ramdisk-" prefix.  For pseudo ramdisks use the minor
    104 	 * name, having first stripped any ",raw" suffix.
    105 	 */
    106 	if (di_nodeid(node) == DI_PROM_NODEID) {
    107 		RD_STRIP_PREFIX(name, di_node_name(node));
    108 		(void) strlcpy(devnm, name, sizeof (devnm));
    109 	} else {
    110 		(void) strlcpy(devnm, di_minor_name(di_minor), sizeof (devnm));
    111 		RD_STRIP_SUFFIX(devnm);
    112 	}
    113 
    114 	if (strcmp(devnm, RD_CTL_NODE) == 0) {
    115 		(void) devfsadm_mklink(RD_CTL_NAME, node, di_minor, 0);
    116 	} else {
    117 		/*
    118 		 * Make the link in /dev/ramdisk or /dev/rramdisk.
    119 		 */
    120 		(void) snprintf(path, sizeof (path), "%s/%s",
    121 		    di_minor_spectype(di_minor) == S_IFBLK ?
    122 		    RD_BLOCK_NAME : RD_CHAR_NAME, devnm);
    123 		(void) devfsadm_mklink(path, node, di_minor, 0);
    124 	}
    125 
    126 	return (DEVFSADM_CONTINUE);
    127 }
    128