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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2016 Toomas Soome <tsoome@me.com> 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <regex.h> 28 #include <devfsadm.h> 29 #include <stdio.h> 30 #include <strings.h> 31 #include <stdlib.h> 32 #include <limits.h> 33 #include <sys/mkdev.h> 34 #include <sys/lofi.h> 35 36 37 static int lofi(di_minor_t minor, di_node_t node); 38 static int lofi_rm_all(char *link); 39 40 /* 41 * devfs create callback register 42 */ 43 static devfsadm_create_t lofi_create_cbt[] = { 44 { "pseudo", "ddi_pseudo", LOFI_DRIVER_NAME, 45 TYPE_EXACT | DRV_EXACT, ILEVEL_0, lofi, 46 }, 47 }; 48 DEVFSADM_CREATE_INIT_V0(lofi_create_cbt); 49 50 /* 51 * devfs cleanup register 52 */ 53 static devfsadm_remove_V1_t lofi_remove_cbt[] = { 54 {"pseudo", "^r?lofi/[0-9]+$", RM_ALWAYS | RM_PRE | RM_HOT, 55 ILEVEL_0, lofi_rm_all}, 56 }; 57 DEVFSADM_REMOVE_INIT_V1(lofi_remove_cbt); 58 59 /* 60 * Wrapper around devfsadm_rm_all() that allows termination of remove 61 * process 62 */ 63 static int 64 lofi_rm_all(char *link) 65 { 66 devfsadm_rm_all(link); 67 return (DEVFSADM_TERMINATE); 68 } 69 70 71 /* 72 * For the master device: 73 * /dev/lofictl -> /devices/pseudo/lofi@0:ctl 74 * For each other device 75 * /dev/lofi/1 -> /devices/pseudo/lofi@1:disk 76 * /dev/rlofi/1 -> /devices/pseudo/lofi@1:disk,raw 77 */ 78 static int 79 lofi(di_minor_t minor, di_node_t node) 80 { 81 int instance; 82 char mn[MAXNAMELEN + 1]; 83 char path[PATH_MAX + 1]; 84 85 (void) strcpy(mn, di_minor_name(minor)); 86 87 if (strcmp(mn, "ctl") == 0) { 88 (void) devfsadm_mklink(LOFI_CTL_NAME, node, minor, 0); 89 } else { 90 instance = di_instance(node); 91 92 if (strcmp(mn, LOFI_BLOCK_NODE) == 0) { 93 (void) snprintf(path, sizeof (path), "%s/%d", 94 LOFI_BLOCK_NAME, instance); 95 } else if (strcmp(mn, LOFI_CHAR_NODE) == 0) { 96 (void) snprintf(path, sizeof (path), "%s/%d", 97 LOFI_CHAR_NAME, instance); 98 } else { 99 return (DEVFSADM_CONTINUE); 100 } 101 102 (void) devfsadm_mklink(path, node, minor, 0); 103 } 104 return (DEVFSADM_CONTINUE); 105 } 106