diff usr/src/cmd/devfsadm/lofi_link.c @ 0:c9caec207d52 b86

Initial porting based on b86
author Koji Uno <koji.uno@sun.com>
date Tue, 02 Jun 2009 18:56:50 +0900
parents
children 1a15d5aaf794
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/devfsadm/lofi_link.c	Tue Jun 02 18:56:50 2009 +0900
@@ -0,0 +1,112 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"@(#)lofi_link.c	1.5	06/10/02 SMI"
+
+#include <regex.h>
+#include <devfsadm.h>
+#include <stdio.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <sys/mkdev.h>
+#include <sys/lofi.h>
+
+
+static int lofi(di_minor_t minor, di_node_t node);
+static int lofi_rm_all(char *link);
+
+/*
+ * devfs create callback register
+ */
+static devfsadm_create_t lofi_create_cbt[] = {
+	{ "pseudo", "ddi_pseudo", LOFI_DRIVER_NAME,
+	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, lofi,
+	},
+};
+DEVFSADM_CREATE_INIT_V0(lofi_create_cbt);
+
+/*
+ * devfs cleanup register
+ */
+static devfsadm_remove_V1_t lofi_remove_cbt[] = {
+	{"pseudo", "^r?lofi/[0-9]+$", RM_ALWAYS | RM_PRE | RM_HOT,
+	    ILEVEL_0, lofi_rm_all},
+};
+DEVFSADM_REMOVE_INIT_V1(lofi_remove_cbt);
+
+/*
+ * Wrapper around devfsadm_rm_all() that allows termination of remove
+ * process
+ */
+static int
+lofi_rm_all(char *link)
+{
+	devfsadm_rm_all(link);
+	return (DEVFSADM_TERMINATE);
+}
+
+
+/*
+ * For the master device:
+ *	/dev/lofictl -> /devices/pseudo/lofi@0:ctl
+ * For each other device
+ *	/dev/lofi/1 -> /devices/pseudo/lofi@0:1
+ *	/dev/rlofi/1 -> /devices/pseudo/lofi@0:1,raw
+ */
+static int
+lofi(di_minor_t minor, di_node_t node)
+{
+	dev_t	dev;
+	char mn[MAXNAMELEN + 1];
+	char blkname[MAXNAMELEN + 1];
+	char rawname[MAXNAMELEN + 1];
+	char path[PATH_MAX + 1];
+
+	(void) strcpy(mn, di_minor_name(minor));
+
+	if (strcmp(mn, "ctl") == 0) {
+		(void) devfsadm_mklink(LOFI_CTL_NAME, node, minor, 0);
+	} else {
+		dev = di_minor_devt(minor);
+		(void) snprintf(blkname, sizeof (blkname), "%d",
+		    (int)minor(dev));
+		(void) snprintf(rawname, sizeof (rawname), "%d,raw",
+		    (int)minor(dev));
+
+		if (strcmp(mn, blkname) == 0) {
+			(void) snprintf(path, sizeof (path), "%s/%s",
+			    LOFI_BLOCK_NAME, blkname);
+		} else if (strcmp(mn, rawname) == 0) {
+			(void) snprintf(path, sizeof (path), "%s/%s",
+			    LOFI_CHAR_NAME, blkname);
+		} else {
+			return (DEVFSADM_CONTINUE);
+		}
+
+		(void) devfsadm_mklink(path, node, minor, 0);
+	}
+	return (DEVFSADM_CONTINUE);
+}