int main(int argc, char *argv[]) { switch (argc) { case 1: printf("%i\n", getuid()); return 0; case 2: if (!strcmp(argv[1], "-h")) return usage(0); if (*argv[1] == '-') { const char *name = argv[1] + 1; struct passwd *pwd = getpwnam(name); if (!pwd) errp("getpwnam(%s) failed", name); printf("%i\n", pwd->pw_uid); } else { const char *file = argv[1]; struct stat st; if (lstat(file, &st)) errp("lstat(%s) failed", file); printf("%i\n", st.st_uid); } return 0; } return usage(1); }
/* * re/start kernel threads */ void cpr_start_kernel_threads(void) { DEBUG1(errp("starting kernel daemons...")); (void) callb_execute_class(CB_CL_CPR_DAEMON, CB_CODE_CPR_RESUME); DEBUG1(errp("done\n")); /* see table lock below */ callb_unlock_table(); }
/* * Checks and makes sure all user threads are stopped */ static int cpr_check_user_threads() { kthread_id_t tp; int rc = 0; mutex_enter(&pidlock); tp = curthread->t_next; do { if (ttoproc(tp)->p_as == &kas || ttoproc(tp)->p_stat == SZOMB) continue; thread_lock(tp); /* * make sure that we are off all the queues and in a stopped * state. */ if (!CPR_ISTOPPED(tp)) { thread_unlock(tp); mutex_exit(&pidlock); if (count == CPR_UTSTOP_RETRY) { DEBUG1(errp("Suspend failed: cannt stop " "uthread\n")); cpr_err(CE_WARN, "Suspend cannot stop " "process %s (%p:%x).", ttoproc(tp)->p_user.u_psargs, (void *)tp, tp->t_state); cpr_err(CE_WARN, "Process may be waiting for" " network request, please try again."); } DEBUG2(errp("cant stop t=%p state=%x pfg=%x sched=%x\n", tp, tp->t_state, tp->t_proc_flag, tp->t_schedflag)); DEBUG2(errp("proc %p state=%x pid=%d\n", ttoproc(tp), ttoproc(tp)->p_stat, ttoproc(tp)->p_pidp->pid_id)); return (1); } thread_unlock(tp); } while ((tp = tp->t_next) != curthread && rc == 0); mutex_exit(&pidlock); return (0); }
static int file_open(struct tcmu_device *dev) { struct file_state *state; int64_t size; char *config; state = calloc(1, sizeof(*state)); if (!state) return -ENOMEM; tcmu_set_dev_private(dev, state); state->block_size = tcmu_get_attribute(dev, "hw_block_size"); if (state->block_size == -1) { errp("Could not get device block size\n"); goto err; } size = tcmu_get_device_size(dev); if (size == -1) { errp("Could not get device size\n"); goto err; } state->num_lbas = size / state->block_size; config = strchr(tcmu_get_dev_cfgstring(dev), '/'); if (!config) { errp("no configuration found in cfgstring\n"); goto err; } config += 1; /* get past '/' */ state->fd = open(config, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (state->fd == -1) { errp("could not open %s: %m\n", config); goto err; } return 0; err: free(state); return -EINVAL; }
/* * Stop kernel threads by using the callback mechanism. If any thread * cannot be stopped, return failure. */ int cpr_stop_kernel_threads(void) { caddr_t name; kthread_id_t tp; proc_t *p; callb_lock_table(); /* Note: we unlock the table in resume. */ DEBUG1(errp("stopping kernel daemons...")); if ((name = callb_execute_class(CB_CL_CPR_DAEMON, CB_CODE_CPR_CHKPT)) != (caddr_t)NULL) { cpr_err(CE_WARN, "Could not stop \"%s\" kernel thread. " "Please try again later.", name); return (EBUSY); } /* * We think we stopped all the kernel threads. Just in case * someone is not playing by the rules, take a spin through * the threadlist and see if we can account for everybody. */ mutex_enter(&pidlock); tp = curthread->t_next; do { p = ttoproc(tp); if (p->p_as != &kas) continue; if (tp->t_flag & T_INTR_THREAD) continue; if (! callb_is_stopped(tp, &name)) { mutex_exit(&pidlock); cpr_err(CE_WARN, "\"%s\" kernel thread not stopped.", name); return (EBUSY); } } while ((tp = tp->t_next) != curthread); mutex_exit(&pidlock); DEBUG1(errp("done\n")); return (0); }
static int foo_handle_cmd( struct tcmu_device *dev, uint8_t *cdb, struct iovec *iovec, size_t iov_cnt, uint8_t *sense) { struct foo_state *state = tcmu_get_dev_private(dev); uint8_t cmd; cmd = cdb[0]; switch (cmd) { case INQUIRY: return tcmu_emulate_inquiry(dev, cdb, iovec, iov_cnt, sense); break; case TEST_UNIT_READY: return tcmu_emulate_test_unit_ready(cdb, iovec, iov_cnt, sense); break; case SERVICE_ACTION_IN_16: if (cdb[1] == READ_CAPACITY_16) return tcmu_emulate_read_capacity_16(state->num_lbas, state->block_size, cdb, iovec, iov_cnt, sense); else return TCMU_NOT_HANDLED; break; case MODE_SENSE: case MODE_SENSE_10: return tcmu_emulate_mode_sense(cdb, iovec, iov_cnt, sense); break; case MODE_SELECT: case MODE_SELECT_10: return tcmu_emulate_mode_select(cdb, iovec, iov_cnt, sense); break; case READ_6: case READ_10: case READ_12: case READ_16: // A real "read" implementation goes here! return set_medium_error(sense); case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_16: // A real "write" implemention goes here! return SAM_STAT_GOOD; default: errp("unknown command %x\n", cdb[0]); return TCMU_NOT_HANDLED; } }
// This function updates the shared memory with the outputs of the simulink model void Airdata_SFL_UpdateOutputs() { // Declare output data structures from the model // static: Memory will stay allocated and can be used in next call to the function static airdata_t _airdata; // Airdata output structure v3_t tas_alpha_beta; clock_gettime( CLOCK_REALTIME, &_airdata.timestamp); // Read data from simulink model _airdata.IAS = airdata[0]; _airdata.CAS = airdata[1]; _airdata.EAS = airdata[2]; _airdata.TAS = airdata[3]; _airdata.altitude = airdata[4]; _airdata.alpha = airdata[5]; _airdata.beta = airdata[6]; _airdata.temperature = airdata[7]; _airdata.voltage = airdata_sfl_data.voltage; _airdata.status = airdata_sfl_data.status; tas_alpha_beta.timestamp.tv_sec = _airdata.timestamp.tv_sec; tas_alpha_beta.timestamp.tv_nsec = _airdata.timestamp.tv_nsec; tas_alpha_beta.val[0] = _airdata.TAS; tas_alpha_beta.val[1] = _airdata.alpha; tas_alpha_beta.val[2] = _airdata.beta; // Output debug data dprintf("airdata_sfl: IAS = %f, CAS = %f\n EAS = %f, TAS = %f\n alpha = %f, beta = %f\n\n\n", _airdata.IAS, _airdata.CAS, _airdata.EAS, _airdata.TAS, _airdata.alpha, _airdata.beta ); // Write data to shared memory slot // errp Check for errors in function calls // SHM_WriteSlot Write data to public slot errp(SHM_WriteSlot(cfg.shm_out_airdata, &_airdata, sizeof(_airdata))); errp(SHM_WriteSlot(cfg.shm_out_tas_alpha_beta, &tas_alpha_beta, sizeof(tas_alpha_beta))); }
const char *qpkg_get_bindir(void) { if (qpkg_bindir != NULL) return qpkg_bindir; if (getuid() == 0) return "/var/tmp/binpkgs"; if (getenv("HOME") == NULL) errp("Your $HOME env var isn't set, aborting"); xasprintf(&qpkg_bindir, "%s/binpkgs", getenv("HOME")); return qpkg_bindir; }
void safe_timer(long long *tm, int period_mcs) { uint64_t time_now; uint64_t period_ns; struct timespec wake_up_time; long long *dummy; dummy = tm; ifperrs(ClockTime(CLOCK_MONOTONIC, NULL, &time_now) == -1, AR_ERR_SYS_RESOURCES, strerror(errno)); period_ns = period_mcs*1000; time_now = time_now - time_now % period_ns + period_ns; wake_up_time.tv_sec = time_now/1000000000LL; wake_up_time.tv_nsec = time_now % 1000000000LL; errp(clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &wake_up_time, NULL)); }
/* * CPU ONLINE/OFFLINE CODE */ int cpr_mp_offline(void) { cpu_t *cp, *bootcpu; int rc = 0; int brought_up_boot = 0; /* * Do nothing for UP. */ if (ncpus == 1) return (0); mutex_enter(&cpu_lock); cpr_save_mp_state(); bootcpu = i_cpr_bootcpu(); if (!CPU_ACTIVE(bootcpu)) { if ((rc = cpr_p_online(bootcpu, CPU_CPR_ONLINE))) { mutex_exit(&cpu_lock); return (rc); } brought_up_boot = 1; } cp = cpu_list; do { if (cp == bootcpu) continue; if (cp->cpu_flags & CPU_OFFLINE) continue; if ((rc = cpr_p_online(cp, CPU_CPR_OFFLINE))) { mutex_exit(&cpu_lock); return (rc); } } while ((cp = cp->cpu_next) != cpu_list); if (brought_up_boot && (cpr_debug & (LEVEL1 | LEVEL6))) errp("changed cpu %p to state %d\n", bootcpu, CPU_CPR_ONLINE); mutex_exit(&cpu_lock); return (rc); }
static void * corr_data_thread_func(void* arg) { char buffer[MAX_GPS_CORRECTION_SIZE]; int err; gps_corr_t gps_corr; int received_bytes; struct termios termios_p; if(config.queue_corr_data == 0) { if(tcgetattr(fd_corr_data_read, &termios_p)==0) { termios_p.c_cc[VTIME] = 5; // 2*0.1s = 0.2s termios_p.c_cc[VMIN] = 1; tcsetattr(fd_corr_data_read, TCSADRAIN, &termios_p); } } while(1) { if(config.queue_corr_data != 0) { memset(&gps_corr, 0, sizeof(gps_corr)); errp(Q_ReadSlot(config.queue_corr_data, &gps_corr, sizeof(gps_corr), &received_bytes)); gps_corr.size = ntohl(gps_corr.size); ifperr(gps_corr.size > MAX_GPS_CORRECTION_SIZE, AR_ERR_CONSI); // fprintf(stderr, "got <%d> bytes from queue, <%d> bytes corr. data\n", received_bytes, gps_corr.size); err = write(fd, gps_corr.buffer, gps_corr.size); // fprintf(stderr, " wrote <%d> bytes to fd\n", err); if(err != gps_corr.size) { perrs(AR_ERR_IO_ERROR, "can not write GPS corr. data from queue to ser. device\n"); } } else { err = read(fd_corr_data_read, buffer, MAX_GPS_CORRECTION_SIZE); if(err>0) { err = write(fd, buffer, err); if(err <= 0) { perrs(AR_ERR_IO_ERROR, "can not write GPS corr. data from ser. device to ser. device\n"); } //fprintf(stderr, " wrote <%d> bytes to fd\n", err); } else if (err < 0) { perrs(AR_ERR_IO_ERROR, "can not read GPS corr. data from ser. device\n"); } } } return 0; }
// This function updates the inputs to the simulink model void Airdata_SFL_UpdateInputs() { // Declare input data structures to the model // !!!! CHANGE THIS HERE!!! // Read airdata from shared memory // -> errp Makro from ar_err library to check for errors // -> SHM_Priv_ReadSlot Reads data from private (only to this process) shared memory slot errp(SHM_Priv_ReadSlot(AR_SHM_PRIV_SLOT_AIRDATA_SFL, &airdata_sfl_data, sizeof(airdata_sfl_data))); // Set data in simulation from structure airdata_sfl_P.IAS_S_Value = airdata_sfl_data.IAS; airdata_sfl_P.TAS_S_Value = airdata_sfl_data.TAS; airdata_sfl_P.altitude_S_Value = airdata_sfl_data.altitude; airdata_sfl_P.alpha_S_Value = airdata_sfl_data.alpha; airdata_sfl_P.beta_S_Value = airdata_sfl_data.beta; airdata_sfl_P.temperature_S_Value = airdata_sfl_data.temperature; airdata_sfl_P.voltage_S_Value = airdata_sfl_data.voltage; airdata_sfl_P.status_S_Value = airdata_sfl_data.status; }
void read_corr_data_loop() { int err; gps_corr_t gps_corr; struct termios termios_p; if(tcgetattr(fd, &termios_p)==0) { termios_p.c_cc[VTIME] = 5; // 2*0.1s = 0.2s termios_p.c_cc[VMIN] = 1; tcsetattr(fd, TCSANOW, &termios_p); } while(1) { memset(&gps_corr, 0, sizeof(gps_corr)); err = read(fd, gps_corr.buffer, MAX_GPS_CORRECTION_SIZE); if(err>0) { //printf("len=%i\n",err); gps_corr.size = htonl(err); errp(Q_WriteSlot(config.queue_corr_data_1, &gps_corr, sizeof(gps_corr.size) + err)); if(config.queue_corr_data_2 != 0) { errp(Q_WriteSlot(config.queue_corr_data_2, &gps_corr, sizeof(gps_corr.size) + err)); } if(config.queue_corr_data_3 != 0) { errp(Q_WriteSlot(config.queue_corr_data_3, &gps_corr, sizeof(gps_corr.size) + err)); } if(config.queue_corr_data_4 != 0) { errp(Q_WriteSlot(config.queue_corr_data_4, &gps_corr, sizeof(gps_corr.size) + err)); } if(config.queue_corr_data_5 != 0) { errp(Q_WriteSlot(config.queue_corr_data_5, &gps_corr, sizeof(gps_corr.size) + err)); } if(config.queue_corr_data_6 != 0) { errp(Q_WriteSlot(config.queue_corr_data_6, &gps_corr, sizeof(gps_corr.size) + err)); } safe_timer(NULL, 10000); } else { gps_corr.size = 0; perrs(AR_ERR_IO_ERROR, "can not read GPS corr. data from ser. device\n"); } } }
static int qglsa_run_action(const char *overlay, qglsa_action action, const char *fixed_list, bool all_glsas, unsigned int ind, int argc, char **argv) { int i; DIR *dir; struct dirent *dentry; char *buf; size_t buflen = 0; char *s, *p; int overlay_fd, glsa_fd; overlay_fd = open(overlay, O_RDONLY|O_CLOEXEC|O_PATH); glsa_fd = openat(overlay_fd, "metadata/glsa", O_RDONLY|O_CLOEXEC); switch (action) { /*case GLSA_FIX:*/ case GLSA_INJECT: buf = NULL; for (i = ind; i < argc; ++i) { free(buf); xasprintf(&buf, "glsa-%s.xml", argv[i]); if (faccessat(glsa_fd, buf, R_OK, 0)) { warnp("Skipping invalid GLSA '%s'", argv[i]); continue; } if (fixed_list) { if (strstr(fixed_list, argv[i])) { warn("Skipping already installed GLSA %s", argv[i]); continue; } } if (action == GLSA_FIX) { printf("Fixing GLSA %s%s%s\n", GREEN, argv[i], NORM); continue; } else if (action == GLSA_INJECT) printf("Injecting GLSA %s%s%s\n", GREEN, argv[i], NORM); qglsa_append_to_list(argv[i]); } free(buf); break; default: if ((dir = fdopendir(glsa_fd)) == NULL) return EXIT_FAILURE; buf = NULL; buflen = 0; while ((dentry = readdir(dir)) != NULL) { /* validate this file as a proper glsa */ char glsa_id[20]; if (strncmp(dentry->d_name, "glsa-", 5)) continue; if ((s = strchr(dentry->d_name, '.')) == NULL || memcmp(s, ".xml\0", 5)) continue; size_t len = s - dentry->d_name; if (len >= sizeof(glsa_id) || len <= 5) continue; memcpy(glsa_id, dentry->d_name + 5, len - 5); glsa_id[len - 5] = '\0'; /* see if we want to skip glsa's already fixed */ if (!all_glsas && fixed_list) { if (strstr(fixed_list, glsa_id)) continue; } /* load the glsa into memory */ if (!eat_file_at(glsa_fd, dentry->d_name, &buf, &buflen)) errp("could not eat %s", dentry->d_name); /* now lets figure out what to do with this memory */ switch (action) { case GLSA_LIST: s = qglsa_get_xml_tag(buf, "title"); printf("%s%s%s: %s", GREEN, glsa_id, NORM, s); if (verbose) { int num_shown = 0; p = qglsa_get_xml_tag(buf, "affected"); if (p) { printf(" ("); while (p++) { s = qglsa_get_xml_tag_attribute(p, "package", "name"); if (s) { if (verbose < 2 && ++num_shown > 3) { printf(" ..."); break; } printf(" %s", s); } else break; p = strstr(p, "</package>"); } printf(" )"); } } printf("\n"); break; case GLSA_DUMP: s = qglsa_get_xml_tag(buf, "title"); printf("%s%s%s: %s\n", GREEN, glsa_id, NORM, s); s = qglsa_get_xml_tag(buf, "bug"); printf(" %sRef%s: http://bugs.gentoo.org/%s\n", BLUE, NORM, s); s = qglsa_get_xml_tag(buf, "access"); printf(" %saccess%s: %s\n", BLUE, NORM, s); s = qglsa_get_xml_tag(buf, "synopsis"); printf(" %ssynopsis%s:\n%s\n", BLUE, NORM, s); s = qglsa_get_xml_tag(buf, "affected"); printf(" %saffected%s:\n%s\n", BLUE, NORM, s); if (verbose) { s = qglsa_get_xml_tag(buf, "description"); printf(" %sdescription%s:\n%s\n", BLUE, NORM, s); s = qglsa_get_xml_tag(buf, "workaround"); printf(" %sworkaround%s:\n%s\n", BLUE, NORM, s); } break; } } closedir(dir); } close(glsa_fd); close(overlay_fd); return EXIT_SUCCESS; }
int qpkg_main(int argc, char **argv) { q_vdb_ctx *ctx; q_vdb_cat_ctx *cat_ctx; q_vdb_pkg_ctx *pkg_ctx; size_t s, pkgs_made; int i; struct stat st; char buf[BUFSIZE]; const char *bindir; depend_atom *atom; int restrict_chmod = 0; int qclean = 0; while ((i = GETOPT_LONG(QPKG, qpkg, "")) != -1) { switch (i) { case 'E': eclean = qclean = 1; break; case 'c': qclean = 1; break; case 'p': pretend = 1; break; case 'P': restrict_chmod = 1; free(qpkg_bindir); qpkg_bindir = xstrdup(optarg); if (access(qpkg_bindir, W_OK) != 0) errp("%s", qpkg_bindir); break; COMMON_GETOPTS_CASES(qpkg) } } if (qclean) return qpkg_clean(qpkg_bindir == NULL ? pkgdir : qpkg_bindir); if (argc == optind) qpkg_usage(EXIT_FAILURE); /* setup temp dirs */ i = 0; bindir = qpkg_get_bindir(); if (*bindir != '/') err("'%s' is not a valid package destination", bindir); retry_mkdir: if (mkdir(bindir, 0750) == -1) { lstat(bindir, &st); if (!S_ISDIR(st.st_mode)) { unlink(bindir); if (!i++) goto retry_mkdir; errp("could not create temp bindir '%s'", bindir); } if (!restrict_chmod) if (chmod(bindir, 0750)) errp("could not chmod(0750) temp bindir '%s'", bindir); } /* we have to change to the root so that we can feed the full paths * to tar when we create the binary package. */ xchdir(portroot); /* first process any arguments which point to /var/db/pkg */ pkgs_made = 0; s = strlen(portvdb); for (i = optind; i < argc; ++i) { size_t asize = strlen(argv[i]); if (asize == 0) { argv[i] = NULL; continue; } if (argv[i][asize-1] == '/') argv[i][asize-1] = '\0'; if (!strncmp(portvdb, argv[i], s)) memmove(argv[i], argv[i]+s+1, asize-s); else if (argv[i][0] == '/' && !strncmp(portvdb, argv[i]+1, s)) memmove(argv[i], argv[i]+s+2, asize-s-1); else continue; atom = atom_explode(argv[i]); if (atom) { if (!qpkg_make(atom)) ++pkgs_made; atom_implode(atom); } else warn("could not explode '%s'", argv[i]); argv[i] = NULL; } /* now try to run through vdb and locate matches for user inputs */ ctx = q_vdb_open(portroot, portvdb); if (!ctx) return EXIT_FAILURE; /* scan all the categories */ while ((cat_ctx = q_vdb_next_cat(ctx))) { /* scan all the packages in this category */ const char *catname = cat_ctx->name; while ((pkg_ctx = q_vdb_next_pkg(cat_ctx))) { const char *pkgname = pkg_ctx->name; /* see if user wants any of these packages */ snprintf(buf, sizeof(buf), "%s/%s", catname, pkgname); atom = atom_explode(buf); if (!atom) { warn("could not explode '%s'", buf); goto next_pkg; } snprintf(buf, sizeof(buf), "%s/%s", atom->CATEGORY, atom->PN); for (i = optind; i < argc; ++i) { if (!argv[i]) continue; if (!strcmp(argv[i], atom->PN) || !strcmp(argv[i], atom->P) || !strcmp(argv[i], buf) || !strcmp(argv[i], "world")) if (!qpkg_make(atom)) ++pkgs_made; } atom_implode(atom); next_pkg: q_vdb_close_pkg(pkg_ctx); } } s = (argc - optind) - pkgs_made; if (s && !pretend) printf(" %s*%s %i package%s could not be matched :/\n", RED, NORM, (int)s, (s > 1 ? "s" : "")); if (pkgs_made) qprintf(" %s*%s Packages can be found in %s\n", GREEN, NORM, bindir); return (pkgs_made ? EXIT_SUCCESS : EXIT_FAILURE); }
int qsearch_main(int argc, char **argv) { FILE *fp; char *ebuild = NULL; char last[126] = ""; char *p, *q, *str; char *search_me = NULL; char show_homepage = 0, show_name_only = 0; char search_desc = 0, search_all = 0, search_name = 1, search_cache = CACHE_EBUILD; const char *search_vars[] = { "DESCRIPTION=", "HOMEPAGE=" }; size_t search_len, ebuild_len; int i, idx=0; DBG("argc=%d argv[0]=%s argv[1]=%s", argc, argv[0], argc > 1 ? argv[1] : "NULL?"); while ((i = GETOPT_LONG(QSEARCH, qsearch, "")) != -1) { switch (i) { COMMON_GETOPTS_CASES(qsearch) case 'a': search_all = 1; break; case 'c': search_cache = CACHE_METADATA; break; case 'e': search_cache = CACHE_EBUILD; break; case 's': search_desc = 0; search_name = 1; break; case 'S': search_desc = 1; search_name = 0; break; case 'N': show_name_only = 1; break; case 'H': show_homepage = 1, idx = 1; break; } } if (search_all) { search_desc = 1; search_name = 0; } else { if (argc == optind) qsearch_usage(EXIT_FAILURE); search_me = argv[optind]; } #ifdef TESTING /* FIXME: hardcoded */ if ((search_cache == CACHE_EBUILD) && (access("/usr/portage/.qsearch.x", R_OK) == 0)) { if ((fp = fopen("/usr/portage/.qsearch.x", "r")) != NULL) { search_len = strlen(search_me); while (fgets(buf, sizeof(buf), fp) != NULL) { if (strlen(buf) <= search_len) continue; /* add regexp, color highlighting and basename checks */ if (strncmp(buf, search_me, search_len) == 0) { fputs(buf, stdout); } } fclose(fp); return 0; } } #endif last[0] = 0; fp = fopen(initialize_flat(search_cache, false), "r"); if (!fp) return 1; int portdir_fd = open(portdir, O_RDONLY|O_CLOEXEC|O_PATH); if (portdir_fd < 0) errp("open(%s) failed", portdir); q = NULL; /* Silence a gcc warning. */ search_len = strlen(search_vars[idx]); while (getline(&ebuild, &ebuild_len, fp) != -1) { if ((p = strchr(ebuild, '\n')) != NULL) *p = 0; if (!ebuild[0]) continue; switch (search_cache) { case CACHE_METADATA: { portage_cache *pcache; if ((pcache = cache_read_file(ebuild)) != NULL) { if (strcmp(pcache->atom->PN, last) != 0) { strncpy(last, pcache->atom->PN, sizeof(last)); if ((rematch(search_me, (search_desc ? pcache->DESCRIPTION : ebuild), REG_EXTENDED | REG_ICASE) == 0) || search_all) printf("%s%s/%s%s%s %s\n", BOLD, pcache->atom->CATEGORY, BLUE, pcache->atom->PN, NORM, (show_name_only ? "" : (show_homepage ? pcache->HOMEPAGE : pcache->DESCRIPTION))); } cache_free(pcache); } else { if (!reinitialize) warnf("(cache update pending) %s", ebuild); reinitialize = 1; } break; } case CACHE_EBUILD: { FILE *ebuildfp; str = xstrdup(ebuild); p = dirname(str); if (strcmp(p, last) != 0) { bool show_it = false; strncpy(last, p, sizeof(last)); if (search_name) { if (rematch(search_me, basename(last), REG_EXTENDED | REG_ICASE) != 0) { goto no_cache_ebuild_match; } else { q = NULL; show_it = true; } } int fd = openat(portdir_fd, ebuild, O_RDONLY|O_CLOEXEC); if (fd != -1) { ebuildfp = fdopen(fd, "r"); if (ebuildfp == NULL) { close(fd); continue; } } else { if (!reinitialize) warnfp("(cache update pending) %s", ebuild); reinitialize = 1; goto no_cache_ebuild_match; } char *buf = NULL; size_t buflen; while (getline(&buf, &buflen, ebuildfp) != -1) { if (strlen(buf) <= search_len) continue; if (strncmp(buf, search_vars[idx], search_len) != 0) continue; if ((q = strrchr(buf, '"')) != NULL) *q = 0; if (strlen(buf) <= search_len) break; q = buf + search_len + 1; if (!search_all && !search_name && rematch(search_me, q, REG_EXTENDED | REG_ICASE) != 0) break; show_it = true; break; } if (show_it) { printf("%s%s/%s%s%s %s\n", BOLD, dirname(p), BLUE, basename(p), NORM, (show_name_only ? "" : q ? : "<no DESCRIPTION found>")); } free(buf); fclose(ebuildfp); } no_cache_ebuild_match: free(str); break; } /* case CACHE_EBUILD */ } /* switch (search_cache) */ }
int qgrep_main(int argc, char **argv) { int i; int count = 0; char *p; char do_count, do_regex, do_eclass, do_installed, do_list; char show_filename, skip_comments, invert_list, show_name; char per_file_output; FILE *fp = NULL; DIR *eclass_dir = NULL; DIR *vdb_dir = NULL; DIR *cat_dir = NULL; struct dirent *dentry; char ebuild[_Q_PATH_MAX]; char name[_Q_PATH_MAX]; char *label; int reflags = 0; char invert_match = 0; regex_t preg, skip_preg; char *skip_pattern = NULL; depend_atom** include_atoms = NULL; unsigned long int context_optarg; char num_lines_before = 0; char num_lines_after = 0; qgrep_buf_t *buf_list; int need_separator = 0; char status = 1; QGREP_STR_FUNC strfunc = strstr; do_count = do_regex = do_eclass = do_installed = do_list = 0; show_filename = skip_comments = invert_list = show_name = 0; while ((i = GETOPT_LONG(QGREP, qgrep, "")) != -1) { switch (i) { case 'I': invert_match = 1; break; case 'i': strfunc = strcasestr; reflags |= REG_ICASE; break; case 'c': do_count = 1; break; case 'l': do_list = 1; break; case 'L': do_list = invert_list = 1; break; case 'e': do_regex = 1; break; case 'x': do_regex = 1; reflags |= REG_EXTENDED; break; case 'J': do_installed = 1; break; case 'E': do_eclass = 1; break; case 'H': show_filename = 1; break; case 'N': show_name = 1; break; case 's': skip_comments = 1; break; case 'S': skip_pattern = optarg; break; case 'B': case 'A': errno = 0; context_optarg = strtol(optarg, &p, 10); if (errno != 0) errp("%s: not a valid integer", optarg); else if (p == optarg || *p != '\0') err("%s: not a valid integer", optarg); if (context_optarg > 254) err("%s: silly value!", optarg); if (i == 'B') num_lines_before = context_optarg; else num_lines_after = context_optarg; break; COMMON_GETOPTS_CASES(qgrep) } } if (argc == optind) qgrep_usage(EXIT_FAILURE); if (do_list && do_count) { warn("%s and --count are incompatible options. The former wins.", (invert_list ? "--invert-list" : "--list")); do_count = 0; } if (show_name && show_filename) { warn("--with-name and --with-filename are incompatible options. The former wins."); show_filename = 0; } if (do_list && num_lines_before) { warn("%s and --before are incompatible options. The former wins.", (invert_list ? "--invert-list" : "--list")); num_lines_before = 0; } if (do_list && num_lines_after) { warn("%s and --after are incompatible options. The former wins.", (invert_list ? "--invert-list" : "--list")); num_lines_after = 0; } if (do_count && num_lines_before) { warn("--count and --before are incompatible options. The former wins."); num_lines_before = 0; } if (do_count && num_lines_after) { warn("--count and --after are incompatible options. The former wins."); num_lines_after = 0; } if (do_installed && do_eclass) { warn("--installed and --eclass are incompatible options. The former wins."); do_eclass = 0; } /* do we report results once per file or per line ? */ per_file_output = do_count || (do_list && (!verbose || invert_list)); /* label for prefixing matching lines or listing matching files */ label = (show_name ? name : ((verbose || show_filename || do_list) ? ebuild : NULL)); if (argc > (optind + 1)) { include_atoms = xcalloc(sizeof(depend_atom*), (argc - optind - 1)); for (i = (optind + 1); i < argc; i++) if ((include_atoms[i - optind - 1] = atom_explode(argv[i])) == NULL) warn("%s: invalid atom, will be ignored", argv[i]); } /* pre-compile regexps once for all */ if (do_regex) { if (invert_match || *RED == '\0') reflags |= REG_NOSUB; xregcomp(&preg, argv[optind], reflags); reflags |= REG_NOSUB; if (skip_pattern) xregcomp(&skip_preg, skip_pattern, reflags); } /* allocate a circular buffers list for --before */ buf_list = qgrep_buf_list_alloc(num_lines_before + 1); size_t n; char *overlay; array_for_each(overlays, n, overlay) { /* go look either in ebuilds or eclasses or VDB */ if (!do_eclass && !do_installed) { fp = fopen(initialize_flat(overlay, CACHE_EBUILD, false), "re"); if (fp == NULL) continue; xchdir(overlay); } else if (do_eclass) { xchdir(overlay); if ((eclass_dir = opendir("eclass")) == NULL) { if (errno != ENOENT) warnp("opendir(\"%s/eclass\") failed", overlay); continue; } } else { /* if (do_install) */ char buf[_Q_PATH_MAX]; snprintf(buf, sizeof(buf), "%s/%s", portroot, portvdb); xchdir(buf); if ((vdb_dir = opendir(".")) == NULL) errp("could not opendir(%s/%s) for ROOT/VDB", portroot, portvdb); } /* iteration is either over ebuilds or eclasses */ while (do_eclass ? ((dentry = readdir(eclass_dir)) && snprintf(ebuild, sizeof(ebuild), "eclass/%s", dentry->d_name)) : (do_installed ? (get_next_installed_ebuild(ebuild, vdb_dir, &dentry, &cat_dir) != NULL) : (fgets(ebuild, sizeof(ebuild), fp) != NULL))) { FILE *newfp; /* filter badly named files, prepare eclass or package name, etc. */ if (do_eclass) { if ((p = strrchr(ebuild, '.')) == NULL) continue; if (strcmp(p, ".eclass")) continue; if (show_name || (include_atoms != NULL)) { /* cut ".eclass" */ *p = '\0'; /* and skip "eclass/" */ snprintf(name, sizeof(name), "%s", ebuild + 7); /* restore the filepath */ *p = '.'; } } else { if ((p = strchr(ebuild, '\n')) != NULL) *p = '\0'; if (show_name || (include_atoms != NULL)) { /* cut ".ebuild" */ if (p == NULL) p = ebuild + strlen(ebuild); *(p-7) = '\0'; /* cut "/foo/" from "cat/foo/foo-x.y" */ if ((p = strchr(ebuild, '/')) == NULL) continue; *(p++) = '\0'; /* find head of the ebuild basename */ if ((p = strchr(p, '/')) == NULL) continue; /* find start of the pkg name */ snprintf(name, sizeof(name), "%s/%s", ebuild, (p+1)); /* restore the filepath */ *p = '/'; *(p + strlen(p)) = '.'; ebuild[strlen(ebuild)] = '/'; } } /* filter the files we grep when there are extra args */ if (include_atoms != NULL) if (!qgrep_name_match(name, (argc - optind - 1), include_atoms)) continue; if ((newfp = fopen(ebuild, "r")) != NULL) { int lineno = 0; char remaining_after_context = 0; count = 0; /* if there have been some matches already, then a separator will be needed */ need_separator = (!status) && (num_lines_before || num_lines_after); /* whatever is in the circular buffers list is no more a valid context */ qgrep_buf_list_invalidate(buf_list); /* reading a new line always happen in the next buffer of the list */ while ((buf_list = buf_list->next) && (fgets(buf_list->buf, sizeof(buf_list->buf), newfp)) != NULL) { lineno++; buf_list->valid = 1; /* cleanup EOL */ if ((p = strrchr(buf_list->buf, '\n')) != NULL) *p = 0; if ((p = strrchr(buf_list->buf, '\r')) != NULL) *p = 0; if (skip_comments) { /* reject comments line ("^[ \t]*#") */ p = buf_list->buf; while (*p == ' ' || *p == '\t') p++; if (*p == '#') goto print_after_context; } if (skip_pattern) { /* reject some other lines which match an optional pattern */ if (!do_regex) { if (strfunc(buf_list->buf, skip_pattern) != NULL) goto print_after_context; } else { if (regexec(&skip_preg, buf_list->buf, 0, NULL, 0) == 0) goto print_after_context; } } /* four ways to match a line (with/without inversion and regexp) */ if (!invert_match) { if (do_regex == 0) { if (strfunc(buf_list->buf, argv[optind]) == NULL) goto print_after_context; } else { if (regexec(&preg, buf_list->buf, 0, NULL, 0) != 0) goto print_after_context; } } else { if (do_regex == 0) { if (strfunc(buf_list->buf, argv[optind]) != NULL) goto print_after_context; } else { if (regexec(&preg, buf_list->buf, 0, NULL, 0) == 0) goto print_after_context; } } count++; status = 0; /* got a match, exit status should be 0 */ if (per_file_output) continue; /* matching files are listed out of this loop */ if ((need_separator > 0) && (num_lines_before || num_lines_after)) printf("--\n"); /* "need_separator" is not a flag, but a counter, so that * adjacent contextes are not separated */ need_separator = 0 - num_lines_before; if (!do_list) { /* print the leading context */ qgrep_print_before_context(buf_list, num_lines_before, label, ((verbose > 1) ? lineno : -1)); /* print matching line */ if (invert_match || *RED == '\0') qgrep_print_matching_line_nocolor(buf_list, label, ((verbose > 1) ? lineno : -1)); else if (do_regex) qgrep_print_matching_line_regcolor(buf_list, label, ((verbose > 1) ? lineno : -1), &preg); else qgrep_print_matching_line_strcolor(buf_list, label, ((verbose > 1) ? lineno : -1), strfunc, argv[optind]); } else { /* in verbose do_list mode, list the file once per match */ printf("%s", label); if (verbose > 1) printf(":%d", lineno); putchar('\n'); } /* init count down of trailing context lines */ remaining_after_context = num_lines_after; continue; print_after_context: /* print some trailing context lines when needed */ if (!remaining_after_context) { if (!status) /* we're getting closer to the need of a separator between * current match block and the next one */ ++need_separator; } else { qgrep_print_context_line(buf_list, label, ((verbose > 1) ? lineno : -1)); --remaining_after_context; } } fclose(newfp); if (!per_file_output) continue; /* matches were already displayed, line per line */ if (do_count && count) { if (label != NULL) /* -c without -v/-N/-H only outputs * the matches count of the file */ printf("%s:", label); printf("%d\n", count); } else if ((count && !invert_list) || (!count && invert_list)) printf("%s\n", label); /* do_list == 1, or we wouldn't be here */ } } if (do_eclass) closedir(eclass_dir); else if (!do_installed) fclose(fp); if (do_installed) break; } if (do_regex) regfree(&preg); if (do_regex && skip_pattern) regfree(&skip_preg); if (include_atoms != NULL) { for (i = 0; i < (argc - optind - 1); i++) if (include_atoms[i] != NULL) atom_implode(include_atoms[i]); free(include_atoms); } qgrep_buf_list_free(buf_list); return status; }
void xchdir(const char *path) { if (unlikely(chdir(path) != 0)) errp("chdir(%s) failed", path); }
/* * Return scsi status or TCMU_NOT_HANDLED */ static int file_handle_cmd( struct tcmu_device *dev, uint8_t *cdb, struct iovec *iovec, size_t iov_cnt, uint8_t *sense) { struct file_state *state = tcmu_get_dev_private(dev); uint8_t cmd; int remaining; size_t ret; cmd = cdb[0]; switch (cmd) { case INQUIRY: return tcmu_emulate_inquiry(dev, cdb, iovec, iov_cnt, sense); break; case TEST_UNIT_READY: return tcmu_emulate_test_unit_ready(cdb, iovec, iov_cnt, sense); break; case SERVICE_ACTION_IN_16: if (cdb[1] == READ_CAPACITY_16) return tcmu_emulate_read_capacity_16(state->num_lbas, state->block_size, cdb, iovec, iov_cnt, sense); else return TCMU_NOT_HANDLED; break; case MODE_SENSE: case MODE_SENSE_10: return tcmu_emulate_mode_sense(cdb, iovec, iov_cnt, sense); break; case MODE_SELECT: case MODE_SELECT_10: return tcmu_emulate_mode_select(cdb, iovec, iov_cnt, sense); break; case READ_6: case READ_10: case READ_12: case READ_16: { void *buf; uint64_t offset = state->block_size * tcmu_get_lba(cdb); int length = tcmu_get_xfer_length(cdb) * state->block_size; ret = lseek(state->fd, offset, SEEK_SET); if (ret == -1) { errp("lseek failed: %m\n"); return set_medium_error(sense); } /* Using this buf DTRT even if seek is beyond EOF */ buf = malloc(length); if (!buf) return set_medium_error(sense); memset(buf, 0, length); ret = read(state->fd, buf, length); if (ret == -1) { errp("read failed: %m\n"); free(buf); return set_medium_error(sense); } tcmu_memcpy_into_iovec(iovec, iov_cnt, buf, length); free(buf); return SAM_STAT_GOOD; } break; case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_16: { uint64_t offset = state->block_size * tcmu_get_lba(cdb); int length = be16toh(*((uint16_t *)&cdb[7])) * state->block_size; ret = lseek(state->fd, offset, SEEK_SET); if (ret == -1) { errp("lseek failed: %m\n"); return set_medium_error(sense); } remaining = length; while (remaining) { unsigned int to_copy; to_copy = (remaining > iovec->iov_len) ? iovec->iov_len : remaining; ret = write(state->fd, iovec->iov_base, to_copy); if (ret == -1) { errp("Could not write: %m\n"); return set_medium_error(sense); } remaining -= to_copy; iovec++; } return SAM_STAT_GOOD; } break; default: errp("unknown command %x\n", cdb[0]); return TCMU_NOT_HANDLED; } }
int main(int argc, char **argv) { struct tcmulib_context *tcmulib_cxt; struct pollfd pollfds[16]; int i; int ret; /* If any TCMU devices that exist that match subtype, handler->added() will now be called from within tcmulib_initialize(). */ tcmulib_cxt = tcmulib_initialize(&foo_handler, 1, errp); if (tcmulib_cxt <= 0) { errp("tcmulib_initialize failed with %p\n", tcmulib_cxt); exit(1); } while (1) { pollfds[0].fd = tcmulib_get_master_fd(tcmulib_cxt); pollfds[0].events = POLLIN; pollfds[0].revents = 0; for (i = 0; i < dev_array_len; i++) { pollfds[i+1].fd = tcmu_get_dev_fd(tcmu_dev_array[i]); pollfds[i+1].events = POLLIN; pollfds[i+1].revents = 0; } ret = poll(pollfds, dev_array_len+1, -1); if (ret <= 0) { errp("poll() returned %d, exiting\n", ret); exit(1); } if (pollfds[0].revents) { /* If any tcmu devices have been added or removed, the added() and removed() handler callbacks will be called from within this. */ tcmulib_master_fd_ready(tcmulib_cxt); /* Since devices (may) have changed, re-poll() instead of processing per-device fds. */ continue; } for (i = 0; i < dev_array_len; i++) { if (pollfds[i+1].revents) { struct tcmulib_cmd *cmd; struct tcmu_device *dev = tcmu_dev_array[i]; while ((cmd = tcmulib_get_next_command(dev)) != NULL) { ret = foo_handle_cmd(dev, cmd->cdb, cmd->iovec, cmd->iov_cnt, cmd->sense_buf); tcmulib_command_complete(dev, cmd, ret); } tcmulib_processing_complete(dev); } } } return 0; }
int main(int argc, char *argv[]) { int policy; struct sched_param param; pthread_attr_t attr; char buffer[1024]; int err; dprintf("init\n"); if(argc != 2) { perr(AR_ERR_BAD_INIT_PARAM); printf("Useage: %s INSTANCE\n", AR_MODULE_NAME); return(AR_ERR_BAD_INIT_PARAM); } memset(&config, 0, sizeof(config)); erret(init_config(AR_MODULE_NAME, atoi(argv[1]), &config.base)); erret(read_config_int(config.base.name, "PRIORITY", &config.priority)); erret(read_config_int(config.base.name, "PRIORITY_DGPS_CORR_DATA", &config.priority_dgps_corr_data)); erret(read_config_string(config.base.name, "DEVICE", config.ser_device, sizeof(config.ser_device))); err = read_config_int_tab(config.base.name, "QUEUE_INDEX", "QUEUE_IN_GPS_CORR", &config.queue_corr_data); if(err != 0) { erret(read_config_string(config.base.name, "DEVICE_CORR_DATA_READ", config.ser_device_corr_data_read, sizeof(config.ser_device_corr_data_read))); // fprintf(stderr, "DGPS correction data from ser. device <%s>\n", config.ser_device_corr_data_read); } else { // fprintf(stderr, "DGPS correction data from queue <%d>\n", config.queue_corr_data); } memset(buffer, 0, sizeof(buffer)); config.corr_mode = -1; erret(read_config_string(config.base.name, "CORRECTION_MODE", buffer, sizeof(buffer))); if(strnicmp(buffer, "RTCA", strlen("RTCA")) == 0) { config.corr_mode = OEM4_RTCA_MODE; } else if(strnicmp(buffer, "RTCM", strlen("RTCM")) == 0) { config.corr_mode = OEM4_RTCM_MODE; } else { perrs(AR_ERR_BAD_INIT_PARAM, "Correction data mode not specified (RTCA | RTCM)."); // return(AR_ERR_BAD_INIT_PARAM); } erret(read_config_int_tab(config.base.name, "SHM_INDEX", "SHM_OUT_GPS_POS", &config.ishm_pos_out)); erret(read_config_int_tab(config.base.name, "SHM_INDEX", "SHM_OUT_GPS_VEL", &config.ishm_vel_out)); if(read_config_int(config.base.name, "UTC_OFFSET", &config.utc_offset)) { config.utc_offset = 15; } erret(SHM_Init()); erret(SHM_InitSlot(config.ishm_pos_out, sizeof(gps_pos_novatel_t))); erret(SHM_InitSlot(config.ishm_vel_out, sizeof(gps_vel_novatel_t))); if(config.queue_corr_data != 0) { erret(Q_Init()); erret(Q_InitSlot(config.queue_corr_data, sizeof(gps_corr_t), MAX_GPS_CORRECTION_Q_ITEMS_NUMBER, 1)); } else if (strlen(config.ser_device_corr_data_read)>0){ erret(open_comport(&fd_corr_data_read, config.ser_device_corr_data_read, O_RDWR, 115200)); } erret(open_comport(&fd, config.ser_device, O_RDWR, 57600)); if(0){ struct termios termios_p; if(tcgetattr(fd, &termios_p)==0) { termios_p.c_cc[VTIME] = 1; // 2*0.1s = 0.2s termios_p.c_cc[VMIN] = 0; tcsetattr(fd, TCSADRAIN, &termios_p); } else fprintf(stderr, "failed to set read timeout\n"); } //create thread for reading and writing of the correction data: ifret(pthread_getschedparam(pthread_self(), &policy, ¶m), AR_ERR_SYS_RESOURCES); param.sched_priority = config.priority_dgps_corr_data; pthread_attr_init( &attr ); ifret(pthread_attr_setschedparam(&attr, ¶m), AR_ERR_SYS_RESOURCES); ifret(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED), AR_ERR_SYS_RESOURCES); ifret(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED), AR_ERR_SYS_RESOURCES); if(config.corr_mode == OEM4_RTCA_MODE) { ifret(write(fd, OEM4_INIT_ROVER_RTCA, strlen(OEM4_INIT_ROVER_RTCA))==-1, AR_ERR_IO_ERROR); ifret(pthread_create(&pthreads[0], &attr, &corr_data_thread_func, NULL), AR_ERR_SYS_RESOURCES); } else if(config.corr_mode == OEM4_RTCM_MODE) { ifret(write(fd, OEM4_INIT_ROVER_RTCM, strlen(OEM4_INIT_ROVER_RTCM))==-1, AR_ERR_IO_ERROR); ifret(pthread_create(&pthreads[0], &attr, &corr_data_thread_func, NULL), AR_ERR_SYS_RESOURCES); } else { ifret(write(fd, OEM4_INIT_ROVER_COM1, strlen(OEM4_INIT_ROVER_COM1))==-1, AR_ERR_IO_ERROR); printf("running without differential data\n"); } ifret(pthread_getschedparam(pthread_self(), &policy, ¶m), AR_ERR_SYS_RESOURCES); param.sched_priority = config.priority; ifret(pthread_setschedparam(pthread_self(), policy, ¶m), AR_ERR_SYS_RESOURCES); while(1) { errp(read_data()); } return 0; }
int cpr_alloc_statefile(int alloc_retry) { register int rc = 0; char *str; /* * Statefile size validation. If checkpoint the first time, disk blocks * allocation will be done; otherwise, just do file size check. * if statefile allocation is being retried, C_VP will be inited */ if (alloc_retry) { str = "\n-->Retrying statefile allocation..."; if (cpr_debug & (LEVEL1 | LEVEL7)) errp(str); if (C_VP->v_type != VBLK) (void) VOP_DUMPCTL(C_VP, DUMP_FREE, NULL); } else { /* * Open an exiting file for writing, the state file needs to be * pre-allocated since we can't and don't want to do allocation * during checkpoint (too much of the OS is disabled). * - do a preliminary size checking here, if it is too small, * allocate more space internally and retry. * - check the vp to make sure it's the right type. */ char *path = cpr_build_statefile_path(); if (path == NULL) return (ENXIO); else if (rc = cpr_verify_statefile_path()) return (rc); if (rc = vn_open(path, UIO_SYSSPACE, FCREAT|FWRITE, 0600, &C_VP, CRCREAT, 0)) { cpr_err(CE_WARN, "cannot open statefile %s", path); return (rc); } } /* * Only ufs and block special statefiles supported */ if (C_VP->v_type != VREG && C_VP->v_type != VBLK) { cpr_err(CE_CONT, "Statefile must be regular file or block special file."); return (EACCES); } if (rc = cpr_statefile_ok(C_VP, alloc_retry)) return (rc); if (C_VP->v_type != VBLK) { /* * sync out the fs change due to the statefile reservation. */ (void) VFS_SYNC(C_VP->v_vfsp, 0, CRED()); /* * Validate disk blocks allocation for the state file. * Ask the file system prepare itself for the dump operation. */ if (rc = VOP_DUMPCTL(C_VP, DUMP_ALLOC, NULL)) { cpr_err(CE_CONT, "Error allocating " "blocks for cpr statefile."); return (rc); } } return (0); }
static int tcmu_glfs_open(struct tcmu_device *dev) { struct glfs_state *gfsp; int ret = 0; char *config; struct stat st; int attribute; gfsp = calloc(1, sizeof(*gfsp)); if (!gfsp) return -ENOMEM; tcmu_set_dev_private(dev, gfsp); attribute = tcmu_get_attribute(dev, "hw_block_size"); if (attribute == -1) { errp("Could not get hw_block_size setting\n"); goto fail; } gfsp->block_size = attribute; config = strchr(tcmu_get_dev_cfgstring(dev), '/'); if (!config) { errp("no configuration found in cfgstring\n"); goto fail; } config += 1; /* get past '/' */ if (parse_imagepath(config, &gfsp->servername, &gfsp->volname, &gfsp->pathname) == -1) { errp("servername, volname, or pathname not set\n"); goto fail; } gfsp->fs = glfs_new(gfsp->volname); if (!gfsp->fs) { errp("glfs_new failed\n"); goto fail; } ret = glfs_set_volfile_server(gfsp->fs, "tcp", gfsp->servername, GLUSTER_PORT); if (ret) { errp("glfs_set_volfile_server failed: %m\n"); goto fail; } ret = glfs_init(gfsp->fs); if (ret) { errp("glfs_init failed: %m\n"); goto fail; } gfsp->gfd = glfs_open(gfsp->fs, gfsp->pathname, ALLOWED_BSOFLAGS); if (!gfsp->gfd) { errp("glfs_open failed: %m\n"); goto fail; } ret = glfs_lstat(gfsp->fs, gfsp->pathname, &st); if (ret) { errp("glfs_lstat failed: %m\n"); goto fail; } if (st.st_size != tcmu_get_device_size(dev)) { errp("device size and backing size disagree: " "device %lld backing %lld\n", tcmu_get_device_size(dev), (long long) st.st_size); goto fail; } return 0; fail: if (gfsp->gfd) glfs_close(gfsp->gfd); if (gfsp->fs) glfs_fini(gfsp->fs); free(gfsp->volname); free(gfsp->pathname); free(gfsp->servername); free(gfsp); return -EIO; }
/* * do a simple estimate of the space needed to hold the statefile * taking compression into account, but be fairly conservative * so we have a better chance of completing; when dump fails, * the retry cost is fairly high. * * Do disk blocks allocation for the state file if no space has * been allocated yet. Since the state file will not be removed, * allocation should only be done once. */ static int cpr_statefile_ok(vnode_t *vp, int alloc_retry) { extern size_t cpr_bitmap_size; struct inode *ip = VTOI(vp); const int UCOMP_RATE = 20; /* comp. ratio*10 for user pages */ u_longlong_t size, isize, ksize, raw_data; char *str, *est_fmt; size_t space; int error; /* * number of pages short for swapping. */ STAT->cs_nosw_pages = k_anoninfo.ani_mem_resv; if (STAT->cs_nosw_pages < 0) STAT->cs_nosw_pages = 0; str = "cpr_statefile_ok:"; DEBUG9(errp("Phys swap: max=%lu resv=%lu\n", k_anoninfo.ani_max, k_anoninfo.ani_phys_resv)); DEBUG9(errp("Mem swap: max=%ld resv=%lu\n", MAX(availrmem - swapfs_minfree, 0), k_anoninfo.ani_mem_resv)); DEBUG9(errp("Total available swap: %ld\n", CURRENT_TOTAL_AVAILABLE_SWAP)); /* * try increasing filesize by 15% */ if (alloc_retry) { /* * block device doesn't get any bigger */ if (vp->v_type == VBLK) { if (cpr_debug & (LEVEL1 | LEVEL6)) errp("Retry statefile on special file\n"); return (ENOMEM); } else { rw_enter(&ip->i_contents, RW_READER); size = (ip->i_size * SIZE_RATE) / INTEGRAL; rw_exit(&ip->i_contents); } if (cpr_debug & (LEVEL1 | LEVEL6)) errp("Retry statefile size = %lld\n", size); } else { u_longlong_t cpd_size; pgcnt_t npages, nback; int ndvram; ndvram = 0; (void) callb_execute_class(CB_CL_CPR_FB, (int)(uintptr_t)&ndvram); if (cpr_debug & (LEVEL1 | LEVEL6)) errp("ndvram size = %d\n", ndvram); /* * estimate 1 cpd_t for every (CPR_MAXCONTIG / 2) pages */ npages = cpr_count_kpages(REGULAR_BITMAP, cpr_nobit); cpd_size = sizeof (cpd_t) * (npages / (CPR_MAXCONTIG / 2)); raw_data = cpd_size + cpr_bitmap_size; ksize = ndvram + mmu_ptob(npages); est_fmt = "%s estimated size with " "%scompression %lld, ksize %lld\n"; nback = mmu_ptob(STAT->cs_nosw_pages); if (CPR->c_flags & C_COMPRESSING) { size = ((ksize * COMPRESS_PERCENT) / INTEGRAL) + raw_data + ((nback * 10) / UCOMP_RATE); DEBUG1(errp(est_fmt, str, "", size, ksize)); } else { size = ksize + raw_data + nback; DEBUG1(errp(est_fmt, str, "no ", size, ksize)); } } /* * All this is much simpler for a block device */ if (vp->v_type == VBLK) { space = cpr_get_devsize(vp->v_rdev); if (cpr_debug & (LEVEL1 | LEVEL6)) errp("statefile dev size %lu\n", space); /* * Export the estimated filesize info, this value will be * compared before dumping out the statefile in the case of * no compression. */ STAT->cs_est_statefsz = size; if (cpr_debug & (LEVEL1 | LEVEL6)) errp("%s Estimated statefile size %llu, space %lu\n", str, size, space); if (size > space) { cpr_err(CE_CONT, "Statefile partition too small."); return (ENOMEM); } return (0); } else { if (CPR->c_alloc_cnt++ > C_MAX_ALLOC_RETRY) { cpr_err(CE_CONT, "Statefile allocation retry failed\n"); return (ENOMEM); } /* * Estimate space needed for the state file. * * State file size in bytes: * kernel size + non-cache pte seg + * bitmap size + cpr state file headers size * (round up to fs->fs_bsize) */ size = blkroundup(ip->i_fs, size); /* * Export the estimated filesize info, this value will be * compared before dumping out the statefile in the case of * no compression. */ STAT->cs_est_statefsz = size; error = cpr_grow_statefile(vp, size); if (cpr_debug & (LEVEL1 | LEVEL6)) { rw_enter(&ip->i_contents, RW_READER); isize = ip->i_size; rw_exit(&ip->i_contents); errp("%s Estimated statefile size %lld, i_size %lld\n", str, size, isize); } return (error); } }
/* * Return scsi status or TCMU_NOT_HANDLED */ int tcmu_glfs_handle_cmd( struct tcmu_device *dev, struct tcmulib_cmd *tcmulib_cmd) { uint8_t *cdb = tcmulib_cmd->cdb; struct iovec *iovec = tcmulib_cmd->iovec; size_t iov_cnt = tcmulib_cmd->iov_cnt; uint8_t *sense = tcmulib_cmd->sense_buf; struct glfs_state *state = tcmu_get_dev_private(dev); uint8_t cmd; glfs_fd_t *gfd = state->gfd; int ret; uint32_t length; int result = SAM_STAT_GOOD; char *tmpbuf; uint64_t offset = state->block_size * tcmu_get_lba(cdb); uint32_t tl = state->block_size * tcmu_get_xfer_length(cdb); int do_verify = 0; uint32_t cmp_offset; ret = length = 0; cmd = cdb[0]; switch (cmd) { case INQUIRY: return tcmu_emulate_inquiry(dev, cdb, iovec, iov_cnt, sense); break; case TEST_UNIT_READY: return tcmu_emulate_test_unit_ready(cdb, iovec, iov_cnt, sense); break; case SERVICE_ACTION_IN_16: if (cdb[1] == READ_CAPACITY_16) { long long size; unsigned long long num_lbas; size = tcmu_get_device_size(dev); if (size == -1) { errp("Could not get device size\n"); return TCMU_NOT_HANDLED; } num_lbas = size / state->block_size; return tcmu_emulate_read_capacity_16(num_lbas, state->block_size, cdb, iovec, iov_cnt, sense); } else { return TCMU_NOT_HANDLED; } break; case MODE_SENSE: case MODE_SENSE_10: return tcmu_emulate_mode_sense(cdb, iovec, iov_cnt, sense); break; case MODE_SELECT: case MODE_SELECT_10: return tcmu_emulate_mode_select(cdb, iovec, iov_cnt, sense); break; case COMPARE_AND_WRITE: /* Blocks are transferred twice, first the set that * we compare to the existing data, and second the set * to write if the compare was successful. */ length = tl / 2; tmpbuf = malloc(length); if (!tmpbuf) { result = tcmu_set_sense_data(sense, HARDWARE_ERROR, ASC_INTERNAL_TARGET_FAILURE, NULL); break; } ret = glfs_pread(gfd, tmpbuf, length, offset, SEEK_SET); if (ret != length) { result = set_medium_error(sense); free(tmpbuf); break; } cmp_offset = tcmu_compare_with_iovec(tmpbuf, iovec, length); if (cmp_offset != -1) { result = tcmu_set_sense_data(sense, MISCOMPARE, ASC_MISCOMPARE_DURING_VERIFY_OPERATION, &cmp_offset); free(tmpbuf); break; } free(tmpbuf); tcmu_seek_in_iovec(iovec, length); goto write; case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE_16: if (cdb[1] & 0x2) result = tcmu_set_sense_data(sense, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB, NULL); else glfs_fdatasync(gfd); break; case WRITE_VERIFY: case WRITE_VERIFY_12: case WRITE_VERIFY_16: do_verify = 1; case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_16: length = tl; write: ret = glfs_pwritev(gfd, iovec, iov_cnt, offset, ALLOWED_BSOFLAGS); if (ret == length) { /* Sync if FUA */ if ((cmd != WRITE_6) && (cdb[1] & 0x8)) glfs_fdatasync(gfd); } else { errp("Error on write %x %x\n", ret, length); result = set_medium_error(sense); break; } if (!do_verify) break; tmpbuf = malloc(length); if (!tmpbuf) { result = tcmu_set_sense_data(sense, HARDWARE_ERROR, ASC_INTERNAL_TARGET_FAILURE, NULL); break; } ret = glfs_pread(gfd, tmpbuf, length, offset, ALLOWED_BSOFLAGS); if (ret != length) { result = set_medium_error(sense); free(tmpbuf); break; } cmp_offset = tcmu_compare_with_iovec(tmpbuf, iovec, length); if (cmp_offset != -1) result = tcmu_set_sense_data(sense, MISCOMPARE, ASC_MISCOMPARE_DURING_VERIFY_OPERATION, &cmp_offset); free(tmpbuf); break; case WRITE_SAME: case WRITE_SAME_16: errp("WRITE_SAME called, but has vpd b2 been implemented?\n"); result = tcmu_set_sense_data(sense, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB, NULL); break; #if 0 /* WRITE_SAME used to punch hole in file */ if (cdb[1] & 0x08) { ret = glfs_discard(gfd, offset, tl); if (ret != 0) { result = tcmu_set_sense_data(sense, HARDWARE_ERROR, ASC_INTERNAL_TARGET_FAILURE, NULL); } break; } while (tl > 0) { size_t blocksize = state->block_size; uint32_t val32; uint64_t val64; assert(iovec->iov_len >= 8); switch (cdb[1] & 0x06) { case 0x02: /* PBDATA==0 LBDATA==1 */ val32 = htobe32(offset); memcpy(iovec->iov_base, &val32, 4); break; case 0x04: /* PBDATA==1 LBDATA==0 */ /* physical sector format */ /* hey this is wrong val! But how to fix? */ val64 = htobe64(offset); memcpy(iovec->iov_base, &val64, 8); break; default: /* FIXME */ errp("PBDATA and LBDATA set!!!\n"); } ret = glfs_pwritev(gfd, iovec, blocksize, offset, ALLOWED_BSOFLAGS); if (ret != blocksize) result = set_medium_error(sense); offset += blocksize; tl -= blocksize; } break; #endif case READ_6: case READ_10: case READ_12: case READ_16: length = tcmu_iovec_length(iovec, iov_cnt); ret = glfs_preadv(gfd, iovec, iov_cnt, offset, SEEK_SET); if (ret != length) { errp("Error on read %x %x\n", ret, length); result = set_medium_error(sense); } break; case UNMAP: /* TODO: implement UNMAP */ result = tcmu_set_sense_data(sense, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB, NULL); break; default: result = TCMU_NOT_HANDLED; break; } dbgp("io done %p %x %d %u\n", cdb, cmd, result, length); if (result == TCMU_NOT_HANDLED) dbgp("io not handled %p %x %x %d %d %llu\n", cdb, result, cmd, ret, length, (unsigned long long)offset); else if (result != SAM_STAT_GOOD) { errp("io error %p %x %x %d %d %llu\n", cdb, result, cmd, ret, length, (unsigned long long)offset); } return result; }
int qgrep_main(int argc, char **argv) { int i; char *p; bool do_eclass; bool do_installed; DIR *eclass_dir = NULL; struct dirent *dentry = NULL; int reflags = 0; unsigned long int context_optarg; char status = 1; size_t n; char *overlay; struct qgrep_grepargs args = { .do_count = 0, .do_regex = 0, .do_list = 0, .show_filename = 0, .show_name = 0, .skip_comments = 0, .invert_list = 0, .invert_match = 0, .skip_pattern = NULL, .num_lines_before = 0, .num_lines_after = 0, .buf_list = NULL, .query = NULL, .strfunc = strstr, .include_atoms = NULL, .portdir = NULL, }; do_eclass = do_installed = 0; while ((i = GETOPT_LONG(QGREP, qgrep, "")) != -1) { switch (i) { case 'I': args.invert_match = true; break; case 'i': args.strfunc = strcasestr; reflags |= REG_ICASE; break; case 'c': args.do_count = true; break; case 'l': args.do_list = true; break; case 'L': args.do_list = args.invert_list = true; break; case 'e': args.do_regex = true; break; case 'x': args.do_regex = true; reflags |= REG_EXTENDED; break; case 'J': do_installed = true; break; case 'E': do_eclass = true; break; case 'H': args.show_filename = true; break; case 'N': args.show_name = true; break; case 's': args.skip_comments = true; break; case 'R': args.show_repo = args.show_name = true; break; case 'S': args.skip_pattern = optarg; break; case 'B': case 'A': errno = 0; context_optarg = strtol(optarg, &p, 10); if (errno != 0) errp("%s: not a valid integer", optarg); else if (p == optarg || *p != '\0') err("%s: not a valid integer", optarg); if (context_optarg > 254) err("%s: silly value!", optarg); if (i == 'B') args.num_lines_before = context_optarg; else args.num_lines_after = context_optarg; break; COMMON_GETOPTS_CASES(qgrep) } } if (argc == optind) qgrep_usage(EXIT_FAILURE); if (args.do_list && args.do_count) { warn("%s and --count are incompatible options. The former wins.", (args.invert_list ? "--invert-list" : "--list")); args.do_count = false; } if (args.show_name && args.show_filename) { warn("--with-name and --with-filename are incompatible options. " "The former wins."); args.show_filename = false; } if (args.do_list && args.num_lines_before) { warn("%s and --before are incompatible options. The former wins.", (args.invert_list ? "--invert-list" : "--list")); args.num_lines_before = 0; } if (args.do_list && args.num_lines_after) { warn("%s and --after are incompatible options. The former wins.", (args.invert_list ? "--invert-list" : "--list")); args.num_lines_after = 0; } if (args.do_count && args.num_lines_before) { warn("--count and --before are incompatible options. The former wins."); args.num_lines_before = 0; } if (args.do_count && args.num_lines_after) { warn("--count and --after are incompatible options. The former wins."); args.num_lines_after = 0; } if (do_installed && do_eclass) { warn("--installed and --eclass are incompatible options. " "The former wins."); do_eclass = false; } if (argc > (optind + 1)) { depend_atom **d = args.include_atoms = xcalloc(sizeof(depend_atom *), (argc - optind - 1) + 1); for (i = (optind + 1); i < argc; i++) { *d = atom_explode(argv[i]); if (*d == NULL) { warn("%s: invalid atom, will be ignored", argv[i]); } else { d++; } } *d = NULL; } /* make it easier to see what needs to be printed */ if (!args.show_name && (verbose || args.do_list)) args.show_filename = true; /* pre-compile regexps once for all */ if (args.do_regex) { if (args.invert_match || *RED == '\0') reflags |= REG_NOSUB; xregcomp(&args.preg, argv[optind], reflags); reflags |= REG_NOSUB; if (args.skip_pattern) xregcomp(&args.skip_preg, args.skip_pattern, reflags); } args.query = argv[optind]; /* allocate a circular buffers list for --before */ args.buf_list = qgrep_buf_list_alloc(args.num_lines_before + 1); array_for_each(overlays, n, overlay) { args.portdir = overlay; if (do_eclass) { char buf[_Q_PATH_MAX]; char name[_Q_PATH_MAX]; char *label; int efd; snprintf(buf, sizeof(buf), "%s/%s/eclass", portroot, overlay); efd = open(buf, O_RDONLY|O_CLOEXEC); if (efd == -1 || (eclass_dir = fdopendir(efd)) == NULL) { if (errno != ENOENT) warnp("opendir(\"%s/eclass\") failed", overlay); continue; } while ((dentry = readdir(eclass_dir)) != NULL) { if (strstr(dentry->d_name, ".eclass") == NULL) continue; /* filter the files we grep when there are extra args */ if (args.include_atoms != NULL) { depend_atom **d; for (d = args.include_atoms; *d != NULL; d++) { if ((*d)->PN != NULL && strncmp(dentry->d_name, (*d)->PN, strlen((*d)->PN)) == 0) break; } if (*d == NULL) continue; } label = NULL; if (args.show_name) { snprintf(name, sizeof(name), "%s%.*s%s", BLUE, (int)(strlen(dentry->d_name) - 7), dentry->d_name, NORM); label = name; } else if (args.show_filename) { snprintf(name, sizeof(name), "eclass/%s", dentry->d_name); label = name; } status = qgrep_grepat(efd, dentry->d_name, label, &args); } closedir(eclass_dir); } else if (do_installed) { status = q_vdb_foreach_pkg(portroot, portvdb, qgrep_vdb_cb, &args, NULL); } else { /* do_ebuild */ status = cache_foreach_pkg(portroot, overlay, qgrep_cache_cb, &args, NULL); } } if (args.do_regex) regfree(&args.preg); if (args.do_regex && args.skip_pattern) regfree(&args.skip_preg); if (args.include_atoms != NULL) { for (i = 0; i < (argc - optind - 1); i++) if (args.include_atoms[i] != NULL) atom_implode(args.include_atoms[i]); free(args.include_atoms); } qgrep_buf_list_free(args.buf_list); return status; }