nrelease: Clean up a bit the 'clean' target
[dragonfly.git] / usr.sbin / fstyp / hammer.c
blob722cfde98690766c36a1d9131b30365bdf7505bc
1 /*-
2 * Copyright (c) 2016-2019 The DragonFly Project
3 * Copyright (c) 2016-2019 Tomohiro Kusumi <tkusumi@netbsd.org>
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <err.h>
32 #include <uuid.h>
33 #include <vfs/hammer/hammer_disk.h>
35 #include "fstyp.h"
37 static hammer_volume_ondisk_t
38 read_ondisk(FILE *fp)
40 return (read_buf(fp, 0, sizeof(struct hammer_volume_ondisk)));
43 static int
44 test_ondisk(const hammer_volume_ondisk_t ondisk)
46 static int count = 0;
47 static hammer_uuid_t fsid, fstype;
48 static char label[64];
50 if (ondisk->vol_signature != HAMMER_FSBUF_VOLUME &&
51 ondisk->vol_signature != HAMMER_FSBUF_VOLUME_REV)
52 return (1);
53 if (ondisk->vol_rootvol != HAMMER_ROOT_VOLNO)
54 return (1);
55 if (ondisk->vol_no < 0 || ondisk->vol_no > HAMMER_MAX_VOLUMES - 1)
56 return (1);
57 if (ondisk->vol_count < 1 || ondisk->vol_count > HAMMER_MAX_VOLUMES)
58 return (1);
60 if (count == 0) {
61 count = ondisk->vol_count;
62 if (count == 0)
63 return (1);
64 memcpy(&fsid, &ondisk->vol_fsid, sizeof(fsid));
65 memcpy(&fstype, &ondisk->vol_fstype, sizeof(fstype));
66 strlcpy(label, ondisk->vol_label, sizeof(label));
67 } else {
68 if (ondisk->vol_count != count)
69 return (1);
70 if (!uuid_equal(&ondisk->vol_fsid, &fsid, NULL))
71 return (1);
72 if (!uuid_equal(&ondisk->vol_fstype, &fstype, NULL))
73 return (1);
74 if (strcmp(ondisk->vol_label, label))
75 return (1);
78 return (0);
81 static const char*
82 extract_device_name(const char *devpath)
84 const char *p;
86 p = strrchr(devpath, '/');
87 if (p) {
88 p++;
89 if (*p == 0)
90 p = NULL;
91 } else {
92 p = devpath;
94 return (p);
97 int
98 fstyp_hammer(FILE *fp, char *label, size_t size, const char *devpath)
100 hammer_volume_ondisk_t ondisk;
101 int error = 1;
102 #ifdef HAS_DEVPATH
103 const char *p;
104 #endif
105 ondisk = read_ondisk(fp);
106 if (!ondisk)
107 goto fail;
108 if (ondisk->vol_no != HAMMER_ROOT_VOLNO)
109 goto fail;
110 if (ondisk->vol_count != 1)
111 goto fail;
112 if (test_ondisk(ondisk))
113 goto fail;
116 * fstyp_function in DragonFly takes an additional devpath argument
117 * which doesn't exist in FreeBSD and NetBSD.
119 #ifdef HAS_DEVPATH
120 /* Add device name to help support multiple autofs -media mounts. */
121 p = extract_device_name(devpath);
122 if (p)
123 snprintf(label, size, "%s_%s", ondisk->vol_label, p);
124 else
125 strlcpy(label, ondisk->vol_label, size);
126 #else
127 strlcpy(label, ondisk->vol_label, size);
128 #endif
129 error = 0;
130 fail:
131 free(ondisk);
132 return (error);
135 static int
136 test_volume(const char *volpath)
138 hammer_volume_ondisk_t ondisk = NULL;
139 FILE *fp;
140 int volno = -1;
142 if ((fp = fopen(volpath, "r")) == NULL)
143 goto fail;
145 ondisk = read_ondisk(fp);
146 if (!ondisk)
147 goto fail;
148 if (test_ondisk(ondisk))
149 goto fail;
151 volno = ondisk->vol_no;
152 fail:
153 if (fp)
154 fclose(fp);
155 free(ondisk);
156 return (volno);
159 static int
160 __fsvtyp_hammer(const char *blkdevs, char *label, size_t size, int partial)
162 hammer_volume_ondisk_t ondisk = NULL;
163 FILE *fp = NULL;
164 char *dup = NULL, *p, *volpath, *rootvolpath, x[HAMMER_MAX_VOLUMES];
165 int i, volno, error = 1;
167 if (!blkdevs)
168 goto fail;
170 memset(x, 0, sizeof(x));
171 dup = strdup(blkdevs);
172 p = dup;
174 volpath = NULL;
175 rootvolpath = NULL;
176 volno = -1;
177 while (p) {
178 volpath = p;
179 if ((p = strchr(p, ':')) != NULL)
180 *p++ = '\0';
181 if ((volno = test_volume(volpath)) == -1)
182 break;
183 if (volno < 0 || volno >= HAMMER_MAX_VOLUMES)
184 goto fail;
185 x[volno]++;
186 if (volno == HAMMER_ROOT_VOLNO)
187 rootvolpath = volpath;
190 /* If no rootvolpath, proceed only if partial mode with volpath. */
191 if (rootvolpath)
192 volpath = rootvolpath;
193 else if (!partial || !volpath)
194 goto fail;
195 if ((fp = fopen(volpath, "r")) == NULL)
196 goto fail;
197 ondisk = read_ondisk(fp);
198 if (!ondisk)
199 goto fail;
201 if (volno == -1)
202 goto fail;
203 if (partial)
204 goto success;
206 for (i = 0; i < HAMMER_MAX_VOLUMES; i++)
207 if (x[i] > 1)
208 goto fail;
209 for (i = 0; i < HAMMER_MAX_VOLUMES; i++)
210 if (x[i] == 0)
211 break;
212 if (ondisk->vol_count != i)
213 goto fail;
214 for (; i < HAMMER_MAX_VOLUMES; i++)
215 if (x[i] != 0)
216 goto fail;
217 success:
218 /* Add device name to help support multiple autofs -media mounts. */
219 p = (char*)extract_device_name(volpath);
220 if (p)
221 snprintf(label, size, "%s_%s", ondisk->vol_label, p);
222 else
223 strlcpy(label, ondisk->vol_label, size);
224 error = 0;
225 fail:
226 if (fp)
227 fclose(fp);
228 free(ondisk);
229 free(dup);
230 return (error);
234 fsvtyp_hammer(const char *blkdevs, char *label, size_t size)
236 return (__fsvtyp_hammer(blkdevs, label, size, 0));
240 fsvtyp_hammer_partial(const char *blkdevs, char *label, size_t size)
242 return (__fsvtyp_hammer(blkdevs, label, size, 1));