2006-10-02 13:18:14 +04:00
/*
* Copyright ( C ) 2004 IBM Corporation
*
* Author : Serge Hallyn < serue @ us . ibm . com >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation , version 2 of the
* License .
*/
# include <linux/module.h>
# include <linux/uts.h>
# include <linux/utsname.h>
2007-07-16 10:41:06 +04:00
# include <linux/err.h>
2008-04-29 11:59:25 +04:00
# include <linux/slab.h>
2006-10-02 13:18:14 +04:00
2009-06-18 03:27:54 +04:00
static struct uts_namespace * create_uts_ns ( void )
{
struct uts_namespace * uts_ns ;
uts_ns = kmalloc ( sizeof ( struct uts_namespace ) , GFP_KERNEL ) ;
if ( uts_ns )
kref_init ( & uts_ns - > kref ) ;
return uts_ns ;
}
2006-10-02 13:18:17 +04:00
/*
* Clone a new ns copying an original utsname , setting refcount to 1
* @ old_ns : namespace to clone
* Return NULL on error ( failure to kmalloc ) , new ns otherwise
*/
static struct uts_namespace * clone_uts_ns ( struct uts_namespace * old_ns )
{
struct uts_namespace * ns ;
2009-06-18 03:27:54 +04:00
ns = create_uts_ns ( ) ;
2007-07-16 10:41:06 +04:00
if ( ! ns )
return ERR_PTR ( - ENOMEM ) ;
2007-09-19 09:46:27 +04:00
down_read ( & uts_sem ) ;
2007-07-16 10:41:06 +04:00
memcpy ( & ns - > name , & old_ns - > name , sizeof ( ns - > name ) ) ;
2007-09-19 09:46:27 +04:00
up_read ( & uts_sem ) ;
2006-10-02 13:18:17 +04:00
return ns ;
}
2006-10-02 13:18:14 +04:00
/*
* Copy task tsk ' s utsname namespace , or clone it if flags
* specifies CLONE_NEWUTS . In latter case , changes to the
* utsname of this process won ' t be seen by parent , and vice
* versa .
*/
2007-07-16 10:41:15 +04:00
struct uts_namespace * copy_utsname ( unsigned long flags , struct uts_namespace * old_ns )
2006-10-02 13:18:14 +04:00
{
2006-10-02 13:18:17 +04:00
struct uts_namespace * new_ns ;
2006-10-02 13:18:14 +04:00
2007-05-08 11:25:21 +04:00
BUG_ON ( ! old_ns ) ;
2006-10-02 13:18:14 +04:00
get_uts_ns ( old_ns ) ;
2006-10-02 13:18:17 +04:00
if ( ! ( flags & CLONE_NEWUTS ) )
2007-05-08 11:25:21 +04:00
return old_ns ;
2006-10-02 13:18:17 +04:00
new_ns = clone_uts_ns ( old_ns ) ;
put_uts_ns ( old_ns ) ;
2007-05-08 11:25:21 +04:00
return new_ns ;
2006-10-02 13:18:14 +04:00
}
void free_uts_ns ( struct kref * kref )
{
struct uts_namespace * ns ;
ns = container_of ( kref , struct uts_namespace , kref ) ;
kfree ( ns ) ;
}