Skip to content

Commit c0114a0

Browse files
ricardobranco777bsdjhb
authored andcommitted
glabel: Add support for Linux swap
Reviewed by: imp, kib Pull Request: freebsd/freebsd-src#1205
2 parents 39e3003 + 78444b5 commit c0114a0

File tree

6 files changed

+98
-0
lines changed

6 files changed

+98
-0
lines changed

lib/geom/label/glabel.8

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ EXT2FS (directory
115115
.It
116116
NTFS (directory
117117
.Pa /dev/ntfs/ ) .
118+
.It
119+
Swap Linux (directory
120+
.Pa /dev/swaplinux/ ) .
118121
.El
119122
.Pp
120123
Support for partition metadata is implemented for:

sys/conf/files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3767,6 +3767,7 @@ geom/label/g_label_ntfs.c optional geom_label
37673767
geom/label/g_label_ufs.c optional geom_label
37683768
geom/label/g_label_gpt.c optional geom_label | geom_label_gpt
37693769
geom/label/g_label_disk_ident.c optional geom_label
3770+
geom/label/g_label_swaplinux.c optional geom_label
37703771
geom/linux_lvm/g_linux_lvm.c optional geom_linux_lvm
37713772
geom/mirror/g_mirror.c optional geom_mirror
37723773
geom/mirror/g_mirror_ctl.c optional geom_mirror

sys/geom/label/g_label.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ const struct g_label_desc *g_labels[] = {
104104
&g_label_ntfs,
105105
&g_label_disk_ident,
106106
&g_label_flashmap,
107+
&g_label_swaplinux,
107108
#endif
108109
&g_label_generic,
109110
NULL

sys/geom/label/g_label.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ extern struct g_label_desc g_label_gpt;
7878
extern struct g_label_desc g_label_gpt_uuid;
7979
extern struct g_label_desc g_label_disk_ident;
8080
extern struct g_label_desc g_label_flashmap;
81+
extern struct g_label_desc g_label_swaplinux;
8182

8283
extern void g_label_rtrim(char *label, size_t size);
8384
#endif /* _KERNEL */

sys/geom/label/g_label_swaplinux.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*-
2+
* SPDX-License-Identifier: BSD-2-Clause
3+
*/
4+
5+
#include <sys/param.h>
6+
#include <sys/systm.h>
7+
#include <sys/kernel.h>
8+
#include <sys/malloc.h>
9+
10+
#include <geom/geom.h>
11+
#include <geom/geom_dbg.h>
12+
#include <geom/label/g_label.h>
13+
14+
/*
15+
* Taken from
16+
* https://github.com/util-linux/util-linux/blob/master/include/swapheader.h
17+
*/
18+
19+
#define SWAP_VERSION 1
20+
#define SWAP_UUID_LENGTH 16
21+
#define SWAP_LABEL_LENGTH 16
22+
#define SWAP_SIGNATURE "SWAPSPACE2"
23+
#define SWAP_SIGNATURE_SZ (sizeof(SWAP_SIGNATURE) - 1)
24+
25+
struct swap_header_v1_2 {
26+
char bootbits[1024]; /* Space for disklabel etc. */
27+
uint32_t version;
28+
uint32_t last_page;
29+
uint32_t nr_badpages;
30+
unsigned char uuid[SWAP_UUID_LENGTH];
31+
char volume_name[SWAP_LABEL_LENGTH];
32+
uint32_t padding[117];
33+
uint32_t badpages[1];
34+
};
35+
36+
typedef union {
37+
struct swap_header_v1_2 header;
38+
struct {
39+
uint8_t reserved[PAGE_SIZE - SWAP_SIGNATURE_SZ];
40+
char signature[SWAP_SIGNATURE_SZ];
41+
} tail;
42+
} swhdr_t;
43+
44+
#define sw_version header.version
45+
#define sw_volume_name header.volume_name
46+
#define sw_signature tail.signature
47+
48+
static void
49+
g_label_swaplinux_taste(struct g_consumer *cp, char *label, size_t size)
50+
{
51+
struct g_provider *pp;
52+
swhdr_t *hdr;
53+
54+
g_topology_assert_not();
55+
pp = cp->provider;
56+
label[0] = '\0';
57+
58+
KASSERT(pp->sectorsize != 0, ("Tasting a disk with 0 sectorsize"));
59+
if ((PAGE_SIZE % pp->sectorsize) != 0)
60+
return;
61+
62+
hdr = (swhdr_t *)g_read_data(cp, 0, PAGE_SIZE, NULL);
63+
if (hdr == NULL)
64+
return;
65+
66+
/* Check version and magic string */
67+
if (hdr->sw_version == SWAP_VERSION &&
68+
!memcmp(hdr->sw_signature, SWAP_SIGNATURE, SWAP_SIGNATURE_SZ))
69+
G_LABEL_DEBUG(1, "linux swap detected on %s.", pp->name);
70+
else
71+
goto exit_free;
72+
73+
/* Check for volume label */
74+
if (hdr->sw_volume_name[0] == '\0')
75+
goto exit_free;
76+
77+
/* Terminate label */
78+
hdr->sw_volume_name[sizeof(hdr->sw_volume_name) - 1] = '\0';
79+
strlcpy(label, hdr->sw_volume_name, size);
80+
81+
exit_free:
82+
g_free(hdr);
83+
}
84+
85+
struct g_label_desc g_label_swaplinux = {
86+
.ld_taste = g_label_swaplinux_taste,
87+
.ld_dirprefix = "swaplinux/",
88+
.ld_enabled = 1
89+
};
90+
91+
G_LABEL_INIT(swaplinux, g_label_swaplinux, "Create device nodes for Linux swap");

sys/modules/geom/geom_label/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ SRCS+= g_label_iso9660.c
1111
SRCS+= g_label_msdosfs.c
1212
SRCS+= g_label_ntfs.c
1313
SRCS+= g_label_ufs.c
14+
SRCS+= g_label_swaplinux.c
1415
SRCS+= opt_geom.h
1516
SRCS+= vnode_if.h
1617

0 commit comments

Comments
 (0)