int main(int argc, char **argv) { int err; int has_set_log_format = 0; int is_clear_log = 0; int getLogSize = 0; int mode = O_RDONLY; int i; // const char *forceFilters = NULL; struct log_device_t* devices = NULL; struct log_device_t* dev; g_logformat = (log_format *)log_format_new(); if (argc == 2 && 0 == strcmp(argv[1], "--test")) { logprint_run_tests(); exit(0); } if (argc == 2 && 0 == strcmp(argv[1], "--help")) { show_help(argv[0]); exit(0); } for (;;) { int ret; ret = getopt(argc, argv, "cdt:gsf:r:n:v:b:D"); if (ret < 0) { break; } switch(ret) { case 's': // default to all silent log_add_filter_rule(g_logformat, "*:s"); break; case 'c': is_clear_log = 1; mode = O_WRONLY; break; case 'd': g_nonblock = true; break; case 't': g_nonblock = true; g_tail_lines = atoi(optarg); break; case 'g': getLogSize = 1; break; case 'b': { char* buf = (char*) malloc(strlen(LOG_FILE_DIR) + strlen(optarg) + 1); if (buf == NULL) { fprintf(stderr,"Can't malloc LOG_FILE_DIR\n"); exit(-1); } strcpy(buf, LOG_FILE_DIR); strcat(buf, optarg); // snprintf(buf, strlen(LOG_FILE_DIR) + strlen(optarg) + 1, "%s%s", LOG_FILE_DIR, optarg); if (devices) { dev = devices; while (dev->next) { dev = dev->next; } dev->next = (struct log_device_t *)malloc( sizeof(struct log_device_t)); if (dev->next == NULL) { fprintf(stderr,"Can't malloc log_device\n"); exit(-1); } dev->next->device = buf; dev->next->fd = -1; dev->next->printed = false; dev->next->queue = NULL; dev->next->next = NULL; } else { devices = (struct log_device_t *)malloc( sizeof(struct log_device_t)); if (devices == NULL) { fprintf(stderr,"Can't malloc log_device\n"); exit(-1); } devices->device = buf; devices->fd = -1; devices->printed = false; devices->queue = NULL; devices->next = NULL; } g_dev_count++; } break; case 'f': // redirect output to a file g_output_filename = optarg; break; case 'r': // if (optarg == NULL) { // fprintf(stderr,"optarg == null\n"); // g_log_rotate_size_kbytes = DEFAULT_LOG_ROTATE_SIZE_KBYTES; // } else { //long logRotateSize; //char *lastDigit; if (!isdigit(optarg[0])) { fprintf(stderr,"Invalid parameter to -r\n"); show_help(argv[0]); exit(-1); } g_log_rotate_size_kbytes = atoi(optarg); // } break; case 'n': if (!isdigit(optarg[0])) { fprintf(stderr,"Invalid parameter to -r\n"); show_help(argv[0]); exit(-1); } g_max_rotated_logs = atoi(optarg); break; case 'v': err = set_log_format (optarg); if (err < 0) { fprintf(stderr,"Invalid parameter to -v\n"); show_help(argv[0]); exit(-1); } has_set_log_format = 1; break; default: fprintf(stderr,"Unrecognized Option\n"); show_help(argv[0]); exit(-1); break; } } if (!devices) { devices = (struct log_device_t *)malloc( sizeof(struct log_device_t)); if (devices == NULL) { fprintf(stderr,"Can't malloc log_device\n"); exit(-1); } devices->device = strdup("/dev/"LOGGER_LOG_MAIN); devices->fd = -1; devices->printed = false; devices->queue = NULL; devices->next = NULL; g_dev_count = 1; int accessmode = (mode & O_RDONLY) ? R_OK : 0 | (mode & O_WRONLY) ? W_OK : 0; // only add this if it's available if (0 == access("/dev/"LOGGER_LOG_SYSTEM, accessmode)) { devices->next = (struct log_device_t *)malloc( sizeof(struct log_device_t)); if (devices->next == NULL) { fprintf(stderr,"Can't malloc log_device\n"); exit(-1); } devices->next->device = strdup("/dev/"LOGGER_LOG_SYSTEM); devices->next->fd = -1; devices->next->printed = false; devices->next->queue = NULL; devices->next->next = NULL; g_dev_count ++; } if (0 == access("/dev/"LOGGER_LOG_APPS, accessmode)) { devices->next = (struct log_device_t *)malloc( sizeof(struct log_device_t)); if (devices->next == NULL) { fprintf(stderr,"Can't malloc log_device\n"); exit(-1); } devices->next->device = strdup("/dev/"LOGGER_LOG_APPS); devices->next->fd = -1; devices->next->printed = false; devices->next->queue = NULL; devices->next->next = NULL; g_dev_count ++; } /* // only add this if it's available int fd; if ((fd = open("/dev/"LOGGER_LOG_SYSTEM, mode)) != -1) { devices->next = (struct log_device_t *)malloc( sizeof(struct log_device_t)); devices->next->device = strdup("/dev/"LOGGER_LOG_SYSTEM); devices->next->fd = -1; devices->next->printed = false; devices->next->queue = NULL; devices->next->next = NULL; g_dev_count ++; close(fd); } */ } if (g_log_rotate_size_kbytes != 0 && g_output_filename == NULL) { fprintf(stderr,"-r requires -f as well\n"); show_help(argv[0]); exit(-1); } setup_output(); if (has_set_log_format == 0) { err = set_log_format("brief"); } /* const char* logFormat = getenv("DLOG_PRINTF_LOG"); if (logFormat != NULL) { err = set_log_format("brief"); if (err < 0) { fprintf(stderr, "invalid format in DLOG_PRINTF_LOG '%s'\n", logFormat); } } } if (forceFilters) { err = log_add_filter_string(g_logformat, forceFilters); if (err < 0) { fprintf (stderr, "Invalid filter expression in -logcat option\n"); exit(0); } } else if (argc == optind) { // Add from environment variable char *env_tags_orig = getenv("DLOG_LOG_TAGS"); if (env_tags_orig != NULL) { err = log_add_filter_string(g_logformat, env_tags_orig); if (err < 0) { fprintf(stderr, "Invalid filter expression in DLOG_LOG_TAGS\n"); show_help(argv[0]); exit(-1); } } } else { // Add from commandline */ fprintf(stderr,"arc = %d, optind = %d ,Kb %d, rotate %d\n", argc, optind,g_log_rotate_size_kbytes,g_max_rotated_logs); if(argc == optind ) { // Add from environment variable //char *env_tags_orig = getenv("DLOG_TAGS"); log_add_filter_string(g_logformat, "*:d"); } else { for (i = optind ; i < argc ; i++) { err = log_add_filter_string(g_logformat, argv[i]); if (err < 0) { fprintf (stderr, "Invalid filter expression '%s'\n", argv[i]); show_help(argv[0]); exit(-1); } } } /* } */ dev = devices; while (dev) { dev->fd = open(dev->device, mode); if (dev->fd < 0) { fprintf(stderr, "Unable to open log device '%s': %s\n", dev->device, strerror(errno)); exit(EXIT_FAILURE); } if (is_clear_log) { int ret; ret = clear_log(dev->fd); if (ret) { perror("ioctl"); exit(EXIT_FAILURE); } } if (getLogSize) { int size, readable; size = get_log_size(dev->fd); if (size < 0) { perror("ioctl"); exit(EXIT_FAILURE); } readable = get_log_readable_size(dev->fd); if (readable < 0) { perror("ioctl"); exit(EXIT_FAILURE); } printf("%s: ring buffer is %dKb (%dKb consumed), " "max entry is %db, max payload is %db\n", dev->device, size / 1024, readable / 1024, (int) LOGGER_ENTRY_MAX_LEN, (int) LOGGER_ENTRY_MAX_PAYLOAD); } dev = dev->next; } if (getLogSize) { return 0; } if (is_clear_log) { return 0; } read_log_lines(devices); return 0; }
static void test_migrate(void) { TestServer *s = test_server_new("src"); TestServer *dest = test_server_new("dest"); char *uri = g_strdup_printf("%s%s", "unix:", dest->mig_path); QTestState *global = global_qtest, *from, *to; GSource *source; gchar *cmd; QDict *rsp; guint8 *log; guint64 size; test_server_listen(s); test_server_listen(dest); cmd = GET_QEMU_CMDE(s, 2, "", ""); from = qtest_start(cmd); g_free(cmd); init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC); wait_for_fds(s); size = get_log_size(s); g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8)); cmd = GET_QEMU_CMDE(dest, 2, "", " -incoming %s", uri); to = qtest_init(cmd); g_free(cmd); source = g_source_new(&test_migrate_source_funcs, sizeof(TestMigrateSource)); ((TestMigrateSource *)source)->src = s; ((TestMigrateSource *)source)->dest = dest; g_source_attach(source, NULL); /* slow down migration to have time to fiddle with log */ /* TODO: qtest could learn to break on some places */ rsp = qmp("{ 'execute': 'migrate_set_speed'," "'arguments': { 'value': 10 } }"); g_assert(qdict_haskey(rsp, "return")); QDECREF(rsp); cmd = g_strdup_printf("{ 'execute': 'migrate'," "'arguments': { 'uri': '%s' } }", uri); rsp = qmp(cmd); g_free(cmd); g_assert(qdict_haskey(rsp, "return")); QDECREF(rsp); wait_for_log_fd(s); log = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, s->log_fd, 0); g_assert(log != MAP_FAILED); /* modify first page */ write_guest_mem(s, 0x42); log[0] = 1; munmap(log, size); /* speed things up */ rsp = qmp("{ 'execute': 'migrate_set_speed'," "'arguments': { 'value': 0 } }"); g_assert(qdict_haskey(rsp, "return")); QDECREF(rsp); qmp_eventwait("STOP"); global_qtest = to; qmp_eventwait("RESUME"); read_guest_mem_server(dest); uninit_virtio_dev(s); g_source_destroy(source); g_source_unref(source); qtest_quit(to); test_server_free(dest); qtest_quit(from); test_server_free(s); g_free(uri); global_qtest = global; }