namespace.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * linux/ipc/namespace.c
  3. * Copyright (C) 2006 Pavel Emelyanov <xemul@openvz.org> OpenVZ, SWsoft Inc.
  4. */
  5. #include <linux/ipc.h>
  6. #include <linux/msg.h>
  7. #include <linux/ipc_namespace.h>
  8. #include <linux/rcupdate.h>
  9. #include <linux/nsproxy.h>
  10. #include <linux/slab.h>
  11. #include "util.h"
  12. static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
  13. {
  14. int err;
  15. struct ipc_namespace *ns;
  16. err = -ENOMEM;
  17. ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
  18. if (ns == NULL)
  19. goto err_mem;
  20. err = sem_init_ns(ns);
  21. if (err)
  22. goto err_sem;
  23. err = msg_init_ns(ns);
  24. if (err)
  25. goto err_msg;
  26. err = shm_init_ns(ns);
  27. if (err)
  28. goto err_shm;
  29. kref_init(&ns->kref);
  30. return ns;
  31. err_shm:
  32. msg_exit_ns(ns);
  33. err_msg:
  34. sem_exit_ns(ns);
  35. err_sem:
  36. kfree(ns);
  37. err_mem:
  38. return ERR_PTR(err);
  39. }
  40. struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
  41. {
  42. struct ipc_namespace *new_ns;
  43. BUG_ON(!ns);
  44. get_ipc_ns(ns);
  45. if (!(flags & CLONE_NEWIPC))
  46. return ns;
  47. new_ns = clone_ipc_ns(ns);
  48. put_ipc_ns(ns);
  49. return new_ns;
  50. }
  51. void free_ipc_ns(struct kref *kref)
  52. {
  53. struct ipc_namespace *ns;
  54. ns = container_of(kref, struct ipc_namespace, kref);
  55. sem_exit_ns(ns);
  56. msg_exit_ns(ns);
  57. shm_exit_ns(ns);
  58. kfree(ns);
  59. }