1 /* 2 * Copyright (C) 2004 IBM Corporation 3 * 4 * Author: Serge Hallyn <serue@us.ibm.com> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation, version 2 of the 9 * License. 10 */ 11 12 #include <linux/module.h> 13 #include <linux/uts.h> 14 #include <linux/utsname.h> 15 #include <linux/err.h> 16 #include <linux/slab.h> 17 18 static struct uts_namespace *create_uts_ns(void) 19 { 20 struct uts_namespace *uts_ns; 21 22 uts_ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL); 23 if (uts_ns) 24 kref_init(&uts_ns->kref); 25 return uts_ns; 26 } 27 28 /* 29 * Clone a new ns copying an original utsname, setting refcount to 1 30 * @old_ns: namespace to clone 31 * Return NULL on error (failure to kmalloc), new ns otherwise 32 */ 33 static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns) 34 { 35 struct uts_namespace *ns; 36 37 ns = create_uts_ns(); 38 if (!ns) 39 return ERR_PTR(-ENOMEM); 40 41 down_read(&uts_sem); 42 memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); 43 up_read(&uts_sem); 44 return ns; 45 } 46 47 /* 48 * Copy task tsk's utsname namespace, or clone it if flags 49 * specifies CLONE_NEWUTS. In latter case, changes to the 50 * utsname of this process won't be seen by parent, and vice 51 * versa. 52 */ 53 struct uts_namespace *copy_utsname(unsigned long flags, struct uts_namespace *old_ns) 54 { 55 struct uts_namespace *new_ns; 56 57 BUG_ON(!old_ns); 58 get_uts_ns(old_ns); 59 60 if (!(flags & CLONE_NEWUTS)) 61 return old_ns; 62 63 new_ns = clone_uts_ns(old_ns); 64 65 put_uts_ns(old_ns); 66 return new_ns; 67 } 68 69 void free_uts_ns(struct kref *kref) 70 { 71 struct uts_namespace *ns; 72 73 ns = container_of(kref, struct uts_namespace, kref); 74 kfree(ns); 75 } 76