g_label_disk_ident.c revision 249564
166458Sdfr/*-
266458Sdfr * Copyright (c) 2012 Ivan Voras <ivoras@FreeBSD.org>
366458Sdfr * All rights reserved.
4139790Simp *
566458Sdfr * Redistribution and use in source and binary forms, with or without
666458Sdfr * modification, are permitted provided that the following conditions
766458Sdfr * are met:
866458Sdfr * 1. Redistributions of source code must retain the above copyright
966458Sdfr *    notice, this list of conditions and the following disclaimer.
1066458Sdfr * 2. Redistributions in binary form must reproduce the above copyright
1166458Sdfr *    notice, this list of conditions and the following disclaimer in the
1266458Sdfr *    documentation and/or other materials provided with the distribution.
1366458Sdfr *
1466458Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
1566458Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1666458Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1766458Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
1866458Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1966458Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2066458Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2166458Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2266458Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2366458Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2466458Sdfr * SUCH DAMAGE.
2566458Sdfr */
2666458Sdfr
2766458Sdfr#include <sys/cdefs.h>
2866458Sdfr__FBSDID("$FreeBSD: head/sys/geom/label/g_label_disk_ident.c 249564 2013-04-16 19:58:24Z ivoras $");
2966458Sdfr
3066458Sdfr#include <sys/param.h>
3166458Sdfr#include <sys/systm.h>
3266458Sdfr#include <sys/kernel.h>
3366458Sdfr#include <sys/malloc.h>
3466458Sdfr
35113941Skan#include <geom/geom.h>
36113941Skan#include <geom/geom_disk.h>
3766458Sdfr#include <geom/label/g_label.h>
38114678Skan#include <geom/multipath/g_multipath.h>
39114678Skan
40114678Skan
41114678Skan#define G_LABEL_DISK_IDENT_DIR	"diskid"
42114678Skan
43114678Skanstatic char* classes_pass[] = { G_DISK_CLASS_NAME, G_MULTIPATH_CLASS_NAME,
44114678Skan    NULL };
45114678Skan
46114678Skanstatic void
47114678Skang_label_disk_ident_taste(struct g_consumer *cp, char *label, size_t size)
48114678Skan{
49115164Skan	struct g_class *cls;
50115164Skan	char ident[100];
51113941Skan	int ident_len, found, i;
52113941Skan
5366458Sdfr	g_topology_assert_not();
54113941Skan	label[0] = '\0';
5566458Sdfr
56113941Skan	cls = cp->provider->geom->class;
57113941Skan
58113941Skan	/*
5966458Sdfr	 * Get the GEOM::ident string, and construct a label in the format
60113941Skan	 * "CLASS_NAME-ident"
61113941Skan	 */
62113941Skan	ident_len = sizeof(ident);
6366458Sdfr	if (g_io_getattr("GEOM::ident", cp, &ident_len, ident) == 0) {
64113941Skan		if (ident_len == 0 || ident[0] == '\0')
65113941Skan			return;
66113941Skan		for (i = 0, found = 0; classes_pass[i] != NULL; i++)
67113941Skan			if (strcmp(classes_pass[i], cls->name) == 0) {
6867488Sobrien				found = 1;
6967488Sobrien				break;
70113941Skan			}
71113941Skan		if (!found)
72113941Skan			return;
7367488Sobrien		/*
74113941Skan		 * We can safely ignore the result of strncpy; the label will
7566458Sdfr		 * simply be truncated, which at most is only annoying.
76113941Skan		 */
7766458Sdfr		(void)snprintf(label, size, "%s-%s", cls->name, ident);
78113941Skan	}
79113941Skan}
8081720Sache
8167488Sobrienstruct g_label_desc g_label_disk_ident = {
82113941Skan	.ld_taste = g_label_disk_ident_taste,
83113941Skan	.ld_dir = G_LABEL_DISK_IDENT_DIR,
84113941Skan	.ld_enabled = 1
8566458Sdfr};
86113941Skan
87113941SkanG_LABEL_INIT(disk_ident, g_label_disk_ident, "Create device nodes for drives "
8866458Sdfr    "which export a disk identification string");
89113941Skan