⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 appldata_base.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	__appldata_vtimer_setup(APPLDATA_MOD_TIMER);	spin_unlock(&appldata_timer_lock);	P_INFO("Monitoring CPU interval set to %u milliseconds.\n",		 interval);out:	*lenp = len;	*ppos += len;	return 0;}/* * appldata_generic_handler() * * Generic start/stop monitoring and DIAG, show status of * monitoring (0 = not in process, 1 = in process) */static intappldata_generic_handler(ctl_table *ctl, int write, struct file *filp,			   void __user *buffer, size_t *lenp, loff_t *ppos){	struct appldata_ops *ops = NULL, *tmp_ops;	int rc, len, found;	char buf[2];	struct list_head *lh;	found = 0;	spin_lock(&appldata_ops_lock);	list_for_each(lh, &appldata_ops_list) {		tmp_ops = list_entry(lh, struct appldata_ops, list);		if (&tmp_ops->ctl_table[2] == ctl) {			found = 1;		}	}	if (!found) {		spin_unlock(&appldata_ops_lock);		return -ENODEV;	}	ops = ctl->data;	if (!try_module_get(ops->owner)) {	// protect this function		spin_unlock(&appldata_ops_lock);		return -ENODEV;	}	spin_unlock(&appldata_ops_lock);	if (!*lenp || *ppos) {		*lenp = 0;		module_put(ops->owner);		return 0;	}	if (!write) {		len = sprintf(buf, ops->active ? "1\n" : "0\n");		if (len > *lenp)			len = *lenp;		if (copy_to_user(buffer, buf, len)) {			module_put(ops->owner);			return -EFAULT;		}		goto out;	}	len = *lenp;	if (copy_from_user(buf, buffer,			   len > sizeof(buf) ? sizeof(buf) : len)) {		module_put(ops->owner);		return -EFAULT;	}	spin_lock(&appldata_ops_lock);	if ((buf[0] == '1') && (ops->active == 0)) {		// protect work queue callback		if (!try_module_get(ops->owner)) {			spin_unlock(&appldata_ops_lock);			module_put(ops->owner);			return -ENODEV;		}		ops->active = 1;		ops->callback(ops->data);	// init record		rc = appldata_diag(ops->record_nr,					APPLDATA_START_INTERVAL_REC,					(unsigned long) ops->data, ops->size);		if (rc != 0) {			P_ERROR("START DIAG 0xDC for %s failed, "				"return code: %d\n", ops->name, rc);			module_put(ops->owner);			ops->active = 0;		} else {			P_INFO("Monitoring %s data enabled, "				"DIAG 0xDC started.\n", ops->name);		}	} else if ((buf[0] == '0') && (ops->active == 1)) {		ops->active = 0;		rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,				(unsigned long) ops->data, ops->size);		if (rc != 0) {			P_ERROR("STOP DIAG 0xDC for %s failed, "				"return code: %d\n", ops->name, rc);		} else {			P_INFO("Monitoring %s data disabled, "				"DIAG 0xDC stopped.\n", ops->name);		}		module_put(ops->owner);	}	spin_unlock(&appldata_ops_lock);out:	*lenp = len;	*ppos += len;	module_put(ops->owner);	return 0;}/*************************** /proc stuff <END> *******************************//************************* module-ops management *****************************//* * appldata_register_ops() * * update ops list, register /proc/sys entries */int appldata_register_ops(struct appldata_ops *ops){	struct list_head *lh;	struct appldata_ops *tmp_ops;	int i;	i = 0;	if ((ops->size > APPLDATA_MAX_REC_SIZE) ||		(ops->size < 0)){		P_ERROR("Invalid size of %s record = %i, maximum = %i!\n",			ops->name, ops->size, APPLDATA_MAX_REC_SIZE);		return -ENOMEM;	}	if ((ops->ctl_nr == CTL_APPLDATA) ||	    (ops->ctl_nr == CTL_APPLDATA_TIMER) ||	    (ops->ctl_nr == CTL_APPLDATA_INTERVAL)) {		P_ERROR("ctl_nr %i already in use!\n", ops->ctl_nr);		return -EBUSY;	}	ops->ctl_table = kmalloc(4*sizeof(struct ctl_table), GFP_KERNEL);	if (ops->ctl_table == NULL) {		P_ERROR("Not enough memory for %s ctl_table!\n", ops->name);		return -ENOMEM;	}	memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table));	spin_lock(&appldata_ops_lock);	list_for_each(lh, &appldata_ops_list) {		tmp_ops = list_entry(lh, struct appldata_ops, list);		P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n",			++i, tmp_ops->name, tmp_ops->ctl_nr);		P_DEBUG("Comparing %s (ctl %i) with %s (ctl %i)\n",			tmp_ops->name, tmp_ops->ctl_nr, ops->name,			ops->ctl_nr);		if (strncmp(tmp_ops->name, ops->name,				APPLDATA_PROC_NAME_LENGTH) == 0) {			P_ERROR("Name \"%s\" already registered!\n", ops->name);			kfree(ops->ctl_table);			spin_unlock(&appldata_ops_lock);			return -EBUSY;		}		if (tmp_ops->ctl_nr == ops->ctl_nr) {			P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr);			kfree(ops->ctl_table);			spin_unlock(&appldata_ops_lock);			return -EBUSY;		}	}	list_add(&ops->list, &appldata_ops_list);	spin_unlock(&appldata_ops_lock);	ops->ctl_table[0].ctl_name = CTL_APPLDATA;	ops->ctl_table[0].procname = appldata_proc_name;	ops->ctl_table[0].maxlen   = 0;	ops->ctl_table[0].mode     = S_IRUGO | S_IXUGO;	ops->ctl_table[0].child    = &ops->ctl_table[2];	ops->ctl_table[1].ctl_name = 0;	ops->ctl_table[2].ctl_name = ops->ctl_nr;	ops->ctl_table[2].procname = ops->name;	ops->ctl_table[2].mode     = S_IRUGO | S_IWUSR;	ops->ctl_table[2].proc_handler = appldata_generic_handler;	ops->ctl_table[2].data = ops;	ops->ctl_table[3].ctl_name = 0;	ops->sysctl_header = register_sysctl_table(ops->ctl_table,1);	P_INFO("%s-ops registered!\n", ops->name);	return 0;}/* * appldata_unregister_ops() * * update ops list, unregister /proc entries, stop DIAG if necessary */void appldata_unregister_ops(struct appldata_ops *ops){	void *table;	spin_lock(&appldata_ops_lock);	list_del(&ops->list);	/* at that point any incoming access will fail */	table = ops->ctl_table;	ops->ctl_table = NULL;	spin_unlock(&appldata_ops_lock);	unregister_sysctl_table(ops->sysctl_header);	kfree(table);	P_INFO("%s-ops unregistered!\n", ops->name);}/********************** module-ops management <END> **************************//******************************* init / exit *********************************/static voidappldata_online_cpu(int cpu){	init_virt_timer(&per_cpu(appldata_timer, cpu));	per_cpu(appldata_timer, cpu).function = appldata_timer_function;	per_cpu(appldata_timer, cpu).data = (unsigned long)		&appldata_work;	atomic_inc(&appldata_expire_count);	spin_lock(&appldata_timer_lock);	__appldata_vtimer_setup(APPLDATA_MOD_TIMER);	spin_unlock(&appldata_timer_lock);}static voidappldata_offline_cpu(int cpu){	del_virt_timer(&per_cpu(appldata_timer, cpu));	if (atomic_dec_and_test(&appldata_expire_count)) {		atomic_set(&appldata_expire_count, num_online_cpus());		queue_work(appldata_wq, &appldata_work);	}	spin_lock(&appldata_timer_lock);	__appldata_vtimer_setup(APPLDATA_MOD_TIMER);	spin_unlock(&appldata_timer_lock);}static intappldata_cpu_notify(struct notifier_block *self,		    unsigned long action, void *hcpu){	switch (action) {	case CPU_ONLINE:		appldata_online_cpu((long) hcpu);		break;#ifdef CONFIG_HOTPLUG_CPU	case CPU_DEAD:		appldata_offline_cpu((long) hcpu);		break;#endif	default:		break;	}	return NOTIFY_OK;}static struct notifier_block __devinitdata appldata_nb = {	.notifier_call = appldata_cpu_notify,};/* * appldata_init() * * init timer, register /proc entries */static int __init appldata_init(void){	int i;	P_DEBUG("sizeof(parameter_list) = %lu\n",		sizeof(struct appldata_parameter_list));	appldata_wq = create_singlethread_workqueue("appldata");	if (!appldata_wq) {		P_ERROR("Could not create work queue\n");		return -ENOMEM;	}	for_each_online_cpu(i)		appldata_online_cpu(i);	/* Register cpu hotplug notifier */	register_cpu_notifier(&appldata_nb);	appldata_sysctl_header = register_sysctl_table(appldata_dir_table, 1);#ifdef MODULE	appldata_dir_table[0].de->owner = THIS_MODULE;	appldata_table[0].de->owner = THIS_MODULE;	appldata_table[1].de->owner = THIS_MODULE;#endif	P_DEBUG("Base interface initialized.\n");	return 0;}/* * appldata_exit() * * stop timer, unregister /proc entries */static void __exit appldata_exit(void){	struct list_head *lh;	struct appldata_ops *ops;	int rc, i;	P_DEBUG("Unloading module ...\n");	/*	 * ops list should be empty, but just in case something went wrong...	 */	spin_lock(&appldata_ops_lock);	list_for_each(lh, &appldata_ops_list) {		ops = list_entry(lh, struct appldata_ops, list);		rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,				(unsigned long) ops->data, ops->size);		if (rc != 0) {			P_ERROR("STOP DIAG 0xDC for %s failed, "				"return code: %d\n", ops->name, rc);		}	}	spin_unlock(&appldata_ops_lock);	for_each_online_cpu(i)		appldata_offline_cpu(i);	appldata_timer_active = 0;	unregister_sysctl_table(appldata_sysctl_header);	destroy_workqueue(appldata_wq);	P_DEBUG("... module unloaded!\n");}/**************************** init / exit <END> ******************************/module_init(appldata_init);module_exit(appldata_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Gerald Schaefer");MODULE_DESCRIPTION("Linux-VM Monitor Stream, base infrastructure");EXPORT_SYMBOL_GPL(appldata_register_ops);EXPORT_SYMBOL_GPL(appldata_unregister_ops);#ifdef MODULE/* * Kernel symbols needed by appldata_mem and appldata_os modules. * However, if this file is compiled as a module (for testing only), these * symbols are not exported. In this case, we define them locally and export * those. */void si_swapinfo(struct sysinfo *val){	val->freeswap = -1ul;	val->totalswap = -1ul;}unsigned long avenrun[3] = {-1 - FIXED_1/200, -1 - FIXED_1/200,				-1 - FIXED_1/200};int nr_threads = -1;void get_full_page_state(struct page_state *ps){	memset(ps, -1, sizeof(struct page_state));}unsigned long nr_running(void){	return -1;}unsigned long nr_iowait(void){	return -1;}/*unsigned long nr_context_switches(void){	return -1;}*/#endif /* MODULE */EXPORT_SYMBOL_GPL(si_swapinfo);EXPORT_SYMBOL_GPL(nr_threads);EXPORT_SYMBOL_GPL(avenrun);EXPORT_SYMBOL_GPL(get_full_page_state);EXPORT_SYMBOL_GPL(nr_running);EXPORT_SYMBOL_GPL(nr_iowait);//EXPORT_SYMBOL_GPL(nr_context_switches);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -