static void hrPrinter_get_OS_entries(void) { int status, more; struct printer myprinter, *pp = &myprinter; init_printer(pp); HRDBG("---->Getting printers ....."); more = firstprinter(pp, &status); if (status) goto errloop; while (more) { do { HRDBG("---->Got printer %s", pp->printer); handle_printer(pp); more = nextprinter(pp, &status); errloop: if (status) syslog(LOG_WARNING, "hrPrinterTable: printcap entry for %s " "has errors, skipping", pp->printer ? pp->printer : "<noname?>"); } while (more && status); } lastprinter(); printer_tick = this_tick; }
void refresh_storage_tbl(int force) { struct storage_entry *entry, *entry_tmp; if (!force && storage_tick != 0 && this_tick - storage_tick < storage_tbl_refresh) { HRDBG("no refresh needed"); return; } /* mark each entry as missing */ TAILQ_FOREACH(entry, &storage_tbl, link) entry->flags &= ~HR_STORAGE_FOUND; storage_OS_get_vm(); storage_OS_get_swap(); storage_OS_get_fs(); storage_OS_get_memstat(); /* * Purge items that disappeared */ TAILQ_FOREACH_SAFE(entry, &storage_tbl, link, entry_tmp) if (!(entry->flags & HR_STORAGE_FOUND)) storage_entry_delete(entry); storage_tick = this_tick; HRDBG("refresh DONE"); }
/** * Refresh the hrSWRun and hrSWRunPert tables. */ static void refresh_swrun_tbl(void) { struct swrun_entry *entry, *entry_tmp; if (this_tick - swrun_tick < swrun_tbl_refresh) { HRDBG("no refresh needed "); return; } /* mark each entry as missing */ TAILQ_FOREACH(entry, &swrun_tbl, link) entry->flags &= ~HR_SWRUN_FOUND; swrun_OS_get_procs(); swrun_OS_get_kinfo(); /* * Purge items that disappeared */ TAILQ_FOREACH_SAFE(entry, &swrun_tbl, link, entry_tmp) if (!(entry->flags & HR_SWRUN_FOUND)) swrun_entry_delete(entry); swrun_tick = this_tick; HRDBG("refresh DONE"); }
/** * Refresh the printer table if needed. */ void refresh_printer_tbl(void) { struct printer_entry *entry; struct printer_entry *entry_tmp; if (this_tick <= printer_tick) { HRDBG("no refresh needed"); return; } /* mark each entry as missing */ TAILQ_FOREACH(entry, &printer_tbl, link) entry->flags &= ~HR_PRINTER_FOUND; hrPrinter_get_OS_entries(); /* * Purge items that disappeared */ entry = TAILQ_FIRST(&printer_tbl); while (entry != NULL) { entry_tmp = TAILQ_NEXT(entry, link); if (!(entry->flags & HR_PRINTER_FOUND)) printer_entry_delete(entry); entry = entry_tmp; } printer_tick = this_tick; HRDBG("refresh DONE "); }
/** * Get the disk parameters */ static void disk_query_disk(struct disk_entry *entry) { char dev_path[128]; int fd; off_t mediasize; if (entry == NULL || entry->dev_name[0] == '\0') return; snprintf(dev_path, sizeof(dev_path), "%s%s", _PATH_DEV, entry->dev_name); entry->capacity = 0; HRDBG("OPENING device %s", dev_path); if ((fd = open(dev_path, O_RDONLY|O_NONBLOCK)) == -1) { HRDBG("OPEN device %s failed: %s", dev_path, strerror(errno)); return; } if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) { HRDBG("DIOCGMEDIASIZE for device %s failed: %s", dev_path, strerror(errno)); (void)close(fd); return; } mediasize = mediasize / 1024; entry->capacity = (mediasize > INT_MAX ? INT_MAX : mediasize); partition_tbl_handle_disk(entry->index, entry->dev_name); (void)close(fd); }
/* * HOST RESOURCES mib module finalization hook. * Returns 0 on success, < 0 on error */ static int hostres_fini(void) { if (hr_kd != NULL) (void)kvm_close(hr_kd); fini_storage_tbl(); fini_fs_tbl(); fini_processor_tbl(); fini_disk_storage_tbl(); fini_device_tbl(); fini_partition_tbl(); fini_network_tbl(); fini_printer_tbl(); fini_swrun_tbl(); fini_swins_tbl(); fini_scalars(); if (host_registration_id > 0) or_unregister(host_registration_id); HRDBG("done."); return (0); }
/** * Refresh the installed software table. */ void refresh_swins_tbl(void) { int ret; struct swins_entry *entry, *entry_tmp; if (this_tick - swins_tick < swins_tbl_refresh) { HRDBG("no refresh needed"); return; } /* mark each entry as missing */ TAILQ_FOREACH(entry, &swins_tbl, link) entry->flags &= ~HR_SWINSTALLED_FOUND; ret = swins_get_packages(); TAILQ_FOREACH_SAFE(entry, &swins_tbl, link, entry_tmp) if (!(entry->flags & HR_SWINSTALLED_FOUND) && !(entry->flags & HR_SWINSTALLED_IMMUTABLE)) swins_entry_delete(entry); if (ret == 0) swins_tick = this_tick; }
/** * Popuplate the hrSWRunTable. */ void init_swrun_tbl(void) { refresh_swrun_tbl(); HRDBG("done"); }
/** * Get kernel boot path. For FreeBSD it seems that no arguments are * present. Returns NULL if an error occured. The returned data is a * pointer to a global strorage. */ int OS_getSystemInitialLoadParameters(u_char **params) { if (boot_line == NULL) { int mib[2] = { CTL_KERN, KERN_BOOTFILE }; char *buf; size_t buf_len = 0; /* get the needed buffer len */ if (sysctl(mib, 2, NULL, &buf_len, NULL, 0) != 0) { syslog(LOG_ERR, "sysctl({CTL_KERN,KERN_BOOTFILE}) failed: %m"); return (SNMP_ERR_GENERR); } if ((buf = malloc(buf_len)) == NULL) { syslog(LOG_ERR, "malloc failed"); return (SNMP_ERR_GENERR); } if (sysctl(mib, 2, buf, &buf_len, NULL, 0)) { syslog(LOG_ERR, "sysctl({CTL_KERN,KERN_BOOTFILE}) failed: %m"); free(buf); return (SNMP_ERR_GENERR); } boot_line = buf; HRDBG("kernel boot file: %s", boot_line); } *params = boot_line; return (SNMP_ERR_NOERROR); }
/* * Refresh the FS table. This is done by forcing a refresh of the storage table. */ void refresh_fs_tbl(void) { if (fs_tick == 0 || this_tick - fs_tick >= fs_tbl_refresh) { refresh_storage_tbl(1); HRDBG("refresh DONE"); } }
/** * Update the information in this entry */ static void fetch_swrun_entry(struct swrun_entry *entry) { struct kinfo_proc *plist; int nproc; struct kld_file_stat stat; assert(entry != NULL); if (entry->index >= NO_PID + 1) { /* * kernel and kernel files (*.ko) will be indexed * starting with NO_PID + 1; NO_PID is PID_MAX + 1 * thus it will be no risk to overlap with real PIDs * which are in range of 1 .. NO_PID */ stat.version = sizeof(stat); if (kldstat(entry->index - NO_PID - 1, &stat) == -1) { /* * not found, it's gone. Mark it as invalid for now, it * will be removed from the list at next global refersh */ HRDBG("missing item with kid=%d", entry->index - NO_PID - 1); entry->status = (int32_t)SRS_INVALID; } else kld_file_stat_to_swrun(&stat, entry); } else { /* this is a process */ assert(hr_kd != NULL); plist = kvm_getprocs(hr_kd, KERN_PROC_PID, entry->index - 1, &nproc); if (plist == NULL || nproc != 1) { HRDBG("missing item with PID=%d", entry->index - 1); entry->status = (int32_t)SRS_INVALID; } else kinfo_proc_to_swrun_entry(plist, entry); } }
/** * Create and populate the package table */ void init_swins_tbl(void) { if ((pkg_dir = malloc(sizeof(PATH_PKGDIR))) == NULL) syslog(LOG_ERR, "%s: %m", __func__); else strcpy(pkg_dir, PATH_PKGDIR); swins_get_OS_ident(); refresh_swins_tbl(); HRDBG("init done"); }
/* * Given information returned from statfs(2) either create a new entry into * the fs_tbl or refresh the entry if it is already there. */ void fs_tbl_process_statfs_entry(const struct statfs *fs_p, int32_t storage_idx) { struct fs_entry *entry; assert(fs_p != 0); HRDBG("for hrStorageEntry::index %d", storage_idx); if (fs_p == NULL) return; if ((entry = fs_find_by_name(fs_p->f_mntonname)) != NULL || (entry = fs_entry_create(fs_p->f_mntonname)) != NULL) { entry->flags |= HR_FS_FOUND; if (!(fs_p->f_flags & MNT_LOCAL)) { /* this is a remote mount */ entry->remoteMountPoint = strdup(fs_p->f_mntfromname); /* if strdup failed, let it be NULL */ } else { entry->remoteMountPoint = strdup(""); /* if strdup failed, let it be NULL */ } entry->type = fs_get_type(fs_p); if ((fs_p->f_flags & MNT_RDONLY) == MNT_RDONLY) entry->access = FS_READ_ONLY; else entry->access = FS_READ_WRITE; /* FIXME - bootable fs ?! */ entry->bootable = TRUTH_MK((fs_p->f_flags & MNT_ROOTFS) == MNT_ROOTFS); entry->storageIndex = storage_idx; /* Info not available */ memset(entry->lastFullBackupDate, 0, sizeof(entry->lastFullBackupDate)); /* Info not available */ memset(entry->lastPartialBackupDate, 0, sizeof(entry->lastPartialBackupDate)); handle_partition_fs_index(fs_p->f_mntfromname, entry->index); } }
/** * Save a new sample to proc entry and get the average usage. * * Samples are stored in a ringbuffer from 0..(MAX_CPU_SAMPLES-1) */ static void save_sample(struct processor_entry *e, long *cp_times) { int i; e->cur_sample_idx = (e->cur_sample_idx + 1) % MAX_CPU_SAMPLES; for (i = 0; cp_times != NULL && i < CPUSTATES; i++) e->states[e->cur_sample_idx][i] = cp_times[i]; e->sample_cnt++; if (e->sample_cnt > MAX_CPU_SAMPLES) e->sample_cnt = MAX_CPU_SAMPLES; HRDBG("sample count for CPU no. %d went to %d", e->cpu_no, e->sample_cnt); e->load = get_avg_load(e); }
/** * Called for each printer found in /etc/printcap. */ static void handle_printer(struct printer *pp) { struct device_entry *dev_entry; struct printer_entry *printer_entry; char dev_only[128]; struct stat sb; if (pp->remote_host != NULL) { HRDBG("skipped %s -- remote", pp->printer); return; } if (strncmp(pp->lp, _PATH_DEV, strlen(_PATH_DEV)) != 0) { HRDBG("skipped %s [device %s] -- remote", pp->printer, pp->lp); return; } memset(dev_only, '\0', sizeof(dev_only)); snprintf(dev_only, sizeof(dev_only), "%s", pp->lp + strlen(_PATH_DEV)); HRDBG("printer %s has device %s", pp->printer, dev_only); if (stat(pp->lp, &sb) < 0) { if (errno == ENOENT) { HRDBG("skipped %s -- device %s missing", pp->printer, pp->lp); return; } } if ((dev_entry = device_find_by_name(dev_only)) == NULL) { HRDBG("%s not in hrDeviceTable", pp->lp); return; } HRDBG("%s found in hrDeviceTable", pp->lp); dev_entry->type = &OIDX_hrDevicePrinter_c; dev_entry->flags |= HR_DEVICE_IMMUTABLE; /* Then check hrPrinterTable for this device */ if ((printer_entry = printer_find_by_index(dev_entry->index)) == NULL && (printer_entry = printer_entry_create(dev_entry)) == NULL) return; printer_entry->flags |= HR_PRINTER_FOUND; printer_entry->status = get_printer_status(pp); memset(printer_entry->detectedErrorState, 0, sizeof(printer_entry->detectedErrorState)); }
/** * Get system uptime in hundredths of seconds since the epoch * Returns 0 in case of an error */ static int OS_getSystemUptime(uint32_t *ut) { struct timeval right_now; uint64_t now; if (kernel_boot == 0) { /* first time, do the sysctl */ struct timeval kernel_boot_timestamp; int mib[2] = { CTL_KERN, KERN_BOOTTIME }; size_t len = sizeof(kernel_boot_timestamp); if (sysctl(mib, 2, &kernel_boot_timestamp, &len, NULL, 0) == -1) { syslog(LOG_ERR, "sysctl KERN_BOOTTIME failed: %m"); return (SNMP_ERR_GENERR); } HRDBG("boot timestamp from kernel: {%lld, %ld}", (long long)kernel_boot_timestamp.tv_sec, (long)kernel_boot_timestamp.tv_usec); kernel_boot = ((uint64_t)kernel_boot_timestamp.tv_sec * 100) + (kernel_boot_timestamp.tv_usec / 10000); } if (gettimeofday(&right_now, NULL) < 0) { syslog(LOG_ERR, "gettimeofday failed: %m"); return (SNMP_ERR_GENERR); } now = ((uint64_t)right_now.tv_sec * 100) + (right_now.tv_usec / 10000); if (now - kernel_boot > UINT32_MAX) *ut = UINT32_MAX; else *ut = now - kernel_boot; return (SNMP_ERR_NOERROR); }
/** * Returns the CPU usage of a given processor entry. * * It needs at least two cp_times "tick" samples to calculate a delta and * thus, the usage over the sampling period. */ static int get_avg_load(struct processor_entry *e) { u_int i, oldest; long delta = 0; double usage = 0.0; assert(e != NULL); /* Need two samples to perform delta calculation. */ if (e->sample_cnt <= 1) return (0); /* Oldest usable index, we wrap around. */ if (e->sample_cnt == MAX_CPU_SAMPLES) oldest = (e->cur_sample_idx + 1) % MAX_CPU_SAMPLES; else oldest = 0; /* Sum delta for all states. */ for (i = 0; i < CPUSTATES; i++) { delta += e->states[e->cur_sample_idx][i]; delta -= e->states[oldest][i]; } if (delta == 0) return 0; /* Take idle time from the last element and convert to * percent usage by contrasting with total ticks delta. */ usage = (double)(e->states[e->cur_sample_idx][CPUSTATES-1] - e->states[oldest][CPUSTATES-1]) / delta; usage = 100 - (usage * 100); HRDBG("CPU no. %d, delta ticks %ld, pct usage %.2f", e->cpu_no, delta, usage); return ((int)(usage)); }
/** * Create a new entry into the storage table and, if necessary, an * entry into the storage map. */ static struct storage_entry * storage_entry_create(const char *name) { struct storage_entry *entry; struct storage_map_entry *map; size_t name_len; assert(name != NULL); assert(strlen(name) > 0); STAILQ_FOREACH(map, &storage_map, link) if (strcmp(map->a_name, name) == 0) break; if (map == NULL) { /* new object - get a new index */ if (next_storage_index > INT_MAX) { syslog(LOG_ERR, "%s: hrStorageTable index wrap", __func__); errx(EX_SOFTWARE, "hrStorageTable index wrap"); } if ((map = malloc(sizeof(*map))) == NULL) { syslog(LOG_ERR, "hrStorageTable: %s: %m", __func__ ); return (NULL); } name_len = strlen(name) + 1; if (name_len > SE_DESC_MLEN) name_len = SE_DESC_MLEN; if ((map->a_name = malloc(name_len)) == NULL) { free(map); return (NULL); } strlcpy(map->a_name, name, name_len); map->hrIndex = next_storage_index++; STAILQ_INSERT_TAIL(&storage_map, map, link); HRDBG("%s added into hrStorageMap at index=%d", name, map->hrIndex); } else { HRDBG("%s exists in hrStorageMap index=%d\n", name, map->hrIndex); } if ((entry = malloc(sizeof(*entry))) == NULL) { syslog(LOG_WARNING, "%s: %m", __func__); return (NULL); } memset(entry, 0, sizeof(*entry)); entry->index = map->hrIndex; if ((entry->descr = strdup(map->a_name)) == NULL) { free(entry); return (NULL); } map->entry = entry; INSERT_OBJECT_INT(entry, &storage_tbl); return (entry); }
/** * Invalidate entry. For KLDs we try to unload it, for processes we SIGKILL it. */ static int invalidate_swrun_entry(struct swrun_entry *entry, int commit) { struct kinfo_proc *plist; int nproc; struct kld_file_stat stat; assert(entry != NULL); if (entry->index >= NO_PID + 1) { /* this is a kernel item */ HRDBG("atempt to unload KLD %d", entry->index - NO_PID - 1); if (entry->index == SWOSIndex) { /* can't invalidate the kernel itself */ return (SNMP_ERR_NOT_WRITEABLE); } stat.version = sizeof(stat); if (kldstat(entry->index - NO_PID - 1, &stat) == -1) { /* * not found, it's gone. Mark it as invalid for now, it * will be removed from the list at next global * refresh */ HRDBG("missing item with kid=%d", entry->index - NO_PID - 1); entry->status = (int32_t)SRS_INVALID; return (SNMP_ERR_NOERROR); } /* * There is no way to try to unload a module. There seems * also no way to find out whether it is busy without unloading * it. We can assume that it is busy, if the reference count * is larger than 2, but if it is 1 nothing helps. */ if (!commit) { if (stat.refs > 1) return (SNMP_ERR_NOT_WRITEABLE); return (SNMP_ERR_NOERROR); } if (kldunload(stat.id) == -1) { syslog(LOG_ERR,"kldunload for %d/%s failed: %m", stat.id, stat.name); if (errno == EBUSY) return (SNMP_ERR_NOT_WRITEABLE); else return (SNMP_ERR_RES_UNAVAIL); } } else { /* this is a process */ assert(hr_kd != NULL); plist = kvm_getprocs(hr_kd, KERN_PROC_PID, entry->index - 1, &nproc); if (plist == NULL || nproc != 1) { HRDBG("missing item with PID=%d", entry->index - 1); entry->status = (int32_t)SRS_INVALID; return (SNMP_ERR_NOERROR); } if (IS_KERNPROC(plist)) { /* you don't want to do this */ return (SNMP_ERR_NOT_WRITEABLE); } if (kill(entry->index - 1, commit ? SIGKILL : 0) < 0) { syslog(LOG_ERR,"kill (%d, SIGKILL) failed: %m", entry->index - 1); if (errno == ESRCH) { /* race: just gone */ entry->status = (int32_t)SRS_INVALID; return (SNMP_ERR_NOERROR); } return (SNMP_ERR_GENERR); } } return (SNMP_ERR_NOERROR); }
/** * Create a new entry into the hrSWInstalledTable */ static struct swins_entry * swins_entry_create(const char *name) { struct swins_entry *entry; struct swins_map_entry *map; STAILQ_FOREACH(map, &swins_map, link) if (strcmp((const char *)map->name, name) == 0) break; if (map == NULL) { size_t name_len; /* new object - get a new index */ if (next_swins_index > INT_MAX) { syslog(LOG_ERR, "%s: hrSWInstalledTable index wrap", __func__ ); /* There isn't much we can do here. * If the next_swins_index is consumed * then we can't add entries to this table * So it is better to exit - if the table is sparsed * at the next agent run we can fill it fully. */ errx(EX_SOFTWARE, "hrSWInstalledTable index wrap"); } if ((map = malloc(sizeof(*map))) == NULL) { syslog(LOG_ERR, "%s: %m", __func__ ); return (NULL); } name_len = strlen(name) + 1; if (name_len > SW_NAME_MLEN) name_len = SW_NAME_MLEN; if ((map->name = malloc(name_len)) == NULL) { syslog(LOG_WARNING, "%s: %m", __func__); free(map); return (NULL); } map->index = next_swins_index++; strlcpy((char *)map->name, name, name_len); STAILQ_INSERT_TAIL(&swins_map, map, link); HRDBG("%s added into hrSWInstalled at %d", name, map->index); } if ((entry = malloc(sizeof(*entry))) == NULL) { syslog(LOG_WARNING, "%s: %m", __func__); return (NULL); } memset(entry, 0, sizeof(*entry)); if ((entry->name = strdup(map->name)) == NULL) { syslog(LOG_WARNING, "%s: %m", __func__); free(entry); return (NULL); } entry->index = map->index; map->entry = entry; INSERT_OBJECT_INT(entry, &swins_tbl); return (entry); }
/** * Read the installed packages */ static int swins_get_packages(void) { struct stat sb; DIR *p_dir; struct dirent *ent; struct tm k_ts; char *pkg_file; struct swins_entry *entry; int ret = 0; if (pkg_dir == NULL) /* initialisation may have failed */ return (-1); if (stat(pkg_dir, &sb) != 0) { syslog(LOG_ERR, "hrSWInstalledTable: stat(\"%s\") failed: %m", pkg_dir); return (-1); } if (!S_ISDIR(sb.st_mode)) { syslog(LOG_ERR, "hrSWInstalledTable: \"%s\" is not a directory", pkg_dir); return (-1); } if (sb.st_ctime <= os_pkg_last_change) { HRDBG("no need to rescan installed packages -- " "directory time-stamp unmodified"); TAILQ_FOREACH(entry, &swins_tbl, link) entry->flags |= HR_SWINSTALLED_FOUND; return (0); } if ((p_dir = opendir(pkg_dir)) == NULL) { syslog(LOG_ERR, "hrSWInstalledTable: opendir(\"%s\") failed: " "%m", pkg_dir); return (-1); } while (errno = 0, (ent = readdir(p_dir)) != NULL) { HRDBG(" pkg file: %s", ent->d_name); /* check that the contents file is a regular file */ if (asprintf(&pkg_file, "%s/%s/%s", pkg_dir, ent->d_name, CONTENTS_FNAME) == -1) continue; if (stat(pkg_file, &sb) != 0 ) { free(pkg_file); continue; } if (!S_ISREG(sb.st_mode)) { syslog(LOG_ERR, "hrSWInstalledTable: \"%s\" not a " "regular file -- skipped", pkg_file); free(pkg_file); continue; } free(pkg_file); /* read directory timestamp on package */ if (asprintf(&pkg_file, "%s/%s", pkg_dir, ent->d_name) == -1) continue; if (stat(pkg_file, &sb) == -1 || localtime_r(&sb.st_ctime, &k_ts) == NULL) { free(pkg_file); continue; } free(pkg_file); /* update or create entry */ if ((entry = swins_find_by_name(ent->d_name)) == NULL && (entry = swins_entry_create(ent->d_name)) == NULL) { ret = -1; goto PKG_LOOP_END; } entry->flags |= HR_SWINSTALLED_FOUND; entry->id = &oid_zeroDotZero; entry->type = (int32_t)SWI_APPLICATION; entry->date_len = make_date_time(entry->date, &k_ts, 0); } if (errno != 0) { syslog(LOG_ERR, "hrSWInstalledTable: readdir_r(\"%s\") failed:" " %m", pkg_dir); ret = -1; } else { /* * save the timestamp of directory * to avoid any further scanning */ os_pkg_last_change = sb.st_ctime; } PKG_LOOP_END: (void)closedir(p_dir); return (ret); }
/** * Create an entry into the FS table and an entry in the map (if needed). */ static struct fs_entry * fs_entry_create(const char *name) { struct fs_entry *entry; struct fs_map_entry *map; assert(name != NULL); assert(strlen(name) > 0); STAILQ_FOREACH(map, &fs_map, link) if (strcmp(map->a_name, name) == 0) break; if (map == NULL) { size_t mount_point_len; /* new object - get a new index */ if (next_fs_index > INT_MAX) { /* Unrecoverable error - die clean and quicly*/ syslog(LOG_ERR, "%s: hrFSTable index wrap", __func__); errx(EX_SOFTWARE, "hrFSTable index wrap"); } if ((map = malloc(sizeof(*map))) == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return (NULL); } mount_point_len = strlen(name) + 1; if (mount_point_len > FS_MP_MLEN) mount_point_len = FS_MP_MLEN; if ((map->a_name = malloc(mount_point_len)) == NULL) { syslog(LOG_ERR, "%s: %m", __func__); free(map); return (NULL); } strlcpy(map->a_name, name, mount_point_len); map->hrIndex = next_fs_index++; map->entry = NULL; STAILQ_INSERT_TAIL(&fs_map, map, link); HRDBG("%s added into hrFSMap at index=%d", name, map->hrIndex); } else { HRDBG("%s exists in hrFSMap index=%d", name, map->hrIndex); } if ((entry = malloc(sizeof(*entry))) == NULL) { syslog(LOG_WARNING, "%s: %m", __func__); return (NULL); } if ((entry->mountPoint = strdup(name)) == NULL) { syslog(LOG_ERR, "%s: %m", __func__); free(entry); return (NULL); } entry->index = map->hrIndex; map->entry = entry; INSERT_OBJECT_INT(entry, &fs_tbl); return (entry); }
static void storage_OS_get_memstat(void) { struct memory_type *mt_item; struct storage_entry *entry; if (mt_list == NULL) { if ((mt_list = memstat_mtl_alloc()) == NULL) /* again? we have a serious problem */ return; } if (memstat_sysctl_all(mt_list, 0) < 0) { syslog(LOG_ERR, "memstat_sysctl_all failed: %s", memstat_strerror(memstat_mtl_geterror(mt_list)) ); return; } if ((mt_item = memstat_mtl_first(mt_list)) == NULL) { /* usually this is not an error, no errno for this failure*/ HRDBG("memstat_mtl_first failed"); return; } do { const char *memstat_name; uint64_t tmp_size; int allocator; char alloc_descr[SE_DESC_MLEN]; memstat_name = memstat_get_name(mt_item); if (memstat_name == NULL || strlen(memstat_name) == 0) continue; switch (allocator = memstat_get_allocator(mt_item)) { case ALLOCATOR_MALLOC: snprintf(alloc_descr, sizeof(alloc_descr), "MALLOC: %s", memstat_name); break; case ALLOCATOR_UMA: snprintf(alloc_descr, sizeof(alloc_descr), "UMA: %s", memstat_name); break; default: snprintf(alloc_descr, sizeof(alloc_descr), "UNKNOWN%d: %s", allocator, memstat_name); break; } if ((entry = storage_find_by_name(alloc_descr)) == NULL && (entry = storage_entry_create(alloc_descr)) == NULL) return; entry->flags |= HR_STORAGE_FOUND; entry->type = &OIDX_hrStorageRam_c; if ((tmp_size = memstat_get_size(mt_item)) == 0) tmp_size = memstat_get_sizemask(mt_item); entry->allocationUnits = (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size); tmp_size = memstat_get_countlimit(mt_item); entry->size = (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size); tmp_size = memstat_get_count(mt_item); entry->used = (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size); tmp_size = memstat_get_failures(mt_item); entry->allocationFailures = (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size); } while((mt_item = memstat_mtl_next(mt_item)) != NULL); }
/** * Get swap info */ static void storage_OS_get_swap(void) { int nswapdev = 0; size_t len = sizeof(nswapdev); struct storage_entry *entry; char swap_w_prefix[SE_DESC_MLEN]; if (sysctlbyname("vm.nswapdev", &nswapdev, &len, NULL,0 ) < 0) { syslog(LOG_ERR, "hrStorageTable: sysctlbyname(\"vm.nswapdev\") " "failed. %m"); assert(0); return; } if (nswapdev <= 0) { HRDBG("vm.nswapdev is %d", nswapdev); return; } if (nswapdev + 1 != (int)swap_devs_len || swap_devs == NULL) { swap_devs_len = nswapdev + 1; swap_devs = reallocf(swap_devs, swap_devs_len * sizeof(struct kvm_swap)); assert(swap_devs != NULL); if (swap_devs == NULL) { swap_devs_len = 0; return; } } nswapdev = kvm_getswapinfo(hr_kd, swap_devs, swap_devs_len, 0); if (nswapdev < 0) { syslog(LOG_ERR, "hrStorageTable: kvm_getswapinfo failed. %m\n"); assert(0); return; } for (len = 0; len < (size_t)nswapdev; len++) { memset(&swap_w_prefix[0], '\0', sizeof(swap_w_prefix)); snprintf(swap_w_prefix, sizeof(swap_w_prefix) - 1, "Swap:%s%s", _PATH_DEV, swap_devs[len].ksw_devname); entry = storage_find_by_name(swap_w_prefix); if (entry == NULL) entry = storage_entry_create(swap_w_prefix); assert (entry != NULL); if (entry == NULL) return; /* Out of luck */ entry->flags |= HR_STORAGE_FOUND; entry->type = &OIDX_hrStorageVirtualMemory_c; entry->allocationUnits = getpagesize(); entry->size = swap_devs[len].ksw_total; entry->used = swap_devs[len].ksw_used; entry->allocationFailures = 0; } }
/** * Query the underlaying OS for the mounted file systems * anf fill in the respective lists (for hrStorageTable and for hrFSTable) */ static void storage_OS_get_fs(void) { struct storage_entry *entry; uint64_t size, used; int i, mounted_fs_count, units; char fs_string[SE_DESC_MLEN]; if ((mounted_fs_count = getfsstat(NULL, 0, MNT_NOWAIT)) < 0) { syslog(LOG_ERR, "hrStorageTable: getfsstat() failed: %m"); return; /* out of luck this time */ } if (mounted_fs_count != (int)fs_buf_count || fs_buf == NULL) { fs_buf_count = mounted_fs_count; fs_buf = reallocf(fs_buf, fs_buf_count * sizeof(struct statfs)); if (fs_buf == NULL) { fs_buf_count = 0; assert(0); return; } } if ((mounted_fs_count = getfsstat(fs_buf, fs_buf_count * sizeof(struct statfs), MNT_NOWAIT)) < 0) { syslog(LOG_ERR, "hrStorageTable: getfsstat() failed: %m"); return; /* out of luck this time */ } HRDBG("got %d mounted FS", mounted_fs_count); fs_tbl_pre_refresh(); for (i = 0; i < mounted_fs_count; i++) { snprintf(fs_string, sizeof(fs_string), "%s, type: %s, dev: %s", fs_buf[i].f_mntonname, fs_buf[i].f_fstypename, fs_buf[i].f_mntfromname); entry = storage_find_by_name(fs_string); if (entry == NULL) entry = storage_entry_create(fs_string); assert (entry != NULL); if (entry == NULL) return; /* Out of luck */ entry->flags |= HR_STORAGE_FOUND; entry->type = fs_get_type(&fs_buf[i]); /*XXX - This is wrong*/ units = fs_buf[i].f_bsize; size = fs_buf[i].f_blocks; used = fs_buf[i].f_blocks - fs_buf[i].f_bfree; while (size > INT_MAX) { units <<= 1; size >>= 1; used >>= 1; } entry->allocationUnits = units; entry->size = size; entry->used = used; entry->allocationFailures = 0; /* take care of hrFSTable */ fs_tbl_process_statfs_entry(&fs_buf[i], entry->index); } fs_tbl_post_refresh(); }