]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - mount/swapon.c
2 * A swapon(8)/swapoff(8) for Linux 0.99.
3 * swapon.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
5 * 1997-02-xx <Vincent.Renardias@waw.com>
6 * - added '-s' (summary option)
7 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
8 * - added Native Language Support
9 * 1999-03-21 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
10 * - fixed strerr(errno) in gettext calls
11 * 2001-03-22 Erik Troan <ewt@redhat.com>
12 * - added -e option for -a
13 * - -a shouldn't try to add swaps that are already enabled
24 #include "swap_constants.h"
28 #define streq(s, t) (strcmp ((s), (t)) == 0)
30 #define _PATH_FSTAB "/etc/fstab"
31 #define PROC_SWAPS "/proc/swaps"
33 #define SWAPON_NEEDS_TWO_ARGS
39 int priority
= -1; /* non-prioritized swap by default */
41 /* If true, don't complain if the device/file doesn't exist */
44 extern char version
[];
45 static char *program_name
;
47 static struct option longswaponopts
[] = {
49 { "priority", required_argument
, 0, 'p' },
50 { "ifexists", 0, 0, 'e' },
51 { "summary", 0, 0, 's' },
52 /* also for swapoff */
54 { "help", 0, 0, 'h' },
55 { "verbose", 0, 0, 'v' },
56 { "version", 0, 0, 'V' },
60 static struct option
*longswapoffopts
= &longswaponopts
[2];
63 swapon_usage(FILE *fp
, int n
) {
64 fprintf(fp
, _("usage: %s [-hV]\n"
66 " %s [-v] [-p priority] special ...\n"
68 program_name
, program_name
, program_name
, program_name
);
73 swapoff_usage(FILE *fp
, int n
) {
74 fprintf(fp
, _("usage: %s [-hV]\n"
76 " %s [-v] special ...\n"),
77 program_name
, program_name
, program_name
);
81 #ifdef SWAPON_HAS_TWO_ARGS
82 #define SWAPON_NEEDS_TWO_ARGS
85 #ifdef SWAPON_NEEDS_TWO_ARGS
86 #ifdef SWAPON_HAS_TWO_ARGS
90 /* We want a swapon with two args, but have an old libc.
91 Build the kernel call by hand. */
92 #include <linux/unistd.h>
94 _syscall2(int, swapon
, const char *, path
, int, flags
);
96 _syscall1(int, swapoff
, const char *, path
);
99 /* just do as libc says */
105 * contents of /proc/swaps
108 static char **swapFiles
; /* array of swap file and partition names */
111 read_proc_swaps(void) {
119 swaps
= fopen(PROC_SWAPS
, "r");
121 return; /* nothing wrong */
123 /* skip the first line */
124 fgets(line
, sizeof(line
), swaps
);
126 while (fgets(line
, sizeof(line
), swaps
)) {
128 * Cut the line "swap_device ... more info" after device.
129 * This will fail with names with embedded spaces.
131 for (p
= line
; *p
&& *p
!= ' '; p
++);
135 swapFiles
= realloc(swapFiles
,
136 numSwaps
* sizeof(*swapFiles
));
137 swapFiles
[numSwaps
-1] = strdup(line
);
143 is_in_proc_swaps(char *fname
) {
146 for (i
= 0; i
< numSwaps
; i
++)
147 if (!strcmp(fname
, swapFiles
[i
]))
153 display_summary(void)
158 if ((swaps
= fopen(PROC_SWAPS
, "r")) == NULL
) {
160 fprintf(stderr
, "%s: %s: %s\n", program_name
, PROC_SWAPS
,
165 while (fgets(line
, sizeof(line
), swaps
))
173 do_swapon(const char *special
, int prio
) {
178 printf(_("%s on %s\n"), program_name
, special
);
180 if (stat(special
, &st
) < 0) {
182 fprintf(stderr
, _("swapon: cannot stat %s: %s\n"),
183 special
, strerror(errsv
));
187 /* people generally dislike this warning - now it is printed
188 only when `verbose' is set */
190 int permMask
= (S_ISBLK(st
.st_mode
) ? 07007 : 07077);
192 if ((st
.st_mode
& permMask
) != 0) {
193 fprintf(stderr
, _("swapon: warning: %s has "
194 "insecure permissions %04o, "
196 special
, st
.st_mode
& 07777,
201 /* test for holes by LBT */
202 if (S_ISREG(st
.st_mode
)) {
203 if (st
.st_blocks
* 512 < st
.st_size
) {
205 _("swapon: Skipping file %s - it appears "
212 #ifdef SWAPON_NEEDS_TWO_ARGS
216 #ifdef SWAP_FLAG_PREFER
218 if (prio
> SWAP_FLAG_PRIO_MASK
)
219 prio
= SWAP_FLAG_PRIO_MASK
;
220 flags
= SWAP_FLAG_PREFER
221 | ((prio
& SWAP_FLAG_PRIO_MASK
)
222 << SWAP_FLAG_PRIO_SHIFT
);
225 status
= swapon(special
, flags
);
228 status
= swapon(special
);
232 fprintf(stderr
, "%s: %s: %s\n", program_name
,
233 special
, strerror(errsv
));
240 do_swapoff(const char *special
, int quiet
) {
242 printf(_("%s on %s\n"), program_name
, special
);
244 if (swapoff(special
) == 0)
245 return 0; /* success */
247 if (errno
== EPERM
) {
248 fprintf(stderr
, _("Not superuser.\n"));
249 exit(1); /* any further swapoffs will also fail */
252 if (!quiet
|| errno
== ENOMEM
) {
254 fprintf(stderr
, "%s: %s: %s\n", program_name
,
255 special
, strerror(errsv
));
261 main_swapon(int argc
, char *argv
[]) {
263 struct mntent
*fstab
;
267 while ((c
= getopt_long(argc
, argv
, "ahep:svV",
268 longswaponopts
, NULL
)) != -1) {
274 swapon_usage(stdout
, 0);
276 case 'p': /* priority */
277 priority
= atoi(optarg
);
279 case 'e': /* ifexists */
282 case 's': /* status report */
283 status
= display_summary();
285 case 'v': /* be chatty */
288 case 'V': /* version */
289 printf("%s: %s\n", program_name
, version
);
295 swapon_usage(stderr
, 1);
300 if (!all
&& *argv
== NULL
)
301 swapon_usage(stderr
, 2);
303 if (ifexists
&& (!all
|| strcmp(program_name
, "swapon")))
304 swapon_usage(stderr
, 1);
309 fp
= setmntent(_PATH_FSTAB
, "r");
312 fprintf(stderr
, _("%s: cannot open %s: %s\n"),
313 program_name
, _PATH_FSTAB
, strerror(errsv
));
316 while ((fstab
= getmntent(fp
)) != NULL
) {
317 char *special
= fstab
->mnt_fsname
;
319 if (streq(fstab
->mnt_type
, MNTTYPE_SWAP
) &&
320 !is_in_proc_swaps(special
)
321 && (!ifexists
|| !access(special
, R_OK
))) {
322 /* parse mount options; */
323 char *opt
, *opts
= strdup(fstab
->mnt_opts
);
325 for (opt
= strtok(opts
, ","); opt
!= NULL
;
326 opt
= strtok(NULL
, ","))
327 if (strncmp(opt
, "pri=", 4) == 0)
328 priority
= atoi(opt
+4);
329 status
|= do_swapon(special
, priority
);
335 while (*argv
!= NULL
)
336 status
|= do_swapon(*argv
++, priority
);
342 main_swapoff(int argc
, char *argv
[]) {
344 struct mntent
*fstab
;
348 while ((c
= getopt_long(argc
, argv
, "ahvV",
349 longswapoffopts
, NULL
)) != -1) {
355 swapoff_usage(stdout
, 0);
357 case 'v': /* be chatty */
360 case 'V': /* version */
361 printf("%s: %s\n", program_name
, version
);
367 swapoff_usage(stderr
, 1);
372 if (!all
&& *argv
== NULL
)
373 swapoff_usage(stderr
, 2);
376 * swapoff any explicitly given arguments.
377 * Complain in case the swapoff call fails.
379 while (*argv
!= NULL
)
380 status
|= do_swapoff(*argv
++, !QUIET
);
384 * In case /proc/swaps exists, unmount stuff listed there.
385 * We are quiet but report errors in status.
386 * Errors might mean that /proc/swaps
387 * exists as ordinary file, not in procfs.
388 * do_swapoff() exits immediately on EPERM.
391 for(i
=0; i
<numSwaps
; i
++)
392 status
|= do_swapoff(swapFiles
[i
], QUIET
);
395 * Unmount stuff mentioned in /etc/fstab.
396 * Probably it was unmounted already, so errors are not bad.
397 * Doing swapoff -a twice should not give error messages.
399 fp
= setmntent(_PATH_FSTAB
, "r");
402 fprintf(stderr
, _("%s: cannot open %s: %s\n"),
403 program_name
, _PATH_FSTAB
, strerror(errsv
));
406 while ((fstab
= getmntent(fp
)) != NULL
) {
407 if (streq(fstab
->mnt_type
, MNTTYPE_SWAP
) &&
408 !is_in_proc_swaps(fstab
->mnt_fsname
))
409 do_swapoff(fstab
->mnt_fsname
, QUIET
);
418 main(int argc
, char *argv
[]) {
421 setlocale(LC_ALL
, "");
422 bindtextdomain(PACKAGE
, LOCALEDIR
);
425 program_name
= argv
[0];
426 p
= strrchr(program_name
, '/');
430 if (streq(program_name
, "swapon"))
431 return main_swapon(argc
, argv
);
433 return main_swapoff(argc
, argv
);