/** * Thread processing network events (coming from other nodes). * * This routine may set the network status to down as a side-effect * of calling network_recv(), and sets said status to up when the * network comes back. * * \param[in] dummy Unused * * \return NULL */ static void net_events_routine(void *dummy) { int dest_mbox; ExamsgMID mid; size_t size; char *msg; int s; exalog_as(EXAMSG_CMSGD_ID); exalog_trace("network events routine started"); while (!quit) { int status = network_status(); bool retry; if (status == -ENETDOWN) { network_waitup(); network_set_status(0); } do { s = network_recv(net_mh, &mid, &msg, &size, &dest_mbox); retry = (s < 0 && network_manageable(s) && s != -ENETDOWN); if (retry) os_sleep(1); } while (retry); /* Succeeded, the network status is ok */ if (s > 0 && status != 0) network_set_status(0); if (s == 0 || s == -ENETDOWN) continue; EXA_ASSERT(s > 0); /* Ping from another node for keepalive */ if (((ExamsgAny *)msg)->type == EXAMSG_PING) { EXA_ASSERT(dest_mbox == EXAMSG_CMSGD_ID); exalog_trace("received an EXAMSG_PING from %u:%s", mid.netid.node, mid.host); continue; } exalog_trace("delivering %" PRIzu " bytes to %d", size, dest_mbox); s = examsgMboxSend(&mid, examsgOwner(net_mh), dest_mbox, msg, size); switch (s) { case -ENXIO: /* The mailbox does not exist (yet). This is not an error: csupd may * not be started yet and we receive an examsg for it. * XXX Doesn't sound too good to me, and we should at least check that * the destination is indeed csupd */ break; case -ENOSPC: mailbox_full(dest_mbox, &mid, (Examsg *)msg); break; default: EXA_ASSERT_VERBOSE(s == size + sizeof(mid), "Error %d delivering message to %d", s, dest_mbox); break; } } }
int main(int argc, char *argv[]) { bool static_init_ok = false; const char *action; int err = 0; self = os_program_name(argv[0]); if (argc <= 1) { usage(); err = 1; goto done; } err = examsg_static_init(EXAMSG_STATIC_GET); if (err != 0) { fprintf(stderr, "examsg_static_init failed: %s (%d)\n", exa_error_msg(-err), err); goto done; } static_init_ok = true; mh = examsgInit(EXAMSG_TEST_ID); if (!mh) { fprintf(stderr, "examsgInit failed\n"); goto done; } err = examsgAddMbox(mh, examsgOwner(mh), 3, EXAMSG_MSG_MAX); if (err != 0) { fprintf(stderr, "examsgAddMbox failed: %s (%d)\n", exa_error_msg(-err), err); goto done; } action = argv[1]; if (strcmp(action, "is_fs_mounted") == 0) { int m; if (argc != 3) { usage(); goto done; } m = fsd_is_fs_mounted(mh, argv[2]); if (m < 0) err = m; } else if (strcmp(action, "is_mountpoint_used") == 0) { int u; if (argc != 3) { usage(); goto done; } u = fsd_is_mountpoint_used(mh, argv[2]); if (u < 0) err = u; } else if (strcmp(action, "prepare_gfs") == 0) { fs_data_t fs; size_t sz; if (argc != 3) { usage(); goto done; } COMPILE_TIME_ASSERT(sizeof("sfs") <= sizeof(fs.fstype)); os_strlcpy(fs.fstype, "sfs", sizeof(fs.fstype)); sz = os_strlcpy(fs.clustered.gfs.lock_protocol, argv[2], sizeof(fs.clustered.gfs.lock_protocol)); if (sz >= sizeof(fs.clustered.gfs.lock_protocol)) { fprintf(stderr, "Invalid lock protocol: '%s' (too long)\n", argv[2]); goto done; } err = fsd_prepare(mh, &fs); } else if (strcmp(action, "mount") == 0) { fs_data_t fs; size_t sz; if (argc != 7) { usage(); goto done; } sz = os_strlcpy(fs.fstype, argv[2], sizeof(fs.fstype)); if (sz >= sizeof(fs.fstype)) { fprintf(stderr, "Invalid fs type: '%s' (too long)\n", argv[2]); goto done; } sz = os_strlcpy(fs.mountpoint, argv[3], sizeof(fs.mountpoint)); if (sz >= sizeof(fs.mountpoint)) { fprintf(stderr, "Invalid mountpoint: '%s' (too long)\n", argv[3]); goto done; } sz = os_strlcpy(fs.devpath, argv[4], sizeof(fs.devpath)); if (sz >= sizeof(fs.devpath)) { fprintf(stderr, "Invalid dev path: '%s' (too long)\n", argv[4]); goto done; } err = fsd_mount(mh, &fs, 1 , 0, argv[5], argv[6]); } else if (strcmp(action, "umount") == 0) { fs_data_t fs; size_t sz; if (argc != 6) { usage(); goto done; } sz = os_strlcpy(fs.mountpoint, argv[2], sizeof(fs.mountpoint)); if (sz >= sizeof(fs.mountpoint)) { fprintf(stderr, "Invalid mountpoint: '%s' (too long)\n", argv[2]); goto done; } sz = os_strlcpy(fs.devpath, argv[3], sizeof(fs.devpath)); if (sz >= sizeof(fs.devpath)) { fprintf(stderr, "Invalid dev path: '%s' (too long)\n", argv[3]); goto done; } err = fsd_umount(mh, &fs, argv[5], argv[6]); } else if (strcmp(action, "unload") == 0) { fs_data_t fs; size_t sz; if (argc != 3) { usage(); goto done; } sz = os_strlcpy(fs.fstype, argv[2], sizeof(fs.fstype)); if (sz >= sizeof(fs.fstype)) { fprintf(stderr, "Invalid fs type: '%s' (too long)\n", argv[2]); goto done; } err = fsd_unload(mh, &fs); } else if (strcmp(action, "create_local") == 0) { if (argc != 4) { usage(); goto done; } err = fsd_fs_create_local(mh, argv[2], argv[3]); } else if (strcmp(action, "create_gfs") == 0) { fs_data_t fs; size_t sz; if (argc != 7) { usage(); goto done; } COMPILE_TIME_ASSERT(sizeof("sfs") <= sizeof(fs.fstype)) sz = os_strlcpy(fs.fstype, "sfs", sizeof(fs.fstype)); sz = os_strlcpy(fs.devpath, argv[2], sizeof(fs.devpath)); if (sz >= sizeof(fs.devpath)) { fprintf(stderr, "Invalid dev path: '%s' (too long)\n", argv[2]); goto done; } sz = os_strlcpy(fs.clustered.gfs.lock_protocol, argv[3], sizeof(fs.clustered.gfs.lock_protocol)); if (sz >= sizeof(fs.clustered.gfs.lock_protocol)) { fprintf(stderr, "Invalid lock protocol: '%s' (too long)\n", argv[3]); goto done; } if (to_uint64(argv[4], &fs.sizeKB) != EXA_SUCCESS) { fprintf(stderr, "Invalid size: '%s'\n", argv[4]); goto done; } sz = os_strlcpy(fs.clustered.gfs.uuid, argv[5], sizeof(fs.clustered.gfs.uuid)); if (sz >= sizeof(fs.clustered.gfs.uuid)) { fprintf(stderr, "Invalid GFS uuid: '%s' (too long)\n", argv[5]); goto done; } if (to_uint64(argv[6], &fs.clustered.gfs.nb_logs) != EXA_SUCCESS) { fprintf(stderr, "Invalid number of logs: '%s'\n", argv[6]); goto done; } err = fsd_fs_create_gfs(mh, &fs); } else if (strcmp(action, "dfinfo") == 0) { struct fsd_capa buf; if (argc != 3) { usage(); goto done; } err = fsd_df(mh, argv[2], &buf); if (err == 0) printf("size=%"PRId64" bytes\n" "used=%"PRId64" bytes\n" "free=%"PRId64" bytes\n", buf.size, buf.used, buf.free); } else if (strcmp(action, "resize") == 0) { uint64_t size_kb; if (argc != 6) { usage(); goto done; } if (to_uint64(argv[5], &size_kb) != EXA_SUCCESS) { fprintf(stderr, "Invalid new size: '%s'\n", argv[5]); goto done; } err = fsd_resize(mh, argv[2], argv[3], argv[4], size_kb); } else if (strcmp(action, "prepare_resize") == 0) { if (argc != 4) { usage(); goto done; } err = fsd_prepare_resize(mh, argv[2], argv[3]); } else if (strcmp(action, "read_shm") == 0) { read_shm(); } else if (strcmp(action, "add_logs") == 0) { fs_data_t fs; int num_logs, actual_num_logs; size_t sz; if (argc != 4) { usage(); goto done; } COMPILE_TIME_ASSERT(sizeof("sfs") <= sizeof(fs.fstype)); os_strlcpy(fs.fstype, "sfs", sizeof(fs.fstype)); sz = os_strlcpy(fs.devpath, argv[2], sizeof(fs.devpath)); if (sz >= sizeof(fs.devpath)) { fprintf(stderr, "Invalid dev path: '%s' (too long)\n", argv[2]); goto done; } if (to_int(argv[3], &num_logs) != EXA_SUCCESS) { fprintf(stderr, "Invalid number of logs: '%s'\n", argv[3]); goto done; } actual_num_logs = fsd_set_gfs_logs(mh, &fs, num_logs); if (actual_num_logs < 0) err = actual_num_logs; else { examsgDelMbox(mh, EXAMSG_TEST_ID); printf("Number of logs after the operation: %d\n", actual_num_logs); } } else usage(); if (err != 0) fprintf(stderr, "Action finished with error %d: %s\n", err, exa_error_msg(-err)); done: examsgDelMbox(mh, EXAMSG_TEST_ID); if (mh != NULL) examsgExit(mh); if (static_init_ok) examsg_static_clean(EXAMSG_STATIC_RELEASE); return err == 0 ? 0 : 1; }