static int _stp_register_ctl_channel_fs(void) { struct dentry *module_dir = _stp_get_module_dir(); if (module_dir == NULL) { errk("no module directory found.\n"); return -1; } /* create [debugfs]/systemtap/module_name/.cmd */ _stp_cmd_file = debugfs_create_file(".cmd", 0600, module_dir, NULL, &_stp_ctl_fops_cmd); if (_stp_cmd_file == NULL) { errk("Error creating systemtap debugfs entries.\n"); return -1; } else if (IS_ERR(_stp_cmd_file)) { _stp_cmd_file = NULL; errk("Error creating systemtap debugfs entries: %ld\n", -PTR_ERR(_stp_cmd_file)); return -1; } _stp_cmd_file->d_inode->i_uid = _stp_uid; _stp_cmd_file->d_inode->i_gid = _stp_gid; return 0; }
static void _stp_do_relocation(const char __user *buf, size_t count) { static struct _stp_msg_relocation msg; /* by protocol, never concurrently used */ static struct _stp13_msg_relocation msg13; /* ditto */ /* PR12612: Let's try to be compatible with systemtap modules being compiled by new systemtap, but loaded (staprun'd) by an older systemtap runtime. The only known incompatilibility is that we get an older, smaller, relocation message. So here we accept both sizes. */ if (sizeof(msg) == count) { /* systemtap 1.4+ runtime */ if (unlikely(copy_from_user (& msg, buf, count))) return; } else if (sizeof(msg13) == count) { /* systemtap 1.3- runtime */ if (unlikely(copy_from_user (& msg13, buf, count))) return; #if STP_MODULE_NAME_LEN <= STP13_MODULE_NAME_LEN #error "STP_MODULE_NAME_LEN should not be smaller than STP13_MODULE_NAME_LEN" #endif strlcpy (msg.module, msg13.module, STP13_MODULE_NAME_LEN); strlcpy (msg.reloc, msg13.reloc, STP13_MODULE_NAME_LEN); msg.address = msg13.address; } else { errk ("STP_RELOCATE message size mismatch (%lu or %lu vs %lu)\n", (long unsigned) sizeof(msg), (long unsigned) sizeof (msg13), (long unsigned) count); return; } dbug_sym(2, "relocate (%s %s 0x%lx)\n", msg.module, msg.reloc, (unsigned long) msg.address); /* Detect actual kernel load address. */ if (!strcmp ("kernel", msg.module) && !strcmp ("_stext", msg.reloc)) { dbug_sym(2, "found kernel _stext load address: 0x%lx\n", (unsigned long) msg.address); if (_stp_kretprobe_trampoline != (unsigned long) -1) _stp_kretprobe_trampoline += (unsigned long) msg.address; } _stp_kmodule_update_address(msg.module, msg.reloc, msg.address); }
static int _stp_lock_transport_dir(void) { int numtries = 0; #if STP_TRANSPORT_VERSION == 1 while ((_stp_lockfile = relayfs_create_dir("systemtap_lock", NULL)) == NULL) { #else while ((_stp_lockfile = debugfs_create_dir("systemtap_lock", NULL)) == NULL) { #endif if (numtries++ >= 50) return 0; msleep(50); } return 1; } static void _stp_unlock_transport_dir(void) { if (_stp_lockfile) { #if STP_TRANSPORT_VERSION == 1 relayfs_remove_dir(_stp_lockfile); #else debugfs_remove(_stp_lockfile); #endif _stp_lockfile = NULL; } } static struct dentry *__stp_root_dir = NULL; /* _stp_get_root_dir() - creates root directory or returns * a pointer to it if it already exists. * * The caller *must* lock the transport directory. */ static struct dentry *_stp_get_root_dir(void) { struct file_system_type *fs; struct super_block *sb; const char *name = "systemtap"; if (__stp_root_dir != NULL) { return __stp_root_dir; } #if STP_TRANSPORT_VERSION == 1 fs = get_fs_type("relayfs"); if (!fs) { errk("Couldn't find relayfs filesystem.\n"); return NULL; } #else fs = get_fs_type("debugfs"); if (!fs) { errk("Couldn't find debugfs filesystem.\n"); return NULL; } #endif #if STP_TRANSPORT_VERSION == 1 __stp_root_dir = relayfs_create_dir(name, NULL); #else __stp_root_dir = debugfs_create_dir(name, NULL); #endif if (!__stp_root_dir) { /* Couldn't create it because it is already there, so * find it. */ #ifdef STAPCONF_FS_SUPERS_HLIST sb = hlist_entry(fs->fs_supers.first, struct super_block, s_instances); #else sb = list_entry(fs->fs_supers.next, struct super_block, s_instances); #endif _stp_lock_inode(sb->s_root->d_inode); __stp_root_dir = lookup_one_len(name, sb->s_root, strlen(name)); _stp_unlock_inode(sb->s_root->d_inode); if (!IS_ERR(__stp_root_dir)) dput(__stp_root_dir); else { __stp_root_dir = NULL; errk("Could not create or find transport directory.\n"); } } else if (IS_ERR(__stp_root_dir)) {
/* * Safely creates '/proc/systemtap' (if necessary) and * '/proc/systemtap/{module_name}'. * * NB: this function is suitable to call from early in the the * module-init function, and doesn't rely on any other facilities * in our runtime. PR19833. See also PR15408. */ static int _stp_mkdir_proc_module(void) { int found = 0; static char proc_root_name[STP_MODULE_NAME_LEN + sizeof("systemtap/")]; #if defined(STAPCONF_PATH_LOOKUP) || defined(STAPCONF_KERN_PATH_PARENT) struct nameidata nd; #else /* STAPCONF_VFS_PATH_LOOKUP or STAPCONF_KERN_PATH */ struct path path; #if defined(STAPCONF_VFS_PATH_LOOKUP) struct vfsmount *mnt; #endif int rc; #endif /* STAPCONF_VFS_PATH_LOOKUP or STAPCONF_KERN_PATH */ if (_stp_proc_root != NULL) return 0; #if defined(STAPCONF_PATH_LOOKUP) || defined(STAPCONF_KERN_PATH_PARENT) /* Why "/proc/systemtap/foo"? kern_path_parent() is basically * the same thing as calling the old path_lookup() with flags * set to LOOKUP_PARENT, which means to look up the parent of * the path, which in this case is "/proc/systemtap". */ if (! kern_path_parent("/proc/systemtap/foo", &nd)) { found = 1; #ifdef STAPCONF_NAMEIDATA_CLEANUP path_put(&nd.path); #else /* !STAPCONF_NAMEIDATA_CLEANUP */ path_release(&nd); #endif /* !STAPCONF_NAMEIDATA_CLEANUP */ } #elif defined(STAPCONF_KERN_PATH) /* Prefer kern_path() over vfs_path_lookup(), since on some * kernels the declaration for vfs_path_lookup() was moved to * a private header. */ /* See if '/proc/systemtap' exists. */ rc = kern_path("/proc/systemtap", 0, &path); if (rc == 0) { found = 1; path_put (&path); } #else /* STAPCONF_VFS_PATH_LOOKUP */ /* See if '/proc/systemtap' exists. */ if (! init_pid_ns.proc_mnt) { errk("Unable to create '/proc/systemap':" " '/proc' doesn't exist.\n"); goto done; } mnt = init_pid_ns.proc_mnt; rc = vfs_path_lookup(mnt->mnt_root, mnt, "systemtap", 0, &path); if (rc == 0) { found = 1; path_put (&path); } #endif /* STAPCONF_VFS_PATH_LOOKUP */ /* If we couldn't find "/proc/systemtap", create it. */ if (!found) { struct proc_dir_entry *de; de = proc_mkdir ("systemtap", NULL); if (de == NULL) { errk("Unable to create '/proc/systemap':" " proc_mkdir failed.\n"); goto done; } } /* Create the "systemtap/{module_name} directory in procfs. */ strlcpy(proc_root_name, "systemtap/", sizeof(proc_root_name)); strlcat(proc_root_name, THIS_MODULE->name, sizeof(proc_root_name)); _stp_proc_root = proc_mkdir(proc_root_name, NULL); #ifdef STAPCONF_PROCFS_OWNER if (_stp_proc_root != NULL) _stp_proc_root->owner = THIS_MODULE; #endif if (_stp_proc_root == NULL) errk("Unable to create '/proc/systemap/%s':" " proc_mkdir failed.\n", THIS_MODULE->name); done: return (_stp_proc_root) ? 0 : -EINVAL; }