]> git.ipfire.org Git - thirdparty/util-linux.git/blame - disk-utils/mkswap.c
fdformat: cast before lseek [lgtm scan]
[thirdparty/util-linux.git] / disk-utils / mkswap.c
CommitLineData
6dbe3af9
KZ
1/*
2 * mkswap.c - set up a linux swap device
3 *
8591859c
KZ
4 * Copyright (C) 1991 Linus Torvalds
5 * 20.12.91 - time began. Got VM working yesterday by doing this by hand.
3e18b040 6 *
8591859c
KZ
7 * Copyright (C) 1999 Jakub Jelinek <jj@ultra.linux.cz>
8 * Copyright (C) 2007-2014 Karel Zak <kzak@redhat.com>
6dbe3af9
KZ
9 */
10
11#include <stdio.h>
12#include <unistd.h>
13#include <string.h>
14#include <fcntl.h>
15#include <stdlib.h>
99e6d525 16#include <limits.h>
5c36a0eb 17#include <sys/utsname.h>
6dbe3af9 18#include <sys/stat.h>
3e18b040 19#include <errno.h>
e079c4e6 20#include <getopt.h>
99f78758 21#include <assert.h>
3e18b040
KZ
22#ifdef HAVE_LIBSELINUX
23#include <selinux/selinux.h>
24#include <selinux/context.h>
25#endif
26
8023c83b 27#include "linux_version.h"
756bfd01 28#include "swapheader.h"
8abcf290 29#include "strutils.h"
66ee8158 30#include "nls.h"
54e377b3 31#include "blkdev.h"
fc68cd49 32#include "pathnames.h"
e12c9866 33#include "all-io.h"
94a50e28 34#include "xalloc.h"
08675263 35#include "c.h"
45ca68ec 36#include "closestream.h"
def478cf 37#include "ismounted.h"
66ee8158 38
766dd757 39#ifdef HAVE_LIBUUID
7ee96990 40# include <uuid.h>
756bfd01
KZ
41#endif
42
64d15476 43#ifdef HAVE_LIBBLKID
566f35bc
KZ
44# include <blkid.h>
45#endif
46
de3822c3 47#define MIN_GOODPAGES 10
5c36a0eb 48
3e18b040
KZ
49#define SELINUX_SWAPFILE_TYPE "swapfile_t"
50
de3822c3 51struct mkswap_control {
99f78758 52 struct swap_header_v1_2 *hdr; /* swap header */
8591859c
KZ
53 void *signature_page;/* buffer with swap header */
54
fabf29f4
KZ
55 char *devname; /* device or file name */
56 struct stat devstat; /* stat() result */
57 int fd; /* swap file descriptor */
8591859c
KZ
58
59 unsigned long long npages; /* number of pages */
60 unsigned long nbadpages; /* number of bad pages */
61
62 int user_pagesize; /* --pagesize */
63 int pagesize; /* final pagesize used for the header */
64
65 char *opt_label; /* LABEL as specified on command line */
66 unsigned char *uuid; /* UUID parsed by libbuuid */
67
68 unsigned int check:1, /* --check */
69 force:1; /* --force */
de3822c3 70};
5c36a0eb 71
99f78758 72static void init_signature_page(struct mkswap_control *ctl)
f2704664 73{
076ba5a6 74 const int kernel_pagesize = getpagesize();
eb63b9b8 75
de3822c3
SK
76 if (ctl->user_pagesize) {
77 if (ctl->user_pagesize < 0 || !is_power_of_2(ctl->user_pagesize) ||
78 (size_t) ctl->user_pagesize < sizeof(struct swap_header_v1_2) + 10)
00a7d0d2 79 errx(EXIT_FAILURE,
076ba5a6
SK
80 _("Bad user-specified page size %u"),
81 ctl->user_pagesize);
82 if (ctl->user_pagesize != kernel_pagesize)
83 warnx(_("Using user-specified page size %d, "
00a7d0d2 84 "instead of the system value %d"),
4850e972 85 ctl->user_pagesize, kernel_pagesize);
076ba5a6
SK
86 ctl->pagesize = ctl->user_pagesize;
87 } else
88 ctl->pagesize = kernel_pagesize;
99f78758 89
fea1cbf7 90 ctl->signature_page = xcalloc(1, ctl->pagesize);
99f78758
KZ
91 ctl->hdr = (struct swap_header_v1_2 *) ctl->signature_page;
92}
93
94static void deinit_signature_page(struct mkswap_control *ctl)
95{
96 free(ctl->signature_page);
97
98 ctl->hdr = NULL;
99 ctl->signature_page = NULL;
5c36a0eb
KZ
100}
101
3ba01c14 102static void set_signature(const struct mkswap_control *ctl)
f2704664 103{
de3822c3 104 char *sp = (char *) ctl->signature_page;
5c36a0eb 105
fabf29f4 106 assert(sp);
d2f265d6 107 memcpy(sp + ctl->pagesize - SWAP_SIGNATURE_SZ, SWAP_SIGNATURE, SWAP_SIGNATURE_SZ);
5c36a0eb
KZ
108}
109
3ba01c14 110static void set_uuid_and_label(const struct mkswap_control *ctl)
f2704664 111{
99f78758
KZ
112 assert(ctl);
113 assert(ctl->hdr);
756bfd01 114
99f78758 115 /* set UUID */
de3822c3 116 if (ctl->uuid)
99f78758
KZ
117 memcpy(ctl->hdr->uuid, ctl->uuid, sizeof(ctl->hdr->uuid));
118
119 /* set LABEL */
de3822c3 120 if (ctl->opt_label) {
99f78758
KZ
121 xstrncpy(ctl->hdr->volume_name,
122 ctl->opt_label, sizeof(ctl->hdr->volume_name));
123 if (strlen(ctl->opt_label) > strlen(ctl->hdr->volume_name))
00a7d0d2 124 warnx(_("Label was truncated."));
756bfd01 125 }
99f78758 126
9e930041 127 /* report results */
de3822c3
SK
128 if (ctl->uuid || ctl->opt_label) {
129 if (ctl->opt_label)
99f78758 130 printf("LABEL=%s, ", ctl->hdr->volume_name);
756bfd01
KZ
131 else
132 printf(_("no label, "));
766dd757 133#ifdef HAVE_LIBUUID
de3822c3 134 if (ctl->uuid) {
b443c177 135 char uuid_string[UUID_STR_LEN];
de3822c3 136 uuid_unparse(ctl->uuid, uuid_string);
756bfd01
KZ
137 printf("UUID=%s\n", uuid_string);
138 } else
139#endif
140 printf(_("no uuid\n"));
141 }
142}
143
6e1eda6f 144static void __attribute__((__noreturn__)) usage(void)
e079c4e6 145{
6e1eda6f 146 FILE *out = stdout;
e079c4e6
SK
147 fprintf(out,
148 _("\nUsage:\n"
149 " %s [options] device [size]\n"),
00a7d0d2 150 program_invocation_short_name);
e079c4e6 151
451dbcfa
BS
152 fputs(USAGE_SEPARATOR, out);
153 fputs(_("Set up a Linux swap area.\n"), out);
154
e079c4e6
SK
155 fprintf(out, _(
156 "\nOptions:\n"
157 " -c, --check check bad blocks before creating the swap area\n"
158 " -f, --force allow swap size area be larger than device\n"
159 " -p, --pagesize SIZE specify page size in bytes\n"
160 " -L, --label LABEL specify label\n"
161 " -v, --swapversion NUM specify swap-space version number\n"
162 " -U, --uuid UUID specify the uuid to use\n"
b3054454 163 ));
f45f3ec3 164 printf(USAGE_HELP_OPTIONS(27));
e079c4e6 165
b3054454 166 printf(USAGE_MAN_TAIL("mkswap(8)"));
6e1eda6f 167 exit(EXIT_SUCCESS);
eb63b9b8 168}
6dbe3af9 169
99f78758 170static void page_bad(struct mkswap_control *ctl, unsigned int page)
f2704664 171{
99f78758
KZ
172 const unsigned long max_badpages =
173 (ctl->pagesize - 1024 - 128 * sizeof(int) - 10) / sizeof(int);
3e16599a 174
8591859c 175 if (ctl->nbadpages == max_badpages)
d68f402c 176 errx(EXIT_FAILURE, _("too many bad pages: %lu"), max_badpages);
99f78758
KZ
177
178 ctl->hdr->badpages[ctl->nbadpages] = page;
8591859c 179 ctl->nbadpages++;
5c36a0eb
KZ
180}
181
99f78758 182static void check_blocks(struct mkswap_control *ctl)
f2704664 183{
d68f402c 184 unsigned int current_page = 0;
6dbe3af9 185 int do_seek = 1;
5c36a0eb 186 char *buffer;
6dbe3af9 187
99f78758
KZ
188 assert(ctl);
189 assert(ctl->fd > -1);
190
de3822c3 191 buffer = xmalloc(ctl->pagesize);
8591859c 192 while (current_page < ctl->npages) {
f3b16286
KZ
193 ssize_t rc;
194
de3822c3
SK
195 if (do_seek && lseek(ctl->fd, current_page * ctl->pagesize, SEEK_SET) !=
196 current_page * ctl->pagesize)
00a7d0d2 197 errx(EXIT_FAILURE, _("seek failed in check_blocks"));
f3b16286 198
de3822c3
SK
199 rc = read(ctl->fd, buffer, ctl->pagesize);
200 do_seek = (rc < 0 || rc != ctl->pagesize);
f3b16286 201 if (do_seek)
de3822c3 202 page_bad(ctl, current_page);
adda7f7e 203 current_page++;
6dbe3af9 204 }
8591859c 205 printf(P_("%lu bad page\n", "%lu bad pages\n", ctl->nbadpages), ctl->nbadpages);
3216beb0 206 free(buffer);
6dbe3af9
KZ
207}
208
99e6d525 209/* return size in pages */
fabf29f4 210static unsigned long long get_size(const struct mkswap_control *ctl)
f2704664
SK
211{
212 int fd;
54e377b3 213 unsigned long long size;
6dbe3af9 214
fabf29f4 215 fd = open(ctl->devname, O_RDONLY);
3d5c8ba1 216 if (fd < 0)
fabf29f4 217 err(EXIT_FAILURE, _("cannot open %s"), ctl->devname);
54e377b3 218 if (blkdev_get_size(fd, &size) == 0)
de3822c3 219 size /= ctl->pagesize;
54e377b3 220
6dbe3af9
KZ
221 close(fd);
222 return size;
223}
224
979f1dd5 225#ifdef HAVE_LIBBLKID
fabf29f4 226static blkid_probe new_prober(const struct mkswap_control *ctl)
979f1dd5
KZ
227{
228 blkid_probe pr = blkid_new_probe();
229 if (!pr)
230 errx(EXIT_FAILURE, _("unable to alloc new libblkid probe"));
6af18227 231 if (blkid_probe_set_device(pr, ctl->fd, 0, 0))
979f1dd5
KZ
232 errx(EXIT_FAILURE, _("unable to assign device to libblkid probe"));
233 return pr;
234}
235#endif
236
fabf29f4
KZ
237static void open_device(struct mkswap_control *ctl)
238{
239 assert(ctl);
240 assert(ctl->devname);
241
242 if (stat(ctl->devname, &ctl->devstat) < 0)
fc14ceba 243 err(EXIT_FAILURE, _("stat of %s failed"), ctl->devname);
80c320fa 244 ctl->fd = open_blkdev_or_file(&ctl->devstat, ctl->devname, O_RDWR);
fabf29f4
KZ
245 if (ctl->fd < 0)
246 err(EXIT_FAILURE, _("cannot open %s"), ctl->devname);
80c320fa
SK
247 if (ctl->check && S_ISREG(ctl->devstat.st_mode)) {
248 ctl->check = 0;
249 warnx(_("warning: checking bad blocks from swap file is not supported: %s"),
250 ctl->devname);
251 }
fabf29f4
KZ
252}
253
254static void wipe_device(struct mkswap_control *ctl)
ff3bed80 255{
566f35bc 256 char *type = NULL;
ff3bed80 257 int zap = 1;
9206b238 258#ifdef HAVE_LIBBLKID
979f1dd5 259 blkid_probe pr = NULL;
9206b238 260#endif
6af18227 261 if (!ctl->force) {
f11157e8
KZ
262 const char *v = NULL;
263
6af18227 264 if (lseek(ctl->fd, 0, SEEK_SET) != 0)
00a7d0d2 265 errx(EXIT_FAILURE, _("unable to rewind swap-device"));
ff3bed80 266
64d15476 267#ifdef HAVE_LIBBLKID
6af18227 268 pr = new_prober(ctl);
c1f1b301
MB
269 blkid_probe_enable_partitions(pr, 1);
270 blkid_probe_enable_superblocks(pr, 0);
271
272 if (blkid_do_fullprobe(pr) == 0 &&
f11157e8
KZ
273 blkid_probe_lookup_value(pr, "PTTYPE", &v, NULL) == 0 && v) {
274 type = xstrdup(v);
ff3bed80 275 zap = 0;
566f35bc 276 }
c1f1b301
MB
277#else
278 /* don't zap if compiled without libblkid */
279 zap = 0;
280#endif
ff3bed80
KZ
281 }
282
283 if (zap) {
979f1dd5 284 /*
d68f402c 285 * Wipe bootbits
979f1dd5 286 */
d68f402c 287 char buf[1024] = { '\0' };
ff3bed80 288
6af18227 289 if (lseek(ctl->fd, 0, SEEK_SET) != 0)
00a7d0d2 290 errx(EXIT_FAILURE, _("unable to rewind swap-device"));
ff3bed80 291
6af18227 292 if (write_all(ctl->fd, buf, sizeof(buf)))
00a7d0d2 293 errx(EXIT_FAILURE, _("unable to erase bootbits sectors"));
979f1dd5
KZ
294#ifdef HAVE_LIBBLKID
295 /*
296 * Wipe rest of the device
297 */
298 if (!pr)
6af18227 299 pr = new_prober(ctl);
979f1dd5
KZ
300
301 blkid_probe_enable_superblocks(pr, 1);
302 blkid_probe_enable_partitions(pr, 0);
c1f1b301 303 blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC|BLKID_SUBLKS_TYPE);
979f1dd5 304
c1f1b301 305 while (blkid_do_probe(pr) == 0) {
a0b42dc3
KZ
306 const char *data = NULL;
307
c1f1b301 308 if (blkid_probe_lookup_value(pr, "TYPE", &data, NULL) == 0 && data)
fabf29f4 309 warnx(_("%s: warning: wiping old %s signature."), ctl->devname, data);
979f1dd5 310 blkid_do_wipe(pr, 0);
c1f1b301 311 }
979f1dd5
KZ
312#endif
313 } else {
314 warnx(_("%s: warning: don't erase bootbits sectors"),
fabf29f4 315 ctl->devname);
979f1dd5
KZ
316 if (type)
317 fprintf(stderr, _(" (%s partition table detected). "), type);
979f1dd5
KZ
318 else
319 fprintf(stderr, _(" (compiled without libblkid). "));
8c219bf4 320 fprintf(stderr, _("Use -f to force.\n"));
ff3bed80 321 }
acec6eec 322 free(type);
979f1dd5
KZ
323#ifdef HAVE_LIBBLKID
324 blkid_free_probe(pr);
325#endif
ff3bed80
KZ
326}
327
3ba01c14
KZ
328#define SIGNATURE_OFFSET 1024
329
330static void write_header_to_device(struct mkswap_control *ctl)
331{
332 assert(ctl);
333 assert(ctl->fd > -1);
334 assert(ctl->signature_page);
335
336 if (lseek(ctl->fd, SIGNATURE_OFFSET, SEEK_SET) != SIGNATURE_OFFSET)
337 errx(EXIT_FAILURE, _("unable to rewind swap-device"));
338
339 if (write_all(ctl->fd, (char *) ctl->signature_page + SIGNATURE_OFFSET,
340 ctl->pagesize - SIGNATURE_OFFSET) == -1)
341 err(EXIT_FAILURE,
342 _("%s: unable to write signature page"),
343 ctl->devname);
344}
345
9a83b03c
KZ
346int main(int argc, char **argv)
347{
99f78758 348 struct mkswap_control ctl = { .fd = -1 };
cc706d9f 349 int c, permMask;
9a83b03c 350 uint64_t sz;
8a101b14 351 int version = SWAP_VERSION;
9a83b03c 352 char *block_count = NULL, *strsz = NULL;
766dd757 353#ifdef HAVE_LIBUUID
7b241808 354 const char *opt_uuid = NULL;
756bfd01
KZ
355 uuid_t uuid_dat;
356#endif
6c7d5ae9 357 static const struct option longopts[] = {
87918040
SK
358 { "check", no_argument, NULL, 'c' },
359 { "force", no_argument, NULL, 'f' },
360 { "pagesize", required_argument, NULL, 'p' },
361 { "label", required_argument, NULL, 'L' },
362 { "swapversion", required_argument, NULL, 'v' },
363 { "uuid", required_argument, NULL, 'U' },
364 { "version", no_argument, NULL, 'V' },
365 { "help", no_argument, NULL, 'h' },
366 { NULL, 0, NULL, 0 }
e079c4e6 367 };
eb63b9b8 368
7eda085c
KZ
369 setlocale(LC_ALL, "");
370 bindtextdomain(PACKAGE, LOCALEDIR);
371 textdomain(PACKAGE);
2c308875 372 close_stdout_atexit();
5c36a0eb 373
e079c4e6
SK
374 while((c = getopt_long(argc, argv, "cfp:L:v:U:Vh", longopts, NULL)) != -1) {
375 switch (c) {
376 case 'c':
de3822c3 377 ctl.check = 1;
e079c4e6
SK
378 break;
379 case 'f':
de3822c3 380 ctl.force = 1;
e079c4e6
SK
381 break;
382 case 'p':
de3822c3 383 ctl.user_pagesize = strtou32_or_err(optarg, _("parsing page size failed"));
e079c4e6
SK
384 break;
385 case 'L':
de3822c3 386 ctl.opt_label = optarg;
e079c4e6
SK
387 break;
388 case 'v':
8c219bf4 389 version = strtos32_or_err(optarg, _("parsing version number failed"));
de3822c3
SK
390 if (version != SWAP_VERSION)
391 errx(EXIT_FAILURE,
392 _("swapspace version %d is not supported"), version);
e079c4e6
SK
393 break;
394 case 'U':
93bf0f28 395#ifdef HAVE_LIBUUID
e079c4e6 396 opt_uuid = optarg;
93bf0f28 397#else
4e096801 398 warnx(_("warning: ignoring -U (UUIDs are unsupported by %s)"),
e079c4e6 399 program_invocation_short_name);
93bf0f28 400#endif
e079c4e6
SK
401 break;
402 case 'V':
2c308875 403 print_version(EXIT_SUCCESS);
e079c4e6 404 case 'h':
6e1eda6f 405 usage();
e079c4e6 406 default:
677ec86c 407 errtryhelp(EXIT_FAILURE);
e079c4e6
SK
408 }
409 }
3ba01c14 410
e079c4e6 411 if (optind < argc)
fabf29f4 412 ctl.devname = argv[optind++];
e079c4e6
SK
413 if (optind < argc)
414 block_count = argv[optind++];
415 if (optind != argc) {
8c219bf4 416 warnx(_("only one device argument is currently supported"));
6e1eda6f 417 errtryhelp(EXIT_FAILURE);
6dbe3af9 418 }
eb63b9b8 419
766dd757 420#ifdef HAVE_LIBUUID
93bf0f28
MS
421 if(opt_uuid) {
422 if (uuid_parse(opt_uuid, uuid_dat) != 0)
8c219bf4 423 errx(EXIT_FAILURE, _("error: parsing UUID failed"));
93bf0f28
MS
424 } else
425 uuid_generate(uuid_dat);
de3822c3 426 ctl.uuid = uuid_dat;
756bfd01
KZ
427#endif
428
de3822c3 429 init_signature_page(&ctl); /* get pagesize and allocate signature page */
eb63b9b8 430
fabf29f4 431 if (!ctl.devname) {
00a7d0d2 432 warnx(_("error: Nowhere to set up swap on?"));
6e1eda6f 433 errtryhelp(EXIT_FAILURE);
fd6b7a7f 434 }
eb63b9b8 435 if (block_count) {
20543e61 436 /* this silly user specified the number of blocks explicitly */
33fb5cfd
KZ
437 uint64_t blks = strtou64_or_err(block_count,
438 _("invalid block count argument"));
8591859c 439 ctl.npages = blks / (ctl.pagesize / 1024);
eb63b9b8 440 }
3ba01c14 441
de3822c3 442 sz = get_size(&ctl);
8591859c
KZ
443 if (!ctl.npages)
444 ctl.npages = sz;
445 else if (ctl.npages > sz && !ctl.force)
00a7d0d2
SK
446 errx(EXIT_FAILURE,
447 _("error: "
fdbd7bb9 448 "size %llu KiB is larger than device size %"PRIu64" KiB"),
8591859c 449 ctl.npages * (ctl.pagesize / 1024), sz * (ctl.pagesize / 1024));
5c36a0eb 450
8591859c 451 if (ctl.npages < MIN_GOODPAGES)
793a05f8
SK
452 errx(EXIT_FAILURE,
453 _("error: swap area needs to be at least %ld KiB"),
de3822c3 454 (long)(MIN_GOODPAGES * ctl.pagesize / 1024));
8591859c 455 if (ctl.npages > UINT32_MAX) {
a1466ab2 456 /* true when swap is bigger than 17.59 terabytes */
8591859c 457 ctl.npages = UINT32_MAX;
00a7d0d2 458 warnx(_("warning: truncating swap area to %llu KiB"),
8591859c 459 ctl.npages * ctl.pagesize / 1024);
726f69e2 460 }
5c36a0eb 461
fabf29f4 462 if (is_mounted(ctl.devname))
dceb1f22 463 errx(EXIT_FAILURE, _("error: "
4e096801 464 "%s is mounted; will not make swapspace"),
fabf29f4
KZ
465 ctl.devname);
466
467 open_device(&ctl);
cc706d9f
WR
468 permMask = S_ISBLK(ctl.devstat.st_mode) ? 07007 : 07077;
469 if ((ctl.devstat.st_mode & permMask) != 0)
470 warnx(_("%s: insecure permissions %04o, %04o suggested."),
471 ctl.devname, ctl.devstat.st_mode & 07777,
472 ~permMask & 0666);
473 if (getuid() == 0 && S_ISREG(ctl.devstat.st_mode) && ctl.devstat.st_uid != 0)
474 warnx(_("%s: insecure file owner %d, 0 (root) suggested."),
475 ctl.devname, ctl.devstat.st_uid);
476
dceb1f22 477
de3822c3
SK
478 if (ctl.check)
479 check_blocks(&ctl);
4c85aa3a 480
6af18227 481 wipe_device(&ctl);
ff3bed80 482
99f78758 483 assert(ctl.hdr);
de3822c3 484 ctl.hdr->version = version;
8591859c
KZ
485 ctl.hdr->last_page = ctl.npages - 1;
486 ctl.hdr->nr_badpages = ctl.nbadpages;
5c36a0eb 487
8591859c 488 if ((ctl.npages - MIN_GOODPAGES) < ctl.nbadpages)
00a7d0d2 489 errx(EXIT_FAILURE, _("Unable to set up swap-space: unreadable"));
4c85aa3a 490
9a83b03c
KZ
491 sz = (ctl.npages - ctl.nbadpages - 1) * ctl.pagesize;
492 strsz = size_to_human_string(SIZE_SUFFIX_SPACE | SIZE_SUFFIX_3LETTER, sz);
493
fdbd7bb9 494 printf(_("Setting up swapspace version %d, size = %s (%"PRIu64" bytes)\n"),
9a83b03c 495 version, strsz, sz);
acec6eec 496 free(strsz);
5c36a0eb 497
3ba01c14
KZ
498 set_signature(&ctl);
499 set_uuid_and_label(&ctl);
756bfd01 500
3ba01c14 501 write_header_to_device(&ctl);
99f78758
KZ
502
503 deinit_signature_page(&ctl);
504
3e18b040 505#ifdef HAVE_LIBSELINUX
fabf29f4 506 if (S_ISREG(ctl.devstat.st_mode) && is_selinux_enabled() > 0) {
3e18b040
KZ
507 security_context_t context_string;
508 security_context_t oldcontext;
509 context_t newcontext;
510
de3822c3 511 if (fgetfilecon(ctl.fd, &oldcontext) < 0) {
00a7d0d2
SK
512 if (errno != ENODATA)
513 err(EXIT_FAILURE,
8d1b0fe2 514 _("%s: unable to obtain selinux file label"),
fabf29f4
KZ
515 ctl.devname);
516 if (matchpathcon(ctl.devname, ctl.devstat.st_mode, &oldcontext))
00a7d0d2 517 errx(EXIT_FAILURE, _("unable to matchpathcon()"));
3e18b040
KZ
518 }
519 if (!(newcontext = context_new(oldcontext)))
00a7d0d2 520 errx(EXIT_FAILURE, _("unable to create new selinux context"));
3e18b040 521 if (context_type_set(newcontext, SELINUX_SWAPFILE_TYPE))
00a7d0d2 522 errx(EXIT_FAILURE, _("couldn't compute selinux context"));
3e18b040
KZ
523
524 context_string = context_str(newcontext);
525
526 if (strcmp(context_string, oldcontext)!=0) {
d97dc0ee 527 if (fsetfilecon(ctl.fd, context_string) && errno != ENOTSUP)
00a7d0d2 528 err(EXIT_FAILURE, _("unable to relabel %s to %s"),
fabf29f4 529 ctl.devname, context_string);
3e18b040
KZ
530 }
531 context_free(newcontext);
532 freecon(oldcontext);
533 }
534#endif
833b7e0d
SK
535 /*
536 * A subsequent swapon() will fail if the signature
537 * is not actually on disk. (This is a kernel bug.)
538 * The fsync() in close_fd() will take care of writing.
539 */
de3822c3 540 if (close_fd(ctl.fd) != 0)
833b7e0d 541 err(EXIT_FAILURE, _("write failed"));
a4d3e778 542 return EXIT_SUCCESS;
6dbe3af9 543}