xref: /dragonfly/lib/libhammer/info.c (revision 431893ca)
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 Antonio Huete <tuxillo@quantumachine.net>
6cb7575e6SAntonio Huete Jimenez  *
7cb7575e6SAntonio Huete Jimenez  * Redistribution and use in source and binary forms, with or without
8cb7575e6SAntonio Huete Jimenez  * modification, are permitted provided that the following conditions
9cb7575e6SAntonio Huete Jimenez  * are met:
10cb7575e6SAntonio Huete Jimenez  *
11cb7575e6SAntonio Huete Jimenez  * 1. Redistributions of source code must retain the above copyright
12cb7575e6SAntonio Huete Jimenez  *    notice, this list of conditions and the following disclaimer.
13cb7575e6SAntonio Huete Jimenez  * 2. Redistributions in binary form must reproduce the above copyright
14cb7575e6SAntonio Huete Jimenez  *    notice, this list of conditions and the following disclaimer in
15cb7575e6SAntonio Huete Jimenez  *    the documentation and/or other materials provided with the
16cb7575e6SAntonio Huete Jimenez  *    distribution.
17cb7575e6SAntonio Huete Jimenez  * 3. Neither the name of The DragonFly Project nor the names of its
18cb7575e6SAntonio Huete Jimenez  *    contributors may be used to endorse or promote products derived
19cb7575e6SAntonio Huete Jimenez  *    from this software without specific, prior written permission.
20cb7575e6SAntonio Huete Jimenez  *
21cb7575e6SAntonio Huete Jimenez  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22cb7575e6SAntonio Huete Jimenez  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23cb7575e6SAntonio Huete Jimenez  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24cb7575e6SAntonio Huete Jimenez  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25cb7575e6SAntonio Huete Jimenez  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26cb7575e6SAntonio Huete Jimenez  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27cb7575e6SAntonio Huete Jimenez  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28cb7575e6SAntonio Huete Jimenez  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29cb7575e6SAntonio Huete Jimenez  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30cb7575e6SAntonio Huete Jimenez  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31cb7575e6SAntonio Huete Jimenez  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32cb7575e6SAntonio Huete Jimenez  * SUCH DAMAGE.
33cb7575e6SAntonio Huete Jimenez  */
34c8fec8afSAntonio Huete Jimenez 
35cb7575e6SAntonio Huete Jimenez #include <dirent.h>
36cb7575e6SAntonio Huete Jimenez #include <err.h>
37cb7575e6SAntonio Huete Jimenez #include <errno.h>
38cb7575e6SAntonio Huete Jimenez #include <fcntl.h>
39cb7575e6SAntonio Huete Jimenez #include <stdio.h>
40cb7575e6SAntonio Huete Jimenez #include <stdlib.h>
41cb7575e6SAntonio Huete Jimenez #include <string.h>
42cb7575e6SAntonio Huete Jimenez #include <sys/param.h>
43cb7575e6SAntonio Huete Jimenez #include <sys/stat.h>
44cb7575e6SAntonio Huete Jimenez #include <unistd.h>
45cb7575e6SAntonio Huete Jimenez 
463729b417SAntonio Huete Jimenez #include "libhammer.h"
47cb7575e6SAntonio Huete Jimenez 
48cb7575e6SAntonio Huete Jimenez static u_int32_t count_snapshots(u_int32_t, char *, char *, int *);
49cb7575e6SAntonio Huete Jimenez 
50cb7575e6SAntonio Huete Jimenez libhammer_volinfo_t
51cb7575e6SAntonio Huete Jimenez libhammer_get_volinfo(const char *path)
52cb7575e6SAntonio Huete Jimenez {
53cb7575e6SAntonio Huete Jimenez 	struct hammer_pseudofs_data *pfs_od;
54*431893caSAntonio Huete Jimenez 	struct hammer_ioc_pfs_iterate pi;
55cb7575e6SAntonio Huete Jimenez 	struct hammer_ioc_info info;
56cb7575e6SAntonio Huete Jimenez 	libhammer_pfsinfo_t pfstmp;
57cb7575e6SAntonio Huete Jimenez 	libhammer_volinfo_t hvi;
58*431893caSAntonio Huete Jimenez 	int error = 0;
59cb7575e6SAntonio Huete Jimenez 	int fd;
60cb7575e6SAntonio Huete Jimenez 
61cb7575e6SAntonio Huete Jimenez 	if ((fd = open(path, O_RDONLY)) < 0)
62c8fec8afSAntonio Huete Jimenez 		return NULL;
63cb7575e6SAntonio Huete Jimenez 
64c8fec8afSAntonio Huete Jimenez 	hvi = _libhammer_malloc(sizeof(*hvi));
65c8fec8afSAntonio Huete Jimenez 	TAILQ_INIT(&hvi->list_pseudo);
66c8fec8afSAntonio Huete Jimenez 	if ((ioctl(fd, HAMMERIOC_GET_INFO, &info)) < 0) {
67c8fec8afSAntonio Huete Jimenez 		libhammer_free_volinfo(hvi);
68c8fec8afSAntonio Huete Jimenez 		close(fd);
69c8fec8afSAntonio Huete Jimenez 		return NULL;
70c8fec8afSAntonio Huete Jimenez 	}
71cb7575e6SAntonio Huete Jimenez 
72cb7575e6SAntonio Huete Jimenez 	/* Fill volume information */
73cb7575e6SAntonio Huete Jimenez 	snprintf(hvi->vol_name, TXTLEN, "%s", info.vol_name);
74cb7575e6SAntonio Huete Jimenez 	hvi->vol_fsid = info.vol_fsid;
75cb7575e6SAntonio Huete Jimenez 	hvi->version = info.version;
76cb7575e6SAntonio Huete Jimenez 	hvi->nvolumes = info.nvolumes;
77925016b9SAntonio Huete Jimenez 	hvi->inodes = info.inodes;
78cb7575e6SAntonio Huete Jimenez 	hvi->bigblocks = info.bigblocks;
79e2fb4261SAntonio Huete Jimenez 	hvi->freebigblocks = info.freebigblocks;
80cb7575e6SAntonio Huete Jimenez 	hvi->rsvbigblocks = info.rsvbigblocks;
81cb7575e6SAntonio Huete Jimenez 
82*431893caSAntonio Huete Jimenez 	bzero(&pi, sizeof(pi));
83*431893caSAntonio Huete Jimenez 	pi.ondisk = _libhammer_malloc(sizeof(*pfs_od));
84*431893caSAntonio Huete Jimenez 	while(error == 0) {
85*431893caSAntonio Huete Jimenez 		error = ioctl(fd, HAMMERIOC_PFS_ITERATE, &pi);
86*431893caSAntonio Huete Jimenez 		if (error == 0 &&
87*431893caSAntonio Huete Jimenez 		    ((pi.head.flags & HAMMER_PFSD_DELETED) == 0)) {
88c8fec8afSAntonio Huete Jimenez 			/*
89c8fec8afSAntonio Huete Jimenez 			 * XXX - In the case the path passed is on PFS#0 but it
90c8fec8afSAntonio Huete Jimenez 			 * is not the mountpoint itself, it could produce a
91c8fec8afSAntonio Huete Jimenez 			 * wrong type of PFS.
92cb7575e6SAntonio Huete Jimenez 			 */
93c8fec8afSAntonio Huete Jimenez 			pfstmp = _libhammer_malloc(sizeof(*pfstmp));
94*431893caSAntonio Huete Jimenez 			pfs_od = pi.ondisk;
95c8fec8afSAntonio Huete Jimenez 			pfstmp->ismaster =
96c8fec8afSAntonio Huete Jimenez 			    (pfs_od->mirror_flags & HAMMER_PFSD_SLAVE) ? 0 : 1;
97cb7575e6SAntonio Huete Jimenez 
98*431893caSAntonio Huete Jimenez 			if (pi.pos == 0)
99cb7575e6SAntonio Huete Jimenez 				pfstmp->mountedon = strdup(path);
100cb7575e6SAntonio Huete Jimenez 			else
101c8fec8afSAntonio Huete Jimenez 				pfstmp->mountedon =
102*431893caSAntonio Huete Jimenez 				    libhammer_find_pfs_mount(pi.pos,
103cb7575e6SAntonio Huete Jimenez 					hvi->vol_fsid, pfstmp->ismaster);
104cb7575e6SAntonio Huete Jimenez 			/*
105cb7575e6SAntonio Huete Jimenez 			 * Fill in structs used in the library. We don't rely on
106cb7575e6SAntonio Huete Jimenez 			 * HAMMER own struct but we do fill our own.
107cb7575e6SAntonio Huete Jimenez 			 */
108*431893caSAntonio Huete Jimenez 			pfstmp->version = hvi->version;
109*431893caSAntonio Huete Jimenez 			pfstmp->pfs_id = pi.pos;
110cb7575e6SAntonio Huete Jimenez 			pfstmp->mirror_flags = pfs_od->mirror_flags;
111cb7575e6SAntonio Huete Jimenez 			pfstmp->snapcount = count_snapshots(hvi->version,
112c8fec8afSAntonio Huete Jimenez 			    pfstmp->snapshots, pfstmp->mountedon,
113c8fec8afSAntonio Huete Jimenez 			    &pfstmp->head.error);
114cb7575e6SAntonio Huete Jimenez 
115cb7575e6SAntonio Huete Jimenez 			TAILQ_INSERT_TAIL(&hvi->list_pseudo, pfstmp, entries);
116cb7575e6SAntonio Huete Jimenez 		}
117*431893caSAntonio Huete Jimenez 		pi.pos++;
118cb7575e6SAntonio Huete Jimenez 	}
119*431893caSAntonio Huete Jimenez 	free(pi.ondisk);
120*431893caSAntonio Huete Jimenez 
121cb7575e6SAntonio Huete Jimenez 	close (fd);
122cb7575e6SAntonio Huete Jimenez 
123cb7575e6SAntonio Huete Jimenez 	return (hvi);
124cb7575e6SAntonio Huete Jimenez }
125cb7575e6SAntonio Huete Jimenez 
126cb7575e6SAntonio Huete Jimenez void
127cb7575e6SAntonio Huete Jimenez libhammer_free_volinfo(libhammer_volinfo_t volinfo)
128cb7575e6SAntonio Huete Jimenez {
129cb7575e6SAntonio Huete Jimenez 	struct libhammer_pfsinfo *pfstmp;
130cb7575e6SAntonio Huete Jimenez 
131cb7575e6SAntonio Huete Jimenez 	while(!TAILQ_EMPTY(&volinfo->list_pseudo)) {
132cb7575e6SAntonio Huete Jimenez 		pfstmp = TAILQ_FIRST(&volinfo->list_pseudo);
133cb7575e6SAntonio Huete Jimenez 		free(pfstmp->mountedon);
134cb7575e6SAntonio Huete Jimenez 		TAILQ_REMOVE(&volinfo->list_pseudo, pfstmp, entries);
135cb7575e6SAntonio Huete Jimenez 		free(pfstmp);
136cb7575e6SAntonio Huete Jimenez 	}
137cb7575e6SAntonio Huete Jimenez 	free(volinfo);
138cb7575e6SAntonio Huete Jimenez }
139cb7575e6SAntonio Huete Jimenez 
140cb7575e6SAntonio Huete Jimenez static u_int32_t
141c8fec8afSAntonio Huete Jimenez count_snapshots(u_int32_t version, char *pfs_snapshots, char *mountedon,
142c8fec8afSAntonio Huete Jimenez     int *errorp)
143cb7575e6SAntonio Huete Jimenez {
144cb7575e6SAntonio Huete Jimenez 	struct hammer_ioc_snapshot snapinfo;
145cb7575e6SAntonio Huete Jimenez 	char *snapshots_path, *fpath;
146cb7575e6SAntonio Huete Jimenez 	struct dirent *den;
147cb7575e6SAntonio Huete Jimenez 	struct stat st;
148cb7575e6SAntonio Huete Jimenez 	DIR *dir;
149cb7575e6SAntonio Huete Jimenez 	u_int32_t snapshot_count;
150cb7575e6SAntonio Huete Jimenez 	int fd;
151cb7575e6SAntonio Huete Jimenez 
152cb7575e6SAntonio Huete Jimenez 	snapshot_count = 0;
153cb7575e6SAntonio Huete Jimenez 
154cb7575e6SAntonio Huete Jimenez 	bzero(&snapinfo, sizeof(struct hammer_ioc_snapshot));
155cb7575e6SAntonio Huete Jimenez 
156cb7575e6SAntonio Huete Jimenez 	fd = open(mountedon, O_RDONLY);
157cb7575e6SAntonio Huete Jimenez 	if (fd < 0) {
158cb7575e6SAntonio Huete Jimenez 		*errorp = errno;
159cb7575e6SAntonio Huete Jimenez 		return 0;
160cb7575e6SAntonio Huete Jimenez 	}
161cb7575e6SAntonio Huete Jimenez 
162cb7575e6SAntonio Huete Jimenez 	if (version < 3) {
163cb7575e6SAntonio Huete Jimenez 		/*
164cb7575e6SAntonio Huete Jimenez 		 * old style: count the number of softlinks in the snapshots dir
165cb7575e6SAntonio Huete Jimenez 		 */
166cb7575e6SAntonio Huete Jimenez 		if (pfs_snapshots[0])
167cb7575e6SAntonio Huete Jimenez 			snapshots_path = pfs_snapshots;
168cb7575e6SAntonio Huete Jimenez 		else
169cb7575e6SAntonio Huete Jimenez 			asprintf(&snapshots_path, "%s/snapshots", mountedon);
170cb7575e6SAntonio Huete Jimenez 		if ((dir = opendir(snapshots_path)) != NULL) {
171cb7575e6SAntonio Huete Jimenez 			while ((den = readdir(dir)) != NULL) {
172cb7575e6SAntonio Huete Jimenez 				if (den->d_name[0] == '.')
173cb7575e6SAntonio Huete Jimenez 					continue;
174cb7575e6SAntonio Huete Jimenez 				asprintf(&fpath, "%s/%s", snapshots_path,
175cb7575e6SAntonio Huete Jimenez 				    den->d_name);
176cb7575e6SAntonio Huete Jimenez 				if (lstat(fpath, &st) == 0 &&
177cb7575e6SAntonio Huete Jimenez 				    S_ISLNK(st.st_mode))
178cb7575e6SAntonio Huete Jimenez 					snapshot_count++;
179cb7575e6SAntonio Huete Jimenez 				free(fpath);
180cb7575e6SAntonio Huete Jimenez 			}
181cb7575e6SAntonio Huete Jimenez 			closedir(dir);
182cb7575e6SAntonio Huete Jimenez 		}
183cb7575e6SAntonio Huete Jimenez 	} else {
184cb7575e6SAntonio Huete Jimenez 		/*
185cb7575e6SAntonio Huete Jimenez 		 * new style: file system meta-data
186cb7575e6SAntonio Huete Jimenez 		 */
187cb7575e6SAntonio Huete Jimenez 		do {
188cb7575e6SAntonio Huete Jimenez 			if (ioctl(fd, HAMMERIOC_GET_SNAPSHOT, &snapinfo) < 0) {
189cb7575e6SAntonio Huete Jimenez 				*errorp = errno;
190cb7575e6SAntonio Huete Jimenez 				goto out;
191cb7575e6SAntonio Huete Jimenez 			}
192cb7575e6SAntonio Huete Jimenez 
193cb7575e6SAntonio Huete Jimenez 			snapshot_count += snapinfo.count;
194cb7575e6SAntonio Huete Jimenez 		} while (snapinfo.head.error == 0 && snapinfo.count);
195cb7575e6SAntonio Huete Jimenez 	}
196cb7575e6SAntonio Huete Jimenez 
197cb7575e6SAntonio Huete Jimenez out:
198afc801daSAntonio Huete Jimenez 	if (!pfs_snapshots[0])
199afc801daSAntonio Huete Jimenez 		free(snapshots_path);
200cb7575e6SAntonio Huete Jimenez 	if (fd != -1)
201cb7575e6SAntonio Huete Jimenez 		close(fd);
202cb7575e6SAntonio Huete Jimenez 	return snapshot_count;
203cb7575e6SAntonio Huete Jimenez }
204