📄 obd.c
字号:
strerror(errno)); return; } /* Attatch to new segment */ shared_data = (struct shared_data *)shmat(shmid, NULL, 0); if (shared_data == (struct shared_data *)(-1)) { fprintf(stderr, "Can't attach shared data: %s\n", strerror(errno)); shared_data = NULL; return; } /* Mark segment as destroyed, so it will disappear when we exit. * Forks will inherit attached segments, so we should be OK. */ if (shmctl(shmid, IPC_RMID, NULL) == -1) { fprintf(stderr, "Can't destroy shared data: %s\n", strerror(errno)); }}static inline void shmem_lock(void){ l_mutex_lock(&shared_data->mutex);}static inline void shmem_unlock(void){ l_mutex_unlock(&shared_data->mutex);}static inline void shmem_reset(int total_threads){ if (shared_data == NULL) return; memset(shared_data, 0, sizeof(*shared_data)); l_mutex_init(&shared_data->mutex); l_cond_init(&shared_data->cond); memset(counter_snapshot, 0, sizeof(counter_snapshot)); prev_valid = 0; shared_data->barrier = total_threads;}static inline void shmem_bump(void){ static int bumped_running; if (shared_data == NULL || thread <= 0 || thread > MAX_THREADS) return; shmem_lock(); shared_data->counters[thread - 1]++; if (!bumped_running) shared_data->running++; shmem_unlock(); bumped_running = 1;}static void shmem_snap(int total_threads, int live_threads){ struct timeval this_time; int non_zero = 0; __u64 total = 0; double secs; int running; int i; if (shared_data == NULL || total_threads > MAX_THREADS) return; shmem_lock(); memcpy(counter_snapshot[0], shared_data->counters, total_threads * sizeof(counter_snapshot[0][0])); running = shared_data->running; shmem_unlock(); gettimeofday(&this_time, NULL); for (i = 0; i < total_threads; i++) { long long this_count = counter_snapshot[0][i] - counter_snapshot[1][i]; if (this_count != 0) { non_zero++; total += this_count; } } secs = (this_time.tv_sec + this_time.tv_usec / 1000000.0) - (prev_time.tv_sec + prev_time.tv_usec / 1000000.0); if (prev_valid && live_threads == total_threads && secs > 0.0) /* someone screwed with the time? */ printf("%d/%d Total: %f/second\n", non_zero, total_threads, total / secs); memcpy(counter_snapshot[1], counter_snapshot[0], total_threads * sizeof(counter_snapshot[0][0])); prev_time = this_time; if (!prev_valid && running == total_threads) prev_valid = 1;}static void shmem_stop(void){ if (shared_data == NULL) return; shared_data->stop = 1;}static int shmem_running(void){ return (shared_data == NULL || !shared_data->stop);}#elsestatic void shmem_setup(void){}static inline void shmem_reset(int total_threads){}static inline void shmem_bump(void){}static void shmem_lock(){}static void shmem_unlock(){}static void shmem_stop(void){}static int shmem_running(void){ return 1;}#endifextern command_t cmdlist[];static int do_device(char *func, char *devname){ int dev; dev = parse_devname(func, devname); if (dev < 0) return -1; lcfg_set_devname(devname); cur_device = dev; return 0;}int jt_obd_get_device(){ return cur_device;}int jt_obd_device(int argc, char **argv){ int rc; if (argc > 2) return CMD_HELP; if (argc == 1) { printf("current device is %d - %s\n", cur_device, lcfg_get_devname() ? : "not set"); return 0; } rc = do_device("device", argv[1]); return rc;}int jt_opt_device(int argc, char **argv){ int ret; int rc; if (argc < 3) return CMD_HELP; rc = do_device("device", argv[1]); if (!rc) rc = Parser_execarg(argc - 2, argv + 2, cmdlist); ret = do_disconnect(argv[0], 0); if (!rc) rc = ret; return rc;}#ifdef MAX_THREADSstatic void parent_sighandler (int sig){ return;}int jt_opt_threads(int argc, char **argv){ static char cmdstr[128]; sigset_t saveset; sigset_t sigset; struct sigaction sigact; struct sigaction saveact1; struct sigaction saveact2; unsigned long threads; __u64 next_thread; int verbose; int rc = 0; int report_count = -1; char *end; int i; if (argc < 5) return CMD_HELP; threads = strtoul(argv[1], &end, 0); if (*end == '.') report_count = strtoul(end + 1, &end, 0); if (*end || threads > MAX_THREADS) { fprintf(stderr, "error: %s: invalid thread count '%s'\n", jt_cmdname(argv[0]), argv[1]); return CMD_HELP; } verbose = get_verbose(argv[0], argv[2]); if (verbose == BAD_VERBOSE) return CMD_HELP; if (verbose != 0) { snprintf(cmdstr, sizeof(cmdstr), "%s", argv[4]); for (i = 5; i < argc; i++) snprintf(cmdstr + strlen(cmdstr), sizeof(cmdstr), " %s", argv[i]); printf("%s: starting %ld threads on device %s running %s\n", argv[0], threads, argv[3], cmdstr); } shmem_reset(threads); sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, &saveset); nthreads = threads; for (i = 1, next_thread = verbose; i <= threads; i++) { rc = fork(); if (rc < 0) { fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i, strerror(rc = errno)); break; } else if (rc == 0) { sigprocmask(SIG_SETMASK, &saveset, NULL); thread = i; argv[2] = "--device"; return jt_opt_device(argc - 2, argv + 2); } else if (be_verbose(verbose, NULL, i, &next_thread, threads)) printf("%s: thread #%d (PID %d) started\n", argv[0], i, rc); rc = 0; } if (!thread) { /* parent process */ int live_threads = threads; sigemptyset(&sigset); sigemptyset(&sigact.sa_mask); sigact.sa_handler = parent_sighandler; sigact.sa_flags = 0; sigaction(SIGALRM, &sigact, &saveact1); sigaction(SIGCHLD, &sigact, &saveact2); while (live_threads > 0) { int status; pid_t ret; if (verbose < 0) /* periodic stats */ alarm(-verbose); sigsuspend(&sigset); alarm(0); while (live_threads > 0) { ret = waitpid(0, &status, WNOHANG); if (ret == 0) break; if (ret < 0) { fprintf(stderr, "error: %s: wait - %s\n", argv[0], strerror(errno)); if (!rc) rc = errno; continue; } else { /* * This is a hack. We _should_ be able * to use WIFEXITED(status) to see if * there was an error, but it appears * to be broken and it always returns 1 * (OK). See wait(2). */ int err = WEXITSTATUS(status); if (err || WIFSIGNALED(status)) fprintf(stderr, "%s: PID %d had rc=%d\n", argv[0], ret, err); if (!rc) rc = err; live_threads--; } } /* Show stats while all threads running */ if (verbose < 0) { shmem_snap(threads, live_threads); if (report_count > 0 && --report_count == 0) shmem_stop(); } } sigaction(SIGCHLD, &saveact2, NULL); sigaction(SIGALRM, &saveact1, NULL); } sigprocmask(SIG_SETMASK, &saveset, NULL); return rc;}#elseint jt_opt_threads(int argc, char **argv){ fprintf(stderr, "%s not-supported in a single-threaded runtime\n", jt_cmdname(argv[0])); return CMD_HELP;}#endifint jt_opt_net(int argc, char **argv){ char *arg2[3]; int rc; if (argc < 3) return CMD_HELP; arg2[0] = argv[0]; arg2[1] = argv[1]; arg2[2] = NULL; rc = jt_ptl_network (2, arg2); if (!rc) rc = Parser_execarg(argc - 2, argv + 2, cmdlist); return rc;}int jt_obd_no_transno(int argc, char **argv){ struct obd_ioctl_data data; int rc; IOC_INIT(data); if (argc != 1) return CMD_HELP; IOC_PACK(argv[0], data); rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_NO_TRANSNO, buf); if (rc < 0) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); return rc;}int jt_obd_set_readonly(int argc, char **argv){ struct obd_ioctl_data data; int rc; IOC_INIT(data); if (argc != 1) return CMD_HELP; IOC_PACK(argv[0], data); rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_SET_READONLY, buf); if (rc < 0) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); return rc;}int jt_obd_abort_recovery(int argc, char **argv){ struct obd_ioctl_data data; int rc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -