/** \brief Initialization of examsgd daemon. * * Command line must contain the node name and the interface name to use * for control messages. * * Accepts hidden option -d (debugging mode). * * \param[in] argc Argument count. * \param[in] argv Array of argument values. * * \return exit code. */ int daemon_init(int argc, char *argv[]) { int s; /* getopt variables */ static struct option long_opts[] = { { "cluster-id", required_argument, NULL, 'c' }, { "help", no_argument, NULL, 'h' }, { "hostname", required_argument, NULL, 'N' }, { "incarnation", required_argument, NULL, 'I' }, { "mcast-addr", required_argument, NULL, 'm' }, { "mcast-port", required_argument, NULL, 'p' }, { "node-id", required_argument, NULL, 'i' }, { "node-name", required_argument, NULL, 'n' }, { "stats", no_argument, NULL, 's' }, { NULL, 0, NULL, 0 } }; int long_idx, c; char *e; extern char *optarg; extern int optind; /* configurable options and default values */ const char *node_name = NULL; const char *hostname = NULL; const char *mgroup = EXAMSG_MCASTIP; unsigned short mport = EXAMSG_PORT; unsigned short inca = 0; exa_uuid_t cluster_uuid; exa_nodeid_t nodeid; bool err = false; uuid_zero(&cluster_uuid); nodeid = EXA_NODEID_NONE; /* options parsing */ while ((c = os_getopt_long(argc, argv, "c:dhi:I:m:n:N:p:s", long_opts, &long_idx)) != -1) switch (c) { case 'c': if (uuid_scan(optarg, &cluster_uuid) < 0) { fprintf(stderr, "invalid cluster id: '%s'\n", optarg); return -EINVAL; } break; case 'i': nodeid = (exa_nodeid_t)strtol(optarg, &e, 10); if (*e || !EXA_NODEID_VALID(nodeid)) { fprintf(stderr, "invalid node id: '%s'\n", optarg); return -EINVAL; } break; case 'I': inca = (unsigned short)strtol(optarg, &e, 10); if (*e || inca == 0) { fprintf(stderr, "invalid incarnation: '%s'\n", optarg); return -EINVAL; } break; /* multicast group */ case 'm': mgroup = optarg; break; case 'n': node_name = optarg; break; /* hostname */ case 'N': hostname = optarg; break; /* communication port */ case 'p': mport = strtol(optarg, &e, 0); if (*e != '\0') { fprintf(stderr, "invalid port number '%s'\n", optarg); return -EINVAL; } break; case 's': examsg_show_stats(); return 0; break; /* usage */ case 'h': case '?': default: usage(argv[0]); return -EINVAL; } if (uuid_is_zero(&cluster_uuid)) { fprintf(stderr, "missing cluster id\n"); err = true; } if (nodeid == EXA_NODEID_NONE) { fprintf(stderr, "missing node id\n"); err = true; } if (node_name == NULL) { fprintf(stderr, "missing node name\n"); err = true; } if (hostname == NULL) { fprintf(stderr, "missing hostname\n"); err = true; } if (inca == 0) { fprintf(stderr, "missing incarnation\n"); err = true; } if (err) return -EINVAL; /* Get cluster id, number of nodes, node id, node name and interface parameters */ if (argc - optind != 0) { fprintf(stderr, "stray parameters\n"); usage(argv[0]); return -EINVAL; } signal(SIGTERM, sig_term); signal(SIGINT, sig_term); s = examsg_static_init(EXAMSG_STATIC_GET); if (s) { fprintf(stderr, "Can't initialize messaging layer."); return s; } exalog_static_init(); /* Log as exa_msgd by default */ exalog_as(EXAMSG_CMSGD_ID); #ifdef USE_YAOURT if (yaourt_init()) exalog_debug("Yaourt: Examsgd init OK"); else exalog_warning("Yaourt: Examsgd init FAILED (%s)", yaourt_error); #endif /* set up network communication */ return startup(&cluster_uuid, node_name, hostname, nodeid, mgroup, mport, inca); }
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; }