2
libparted - a library for manipulating disk partitions
3
Copyright (C) 1999-2000, 2002, 2007-2012 Free Software Foundation, Inc.
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 3 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program. If not, see <http://www.gnu.org/licenses/>.
19
/* It's a bit silly calling a swap partition a file system. Oh well... */
23
#include <parted/parted.h>
24
#include <parted/endian.h>
28
# define _(String) dgettext (PACKAGE, String)
30
# define _(String) (String)
31
#endif /* ENABLE_NLS */
34
#include <uuid/uuid.h>
36
#define SWAP_SPECIFIC(fs) ((SwapSpecific*) (fs->type_specific))
37
#define BUFFER_SIZE 128
39
#define LINUXSWAP_BLOCK_SIZES ((int[2]){512, 0})
45
/* ripped from mkswap */
47
char bootbits[1024]; /* Space for disklabel etc. */
51
unsigned char sws_uuid[16];
52
unsigned char sws_volume[16];
53
uint32_t padding[117];
66
PedSector page_sectors;
67
unsigned int page_count;
69
unsigned int max_bad_pages;
72
static PedFileSystemType _swap_v0_type;
73
static PedFileSystemType _swap_v1_type;
74
static PedFileSystemType _swap_swsusp_type;
76
static PedFileSystem* _swap_v0_open (PedGeometry* geom);
77
static PedFileSystem* _swap_v1_open (PedGeometry* geom);
78
static PedFileSystem* _swap_swsusp_open (PedGeometry* geom);
79
static int swap_close (PedFileSystem* fs);
82
_generic_swap_probe (PedGeometry* geom, int kind)
85
SwapSpecific* fs_info;
86
PedGeometry* probed_geom;
89
/* Fail the swap-file-system-recognizing test when sector size
90
is not the default. */
91
if (geom->dev->sector_size != PED_SECTOR_SIZE_DEFAULT)
95
/* Check for old style swap partitions. */
97
fs = _swap_v0_open(geom);
99
/* Check for new style swap partitions. */
101
fs = _swap_v1_open(geom);
103
/* Check for swap partitions containing swsusp data. */
105
fs = _swap_swsusp_open(geom);
114
fs_info = SWAP_SPECIFIC (fs);
116
if (fs_info->version)
117
length = fs_info->page_sectors * fs_info->page_count;
119
length = geom->length;
121
probed_geom = ped_geometry_new (geom->dev, geom->start, length);
135
swap_init (PedFileSystem* fs, int fresh)
137
SwapSpecific* fs_info = SWAP_SPECIFIC (fs);
139
fs_info->page_sectors = getpagesize () / 512;
140
fs_info->page_count = fs->geom->length / fs_info->page_sectors;
141
fs_info->version = 1;
142
fs_info->max_bad_pages = (getpagesize()
143
- sizeof (SwapNewHeader)) / 4;
148
memset (fs_info->header, 0, getpagesize());
150
/* version is always 1 here */
151
uuid_generate (uuid_dat);
152
memcpy (fs_info->header->new.sws_uuid, uuid_dat,
153
sizeof (fs_info->header->new.sws_uuid));
157
return ped_geometry_read (fs->geom, fs_info->header,
158
0, fs_info->page_sectors);
162
static PedFileSystem*
163
swap_alloc (PedGeometry* geom)
166
SwapSpecific* fs_info;
168
fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
172
fs->type_specific = (SwapSpecific*) ped_malloc (sizeof (SwapSpecific));
173
if (!fs->type_specific)
176
fs_info = SWAP_SPECIFIC (fs);
177
fs_info->header = ped_malloc (getpagesize());
178
if (!fs_info->header)
179
goto error_free_type_specific;
181
fs_info = SWAP_SPECIFIC (fs);
182
fs_info->buffer_size = getpagesize() * BUFFER_SIZE;
183
fs_info->buffer = ped_malloc (fs_info->buffer_size);
184
if (!fs_info->buffer)
185
goto error_free_header;
187
fs->geom = ped_geometry_duplicate (geom);
189
goto error_free_buffer;
190
fs->type = &_swap_v1_type;
194
free (fs_info->buffer);
196
free (fs_info->header);
197
error_free_type_specific:
198
free (fs->type_specific);
206
swap_free (PedFileSystem* fs)
208
SwapSpecific* fs_info = SWAP_SPECIFIC (fs);
210
free (fs_info->buffer);
211
free (fs_info->header);
212
free (fs->type_specific);
214
ped_geometry_destroy (fs->geom);
218
static PedFileSystem*
219
_swap_v0_open (PedGeometry* geom)
222
SwapSpecific* fs_info;
225
fs = swap_alloc (geom);
230
fs_info = SWAP_SPECIFIC (fs);
231
if (!ped_geometry_read (fs->geom, fs_info->header, 0,
232
fs_info->page_sectors))
235
sig = ((char*) fs_info->header) + getpagesize() - 10;
236
if (strncmp (sig, "SWAP-SPACE", 10) == 0) {
237
fs_info->version = 0;
239
= PED_MIN (fs->geom->length / fs_info->page_sectors,
240
8 * (getpagesize() - 10));
244
memcpy (_sig, sig, 10);
246
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
247
_("Unrecognised old style linux swap signature '%10s'."), _sig);
260
static PedFileSystem*
261
_swap_v1_open (PedGeometry* geom)
264
SwapSpecific* fs_info;
267
fs = swap_alloc (geom);
270
/* swap_init (fs, 0); */
272
/* fs_info = SWAP_SPECIFIC (fs); */
273
/* if (!ped_geometry_read (fs->geom, fs_info->header, 0, */
274
/* fs_info->page_sectors)) */
275
if (!swap_init(fs, 0))
278
fs_info = SWAP_SPECIFIC (fs);
280
sig = ((char*) fs_info->header) + getpagesize() - 10;
281
if (strncmp (sig, "SWAPSPACE2", 10) == 0) {
282
fs_info->version = 1;
283
fs_info->page_count = fs_info->header->new.last_page;
287
memcpy (_sig, sig, 10);
289
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
290
_("Unrecognised new style linux swap signature '%10s'."), _sig);
303
static PedFileSystem*
304
_swap_swsusp_open (PedGeometry* geom)
307
SwapSpecific* fs_info;
310
fs = swap_alloc (geom);
313
fs->type = &_swap_swsusp_type;
316
fs_info = SWAP_SPECIFIC (fs);
317
if (!ped_geometry_read (fs->geom, fs_info->header, 0,
318
fs_info->page_sectors))
321
sig = ((char*) fs_info->header) + getpagesize() - 10;
322
if (strncmp (sig, "S1SUSPEND", 9) == 0) {
323
fs_info->version = -1;
327
memcpy (_sig, sig, 9);
329
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
330
_("Unrecognised swsusp linux swap signature '%9s'."), _sig);
344
swap_close (PedFileSystem* fs)
351
_swap_v0_probe (PedGeometry* geom) {
352
return _generic_swap_probe (geom, 0);
356
_swap_v1_probe (PedGeometry* geom) {
357
return _generic_swap_probe (geom, 1);
361
_swap_swsusp_probe (PedGeometry* geom) {
362
return _generic_swap_probe (geom, -1);
365
static PedFileSystemOps _swap_v0_ops = {
366
probe: _swap_v0_probe,
369
static PedFileSystemOps _swap_v1_ops = {
370
probe: _swap_v1_probe,
373
static PedFileSystemOps _swap_swsusp_ops = {
374
probe: _swap_swsusp_probe,
377
static PedFileSystemType _swap_v0_type = {
380
name: "linux-swap(v0)",
381
block_sizes: LINUXSWAP_BLOCK_SIZES
384
static PedFileSystemType _swap_v1_type = {
387
name: "linux-swap(v1)",
388
block_sizes: LINUXSWAP_BLOCK_SIZES
391
static PedFileSystemType _swap_swsusp_type = {
393
ops: &_swap_swsusp_ops,
395
block_sizes: LINUXSWAP_BLOCK_SIZES
399
ped_file_system_linux_swap_init ()
401
ped_file_system_type_register (&_swap_v0_type);
402
ped_file_system_type_register (&_swap_v1_type);
403
ped_file_system_type_register (&_swap_swsusp_type);
405
ped_file_system_alias_register (&_swap_v0_type, "linux-swap(old)", 1);
406
ped_file_system_alias_register (&_swap_v1_type, "linux-swap(new)", 1);
407
ped_file_system_alias_register (&_swap_v1_type, "linux-swap", 0);
411
ped_file_system_linux_swap_done ()
413
ped_file_system_alias_unregister (&_swap_v0_type, "linux-swap(old)");
414
ped_file_system_alias_unregister (&_swap_v1_type, "linux-swap(new)");
415
ped_file_system_alias_unregister (&_swap_v1_type, "linux-swap");
417
ped_file_system_type_unregister (&_swap_v0_type);
418
ped_file_system_type_unregister (&_swap_v1_type);
419
ped_file_system_type_unregister (&_swap_swsusp_type);