Фишки

от программирования и прочей повседневщины
Создано Harbour в Ср 28 / Окт, 2009 15:44 EET
Последнее сообщение Вт 23 / Mar, 2010 14:39 EET
(2 Сообщений | 797 Посещений | Активность=2.00)

Поиск:

SwitchVox - это обкоцанный Asterisk от Digium с жалкой попыткой защиты от копирования/нелегального использования. Для начала получаем в нем root :

1. boot in single user mode (press 'a' in Grub and append word 'single' to kernel command line)
2. добавляем юзера root2 - adduser -o -u 0 root2
3. Устанавливаем ему пароль - passwd root2
4. Устанавливаем запуск SSHD при старте сервера - chkconfig --level 3 sshd on
5. reboot и enjoy full system access

 Как-то понадобилось создать пару тыщ таймеров для обьектов и по срабатыванию очередного таймера совершать некие операции над обьектами, с которыми эти таймеры были ассоциированы. По наводке от JustMad пощупал timerfd интерфейс, ничего так, ниже дан неотшлифованный примерчик, который создает тыщу таймеров в одном потоке и другим потоком их разгребает, почти не загружая при этом проц :

// тест timerfd подсистемы :
//
// - создает следящий тред
// - добавляет 1024 таймера с разными expire временами в fdset
// - запускает и проверяет expire event
// - при timer expire таймер удаляется из fdset

#include <sys/timerfd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <poll.h>

pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER;

typedef struct timers_fds_t {
  struct pollfd *pfds;
  int nfds;

} timers_fds_t;

timers_fds_t timers_fds;

void remove_timer(int fd)
{
 int i;

 pthread_mutex_lock(&timer_mutex);
 for (i = 0; i < timers_fds.nfds; i++) {
   if (timers_fds.pfds[i].fd == fd) {
     // освобождаем kernel resources
     close(timers_fds.pfds[i].fd);
     // меняем fd на последний
     memcpy(&(timers_fds.pfds[i]),
       &(timers_fds.pfds[timers_fds.nfds - 1]), sizeof(struct pollfd));
     timers_fds.nfds--;
     if (!timers_fds.nfds) {
       printf("All timers expired\n");
       exit(0);
    }
     break;
   }
 }
 pthread_mutex_unlock(&timer_mutex);
}

void *timer_thread(void *args)
{
 timers_fds_t local_timers_fds;
 int res, i;

 while(1) {
   if (timers_fds.nfds) {
     local_timers_fds.nfds = timers_fds.nfds;
     local_timers_fds.pfds =
       malloc(local_timers_fds.nfds * sizeof(struct pollfd));
     if (!local_timers_fds.pfds) {
       printf("no memory\n");
       exit(-2);
     }
     memcpy((void *)local_timers_fds.pfds, (void *)timers_fds.pfds,
       sizeof(struct pollfd) * local_timers_fds.nfds);
     pthread_mutex_unlock(&timer_mutex);
   } else {
     pthread_mutex_unlock(&timer_mutex);
     usleep(10000);
     continue;
  }
   pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
   pthread_testcancel();
   res = poll(local_timers_fds.pfds, local_timers_fds.nfds, 100); // 100 ms timeout
   pthread_testcancel();
   pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
   if (res <= 0) {
     if (!res) // timeout
       goto next;
     if ((errno != EAGAIN) && (errno != EINTR)) { // error
       printf("poll return %d: %s\n", res, strerror(errno));
     }
     goto next;
   }
   for (i = 0; i < local_timers_fds.nfds; i++) {
     if (local_timers_fds.pfds[i].revents & POLLIN) { // timer expired
       printf("%d: Expired timer_fd %d\n", i,
         local_timers_fds.pfds[i].fd);
       remove_timer(local_timers_fds.pfds[i].fd);
       // delete timer_fd from pfds
     } else if (local_timers_fds.pfds[i].revents) {
       printf("got %x event for timer_fd %d\n", local_timers_fds.pfds[i].revents,
         local_timers_fds.pfds[i].fd);
     }
   }
next:
  free(local_timers_fds.pfds);
 }
  return 0;
}

void add_timer(int ms)
{
 int timer_fd = timerfd_create(CLOCK_MONOTONIC, 0);
 timers_fds_t local_timers_fds;
 struct itimerspec new_value;

 if (timer_fd < 1) {
   printf("timerfd_create: %s\n", strerror(errno));
   exit(-1);
 }
  pthread_mutex_lock(&timer_mutex);
  local_timers_fds.nfds = timers_fds.nfds;
  local_timers_fds.pfds =
    malloc((local_timers_fds.nfds + 1) * sizeof(struct pollfd));
  if (!local_timers_fds.pfds) {
    printf("no memory\n");
    exit(-2);
  }
  if (local_timers_fds.nfds) // copy old pfds
     memcpy((void *)local_timers_fds.pfds, (void *)timers_fds.pfds,
       sizeof(struct pollfd) * local_timers_fds.nfds);
  // set timer initial expiration
  new_value.it_interval.tv_sec = ms / 1000;
  new_value.it_interval.tv_nsec = (ms % 1000) * 1000000;
  // period after initial expiration
  new_value.it_value.tv_sec = new_value.it_interval.tv_sec;
  new_value.it_value.tv_nsec = new_value.it_interval.tv_nsec;
  if (timerfd_settime(timer_fd, 0, &new_value, 0)) {
    printf("timerfd_settime: %s\n", strerror(errno));
    exit(-3);
  }
  // add timer fd
  local_timers_fds.pfds[local_timers_fds.nfds].events = POLLPRI | POLLIN |
    POLLRDHUP | POLLERR;
  local_timers_fds.pfds[local_timers_fds.nfds].fd = timer_fd;
  local_timers_fds.pfds[local_timers_fds.nfds].revents = 0;
  local_timers_fds.nfds++;
  // copy to global
  free(timers_fds.pfds);
  timers_fds.pfds = local_timers_fds.pfds;
  timers_fds.nfds = local_timers_fds.nfds;
  printf("Adding %d timer_fd %d with %d s and %d ns (%d ms)\n",
    timers_fds.nfds, timer_fd, ms / 1000, (ms % 1000) * 1000000, ms);
  pthread_mutex_unlock(&timer_mutex);
}

int main()
{
 pthread_t tid;
 pthread_attr_t thr_attr;
 void *args = 0;
 int err, count = 0, tms;

 memset((void *)&timers_fds, 0, sizeof(timers_fds_t));
 // create timer thread
 pthread_attr_init(&thr_attr);
 err = pthread_create(&tid, &thr_attr, timer_thread, args);
 if (err) {
   printf("pthread_create: %s\n", strerror(err));
   exit(-1);
 }
 // add some random timers, 4 seconds max
 while (count++ <= 1024) {
   while (!(tms = drand48() * 4000));
   add_timer(tms);
 }
 while(1)
   sleep(1);
 return 0;
}

Последние сообщения блога

  1. Переезд, будь он неладен ...
    Вт 06 / Апр, 2010 18:44 EEST
  2. О трудах человеческих
    Вт 23 / Mar, 2010 19:22 EET
  3. Получаем root в SwitchVox
    Вт 23 / Mar, 2010 14:37 EET
  4. Из лекции Махараджа Шри Девдаса
    Сб 13 / Февр, 2010 12:56 EET
  5. Жизнь должна быть ...
    Пт 12 / Февр, 2010 15:49 EET
  6. Из Дао де Дзин
    Пт 12 / Февр, 2010 15:48 EET
  7. Из Дао де Дзин
    Пт 12 / Февр, 2010 15:48 EET