Skip to content

Commit

Permalink
glabel: Add support for Linux swap
Browse files Browse the repository at this point in the history
Reviewed by: imp, kib
Pull Request: freebsd/freebsd-src#1205
  • Loading branch information
ricardobranco777 authored and bsdjhb committed Aug 19, 2024
2 parents 39e3003 + 78444b5 commit c0114a0
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/geom/label/glabel.8
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ EXT2FS (directory
.It
NTFS (directory
.Pa /dev/ntfs/ ) .
.It
Swap Linux (directory
.Pa /dev/swaplinux/ ) .
.El
.Pp
Support for partition metadata is implemented for:
Expand Down
1 change: 1 addition & 0 deletions sys/conf/files
Original file line number Diff line number Diff line change
Expand Up @@ -3767,6 +3767,7 @@ geom/label/g_label_ntfs.c optional geom_label
geom/label/g_label_ufs.c optional geom_label
geom/label/g_label_gpt.c optional geom_label | geom_label_gpt
geom/label/g_label_disk_ident.c optional geom_label
geom/label/g_label_swaplinux.c optional geom_label
geom/linux_lvm/g_linux_lvm.c optional geom_linux_lvm
geom/mirror/g_mirror.c optional geom_mirror
geom/mirror/g_mirror_ctl.c optional geom_mirror
Expand Down
1 change: 1 addition & 0 deletions sys/geom/label/g_label.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ const struct g_label_desc *g_labels[] = {
&g_label_ntfs,
&g_label_disk_ident,
&g_label_flashmap,
&g_label_swaplinux,
#endif
&g_label_generic,
NULL
Expand Down
1 change: 1 addition & 0 deletions sys/geom/label/g_label.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ extern struct g_label_desc g_label_gpt;
extern struct g_label_desc g_label_gpt_uuid;
extern struct g_label_desc g_label_disk_ident;
extern struct g_label_desc g_label_flashmap;
extern struct g_label_desc g_label_swaplinux;

extern void g_label_rtrim(char *label, size_t size);
#endif /* _KERNEL */
Expand Down
91 changes: 91 additions & 0 deletions sys/geom/label/g_label_swaplinux.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>

#include <geom/geom.h>
#include <geom/geom_dbg.h>
#include <geom/label/g_label.h>

/*
* Taken from
* https://github.com/util-linux/util-linux/blob/master/include/swapheader.h
*/

#define SWAP_VERSION 1
#define SWAP_UUID_LENGTH 16
#define SWAP_LABEL_LENGTH 16
#define SWAP_SIGNATURE "SWAPSPACE2"
#define SWAP_SIGNATURE_SZ (sizeof(SWAP_SIGNATURE) - 1)

struct swap_header_v1_2 {
char bootbits[1024]; /* Space for disklabel etc. */
uint32_t version;
uint32_t last_page;
uint32_t nr_badpages;
unsigned char uuid[SWAP_UUID_LENGTH];
char volume_name[SWAP_LABEL_LENGTH];
uint32_t padding[117];
uint32_t badpages[1];
};

typedef union {
struct swap_header_v1_2 header;
struct {
uint8_t reserved[PAGE_SIZE - SWAP_SIGNATURE_SZ];
char signature[SWAP_SIGNATURE_SZ];
} tail;
} swhdr_t;

#define sw_version header.version
#define sw_volume_name header.volume_name
#define sw_signature tail.signature

static void
g_label_swaplinux_taste(struct g_consumer *cp, char *label, size_t size)
{
struct g_provider *pp;
swhdr_t *hdr;

g_topology_assert_not();
pp = cp->provider;
label[0] = '\0';

KASSERT(pp->sectorsize != 0, ("Tasting a disk with 0 sectorsize"));
if ((PAGE_SIZE % pp->sectorsize) != 0)
return;

hdr = (swhdr_t *)g_read_data(cp, 0, PAGE_SIZE, NULL);
if (hdr == NULL)
return;

/* Check version and magic string */
if (hdr->sw_version == SWAP_VERSION &&
!memcmp(hdr->sw_signature, SWAP_SIGNATURE, SWAP_SIGNATURE_SZ))
G_LABEL_DEBUG(1, "linux swap detected on %s.", pp->name);
else
goto exit_free;

/* Check for volume label */
if (hdr->sw_volume_name[0] == '\0')
goto exit_free;

/* Terminate label */
hdr->sw_volume_name[sizeof(hdr->sw_volume_name) - 1] = '\0';
strlcpy(label, hdr->sw_volume_name, size);

exit_free:
g_free(hdr);
}

struct g_label_desc g_label_swaplinux = {
.ld_taste = g_label_swaplinux_taste,
.ld_dirprefix = "swaplinux/",
.ld_enabled = 1
};

G_LABEL_INIT(swaplinux, g_label_swaplinux, "Create device nodes for Linux swap");
1 change: 1 addition & 0 deletions sys/modules/geom/geom_label/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ SRCS+= g_label_iso9660.c
SRCS+= g_label_msdosfs.c
SRCS+= g_label_ntfs.c
SRCS+= g_label_ufs.c
SRCS+= g_label_swaplinux.c
SRCS+= opt_geom.h
SRCS+= vnode_if.h

Expand Down

0 comments on commit c0114a0

Please sign in to comment.