Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108672937
D40109.id121969.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D40109.id121969.diff
View Options
diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h
--- a/usr.sbin/bhyve/pci_emul.h
+++ b/usr.sbin/bhyve/pci_emul.h
@@ -263,9 +263,10 @@
uint64_t pci_ecfg_base(void);
int pci_bus_configured(int bus);
#ifdef BHYVE_SNAPSHOT
+struct pci_devinst *pci_next(struct pci_devinst *cursor);
int pci_snapshot(struct vm_snapshot_meta *meta);
-int pci_pause(const char *dev_name);
-int pci_resume(const char *dev_name);
+int pci_pause(struct pci_devinst *pdi);
+int pci_resume(struct pci_devinst *pdi);
#endif
static __inline void
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -2364,42 +2364,6 @@
return (ret);
}
-static int
-pci_find_slotted_dev(const char *dev_name, struct pci_devemu **pde,
- struct pci_devinst **pdi)
-{
- struct businfo *bi;
- struct slotinfo *si;
- struct funcinfo *fi;
- int bus, slot, func;
-
- assert(dev_name != NULL);
- assert(pde != NULL);
- assert(pdi != NULL);
-
- for (bus = 0; bus < MAXBUSES; bus++) {
- if ((bi = pci_businfo[bus]) == NULL)
- continue;
-
- for (slot = 0; slot < MAXSLOTS; slot++) {
- si = &bi->slotinfo[slot];
- for (func = 0; func < MAXFUNCS; func++) {
- fi = &si->si_funcs[func];
- if (fi->fi_pde == NULL)
- continue;
- if (strcmp(dev_name, fi->fi_pde->pe_emu) != 0)
- continue;
-
- *pde = fi->fi_pde;
- *pdi = fi->fi_devi;
- return (0);
- }
- }
- }
-
- return (EINVAL);
-}
-
int
pci_snapshot(struct vm_snapshot_meta *meta)
{
@@ -2409,57 +2373,28 @@
assert(meta->dev_name != NULL);
- ret = pci_find_slotted_dev(meta->dev_name, &pde, &pdi);
- if (ret != 0) {
- fprintf(stderr, "%s: no such name: %s\r\n",
- __func__, meta->dev_name);
- memset(meta->buffer.buf_start, 0, meta->buffer.buf_size);
- return (0);
- }
-
- meta->dev_data = pdi;
+ pdi = meta->dev_data;
+ pde = pdi->pi_d;
- if (pde->pe_snapshot == NULL) {
- fprintf(stderr, "%s: not implemented yet for: %s\r\n",
- __func__, meta->dev_name);
- return (-1);
- }
+ if (pde->pe_snapshot == NULL)
+ return (ENOTSUP);
ret = pci_snapshot_pci_dev(meta);
- if (ret != 0) {
- fprintf(stderr, "%s: failed to snapshot pci dev\r\n",
- __func__);
- return (-1);
- }
-
- ret = (*pde->pe_snapshot)(meta);
+ if (ret == 0)
+ ret = (*pde->pe_snapshot)(meta);
return (ret);
}
int
-pci_pause(const char *dev_name)
+pci_pause(struct pci_devinst *pdi)
{
- struct pci_devemu *pde;
- struct pci_devinst *pdi;
- int ret;
-
- assert(dev_name != NULL);
-
- ret = pci_find_slotted_dev(dev_name, &pde, &pdi);
- if (ret != 0) {
- /*
- * It is possible to call this function without
- * checking that the device is inserted first.
- */
- fprintf(stderr, "%s: no such name: %s\n", __func__, dev_name);
- return (0);
- }
+ struct pci_devemu *pde = pdi->pi_d;
if (pde->pe_pause == NULL) {
/* The pause/resume functionality is optional. */
fprintf(stderr, "%s: not implemented for: %s\n",
- __func__, dev_name);
+ __func__, pdi->pi_name);
return (0);
}
@@ -2467,28 +2402,14 @@
}
int
-pci_resume(const char *dev_name)
+pci_resume(struct pci_devinst *pdi)
{
- struct pci_devemu *pde;
- struct pci_devinst *pdi;
- int ret;
-
- assert(dev_name != NULL);
-
- ret = pci_find_slotted_dev(dev_name, &pde, &pdi);
- if (ret != 0) {
- /*
- * It is possible to call this function without
- * checking that the device is inserted first.
- */
- fprintf(stderr, "%s: no such name: %s\n", __func__, dev_name);
- return (0);
- }
+ struct pci_devemu *pde = pdi->pi_d;
if (pde->pe_resume == NULL) {
/* The pause/resume functionality is optional. */
fprintf(stderr, "%s: not implemented for: %s\n",
- __func__, dev_name);
+ __func__, pdi->pi_name);
return (0);
}
@@ -2665,6 +2586,42 @@
}
#ifdef BHYVE_SNAPSHOT
+struct pci_devinst *
+pci_next(struct pci_devinst *cursor)
+{
+ unsigned bus = 0, slot = 0, func = 0;
+ struct businfo *bi;
+ struct slotinfo *si;
+ struct funcinfo *fi;
+
+ bus = cursor ? cursor->pi_bus : 0;
+ slot = cursor ? cursor->pi_slot : 0;
+ func = cursor ? (cursor->pi_func + 1) : 0;
+
+ for (; bus < MAXBUSES; bus++) {
+ if ((bi = pci_businfo[bus]) == NULL)
+ continue;
+
+ if (slot >= MAXSLOTS)
+ slot = 0;
+
+ for (; slot < MAXSLOTS; slot++) {
+ si = &bi->slotinfo[slot];
+ if (func >= MAXFUNCS)
+ func = 0;
+ for (; func < MAXFUNCS; func++) {
+ fi = &si->si_funcs[func];
+ if (fi->fi_devi == NULL)
+ continue;
+
+ return (fi->fi_devi);
+ }
+ }
+ }
+
+ return (NULL);
+}
+
static int
pci_emul_snapshot(struct vm_snapshot_meta *meta __unused)
{
diff --git a/usr.sbin/bhyve/snapshot.c b/usr.sbin/bhyve/snapshot.c
--- a/usr.sbin/bhyve/snapshot.c
+++ b/usr.sbin/bhyve/snapshot.c
@@ -138,20 +138,6 @@
_a < _b ? _a : _b; \
})
-static const struct vm_snapshot_dev_info snapshot_devs[] = {
- { "atkbdc", atkbdc_snapshot, NULL, NULL },
- { "virtio-net", pci_snapshot, pci_pause, pci_resume },
- { "virtio-blk", pci_snapshot, pci_pause, pci_resume },
- { "virtio-rnd", pci_snapshot, NULL, NULL },
- { "lpc", pci_snapshot, NULL, NULL },
- { "fbuf", pci_snapshot, NULL, NULL },
- { "xhci", pci_snapshot, NULL, NULL },
- { "e1000", pci_snapshot, NULL, NULL },
- { "ahci", pci_snapshot, pci_pause, pci_resume },
- { "ahci-hd", pci_snapshot, pci_pause, pci_resume },
- { "ahci-cd", pci_snapshot, pci_pause, pci_resume },
-};
-
static const struct vm_snapshot_kern_info snapshot_kern_structs[] = {
{ "vhpet", STRUCT_VHPET },
{ "vm", STRUCT_VM },
@@ -857,31 +843,29 @@
static int
-vm_restore_device(struct restore_state *rstate,
- const struct vm_snapshot_dev_info *info)
+vm_restore_device(struct restore_state *rstate, vm_snapshot_dev_cb func,
+ const char *name, void *data)
{
void *dev_ptr;
size_t dev_size;
int ret;
struct vm_snapshot_meta *meta;
- dev_ptr = lookup_dev(info->dev_name, JSON_DEV_ARR_KEY, rstate,
- &dev_size);
+ dev_ptr = lookup_dev(name, JSON_DEV_ARR_KEY, rstate, &dev_size);
+
if (dev_ptr == NULL) {
- fprintf(stderr, "Failed to lookup dev: %s\r\n", info->dev_name);
- fprintf(stderr, "Continuing the restore/migration process\r\n");
- return (0);
+ warnx("Failed to lookup dev: %s", name);
+ return (EINVAL);
}
if (dev_size == 0) {
- fprintf(stderr, "%s: Device size is 0. "
- "Assuming %s is not used\r\n",
- __func__, info->dev_name);
- return (0);
+ warnx("Restore device size is 0: %s", name);
+ return (EINVAL);
}
meta = &(struct vm_snapshot_meta) {
- .dev_name = info->dev_name,
+ .dev_name = name,
+ .dev_data = data,
.buffer.buf_start = dev_ptr,
.buffer.buf_size = dev_size,
@@ -892,11 +876,10 @@
.op = VM_SNAPSHOT_RESTORE,
};
- ret = (*info->snapshot_cb)(meta);
+ ret = func(meta);
if (ret != 0) {
- fprintf(stderr, "Failed to restore dev: %s\r\n",
- info->dev_name);
- return (-1);
+ warnx("Failed to restore dev: %s %d", name, ret);
+ return (ret);
}
return (0);
@@ -905,33 +888,31 @@
int
vm_restore_devices(struct restore_state *rstate)
{
- size_t i;
int ret;
+ struct pci_devinst *pdi = NULL;
- for (i = 0; i < nitems(snapshot_devs); i++) {
- ret = vm_restore_device(rstate, &snapshot_devs[i]);
- if (ret != 0)
+ /* For each pci device */
+ while ((pdi = pci_next(pdi)) != NULL) {
+ ret = vm_restore_device(rstate, pci_snapshot, pdi->pi_name, pdi);
+ if (ret)
return (ret);
}
- return 0;
+ return vm_restore_device(rstate, atkbdc_snapshot, "atkbdc", NULL);
}
int
vm_pause_devices(void)
{
- const struct vm_snapshot_dev_info *info;
- size_t i;
int ret;
+ struct pci_devinst *pdi = NULL;
- for (i = 0; i < nitems(snapshot_devs); i++) {
- info = &snapshot_devs[i];
- if (info->pause_cb == NULL)
- continue;
-
- ret = info->pause_cb(info->dev_name);
- if (ret != 0)
+ while ((pdi = pci_next(pdi)) != NULL) {
+ ret = pci_pause(pdi);
+ if (ret) {
+ warnx("Cannot pause dev %s: %d", pdi->pi_name, ret);
return (ret);
+ }
}
return (0);
@@ -940,18 +921,15 @@
int
vm_resume_devices(void)
{
- const struct vm_snapshot_dev_info *info;
- size_t i;
int ret;
+ struct pci_devinst *pdi = NULL;
- for (i = 0; i < nitems(snapshot_devs); i++) {
- info = &snapshot_devs[i];
- if (info->resume_cb == NULL)
- continue;
-
- ret = info->resume_cb(info->dev_name);
- if (ret != 0)
+ while ((pdi = pci_next(pdi)) != NULL) {
+ ret = pci_resume(pdi);
+ if (ret) {
+ warnx("Cannot resume '%s': %d", pdi->pi_name, ret);
return (ret);
+ }
}
return (0);
@@ -1090,16 +1068,21 @@
}
static int
-vm_snapshot_device(const struct vm_snapshot_dev_info *info,
- int data_fd, xo_handle_t *xop,
- struct vm_snapshot_meta *meta, off_t *offset)
+vm_snapshot_device(vm_snapshot_dev_cb func, const char *dev_name,
+ void *devdata, int data_fd, xo_handle_t *xop,
+ struct vm_snapshot_meta *meta, off_t *offset)
{
int ret;
- ret = (*info->snapshot_cb)(meta);
+ memset(meta->buffer.buf_start, 0, meta->buffer.buf_size);
+ meta->buffer.buf = meta->buffer.buf_start;
+ meta->buffer.buf_rem = meta->buffer.buf_size;
+ meta->dev_name = dev_name;
+ meta->dev_data = devdata;
+
+ ret = func(meta);
if (ret != 0) {
- fprintf(stderr, "Failed to snapshot %s; ret=%d\r\n",
- meta->dev_name, ret);
+ warnx("Failed to snapshot %s; ret=%d", dev_name, ret);
return (ret);
}
@@ -1117,8 +1100,9 @@
int ret;
off_t offset;
void *buffer;
- size_t buf_size, i;
+ size_t buf_size;
struct vm_snapshot_meta *meta;
+ struct pci_devinst *pdi;
buf_size = SNAPSHOT_BUFFER_SIZE;
@@ -1144,20 +1128,18 @@
xo_open_list_h(xop, JSON_DEV_ARR_KEY);
- /* Restore other devices that support this feature */
- for (i = 0; i < nitems(snapshot_devs); i++) {
- meta->dev_name = snapshot_devs[i].dev_name;
-
- memset(meta->buffer.buf_start, 0, meta->buffer.buf_size);
- meta->buffer.buf = meta->buffer.buf_start;
- meta->buffer.buf_rem = meta->buffer.buf_size;
-
- ret = vm_snapshot_device(&snapshot_devs[i], data_fd, xop,
- meta, &offset);
+ /* for_each */
+ pdi = NULL;
+ while ((pdi = pci_next(pdi)) != NULL) {
+ ret = vm_snapshot_device(pci_snapshot, pdi->pi_name, pdi,
+ data_fd, xop, meta, &offset);
if (ret != 0)
goto snapshot_err;
}
+ ret = vm_snapshot_device(atkbdc_snapshot, "atkbdc", NULL,
+ data_fd, xop, meta, &offset);
+
xo_close_list_h(xop, JSON_DEV_ARR_KEY);
snapshot_err:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 28, 5:29 AM (1 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16252253
Default Alt Text
D40109.id121969.diff (10 KB)
Attached To
Mode
D40109: bhyve: [snapshot] Use pci_next() to save/restore pci devices
Attached
Detach File
Event Timeline
Log In to Comment