== SYNOPSIS
-*mkswap* [options] _device_ [_size_]
+*mkswap* [options] _device_ [_blocks_]
+
+*mkswap* [options] --size _size_ --file _file_
== DESCRIPTION
The _device_ argument will usually be a disk partition (something like _/dev/sdb7_) but can also be a file. The Linux kernel does not look at partition IDs, but many installation scripts will assume that partitions of hex type 82 (LINUX_SWAP) are meant to be swap partitions. (*Warning: Solaris also uses this type. Be careful not to kill your Solaris partitions.*)
-The _size_ parameter is superfluous but retained for backwards compatibility. (It specifies the desired size of the swap area in 1024-byte blocks. *mkswap* will use the entire partition or file if it is omitted. Specifying it is unwise - a typo may destroy your disk.)
+The _blocks_ parameter is superfluous but retained for backwards compatibility. (It specifies the desired size of the swap area in 1024-byte blocks. *mkswap* will use the entire partition or file if it is omitted. Specifying it is unwise - a typo may destroy your disk.)
After creating the swap area, you need the *swapon*(8) command to start using it. Usually swap areas are listed in _/etc/fstab_ so that they can be taken into use at boot time by a *swapon -a* command in some boot script.
*-c*, *--check*::
Check the device (if it is a block device) for bad blocks before creating the swap area. If any bad blocks are found, the count is printed.
+*-F*, *--file*::
+Create a swap file with the appropriate file permissions and populated blocks on disk.
+
*-f*, *--force*::
Go ahead even if the command is stupid. This allows the creation of a swap area larger than the file or partition it resides on.
+
*-o*, *--offset* _offset_::
Specify the _offset_ to write the swap area to.
+*-s*, *--size* _size_::
+Specify the size of the created swap file in bytes and may be followed by a multiplicative suffix: KiB (=1024), MiB (=1024*1024), and so on for GiB, TiB, PiB, EiB, ZiB and YiB (the "iB" is optional, e.g., "K" has the same meaning as "KiB"). If the file exists and is larger than _size_, it will be truncated to this size. This option only makes sense when used with *--file*.
+
*-v*, *--swapversion 1*::
Specify the swap-space version. (This option is currently pointless, as the old *-v 0* option has become obsolete and now only *-v 1* is supported. The kernel has not supported v0 swap-space format since 2.5.22 (June 2002). The new version v1 is supported since 2.1.117 (August 1998).)
char *opt_label; /* LABEL as specified on command line */
unsigned char *uuid; /* UUID parsed by libbuuid */
+ unsigned long long filesz; /* desired swap file size */
+
size_t nbad_extents;
enum ENDIANNESS endianness;
unsigned int check:1, /* --check */
verbose:1, /* --verbose */
quiet:1, /* --quiet */
- force:1; /* --force */
+ force:1, /* --force */
+ file:1; /* --file */
};
static uint32_t cpu32_to_endianness(uint32_t v, enum ENDIANNESS e)
_(" -e, --endianness=<value> specify the endianness to use "
"(%s, %s or %s)\n"), "native", "little", "big");
fputs(_(" -o, --offset OFFSET specify the offset in the device\n"), out);
+ fputs(_(" -s, --size SIZE specify the size of a swap file in bytes\n"), out);
+ fputs(_(" -F, --file create a swap file\n"), out);
fputs(_(" --verbose verbose output\n"), out);
fprintf(out,
/* return size in pages */
static unsigned long long get_size(const struct mkswap_control *ctl)
{
- int fd;
unsigned long long size;
- fd = open(ctl->devname, O_RDONLY);
- if (fd < 0)
- err(EXIT_FAILURE, _("cannot open %s"), ctl->devname);
- if (blkdev_get_size(fd, &size) < 0)
- err(EXIT_FAILURE, _("cannot determine size of %s"), ctl->devname);
- if ((unsigned long long) ctl->offset > size)
- errx(EXIT_FAILURE, _("offset larger than file size"));
+ if (ctl->file && ctl->filesz)
+ size = ctl->filesz;
+ else {
+ int fd = open(ctl->devname, O_RDONLY);
+ if (fd < 0)
+ err(EXIT_FAILURE, _("cannot open %s"), ctl->devname);
+ if (blkdev_get_size(fd, &size) < 0)
+ err(EXIT_FAILURE, _("cannot determine size of %s"), ctl->devname);
+ if ((unsigned long long) ctl->offset > size)
+ errx(EXIT_FAILURE, _("offset larger than file size"));
+ close(fd);
+ }
size -= ctl->offset;
size /= ctl->pagesize;
-
- close(fd);
return size;
}
assert(ctl);
assert(ctl->devname);
- if (stat(ctl->devname, &ctl->devstat) < 0)
- err(EXIT_FAILURE, _("stat of %s failed"), ctl->devname);
- ctl->fd = open_blkdev_or_file(&ctl->devstat, ctl->devname, O_RDWR);
+ if (ctl->file) {
+ if (stat(ctl->devname, &ctl->devstat) == 0) {
+ if (!S_ISREG(ctl->devstat.st_mode))
+ err(EXIT_FAILURE, _("cannot create swap file %s: node isn't regular file"), ctl->devname);
+ if (chmod(ctl->devname, 0600) < 9)
+ err(EXIT_FAILURE, _("cannot set permissions on swap file %s"), ctl->devname);
+ }
+ ctl->fd = open(ctl->devname, O_RDWR | O_CREAT, 0600);
+ } else {
+ if (stat(ctl->devname, &ctl->devstat) < 0)
+ err(EXIT_FAILURE, _("stat of %s failed"), ctl->devname);
+ ctl->fd = open_blkdev_or_file(&ctl->devstat, ctl->devname, O_RDWR);
+ }
if (ctl->fd < 0)
err(EXIT_FAILURE, _("cannot open %s"), ctl->devname);
+ if (ctl->file && ctl->filesz) {
+ if (ftruncate(ctl->fd, ctl->filesz) < 0)
+ err(EXIT_FAILURE, _("couldn't allocate swap file %s"), ctl->devname);
+#ifdef HAVE_POSIX_FALLOCATE
+ errno = posix_fallocate(ctl->fd, 0, ctl->filesz);
+ if (errno)
+ err(EXIT_FAILURE, _("couldn't allocate swap file %s"), ctl->devname);
+#elif defined(HAVE_FALLOCATE)
+ if (fallocate(ctl->fd, 0, 0, ctl->filesz) < 0)
+ err(EXIT_FAILURE, _("couldn't allocate swap file %s"), ctl->devname);
+#endif
+ }
if (blkdev_lock(ctl->fd, ctl->devname, ctl->lockmode) != 0)
exit(EXIT_FAILURE);
{ "uuid", required_argument, NULL, 'U' },
{ "endianness", required_argument, NULL, 'e' },
{ "offset", required_argument, NULL, 'o' },
+ { "size", required_argument, NULL, 's' },
+ { "file", no_argument, NULL, 'F' },
{ "version", no_argument, NULL, 'V' },
{ "help", no_argument, NULL, 'h' },
{ "lock", optional_argument, NULL, OPT_LOCK },
textdomain(PACKAGE);
close_stdout_atexit();
- while((c = getopt_long(argc, argv, "cfp:qL:v:U:e:o:Vh", longopts, NULL)) != -1) {
+ while((c = getopt_long(argc, argv, "cfp:qL:v:U:e:o:s:FVh", longopts, NULL)) != -1) {
err_exclusive_options(c, longopts, excl, excl_st);
ctl.offset = str2unum_or_err(optarg,
10, _("Invalid offset"), SINT_MAX(off_t));
break;
+ case 's':
+ ctl.filesz = strtosize_or_err(optarg, _("Invalid size"));
+ break;
+ case 'F':
+ ctl.file = 1;
+ break;
case 'V':
print_version(EXIT_SUCCESS);
break;