mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
pci: Remove PATH_MAX sized stack allocations
Use virAsprintf instead of snprintf.
This commit is contained in:
parent
1573158190
commit
57162db82c
172
src/util/pci.c
172
src/util/pci.c
@ -775,38 +775,72 @@ pciResetDevice(pciDevice *dev,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pciDriverDir(char *buf, size_t buflen, const char *driver)
|
||||
static int
|
||||
pciDriverDir(char **buffer, const char *driver)
|
||||
{
|
||||
snprintf(buf, buflen, PCI_SYSFS "drivers/%s", driver);
|
||||
VIR_FREE(*buffer);
|
||||
|
||||
if (virAsprintf(buffer, PCI_SYSFS "drivers/%s", driver) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pciDriverFile(char *buf, size_t buflen, const char *driver, const char *file)
|
||||
static int
|
||||
pciDriverFile(char **buffer, const char *driver, const char *file)
|
||||
{
|
||||
snprintf(buf, buflen, PCI_SYSFS "drivers/%s/%s", driver, file);
|
||||
VIR_FREE(*buffer);
|
||||
|
||||
if (virAsprintf(buffer, PCI_SYSFS "drivers/%s/%s", driver, file) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pciDeviceFile(char *buf, size_t buflen, const char *device, const char *file)
|
||||
static int
|
||||
pciDeviceFile(char **buffer, const char *device, const char *file)
|
||||
{
|
||||
snprintf(buf, buflen, PCI_SYSFS "devices/%s/%s", device, file);
|
||||
VIR_FREE(*buffer);
|
||||
|
||||
if (virAsprintf(buffer, PCI_SYSFS "devices/%s/%s", device, file) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
pciFindStubDriver(void)
|
||||
{
|
||||
char drvpath[PATH_MAX];
|
||||
char *drvpath = NULL;
|
||||
int probed = 0;
|
||||
|
||||
recheck:
|
||||
pciDriverDir(drvpath, sizeof(drvpath), "pci-stub");
|
||||
if (virFileExists(drvpath))
|
||||
if (pciDriverDir(&drvpath, "pci-stub") < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (virFileExists(drvpath)) {
|
||||
VIR_FREE(drvpath);
|
||||
return "pci-stub";
|
||||
pciDriverDir(drvpath, sizeof(drvpath), "pciback");
|
||||
if (virFileExists(drvpath))
|
||||
}
|
||||
|
||||
if (pciDriverDir(&drvpath, "pciback") < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (virFileExists(drvpath)) {
|
||||
VIR_FREE(drvpath);
|
||||
return "pciback";
|
||||
}
|
||||
|
||||
VIR_FREE(drvpath);
|
||||
|
||||
if (!probed) {
|
||||
const char *const stubprobe[] = { MODPROBE, "pci-stub", NULL };
|
||||
@ -837,8 +871,9 @@ recheck:
|
||||
static int
|
||||
pciBindDeviceToStub(pciDevice *dev, const char *driver)
|
||||
{
|
||||
char drvdir[PATH_MAX];
|
||||
char path[PATH_MAX];
|
||||
int result = -1;
|
||||
char *drvdir = NULL;
|
||||
char *path = NULL;
|
||||
|
||||
/* Add the PCI device ID to the stub's dynamic ID table;
|
||||
* this is needed to allow us to bind the device to the stub.
|
||||
@ -848,12 +883,15 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
|
||||
* is triggered for such a device, it will also be immediately
|
||||
* bound by the stub.
|
||||
*/
|
||||
pciDriverFile(path, sizeof(path), driver, "new_id");
|
||||
if (pciDriverFile(&path, driver, "new_id") < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virFileWriteStr(path, dev->id, 0) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to add PCI device ID '%s' to %s"),
|
||||
dev->id, driver);
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* If the device is already bound to a driver, unbind it.
|
||||
@ -861,48 +899,69 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
|
||||
* PCI device happens to be IDE controller for the disk hosting
|
||||
* your root filesystem.
|
||||
*/
|
||||
pciDeviceFile(path, sizeof(path), dev->name, "driver/unbind");
|
||||
if (pciDeviceFile(&path, dev->name, "driver/unbind") < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to unbind PCI device '%s'"), dev->name);
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* If the device isn't already bound to pci-stub, try binding it now.
|
||||
*/
|
||||
pciDriverDir(drvdir, sizeof(drvdir), driver);
|
||||
pciDeviceFile(path, sizeof(path), dev->name, "driver");
|
||||
if (pciDriverDir(&drvdir, driver) < 0 ||
|
||||
pciDeviceFile(&path, dev->name, "driver") < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!virFileLinkPointsTo(path, drvdir)) {
|
||||
/* Xen's pciback.ko wants you to use new_slot first */
|
||||
pciDriverFile(path, sizeof(path), driver, "new_slot");
|
||||
if (pciDriverFile(&path, driver, "new_slot") < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to add slot for PCI device '%s' to %s"),
|
||||
dev->name, driver);
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (pciDriverFile(&path, driver, "bind") < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
pciDriverFile(path, sizeof(path), driver, "bind");
|
||||
if (virFileWriteStr(path, dev->name, 0) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to bind PCI device '%s' to %s"),
|
||||
dev->name, driver);
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* If 'remove_id' exists, remove the device id from pci-stub's dynamic
|
||||
* ID table so that 'drivers_probe' works below.
|
||||
*/
|
||||
pciDriverFile(path, sizeof(path), driver, "remove_id");
|
||||
if (pciDriverFile(&path, driver, "remove_id") < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virFileExists(path) && virFileWriteStr(path, dev->id, 0) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to remove PCI ID '%s' from %s"),
|
||||
dev->id, driver);
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return 0;
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(drvdir);
|
||||
VIR_FREE(path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
@ -927,49 +986,67 @@ pciDettachDevice(pciDevice *dev, pciDeviceList *activeDevs)
|
||||
static int
|
||||
pciUnBindDeviceFromStub(pciDevice *dev, const char *driver)
|
||||
{
|
||||
char drvdir[PATH_MAX];
|
||||
char path[PATH_MAX];
|
||||
int result = -1;
|
||||
char *drvdir = NULL;
|
||||
char *path = NULL;
|
||||
|
||||
/* If the device is bound to stub, unbind it.
|
||||
*/
|
||||
pciDriverDir(drvdir, sizeof(drvdir), driver);
|
||||
pciDeviceFile(path, sizeof(path), dev->name, "driver");
|
||||
if (pciDriverDir(&drvdir, driver) < 0 ||
|
||||
pciDeviceFile(&path, dev->name, "driver") < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virFileExists(drvdir) && virFileLinkPointsTo(path, drvdir)) {
|
||||
pciDriverFile(path, sizeof(path), driver, "unbind");
|
||||
if (pciDriverFile(&path, driver, "unbind") < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virFileWriteStr(path, dev->name, 0) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to bind PCI device '%s' to %s"),
|
||||
dev->name, driver);
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Xen's pciback.ko wants you to use remove_slot on the specific device */
|
||||
pciDriverFile(path, sizeof(path), driver, "remove_slot");
|
||||
if (pciDriverFile(&path, driver, "remove_slot") < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to remove slot for PCI device '%s' to %s"),
|
||||
dev->name, driver);
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
/* Trigger a re-probe of the device is not in the stub's dynamic
|
||||
* ID table. If the stub is available, but 'remove_id' isn't
|
||||
* available, then re-probing would just cause the device to be
|
||||
* re-bound to the stub.
|
||||
*/
|
||||
pciDriverFile(path, sizeof(path), driver, "remove_id");
|
||||
if (pciDriverFile(&path, driver, "remove_id") < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!virFileExists(drvdir) || virFileExists(path)) {
|
||||
if (virFileWriteStr(PCI_SYSFS "drivers_probe", dev->name, 0) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to trigger a re-probe for PCI device '%s'"),
|
||||
dev->name);
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(drvdir);
|
||||
VIR_FREE(path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
@ -1103,15 +1180,20 @@ pciWaitForDeviceCleanup(pciDevice *dev, const char *matcher)
|
||||
static char *
|
||||
pciReadDeviceID(pciDevice *dev, const char *id_name)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char *path;
|
||||
char *id_str;
|
||||
|
||||
snprintf(path, sizeof(path), PCI_SYSFS "devices/%s/%s",
|
||||
dev->name, id_name);
|
||||
if (pciDeviceFile(&path, dev->name, id_name) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ID string is '0xNNNN\n' ... i.e. 7 bytes */
|
||||
if (virFileReadAll(path, 7, &id_str) < 0)
|
||||
if (virFileReadAll(path, 7, &id_str) < 0) {
|
||||
VIR_FREE(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VIR_FREE(path);
|
||||
|
||||
/* Check for 0x suffix */
|
||||
if (id_str[0] != '0' || id_str[1] != 'x') {
|
||||
|
Loading…
x
Reference in New Issue
Block a user