]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libfrog/linux.c
libfrog: move platform specific runtime support code out of libxfs
[thirdparty/xfsprogs-dev.git] / libfrog / linux.c
CommitLineData
9440d84d 1/*
da23017d
NS
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
9440d84d 4 *
da23017d
NS
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
9440d84d
NS
7 * published by the Free Software Foundation.
8 *
da23017d
NS
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.
9440d84d 13 *
da23017d
NS
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
9440d84d
NS
17 */
18
9440d84d
NS
19#include <mntent.h>
20#include <sys/stat.h>
9440d84d
NS
21#include <sys/mount.h>
22#include <sys/ioctl.h>
2556c98b 23#include <sys/sysinfo.h>
9440d84d 24
9c799827 25#include "libxfs_priv.h"
b626fb59
DC
26#include "xfs_fs.h"
27
e321f629 28int platform_has_uuid = 1;
9440d84d 29extern char *progname;
b74a1f6a 30static int max_block_alignment;
9440d84d
NS
31
32#ifndef BLKGETSIZE64
7f090a57 33# define BLKGETSIZE64 _IOR(0x12,114,size_t)
9440d84d
NS
34#endif
35#ifndef BLKBSZSET
7f090a57 36# define BLKBSZSET _IOW(0x12,113,size_t)
9440d84d 37#endif
74668075
NS
38#ifndef BLKSSZGET
39# define BLKSSZGET _IO(0x12,104)
40#endif
9440d84d 41
ac419944
NS
42#ifndef RAMDISK_MAJOR
43#define RAMDISK_MAJOR 1 /* ramdisk major number */
44#endif
45
9440d84d
NS
46#define PROC_MOUNTED "/proc/mounts"
47
4d457e24
ES
48/*
49 * Check if the filesystem is mounted. Be verbose if asked, and
50 * optionally restrict check to /writable/ mounts (i.e. RO is OK)
51 */
52#define CHECK_MOUNT_VERBOSE 0x1
53#define CHECK_MOUNT_WRITABLE 0x2
54
55static int
f594a0d1 56platform_check_mount(char *name, char *block, struct stat *s, int flags)
9440d84d 57{
4e7a824f 58 FILE *f;
f594a0d1 59 struct stat st, mst;
4e7a824f
FJ
60 struct mntent *mnt;
61 char mounts[MAXPATHLEN];
9440d84d
NS
62
63 if (!s) {
4d457e24 64 /* If either fails we are not mounted */
f594a0d1 65 if (stat(block, &st) < 0)
9440d84d
NS
66 return 0;
67 if ((st.st_mode & S_IFMT) != S_IFBLK)
68 return 0;
69 s = &st;
70 }
71
4e7a824f
FJ
72 strcpy(mounts, (!access(PROC_MOUNTED, R_OK)) ? PROC_MOUNTED : MOUNTED);
73 if ((f = setmntent(mounts, "r")) == NULL) {
4d457e24 74 /* Unexpected failure, warn unconditionally */
4e7a824f
FJ
75 fprintf(stderr,
76 _("%s: %s possibly contains a mounted filesystem\n"),
77 progname, name);
78 return 1;
79 }
80 while ((mnt = getmntent(f)) != NULL) {
f594a0d1 81 if (stat(mnt->mnt_dir, &mst) < 0)
4e7a824f
FJ
82 continue;
83 if (mst.st_dev != s->st_rdev)
84 continue;
4d457e24
ES
85 /* Found our device, is RO OK? */
86 if ((flags & CHECK_MOUNT_WRITABLE) && hasmntopt(mnt, MNTOPT_RO))
87 continue;
88 else
89 break;
90 }
91 endmntent(f);
4e7a824f 92
4d457e24
ES
93 /* No mounts contained the condition we were looking for */
94 if (mnt == NULL)
95 return 0;
96
97 if (flags & CHECK_MOUNT_VERBOSE) {
98 if (flags & CHECK_MOUNT_WRITABLE) {
99 fprintf(stderr,
100_("%s: %s contains a mounted and writable filesystem\n"),
101 progname, name);
102 } else {
9440d84d 103 fprintf(stderr,
4d457e24 104_("%s: %s contains a mounted filesystem\n"),
9440d84d 105 progname, name);
4d457e24 106 }
9440d84d 107 }
4d457e24 108 return 1;
9440d84d
NS
109}
110
111int
f594a0d1 112platform_check_ismounted(char *name, char *block, struct stat *s, int verbose)
9440d84d 113{
4d457e24 114 int flags;
9440d84d 115
4d457e24
ES
116 flags = verbose ? CHECK_MOUNT_VERBOSE : 0;
117 return platform_check_mount(name, block, s, flags);
118}
7f510afb 119
4d457e24 120int
f594a0d1 121platform_check_iswritable(char *name, char *block, struct stat *s)
4d457e24
ES
122{
123 int flags;
124
125 /* Writable checks are always verbose */
126 flags = CHECK_MOUNT_WRITABLE | CHECK_MOUNT_VERBOSE;
127 return platform_check_mount(name, block, s, flags);
9440d84d
NS
128}
129
edd45774
TS
130int
131platform_set_blocksize(int fd, char *path, dev_t device, int blocksize, int fatal)
9440d84d 132{
edd45774
TS
133 int error = 0;
134
76956054 135 if (major(device) != RAMDISK_MAJOR) {
edd45774
TS
136 if ((error = ioctl(fd, BLKBSZSET, &blocksize)) < 0) {
137 fprintf(stderr, _("%s: %s - cannot set blocksize "
fd5eda53 138 "%d on block device %s: %s\n"),
edd45774 139 progname, fatal ? "error": "warning",
fd5eda53 140 blocksize, path, strerror(errno));
76956054 141 }
9440d84d 142 }
edd45774 143 return error;
9440d84d
NS
144}
145
146void
ac419944 147platform_flush_device(int fd, dev_t device)
9440d84d 148{
f594a0d1 149 struct stat st;
06ac92fd
DC
150 if (major(device) == RAMDISK_MAJOR)
151 return;
152
f594a0d1 153 if (fstat(fd, &st) < 0)
06ac92fd
DC
154 return;
155
156 if (S_ISREG(st.st_mode))
157 fsync(fd);
158 else
ac419944 159 ioctl(fd, BLKFLSBUF, 0);
9440d84d
NS
160}
161
f02037ce
NS
162void
163platform_findsizes(char *path, int fd, long long *sz, int *bsz)
9440d84d 164{
f594a0d1 165 struct stat st;
14f8b681 166 uint64_t size;
f02037ce 167 int error;
9440d84d 168
f594a0d1 169 if (fstat(fd, &st) < 0) {
9440d84d
NS
170 fprintf(stderr, _("%s: "
171 "cannot stat the device file \"%s\": %s\n"),
172 progname, path, strerror(errno));
173 exit(1);
174 }
98dd72d3 175
f02037ce 176 if ((st.st_mode & S_IFMT) == S_IFREG) {
98dd72d3 177 struct dioattr da;
5a7d5937 178
f02037ce 179 *sz = (long long)(st.st_size >> 9);
98dd72d3
ES
180
181 if (ioctl(fd, XFS_IOC_DIOINFO, &da) < 0) {
5a7d5937
ES
182 /*
183 * fall back to BBSIZE; mkfs might fail if there's a
184 * size mismatch between the image & the host fs...
185 */
186 *bsz = BBSIZE;
187 } else
98dd72d3 188 *bsz = da.d_miniosz;
5a7d5937
ES
189
190 if (*bsz > max_block_alignment)
191 max_block_alignment = *bsz;
f02037ce 192 return;
9440d84d
NS
193 }
194
195 error = ioctl(fd, BLKGETSIZE64, &size);
196 if (error >= 0) {
197 /* BLKGETSIZE64 returns size in bytes not 512-byte blocks */
f02037ce 198 *sz = (long long)(size >> 9);
9440d84d
NS
199 } else {
200 /* If BLKGETSIZE64 fails, try BLKGETSIZE */
201 unsigned long tmpsize;
f02037ce 202
9440d84d
NS
203 error = ioctl(fd, BLKGETSIZE, &tmpsize);
204 if (error < 0) {
205 fprintf(stderr, _("%s: can't determine device size\n"),
206 progname);
207 exit(1);
208 }
f02037ce 209 *sz = (long long)tmpsize;
9440d84d
NS
210 }
211
f02037ce
NS
212 if (ioctl(fd, BLKSSZGET, bsz) < 0) {
213 fprintf(stderr, _("%s: warning - cannot get sector size "
214 "from block device %s: %s\n"),
215 progname, path, strerror(errno));
216 *bsz = BBSIZE;
217 }
b74a1f6a
NS
218 if (*bsz > max_block_alignment)
219 max_block_alignment = *bsz;
9440d84d 220}
cb5b3ef4 221
cb5b3ef4
MV
222char *
223platform_findrawpath(char *path)
224{
b74a1f6a
NS
225 return path;
226}
227
228char *
229platform_findblockpath(char *path)
230{
231 return path;
232}
233
234int
235platform_direct_blockdev(void)
236{
237 return 1;
238}
239
240int
241platform_align_blockdev(void)
242{
243 if (!max_block_alignment)
76956054 244 return getpagesize();
b74a1f6a 245 return max_block_alignment;
cb5b3ef4 246}
3b6ac903
MV
247
248int
249platform_nproc(void)
250{
251 return sysconf(_SC_NPROCESSORS_ONLN);
252}
2556c98b
BN
253
254unsigned long
255platform_physmem(void)
256{
257 struct sysinfo si;
258
259 if (sysinfo(&si) < 0) {
260 fprintf(stderr, _("%s: can't determine memory size\n"),
261 progname);
262 exit(1);
263 }
264 return (si.totalram >> 10) * si.mem_unit; /* kilobytes */
265}