static fqd_queue_impl_data queue_jlog_setup(fq_rk *qname, uint32_t *count) { char qpath[PATH_MAX]; jlog_id chkpt; struct queue_jlog *d; d = calloc(1, sizeof(*d)); d->auto_chkpt = true; fqd_config_construct_queue_path(qpath, sizeof(qpath), qname); d->qpath = strdup(qpath); d->writer = jlog_new(d->qpath); if(jlog_ctx_open_writer(d->writer) != 0) { jlog_ctx_close(d->writer); d->writer = jlog_new(d->qpath); if(jlog_ctx_init(d->writer) != 0) { fq_debug(FQ_DEBUG_IO, "jlog init: %s\n", jlog_ctx_err_string(d->writer)); goto bail; } jlog_ctx_close(d->writer); d->writer = jlog_new(d->qpath); if(jlog_ctx_open_writer(d->writer) != 0) { fq_debug(FQ_DEBUG_IO, "jlog writer: %s\n", jlog_ctx_err_string(d->writer)); goto bail; } } d->reader = jlog_new(d->qpath); if(jlog_get_checkpoint(d->reader, "fq", &chkpt) != 0) { if(jlog_ctx_add_subscriber(d->reader, "fq", JLOG_BEGIN) != 0) { fq_debug(FQ_DEBUG_IO, "jlog add sub: %s\n", jlog_ctx_err_string(d->reader)); goto bail; } } if(jlog_ctx_open_reader(d->reader, "fq") != 0) { fq_debug(FQ_DEBUG_IO, "jlog: %s\n", jlog_ctx_err_string(d->reader)); goto bail; } uuid_generate(d->uuid); write_sig(d); *count = 0; (void)qname; return d; bail: if(d->writer) jlog_ctx_close(d->writer); if(d->reader) jlog_ctx_close(d->reader); free(d->qpath); free(d); return NULL; }
static void segv_handler(int sig) { static int crashing = 0; void* array[64]; size_t size; // So we don't recurse! if(crashing) exit(101); crashing = 1; int fd = STDERR_FILENO; char* pause_env = getenv("RBX_PAUSE_ON_CRASH"); if(pause_env) { long timeout = strtol(pause_env, NULL, 10); if(timeout <= 0) { timeout = 60; } else { timeout *= 60; } std::cerr << "\n========== CRASH (" << getpid(); std::cerr << "), pausing for " << timeout << " seconds to attach debugger\n"; sleep(timeout); } // If there is a report_path setup.. if(report_path[0]) { fd = open(report_path, O_WRONLY | O_CREAT | O_TRUNC, 0666); // If we can't open this path, use stderr. if(fd == -1) fd = STDERR_FILENO; } // print out all the frames to stderr static const char header[] = "Rubinius Crash Report #rbxcrashreport\n\n" "Error: signal "; safe_write(fd, header, sizeof(header)); write_sig(fd, sig); safe_write(fd, "\n\n[[Backtrace]]\n"); // get void*'s for all entries on the stack size = backtrace(array, 64); backtrace_symbols_fd(array, size, fd); // Try to get the output to flush... safe_write(fd, "\n[[System Info]]\n"); safe_write(fd, "sysname: "); safe_write(fd, machine_info.sysname); safe_write(fd, "\n"); safe_write(fd, "nodename: "); safe_write(fd, machine_info.nodename); safe_write(fd, "\n"); safe_write(fd, "release: "); safe_write(fd, machine_info.release); safe_write(fd, "\n"); safe_write(fd, "version: "); safe_write(fd, machine_info.version); safe_write(fd, "\n"); safe_write(fd, "machine: "); safe_write(fd, machine_info.machine); safe_write(fd, "\n"); // If we didn't write to stderr, then close the file down and // write info to stderr about reporting the error. if(fd != STDERR_FILENO) { close(fd); safe_write(STDERR_FILENO, "\n---------------------------------------------\n"); safe_write(STDERR_FILENO, "CRASH: A fatal error has occurred.\n\nBacktrace:\n"); backtrace_symbols_fd(array, size, 2); safe_write(STDERR_FILENO, "\n\n"); safe_write(STDERR_FILENO, "Wrote full error report to: "); safe_write(STDERR_FILENO, report_path); safe_write(STDERR_FILENO, "\nRun 'rbx report' to submit this crash report!\n"); } exit(100); }
static void segv_handler(int sig) { static int crashing = 0; void* array[64]; size_t size; // So we don't recurse! if(crashing) exit(101); crashing = 1; int fd = 2; // If there is a report_path setup.. if(report_path[0]) { fd = open(report_path, O_WRONLY | O_CREAT | O_TRUNC, 0666); // If we can't open this path, use stderr. if(fd == -1) fd = 2; } // print out all the frames to stderr static const char header[] = "Rubinius Crash Report #rbxcrashreport\n\n" "Error: signal "; safe_write(fd, header, sizeof(header)); write_sig(fd, sig); safe_write(fd, "\n\n[[Backtrace]]\n"); // get void*'s for all entries on the stack size = backtrace(array, 64); backtrace_symbols_fd(array, size, fd); // Try to get the output to flush... safe_write(fd, "\n[[System Info]]\n"); safe_write(fd, "sysname: "); safe_write(fd, machine_info.sysname); safe_write(fd, "\n"); safe_write(fd, "nodename: "); safe_write(fd, machine_info.nodename); safe_write(fd, "\n"); safe_write(fd, "release: "); safe_write(fd, machine_info.release); safe_write(fd, "\n"); safe_write(fd, "version: "); safe_write(fd, machine_info.version); safe_write(fd, "\n"); safe_write(fd, "machine: "); safe_write(fd, machine_info.machine); safe_write(fd, "\n"); // If we didn't write to stderr, then close the file down and // write info to stderr about reporting the error. if(fd != 2) { close(fd); safe_write(2, "\n---------------------------------------------\n"); safe_write(2, "CRASH: A fatal error has occured.\n\nBacktrace:\n"); backtrace_symbols_fd(array, size, 2); safe_write(2, "\n\n"); safe_write(2, "Wrote full error report to: "); safe_write(2, report_path); safe_write(2, "\nRun 'rbx report' to submit this crash report!\n"); } exit(100); }
/* * returns -1 when the incoming checkpoint is out of range of the log * returns -2 if there was an error actually setting the checkpoint */ static int queue_log_add_checkpoint(fqd_queue_impl_data data, const char *name, const fq_msgid *id) { struct queue_jlog *d = (struct queue_jlog *)data; jlog_id jid = { .log = id->id.u32.p1, .marker = id->id.u32.p2 }; /* ensure the checkpoint makes sense */ jlog_id first = { .log = 0, .marker = 0 }; jlog_id last = { .log = 0, .marker = 0 }; jlog_ctx_first_log_id(d->reader, &first); jlog_ctx_last_log_id(d->reader, &last); if (! (jid.log >= first.log && jid.log <= last.log && jid.marker >= first.marker && jid.marker <= last.marker)) { return -1; } char **subs; int sub_count = jlog_ctx_list_subscribers(d->reader, &subs); int have_it = 0; for (int i = 0; i < sub_count; i++) { have_it += strcmp(subs[i], name) == 0 ? 1 : 0; } if (have_it == 0) { jlog_ctx_add_subscriber(d->reader, name, JLOG_BEGIN); } if (jlog_ctx_read_checkpoint(d->reader, &jid) == -1) { /* If we failed to checkpoint we are in a situation where the 'add_subscriber' call above put them at the beginning of the log so we have to remove the subscriber if we just added them However, if they already existed and had a previous good checkpoint, leave it alone */ if (have_it == 0) { jlog_ctx_remove_subscriber(d->reader, name); } return -2; } return 0; } /* * return -1 if the subscriber doesn't exist * return 0 on success */ static int queue_log_remove_checkpoint(fqd_queue_impl_data data, const char *name) { struct queue_jlog *d = (struct queue_jlog *)data; if (jlog_ctx_remove_subscriber(d->reader, name) == 0) { return -1; } return 0; } /* * return -1 if the subscriber doesn't exist * return -2 if we can't reset the checkpoint * return 0 on success */ static int queue_log_reset_to_checkpoint(fqd_queue_impl_data data, const char *name) { struct queue_jlog *d = (struct queue_jlog *)data; char **subs; int sub_count = jlog_ctx_list_subscribers(d->reader, &subs); int have_it = 0; for (int i = 0; i < sub_count; i++) { have_it += strcmp(subs[i], name) == 0 ? 1 : 0; } if (have_it == 0) { return -1; } jlog_id checkpoint; if (jlog_get_checkpoint(d->reader, name, &checkpoint) == -1) { return -2; } if (jlog_ctx_read_checkpoint(d->reader, &checkpoint) == -1) { return -2; } return 0; } static int write_sig(struct queue_jlog *d) { char sigfile[PATH_MAX]; int fd; snprintf(sigfile, sizeof(sigfile), "%s/.sig", d->qpath); fd = open(sigfile, O_CREAT|O_TRUNC|O_WRONLY, 0640); if(fd < 0) return -1; write(fd, d->uuid, 16); close(fd); return 0; } static int read_sig(struct queue_jlog *d, uuid_t out) { char sigfile[PATH_MAX]; int fd, rv; snprintf(sigfile, sizeof(sigfile), "%s/.sig", d->qpath); fd = open(sigfile, O_RDONLY); if(fd < 0) return -1; rv = read(fd, out, 16); close(fd); return (rv == 16) ? 0 : -1; } static fqd_queue_impl_data queue_jlog_setup(fq_rk *qname, uint32_t *count) { char qpath[PATH_MAX]; jlog_id chkpt; struct queue_jlog *d; d = calloc(1, sizeof(*d)); d->auto_chkpt = true; fqd_config_construct_queue_path(qpath, sizeof(qpath), qname); d->qpath = strdup(qpath); d->writer = jlog_new(d->qpath); jlog_ctx_set_pre_commit_buffer_size(d->writer, 1024 * 1024); jlog_ctx_set_multi_process(d->writer, 0); jlog_ctx_set_use_compression(d->writer, 1); if(jlog_ctx_open_writer(d->writer) != 0) { jlog_ctx_close(d->writer); d->writer = jlog_new(d->qpath); jlog_ctx_set_pre_commit_buffer_size(d->writer, 1024 * 1024); jlog_ctx_set_multi_process(d->writer, 0); jlog_ctx_set_use_compression(d->writer, 1); if(jlog_ctx_init(d->writer) != 0) { fq_debug(FQ_DEBUG_IO, "jlog init: %s\n", jlog_ctx_err_string(d->writer)); goto bail; } jlog_ctx_close(d->writer); d->writer = jlog_new(d->qpath); jlog_ctx_set_pre_commit_buffer_size(d->writer, 1024 * 1024); jlog_ctx_set_multi_process(d->writer, 0); jlog_ctx_set_use_compression(d->writer, 1); if(jlog_ctx_open_writer(d->writer) != 0) { fq_debug(FQ_DEBUG_IO, "jlog writer: %s\n", jlog_ctx_err_string(d->writer)); goto bail; } } /* 128MB journal chunks */ jlog_ctx_alter_journal_size(d->writer, 128 * 1024 * 1024); d->reader = jlog_new(d->qpath); if(jlog_get_checkpoint(d->reader, "fq", &chkpt) != 0) { if(jlog_ctx_add_subscriber(d->reader, "fq", JLOG_BEGIN) != 0) { fq_debug(FQ_DEBUG_IO, "jlog add sub: %s\n", jlog_ctx_err_string(d->reader)); goto bail; } } if(jlog_ctx_open_reader(d->reader, "fq") != 0) { fq_debug(FQ_DEBUG_IO, "jlog: %s\n", jlog_ctx_err_string(d->reader)); goto bail; } uuid_generate(d->uuid); write_sig(d); *count = d->count = jlog_ctx_read_interval(d->reader, &d->start, &d->finish); (void)qname; return d; bail: if(d->writer) jlog_ctx_close(d->writer); if(d->reader) jlog_ctx_close(d->reader); free(d->qpath); free(d); return NULL; }
/* * Create an EE or CA certificate using the * table to set the fields. The table is build * using command line arguments */ int create_cert( struct object_field *table) { int ret = 0; int i; struct Certificate cert; Certificate(&cert, (ushort) 0); // constructor for the cert struct char *keyfile = NULL, *val; int val_type; eecert = 0; // is it a ca or ee cert if ((ret = setEEorCA(table)) != SUCCESS) return ret; setSelfSigned(table); // Read the certificate template into the certificate if (!templateFile) { if (eecert) templateFile = CONFIG_TEMPLATE_EE_CERT_get(); else templateFile = CONFIG_TEMPLATE_CA_CERT_get(); } ret = get_casn_file(&cert.self, (char *)templateFile, 0); if (ret < 0) { warn(FILE_OPEN_ERR, (char *)templateFile); return (FILE_OPEN_ERR); } // clear out fields in the template (only keeping a few); clear_cert(&cert); // fill in the default fields write_default_fields(&cert); // Populate the certificate fields with data from the // table. Note the table is populated from input arguments // If there is no function to call and the argument is optional then // it is ok otherwise it is an error. for (i = 0; table[i].name != NULL; i++) { if (table[i].func != NULL) { if (table[i].value != NULL) { if (table[i].func(&cert.self, table[i].value) < 0) { fprintf(stderr, "Error writing %s into field %s\n", table[i].value, table[i].name); } } else { if (table[i].required) fprintf(stderr, "Missing value for %s\n", table[i].name); } } } // if signature value is set in the table, write that value as the // signature, // otherwise sign it if (get_table_value("signatureValue", table, &val, &val_type) != 0) { fprintf(stdout, "Error writing signature"); return (-1); } if (val != NULL) // input signature { if (write_sig(&cert, val) != SUCCESS) { fprintf(stdout, "Error writing signature"); return (-1); } } else { // have to sign it, get key from subject // keyfile if selfsigned else parents if (selfSigned) get_table_value("subjkeyfile", table, &keyfile, &val_type); else get_table_value("parentkeyfile", table, &keyfile, &val_type); if (keyfile == NULL || (sign_cert(&cert, keyfile) != SUCCESS)) return -1; } // write out the certificate using the ouput filename if (get_table_value("outputfilename", table, &val, &val_type) < 0) { warn(FILE_WRITE_ERR, "outputfilename missing"); return (FILE_WRITE_ERR); } if (put_casn_file(&cert.self, val, 0) < 0) { warn(FILE_WRITE_ERR, val); return (FILE_WRITE_ERR); } else warn(SUCCESS, val); return (SUCCESS); }