int get_first_region(client_handle_t handle, region_info_t *rgn) { socket_info_t *s = SOCKET(handle); if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; if ((handle->Attributes & INFO_MASTER_CLIENT) && (!(s->state & SOCKET_REGION_INFO))) { setup_regions(handle, 0, &s->c_region); setup_regions(handle, 1, &s->a_region); s->state |= SOCKET_REGION_INFO; } if (rgn->Attributes & REGION_TYPE_AM) return match_region(handle, s->a_region, rgn); else return match_region(handle, s->c_region, rgn); } /* get_first_region */
int dump_regions_from_environment(void) { Elf32_Ehdr *elfhdr_addr; int rc = 0; char *orig_bootargs; char *bootargs; char *p; char *memargs_cmd; char *memargs; int nuf_ph; range_t ck = {0, 0}; range_t *regions; char *crashkernel; unsigned int i; unsigned int region_no; /* Right now getenv("crashkernel") has a value on the form "crashkernel=nn[KMG]@ss[KMG]" but this is expanded into "crashkernel=${crashkernel}" when constructing the kernel commandline, amounting to: "crashkernel=crashkernel=nn[KMG]@ss[KMG]" This might get fixed so this code can handle both. */ crashkernel = getenv("crashkernel"); if(crashkernel == NULL) { debug("checkcrash: no crashkernel environment variable\n"); rc = 1; goto out5; } crashkernel = strdup(crashkernel); if(crashkernel == NULL) { debug("checkcrash: could not strdup crashkernel variable\n"); rc = 1; goto out5; } p = strchr(crashkernel, '='); if (p != NULL) { p++; suffixed_addr_toul(p, &ck); } else { suffixed_addr_toul(crashkernel, &ck); } /* Make copy of bootargs, if it exists */ orig_bootargs = getenv("bootargs"); if(orig_bootargs != NULL) { orig_bootargs = strdup(orig_bootargs); if(orig_bootargs == NULL) { debug("checkcrash: could not strdup bootargs variable to reset to\n"); rc = 1; goto out4; } } /* Unset bootargs */ if (setenv("bootargs", "") != 0) { debug("checkcrash: could not unset bootargs variable\n"); rc = 1; goto out3; } /* Run memargs to set bootargs */ memargs_cmd = getenv("memargs"); if(memargs_cmd == NULL) { debug("checkcrash: no memargs_cmd environment variable\n"); rc = 1; goto out3; } #ifndef CONFIG_SYS_HUSH_PARSER if (run_command(memargs_cmd, 0) < 0) { debug("checkcrash: failed to run memargs\n"); rc = 1; goto out3; } #else if (parse_string_outer(memargs_cmd, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0) { debug("checkcrash: failed to run memargs\n"); rc = 1; goto out3; } #endif memargs = bootargs = strdup(getenv("bootargs")); if(bootargs == NULL) { debug("checkcrash: could not strdup bootargs variable to manipulate it\n"); rc = 1; goto out3; } /* Restore bootargs */ if (orig_bootargs && setenv("bootargs", orig_bootargs)) { debug("checkcrash: could not reset bootargs variable\n"); rc = 1; goto out2; } /* Calculate the number of regions */ nuf_ph = 1; // One extra since the crashkernel is likely to split one of the regions p = memargs; while (*p != '\0') { if (match_region(p)) {nuf_ph++;} while (!isspace(*p)) { p++; } while (isspace(*p)) { p++; } } /* Add one entry for SOC_AVS_BACKUPRAM */ nuf_ph += 1; printf ("nuf_ph %d\n", nuf_ph); regions = malloc(nuf_ph*sizeof(*regions)); if (regions == NULL) { debug("checkcrash: could not allocate array of ranges\n"); rc = 1; goto out2; } region_no = 0; while (memargs != NULL) { size_t len; p = strsep(&memargs, " \t"); len = match_region(p); if (!len) continue; p += len; suffixed_addr_toul(p, ®ions[region_no]); if (ck.start==(regions[region_no].start) && (ck.start+ck.size)==(regions[region_no].start+regions[region_no].size)) { /* Skip */ } else if (ck.start==(regions[region_no].start) && (ck.start+ck.size)<(regions[region_no].start+regions[region_no].size)) { /* Skip beginning */ regions[region_no].start = ck.start+ck.size; regions[region_no].size -= ck.size; } else if (ck.start>(regions[region_no].start) && (ck.start+ck.size)==(regions[region_no].start+regions[region_no].size)) { /* Skip end */ regions[region_no].size -= ck.size; } else if (ck.start>=(regions[region_no].start) && (ck.start+ck.size)<=(regions[region_no].start+regions[region_no].size)) { /* Split */ regions[region_no+1].start = ck.start + ck.size; regions[region_no+1].size = (regions[region_no].start + regions[region_no].size) - regions[region_no+1].start; regions[region_no].size = ck.start - regions[region_no].start; region_no++; } region_no++; } /* Add SOC_AVS_BACKUPRAM */ regions[region_no].start = SOC_AVS_BACKUPRAM; regions[region_no].size = SOC_AVS_BACKUPRAM_LEN; region_no++; for (i=0;i<region_no;i++) { debug("%lu placed at %lu\n", regions[i].size, regions[i].start); } elfhdr_addr = create_elfhdr(regions, region_no); if (elfhdr_addr == NULL) { debug("Could not create elfhdr\n"); rc = 1; goto out1; } if (crashdump(elfhdr_addr) != 0) { rc = 1; } free(elfhdr_addr); out1: free(regions); out2: free(bootargs); out3: free(orig_bootargs); out4: free(crashkernel); out5: return rc; }
int get_next_region(client_handle_t handle, region_info_t *rgn) { if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; return match_region(handle, rgn->next, rgn); } /* get_next_region */