* Returns 0 on success, -1 on failure
*
*/
-int
+static int
virNetDevReplaceMacAddress(const char *linkdev,
const virMacAddr *macaddress,
const char *stateDir)
* Returns 0 on success, -errno on failure.
*
*/
-int
+static int
virNetDevRestoreMacAddress(const char *linkdev,
const char *stateDir)
{
}
static int
-virNetDevRestoreVfConfig(const char *pflinkdev, int vf,
+virNetDevRestoreVfConfig(const char *pflinkdev,
+ int vf, const char *vflinkdev,
const char *stateDir)
{
int rc = -1;
stateDir, pflinkdev, vf) < 0)
return rc;
+ if (vflinkdev && !virFileExists(path)) {
+ /* this VF's config may have been stored with
+ * virNetDevReplaceMacAddress while running an older version
+ * of libvirt. If so, the ${pf}_vf${id} file won't exist. In
+ * that case, try to restore using the older method with the
+ * VF's name directly.
+ */
+ rc = virNetDevRestoreMacAddress(vflinkdev, stateDir);
+ goto cleanup;
+ }
+
if (virFileReadAll(path, 128, &fileData) < 0)
goto cleanup;
const virMacAddr *macaddress, int vlanid,
const char *stateDir)
{
+ int ret = -1;
+ char *pfdevname = NULL;
+
+ if (vf == -1 && virNetDevIsVirtualFunction(linkdev)) {
+ /* If this really *is* a VF and the caller just didn't know
+ * it, we should set the MAC address via PF+vf# instead of
+ * setting directly via VF, because the latter will be
+ * rejected any time after the former has been done.
+ */
+ if (virNetDevGetPhysicalFunction(linkdev, &pfdevname) < 0)
+ goto cleanup;
+ if (virNetDevGetVirtualFunctionIndex(pfdevname, linkdev, &vf) < 0)
+ goto cleanup;
+ linkdev = pfdevname;
+ }
+
if (vf == -1)
- return virNetDevReplaceMacAddress(linkdev, macaddress, stateDir);
+ ret = virNetDevReplaceMacAddress(linkdev, macaddress, stateDir);
else
- return virNetDevReplaceVfConfig(linkdev, vf, macaddress, vlanid,
- stateDir);
+ ret = virNetDevReplaceVfConfig(linkdev, vf, macaddress, vlanid,
+ stateDir);
+
+ cleanup:
+ VIR_FREE(pfdevname);
+ return ret;
}
/**
int
virNetDevRestoreNetConfig(const char *linkdev, int vf, const char *stateDir)
{
+ int ret = -1;
+ char *pfdevname = NULL;
+ const char *vfdevname = NULL;
+
+ if (vf == -1 && virNetDevIsVirtualFunction(linkdev)) {
+ /* If this really *is* a VF and the caller just didn't know
+ * it, we should set the MAC address via PF+vf# instead of
+ * setting directly via VF, because the latter will be
+ * rejected any time after the former has been done.
+ */
+ if (virNetDevGetPhysicalFunction(linkdev, &pfdevname) < 0)
+ goto cleanup;
+ if (virNetDevGetVirtualFunctionIndex(pfdevname, linkdev, &vf) < 0)
+ goto cleanup;
+ vfdevname = linkdev;
+ linkdev = pfdevname;
+ }
+
if (vf == -1)
- return virNetDevRestoreMacAddress(linkdev, stateDir);
+ ret = virNetDevRestoreMacAddress(linkdev, stateDir);
else
- return virNetDevRestoreVfConfig(linkdev, vf, stateDir);
+ ret = virNetDevRestoreVfConfig(linkdev, vf, vfdevname, stateDir);
+
+ cleanup:
+ VIR_FREE(pfdevname);
+ return ret;
}
#else /* defined(__linux__) && defined(HAVE_LIBNL) */