//Remove a battery's entries from the xenstore. static void cleanup_removed_battery(unsigned int battery_index) { char path[256]; snprintf(path, 255, "%s%d", XS_BATTERY_PATH, battery_index); xenstore_rm(path); if (battery_index > 0) { xenstore_rm(XS_BST1); xenstore_rm(XS_BIF1); } else { xenstore_rm(XS_BST); xenstore_rm(XS_BIF); } if (get_num_batteries_present() == 0) xenstore_write("0", XS_BATTERY_PRESENT); else xenstore_write("1", XS_BATTERY_PRESENT); }
/** * Delete XenStore value * * @v netfront Netfront device * @v subkey Subkey * @ret rc Return status code */ static int netfront_rm ( struct netfront_nic *netfront, const char *subkey ) { struct xen_device *xendev = netfront->xendev; struct xen_hypervisor *xen = xendev->xen; int rc; /* Remove value */ if ( ( rc = xenstore_rm ( xen, xendev->key, subkey, NULL ) ) != 0 ) { DBGC ( netfront, "NETFRONT %s could not delete %s: %s\n", xendev->key, subkey, strerror ( rc ) ); return rc; } return 0; }
int main(int argc, char *argv[]) { int ret = 0; #ifndef RUN_STANDALONE openlog("xcpmd", 0, LOG_DAEMON); daemonize(); #endif xcpmd_log(LOG_INFO, "Starting XenClient power management daemon.\n"); //Initialize libevent library event_init(); //Initialize xenstore. if (xenstore_init() == -1) { xcpmd_log(LOG_ERR, "Unable to init xenstore\n"); return -1; } // Allow everyone to read from /pm/ in xenstore xenstore_rm("/pm"); xenstore_mkdir("/pm"); xenstore_chmod("r0", 1, "/pm"); initialize_platform_info(); xcpmd_log(LOG_INFO, "Starting DBUS server.\n"); if (xcpmd_dbus_initialize() == -1) { xcpmd_log(LOG_ERR, "Failed to initialize DBUS server\n"); goto xcpmd_err; } xcpmd_log(LOG_INFO, "Starting ACPI events monitor.\n"); if (acpi_events_initialize() == -1) { xcpmd_log(LOG_ERR, "Failed to initialize ACPI events monitor\n"); goto xcpmd_err; } // Load modules xcpmd_log(LOG_INFO, "Loading modules.\n"); if (init_modules() == -1) { xcpmd_log(LOG_ERR, "Failed to load all modules\n"); goto xcpmd_err; } //This relies on both acpi-events and acpi-module having been initialized xcpmd_log(LOG_INFO, "Initializing ACPI state.\n"); acpi_initialize_state(); // Load policy xcpmd_log(LOG_INFO, "Loading policy.\n"); if (load_policy_from_db() == -1) { xcpmd_log(LOG_WARNING, "Error loading policy from DB; continuing...\n"); } #ifdef POLICY_FILE_PATH if (load_policy_from_file(POLICY_FILE_PATH) == -1) { xcpmd_log(LOG_WARNING, "Error loading policy from file %s; continuing...\n", POLICY_FILE_PATH); } #endif #ifdef XCPMD_DEBUG xcpmd_log(LOG_DEBUG, "Rules loaded:\n"); print_rules(); #endif xcpmd_log(LOG_INFO, "Entering event loop.\n"); event_dispatch(); goto xcpmd_out; xcpmd_err: ret = -1; xcpmd_out: uninit_modules(); acpi_events_cleanup(); xcpmd_dbus_cleanup(); #ifndef RUN_STANDALONE closelog(); #endif return ret; }
//Exactly what it says on the tin. void write_battery_status_to_xenstore(unsigned int battery_index) { struct battery_status * status; char bst[35], xenstore_path[128]; int num_batteries, current_battery_level; if (battery_index >= num_battery_structs_allocd) { cleanup_removed_battery(battery_index); } num_batteries = get_num_batteries_present(); if (num_batteries == 0) { xenstore_write("0", XS_BATTERY_PRESENT); return; } else { xenstore_write("1", XS_BATTERY_PRESENT); } status = &last_status[battery_index]; //Delete the BST and reset the "present" flag if the battery is not currently present. if (status->present != YES) { snprintf(xenstore_path, 255, "%s%i/%s", XS_BATTERY_PATH, battery_index, XS_BST_LEAF); xenstore_rm(xenstore_path); snprintf(xenstore_path, 255, "%s%i/%s", XS_BATTERY_PATH, battery_index, XS_BATTERY_PRESENT_LEAF); xenstore_write("0", xenstore_path); return; } //Build the BST structure. memset(bst, 0, 35); snprintf(bst, 3, "%02x", 16); write_ulong_lsb_first(bst+2, status->state); write_ulong_lsb_first(bst+10, status->present_rate); write_ulong_lsb_first(bst+18, status->remaining_capacity); write_ulong_lsb_first(bst+26, status->present_voltage); //Ensure the directory exists before trying to write the leaves make_xenstore_battery_dir(battery_index); //Now write the leaves. snprintf(xenstore_path, 255, XS_BATTERY_PATH "%i/" XS_BST_LEAF, battery_index); xenstore_write(bst, xenstore_path); snprintf(xenstore_path, 255, "%s%i/%s", XS_BATTERY_PATH, battery_index, XS_BATTERY_PRESENT_LEAF); xenstore_write("1", xenstore_path); //Here for compatibility--will be removed eventually if (battery_index == 0) xenstore_write(bst, XS_BST); else xenstore_write(bst, XS_BST1); current_battery_level = get_current_battery_level(); if (current_battery_level == NORMAL || get_ac_adapter_status() == ON_AC) xenstore_rm(XS_CURRENT_BATTERY_LEVEL); else { xenstore_write_int(current_battery_level, XS_CURRENT_BATTERY_LEVEL); notify_com_citrix_xenclient_xcpmd_battery_level_notification(xcdbus_conn, XCPMD_SERVICE, XCPMD_PATH); xcpmd_log(LOG_ALERT, "Battery level below normal - %d!\n", current_battery_level); } #ifdef XCPMD_DEBUG xcpmd_log(LOG_DEBUG, "~Updated battery information in xenstore\n"); #endif }