]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxcmd/paths.c
2 * Copyright (c) 2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <sys/types.h>
28 #include <xfs/input.h>
29 #include <xfs/project.h>
32 struct fs_path
*fs_table
;
33 struct fs_path
*fs_path
;
36 #define PROC_MOUNTS "/proc/self/mounts"
46 if (stat64(dir
, &sbuf
) < 0)
48 for (i
= 0; i
< fs_count
; i
++) {
49 if ((flags
& fs_table
[i
].fs_flags
) == 0)
51 if (sbuf
.st_dev
== fs_table
[i
].fs_datadev
)
67 dev_t datadev
, logdev
, rtdev
;
72 datadev
= logdev
= rtdev
= 0;
73 if (stat64(dir
, &sbuf
) < 0)
75 datadev
= sbuf
.st_dev
;
77 if (stat64(fslog
, &sbuf
) < 0)
82 if (stat64(fsrt
, &sbuf
) < 0)
87 fs_table
= realloc(fs_table
, sizeof(fs_path_t
) * (fs_count
+ 1));
91 fs_path
= &fs_table
[fs_count
];
92 fs_path
->fs_dir
= dir
;
93 fs_path
->fs_prid
= prid
;
94 fs_path
->fs_flags
= flags
;
95 fs_path
->fs_name
= fsname
;
96 fs_path
->fs_log
= fslog
;
97 fs_path
->fs_rt
= fsrt
;
98 fs_path
->fs_datadev
= datadev
;
99 fs_path
->fs_logdev
= logdev
;
100 fs_path
->fs_rtdev
= rtdev
;
106 if (fsrt
) free(fsrt
);
107 if (fslog
) free(fslog
);
108 if (fsname
) free(fsname
);
113 fs_table_destroy(void)
115 while (--fs_count
>= 0) {
116 free(fs_table
[fs_count
].fs_name
);
117 if (fs_table
[fs_count
].fs_log
)
118 free(fs_table
[fs_count
].fs_log
);
119 if (fs_table
[fs_count
].fs_rt
)
120 free(fs_table
[fs_count
].fs_rt
);
121 free(fs_table
[fs_count
].fs_dir
);
130 #if defined(HAVE_GETMNTENT)
134 fs_extract_mount_options(
139 char *fslog
, *fsrt
, *fslogend
, *fsrtend
;
141 fslog
= fsrt
= fslogend
= fsrtend
= NULL
;
143 /* Extract log device and realtime device from mount options */
144 if ((fslog
= hasmntopt(mnt
, "logdev=")))
146 if ((fsrt
= hasmntopt(mnt
, "rtdev=")))
149 /* Do this only after we've finished processing mount options */
151 fslogend
= strtok(fslog
, " ,");
152 fslog
= strdup(fslog
);
155 fsrtend
= strtok(fsrt
, " ,");
164 fs_table_initialise_mounts(
169 char *dir
= NULL
, *fsname
= NULL
, *fslog
, *fsrt
;
170 int error
= 0, found
= 0;
173 mtab_file
= PROC_MOUNTS
;
174 if (access(mtab_file
, R_OK
) != 0)
178 if ((mtp
= setmntent(mtab_file
, "r")) == NULL
)
181 while ((mnt
= getmntent(mtp
)) != NULL
) {
182 if (strcmp(mnt
->mnt_type
, "xfs") != 0)
185 ((strcmp(path
, mnt
->mnt_dir
) != 0) &&
186 (strcmp(path
, mnt
->mnt_fsname
) != 0)))
189 dir
= strdup(mnt
->mnt_dir
);
190 fsname
= strdup(mnt
->mnt_fsname
);
191 if (!dir
|| !fsname
) {
195 fs_extract_mount_options(mnt
, &fslog
, &fsrt
);
196 if ((error
= fs_table_insert(dir
, 0, FS_MOUNT_POINT
,
197 fsname
, fslog
, fsrt
)))
201 if (!error
&& path
&& !found
)
210 #elif defined(HAVE_GETMNTINFO)
211 #include <sys/mount.h>
214 fs_table_initialise_mounts(
217 struct statfs
*stats
;
218 char *dir
= NULL
, *fsname
= NULL
, *fslog
= NULL
, *fsrt
= NULL
;
219 int i
, count
, found
= 0, error
= 0;
221 if ((count
= getmntinfo(&stats
, 0)) < 0) {
222 perror("getmntinfo");
226 for (i
= 0; i
< count
; i
++) {
227 if (strcmp(stats
[i
].f_fstypename
, "xfs") != 0)
230 ((strcmp(path
, stats
[i
].f_mntonname
) != 0) &&
231 (strcmp(path
, stats
[i
].f_mntfromname
) != 0)))
234 dir
= strdup(stats
[i
].f_mntonname
);
235 fsname
= strdup(stats
[i
].f_mntfromname
);
236 if (!dir
|| !fsname
) {
240 /* TODO: external log and realtime device? */
241 if ((error
= fs_table_insert(dir
, 0, FS_MOUNT_POINT
,
242 fsname
, fslog
, fsrt
)))
245 if (!error
&& path
&& !found
)
255 # error "How do I extract info about mounted filesystems on this platform?"
259 * Given a directory, match it up to a filesystem mount point.
261 static struct fs_path
*
262 fs_mount_point_from_path(
269 if (stat64(dir
, &s
) < 0) {
274 fs_cursor_initialise(NULL
, FS_MOUNT_POINT
, &cursor
);
275 while ((fs
= fs_cursor_next_entry(&cursor
))) {
276 if (fs
->fs_datadev
== s
.st_dev
)
283 fs_table_initialise_projects(
286 fs_project_path_t
*path
;
289 char *dir
= NULL
, *fsname
= NULL
;
290 int error
= 0, found
= 0;
293 prid
= prid_from_string(project
);
296 while ((path
= getprpathent()) != NULL
) {
297 if (project
&& prid
!= path
->pp_prid
)
299 if ((fs
= fs_mount_point_from_path(path
->pp_pathname
)) == NULL
)
302 dir
= strdup(path
->pp_pathname
);
303 fsname
= strdup(fs
->fs_name
);
304 if (!dir
|| !fsname
) {
308 if ((error
= fs_table_insert(dir
, path
->pp_prid
,
309 FS_PROJECT_PATH
, fsname
, NULL
, NULL
)))
314 if (!error
&& project
&& !found
)
324 fs_table_initialise(void)
328 error
= fs_table_initialise_mounts(NULL
);
330 error
= fs_table_initialise_projects(NULL
);
333 fprintf(stderr
, _("%s: cannot initialise path table: %s\n"),
334 progname
, strerror(error
));
340 fs_table_insert_mount(
345 error
= fs_table_initialise_mounts(mount
);
348 fprintf(stderr
, _("%s: cannot setup path for mount %s: %s\n"),
349 progname
, mount
, strerror(error
));
355 fs_table_insert_project(
361 fprintf(stderr
, _("%s: no mount table yet, so no projects\n"),
365 error
= fs_table_initialise_projects(project
);
368 fprintf(stderr
, _("%s: cannot setup path for project %s: %s\n"),
369 progname
, project
, strerror(error
));
375 * Table iteration (cursor-based) interfaces
379 fs_cursor_initialise(
386 memset(cur
, 0, sizeof(*cur
));
388 if ((path
= fs_table_lookup(dir
, flags
)) == NULL
)
392 cur
->table
= &cur
->local
;
394 cur
->count
= fs_count
;
395 cur
->table
= fs_table
;
401 fs_cursor_next_entry(
404 fs_path_t
*next
= NULL
;
406 while (cur
->index
< cur
->count
) {
407 next
= &cur
->table
[cur
->index
++];
408 if (cur
->flags
& next
->fs_flags
)