/* Skips deleting first entry of export list. */ int rebuild_export_list() { #ifndef FIXME_EXPORT_RELOAD return 0; #else int status = 0; config_file_t config_struct; /* If no configuration file is given, then the caller must want to reparse the * configuration file from startup. */ if(config_path[0] == '\0') { LogCrit(COMPONENT_CONFIG, "Error: No configuration file was specified for reloading exports."); return 0; } /* Attempt to parse the new configuration file */ config_struct = config_ParseFile(config_path); if(!config_struct) { LogCrit(COMPONENT_CONFIG, "rebuild_export_list: Error while parsing new configuration file %s: %s", config_path, config_GetErrorMsg()); return 0; } /* Create the new exports list */ status = ReadExports(config_struct, &temp_exportlist); if(status < 0) { LogCrit(COMPONENT_CONFIG, "rebuild_export_list: Error while parsing export entries"); return status; } else if(status == 0) { LogWarn(COMPONENT_CONFIG, "rebuild_export_list: No export entries found in configuration file !!!"); return 0; } /* At least one worker thread should exist. Each worker thread has a pointer to * the same hash table. */ if(nfs_export_create_root_entry(&temp_exportlist) != TRUE) { LogCrit(COMPONENT_MAIN, "replace_exports: Error initializing Cache Inode root entries"); return 0; } return 1; #endif }
/* Skips deleting first entry of export list. */ int rebuild_export_list(void) { #if 0 int status = 0; config_file_t config_struct; /* If no configuration file is given, then the caller must want to reparse the * configuration file from startup. */ if(config_path == NULL) { LogCrit(COMPONENT_CONFIG, "Error: No configuration file was specified for reloading exports."); return 0; } /* Attempt to parse the new configuration file */ config_struct = config_ParseFile(config_path); if(!config_struct) { LogCrit(COMPONENT_CONFIG, "rebuild_export_list: Error while parsing new configuration file %s: %s", config_path, config_GetErrorMsg()); return 0; } /* Create the new exports list */ status = ReadExports(config_struct, &temp_exportlist); if(status < 0) { LogCrit(COMPONENT_CONFIG, "rebuild_export_list: Error while parsing export entries"); return status; } else if(status == 0) { LogWarn(COMPONENT_CONFIG, "rebuild_export_list: No export entries found in configuration file !!!"); return 0; } return 1; #else return 0; #endif }
/** * @brief Load parameters from config file * * @param[in] config_struct Parsed config file * @param[out] p_start_info Startup parameters * * @return -1 on failure. */ int nfs_set_param_from_conf(config_file_t config_struct, nfs_start_info_t *p_start_info) { int rc; cache_inode_status_t cache_inode_status; /* * Initialize exports and clients so config parsing can use them * early. */ client_pkginit(); export_pkginit(); rc = read_log_config(config_struct); if (rc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing log configuration"); return -1; } /* Core parameters */ rc = nfs_read_core_conf(config_struct, &nfs_param.core_param); if (rc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing core configuration"); return -1; } else { /* No such stanza in configuration file */ if (rc == 1) LogEvent(COMPONENT_INIT, "No core configuration found in config file, using default"); else LogDebug(COMPONENT_INIT, "core configuration read from config file"); } /* Worker paramters: ip/name hash table and expiration for each entry */ rc = nfs_read_ip_name_conf(config_struct, &nfs_param.ip_name_param); if (rc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing IP/name configuration"); return -1; } else { /* No such stanza in configuration file */ if (rc == 1) LogDebug(COMPONENT_INIT, "No IP/name configuration found in config file, using default"); else LogDebug(COMPONENT_INIT, "IP/name configuration read from config file"); } #ifdef _HAVE_GSSAPI /* NFS kerberos5 configuration */ rc = nfs_read_krb5_conf(config_struct, &nfs_param.krb5_param); if (rc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing NFS/KRB5 configuration for RPCSEC_GSS"); return -1; } else { /* No such stanza in configuration file */ if (rc == 1) LogDebug(COMPONENT_INIT, "No NFS/KRB5 configuration found in config file, using default"); else LogDebug(COMPONENT_INIT, "NFS/KRB5 configuration read from config file"); } #endif /* NFSv4 specific configuration */ rc = nfs_read_version4_conf(config_struct, &nfs_param.nfsv4_param); if (rc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing NFSv4 specific configuration"); return -1; } else { /* No such stanza in configuration file */ if (rc == 1) LogDebug(COMPONENT_INIT, "No NFSv4 specific configuration found in config file, using default"); else LogDebug(COMPONENT_INIT, "NFSv4 specific configuration read from config file"); } #ifdef _USE_9P rc = _9p_read_conf(config_struct, &nfs_param._9p_param); if (rc < 0) { if (rc == -2) LogDebug(COMPONENT_INIT, "No 9P configuration found, using default"); else { LogCrit(COMPONENT_INIT, "Error while parsing 9P configuration"); return -1; } } #endif /* Cache inode client parameters */ cache_inode_status = cache_inode_read_conf_parameter(config_struct, &nfs_param.cache_param); if (cache_inode_status != CACHE_INODE_SUCCESS) { if (cache_inode_status == CACHE_INODE_NOT_FOUND) LogDebug(COMPONENT_INIT, "No Cache Inode Client configuration found, using default"); else { LogCrit(COMPONENT_INIT, "Error while parsing Cache Inode Client configuration"); return 1; } } else LogDebug(COMPONENT_INIT, "Cache Inode Client configuration read from config file"); /* Load export entries from parsed file * returns the number of export entries. */ rc = ReadExports(config_struct); if (rc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing export entries"); return -1; } else if (rc == 0) { LogWarn(COMPONENT_INIT, "No export entries found in configuration file !!!"); } LogEvent(COMPONENT_INIT, "Configuration file successfully parsed"); return 0; }
int main(int argc, char *argv[]) { char *tempo_exec_name = NULL; char localmachine[MAXHOSTNAMELEN + 1]; int c; int dsc; int rc; int pidfile; char *log_path = NULL; char *exec_name = "nfs-ganesha"; int debug_level = -1; int detach_flag = true; bool dump_trace = false; #ifndef HAVE_DAEMON int dev_null_fd = 0; pid_t son_pid; #endif sigset_t signals_to_block; struct config_error_type err_type; /* Set the server's boot time and epoch */ now(&nfs_ServerBootTime); nfs_ServerEpoch = (time_t) nfs_ServerBootTime.tv_sec; srand(nfs_ServerEpoch); tempo_exec_name = strrchr(argv[0], '/'); if (tempo_exec_name != NULL) exec_name = main_strdup("exec_name", tempo_exec_name + 1); if (*exec_name == '\0') exec_name = argv[0]; /* get host name */ if (gethostname(localmachine, sizeof(localmachine)) != 0) { fprintf(stderr, "Could not get local host name, exiting...\n"); exit(1); } else { nfs_host_name = main_strdup("host_name", localmachine); } /* now parsing options with getopt */ while ((c = getopt(argc, argv, options)) != EOF) { switch (c) { case 'v': case '@': printf("NFS-Ganesha Release = V%s\n", GANESHA_VERSION); #if !GANESHA_BUILD_RELEASE /* A little backdoor to keep track of binary versions */ printf("%s compiled on %s at %s\n", exec_name, __DATE__, __TIME__); printf("Release comment = %s\n", VERSION_COMMENT); printf("Git HEAD = %s\n", _GIT_HEAD_COMMIT); printf("Git Describe = %s\n", _GIT_DESCRIBE); #endif exit(0); break; case 'L': /* Default Log */ log_path = main_strdup("log_path", optarg); break; case 'N': /* debug level */ debug_level = ReturnLevelAscii(optarg); if (debug_level == -1) { fprintf(stderr, "Invalid value for option 'N': NIV_NULL, NIV_MAJ, NIV_CRIT, NIV_EVENT, NIV_DEBUG, NIV_MID_DEBUG or NIV_FULL_DEBUG expected.\n"); exit(1); } break; case 'f': /* config file */ nfs_config_path = main_strdup("config_path", optarg); break; case 'p': /* PID file */ nfs_pidfile_path = main_strdup("pidfile_path", optarg); break; case 'F': /* Don't detach, foreground mode */ detach_flag = false; break; case 'R': /* Shall we manage RPCSEC_GSS ? */ fprintf(stderr, "\n\nThe -R flag is deprecated, use this syntax in the configuration file instead:\n\n"); fprintf(stderr, "NFS_KRB5\n"); fprintf(stderr, "{\n"); fprintf(stderr, "\tPrincipalName = nfs@<your_host> ;\n"); fprintf(stderr, "\tKeytabPath = /etc/krb5.keytab ;\n"); fprintf(stderr, "\tActive_krb5 = true ;\n"); fprintf(stderr, "}\n\n\n"); exit(1); break; case 'T': /* Dump the default configuration on stdout */ my_nfs_start_info.dump_default_config = true; break; case 'C': dump_trace = true; break; case 'E': nfs_ServerEpoch = (time_t) atoll(optarg); break; case 'h': fprintf(stderr, usage, exec_name); exit(0); default: /* '?' */ fprintf(stderr, "Try '%s -h' for usage\n", exec_name); exit(1); } } /* initialize memory and logging */ nfs_prereq_init(exec_name, nfs_host_name, debug_level, log_path, dump_trace); #if GANESHA_BUILD_RELEASE LogEvent(COMPONENT_MAIN, "%s Starting: Ganesha Version %s", exec_name, GANESHA_VERSION); #else LogEvent(COMPONENT_MAIN, "%s Starting: %s", exec_name, "Ganesha Version " _GIT_DESCRIBE ", built at " __DATE__ " " __TIME__ " on " BUILD_HOST); #endif /* initialize nfs_init */ nfs_init_init(); nfs_check_malloc(); /* Start in background, if wanted */ if (detach_flag) { #ifdef HAVE_DAEMON /* daemonize the process (fork, close xterm fds, * detach from parent process) */ if (daemon(0, 0)) LogFatal(COMPONENT_MAIN, "Error detaching process from parent: %s", strerror(errno)); /* In the child process, change the log header * if not, the header will contain the parent's pid */ set_const_log_str(); #else /* Step 1: forking a service process */ switch (son_pid = fork()) { case -1: /* Fork failed */ LogFatal(COMPONENT_MAIN, "Could not start nfs daemon (fork error %d (%s)", errno, strerror(errno)); break; case 0: /* This code is within the son (that will actually work) * Let's make it the leader of its group of process */ if (setsid() == -1) { LogFatal(COMPONENT_MAIN, "Could not start nfs daemon (setsid error %d (%s)", errno, strerror(errno)); } /* stdin, stdout and stderr should not refer to a tty * I close 0, 1 & 2 and redirect them to /dev/null */ dev_null_fd = open("/dev/null", O_RDWR); if (dev_null_fd < 0) LogFatal(COMPONENT_MAIN, "Could not open /dev/null: %d (%s)", errno, strerror(errno)); if (close(STDIN_FILENO) == -1) LogEvent(COMPONENT_MAIN, "Error while closing stdin: %d (%s)", errno, strerror(errno)); else { LogEvent(COMPONENT_MAIN, "stdin closed"); dup(dev_null_fd); } if (close(STDOUT_FILENO) == -1) LogEvent(COMPONENT_MAIN, "Error while closing stdout: %d (%s)", errno, strerror(errno)); else { LogEvent(COMPONENT_MAIN, "stdout closed"); dup(dev_null_fd); } if (close(STDERR_FILENO) == -1) LogEvent(COMPONENT_MAIN, "Error while closing stderr: %d (%s)", errno, strerror(errno)); else { LogEvent(COMPONENT_MAIN, "stderr closed"); dup(dev_null_fd); } if (close(dev_null_fd) == -1) LogFatal(COMPONENT_MAIN, "Could not close tmp fd to /dev/null: %d (%s)", errno, strerror(errno)); /* In the child process, change the log header * if not, the header will contain the parent's pid */ set_const_log_str(); break; default: /* This code is within the parent process, * it is useless, it must die */ LogFullDebug(COMPONENT_MAIN, "Starting a child of pid %d", son_pid); exit(0); break; } #endif } /* Make sure Linux file i/o will return with error * if file size is exceeded. */ #ifdef _LINUX signal(SIGXFSZ, SIG_IGN); #endif /* Echo PID into pidfile */ pidfile = open(nfs_pidfile_path, O_CREAT | O_RDWR, 0644); if (pidfile == -1) { LogFatal(COMPONENT_MAIN, "Can't open pid file %s for writing", nfs_pidfile_path); } else { char linebuf[1024]; struct flock lk; /* Try to obtain a lock on the file */ lk.l_type = F_WRLCK; lk.l_whence = SEEK_SET; lk.l_start = (off_t) 0; lk.l_len = (off_t) 0; if (fcntl(pidfile, F_SETLK, &lk) == -1) LogFatal(COMPONENT_MAIN, "Ganesha already started"); /* Put pid into file, then close it */ (void)snprintf(linebuf, sizeof(linebuf), "%u\n", getpid()); if (write(pidfile, linebuf, strlen(linebuf)) == -1) LogCrit(COMPONENT_MAIN, "Couldn't write pid to file %s", nfs_pidfile_path); } /* Set up for the signal handler. * Blocks the signals the signal handler will handle. */ sigemptyset(&signals_to_block); sigaddset(&signals_to_block, SIGTERM); sigaddset(&signals_to_block, SIGHUP); sigaddset(&signals_to_block, SIGPIPE); if (pthread_sigmask(SIG_BLOCK, &signals_to_block, NULL) != 0) LogFatal(COMPONENT_MAIN, "Could not start nfs daemon, pthread_sigmask failed"); /* init URL package */ config_url_init(); /* Create a memstream for parser+processing error messages */ if (!init_error_type(&err_type)) goto fatal_die; /* Parse the configuration file so we all know what is going on. */ if (nfs_config_path == NULL || nfs_config_path[0] == '\0') { LogWarn(COMPONENT_INIT, "No configuration file named."); nfs_config_struct = NULL; } else nfs_config_struct = config_ParseFile(nfs_config_path, &err_type); if (!config_error_no_error(&err_type)) { char *errstr = err_type_str(&err_type); if (!config_error_is_harmless(&err_type)) { LogCrit(COMPONENT_INIT, "Error %s while parsing (%s)", errstr != NULL ? errstr : "unknown", nfs_config_path); if (errstr != NULL) gsh_free(errstr); goto fatal_die; } else LogWarn(COMPONENT_INIT, "Error %s while parsing (%s)", errstr != NULL ? errstr : "unknown", nfs_config_path); if (errstr != NULL) gsh_free(errstr); } if (read_log_config(nfs_config_struct, &err_type) < 0) { LogCrit(COMPONENT_INIT, "Error while parsing log configuration"); goto fatal_die; } /* We need all the fsal modules loaded so we can have * the list available at exports parsing time. */ start_fsals(); /* parse configuration file */ if (nfs_set_param_from_conf(nfs_config_struct, &my_nfs_start_info, &err_type)) { LogCrit(COMPONENT_INIT, "Error setting parameters from configuration file."); goto fatal_die; } /* initialize core subsystems and data structures */ if (init_server_pkgs() != 0) { LogCrit(COMPONENT_INIT, "Failed to initialize server packages"); goto fatal_die; } /* Load Data Server entries from parsed file * returns the number of DS entries. */ dsc = ReadDataServers(nfs_config_struct, &err_type); if (dsc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing DS entries"); goto fatal_die; } /* Create stable storage directory, this needs to be done before * starting the recovery thread. */ rc = nfs4_recovery_init(); if (rc) { LogCrit(COMPONENT_INIT, "Recovery backend initialization failed!"); goto fatal_die; } /* Start grace period */ nfs_start_grace(NULL); /* Wait for enforcement to begin */ nfs_wait_for_grace_enforcement(); /* Load export entries from parsed file * returns the number of export entries. */ rc = ReadExports(nfs_config_struct, &err_type); if (rc < 0) { LogCrit(COMPONENT_INIT, "Error while parsing export entries"); goto fatal_die; } if (rc == 0 && dsc == 0) LogWarn(COMPONENT_INIT, "No export entries found in configuration file !!!"); report_config_errors(&err_type, NULL, config_errs_to_log); /* freeing syntax tree : */ config_Free(nfs_config_struct); /* Everything seems to be OK! We can now start service threads */ nfs_start(&my_nfs_start_info); return 0; fatal_die: report_config_errors(&err_type, NULL, config_errs_to_log); LogFatal(COMPONENT_INIT, "Fatal errors. Server exiting..."); /* NOT REACHED */ return 2; }
bool DefFile::Read() { stream = new std::fstream(fileName.c_str(), std::ios::in); if (stream != NULL) { try { lineno = 0; NextToken(); while (!stream->eof()) { if (token->IsEnd()) { NextToken(); } else if (!token->IsKeyword()) { throw new std::runtime_error("Invalid directive"); } else { switch(token->GetKeyword()) { case edt_name: ReadName(); break; case edt_library: ReadLibrary(); break; case edt_exports: ReadExports(); break; case edt_imports: ReadImports(); break; case edt_description: ReadDescription(); break; case edt_stacksize: ReadStacksize(); break; case edt_heapsize: ReadHeapsize(); break; case edt_code: ReadCode(); break; case edt_data: ReadData(); break; case edt_sections: ReadSections(); break; default: throw new std::runtime_error("Invalid directive"); } } } } catch (std::runtime_error *e) { std::cout << fileName << "(" << lineno << "): " << e->what() << std::endl ; delete e; } delete stream; } else { std::cout << "File '" << name << "' not found." << std::endl; } return true; }