Exemplo n.º 1
0
/**
 * 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;
}
Exemplo n.º 2
0
/**
 * 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;
}