mcctrl: use IHK OS notifiers to establish/tear down syscall channels

This patch eliminates the need for rmmod/insmod the mcctrl module
every time an OS instance is rebooted.
This commit is contained in:
Balazs Gerofi
2016-07-11 16:22:50 +09:00
parent d135731398
commit 7d9bbecd7a
3 changed files with 83 additions and 54 deletions

View File

@ -87,11 +87,6 @@ if [ "$cpus" == "" ]; then
if [ "$cpus" == "" ]; then echo "error: no available CPUs on NUMA node 0?"; exit; fi if [ "$cpus" == "" ]; then echo "error: no available CPUs on NUMA node 0?"; exit; fi
fi fi
# Remove delegator if loaded
if [ "`lsmod | grep mcctrl`" != "" ]; then
if ! rmmod mcctrl; then echo "error: removing mcctrl"; exit; fi
fi
# Remove mcoverlay if loaded # Remove mcoverlay if loaded
if [ "$enable_mcoverlay" == "yes" ]; then if [ "$enable_mcoverlay" == "yes" ]; then
if [ "`lsmod | grep mcoverlay`" != "" ]; then if [ "`lsmod | grep mcoverlay`" != "" ]; then
@ -137,6 +132,11 @@ else
fi fi
fi fi
# Load mcctrl if not loaded
if [ "`lsmod | grep mcctrl`" == "" ]; then
if ! insmod ${KMODDIR}/mcctrl.ko; then echo "error: inserting mcctrl.ko"; exit; fi
fi
# Check for existing OS instance and destroy # Check for existing OS instance and destroy
if [ -c /dev/mcos0 ]; then if [ -c /dev/mcos0 ]; then
# Query CPU cores and memory of OS instance so that the same values are used as previously # Query CPU cores and memory of OS instance so that the same values are used as previously
@ -160,7 +160,6 @@ if ! ${SBINDIR}/ihkosctl 0 assign mem ${mem}; then echo "error: assign memory";
if ! ${SBINDIR}/ihkosctl 0 load ${KERNDIR}/mckernel.img; then echo "error: loading kernel image"; exit; fi if ! ${SBINDIR}/ihkosctl 0 load ${KERNDIR}/mckernel.img; then echo "error: loading kernel image"; exit; fi
if ! ${SBINDIR}/ihkosctl 0 kargs "hidos ksyslogd=${LOGMODE}"; then echo "error: setting kernel arguments"; exit; fi if ! ${SBINDIR}/ihkosctl 0 kargs "hidos ksyslogd=${LOGMODE}"; then echo "error: setting kernel arguments"; exit; fi
if ! ${SBINDIR}/ihkosctl 0 boot; then echo "error: booting"; exit; fi if ! ${SBINDIR}/ihkosctl 0 boot; then echo "error: booting"; exit; fi
if ! insmod ${KMODDIR}/mcctrl.ko; then echo "error: inserting mcctrl.ko"; exit; fi
if ! chown `logname` /dev/mcd* /dev/mcos*; then echo "error: chowning device files"; exit; fi if ! chown `logname` /dev/mcd* /dev/mcos*; then echo "error: chowning device files"; exit; fi
if [ "$enable_mcoverlay" == "yes" ]; then if [ "$enable_mcoverlay" == "yes" ]; then

View File

@ -255,7 +255,7 @@ void __init binfmt_mcexec_init(void)
insert_binfmt(&mcexec_format); insert_binfmt(&mcexec_format);
} }
void __exit binfmt_mcexec_exit(void) void binfmt_mcexec_exit(void)
{ {
unregister_binfmt(&mcexec_format); unregister_binfmt(&mcexec_format);
} }

View File

@ -82,79 +82,109 @@ static struct ihk_os_user_call mcctrl_uc[OS_MAX_MINOR];
static ihk_os_t os[OS_MAX_MINOR]; static ihk_os_t os[OS_MAX_MINOR];
ihk_os_t ihk_os_t osnum_to_os(int n)
osnum_to_os(int n)
{ {
return os[n]; return os[n];
} }
static int __init mcctrl_init(void) /* OS event notifier implementation */
int mcctrl_os_boot_notifier(int os_index)
{ {
int i;
int rc; int rc;
rc = -ENOENT; os[os_index] = ihk_host_find_os(os_index, NULL);
for(i = 0; i < OS_MAX_MINOR; i++){ if (!os[os_index]) {
os[i] = ihk_host_find_os(i, NULL); printk("mcctrl: error: OS ID %d couldn't be found\n", os_index);
if (os[i]) { return -EINVAL;
printk("OS #%d found.\n", i);
rc = 0;
}
}
if(rc){
printk("OS not found.\n");
return rc;
} }
for(i = 0; i < OS_MAX_MINOR; i++){ if (prepare_ikc_channels(os[os_index]) != 0) {
if (os[i]) { printk("mcctrl: error: preparing IKC channels for OS %d\n", os_index);
if (prepare_ikc_channels(os[i]) != 0) {
printk("Preparing syscall channels failed.\n"); os[os_index] = NULL;
os[i] = NULL; return -EFAULT;
}
}
} }
memcpy(mcctrl_uc + os_index, &mcctrl_uc_proto, sizeof mcctrl_uc_proto);
rc = ihk_os_register_user_call_handlers(os[os_index], mcctrl_uc + os_index);
if (rc < 0) {
destroy_ikc_channels(os[os_index]);
printk("mcctrl: error: registering callbacks for OS %d\n", os_index);
goto error_cleanup_channels;
}
procfs_init(os_index);
printk("mcctrl: OS ID %d boot event handled\n", os_index);
return 0;
error_cleanup_channels:
destroy_ikc_channels(os[os_index]);
os[os_index] = NULL;
return rc;
}
int mcctrl_os_shutdown_notifier(int os_index)
{
sysfsm_cleanup(os[os_index]);
free_topology_info(os[os_index]);
ihk_os_unregister_user_call_handlers(os[os_index], mcctrl_uc + os_index);
destroy_ikc_channels(os[os_index]);
procfs_exit(os_index);
printk("mcctrl: OS ID %d shutdown event handled\n", os_index);
return 0;
}
static struct ihk_os_notifier_ops mcctrl_os_notifier_ops = {
.boot = mcctrl_os_boot_notifier,
.shutdown = mcctrl_os_shutdown_notifier,
};
static struct ihk_os_notifier mcctrl_os_notifier = {
.ops = &mcctrl_os_notifier_ops,
};
static int __init mcctrl_init(void)
{
int ret = 0;
#ifndef DO_USER_MODE #ifndef DO_USER_MODE
mcctrl_syscall_init(); mcctrl_syscall_init();
#endif #endif
rus_page_hash_init(); rus_page_hash_init();
for(i = 0; i < OS_MAX_MINOR; i++){
if (os[i]) {
memcpy(mcctrl_uc + i, &mcctrl_uc_proto, sizeof mcctrl_uc_proto);
rc = ihk_os_register_user_call_handlers(os[i], mcctrl_uc + i);
if(rc < 0){
destroy_ikc_channels(os[i]);
os[i] = NULL;
}
procfs_init(i);
}
}
binfmt_mcexec_init(); binfmt_mcexec_init();
return 0; if ((ret = ihk_host_register_os_notifier(&mcctrl_os_notifier)) != 0) {
printk("mcctrl: error: registering OS notifier\n");
goto error;
}
printk("mcctrl: initialized successfully.\n");
return ret;
error:
binfmt_mcexec_exit();
rus_page_hash_put_pages();
return ret;
} }
static void __exit mcctrl_exit(void) static void __exit mcctrl_exit(void)
{ {
int i; if (ihk_host_deregister_os_notifier(&mcctrl_os_notifier) != 0) {
printk("mcctrl: warning: failed to deregister OS notifier??\n");
binfmt_mcexec_exit();
printk("mcctrl: unregistered.\n");
for(i = 0; i < OS_MAX_MINOR; i++){
if(os[i]){
sysfsm_cleanup(os[i]);
free_topology_info(os[i]);
ihk_os_unregister_user_call_handlers(os[i], mcctrl_uc + i);
destroy_ikc_channels(os[i]);
procfs_exit(i);
}
} }
binfmt_mcexec_exit();
rus_page_hash_put_pages(); rus_page_hash_put_pages();
printk("mcctrl: unregistered.\n");
} }
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");