1cb7575e6SAntonio Huete Jimenez /*
2cb7575e6SAntonio Huete Jimenez * Copyright (c) 2011 The DragonFly Project. All rights reserved.
3cb7575e6SAntonio Huete Jimenez *
4cb7575e6SAntonio Huete Jimenez * This code is derived from software contributed to The DragonFly Project
5cb7575e6SAntonio Huete Jimenez * by Matthew Dillon <dillon@backplane.com>
6cb7575e6SAntonio Huete Jimenez * by Antonio Huete <tuxillo@quantumachine.net>
7cb7575e6SAntonio Huete Jimenez *
8cb7575e6SAntonio Huete Jimenez * Redistribution and use in source and binary forms, with or without
9cb7575e6SAntonio Huete Jimenez * modification, are permitted provided that the following conditions
10cb7575e6SAntonio Huete Jimenez * are met:
11cb7575e6SAntonio Huete Jimenez *
12cb7575e6SAntonio Huete Jimenez * 1. Redistributions of source code must retain the above copyright
13cb7575e6SAntonio Huete Jimenez * notice, this list of conditions and the following disclaimer.
14cb7575e6SAntonio Huete Jimenez * 2. Redistributions in binary form must reproduce the above copyright
15cb7575e6SAntonio Huete Jimenez * notice, this list of conditions and the following disclaimer in
16cb7575e6SAntonio Huete Jimenez * the documentation and/or other materials provided with the
17cb7575e6SAntonio Huete Jimenez * distribution.
18cb7575e6SAntonio Huete Jimenez * 3. Neither the name of The DragonFly Project nor the names of its
19cb7575e6SAntonio Huete Jimenez * contributors may be used to endorse or promote products derived
20cb7575e6SAntonio Huete Jimenez * from this software without specific, prior written permission.
21cb7575e6SAntonio Huete Jimenez *
22cb7575e6SAntonio Huete Jimenez * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23cb7575e6SAntonio Huete Jimenez * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24cb7575e6SAntonio Huete Jimenez * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25cb7575e6SAntonio Huete Jimenez * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26cb7575e6SAntonio Huete Jimenez * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27cb7575e6SAntonio Huete Jimenez * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28cb7575e6SAntonio Huete Jimenez * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29cb7575e6SAntonio Huete Jimenez * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30cb7575e6SAntonio Huete Jimenez * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31cb7575e6SAntonio Huete Jimenez * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32cb7575e6SAntonio Huete Jimenez * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33cb7575e6SAntonio Huete Jimenez * SUCH DAMAGE.
34cb7575e6SAntonio Huete Jimenez */
35*a77d0377SAntonio Huete Jimenez
36*a77d0377SAntonio Huete Jimenez #include <assert.h>
37cb7575e6SAntonio Huete Jimenez #include <fcntl.h>
38cb7575e6SAntonio Huete Jimenez #include <err.h>
39cb7575e6SAntonio Huete Jimenez #include <stdio.h>
40cb7575e6SAntonio Huete Jimenez #include <stdlib.h>
41cb7575e6SAntonio Huete Jimenez #include <string.h>
42cb7575e6SAntonio Huete Jimenez
43*a77d0377SAntonio Huete Jimenez #include <sys/types.h>
44*a77d0377SAntonio Huete Jimenez #include <sys/stat.h>
45cb7575e6SAntonio Huete Jimenez #include <sys/mount.h>
46cb7575e6SAntonio Huete Jimenez #include <unistd.h>
47cb7575e6SAntonio Huete Jimenez #include <uuid.h>
48cb7575e6SAntonio Huete Jimenez
493729b417SAntonio Huete Jimenez #include "libhammer.h"
50cb7575e6SAntonio Huete Jimenez
51cb7575e6SAntonio Huete Jimenez char *
libhammer_find_pfs_mount(uuid_t * unique_uuid)52d428efb7SAntonio Huete Jimenez libhammer_find_pfs_mount(uuid_t *unique_uuid)
53cb7575e6SAntonio Huete Jimenez {
54d428efb7SAntonio Huete Jimenez struct hammer_ioc_pseudofs_rw pfs;
55d428efb7SAntonio Huete Jimenez struct hammer_pseudofs_data pfsd;
56cb7575e6SAntonio Huete Jimenez struct statfs *mntbuf;
57cb7575e6SAntonio Huete Jimenez int mntsize;
58cb7575e6SAntonio Huete Jimenez int curmount;
59cb7575e6SAntonio Huete Jimenez int fd;
60cb7575e6SAntonio Huete Jimenez size_t mntbufsize;
61d428efb7SAntonio Huete Jimenez uuid_t uuid;
62cb7575e6SAntonio Huete Jimenez char *retval;
63cb7575e6SAntonio Huete Jimenez
64cb7575e6SAntonio Huete Jimenez retval = NULL;
65cb7575e6SAntonio Huete Jimenez
66cb7575e6SAntonio Huete Jimenez /* Do not continue if there are no mounted filesystems */
67cb7575e6SAntonio Huete Jimenez mntsize = getfsstat(NULL, 0, MNT_NOWAIT);
68cb7575e6SAntonio Huete Jimenez if (mntsize <= 0)
69cb7575e6SAntonio Huete Jimenez return retval;
70cb7575e6SAntonio Huete Jimenez
71e8308858STomohiro Kusumi mntbufsize = mntsize * sizeof(struct statfs);
72cb7575e6SAntonio Huete Jimenez mntbuf = _libhammer_malloc(mntbufsize);
73cb7575e6SAntonio Huete Jimenez
74cb7575e6SAntonio Huete Jimenez mntsize = getfsstat(mntbuf, (long)mntbufsize, MNT_NOWAIT);
75cb7575e6SAntonio Huete Jimenez curmount = mntsize - 1;
76cb7575e6SAntonio Huete Jimenez
77cb7575e6SAntonio Huete Jimenez /*
78cb7575e6SAntonio Huete Jimenez * Iterate all the mounted points looking for the PFS passed to
79cb7575e6SAntonio Huete Jimenez * this function.
80cb7575e6SAntonio Huete Jimenez */
81cb7575e6SAntonio Huete Jimenez while(curmount >= 0) {
824ac019b8STomohiro Kusumi struct statfs *mnt = &mntbuf[curmount];
83cb7575e6SAntonio Huete Jimenez /*
84d428efb7SAntonio Huete Jimenez * Discard any non null(5) or hammer(5) filesystems as synthetic
85d428efb7SAntonio Huete Jimenez * filesystems like procfs(5) could accept ioctl calls and thus
86d428efb7SAntonio Huete Jimenez * produce bogus results.
87cb7575e6SAntonio Huete Jimenez */
88d428efb7SAntonio Huete Jimenez if ((strcmp("hammer", mnt->f_fstypename) != 0) &&
89d428efb7SAntonio Huete Jimenez (strcmp("null", mnt->f_fstypename) != 0)) {
90cb7575e6SAntonio Huete Jimenez curmount--;
91cb7575e6SAntonio Huete Jimenez continue;
92cb7575e6SAntonio Huete Jimenez }
93d428efb7SAntonio Huete Jimenez bzero(&pfs, sizeof(pfs));
94d428efb7SAntonio Huete Jimenez bzero(&pfsd, sizeof(pfsd));
95d428efb7SAntonio Huete Jimenez pfs.pfs_id = -1;
96d428efb7SAntonio Huete Jimenez pfs.ondisk = &pfsd;
97d428efb7SAntonio Huete Jimenez pfs.bytes = sizeof(struct hammer_pseudofs_data);
98d428efb7SAntonio Huete Jimenez fd = open(mnt->f_mntonname, O_RDONLY);
990b4d026eSAntonio Huete Jimenez if (fd < 0 || (ioctl(fd, HAMMERIOC_GET_PSEUDOFS, &pfs) < 0)) {
10042cb3c2bSTomohiro Kusumi close(fd);
101cb7575e6SAntonio Huete Jimenez curmount--;
102cb7575e6SAntonio Huete Jimenez continue;
103cb7575e6SAntonio Huete Jimenez }
104cb7575e6SAntonio Huete Jimenez
105d428efb7SAntonio Huete Jimenez memcpy(&uuid, &pfs.ondisk->unique_uuid, sizeof(uuid));
106d428efb7SAntonio Huete Jimenez if (uuid_compare(unique_uuid, &uuid, NULL) == 0) {
1074ac019b8STomohiro Kusumi retval = strdup(mnt->f_mntonname);
1080b4d026eSAntonio Huete Jimenez close(fd);
109cb7575e6SAntonio Huete Jimenez break;
110cb7575e6SAntonio Huete Jimenez }
111d428efb7SAntonio Huete Jimenez
112cb7575e6SAntonio Huete Jimenez curmount--;
113cb7575e6SAntonio Huete Jimenez close(fd);
114cb7575e6SAntonio Huete Jimenez }
11542cb3c2bSTomohiro Kusumi free(mntbuf);
116cb7575e6SAntonio Huete Jimenez
117cb7575e6SAntonio Huete Jimenez return retval;
118cb7575e6SAntonio Huete Jimenez }
119cb7575e6SAntonio Huete Jimenez
120cb7575e6SAntonio Huete Jimenez /*
121*a77d0377SAntonio Huete Jimenez * Find out the path that can be used to open(2) a PFS
122*a77d0377SAntonio Huete Jimenez * when it is not mounted. It allocates *path so the
123*a77d0377SAntonio Huete Jimenez * caller is in charge of freeing it up.
124*a77d0377SAntonio Huete Jimenez */
125*a77d0377SAntonio Huete Jimenez void
libhammer_pfs_canonical_path(char * mtpt,libhammer_pfsinfo_t pip,char ** path)126*a77d0377SAntonio Huete Jimenez libhammer_pfs_canonical_path(char * mtpt, libhammer_pfsinfo_t pip, char **path)
127*a77d0377SAntonio Huete Jimenez {
128*a77d0377SAntonio Huete Jimenez struct statfs st;
129*a77d0377SAntonio Huete Jimenez
130*a77d0377SAntonio Huete Jimenez assert(pip != NULL);
131*a77d0377SAntonio Huete Jimenez assert(mtpt != NULL);
132*a77d0377SAntonio Huete Jimenez
133*a77d0377SAntonio Huete Jimenez if ((statfs(mtpt, &st) < 0) ||
134*a77d0377SAntonio Huete Jimenez ((strcmp("hammer", st.f_fstypename) != 0) &&
135*a77d0377SAntonio Huete Jimenez (strcmp("null", st.f_fstypename) != 0))) {
136*a77d0377SAntonio Huete Jimenez *path = NULL;
137*a77d0377SAntonio Huete Jimenez return;
138*a77d0377SAntonio Huete Jimenez }
139*a77d0377SAntonio Huete Jimenez
140*a77d0377SAntonio Huete Jimenez if (pip->ismaster)
141*a77d0377SAntonio Huete Jimenez asprintf(path, "%s/@@-1:%.5d", mtpt,
142*a77d0377SAntonio Huete Jimenez pip->pfs_id);
143*a77d0377SAntonio Huete Jimenez else
144*a77d0377SAntonio Huete Jimenez asprintf(path, "%s/@@0x%016jx:%.5d", mtpt,
145*a77d0377SAntonio Huete Jimenez pip->end_tid, pip->pfs_id);
146*a77d0377SAntonio Huete Jimenez }
147*a77d0377SAntonio Huete Jimenez
148*a77d0377SAntonio Huete Jimenez
149*a77d0377SAntonio Huete Jimenez /*
150cb7575e6SAntonio Huete Jimenez * Allocate len bytes of memory and return the pointer.
151cb7575e6SAntonio Huete Jimenez * It'll exit in the case no memory could be allocated.
152cb7575e6SAntonio Huete Jimenez *
153cb7575e6SAntonio Huete Jimenez * To be used only by the library itself.
154cb7575e6SAntonio Huete Jimenez */
155cb7575e6SAntonio Huete Jimenez void *
_libhammer_malloc(size_t len)156cb7575e6SAntonio Huete Jimenez _libhammer_malloc(size_t len)
157cb7575e6SAntonio Huete Jimenez {
158cb7575e6SAntonio Huete Jimenez void *m;
159cb7575e6SAntonio Huete Jimenez
160cb7575e6SAntonio Huete Jimenez m = calloc(len, sizeof(char));
161cb7575e6SAntonio Huete Jimenez if (m == NULL)
162cb7575e6SAntonio Huete Jimenez errx(1, "Failed to allocate %zd bytes", len);
163cb7575e6SAntonio Huete Jimenez
164cb7575e6SAntonio Huete Jimenez return (m);
165cb7575e6SAntonio Huete Jimenez }
166