Esempio n. 1
0
static gboolean
_nmp_netns_push_type (NMPNetns *self, int ns_types)
{
	NetnsInfo *info;
	char sbuf[100];

	_stack_ensure_init ();

	info = _stack_peek ();
	g_return_val_if_fail (info, FALSE);

	if (info->netns == self && info->ns_types == ns_types) {
		info->count++;
		_LOGt (self, "push#%u* %s (increase count to %d)",
		       _stack_size () - 1,
		       _ns_types_to_str (ns_types, ns_types, sbuf), info->count);
		return TRUE;
	}

	_LOGD (self, "push#%u %s",
	       _stack_size (),
	       _ns_types_to_str (ns_types,
	                         _stack_current_ns_types (self, ns_types),
	                         sbuf));

	if (!_netns_switch_push (self, ns_types))
		return FALSE;

	_stack_push (self, ns_types);
	return TRUE;
}
Esempio n. 2
0
// -----[ _radix_tree_enum_has_next ]--------------------------------
static int _radix_tree_enum_has_next(void * ctx)
{
  _enum_ctx_t * ectx= (_enum_ctx_t *) ctx;

  // Depth first search
  while ((ectx->data == NULL) && (ectx->tree_item != NULL)) {

    if (ectx->tree_item->data != NULL)
      ectx->data= ectx->tree_item->data;

    // Move to next item
    if (ectx->tree_item->left != NULL) {
      if (ectx->tree_item->right != NULL)
	_stack_push(ectx->stack, ectx->tree_item->right, ectx->key_len+1,
		    ectx->key+(1 << (ectx->tree->key_len-ectx->key_len-1)));
      ectx->tree_item= ectx->tree_item->left;
      ectx->key_len++;
    } else if (ectx->tree_item->right != NULL) {
      ectx->tree_item= ectx->tree_item->right;
      ectx->key= ectx->key+(1 << (ectx->tree->key_len-ectx->key_len-1));
      ectx->key_len++;
    } else {
      if (stack_depth(ectx->stack) > 0)
	_stack_pop(ectx->stack, &ectx->tree_item, &ectx->key_len, &ectx->key);
      else
	ectx->tree_item= NULL;
    }
  }
  return (ectx->data != NULL);
}
Esempio n. 3
0
static void
_stack_ensure_init_impl (void)
{
	NMPNetns *netns;
	GError *error = NULL;

	nm_assert (!netns_stack);

	netns_stack = g_array_new (FALSE, FALSE, sizeof (NetnsInfo));

	/* at the bottom of the stack we must try to create a netns instance
	 * that we never pop. It's the base to which we need to return. */

	netns = _netns_new (&error);

	if (!netns) {
		/* don't know how to recover from this error. Netns are not supported. */
		_LOGE (NULL, "failed to create initial netns: %s", error->message);
		g_clear_error (&error);
		return;
	}

	_stack_push (netns, _CLONE_NS_ALL);

	/* we leak this instance inside netns_stack. It cannot be popped. */
	g_object_unref (netns);
}
Esempio n. 4
0
NMPNetns *
nmp_netns_new (void)
{
	NMPNetns *self;
	int errsv;
	GError *error = NULL;

	_stack_ensure_init ();

	if (!_stack_peek ()) {
		/* there are no netns instances. We cannot create a new one
		 * (because after unshare we couldn't return to the original one). */
		return NULL;
	}

	if (unshare (_CLONE_NS_ALL) != 0) {
		errsv = errno;
		_LOGE (NULL, "failed to create new net and mnt namespace: %s", g_strerror (errsv));
		return NULL;
	}

	if (mount ("", "/", "none", MS_SLAVE | MS_REC, NULL) != 0) {
		errsv = errno;
		_LOGE (NULL, "failed mount --make-rslave: %s", g_strerror (errsv));
		goto err_out;
	}

	if (umount2 ("/sys", MNT_DETACH) != 0) {
		errsv = errno;
		_LOGE (NULL, "failed umount /sys: %s", g_strerror (errsv));
		goto err_out;
	}

	if (mount ("sysfs", "/sys", "sysfs", 0, NULL) != 0) {
		errsv = errno;
		_LOGE (NULL, "failed mount /sys: %s", g_strerror (errsv));
		goto err_out;
	}

	self = _netns_new (&error);
	if (!self) {
		_LOGE (NULL, "failed to create netns after unshare: %s", error->message);
		g_clear_error (&error);
		goto err_out;
	}

	_stack_push (self, _CLONE_NS_ALL);

	return self;
err_out:
	_netns_switch_pop (NULL, _CLONE_NS_ALL);
	return NULL;
}
Esempio n. 5
0
/**
 * Call the 'fForEach' function for each non empty node.
 */
int radix_tree_for_each(gds_radix_tree_t * tree,
			FRadixTreeForEach fForEach,
			void * ctx)
{
  gds_stack_t * stack= stack_create(tree->key_len);
  _radix_tree_item_t * tree_item;
  int result= 0;
  uint32_t key;
  uint8_t key_len;

  tree_item= tree->root;
  key= 0;
  key_len= 0;

  // Depth first search
  while (tree_item != NULL) {
    if (tree_item->data!= NULL) {
      result= fForEach(key, key_len, tree_item->data, ctx);
      if (result != 0)
	return result;
    }
    if (tree_item->left != NULL) {
      if (tree_item->right != NULL)
	_stack_push(stack, tree_item->right, key_len+1,
		    key+(1 << (tree->key_len-key_len-1)));
      tree_item= tree_item->left;
      key_len++;
    } else if (tree_item->right != NULL) {
      tree_item= tree_item->right;
      key= key+(1 << (tree->key_len-key_len-1));
      key_len++;
    } else {
      if (stack_depth(stack) > 0)
	_stack_pop(stack, &tree_item, &key_len, &key);
      else
	break;
    }
  }
  stack_destroy(&stack);
  return 0;
}