Merge branch 'master' of https://github.com/dsd/util-linux
* 'master' of https://github.com/dsd/util-linux: libblkid: improve identification of ISO9660 partition isosize: move ISO size functions into a shared header
This commit is contained in:
commit
63f8c66af8
|
@ -29,6 +29,7 @@
|
|||
#include "c.h"
|
||||
#include "strutils.h"
|
||||
#include "closestream.h"
|
||||
#include "iso9660.h"
|
||||
|
||||
#define ISOSIZE_EXIT_ALLFAILED 32
|
||||
#define ISOSIZE_EXIT_SOMEOK 64
|
||||
|
@ -42,56 +43,6 @@ static int is_iso(int fd)
|
|||
return memcmp(&label, &"\1CD001\1", 8);
|
||||
}
|
||||
|
||||
static int isonum_721(unsigned char *p)
|
||||
{
|
||||
return ((p[0] & 0xff)
|
||||
| ((p[1] & 0xff) << 8));
|
||||
}
|
||||
|
||||
static int isonum_722(unsigned char *p)
|
||||
{
|
||||
return ((p[1] & 0xff)
|
||||
| ((p[0] & 0xff) << 8));
|
||||
}
|
||||
|
||||
static int isonum_723(unsigned char *p, int xflag)
|
||||
{
|
||||
int le = isonum_721(p);
|
||||
int be = isonum_722(p + 2);
|
||||
|
||||
if (xflag && le != be)
|
||||
/* translation is useless */
|
||||
warnx("723error: le=%d be=%d", le, be);
|
||||
return (le);
|
||||
}
|
||||
|
||||
static int isonum_731(unsigned char *p)
|
||||
{
|
||||
return ((p[0] & 0xff)
|
||||
| ((p[1] & 0xff) << 8)
|
||||
| ((p[2] & 0xff) << 16)
|
||||
| ((p[3] & 0xff) << 24));
|
||||
}
|
||||
|
||||
static int isonum_732(unsigned char *p)
|
||||
{
|
||||
return ((p[3] & 0xff)
|
||||
| ((p[2] & 0xff) << 8)
|
||||
| ((p[1] & 0xff) << 16)
|
||||
| ((p[0] & 0xff) << 24));
|
||||
}
|
||||
|
||||
static int isonum_733(unsigned char *p, int xflag)
|
||||
{
|
||||
int le = isonum_731(p);
|
||||
int be = isonum_732(p + 4);
|
||||
|
||||
if (xflag && le != be)
|
||||
/* translation is useless */
|
||||
warnx("733error: le=%d be=%d", le, be);
|
||||
return (le);
|
||||
}
|
||||
|
||||
static int isosize(int argc, char *filenamep, int xflag, long divisor)
|
||||
{
|
||||
int fd, nsecs, ssize, rc = -1;
|
||||
|
|
|
@ -22,6 +22,7 @@ dist_noinst_HEADERS += \
|
|||
include/fileutils.h \
|
||||
include/idcache.h \
|
||||
include/ismounted.h \
|
||||
include/iso9660.h \
|
||||
include/pwdutils.h \
|
||||
include/linux_version.h \
|
||||
include/list.h \
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef UTIL_LINUX_ISO_H
|
||||
#define UTIL_LINUX_ISO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "c.h"
|
||||
|
||||
static inline int isonum_721(unsigned char *p)
|
||||
{
|
||||
return ((p[0] & 0xff)
|
||||
| ((p[1] & 0xff) << 8));
|
||||
}
|
||||
|
||||
static inline int isonum_722(unsigned char *p)
|
||||
{
|
||||
return ((p[1] & 0xff)
|
||||
| ((p[0] & 0xff) << 8));
|
||||
}
|
||||
|
||||
static inline int isonum_723(unsigned char *p, bool check_match)
|
||||
{
|
||||
int le = isonum_721(p);
|
||||
int be = isonum_722(p + 2);
|
||||
|
||||
if (check_match && le != be)
|
||||
/* translation is useless */
|
||||
warnx("723error: le=%d be=%d", le, be);
|
||||
return (le);
|
||||
}
|
||||
|
||||
static inline int isonum_731(unsigned char *p)
|
||||
{
|
||||
return ((p[0] & 0xff)
|
||||
| ((p[1] & 0xff) << 8)
|
||||
| ((p[2] & 0xff) << 16)
|
||||
| ((p[3] & 0xff) << 24));
|
||||
}
|
||||
|
||||
static inline int isonum_732(unsigned char *p)
|
||||
{
|
||||
return ((p[3] & 0xff)
|
||||
| ((p[2] & 0xff) << 8)
|
||||
| ((p[1] & 0xff) << 16)
|
||||
| ((p[0] & 0xff) << 24));
|
||||
}
|
||||
|
||||
static inline int isonum_733(unsigned char *p, bool check_match)
|
||||
{
|
||||
int le = isonum_731(p);
|
||||
int be = isonum_732(p + 4);
|
||||
|
||||
if (check_match && le != be)
|
||||
/* translation is useless */
|
||||
warnx("733error: le=%d be=%d", le, be);
|
||||
return(le);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,7 +19,9 @@
|
|||
#include <stdint.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "iso9660.h"
|
||||
#include "superblocks.h"
|
||||
#include "sysfs.h"
|
||||
|
||||
struct iso9660_date {
|
||||
unsigned char year[4];
|
||||
|
@ -43,11 +45,13 @@ struct iso_volume_descriptor {
|
|||
unsigned char unused[8];
|
||||
unsigned char space_size[8];
|
||||
unsigned char escape_sequences[8];
|
||||
unsigned char unused1[222];
|
||||
unsigned char unused1[32];
|
||||
unsigned char logical_block_size[4];
|
||||
unsigned char unused2[186];
|
||||
unsigned char publisher_id[128];
|
||||
unsigned char unused2[128];
|
||||
unsigned char unused3[128];
|
||||
unsigned char application_id[128];
|
||||
unsigned char unused3[111];
|
||||
unsigned char unused4[111];
|
||||
struct iso9660_date created;
|
||||
struct iso9660_date modified;
|
||||
} __attribute__((packed));
|
||||
|
@ -169,15 +173,22 @@ static int is_str_empty(const unsigned char *str, size_t len)
|
|||
/*
|
||||
* The ISO format specifically avoids the first 32kb to allow for a
|
||||
* partition table to be added, if desired.
|
||||
* When an ISO contains a partition table, the usual thing to do is to
|
||||
* have a partition that points at the iso filesystem. In such case,
|
||||
* When an ISO contains a partition table, it is common to have a partition
|
||||
* that points at the iso mani filesystem. In such case,
|
||||
* we want to only probe the iso metadata for the corresponding partition
|
||||
* device, avoiding returning the metadata for the parent block device.
|
||||
*/
|
||||
static bool isofs_belongs_to_device(blkid_probe pr)
|
||||
static bool isofs_belongs_to_device(blkid_probe pr, struct iso_volume_descriptor *iso)
|
||||
{
|
||||
dev_t devno;
|
||||
dev_t devno, disk_devno, isopart_devno;
|
||||
blkid_partlist ls;
|
||||
blkid_loff_t pr_offset;
|
||||
int isopart_partno = -1;
|
||||
int nparts, i;
|
||||
int num_sectors, sector_size;
|
||||
long iso_size;
|
||||
blkid_partition par;
|
||||
struct path_cxt *pc;
|
||||
|
||||
/* Get device number, but if that fails, assume we aren't dealing
|
||||
* with partitions, and continue probing. */
|
||||
|
@ -191,10 +202,49 @@ static bool isofs_belongs_to_device(blkid_probe pr)
|
|||
if (!ls)
|
||||
return true;
|
||||
|
||||
/* Check that the device we're working with corresponds to an
|
||||
* entry in the partition table. If so, this is the correct
|
||||
* device to return the iso metadata on. */
|
||||
return blkid_partlist_devno_to_partition(ls, devno) != NULL;
|
||||
/* Calculate size of ISO9660 filesystem */
|
||||
num_sectors = isonum_733(iso->space_size, false);
|
||||
sector_size = isonum_723(iso->logical_block_size, false);
|
||||
iso_size = ((long)num_sectors * (long)sector_size) >> 9;
|
||||
|
||||
/* Look for a partition that matches the ISO9660 filesystem start sector
|
||||
* and size. */
|
||||
pr_offset = blkid_probe_get_offset(pr);
|
||||
nparts = blkid_partlist_numof_partitions(ls);
|
||||
for (i = 0; i < nparts; i++) {
|
||||
par = blkid_partlist_get_partition(ls, i);
|
||||
if (blkid_partition_get_start(par) == pr_offset &&
|
||||
blkid_partition_get_size(par) == iso_size) {
|
||||
isopart_partno = blkid_partition_get_partno(par);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we didn't find a matching partition, consider the current
|
||||
* device as an appropriate owner of the ISO9660 filesystem. */
|
||||
if (isopart_partno == -1)
|
||||
return true;
|
||||
|
||||
/* A partition matching the ISO9660 filesystem was found. Look for
|
||||
* a devno that corresponds to this partition. */
|
||||
disk_devno = blkid_probe_get_wholedisk_devno(pr);
|
||||
pc = ul_new_sysfs_path(disk_devno, NULL, NULL);
|
||||
if (!pc)
|
||||
return true;
|
||||
|
||||
isopart_devno = sysfs_blkdev_partno_to_devno(pc, isopart_partno);
|
||||
ul_unref_path(pc);
|
||||
|
||||
/* If no ISO9660 partition devno was found, consider the current device
|
||||
* as an appropriate owner of the filesystem. This can happen for CD/DVDs,
|
||||
* where partitions may exist in the table, but are not usually probed by
|
||||
* the kernel. */
|
||||
if (!isopart_devno)
|
||||
return true;
|
||||
|
||||
/* We found a partition that matches the ISO9660 filesystem. Check that it
|
||||
* corresponds to the device that we are probing. */
|
||||
return devno == isopart_devno;
|
||||
}
|
||||
|
||||
/* iso9660 [+ Microsoft Joliet Extension] */
|
||||
|
@ -214,7 +264,7 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
|
||||
/* Check if the iso metadata should be returned on a different device
|
||||
* instead of this one. */
|
||||
if (!isofs_belongs_to_device(pr))
|
||||
if (!isofs_belongs_to_device(pr, iso))
|
||||
return 1;
|
||||
|
||||
memcpy(label, iso->volume_id, sizeof(label));
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
ID_FS_BLOCK_SIZE=2048
|
||||
ID_FS_UUID=2019-12-16-06-07-35-00
|
||||
ID_FS_UUID_ENC=2019-12-16-06-07-35-00
|
||||
ID_FS_BOOT_SYSTEM_ID=EL TORITO SPECIFICATION
|
||||
ID_FS_LABEL=ISOIMAGE
|
||||
ID_FS_LABEL_ENC=ISOIMAGE
|
||||
ID_FS_TYPE=iso9660
|
||||
ID_FS_USAGE=filesystem
|
||||
ID_PART_TABLE_UUID=4b46ece2-6efb-4bf9-90a6-858c95e5581d
|
||||
ID_PART_TABLE_TYPE=gpt
|
|
@ -69,4 +69,23 @@ udevadm settle
|
|||
$TS_CMD_BLKID -p -o udev ${TS_DEVICE} >> $TS_OUTPUT
|
||||
ts_finalize_subtest
|
||||
|
||||
# This image (created by grub-mkrescue) has a partition table where the
|
||||
# partitions do not point to the ISO9660 filesystem.
|
||||
xz -dc ${TS_SELF}/iso-partitions-grub.img.xz > ${TS_DEVICE}
|
||||
udevadm settle
|
||||
|
||||
ts_init_subtest "grub"
|
||||
$TS_CMD_PARTX -a ${TS_DEVICE} &>/dev/null
|
||||
udevadm settle
|
||||
|
||||
# Check that the ISO metadata is shown on the main disk device
|
||||
$TS_CMD_BLKID -p -o udev ${TS_DEVICE} >> $TS_OUTPUT
|
||||
|
||||
# substitute major/minor number before comparison
|
||||
sed -i \
|
||||
-e 's/^\(ID_PART_ENTRY_DISK\)=.*/\1=__ts_majorminor__/' \
|
||||
$TS_OUTPUT
|
||||
|
||||
ts_finalize_subtest
|
||||
|
||||
ts_finalize
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue