From 7369f0ce5fdde7f8a1cc6e49211469b905c2c58f Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 10 Jan 2005 23:58:11 -0500 Subject: [PATCH] Apply Janos Farkas's patch to support extracting the uuid and label information from swap partitions. Also make sure that if a partition has a label removed, that the label is removed form the blkid cache as well. Add support for detecting 32k and 64k pagesize swap files. --- lib/blkid/ChangeLog | 21 ++++++++++++- lib/blkid/probe.c | 86 +++++++++++++++++++++++++++++++++++++++++++---------- lib/blkid/probe.h | 19 +++++++----- 3 files changed, 102 insertions(+), 24 deletions(-) diff --git a/lib/blkid/ChangeLog b/lib/blkid/ChangeLog index c4be87f..679e48b 100644 --- a/lib/blkid/ChangeLog +++ b/lib/blkid/ChangeLog @@ -1,3 +1,22 @@ +2005-01-10 Theodore Ts'o + + * probe.c: Integrate and fix up Janos Farkas's patch. Version 0 + swap headers won't ever have uuid/labels. Also, if the + swap partition is recreated without a label, make sure + label in the blkid file gets freed. + (get_ext2_info, probe_vfat, probe_msdos, probe_reiserfs): + Make sure the label is cleared from the blkid file if the + label gets cleared from the filesystem. + (probe_romfs): Avoid dereferencing a null pointer of the + label is not present. + +2005-01-10 Janos Farkas + + * probe.h: Define linux swap format. + + * probe.c: Fetch uuid/label from swap headers if present. Mark + swap types as needing extra probe. + 2005-01-05 Theodore Ts'o * save.c (save_dev): Don't save relative pathnames since they @@ -168,7 +187,7 @@ * probe.c, probe.h: Fix XFS superblock definition. Add support to extract UUID and labels for JFS and romfs. (Thanks to - Janos Farkas .) + Janos Farkas .) 2003-03-30 Theodore Ts'o diff --git a/lib/blkid/probe.c b/lib/blkid/probe.c index c014580..d91e2a3 100644 --- a/lib/blkid/probe.c +++ b/lib/blkid/probe.c @@ -88,10 +88,9 @@ static void get_ext2_info(blkid_dev dev, unsigned char *buf) blkid_le32(es->s_feature_incompat), blkid_le32(es->s_feature_ro_compat))); - if (strlen(es->s_volume_name)) { + if (strlen(es->s_volume_name)) label = es->s_volume_name; - blkid_set_tag(dev, "LABEL", label, sizeof(es->s_volume_name)); - } + blkid_set_tag(dev, "LABEL", label, sizeof(es->s_volume_name)); set_uuid(dev, es->s_uuid); } @@ -168,6 +167,7 @@ static int probe_vfat(int fd __BLKID_ATTR((unused)), struct vfat_super_block *vs; char serno[10]; const char *label = 0; + int label_len = 0; vs = (struct vfat_super_block *)buf; @@ -176,14 +176,16 @@ static int probe_vfat(int fd __BLKID_ATTR((unused)), while (*end == ' ' && end >= vs->vs_label) --end; - if (end >= vs->vs_label) + if (end >= vs->vs_label) { label = vs->vs_label; - blkid_set_tag(dev, "LABEL", label, end - vs->vs_label + 1); + label_len = end - vs->vs_label + 1; + } } /* We can't just print them as %04X, because they are unaligned */ sprintf(serno, "%02X%02X-%02X%02X", vs->vs_serno[3], vs->vs_serno[2], vs->vs_serno[1], vs->vs_serno[0]); + blkid_set_tag(dev, "LABEL", label, label_len); blkid_set_tag(dev, "UUID", serno, sizeof(serno)); return 0; @@ -198,21 +200,24 @@ static int probe_msdos(int fd __BLKID_ATTR((unused)), struct msdos_super_block *ms = (struct msdos_super_block *) buf; char serno[10]; const char *label = 0; + int label_len = 0; if (strncmp(ms->ms_label, "NO NAME", 7)) { char *end = ms->ms_label + sizeof(ms->ms_label) - 1; while (*end == ' ' && end >= ms->ms_label) --end; - if (end >= ms->ms_label) + if (end >= ms->ms_label) { label = ms->ms_label; - blkid_set_tag(dev, "LABEL", label, end - ms->ms_label + 1); + label_len = end - ms->ms_label + 1; + } } /* We can't just print them as %04X, because they are unaligned */ sprintf(serno, "%02X%02X-%02X%02X", ms->ms_serno[3], ms->ms_serno[2], ms->ms_serno[1], ms->ms_serno[0]); blkid_set_tag(dev, "UUID", serno, 0); + blkid_set_tag(dev, "LABEL", label, label_len); blkid_set_tag(dev, "SEC_TYPE", "msdos", sizeof("msdos")); return 0; @@ -256,9 +261,9 @@ static int probe_reiserfs(int fd __BLKID_ATTR((unused)), !strcmp(id->bim_magic, "ReIsEr3Fs")) { if (strlen(rs->rs_label)) label = rs->rs_label; - blkid_set_tag(dev, "LABEL", label, sizeof(rs->rs_label)); set_uuid(dev, rs->rs_uuid); } + blkid_set_tag(dev, "LABEL", label, sizeof(rs->rs_label)); return 0; } @@ -294,7 +299,54 @@ static int probe_romfs(int fd __BLKID_ATTR((unused)), if (strlen((char *) ros->ros_volume)) label = (char *) ros->ros_volume; - blkid_set_tag(dev, "LABEL", label, strlen(label)); + blkid_set_tag(dev, "LABEL", label, 0); + return 0; +} + +static int probe_swap0(int fd __BLKID_ATTR((unused)), + blkid_cache cache __BLKID_ATTR((unused)), + blkid_dev dev, + struct blkid_magic *id __BLKID_ATTR((unused)), + unsigned char *buf __BLKID_ATTR((unused))) +{ + blkid_set_tag(dev, "UUID", 0, 0); + blkid_set_tag(dev, "LABEL", 0, 0); + return 0; +} + +static int probe_swap1(int fd, + blkid_cache cache __BLKID_ATTR((unused)), + blkid_dev dev, + struct blkid_magic *id __BLKID_ATTR((unused)), + unsigned char *buf __BLKID_ATTR((unused))) +{ + struct swap_id_block *sws; + const char *label = 0; + + probe_swap0(fd, cache, dev, id, buf); + /* + * Version 1 swap headers are always located at offset of 1024 + * bytes, although the swap signature itself is located at the + * end of the page (which may vary depending on hardware + * pagesize). + */ + if (lseek(fd, 1024, SEEK_SET) < 0) return 1; + if (!(sws = (struct swap_id_block *)malloc(1024))) return 1; + if (read(fd, sws, 1024) != 1024) { + free(sws); + return 1; + } + + /* arbitrary sanity check.. is there any garbage down there? */ + if (sws->sws_pad[32] == 0 && sws->sws_pad[33] == 0) { + if (sws->sws_volume[0]) + blkid_set_tag(dev, "LABEL", sws->sws_volume, + sizeof(sws->sws_volume)); + if (sws->sws_uuid[0]) + set_uuid(dev, sws->sws_uuid); + } + free(sws); + return 0; } @@ -438,12 +490,16 @@ static struct blkid_magic type_array[] = { { "ufs", 8, 0x55c, 4, "T\031\001\000", 0 }, { "hpfs", 8, 0, 4, "I\350\225\371", 0 }, { "sysv", 0, 0x3f8, 4, "\020~\030\375", 0 }, - { "swap", 0, 0xff6, 10, "SWAP-SPACE", 0 }, - { "swap", 0, 0xff6, 10, "SWAPSPACE2", 0 }, - { "swap", 0, 0x1ff6, 10, "SWAP-SPACE", 0 }, - { "swap", 0, 0x1ff6, 10, "SWAPSPACE2", 0 }, - { "swap", 0, 0x3ff6, 10, "SWAP-SPACE", 0 }, - { "swap", 0, 0x3ff6, 10, "SWAPSPACE2", 0 }, + { "swap", 0, 0xff6, 10, "SWAP-SPACE", probe_swap0 }, + { "swap", 0, 0xff6, 10, "SWAPSPACE2", probe_swap1 }, + { "swap", 0, 0x1ff6, 10, "SWAP-SPACE", probe_swap0 }, + { "swap", 0, 0x1ff6, 10, "SWAPSPACE2", probe_swap1 }, + { "swap", 0, 0x3ff6, 10, "SWAP-SPACE", probe_swap0 }, + { "swap", 0, 0x3ff6, 10, "SWAPSPACE2", probe_swap1 }, + { "swap", 0, 0x7ff6, 10, "SWAP-SPACE", probe_swap0 }, + { "swap", 0, 0x7ff6, 10, "SWAPSPACE2", probe_swap1 }, + { "swap", 0, 0xfff6, 10, "SWAP-SPACE", probe_swap0 }, + { "swap", 0, 0xfff6, 10, "SWAPSPACE2", probe_swap1 }, { "ocfs", 0, 8, 9, "OracleCFS", probe_ocfs }, { "ocfs2", 1, 0, 6, "OCFSV2", probe_ocfs2 }, { "ocfs2", 2, 0, 6, "OCFSV2", probe_ocfs2 }, diff --git a/lib/blkid/probe.h b/lib/blkid/probe.h index 0067600..ee91abb 100644 --- a/lib/blkid/probe.h +++ b/lib/blkid/probe.h @@ -108,6 +108,17 @@ struct romfs_super_block { unsigned char ros_volume[16]; }; +struct swap_id_block { +/* unsigned char sws_boot[1024]; */ + __u32 sws_version; + __u32 sws_lastpage; + __u32 sws_nrbad; + unsigned char sws_uuid[16]; + unsigned char sws_volume[16]; + unsigned char sws_pad[117]; + __u32 sws_badpg; +}; + /* Yucky misaligned values */ struct vfat_super_block { /* 00*/ unsigned char vs_ignored[3]; @@ -176,14 +187,6 @@ struct minix_super_block { __u32 ms_zones; }; -struct swap_header { - char sh_bootbits[1024]; - unsigned int sh_version; - unsigned int sh_last_page; - unsigned int sh_nr_badpages; - char sh_label[16]; -}; - struct mdp_superblock_s { __u32 md_magic; __u32 major_version; -- 1.8.3.1