]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libfrog/linux.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
10 #include <sys/sysinfo.h>
12 #include "platform_defs.h"
15 #include "libfrog/platform.h"
17 extern char *progname
;
18 static int max_block_alignment
;
21 # define BLKGETSIZE64 _IOR(0x12,114,size_t)
24 # define BLKBSZSET _IOW(0x12,113,size_t)
27 # define BLKSSZGET _IO(0x12,104)
31 #define RAMDISK_MAJOR 1 /* ramdisk major number */
34 #define PROC_MOUNTED "/proc/mounts"
37 * Check if the filesystem is mounted. Be verbose if asked, and
38 * optionally restrict check to /writable/ mounts (i.e. RO is OK)
40 #define CHECK_MOUNT_VERBOSE 0x1
41 #define CHECK_MOUNT_WRITABLE 0x2
44 platform_check_mount(char *name
, char *block
, struct stat
*s
, int flags
)
49 char mounts
[MAXPATHLEN
];
52 /* If either fails we are not mounted */
53 if (stat(block
, &st
) < 0)
55 if ((st
.st_mode
& S_IFMT
) != S_IFBLK
)
60 strcpy(mounts
, (!access(PROC_MOUNTED
, R_OK
)) ? PROC_MOUNTED
: MOUNTED
);
61 if ((f
= setmntent(mounts
, "r")) == NULL
) {
62 /* Unexpected failure, warn unconditionally */
64 _("%s: %s possibly contains a mounted filesystem\n"),
69 * This whole business is to work out if our block device is mounted
70 * after we lost ustat(2), see:
71 * 4e7a824 libxfs/linux.c: Replace use of ustat by stat
72 * We don't really want to stat every single mounted directory,
73 * as that may include tmpfs, cgroups, procfs or - worst - hung nfs
74 * servers. So first, a simple check: does the "dev" start with "/" ?
76 while ((mnt
= getmntent(f
)) != NULL
) {
77 if (!strcmp(mnt
->mnt_type
, "autofs"))
79 if (mnt
->mnt_fsname
[0] != '/')
81 if (stat(mnt
->mnt_dir
, &mst
) < 0)
83 if (mst
.st_dev
!= s
->st_rdev
)
85 /* Found our device, is RO OK? */
86 if ((flags
& CHECK_MOUNT_WRITABLE
) && hasmntopt(mnt
, MNTOPT_RO
))
93 /* No mounts contained the condition we were looking for */
97 if (flags
& CHECK_MOUNT_VERBOSE
) {
98 if (flags
& CHECK_MOUNT_WRITABLE
) {
100 _("%s: %s contains a mounted and writable filesystem\n"),
104 _("%s: %s contains a mounted filesystem\n"),
112 platform_check_ismounted(char *name
, char *block
, struct stat
*s
, int verbose
)
116 flags
= verbose
? CHECK_MOUNT_VERBOSE
: 0;
117 return platform_check_mount(name
, block
, s
, flags
);
121 platform_check_iswritable(char *name
, char *block
, struct stat
*s
)
125 /* Writable checks are always verbose */
126 flags
= CHECK_MOUNT_WRITABLE
| CHECK_MOUNT_VERBOSE
;
127 return platform_check_mount(name
, block
, s
, flags
);
131 platform_set_blocksize(int fd
, char *path
, dev_t device
, int blocksize
,
136 if (major(device
) == RAMDISK_MAJOR
)
138 error
= ioctl(fd
, BLKBSZSET
, &blocksize
);
140 fprintf(stderr
, _("%s: %s - cannot set blocksize "
141 "%d on block device %s: %s\n"),
142 progname
, fatal
? "error": "warning",
143 blocksize
, path
, strerror(errno
));
150 * Flush dirty pagecache and disk write cache to stable media. Returns 0 for
151 * success or -1 (with errno set) for failure.
154 platform_flush_device(
161 if (major(device
) == RAMDISK_MAJOR
)
168 ret
= fstat(fd
, &st
);
172 if (S_ISBLK(st
.st_mode
))
173 return ioctl(fd
, BLKFLSBUF
, 0);
179 platform_findsizes(char *path
, int fd
, long long *sz
, int *bsz
)
185 if (fstat(fd
, &st
) < 0) {
186 fprintf(stderr
, _("%s: "
187 "cannot stat the device file \"%s\": %s\n"),
188 progname
, path
, strerror(errno
));
192 if ((st
.st_mode
& S_IFMT
) == S_IFREG
) {
195 *sz
= (long long)(st
.st_size
>> 9);
197 if (ioctl(fd
, XFS_IOC_DIOINFO
, &da
) < 0) {
199 * fall back to BBSIZE; mkfs might fail if there's a
200 * size mismatch between the image & the host fs...
206 if (*bsz
> max_block_alignment
)
207 max_block_alignment
= *bsz
;
211 error
= ioctl(fd
, BLKGETSIZE64
, &size
);
213 /* BLKGETSIZE64 returns size in bytes not 512-byte blocks */
214 *sz
= (long long)(size
>> 9);
216 /* If BLKGETSIZE64 fails, try BLKGETSIZE */
217 unsigned long tmpsize
;
219 error
= ioctl(fd
, BLKGETSIZE
, &tmpsize
);
221 fprintf(stderr
, _("%s: can't determine device size\n"),
225 *sz
= (long long)tmpsize
;
228 if (ioctl(fd
, BLKSSZGET
, bsz
) < 0) {
229 fprintf(stderr
, _("%s: warning - cannot get sector size "
230 "from block device %s: %s\n"),
231 progname
, path
, strerror(errno
));
234 if (*bsz
> max_block_alignment
)
235 max_block_alignment
= *bsz
;
239 platform_direct_blockdev(void)
245 platform_align_blockdev(void)
247 if (!max_block_alignment
)
248 return getpagesize();
249 return max_block_alignment
;
252 /* How many CPUs are online? */
256 long nproc
= sysconf(_SC_NPROCESSORS_ONLN
);
260 if (nproc
>= INT_MAX
)
266 platform_physmem(void)
270 if (sysinfo(&si
) < 0) {
271 fprintf(stderr
, _("%s: can't determine memory size\n"),
275 return (si
.totalram
>> 10) * si
.mem_unit
; /* kilobytes */