mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 06:05:27 +00:00
storage: Add partition type checks for BLKID probing
A device may be formatted using some sort of disk partition format type. We can check that using the blkid_ API's as well - so alter the logic to allow checking the device for both a filesystem and a disk partition. Signed-off-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
f23d4bbce3
commit
a22e1a0032
@ -2639,37 +2639,117 @@ virStorageBackendFindGlusterPoolSources(const char *host ATTRIBUTE_UNUSED,
|
||||
|
||||
|
||||
#if WITH_BLKID
|
||||
|
||||
typedef enum {
|
||||
VIR_STORAGE_BLKID_PROBE_ERROR = -1,
|
||||
VIR_STORAGE_BLKID_PROBE_UNDEFINED, /* Nothing found */
|
||||
VIR_STORAGE_BLKID_PROBE_UNKNOWN, /* Don't know libvirt fs/part type */
|
||||
VIR_STORAGE_BLKID_PROBE_MATCH, /* Matches the on disk format */
|
||||
VIR_STORAGE_BLKID_PROBE_DIFFERENT, /* Format doesn't match on disk format */
|
||||
} virStorageBackendBLKIDProbeResult;
|
||||
|
||||
/*
|
||||
* Utility function to probe for a file system on the device using the
|
||||
* blkid "superblock" (e.g. default) APIs.
|
||||
*
|
||||
* NB: In general this helper will handle the virStoragePoolFormatFileSystem
|
||||
* format types; however, if called from the Disk path, the initial fstype
|
||||
* check will fail forcing the usage of the ProbePart helper.
|
||||
*
|
||||
* Returns virStorageBackendBLKIDProbeResult enum
|
||||
*/
|
||||
static virStorageBackendBLKIDProbeResult
|
||||
virStorageBackendBLKIDFindFS(blkid_probe probe,
|
||||
const char *device,
|
||||
const char *format)
|
||||
{
|
||||
const char *fstype = NULL;
|
||||
|
||||
/* Make sure we're doing a superblock probe from the start */
|
||||
blkid_probe_enable_superblocks(probe, true);
|
||||
blkid_probe_reset_superblocks_filter(probe);
|
||||
|
||||
if (blkid_do_probe(probe) != 0) {
|
||||
VIR_INFO("No filesystem found on device '%s'", device);
|
||||
return VIR_STORAGE_BLKID_PROBE_UNDEFINED;
|
||||
}
|
||||
|
||||
if (blkid_probe_lookup_value(probe, "TYPE", &fstype, NULL) == 0) {
|
||||
if (STREQ(fstype, format))
|
||||
return VIR_STORAGE_BLKID_PROBE_MATCH;
|
||||
|
||||
return VIR_STORAGE_BLKID_PROBE_DIFFERENT;
|
||||
}
|
||||
|
||||
if (blkid_known_fstype(format) == 0)
|
||||
return VIR_STORAGE_BLKID_PROBE_UNKNOWN;
|
||||
|
||||
return VIR_STORAGE_BLKID_PROBE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Utility function to probe for a partition on the device using the
|
||||
* blkid "partitions" APIs.
|
||||
*
|
||||
* NB: In general, this API will be validating the virStoragePoolFormatDisk
|
||||
* format types.
|
||||
*
|
||||
* Returns virStorageBackendBLKIDProbeResult enum
|
||||
*/
|
||||
static virStorageBackendBLKIDProbeResult
|
||||
virStorageBackendBLKIDFindPart(blkid_probe probe,
|
||||
const char *device,
|
||||
const char *format)
|
||||
{
|
||||
const char *pttype = NULL;
|
||||
|
||||
/* Make sure we're doing a partitions probe from the start */
|
||||
blkid_probe_enable_partitions(probe, true);
|
||||
blkid_probe_reset_partitions_filter(probe);
|
||||
|
||||
if (blkid_do_probe(probe) != 0) {
|
||||
VIR_INFO("No partition found on device '%s'", device);
|
||||
return VIR_STORAGE_BLKID_PROBE_UNDEFINED;
|
||||
}
|
||||
|
||||
if (blkid_probe_lookup_value(probe, "PTTYPE", &pttype, NULL) == 0) {
|
||||
if (STREQ(pttype, format))
|
||||
return VIR_STORAGE_BLKID_PROBE_MATCH;
|
||||
|
||||
return VIR_STORAGE_BLKID_PROBE_DIFFERENT;
|
||||
}
|
||||
|
||||
if (blkid_known_pttype(format) == 0)
|
||||
return VIR_STORAGE_BLKID_PROBE_UNKNOWN;
|
||||
|
||||
return VIR_STORAGE_BLKID_PROBE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @device: Path to device
|
||||
* @format: Desired format
|
||||
*
|
||||
* Use the blkid_ APIs in order to get details regarding whether a file
|
||||
* system exists on the disk already.
|
||||
* system or partition exists on the disk already.
|
||||
*
|
||||
* Returns:
|
||||
* -1: An error was encountered, with error message set
|
||||
* 0: No file system found
|
||||
*/
|
||||
static int
|
||||
virStorageBackendBLKIDFindFS(const char *device,
|
||||
const char *format)
|
||||
virStorageBackendBLKIDFindEmpty(const char *device,
|
||||
const char *format)
|
||||
{
|
||||
|
||||
int ret = -1;
|
||||
int rc;
|
||||
blkid_probe probe = NULL;
|
||||
const char *fstype = NULL;
|
||||
|
||||
VIR_DEBUG("Probing for existing filesystem of type %s on device %s",
|
||||
VIR_DEBUG("Probe for existing filesystem/partition format %s on device %s",
|
||||
format, device);
|
||||
|
||||
if (blkid_known_fstype(format) == 0) {
|
||||
virReportError(VIR_ERR_STORAGE_PROBE_FAILED,
|
||||
_("Not capable of probing for filesystem of "
|
||||
"type %s, requires --overwrite"),
|
||||
format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(probe = blkid_new_probe_from_filename(device))) {
|
||||
virReportError(VIR_ERR_STORAGE_PROBE_FAILED,
|
||||
_("Failed to create filesystem probe for device %s"),
|
||||
@ -2677,34 +2757,53 @@ virStorageBackendBLKIDFindFS(const char *device,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (blkid_do_probe(probe) != 0) {
|
||||
VIR_INFO("No filesystem of type '%s' found on device '%s'",
|
||||
format, device);
|
||||
} else if (blkid_probe_lookup_value(probe, "TYPE", &fstype, NULL) == 0) {
|
||||
if (STREQ(fstype, format)) {
|
||||
virReportError(VIR_ERR_STORAGE_POOL_BUILT,
|
||||
_("Device '%s' already contains a filesystem "
|
||||
"of type '%s'"),
|
||||
device, fstype);
|
||||
} else {
|
||||
virReportError(VIR_ERR_STORAGE_POOL_BUILT,
|
||||
_("Existing filesystem of type '%s' found on "
|
||||
"device '%s', requires --overwrite"),
|
||||
fstype, device);
|
||||
}
|
||||
goto cleanup;
|
||||
/* Look for something on FS, if it either doesn't recognize the
|
||||
* format type as a valid FS format type or it doesn't find a valid
|
||||
* format type on the device, then perform the same check using
|
||||
* partition probing. */
|
||||
rc = virStorageBackendBLKIDFindFS(probe, device, format);
|
||||
if (rc == VIR_STORAGE_BLKID_PROBE_UNDEFINED ||
|
||||
rc == VIR_STORAGE_BLKID_PROBE_UNKNOWN)
|
||||
rc = virStorageBackendBLKIDFindPart(probe, device, format);
|
||||
|
||||
switch (rc) {
|
||||
case VIR_STORAGE_BLKID_PROBE_UNDEFINED:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case VIR_STORAGE_BLKID_PROBE_ERROR:
|
||||
virReportError(VIR_ERR_STORAGE_PROBE_FAILED,
|
||||
_("Failed to probe for format type '%s'"), format);
|
||||
break;
|
||||
|
||||
case VIR_STORAGE_BLKID_PROBE_UNKNOWN:
|
||||
virReportError(VIR_ERR_STORAGE_PROBE_FAILED,
|
||||
_("Not capable of probing for format type '%s', "
|
||||
"requires build --overwrite"),
|
||||
format);
|
||||
break;
|
||||
|
||||
case VIR_STORAGE_BLKID_PROBE_MATCH:
|
||||
virReportError(VIR_ERR_STORAGE_POOL_BUILT,
|
||||
_("Device '%s' already formatted using '%s'"),
|
||||
device, format);
|
||||
break;
|
||||
|
||||
case VIR_STORAGE_BLKID_PROBE_DIFFERENT:
|
||||
virReportError(VIR_ERR_STORAGE_POOL_BUILT,
|
||||
_("Device '%s' formatted cannot overwrite using '%s', "
|
||||
"requires build --overwrite"),
|
||||
device, format);
|
||||
break;
|
||||
}
|
||||
|
||||
if (blkid_do_probe(probe) != 1) {
|
||||
if (ret == 0 && blkid_do_probe(probe) != 1) {
|
||||
virReportError(VIR_ERR_STORAGE_PROBE_FAILED, "%s",
|
||||
_("Found additional probes to run, "
|
||||
"filesystem probing may be incorrect"));
|
||||
goto cleanup;
|
||||
_("Found additional probes to run, probing may "
|
||||
"be incorrect"));
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
blkid_free_probe(probe);
|
||||
|
||||
return ret;
|
||||
@ -2713,8 +2812,8 @@ virStorageBackendBLKIDFindFS(const char *device,
|
||||
#else /* #if WITH_BLKID */
|
||||
|
||||
static int
|
||||
virStorageBackendBLKIDFindFS(const char *device ATTRIBUTE_UNUSED,
|
||||
const char *format ATTRIBUTE_UNUSED)
|
||||
virStorageBackendBLKIDFindEmpty(const char *device ATTRIBUTE_UNUSED,
|
||||
const char *format ATTRIBUTE_UNUSED)
|
||||
{
|
||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
_("probing for filesystems is unsupported "
|
||||
@ -2739,5 +2838,5 @@ bool
|
||||
virStorageBackendDeviceIsEmpty(const char *devpath,
|
||||
const char *format)
|
||||
{
|
||||
return virStorageBackendBLKIDFindFS(devpath, format) == 0;
|
||||
return virStorageBackendBLKIDFindEmpty(devpath, format) == 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user