Nagios – система мониторинга ЦОД Сергей Болдин Листинг 1. Установка NagiosXI // Заходим в директорию для распаковки архива cd /tmp // Скачиваем последнюю версию NagiosXI wget http://assets.nagios.com/downloads/nagiosxi/xi-latest.tar.gz // Переходим в папку со всем содержимым для установки системы cd /tmp/nagiosxi // Запускаем установочный файл ./fullinstall ----------------------------------------------------------------------------------------------------------------- Memcached. Эффективно работаем с кэшированием Константин Кондаков $ sudo rpm -Uvh http://mirrors.kernel.org/fedora-epel/5/x86_64/epel-release-5-4.noarch.rpm $ sudo yum -y install memcached $ sudo /etc/init.d/memcached restart $ sudo chkconfig memcached on $ perl -MCPAN -e shell > install Cache::Memcached define command { command_name check_Memcached command_line $USER1$/check_Memcached.pl -H $HOSTADDRESS$ -p $ARG1$ -T $ARG2$ -R $ARG3$ -U $ARG4$ -a curr_connections,evictions -w ~,~ -c ~,~ -f -A 'utilization,hitrate,response_time, curr_connections,evictions,cmd_set, bytes_written,curr_items,uptime,rusage_system, get_hits,total_connections,get_misses,bytes, time,connection_structures,total_items, limit_maxbytes,rusage_user,cmd_get,bytes_read, threads,rusage_user_ms,rusage_system_ms,cas_hits, conn_yields,incr_misses,decr_misses,delete_misses, incr_hits,decr_hits,delete_hits,cas_badval, cas_misses,cmd_flush,listen_disabled_num, accepting_conns,pointer_size,pid' -P "$SERVICEPERFDATA$" } # ARG1: Порт для соединения с Memcached (может быть 11211 или 11212 или любой другой на усмотрение администратора). # ARG2: Процент «попадания в кэш»: все, что ниже 60%, – предупреждение, а ниже 30% – критическая отметка. Разумеется, это все можно настроить. # ARG3: Время доступа: медленнее, чем 0,1 секунды, – «предупреждение», медленнее 0,2 секунды – критическое значение. # ARG4: Процент утилизации: больше 95% – предупреждение, а больше 98% – это критическое значение. define service { use prod-service service_description Memcached: Port 11212 check_command check_Memcached!11212!'>0.1,>0.2'!'<60,<30'!'>95,>98' hostgroups Memcached } create table tomcat_sessions ( session_id varchar(100) not null primary key, valid_session char(1) not null, max_inactive int not null, last_access bigint not null, app_context varchar(255), session_data meduimlob, KEY kapp_context(app_context) ); $ chown tommy:dev /usr/local/tomcat/lib/*.jar $ chmod 644 /usr/local/tomcat/lib/*.jar ----------------------------------------------------------------------------------------------------------------- Этюд о виртуализации Игорь Орещенков C:\{QEMU-path}\qemu-img create harddrive.img 1000M C:\{QEMU-path}\qemu-system-i386 -m 64M -serial COM1 -boot order=dc -cdrom zoot-i386.iso harddrive.img s0:2345:respawn:/sbin/getty ttyS0 DT9600 # kill -HUP 1 command> change CNCA0 PortName=COM2 command> change CNCB0 PortName=COM3 command> change CNCA0 EmuBR=yes,EmuOverrun=yes command> change CNCB0 EmuBR=yes,EmuOverrun=yes -net tap,ifname=TAP-Win32 -net nic;model=ne2k_pci qemu-system-i386 -m 64M -serial COM2 -net tap,ifname=TAP-Win32 -net nic,model=ne2k_pci -boot order=c harddrive.img ----------------------------------------------------------------------------------------------------------------- Теория и практика Open vSwitch. Часть 2. Протокол OpenFlow Александр Руденко set controller management-interface config static [ ] # ovs-vsctl show # ovs-ofctl dump-flows xenbr0 # sudo ovs-ofctl add-flow xenbr0 idle_timeout=0, icmp,action=drop # ovs-ofctl add-flow xenbr0 "in_port=1 ip idle_timeout=0 nw_dst=192.168.14.0/24 priority=40000 action=drop" # ovs-dpctl show xenbr0 ----------------------------------------------------------------------------------------------------------------- Microsoft Exchange 2010/2013. Управление БД почтовых ящиков Сергей Барамба Get-Mailbox -Arbitration Get-Mailbox -Monitoring Get-Mailbox -Database "" -Arbitration | New-MoveRequest -TargetDatabase "" Set-MailboxDatabase -IsExcludedFromProvisioning $true Get-MailboxDatabase -status |ft server,name, AvailableNewMailboxSpace -AutoSize eseutil /ms "database.edb" ----------------------------------------------------------------------------------------------------------------- Новое в Windows Server 2012 R2: целостность, конфиденциальность и доступность Андрей Бирюков > mstsc /restrictedadmin ----------------------------------------------------------------------------------------------------------------- PowerShell: безопасность. Управление паролями Иван Коробко $t = read-host -AsSecureString $Ptr=[System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($t) $pwd="*******" $Ptr=[System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($pwd) $str=[System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr) Write-host security string: $str $obj=Get-Credential $pwd=$obj.Password $uname=$obj.UserName $Ptr=[System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($pwd) $str=[System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr) Write-host username: $uname write-host password: $str $username = "domain\username" $password="*******" $server="servername" $pwd = ConvertTo-SecureString -String $password -asplaintext -force $cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $username,$pwd Invoke-Command -ComputerName $server -ScriptBlock {(dir env:computername).value} -Credential $cred $path = (dir Env:\windir).Value $Obj = Get-Acl -Path $Path $Obj.Access | Out-GridView $acl = Get-Acl c:\Windows $acl | Set-Acl c:\Folder $acl = Get-Acl c:\Folder $permission = "island\corwin", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow" # Равнозначная запись: # $permission = "island\corwin",2032127, 3, 0, 0 $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission $acl.SetAccessRule($accessRule) $acl | Set-Acl $acl.path $acl = Get-Acl c:\Folder $acl.access | % { $acl.PurgeAccessRules($_.IdentityReference) } $acl | Set-Acl $acl.path ----------------------------------------------------------------------------------------------------------------- Программирование для Android. Изучаем ресурсы и делаем приложение в ADT Сергей Ильичев setContentView( R.layout.main ); AssetsFileListerApp Выбор файла Файл 1 Файл 2 Файл 3 Файл 4 Файл 5 public class MainActivity extends Activity { implements OnClickListener public void onClick(View arg0) { }. final String LOG_TAG = "myLogs"; String[] files; ListView fileListView; Map fMap = new TreeMap(); List l = new ArrayList(); Log.d(LOG_TAG, "Сообщение 1"); private void getFileTableFromXML() throws XmlPullParserException, IOException { Resources res = this.getResources(); XmlResourceParser xp = res.getXml(R.xml.namelist); String filename = ""; xp.next(); int eventType = xp.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_DOCUMENT) { Log.d(LOG_TAG, "StartReadXMLDocument"); } else if (eventType == XmlPullParser.START_TAG) { if (!xp.getName().equals("namelist")) { filename = xp.getName(); } } else if (eventType ==XmlPullParser.TEXT) { fMap.put(xp.getText(), filename); } eventType = xp.next(); } } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Берем информацию из xml-файла в контейнер Map try { getFileTableFromXML(); } catch (IOException ioe) {} catch (XmlPullParserException xmlppe) {} //Преобразуем значения ключей Мар в массив названий Set ks = fMap.keySet(); files = new String[ks.size()]; files = ks.toArray(files); //Создаем список fileListView = (ListView) findViewById(R.id.list_of_files); //Устанавливаем режим выбора пунктов списка fileListView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE); //Создаем адаптер ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_single_choice, files); //Адаптер передает значения массива списку fileListView.setAdapter(adapter); //Рисуем кнопку и устанавливаем ее обработчик Button btnChecked = (Button) findViewById(R.id.btnChecked); btnChecked.setOnClickListener(this); } public void onClick(View arg0) { //Пишем в лог выделенный элемент Log.d(LOG_TAG, "checked: " + files[fileListView.getCheckedItemPosition()]); //и название файла Log.d ( LOG_TAG, "file: " + fMap.get(files[fileListView.getCheckedItemPosition()]) ); //Читаем данные из файла String fname = fMap.get( files[fileListView.getCheckedItemPosition()]); try { //Из TreeMap берем имя файла и читаем из него InputStream is = getAssets().open("group1/" + fname); BufferedReader in = new BufferedReader(new InputStreamReader(is)); String inputLine; //Обнуляем ArrayList l.removeAll(l); while ( !(inputLine = in.readLine()).equals("@->endofpmfile<-@") ) { Log.d (LOG_TAG, inputLine); } in.close(); } catch (IOException ioe) {} } ----------------------------------------------------------------------------------------------------------------- NoSQL как он есть Александр Календарев Alexandre Kalendarev
Bolshaya monetnaya street,Saint-Petersburg, Russia
some data< /description > < /Goods> < Invoice > { Invoice : { number:123456, date: 21.10.2010" , Customer : { Id:1321, CustomerName: Alexandre "Kalendarev" , Address: "Bolshaya monetnaya street, Saint-Petersburg, Russia" }, Goods : [ Item: { Name : "Camera Cannon S-90", Id : 123432, Iean : "54321234", Categoty : "photo" CategoryId : "12", description : "some data" }, ] } CREATE TABLE `товары` ( `id` INT NOT NULL , `наименование` VARCHAR(45) NULL , `заказчик` INT(11) NULL , `накладная` INT(11) NULL , `цена` INT(11) NULL , `описание` TINYTEXT NULL , PRIMARY KEY (`id`) ) struct good { int name id; char[45]; int customer_id; int invoice_id; int price; char* description; } наименование: колонка_1, колонка_2, колонка_3. struct name { char value[45]; time_t timestamp ; } ----------------------------------------------------------------------------------------------------------------- Разработка программного модуля PAM Рашид Ачилов auth sufficient pam_unix.so no_warn try_first_pass local_pass debug auth required pam_ldap.so use_first_pass account sufficient pam_unix.so account required pam_mkhome.so mode=0700 session required pam_mkhome.so mode=0700 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define PAM_SM_ACCOUNT #define PAM_SM_SESSION #include #include #include /* Эта функция вызывается, когда вызван сервис account */ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags __unused, int argc , const char *argv[] ) { return(_pam_homedir(pamh, argc, argv)); } /* Эта функция вызывается, когда вызван сервис session */ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags __unused, int argc , const char *argv[] ) { return(_pam_homedir(pamh, argc, argv)); } /* Это фиктивный вызов, но он должен присутствовать. */ /* Он ничего не делает */ PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused, int argc __unused, const char *argv[] __unused) { return (PAM_SUCCESS); } PAM_MODULE_ENTRY("pam_mkhome"); int _pam_homedir(pam_handle_t *pamh, int argc , const char *argv[] ) { struct passwd *pwd; const char *user; int pam_err = PAM_SUCCESS, i; struct stat st; mode_t *set = NULL; const char *res = NULL; char *buff,*skeldir,*modeval; /* Выделяем рабочие области */ buff = calloc(MAXPATHLEN * 3,1); skeldir = buff + MAXPATHLEN; modeval = skeldir + MAXPATHLEN; extern int openpam_debug; /* Разбираем параметры вызова. Если не задано, заносим умолчания */ /* Обрабатываем debug=N. Все, кроме '1', обрабатывается как '0' */ if ((res = (openpam_get_option(pamh, "debug"))) != NULL) if (i = isdigit(*res)) openpam_debug = i; else openpam_debug = 0; else openpam_debug = 0; /* Обрабатываем параметр 'skel=/path' */ if ((res = (openpam_get_option(pamh, "skel"))) != NULL) strncpy(skeldir,res,sizeof(res)); else strncpy(skeldir,"/usr/share/skel",sizeof(skeldir)); /* Обрабатываем параметр 'mode=xxxx' */ if ((res = (openpam_get_option(pamh, "mode"))) != NULL) strncpy(modeval,res,sizeof(res)); else strncpy(modeval,"0755",sizeof(modeval)); #define PAM_LOG(...) openpam_log(PAM_LOG_DEBUG, __VA_ARGS__) /* Получить имя пользователя */ pam_err = pam_get_user(pamh, &user, NULL); if (pam_err != PAM_SUCCESS) PAM_LOG("Cannot get user: %s [%d]", pam_strerror(pamh, pam_err), pam_err); else PAM_LOG("Taken username [%s]", user); /* Получить данные пользователя */ if ((user == NULL) || ((pwd = getpwnam(user)) == NULL)) { PAM_LOG("User has NULL name or does not specified ↵homedir"); pam_err = PAM_SERVICE_ERR; } /* Если домашний каталог, указанный в данных пользователя, существует, и это каталог – просто завершаем работу */ if ((stat(pwd->pw_dir,&st) == 0) && (S_ISDIR(st.st_mode))) { free(buff); return (PAM_SUCCESS); } /* Если были ошибки – ничего не делать */ if (!pam_err) { /* Проверить указанный режим для каталога */ if ((set = setmode(modeval)) == NULL ) { PAM_LOG("Value set in mode is not a mode - see chmod(1) for details"); pam_err = PAM_SYSTEM_ERR; } /* В этом месте мы на самом деле создаем каталог и копируем файлы */ if (!pam_err) pam_err = _copymkdir(pwd->pw_dir, skeldir, getmode(set, S_IRWXU | S_IRWXG | S_IRWXO), pwd->pw_uid, pwd->pw_gid); /* Освободить данные, выделенные setmode() */ free(set); } free(buff); /* Process option 'no_fail' */ if ((!pam_err) || (openpam_get_option(pamh, "no_fail"))) return(PAM_SUCCESS); else return (pam_err); } int_copymkdir(char const *dir, char const *skel, mode_t mode, uid_t uid, gid_t gid) { char *src, *dst; int infd, outfd, b; struct stat st; static char *copybuf = NULL; DIR *d; struct dirent *e; /* Распределить память для буферов */ src = calloc(MAXPATHLEN * 2, 1); dst = src + MAXPATHLEN; PAM_LOG("Called: dir %s, uid:[%d], gid:[%d]",dir,uid,gid); /* Если каталог невозможно создать и ошибка не "already exist" – возвращаем ошибку */ if (mkdir(dir, mode) != 0 && errno != EEXIST) { PAM_LOG("mkdir(%s), error: %s [%d], euid:%d, egid:%d", dir,strerror(errno),errno,geteuid(),getegid()); free(src); return(PAM_SERVICE_ERR); } /* Изменить владельца и группу */ if (chown(dir, uid, gid) != 0) { PAM_LOG("Cannot change owner or group: %s [%d]", strerror(errno), errno); free(src); return(PAM_SERVICE_ERR); } /* Проверить наличие каталога шаблонов */ if (skel == NULL || *skel == '\0') { free(src); PAM_LOG("Skel directory does not specified or NULL"); return(PAM_SERVICE_ERR); } if ((stat(skel,&st) != 0) || (!S_ISDIR(st.st_mode))) { PAM_LOG("Skel directory %s does not exist or is not a directory",skel); free(src); return(PAM_SERVICE_ERR); } /* Oткрыть каталог на чтение */ if ((d = opendir(skel)) == NULL) { PAM_LOG("Cannot open skel directory %s for reading: [%d]",skel,errno); free(src); return(PAM_SERVICE_ERR); } /* Чтение каталога */ while ((e = readdir(d)) != NULL) { char *p = e->d_name; /* Если длина итоговой строки skel+p больше или равна MAXPATHLEN, мы не копируем, но возвращаем успех */ if ((strlen(skel) + strlen(p)) >= MAXPATHLEN) { PAM_LOG("warning: path too long '%s/%s' (skel not copied)", skel, p); continue; } else snprintf(src, MAXPATHLEN, "%s/%s", skel, p); /* Получить данные о копируемом файле */ if (stat(src, &st) == 0) { /* Если имя начинается с «dot.», пропустить */ /* текст «dot» */ if (strncmp(p, "dot.", 4) == 0) p += 3; /* Если длина пути и имени файла, в который копируется, превышает MAXPATHLEN, не копируем, но возвращаем success */ if ((strlen(dir) + strlen(p)) >= MAXPATHLEN) { PAM_LOG("warning: path too long '%s/%s' (skel file skipped)", dir, p); continue; } else snprintf(dst, MAXPATHLEN, "%s/%s", dir, p); /* Если это каталог, скопировать его рекурсивно */ /* Пропустить «.» и «..» */ if (S_ISDIR(st.st_mode)) { if ((strcmp(e->d_name, ".") != 0) && (strcmp(e->d_name, "..") != 0))_copymkdir(dst, src, (st.st_mode& 0777), uid, gid); chflags(dst, st.st_flags); } else /* Это обычный файл и файл приемника открыты */ /* успешно */ if (S_ISREG(st.st_mode) && (outfd = open(dst, O_RDWR | O_CREAT | O_EXCL, st.st_mode)) != -1) { /* Не открыли исходный файл */ if ((infd = open(src, O_RDONLY)) == -1) { PAM_LOG("Source %s cannot open: [%d]",src,errno); /* Закрыть приемник и удалить его */ close(outfd); remove(dst); free(src); return(PAM_SERVICE_ERR); } else { if (copybuf == NULL) copybuf = malloc(4096); /* Копируем прямым чтением/записью */ while ((b = read(infd, copybuf, 4096)) > 0) write(outfd, copybuf, b); close(infd); /* Set owner and flags */ close(outfd); chown(dst, uid, gid); chmod(dst, st.st_mode); chflags(dst, st.st_flags); } /* if infd=open... */ } /* if S_ISREG(st.st_mode.. */ else { PAM_LOG("Destination %s cannot open: [%d]", dst, errno); free(src); return(PAM_SERVICE_ERR); } } else { /* if stat(src==0) */ PAM_LOG("Cannot stat source %s: [%d]",src,errno); free(src); return(PAM_SERVICE_ERR); } } /* while (e=readdir... */ closedir(d); if (copybuf != NULL) { free(copybuf); copybuf = NULL; } free(src); return(PAM_SUCCESS); } CFLAGS+= -DOPENPAM_DEBUG ----------------------------------------------------------------------------------------------------------------- lguest: виртуализация изнутри Валентин Синицын #ifdef CONFIG_PARAVIRT #include #else … static inline notrace unsigned long arch_local_save_flags(void) { return native_save_fl(); } pushf; pop flags static inline notrace unsigned long arch_local_save_flags(void) { return PVOP_CALLEE0(unsigned long, pv_irq_ops.save_fl); } __init void lguest_init(void) { pv_info.name = "lguest"; pv_info.paravirt_enabled = 1; pv_info.kernel_rpl = 1; … pv_irq_ops.save_fl = PV_CALLEE_SAVE(save_fl); … static unsigned long save_fl(void) { return lguest_data.irq_enabled; } struct pv_info pv_info = { .name = "bare hardware", .paravirt_enabled = 0, .kernel_rpl = 0, … struct pv_irq_ops pv_irq_ops = { .save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), … apply_paravirt(__parainstructions, __parainstructions_end); for (p = start; p < end; p++) { … memcpy(insnbuf, p->instr, p->len); used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf, (unsigned long)p->instr, p->len); … } pushf; pop %eax static inline void load_idt(const struct desc_ptr *dtr) { PVOP_VCALL1(pv_cpu_ops.load_idt, dtr); } static void lguest_load_idt(const struct desc_ptr *desc) { unsigned int i; struct desc_struct *idt = (void *)desc->address; for (i = 0; i < (desc->size+1)/8; i++) hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b, 0); } … lidt LGUEST_PAGES_guest_idt_desc(%eax) … … movl LGUEST_PAGES_regs_trapnum(%eax), %ebx; … iret int run_guest(struct lg_cpu *cpu, unsigned long __user *user) { while (!cpu->lg->dead) { … if (cpu->hcall) do_hypercalls(cpu); … local_irq_disable(); lguest_arch_run_guest(cpu); local_irq_enable(); lguest_arch_handle_trap(cpu); } … } void lguest_arch_handle_trap(struct lg_cpu *cpu) { switch (cpu->regs->trapnum) { … case LGUEST_TRAP_ENTRY: cpu->hcall = (struct hcall_args *)cpu->regs; return; } … void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int num, u32 lo, u32 hi) { if (num == 2 || num == 8 || num == 15 || num == LGUEST_TRAP_ENTRY) return; … if (num >= ARRAY_SIZE(cpu->arch.idt)) kill_guest(cpu, "Setting idt entry %u", num); else set_trap(cpu, &cpu->arch.idt[num], num, lo, hi); } bool deliver_trap(struct lg_cpu *cpu, unsigned int num) { if (num >= ARRAY_SIZE(cpu->arch.idt)) return false; if (!idt_present(cpu->arch.idt[num].a, cpu->arch.idt[num].b)) return false; set_guest_interrupt(cpu, cpu->arch.idt[num].a, cpu->arch.idt[num].b, has_err(num)); return true; } static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, bool has_err) { … cpu->regs->ss = ss; cpu->regs->esp = virtstack + (gstack - origstack); cpu->regs->cs = (__KERNEL_CS|GUEST_PL); cpu->regs->eip = idt_address(lo, hi); … } start = load_kernel(open_or_die(argv[optind+1], O_RDONLY)); … boot = from_guest_phys(0); … boot->hdr.hardware_subarch = 1; … tell_kernel(start); unsigned long args[] = { LHREQ_INITIALIZE, (unsigned long)guest_base, guest_limit / getpagesize(), start }; lguest_fd = open_or_die("/dev/lguest", O_RDWR); write(lguest_fd, args, sizeof(args); static void lg_notify(struct virtqueue *vq) { struct lguest_vq_info *lvq = vq->priv; hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0); } … case LHCALL_NOTIFY: cpu->pending_notify = args->arg1; break; … … if (cpu->pending_notify) { if (!send_notify_to_eventfd(cpu)) { if (put_user(cpu->pending_notify, user)) return -EFAULT; return sizeof(cpu->pending_notify); } } … static void create_thread(struct virtqueue *vq) { … unsigned long args[] = { LHREQ_EVENTFD, vq->config. pfn*getpagesize(), 0 }; vq->eventfd = eventfd(0, 0); if (vq->eventfd < 0) err(1, "Creating eventfd"); args[2] = vq->eventfd; … static void net_output(struct virtqueue *vq) { … head = wait_for_vq_desc(vq, iov, &out, &in); … if (writev(net_info->tunfd, iov, out) < 0) warnx("Write to tun failed (%d)?", errno); add_used(vq, head, 0); } static unsigned wait_for_vq_desc(…) { … while (last_avail == vq->vring.avail->idx) { … trigger_irq(vq); … static void trigger_irq(struct virtqueue *vq) { unsigned long buf[] = { LHREQ_IRQ, vq->config.irq }; … if (write(lguest_fd, buf, sizeof(buf)) != 0) err(1, "Triggering irq %i", vq->config.irq); } void set_interrupt(struct lg_cpu *cpu, unsigned int irq) { set_bit(irq, cpu->irqs_pending); if (!wake_up_process(cpu->tsk)) kick_process(cpu->tsk); } irq = interrupt_pending(cpu, &more); if (irq < LGUEST_IRQS) try_deliver_interrupt(cpu, irq, more); idt = &cpu->arch.idt[FIRST_EXTERNAL_VECTOR+irq]; if (idt_present(idt->a, idt->b)) { set_guest_interrupt(cpu, idt->a, idt->b, false); } ENTRY(switch_to_guest) … // Interrupts are turned back on: we are Guest. iret -----------------------------------------------------------------------------------------------------------------