]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxcmd/paths.c
2 * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
39 #include <sys/types.h>
42 #include <xfs/input.h>
43 #include <xfs/project.h>
46 struct fs_path
*fs_table
;
47 struct fs_path
*fs_path
;
50 #define PROC_MOUNTS "/proc/self/mounts"
60 if (stat64(dir
, &sbuf
) < 0)
62 for (i
= 0; i
< fs_count
; i
++) {
63 if ((flags
& fs_table
[i
].fs_flags
) == 0)
65 if (sbuf
.st_dev
== fs_table
[i
].fs_datadev
)
81 dev_t datadev
, logdev
, rtdev
;
86 datadev
= logdev
= rtdev
= 0;
87 if (stat64(dir
, &sbuf
) < 0)
89 datadev
= sbuf
.st_dev
;
91 if (stat64(fslog
, &sbuf
) < 0)
96 if (stat64(fsrt
, &sbuf
) < 0)
101 fs_table
= realloc(fs_table
, sizeof(fs_path_t
) * (fs_count
+ 1));
105 fs_path
= &fs_table
[fs_count
];
106 fs_path
->fs_dir
= dir
;
107 fs_path
->fs_prid
= prid
;
108 fs_path
->fs_flags
= flags
;
109 fs_path
->fs_name
= fsname
;
110 fs_path
->fs_log
= fslog
;
111 fs_path
->fs_rt
= fsrt
;
112 fs_path
->fs_datadev
= datadev
;
113 fs_path
->fs_logdev
= logdev
;
114 fs_path
->fs_rtdev
= rtdev
;
120 if (fsrt
) free(fsrt
);
121 if (fslog
) free(fslog
);
122 if (fsname
) free(fsname
);
127 fs_table_destroy(void)
129 while (--fs_count
>= 0) {
130 free(fs_table
[fs_count
].fs_name
);
131 if (fs_table
[fs_count
].fs_log
)
132 free(fs_table
[fs_count
].fs_log
);
133 if (fs_table
[fs_count
].fs_rt
)
134 free(fs_table
[fs_count
].fs_rt
);
135 free(fs_table
[fs_count
].fs_dir
);
144 #if defined(HAVE_GETMNTENT)
148 fs_extract_mount_options(
153 char *fslog
, *fsrt
, *fslogend
, *fsrtend
;
155 fslog
= fsrt
= fslogend
= fsrtend
= NULL
;
157 /* Extract log device and realtime device from mount options */
158 if ((fslog
= hasmntopt(mnt
, "logdev=")))
160 if ((fsrt
= hasmntopt(mnt
, "rtdev=")))
163 /* Do this only after we've finished processing mount options */
165 fslogend
= strtok(fslog
, " ,");
166 fslog
= strdup(fslog
);
169 fsrtend
= strtok(fsrt
, " ,");
178 fs_table_initialise_mounts(
183 char *dir
= NULL
, *fsname
= NULL
, *fslog
, *fsrt
;
184 int error
= 0, found
= 0;
187 mtab_file
= PROC_MOUNTS
;
188 if (access(mtab_file
, R_OK
) != 0)
192 if ((mtp
= setmntent(mtab_file
, "r")) == NULL
)
195 while ((mnt
= getmntent(mtp
)) != NULL
) {
196 if (strcmp(mnt
->mnt_type
, "xfs") != 0)
199 ((strcmp(path
, mnt
->mnt_dir
) != 0) &&
200 (strcmp(path
, mnt
->mnt_fsname
) != 0)))
203 dir
= strdup(mnt
->mnt_dir
);
204 fsname
= strdup(mnt
->mnt_fsname
);
205 if (!dir
|| !fsname
) {
209 fs_extract_mount_options(mnt
, &fslog
, &fsrt
);
210 if ((error
= fs_table_insert(dir
, 0, FS_MOUNT_POINT
,
211 fsname
, fslog
, fsrt
)))
215 if (!error
&& path
&& !found
)
224 #elif defined(HAVE_GETMNTINFO)
225 #include <sys/mount.h>
228 fs_table_initialise_mounts(
231 struct statfs
*stats
;
232 char *dir
= NULL
, *fsname
= NULL
, *fslog
= NULL
, *fsrt
= NULL
;
233 int i
, count
, found
= 0, error
= 0;
235 if ((count
= getmntinfo(&stats
, 0)) < 0) {
236 perror("getmntinfo");
240 for (i
= 0; i
< count
; i
++) {
241 if (strcmp(stats
[i
].f_fstypename
, "xfs") != 0)
244 ((strcmp(path
, stats
[i
].f_mntonname
) != 0) &&
245 (strcmp(path
, stats
[i
].f_mntfromname
) != 0)))
248 dir
= strdup(stats
[i
].f_mntonname
);
249 fsname
= strdup(stats
[i
].f_mntfromname
);
250 if (!dir
|| !fsname
) {
254 /* TODO: external log and realtime device? */
255 if ((error
= fs_table_insert(dir
, 0, FS_MOUNT_POINT
,
256 fsname
, fslog
, fsrt
)))
259 if (!error
&& path
&& !found
)
269 # error "How do I extract info about mounted filesystems on this platform?"
273 * Given a directory, match it up to a filesystem mount point.
275 static struct fs_path
*
276 fs_mount_point_from_path(
283 if (stat64(dir
, &s
) < 0) {
288 fs_cursor_initialise(NULL
, FS_MOUNT_POINT
, &cursor
);
289 while ((fs
= fs_cursor_next_entry(&cursor
))) {
290 if (fs
->fs_datadev
== s
.st_dev
)
297 fs_table_initialise_projects(
300 fs_project_path_t
*path
;
303 char *dir
= NULL
, *fsname
= NULL
;
304 int error
= 0, found
= 0;
307 prid
= prid_from_string(project
);
310 while ((path
= getprpathent()) != NULL
) {
311 if (project
&& prid
!= path
->pp_prid
)
313 if ((fs
= fs_mount_point_from_path(path
->pp_pathname
)) == NULL
)
316 dir
= strdup(path
->pp_pathname
);
317 fsname
= strdup(fs
->fs_name
);
318 if (!dir
|| !fsname
) {
322 if ((error
= fs_table_insert(dir
, path
->pp_prid
,
323 FS_PROJECT_PATH
, fsname
, NULL
, NULL
)))
328 if (!error
&& project
&& !found
)
338 fs_table_initialise(void)
342 error
= fs_table_initialise_mounts(NULL
);
344 error
= fs_table_initialise_projects(NULL
);
347 fprintf(stderr
, _("%s: cannot initialise path table: %s\n"),
348 progname
, strerror(error
));
354 fs_table_insert_mount(
359 error
= fs_table_initialise_mounts(mount
);
362 fprintf(stderr
, _("%s: cannot setup path for mount %s: %s\n"),
363 progname
, mount
, strerror(error
));
369 fs_table_insert_project(
375 fprintf(stderr
, _("%s: no mount table yet, so no projects\n"),
379 error
= fs_table_initialise_projects(project
);
382 fprintf(stderr
, _("%s: cannot setup path for project %s: %s\n"),
383 progname
, project
, strerror(error
));
389 * Table iteration (cursor-based) interfaces
393 fs_cursor_initialise(
400 memset(cur
, 0, sizeof(*cur
));
402 if ((path
= fs_table_lookup(dir
, flags
)) == NULL
)
406 cur
->table
= &cur
->local
;
408 cur
->count
= fs_count
;
409 cur
->table
= fs_table
;
415 fs_cursor_next_entry(
418 fs_path_t
*next
= NULL
;
420 while (cur
->index
< cur
->count
) {
421 next
= &cur
->table
[cur
->index
++];
422 if (cur
->flags
& next
->fs_flags
)