Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/devname2devid.c
48529 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* The contents of this file are subject to the terms of the
6
* Common Development and Distribution License (the "License").
7
* You may not use this file except in compliance with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or https://opensource.org/licenses/CDDL-1.0.
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
/*
24
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
25
* Use is subject to license terms.
26
*
27
* Copyright (c) 2016, Intel Corporation.
28
*/
29
30
#include <sys/types.h>
31
#include <sys/param.h>
32
#include <sys/stat.h>
33
#include <libudev.h>
34
#include <errno.h>
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <string.h>
38
#include <fcntl.h>
39
40
/*
41
* Linux persistent device strings for vdev labels
42
*
43
* based on udev_device_get_devid() at zfs/lib/libzfs/libzfs_import.c
44
*/
45
46
#define DEV_BYID_PATH "/dev/disk/by-id/"
47
48
static int
49
udev_device_get_devid(struct udev_device *dev, char *bufptr, size_t buflen)
50
{
51
struct udev_list_entry *entry;
52
const char *bus;
53
char devbyid[MAXPATHLEN];
54
55
/* The bus based by-id path is preferred */
56
bus = udev_device_get_property_value(dev, "ID_BUS");
57
58
if (bus == NULL) {
59
const char *dm_uuid;
60
61
/*
62
* For multipath nodes use the persistent uuid based identifier
63
*
64
* Example: 'dm-uuid-mpath-35000c5006304de3f'
65
*/
66
dm_uuid = udev_device_get_property_value(dev, "DM_UUID");
67
if (dm_uuid != NULL) {
68
(void) snprintf(bufptr, buflen, "dm-uuid-%s", dm_uuid);
69
return (0);
70
}
71
return (ENODATA);
72
}
73
74
/*
75
* locate the bus specific by-id link
76
*
77
* Example: 'scsi-MG03SCA300_350000494a8cb3d67-part1'
78
*/
79
(void) snprintf(devbyid, sizeof (devbyid), "%s%s-", DEV_BYID_PATH, bus);
80
entry = udev_device_get_devlinks_list_entry(dev);
81
while (entry != NULL) {
82
const char *name;
83
84
name = udev_list_entry_get_name(entry);
85
if (strncmp(name, devbyid, strlen(devbyid)) == 0) {
86
name += strlen(DEV_BYID_PATH);
87
(void) stpncpy(bufptr, name, buflen - 1);
88
bufptr[buflen - 1] = '\0';
89
return (0);
90
}
91
entry = udev_list_entry_get_next(entry);
92
}
93
94
return (ENODATA);
95
}
96
97
/*
98
* Usage: devname2devid <devicepath>
99
*
100
* Examples:
101
* # ./devname2devid /dev/sda1
102
* devid scsi-350000394a8caede4-part1
103
*
104
* # ./devname2devid /dev/dm-1
105
* devid: 'dm-uuid-mpath-35000c5006304de3f'
106
*
107
* This program accepts a disk or disk slice path and prints a
108
* device id.
109
*
110
* Exit values:
111
* 0 - means success
112
* 1 - means failure
113
*
114
*/
115
int
116
main(int argc, char *argv[])
117
{
118
struct udev *udev;
119
struct udev_device *dev = NULL;
120
char devid[128], nodepath[MAXPATHLEN];
121
char *device, *sysname;
122
int ret;
123
124
if (argc == 1) {
125
(void) printf("%s <devicepath> [search path]\n", argv[0]);
126
exit(1);
127
}
128
device = argv[1];
129
130
if ((udev = udev_new()) == NULL) {
131
perror("udev_new");
132
exit(1);
133
}
134
135
/* resolve path to a runtime device node instance */
136
if (realpath(device, nodepath) == NULL) {
137
perror("realpath");
138
exit(1);
139
}
140
sysname = strrchr(nodepath, '/') + 1;
141
142
if ((dev = udev_device_new_from_subsystem_sysname(udev, "block",
143
sysname)) == NULL) {
144
perror(sysname);
145
exit(1);
146
}
147
148
if ((ret = udev_device_get_devid(dev, devid, sizeof (devid))) != 0) {
149
udev_device_unref(dev);
150
errno = ret;
151
perror(sysname);
152
exit(1);
153
}
154
155
(void) printf("devid %s\n", devid);
156
157
udev_device_unref(dev);
158
udev_unref(udev);
159
160
return (0);
161
}
162
163