Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.0:Staging:E
kexec-tools
kexec-tools-xen-balloon-up.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File kexec-tools-xen-balloon-up.patch of Package kexec-tools
Reference: bnc#694863 A PVonHVM guest can not kexec if balloon driver gave some memory back to hypervisor. Disable ballooning before doing kexec. --- kexec/crashdump-xen.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++--- kexec/kexec.c | 6 ++ kexec/kexec.h | 1 3 files changed, 119 insertions(+), 6 deletions(-) --- a/kexec/crashdump-xen.c +++ b/kexec/crashdump-xen.c @@ -8,6 +8,7 @@ #include <limits.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/select.h> #include <unistd.h> #include <fcntl.h> #include <setjmp.h> @@ -30,9 +31,20 @@ struct crash_note_info { static int xen_phys_cpus; static struct crash_note_info *xen_phys_notes; +#define XEN_MEM0_DIR "/sys/devices/system/xen_memory/xen_memory0" +#define XEN_MEM0_TARGET XEN_MEM0_DIR "/target_kb" +#define XEN_MEM0_LOW XEN_MEM0_DIR "/info/low_kb" +#define XEN_MEM0_HIGH XEN_MEM0_DIR "/info/high_kb" + /* based on code from xen-detect.c */ static int is_dom0; #if defined(__i386__) || defined(__x86_64__) +enum { + XEN_PV = 1, + XEN_HVM = 2, + XEN_NONE = 3, +}; +static int guest_type; static jmp_buf xen_sigill_jmp; void xen_sigill_handler(int sig) { @@ -84,29 +96,118 @@ found: return regs[0]; } -static int xen_detect_pv_guest(void) +static void xen_detect_guest_type(void) { struct sigaction act, oldact; - int is_pv = -1; + + guest_type = XEN_NONE; + if (check_for_xen(0)) { + guest_type = XEN_HVM; + return; + } if (setjmp(xen_sigill_jmp)) - return is_pv; + return; memset(&act, 0, sizeof(act)); act.sa_handler = xen_sigill_handler; sigemptyset (&act.sa_mask); if (sigaction(SIGILL, &act, &oldact)) - return is_pv; + return; if (check_for_xen(1)) - is_pv = 1; + guest_type = XEN_PV; sigaction(SIGILL, &oldact, NULL); - return is_pv; + return; +} + +static int xen_detect_pv_guest(void) +{ + if (!guest_type) + xen_detect_guest_type(); + + return guest_type == XEN_PV ? 1 : -1; } + +static int do_balloon_up(void) +{ + char line[123]; + FILE *f; + int done = 0, seen_lo, seen_hi; + long long lo, hi, prev_lo = 0, prev_hi = 0; + + if (!guest_type) + xen_detect_guest_type(); + + if (guest_type != XEN_HVM) + return 0; + + /* Nothing to do if no balloon driver */ + f = fopen(XEN_MEM0_TARGET, "w"); + if (!f) + return 0; + + /* Balloon up to maximum, the guest can not exceed its max_memkb */ + printf("Ballooning up in PVonHVM guest.\n"); + snprintf(line, sizeof(line), "%llu", -1LL); + fwrite(line, strlen(line), 1, f); + fclose(f); + + do { + struct timeval timeout = {.tv_usec = 654321, }; + seen_lo = seen_hi = 0; + lo = hi = -1; + + /* Wait for balloon driver to reach maximum */ + if (select(0, NULL, NULL, NULL, &timeout) < 0) { + perror("select"); + break; + } + + /* Check ballooned low mem */ + f = fopen(XEN_MEM0_LOW, "r"); + if (!f) + break; + if (fscanf(f, "%lld", &lo) == 1) + seen_lo = 1; + fclose(f); + + /* Check ballooned high mem */ + f = fopen(XEN_MEM0_HIGH, "r"); + if (!f) + break; + if (fscanf(f, "%lld", &hi) == 1) + seen_hi = 1; + fclose(f); + + /* Print progress if current values changed */ + if ((seen_lo || seen_hi) && (hi || lo) && (lo != prev_lo || hi != prev_hi)) { + printf("h: %lld, l: %lld\n", hi, lo); + if (seen_lo && lo != prev_lo) + prev_lo = lo; + if (seen_hi && hi != prev_hi) + prev_hi = hi; + } + + /* Exit loop if nothing is ballooned anymore */ + if (seen_lo && seen_hi && hi == 0 && lo == 0) + done = 1; + + } while (!done); + + printf("%s.\n", done ? "Done" : "Not done"); + return !done; +} + #else static int xen_detect_pv_guest(void) { return 1; } + +static int do_balloon_up(void) +{ + return 0; +} #endif /* @@ -125,6 +226,11 @@ int xen_present(void) return is_dom0 > 0; } +int xen_balloon_up(void) +{ + return do_balloon_up(); +} + unsigned long xen_architecture(struct crash_elf_info *elf_info) { unsigned long machine = elf_info->machine; --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -1240,6 +1240,7 @@ int main(int argc, char *argv[]) int do_shutdown = 1; int do_sync = 1, skip_sync = 0; int do_ifdown = 0, skip_ifdown = 0; + int do_balloon = 0; int do_unload = 0; int do_reuse_initrd = 0; int do_kexec_file_syscall = 0; @@ -1298,6 +1299,7 @@ int main(int argc, char *argv[]) do_shutdown = 0; do_sync = 1; do_ifdown = 1; + do_balloon = 1; do_exec = 1; break; case OPT_LOAD: @@ -1318,6 +1320,7 @@ int main(int argc, char *argv[]) do_shutdown = 0; do_sync = 1; do_ifdown = 1; + do_balloon = 1; do_exec = 1; break; case OPT_LOAD_JUMP_BACK_HELPER: @@ -1482,6 +1485,9 @@ int main(int argc, char *argv[]) if ((result == 0) && do_ifdown) { ifdown(); } + if ((result == 0) && do_balloon) { + result = xen_balloon_up(); + } if ((result == 0) && do_exec) { result = my_exec(); } --- a/kexec/kexec.h +++ b/kexec/kexec.h @@ -316,6 +316,7 @@ int xen_kexec_load(struct kexec_info *in int xen_kexec_unload(uint64_t kexec_flags); void xen_kexec_exec(void); int xen_kexec_status(uint64_t kexec_flags); +int xen_balloon_up(void); extern unsigned long long get_kernel_sym(const char *text);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor