/* * Set the PF_NOFREEZE flag on the given process to ensure it can run whilst we * are hibernating. */ static int nl_set_nofreeze(struct user_helper_data *uhd, __u32 pid) { struct task_struct *t; if (uhd->debug) printk(KERN_ERR "nl_set_nofreeze for pid %d.\n", pid); read_lock(&tasklist_lock); t = find_task_by_pid_type_ns(PIDTYPE_PID, pid, &init_pid_ns); if (!t) { read_unlock(&tasklist_lock); printk(KERN_INFO "Strange. Can't find the userspace task %d.\n", pid); return -EINVAL; } t->flags |= PF_NOFREEZE; read_unlock(&tasklist_lock); uhd->pid = pid; toi_send_netlink_message(uhd, NETLINK_MSG_NOFREEZE_ACK, NULL, 0); return 0; }
static void send_whether_debugging(struct user_helper_data *uhd) { static u8 is_debugging = 1; toi_send_netlink_message(uhd, NETLINK_MSG_IS_DEBUGGING, &is_debugging, sizeof(u8)); }
int toi_activate_storage(int force) { int tries = 1; if (usm_helper_data.pid == -1 || !usm_ops.enabled) return 0; message_received = 0; activations++; if (activations > 1 && !force) return 0; while ((!message_received || message_received == USM_MSG_FAILED) && tries < 2) { toi_prepare_status(DONT_CLEAR_BAR, "Activate storage attempt " "%d.\n", tries); init_completion(&usm_helper_data.wait_for_process); toi_send_netlink_message(&usm_helper_data, USM_MSG_CONNECT, NULL, 0); /* Wait 2 seconds for the userspace process to make contact */ wait_for_completion_timeout(&usm_helper_data.wait_for_process, 2 * HZ); tries++; } return 0; }
int toi_deactivate_storage(int force) { if (usm_helper_data.pid == -1 || !usm_ops.enabled) return 0; message_received = 0; activations--; if (activations && !force) return 0; init_completion(&usm_helper_data.wait_for_process); toi_send_netlink_message(&usm_helper_data, USM_MSG_DISCONNECT, NULL, 0); wait_for_completion_timeout(&usm_helper_data.wait_for_process, 2*HZ); if (!message_received || message_received == USM_MSG_FAILED) { printk(KERN_INFO "Returning failure disconnecting storage.\n"); return 1; } return 0; }
void toi_netlink_close(struct user_helper_data *uhd) { struct task_struct *t; read_lock(&tasklist_lock); t = find_task_by_pid_type_ns(PIDTYPE_PID, uhd->pid, &init_pid_ns); if (t) t->flags &= ~PF_NOFREEZE; read_unlock(&tasklist_lock); toi_send_netlink_message(uhd, NETLINK_MSG_CLEANUP, NULL, 0); }
/** * userui_post_atomic_restore - Tell userui that atomic restore just happened. * * Tell userui that atomic restore just occured, so that it can do things like * redrawing the screen, re-getting settings and so on. */ static void userui_post_atomic_restore(void) { toi_send_netlink_message(&ui_helper_data, USERUI_MSG_POST_ATOMIC_RESTORE, NULL, 0); }
static int netlink_prepare(struct user_helper_data *uhd) { struct netlink_kernel_cfg cfg = { .groups = 0, .input = toi_user_rcv_skb, }; uhd->next = uhd_list; uhd_list = uhd; uhd->sock_seq = 0x42c0ffee; uhd->nl = netlink_kernel_create(&init_net, uhd->netlink_id, &cfg); if (!uhd->nl) { printk(KERN_INFO "Failed to allocate netlink socket for %s.\n", uhd->name); return -ENOMEM; } toi_fill_skb_pool(uhd); return 0; } void toi_netlink_close(struct user_helper_data *uhd) { struct task_struct *t; toi_read_lock_tasklist(); t = find_task_by_pid_ns(uhd->pid, &init_pid_ns); if (t) t->flags &= ~PF_NOFREEZE; toi_read_unlock_tasklist(); toi_send_netlink_message(uhd, NETLINK_MSG_CLEANUP, NULL, 0); } EXPORT_SYMBOL_GPL(toi_netlink_close); int toi_netlink_setup(struct user_helper_data *uhd) { /* In case userui didn't cleanup properly on us */ toi_netlink_close_complete(uhd); if (netlink_prepare(uhd) < 0) { printk(KERN_INFO "Netlink prepare failed.\n"); return 1; } if (toi_launch_userspace_program(uhd->program, uhd->netlink_id, UMH_WAIT_EXEC, uhd->debug) < 0) { printk(KERN_INFO "Launch userspace program failed.\n"); toi_netlink_close_complete(uhd); return 1; } /* Wait 2 seconds for the userspace process to make contact */ wait_for_completion_timeout(&uhd->wait_for_process, 2*HZ); if (uhd->pid == -1) { printk(KERN_INFO "%s: Failed to contact userspace process.\n", uhd->name); toi_netlink_close_complete(uhd); return 1; } return 0; }