/** * nsm_get_state - retrieve on-disk NSM state number * * Returns an odd NSM state number read from disk, or an initial * state number. Zero is returned if some error occurs. */ int nsm_get_state(_Bool update) { int fd, state = 0; ssize_t result; char *path = NULL; path = nsm_make_pathname(NSM_STATE_FILE); if (path == NULL) { xlog(L_ERROR, "Failed to allocate path for " NSM_STATE_FILE); goto out; } fd = open(path, O_RDONLY); if (fd == -1) { if (errno != ENOENT) { xlog(L_ERROR, "Failed to open %s: %m", path); goto out; } xlog(L_NOTICE, "Initializing NSM state"); state = 1; update = true; goto update; } result = read(fd, &state, sizeof(state)); if (exact_error_check(result, sizeof(state))) { xlog_warn("Failed to read %s: %m", path); xlog(L_NOTICE, "Initializing NSM state"); state = 1; update = true; goto update; } if ((state & 1) == 0) state++; update: (void)close(fd); if (update) { state += 2; if (!nsm_atomic_write(path, &state, sizeof(state))) state = 0; } out: free(path); return state; }
/** * nsm_retire_monitored_hosts - back up all hosts from "sm/" to "sm.bak/" * * Returns the count of host records that were moved. * * Note that if any error occurs during this process, some monitor * records may be left in the "sm" directory. */ unsigned int nsm_retire_monitored_hosts(void) { unsigned int count = 0; struct dirent *de; char *path; DIR *dir; path = nsm_make_pathname(NSM_MONITOR_DIR); if (path == NULL) { xlog(L_ERROR, "Failed to allocate path for " NSM_MONITOR_DIR); return count; } dir = opendir(path); free(path); if (dir == NULL) { xlog_warn("Failed to open " NSM_MONITOR_DIR ": %m"); return count; } while ((de = readdir(dir)) != NULL) { char *src, *dst; struct stat stb; if (de->d_name[0] == '.') continue; src = nsm_make_record_pathname(NSM_MONITOR_DIR, de->d_name); if (src == NULL) { xlog_warn("Bad monitor file name, skipping"); continue; } /* NB: not all file systems fill in d_type correctly */ if (lstat(src, &stb) == -1) { xlog_warn("Bad monitor file %s, skipping: %m", de->d_name); free(src); continue; } if (!S_ISREG(stb.st_mode)) { xlog(D_GENERAL, "Skipping non-regular file %s", de->d_name); free(src); continue; } dst = nsm_make_record_pathname(NSM_NOTIFY_DIR, de->d_name); if (dst == NULL) { free(src); xlog_warn("Bad notify file name, skipping"); continue; } if (rename(src, dst) == -1) xlog_warn("Failed to rename %s -> %s: %m", src, dst); else { xlog(D_GENERAL, "Retired record for mon_name %s", de->d_name); count++; } free(dst); free(src); } (void)closedir(dir); return count; }